r239 - in tags: . rott-1.1 rott-1.1/doc rott-1.1/mac rott-1.1/mac/English.lproj rott-1.1/mac/Rise of the Triad.pbproj rott-1.1/misc rott-1.1/rott rott-1.1/rott/audiolib rott-1.1/vs.net

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Mon Jul 14 13:09:17 EDT 2008


Author: fabian
Date: 2008-07-14 13:09:15 -0400 (Mon, 14 Jul 2008)
New Revision: 239

Added:
   tags/rott-1.1/
   tags/rott-1.1/COPYING
   tags/rott-1.1/README
   tags/rott-1.1/doc/
   tags/rott-1.1/doc/13todo.txt
   tags/rott-1.1/doc/cheats.txt
   tags/rott-1.1/doc/cmdline.txt
   tags/rott-1.1/doc/hacker.txt
   tags/rott-1.1/doc/readme.txt
   tags/rott-1.1/doc/rott.6
   tags/rott-1.1/doc/wad.txt
   tags/rott-1.1/mac/
   tags/rott-1.1/mac/English.lproj/
   tags/rott-1.1/mac/English.lproj/InfoPlist.strings
   tags/rott-1.1/mac/Rise of the Triad.pbproj/
   tags/rott-1.1/mac/Rise of the Triad.pbproj/project.pbxproj
   tags/rott-1.1/mac/SDLMain.h
   tags/rott-1.1/mac/SDLMain.m
   tags/rott-1.1/misc/
   tags/rott-1.1/misc/rott.xpm
   tags/rott-1.1/misc/runrott.sh
   tags/rott-1.1/rott/
   tags/rott-1.1/rott/Makefile
   tags/rott-1.1/rott/WinRott.h
   tags/rott-1.1/rott/_engine.h
   tags/rott-1.1/rott/_isr.h
   tags/rott-1.1/rott/_rt_acto.h
   tags/rott-1.1/rott/_rt_buil.h
   tags/rott-1.1/rott/_rt_com.h
   tags/rott-1.1/rott/_rt_dman.h
   tags/rott-1.1/rott/_rt_door.h
   tags/rott-1.1/rott/_rt_draw.h
   tags/rott-1.1/rott/_rt_floo.h
   tags/rott-1.1/rott/_rt_game.h
   tags/rott-1.1/rott/_rt_in.h
   tags/rott-1.1/rott/_rt_main.h
   tags/rott-1.1/rott/_rt_map.h
   tags/rott-1.1/rott/_rt_menu.h
   tags/rott-1.1/rott/_rt_msg.h
   tags/rott-1.1/rott/_rt_net.h
   tags/rott-1.1/rott/_rt_play.h
   tags/rott-1.1/rott/_rt_rand.h
   tags/rott-1.1/rott/_rt_scal.h
   tags/rott-1.1/rott/_rt_soun.h
   tags/rott-1.1/rott/_rt_spba.h
   tags/rott-1.1/rott/_rt_stat.h
   tags/rott-1.1/rott/_rt_str.h
   tags/rott-1.1/rott/_rt_swft.h
   tags/rott-1.1/rott/_rt_ted.h
   tags/rott-1.1/rott/_rt_util.h
   tags/rott-1.1/rott/_rt_vid.h
   tags/rott-1.1/rott/_w_wad.h
   tags/rott-1.1/rott/_z_zone.h
   tags/rott-1.1/rott/audiolib/
   tags/rott-1.1/rott/audiolib/Makefile
   tags/rott-1.1/rott/audiolib/_al_midi.h
   tags/rott-1.1/rott/audiolib/_blaster.h
   tags/rott-1.1/rott/audiolib/_guswave.h
   tags/rott-1.1/rott/audiolib/_midi.h
   tags/rott-1.1/rott/audiolib/_multivc.h
   tags/rott-1.1/rott/audiolib/_pas16.h
   tags/rott-1.1/rott/audiolib/_sndscap.h
   tags/rott-1.1/rott/audiolib/adlibfx.c
   tags/rott-1.1/rott/audiolib/adlibfx.h
   tags/rott-1.1/rott/audiolib/al_midi.c
   tags/rott-1.1/rott/audiolib/al_midi.h
   tags/rott-1.1/rott/audiolib/assert.h
   tags/rott-1.1/rott/audiolib/awe32.c
   tags/rott-1.1/rott/audiolib/awe32.h
   tags/rott-1.1/rott/audiolib/blaster.c
   tags/rott-1.1/rott/audiolib/blaster.h
   tags/rott-1.1/rott/audiolib/ctaweapi.h
   tags/rott-1.1/rott/audiolib/debugio.c
   tags/rott-1.1/rott/audiolib/debugio.h
   tags/rott-1.1/rott/audiolib/dma.c
   tags/rott-1.1/rott/audiolib/dma.h
   tags/rott-1.1/rott/audiolib/dpmi.c
   tags/rott-1.1/rott/audiolib/dpmi.h
   tags/rott-1.1/rott/audiolib/dsl.c
   tags/rott-1.1/rott/audiolib/dsl.h
   tags/rott-1.1/rott/audiolib/fx_man.c
   tags/rott-1.1/rott/audiolib/fx_man.h
   tags/rott-1.1/rott/audiolib/gmtimbre.c
   tags/rott-1.1/rott/audiolib/gus.c
   tags/rott-1.1/rott/audiolib/gusmidi.c
   tags/rott-1.1/rott/audiolib/gusmidi.h
   tags/rott-1.1/rott/audiolib/guswave.c
   tags/rott-1.1/rott/audiolib/guswave.h
   tags/rott-1.1/rott/audiolib/interrup.h
   tags/rott-1.1/rott/audiolib/irq.c
   tags/rott-1.1/rott/audiolib/irq.h
   tags/rott-1.1/rott/audiolib/leetimbr.c
   tags/rott-1.1/rott/audiolib/linklist.h
   tags/rott-1.1/rott/audiolib/ll_man.c
   tags/rott-1.1/rott/audiolib/ll_man.h
   tags/rott-1.1/rott/audiolib/midi.c
   tags/rott-1.1/rott/audiolib/midi.h
   tags/rott-1.1/rott/audiolib/mpu401.c
   tags/rott-1.1/rott/audiolib/mpu401.h
   tags/rott-1.1/rott/audiolib/multivoc.c
   tags/rott-1.1/rott/audiolib/multivoc.h
   tags/rott-1.1/rott/audiolib/music.c
   tags/rott-1.1/rott/audiolib/music.h
   tags/rott-1.1/rott/audiolib/mv_mix.asm
   tags/rott-1.1/rott/audiolib/mv_mix.c
   tags/rott-1.1/rott/audiolib/mv_mix16.asm
   tags/rott-1.1/rott/audiolib/mvreverb.asm
   tags/rott-1.1/rott/audiolib/mvreverb.c
   tags/rott-1.1/rott/audiolib/myprint.c
   tags/rott-1.1/rott/audiolib/myprint.h
   tags/rott-1.1/rott/audiolib/newgf1.h
   tags/rott-1.1/rott/audiolib/nodpmi.c
   tags/rott-1.1/rott/audiolib/nomusic.c
   tags/rott-1.1/rott/audiolib/pas16.c
   tags/rott-1.1/rott/audiolib/pas16.h
   tags/rott-1.1/rott/audiolib/pitch.c
   tags/rott-1.1/rott/audiolib/pitch.h
   tags/rott-1.1/rott/audiolib/platform.h
   tags/rott-1.1/rott/audiolib/sndcards.h
   tags/rott-1.1/rott/audiolib/sndscape.c
   tags/rott-1.1/rott/audiolib/sndscape.h
   tags/rott-1.1/rott/audiolib/sndsrc.c
   tags/rott-1.1/rott/audiolib/sndsrc.h
   tags/rott-1.1/rott/audiolib/standard.h
   tags/rott-1.1/rott/audiolib/task_man.c
   tags/rott-1.1/rott/audiolib/task_man.h
   tags/rott-1.1/rott/audiolib/user.c
   tags/rott-1.1/rott/audiolib/user.h
   tags/rott-1.1/rott/audiolib/usrhooks.c
   tags/rott-1.1/rott/audiolib/usrhooks.h
   tags/rott-1.1/rott/audiolib/util.h
   tags/rott-1.1/rott/byteordr.c
   tags/rott-1.1/rott/byteordr.h
   tags/rott-1.1/rott/cin_actr.c
   tags/rott-1.1/rott/cin_actr.h
   tags/rott-1.1/rott/cin_def.h
   tags/rott-1.1/rott/cin_efct.c
   tags/rott-1.1/rott/cin_efct.h
   tags/rott-1.1/rott/cin_evnt.c
   tags/rott-1.1/rott/cin_evnt.h
   tags/rott-1.1/rott/cin_glob.c
   tags/rott-1.1/rott/cin_glob.h
   tags/rott-1.1/rott/cin_main.c
   tags/rott-1.1/rott/cin_main.h
   tags/rott-1.1/rott/cin_util.c
   tags/rott-1.1/rott/cin_util.h
   tags/rott-1.1/rott/develop.h
   tags/rott-1.1/rott/dosutil.c
   tags/rott-1.1/rott/dukemusc.c
   tags/rott-1.1/rott/engine.c
   tags/rott-1.1/rott/engine.h
   tags/rott-1.1/rott/f_scale.asm
   tags/rott-1.1/rott/f_scale.h
   tags/rott-1.1/rott/fli_def.h
   tags/rott-1.1/rott/fli_glob.h
   tags/rott-1.1/rott/fli_main.c
   tags/rott-1.1/rott/fli_main.h
   tags/rott-1.1/rott/fli_type.h
   tags/rott-1.1/rott/fli_util.c
   tags/rott-1.1/rott/fli_util.h
   tags/rott-1.1/rott/fx_man.c
   tags/rott-1.1/rott/fx_man.h
   tags/rott-1.1/rott/gmove.h
   tags/rott-1.1/rott/isr.c
   tags/rott-1.1/rott/isr.h
   tags/rott-1.1/rott/keyb.h
   tags/rott-1.1/rott/lookups.c
   tags/rott-1.1/rott/lumpy.h
   tags/rott-1.1/rott/memcheck.h
   tags/rott-1.1/rott/modexlib.c
   tags/rott-1.1/rott/modexlib.h
   tags/rott-1.1/rott/music.h
   tags/rott-1.1/rott/myprint.h
   tags/rott-1.1/rott/profile.h
   tags/rott-1.1/rott/r_scale.asm
   tags/rott-1.1/rott/rottnet.h
   tags/rott-1.1/rott/rt_actor.c
   tags/rott-1.1/rott/rt_actor.h
   tags/rott-1.1/rott/rt_battl.c
   tags/rott-1.1/rott/rt_battl.h
   tags/rott-1.1/rott/rt_build.c
   tags/rott-1.1/rott/rt_build.h
   tags/rott-1.1/rott/rt_cfg.c
   tags/rott-1.1/rott/rt_cfg.h
   tags/rott-1.1/rott/rt_com.c
   tags/rott-1.1/rott/rt_com.h
   tags/rott-1.1/rott/rt_crc.c
   tags/rott-1.1/rott/rt_crc.h
   tags/rott-1.1/rott/rt_debug.c
   tags/rott-1.1/rott/rt_debug.h
   tags/rott-1.1/rott/rt_def.h
   tags/rott-1.1/rott/rt_dmand.c
   tags/rott-1.1/rott/rt_dmand.h
   tags/rott-1.1/rott/rt_door.c
   tags/rott-1.1/rott/rt_door.h
   tags/rott-1.1/rott/rt_dr_a.asm
   tags/rott-1.1/rott/rt_dr_a.h
   tags/rott-1.1/rott/rt_draw.c
   tags/rott-1.1/rott/rt_draw.h
   tags/rott-1.1/rott/rt_err.c
   tags/rott-1.1/rott/rt_error.c
   tags/rott-1.1/rott/rt_error.h
   tags/rott-1.1/rott/rt_fc_a.asm
   tags/rott-1.1/rott/rt_fc_a.h
   tags/rott-1.1/rott/rt_floor.c
   tags/rott-1.1/rott/rt_floor.h
   tags/rott-1.1/rott/rt_game.c
   tags/rott-1.1/rott/rt_game.h
   tags/rott-1.1/rott/rt_in.c
   tags/rott-1.1/rott/rt_in.h
   tags/rott-1.1/rott/rt_main.c
   tags/rott-1.1/rott/rt_main.h
   tags/rott-1.1/rott/rt_map.c
   tags/rott-1.1/rott/rt_map.h
   tags/rott-1.1/rott/rt_menu.c
   tags/rott-1.1/rott/rt_menu.h
   tags/rott-1.1/rott/rt_msg.c
   tags/rott-1.1/rott/rt_msg.h
   tags/rott-1.1/rott/rt_net.c
   tags/rott-1.1/rott/rt_net.h
   tags/rott-1.1/rott/rt_playr.c
   tags/rott-1.1/rott/rt_playr.h
   tags/rott-1.1/rott/rt_rand.c
   tags/rott-1.1/rott/rt_rand.h
   tags/rott-1.1/rott/rt_sc_a.asm
   tags/rott-1.1/rott/rt_sc_a.h
   tags/rott-1.1/rott/rt_scale.c
   tags/rott-1.1/rott/rt_scale.h
   tags/rott-1.1/rott/rt_sound.c
   tags/rott-1.1/rott/rt_sound.h
   tags/rott-1.1/rott/rt_spbal.c
   tags/rott-1.1/rott/rt_spbal.h
   tags/rott-1.1/rott/rt_sqrt.c
   tags/rott-1.1/rott/rt_sqrt.h
   tags/rott-1.1/rott/rt_stat.c
   tags/rott-1.1/rott/rt_stat.h
   tags/rott-1.1/rott/rt_state.c
   tags/rott-1.1/rott/rt_str.c
   tags/rott-1.1/rott/rt_str.h
   tags/rott-1.1/rott/rt_swift.c
   tags/rott-1.1/rott/rt_swift.h
   tags/rott-1.1/rott/rt_table.h
   tags/rott-1.1/rott/rt_ted.c
   tags/rott-1.1/rott/rt_ted.h
   tags/rott-1.1/rott/rt_util.c
   tags/rott-1.1/rott/rt_util.h
   tags/rott-1.1/rott/rt_vh_a.asm
   tags/rott-1.1/rott/rt_vh_a.h
   tags/rott-1.1/rott/rt_vid.c
   tags/rott-1.1/rott/rt_vid.h
   tags/rott-1.1/rott/rt_view.c
   tags/rott-1.1/rott/rt_view.h
   tags/rott-1.1/rott/sbconfig.c
   tags/rott-1.1/rott/sbconfig.h
   tags/rott-1.1/rott/scriplib.c
   tags/rott-1.1/rott/scriplib.h
   tags/rott-1.1/rott/snd_reg.h
   tags/rott-1.1/rott/snd_shar.h
   tags/rott-1.1/rott/sndcards.h
   tags/rott-1.1/rott/splib.h
   tags/rott-1.1/rott/sprites.h
   tags/rott-1.1/rott/states.h
   tags/rott-1.1/rott/task_man.h
   tags/rott-1.1/rott/version.h
   tags/rott-1.1/rott/w_wad.c
   tags/rott-1.1/rott/w_wad.h
   tags/rott-1.1/rott/watcom.c
   tags/rott-1.1/rott/watcom.h
   tags/rott-1.1/rott/winrott.c
   tags/rott-1.1/rott/z_zone.c
   tags/rott-1.1/rott/z_zone.h
   tags/rott-1.1/vs.net/
   tags/rott-1.1/vs.net/rott.vcproj
Log:
Tagging 1.1 release.


Added: tags/rott-1.1/COPYING
===================================================================
--- tags/rott-1.1/COPYING	                        (rev 0)
+++ tags/rott-1.1/COPYING	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,342 @@
+		    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
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+

Added: tags/rott-1.1/README
===================================================================
--- tags/rott-1.1/README	                        (rev 0)
+++ tags/rott-1.1/README	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,101 @@
+================
+ROTT Port README
+================
+
+This is a port of Apogee's 3D action title Rise of the Triad, originally
+released in 1994.  This port duplicates the functionality of the original
+game on modern operating systems, including Linux, Win32, and Mac OS X.
+
+This port makes use of the Simple Direct Media Layer, or SDL, and an additional
+library named SDL_mixer.  If you do not have these libraries installed, check
+the links section below.
+
+This software is distributed in source code format and is licensed under the
+terms of the GNU General Public License.  A copy of this license is included
+with the software in the file COPYING.
+
+This software is not supported by 3D Realms, Apogee, or the porters.
+
+For reference, the primary contributors to this port are:
+
+Steven Fuller
+Ryan C. Gordon
+John Hall
+Dan Olson
+
+
+-------------------------
+Notes for the 1.1 Release
+-------------------------
+
+Thanks to the effort of the contributors listed below (and probably many more),
+lots of bug fixes, portability improvements and new features have found their
+way into the 1.1 release. Many changes have been ported over from the WinRott
+port (not WinRottGL but plain WinRott) with the high resolution software
+rendering support being the main feature of all these changes. Portability
+fixes include support for 64-bit and big-endian systems.
+
+Birger N. Andreasen (author of the WinRott port
+  <http://home14.inet.tele.dk/Bna-Info/>, initial work by Jonathan Bailey)
+Hans de Goede (porting of the WinRott high resolution renderer,
+  lots of bug and portability fixes for the Fedora package)
+Alexander Thomas aka Dr. Lex (author of the OS X port
+  <http://www.dr-lex.be/software/rott.html>, thanks Filippo Giunchedi for
+  creating the appropriate patch for the Debian package)
+Michael Karcher (lots of bug and portability fixes for the Debian package)
+Fabian Greffrath (some minor improvements)
+
+Getting network play working is considered the release goal for the 2.0
+version.
+
+
+-------------
+General Hints
+-------------
+
+To compile the source code under Linux, change to the rott/ directory and type:
+
+make clean
+make
+
+The source code is setup to use shareware binaries.  If you want to use the
+registered version of ROTT, edit rott/develop.h and make the following changes:
+
+change
+#define SHAREWARE   1
+#define SUPERROTT   0
+to
+#define SHAREWARE   0
+#define SUPERROTT   1
+
+After this, save your changes and compile as normal.
+
+If you experience difficulty with sound, you may need to download a CVS version
+of SDL_mixer.  Instructions for doing this can be found at the SDL_mixer site,
+linked below.
+
+
+------------
+Known Issues
+------------
+
+- Demos go out of sync.
+- No netplay support.
+
+
+-------------
+Helpful Links
+-------------
+
+ROTT Port site:
+http://icculus.org/rott/
+
+The Simple Direct Media Layer:
+http://www.libsdl.org/
+
+SDL_mixer:
+http://www.libsdl.org/projects/SDL_mixer
+
+3D Realms official forum on ROTT source code:
+http://forums.3drealms.com/ubb/ultimatebb.php?ubb=forum;f=24
+

Added: tags/rott-1.1/doc/13todo.txt
===================================================================
--- tags/rott-1.1/doc/13todo.txt	                        (rev 0)
+++ tags/rott-1.1/doc/13todo.txt	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,35 @@
+( ) NME does not always exit level upon killing him
+( ) Game locks when firing Darkstaff or Dog Mode at El Oscuro
+( ) Network server locks up when exiting net game
+( ) Stand( )alone server doesn't work consistently
+( ) Break out with error message if ROTT is run with no sound.rot
+( ) Quickload question should have (Y/N) on end
+( ) Phone number length needs to be lengthed.
+( ) Network packets need checksum word added to their packets
+( ) VR gear new mouse sub functions
+( ) Dog mode still locks up as well as some bat blast stuff
+( ) Fix Live Remote Ridicule
+( ) Wall can push you into platform so you fall down inside of it and be
+    stuck.
+( ) Hanging at menu after a few network/modem games
+( ) Hanging at warp menu prompt
+( ) Warp Menu: chose level, screen went black, some how still in level select
+( ) Unexpect Interrupt
+( ) Generat random levels and battle levels.  Choose alternate both.
+    New game End Game New Game Kaboom
+( ) Make snake heads hurt to touch (fixes snake trapping you)
+( ) Fix missiles not hitting enemy when standing face to face
+( ) lockup on snake with one head left
+( ) gamepad enabled before joystick enabled
+( ) bark blast under dog walls and stuff
+( ) config files saved in alternat RTS directory
+( ) people complaining about reconfiging joystick each time
+( ) Panic mapping over modem glass in 8 megs not in 4 megs
+( ) Voice credit for OverPatrol (CHuck) Lightning guard (william)
+
+MAP Stuff
+( ) level 1( )3 in random powerup crossroads room, two different wall types
+( ) Krist, if led outside of room, goes up disks, but can't go down them.
+  So he winds up running around sky.  Fix map to lock door so Krist cannot
+  come out...
+

Added: tags/rott-1.1/doc/cheats.txt
===================================================================
--- tags/rott-1.1/doc/cheats.txt	                        (rev 0)
+++ tags/rott-1.1/doc/cheats.txt	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,106 @@
+  DISPSTICK                // enable cheats
+  \ECC                     // enable cheats
+  SLACKER                  // three keys, more health
+  \BUM                     // three keys, more health
+  CHOJIN                   // normal god mode
+  \WWW                     // normal god mode
+  GOTO                     // warp
+  \GTL                     // warp
+  SIXTOYS                  // all keys, armor, 100% health
+  \GAI                     // all keys, armor, 100% health
+  TOOSAD                   // god mode powerup
+  \GOD                     // god mode powerup
+
+  // Register only
+  WOOF                     // dog mode powerup
+  \DOG                     // dog mode powerup
+  // end
+
+  FLYBOY                   // mercury mode powerup
+  \MER                     // mercury mode powerup
+  BADTRIP                  // shrooms mode powerup
+  \SHR                     // shrooms mode powerup
+  BOING                    // elasto mode powerup
+  \ELA                     // elasto mode powerup
+  GOOBERS                  // warp to level 1, start with pistol
+  \GOO                     // warp to level 1, start with pistol
+  WHACK                    // hurt player 10%
+  \OOF                     // hurt player 10%
+  SPEED                    // run fast all the time
+  \RFA                     // run fast all the time
+  PANIC                    // back to normal
+  \PAN                     // back to normal
+  DIMON                    // light diminishing on
+  \DON                     // light diminishing on
+  DIMOFF                   // light diminishing off
+  \DOF                     // light diminishing off
+  LONDON                   // fog on (0x00 - 0x80 minmax)
+  \FON                     // fog on (0x00 - 0x80 minmax)
+  NODNOL                   // fog off (0x80 - 0xFF minmax)
+  \FOF                     // fog off (0x80 - 0xFF minmax)
+  GOGATES                  // blow out of game
+  \L8R                     // blow out of game
+  GOARCH                   // end the current level
+  \ECL                     // end the current level
+  GOTA386                  // floor and ceiling off
+  \CON                     // floor and ceiling off
+  GOTA486                  // floor and ceiling on
+  \COF                     // floor and ceiling on
+  SHOOTME                  // bullet proof armor
+  \BAR                     // bullet proof armor
+  BURNME                   // fire proof armor
+  \FAR                     // fire proof armor
+  LUNGDUNG                 // gas mask
+  \GAR                     // gas mask
+  HUNTPACK                 // all keys, armor, 100% health, MP40,
+  \OFP                     // all keys, armor, 100% health, MP40,
+  86ME                     // kill player
+  \DIE                     // kill player
+  NEER                     // re-enter level
+  \REL                     // re-enter level
+  JOHNWOO                  // give double pistol
+  \GW2                     // give double pistol
+  PLUGME                   // give mp40
+  \GW3                     // give mp40
+  VANILLA                  // give bazooka
+  \GW4                     // give bazooka
+  HOTTIMES                 // give heatseeker
+  \GW5                     // give heatseeker
+  BOOZE                    // give drunk missile
+  \GW6                     // give drunk missile
+  FIREBOMB                 // give firebomb
+  \GW7                     // give firebomb
+  BONES                    // give firewall
+  \GW8                     // give firewall
+  SEEYA                    // give god hand
+  \GW9                     // give god hand
+
+  // Register Only
+  SPLIT                    // give split missile
+  \GWA                     // give split missile
+  KESOFDEATH               // give kes
+  \GWB                     // give kes
+  HOMERUN                  // give bat
+  \GWC                     // give bat
+  CUJO                     // give dog weapon
+  \GWD                     // give dog weapon
+  // end
+
+  RIDE                     // give MISSILE CAM
+  \CAM                     // give Missile Cam
+  WHERE                    // turn where am i on/off
+  \HUD                     // give hud
+  \FUN                     // Rotation fun
+  RECORD                   // Demo RECORD
+  STOP                     // Demo stop recording
+  PLAY                     // Demo Playback
+  \EKG                     // Engine Killing Gibs
+  MAESTRO                  // JukeBox
+  \LEE                     // JukeBox
+  CARTIER                  // Map Cheat
+  \MAP                     // Map Cheat
+  \YOU                     // Secret Message
+  HAVE                     // Secret Message
+  \NO                      // Secret Message
+  LIFE                     // Secret Message
+

Added: tags/rott-1.1/doc/cmdline.txt
===================================================================
--- tags/rott-1.1/doc/cmdline.txt	                        (rev 0)
+++ tags/rott-1.1/doc/cmdline.txt	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,75 @@
+
+ROTT.EXE
+========
+
+NOWAIT       go to menu, skip intro
+NOSOUND      no music no sound
+NOW          go immediately into game default difficulty default level 1
+DOPEFISH     Scott Head intro, random sounds in credits, burping while
+             caching, silly strings, eluder/deluder as scott's head,
+             silly death cam, silly menu sounds
+
+MAPSTATS     Print out map statistics to MAPDEBUG.TXT
+TILESTATS    Print out tile statistics to MAPDEBUG.TXT
+VER          Rott version number
+PAUSE        Pause after printing startup info
+SOUNDSETUP   Launch sound Setup WARP [level] Launch to any level (1 based)
+LEVELSIZE    compute memory needed for level
+SLOWDEATH    slow down death rotation
+QUIET        get rid of all start up text except for errors
+FILE
+FILE1        add external wads for graphic replacement
+FILE2
+NOJOYS       disable joystick test
+NOMOUSE      disable mouse test
+SPACEBALL    enable spaceball avenger
+CYBERMAN     enable cyberman
+ASSASSIN     enable wingman assassin
+NOECHO       turn off reverb effect
+DEMOEXIT     exit the game when demo is interrupted
+TIMELIMIT    play for a certain amount of time in seconds
+             once time is gone game ends (unlimited lives)
+             get more time by killing guards and picking up ankhs
+             must use MAXTIMELIMIT as well
+MAXTIMELIMIT the max time to count down from so if you keep killing
+             guards you cannot get an infinite amount of time
+             must use TIMELIMIT as well
+ENABLEVR     enable Virtual Reality support for HMD's (Head mounted disp)
+WARP         warp to a specific level 1 based level 1 is 1
+NET          Used by ROTTSER and ROTTIPX
+IS8250       Used by ROTTSER whether you have an 8250 or not
+TEDLEVEL     Ted stuff
+(DEV ONLY) MONO         enable mono-monitor support (Development only)
+(DEV ONLY) TRANSPORT    Warp to any x,y,angle in level (Development only)
+(DEV ONLY) SCREENSHOTS  get rid of screen title stuff (Development only)
+
+
+ROTTSER.EXE
+========
+
+VECTOR       interrupt vector with which to communicate with ROTT
+ANSWER       answer mode
+DIAL         dial mode
+PAUSE        pause before launching
+STATS        print out run time stats after ROTT returns
+PLAYER       0 - makes you the master
+             1 - makes you not the master
+             must be used on both systems with different values, to work
+             properly
+
+
+ROTTIPX.EXE
+========
+
+VECTOR       interrupt vector with which to communicate with ROTT
+PAUSE        pause before launching
+NODES        number of players in game
+SOCKET       network socket to use
+SERVER       specify this computer to be a server
+STANDALONE   specify this server to be standalone
+             else client on top of server
+MASTER       used by client to make yourself the master
+REMOTERIDICULE turn on remote ridicule support
+
+
+

Added: tags/rott-1.1/doc/hacker.txt
===================================================================
--- tags/rott-1.1/doc/hacker.txt	                        (rev 0)
+++ tags/rott-1.1/doc/hacker.txt	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,508 @@
+
+                              Rise of the Triad
+
+                                 Version 1.1
+
+                                 Hacker Info
+
+RTL & RTC File format:
+----------------------
+
+Rise of the Triad (ROTT) uses two file extensions for levels data, RTL
+and RTC.  RTC indicates that the file is for Comm-bat (multiplayer) play
+only and does not contain any enemies or exits.  RTL indicates the file
+can can be used for both Comm-bat and standard game levels.  In Comm-bat,
+the enemies in RTL maps in standard play are not present during Comm-bat
+games and the exit and entrance arches behave like teleporters.  Other than
+these differences, the two files are alike.
+
+The RTL/RTC file format changed with the release of ROTT version 1.1.
+Since the shareware version of ROTT cannot use alternate levels, this
+should not be a problem for map designers.  The new format is much more
+formal.  If any changes are made in the format in the future,  the first 8
+bytes of the file will inform you if it is compatible with your editor/viewer.
+
+The RTL/RTC file is broken into three sections:  Version info, Header block,
+and Data block.
+
+
+                            RTL/RTC version info
+
+This 8 byte block of data indicates what type of file it is and which
+version of the RTL/RTC file format it is.
+
+  Offset   Size    Description
+-------------------------------------------------------------
+    0        4     Format signature
+    4        4     Version number
+
+Format signature :
+
+This is used to indicate what type of levels are contained within the
+file.  This is a null-terminated string containing either "RTL" or "RTC".
+
+Version number :
+
+0101h for version 1.1.  If this value is higher, it indicates that the file
+format has changed.  This is NOT the ROTT version.
+
+
+                            RTL/RTC Header block
+
+The header block contains an array of 100 structures with the following
+format:
+
+  Offset   Size    Explanation
+-------------------------------------------------------------
+    0        4     Used flag
+    4        4     CRC
+    8        4     RLEWtag
+   12        4     MapSpecials
+   12        4     Offset in file of Wall plane
+   16        4     Offset in file of Sprite plane
+   20        4     Offset in file of Info plane
+   24        4     Length of Wall plane
+   28        4     Length of Sprite plane
+   32        4     Length of Info plane
+   36       24     Name of level
+
+
+Used flag :
+
+This is non-zero if a map exists at this position.
+
+CRC :
+
+This value is used to determine if all the players in a multiplayer game
+are using the same maps.  You can use any method you like to calculate this
+value.
+
+RLEWtag :
+
+This is the run-length encoding tag used for compressing and decompressing
+the map data.  The use of this will be described below.
+
+MapSpecials :
+
+This is used for flags that describe special conditions for the level.
+Currently only one flag is used.  If Bit 0 is set, then all the pushwalls
+will be activated in Comm-bat mode.  This is done in case there are player
+start locations within hidden areas and the player would be trapped until
+a pushwall was activated.
+
+Offsets :
+
+The Wall, Sprite, and Info plane offsets are each absolute offsets of the
+data from the beginning of the file.
+
+Lengths :
+
+The Wall, Sprite, and Info plane lengths are each lengths of the
+uncompressed data.
+
+Name of level :
+
+This is a null-terminated string containing the name of the level.
+Although there is 24 bytes available, level names should be at most 22
+bytes long.
+
+                             RTL/RTC Data block
+
+When expanded, ROTT maps contain 3 planes of 128 by 128 word sized data.
+They are stored in the RTL/RTC files as 3 blocks of run-length encoded
+data.  The procedure for decompressing them is as follows:
+
+    1) Allocate 128 * 128 words of memory (32768 bytes)
+    2) Read one word from compressed block
+    3) If word is equal to RLEWTag, then the next two words are a compressed
+       run of data.  The first word is the number of words to write.
+       The second word is the value to write map.
+       If word was not equal to RLEWTag, then simply write that word
+       to the map.
+    4) Go back to 2 until all data is written.
+
+Here's an example of the procedure in C.
+
+
+/*---------------------------------------------------------------------
+   Function: RLEW_Expand
+
+   Run-length encoded word decompression.
+---------------------------------------------------------------------*/
+
+void RLEW_Expand
+   (
+   unsigned short *source,
+   unsigned short *dest,
+   long length,
+   unsigned short rlewtag
+   )
+
+   {
+   unsigned short value;
+   unsigned short count;
+   unsigned short *end;
+
+   end = dest + length;
+
+   while( dest < end );
+      {
+      value = *source;
+      source++;
+
+      if ( value != rlewtag )
+         {
+         //
+         // uncompressed data
+         //
+         *dest = value;
+         dest++;
+         }
+      else
+         {
+         //
+         // compressed string
+         //
+         count = *source;
+         source++;
+
+         value = *source;
+         source++;
+
+         //
+         // expand the data
+         //
+         while( count > 0 )
+            {
+            *dest = value;
+            dest++;
+            count--;
+            }
+         }
+      }
+   }
+
+
+Here is sample code for loading a ROTT map.
+
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <io.h>
+
+/*---------------------------------------------------------------------
+   Map constants
+---------------------------------------------------------------------*/
+
+#define MAXLEVELNAMELENGTH           23
+#define ALLOCATEDLEVELNAMELENGTH     24
+#define NUMPLANES                    3
+#define NUMHEADEROFFSETS             100
+#define MAPWIDTH                     128
+#define MAPHEIGHT                    128
+#define MAP_SPECIAL_TOGGLE_PUSHWALLS 0x0001
+
+#define WALL_PLANE    0
+#define SPRITE_PLANE  1
+#define INFO_PLANE    2
+
+/*---------------------------------------------------------------------
+   Type definitions
+---------------------------------------------------------------------*/
+
+typedef struct
+   {
+   unsigned long used;
+   unsigned long CRC;
+   unsigned long RLEWtag;
+   unsigned long MapSpecials;
+   unsigned long planestart[ NUMPLANES ];
+   unsigned long planelength[ NUMPLANES ];
+   char          Name[ ALLOCATEDLEVELNAMELENGTH ];
+   } RTLMAP;
+
+
+/*---------------------------------------------------------------------
+   Global variables
+---------------------------------------------------------------------*/
+
+unsigned short *mapplanes[ NUMPLANES ];
+
+
+/*---------------------------------------------------------------------
+   Macros
+---------------------------------------------------------------------*/
+
+#define MAPSPOT( x, y, plane ) \
+   ( mapplanes[ plane ][ MAPWIDTH * ( y ) + ( x ) ] )
+
+#define WALL_AT( x, y )   ( MAPSPOT( ( x ), ( y ), WALL_PLANE ) )
+#define SPRITE_AT( x, y ) ( MAPSPOT( ( x ), ( y ), SPRITE_PLANE ) )
+#define INFO_AT( x, y )   ( MAPSPOT( ( x ), ( y ), INFO_PLANE ) )
+
+
+/*---------------------------------------------------------------------
+   Function: ReadROTTMap
+
+   Read a map from a RTL/RTC file.
+---------------------------------------------------------------------*/
+
+void ReadROTTMap
+   (
+   char *filename,
+   int mapnum
+   )
+
+   {
+   char            RTLSignature[ 4 ];
+   unsigned long   RTLVersion;
+   RTLMAP          RTLMap;
+   int             filehandle;
+   long            pos;
+   long            compressed;
+   long            expanded;
+   int             plane;
+   unsigned short *buffer;
+
+   filehandle = open( filename, O_RDONLY | O_BINARY );
+
+   //
+   // Load RTL signature
+   //
+   read( filehandle, RTLSignature, sizeof( RTLSignature ) );
+
+   //
+   // Read the version number
+   //
+   read( filehandle, &RTLVersion, sizeof( RTLVersion ) );
+
+   //
+   // Load map header
+   //
+   lseek( filehandle, mapnum * sizeof( RTLMap ), SEEK_CUR );
+   read( filehandle, &RTLMap, sizeof( RTLMap ) );
+
+   if ( !RTLMap.used )
+      {
+      //
+      // Exit on error
+      //
+      printf( "ReadROTTMap: Tried to load a non existent map!" );
+      exit( 1 );
+      }
+
+   //
+   // load the planes in
+   //
+   expanded = MAPWIDTH * MAPHEIGHT * 2;
+
+	for( plane = 0; plane <= 2; plane++ )
+      {
+      pos        = RTLMap.planestart[ plane ];
+      compressed = RTLMap.planelength[ plane ];
+      buffer     = malloc( compressed );
+
+      lseek( filehandle, pos, SEEK_SET );
+      read( filehandle, buffer, compressed );
+
+      mapplanes[ plane ] = malloc( expanded );
+
+      RLEW_Expand( buffer, mapplanes[ plane ], expanded >> 1, RTLMap.RLEWtag );
+
+      free( buffer );
+      }
+
+   close( filehandle );
+   }
+
+
+MAP WEIRDNESS
+-------------
+You can pretty much figure out most of the map data easily, but there are
+a few things in the map which are a little oddly set up.  Here's a few
+helpful items.
+
+
+THE UPPER CORNER
+The first row of a map contains vital information to setting up a map.
+
+In the first plane (WALLS) are these values:
+
+0,0   FLOOR # (0xB4 through 0xC3, though we might cut some)
+1,0   CEILING # (0xC6 through 0xD5, or skies: 0xEA to 0xEE)
+2,0   BRIGHTNESS LEVEL (0xD8 to 0xDF, from dark to light)
+3,0   RATE AT WHICH LIGHT FADES OUT WITH DISTANCE
+        (0xFC to 0x010B, fast to slow)
+
+In the second plane (SPRITES) are these:
+
+0,0   Height of level
+	(1-8 ranges from 0x5A to 0x61, 9-16 is from 0x01C2 to 0x01C9)
+1,0   Height that sky is at relative to level (with same 1-16 arrangement)
+        (not needed for level with a ceiling)
+2,0   Icon for NO FOG (0x68) or FOG (0x69)
+3,0   Light sourcing icon (0x8B: if present, lights illuminate walls)
+
+Optional items in the upper corner are:
+
+Second Plane
+	Lightning icon (0x0179)
+	Timer icon (0x79: third plane points 0xXXYY to X,Y location of
+	  timed thing--time in minutes/seconds there is MMSS in decimal
+	  digits, so 0130 is 1 minute thirty seconds--and to one side of
+	  that timed thing is the end time in the same format. This, for
+	  instance, would say when to shut the door that opened at the
+	  start time)
+
+Third Plane (INFO)
+	Song number: 0xBAnn, where nn is song number.  If not present,
+	 the game will choose song 0.  If greater than the number of
+	 level songs (18 in shareware), the game will blow out.
+
+
+DISKS
+Gravitational Anomaly Disks (GADS) are set up with a GAD icon in the
+second plane and a height in the third plane.  The actual graphic has a
+disk in the top quarter, so to put one on the floor, you sort of have to
+put the object IN the floor, so the disk will be at the right height.
+Heights for objects start with 0xB0 and have that last byte as a
+tiles-off-the-floor nybble and sixteenths-of-a-tile fraction.
+
+So 0xB000 is, for normal sprites, resting on the floor.
+
+For disks, that would be a disk you could stand on to be one story
+(eight feet) in the air. The heights of disks usually go by sixes (that's
+the maximum they can be apart and you can still climb them like stairs) or
+fours (for a more gradual ascension).  Here are three sets of height
+values.  The values of 0xB0F1-$B0FE are into the floor, and $B0F6 is right
+about floor height.
+
+by 6     by 4     by 2
+B0F6     B0F6     B0F6
+B0FC     B0FA     B0F8
+B002     B0FE     B0FA
+B008     B002     B0FC
+B00E     B006     B0FE
+B014     B00A     B010
+B01A     B00E     B012
+B020     B012     B014
+B026     B016     ...
+B02C     B01A
+B032     B01E
+B038     B022
+B03E     B026
+B044     B02A
+B04A     B02E
+B050     B032
+B056     B036
+B05C     B03A
+B062     B03E
+B068     B042
+B06E     B046
+B074     B04A
+B07A     B04E
+
+If you need higher ones, calculate them yourself, man.
+
+
+SWITCHES AND TOUCHPLATES
+
+Everything activated by a switch or touchplates points to the switch or
+touchplate that activates it, with the standard 0xXXYY format.  This way
+tons of things can be activated by one switch.  To make a door open with
+multiple switches/touchplates, make it a few tiles wide and have different
+parts of the door point to the different switches.
+
+LOCKED DOORS
+Locked doors are normal doors with a key sprite icon placed on them.
+
+
+============================================================================
+
+The ROTT WAD Format
+-------------------
+
+        Most of you out there are probably very familiar with the WAD file
+format developed by Id Software.  We borrowed the format with their
+consent and use it for all the data in Rise of the Triad.
+
+        The WAD structure itself is identical to that of other WAD's,
+where the WAD header is as follows:
+
+typedef struct
+{
+	char	identification[4];
+	long	numlumps;
+	long	infotableofs;
+} wadinfo_t;
+
+and the WAD directory is made up of [numlumps] of:
+
+typedef struct
+{
+	long		filepos;
+	long		size;
+	char		name[8];
+} lumpinfo_t;
+
+
+ROTT Specific Data
+------------------
+
+WALLS - Walls are stored in the WAD between the two labels "WALLSTRT" and
+"WALLSTOP".  The format of each wall is a 4,096 block of data with no
+header.  The bitmaps are grabbed in vertical posts so that drawing in
+modex is more straight format.  All walls must be 64 x 64. The walls must
+be the first few lumps in the WAD.
+
+MASKED OBJECTS - Masked objects in the wad comprise all actors and
+sprites.  They can be found as weapons, objects, actors etc.  They use the
+following headers and structures:
+
+typedef struct
+{
+   short          origsize;         // the orig size of "grabbed" gfx
+   short          width;            // bounding box size
+   short          height;
+   short          leftoffset;       // pixels to the left of origin
+   short          topoffset;        // pixels above the origin
+   unsigned short collumnofs[320];  // only [width] used, the [0] is &collumnofs[width]
+} patch_t;
+
+These are extremely similar to the patches used in another game, except
+for the addition of the origsize parameter.
+
+typedef struct
+{
+   short origsize;         // the orig size of "grabbed" gfx
+   short width;            // bounding box size
+   short height;
+   short leftoffset;       // pixels to the left of origin
+   short topoffset;        // pixels above the origin
+   short translevel;
+   short collumnofs[320];  // only [width] used, the [0] is &collumnofs[width]
+} transpatch_t;
+
+Certain objects in the game like masked walls and touch plates will use
+the second type of patch which acts like a translucent patch.
+
+SKYS, FLOORS and CEILINGS - Skys are larger than the screen and are made
+up of two 256X200 grabs in posts similar to the walls.  The first grab
+represents the bottom part of the sky and the second part the top of the
+sky.  The skys are denoted by the labels SKYSTRT and SKYSTOP.  Floors and
+ceilings use the following structure:
+
+typedef struct
+{
+   short     width,height;
+   short     orgx,orgy;
+   byte     data;
+} lpic_t;
+
+They can be found between the labels UPDNSTRT and UPDNSTOP.
+
+
+Okay, enough hints!  Have fun figuring stuff out.
+
+--THE DEVELOPERS OF INCREDIBLE POWER

Added: tags/rott-1.1/doc/readme.txt
===================================================================
--- tags/rott-1.1/doc/readme.txt	                        (rev 0)
+++ tags/rott-1.1/doc/readme.txt	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,86 @@
+Rise of the Triad (v1.3 CD Version) Source Code Release - December 20, 2002.
+(If you can't read this right in your editor, turn on word wrap)
+
+Please note that this is being released without any kind of support from Apogee Software, Ltd / 3D Realms Entertainment.  We cannot and will not help in getting this running.  We do not guarantee that you will be able to get it to work, nor do we guarantee that it won't blow up your computer if you do try and use it.  Caveat Emptor - Use at your own risk.  Having said that, this source code release was compiled on December 7, 2002 using the materials in this archive.  Here's a note from one of the original ROTT programmers (Jim Dose) as to what will be needed to get this compiled:
+
+------
+
+You will need Watcom C v10.0b, which is what was used to compile the game originally.  This source code release was tested with that version.  Other versions are not guaranteed to work.  Later versions such as v11.0 are known to most likely not work because of changes in the way data types are handled.
+
+You also need Borland's Turbo Assembler (TASM), but it is not required to build the full game if you use the .obj files that are already included.  To do a full rebuild of the C code without having TASM, delete all the .obj files except for the following files:
+
+F_SCALE.OBJ
+RT_DR_A.OBJ
+RT_FC_A.OBJ
+RT_SC_A.OBJ
+RT_VH_A.OBJ
+
+To compile ROTT, type "wmake all".  To compile the audio library, run "wmake.bat".
+
+(You'll also need a registered CD version of Rise of the Triad, too.)
+
+-----
+
+Please note that while we are releasing the source code to Rise of the Triad, the game itself has not been released in the same manner (in other words, Rise of the Triad is still commercial software).  You can still buy the game from us by visiting http://www.3drealms.com.
+
+Thanks to all the fans who have hung in there and waited for us to do something like this, we hope you enjoy it.  If you produce something cool with this source code, drop us a line at rott at 3drealms.com.   In honor of the source code release, we contacted Tom Hall to reminicse a bit about the game, and we have some history from Scott Miller, President of Apogee. Their thoughts are below.
+
+Furthermore, the release of the Rise of the Triad source code is dedicated to our late friend and cohort, William Scarboro.  William was one of the original Rise of the Triad programmers, and he unfortunately died of an asthma attack on August 9, 2002.
+
+William was born March 2, 1971 in El Paso, TX. He was a graduate of Texas A&M with a degree in Computer Science. He came to work here back in 1993, and was the first programmer we hired back then when we started doing in house development. He was mainly known for his work on Rise of the Triad where he worked on actor code, weapon stuff, and the gibs. In fact, William was directly responsible for the /EKG gib cheat in ROTT.
+
+Joe Siegler
+Apogee Software / 3D Realms
+Dec 20, 2002
+
+==============================================================================================
+
+RISE OF THE TRIAD: The Source Code Release
+A Note from Tom Hall
+
+It was 1992.  I had just worked through half of DOOM, a creative guy in a technologically-oriented company.  We parted ways and I left to start up "In-House Development" at Apogee (later 3D Realms). We started accruing a programmer here, and artist there. Soon we had a team.  I came in with a memo about something (like bonus dough for library functions or something), and at the end I said something like, "And once we complete all these, we will be... THE DEVELOPERS OF INCREDIBLE POWER!" The guys laughed and liked this a lot.  And thus we became the DIPs. :)
+
+With a game called ROTT, and a bunch of DIPs, you're heading for some derision. :) We had a fairly inexperienced crew: me, inexperienced at management; the rest of the guys, fairly new to the industry. It started as WOLFENSTEIN 3D, Part 2 -- a "transition project" my heart wasn't in, really.  It wasn't my idea to do it, but it was something to do. Once we parted ways with that idea and id's involvement, things got rewritten, changed, and we came up with s-Quake functionality crammed into a Wolfenstein Plus/sub-DOOM engine.  It was an example of pushing a technology to do what it really can't do well.  We had a fun engine, but one that looked ugly, especially in the masked platforms -- they were paper thin!  You could have had a fun game without doing what it couldn't do... but we were trying to beat the Joneses. And once we split ways with the id thing, I made three bad decisions: a) to keep the art we had already, b) to not redesign a new game and c) not to move over to the Build engine, where we could have had a Duke/DOOM level game going decently quickly.
+
+Ah well. Hindsight's 20/20.  I am too nice, I guess. Yet, ROTT, for all its tortured technology, all its semi-justified graphics, did have some stuff that there was to be proud of. It was the first game with Rocket Jumping, the first game with Jumppads, the first game with parental password and Violence level adjustment, the first game with Capture the Flag...  Plus, I believe, the record for the most cheat codes ever in a game!  And a Random Level creator!  And what about all those cool Deathmatch options! And speaking of Deathmatch, I recall William's wonderful Corpseyard deathmatch map, and his "totally heinous" insane Drunk Missiles!  Mr. Scarboro, you, and your tuna, egg, salsa, and Omega 3 fatty acid bowls of goo will be missed.  Wah-bgsht! To Mark, Jim, Nolan, Steve, Tim, Chuck, Susan, JoeSke, Big Joe, Marianna, Lee, Bobby, Robert and all, thanks for sharing a strange time with me, and so many crazy memories!  "Uh, guys... um...."  The Disturbathon.  "50 kills!" "Ooooooooooh...  Mmmmmmm..."  Going to that crazy Bazaar to digitize old weapons.  "Check out what I got the boulders to do now."  "Ass!" "Use the fish." "Bowooooooooo!"  "I'm lookin' for some hot buns..."
+
+And on and on... And thanks to Scott and George, for providing a place for us to be crazy together, and sticking with it even though it wasn't blockbuster stuff. I do owe you a debt in what was an odd, disorienting time for me. In the end, a couple hundred thousand folks seem to have enjoyed it, so there was something there that they liked. "See, Charlie Brown?  It wasn't such a bad tree after all."
+
+======
+
+A little history...
+by Scott Miller
+
+ROTT, as it quickly became known, marked a turning point for Apogee.  It was our first in-house game since I started the company in 1987 with my home grown Kroz games, the games that started the shareware revolution that resulted in the launch of three of the most successful independent PC developers, Epic, Id, and us -- all three still kicking after 12+ years (as of Dec. '02).  It's hard to believe we're among the oldest of all surviving independent PC developers in the world now.  Before ROTT, Apogee, as we were then known, solely worked with outside development teams, often funding and helping organize these teams, and helping guide their game designs using our experience.  But around 1993 it was evident that this method wasn't going to work out much longer because as games got larger and more complicated to make, team sizes had to grow, too.  So, in 1994 we started hiring developers to form our own internal team, with the first of those hires including William Scarboro, Nolan Martin, Mark Dochtermann, Jim Dosé, and the ever creative Tom Hall to run the show.
+
+As Tom notes above, ROTT was originally an Id-approved sequel to Wolfenstein 3-D, using the original Wolf engine.  The game was going to be called, Wolfenstein: Rise of the Triad, and explore what happened after Hitler's demise.  About 4-5 months into development, though, a surprise call from John Romero ended the project, and we were left with a lot of content specific to the Wolfenstein premise, which had to be rolled into a new game concept so that we didn't waste all that we'd done.  The result was a bit of a mish-mash, and as Tom says above, the project probably should've been restarted using our new Build engine, which our second internal team down the hall was using, making Duke Nukem 3D.
+
+ROTT ended up selling several hundred thousand copies and making enough money to keep Duke 3D funded.  But it was at this time that we knew we  had to make a radical company change to shift with the times, and so we created the 3D Realms label, and began phasing out Apogee, which we were leaving behind with the glory days of shareware, and the arcade-style games Apogee was best known for.
+
+We get a lot of requests to release the source code to many of the older Apogee games, but the problem is that Apogee does not own these games that were developed by external teams.
+
+This source release is a long time coming, and hopefully it's not the last time we're able to do this.
+
+Scott Miller, CEO / Founder
+
+======
+
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/

Added: tags/rott-1.1/doc/rott.6
===================================================================
--- tags/rott-1.1/doc/rott.6	                        (rev 0)
+++ tags/rott-1.1/doc/rott.6	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,90 @@
+.TH ROTT 6 "2008-04-23" "1.0" "Rise of the Triad"
+
+.SH NAME
+rott \- Rise of the Triad
+
+.SH SYNOPSIS
+.B rott
+.RI [ options ]
+
+.SH DESCRIPTION
+.B ROTT
+is a port of Apogee's 3D action title Rise of the Triad, originally released in 1994.
+This port duplicates the functionality of the original game on modern operating systems, including Linux, Win32, and Mac OS X.
+
+.SH OPTIONS
+.TP
+.BR aim
+Give aim crosshair.
+.TP
+.BR fullscreen
+Start in fullscreen mode.
+.TP
+.BR window
+Start in windowed mode.
+.TP
+.BR resolution\  \fIwidth\fPx\fIheight\fP
+Specify the screen resolution to use (next parameter is widthxheight).
+Valid resolutions are 320x200, 640x480 and 800x600.
+.TP
+.BR spaceball
+Enable check for Spaceball.
+.TP
+.BR nojoys
+Disable check for joystick.
+.TP
+.BR nomouse
+Disable check for mouse.
+.TP
+.BR cyberman
+Enable check for Cyberman.
+.TP
+.BR assassin
+Enable check for Wingman Assassin.
+.TP
+.BR ver
+Version number.
+.TP
+.BR mapstats
+Dump Map statistics to ERROR.
+.TP
+.BR tilestats
+Dump Tile statistics to ERROR.
+.TP
+.BR mono
+Enable mono-monitor support.
+.TP
+.BR screenshots
+Clean screen capture for shots.
+.TP
+.BR pause
+Pauses startup screen information.
+.TP
+.BR enablevr
+Enable VR helmet input devices.
+.TP
+.BR noecho
+Turn off sound reverb.
+.TP
+.BR demoexit
+Exit program when demo is terminated.
+.TP
+.BR warp\  \fIlevel\fP
+Warp to specific ROTT level (next paramater is level to start on).
+.TP
+.BR timelimit\  \fItime\fP
+Play ROTT in time limit mode (next paramater is time in seconds).
+.TP
+.BR maxtimelimit\  \fItime\fP
+Maximimum time to count down from (next paramater is time in seconds).
+.TP
+.BR dopefish
+?
+
+.SH AUTHORS
+ROTT was created and published as shareware by Apogee Software, Ltd. and was published commercially by FormGen, Inc.
+.PP
+The primary contributors to the icculus.org port are: Steven Fuller, Ryan C. Gordon, John Hall and Dan Olson.
+.PP
+This manual page was written by Fabian Greffrath <fabian at debian-unofficial.org>
+for the Debian project (but may be used by others).

Added: tags/rott-1.1/doc/wad.txt
===================================================================
--- tags/rott-1.1/doc/wad.txt	                        (rev 0)
+++ tags/rott-1.1/doc/wad.txt	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,82 @@
+The ROTT WAD Format
+-------------------
+
+        Most of you out there are probably very familiar with the WAD file
+format developed by Id Software.  We borrowed the format with their
+consent and use it for all the data in Rise of the Triad.
+
+        The WAD structure itself is identical to that of other WAD's,
+where the WAD header is as follows:
+
+typedef struct
+{
+	char	identification[4];
+	long	numlumps;
+	long	infotableofs;
+} wadinfo_t;
+
+and the WAD directory is made up of [numlumps] of:
+
+typedef struct
+{
+	long		filepos;
+	long		size;
+	char		name[8];
+} lumpinfo_t;
+
+
+ROTT Specific Data
+------------------
+
+WALLS - Walls are stored in the WAD between the two labels "WALLSTRT" and
+"WALLSTOP".  The format of each wall is a 4,096 block of data with no
+header.  The bitmaps are grabbed in vertical posts so that drawing in
+modex is more straight format.  All walls must be 64 x 64. The walls must
+be the first few lumps in the WAD.
+
+MASKED OBJECTS - Masked objects in the wad comprise all actors and
+sprites.  They can be found as weapons, objects, actors etc.  They use the
+following headers and structures:
+
+typedef struct
+{
+   short          origsize;         // the orig size of "grabbed" gfx
+   short          width;            // bounding box size
+   short          height;
+   short          leftoffset;       // pixels to the left of origin
+   short          topoffset;        // pixels above the origin
+   unsigned short collumnofs[320];  // only [width] used, the [0] is &collumnofs[width]
+} patch_t;
+
+These are extremely similar to the patches used in another game, except
+for the addition of the origsize parameter.
+
+typedef struct
+{
+   short origsize;         // the orig size of "grabbed" gfx
+   short width;            // bounding box size
+   short height;
+   short leftoffset;       // pixels to the left of origin
+   short topoffset;        // pixels above the origin
+   short translevel;
+   short collumnofs[320];  // only [width] used, the [0] is &collumnofs[width]
+} transpatch_t;
+
+Certain objects in the game like masked walls and touch plates will use
+the second type of patch which acts like a translucent patch.
+
+SKYS, FLOORS and CEILINGS - Skys are larger than the screen and are made
+up of two 256X200 grabs in posts similar to the walls.  The first grab
+represents the bottom part of the sky and the second part the top of the
+sky.  The skys are denoted by the labels SKYSTRT and SKYSTOP.  Floors and
+ceilings use the following structure:
+
+typedef struct
+{
+   short     width,height;
+   short     orgx,orgy;
+   byte     data;
+} lpic_t;
+
+They can be found between the labels UPDNSTRT and UPDNSTOP.
+

Added: tags/rott-1.1/mac/English.lproj/InfoPlist.strings
===================================================================
(Binary files differ)


Property changes on: tags/rott-1.1/mac/English.lproj/InfoPlist.strings
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mime-type
   + application/octet-stream

Added: tags/rott-1.1/mac/Rise of the Triad.pbproj/project.pbxproj
===================================================================
--- tags/rott-1.1/mac/Rise of the Triad.pbproj/project.pbxproj	                        (rev 0)
+++ tags/rott-1.1/mac/Rise of the Triad.pbproj/project.pbxproj	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1187 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 38;
+	objects = {
+		080E96DDFE201D6D7F000001 = {
+			children = (
+				F5A47A9D01A0482F01D3D55B,
+				F5A47A9E01A0483001D3D55B,
+			);
+			isa = PBXGroup;
+			name = Classes;
+			refType = 4;
+		};
+		089C165CFE840E0CC02AAC07 = {
+			children = (
+				089C165DFE840E0CC02AAC07,
+			);
+			isa = PBXVariantGroup;
+			name = InfoPlist.strings;
+			refType = 4;
+		};
+		089C165DFE840E0CC02AAC07 = {
+			fileEncoding = 10;
+			isa = PBXFileReference;
+			name = English;
+			path = English.lproj/InfoPlist.strings;
+			refType = 4;
+		};
+		089C165EFE840E0CC02AAC07 = {
+			fileRef = 089C165CFE840E0CC02AAC07;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//080
+//081
+//082
+//083
+//084
+//100
+//101
+//102
+//103
+//104
+		1058C7A0FEA54F0111CA2CBB = {
+			children = (
+				1058C7A1FEA54F0111CA2CBB,
+			);
+			isa = PBXGroup;
+			name = "Linked Frameworks";
+			refType = 4;
+		};
+		1058C7A1FEA54F0111CA2CBB = {
+			isa = PBXFrameworkReference;
+			name = Cocoa.framework;
+			path = /System/Library/Frameworks/Cocoa.framework;
+			refType = 0;
+		};
+		1058C7A2FEA54F0111CA2CBB = {
+			children = (
+				29B97325FDCFA39411CA2CEA,
+				29B97324FDCFA39411CA2CEA,
+			);
+			isa = PBXGroup;
+			name = "Other Frameworks";
+			refType = 4;
+		};
+		1058C7A3FEA54F0111CA2CBB = {
+			fileRef = 1058C7A1FEA54F0111CA2CBB;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//100
+//101
+//102
+//103
+//104
+//170
+//171
+//172
+//173
+//174
+		17587328FF379C6511CA2CBB = {
+			isa = PBXApplicationReference;
+			path = "Rise of the Triad.app";
+			refType = 3;
+		};
+//170
+//171
+//172
+//173
+//174
+//190
+//191
+//192
+//193
+//194
+		19C28FACFE9D520D11CA2CBB = {
+			children = (
+				17587328FF379C6511CA2CBB,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+		};
+//190
+//191
+//192
+//193
+//194
+//290
+//291
+//292
+//293
+//294
+		29B97313FDCFA39411CA2CEA = {
+			buildStyles = (
+				4A9504CCFFE6A4B311CA0CBA,
+				4A9504CDFFE6A4B311CA0CBA,
+			);
+			isa = PBXProject;
+			mainGroup = 29B97314FDCFA39411CA2CEA;
+			projectDirPath = "";
+			targets = (
+				29B97326FDCFA39411CA2CEA,
+			);
+		};
+		29B97314FDCFA39411CA2CEA = {
+			children = (
+				080E96DDFE201D6D7F000001,
+				29B97315FDCFA39411CA2CEA,
+				29B97317FDCFA39411CA2CEA,
+				29B97323FDCFA39411CA2CEA,
+				19C28FACFE9D520D11CA2CBB,
+				F5A3D67703BAB75001000002,
+				F5A3D67803BAB75001000002,
+				F5A3D67903BAB75001000002,
+				F5A3D67A03BAB75001000002,
+				F5A3D67B03BAB75001000002,
+				F5A3D67C03BAB75001000002,
+				F5A3D67D03BAB75001000002,
+				F5A3D67E03BAB75001000002,
+				F5A3D67F03BAB75001000002,
+				F5A3D68003BAB75001000002,
+				F5A3D68103BAB75001000002,
+				F5A3D68203BAB75001000002,
+			);
+			isa = PBXGroup;
+			name = "SDL App";
+			path = "";
+			refType = 4;
+		};
+		29B97315FDCFA39411CA2CEA = {
+			children = (
+				F5C71B7403B6FF1D01000002,
+				F5C71B7503B6FF1D01000002,
+				F5C71B7603B6FF1D01000002,
+				F5C71B7703B6FF1D01000002,
+				F5C71B7803B6FF1D01000002,
+				F5C71B7903B6FF1D01000002,
+				F5C71B7A03B6FF1D01000002,
+				F5C71B7D03B6FF1D01000002,
+				F5C71B7E03B6FF1D01000002,
+				F5C71B8003B6FF1D01000002,
+				F5C71B8103B6FF1D01000002,
+				F5C71B8203B6FF1D01000002,
+				F5C71B8303B6FF1D01000002,
+				F5C71B8403B6FF1D01000002,
+				F5C71B8503B6FF1D01000002,
+				F5C71B8603B6FF1D01000002,
+				F5C71B8703B6FF1D01000002,
+				F5C71B8803B6FF1D01000002,
+				F5C71B8903B6FF1D01000002,
+				F5C71B8A03B6FF1D01000002,
+				F5C71B8B03B6FF1D01000002,
+				F5C71B8E03B6FF1D01000002,
+				F5C71B8F03B6FF1D01000002,
+				F5C71B9003B6FF1D01000002,
+				F5C71B9103B6FF1D01000002,
+				F5C71B9203B6FF1D01000002,
+				F5C71B9303B6FF1D01000002,
+				F5C71B9403B6FF1D01000002,
+				F5C71B9503B6FF1D01000002,
+				F5C71B9603B6FF1D01000002,
+				F5C71B9703B6FF1D01000002,
+				F5C71B9803B6FF1D01000002,
+				F5C71B9A03B6FF1D01000002,
+				F5C71B9B03B6FF1D01000002,
+				F5C71B9C03B6FF1D01000002,
+				F5C71B9D03B6FF1D01000002,
+				F5C71B9E03B6FF1D01000002,
+				F5C71B9F03B6FF1D01000002,
+				F5C71BA003B6FF1D01000002,
+				F5C71BA103B6FF1D01000002,
+				F5C71BA303B6FF1D01000002,
+				F5C71BA503B6FF1D01000002,
+				F5C71BA603B6FF1D01000002,
+				F5C71BA803B6FF1D01000002,
+				F5C71BAB03B6FF1D01000002,
+				F5C71BAC03B6FF1D01000002,
+				F5C71BAD03B6FF1D01000002,
+				F5C71BF203B713D201000002,
+				F5C71BFF03B79CF301000002,
+			);
+			isa = PBXGroup;
+			name = "Other Sources";
+			path = "";
+			refType = 4;
+		};
+		29B97317FDCFA39411CA2CEA = {
+			children = (
+				089C165CFE840E0CC02AAC07,
+			);
+			isa = PBXGroup;
+			name = Resources;
+			path = "";
+			refType = 4;
+		};
+		29B97323FDCFA39411CA2CEA = {
+			children = (
+				1058C7A0FEA54F0111CA2CBB,
+				1058C7A2FEA54F0111CA2CBB,
+			);
+			isa = PBXGroup;
+			name = Frameworks;
+			path = "";
+			refType = 4;
+		};
+		29B97324FDCFA39411CA2CEA = {
+			isa = PBXFrameworkReference;
+			name = AppKit.framework;
+			path = /System/Library/Frameworks/AppKit.framework;
+			refType = 0;
+		};
+		29B97325FDCFA39411CA2CEA = {
+			isa = PBXFrameworkReference;
+			name = Foundation.framework;
+			path = /System/Library/Frameworks/Foundation.framework;
+			refType = 0;
+		};
+		29B97326FDCFA39411CA2CEA = {
+			buildPhases = (
+				29B97327FDCFA39411CA2CEA,
+				29B97328FDCFA39411CA2CEA,
+				29B9732BFDCFA39411CA2CEA,
+				29B9732DFDCFA39411CA2CEA,
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "\"$(HOME)/Library/Frameworks\" /Users/overcode/Library/Frameworks";
+				HEADER_SEARCH_PATHS = "\"$(HOME)/Library/Frameworks/SDL.framework/Headers\" \"$(HOME)/Library/Frameworks/SDL_mixer.framework/Headers\"";
+				INSTALL_PATH = "$(HOME)/Applications";
+				LIBRARY_SEARCH_PATHS = "";
+				OTHER_CFLAGS = "-DUSE_SDL=1 -DPLATFORM_UNIX=1 -DPLATFORM_MACOSX=1 -DUSE_C_SQRT=1";
+				OTHER_LDFLAGS = "-framework SDL -framework SDL_mixer";
+				PRODUCT_NAME = "Rise of the Triad";
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas -Wno-unused -Wno-switch";
+				WRAPPER_EXTENSION = app;
+			};
+			dependencies = (
+			);
+			isa = PBXApplicationTarget;
+			name = "Rise of the Triad";
+			productInstallPath = "$(HOME)/Applications";
+			productName = "SDL App";
+			productReference = 17587328FF379C6511CA2CBB;
+			productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>Rise of the Triad</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.1</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>
+";
+			shouldUseHeadermap = 1;
+		};
+		29B97327FDCFA39411CA2CEA = {
+			buildActionMask = 2147483647;
+			files = (
+				F5A47AA101A0483001D3D55B,
+			);
+			isa = PBXHeadersBuildPhase;
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		29B97328FDCFA39411CA2CEA = {
+			buildActionMask = 2147483647;
+			files = (
+				089C165EFE840E0CC02AAC07,
+				F5A3D68303BAB75001000002,
+				F5A3D68403BAB75001000002,
+				F5A3D68503BAB75001000002,
+				F5A3D68603BAB75001000002,
+				F5A3D68703BAB75001000002,
+				F5A3D68803BAB75001000002,
+				F5A3D68903BAB75001000002,
+				F5A3D68A03BAB75001000002,
+				F5A3D68B03BAB75001000002,
+				F5A3D68C03BAB75001000002,
+				F5A3D68D03BAB75001000002,
+				F5A3D68E03BAB75001000002,
+			);
+			isa = PBXResourcesBuildPhase;
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		29B9732BFDCFA39411CA2CEA = {
+			buildActionMask = 2147483647;
+			files = (
+				F5A47AA301A0483001D3D55B,
+				F5C71BAE03B6FF1D01000002,
+				F5C71BAF03B6FF1D01000002,
+				F5C71BB003B6FF1D01000002,
+				F5C71BB103B6FF1D01000002,
+				F5C71BB203B6FF1D01000002,
+				F5C71BB303B6FF1D01000002,
+				F5C71BB403B6FF1D01000002,
+				F5C71BB703B6FF1D01000002,
+				F5C71BB803B6FF1D01000002,
+				F5C71BBA03B6FF1D01000002,
+				F5C71BBB03B6FF1D01000002,
+				F5C71BBC03B6FF1D01000002,
+				F5C71BBD03B6FF1D01000002,
+				F5C71BBE03B6FF1D01000002,
+				F5C71BBF03B6FF1D01000002,
+				F5C71BC003B6FF1D01000002,
+				F5C71BC103B6FF1D01000002,
+				F5C71BC203B6FF1D01000002,
+				F5C71BC303B6FF1D01000002,
+				F5C71BC403B6FF1D01000002,
+				F5C71BC503B6FF1D01000002,
+				F5C71BC803B6FF1D01000002,
+				F5C71BC903B6FF1D01000002,
+				F5C71BCA03B6FF1D01000002,
+				F5C71BCB03B6FF1D01000002,
+				F5C71BCC03B6FF1D01000002,
+				F5C71BCD03B6FF1D01000002,
+				F5C71BCE03B6FF1D01000002,
+				F5C71BCF03B6FF1D01000002,
+				F5C71BD003B6FF1D01000002,
+				F5C71BD103B6FF1D01000002,
+				F5C71BD203B6FF1D01000002,
+				F5C71BD403B6FF1D01000002,
+				F5C71BD503B6FF1D01000002,
+				F5C71BD603B6FF1D01000002,
+				F5C71BD703B6FF1D01000002,
+				F5C71BD803B6FF1D01000002,
+				F5C71BD903B6FF1D01000002,
+				F5C71BDA03B6FF1D01000002,
+				F5C71BDB03B6FF1D01000002,
+				F5C71BDD03B6FF1D01000002,
+				F5C71BDF03B6FF1D01000002,
+				F5C71BE003B6FF1D01000002,
+				F5C71BE203B6FF1D01000002,
+				F5C71BE503B6FF1D01000002,
+				F5C71BE603B6FF1D01000002,
+				F5C71BE703B6FF1D01000002,
+				F5C71BF303B713D201000002,
+				F5C71C0003B79CF301000002,
+			);
+			isa = PBXSourcesBuildPhase;
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		29B9732DFDCFA39411CA2CEA = {
+			buildActionMask = 2147483647;
+			files = (
+				1058C7A3FEA54F0111CA2CBB,
+			);
+			isa = PBXFrameworksBuildPhase;
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+//290
+//291
+//292
+//293
+//294
+//4A0
+//4A1
+//4A2
+//4A3
+//4A4
+		4A9504CCFFE6A4B311CA0CBA = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				OPTIMIZATION_CFLAGS = "-O0";
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		4A9504CDFFE6A4B311CA0CBA = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+				OPTIMIZATION_CFLAGS = "-O3";
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+//4A0
+//4A1
+//4A2
+//4A3
+//4A4
+//F50
+//F51
+//F52
+//F53
+//F54
+		F5A3D67703BAB75001000002 = {
+			isa = PBXFileReference;
+			name = DEMO1_3.DMO;
+			path = /Users/overcode/Code/rott/swdata/DEMO1_3.DMO;
+			refType = 0;
+		};
+		F5A3D67803BAB75001000002 = {
+			isa = PBXFileReference;
+			name = DEMO2_3.DMO;
+			path = /Users/overcode/Code/rott/swdata/DEMO2_3.DMO;
+			refType = 0;
+		};
+		F5A3D67903BAB75001000002 = {
+			isa = PBXFileReference;
+			name = DEMO3_3.DMO;
+			path = /Users/overcode/Code/rott/swdata/DEMO3_3.DMO;
+			refType = 0;
+		};
+		F5A3D67A03BAB75001000002 = {
+			isa = PBXFileReference;
+			name = DEMO4_3.DMO;
+			path = /Users/overcode/Code/rott/swdata/DEMO4_3.DMO;
+			refType = 0;
+		};
+		F5A3D67B03BAB75001000002 = {
+			isa = PBXFileReference;
+			name = HUNTBGIN.RTC;
+			path = /Users/overcode/Code/rott/swdata/HUNTBGIN.RTC;
+			refType = 0;
+		};
+		F5A3D67C03BAB75001000002 = {
+			isa = PBXFileReference;
+			name = HUNTBGIN.RTL;
+			path = /Users/overcode/Code/rott/swdata/HUNTBGIN.RTL;
+			refType = 0;
+		};
+		F5A3D67D03BAB75001000002 = {
+			isa = PBXFileReference;
+			name = HUNTBGIN.WAD;
+			path = /Users/overcode/Code/rott/swdata/HUNTBGIN.WAD;
+			refType = 0;
+		};
+		F5A3D67E03BAB75001000002 = {
+			isa = PBXFileReference;
+			name = MODEM.PCK;
+			path = /Users/overcode/Code/rott/swdata/MODEM.PCK;
+			refType = 0;
+		};
+		F5A3D67F03BAB75001000002 = {
+			isa = PBXFileReference;
+			name = ORDER.FRM;
+			path = /Users/overcode/Code/rott/swdata/ORDER.FRM;
+			refType = 0;
+		};
+		F5A3D68003BAB75001000002 = {
+			isa = PBXFileReference;
+			name = README;
+			path = /Users/overcode/Code/rott/swdata/README;
+			refType = 0;
+		};
+		F5A3D68103BAB75001000002 = {
+			isa = PBXFileReference;
+			name = REMOTE1.RTS;
+			path = /Users/overcode/Code/rott/swdata/REMOTE1.RTS;
+			refType = 0;
+		};
+		F5A3D68203BAB75001000002 = {
+			isa = PBXFileReference;
+			name = VENDOR.DOC;
+			path = /Users/overcode/Code/rott/swdata/VENDOR.DOC;
+			refType = 0;
+		};
+		F5A3D68303BAB75001000002 = {
+			fileRef = F5A3D67703BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68403BAB75001000002 = {
+			fileRef = F5A3D67803BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68503BAB75001000002 = {
+			fileRef = F5A3D67903BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68603BAB75001000002 = {
+			fileRef = F5A3D67A03BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68703BAB75001000002 = {
+			fileRef = F5A3D67B03BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68803BAB75001000002 = {
+			fileRef = F5A3D67C03BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68903BAB75001000002 = {
+			fileRef = F5A3D67D03BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68A03BAB75001000002 = {
+			fileRef = F5A3D67E03BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68B03BAB75001000002 = {
+			fileRef = F5A3D67F03BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68C03BAB75001000002 = {
+			fileRef = F5A3D68003BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68D03BAB75001000002 = {
+			fileRef = F5A3D68103BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A3D68E03BAB75001000002 = {
+			fileRef = F5A3D68203BAB75001000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A47A9D01A0482F01D3D55B = {
+			isa = PBXFileReference;
+			path = SDLMain.h;
+			refType = 2;
+		};
+		F5A47A9E01A0483001D3D55B = {
+			isa = PBXFileReference;
+			path = SDLMain.m;
+			refType = 2;
+		};
+		F5A47AA101A0483001D3D55B = {
+			fileRef = F5A47A9D01A0482F01D3D55B;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5A47AA301A0483001D3D55B = {
+			fileRef = F5A47A9E01A0483001D3D55B;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71B7403B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = cin_actr.c;
+			path = /Users/overcode/Code/rott/rott/cin_actr.c;
+			refType = 0;
+		};
+		F5C71B7503B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = cin_efct.c;
+			path = /Users/overcode/Code/rott/rott/cin_efct.c;
+			refType = 0;
+		};
+		F5C71B7603B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = cin_evnt.c;
+			path = /Users/overcode/Code/rott/rott/cin_evnt.c;
+			refType = 0;
+		};
+		F5C71B7703B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = cin_glob.c;
+			path = /Users/overcode/Code/rott/rott/cin_glob.c;
+			refType = 0;
+		};
+		F5C71B7803B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = cin_main.c;
+			path = /Users/overcode/Code/rott/rott/cin_main.c;
+			refType = 0;
+		};
+		F5C71B7903B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = cin_util.c;
+			path = /Users/overcode/Code/rott/rott/cin_util.c;
+			refType = 0;
+		};
+		F5C71B7A03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = engine.c;
+			path = /Users/overcode/Code/rott/rott/engine.c;
+			refType = 0;
+		};
+		F5C71B7D03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = fx_man.c;
+			path = /Users/overcode/Code/rott/rott/fx_man.c;
+			refType = 0;
+		};
+		F5C71B7E03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = isr.c;
+			path = /Users/overcode/Code/rott/rott/isr.c;
+			refType = 0;
+		};
+		F5C71B8003B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = modexlib.c;
+			path = /Users/overcode/Code/rott/rott/modexlib.c;
+			refType = 0;
+		};
+		F5C71B8103B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_actor.c;
+			path = /Users/overcode/Code/rott/rott/rt_actor.c;
+			refType = 0;
+		};
+		F5C71B8203B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_battl.c;
+			path = /Users/overcode/Code/rott/rott/rt_battl.c;
+			refType = 0;
+		};
+		F5C71B8303B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_build.c;
+			path = /Users/overcode/Code/rott/rott/rt_build.c;
+			refType = 0;
+		};
+		F5C71B8403B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_cfg.c;
+			path = /Users/overcode/Code/rott/rott/rt_cfg.c;
+			refType = 0;
+		};
+		F5C71B8503B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_com.c;
+			path = /Users/overcode/Code/rott/rott/rt_com.c;
+			refType = 0;
+		};
+		F5C71B8603B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_crc.c;
+			path = /Users/overcode/Code/rott/rott/rt_crc.c;
+			refType = 0;
+		};
+		F5C71B8703B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_debug.c;
+			path = /Users/overcode/Code/rott/rott/rt_debug.c;
+			refType = 0;
+		};
+		F5C71B8803B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_dmand.c;
+			path = /Users/overcode/Code/rott/rott/rt_dmand.c;
+			refType = 0;
+		};
+		F5C71B8903B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_door.c;
+			path = /Users/overcode/Code/rott/rott/rt_door.c;
+			refType = 0;
+		};
+		F5C71B8A03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_draw.c;
+			path = /Users/overcode/Code/rott/rott/rt_draw.c;
+			refType = 0;
+		};
+		F5C71B8B03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_err.c;
+			path = /Users/overcode/Code/rott/rott/rt_err.c;
+			refType = 0;
+		};
+		F5C71B8E03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_floor.c;
+			path = /Users/overcode/Code/rott/rott/rt_floor.c;
+			refType = 0;
+		};
+		F5C71B8F03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_game.c;
+			path = /Users/overcode/Code/rott/rott/rt_game.c;
+			refType = 0;
+		};
+		F5C71B9003B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_in.c;
+			path = /Users/overcode/Code/rott/rott/rt_in.c;
+			refType = 0;
+		};
+		F5C71B9103B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_main.c;
+			path = /Users/overcode/Code/rott/rott/rt_main.c;
+			refType = 0;
+		};
+		F5C71B9203B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_map.c;
+			path = /Users/overcode/Code/rott/rott/rt_map.c;
+			refType = 0;
+		};
+		F5C71B9303B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_menu.c;
+			path = /Users/overcode/Code/rott/rott/rt_menu.c;
+			refType = 0;
+		};
+		F5C71B9403B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_msg.c;
+			path = /Users/overcode/Code/rott/rott/rt_msg.c;
+			refType = 0;
+		};
+		F5C71B9503B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_net.c;
+			path = /Users/overcode/Code/rott/rott/rt_net.c;
+			refType = 0;
+		};
+		F5C71B9603B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_playr.c;
+			path = /Users/overcode/Code/rott/rott/rt_playr.c;
+			refType = 0;
+		};
+		F5C71B9703B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_rand.c;
+			path = /Users/overcode/Code/rott/rott/rt_rand.c;
+			refType = 0;
+		};
+		F5C71B9803B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_scale.c;
+			path = /Users/overcode/Code/rott/rott/rt_scale.c;
+			refType = 0;
+		};
+		F5C71B9A03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_sound.c;
+			path = /Users/overcode/Code/rott/rott/rt_sound.c;
+			refType = 0;
+		};
+		F5C71B9B03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_spbal.c;
+			path = /Users/overcode/Code/rott/rott/rt_spbal.c;
+			refType = 0;
+		};
+		F5C71B9C03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_sqrt.c;
+			path = /Users/overcode/Code/rott/rott/rt_sqrt.c;
+			refType = 0;
+		};
+		F5C71B9D03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_stat.c;
+			path = /Users/overcode/Code/rott/rott/rt_stat.c;
+			refType = 0;
+		};
+		F5C71B9E03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_state.c;
+			path = /Users/overcode/Code/rott/rott/rt_state.c;
+			refType = 0;
+		};
+		F5C71B9F03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_str.c;
+			path = /Users/overcode/Code/rott/rott/rt_str.c;
+			refType = 0;
+		};
+		F5C71BA003B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_swift.c;
+			path = /Users/overcode/Code/rott/rott/rt_swift.c;
+			refType = 0;
+		};
+		F5C71BA103B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_ted.c;
+			path = /Users/overcode/Code/rott/rott/rt_ted.c;
+			refType = 0;
+		};
+		F5C71BA303B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_util.c;
+			path = /Users/overcode/Code/rott/rott/rt_util.c;
+			refType = 0;
+		};
+		F5C71BA503B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_vid.c;
+			path = /Users/overcode/Code/rott/rott/rt_vid.c;
+			refType = 0;
+		};
+		F5C71BA603B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = rt_view.c;
+			path = /Users/overcode/Code/rott/rott/rt_view.c;
+			refType = 0;
+		};
+		F5C71BA803B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = scriplib.c;
+			path = /Users/overcode/Code/rott/rott/scriplib.c;
+			refType = 0;
+		};
+		F5C71BAB03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = w_wad.c;
+			path = /Users/overcode/Code/rott/rott/w_wad.c;
+			refType = 0;
+		};
+		F5C71BAC03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = watcom.c;
+			path = /Users/overcode/Code/rott/rott/watcom.c;
+			refType = 0;
+		};
+		F5C71BAD03B6FF1D01000002 = {
+			isa = PBXFileReference;
+			name = z_zone.c;
+			path = /Users/overcode/Code/rott/rott/z_zone.c;
+			refType = 0;
+		};
+		F5C71BAE03B6FF1D01000002 = {
+			fileRef = F5C71B7403B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BAF03B6FF1D01000002 = {
+			fileRef = F5C71B7503B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BB003B6FF1D01000002 = {
+			fileRef = F5C71B7603B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BB103B6FF1D01000002 = {
+			fileRef = F5C71B7703B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BB203B6FF1D01000002 = {
+			fileRef = F5C71B7803B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BB303B6FF1D01000002 = {
+			fileRef = F5C71B7903B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BB403B6FF1D01000002 = {
+			fileRef = F5C71B7A03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BB703B6FF1D01000002 = {
+			fileRef = F5C71B7D03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BB803B6FF1D01000002 = {
+			fileRef = F5C71B7E03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BBA03B6FF1D01000002 = {
+			fileRef = F5C71B8003B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BBB03B6FF1D01000002 = {
+			fileRef = F5C71B8103B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BBC03B6FF1D01000002 = {
+			fileRef = F5C71B8203B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BBD03B6FF1D01000002 = {
+			fileRef = F5C71B8303B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BBE03B6FF1D01000002 = {
+			fileRef = F5C71B8403B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BBF03B6FF1D01000002 = {
+			fileRef = F5C71B8503B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BC003B6FF1D01000002 = {
+			fileRef = F5C71B8603B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BC103B6FF1D01000002 = {
+			fileRef = F5C71B8703B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BC203B6FF1D01000002 = {
+			fileRef = F5C71B8803B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BC303B6FF1D01000002 = {
+			fileRef = F5C71B8903B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BC403B6FF1D01000002 = {
+			fileRef = F5C71B8A03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BC503B6FF1D01000002 = {
+			fileRef = F5C71B8B03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BC803B6FF1D01000002 = {
+			fileRef = F5C71B8E03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BC903B6FF1D01000002 = {
+			fileRef = F5C71B8F03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BCA03B6FF1D01000002 = {
+			fileRef = F5C71B9003B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BCB03B6FF1D01000002 = {
+			fileRef = F5C71B9103B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BCC03B6FF1D01000002 = {
+			fileRef = F5C71B9203B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BCD03B6FF1D01000002 = {
+			fileRef = F5C71B9303B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BCE03B6FF1D01000002 = {
+			fileRef = F5C71B9403B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BCF03B6FF1D01000002 = {
+			fileRef = F5C71B9503B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BD003B6FF1D01000002 = {
+			fileRef = F5C71B9603B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BD103B6FF1D01000002 = {
+			fileRef = F5C71B9703B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BD203B6FF1D01000002 = {
+			fileRef = F5C71B9803B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BD403B6FF1D01000002 = {
+			fileRef = F5C71B9A03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BD503B6FF1D01000002 = {
+			fileRef = F5C71B9B03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BD603B6FF1D01000002 = {
+			fileRef = F5C71B9C03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BD703B6FF1D01000002 = {
+			fileRef = F5C71B9D03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BD803B6FF1D01000002 = {
+			fileRef = F5C71B9E03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BD903B6FF1D01000002 = {
+			fileRef = F5C71B9F03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BDA03B6FF1D01000002 = {
+			fileRef = F5C71BA003B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BDB03B6FF1D01000002 = {
+			fileRef = F5C71BA103B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BDD03B6FF1D01000002 = {
+			fileRef = F5C71BA303B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BDF03B6FF1D01000002 = {
+			fileRef = F5C71BA503B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BE003B6FF1D01000002 = {
+			fileRef = F5C71BA603B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BE203B6FF1D01000002 = {
+			fileRef = F5C71BA803B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BE503B6FF1D01000002 = {
+			fileRef = F5C71BAB03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BE603B6FF1D01000002 = {
+			fileRef = F5C71BAC03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BE703B6FF1D01000002 = {
+			fileRef = F5C71BAD03B6FF1D01000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BF203B713D201000002 = {
+			isa = PBXFileReference;
+			name = dosutil.c;
+			path = /Users/overcode/Code/rott/rott/dosutil.c;
+			refType = 0;
+		};
+		F5C71BF303B713D201000002 = {
+			fileRef = F5C71BF203B713D201000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C71BFF03B79CF301000002 = {
+			isa = PBXFileReference;
+			name = byteordr.c;
+			path = /Users/overcode/Code/rott/rott/byteordr.c;
+			refType = 0;
+		};
+		F5C71C0003B79CF301000002 = {
+			fileRef = F5C71BFF03B79CF301000002;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+	};
+	rootObject = 29B97313FDCFA39411CA2CEA;
+}


Property changes on: tags/rott-1.1/mac/Rise of the Triad.pbproj/project.pbxproj
___________________________________________________________________
Name: svn:executable
   + *

Added: tags/rott-1.1/mac/SDLMain.h
===================================================================
--- tags/rott-1.1/mac/SDLMain.h	                        (rev 0)
+++ tags/rott-1.1/mac/SDLMain.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,12 @@
+/*   SDLMain.m - main entry point for our Cocoa-ized SDL app
+       Initial Version: Darrell Walisser <dwaliss1 at purdue.edu>
+       Non-NIB-Code & other changes: Max Horn <max at quendi.de>
+
+    Feel free to customize this file to suit your needs
+*/
+
+#import <Cocoa/Cocoa.h>
+
+ at interface SDLMain : NSObject
+ at end
+


Property changes on: tags/rott-1.1/mac/SDLMain.h
___________________________________________________________________
Name: svn:executable
   + *

Added: tags/rott-1.1/mac/SDLMain.m
===================================================================
--- tags/rott-1.1/mac/SDLMain.m	                        (rev 0)
+++ tags/rott-1.1/mac/SDLMain.m	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,278 @@
+/*   SDLMain.m - main entry point for our Cocoa-ized SDL app
+       Initial Version: Darrell Walisser <dwaliss1 at purdue.edu>
+       Non-NIB-Code & other changes: Max Horn <max at quendi.de>
+
+    Feel free to customize this file to suit your needs
+*/
+
+#import "SDL.h"
+#import "SDLMain.h"
+#import <sys/param.h> /* for MAXPATHLEN */
+#import <unistd.h>
+
+/* Use this flag to determine whether we use SDLMain.nib or not */
+#define		SDL_USE_NIB_FILE	0
+
+
+static int    gArgc;
+static char  **gArgv;
+static BOOL   gFinderLaunch;
+
+#if SDL_USE_NIB_FILE
+/* A helper category for NSString */
+ at interface NSString (ReplaceSubString)
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
+ at end
+#else
+/* An internal Apple class used to setup Apple menus */
+ at interface NSAppleMenuController:NSObject {}
+- (void)controlMenu:(NSMenu *)aMenu;
+ at end
+#endif
+
+ at interface SDLApplication : NSApplication
+ at end
+
+ at implementation SDLApplication
+/* Invoked from the Quit menu item */
+- (void)terminate:(id)sender
+{
+    /* Post a SDL_QUIT event */
+    SDL_Event event;
+    event.type = SDL_QUIT;
+    SDL_PushEvent(&event);
+}
+ at end
+
+
+/* The main class of the application, the application's delegate */
+ at implementation SDLMain
+
+/* Set the working directory to the .app's parent directory */
+- (void) setupWorkingDirectory:(BOOL)shouldChdir
+{
+    char parentdir[MAXPATHLEN];
+    char *c;
+    
+    strncpy ( parentdir, gArgv[0], sizeof(parentdir) );
+    c = (char*) parentdir;
+
+    while (*c != '\0')     /* go to end */
+        c++;
+    
+    while (*c != '/')      /* back up to parent */
+        c--;
+    
+    *c++ = '\0';             /* cut off last part (binary name) */
+  
+    if (shouldChdir)
+    {
+      assert ( chdir (parentdir) == 0 );   /* chdir to the binary app's parent */
+      assert ( chdir ("../../../") == 0 ); /* chdir to the .app's parent */
+    }
+}
+
+#if SDL_USE_NIB_FILE
+
+/* Fix menu to contain the real app name instead of "SDL App" */
+- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
+{
+    NSRange aRange;
+    NSEnumerator *enumerator;
+    NSMenuItem *menuItem;
+
+    aRange = [[aMenu title] rangeOfString:@"SDL App"];
+    if (aRange.length != 0)
+        [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
+
+    enumerator = [[aMenu itemArray] objectEnumerator];
+    while ((menuItem = [enumerator nextObject]))
+    {
+        aRange = [[menuItem title] rangeOfString:@"SDL App"];
+        if (aRange.length != 0)
+            [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
+        if ([menuItem hasSubmenu])
+            [self fixMenu:[menuItem submenu] withAppName:appName];
+    }
+    [ aMenu sizeToFit ];
+}
+
+#else
+
+void setupAppleMenu(void)
+{
+    /* warning: this code is very odd */
+    NSAppleMenuController *appleMenuController;
+    NSMenu *appleMenu;
+    NSMenuItem *appleMenuItem;
+
+    appleMenuController = [[NSAppleMenuController alloc] init];
+    appleMenu = [[NSMenu alloc] initWithTitle:@""];
+    appleMenuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+    
+    [appleMenuItem setSubmenu:appleMenu];
+
+    /* yes, we do need to add it and then remove it --
+       if you don't add it, it doesn't get displayed
+       if you don't remove it, you have an extra, titleless item in the menubar
+       when you remove it, it appears to stick around
+       very, very odd */
+    [[NSApp mainMenu] addItem:appleMenuItem];
+    [appleMenuController controlMenu:appleMenu];
+    [[NSApp mainMenu] removeItem:appleMenuItem];
+    [appleMenu release];
+    [appleMenuItem release];
+}
+
+/* Create a window menu */
+void setupWindowMenu(void)
+{
+    NSMenu		*windowMenu;
+    NSMenuItem	*windowMenuItem;
+    NSMenuItem	*menuItem;
+
+
+    windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+    
+    /* "Minimize" item */
+    menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
+    [windowMenu addItem:menuItem];
+    [menuItem release];
+    
+    /* Put menu into the menubar */
+    windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
+    [windowMenuItem setSubmenu:windowMenu];
+    [[NSApp mainMenu] addItem:windowMenuItem];
+    
+    /* Tell the application object that this is now the window menu */
+    [NSApp setWindowsMenu:windowMenu];
+
+    /* Finally give up our references to the objects */
+    [windowMenu release];
+    [windowMenuItem release];
+}
+
+/* Replacement for NSApplicationMain */
+void CustomApplicationMain (argc, argv)
+{
+    NSAutoreleasePool	*pool = [[NSAutoreleasePool alloc] init];
+    SDLMain				*sdlMain;
+
+    /* Ensure the application object is initialised */
+    [SDLApplication sharedApplication];
+    
+    /* Set up the menubar */
+    [NSApp setMainMenu:[[NSMenu alloc] init]];
+    setupAppleMenu();
+    setupWindowMenu();
+    
+    /* Create SDLMain and make it the app delegate */
+    sdlMain = [[SDLMain alloc] init];
+    [NSApp setDelegate:sdlMain];
+    
+    /* Start the main event loop */
+    [NSApp run];
+    
+    [sdlMain release];
+    [pool release];
+}
+
+#endif
+
+/* Called when the internal event loop has just started running */
+- (void) applicationDidFinishLaunching: (NSNotification *) note
+{
+    int status;
+
+    /* Set the working directory to the .app's parent directory */
+    [self setupWorkingDirectory:gFinderLaunch];
+
+#if SDL_USE_NIB_FILE
+    /* Set the main menu to contain the real app name instead of "SDL App" */
+    [self fixMenu:[NSApp mainMenu] withAppName:[[NSProcessInfo processInfo] processName]];
+#endif
+
+    /* Hand off to main application code */
+    status = SDL_main (gArgc, gArgv);
+
+    /* We're done, thank you for playing */
+    exit(status);
+}
+ at end
+
+
+ at implementation NSString (ReplaceSubString)
+
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
+{
+    unsigned int bufferSize;
+    unsigned int selfLen = [self length];
+    unsigned int aStringLen = [aString length];
+    unichar *buffer;
+    NSRange localRange;
+    NSString *result;
+
+    bufferSize = selfLen + aStringLen - aRange.length;
+    buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
+    
+    /* Get first part into buffer */
+    localRange.location = 0;
+    localRange.length = aRange.location;
+    [self getCharacters:buffer range:localRange];
+    
+    /* Get middle part into buffer */
+    localRange.location = 0;
+    localRange.length = aStringLen;
+    [aString getCharacters:(buffer+aRange.location) range:localRange];
+     
+    /* Get last part into buffer */
+    localRange.location = aRange.location + aRange.length;
+    localRange.length = selfLen - localRange.location;
+    [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
+    
+    /* Build output string */
+    result = [NSString stringWithCharacters:buffer length:bufferSize];
+    
+    NSDeallocateMemoryPages(buffer, bufferSize);
+    
+    return result;
+}
+
+ at end
+
+
+
+#ifdef main
+#  undef main
+#endif
+
+
+/* Main entry point to executable - should *not* be SDL_main! */
+int main (int argc, char **argv)
+{
+
+    /* Copy the arguments into a global variable */
+    int i;
+    
+    /* This is passed if we are launched by double-clicking */
+    if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
+        gArgc = 1;
+	gFinderLaunch = YES;
+    } else {
+        gArgc = argc;
+	gFinderLaunch = NO;
+    }
+    gArgv = (char**) malloc (sizeof(*gArgv) * (gArgc+1));
+    assert (gArgv != NULL);
+    for (i = 0; i < gArgc; i++)
+        gArgv[i] = argv[i];
+    gArgv[i] = NULL;
+
+#if SDL_USE_NIB_FILE
+    [SDLApplication poseAsClass:[NSApplication class]];
+    NSApplicationMain (argc, argv);
+#else
+    CustomApplicationMain (argc, argv);
+#endif
+    return 0;
+}


Property changes on: tags/rott-1.1/mac/SDLMain.m
___________________________________________________________________
Name: svn:executable
   + *

Added: tags/rott-1.1/misc/rott.xpm
===================================================================
--- tags/rott-1.1/misc/rott.xpm	                        (rev 0)
+++ tags/rott-1.1/misc/rott.xpm	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,67 @@
+/* XPM */
+static char * rott_xpm[] = {
+"32 29 35 1",
+" 	c None",
+".	c #240000",
+"+	c #242424",
+"@	c #926D6D",
+"#	c #000000",
+"$	c #6D4949",
+"%	c #926D49",
+"&	c #494924",
+"*	c #6D6D49",
+"=	c #494949",
+"-	c #49496D",
+";	c #92926D",
+">	c #242449",
+",	c #49246D",
+"'	c #494992",
+")	c #242492",
+"!	c #492424",
+"~	c #242400",
+"{	c #6D4900",
+"]	c #24246D",
+"^	c #924900",
+"/	c #926D00",
+"(	c #492449",
+"_	c #6D4924",
+":	c #B69200",
+"<	c #929200",
+"[	c #B6B600",
+"}	c #494900",
+"|	c #000049",
+"1	c #240024",
+"2	c #002449",
+"3	c #492400",
+"4	c #000024",
+"5	c #6D6D00",
+"6	c #B6DB00",
+"               ..               ",
+"              +@@.              ",
+"             #$%@&              ",
+"             +*+=&.             ",
+"            #**+-*=             ",
+"            &;+>>=%+            ",
+"           .@$>>+,*$#           ",
+"          #=%>'&+)=@!           ",
+"          ~;=>,{&]>$*#          ",
+"         #&@>'>^{>]=%!          ",
+"         +@=])=^{>]]=*.         ",
+"        #$@>']!//+]](*&#        ",
+"        +%+)]]_:<!]>]=%~        ",
+"       .*=>)]]{[:}|]>>$&#       ",
+"       &@>)]]({[[{>]>|=$+       ",
+"      .@=]])]+^</{12||>$$#      ",
+"     #=@>]]]]>3{{!|||||($+      ",
+"     ~@(]])]]>]|||]||||>&&#     ",
+"    #$$>]]2>>]]>]>|+>|||=$!     ",
+"    + at +|]>+{^!||>|}{}4|||&$~    ",
+"   #$$|]]+{:<{1||+{/5}1||+&!    ",
+"   !*+]>+{:6[^~||!{<<5}1||!&.   ",
+"  #$&||({/:/{34||+3}{5{}141&!#  ",
+"  !$12!/{{3+4||||||4+33}}14+&+# ",
+" .*+|!}!+|||||||||||4441~3#4&&. ",
+"#&$1111||||||||4||44444444#4+&+ ",
+"~$!$$=======&=&&&&&&!!&&!!!!!&&#",
+"~$$$$*$*$%$*$$$$$$$$$&$$$&$&&&&.",
+" .....~...####~~.........#.###. "};

Added: tags/rott-1.1/misc/runrott.sh
===================================================================
--- tags/rott-1.1/misc/runrott.sh	                        (rev 0)
+++ tags/rott-1.1/misc/runrott.sh	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,28 @@
+#!/bin/sh
+# quick hack rott.rot generation in sh v0.1 by Steven Fuller
+# inspired by Delphi Dude's RUNROTT:
+# http://www.delphidude.com/personal/utilities/games/
+
+CONFIG=$HOME/.rott/darkwar/rott.rot
+EXE=./rott
+
+if [ $# != 1 ]; then
+	echo "usage: "$0" <RTL or RTC filename>"
+	exit 1
+fi
+
+if [ ! -r $1 ]; then
+	echo "error: "$1" does not exist"
+	exit 1
+fi
+
+cat > $CONFIG <<!END!
+; Rise of the Triad Game Information File
+; (c) 1997
+PHONENUMBER          ~
+REMOTESOUNDFILE      ~
+GAMELEVELFILE        $1
+COMMBATLEVELFILE     ~
+!END!
+
+exec $EXE


Property changes on: tags/rott-1.1/misc/runrott.sh
___________________________________________________________________
Name: svn:executable
   + *

Added: tags/rott-1.1/rott/Makefile
===================================================================
--- tags/rott-1.1/rott/Makefile	                        (rev 0)
+++ tags/rott-1.1/rott/Makefile	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,123 @@
+#-----------------------------------------------------------------------------#
+# ROTT makefile.
+#-----------------------------------------------------------------------------#
+
+
+#-----------------------------------------------------------------------------#
+# If this makefile fails to detect Cygwin correctly, or you want to force
+#  the build process's behaviour, set it to "true" or "false" (w/o quotes).
+#-----------------------------------------------------------------------------#
+#cygwin := true
+#cygwin := false
+cygwin := autodetect
+
+# you only need to set these for Cygwin at the moment.
+SDL_INC_DIR = /cygdrive/c/SDL/include
+SDL_LIB_DIR = /cygdrive/c/SDL/lib
+
+
+# Don't touch anything below this line unless you know what you're doing.
+
+ifeq ($(strip $(cygwin)),autodetect)
+  ifneq ($(strip $(shell gcc -v 2>&1 |grep "cygwin")),)
+    cygwin := true
+  else
+    cygwin := false
+  endif
+endif
+
+
+ifeq ($(strip $(cygwin)),true)
+  ifeq ($(strip $(SDL_INC_DIR)),please_set_me_cygwin_users)
+    $(error Cygwin users need to set the SDL_INC_DIR envr var.)
+  else
+    SDL_CFLAGS := -I$(SDL_INC_DIR)
+  endif
+
+  ifeq ($(strip $(SDL_LIB_DIR)),please_set_me_cygwin_users)
+    $(error Cygwin users need to set the SDL_LIB_DIR envr var.)
+  else
+    SDL_LDFLAGS := -L$(SDL_LIB_DIR) -lSDL
+  endif
+else
+  SDL_CFLAGS := $(shell sdl-config --cflags)
+  SDL_LDFLAGS := $(shell sdl-config --libs)
+  EXTRACFLAGS += -DUSE_EXECINFO=1
+endif
+
+
+CC = gcc
+CFLAGS += -g -W -Wall -Wno-unused -Wno-pointer-sign
+ALL_CFLAGS = $(SDL_CFLAGS) -DUSE_SDL=1 -DPLATFORM_UNIX=1 $(CFLAGS) $(EXTRACFLAGS)
+LDFLAGS += -Wl,-E
+LDLIBS = $(LDFLAGS) $(SDL_LDFLAGS) -lSDL -lSDL_mixer $(EXTRALDFLAGS)
+
+%.o: %.c
+	$(CC) $(ALL_CFLAGS) -c $< -o $@
+
+all: rott
+
+audiolib/audiolib.a:
+	$(MAKE) -C audiolib CC="$(CC)" CFLAGS="$(ALL_CFLAGS)" LDLIBS="$(LDLIBS)"
+
+rott: 	\
+	cin_actr.o \
+	cin_efct.o \
+	cin_evnt.o \
+	cin_glob.o \
+	cin_main.o \
+	cin_util.o \
+	dosutil.o \
+	engine.o \
+	isr.o \
+	modexlib.o \
+	rt_actor.o \
+	rt_battl.o \
+	rt_build.o \
+	rt_cfg.o \
+	rt_crc.o \
+	rt_com.o \
+	rt_debug.o \
+	rt_dmand.o \
+	rt_door.o \
+	rt_draw.o \
+	rt_floor.o \
+	rt_game.o \
+	rt_in.o \
+	rt_main.o \
+	rt_map.o \
+	rt_menu.o \
+	rt_msg.o \
+	rt_net.o \
+	rt_playr.o \
+	rt_rand.o \
+	rt_scale.o \
+	rt_sound.o \
+	rt_spbal.o \
+	rt_sqrt.o \
+	rt_stat.o \
+	rt_state.o \
+	rt_str.o \
+	rt_swift.o \
+	rt_ted.o \
+	rt_util.o \
+	rt_view.o \
+	rt_vid.o \
+	rt_err.o \
+	scriplib.o \
+	w_wad.o \
+	watcom.o \
+	z_zone.o \
+	byteordr.o \
+	dukemusc.o \
+	audiolib/audiolib.a \
+	winrott.o
+	$(CC) $^ $(LDLIBS) -o $@
+
+clean:
+	$(MAKE) -C audiolib clean
+	rm -rf rott *.o
+
+distclean: clean
+	$(MAKE) -C audiolib distclean
+	rm -rf *~

Added: tags/rott-1.1/rott/WinRott.h
===================================================================
--- tags/rott-1.1/rott/WinRott.h	                        (rev 0)
+++ tags/rott-1.1/rott/WinRott.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,55 @@
+
+
+// winrott.h
+
+
+//husk at rette i winrott.c
+
+extern int iGLOBAL_SCREENWIDTH;//bna val 800
+extern int iGLOBAL_SCREENHEIGHT;//bna val 600
+extern int iGLOBAL_SCREENBWIDE ;
+extern int iG_SCREENWIDTH;// default screen width in bytes
+
+extern int iGLOBAL_HEALTH_X;
+extern int iGLOBAL_HEALTH_Y;
+extern int iGLOBAL_AMMO_X;
+extern int iGLOBAL_AMMO_Y;
+
+extern int iGLOBAL_FOCALWIDTH;
+extern double dGLOBAL_FPFOCALWIDTH;
+
+void EnableScreenStretch(void);
+void DisableScreenStretch(void);
+
+/*
+double dYZANGLELIMIT;
+
+#define FOCALWIDTH 160//160
+#define FPFOCALWIDTH 160.0//160.0
+
+
+
+#define MAXSCREENHEIGHT    480//600//     200*2
+#define MAXSCREENWIDTH     640//800//     320*2
+#define SCREENBWIDE        640*(96/320)//800*(96/320)//     96*2
+#define MAXVIEWWIDTH       640//     320*2
+#define SCREENWIDTH        640*(96/320)//800*(96/320)//     96*2              // default screen width in bytes
+
+
+#define MAXSCREENHEIGHT    600
+#define MAXSCREENWIDTH     800
+#define SCREENBWIDE        800*(96/320)
+#define MAXVIEWWIDTH       800
+#define SCREENWIDTH        800*(96/320)// default screen width in bytes
+
+*/
+//#define VIEWWIDTH               MAXSCREENWIDTH//320*2             // size of view window
+//#define VIEWHEIGHT              MAXSCREENHEIGHT//200*2
+//#define MAXSCANLINES            MAXSCREENHEIGHT//200*2             // size of ylookup table
+
+
+
+
+
+
+

Added: tags/rott-1.1/rott/_engine.h
===================================================================
--- tags/rott-1.1/rott/_engine.h	                        (rev 0)
+++ tags/rott-1.1/rott/_engine.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,27 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _engine_private
+#define _engine_private
+
+#define NOTSAMETILE(x1,x2)     ( (posts[(x1)].posttype!=posts[(x2)].posttype) || \
+                                 (posts[(x1)].offset!=posts[(x2)].offset))
+#define SGN(x)                 (x>0 ? 1 : -1)
+
+#endif

Added: tags/rott-1.1/rott/_isr.h
===================================================================
--- tags/rott-1.1/rott/_isr.h	                        (rev 0)
+++ tags/rott-1.1/rott/_isr.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    ISR Constants
+//
+//***************************************************************************
+
+#ifndef _isr_private
+#define _isr_private
+
+#define TIMERINT                0x08
+#define KEYBOARDINT             0x09
+
+#endif

Added: tags/rott-1.1/rott/_rt_acto.h
===================================================================
--- tags/rott-1.1/rott/_rt_acto.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_acto.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,296 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_actor_private
+#define _rt_actor_private
+
+#define MAXGIBS            600
+#define HAAPT              24
+#define VAAPT              24
+#define GODHAPT            1024
+#define GODVAPT            1024
+#define MAXDELTAYZSHOOT    (((5*FINEANGLES)/360))
+#define MAXDELTAYZSEE      (((15*FINEANGLES)/360))
+#define MAXSHOOTOFFSET     (((15*FINEANGLES)/360))
+#define MAXSHOOTSHIFT      (1)
+#define MAXDAMAGE          (64)
+#define MAXYZANGLE         (((30*FINEANGLES)/360))
+#define SMOKEWALLOFFSET    (0x800)
+#define MZADJUST           0x30000;
+#define MAXSTEPHEIGHT      24
+#define SIGN(x)            ((x)>=0)?(1):(-1)
+#define MAXRAIN            128
+#define SG_PSTAT      0x4000
+#define SG_PSTATE     0x2000
+#define EXPLOSION_DAMAGE   50
+#define LOWFALLCLIPZ       (maxheight - 96)
+#define HIGHFALLCLIPZ      -5
+#define LOWRISECLIPZ       (nominalheight)
+#define HIGHRISECLIPZ      64
+#define NORMALGIBSPEED     0x2f00
+
+#define FL_PLEADING        0x400
+#define FL_EYEBALL         0x400
+#define FL_UNDEAD          0x8000
+
+#define NME_DRUNKTYPE       0x01
+#define NME_HEATSEEKINGTYPE 0x02
+
+#define NUMSTATES 11
+
+enum {
+  STAND,
+  PATH,
+  COLLIDE1,
+  COLLIDE2,
+  CHASE,
+  USE,
+  AIM,
+  DIE,
+  FIRE,
+  WAIT,
+  CRUSH
+  };
+
+#define SHOTMOM                0x200l
+#define NEXT                   1
+#define PREV                   0
+#define ANGLEMOVE              0x2b000l
+#define PAINTIME               5l
+#define LOOKAHEAD              (20 << 16)
+#define DRAINTIME              70l
+#define EXPLOSION_IMPULSE      0x2600l
+#define ZEROMOM                ob->momentumx = ob->momentumy = 0
+#define NOMOM                  ((!ob->momentumx) && (!ob->momentumy))
+#define WHICHACTOR             (ob->obclass-lowguardobj)
+#define SPDPATROL              0x600l
+//#define ENEMYRUNSPEED          (3*SPDPATROL)
+#define ENEMYRUNSPEED          (0xc00)
+#define ENEMYFASTRUNSPEED      (5*SPDPATROL)
+#define ENEMYINSANESPEED       (7*SPDPATROL)
+#define MAXMOVE                0x2000l
+#define PROJECTILESIZE         0x6000l
+#define DEADFRICTION           0x6000l
+#define ROLLMOMENTUM           0x920l
+#define PROJSIZE               0x4000l
+#define PILLARMOM              0x800l
+#define HALFGLOBAL1            (TILEGLOBAL/2)
+#define TOUCHDIST              0xb000l
+#define STANDDIST              0x5000l
+#define SNAKERAD               0x4000l
+#define MINSIGHT               0x18000l
+#define HBM                    -2
+#define SNEAKY                 -3
+#define GIBVALUE               -3
+#define DISKMOMZ               4
+
+//=========================== macros =============================
+
+#define M_ISWALL(x)           ((x->which == WALL) || (x->which == PWALL) || (x->which == MWALL))
+#define M_DISTOK(p1,p2,d)     (abs((p1)-(p2)) <= d)
+#define M_NONS(x)             ((x->obclass == wallfireobj) || (x->obclass == pillarobj))
+#define M_CHOOSETIME(x)       ((int)(TILEGLOBAL/((x->speed))))
+#define M_DIST(x1,x2,y1,y2)   (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
+#define M_S(x)                (UPDATE_STATES[x][ob->obclass-lowguardobj])
+#define Fix(a)                (a &= (FINEANGLES - 1))
+
+
+#define STOPACTOR(ob)                   \
+   {                                    \
+   ob->momentumx = ob->momentumy = 0;   \
+   ob->dirchoosetime = 0;               \
+   }
+
+
+#define M_CHECKDIR(ob,tdir)             \
+   {                                    \
+   ob->dir = tdir;                      \
+   ParseMomentum(ob,dirangle8[tdir]);   \
+   ActorMovement(ob);                   \
+   if (ob->momentumx || ob->momentumy)  \
+      return;                           \
+   }                                    \
+
+
+#define M_CHECKTURN(x,ndir)                             \
+   {                                                    \
+   if (ndir == olddir)                                  \
+      ZEROMOM;                                          \
+   ParseMomentum(x,dirangle8[ndir]);                    \
+   ActorMovement(x);                                    \
+   if (!NOMOM)                                          \
+      {                                                 \
+      if (ndir != olddir)                               \
+         {                                              \
+         next = dirorder[olddir][NEXT];                 \
+         prev = dirorder[olddir][PREV];                 \
+         x->temp1 = ndir;                               \
+         if (dirdiff[ndir][next] < dirdiff[ndir][prev]) \
+            NewState(x,&s_kristleft);                   \
+         else                                           \
+            NewState(x,&s_kristright);                  \
+         }                                              \
+      return;                                           \
+      }                                                 \
+   }                                                    \
+
+#define M_CheckDoor(ob)                          \
+   {                                             \
+   door = ob->door_to_open;                      \
+   if (door != -1)                               \
+      {                                          \
+      if ((ob->obclass > shurikenobj) &&         \
+          (ob->obclass != collectorobj)          \
+         )                                       \
+         Error("you got it !!!");                \
+      LinkedOpenDoor(door);                      \
+      if (doorobjlist[door]->action != dr_open)  \
+         return;                                 \
+      ob->door_to_open = -1;                     \
+      }                                          \
+   }                                             \
+
+#define M_CheckBossSounds(ob)                                 \
+   {                                                          \
+   if ((ob->obclass >= b_darianobj) &&                        \
+       (ob->obclass <= b_darksnakeobj) &&                     \
+       (ob->flags & FL_ATTACKMODE)  &&                        \
+       (ob->obclass != b_robobossobj) &&                      \
+       (!(ob->flags & FL_DYING))                              \
+      )                                                       \
+      {                                                       \
+      if (MISCVARS->SOUNDTIME)                                \
+         MISCVARS->SOUNDTIME --;                              \
+      else                                                    \
+         {                                                    \
+         MISCVARS->SOUNDTIME = 5*VBLCOUNTER;                  \
+         if (GameRandomNumber("boss sound check",0)<160)      \
+            {                                                 \
+            int rand,sound;                                   \
+                                                              \
+            rand = GameRandomNumber("boss sounds",0);         \
+            sound = BAS[ob->obclass].operate;                 \
+            if (rand < 160)                                   \
+               sound ++;                                      \
+            if (rand < 80)                                    \
+               sound ++;                                      \
+                                                              \
+            SD_PlaySoundRTP(sound,ob->x,ob->y);               \
+            }                                                 \
+         }                                                    \
+      if (MISCVARS->REDTIME)                                  \
+         {                                                    \
+         MISCVARS->REDTIME --;                                \
+         MISCVARS->redindex = ((MISCVARS->REDTIME >> 1) & 15);\
+         }                                                    \
+      }                                                       \
+   }
+
+
+
+
+#define SET_DEATH_SHAPEOFFSET(ob)                     \
+   {                                                  \
+   ob->flags |= FL_ALTERNATE;                         \
+   ob->shapeoffset += deathshapeoffset[ob->obclass];  \
+   }
+
+
+#define RESET_DEATH_SHAPEOFFSET(ob)                   \
+   {                                                  \
+   ob->flags &= ~FL_ALTERNATE;                        \
+   ob->shapeoffset -= deathshapeoffset[ob->obclass];  \
+   }
+
+#define LOW_VIOLENCE_DEATH_SHOULD_BE_SET(ob)          \
+     ((gamestate.violence < vl_high) &&               \
+      (ob->obclass >= lowguardobj) &&                 \
+      (ob->obclass <= triadenforcerobj) &&            \
+      (!(ob->flags & FL_ALTERNATE))                   \
+     )                                                \
+
+#define LOW_VIOLENCE_DEATH_IS_SET(ob)   (ob->flags & FL_ALTERNATE)
+
+#define LOW_VIOLENCE_PAIN_SHOULD_BE_SET  LOW_VIOLENCE_DEATH_SHOULD_BE_SET
+
+#define LOW_VIOLENCE_PAIN_IS_SET  LOW_VIOLENCE_DEATH_IS_SET
+
+#define SET_PAIN_SHAPEOFFSET  SET_DEATH_SHAPEOFFSET
+
+#define RESET_PAIN_SHAPEOFFSET  RESET_DEATH_SHAPEOFFSET
+
+
+// default = actor
+
+typedef struct  sat
+ { int          x,y,z;
+	unsigned     flags;
+	int          hitpoints;
+	int          targetx,targety;
+	int          angle;
+	int          yzangle;
+	int          speed;
+	int          momentumx,momentumy,momentumz;
+	int          temp1,temp2,temp3;
+	int          whateverindex,targetindex;
+
+	short        ticcount;
+	short        shapeoffset;
+	short        stateindex;
+	short        dirchoosetime;
+
+	byte         areanumber;
+	byte         obclass;
+	signed char  door_to_open;
+	signed char  dir;
+
+ }saved_actor_type;
+
+
+typedef struct
+ {thingtype which;
+  byte tilex,tiley;
+  fixed x,y,z;
+ }tpoint;
+
+
+//========================== Function Prototypes ==============================
+
+void     MissileMovement(objtype*);
+boolean  MissileTryMove(objtype*,int,int,int);
+void     T_DarkSnakeChase(objtype*);
+void     HeatSeek(objtype*);
+boolean  CheckDoor(objtype *ob,doorobj_t*,int,int);
+boolean  NextToDoor(objtype*ob);
+void     MissileHit (objtype *ob,void*);
+int      Near(objtype*,void*,int);
+void     FirstSighting(objtype*);
+void     SelectOrobotChaseDir(objtype*);
+void     SelectPathDir(objtype*);
+void     SelectChaseDir(objtype*);
+void     SelectRoboChaseDir(objtype*);
+void     SelectDodgeDir(objtype*);
+void     SelectRollDir (objtype*);
+void     SelectTouchDir(objtype*);
+void     SelectMineDir(objtype*);
+boolean  WallCheck(int,int);
+boolean  NMEspincheck(objtype*);
+void     TurnActorIntoSprite(objtype*ob);
+void     ActivateEnemy(objtype*);
+#endif

Added: tags/rott-1.1/rott/_rt_buil.h
===================================================================
--- tags/rott-1.1/rott/_rt_buil.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_buil.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,48 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_build_private
+#define _rt_build_private
+
+#define MAX(x,y)               ((x>y) ? (x) : (y))
+#define MAXPLANES 10
+
+// Should be 10 with titles
+#define MENUOFFY     (10)
+#define MENUBACKNAME ("plane")
+#define MENUTITLEY 10
+#define TEXTUREW     (288)
+#define TEXTUREWIDTH ((TEXTUREW*1024)-1)
+#define TEXTUREHEIGHT (158)
+#define NORMALVIEW   (0x40400L)
+#define NORMALHEIGHTDIVISOR   (156000000)
+#define NORMALWIDTHMULTIPLIER (241)
+#define FLIPTIME     20//60
+
+
+typedef struct
+{
+   int   x1, y1;
+   int   x2, y2;
+   int   texturewidth;
+   int   texture;
+   int   origheight;
+} plane_t;
+
+#endif

Added: tags/rott-1.1/rott/_rt_com.h
===================================================================
--- tags/rott-1.1/rott/_rt_com.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_com.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,53 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_com_private
+#define _rt_com_private
+
+
+#define SYNCPACKETSIZE 32
+
+#define SYNC_PHASE0 6
+#define SYNC_PHASE1 0
+#define SYNC_PHASE2 1
+#define SYNC_PHASE3 2
+#define SYNC_PHASE4 3
+#define SYNC_PHASE5 4
+#define SYNC_MEMO   99
+#define NUMSYNCPHASES 5
+
+#define SYNCTIME    15
+
+typedef struct
+{
+   byte type;
+   int  phase;
+   int  clocktime;
+   int  delta;
+   byte data[SYNCPACKETSIZE];
+} syncpackettype;
+
+typedef struct
+{
+   int  sendtime;
+   int  deltatime;
+   syncpackettype pkt;
+} synctype;
+
+#endif

Added: tags/rott-1.1/rott/_rt_dman.h
===================================================================
--- tags/rott-1.1/rott/_rt_dman.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_dman.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,29 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_dmand_private
+#define _rt_dmand_private
+
+#define RECORDINGSAMPLERATE 7000
+#define RECORDINGBUFFERSIZE 16384
+#define PLAYBACKBUFFERSIZE 16384
+#define PLAYBACKDELTASIZE  256
+
+#endif
+

Added: tags/rott-1.1/rott/_rt_door.h
===================================================================
--- tags/rott-1.1/rott/_rt_door.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_door.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,48 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_door_private
+#define _rt_door_private
+
+#define OPENTICS	165
+
+typedef struct tp
+ {
+  signed char actionindex;
+  signed char swapactionindex;
+  int         whichobj;
+  byte        tictime;
+  byte        ticcount;
+  byte        triggered;
+  byte        complete;
+  byte        done;
+ } saved_touch_type;
+
+
+#define NUMTOUCHPLATEACTIONS 8
+
+#define FL_TACT 0x4000
+#define FL_TSTAT 0x8000
+
+#define PUSHWALLSPEED 10
+
+#define AMW_NUMFRAMES 9
+#define AMW_TICCOUNT  3
+
+#endif

Added: tags/rott-1.1/rott/_rt_draw.h
===================================================================
--- tags/rott-1.1/rott/_rt_draw.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_draw.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,74 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_draw_private
+#define _rt_draw_private
+
+#include "develop.h"
+
+#define MINZ                            0x2700
+#define MAXBOB                          0x9000
+
+#define GOLOWER  0x38000
+#define GOHIGHER 0x20000
+
+#define MAXVISIBLEDOORS 30
+
+#define DHEIGHTFRACTION 8
+
+#define MINZ                            0x2700
+#define MAXDRAWNTICS                    40
+
+#define W_CHANGE  (WEAPONUPTICS || WEAPONDOWNTICS)
+
+#if (SHAREWARE == 0)
+ #define NUMWEAPGRAPHICS 16
+#else
+ #define NUMWEAPGRAPHICS 9
+#endif
+
+#define HFRACTION (6+HEIGHTFRACTION)
+
+#define FIXEDTRANSLEVEL (30)
+
+typedef struct
+{
+   int x;
+   int y;
+   int angle;
+   int scale;
+   int dx;
+   int dy;
+   int dangle;
+   int dscale;
+   int phase;
+   int time;
+   int pausetime;
+   int pausex;
+   int pausey;
+} screensaver_t;
+
+void  DrawPlayerWeapon(void);
+boolean TransformPlane (int x1, int y1, int x2, int y2, visobj_t * plane);
+int   CalcRotate (objtype *ob);
+void  DrawScaleds (void);
+void  FixOfs (void);
+void SetSpriteLightLevel (int x, int y, visobj_t * sprite, int dir, int fullbright);
+
+#endif

Added: tags/rott-1.1/rott/_rt_floo.h
===================================================================
--- tags/rott-1.1/rott/_rt_floo.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_floo.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,28 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_floor_private
+#define _rt_floor_private
+
+//#define	MAXVIEWHEIGHT MAXSCREENHEIGHT	
+#define MAXSKYSEGS    2048
+#define MAXSKYDATA    8
+#define MINSKYHEIGHT  0//148 //bna++ sky change here
+
+#endif

Added: tags/rott-1.1/rott/_rt_game.h
===================================================================
--- tags/rott-1.1/rott/_rt_game.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_game.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,165 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_game_private
+#define _rt_game_private
+
+//******************************************************************************
+//
+// Private header for RT_GAME.C
+//
+//******************************************************************************
+
+
+//******************************************************************************
+//
+// TYPEDEFS
+//
+//******************************************************************************
+
+typedef struct {
+   char str[10];
+   int length;
+} STR;
+
+//******************************************************************************
+//
+// DEFINES
+//
+//******************************************************************************
+
+#define MENUSHADELEVEL  105
+
+#define KILLS_X      0
+#define KILLS_Y      176
+#define KILLS_WIDTH  32
+#define KILLS_HEIGHT 24
+#define KILLS_OFFSET 14
+#define KILLS_NAME_Y ( KILLS_Y + 16 )
+#define MAXKILLBOXES 10
+#define PLAYERS_Y      ( 107 + ( gamestate.teamplay ? 0 : 4 ) )
+#define PLAYERS_NAME_Y ( PLAYERS_Y + 16 )
+#define PLAYERS_TEAM_Y ( PLAYERS_Y + 24 )
+
+#define LEADER_X      0
+#define LEADER_Y      0
+#define LEADER_NUM_X  61
+#define LEADER_NUM_Y  ( LEADER_Y )
+#define LEADER_NAME_X ( LEADER_X + 3 )
+#define LEADER_NAME_Y ( LEADER_Y + 2 )
+#define LEADER_WIDTH  88
+#define LEADER_HEIGHT 16
+/* bna++
+#define HEALTH_X  20
+#define HEALTH_Y  185
+
+#define AMMO_X    300
+#define AMMO_Y    184
+*/
+//--------------------
+#define HEALTH_X  20*2
+#define HEALTH_Y  (185*2)+16
+
+#define AMMO_X    300*2
+#define AMMO_Y    (184*2)+16
+//--------------------
+
+#define SCORE_X   4
+#define SCORE_Y   0
+
+/*
+#define KEY1_X    152
+#define KEY2_X    160
+#define KEY3_X    168
+#define KEY4_X    176
+#define KEY_Y     0
+
+#define POWER_X   184
+#define POWER_Y   0
+
+#define ARMOR_X   200
+#define ARMOR_Y   0
+
+#define MEN_X     216
+#define MEN_Y     0
+*/
+//--------------------
+#define KEY1_X    152
+#define KEY2_X    160
+#define KEY3_X    168
+#define KEY4_X    176
+#define KEY_Y     0
+
+#define POWER_X   (184)
+#define POWER_Y   0
+
+#define ARMOR_X   200
+#define ARMOR_Y   0
+
+#define MEN_X     216
+#define MEN_Y     0
+//--------------------
+#define HOUR_X    7
+#define MIN_X     26
+#define SEC_X     45
+#define TIME_Y    0
+
+#define GAMETIME_X 88
+#define GAMETIME_Y 0
+
+#define TALLYTIME_X 130
+#define TALLYTIME_Y 8
+
+#define LIVES_X   288
+#define LIVES_Y   0
+
+#define TRIAD_X   308
+#define TRIAD_Y   6
+
+#define POWERUP1X 184
+#define POWERUP2X 200
+#define POWERUPY  0
+
+#define EXTRAPOINTS        50000
+#define ADRENALINEBONUS    5
+
+#define STR_SAVECHT1 "Your Save Game file is,"
+#define STR_SAVECHT2 "shall we say, \"corrupted\"."
+#define STR_SAVECHT3 "But I'll let you go on and"
+#define STR_SAVECHT4 "play anyway...."
+
+#define MAXSAVEDGAMESIZE 120000
+
+#if (SHAREWARE == 0)
+#define WEAPON_IS_MAGICAL(x) (((x) == wp_dog) || ((x) == wp_godhand))
+#else
+#define WEAPON_IS_MAGICAL(x) ((x) == wp_godhand)
+#endif
+
+//******************************************************************************
+//
+// PROTOTYPES
+//
+//******************************************************************************
+
+void DrawMPPic (int xpos, int ypos, int width, int height, int heightmod, byte *src, boolean bufferofsonly);
+void DrawHighScores (void);
+void GM_MemToScreen (byte *source, int width, int height, int x, int y);
+
+#endif

Added: tags/rott-1.1/rott/_rt_in.h
===================================================================
--- tags/rott-1.1/rott/_rt_in.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_in.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,61 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//****************************************************************************
+//
+// Private header for RT_IN.C
+//
+//****************************************************************************
+
+#ifndef _rt_in_private
+#define _rt_in_private
+
+
+//****************************************************************************
+//
+// TYPEDEFS
+//
+//****************************************************************************
+
+
+//****************************************************************************
+//
+// DEFINES
+//
+//****************************************************************************
+
+#define  KeyInt         9  // The keyboard ISR number
+#define  MReset         0
+#define  MButtons       3
+#define  MDelta         11
+#define  MouseInt       0x33
+#define  JoyScaleMax    32768
+#define  JoyScaleShift  8
+#define  MaxJoyValue    5000
+
+void Mouse (int x);
+
+#if defined(__WATCOMC__)
+#pragma aux Mouse =  \
+   "int  33h"        \
+   parm [EAX]        \
+   modify [EAX]
+#endif
+
+#endif

Added: tags/rott-1.1/rott/_rt_main.h
===================================================================
--- tags/rott-1.1/rott/_rt_main.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_main.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,74 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_main_private
+#define _rt_main_private
+
+#include "develop.h"
+
+void GameLoop (void);
+void PlayLoop (void);
+void PollKeyboard(void);
+void FixColorMap( void );
+
+#define QUITTIMEINTERVAL ((35*6)-5)
+boolean CheckForQuickLoad ( void );
+
+#if SAVE_SCREEN
+
+void WriteLBMfile (char *filename, byte *data, int width, int height);
+void GetFileName (boolean saveLBM);
+void DrawRottTitle ( void );
+
+void WritePCX (char * file, byte * source);
+int PutBytes (unsigned char *ptr, unsigned int bytes);
+
+typedef struct
+{
+	unsigned short w,h;
+	short          x,y;
+	unsigned char  nPlanes;
+	unsigned char  masking;
+	unsigned char  compression;
+	unsigned char  pad1;
+	unsigned short transparentColor;
+	unsigned char  xAspect,yAspect;
+	short          pageWidth,pageHeight;
+} bmhd_t;
+
+
+typedef struct {
+   unsigned char manufacturer;
+   unsigned char version;
+   unsigned char encoding;
+   unsigned char bitsperpixel;
+   unsigned short int  xmin, ymin, xmax, ymax;
+   unsigned short int  hres, vres;
+   unsigned char colormap[16][3];
+   unsigned char reserved;
+   unsigned char nplanes;
+   unsigned short int  bytesperline;
+} PCX_HEADER;
+
+#define GAP_SIZE  (128 - sizeof (PCX_HEADER))
+
+
+#endif
+
+#endif

Added: tags/rott-1.1/rott/_rt_map.h
===================================================================
--- tags/rott-1.1/rott/_rt_map.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_map.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_map_private
+#define _rt_map_private
+
+#if defined(__WATCOM__)
+#pragma aux FastFill =  \
+        "rep stosb"       \
+        parm    [edi] [eax] [ecx] \
+        modify exact [ecx]
+#endif
+void FastFill(byte * buf, int color, int count);
+
+
+#define MAP_PLAYERCOLOR 4
+#define MAP_MWALLCOLOR 13
+#define MAP_PWALLCOLOR 8
+#define MAP_AWALLCOLOR 9
+#define MAP_WALLCOLOR 7
+#define MAP_DOORCOLOR 3
+#define MAP_SPRITECOLOR 2
+#define MAP_ACTORCOLOR 15
+#define MAP_SKYCOLOR 11
+
+#define FULLMAP_SCALE 5
+
+#endif

Added: tags/rott-1.1/rott/_rt_menu.h
===================================================================
--- tags/rott-1.1/rott/_rt_menu.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_menu.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,369 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_menu_private
+#define _rt_menu_private
+
+//******************************************************************************
+//
+// Private Header for RT_MENU.C
+//
+//******************************************************************************
+
+#include "rt_in.h"
+
+//
+// Specific Menu defines
+//
+
+#define BORDCOLOR       0x29
+#define BORD2COLOR      0x23
+#define DEACTIVE        0x2b
+#define BKGDCOLOR       0x2d
+#define STRIPE          0x2c
+
+
+#define SENSITIVE       60
+#define CENTER          SENSITIVE*2
+
+
+#define MENU_X          32
+#define MENU_Y          16
+#define MENU_W          235
+#define MENU_H          14*9+4
+
+
+#define LSM_X           180      //32
+#define LSM_Y           16
+#define LSM_W           80       //176
+#define LSM_H           10*14+8
+
+#define LSA_X           96
+#define LSA_Y           80
+#define LSA_W           130
+#define LSA_H           42
+
+
+#define SM_X            32
+#define SM_Y            52
+#define SM_W            252
+#define SM_H            35
+
+#define SM_Y1           20
+#define SM_H1           4*14-9
+#define SM_Y2           SM_Y1+5*14
+#define SM_H2           4*14-9
+#define SM_Y3           SM_Y2+5*14
+#define SM_H3           3*14-9
+
+
+#define CTL_X           19
+#define CTL_Y           32
+#define CTL_W           284
+#define CTL_H           105
+
+
+#define CST_X           20
+#define CST_Y           43
+#define CST_START       60
+#define CST_SPC         60
+
+
+#define TUF_X           0
+#define TUF_Y           32
+
+
+#define HLP_X           34
+#define HLP_Y           63
+#define HLP_W           264
+#define HLP_H           51
+
+
+#define MU_X            32
+#define MU_Y            22
+#define MU_W            252
+#define MU_H            118
+
+
+#define FX_X            32
+#define FX_Y            16
+#define FX_W            252
+#define FX_H            130
+
+
+#define MP_X            55//32
+#define MP_Y            60
+#define MP_W            252
+#define MP_H            35
+
+
+#define X1_X            55
+#define X1_Y            25
+#define X1_W            252
+
+#define X2_X            55
+#define X2_Y            65
+#define X2_W            252
+#define X2_H            35
+
+#define X3_X            55
+#define X3_Y            65
+#define X3_W            252
+#define X3_H            35
+
+#define LEVSEL_X            32
+#define LEVSEL_Y            22
+#define LEVSEL_W            252
+#define LEVSEL_H            118
+#define MAXCUSTOM       12
+
+#define STARTITEM       newgame
+
+//
+// General defines
+//
+#define CP_SemiActive      4
+#define CP_Highlight       5
+
+#define OUTOFRANGE         100
+#define ESCPRESSED         -1
+#define PAGEUP             -2
+#define PAGEDOWN           -3
+#define NOTAVAILABLECOLOR  7
+#define NEXTPAGECOLOR      16
+#define NORMALCOLOR        21
+#define DIMMEDCOLOR        24
+#define ACTIVECOLOR        241
+#define HIGHLIGHTCOLOR     1
+
+#define MouseInt 0x33
+#define GAMESVD      "There's already a game\n" \
+                     "saved at this position.\n"\
+                     "Overwrite?"
+#define COLOR        235
+
+#define CUSTOMX      76
+
+#define NUMSAVEGAMES 14
+
+#define PWORDX 58
+#define PWORDY 46
+//#define PBOXX  68
+#define PBOXX  ( ( 288 - PBOXW ) / 2 )
+#define PBOXY  71
+#define PBOXW  115
+#define PSTRW  110
+#define PBOXH  12
+
+
+#define QUICKSAVEBACKUP ("rottgamf.rot")
+//******************************************************************************
+//
+// ENUMS
+//
+//******************************************************************************
+
+typedef struct
+{
+   int allowed[4];
+} CustomCtrls;
+
+// FOR INPUT TYPES
+enum {MOUSE, JOYSTICK, KEYBOARDBTNS, KEYBOARDMOVE, SPECIAL1, SPECIAL2};
+
+
+//******************************************************************************
+//
+// GLOBALS
+//
+//******************************************************************************
+
+static byte *ScanNames[] =    // Scan code names with single chars
+{
+   "?","?","1","2","3","4","5","6","7","8","9","0","-","+","?","?",
+   "Q","W","E","R","T","Y","U","I","O","P","[","]","|","?","A","S",
+   "D","F","G","H","J","K","L",";","\"","?","?","?","Z","X","C","V",
+   "B","N","M",",",".","/","?","?","?","?","?","?","?","?","?","?",
+   "?","?","?","?","?","?","?","?","\xf","?","-","\x15","5","\x11","+","?",
+   "\x13","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
+   "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
+   "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"
+};
+
+
+static byte ExtScanCodes[] = // Scan codes with >1 char names
+{
+   1,    0xe,  0xf,  0x1d, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
+   0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, 0x46, 0x1c, 0x36,
+   0x37, 0x38, 0x47, 0x49, 0x4f, 0x51, 0x52, 0x53, 0x45, 0x48,
+   0x50, 0x4b, 0x4d, 0x00
+};
+
+static byte *ExtScanNames[] = // Names corresponding to ExtScanCodes
+{
+   "Esc","BkSp","Tab","Ctrl","Space","CapLk","F1","F2","F3","F4",
+   "F5","F6","F7","F8","F9","F10","F11","F12","SclLk","Enter","Shift",
+   "PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up",
+   "Down","Left","Right",""
+};
+
+
+//******************************************************************************
+//
+// PROTOTYPES
+//
+//******************************************************************************
+
+void MouseSensitivity (void);
+void DoThreshold (void);
+byte * IN_GetScanName (ScanCode scan);
+void DisplayInfo (int which);
+
+void PrintLSEntry (int w);
+
+void DrawHalfStep (int x, int y);
+
+void DrawCtlScreen (void);
+void DrawCtlButtons (void);
+void DrawSoundMenu (void);
+void DrawCustomScreen (void);
+void DrawLoadSaveScreen (int loadsave);
+void DrawLoadSaveScreenAlt (int loadsave);
+void DrawMusicMenu (void);
+void DrawNewGame (void);
+void DrawNewGameDiff (int w);
+void DrawNewPlayerDiff (int w);
+void DrawFXMenu (void);
+void DrawFXButtons (void);
+void DrawCustomJoystick (void);
+void DrawCustomMouse (void);
+void DrawCustomSpecial (void);
+void DrawCustomMenu (void);
+void DrawPlayerMenu (void);
+
+void DoMainMenu (void);
+
+boolean CP_DisplayMsg (char *s, int number);
+void CP_EndGame (void);
+int CP_SaveGame (void);
+void CP_Control (void);
+void CP_Sound (void);
+void CP_ChangeView (void);
+void CP_DoubleClickSpeed( void );
+void CP_ErrorMsg( char *title, char *error, int font );
+void CP_Quit (int which);
+void CP_NewGame (void);
+void CP_Music (void);
+void CP_FX (void);
+void CP_MCports (void);
+void CP_FXMenu (void);
+void CP_Custom (void);
+void CP_Keyboard (void);
+void CP_Mouse (void);
+void CP_Joystick (void);
+void CP_Special (void);
+void CP_OrderInfo( void );
+
+void DefineMouseBtns1 (void);
+void DefineMouseBtns2 (void);
+void DefineKeyBtns1 (void);
+void DefineKeyBtns2 (void);
+void DefineKeyMove1 (void);
+void DefineKeyMove2 (void);
+void DefineJoyBtns1 (void);
+void DefineJoyBtns2 (void);
+void DefineSpecialBtns1 (void);
+void DefineSpecialBtns2 (void);
+
+void DrawSTMenuBuf (int x, int y, int w, int h, boolean up);
+
+void MusicVolume (void);
+void FXVolume (void);
+
+void DefineKey( void );
+void DefineJoyBtn( void );
+void DefineMouseBtn( void );
+
+void DrawControlMenu (void);
+void CP_ControlMenu (void);
+void DrawOptionsMenu (void);
+void DrawExtOptionsMenu (void);
+void CP_ExtOptionsMenu (void);
+void CP_OptionsMenu (void);
+void DrawOptionsButtons (void);
+void DrawExtOptionsButtons (void);
+void MenuFlipSpeed (void);
+void DrawDetailMenu (void);
+void CP_DetailMenu (void);
+void DrawBattleMenu (void);
+void CP_BattleMenu (void);
+void MCERROR (void);
+
+void DrawKeyboardMenu (void);
+void CP_KeyboardMenu (void);
+boolean SliderMenu( int *number, int upperbound, int lowerbound, int erasex,
+   int erasey, int erasew, int numadjust, char *blockname,
+   void (*routine) (int w), char *title, char *left, char *right );
+
+void DrawF1Help (void);
+void CP_F1Help (void);
+void CP_ScreenSize( void );
+
+void CP_ViolenceMenu (void);
+void DrawViolenceLevelMenu (void);
+void DrawViolenceLevelPWord (void);
+
+void DrawViolenceLevel (void);
+void CP_ViolenceLevel (void);
+
+void DrawPWMenu (void);
+void CP_PWMenu (void);
+
+void DrawBattleModes (void);
+void CP_BattleModes (void);
+
+void DrawBattleOptions (void);
+void CP_BattleOptions (void);
+
+void DrawGravityMenu (void);
+void CP_GravityOptions (void);
+void DrawSpeedMenu (void);
+void CP_SpeedOptions (void);
+void DrawAmmoPerWeaponMenu (void);
+void CP_AmmoPerWeaponOptions (void);
+void DrawHitPointsMenu (void);
+void CP_HitPointsOptions (void);
+void DrawSpawnControlMenu (void);
+void DrawSpawnControlButtons (void);
+void CP_SpawnControlOptions (void);
+void DrawLightLevelMenu (void);
+void CP_LightLevelOptions (void);
+void DrawPointGoalMenu (void);
+void CP_PointGoalOptions (void);
+void DrawDangerMenu (void);
+void CP_DangerOptions (void);
+void DrawTimeLimitMenu (void);
+void CP_TimeLimitOptions (void);
+void PrintBattleOption( boolean inmenu, int x, int y, char *text );
+
+void CP_OnePlayerWarningMessage( void );
+
+void DrawMultiPageCustomMenu( char *title, void ( *redrawfunc )( void ) );
+
+#endif

Added: tags/rott-1.1/rott/_rt_msg.h
===================================================================
--- tags/rott-1.1/rott/_rt_msg.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_msg.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,25 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_msg_private
+#define _rt_msg_private
+
+#define MESSAGETIME (35*6)
+
+#endif

Added: tags/rott-1.1/rott/_rt_net.h
===================================================================
--- tags/rott-1.1/rott/_rt_net.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_net.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,122 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_net_private
+#define _rt_net_private
+
+#define DEMOBUFFSIZE 50000
+
+#define FASTSPEED (0xB000)
+
+#define SETUPTIME     15
+
+#define PlayerCommand(player,command)    \
+        (PlayerCmds[(player)]->Commands[(command)])
+
+#define ClientCommand(player,command)    \
+        (ClientCmds[(player)]->Commands[(command)])
+
+#define LocalCommand(command)    \
+        (LocalCmds->Commands[(command)])
+
+#define ServerCommand(command)    \
+        (ServerCmds->Commands[(command)])
+
+#define CommandAddress(time)    \
+        (((time)-controlupdatestartedtime) & (MAXCMDS-1))
+
+#define NextLocalCommand()    \
+        (LocalCommand(CommandAddress(controlupdatetime)))
+
+#define NextServerCommand()    \
+        (ServerCommand(CommandAddress(serverupdatetime)))
+
+#define ClientTimeCommand(which,whichtime)    \
+        (ClientCmds[(which)]->Commands[(CommandAddress((whichtime)))])
+
+#define ServerCommandStatus(whichtime)    \
+        (CommandState[0]->CommandStates[(CommandAddress((whichtime)))])
+
+#define ServerCommandNumberStatus(command)    \
+        (CommandState[0]->CommandStates[(command)])
+
+#define ClientCommandStatus(which, whichtime)    \
+        (CommandState[(which+1)]->CommandStates[(CommandAddress((whichtime)))])
+
+#define ClientCommandNumberStatus(which, command)    \
+        (CommandState[(which+1)]->CommandStates[(command)])
+
+/*
+#define PacketAddress(time)    \
+        ((time) & (MAXCMDS-1))
+*/
+
+#define PacketAddress(time)    \
+        (time)
+
+
+#define NETWORKTIMEOUT  (VBLCOUNTER/3)
+#define MODEMTIMEOUT    (VBLCOUNTER/2)
+#define SERVERTIMEOUT    (VBLCOUNTER<<3)
+
+#define MAXPOLLTICS 3
+
+
+typedef enum {
+   scfp_nodata,
+   scfp_gameready,
+   scfp_data,
+   scfp_done
+} setupcheckforpacketstate;
+
+typedef enum {
+   cs_ready,
+   cs_notarrived,
+   cs_fixing
+} en_CommandStatus;
+
+typedef enum {
+   player_ingame,
+   player_quitgame,
+   player_leftgame
+} en_playerstatus;
+
+void PreparePacket (MoveType * pkt);
+int  GetPacketSize (void * pkt);
+void SendPacket (void * pkt, int dest);
+void GetRemotePacket (int from, int delay);
+void ResendLocalPackets  (int time, int dest, int numpackets);
+void ResendServerPackets (int time, int dest, int numpackets);
+void ResendPacket (void * pkt, int dest);
+void AddClientDelta (void * pkt, int src);
+void FixupPacket (void * pkt, int src);
+void ProcessPacket (void * pkt, int src);
+void AddServerPacket(void * pkt, int src);
+void AddClientPacket (void * pkt, int src);
+void AddPacket (void * pkt, int src);
+void RequestPacket (int time, int dest, int numpackets);
+boolean AllPlayersReady ( void );
+boolean AreClientsReady ( void );
+boolean IsServerCommandReady ( int time );
+void UpdatePlayerObj ( int player );
+void AddServerSubPacket(COM_ServerHeaderType * serverpkt);
+void AddSubPacket (void * pkt, int src);
+
+
+#endif

Added: tags/rott-1.1/rott/_rt_play.h
===================================================================
--- tags/rott-1.1/rott/_rt_play.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_play.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,125 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_playr_private
+#define _rt_playr_private
+
+#include "watcom.h"
+//double dTopYZANGLELIMIT; in winrott.c
+#define TopYZANGLELIMIT  (44*FINEANGLES/360)//bna added
+#define YZANGLELIMIT  (80*FINEANGLES/360)//bna--(30*FINEANGLES/360)
+/*
+//bna++ had to limit this or the sky would fuck up 
+#define TopYZANGLELIMIT  (6*FINEANGLES/360)//bna added
+#define YZANGLELIMIT  (40*FINEANGLES/360)//bna--(30*FINEANGLES/360)
+//partly fixed you can now se up but not down very much see rt_playr.c TopYZANGLELIMIT
+*/
+
+
+#define YZTILTSPEED   20*4//*2 = bna added
+#define SNAPBACKSPEED 10*15//*2 = bna added
+#define YZHORIZONSPEED 4*5//*2 = bna added
+#define HORIZONYZOFFSET (FINEANGLES/4)
+#define SetPlayerHorizon(ps,hlevel)    \
+    {                                  \
+    if ((hlevel)>YZANGLELIMIT)           \
+       (ps)->horizon=HORIZONYZOFFSET+YZANGLELIMIT;\
+    else if ((hlevel)<-YZANGLELIMIT)     \
+       (ps)->horizon=HORIZONYZOFFSET-YZANGLELIMIT;\
+    else                                  \
+       (ps)->horizon=HORIZONYZOFFSET+(hlevel);\
+	 }
+
+#define StartWeaponChange \
+{\
+ SD_PlaySoundRTP(SD_SELECTWPNSND,ob->x,ob->y);\
+ pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;\
+ if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )\
+	 DrawBarAmmo (false);            \
+}
+
+
+#define BULLETHOLEOFFSET 0x700
+
+#define M_DIST(x1,x2,y1,y2)   (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
+
+#define W_CHANGE(x)   ((x->weapondowntics) || (x->weaponuptics))
+#define NOMOM         ((!ob->momentumx) && (!ob->momentumy))
+#define DISTOK(p1,p2,d)    (abs((p1)-(p2)) <= d)
+#define Fix(a)        (a &= (FINEANGLES-1))
+#define REMOTEPKTSIZE    (sizeof(MoveType))
+#define BJRUNSPEED   2048
+#define BJJUMPSPEED  680
+#define PROJECTILESIZE 0xc000l
+
+#define MOVESCALE       150l
+#define BACKMOVESCALE   100l
+#define EXTRAPOINTS     40000
+#define JETPACKTHRUST (64)
+
+#define RUNMOVE      0xa00
+#define BASEMOVE     0x600
+#define ANGLEMOVE    0x100000
+
+#define SGN(x)                 (x>0 ? 1 : -1)
+#define NETMOM    (BASEMOVE+0x10000)
+
+#define DISTANCE(x1,x2,y1,y2)   (FixedMulShift((x1-x2),(x1-x2),16)+FixedMulShift((y1-y2),(y1-y2),16))
+
+#define TILTLIMIT     95
+#define PLAYERSTEPTIME 0xf000
+
+#define HITWALLSPEED  0x2800
+#define GODVIEWANGLE  FINEANGLES/150
+#define GODOFFSET     10
+#define DOGOFFSET     46
+#define KESTICS       70
+#define BBTIME        105
+
+#define KEYBOARDNORMALTURNAMOUNT (0x160000)
+//#define KEYBOARDPREAMBLETURNAMOUNT (0xe0000)
+#define KEYBOARDPREAMBLETURNAMOUNT (0xa0000)
+#define TURBOTURNTIME      (5)
+#define TURBOTURNAMOUNT    (0x1e000)
+#define TURNAROUNDSPEED   ((ANG180<<16)/15)
+
+#define VR_INPUT_SERVICE (0x30)
+#define VR_FEEDBACK_SERVICE (0x31)
+
+#define VR_RUNBUTTON         (0)
+#define VR_STRAFELEFTBUTTON  (1)
+#define VR_STRAFERIGHTBUTTON (2)
+#define VR_ATTACKBUTTON      (3)
+#define VR_LOOKUPBUTTON      (4)
+#define VR_LOOKDOWNBUTTON    (5)
+#define VR_SWAPWEAPONBUTTON  (6)
+#define VR_USEBUTTON         (7)
+#define VR_HORIZONUPBUTTON   (8)
+#define VR_HORIZONDOWNBUTTON (9)
+#define VR_MAPBUTTON         (10)
+#define VR_PISTOLBUTTON      (11)
+#define VR_DUALPISTOLBUTTON  (12)
+#define VR_MP40BUTTON        (13)
+#define VR_MISSILEWEAPONBUTTON (14)
+#define VR_RECORDBUTTON      (15)
+
+#define STEPADJUST 3
+void BatAttack(objtype*ob);
+void  T_DogLick (objtype *ob);
+#endif

Added: tags/rott-1.1/rott/_rt_rand.h
===================================================================
--- tags/rott-1.1/rott/_rt_rand.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_rand.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,291 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_rand_private
+#define _rt_rand_private
+
+//****************************************************************************
+//
+// Private header for RT_RAND.C
+//
+//****************************************************************************
+
+#define SIZE_OF_RANDOM_TABLE   2048
+
+static const unsigned char RandomTable[ SIZE_OF_RANDOM_TABLE ] =
+   {
+   107,   65,  179,   81,  212,    1,   34,  230,
+   167,  142,   82,   27,   62,   88,  140,  119,
+   222,  252,  254,  160,   26,   33,   30,  234,
+   162,  216,  126,   42,   20,  108,  245,  150,
+   167,  145,  215,  226,  153,  184,  251,  141,
+   116,  225,  201,  114,  111,   92,  223,  185,
+   199,  160,  244,  190,  113,   77,  217,  239,
+    15,  239,  129,  243,   21,  242,  202,  183,
+    49,  151,   38,   38,  147,  179,  234,  130,
+   138,  110,  228,  118,   93,   81,  253,   98,
+   246,   44,   75,  161,  189,   86,   85,  204,
+   169,   95,  199,  178,  186,  123,  200,  250,
+   118,  242,   86,   48,    7,  205,   71,  132,
+   185,  214,  192,   68,  191,  236,  175,  197,
+   199,  177,  163,   57,  220,  139,  133,  182,
+    91,  196,  246,   29,  177,   82,  184,  226,
+   209,  151,  206,  250,  195,  119,  193,  235,
+   144,  146,   58,   61,  245,   83,  204,  214,
+   249,  164,  212,  172,   90,  199,  242,  182,
+   228,  159,  127,   37,  209,  165,   89,  122,
+    87,  254,  222,   43,  148,  205,  155,  230,
+    74,  127,  238,  181,  154,  170,  232,   47,
+   105,   31,   96,  166,  208,    5,  201,   73,
+   244,   67,   55,  168,   84,  221,  251,   85,
+    44,  198,    8,   35,  229,  122,  229,   80,
+   137,   28,  202,  135,  211,   69,  100,  250,
+   224,  156,   75,  128,  176,   53,  207,  157,
+   241,  216,  210,  124,  163,  248,  223,  174,
+   241,  235,   97,  120,   25,    3,  218,  102,
+   143,  187,  202,  116,  209,  253,  227,  151,
+   203,  254,  223,   65,  146,  255,  231,  237,
+   162,  187,  194,   90,  198,   81,  219,   94,
+    70,  158,  106,  175,   81,  239,  181,   79,
+    62,  184,   21,   30,   98,  245,  233,    8,
+    57,   54,  133,   95,   43,  125,  161,  109,
+   167,  130,   32,   46,   72,    3,   42,   34,
+   147,  139,   19,  122,   49,   23,  253,  192,
+   231,  116,  165,    8,   15,   16,  223,  140,
+    29,  136,    2,  114,  248,  219,  214,  168,
+    36,  241,  210,   63,  230,   42,  197,  100,
+   134,  159,  179,  149,   17,   96,  152,   45,
+    93,  151,   26,  202,   35,   58,  189,  220,
+    74,  173,  250,   76,   57,   52,   55,   14,
+   205,   80,  213,  190,   14,  108,   60,   89,
+   236,   41,   53,   59,  249,  237,   88,  217,
+   129,  252,  169,  123,   87,   23,   91,   79,
+    36,  164,   89,   24,  102,  111,  104,  115,
+   116,  221,  212,   82,  166,   16,  244,   18,
+    68,   73,   64,  194,   82,  115,  121,  216,
+   133,   47,   85,  124,  242,  144,    1,   65,
+     0,   75,   91,   83,  137,  183,  132,   15,
+    66,  227,   67,   98,  186,  100,  208,  150,
+    74,   61,   69,  130,  120,   56,   39,   21,
+    44,  166,  180,  145,   97,  101,   68,   19,
+   243,  162,  222,  228,    9,  160,  185,   10,
+   168,   64,  109,  198,  113,   75,   48,   52,
+   119,  163,  176,  201,   12,  246,   20,   92,
+    31,  175,   33,    4,   70,  169,  218,   86,
+   240,  127,    7,   38,  102,   94,  112,   90,
+   114,   63,  139,  119,   45,    5,  183,  224,
+   155,   13,  141,   90,   93,  177,  118,   67,
+   211,  117,   58,  158,  135,   83,  236,  194,
+    72,   59,  131,   40,  196,  232,  247,  132,
+    18,   73,   37,  207,   50,  187,   32,  174,
+    13,   34,  135,   39,   46,  192,   51,  203,
+   216,    3,  188,   99,  245,  112,   61,  206,
+   127,  118,  136,  186,  153,  148,  140,  106,
+    55,  201,   19,    9,   27,   97,   84,   24,
+    48,  227,  108,  202,    5,  190,    6,  235,
+   160,  146,  123,  222,  212,  147,   27,   28,
+    50,  226,  200,  221,  180,  244,   34,  146,
+    41,  104,   37,  217,   10,  238,   52,  198,
+     4,   29,  126,   16,   45,  124,   64,   25,
+    40,   20,  138,  225,   71,  247,  128,   62,
+    62,  178,   31,  251,  197,  215,  226,  193,
+    28,   25,   82,   15,   21,   43,   30,   86,
+    50,   99,  199,  191,   80,  171,  250,    4,
+   149,   61,  163,  128,  143,   95,   76,   56,
+    14,  109,   54,   84,  137,   43,   77,  255,
+   204,  151,  129,    8,   20,   26,  193,   38,
+   205,  125,  203,   22,   78,   47,  101,   37,
+   121,  113,  141,   36,   33,   23,  131,   55,
+    78,   96,  123,  228,   69,  213,   51,  147,
+   195,  195,   85,   54,  225,   65,  143,   13,
+   152,   60,  110,   29,  146,  179,  164,   17,
+    96,   67,  156,    7,    3,   92,   26,  104,
+   157,  220,  211,  154,  103,    2,  174,  136,
+    83,  229,   18,  116,   66,   87,    0,   74,
+    98,   58,   75,  162,  254,  177,   89,  173,
+   169,  107,   12,   90,   71,  193,   53,  255,
+   138,    2,  233,  163,   11,  138,  183,  209,
+   119,  210,  249,  112,  113,   30,  185,  180,
+    11,  171,  164,   77,    5,   99,   35,  218,
+    11,  159,  221,  148,  170,  137,  129,  188,
+   231,  172,  191,  135,  176,   33,  189,   68,
+   190,  152,    7,  220,  246,  203,  181,   63,
+   199,   91,  251,  208,  217,   39,  170,  111,
+   182,  209,  216,  247,  240,  165,  153,  118,
+   238,  233,  204,   12,  126,  105,  168,  234,
+    38,  184,  132,  110,  145,  227,  165,   92,
+   241,   24,  251,  231,  213,  126,  240,  214,
+    31,   11,  223,   46,    0,   35,  218,  242,
+   211,  191,   48,  110,  253,   94,  161,  139,
+    42,  148,  198,  246,  239,  107,   57,    5,
+   117,  252,    9,   12,   73,   77,   58,  167,
+     6,  142,   32,   34,   72,   31,  243,  170,
+     0,   93,  182,   56,  254,  158,  250,   23,
+    77,   81,   45,   69,  142,  237,  225,   44,
+   232,  142,  209,  115,   61,   38,  224,   70,
+    53,   82,   10,  229,  214,  224,  101,   42,
+   100,  121,  133,   85,   67,  150,  116,   91,
+    79,   79,  235,   22,    1,  244,   16,  101,
+    88,   25,   43,  242,   53,  106,  128,   40,
+    18,    2,  196,   22,   47,   96,  130,  249,
+    49,  117,  178,  171,  132,  189,   95,   66,
+   153,  200,   71,   71,  215,  113,  102,  131,
+   172,  235,  192,  204,  107,  127,   60,   52,
+   254,   84,   20,   27,  107,   44,   72,  149,
+   230,   87,   64,  144,  140,  186,  154,   49,
+    76,  156,  162,  219,    9,  146,   41,   80,
+    59,  142,  147,  184,  115,  158,  103,  140,
+     8,  234,  157,   17,  112,   22,  163,  187,
+    47,  178,  207,   63,  125,  202,  156,   30,
+    97,  193,  171,  173,  204,   28,    4,  195,
+   109,  211,  105,  103,  179,  221,  203,  138,
+   139,  172,   14,   44,  119,  150,  185,  180,
+   205,  255,  152,   94,  205,  173,   40,  134,
+    13,   65,  194,  196,   68,  124,   26,  134,
+    85,  228,   50,  216,  159,  254,  237,  206,
+   103,   69,   90,  187,  182,  183,    2,  114,
+     3,  201,    1,  129,  212,  232,   81,   33,
+    56,  182,  133,  176,   19,    6,  144,   84,
+   145,   24,  243,  234,   35,   25,   89,  150,
+    54,  143,  207,  104,  248,  102,   41,  253,
+    46,   44,  197,  208,  200,   52,  219,  238,
+   223,  241,   60,  230,  196,   42,   88,   51,
+   170,   25,   40,  114,   39,   45,   57,   29,
+   186,   54,   36,  167,   51,  249,  194,  108,
+   250,  199,   67,  212,  123,  151,   92,   32,
+    46,   12,  248,  165,  223,   24,  143,  189,
+   120,   57,   38,  222,  169,   17,  188,   27,
+   209,  176,  215,  108,  177,   96,   50,  154,
+    41,   15,   32,  181,   99,  120,   73,  225,
+    49,  200,   43,  177,   72,  202,   97,   92,
+   240,  110,  252,   21,   28,  192,   70,  128,
+    85,   60,  127,   63,  235,  100,  155,   65,
+   241,  119,   34,   80,   75,  117,  148,  102,
+    15,   90,  121,  206,  104,  164,  132,   98,
+    36,  108,  214,    0,   84,   94,  107,  154,
+    14,   26,   23,   93,  195,  224,  162,  171,
+   245,   76,  125,  158,  120,   66,   80,  130,
+   183,  120,  179,  118,   31,  176,  106,  184,
+   164,  111,   59,  253,  118,   62,  114,  215,
+   156,  161,  127,  210,  112,  122,  204,   86,
+    29,   69,  187,  218,  233,   47,  188,   91,
+   105,  153,  236,  116,  135,   19,   83,  175,
+    88,  166,  156,  238,  245,  227,  248,  161,
+    10,  180,   22,  230,  157,  205,    6,   37,
+     3,  234,  155,   49,  239,  229,  122,  223,
+   234,  206,   82,  135,  190,   77,  130,  197,
+   144,  226,  123,  181,  143,  208,  169,    8,
+     1,  174,   97,  177,  232,  201,  210,  193,
+   192,   62,  211,   28,  252,   19,  189,  229,
+   191,  246,    7,  202,   35,   20,   28,   30,
+    70,  221,   55,  159,  237,   10,   15,  134,
+   124,  103,   73,  172,   26,  201,   13,  117,
+    35,  131,  136,   66,   33,  245,  159,  207,
+   225,  147,   18,  248,  126,  131,   33,  153,
+   101,   60,  186,  216,  250,   11,   30,   50,
+    57,   58,  151,  178,  181,  227,  128,  253,
+    10,    5,  224,   48,  160,   34,    7,  111,
+   124,   27,  160,   75,  137,   17,   53,   39,
+   243,  236,   39,   81,  217,  122,   79,   32,
+    13,  115,  191,  167,  137,   87,  228,   91,
+    86,   78,   18,   22,   40,   76,   94,  129,
+   119,   87,   63,  197,  203,   21,  218,  185,
+   166,   49,  161,  213,   38,  111,  209,  154,
+    43,  152,  134,  132,    4,  133,  108,   83,
+   145,   41,   97,   74,  251,  173,   42,  213,
+    46,  118,   73,   68,   21,  244,  106,  158,
+    11,   90,  252,  140,   44,  157,  194,   66,
+   229,   58,  215,  251,  144,  125,  146,  172,
+   165,  136,  105,  102,  173,   95,  150,  169,
+    78,  230,  111,  160,  196,  112,  120,  231,
+   168,  152,  149,  174,  128,  232,  194,  122,
+     3,   74,  231,  105,   12,  239,  180,  239,
+    89,  235,   95,  157,  149,  187,    6,  203,
+   188,   71,  110,    8,  126,  242,  188,  249,
+    71,  123,  162,   93,   59,   65,   16,  222,
+   192,   24,   27,  142,  168,  114,   89,  220,
+   226,  182,  207,   94,  195,  207,  174,  228,
+   142,  130,  115,  175,  154,  106,  206,   48,
+   185,  147,  155,  224,  239,   64,   88,   83,
+    54,  247,  113,  248,  137,   96,    5,  110,
+   240,   51,    1,  208,  166,  200,  233,  167,
+   230,   14,   20,  198,   36,   13,    0,  220,
+   165,  104,   85,  122,    1,  255,  212,  161,
+   190,   37,   86,  226,  195,  105,   78,  244,
+   236,  168,   48,  211,  121,  216,   25,  144,
+    16,  237,    7,   75,   12,   99,   56,  109,
+   218,   87,   35,  204,  155,   61,  191,   41,
+    61,   57,  121,  236,   62,   22,  187,   95,
+    92,   69,  210,  163,  205,  214,   34,   84,
+    73,  184,  109,  124,  231,  103,  217,  241,
+    77,  175,  183,  232,  198,  164,   14,  125,
+   103,  197,  249,  241,  176,   59,   48,   50,
+    25,  222,  134,  199,  252,  196,   23,   19,
+    78,    0,   59,  120,   91,  121,  117,  228,
+    52,   68,  113,  127,  141,   67,   65,  130,
+   132,  243,  160,  138,  138,  116,   10,   98,
+   170,   70,  246,  206,  219,   28,   94,  226,
+    29,   58,  255,   31,  141,   82,  134,  152,
+   251,   84,   52,   23,  154,  139,   74,   55,
+    47,  198,  167,  162,    4,   16,  220,   53,
+    37,  158,  135,  136,  190,   86,  151,  178,
+   238,  161,   88,  171,  148,  169,  137,  212,
+   181,  146,  189,   70,   49,   79,  142,  131,
+   195,  126,  149,  156,   93,   55,  164,  174,
+    87,  243,   66,   92,  207,    9,  126,  123,
+    40,   51,  133,  143,    9,   55,  193,  173,
+    56,   64,  210,  159,    6,  178,  145,  153,
+   115,  215,  185,  238,  101,  210,   98,  157,
+    95,  171,  235,  217,  240,  232,  107,   53,
+    54,  211,  111,  236,  100,   37,  147,   64,
+    60,  215,  174,  136,  128,   98,   79,  234,
+   145,   76,  197,  165,  191,  141,  114,  109,
+   148,  214,   93,   12,  163,  125,  222,   96,
+    71,  220,    8,  225,  200,   14,  139,  166,
+   155,    9,  237,    9,  172,    6,  229,  179,
+   247,   76,   24,  213,   26,  248,   56,  247,
+   106,  221,   63,   20,  206,  231,  168,  196,
+   208,   36,   31,  175,  178,  255,  124,  156,
+   129,  186,   45,  201,    7,  112,  189,   68,
+   225,   64,  150,   74,    2,  218,   62,  159,
+     4,   11,  213,   40,   23,   15,   67,   52,
+   182,  203,  246,  194,   72,   33,   89,  104,
+    16,  131,   60,  150,  243,   21,   59,  175,
+   219,  149,   56,  224,   32,  105,  153,   99,
+    80,  148,  107,   99,  108,   43,  106,   41,
+    32,  244,    4,  186,  253,   27,  233,  104,
+   245,    5,    2,  252,  170,    2,  101,   39,
+    17,  166,  221,   11,  227,  129,  103,   45,
+   144,   79,   17,  139,   70,  237,  176,    6,
+    76,  134,   54,   30,   69,   13,  100,  149,
+   141,  227,  255,   22,  179,   61,   88,   97,
+   121,   29,   24,   77,  170,  190,  242,  109,
+   152,   47,   81,  140,   45,   46,  249,   78,
+   180,  143,  102,   19,  208,  177,   72,   72,
+   247,   51,  115,    3,  141,  117,   39,  188,
+   180,  171,   83,    1,    0,   51,  100,  112,
+   172,   18,  219,  136,  155,  125,  200,  131,
+   157,  217,   78,   63,  213,  238,  193,  173,
+   145,   46,  101,  158,   42,  140,  110,   66,
+   183,  181,  233,  188,   10,  133,   36,  135,
+    17,  254,  138,  233,  117,  240,  184,   80,
+   113,   18,   99,  219,  240,   50,  192,  247
+   };
+
+#endif

Added: tags/rott-1.1/rott/_rt_scal.h
===================================================================
--- tags/rott-1.1/rott/_rt_scal.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_scal.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,25 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_scale_private
+#define _rt_scale_private
+
+#define PLAYERHEIGHT (260<<HEIGHTFRACTION)
+
+#endif

Added: tags/rott-1.1/rott/_rt_soun.h
===================================================================
--- tags/rott-1.1/rott/_rt_soun.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_soun.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,114 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_sound_private
+#define _rt_sound_private
+
+#define SOUNDTYPES 2
+
+typedef struct
+{
+   int     snds[SOUNDTYPES];
+   byte    flags;
+   byte    priority;
+   byte    count;
+   int     prevhandle;
+   int     prevdistance;
+} sound_t;
+
+#define SD_OVERWRITE  0x01
+#define SD_WRITE      0x02
+#define SD_LOOP       0x04
+#define SD_PITCHSHIFTOFF 0x08
+#define SD_PLAYONCE      0x10
+
+enum {
+   sd_prio0=17,
+   sd_prio1=16,
+   sd_prio2=15,
+   sd_prio3=14,
+   sd_prio4=13,
+   sd_prio5=12,
+   sd_prio6=11,
+   sd_prio7=10,
+   sd_prio8=9,
+   sd_prio9=8,
+   sd_prio10=7,
+   sd_prio11=6,
+   sd_prio12=5,
+   sd_prio13=4,
+   sd_prio14=3,
+   sd_prio15=2,
+   sd_prio16=1
+} ;
+
+#define SD_PRIOSECRET sd_prio1
+#define SD_PRIOREMOTE sd_prio1
+#define SD_PRIOPHURT  sd_prio1
+#define SD_PRIOGAME   sd_prio2
+#define SD_PRIOBOSS   sd_prio2
+#define SD_PRIOGODDOG sd_prio2
+#define SD_PRIOEXPL   sd_prio3
+#define SD_PRIOASNEAK sd_prio3
+#define SD_PRIOADEATH sd_prio3
+#define SD_PRIOPMISS  sd_prio4
+#define SD_PRIOPGUNS  sd_prio5
+#define SD_PRIOAFIRE  sd_prio6
+#define SD_PRIOPMP40  sd_prio7
+#define SD_PRIOAHURT  sd_prio8
+#define SD_PRIOGLASS  sd_prio9
+#define SD_PRIOPSNDS  sd_prio11
+#define SD_PRIOPCAUSD sd_prio12
+#define SD_PRIOAGREET sd_prio13
+#define SD_PRIOENVRON sd_prio14
+#define SD_PRIOQUIT   sd_prio15
+#define SD_PRIOMENU   sd_prio16
+
+#define SD_DISTANCESHIFT 12
+
+#define USEADLIB 255
+
+#define SD_RANDOMSHIFT 1
+
+#define PitchOffset()  ((RandomNumber("Pitch Offset",0)-128)>>SD_RANDOMSHIFT)
+
+#define SoundOffset(x) (sounds[x].snds[soundtype])
+
+#define GUSMIDIINIFILE ("gusmidi.ini")
+
+
+typedef enum {
+   loop_yes,
+   loop_no
+} looptypes;
+
+
+typedef struct
+{
+   byte    loopflag;
+   byte    songtype;
+   char    lumpname[9];
+   char    songname[40];
+} song_t;
+
+int SD_PlayIt ( int sndnum, int angle, int distance, int pitch );
+boolean SD_SoundOkay ( int sndnum );
+
+#endif
+

Added: tags/rott-1.1/rott/_rt_spba.h
===================================================================
--- tags/rott-1.1/rott/_rt_spba.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_spba.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,27 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_spba_private
+#define _rt_spba_private
+
+#define SGN(x)                 (x>0 ? 1 : -1)
+
+#define NUMSPACEBALLBUTTONS 6
+
+#endif

Added: tags/rott-1.1/rott/_rt_stat.h
===================================================================
--- tags/rott-1.1/rott/_rt_stat.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_stat.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,58 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_stat_private
+#define _rt_stat_private
+
+void        AddStatic(statobj_t*);
+void        AddAnimStatic(statobj_t*);
+void        PreCacheStaticSounds(int);
+
+#define SOLIDCOLORTICTIME   1
+#define SOLIDCOLORINCREMENT 1
+#define MAXFIRECOLOR      248
+#define INITIALFIRECOLOR  246
+#define IsLight(x,y)          ( (x>=0) && (x<=127) && (y>=0) && (y<=127) &&   \
+										  (sprites[x][y]) && (sprites[x][y]->flags & FL_LIGHT) )
+
+typedef struct
+{
+    int  tictime,
+         numanims;
+    char firstlump[9];
+} awallinfo_t;
+
+
+typedef struct sas
+{
+  int          x,y,z;
+  int          flags;
+  signed char  ticcount;
+  int          hitpoints;
+  short int    shapenum;
+  signed char  ammo;
+  signed char  count;
+  signed char  itemnumber;
+  short int    areanumber;
+  short int    whichstat;
+  byte         numanims;
+  int          linked_to;
+}saved_stat_type;
+
+#endif

Added: tags/rott-1.1/rott/_rt_str.h
===================================================================
--- tags/rott-1.1/rott/_rt_str.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_str.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//******************************************************************************
+//
+// Private header for RT_STR.C
+//
+//******************************************************************************
+
+#ifndef _rt_str_private
+#define _rt_str_private
+
+//******************************************************************************
+//
+// PROTOTYPES
+//
+//******************************************************************************
+
+void VWB_DrawPropString  (const char *string);
+void VW_MeasurePropString (const char *string, int *width, int *height );
+
+//void (*USL_MeasureString)(const char *, int *, int *, font_t *) = VW_MeasurePropString,
+//     (*USL_DrawString)(const char *) = VWB_DrawPropString;
+void (*USL_MeasureString)(const char *, int *, int *, font_t *) = (void (*)(const char *, int *, int *, font_t *))VW_MeasurePropString,
+     (*USL_DrawString)(const char *) = VWB_DrawPropString;
+
+
+#endif

Added: tags/rott-1.1/rott/_rt_swft.h
===================================================================
--- tags/rott-1.1/rott/_rt_swft.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_swft.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,109 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_swift_private
+#define _rt_swift_private
+
+#ifdef DOS
+//****************************************************************************
+//
+// Private header for RT_SWIFT.C.
+//
+//****************************************************************************
+
+
+
+//****************************************************************************
+//
+// DEFINES
+//
+//****************************************************************************
+
+#define DPMI_INT     0x31
+#define MOUSE_INT    0x33
+#define DOSMEMSIZE   64                // enough for any SWIFT structure
+
+//
+// device type codes, returned in deviceType field (SWIFT_StaticData)		
+//
+#define SWIFT_DEV_NONE		0
+#define SWIFT_DEV_CYBERMAN	1
+
+//
+// Dynamic device data
+//
+#define SDD_EXTERNAL_POWER_CONNECTED	1
+#define SDD_EXTERNAL_POWER_TOO_HIGH	   2
+
+#define AX(r) ((r).x.eax)
+#define BX(r) ((r).x.ebx)
+#define CX(r) ((r).x.ecx)
+#define DX(r) ((r).x.edx)
+#define SI(r) ((r).x.esi)
+#define DI(r) ((r).x.edi)
+
+
+//****************************************************************************
+//
+// TYPEDEFS
+//
+//****************************************************************************
+
+                                          // Active flag:
+static int fActive;                       //  TRUE after successful init
+                                          //  and before termination
+static int nAttached = SWIFT_DEV_NONE;    // type of SWIFT device
+
+union REGS regs;
+struct SREGS sregs;
+
+short selector;                           // selector of DOS memory block
+short segment;                            // segment of DOS memory block
+void far *pdosmem;                        // pointer to DOS memory block
+
+// DPMI real mode interrupt structure
+static struct rminfo
+{
+    long di;
+    long si;
+    long bp;
+    long reserved_by_system;
+    long bx;
+    long dx;
+    long cx;
+    long ax;
+    short flags;
+    short es, ds, fs, gs, ip, cs, sp, ss;
+} RMI;
+
+
+//****************************************************************************
+//
+// PROTOTYPES
+//
+//****************************************************************************
+
+void MouseInt (struct rminfo *prmi);
+static void far *allocDOS (unsigned nbytes, short *pseg, short *psel);
+static void freeDOS (short sel);
+
+#endif
+
+#endif
+

Added: tags/rott-1.1/rott/_rt_ted.h
===================================================================
--- tags/rott-1.1/rott/_rt_ted.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_ted.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,103 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_ted_private
+#define _rt_ted_private
+
+#define  MAXPRECACHE    3500
+
+#include "rt_actor.h"
+#include "develop.h"
+
+#define SHAREWARE_TAG     0x4d4b
+#define REGISTERED_TAG    0x4344
+#define RTL_VERSION       ( 0x0101 )
+#define COMMBAT_SIGNATURE ( "RTC" )
+#define NORMAL_SIGNATURE  ( "RTL" )
+#define RTL_HEADER_OFFSET 8
+
+typedef struct
+{
+	int  lump;
+	int  cachelevel;
+	int  type; // To make precaching possible on big endian machines
+} cachetype;
+
+//========================================
+
+typedef struct
+{
+        short   RLEWtag;
+        int             headeroffsets[100];
+        byte            tileinfo[1];
+} mapfiletype;
+
+
+typedef struct
+{
+        int   planestart[3];
+        word  planelength[3];
+        word  width,height;
+        char            name[16];
+} maptype;
+
+#define ActorIsPushWall(xx,yy)   ((actorat[xx][yy])&&(((objtype *)actorat[xx][yy])->which==PWALL) )
+#define ActorIsWall(xx,yy)   ((actorat[xx][yy])&&(((objtype *)actorat[xx][yy])->which==WALL) )
+#define ActorIsSpring(xx,yy)   ((actorat[xx][yy])&&(((objtype *)actorat[xx][yy])->obclass==springobj) )
+#define StaticUndefined(xx,yy)   ((sprites[xx][yy])&&(((statobj_t *)sprites[xx][yy])->z<-64) )
+
+#define  PRECACHEASTRINGX 141
+#define  PRECACHEASTRINGY 8
+
+#define  PRECACHEESTRINGX 16
+#define  PRECACHEESTRINGY 8
+
+#define  PRECACHESTRINGX 16
+#define  PRECACHESTRINGY 144
+
+#define  PRECACHEBARX 28
+#define  PRECACHEBARY 178
+
+#define  PRECACHELED1X 9
+#define  PRECACHELED1Y 8
+
+#define  PRECACHELED2X 9
+#define  PRECACHELED2Y 12
+
+#define  MAXLEDS 57
+
+#define  MAXSILLYSTRINGS 32
+
+#if (SHAREWARE==0)
+   #define  STANDARDGAMELEVELS   (DATADIR "DARKWAR.RTL")
+   #if (SUPERROTT==1)
+       #define  STANDARDBATTLELEVELS (DATADIR "ROTTCD.RTC")
+   #elif (SITELICENSE==1)
+       #define  STANDARDBATTLELEVELS (DATADIR "ROTTSITE.RTC")
+   #else
+       #define  STANDARDBATTLELEVELS (DATADIR "DARKWAR.RTC")
+   #endif
+#else
+   #define  STANDARDGAMELEVELS   (DATADIR "HUNTBGIN.RTL")
+   #define  STANDARDBATTLELEVELS (DATADIR "HUNTBGIN.RTC")
+#endif
+
+
+
+#endif

Added: tags/rott-1.1/rott/_rt_util.h
===================================================================
--- tags/rott-1.1/rott/_rt_util.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_util.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_util_private
+#define _rt_util_private
+
+#ifdef DOS
+#define PEL_WRITE_ADR   0x3c8
+#define PEL_READ_ADR    0x3c7
+#define PEL_DATA        0x3c9
+#define PEL_MASK        0x3c6
+#endif
+
+#define ERRORROW        2
+#define ERRORCOL        11
+
+#define ERRORFILE       ("rotterr.txt")
+#define SOFTERRORFILE   ("error.txt")
+#define DEBUGFILE       ("rott.dbg")
+#define MAPDEBUGFILE    ("mapinfo.txt")
+
+#define SGN(x)          ((x>0) ? (1) : ((x==0) ? (0) : (-1)))
+
+#define SLASHES         ('\\')
+#define MAXCHARS        8
+
+#define WeightR  3
+#define WeightG  5
+#define WeightB  2
+
+#endif

Added: tags/rott-1.1/rott/_rt_vid.h
===================================================================
--- tags/rott-1.1/rott/_rt_vid.h	                        (rev 0)
+++ tags/rott-1.1/rott/_rt_vid.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,45 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_vid_private
+#define _rt_vid_private
+
+//******************************************************************************
+//
+// Private header for RT_VID.C
+//
+//******************************************************************************
+
+
+//******************************************************************************
+//
+// DEFINES
+//
+//******************************************************************************
+
+#define PIXTOBLOCK         4
+
+#define VW_Hlin(x,z,y,c)   VL_Hlin(x,y,(z)-(x)+1,c)
+#define VW_Vlin(y,z,x,c)   VL_Vlin(x,y,(z)-(y)+1,c)
+
+#define VW_THlin(x,z,y,up)    VL_THlin(x,y,(z)-(x)+1, up)
+#define VW_TVlin(y,z,x,up)    VL_TVlin(x,y,(z)-(y)+1, up)
+
+
+#endif

Added: tags/rott-1.1/rott/_w_wad.h
===================================================================
--- tags/rott-1.1/rott/_w_wad.h	                        (rev 0)
+++ tags/rott-1.1/rott/_w_wad.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,76 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _w_wad_private
+#define _w_wad_private
+
+#include "develop.h"
+
+#define CHECKPERIOD 20
+
+
+#if ( SHAREWARE == 1 )
+
+#if ( DELUXE == 1)
+#define WADCHECKSUM (54748)
+#elif ( LOWCOST == 1)
+#define WADCHECKSUM (12185)
+#else
+#ifdef DOS
+#define WADCHECKSUM (45677)
+#else
+#define WADCHECKSUM (20567)
+#endif
+#endif
+
+#else
+
+#define WADCHECKSUM (24222)
+
+#endif
+
+//===============
+//   TYPES
+//===============
+
+
+typedef struct
+{
+        char            name[8];
+        int             handle,position,size;
+        int             byteswapped;
+} lumpinfo_t;
+
+
+typedef struct
+{
+        char            identification[4];              // should be IWAD
+        int             numlumps;
+        int             infotableofs;
+} wadinfo_t;
+
+
+typedef struct
+{
+        int             filepos;
+        int             size;
+        char            name[8];
+} filelump_t;
+
+#endif

Added: tags/rott-1.1/rott/_z_zone.h
===================================================================
--- tags/rott-1.1/rott/_z_zone.h	                        (rev 0)
+++ tags/rott-1.1/rott/_z_zone.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,57 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _z_zone_private
+#define _z_zone_private
+
+#include "develop.h"
+
+#define MINFRAGMENT     64
+#define DPMI_INT  0x31
+#define MAXMEMORYSIZE   9000000
+
+#define LEVELZONESIZE   250000
+
+// memory storage data types
+
+#define MEMORYPRETAG   (0x1a2b3c4d)
+#define MEMORYPOSTTAG  (0x9f8e7d6b)
+
+typedef struct memblock_s
+{
+#if (MEMORYCORRUPTIONTEST==1)
+         int     pretag;
+#endif
+         int     size;   // including the header and possibly tiny fragments
+         void    **user; // NULL if a free block
+			int     tag;    // purgelevel
+         struct memblock_s   *next, *prev;
+#if (MEMORYCORRUPTIONTEST==1)
+         int     posttag;
+#endif
+} memblock_t;
+
+typedef struct
+{
+         int     size;          // total bytes malloced, including header
+         memblock_t  blocklist; // start / end cap for linked list
+         memblock_t  *rover;
+} memzone_t;
+
+#endif

Added: tags/rott-1.1/rott/audiolib/Makefile
===================================================================
--- tags/rott-1.1/rott/audiolib/Makefile	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/Makefile	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,22 @@
+CC=gcc
+AR=ar
+RANLIB=ranlib
+CFLAGS=-g -O2
+LDLIBS=
+
+CFLAGS += $(shell sdl-config --cflags)
+LDLIBS += $(shell sdl-config --libs)
+
+OBJ=fx_man.o dsl.o ll_man.o multivoc.o mv_mix.o mvreverb.o nodpmi.o \
+	pitch.o user.o usrhooks.o
+
+audiolib.a: $(OBJ)
+	rm -rf $@
+	$(AR) rc $@ $^
+	$(RANLIB) $@
+
+clean:
+	rm -rf audiolib.a *.o
+
+distclean: clean
+	rm -rf *~

Added: tags/rott-1.1/rott/audiolib/_al_midi.h
===================================================================
--- tags/rott-1.1/rott/audiolib/_al_midi.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/_al_midi.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,174 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef ___AL_MIDI_H
+#define ___AL_MIDI_H
+
+#define NO_ADLIB_DETECTION    "NOAL"
+
+#define STEREO_DETUNE 5
+
+#define lobyte( num )   ( ( unsigned )*( ( char * )&( num ) ) )
+#define hibyte( num )   ( ( unsigned )*( ( ( char * )&( num ) ) + 1 ) )
+
+#define AL_VoiceNotFound -1
+
+#define  alFreqH     0xb0
+#define  alEffects   0xbd
+
+/* Number of slots for the voices on the chip */
+#define NumChipSlots 18
+
+#define NUM_VOICES      9
+#define NUM_CHANNELS    16
+
+#define NOTE_ON         0x2000  /* Used to turn note on or toggle note */
+#define NOTE_OFF        0x0000
+
+#define MAX_VELOCITY   0x7f
+#define MAX_OCTAVE     7
+#define MAX_NOTE       ( MAX_OCTAVE * 12 + 11 )
+#define FINETUNE_MAX   31
+#define FINETUNE_RANGE ( FINETUNE_MAX + 1 )
+
+#define PITCHBEND_CENTER 1638400
+
+#define note_off             0x80
+#define note_on              0x90
+#define poly_aftertouch      0xa0
+#define control_change       0xb0
+#define program_chng         0xc0
+#define channel_aftertouch   0xd0
+#define pitch_wheel          0xe0
+
+#define MIDI_VOLUME          7
+#define MIDI_PAN             10
+#define MIDI_DETUNE          94
+#define MIDI_ALL_NOTES_OFF   0x7B
+#define MIDI_RESET_ALL_CONTROLLERS 0x79
+#define MIDI_RPN_MSB               100
+#define MIDI_RPN_LSB               101
+#define MIDI_DATAENTRY_MSB         6
+#define MIDI_DATAENTRY_LSB         38
+#define MIDI_PITCHBEND_RPN         0
+
+enum cromatic_scale
+   {
+   C       = 0x157,
+   C_SHARP = 0x16B,
+   D_FLAT  = 0x16B,
+   D       = 0x181,
+   D_SHARP = 0x198,
+   E_FLAT  = 0x198,
+   E       = 0x1B0,
+   F_FLAT  = 0x1B0,
+   E_SHARP = 0x1CA,
+   F       = 0x1CA,
+   F_SHARP = 0x1E5,
+   G_FLAT  = 0x1E5,
+   G       = 0x202,
+   G_SHARP = 0x220,
+   A_FLAT  = 0x220,
+   A       = 0x241,
+   A_SHARP = 0x263,
+   B_FLAT  = 0x263,
+   B       = 0x287,
+   C_FLAT  = 0x287,
+   B_SHARP = 0x2AE,
+   };
+
+/* Definition of octave information to be ORed onto F-Number */
+
+enum octaves
+   {
+   OCTAVE_0 = 0x0000,
+   OCTAVE_1 = 0x0400,
+   OCTAVE_2 = 0x0800,
+   OCTAVE_3 = 0x0C00,
+   OCTAVE_4 = 0x1000,
+   OCTAVE_5 = 0x1400,
+   OCTAVE_6 = 0x1800,
+   OCTAVE_7 = 0x1C00
+   };
+
+typedef struct VOICE
+   {
+   struct VOICE *next;
+   struct VOICE *prev;
+
+   unsigned num;
+   unsigned key;
+   unsigned velocity;
+   unsigned channel;
+   unsigned pitchleft;
+   unsigned pitchright;
+   int      timbre;
+   int      port;
+   unsigned status;
+   } VOICE;
+
+typedef struct
+   {
+   VOICE *start;
+   VOICE *end;
+   } VOICELIST;
+
+typedef struct
+   {
+   VOICELIST Voices;
+   int       Timbre;
+   int       Pitchbend;
+   int       KeyOffset;
+   unsigned  KeyDetune;
+   unsigned  Volume;
+   unsigned  EffectiveVolume;
+   int       Pan;
+   int       Detune;
+   unsigned  RPN;
+   short     PitchBendRange;
+   short     PitchBendSemiTones;
+   short     PitchBendHundreds;
+   } CHANNEL;
+
+typedef struct
+   {
+   unsigned char SAVEK[ 2 ];
+   unsigned char Level[ 2 ];
+   unsigned char Env1[ 2 ];
+   unsigned char Env2[ 2 ];
+   unsigned char Wave[ 2 ];
+   unsigned char Feedback;
+   signed   char Transpose;
+   signed   char Velocity;
+   } TIMBRE;
+
+extern TIMBRE ADLIB_TimbreBank[ 256 ];
+
+static void AL_ResetVoices( void );
+static void AL_CalcPitchInfo( void );
+static void AL_SetVoiceTimbre( int voice );
+static void AL_SetVoiceVolume( int voice );
+static int  AL_AllocVoice( void );
+static int  AL_GetVoice( int channel, int key );
+static void AL_SetVoicePitch( int voice );
+static void AL_SetChannelVolume( int channel, int volume );
+static void AL_SetChannelPan( int channel, int pan );
+static void AL_SetChannelDetune( int channel, int detune );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/_blaster.h
===================================================================
--- tags/rott-1.1/rott/audiolib/_blaster.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/_blaster.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,133 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: _BLASTER.H
+
+   author: James R. Dose
+   date:   February 4, 1994
+
+   Private header for for BLASTER.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___BLASTER_H
+#define ___BLASTER_H
+
+#define VALID   ( 1 == 1 )
+#define INVALID ( !VALID )
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+#define YES ( 1 == 1 )
+#define NO  ( !YES )
+
+#define lobyte( num )   ( ( int )*( ( char * )&( num ) ) )
+#define hibyte( num )   ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
+
+#define BLASTER_MixerAddressPort  0x04
+#define BLASTER_MixerDataPort     0x05
+#define BLASTER_ResetPort         0x06
+#define BLASTER_ReadPort          0x0A
+#define BLASTER_WritePort         0x0C
+#define BLASTER_DataAvailablePort 0x0E
+#define BLASTER_Ready             0xAA
+#define BLASTER_16BitDMAAck       0x0F
+
+#define MIXER_DSP4xxISR_Ack       0x82
+#define MIXER_DSP4xxISR_Enable    0x83
+#define MIXER_MPU401_INT          0x4
+#define MIXER_16BITDMA_INT        0x2
+#define MIXER_8BITDMA_INT         0x1
+#define MIXER_DisableMPU401Interrupts 0xB
+#define MIXER_SBProOutputSetting  0x0E
+#define MIXER_SBProStereoFlag     0x02
+#define MIXER_SBProVoice          0x04
+#define MIXER_SBProMidi           0x26
+#define MIXER_SB16VoiceLeft       0x32
+#define MIXER_SB16VoiceRight      0x33
+#define MIXER_SB16MidiLeft        0x34
+#define MIXER_SB16MidiRight       0x35
+
+#define DSP_Version1xx            0x0100
+#define DSP_Version2xx            0x0200
+#define DSP_Version201            0x0201
+#define DSP_Version3xx            0x0300
+#define DSP_Version4xx            0x0400
+#define DSP_SB16Version           DSP_Version4xx
+
+#define DSP_MaxNormalRate         22000
+#define DSP_MaxHighSpeedRate      44000
+
+#define DSP_8BitAutoInitRecord        0x2c
+#define DSP_8BitHighSpeedAutoInitRecord 0x98
+#define DSP_Old8BitADC                0x24
+#define DSP_8BitAutoInitMode          0x1c
+#define DSP_8BitHighSpeedAutoInitMode 0x90
+#define DSP_SetBlockLength            0x48
+#define DSP_Old8BitDAC                0x14
+#define DSP_16BitDAC                  0xB6
+#define DSP_8BitDAC                   0xC6
+#define DSP_8BitADC                   0xCe
+#define DSP_SetTimeConstant           0x40
+#define DSP_Set_DA_Rate               0x41
+#define DSP_Set_AD_Rate               0x42
+#define DSP_Halt8bitTransfer          0xd0
+#define DSP_Continue8bitTransfer      0xd4
+#define DSP_Halt16bitTransfer         0xd5
+#define DSP_Continue16bitTransfer     0xd6
+#define DSP_SpeakerOn                 0xd1
+#define DSP_SpeakerOff                0xd3
+#define DSP_GetVersion                0xE1
+#define DSP_Reset                     0xFFFF
+
+#define DSP_SignedBit                 0x10
+#define DSP_StereoBit                 0x20
+
+#define DSP_UnsignedMonoData      0x00
+#define DSP_SignedMonoData        ( DSP_SignedBit )
+#define DSP_UnsignedStereoData    ( DSP_StereoBit )
+#define DSP_SignedStereoData      ( DSP_SignedBit | DSP_StereoBit )
+
+#define BlasterEnv_Address    'A'
+#define BlasterEnv_Interrupt  'I'
+#define BlasterEnv_8bitDma    'D'
+#define BlasterEnv_16bitDma   'H'
+#define BlasterEnv_Type       'T'
+#define BlasterEnv_Midi       'P'
+#define BlasterEnv_EmuAddress 'E'
+
+#define CalcTimeConstant( rate, samplesize ) \
+   ( ( 65536L - ( 256000000L / ( ( samplesize ) * ( rate ) ) ) ) >> 8 )
+
+#define CalcSamplingRate( tc ) \
+   ( 256000000L / ( 65536L - ( tc << 8 ) ) )
+
+typedef struct
+   {
+   int IsSupported;
+   int HasMixer;
+   int MaxMixMode;
+   int MinSamplingRate;
+   int MaxSamplingRate;
+   } CARD_CAPABILITY;
+
+#endif

Added: tags/rott-1.1/rott/audiolib/_guswave.h
===================================================================
--- tags/rott-1.1/rott/audiolib/_guswave.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/_guswave.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,164 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   file:   _GUSWAVE.H
+
+   author: James R. Dose
+   date:   March 23, 1994
+
+   Private header for GUSWAVE.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___GUSWAVE_H
+#define ___GUSWAVE_H
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+#define LOADDS _loadds
+
+#define VOC_8BIT            0x0
+#define VOC_CT4_ADPCM       0x1
+#define VOC_CT3_ADPCM       0x2
+#define VOC_CT2_ADPCM       0x3
+#define VOC_16BIT           0x4
+#define VOC_ALAW            0x6
+#define VOC_MULAW           0x7
+#define VOC_CREATIVE_ADPCM  0x200
+
+#define MAX_BLOCK_LENGTH 0x8000
+
+#define GF1BSIZE   896L   /* size of buffer per wav on GUS */
+//#define GF1BSIZE   512L   /* size of buffer per wav on GUS */
+
+//#define VOICES     8      /* maximum amount of concurrent wav files */
+#define VOICES     2      /* maximum amount of concurrent wav files */
+#define MAX_VOICES 32     /* This should always be 32 */
+#define MAX_VOLUME 4095
+#define BUFFER     2048U  /* size of DMA buffer for patch loading */
+
+typedef enum
+   {
+   Raw,
+   VOC,
+   DemandFeed,
+   WAV
+   } wavedata;
+
+typedef enum
+   {
+   NoMoreData,
+   KeepPlaying,
+   SoundDone
+   } playbackstatus;
+
+
+typedef volatile struct VoiceNode
+   {
+   struct VoiceNode *next;
+   struct VoiceNode *prev;
+
+   wavedata      wavetype;
+   int           bits;
+   playbackstatus ( *GetSound )( struct VoiceNode *voice );
+
+   int num;
+
+   unsigned long  mem;           /* location in ultrasound memory */
+   int            Active;        /* this instance in use */
+   int            GF1voice;      /* handle to active voice */
+
+   char          *NextBlock;
+   char          *LoopStart;
+   char          *LoopEnd;
+   unsigned       LoopCount;
+   unsigned long  LoopSize;
+   unsigned long  BlockLength;
+
+   unsigned long  PitchScale;
+
+   unsigned char *sound;
+   unsigned long  length;
+   unsigned long  SamplingRate;
+   unsigned long  RateScale;
+   int            Playing;
+
+   int    handle;
+   int    priority;
+
+   void          ( *DemandFeed )( char **ptr, unsigned long *length );
+
+   unsigned long callbackval;
+
+   int    Volume;
+   int    Pan;
+   }
+VoiceNode;
+
+typedef struct
+   {
+   VoiceNode *start;
+   VoiceNode *end;
+   }
+voicelist;
+
+typedef volatile struct voicestatus
+   {
+   VoiceNode *Voice;
+   int playing;
+   }
+voicestatus;
+
+typedef struct
+   {
+   char          RIFF[ 4 ];
+   unsigned long file_size;
+   char          WAVE[ 4 ];
+   char          fmt[ 4 ];
+   unsigned long format_size;
+   } riff_header;
+
+typedef struct
+   {
+   unsigned short wFormatTag;
+   unsigned short nChannels;
+   unsigned long  nSamplesPerSec;
+   unsigned long  nAvgBytesPerSec;
+   unsigned short nBlockAlign;
+   unsigned short nBitsPerSample;
+   } format_header;
+
+typedef struct
+   {
+   unsigned char DATA[ 4 ];
+   unsigned long size;
+   } data_header;
+
+playbackstatus GUSWAVE_GetNextVOCBlock( VoiceNode *voice );
+VoiceNode *GUSWAVE_GetVoice( int handle );
+
+int GUSWAVE_Play( VoiceNode *voice, int angle, int volume, int channels );
+
+VoiceNode *GUSWAVE_AllocVoice( int priority );
+static int GUSWAVE_InitVoices( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/_midi.h
===================================================================
--- tags/rott-1.1/rott/audiolib/_midi.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/_midi.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,290 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: _MIDI.H
+
+   author: James R. Dose
+   date:   May 25, 1994
+
+   Private header for MIDI.C.  Midi song file playback routines.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___MIDI_H
+#define ___MIDI_H
+
+#define RELATIVE_BEAT( measure, beat, tick ) \
+   ( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) )
+
+//Bobby Prince thinks this may be 100
+//#define GENMIDI_DefaultVolume 100
+#define GENMIDI_DefaultVolume 90
+
+#define MAX_FORMAT            1
+
+#define NUM_MIDI_CHANNELS     16
+
+#define TIME_PRECISION        16
+
+#define MIDI_HEADER_SIGNATURE 0x6468544d    // "MThd"
+#define MIDI_TRACK_SIGNATURE  0x6b72544d    // "MTrk"
+
+#define MIDI_VOLUME                7
+#define MIDI_PAN                   10
+#define MIDI_DETUNE                94
+#define MIDI_RHYTHM_CHANNEL        9
+#define MIDI_RPN_MSB               100
+#define MIDI_RPN_LSB               101
+#define MIDI_DATAENTRY_MSB         6
+#define MIDI_DATAENTRY_LSB         38
+#define MIDI_PITCHBEND_MSB         0
+#define MIDI_PITCHBEND_LSB         0
+#define MIDI_RUNNING_STATUS        0x80
+#define MIDI_NOTE_OFF              0x8
+#define MIDI_NOTE_ON               0x9
+#define MIDI_POLY_AFTER_TCH        0xA
+#define MIDI_CONTROL_CHANGE        0xB
+#define MIDI_PROGRAM_CHANGE        0xC
+#define MIDI_AFTER_TOUCH           0xD
+#define MIDI_PITCH_BEND            0xE
+#define MIDI_SPECIAL               0xF
+#define MIDI_SYSEX                 0xF0
+#define MIDI_SYSEX_CONTINUE        0xF7
+#define MIDI_META_EVENT            0xFF
+#define MIDI_END_OF_TRACK          0x2F
+#define MIDI_TEMPO_CHANGE          0x51
+#define MIDI_TIME_SIGNATURE        0x58
+#define MIDI_RESET_ALL_CONTROLLERS 0x79
+#define MIDI_ALL_NOTES_OFF         0x7b
+#define MIDI_MONO_MODE_ON          0x7E
+#define MIDI_SYSTEM_RESET          0xFF
+
+#define GET_NEXT_EVENT( track, data ) \
+   ( data ) = *( track )->pos; \
+   ( track )->pos += 1
+
+#define GET_MIDI_CHANNEL( event )       ( ( event ) & 0xf )
+#define GET_MIDI_COMMAND( event )       ( ( event ) >> 4 )
+
+#define EMIDI_INFINITE          -1
+#define EMIDI_END_LOOP_VALUE    127
+#define EMIDI_ALL_CARDS         127
+#define EMIDI_INCLUDE_TRACK     110
+#define EMIDI_EXCLUDE_TRACK     111
+#define EMIDI_PROGRAM_CHANGE    112
+#define EMIDI_VOLUME_CHANGE     113
+#define EMIDI_CONTEXT_START     114
+#define EMIDI_CONTEXT_END       115
+#define EMIDI_LOOP_START        116
+#define EMIDI_LOOP_END          117
+#define EMIDI_SONG_LOOP_START   118
+#define EMIDI_SONG_LOOP_END     119
+
+#define EMIDI_GeneralMIDI       0
+#define EMIDI_SoundCanvas       1
+#define EMIDI_AWE32             2
+#define EMIDI_WaveBlaster       3
+#define EMIDI_SoundBlaster      4
+#define EMIDI_ProAudio          5
+#define EMIDI_SoundMan16        6
+#define EMIDI_Adlib             7
+#define EMIDI_Soundscape        8
+#define EMIDI_Ultrasound        9
+
+#define EMIDI_AffectsCurrentCard( c, type ) \
+   ( ( ( c ) == EMIDI_ALL_CARDS ) || ( ( c ) == ( type ) ) )
+
+
+#define EMIDI_NUM_CONTEXTS      7
+typedef struct
+   {
+   unsigned char *pos;
+   unsigned char *loopstart;
+   short          loopcount;
+   short          RunningStatus;
+   unsigned       time;
+   long           FPSecondsPerTick;
+   short          tick;
+   short          beat;
+   short          measure;
+   short          BeatsPerMeasure;
+   short          TicksPerBeat;
+   short          TimeBase;
+   long           delay;
+   short          active;
+   } songcontext;
+
+typedef struct
+   {
+   unsigned char *start;
+   unsigned char *pos;
+
+   long           delay;
+   short          active;
+   short          RunningStatus;
+
+   short          currentcontext;
+   songcontext    context[ EMIDI_NUM_CONTEXTS ];
+
+   char           EMIDI_IncludeTrack;
+   char           EMIDI_ProgramChange;
+   char           EMIDI_VolumeChange;
+   } track;
+
+static long _MIDI_ReadNumber( void *from, size_t size );
+static long _MIDI_ReadDelta( track *ptr );
+static void _MIDI_ResetTracks( void );
+static void _MIDI_AdvanceTick( void );
+static void _MIDI_MetaEvent( track *Track );
+static void _MIDI_SysEx( track *Track );
+static int  _MIDI_InterpretControllerInfo( track *Track, int TimeSet,
+   int channel, int c1, int c2 );
+//static
+   void _MIDI_ServiceRoutine( task *Task );
+static int  _MIDI_SendControlChange( int channel, int c1, int c2 );
+static void _MIDI_SetChannelVolume( int channel, int volume );
+static void _MIDI_SendChannelVolumes( void );
+static int  _MIDI_ProcessNextTick( void );
+static void _MIDI_InitEMIDI( void );
+
+/*
+               if ( c1 == EMIDI_LOOP_START )
+                  {
+                  if ( c2 == 0 )
+                     {
+                     Track->context[ 0 ].loopcount = EMIDI_INFINITE;
+                     }
+                  else
+                     {
+                     Track->context[ 0 ].loopcount = c2;
+                     }
+
+                  Track->context[ 0 ].pos              = Track->pos;
+                  Track->context[ 0 ].loopstart        = Track->pos;
+                  Track->context[ 0 ].RunningStatus    = Track->RunningStatus;
+                  Track->context[ 0 ].time             = _MIDI_Time;
+                  Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
+                  Track->context[ 0 ].tick             = _MIDI_Tick;
+                  Track->context[ 0 ].beat             = _MIDI_Beat;
+                  Track->context[ 0 ].measure          = _MIDI_Measure;
+                  Track->context[ 0 ].BeatsPerMeasure  = _MIDI_BeatsPerMeasure;
+                  Track->context[ 0 ].TicksPerBeat     = _MIDI_TicksPerBeat;
+                  Track->context[ 0 ].TimeBase         = _MIDI_TimeBase;
+                  break;
+                  }
+
+               if ( ( c1 == EMIDI_LOOP_END ) &&
+                  ( c2 == EMIDI_END_LOOP_VALUE ) )
+                  {
+                  if ( ( Track->context[ 0 ].loopstart != NULL ) &&
+                     ( Track->context[ 0 ].loopcount != 0 ) )
+                     {
+                     if ( Track->context[ 0 ].loopcount != EMIDI_INFINITE )
+                        {
+                        Track->context[ 0 ].loopcount--;
+                        }
+
+                     Track->pos           = Track->context[ 0 ].loopstart;
+                     Track->RunningStatus = Track->context[ 0 ].RunningStatus;
+
+                     if ( !TimeSet )
+                        {
+                        _MIDI_Time             = Track->context[ 0 ].time;
+                        _MIDI_FPSecondsPerTick = Track->context[ 0 ].FPSecondsPerTick;
+                        _MIDI_Tick             = Track->context[ 0 ].tick;
+                        _MIDI_Beat             = Track->context[ 0 ].beat;
+                        _MIDI_Measure          = Track->context[ 0 ].measure;
+                        _MIDI_BeatsPerMeasure  = Track->context[ 0 ].BeatsPerMeasure;
+                        _MIDI_TicksPerBeat     = Track->context[ 0 ].TicksPerBeat;
+                        _MIDI_TimeBase         = Track->context[ 0 ].TimeBase;
+                        TimeSet = TRUE;
+                        }
+                     }
+                  break;
+                  }
+
+               if ( c1 == MIDI_MONO_MODE_ON )
+                  {
+                  Track->pos++;
+                  }
+
+               if ( ( c1 == MIDI_VOLUME ) && ( !Track->EMIDI_VolumeChange ) )
+                  {
+                  _MIDI_SetChannelVolume( channel, c2 );
+                  break;
+                  }
+               else if ( ( c1 == EMIDI_VOLUME_CHANGE ) &&
+                  ( Track->EMIDI_VolumeChange ) )
+                  {
+                  _MIDI_SetChannelVolume( channel, c2 );
+                  break;
+                  }
+
+               if ( ( c1 == EMIDI_PROGRAM_CHANGE ) &&
+                  ( Track->EMIDI_ProgramChange ) )
+                  {
+                  _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] );
+                  break;
+                  }
+
+               if ( c1 == EMIDI_CONTEXT_START )
+                  {
+                  break;
+                  }
+
+               if ( c1 == EMIDI_CONTEXT_END )
+                  {
+                  if ( ( Track->currentcontext != _MIDI_Context ) ||
+                     ( Track->context[ _MIDI_Context ].pos == NULL )
+                     {
+                     break;
+                     }
+
+                  Track->currentcontext = _MIDI_Context;
+                  Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart;
+                  Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount;
+                  Track->pos           = Track->context[ _MIDI_Context ].pos;
+                  Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus;
+
+                  if ( TimeSet )
+                     {
+                     break;
+                     }
+
+                  _MIDI_Time             = Track->context[ _MIDI_Context ].time;
+                  _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick;
+                  _MIDI_Tick             = Track->context[ _MIDI_Context ].tick;
+                  _MIDI_Beat             = Track->context[ _MIDI_Context ].beat;
+                  _MIDI_Measure          = Track->context[ _MIDI_Context ].measure;
+                  _MIDI_BeatsPerMeasure  = Track->context[ _MIDI_Context ].BeatsPerMeasure;
+                  _MIDI_TicksPerBeat     = Track->context[ _MIDI_Context ].TicksPerBeat;
+                  _MIDI_TimeBase         = Track->context[ _MIDI_Context ].TimeBase;
+                  TimeSet = TRUE;
+                  break;
+                  }
+
+               if ( _MIDI_Funcs->ControlChange )
+                  {
+                  _MIDI_Funcs->ControlChange( channel, c1, c2 );
+                  }
+ */
+
+#endif

Added: tags/rott-1.1/rott/audiolib/_multivc.h
===================================================================
--- tags/rott-1.1/rott/audiolib/_multivc.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/_multivc.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,286 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   file:   _MULTIVC.H
+
+   author: James R. Dose
+   date:   December 20, 1993
+
+   Private header for MULTIVOC.C
+
+   (c) Copyright 1993 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___MULTIVC_H
+#define ___MULTIVC_H
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+#define VOC_8BIT            0x0
+#define VOC_CT4_ADPCM       0x1
+#define VOC_CT3_ADPCM       0x2
+#define VOC_CT2_ADPCM       0x3
+#define VOC_16BIT           0x4
+#define VOC_ALAW            0x6
+#define VOC_MULAW           0x7
+#define VOC_CREATIVE_ADPCM  0x200
+
+#define T_SIXTEENBIT_STEREO 0
+#define T_8BITS       1
+#define T_MONO        2
+#define T_16BITSOURCE 4
+#define T_LEFTQUIET   8
+#define T_RIGHTQUIET  16
+#define T_DEFAULT     T_SIXTEENBIT_STEREO
+
+#define MV_MaxPanPosition  31
+#define MV_NumPanPositions ( MV_MaxPanPosition + 1 )
+#define MV_MaxTotalVolume  255
+//#define MV_MaxVolume       63
+#define MV_NumVoices       8
+
+#define MIX_VOLUME( volume ) \
+   ( ( max( 0, min( ( volume ), 255 ) ) * ( MV_MaxVolume + 1 ) ) >> 8 )
+//   ( ( max( 0, min( ( volume ), 255 ) ) ) >> 2 )
+
+//#define SILENCE_16BIT     0x80008000
+#define SILENCE_16BIT     0
+#define SILENCE_8BIT      0x80808080
+//#define SILENCE_16BIT_PAS 0
+
+#define MixBufferSize     256
+
+#define NumberOfBuffers   16
+#define TotalBufferSize   ( MixBufferSize * NumberOfBuffers )
+
+#define PI                3.1415926536
+
+typedef enum
+   {
+   Raw,
+   VOC,
+   DemandFeed,
+   WAV
+   } wavedata;
+
+typedef enum
+   {
+   NoMoreData,
+   KeepPlaying
+   } playbackstatus;
+
+
+typedef struct VoiceNode
+   {
+   struct VoiceNode *next;
+   struct VoiceNode *prev;
+
+   wavedata      wavetype;
+   char          bits;
+
+   playbackstatus ( *GetSound )( struct VoiceNode *voice );
+
+   void ( *mix )( unsigned long position, unsigned long rate,
+      const char *start, unsigned long length );
+
+   char         *NextBlock;
+   char         *LoopStart;
+   char         *LoopEnd;
+   unsigned      LoopCount;
+   unsigned long LoopSize;
+   unsigned long BlockLength;
+
+   unsigned long PitchScale;
+   unsigned long FixedPointBufferSize;
+
+   char         *sound;
+   unsigned long length;
+   unsigned long SamplingRate;
+   unsigned long RateScale;
+   unsigned long position;
+   int           Playing;
+
+   int           handle;
+   int           priority;
+
+   void          ( *DemandFeed )( char **ptr, unsigned long *length );
+
+   short        *LeftVolume;
+   short        *RightVolume;
+
+   unsigned long callbackval;
+
+   } VoiceNode;
+
+typedef struct
+   {
+   VoiceNode *start;
+   VoiceNode *end;
+   } VList;
+
+typedef struct
+   {
+   unsigned char left;
+   unsigned char right;
+   } Pan;
+
+typedef signed short MONO16;
+typedef signed char  MONO8;
+
+typedef struct
+   {
+   MONO16 left;
+   MONO16 right;
+//   unsigned short left;
+//   unsigned short right;
+   } STEREO16;
+
+typedef struct
+   {
+   MONO16 left;
+   MONO16 right;
+   } SIGNEDSTEREO16;
+
+typedef struct
+   {
+//   MONO8 left;
+//   MONO8 right;
+   char left;
+   char right;
+   } STEREO8;
+
+typedef struct
+   {
+   char          RIFF[ 4 ];
+   unsigned long file_size;
+   char          WAVE[ 4 ];
+   char          fmt[ 4 ];
+   unsigned long format_size;
+   } riff_header;
+
+typedef struct
+   {
+   unsigned short wFormatTag;
+   unsigned short nChannels;
+   unsigned long  nSamplesPerSec;
+   unsigned long  nAvgBytesPerSec;
+   unsigned short nBlockAlign;
+   unsigned short nBitsPerSample;
+   } format_header;
+
+typedef struct
+   {
+   unsigned char DATA[ 4 ];
+   unsigned long size;
+   } data_header;
+
+typedef MONO8  VOLUME8[ 256 ];
+typedef MONO16 VOLUME16[ 256 ];
+
+typedef char HARSH_CLIP_TABLE_8[ MV_NumVoices * 256 ];
+
+static void MV_Mix( VoiceNode *voice, int buffer );
+static void MV_PlayVoice( VoiceNode *voice );
+static void MV_StopVoice( VoiceNode *voice );
+static void MV_ServiceVoc( void );
+
+static playbackstatus MV_GetNextVOCBlock( VoiceNode *voice );
+static playbackstatus MV_GetNextDemandFeedBlock( VoiceNode *voice );
+static playbackstatus MV_GetNextRawBlock( VoiceNode *voice );
+static playbackstatus MV_GetNextWAVBlock( VoiceNode *voice );
+
+static void       MV_ServiceRecord( void );
+static VoiceNode *MV_GetVoice( int handle );
+static VoiceNode *MV_AllocVoice( int priority );
+
+static short     *MV_GetVolumeTable( int vol );
+
+static void       MV_SetVoiceMixMode( VoiceNode *voice );
+
+static void       MV_SetVoicePitch( VoiceNode *voice, unsigned long rate, int pitchoffset );
+static void       MV_CalcVolume( int MaxLevel );
+static void       MV_CalcPanTable( void );
+
+#ifdef PLAT_DOS
+#define ATR_INDEX               0x3c0
+#define STATUS_REGISTER_1       0x3da
+
+#define SetBorderColor(color) \
+   { \
+   inp  (STATUS_REGISTER_1); \
+   outp (ATR_INDEX,0x31);    \
+   outp (ATR_INDEX,color);   \
+   }
+#endif
+
+void ClearBuffer_DW( void *ptr, unsigned data, int length );
+
+#ifdef PLAT_DOS
+#pragma aux ClearBuffer_DW = \
+   "cld",                    \
+   "push   es",              \
+   "push   ds",              \
+   "pop    es",              \
+   "rep    stosd",           \
+   "pop    es",              \
+parm [ edi ] [ eax ] [ ecx ] modify exact [ ecx edi ];
+#endif
+
+void MV_Mix8BitMono( unsigned long position, unsigned long rate,
+   const char *start, unsigned long length );
+
+void MV_Mix8BitStereo( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_Mix16BitMono( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_Mix16BitStereo( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_Mix16BitMono16( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_Mix8BitMono16( unsigned long position, unsigned long rate,
+   const char *start, unsigned long length );
+
+void MV_Mix8BitStereo16( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_Mix16BitStereo16( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length );
+
+void MV_16BitReverb( const char *src, char *dest, const VOLUME16 *volume, int count );
+
+void MV_8BitReverb( const signed char *src, signed char *dest, const VOLUME16 *volume, int count );
+
+void MV_16BitReverbFast( const char *src, char *dest, int count, int shift );
+
+void MV_8BitReverbFast( const signed char *src, signed char *dest, int count, int shift );
+
+#ifdef PLAT_DOS
+#pragma aux MV_16BitReverb parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
+#pragma aux MV_8BitReverb parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
+#pragma aux MV_16BitReverbFast parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
+#pragma aux MV_8BitReverbFast parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
+#endif
+
+#endif

Added: tags/rott-1.1/rott/audiolib/_pas16.h
===================================================================
--- tags/rott-1.1/rott/audiolib/_pas16.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/_pas16.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,250 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: _PAS16.H
+
+   author: James R. Dose
+   date:   March 27, 1994
+
+   Private header for for PAS16.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___PAS16_H
+#define ___PAS16_H
+
+#define TRUE    ( 1 == 1 )
+#define FALSE   ( !TRUE )
+
+#define VALID   ( 1 == 1 )
+#define INVALID ( !VALID )
+
+#define lobyte( num )   ( ( int )*( ( char * )&( num ) ) )
+#define hibyte( num )   ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
+
+#define STEREO      1
+#define SIXTEEN_BIT 2
+
+#define MONO_8BIT    0
+#define STEREO_8BIT  ( STEREO )
+#define MONO_16BIT   ( SIXTEEN_BIT )
+#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
+
+#define PAS_MaxMixMode        STEREO_16BIT
+
+#define MONO_8BIT_SAMPLE_SIZE    1
+#define MONO_16BIT_SAMPLE_SIZE   2
+#define STEREO_8BIT_SAMPLE_SIZE  ( 2 * MONO_8BIT_SAMPLE_SIZE )
+#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
+
+#define PAS_RevisionBits        0xe0
+
+#define AudioFilterControl      0xb8a
+#define InterruptControl        0xb8b
+#define InterruptStatus         0xb89
+#define PCMDataRegister         0xf88
+#define CrossChannelControl     0xf8a
+#define SampleRateTimer         0x1388
+#define SampleBufferCount       0x1389
+#define LocalSpeakerTimerCount  0x138a
+#define LocalTimerControl       0x138b
+#define SampleSizeConfiguration 0x8389
+
+#define AudioMuteFlag             0x20
+#define SampleRateTimerGateFlag   0x40
+#define SampleBufferCountGateFlag 0x80
+
+#define SampleRateInterruptFlag   0x04
+#define SampleBufferInterruptFlag 0x08
+
+#define PAS_SampleSizeMask     0xf3
+#define PAS_SignedSampleMask   0xe3
+#define PAS_16BitSampleFlag    0x04
+#define PAS_UnsignedSampleFlag 0x10
+//bSC2msbinv   equ   00010000b   ;; invert MSB from standard method
+
+#define PAS_OverSamplingMask 0xfc
+
+#define PAS_1xOverSampling  0x00
+#define PAS_2xOverSampling  0x01
+#define PAS_4xOverSampling  0x03
+
+#define PAS_StereoFlag      0x20
+
+#define PAS_AudioMuteFlag  0x20
+
+#define DEFAULT_BASE ( 0x0388 ^ 0x388 ) /* default base I/O address */
+#define ALT_BASE_1   ( 0x0384 ^ 0x388 ) /* first alternate address  */
+#define ALT_BASE_2   ( 0x038C ^ 0x388 ) /* second alternate address */
+#define ALT_BASE_3   ( 0x0288 ^ 0x388 ) /* third alternate address  */
+
+#define PAS_DMAEnable          0x80
+#define PAS_ChannelConnectMask 0x0f
+#define PAS_PCMStartDAC        0xD0
+#define PAS_PCMStartADC        0xC0
+#define PAS_PCMStopMask        0x3f
+
+#define RECORD   0
+#define PLAYBACK 1
+
+#define SelectSampleRateTimer   0x36   // 00110110b
+#define SelectSampleBufferCount 0x74   // 01110100b
+
+#define CalcTimeInterval( rate ) \
+   ( 1193180UL / ( rate ) )
+
+#define CalcSamplingRate( interval ) \
+   ( 1193180UL / ( interval ) )
+
+#define MV_Signature                 0x4d56
+#define MV_SoundInt                  0x2f
+#define MV_CheckForDriver            0xbc00
+#define MV_GetVersion                0xbc01
+#define MV_GetPointerToStateTable    0xbc02
+#define MV_GetPointerToFunctionTable 0xbc03
+#define MV_GetDmaIrqInt              0xbc04
+#define MV_SendCommandStructure      0xbc05
+#define MV_GetDriverMessage          0xbc06
+#define MV_SetHotkeyScanCodes        0xbc0a
+#define MV_GetPathToDriver           0xbc0b
+
+#define OUTPUTMIXER     0x00         /* output mixer H/W select */
+#define INPUTMIXER      0x40         /* input mixer select      */
+#define DEFMIXER        -1           /* use last mixer selected   */
+
+/* left channel values */
+
+#define L_FM            0x01
+#define L_IMIXER        0x02
+#define L_EXT           0x03
+#define L_INT           0x04
+#define L_MIC           0x05
+#define L_PCM           0x06
+#define L_SPEAKER       0x07
+#define L_FREE          0x00
+#define L_SBDAC         0x00
+
+/* right channel values */
+
+#define R_FM            0x08
+#define R_IMIXER        0x09
+#define R_EXT           0x0A
+#define R_INT           0x0B
+#define R_MIC           0x0C
+#define R_PCM           0x0D
+#define R_SPEAKER       0x0E
+#define R_FREE          0x0F
+#define R_SBDAC         0x0F
+
+typedef struct
+   {
+   unsigned char  sysspkrtmr;   /*   42 System Speaker Timer Address */
+   unsigned char  systmrctlr;   /*   43 System Timer Control         */
+   unsigned char  sysspkrreg;   /*   61 System Speaker Register      */
+   unsigned char  joystick;     /*  201 Joystick Register            */
+   unsigned char  lfmaddr;      /*  388 Left  FM Synth Address       */
+   unsigned char  lfmdata;      /*  389 Left  FM Synth Data          */
+   unsigned char  rfmaddr;      /*  38A Right FM Synth Address       */
+   unsigned char  rfmdata;      /*  38B Right FM Synth Data          */
+   unsigned char  dfmaddr;      /*  788 Dual  FM Synth Address       */
+   unsigned char  dfmdata;      /*  789 Dual  FM Synth Data          */
+   unsigned char  RESRVD1[1];   /*      reserved                     */
+   unsigned char  paudiomixr;   /*  78B Paralllel Audio Mixer Control*/
+   unsigned char  audiomixr;    /*  B88 Audio Mixer Control          */
+   unsigned char  intrctlrst;   /*  B89 Interrupt Status             */
+   unsigned char  audiofilt;    /*  B8A Audio Filter Control         */
+   unsigned char  intrctlr;     /*  B8B Interrupt Control            */
+   unsigned char  pcmdata;      /*  F88 PCM Data I/O Register        */
+   unsigned char  RESRVD2;      /*      reserved                     */
+   unsigned char  crosschannel; /*  F8A Cross Channel                */
+   unsigned char  RESRVD3;      /*      reserved                     */
+   unsigned short samplerate;   /* 1388 Sample Rate Timer            */
+   unsigned short samplecnt;    /* 1389 Sample Count Register        */
+   unsigned short spkrtmr;      /* 138A Shadow Speaker Timer Count   */
+   unsigned char  tmrctlr;      /* 138B Shadow Speaker Timer Control */
+   unsigned char  mdirqvect;    /* 1788 MIDI IRQ Vector Register     */
+   unsigned char  mdsysctlr;    /* 1789 MIDI System Control Register */
+   unsigned char  mdsysstat;    /* 178A MIDI IRQ Status Register     */
+   unsigned char  mdirqclr;     /* 178B MIDI IRQ Clear Register      */
+   unsigned char  mdgroup1;     /* 1B88 MIDI Group #1 Register       */
+   unsigned char  mdgroup2;     /* 1B89 MIDI Group #2 Register       */
+   unsigned char  mdgroup3;     /* 1B8A MIDI Group #3 Register       */
+   unsigned char  mdgroup4;     /* 1B8B MIDI Group #4 Register       */
+   } MVState;
+
+typedef struct
+   {
+   unsigned long SetMixer;
+   unsigned long SetVolume;
+   unsigned long SetFilter;
+   unsigned long SetCrossChannel;
+   unsigned long GetMixer;
+   unsigned long GetVolume;
+   unsigned long GetFilter;
+   unsigned long GetCrossChannel;
+   unsigned long ReadSound;
+   unsigned long FMSplit;
+   } MVFunc;
+
+int     PAS_CheckForDriver( void );
+MVState *PAS_GetStateTable( void );
+MVFunc  *PAS_GetFunctionTable( void );
+int     PAS_GetCardSettings( void );
+void    PAS_EnableInterrupt( void );
+void    PAS_DisableInterrupt( void );
+void    interrupt far PAS_ServiceInterrupt( void );
+//void    interrupt PAS_ServiceInterrupt( void );
+void    PAS_Write( int Register, int Data );
+int     PAS_Read( int Register );
+void    PAS_SetSampleRateTimer( void );
+void    PAS_SetSampleBufferCount( void );
+int     PAS_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
+int     PAS_GetFilterSetting( int rate );
+void    PAS_BeginTransfer( int mode );
+int     PAS_TestAddress( int address );
+int     PAS_FindCard( void );
+int     PAS_CallMVFunction( unsigned long function, int ebx, int ecx, int edx );
+void    PAS_SaveState( void );
+void    PAS_RestoreState( void );
+
+
+#pragma aux PAS_TestAddress = \
+   "mov   dx, 0b8bh", \
+   "xor    dx, ax", \
+   "in    al, dx", \
+   "cmp   al, 0ffh", \
+   "je    TestExit", \
+   "mov   ah, al", \
+   "xor   al, 0e0h", \
+   "out   dx, al", \
+   "jmp   TestDelay1", \
+   "TestDelay1:", \
+   "jmp   TestDelay2", \
+   "TestDelay2:", \
+   "in    al, dx", \
+   "xchg  al, ah", \
+   "out   dx, al", \
+   "sub   al, ah", \
+   "TestExit:", \
+   "and   eax, 0ffh" \
+   parm [ eax ] modify exact [ eax dx ];
+
+#endif

Added: tags/rott-1.1/rott/audiolib/_sndscap.h
===================================================================
--- tags/rott-1.1/rott/audiolib/_sndscap.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/_sndscap.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,136 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: _SNDSCAP.H
+
+   author: James R. Dose
+   date:   October 26, 1994
+
+   Private header for SNDSCAPE.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef ___SNDSCAP_H
+#define ___SNDSCAP_H
+
+#define VALID   ( 1 == 1 )
+#define INVALID ( !VALID )
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+#define lobyte( num )   ( ( int )*( ( char * )&( num ) ) )
+#define hibyte( num )   ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
+
+#define STEREO      1
+#define SIXTEEN_BIT 2
+
+#define MONO_8BIT    0
+#define STEREO_8BIT  ( STEREO )
+#define MONO_16BIT   ( SIXTEEN_BIT )
+#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
+
+#define SOUNDSCAPE_MaxMixMode        STEREO_16BIT
+
+#define MONO_8BIT_SAMPLE_SIZE    1
+#define MONO_16BIT_SAMPLE_SIZE   2
+#define STEREO_8BIT_SAMPLE_SIZE  ( 2 * MONO_8BIT_SAMPLE_SIZE )
+#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
+
+#define SOUNDSCAPE_DefaultSampleRate 11000
+#define SOUNDSCAPE_DefaultMixMode    MONO_8BIT
+#define SOUNDSCAPE_MaxIrq            15
+
+/* Ensoniq gate-array chip defines ... */
+#define ODIE            0       /* ODIE gate array */
+#define OPUS            1       /* OPUS gate array */
+#define MMIC            2       /* MiMIC gate array */
+
+/* relevant direct register defines - offsets from base address */
+#define GA_HOSTCSTAT    2       /* host port ctrl/stat reg */
+#define GA_HOSTDATA     3       /* host port data reg */
+#define GA_REGADDR      4       /* indirect address reg */
+#define GA_REGDATA      5       /* indirect data reg */
+#define SB_IACK      0x22e /* SoundBlaster IACK register */
+
+/* relevant indirect register defines */
+#define GA_DMACHB       3       /* DMA chan B assign reg */
+#define GA_INTCFG       4       /* interrupt configuration reg */
+#define GA_DMACFG       5       /* DMA config reg */
+#define GA_CDCFG        6       /* CD-ROM (AD-1848) config reg */
+#define GA_HMCTL  9  /* host master control reg */
+#define GA_CHIPSEL      10      /* programmable external chip select */
+
+/* AD-1848 chip defines ... */
+/* relevant direct register defines */
+#define AD_REGADDR      0       /* indirect address reg */
+#define AD_REGDATA      1       /* indirect data reg */
+#define AD_STATUS       2       /* status register */
+#define AD_OFFSET       8       /* for some boards, a fixed BasePort offset */
+
+/* relevant indirect register defines */
+#define AD_LEFTOUT      6       /* left DAC output control reg */
+#define AD_RIGHTOUT     7       /* right DAC output control reg */
+#define AD_FORMAT       8       /* clock and data format reg */
+#define AD_CONFIG       9       /* interface config register */
+#define AD_PINCTRL      10      /* external pin control reg */
+#define AD_UCOUNT       14      /* upper count reg */
+#define AD_LCOUNT       15      /* lower count reg */
+
+/* some firmware command and communication defines */
+#define SET_CTL      0x88  /* set a control value */
+#define GET_CTL      0x89  /* get a control value */
+#define SET_REV      0xb0  /* set synth reverb */
+#define SYNTH_VOL 0x04  /* Synth Vol control number */
+#define RXRDY     0x01  /* Receive-Ready bit mask */
+#define TXRDY     0x02  /* Transmit-Ready bit mask */
+
+/* some miscellaneous defines ... soundscape reg values, sytem int regs, ... */
+#define INTCONT1        0x20    /* Interrupt Controller 1 control register */
+#define INTCONT2        0xa0    /* Interrupt Controller 2 control register */
+#define INTMASK1        0x21    /* Interrupt Controller 1 mask register */
+#define INTMASK2        0xa1    /* Interrupt Controller 2 mask register */
+#define VECTBASE1       0x08    /* vector base for XT interrupts */
+#define VECTBASE2       0x70    /* vector base for AT extended interrupts */
+#define EOI             0x20    /* End Of Interrupt command */
+#define AUTO_OUT        0x58    /* DMA controller mode */
+
+static void SOUNDSCAPE_EnableInterrupt( void );
+static void SOUNDSCAPE_DisableInterrupt( void );
+static void __interrupt __far SOUNDSCAPE_ServiceInterrupt( void );
+static int  ga_read( int rnum );
+static void ga_write( int rnum, int value );
+static int  ad_read( int rnum );
+static void ad_write( int rnum, int value );
+static void tdelay( void );
+static void pcm_format( void );
+static int  SOUNDSCAPE_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
+static int  SOUNDSCAPE_BeginPlayback( int length );
+static void SOUNDSCAPE_LockEnd( void );
+static void SOUNDSCAPE_UnlockMemory( void );
+static int  SOUNDSCAPE_LockMemory( void );
+static unsigned short allocateTimerStack( unsigned short size );
+static void deallocateTimerStack( unsigned short selector );
+static int  parse( char *val, char *str, FILE *p1 );
+static int  SOUNDSCAPE_FindCard( void );
+static int  SOUNDSCAPE_Setup( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/adlibfx.c
===================================================================
--- tags/rott-1.1/rott/audiolib/adlibfx.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/adlibfx.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,552 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: ADLIBFX.C
+
+   author: James R. Dose
+   date:   April 1, 1994
+
+   Low level routines to support Adlib sound effects created by Muse.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <dos.h>
+#include <stdlib.h>
+#include <conio.h>
+#include "dpmi.h"
+#include "task_man.h"
+#include "interrup.h"
+#include "al_midi.h"
+#include "adlibfx.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+static void ADLIBFX_SendOutput( int reg, int data );
+static void ADLIBFX_Service( task *Task );
+
+static long     ADLIBFX_LengthLeft;
+static int      ADLIBFX_Block;
+static ALSound *ADLIBFX_Sound = NULL;
+static char    *ADLIBFX_SoundPtr = NULL;
+static int      ADLIBFX_Priority;
+static unsigned long ADLIBFX_CallBackVal;
+static void     ( *ADLIBFX_CallBackFunc )( unsigned long ) = NULL;
+static int      ADLIBFX_SoundVolume;
+static int      ADLIBFX_TotalVolume = ADLIBFX_MaxVolume;
+static task    *ADLIBFX_ServiceTask = NULL;
+static int      ADLIBFX_VoiceHandle = ADLIBFX_MinVoiceHandle;
+
+int ADLIBFX_Installed = FALSE;
+
+int ADLIBFX_ErrorCode = ADLIBFX_Ok;
+
+#define ADLIBFX_SetErrorCode( status ) \
+   ADLIBFX_ErrorCode   = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *ADLIBFX_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case ADLIBFX_Warning :
+      case ADLIBFX_Error :
+         ErrorString = ADLIBFX_ErrorString( ADLIBFX_ErrorCode );
+         break;
+
+      case ADLIBFX_Ok :
+         ErrorString = "Adlib FX ok.";
+         break;
+
+      case ADLIBFX_NoVoices :
+         ErrorString = "No free voices available in Adlib FX.";
+         break;
+
+      case ADLIBFX_VoiceNotFound :
+         ErrorString = "No voice with matching handle found.";
+         break;
+
+      case ADLIBFX_DPMI_Error :
+         ErrorString = "DPMI Error in AdlibFX.";
+         break;
+
+      default :
+         ErrorString = "Unknown Adlib FX error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define ADLIBFX_LockStart ADLIBFX_SendOutput
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_SendOutput
+
+   Writes a byte of data to the specified register on the Adlib card.
+---------------------------------------------------------------------*/
+
+static void ADLIBFX_SendOutput
+   (
+   int reg,
+   int data
+   )
+
+   {
+   int i;
+   int adlib_port = 0x388;
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   outp( adlib_port, reg );
+
+   for( i = 6; i ; i-- )
+      {
+      inp( adlib_port );
+      }
+
+   outp( adlib_port + 1, data );
+
+   for( i = 35; i ; i-- )
+      {
+      inp( adlib_port );
+      }
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_Stop
+
+   Halts playback of the currently playing sound effect.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_Stop
+   (
+   int handle
+   )
+
+   {
+   unsigned flags;
+
+   if ( ( handle != ADLIBFX_VoiceHandle ) || ( ADLIBFX_Sound == NULL ) )
+      {
+      ADLIBFX_SetErrorCode( ADLIBFX_VoiceNotFound );
+      return( ADLIBFX_Warning );
+      }
+
+   flags = DisableInterrupts();
+
+   ADLIBFX_SendOutput( 0xb0, 0 );
+
+   ADLIBFX_Sound      = NULL;
+   ADLIBFX_SoundPtr   = NULL;
+   ADLIBFX_LengthLeft = 0;
+   ADLIBFX_Priority   = 0;
+
+   RestoreInterrupts( flags );
+
+   if ( ADLIBFX_CallBackFunc )
+      {
+      ADLIBFX_CallBackFunc( ADLIBFX_CallBackVal );
+      }
+
+   return( ADLIBFX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_Service
+
+   Task Manager routine to perform the playback of a sound effect.
+---------------------------------------------------------------------*/
+
+static void ADLIBFX_Service
+   (
+   task *Task
+   )
+
+   {
+   int value;
+
+   if ( ADLIBFX_SoundPtr )
+      {
+      value = *ADLIBFX_SoundPtr++;
+      if ( value != 0 )
+         {
+         ADLIBFX_SendOutput( 0xa0, value );
+         ADLIBFX_SendOutput( 0xb0, ADLIBFX_Block );
+         }
+      else
+         {
+         ADLIBFX_SendOutput( 0xb0, 0 );
+         }
+
+      ADLIBFX_LengthLeft--;
+      if ( ADLIBFX_LengthLeft <= 0 )
+         {
+         ADLIBFX_Stop( ADLIBFX_VoiceHandle );
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_SetVolume
+
+   Sets the volume of the currently playing sound effect.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_SetVolume
+   (
+   int handle,
+   int volume
+   )
+
+   {
+   unsigned flags;
+   int      carrierlevel;
+
+   flags = DisableInterrupts();
+   if ( ( handle != ADLIBFX_VoiceHandle ) || ( ADLIBFX_Sound == NULL ) )
+      {
+      RestoreInterrupts( flags );
+      ADLIBFX_SetErrorCode( ADLIBFX_VoiceNotFound );
+      return( ADLIBFX_Warning );
+      }
+
+   volume  = min( volume, ADLIBFX_MaxVolume );
+   volume  = max( volume, 0 );
+   ADLIBFX_SoundVolume = volume;
+
+   volume *= ADLIBFX_TotalVolume;
+   volume /= ADLIBFX_MaxVolume;
+
+   carrierlevel  = ADLIBFX_Sound->cScale & 0x3f;
+   carrierlevel ^= 0x3f;
+   carrierlevel *= ( volume / 2 ) + 0x80;
+   carrierlevel /= ADLIBFX_MaxVolume;
+   carrierlevel ^= 0x3f;
+   carrierlevel |= ADLIBFX_Sound->cScale & 0xc0;
+
+   ADLIBFX_SendOutput( 0x43, carrierlevel );
+
+   RestoreInterrupts( flags );
+   return( ADLIBFX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_SetTotalVolume
+
+   Sets the total volume of the sound effect.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_SetTotalVolume
+   (
+   int volume
+   )
+
+   {
+   volume = max( volume, 0 );
+   volume = min( volume, ADLIBFX_MaxVolume );
+
+   ADLIBFX_TotalVolume = volume;
+   ADLIBFX_SetVolume( ADLIBFX_VoiceHandle, ADLIBFX_SoundVolume );
+
+   return( ADLIBFX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_GetTotalVolume
+
+   Returns the total volume of the sound effect.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_GetTotalVolume
+   (
+   void
+   )
+
+   {
+   return( ADLIBFX_TotalVolume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_VoiceAvailable
+
+   Checks if a voice can be play at the specified priority.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_VoiceAvailable
+   (
+   int priority
+   )
+
+   {
+   if ( priority < ADLIBFX_Priority )
+      {
+      return( FALSE );
+      }
+
+   return( TRUE );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_Play
+
+   Starts playback of a Muse sound effect.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_Play
+   (
+   ALSound *sound,
+   int volume,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   unsigned flags;
+   int      carrierlevel;
+
+   if ( priority < ADLIBFX_Priority )
+      {
+      ADLIBFX_SetErrorCode( ADLIBFX_NoVoices );
+      return( ADLIBFX_Warning );
+      }
+
+   ADLIBFX_Stop( ADLIBFX_VoiceHandle );
+
+   ADLIBFX_VoiceHandle++;
+   if ( ADLIBFX_VoiceHandle < ADLIBFX_MinVoiceHandle )
+      {
+      ADLIBFX_VoiceHandle = ADLIBFX_MinVoiceHandle;
+      }
+
+   flags = DisableInterrupts();
+
+   ADLIBFX_LengthLeft  = sound->length;
+   ADLIBFX_Priority    = priority;
+   ADLIBFX_Sound       = sound;
+   ADLIBFX_SoundPtr    = &sound->data;
+   ADLIBFX_CallBackVal = callbackval;
+
+   ADLIBFX_Block = ( ( sound->block & 7 ) << 2 ) | 0x20;
+
+   volume = min( volume, ADLIBFX_MaxVolume );
+   volume = max( volume, 0 );
+   ADLIBFX_SoundVolume = volume;
+
+   volume *= ADLIBFX_TotalVolume;
+   volume /= ADLIBFX_MaxVolume;
+
+   carrierlevel  = sound->cScale & 0x3f;
+   carrierlevel ^= 0x3f;
+   carrierlevel *= ( volume / 2 ) + 0x80;
+   carrierlevel /= ADLIBFX_MaxVolume;
+   carrierlevel ^= 0x3f;
+   carrierlevel |= sound->cScale & 0xc0;
+
+   ADLIBFX_SendOutput( 0x20, sound->mChar );
+   ADLIBFX_SendOutput( 0x40, sound->mScale );
+   ADLIBFX_SendOutput( 0x60, sound->mAttack );
+   ADLIBFX_SendOutput( 0x80, sound->mSus );
+   ADLIBFX_SendOutput( 0xe0, sound->mWave );
+
+   ADLIBFX_SendOutput( 0x23, sound->cChar );
+   ADLIBFX_SendOutput( 0x43, carrierlevel );
+   ADLIBFX_SendOutput( 0x63, sound->cAttack );
+   ADLIBFX_SendOutput( 0x83, sound->cSus );
+   ADLIBFX_SendOutput( 0xe3, sound->cWave );
+
+   ADLIBFX_SendOutput( 0xc0, 0 );
+
+   RestoreInterrupts( flags );
+
+   return( ADLIBFX_VoiceHandle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_SoundPlaying
+
+   Checks if a sound effect is currently playing.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_SoundPlaying
+   (
+   int handle
+   )
+
+   {
+   int status;
+
+   status = FALSE;
+   if ( ( handle == ADLIBFX_VoiceHandle ) && ( ADLIBFX_LengthLeft > 0 ) )
+      {
+      status = TRUE;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void ADLIBFX_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_SetCallBack
+
+   Set the function to call when a voice stops.
+---------------------------------------------------------------------*/
+
+void ADLIBFX_SetCallBack
+   (
+   void ( *function )( unsigned long )
+   )
+
+   {
+   ADLIBFX_CallBackFunc = function;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_Init
+
+   Initializes the sound effect engine.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_Init
+   (
+   void
+   )
+
+   {
+   int status;
+
+   if ( ADLIBFX_Installed )
+      {
+      ADLIBFX_Shutdown();
+      }
+
+   status  = DPMI_LockMemoryRegion( ADLIBFX_LockStart, ADLIBFX_LockEnd );
+   status |= DPMI_Lock( ADLIBFX_VoiceHandle );
+   status |= DPMI_Lock( ADLIBFX_Sound );
+   status |= DPMI_Lock( ADLIBFX_ErrorCode );
+   status |= DPMI_Lock( ADLIBFX_SoundPtr );
+   status |= DPMI_Lock( ADLIBFX_LengthLeft );
+   status |= DPMI_Lock( ADLIBFX_Priority );
+   status |= DPMI_Lock( ADLIBFX_CallBackFunc );
+   status |= DPMI_Lock( ADLIBFX_Block );
+
+   if ( status != DPMI_Ok )
+      {
+      ADLIBFX_SetErrorCode( ADLIBFX_DPMI_Error );
+      return( ADLIBFX_Error );
+      }
+
+//JIM
+//   AL_ReserveVoice( 0 );
+   ADLIBFX_Stop( ADLIBFX_VoiceHandle );
+   ADLIBFX_ServiceTask = TS_ScheduleTask( &ADLIBFX_Service, 140, 2, NULL );
+   TS_Dispatch();
+   ADLIBFX_Installed = TRUE;
+   ADLIBFX_CallBackFunc = NULL;
+
+   ADLIBFX_SetErrorCode( ADLIBFX_Ok );
+   return( ADLIBFX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ADLIBFX_Shutdown
+
+   Ends the use of the sound effect engine.
+---------------------------------------------------------------------*/
+
+int ADLIBFX_Shutdown
+   (
+   void
+   )
+
+   {
+   if ( ADLIBFX_Installed )
+      {
+      ADLIBFX_Stop( ADLIBFX_VoiceHandle );
+      TS_Terminate( ADLIBFX_ServiceTask );
+      ADLIBFX_ServiceTask = NULL;
+//JIM
+//      AL_ReleaseVoice( 0 );
+      ADLIBFX_Installed = FALSE;
+
+      DPMI_UnlockMemoryRegion( ADLIBFX_LockStart, ADLIBFX_LockEnd );
+      DPMI_Unlock( ADLIBFX_VoiceHandle );
+      DPMI_Unlock( ADLIBFX_Sound );
+      DPMI_Unlock( ADLIBFX_ErrorCode );
+      DPMI_Unlock( ADLIBFX_SoundPtr );
+      DPMI_Unlock( ADLIBFX_LengthLeft );
+      DPMI_Unlock( ADLIBFX_Priority );
+      DPMI_Unlock( ADLIBFX_CallBackFunc );
+      DPMI_Unlock( ADLIBFX_Block );
+      }
+
+   ADLIBFX_SetErrorCode( ADLIBFX_Ok );
+   return( ADLIBFX_Ok );
+   }

Added: tags/rott-1.1/rott/audiolib/adlibfx.h
===================================================================
--- tags/rott-1.1/rott/audiolib/adlibfx.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/adlibfx.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,80 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: ADLIBFX.H
+
+   author: James R. Dose
+   date:   April 1, 1994
+
+   Public header for ADLIBFX.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __ADLIBFX_H
+#define __ADLIBFX_H
+
+enum ADLIBFX_Errors
+   {
+   ADLIBFX_Warning = -2,
+   ADLIBFX_Error   = -1,
+   ADLIBFX_Ok      = 0,
+   ADLIBFX_NoVoices,
+   ADLIBFX_VoiceNotFound,
+   ADLIBFX_DPMI_Error
+   };
+
+typedef	struct
+   {
+   unsigned long  length;
+   short int      priority;
+   char           mChar, cChar;
+   char           mScale, cScale;
+   char           mAttack, cAttack;
+   char           mSus, cSus;
+   char           mWave, cWave;
+   char           nConn;
+   char           voice;
+   char           mode;
+   char           unused[ 3 ];
+   char           block;
+   char           data[];
+   } ALSound;
+
+#define ADLIBFX_MaxVolume      255
+#define ADLIBFX_MinVoiceHandle 1
+
+char *ADLIBFX_ErrorString( int ErrorNumber );
+int   ADLIBFX_Stop( int handle );
+int   ADLIBFX_SetVolume( int handle, int volume );
+int   ADLIBFX_SetTotalVolume( int volume );
+int   ADLIBFX_GetTotalVolume( void );
+int   ADLIBFX_VoiceAvailable( int priority );
+int   ADLIBFX_Play( ALSound *sound, int volume, int priority, unsigned long callbackval );
+int   ADLIBFX_SoundPlaying( int handle );
+void  ADLIBFX_SetCallBack( void ( *function )( unsigned long ) );
+int   ADLIBFX_Init( void );
+int   ADLIBFX_Shutdown( void );
+   #pragma aux ADLIBFX_Shutdown frame;
+void  PCFX_UnlockMemory( void );
+   #pragma aux ADLIBFX_UnlockMemory frame;
+int   PCFX_LockMemory( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/al_midi.c
===================================================================
--- tags/rott-1.1/rott/audiolib/al_midi.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/al_midi.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1510 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: AL_MIDI.C
+
+   author: James R. Dose
+   date:   April 1, 1994
+
+   Low level routines to support General MIDI music on Adlib compatible
+   cards.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <conio.h>
+#include <dos.h>
+#include <stddef.h>
+#include <stdlib.h>
+//#include <math.h>
+#include "dpmi.h"
+#include "interrup.h"
+#include "sndcards.h"
+#include "blaster.h"
+#include "user.h"
+#include "al_midi.h"
+#include "_al_midi.h"
+#include "ll_man.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+static unsigned OctavePitch[ MAX_OCTAVE + 1 ] =
+   {
+   OCTAVE_0, OCTAVE_1, OCTAVE_2, OCTAVE_3,
+   OCTAVE_4, OCTAVE_5, OCTAVE_6, OCTAVE_7,
+   };
+
+static unsigned NoteMod12[ MAX_NOTE + 1 ];
+static unsigned NoteDiv12[ MAX_NOTE + 1 ];
+
+// Pitch table
+
+//static unsigned NotePitch[ FINETUNE_MAX + 1 ][ 12 ] =
+//   {
+//      { C, C_SHARP, D, D_SHARP, E, F, F_SHARP, G, G_SHARP, A, A_SHARP, B },
+//   };
+
+static unsigned NotePitch[ FINETUNE_MAX + 1 ][ 12 ] =
+   {
+      { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263, 0x287 },
+      { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x242, 0x264, 0x288 },
+      { 0x158, 0x16c, 0x182, 0x199, 0x1b1, 0x1cb, 0x1e6, 0x203, 0x221, 0x243, 0x265, 0x289 },
+      { 0x158, 0x16c, 0x183, 0x19a, 0x1b2, 0x1cc, 0x1e7, 0x204, 0x222, 0x244, 0x266, 0x28a },
+      { 0x159, 0x16d, 0x183, 0x19a, 0x1b3, 0x1cd, 0x1e8, 0x205, 0x223, 0x245, 0x267, 0x28b },
+      { 0x15a, 0x16e, 0x184, 0x19b, 0x1b3, 0x1ce, 0x1e9, 0x206, 0x224, 0x246, 0x268, 0x28c },
+      { 0x15a, 0x16e, 0x185, 0x19c, 0x1b4, 0x1ce, 0x1ea, 0x207, 0x225, 0x247, 0x269, 0x28e },
+      { 0x15b, 0x16f, 0x185, 0x19d, 0x1b5, 0x1cf, 0x1eb, 0x208, 0x226, 0x248, 0x26a, 0x28f },
+      { 0x15b, 0x170, 0x186, 0x19d, 0x1b6, 0x1d0, 0x1ec, 0x209, 0x227, 0x249, 0x26b, 0x290 },
+      { 0x15c, 0x170, 0x187, 0x19e, 0x1b7, 0x1d1, 0x1ec, 0x20a, 0x228, 0x24a, 0x26d, 0x291 },
+      { 0x15d, 0x171, 0x188, 0x19f, 0x1b7, 0x1d2, 0x1ed, 0x20b, 0x229, 0x24b, 0x26e, 0x292 },
+      { 0x15d, 0x172, 0x188, 0x1a0, 0x1b8, 0x1d3, 0x1ee, 0x20c, 0x22a, 0x24c, 0x26f, 0x293 },
+      { 0x15e, 0x172, 0x189, 0x1a0, 0x1b9, 0x1d4, 0x1ef, 0x20d, 0x22b, 0x24d, 0x270, 0x295 },
+      { 0x15f, 0x173, 0x18a, 0x1a1, 0x1ba, 0x1d4, 0x1f0, 0x20e, 0x22c, 0x24e, 0x271, 0x296 },
+      { 0x15f, 0x174, 0x18a, 0x1a2, 0x1bb, 0x1d5, 0x1f1, 0x20f, 0x22d, 0x24f, 0x272, 0x297 },
+      { 0x160, 0x174, 0x18b, 0x1a3, 0x1bb, 0x1d6, 0x1f2, 0x210, 0x22e, 0x250, 0x273, 0x298 },
+      { 0x161, 0x175, 0x18c, 0x1a3, 0x1bc, 0x1d7, 0x1f3, 0x211, 0x22f, 0x251, 0x274, 0x299 },
+      { 0x161, 0x176, 0x18c, 0x1a4, 0x1bd, 0x1d8, 0x1f4, 0x212, 0x230, 0x252, 0x276, 0x29b },
+      { 0x162, 0x176, 0x18d, 0x1a5, 0x1be, 0x1d9, 0x1f5, 0x212, 0x231, 0x254, 0x277, 0x29c },
+      { 0x162, 0x177, 0x18e, 0x1a6, 0x1bf, 0x1d9, 0x1f5, 0x213, 0x232, 0x255, 0x278, 0x29d },
+      { 0x163, 0x178, 0x18f, 0x1a6, 0x1bf, 0x1da, 0x1f6, 0x214, 0x233, 0x256, 0x279, 0x29e },
+      { 0x164, 0x179, 0x18f, 0x1a7, 0x1c0, 0x1db, 0x1f7, 0x215, 0x235, 0x257, 0x27a, 0x29f },
+      { 0x164, 0x179, 0x190, 0x1a8, 0x1c1, 0x1dc, 0x1f8, 0x216, 0x236, 0x258, 0x27b, 0x2a1 },
+      { 0x165, 0x17a, 0x191, 0x1a9, 0x1c2, 0x1dd, 0x1f9, 0x217, 0x237, 0x259, 0x27c, 0x2a2 },
+      { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1de, 0x1fa, 0x218, 0x238, 0x25a, 0x27e, 0x2a3 },
+      { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1df, 0x1fb, 0x219, 0x239, 0x25b, 0x27f, 0x2a4 },
+      { 0x167, 0x17c, 0x193, 0x1ab, 0x1c4, 0x1e0, 0x1fc, 0x21a, 0x23a, 0x25c, 0x280, 0x2a6 },
+      { 0x168, 0x17d, 0x194, 0x1ac, 0x1c5, 0x1e0, 0x1fd, 0x21b, 0x23b, 0x25d, 0x281, 0x2a7 },
+      { 0x168, 0x17d, 0x194, 0x1ad, 0x1c6, 0x1e1, 0x1fe, 0x21c, 0x23c, 0x25e, 0x282, 0x2a8 },
+      { 0x169, 0x17e, 0x195, 0x1ad, 0x1c7, 0x1e2, 0x1ff, 0x21d, 0x23d, 0x260, 0x283, 0x2a9 },
+      { 0x16a, 0x17f, 0x196, 0x1ae, 0x1c8, 0x1e3, 0x1ff, 0x21e, 0x23e, 0x261, 0x284, 0x2ab },
+      { 0x16a, 0x17f, 0x197, 0x1af, 0x1c8, 0x1e4, 0x200, 0x21f, 0x23f, 0x262, 0x286, 0x2ac }
+   };
+
+// Slot numbers as a function of the voice and the operator.
+// ( melodic only)
+
+static int slotVoice[ NUM_VOICES ][ 2 ] =
+   {
+      { 0, 3 },    // voice 0
+      { 1, 4 },    // 1
+      { 2, 5 },    // 2
+      { 6, 9 },    // 3
+      { 7, 10 },   // 4
+      { 8, 11 },   // 5
+      { 12, 15 },  // 6
+      { 13, 16 },  // 7
+      { 14, 17 },  // 8
+   };
+
+static int VoiceLevel[ NumChipSlots ][ 2 ];
+static int VoiceKsl[ NumChipSlots ][ 2 ];
+
+// This table gives the offset of each slot within the chip.
+// offset = fn( slot)
+
+static char offsetSlot[ NumChipSlots ] =
+   {
+    0,  1,  2,  3,  4,  5,
+    8,  9, 10, 11, 12, 13,
+   16, 17, 18, 19, 20, 21
+   };
+
+static int VoiceReserved[ NUM_VOICES * 2 ] =
+   {
+   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
+   FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
+   };
+
+static VOICE     Voice[ NUM_VOICES * 2 ];
+static VOICELIST Voice_Pool;
+
+static CHANNEL   Channel[ NUM_CHANNELS ];
+
+static int AL_LeftPort   = 0x388;
+static int AL_RightPort  = 0x388;
+static int AL_Stereo     = FALSE;
+static int AL_SendStereo = FALSE;
+static int AL_OPL3       = FALSE;
+static int AL_MaxMidiChannel = 16;
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define AL_LockStart AL_SendOutputToPort
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SendOutputToPort
+
+   Sends data to the Adlib using a specified port.
+---------------------------------------------------------------------*/
+
+void AL_SendOutputToPort
+   (
+   int  port,
+   int  reg,
+   int  data
+   )
+
+   {
+   int delay;
+
+   outp( port, reg );
+
+   for( delay = 6; delay > 0 ; delay-- )
+//   for( delay = 2; delay > 0 ; delay-- )
+      {
+      inp( port );
+      }
+
+   outp( port + 1, data );
+
+//   for( delay = 35; delay > 0 ; delay-- )
+   for( delay = 27; delay > 0 ; delay-- )
+//   for( delay = 2; delay > 0 ; delay-- )
+      {
+      inp( port );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SendOutput
+
+   Sends data to the Adlib.
+---------------------------------------------------------------------*/
+
+void AL_SendOutput
+   (
+   int  voice,
+   int  reg,
+   int  data
+   )
+
+   {
+   int port;
+
+   if ( AL_SendStereo )
+      {
+      AL_SendOutputToPort( AL_LeftPort, reg, data );
+      AL_SendOutputToPort( AL_RightPort, reg, data );
+      }
+   else
+      {
+      port = ( voice == 0 ) ? AL_RightPort : AL_LeftPort;
+      AL_SendOutputToPort( port, reg, data );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetVoiceTimbre
+
+   Programs the specified voice's timbre.
+---------------------------------------------------------------------*/
+
+static void AL_SetVoiceTimbre
+   (
+   int voice
+   )
+
+   {
+   int    off;
+   int    slot;
+   int    port;
+   int    voc;
+   int    patch;
+   int    channel;
+   TIMBRE *timbre;
+
+   channel = Voice[ voice ].channel;
+
+   if ( channel == 9 )
+      {
+      patch = Voice[ voice ].key + 128;
+      }
+   else
+      {
+      patch = Channel[ channel ].Timbre;
+      }
+
+   if ( Voice[ voice ].timbre == patch )
+      {
+      return;
+      }
+
+   Voice[ voice ].timbre = patch;
+   timbre = &ADLIB_TimbreBank[ patch ];
+
+   port = Voice[ voice ].port;
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
+   slot = slotVoice[ voc ][ 0 ];
+   off  = offsetSlot[ slot ];
+
+   VoiceLevel[ slot ][ port ] = 63 - ( timbre->Level[ 0 ] & 0x3f );
+   VoiceKsl[ slot ][ port ]   = timbre->Level[ 0 ] & 0xc0;
+
+   AL_SendOutput( port, 0xA0 + voc, 0 );
+   AL_SendOutput( port, 0xB0 + voc, 0 );
+
+   // Let voice clear the release
+   AL_SendOutput( port, 0x80 + off, 0xff );
+
+   AL_SendOutput( port, 0x60 + off, timbre->Env1[ 0 ] );
+   AL_SendOutput( port, 0x80 + off, timbre->Env2[ 0 ] );
+   AL_SendOutput( port, 0x20 + off, timbre->SAVEK[ 0 ] );
+   AL_SendOutput( port, 0xE0 + off, timbre->Wave[ 0 ] );
+
+   AL_SendOutput( port, 0x40 + off, timbre->Level[ 0 ] );
+   slot = slotVoice[ voc ][ 1 ];
+
+   if ( AL_SendStereo )
+      {
+      AL_SendOutputToPort( AL_LeftPort, 0xC0 + voice,
+         ( timbre->Feedback & 0x0f ) | 0x20 );
+      AL_SendOutputToPort( AL_RightPort, 0xC0 + voice,
+         ( timbre->Feedback & 0x0f ) | 0x10 );
+      }
+   else
+      {
+      if ( AL_OPL3 )
+         {
+         AL_SendOutput( port, 0xC0 + voc, ( timbre->Feedback & 0x0f ) |
+            0x30 );
+         }
+      else
+         {
+         AL_SendOutputToPort( ADLIB_PORT, 0xC0 + voice, timbre->Feedback );
+         }
+      }
+
+   off = offsetSlot[ slot ];
+
+   VoiceLevel[ slot ][ port ] = 63 - ( timbre->Level[ 1 ] & 0x3f );
+   VoiceKsl[ slot ][ port ]   = timbre->Level[ 1 ] & 0xc0;
+   AL_SendOutput( port, 0x40 + off, 63 );
+
+   // Let voice clear the release
+   AL_SendOutput( port, 0x80 + off, 0xff );
+
+   AL_SendOutput( port, 0x60 + off, timbre->Env1[ 1 ] );
+   AL_SendOutput( port, 0x80 + off, timbre->Env2[ 1 ] );
+   AL_SendOutput( port, 0x20 + off, timbre->SAVEK[ 1 ] );
+   AL_SendOutput( port, 0xE0 + off, timbre->Wave[ 1 ] );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetVoiceVolume
+
+   Sets the volume of the specified voice.
+---------------------------------------------------------------------*/
+
+static void AL_SetVoiceVolume
+   (
+   int voice
+   )
+
+   {
+   int channel;
+   int velocity;
+   int slot;
+   int port;
+   int voc;
+   unsigned long t1;
+   unsigned long t2;
+   unsigned long volume;
+   TIMBRE *timbre;
+
+   channel = Voice[ voice ].channel;
+
+   timbre = &ADLIB_TimbreBank[ Voice[ voice ].timbre ];
+
+   velocity = Voice[ voice ].velocity + timbre->Velocity;
+   velocity = min( velocity, MAX_VELOCITY );
+
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
+   slot = slotVoice[ voc ][ 1 ];
+   port = Voice[ voice ].port;
+
+   // amplitude
+   t1  = ( unsigned )VoiceLevel[ slot ][ port ];
+   t1 *= ( velocity + 0x80 );
+   t1  = ( Channel[ channel ].Volume * t1 ) >> 15;
+
+   if ( !AL_SendStereo )
+      {
+      volume  = t1 ^ 63;
+      volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+      AL_SendOutput( port, 0x40 + offsetSlot[ slot ], volume );
+
+      // Check if this timbre is Additive
+      if ( timbre->Feedback & 0x01 )
+         {
+         slot = slotVoice[ voc ][ 0 ];
+
+         // amplitude
+         t2  = ( unsigned )VoiceLevel[ slot ][ port ];
+         t2 *= ( velocity + 0x80 );
+         t2  = ( Channel[ channel ].Volume * t1 ) >> 15;
+
+         volume  = t2 ^ 63;
+         volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+         AL_SendOutput( port, 0x40 + offsetSlot[ slot ], volume );
+         }
+      }
+   else
+      {
+      // Set left channel volume
+      volume = t1;
+      if ( Channel[ channel ].Pan < 64 )
+         {
+         volume *= Channel[ channel ].Pan;
+         volume >>= 6;
+         }
+
+      volume ^= 63;
+      volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+      AL_SendOutputToPort( AL_LeftPort, 0x40 + offsetSlot[ slot ], volume );
+
+      // Set right channel volume
+      volume = t1;
+      if ( Channel[ channel ].Pan > 64 )
+         {
+         volume *= 127 - Channel[ channel ].Pan;
+         volume >>= 6;
+         }
+
+      volume ^= 63;
+      volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+      AL_SendOutputToPort( AL_RightPort, 0x40 + offsetSlot[ slot ], volume );
+
+      // Check if this timbre is Additive
+      if ( timbre->Feedback & 0x01 )
+         {
+         // amplitude
+         t2  = ( unsigned )VoiceLevel[ slot ][ port ];
+         t2 *= ( velocity + 0x80 );
+         t2  = ( Channel[ channel ].Volume * t1 ) >> 15;
+
+         slot = slotVoice[ voc ][ 0 ];
+
+         // Set left channel volume
+         volume = t2;
+         if ( Channel[ channel ].Pan < 64 )
+            {
+            volume *= Channel[ channel ].Pan;
+            volume >>= 6;
+            }
+
+         volume ^= 63;
+         volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+         AL_SendOutputToPort( AL_LeftPort, 0x40 + offsetSlot[ slot ], volume );
+
+         // Set right channel volume
+         volume = t2;
+         if ( Channel[ channel ].Pan > 64 )
+            {
+            volume *= 127 - Channel[ channel ].Pan;
+            volume >>= 6;
+            }
+
+         volume ^= 63;
+         volume |= ( unsigned )VoiceKsl[ slot ][ port ];
+
+         AL_SendOutputToPort( AL_RightPort, 0x40 + offsetSlot[ slot ], volume );
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_AllocVoice
+
+   Retrieves a free voice from the voice pool.
+---------------------------------------------------------------------*/
+
+static int AL_AllocVoice
+   (
+   void
+   )
+
+   {
+   int voice;
+
+   if ( Voice_Pool.start )
+      {
+      voice = Voice_Pool.start->num;
+      LL_Remove( VOICE, &Voice_Pool, &Voice[ voice ] );
+      return( voice );
+      }
+
+   return( AL_VoiceNotFound );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_GetVoice
+
+   Determines which voice is associated with a specified note and
+   MIDI channel.
+---------------------------------------------------------------------*/
+
+static int AL_GetVoice
+   (
+   int channel,
+   int key
+   )
+
+   {
+   VOICE *voice;
+
+   voice = Channel[ channel ].Voices.start;
+
+   while( voice != NULL )
+      {
+      if ( voice->key == key )
+         {
+         return( voice->num );
+         }
+      voice = voice->next;
+      }
+
+   return( AL_VoiceNotFound );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetVoicePitch
+
+   Programs the pitch of the specified voice.
+---------------------------------------------------------------------*/
+
+static void AL_SetVoicePitch
+   (
+   int voice
+   )
+
+   {
+   int note;
+   int channel;
+   int patch;
+   int detune;
+   int ScaleNote;
+   int Octave;
+   int pitch;
+   int port;
+   int voc;
+
+   port = Voice[ voice ].port;
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
+   channel = Voice[ voice ].channel;
+
+   if ( channel == 9 )
+      {
+      patch = Voice[ voice ].key + 128;
+      note  = ADLIB_TimbreBank[ patch ].Transpose;
+      }
+   else
+      {
+      patch = Channel[ channel ].Timbre;
+      note  = Voice[ voice ].key + ADLIB_TimbreBank[ patch ].Transpose;
+      }
+
+   note += Channel[ channel ].KeyOffset - 12;
+   if ( note > MAX_NOTE )
+      {
+      note = MAX_NOTE;
+      }
+   if ( note < 0 )
+      {
+      note = 0;
+      }
+
+   detune = Channel[ channel ].KeyDetune;
+
+   ScaleNote = NoteMod12[ note ];
+   Octave    = NoteDiv12[ note ];
+
+   pitch = OctavePitch[ Octave ] | NotePitch[ detune ][ ScaleNote ];
+
+   Voice[ voice ].pitchleft = pitch;
+
+   pitch |= Voice[ voice ].status;
+
+   if ( !AL_SendStereo )
+      {
+      AL_SendOutput( port, 0xA0 + voc, pitch );
+      AL_SendOutput( port, 0xB0 + voc, pitch >> 8 );
+      }
+   else
+      {
+      AL_SendOutputToPort( AL_LeftPort, 0xA0 + voice, pitch );
+      AL_SendOutputToPort( AL_LeftPort, 0xB0 + voice, pitch >> 8 );
+
+      if ( channel != 9 )
+         {
+         detune += STEREO_DETUNE;
+         }
+
+      if ( detune > FINETUNE_MAX )
+         {
+         detune -= FINETUNE_RANGE;
+         if ( note < MAX_NOTE )
+            {
+            note++;
+            ScaleNote = NoteMod12[ note ];
+            Octave    = NoteDiv12[ note ];
+            }
+         }
+
+      pitch = OctavePitch[ Octave ] | NotePitch[ detune ][ ScaleNote ];
+
+      Voice[ voice ].pitchright = pitch;
+
+      pitch |= Voice[ voice ].status;
+
+      AL_SendOutputToPort( AL_RightPort, 0xA0 + voice, pitch );
+      AL_SendOutputToPort( AL_RightPort, 0xB0 + voice, pitch >> 8 );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetChannelVolume
+
+   Sets the volume of the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+static void AL_SetChannelVolume
+   (
+   int channel,
+   int volume
+   )
+
+   {
+   VOICE *voice;
+
+   volume = max( 0, volume );
+   volume = min( volume, AL_MaxVolume );
+   Channel[ channel ].Volume = volume;
+
+   voice = Channel[ channel ].Voices.start;
+   while( voice != NULL )
+      {
+      AL_SetVoiceVolume( voice->num );
+      voice = voice->next;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetChannelPan
+
+   Sets the pan position of the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+static void AL_SetChannelPan
+   (
+   int channel,
+   int pan
+   )
+
+   {
+   // Don't pan drum sounds
+   if ( channel != 9 )
+      {
+      Channel[ channel ].Pan = pan;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetChannelDetune
+
+   Sets the stereo voice detune of the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+static void AL_SetChannelDetune
+   (
+   int channel,
+   int detune
+   )
+
+   {
+   Channel[ channel ].Detune = detune;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_ResetVoices
+
+   Sets all voice info to the default state.
+---------------------------------------------------------------------*/
+
+static void AL_ResetVoices
+   (
+   void
+   )
+
+   {
+   int index;
+   int numvoices;
+
+   Voice_Pool.start = NULL;
+   Voice_Pool.end = NULL;
+
+   numvoices = NUM_VOICES;
+   if ( ( AL_OPL3 ) && ( !AL_Stereo ) )
+      {
+      numvoices = NUM_VOICES * 2;
+      }
+   for( index = 0; index < numvoices; index++ )
+      {
+      if ( VoiceReserved[ index ] == FALSE )
+         {
+         Voice[ index ].num = index;
+         Voice[ index ].key = 0;
+         Voice[ index ].velocity = 0;
+         Voice[ index ].channel = -1;
+         Voice[ index ].timbre = -1;
+         Voice[ index ].port = ( index < NUM_VOICES ) ? 0 : 1;
+         Voice[ index ].status = NOTE_OFF;
+         LL_AddToTail( VOICE, &Voice_Pool, &Voice[ index ] );
+         }
+      }
+
+   for( index = 0; index < NUM_CHANNELS; index++ )
+      {
+      Channel[ index ].Voices.start    = NULL;
+      Channel[ index ].Voices.end      = NULL;
+      Channel[ index ].Timbre          = 0;
+      Channel[ index ].Pitchbend       = 0;
+      Channel[ index ].KeyOffset       = 0;
+      Channel[ index ].KeyDetune       = 0;
+      Channel[ index ].Volume          = AL_DefaultChannelVolume;
+      Channel[ index ].Pan             = 64;
+      Channel[ index ].RPN             = 0;
+      Channel[ index ].PitchBendRange     = AL_DefaultPitchBendRange;
+      Channel[ index ].PitchBendSemiTones = AL_DefaultPitchBendRange / 100;
+      Channel[ index ].PitchBendHundreds  = AL_DefaultPitchBendRange % 100;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_CalcPitchInfo
+
+   Calculates the pitch table.
+---------------------------------------------------------------------*/
+
+static void AL_CalcPitchInfo
+   (
+   void
+   )
+
+   {
+   int    note;
+//   int    finetune;
+//   double detune;
+
+   for( note = 0; note <= MAX_NOTE; note++ )
+      {
+      NoteMod12[ note ] = note % 12;
+      NoteDiv12[ note ] = note / 12;
+      }
+
+//   for( finetune = 1; finetune <= FINETUNE_MAX; finetune++ )
+//      {
+//      detune = pow( 2, ( double )finetune / ( 12.0 * FINETUNE_RANGE ) );
+//      for( note = 0; note < 12; note++ )
+//         {
+//         NotePitch[ finetune ][ note ] = ( ( double )NotePitch[ 0 ][ note ] * detune );
+//         }
+//      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_FlushCard
+
+   Sets all voices to a known (quiet) state.
+---------------------------------------------------------------------*/
+
+void AL_FlushCard
+   (
+   int port
+   )
+
+   {
+   int i;
+   unsigned slot1;
+   unsigned slot2;
+
+   for( i = 0 ; i < NUM_VOICES; i++ )
+      {
+      if ( VoiceReserved[ i ] == FALSE )
+         {
+         slot1 = offsetSlot[ slotVoice[ i ][ 0 ] ];
+         slot2 = offsetSlot[ slotVoice[ i ][ 1 ] ];
+
+         AL_SendOutputToPort( port, 0xA0 + i, 0 );
+         AL_SendOutputToPort( port, 0xB0 + i, 0 );
+
+         AL_SendOutputToPort( port, 0xE0 + slot1, 0 );
+         AL_SendOutputToPort( port, 0xE0 + slot2, 0 );
+
+         // Set the envelope to be fast and quiet
+         AL_SendOutputToPort( port, 0x60 + slot1, 0xff );
+         AL_SendOutputToPort( port, 0x60 + slot2, 0xff );
+         AL_SendOutputToPort( port, 0x80 + slot1, 0xff );
+         AL_SendOutputToPort( port, 0x80 + slot2, 0xff );
+
+         // Maximum attenuation
+         AL_SendOutputToPort( port, 0x40 + slot1, 0xff );
+         AL_SendOutputToPort( port, 0x40 + slot2, 0xff );
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_StereoOn
+
+   Sets the card send info in stereo.
+---------------------------------------------------------------------*/
+
+void AL_StereoOn
+   (
+   void
+   )
+
+   {
+   if ( ( AL_Stereo ) && ( !AL_SendStereo ) )
+      {
+      AL_SendStereo = TRUE;
+      if ( AL_OPL3 )
+         {
+         // Set card to OPL3 operation
+         AL_SendOutputToPort( AL_RightPort, 0x5, 1 );
+         }
+      }
+   else if ( AL_OPL3 )
+      {
+      // Set card to OPL3 operation
+      AL_SendOutputToPort( AL_RightPort, 0x5, 1 );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_StereoOff
+
+   Sets the card send info in mono.
+---------------------------------------------------------------------*/
+
+void AL_StereoOff
+   (
+   void
+   )
+
+   {
+   if ( ( AL_Stereo ) && ( AL_SendStereo ) )
+      {
+      AL_SendStereo = FALSE;
+      if ( AL_OPL3 )
+         {
+         // Set card back to OPL2 operation
+         AL_SendOutputToPort( AL_RightPort, 0x5, 0 );
+         }
+      }
+   else if ( AL_OPL3 )
+      {
+      // Set card back to OPL2 operation
+      AL_SendOutputToPort( AL_RightPort, 0x5, 0 );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_Reset
+
+   Sets the card to a known (quiet) state.
+---------------------------------------------------------------------*/
+
+void AL_Reset
+   (
+   void
+   )
+
+   {
+   AL_SendOutputToPort( ADLIB_PORT, 1, 0x20 );
+   AL_SendOutputToPort( ADLIB_PORT, 0x08, 0 );
+
+   // Set the values: AM Depth, VIB depth & Rhythm
+   AL_SendOutputToPort( ADLIB_PORT, 0xBD, 0 );
+
+   AL_StereoOn();
+
+   if ( ( AL_SendStereo ) || ( AL_OPL3 ) )
+      {
+      AL_FlushCard( AL_LeftPort );
+      AL_FlushCard( AL_RightPort );
+      }
+   else
+      {
+      AL_FlushCard( ADLIB_PORT );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_ReserveVoice
+
+   Marks a voice as being not available for use.  This allows the
+   driver to use the rest of the card while another driver uses the
+   reserved voice.
+---------------------------------------------------------------------*/
+
+int AL_ReserveVoice
+   (
+   int voice
+   )
+
+   {
+   unsigned flags;
+
+   if ( ( voice < 0 ) || ( voice >= NUM_VOICES ) )
+      {
+      return( AL_Error );
+      }
+
+   if ( VoiceReserved[ voice ] )
+      {
+      return( AL_Warning );
+      }
+
+   flags = DisableInterrupts();
+
+   if ( Voice[ voice ].status == NOTE_ON )
+      {
+      AL_NoteOff( Voice[ voice ].channel, Voice[ voice ].key, 0 );
+      }
+
+   VoiceReserved[ voice ] = TRUE;
+   LL_Remove( VOICE, &Voice_Pool, &Voice[ voice ] );
+
+   RestoreInterrupts( flags );
+   return( AL_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_ReleaseVoice
+
+   Marks a previously reserved voice as being free to use.
+---------------------------------------------------------------------*/
+
+int AL_ReleaseVoice
+   (
+   int voice
+   )
+
+   {
+   unsigned flags;
+
+   if ( ( voice < 0 ) || ( voice >= NUM_VOICES ) )
+      {
+      return( AL_Error );
+      }
+
+   if ( !VoiceReserved[ voice ] )
+      {
+      return( AL_Warning );
+      }
+
+   flags = DisableInterrupts();
+
+   VoiceReserved[ voice ] = FALSE;
+   LL_AddToTail( VOICE, &Voice_Pool, &Voice[ voice ] );
+
+   RestoreInterrupts( flags );
+   return( AL_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_NoteOff
+
+   Turns off a note on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void AL_NoteOff
+   (
+   int channel,
+   int key,
+   int velocity
+   )
+
+   {
+   int voice;
+   int port;
+   int voc;
+
+   // We only play channels 1 through 10
+   if ( channel > AL_MaxMidiChannel )
+      {
+      return;
+      }
+
+   voice = AL_GetVoice( channel, key );
+
+   if ( voice == AL_VoiceNotFound )
+      {
+      return;
+      }
+
+   Voice[ voice ].status = NOTE_OFF;
+
+   port = Voice[ voice ].port;
+   voc  = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
+
+   if ( AL_SendStereo )
+      {
+      AL_SendOutputToPort( AL_LeftPort, 0xB0 + voice,
+         hibyte( Voice[ voice ].pitchleft ) );
+      AL_SendOutputToPort( AL_RightPort, 0xB0 + voice,
+         hibyte( Voice[ voice ].pitchright ) );
+      }
+   else
+      {
+      AL_SendOutput( port, 0xB0 + voc, hibyte( Voice[ voice ].pitchleft ) );
+      }
+
+   LL_Remove( VOICE, &Channel[ channel ].Voices, &Voice[ voice ] );
+   LL_AddToTail( VOICE, &Voice_Pool, &Voice[ voice ] );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_NoteOn
+
+   Plays a note on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void AL_NoteOn
+   (
+   int channel,
+   int key,
+   int velocity
+   )
+
+   {
+   int voice;
+
+   // We only play channels 1 through 10
+   if ( channel > AL_MaxMidiChannel )
+      {
+      return;
+      }
+
+   if ( velocity == 0 )
+      {
+      AL_NoteOff( channel, key, velocity );
+      return;
+      }
+
+   voice = AL_AllocVoice();
+
+   if ( voice == AL_VoiceNotFound )
+      {
+      if ( Channel[ 9 ].Voices.start )
+         {
+         AL_NoteOff( 9, Channel[ 9 ].Voices.start->key, 0 );
+         voice = AL_AllocVoice();
+         }
+      if ( voice == AL_VoiceNotFound )
+         {
+         return;
+         }
+      }
+
+   Voice[ voice ].key      = key;
+   Voice[ voice ].channel  = channel;
+   Voice[ voice ].velocity = velocity;
+   Voice[ voice ].status   = NOTE_ON;
+
+   LL_AddToTail( VOICE, &Channel[ channel ].Voices, &Voice[ voice ] );
+
+   AL_SetVoiceTimbre( voice );
+   AL_SetVoiceVolume( voice );
+   AL_SetVoicePitch( voice );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_AllNotesOff
+
+   Turns off all currently playing voices.
+---------------------------------------------------------------------*/
+
+void AL_AllNotesOff
+   (
+   int channel
+   )
+
+   {
+   while( Channel[ channel ].Voices.start != NULL )
+      {
+      AL_NoteOff( channel, Channel[ channel ].Voices.start->key, 0 );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_ControlChange
+
+   Sets the value of a controller on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void AL_ControlChange
+   (
+   int channel,
+   int type,
+   int data
+   )
+
+   {
+   // We only play channels 1 through 10
+   if ( channel > AL_MaxMidiChannel )
+      {
+      return;
+      }
+
+   switch( type )
+      {
+      case MIDI_VOLUME :
+         AL_SetChannelVolume( channel, data );
+         break;
+
+      case MIDI_PAN :
+         AL_SetChannelPan( channel, data );
+         break;
+
+      case MIDI_DETUNE :
+         AL_SetChannelDetune( channel, data );
+         break;
+
+      case MIDI_ALL_NOTES_OFF :
+         AL_AllNotesOff( channel );
+         break;
+
+      case MIDI_RESET_ALL_CONTROLLERS :
+         AL_ResetVoices();
+         AL_SetChannelVolume( channel, AL_DefaultChannelVolume );
+         AL_SetChannelPan( channel, 64 );
+         AL_SetChannelDetune( channel, 0 );
+         break;
+
+      case MIDI_RPN_MSB :
+         Channel[ channel ].RPN &= 0x00FF;
+         Channel[ channel ].RPN |= ( data & 0xFF ) << 8;
+         break;
+
+      case MIDI_RPN_LSB :
+         Channel[ channel ].RPN &= 0xFF00;
+         Channel[ channel ].RPN |= data & 0xFF;
+         break;
+
+      case MIDI_DATAENTRY_MSB :
+         if ( Channel[ channel ].RPN == MIDI_PITCHBEND_RPN )
+            {
+            Channel[ channel ].PitchBendSemiTones = data;
+            Channel[ channel ].PitchBendRange     =
+               Channel[ channel ].PitchBendSemiTones * 100 +
+               Channel[ channel ].PitchBendHundreds;
+            }
+         break;
+
+      case MIDI_DATAENTRY_LSB :
+         if ( Channel[ channel ].RPN == MIDI_PITCHBEND_RPN )
+            {
+            Channel[ channel ].PitchBendHundreds = data;
+            Channel[ channel ].PitchBendRange    =
+               Channel[ channel ].PitchBendSemiTones * 100 +
+               Channel[ channel ].PitchBendHundreds;
+            }
+         break;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_ProgramChange
+
+   Selects the instrument to use on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void AL_ProgramChange
+   (
+   int channel,
+   int patch
+   )
+
+   {
+   // We only play channels 1 through 10
+   if ( channel > AL_MaxMidiChannel )
+      {
+      return;
+      }
+
+   Channel[ channel ].Timbre  = patch;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetPitchBend
+
+   Sets the pitch bend amount on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void AL_SetPitchBend
+   (
+   int channel,
+   int lsb,
+   int msb
+   )
+
+   {
+   int            pitchbend;
+   unsigned long  TotalBend;
+   VOICE         *voice;
+
+   // We only play channels 1 through 10
+   if ( channel > AL_MaxMidiChannel )
+      {
+      return;
+      }
+
+   pitchbend = lsb + ( msb << 8 );
+   Channel[ channel ].Pitchbend = pitchbend;
+
+   TotalBend  = pitchbend * Channel[ channel ].PitchBendRange;
+   TotalBend /= ( PITCHBEND_CENTER / FINETUNE_RANGE );
+
+   Channel[ channel ].KeyOffset  = ( int )( TotalBend / FINETUNE_RANGE );
+   Channel[ channel ].KeyOffset -= Channel[ channel ].PitchBendSemiTones;
+
+   Channel[ channel ].KeyDetune = ( unsigned )( TotalBend % FINETUNE_RANGE );
+
+   voice = Channel[ channel ].Voices.start;
+   while( voice != NULL )
+      {
+      AL_SetVoicePitch( voice->num );
+      voice = voice->next;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_DetectFM
+
+   Determines if an Adlib compatible card is installed in the machine.
+---------------------------------------------------------------------*/
+
+int AL_DetectFM
+   (
+   void
+   )
+
+   {
+   int status1;
+   int status2;
+   int i;
+
+   if ( USER_CheckParameter( NO_ADLIB_DETECTION ) )
+      {
+      return( FALSE );
+      }
+
+   AL_SendOutputToPort( ADLIB_PORT, 4, 0x60 );   // Reset T1 & T2
+   AL_SendOutputToPort( ADLIB_PORT, 4, 0x80 );   // Reset IRQ
+
+   status1 = inp( ADLIB_PORT );
+
+   AL_SendOutputToPort( ADLIB_PORT, 2, 0xff );   // Set timer 1
+   AL_SendOutputToPort( ADLIB_PORT, 4, 0x21 );   // Start timer 1
+
+   for( i = 100; i > 0; i-- )
+      {
+      inp( ADLIB_PORT );
+      }
+
+   status2 = inp( ADLIB_PORT );
+
+   AL_SendOutputToPort( ADLIB_PORT, 4, 0x60 );
+   AL_SendOutputToPort( ADLIB_PORT, 4, 0x80 );
+
+   return( ( ( status1 & 0xe0 ) == 0x00 ) && ( ( status2 & 0xe0 ) == 0xc0 ) );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void AL_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_Shutdown
+
+   Ends use of the sound card and resets it to a quiet state.
+---------------------------------------------------------------------*/
+
+void AL_Shutdown
+   (
+   void
+   )
+
+   {
+   AL_StereoOff();
+
+   AL_OPL3 = FALSE;
+   AL_ResetVoices();
+   AL_Reset();
+
+   DPMI_UnlockMemoryRegion( AL_LockStart, AL_LockEnd );
+   DPMI_Unlock( slotVoice );
+   DPMI_Unlock( VoiceLevel );
+   DPMI_Unlock( VoiceKsl );
+   DPMI_Unlock( offsetSlot );
+   DPMI_Unlock( NotePitch );
+   DPMI_Unlock( OctavePitch );
+   DPMI_Unlock( NoteMod12 );
+   DPMI_Unlock( NoteDiv12 );
+   DPMI_Unlock( VoiceReserved );
+   DPMI_Unlock( Voice );
+   DPMI_Unlock( Voice_Pool );
+   DPMI_Unlock( Channel );
+   DPMI_Unlock( AL_LeftPort );
+   DPMI_Unlock( AL_RightPort );
+   DPMI_Unlock( AL_Stereo );
+   DPMI_Unlock( AL_SendStereo );
+   DPMI_Unlock( AL_OPL3 );
+   DPMI_Unlock( AL_MaxMidiChannel );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_SetMaxMidiChannel
+
+   Sets the maximum MIDI channel that FM cards respond to.
+---------------------------------------------------------------------*/
+
+void AL_SetMaxMidiChannel
+   (
+   int channel
+   )
+
+   {
+   AL_MaxMidiChannel = channel - 1;
+   }
+
+/*---------------------------------------------------------------------
+   Function: AL_Init
+
+   Begins use of the sound card.
+---------------------------------------------------------------------*/
+
+int AL_Init
+   (
+   int soundcard
+   )
+
+   {
+   BLASTER_CONFIG Blaster;
+   int status;
+
+   status  = DPMI_LockMemoryRegion( AL_LockStart, AL_LockEnd );
+   status |= DPMI_Lock( slotVoice );
+   status |= DPMI_Lock( VoiceLevel );
+   status |= DPMI_Lock( VoiceKsl );
+   status |= DPMI_Lock( offsetSlot );
+   status |= DPMI_Lock( NotePitch );
+   status |= DPMI_Lock( OctavePitch );
+   status |= DPMI_Lock( NoteMod12 );
+   status |= DPMI_Lock( NoteDiv12 );
+   status |= DPMI_Lock( VoiceReserved );
+   status |= DPMI_Lock( Voice );
+   status |= DPMI_Lock( Voice_Pool );
+   status |= DPMI_Lock( Channel );
+   status |= DPMI_Lock( AL_LeftPort );
+   status |= DPMI_Lock( AL_RightPort );
+   status |= DPMI_Lock( AL_Stereo );
+   status |= DPMI_Lock( AL_SendStereo );
+   status |= DPMI_Lock( AL_OPL3 );
+   status |= DPMI_Lock( AL_MaxMidiChannel );
+
+   if ( status != DPMI_Ok )
+      {
+      return( AL_Error );
+      }
+
+   AL_Stereo = FALSE;
+   AL_OPL3   = FALSE;
+   AL_LeftPort = 0x388;
+   AL_RightPort = 0x388;
+
+   switch( soundcard )
+      {
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         AL_OPL3 = TRUE;
+         AL_LeftPort = 0x388;
+         AL_RightPort = 0x38A;
+         break;
+
+      case SoundBlaster :
+         status = BLASTER_GetCardSettings( &Blaster );
+         if ( status != BLASTER_Ok )
+            {
+            status = BLASTER_GetEnv( &Blaster );
+            if ( status != BLASTER_Ok )
+               {
+               break;
+               }
+            }
+
+         switch( Blaster.Type )
+            {
+            case SBPro2 :
+            case SB16 :
+               AL_OPL3 = TRUE;
+               AL_LeftPort  = Blaster.Address;
+               AL_RightPort = Blaster.Address + 2;
+               break;
+            }
+         break;
+      }
+// Temporarally commented out for ROTT.
+// Stereo FM seems to take too long on some computers and
+// causes the mouse driver to miss interrupts.
+
+/*
+   switch( soundcard )
+      {
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         AL_OPL3 = TRUE;
+         AL_Stereo = TRUE;
+         AL_LeftPort  = 0x388;
+         AL_RightPort = 0x38A;
+         break;
+
+      case SoundBlaster :
+         status = BLASTER_GetCardSettings( &Blaster );
+         if ( status != BLASTER_Ok )
+            {
+            status = BLASTER_GetEnv( &Blaster );
+            if ( status != BLASTER_Ok )
+               {
+               break;
+               }
+            }
+
+         switch( Blaster.Type )
+            {
+            case SBPro2 :
+            case SB16 :
+               AL_OPL3 = TRUE;
+               AL_Stereo = TRUE;
+               AL_LeftPort  = Blaster.Address;
+               AL_RightPort = Blaster.Address + 2;
+               break;
+
+            case SBPro :
+               AL_Stereo = TRUE;
+               AL_LeftPort  = Blaster.Address;
+               AL_RightPort = Blaster.Address + 2;
+               break;
+            }
+         break;
+      }
+*/
+
+   AL_CalcPitchInfo();
+   AL_Reset();
+   AL_ResetVoices();
+
+   return( AL_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AL_RegisterTimbreBank
+
+   Copies user supplied timbres over the default timbre bank.
+---------------------------------------------------------------------*/
+
+void AL_RegisterTimbreBank
+   (
+   unsigned char *timbres
+   )
+
+   {
+   int i;
+
+   for( i = 0; i < 256; i++ )
+      {
+      ADLIB_TimbreBank[ i ].SAVEK[ 0 ] = *( timbres++ );
+      ADLIB_TimbreBank[ i ].SAVEK[ 1 ] = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Level[ 0 ] = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Level[ 1 ] = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Env1[ 0 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Env1[ 1 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Env2[ 0 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Env2[ 1 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Wave[ 0 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Wave[ 1 ]  = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Feedback   = *( timbres++ );
+      ADLIB_TimbreBank[ i ].Transpose  = *( signed char * )( timbres++ );
+      ADLIB_TimbreBank[ i ].Velocity   = *( signed char * )( timbres++ );
+      }
+   }

Added: tags/rott-1.1/rott/audiolib/al_midi.h
===================================================================
--- tags/rott-1.1/rott/audiolib/al_midi.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/al_midi.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,58 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef __AL_MIDI_H
+#define __AL_MIDI_H
+
+enum AL_Errors
+   {
+   AL_Warning  = -2,
+   AL_Error    = -1,
+   AL_Ok       = 0,
+   };
+
+#define AL_MaxVolume             127
+#define AL_DefaultChannelVolume  90
+//#define AL_DefaultPitchBendRange 2
+#define AL_DefaultPitchBendRange 200
+
+#define ADLIB_PORT 0x388
+
+void AL_SendOutputToPort( int port, int reg, int data );
+void AL_SendOutput( int  voice, int reg, int data );
+void AL_StereoOn( void );
+void AL_StereoOff( void );
+int  AL_ReserveVoice( int voice );
+int  AL_ReleaseVoice( int voice );
+void AL_Shutdown( void );
+int  AL_Init( int soundcard );
+void AL_SetMaxMidiChannel( int channel );
+void AL_Reset( void );
+void AL_NoteOff( int channel, int key, int velocity );
+void AL_NoteOn( int channel, int key, int vel );
+//Turned off to test if it works with Watcom 10a
+//   #pragma aux AL_NoteOn frame;
+void AL_AllNotesOff( int channel );
+void AL_ControlChange( int channel, int type, int data );
+void AL_ProgramChange( int channel, int patch );
+void AL_SetPitchBend( int channel, int lsb, int msb );
+int  AL_DetectFM( void );
+void AL_RegisterTimbreBank( unsigned char *timbres );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/assert.h
===================================================================
--- tags/rott-1.1/rott/audiolib/assert.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/assert.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,45 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef    __ASSERT_H
+
+    #define    __ASSERT_H
+
+    #ifdef NDEBUG
+
+        #define ASSERT(f)
+
+    #else
+
+        #pragma aux _Assert aborts;          /* _Assert will not return */
+        extern void _Assert( char *strFile, unsigned  uLine ); /*prototype */
+
+        #define ASSERT(f)          \
+            if (f)                 \
+                ;                  \
+            else                   \
+                _Assert( __FILE__, __LINE__ )
+
+    #endif
+
+#else
+
+    #error Multiple definition of ASSERT()
+
+#endif

Added: tags/rott-1.1/rott/audiolib/awe32.c
===================================================================
--- tags/rott-1.1/rott/audiolib/awe32.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/awe32.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,540 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: AWE32.C
+
+   author: James R. Dose
+   date:   August 23, 1994
+
+   Cover functions for calling the AWE32 low-level library.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <conio.h>
+#include <string.h>
+#include "dpmi.h"
+#include "blaster.h"
+#include "ctaweapi.h"
+#include "awe32.h"
+
+#define _inp    inp
+#define _outp   outp
+
+/*  DSP defines  */
+#define MPU_ACK_OK          0xfe
+#define MPU_RESET_CMD       0xff
+#define MPU_ENTER_UART      0x3f
+
+static WORD wSBCBaseAddx;            /* Sound Blaster base address */
+static WORD wEMUBaseAddx;            /* EMU8000 subsystem base address */
+static WORD wMpuBaseAddx;            /* MPU401 base address */
+
+static unsigned short NoteFlags[ 128 ];
+
+/*  macros  */
+#define SBCPort( x )  ( ( x ) + wSBCBaseAddx )
+#define MPUPort( x )  ( ( x ) + wMpuBaseAddx )
+
+static SOUND_PACKET spSound =
+   {
+   0
+   };
+
+static LONG lBankSizes[ MAXBANKS ] =
+   {
+   0
+   };
+
+unsigned SetES( void );
+#pragma aux SetES = \
+        "xor eax, eax" \
+        "mov ax, es" \
+        "mov bx, ds" \
+        "mov es, bx" \
+        modify [ eax ebx ];
+
+void RestoreES( unsigned num );
+#pragma aux RestoreES = \
+        "mov  es, ax" \
+        parm [ eax ];
+
+int AWE32_ErrorCode = AWE32_Ok;
+
+#define AWE32_SetErrorCode( status ) \
+   AWE32_ErrorCode = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: AWE32_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *AWE32_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case AWE32_Warning :
+      case AWE32_Error :
+         ErrorString = AWE32_ErrorString( AWE32_ErrorCode );
+         break;
+
+      case AWE32_Ok :
+         ErrorString = "AWE32 ok.";
+         break;
+
+      case AWE32_SoundBlasterError :
+         ErrorString = BLASTER_ErrorString( BLASTER_Error );
+         break;
+
+      case AWE32_NotDetected :
+         ErrorString = "Could not detect AWE32.";
+         break;
+
+      case AWE32_UnableToInitialize :
+         ErrorString = "Unable to initialize AWE32.";
+
+      case AWE32_MPU401Error :
+         ErrorString = "MPU-401 initialization failed in AWE32.";
+         break;
+
+      case AWE32_DPMI_Error :
+         ErrorString = "DPMI Error in AWE32.";
+         break;
+
+      default :
+         ErrorString = "Unknown AWE32 error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define AWE32_LockStart AWE32_NoteOff
+
+
+void AWE32_NoteOff
+   (
+   int channel,
+   int key,
+   int velocity
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32NoteOff( channel, key, velocity );
+   RestoreES( temp );
+   NoteFlags[ key ] ^= ( 1 << channel );
+   }
+
+void AWE32_NoteOn
+   (
+   int channel,
+   int key,
+   int velocity
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32NoteOn( channel, key, velocity );
+   RestoreES( temp );
+   NoteFlags[ key ] |= ( 1 << channel );
+   }
+
+void AWE32_PolyAftertouch
+   (
+   int channel,
+   int key,
+   int pressure
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32PolyKeyPressure( channel, key, pressure );
+   RestoreES( temp );
+   }
+
+void AWE32_ChannelAftertouch
+   (
+   int channel,
+   int pressure
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32ChannelPressure( channel, pressure );
+   RestoreES( temp );
+   }
+
+void AWE32_ControlChange
+   (
+   int channel,
+   int number,
+   int value
+   )
+
+   {
+   unsigned temp;
+   int i;
+   unsigned channelmask;
+
+   temp = SetES();
+
+   if ( number == 0x7b )
+      {
+      channelmask = 1 << channel;
+      for( i = 0; i < 128; i++ )
+         {
+         if ( NoteFlags[ i ] & channelmask )
+            {
+            awe32NoteOff( channel, i, 0 );
+            NoteFlags[ i ] ^= channelmask;
+            }
+         }
+      }
+   else
+      {
+      awe32Controller( channel, number, value );
+      }
+   RestoreES( temp );
+   }
+
+void AWE32_ProgramChange
+   (
+   int channel,
+   int program
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32ProgramChange( channel, program );
+   RestoreES( temp );
+   }
+
+void AWE32_PitchBend
+   (
+   int channel,
+   int lsb,
+   int msb
+   )
+
+   {
+   unsigned temp;
+
+   temp = SetES();
+   awe32PitchBend( channel, lsb, msb );
+   RestoreES( temp );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: AWE32_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void AWE32_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*
+static int InitMPU
+   (
+   void
+   )
+
+   {
+   volatile DWORD dwCount;
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
+   _outp(MPUPort(1), MPU_RESET_CMD);
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
+   _inp(MPUPort(0));
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
+   _outp(MPUPort(1), MPU_RESET_CMD);
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
+   _inp(MPUPort(0));
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
+   _outp(MPUPort(1), MPU_ENTER_UART);
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
+   if (!dwCount) return TRUE;
+   if (_inp(MPUPort(0)) != MPU_ACK_OK) return TRUE;
+
+   // mask MPU-401 interrupt
+   _outp(SBCPort(0x4), 0x83);
+   _outp(SBCPort(0x5), _inp(SBCPort(0x5)) & ~0x04);
+
+   return FALSE;
+   }
+*/
+
+/*ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸*/
+/*³ ShutdownMPU                                                    ³*/
+/*³ Cleans up Sound Blaster to normal state.                               ³*/
+/*ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;*/
+
+static void ShutdownMPU
+   (
+   void
+   )
+
+   {
+   volatile DWORD dwCount;
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
+   _outp(MPUPort(1), MPU_RESET_CMD);
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   _inp(MPUPort(0));
+
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   dwCount = 0x2000;
+   while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
+   _outp(MPUPort(1), MPU_RESET_CMD);
+   for (dwCount=0; dwCount<0x2000; dwCount++) ;
+   _inp(MPUPort(0));
+   }
+
+
+/*ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸*/
+/*³ LoadSBK                                                                ³*/
+/*ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;*/
+
+static void LoadSBK
+   (
+   void
+   )
+
+   {
+   /* use embeded preset objects */
+   spSound.bank_no = 0;            /* load as Bank 0 */
+   spSound.total_banks = 1;        /* use 1 bank first */
+   lBankSizes[ 0 ] = 0;            /* ram is not needed */
+
+   spSound.banksizes = lBankSizes;
+   awe32DefineBankSizes( &spSound );
+   awe32SoundPad.SPad1 = awe32SPad1Obj;
+   awe32SoundPad.SPad2 = awe32SPad2Obj;
+   awe32SoundPad.SPad3 = awe32SPad3Obj;
+   awe32SoundPad.SPad4 = awe32SPad4Obj;
+   awe32SoundPad.SPad5 = awe32SPad5Obj;
+   awe32SoundPad.SPad6 = awe32SPad6Obj;
+   awe32SoundPad.SPad7 = awe32SPad7Obj;
+   }
+
+
+int AWE32_Init
+   (
+   void
+   )
+
+   {
+   int status;
+   BLASTER_CONFIG Blaster;
+
+   wSBCBaseAddx = 0x220;
+   wEMUBaseAddx = 0x620;
+   wMpuBaseAddx = 0x330;
+
+   status = BLASTER_GetCardSettings( &Blaster );
+   if ( status != BLASTER_Ok )
+      {
+      status = BLASTER_GetEnv( &Blaster );
+      if ( status != BLASTER_Ok )
+         {
+         AWE32_SetErrorCode( AWE32_SoundBlasterError );
+         return( AWE32_Error );
+         }
+      }
+
+   wSBCBaseAddx = Blaster.Address;
+   if ( wSBCBaseAddx == UNDEFINED )
+      {
+      wSBCBaseAddx = 0x220;
+      }
+
+   wMpuBaseAddx = Blaster.Midi;
+   if ( wMpuBaseAddx == UNDEFINED )
+      {
+      wMpuBaseAddx = 0x330;
+      }
+
+   wEMUBaseAddx = Blaster.Emu;
+   if ( wEMUBaseAddx <= 0 )
+      {
+      wEMUBaseAddx = wSBCBaseAddx + 0x400;
+      }
+
+   status = awe32Detect( wEMUBaseAddx );
+   if ( status )
+      {
+      AWE32_SetErrorCode( AWE32_NotDetected );
+      return( AWE32_Error );
+      }
+
+   status = awe32InitHardware();
+   if ( status )
+      {
+      AWE32_SetErrorCode( AWE32_UnableToInitialize );
+      return( AWE32_Error );
+      }
+
+
+   status = awe32InitMIDI();
+   if ( status )
+      {
+      AWE32_Shutdown();
+      AWE32_SetErrorCode( AWE32_MPU401Error )
+      return( AWE32_Error );
+      }
+
+/*
+    status = InitMPU();
+   if ( status )
+      {
+      ShutdownMPU();
+      status = InitMPU();
+      if ( status )
+         {
+         ShutdownMPU();
+         status = InitMPU();
+         if ( status )
+            {
+            AWE32_Shutdown();
+            AWE32_SetErrorCode( AWE32_MPU401Error )
+            return( AWE32_Error );
+            }
+         }
+      }
+*/
+   status  = DPMI_LockMemoryRegion( AWE32_LockStart, AWE32_LockEnd );
+   status |= DPMI_Lock( wSBCBaseAddx );
+   status |= DPMI_Lock( wEMUBaseAddx );
+   status |= DPMI_Lock( wMpuBaseAddx );
+   status |= DPMI_Lock( spSound );
+   status |= DPMI_Lock( lBankSizes );
+   status |= DPMI_LockMemory( NoteFlags, sizeof( NoteFlags ) );
+
+   // Lock awe32 library
+   status  = DPMI_LockMemoryRegion( __midieng_code, __midieng_ecode );
+   status  = DPMI_LockMemoryRegion( __midieng_code(), __midieng_ecode() );
+   status  = DPMI_LockMemoryRegion( __nrpn_code, __nrpn_ecode );
+   status  = DPMI_LockMemoryRegion( __nrpn_code(), __nrpn_ecode() );
+   status  = DPMI_LockMemoryRegion( &__midivar_data, &__midivar_edata );
+   status  = DPMI_LockMemoryRegion( &__nrpnvar_data, &__nrpnvar_edata );
+   status  = DPMI_LockMemoryRegion( &__embed_data, &__embed_edata );
+
+   if ( status != DPMI_Ok )
+      {
+      ShutdownMPU();
+      awe32Terminate();
+      AWE32_SetErrorCode( AWE32_DPMI_Error );
+      return( AWE32_Error );
+      }
+
+   // Set the number of voices to use to 32
+   awe32NumG = 32;
+
+   awe32TotalPatchRam(&spSound);
+
+   LoadSBK();
+   awe32InitMIDI();
+   awe32InitNRPN();
+
+   memset( NoteFlags, 0, sizeof( NoteFlags ) );
+
+   return( AWE32_Ok );
+   }
+
+void AWE32_Shutdown
+   (
+   void
+   )
+
+   {
+   ShutdownMPU();
+   awe32Terminate();
+
+   DPMI_UnlockMemoryRegion( AWE32_LockStart, AWE32_LockEnd );
+   DPMI_Unlock( wSBCBaseAddx );
+   DPMI_Unlock( wEMUBaseAddx );
+   DPMI_Unlock( wMpuBaseAddx );
+   DPMI_Unlock( spSound );
+   DPMI_Unlock( lBankSizes );
+   DPMI_UnlockMemory( NoteFlags, sizeof( NoteFlags ) );
+
+   // Unlock awe32 library
+   DPMI_UnlockMemoryRegion( __midieng_code, __midieng_ecode );
+   DPMI_UnlockMemoryRegion( __midieng_code(), __midieng_ecode() );
+   DPMI_UnlockMemoryRegion( __nrpn_code, __nrpn_ecode );
+   DPMI_UnlockMemoryRegion( __nrpn_code(), __nrpn_ecode() );
+   DPMI_UnlockMemoryRegion( &__midivar_data, &__midivar_edata );
+   DPMI_UnlockMemoryRegion( &__nrpnvar_data, &__nrpnvar_edata );
+   DPMI_UnlockMemoryRegion( &__embed_data, &__embed_edata );
+   }

Added: tags/rott-1.1/rott/audiolib/awe32.h
===================================================================
--- tags/rott-1.1/rott/audiolib/awe32.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/awe32.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,58 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: AWE32.H
+
+   author: James R. Dose
+   date:   August 23, 1994
+
+   Public header for AWE32.C  Cover functions for calling the
+   AWE32 low-level library.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __AWE32_H
+#define __AWE32_H
+
+enum AWE32_ERRORS
+   {
+   AWE32_Warning = -2,
+   AWE32_Error = -1,
+   AWE32_Ok = 0,
+   AWE32_SoundBlasterError,
+   AWE32_NotDetected,
+   AWE32_UnableToInitialize,
+   AWE32_MPU401Error,
+   AWE32_DPMI_Error
+   };
+
+char *AWE32_ErrorString( int ErrorNumber );
+int  AWE32_Init( void );
+void AWE32_Shutdown( void );
+void AWE32_NoteOff( int channel, int key, int velocity );
+void AWE32_NoteOn( int channel, int key, int velocity );
+void AWE32_PolyAftertouch( int channel, int key, int pressure );
+void AWE32_ChannelAftertouch( int channel, int pressure );
+void AWE32_ControlChange( int channel, int number, int value );
+void AWE32_ProgramChange( int channel, int program );
+void AWE32_PitchBend( int channel, int lsb, int msb );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/blaster.c
===================================================================
--- tags/rott-1.1/rott/audiolib/blaster.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/blaster.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,2330 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: BLASTER.C
+
+   author: James R. Dose
+   date:   February 4, 1994
+
+   Low level routines to support Sound Blaster, Sound Blaster Pro,
+   Sound Blaster 16, and compatible sound cards.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <dos.h>
+#include <conio.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "dpmi.h"
+#include "dma.h"
+#include "irq.h"
+#include "blaster.h"
+#include "_blaster.h"
+
+#define USESTACK
+
+const int BLASTER_Interrupts[ BLASTER_MaxIrq + 1 ]  =
+   {
+   INVALID, INVALID,     0xa,     0xb,
+   INVALID,     0xd, INVALID,     0xf,
+   INVALID, INVALID,    0x72,    0x73,
+      0x74, INVALID, INVALID,    0x77
+   };
+
+const int BLASTER_SampleSize[ BLASTER_MaxMixMode + 1 ] =
+   {
+   MONO_8BIT_SAMPLE_SIZE,  STEREO_8BIT_SAMPLE_SIZE,
+   MONO_16BIT_SAMPLE_SIZE, STEREO_16BIT_SAMPLE_SIZE
+   };
+
+const CARD_CAPABILITY BLASTER_CardConfig[ BLASTER_MaxCardType + 1 ] =
+   {
+      { FALSE, INVALID,      INVALID, INVALID, INVALID }, // Unsupported
+      {  TRUE,      NO,    MONO_8BIT,    4000,   23000 }, // SB 1.0
+      {  TRUE,     YES,  STEREO_8BIT,    4000,   44100 }, // SBPro
+      {  TRUE,      NO,    MONO_8BIT,    4000,   23000 }, // SB 2.xx
+      {  TRUE,     YES,  STEREO_8BIT,    4000,   44100 }, // SBPro 2
+      { FALSE, INVALID,      INVALID, INVALID, INVALID }, // Unsupported
+      {  TRUE,     YES, STEREO_16BIT,    5000,   44100 }, // SB16
+   };
+
+CARD_CAPABILITY BLASTER_Card;
+
+static void    ( __interrupt __far *BLASTER_OldInt )( void );
+
+BLASTER_CONFIG BLASTER_Config =
+   {
+   UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED
+   };
+
+static int BLASTER_Installed = FALSE;
+
+int BLASTER_Version;
+
+static char   *BLASTER_DMABuffer;
+static char   *BLASTER_DMABufferEnd;
+static char   *BLASTER_CurrentDMABuffer;
+static int     BLASTER_TotalDMABufferSize;
+
+static int      BLASTER_TransferLength   = 0;
+static int      BLASTER_MixMode          = BLASTER_DefaultMixMode;
+static int      BLASTER_SamplePacketSize = MONO_16BIT_SAMPLE_SIZE;
+static unsigned BLASTER_SampleRate       = BLASTER_DefaultSampleRate;
+
+static unsigned BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+
+volatile int   BLASTER_SoundPlaying;
+volatile int   BLASTER_SoundRecording;
+
+void ( *BLASTER_CallBack )( void );
+
+static int  BLASTER_IntController1Mask;
+static int  BLASTER_IntController2Mask;
+
+static int BLASTER_MixerAddress = UNDEFINED;
+static int BLASTER_MixerType    = 0;
+static int BLASTER_OriginalMidiVolumeLeft   = 255;
+static int BLASTER_OriginalMidiVolumeRight  = 255;
+static int BLASTER_OriginalVoiceVolumeLeft  = 255;
+static int BLASTER_OriginalVoiceVolumeRight = 255;
+
+static int BLASTER_WaveBlasterState = 0x0F;
+
+// adequate stack size
+#define kStackSize 2048
+
+static unsigned short StackSelector = NULL;
+static unsigned long  StackPointer;
+
+static unsigned short oldStackSelector;
+static unsigned long  oldStackPointer;
+
+// This is defined because we can't create local variables in a
+// function that switches stacks.
+static int GlobalStatus;
+
+// These declarations are necessary to use the inline assembly pragmas.
+
+extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
+extern void SetStack(unsigned short selector,unsigned long stackptr);
+
+// This function will get the current stack selector and pointer and save
+// them off.
+#pragma aux GetStack =  \
+   "mov  [edi],esp"     \
+   "mov  ax,ss"         \
+   "mov  [esi],ax"      \
+   parm [esi] [edi]     \
+   modify [eax esi edi];
+
+// This function will set the stack selector and pointer to the specified
+// values.
+#pragma aux SetStack =  \
+   "mov  ss,ax"         \
+   "mov  esp,edx"       \
+   parm [ax] [edx]      \
+   modify [eax edx];
+
+int BLASTER_DMAChannel;
+
+int BLASTER_ErrorCode = BLASTER_Ok;
+
+#define BLASTER_SetErrorCode( status ) \
+   BLASTER_ErrorCode   = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *BLASTER_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case BLASTER_Warning :
+      case BLASTER_Error :
+         ErrorString = BLASTER_ErrorString( BLASTER_ErrorCode );
+         break;
+
+      case BLASTER_Ok :
+         ErrorString = "Sound Blaster ok.";
+         break;
+
+      case BLASTER_EnvNotFound :
+         ErrorString = "BLASTER environment variable not set.";
+         break;
+
+      case BLASTER_AddrNotSet :
+         ErrorString = "Sound Blaster address not set.";
+         break;
+
+      case BLASTER_DMANotSet :
+         ErrorString = "Sound Blaster 8-bit DMA channel not set.";
+         break;
+
+      case BLASTER_DMA16NotSet :
+         ErrorString = "Sound Blaster 16-bit DMA channel not set.";
+         break;
+
+      case BLASTER_InvalidParameter :
+         ErrorString = "Invalid parameter in BLASTER environment variable.";
+         break;
+
+      case BLASTER_CardNotReady :
+         ErrorString = "Sound Blaster not responding on selected port.";
+         break;
+
+      case BLASTER_NoSoundPlaying :
+         ErrorString = "No sound playing on Sound Blaster.";
+         break;
+
+      case BLASTER_InvalidIrq :
+         ErrorString = "Invalid Sound Blaster Irq.";
+         break;
+
+      case BLASTER_UnableToSetIrq :
+         ErrorString = "Unable to set Sound Blaster IRQ.  Try selecting an IRQ of 7 or below.";
+         break;
+
+      case BLASTER_DmaError :
+         ErrorString = DMA_ErrorString( DMA_Error );
+         break;
+
+      case BLASTER_NoMixer :
+         ErrorString = "Mixer not available on selected Sound Blaster card.";
+         break;
+
+      case BLASTER_DPMI_Error :
+         ErrorString = "DPMI Error in Blaster.";
+         break;
+
+      case BLASTER_OutOfMemory :
+         ErrorString = "Out of conventional memory in Blaster.";
+         break;
+
+      default :
+         ErrorString = "Unknown Sound Blaster error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define BLASTER_LockStart BLASTER_EnableInterrupt
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_EnableInterrupt
+
+   Enables the triggering of the sound card interrupt.
+---------------------------------------------------------------------*/
+
+void BLASTER_EnableInterrupt
+   (
+   void
+   )
+
+   {
+   int Irq;
+   int mask;
+
+   // Unmask system interrupt
+   Irq  = BLASTER_Config.Interrupt;
+   if ( Irq < 8 )
+      {
+      mask = inp( 0x21 ) & ~( 1 << Irq );
+      outp( 0x21, mask  );
+      }
+   else
+      {
+      mask = inp( 0xA1 ) & ~( 1 << ( Irq - 8 ) );
+      outp( 0xA1, mask  );
+
+      mask = inp( 0x21 ) & ~( 1 << 2 );
+      outp( 0x21, mask  );
+      }
+
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DisableInterrupt
+
+   Disables the triggering of the sound card interrupt.
+---------------------------------------------------------------------*/
+
+void BLASTER_DisableInterrupt
+   (
+   void
+   )
+
+   {
+   int Irq;
+   int mask;
+
+   // Restore interrupt mask
+   Irq  = BLASTER_Config.Interrupt;
+   if ( Irq < 8 )
+      {
+      mask  = inp( 0x21 ) & ~( 1 << Irq );
+      mask |= BLASTER_IntController1Mask & ( 1 << Irq );
+      outp( 0x21, mask  );
+      }
+   else
+      {
+      mask  = inp( 0x21 ) & ~( 1 << 2 );
+      mask |= BLASTER_IntController1Mask & ( 1 << 2 );
+      outp( 0x21, mask  );
+
+      mask  = inp( 0xA1 ) & ~( 1 << ( Irq - 8 ) );
+      mask |= BLASTER_IntController2Mask & ( 1 << ( Irq - 8 ) );
+      outp( 0xA1, mask  );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ServiceInterrupt
+
+   Handles interrupt generated by sound card at the end of a voice
+   transfer.  Calls the user supplied callback function.
+---------------------------------------------------------------------*/
+
+void __interrupt __far BLASTER_ServiceInterrupt
+   (
+   void
+   )
+
+   {
+   #ifdef USESTACK
+   // save stack
+   GetStack( &oldStackSelector, &oldStackPointer );
+
+   // set our stack
+   SetStack( StackSelector, StackPointer );
+   #endif
+
+   // Acknowledge interrupt
+   // Check if this is this an SB16 or newer
+   if ( BLASTER_Version >= DSP_Version4xx )
+      {
+      outp( BLASTER_Config.Address + BLASTER_MixerAddressPort,
+         MIXER_DSP4xxISR_Ack );
+
+      GlobalStatus = inp( BLASTER_Config.Address + BLASTER_MixerDataPort );
+
+      // Check if a 16-bit DMA interrupt occurred
+      if ( GlobalStatus & MIXER_16BITDMA_INT )
+         {
+         // Acknowledge 16-bit transfer interrupt
+         inp( BLASTER_Config.Address + BLASTER_16BitDMAAck );
+         }
+      else if ( GlobalStatus & MIXER_8BITDMA_INT )
+         {
+         inp( BLASTER_Config.Address + BLASTER_DataAvailablePort );
+         }
+      else
+         {
+         #ifdef USESTACK
+         // restore stack
+         SetStack( oldStackSelector, oldStackPointer );
+         #endif
+
+         // Wasn't our interrupt.  Call the old one.
+         _chain_intr( BLASTER_OldInt );
+         }
+      }
+   else
+      {
+      // Older card - can't detect if an interrupt occurred.
+      inp( BLASTER_Config.Address + BLASTER_DataAvailablePort );
+      }
+
+   // Keep track of current buffer
+   BLASTER_CurrentDMABuffer += BLASTER_TransferLength;
+
+   if ( BLASTER_CurrentDMABuffer >= BLASTER_DMABufferEnd )
+      {
+      BLASTER_CurrentDMABuffer = BLASTER_DMABuffer;
+      }
+
+   // Continue playback on cards without autoinit mode
+   if ( BLASTER_Version < DSP_Version2xx )
+      {
+      if ( BLASTER_SoundPlaying )
+         {
+         BLASTER_DSP1xx_BeginPlayback( BLASTER_TransferLength );
+         }
+
+      if ( BLASTER_SoundRecording )
+         {
+         BLASTER_DSP1xx_BeginRecord( BLASTER_TransferLength );
+         }
+      }
+
+   // Call the caller's callback function
+   if ( BLASTER_CallBack != NULL )
+      {
+      BLASTER_CallBack();
+      }
+
+   #ifdef USESTACK
+   // restore stack
+   SetStack( oldStackSelector, oldStackPointer );
+   #endif
+
+   // send EOI to Interrupt Controller
+   if ( BLASTER_Config.Interrupt > 7 )
+      {
+      outp( 0xA0, 0x20 );
+      }
+
+   outp( 0x20, 0x20 );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_WriteDSP
+
+   Writes a byte of data to the sound card's DSP.
+---------------------------------------------------------------------*/
+
+int BLASTER_WriteDSP
+   (
+   unsigned data
+   )
+
+   {
+   int      port;
+   unsigned count;
+   int      status;
+
+   port = BLASTER_Config.Address + BLASTER_WritePort;
+
+   status = BLASTER_Error;
+
+   count = 0xFFFF;
+
+   do
+      {
+      if ( ( inp( port ) & 0x80 ) == 0 )
+         {
+         outp( port, data );
+         status = BLASTER_Ok;
+         break;
+         }
+
+      count--;
+      }
+   while( count > 0 );
+
+   if ( status != BLASTER_Ok )
+      {
+      BLASTER_SetErrorCode( BLASTER_CardNotReady );
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ReadDSP
+
+   Reads a byte of data from the sound card's DSP.
+---------------------------------------------------------------------*/
+
+int BLASTER_ReadDSP
+   (
+   void
+   )
+
+   {
+   int      port;
+   unsigned count;
+   int      status;
+
+   port = BLASTER_Config.Address + BLASTER_DataAvailablePort;
+
+   status = BLASTER_Error;
+
+   count = 0xFFFF;
+
+   do
+      {
+      if ( inp( port ) & 0x80 )
+         {
+         status = inp( BLASTER_Config.Address + BLASTER_ReadPort );
+         break;
+         }
+
+      count--;
+      }
+   while( count > 0 );
+
+   if ( status == BLASTER_Error )
+      {
+      BLASTER_SetErrorCode( BLASTER_CardNotReady );
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ResetDSP
+
+   Sends a reset command to the sound card's Digital Signal Processor
+   (DSP), causing it to perform an initialization.
+---------------------------------------------------------------------*/
+
+int BLASTER_ResetDSP
+   (
+   void
+   )
+
+   {
+   volatile int count;
+   int port;
+   int status;
+
+   port = BLASTER_Config.Address + BLASTER_ResetPort;
+
+   status = BLASTER_CardNotReady;
+
+   outp( port, 1 );
+
+/* What the hell am I doing here?
+   count = 100;
+
+   do
+      {
+      if ( inp( port ) == 255 )
+         {
+         break;
+         }
+
+      count--;
+      }
+   while( count > 0 );
+*/
+
+   count = 0x100;
+   do
+      {
+      count--;
+      }
+   while( count > 0 );
+
+   outp( port, 0 );
+
+   count = 100;
+
+   do
+      {
+      if ( BLASTER_ReadDSP() == BLASTER_Ready )
+         {
+         status = BLASTER_Ok;
+         break;
+         }
+
+      count--;
+      }
+   while( count > 0 );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetDSPVersion
+
+   Returns the version number of the sound card's DSP.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetDSPVersion
+   (
+   void
+   )
+
+   {
+   int MajorVersion;
+   int MinorVersion;
+   int version;
+
+   BLASTER_WriteDSP( DSP_GetVersion );
+
+   MajorVersion   = BLASTER_ReadDSP();
+   MinorVersion   = BLASTER_ReadDSP();
+
+   if ( ( MajorVersion == BLASTER_Error ) ||
+      ( MinorVersion == BLASTER_Error ) )
+      {
+      BLASTER_SetErrorCode( BLASTER_CardNotReady );
+      return( BLASTER_Error );
+      }
+
+   version = ( MajorVersion << 8 ) + MinorVersion;
+
+   if ( version >= DSP_Version4xx )
+      {
+      BLASTER_Card.IsSupported     = TRUE;
+      BLASTER_Card.HasMixer        = YES;
+      BLASTER_Card.MaxMixMode      = STEREO_16BIT;
+      BLASTER_Card.MinSamplingRate = 5000;
+      BLASTER_Card.MaxSamplingRate = 44100;
+      BLASTER_MixerType = SB16;
+      }
+   else if ( version >= DSP_Version3xx )
+      {
+      BLASTER_Card.IsSupported     = TRUE;
+      BLASTER_Card.HasMixer        = YES;
+      BLASTER_Card.MaxMixMode      = STEREO_8BIT;
+      BLASTER_Card.MinSamplingRate = 4000;
+      BLASTER_Card.MaxSamplingRate = 44100;
+      BLASTER_MixerType = SBPro;
+      }
+   else if ( version >= DSP_Version2xx )
+      {
+      BLASTER_Card.IsSupported     = TRUE;
+      BLASTER_Card.HasMixer        = NO;
+      BLASTER_Card.MaxMixMode      = MONO_8BIT;
+      BLASTER_Card.MinSamplingRate = 4000;
+      BLASTER_Card.MaxSamplingRate = 23000;
+      BLASTER_MixerType = 0;
+      }
+   else
+      {
+      // DSP_Version1xx
+      BLASTER_Card.IsSupported     = TRUE;
+      BLASTER_Card.HasMixer        = NO;
+      BLASTER_Card.MaxMixMode      = MONO_8BIT;
+      BLASTER_Card.MinSamplingRate = 4000;
+      BLASTER_Card.MaxSamplingRate = 23000;
+      BLASTER_MixerType = 0;
+      }
+
+   return( version );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SpeakerOn
+
+   Enables output from the DAC.
+---------------------------------------------------------------------*/
+
+void BLASTER_SpeakerOn
+   (
+   void
+   )
+
+   {
+   BLASTER_WriteDSP( DSP_SpeakerOn );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SpeakerOff
+
+   Disables output from the DAC.
+---------------------------------------------------------------------*/
+
+void BLASTER_SpeakerOff
+   (
+   void
+   )
+
+   {
+   BLASTER_WriteDSP( DSP_SpeakerOff );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetPlaybackRate
+
+   Sets the rate at which the digitized sound will be played in
+   hertz.
+---------------------------------------------------------------------*/
+
+void BLASTER_SetPlaybackRate
+   (
+   unsigned rate
+   )
+
+   {
+   int LoByte;
+   int HiByte;
+
+   if ( BLASTER_Version < DSP_Version4xx )
+      {
+      int  timeconstant;
+      long ActualRate;
+
+      // Send sampling rate as time constant for older Sound
+      // Blaster compatible cards.
+
+      ActualRate = rate * BLASTER_SamplePacketSize;
+      if ( ActualRate < BLASTER_Card.MinSamplingRate )
+         {
+         rate = BLASTER_Card.MinSamplingRate / BLASTER_SamplePacketSize;
+         }
+
+      if ( ActualRate > BLASTER_Card.MaxSamplingRate )
+         {
+         rate = BLASTER_Card.MaxSamplingRate / BLASTER_SamplePacketSize;
+         }
+
+      timeconstant = ( int )CalcTimeConstant( rate, BLASTER_SamplePacketSize );
+
+      // Keep track of what the actual rate is
+      BLASTER_SampleRate  = ( unsigned )CalcSamplingRate( timeconstant );
+      BLASTER_SampleRate /= BLASTER_SamplePacketSize;
+
+      BLASTER_WriteDSP( DSP_SetTimeConstant );
+      BLASTER_WriteDSP( timeconstant );
+      }
+   else
+      {
+      // Send literal sampling rate for cards with DSP version
+      // 4.xx (Sound Blaster 16)
+
+      BLASTER_SampleRate = rate;
+
+      if ( BLASTER_SampleRate < BLASTER_Card.MinSamplingRate )
+         {
+         BLASTER_SampleRate = BLASTER_Card.MinSamplingRate;
+         }
+
+      if ( BLASTER_SampleRate > BLASTER_Card.MaxSamplingRate )
+         {
+         BLASTER_SampleRate = BLASTER_Card.MaxSamplingRate;
+         }
+
+      HiByte = hibyte( BLASTER_SampleRate );
+      LoByte = lobyte( BLASTER_SampleRate );
+
+      // Set playback rate
+      BLASTER_WriteDSP( DSP_Set_DA_Rate );
+      BLASTER_WriteDSP( HiByte );
+      BLASTER_WriteDSP( LoByte );
+
+      // Set recording rate
+      BLASTER_WriteDSP( DSP_Set_AD_Rate );
+      BLASTER_WriteDSP( HiByte );
+      BLASTER_WriteDSP( LoByte );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetPlaybackRate
+
+   Returns the rate at which the digitized sound will be played in
+   hertz.
+---------------------------------------------------------------------*/
+
+unsigned BLASTER_GetPlaybackRate
+   (
+   void
+   )
+
+   {
+   return( BLASTER_SampleRate );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetMixMode
+
+   Sets the sound card to play samples in mono or stereo.
+---------------------------------------------------------------------*/
+
+int BLASTER_SetMixMode
+   (
+   int mode
+   )
+
+   {
+   int   port;
+   int   data;
+   int   CardType;
+
+   CardType = BLASTER_Config.Type;
+
+   mode &= BLASTER_MaxMixMode;
+
+   if ( !( BLASTER_Card.MaxMixMode & STEREO ) )
+      {
+      mode &= ~STEREO;
+      }
+
+   if ( !( BLASTER_Card.MaxMixMode & SIXTEEN_BIT ) )
+      {
+      mode &= ~SIXTEEN_BIT;
+      }
+
+   BLASTER_MixMode = mode;
+   BLASTER_SamplePacketSize = BLASTER_SampleSize[ mode ];
+
+   // For the Sound Blaster Pro, we have to set the mixer chip
+   // to play mono or stereo samples.
+
+   if ( ( CardType == SBPro ) || ( CardType == SBPro2 ) )
+      {
+      port = BLASTER_Config.Address + BLASTER_MixerAddressPort;
+      outp( port, MIXER_SBProOutputSetting );
+
+      port = BLASTER_Config.Address + BLASTER_MixerDataPort;
+
+      // Get current mode
+      data = inp( port );
+
+      // set stereo mode bit
+      if ( mode & STEREO )
+         {
+         data |= MIXER_SBProStereoFlag;
+         }
+      else
+         {
+         data &= ~MIXER_SBProStereoFlag;
+         }
+
+      // set the mode
+      outp( port, data );
+
+      BLASTER_SetPlaybackRate( BLASTER_SampleRate );
+      }
+
+   return( mode );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_StopPlayback
+
+   Ends the DMA transfer of digitized sound to the sound card.
+---------------------------------------------------------------------*/
+
+void BLASTER_StopPlayback
+   (
+   void
+   )
+
+   {
+   int DmaChannel;
+
+   // Don't allow anymore interrupts
+   BLASTER_DisableInterrupt();
+
+   if ( BLASTER_HaltTransferCommand == DSP_Reset )
+      {
+      BLASTER_ResetDSP();
+      }
+   else
+      {
+      BLASTER_WriteDSP( BLASTER_HaltTransferCommand );
+      }
+
+   // Disable the DMA channel
+   if ( BLASTER_MixMode & SIXTEEN_BIT )
+      {
+      DmaChannel = BLASTER_Config.Dma16;
+      }
+   else
+      {
+      DmaChannel = BLASTER_Config.Dma8;
+      }
+   DMA_EndTransfer( DmaChannel );
+
+   // Turn off speaker
+   BLASTER_SpeakerOff();
+
+   BLASTER_SoundPlaying = FALSE;
+   BLASTER_SoundRecording = FALSE;
+
+   BLASTER_DMABuffer = NULL;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetupDMABuffer
+
+   Programs the DMAC for sound transfer.
+---------------------------------------------------------------------*/
+
+int BLASTER_SetupDMABuffer
+   (
+   char *BufferPtr,
+   int   BufferSize,
+   int   mode
+   )
+
+   {
+   int DmaChannel;
+   int DmaStatus;
+   int errorcode;
+
+   if ( BLASTER_MixMode & SIXTEEN_BIT )
+      {
+      DmaChannel = BLASTER_Config.Dma16;
+      errorcode  = BLASTER_DMA16NotSet;
+      }
+   else
+      {
+      DmaChannel = BLASTER_Config.Dma8;
+      errorcode  = BLASTER_DMANotSet;
+      }
+
+   if ( DmaChannel == UNDEFINED )
+      {
+      BLASTER_SetErrorCode( errorcode );
+      return( BLASTER_Error );
+      }
+
+   DmaStatus = DMA_SetupTransfer( DmaChannel, BufferPtr, BufferSize, mode );
+   if ( DmaStatus == DMA_Error )
+      {
+      BLASTER_SetErrorCode( BLASTER_DmaError );
+      return( BLASTER_Error );
+      }
+
+   BLASTER_DMAChannel = DmaChannel;
+
+   BLASTER_DMABuffer          = BufferPtr;
+   BLASTER_CurrentDMABuffer   = BufferPtr;
+   BLASTER_TotalDMABufferSize = BufferSize;
+   BLASTER_DMABufferEnd       = BufferPtr + BufferSize;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetCurrentPos
+
+   Returns the offset within the current sound being played.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetCurrentPos
+   (
+   void
+   )
+
+   {
+   char *CurrentAddr;
+   int   DmaChannel;
+   int   offset;
+
+   if ( !BLASTER_SoundPlaying )
+      {
+      BLASTER_SetErrorCode( BLASTER_NoSoundPlaying );
+      return( BLASTER_Error );
+      }
+
+   if ( BLASTER_MixMode & SIXTEEN_BIT )
+      {
+      DmaChannel = BLASTER_Config.Dma16;
+      }
+   else
+      {
+      DmaChannel = BLASTER_Config.Dma8;
+      }
+
+   if ( DmaChannel == UNDEFINED )
+      {
+      BLASTER_SetErrorCode( BLASTER_DMANotSet );
+      return( BLASTER_Error );
+      }
+
+   CurrentAddr = DMA_GetCurrentPos( DmaChannel );
+
+   offset = ( int )( ( ( unsigned long )CurrentAddr ) -
+      ( ( unsigned long )BLASTER_CurrentDMABuffer ) );
+
+   if ( BLASTER_MixMode & SIXTEEN_BIT )
+      {
+      offset >>= 1;
+      }
+
+   if ( BLASTER_MixMode & STEREO )
+      {
+      offset >>= 1;
+      }
+
+   return( offset );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP1xx_BeginPlayback
+
+   Starts playback of digitized sound on cards compatible with DSP
+   version 1.xx.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP1xx_BeginPlayback
+   (
+   int length
+   )
+
+   {
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   SampleLength = length - 1;
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   // Program DSP to play sound
+   BLASTER_WriteDSP( DSP_Old8BitDAC );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+
+   BLASTER_SoundPlaying = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP2xx_BeginPlayback
+
+   Starts playback of digitized sound on cards compatible with DSP
+   version 2.xx.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP2xx_BeginPlayback
+   (
+   int length
+   )
+
+   {
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   SampleLength = length - 1;
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   BLASTER_WriteDSP( DSP_SetBlockLength );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   if ( ( BLASTER_Version >= DSP_Version201 ) && ( DSP_MaxNormalRate <
+      ( BLASTER_SampleRate * BLASTER_SamplePacketSize ) ) )
+      {
+      BLASTER_WriteDSP( DSP_8BitHighSpeedAutoInitMode );
+      BLASTER_HaltTransferCommand = DSP_Reset;
+      }
+   else
+      {
+      BLASTER_WriteDSP( DSP_8BitAutoInitMode );
+      BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+      }
+
+   BLASTER_SoundPlaying = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP4xx_BeginPlayback
+
+   Starts playback of digitized sound on cards compatible with DSP
+   version 4.xx, such as the Sound Blaster 16.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP4xx_BeginPlayback
+   (
+   int length
+   )
+
+   {
+   int TransferCommand;
+   int TransferMode;
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   if ( BLASTER_MixMode & SIXTEEN_BIT )
+      {
+      TransferCommand = DSP_16BitDAC;
+      SampleLength = ( length / 2 ) - 1;
+      BLASTER_HaltTransferCommand = DSP_Halt16bitTransfer;
+      if ( BLASTER_MixMode & STEREO )
+         {
+         TransferMode = DSP_SignedStereoData;
+         }
+      else
+         {
+         TransferMode = DSP_SignedMonoData;
+         }
+      }
+   else
+      {
+      TransferCommand = DSP_8BitDAC;
+      SampleLength = length - 1;
+      BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+      if ( BLASTER_MixMode & STEREO )
+         {
+         TransferMode = DSP_UnsignedStereoData;
+         }
+      else
+         {
+         TransferMode = DSP_UnsignedMonoData;
+         }
+      }
+
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   // Program DSP to play sound
+   BLASTER_WriteDSP( TransferCommand );
+   BLASTER_WriteDSP( TransferMode );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   BLASTER_SoundPlaying = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_BeginBufferedPlayback
+
+   Begins multibuffered playback of digitized sound on the sound card.
+---------------------------------------------------------------------*/
+
+int BLASTER_BeginBufferedPlayback
+   (
+   char    *BufferStart,
+   int      BufferSize,
+   int      NumDivisions,
+   unsigned SampleRate,
+   int      MixMode,
+   void  ( *CallBackFunc )( void )
+   )
+
+   {
+   int DmaStatus;
+   int TransferLength;
+
+//JIM
+//   if ( BLASTER_SoundPlaying || BLASTER_SoundRecording )
+      {
+      BLASTER_StopPlayback();
+      }
+
+   BLASTER_SetMixMode( MixMode );
+
+   DmaStatus = BLASTER_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitRead );
+   if ( DmaStatus == BLASTER_Error )
+      {
+      return( BLASTER_Error );
+      }
+
+   BLASTER_SetPlaybackRate( SampleRate );
+
+   BLASTER_SetCallBack( CallBackFunc );
+
+   BLASTER_EnableInterrupt();
+
+   // Turn on speaker
+   BLASTER_SpeakerOn();
+
+   TransferLength = BufferSize / NumDivisions;
+   BLASTER_TransferLength = TransferLength;
+
+   //  Program the sound card to start the transfer.
+   if ( BLASTER_Version < DSP_Version2xx )
+      {
+      BLASTER_DSP1xx_BeginPlayback( TransferLength );
+      }
+   else if ( BLASTER_Version < DSP_Version4xx )
+      {
+      BLASTER_DSP2xx_BeginPlayback( TransferLength );
+      }
+   else
+      {
+      BLASTER_DSP4xx_BeginPlayback( TransferLength );
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP4xx_BeginRecord
+
+   Starts recording of digitized sound on cards compatible with DSP
+   version 4.xx, such as the Sound Blaster 16.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP4xx_BeginRecord
+   (
+   int length
+   )
+
+   {
+   int TransferCommand;
+   int TransferMode;
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   TransferCommand = DSP_8BitADC;
+   SampleLength = length - 1;
+   BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+
+   TransferMode = DSP_UnsignedMonoData;
+
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   // Program DSP to play sound
+   BLASTER_WriteDSP( TransferCommand );
+   BLASTER_WriteDSP( TransferMode );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   BLASTER_SoundRecording = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP2xx_BeginRecord
+
+   Starts recording of digitized sound on cards compatible with DSP
+   version 2.xx.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP2xx_BeginRecord
+   (
+   int length
+   )
+
+   {
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   SampleLength = length - 1;
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   BLASTER_WriteDSP( DSP_SetBlockLength );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   if ( ( BLASTER_Version >= DSP_Version201 ) && ( DSP_MaxNormalRate <
+      ( BLASTER_SampleRate * BLASTER_SamplePacketSize ) ) )
+      {
+      BLASTER_WriteDSP( DSP_8BitHighSpeedAutoInitRecord );
+      BLASTER_HaltTransferCommand = DSP_Reset;
+      }
+   else
+      {
+      BLASTER_WriteDSP( DSP_8BitAutoInitRecord );
+      BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+      }
+
+   BLASTER_SoundRecording = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_DSP1xx_BeginRecord
+
+   Starts recording of digitized sound on cards compatible with DSP
+   version 1.xx.
+---------------------------------------------------------------------*/
+
+int BLASTER_DSP1xx_BeginRecord
+   (
+   int length
+   )
+
+   {
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   SampleLength = length - 1;
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+
+   // Program DSP to play sound
+   BLASTER_WriteDSP( DSP_Old8BitADC );
+   BLASTER_WriteDSP( LoByte );
+   BLASTER_WriteDSP( HiByte );
+
+   BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
+
+   BLASTER_SoundRecording = TRUE;
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_BeginBufferedRecord
+
+   Begins multibuffered recording of digitized sound on the sound card.
+---------------------------------------------------------------------*/
+
+int BLASTER_BeginBufferedRecord
+   (
+   char    *BufferStart,
+   int      BufferSize,
+   int      NumDivisions,
+   unsigned SampleRate,
+   int      MixMode,
+   void  ( *CallBackFunc )( void )
+   )
+
+   {
+   int DmaStatus;
+   int TransferLength;
+
+//JIM
+//   if ( BLASTER_SoundPlaying || BLASTER_SoundRecording )
+      {
+      BLASTER_StopPlayback();
+      }
+
+   BLASTER_SetMixMode( MixMode );
+
+   DmaStatus = BLASTER_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitWrite );
+   if ( DmaStatus == BLASTER_Error )
+      {
+      return( BLASTER_Error );
+      }
+
+   BLASTER_SetPlaybackRate( SampleRate );
+
+   BLASTER_SetCallBack( CallBackFunc );
+
+   BLASTER_EnableInterrupt();
+
+   // Turn off speaker
+   BLASTER_SpeakerOff();
+
+   TransferLength = BufferSize / NumDivisions;
+   BLASTER_TransferLength = TransferLength;
+
+   //  Program the sound card to start the transfer.
+   if ( BLASTER_Version < DSP_Version2xx )
+      {
+      BLASTER_DSP1xx_BeginRecord( TransferLength );
+      }
+   else if ( BLASTER_Version < DSP_Version4xx )
+      {
+      BLASTER_DSP2xx_BeginRecord( TransferLength );
+      }
+   else
+      {
+      BLASTER_DSP4xx_BeginRecord( TransferLength );
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_WriteMixer
+
+   Writes a byte of data to the Sound Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+void BLASTER_WriteMixer
+   (
+   int reg,
+   int data
+   )
+
+   {
+   outp( BLASTER_MixerAddress + BLASTER_MixerAddressPort, reg );
+   outp( BLASTER_MixerAddress + BLASTER_MixerDataPort, data );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ReadMixer
+
+   Reads a byte of data from the Sound Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+int BLASTER_ReadMixer
+   (
+   int reg
+   )
+
+   {
+   int data;
+
+   outp( BLASTER_MixerAddress + BLASTER_MixerAddressPort, reg );
+   data = inp( BLASTER_MixerAddress + BLASTER_MixerDataPort );
+   return( data );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetVoiceVolume
+
+   Reads the average volume of the digitized sound channel from the
+   Sound Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetVoiceVolume
+   (
+   void
+   )
+
+   {
+   int volume;
+   int left;
+   int right;
+
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         left   = BLASTER_ReadMixer( MIXER_SBProVoice );
+         right  = ( left & 0x0f ) << 4;
+         left  &= 0xf0;
+         volume = ( left + right ) / 2;
+         break;
+
+      case SB16 :
+         left  = BLASTER_ReadMixer( MIXER_SB16VoiceLeft );
+         right = BLASTER_ReadMixer( MIXER_SB16VoiceRight );
+         volume = ( left + right ) / 2;
+         break;
+
+      default :
+         BLASTER_SetErrorCode( BLASTER_NoMixer );
+         volume = BLASTER_Error;
+      }
+
+   return( volume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetVoiceVolume
+
+   Sets the volume of the digitized sound channel on the Sound
+   Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+int BLASTER_SetVoiceVolume
+   (
+   int volume
+   )
+
+   {
+   int data;
+   int status;
+
+   volume = min( 255, volume );
+   volume = max( 0, volume );
+
+   status = BLASTER_Ok;
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         data = ( volume & 0xf0 ) + ( volume >> 4 );
+         BLASTER_WriteMixer( MIXER_SBProVoice, data );
+         break;
+
+      case SB16 :
+         BLASTER_WriteMixer( MIXER_SB16VoiceLeft, volume & 0xf8 );
+         BLASTER_WriteMixer( MIXER_SB16VoiceRight, volume & 0xf8 );
+         break;
+
+      default :
+         BLASTER_SetErrorCode( BLASTER_NoMixer );
+         status = BLASTER_Error;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetMidiVolume
+
+   Reads the average volume of the Midi sound channel from the
+   Sound Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetMidiVolume
+   (
+   void
+   )
+
+   {
+   int volume;
+   int left;
+   int right;
+
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         left   = BLASTER_ReadMixer( MIXER_SBProMidi );
+         right  = ( left & 0x0f ) << 4;
+         left  &= 0xf0;
+         volume = ( left + right ) / 2;
+         break;
+
+      case SB16 :
+         left  = BLASTER_ReadMixer( MIXER_SB16MidiLeft );
+         right = BLASTER_ReadMixer( MIXER_SB16MidiRight );
+         volume = ( left + right ) / 2;
+         break;
+
+      default :
+         BLASTER_SetErrorCode( BLASTER_NoMixer );
+         volume = BLASTER_Error;
+      }
+
+   return( volume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetMidiVolume
+
+   Sets the volume of the Midi sound channel on the Sound
+   Blaster's mixer chip.
+---------------------------------------------------------------------*/
+
+int BLASTER_SetMidiVolume
+   (
+   int volume
+   )
+
+   {
+   int data;
+   int status;
+
+   volume = min( 255, volume );
+   volume = max( 0, volume );
+
+   status = BLASTER_Ok;
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         data = ( volume & 0xf0 ) + ( volume >> 4 );
+         BLASTER_WriteMixer( MIXER_SBProMidi, data );
+         break;
+
+      case SB16 :
+         BLASTER_WriteMixer( MIXER_SB16MidiLeft, volume & 0xf8 );
+         BLASTER_WriteMixer( MIXER_SB16MidiRight, volume & 0xf8 );
+         break;
+
+      default :
+         BLASTER_SetErrorCode( BLASTER_NoMixer );
+         status = BLASTER_Error;
+      }
+
+   return( status );
+   }
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_CardHasMixer
+
+   Checks if the selected Sound Blaster card has a mixer.
+---------------------------------------------------------------------*/
+
+int BLASTER_CardHasMixer
+   (
+   void
+   )
+
+   {
+   return( BLASTER_Card.HasMixer );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SaveVoiceVolume
+
+   Saves the user's voice mixer settings.
+---------------------------------------------------------------------*/
+
+void BLASTER_SaveVoiceVolume
+   (
+   void
+   )
+
+   {
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         BLASTER_OriginalVoiceVolumeLeft =
+            BLASTER_ReadMixer( MIXER_SBProVoice );
+         break;
+
+      case SB16 :
+         BLASTER_OriginalVoiceVolumeLeft =
+            BLASTER_ReadMixer( MIXER_SB16VoiceLeft );
+         BLASTER_OriginalVoiceVolumeRight =
+            BLASTER_ReadMixer( MIXER_SB16VoiceRight );
+         break;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_RestoreVoiceVolume
+
+   Restores the user's voice mixer settings.
+---------------------------------------------------------------------*/
+
+void BLASTER_RestoreVoiceVolume
+   (
+   void
+   )
+
+   {
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         BLASTER_WriteMixer( MIXER_SBProVoice,
+            BLASTER_OriginalVoiceVolumeLeft );
+         break;
+
+      case SB16 :
+         BLASTER_WriteMixer( MIXER_SB16VoiceLeft,
+            BLASTER_OriginalVoiceVolumeLeft );
+         BLASTER_WriteMixer( MIXER_SB16VoiceRight,
+            BLASTER_OriginalVoiceVolumeRight );
+         break;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SaveMidiVolume
+
+   Saves the user's FM mixer settings.
+---------------------------------------------------------------------*/
+
+void BLASTER_SaveMidiVolume
+   (
+   void
+   )
+
+   {
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         BLASTER_OriginalMidiVolumeLeft =
+            BLASTER_ReadMixer( MIXER_SBProMidi );
+         break;
+
+      case SB16 :
+         BLASTER_OriginalMidiVolumeLeft =
+            BLASTER_ReadMixer( MIXER_SB16MidiLeft );
+         BLASTER_OriginalMidiVolumeRight =
+            BLASTER_ReadMixer( MIXER_SB16MidiRight );
+         break;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_RestoreMidiVolume
+
+   Restores the user's FM mixer settings.
+---------------------------------------------------------------------*/
+
+void BLASTER_RestoreMidiVolume
+   (
+   void
+   )
+
+   {
+   switch( BLASTER_MixerType )
+      {
+      case SBPro :
+      case SBPro2 :
+         BLASTER_WriteMixer( MIXER_SBProMidi,
+            BLASTER_OriginalMidiVolumeLeft );
+         break;
+
+      case SB16 :
+         BLASTER_WriteMixer( MIXER_SB16MidiLeft,
+            BLASTER_OriginalMidiVolumeLeft );
+         BLASTER_WriteMixer( MIXER_SB16MidiRight,
+            BLASTER_OriginalMidiVolumeRight );
+         break;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetEnv
+
+   Retrieves the BLASTER environment settings and returns them to
+   the caller.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetEnv
+   (
+   BLASTER_CONFIG *Config
+   )
+
+   {
+   char *Blaster;
+   char parameter;
+
+   Config->Address   = UNDEFINED;
+   Config->Type      = UNDEFINED;
+   Config->Interrupt = UNDEFINED;
+   Config->Dma8      = UNDEFINED;
+   Config->Dma16     = UNDEFINED;
+   Config->Midi      = UNDEFINED;
+   Config->Emu       = UNDEFINED;
+
+   Blaster = getenv( "BLASTER" );
+   if ( Blaster == NULL )
+      {
+      BLASTER_SetErrorCode( BLASTER_EnvNotFound );
+      return( BLASTER_Error );
+      }
+
+   while( *Blaster != 0 )
+      {
+      if ( *Blaster == ' ' )
+         {
+         Blaster++;
+         continue;
+         }
+
+      parameter = toupper( *Blaster );
+      Blaster++;
+
+      if ( !isxdigit( *Blaster ) )
+         {
+         BLASTER_SetErrorCode( BLASTER_InvalidParameter );
+         return( BLASTER_Error );
+         }
+
+      switch( parameter )
+         {
+         case BlasterEnv_Address :
+            sscanf( Blaster, "%x", &Config->Address );
+            break;
+         case BlasterEnv_Interrupt :
+            sscanf( Blaster, "%d", &Config->Interrupt );
+            break;
+         case BlasterEnv_8bitDma :
+            sscanf( Blaster, "%d", &Config->Dma8 );
+            break;
+         case BlasterEnv_Type :
+            sscanf( Blaster, "%d", &Config->Type );
+            break;
+         case BlasterEnv_16bitDma :
+            sscanf( Blaster, "%d", &Config->Dma16 );
+            break;
+         case BlasterEnv_Midi :
+            sscanf( Blaster, "%x", &Config->Midi );
+            break;
+         case BlasterEnv_EmuAddress :
+            sscanf( Blaster, "%x", &Config->Emu );
+            break;
+         default  :
+            // Skip the offending data
+            // sscanf( Blaster, "%*s" );
+            break;
+         }
+
+      while( isxdigit( *Blaster ) )
+         {
+         Blaster++;
+         }
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetCardSettings
+
+   Sets up the sound card's parameters.
+---------------------------------------------------------------------*/
+
+int BLASTER_SetCardSettings
+   (
+   BLASTER_CONFIG Config
+   )
+
+   {
+   if ( BLASTER_Installed )
+      {
+      BLASTER_Shutdown();
+      }
+
+   BLASTER_Config.Address   = Config.Address;
+   BLASTER_Config.Type      = Config.Type;
+   BLASTER_Config.Interrupt = Config.Interrupt;
+   BLASTER_Config.Dma8      = Config.Dma8;
+   BLASTER_Config.Dma16     = Config.Dma16;
+   BLASTER_Config.Midi      = Config.Midi;
+   BLASTER_Config.Emu       = Config.Emu;
+   BLASTER_MixerAddress     = Config.Address;
+   BLASTER_MixerType        = Config.Type;
+
+   if ( BLASTER_Config.Emu == UNDEFINED )
+      {
+      BLASTER_Config.Emu = BLASTER_Config.Address + 0x400;
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetCardSettings
+
+   Sets up the sound card's parameters.
+---------------------------------------------------------------------*/
+
+int BLASTER_GetCardSettings
+   (
+   BLASTER_CONFIG *Config
+   )
+
+   {
+   if ( BLASTER_Config.Address == UNDEFINED )
+      {
+      return( BLASTER_Warning );
+      }
+   else
+      {
+      Config->Address   = BLASTER_Config.Address;
+      Config->Type      = BLASTER_Config.Type;
+      Config->Interrupt = BLASTER_Config.Interrupt;
+      Config->Dma8      = BLASTER_Config.Dma8;
+      Config->Dma16     = BLASTER_Config.Dma16;
+      Config->Midi      = BLASTER_Config.Midi;
+      Config->Emu       = BLASTER_Config.Emu;
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_GetCardInfo
+
+   Returns the maximum number of bits that can represent a sample
+   (8 or 16) and the number of channels (1 for mono, 2 for stereo).
+---------------------------------------------------------------------*/
+
+int BLASTER_GetCardInfo
+   (
+   int *MaxSampleBits,
+   int *MaxChannels
+   )
+
+   {
+   if ( BLASTER_Card.MaxMixMode & STEREO )
+      {
+      *MaxChannels = 2;
+      }
+   else
+      {
+      *MaxChannels = 1;
+      }
+
+   if ( BLASTER_Card.MaxMixMode & SIXTEEN_BIT )
+      {
+      *MaxSampleBits = 16;
+      }
+   else
+      {
+      *MaxSampleBits = 8;
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetCallBack
+
+   Specifies the user function to call at the end of a sound transfer.
+---------------------------------------------------------------------*/
+
+void BLASTER_SetCallBack
+   (
+   void ( *func )( void )
+   )
+
+   {
+   BLASTER_CallBack = func;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void BLASTER_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_UnlockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+void BLASTER_UnlockMemory
+   (
+   void
+   )
+
+   {
+   DPMI_UnlockMemoryRegion( BLASTER_LockStart, BLASTER_LockEnd );
+   DPMI_UnlockMemory( ( void * )&BLASTER_Interrupts[ 0 ],
+      sizeof( BLASTER_Interrupts ) );
+   DPMI_UnlockMemory( ( void * )&BLASTER_SampleSize[ 0 ],
+      sizeof( BLASTER_SampleSize ) );
+   DPMI_Unlock( BLASTER_Card );
+   DPMI_Unlock( BLASTER_OldInt );
+   DPMI_Unlock( BLASTER_Config );
+   DPMI_Unlock( BLASTER_Installed );
+   DPMI_Unlock( BLASTER_Version );
+   DPMI_Unlock( BLASTER_DMABuffer );
+   DPMI_Unlock( BLASTER_DMABufferEnd );
+   DPMI_Unlock( BLASTER_CurrentDMABuffer );
+   DPMI_Unlock( BLASTER_TotalDMABufferSize );
+   DPMI_Unlock( BLASTER_TransferLength );
+   DPMI_Unlock( BLASTER_MixMode );
+   DPMI_Unlock( BLASTER_SamplePacketSize );
+   DPMI_Unlock( BLASTER_SampleRate );
+   DPMI_Unlock( BLASTER_HaltTransferCommand );
+   DPMI_Unlock( ( int )BLASTER_SoundPlaying );
+   DPMI_Unlock( ( int )BLASTER_SoundRecording );
+   DPMI_Unlock( BLASTER_CallBack );
+   DPMI_Unlock( BLASTER_IntController1Mask );
+   DPMI_Unlock( BLASTER_IntController2Mask );
+   DPMI_Unlock( BLASTER_MixerAddress );
+   DPMI_Unlock( BLASTER_MixerType );
+   DPMI_Unlock( BLASTER_OriginalMidiVolumeLeft );
+   DPMI_Unlock( BLASTER_OriginalMidiVolumeRight );
+   DPMI_Unlock( BLASTER_OriginalVoiceVolumeLeft );
+   DPMI_Unlock( BLASTER_OriginalVoiceVolumeRight );
+   DPMI_Unlock( GlobalStatus );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_LockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+int BLASTER_LockMemory
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status  = DPMI_LockMemoryRegion( BLASTER_LockStart, BLASTER_LockEnd );
+   status |= DPMI_LockMemory( ( void * )&BLASTER_Interrupts[ 0 ],
+      sizeof( BLASTER_Interrupts ) );
+   status |= DPMI_LockMemory( ( void * )&BLASTER_SampleSize[ 0 ],
+      sizeof( BLASTER_SampleSize ) );
+   status |= DPMI_Lock( BLASTER_Card );
+   status |= DPMI_Lock( BLASTER_OldInt );
+   status |= DPMI_Lock( BLASTER_Config );
+   status |= DPMI_Lock( BLASTER_Installed );
+   status |= DPMI_Lock( BLASTER_Version );
+   status |= DPMI_Lock( BLASTER_DMABuffer );
+   status |= DPMI_Lock( BLASTER_DMABufferEnd );
+   status |= DPMI_Lock( BLASTER_CurrentDMABuffer );
+   status |= DPMI_Lock( BLASTER_TotalDMABufferSize );
+   status |= DPMI_Lock( BLASTER_TransferLength );
+   status |= DPMI_Lock( BLASTER_MixMode );
+   status |= DPMI_Lock( BLASTER_SamplePacketSize );
+   status |= DPMI_Lock( BLASTER_SampleRate );
+   status |= DPMI_Lock( BLASTER_HaltTransferCommand );
+   status |= DPMI_Lock( ( ( int )BLASTER_SoundPlaying ) );
+   status |= DPMI_Lock( ( ( int )BLASTER_SoundRecording ) );
+   status |= DPMI_Lock( BLASTER_CallBack );
+   status |= DPMI_Lock( BLASTER_IntController1Mask );
+   status |= DPMI_Lock( BLASTER_IntController2Mask );
+   status |= DPMI_Lock( BLASTER_MixerAddress );
+   status |= DPMI_Lock( BLASTER_MixerType );
+   status |= DPMI_Lock( BLASTER_OriginalMidiVolumeLeft );
+   status |= DPMI_Lock( BLASTER_OriginalMidiVolumeRight );
+   status |= DPMI_Lock( BLASTER_OriginalVoiceVolumeLeft );
+   status |= DPMI_Lock( BLASTER_OriginalVoiceVolumeRight );
+   status |= DPMI_Lock( GlobalStatus );
+
+   if ( status != DPMI_Ok )
+      {
+      BLASTER_UnlockMemory();
+      BLASTER_SetErrorCode( BLASTER_DPMI_Error );
+      return( BLASTER_Error );
+      }
+
+   return( BLASTER_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: allocateTimerStack
+
+   Allocate a block of memory from conventional (low) memory and return
+   the selector (which can go directly into a segment register) of the
+   memory block or 0 if an error occured.
+---------------------------------------------------------------------*/
+
+static unsigned short allocateTimerStack
+   (
+   unsigned short size
+   )
+
+   {
+   union REGS regs;
+
+   // clear all registers
+   memset( &regs, 0, sizeof( regs ) );
+
+   // DPMI allocate conventional memory
+   regs.w.ax = 0x100;
+
+   // size in paragraphs
+   regs.w.bx = ( size + 15 ) / 16;
+
+   int386( 0x31, &regs, &regs );
+   if (!regs.w.cflag)
+      {
+      // DPMI call returns selector in dx
+      // (ax contains real mode segment
+      // which is ignored here)
+
+      return( regs.w.dx );
+      }
+
+   // Couldn't allocate memory.
+   return( NULL );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: deallocateTimerStack
+
+   Deallocate a block of conventional (low) memory given a selector to
+   it.  Assumes the block was allocated with DPMI function 0x100.
+---------------------------------------------------------------------*/
+
+static void deallocateTimerStack
+   (
+   unsigned short selector
+   )
+
+   {
+   union REGS regs;
+
+   if ( selector != NULL )
+      {
+      // clear all registers
+      memset( &regs, 0, sizeof( regs ) );
+
+      regs.w.ax = 0x101;
+      regs.w.dx = selector;
+      int386( 0x31, &regs, &regs );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_SetupWaveBlaster
+
+   Allows the WaveBlaster to play music while the Sound Blaster 16
+   plays digital sound.
+---------------------------------------------------------------------*/
+
+void BLASTER_SetupWaveBlaster
+   (
+   void
+   )
+
+   {
+
+   if ( BLASTER_MixerType == SB16 )
+      {
+      // Disable MPU401 interrupts.  If they are not disabled,
+      // the SB16 will not produce sound or music.
+      BLASTER_WaveBlasterState = BLASTER_ReadMixer( MIXER_DSP4xxISR_Enable );
+      BLASTER_WriteMixer( MIXER_DSP4xxISR_Enable, MIXER_DisableMPU401Interrupts );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_ShutdownWaveBlaster
+
+   Restores WaveBlaster mixer to original state.
+---------------------------------------------------------------------*/
+
+void BLASTER_ShutdownWaveBlaster
+   (
+   void
+   )
+
+   {
+   if ( BLASTER_MixerType == SB16 )
+      {
+      // Restore the state of MPU401 interrupts.  If they are not disabled,
+      // the SB16 will not produce sound or music.
+      BLASTER_WriteMixer( MIXER_DSP4xxISR_Enable, BLASTER_WaveBlasterState );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_Init
+
+   Initializes the sound card and prepares the module to play
+   digitized sounds.
+---------------------------------------------------------------------*/
+
+int BLASTER_Init
+   (
+   void
+   )
+
+   {
+   int Irq;
+   int Interrupt;
+   int status;
+
+   if ( BLASTER_Installed )
+      {
+      BLASTER_Shutdown();
+      }
+
+   if ( BLASTER_Config.Address == UNDEFINED )
+      {
+      BLASTER_SetErrorCode( BLASTER_AddrNotSet );
+      return( BLASTER_Error );
+      }
+
+   // Save the interrupt masks
+   BLASTER_IntController1Mask = inp( 0x21 );
+   BLASTER_IntController2Mask = inp( 0xA1 );
+
+   status = BLASTER_ResetDSP();
+   if ( status == BLASTER_Ok )
+      {
+      BLASTER_SaveVoiceVolume();
+
+      BLASTER_SoundPlaying = FALSE;
+
+      BLASTER_SetCallBack( NULL );
+
+      BLASTER_DMABuffer = NULL;
+
+      BLASTER_Version = BLASTER_GetDSPVersion();
+
+      BLASTER_SetPlaybackRate( BLASTER_DefaultSampleRate );
+      BLASTER_SetMixMode( BLASTER_DefaultMixMode );
+
+      if ( BLASTER_Config.Dma16 != UNDEFINED )
+         {
+         status = DMA_VerifyChannel( BLASTER_Config.Dma16 );
+         if ( status == DMA_Error )
+            {
+            BLASTER_SetErrorCode( BLASTER_DmaError );
+            return( BLASTER_Error );
+            }
+         }
+
+      if ( BLASTER_Config.Dma8 != UNDEFINED )
+         {
+         status = DMA_VerifyChannel( BLASTER_Config.Dma8 );
+         if ( status == DMA_Error )
+            {
+            BLASTER_SetErrorCode( BLASTER_DmaError );
+            return( BLASTER_Error );
+            }
+         }
+
+      // Install our interrupt handler
+      Irq = BLASTER_Config.Interrupt;
+      if ( !VALID_IRQ( Irq ) )
+         {
+         BLASTER_SetErrorCode( BLASTER_InvalidIrq );
+         return( BLASTER_Error );
+         }
+
+      Interrupt = BLASTER_Interrupts[ Irq ];
+      if ( Interrupt == INVALID )
+         {
+         BLASTER_SetErrorCode( BLASTER_InvalidIrq );
+         return( BLASTER_Error );
+         }
+
+      status = BLASTER_LockMemory();
+      if ( status != BLASTER_Ok )
+         {
+         BLASTER_UnlockMemory();
+         return( status );
+         }
+
+      StackSelector = allocateTimerStack( kStackSize );
+      if ( StackSelector == NULL )
+         {
+         BLASTER_UnlockMemory();
+         BLASTER_SetErrorCode( BLASTER_OutOfMemory );
+         return( BLASTER_Error );
+         }
+
+      // Leave a little room at top of stack just for the hell of it...
+      StackPointer = kStackSize - sizeof( long );
+
+      BLASTER_OldInt = _dos_getvect( Interrupt );
+      if ( Irq < 8 )
+         {
+         _dos_setvect( Interrupt, BLASTER_ServiceInterrupt );
+         }
+      else
+         {
+         status = IRQ_SetVector( Interrupt, BLASTER_ServiceInterrupt );
+         if ( status != IRQ_Ok )
+            {
+            BLASTER_UnlockMemory();
+            deallocateTimerStack( StackSelector );
+            StackSelector = NULL;
+            BLASTER_SetErrorCode( BLASTER_UnableToSetIrq );
+            return( BLASTER_Error );
+            }
+         }
+
+      BLASTER_Installed = TRUE;
+      status = BLASTER_Ok;
+      }
+
+   BLASTER_SetErrorCode( status );
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BLASTER_Shutdown
+
+   Ends transfer of sound data to the sound card and restores the
+   system resources used by the card.
+---------------------------------------------------------------------*/
+
+void BLASTER_Shutdown
+   (
+   void
+   )
+
+   {
+   int Irq;
+   int Interrupt;
+
+   // Halt the DMA transfer
+   BLASTER_StopPlayback();
+
+   BLASTER_RestoreVoiceVolume();
+
+   // Reset the DSP
+   BLASTER_ResetDSP();
+
+   // Restore the original interrupt
+   Irq = BLASTER_Config.Interrupt;
+   Interrupt = BLASTER_Interrupts[ Irq ];
+   if ( Irq >= 8 )
+      {
+      IRQ_RestoreVector( Interrupt );
+      }
+   _dos_setvect( Interrupt, BLASTER_OldInt );
+
+   BLASTER_SoundPlaying = FALSE;
+
+   BLASTER_DMABuffer = NULL;
+
+   BLASTER_SetCallBack( NULL );
+
+   BLASTER_UnlockMemory();
+
+   deallocateTimerStack( StackSelector );
+   StackSelector = NULL;
+
+   BLASTER_Installed = FALSE;
+   }

Added: tags/rott-1.1/rott/audiolib/blaster.h
===================================================================
--- tags/rott-1.1/rott/audiolib/blaster.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/blaster.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,148 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: BLASTER.H
+
+   author: James R. Dose
+   date:   February 4, 1994
+
+   Public header for BLASTER.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __BLASTER_H
+#define __BLASTER_H
+
+typedef struct
+   {
+   unsigned Address;
+   unsigned Type;
+   unsigned Interrupt;
+   unsigned Dma8;
+   unsigned Dma16;
+   unsigned Midi;
+   unsigned Emu;
+   } BLASTER_CONFIG;
+
+extern BLASTER_CONFIG BLASTER_Config;
+extern int BLASTER_DMAChannel;
+
+#define UNDEFINED -1
+
+enum BLASTER_ERRORS
+   {
+   BLASTER_Warning = -2,
+   BLASTER_Error = -1,
+   BLASTER_Ok = 0,
+   BLASTER_EnvNotFound,
+   BLASTER_AddrNotSet,
+   BLASTER_DMANotSet,
+   BLASTER_DMA16NotSet,
+   BLASTER_InvalidParameter,
+   BLASTER_CardNotReady,
+   BLASTER_NoSoundPlaying,
+   BLASTER_InvalidIrq,
+   BLASTER_UnableToSetIrq,
+   BLASTER_DmaError,
+   BLASTER_NoMixer,
+   BLASTER_DPMI_Error,
+   BLASTER_OutOfMemory
+   };
+
+enum BLASTER_Types
+   {
+   SB     = 1,
+   SBPro  = 2,
+   SB20   = 3,
+   SBPro2 = 4,
+   SB16   = 6
+   };
+
+#define BLASTER_MinCardType    SB
+#define BLASTER_MaxCardType    SB16
+
+#define STEREO      1
+#define SIXTEEN_BIT 2
+
+#define MONO_8BIT    0
+#define STEREO_8BIT  ( STEREO )
+#define MONO_16BIT   ( SIXTEEN_BIT )
+#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
+
+#define BLASTER_MaxMixMode        STEREO_16BIT
+
+#define MONO_8BIT_SAMPLE_SIZE    1
+#define MONO_16BIT_SAMPLE_SIZE   2
+#define STEREO_8BIT_SAMPLE_SIZE  ( 2 * MONO_8BIT_SAMPLE_SIZE )
+#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
+
+#define BLASTER_DefaultSampleRate 11000
+#define BLASTER_DefaultMixMode    MONO_8BIT
+#define BLASTER_MaxIrq            15
+
+char *BLASTER_ErrorString( int ErrorNumber );
+void  BLASTER_EnableInterrupt( void );
+void  BLASTER_DisableInterrupt( void );
+int   BLASTER_WriteDSP( unsigned data );
+int   BLASTER_ReadDSP( void );
+int   BLASTER_ResetDSP( void );
+int   BLASTER_GetDSPVersion( void );
+void  BLASTER_SpeakerOn( void );
+void  BLASTER_SpeakerOff( void );
+void  BLASTER_SetPlaybackRate( unsigned rate );
+unsigned BLASTER_GetPlaybackRate( void );
+int   BLASTER_SetMixMode( int mode );
+void  BLASTER_StopPlayback( void );
+int   BLASTER_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
+int   BLASTER_GetCurrentPos( void );
+int   BLASTER_DSP1xx_BeginPlayback( int length );
+int   BLASTER_DSP2xx_BeginPlayback( int length );
+int   BLASTER_DSP4xx_BeginPlayback( int length );
+int   BLASTER_BeginBufferedRecord( char *BufferStart, int BufferSize,
+          int NumDivisions, unsigned SampleRate, int MixMode,
+          void ( *CallBackFunc )( void ) );
+int   BLASTER_BeginBufferedPlayback( char *BufferStart,
+         int BufferSize, int NumDivisions, unsigned SampleRate,
+         int MixMode, void ( *CallBackFunc )( void ) );
+void  BLASTER_WriteMixer( int reg, int data );
+int   BLASTER_ReadMixer( int reg );
+int   BLASTER_GetVoiceVolume( void );
+int   BLASTER_SetVoiceVolume( int volume );
+int   BLASTER_GetMidiVolume( void );
+int   BLASTER_SetMidiVolume( int volume );
+int   BLASTER_CardHasMixer( void );
+void  BLASTER_SaveVoiceVolume( void );
+void  BLASTER_RestoreVoiceVolume( void );
+void  BLASTER_SaveMidiVolume( void );
+void  BLASTER_RestoreMidiVolume( void );
+int   BLASTER_GetEnv( BLASTER_CONFIG *Config );
+int   BLASTER_SetCardSettings( BLASTER_CONFIG Config );
+int   BLASTER_GetCardSettings( BLASTER_CONFIG *Config );
+int   BLASTER_GetCardInfo( int *MaxSampleBits, int *MaxChannels );
+void  BLASTER_SetCallBack( void ( *func )( void ) );
+void  BLASTER_SetupWaveBlaster( void );
+void  BLASTER_ShutdownWaveBlaster( void );
+int   BLASTER_Init( void );
+void  BLASTER_Shutdown( void );
+void  BLASTER_UnlockMemory( void );
+int   BLASTER_LockMemory( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/ctaweapi.h
===================================================================
--- tags/rott-1.1/rott/audiolib/ctaweapi.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/ctaweapi.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,352 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/****************************************************************************\
+*                                                                            *
+* CTAWEAPI.H SB AWE32 DOS API header                                         *
+*                                                                            *
+* (C) Copyright Creative Technology Ltd. 1992-94. All rights reserved        *
+* worldwide.                                                                 *
+*                                                                            *
+* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY      *
+* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE        *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR      *
+* PURPOSE.                                                                   *
+*                                                                            *
+* You have a royalty-free right to use, modify, reproduce and                *
+* distribute the Sample Files (and/or any modified version) in               *
+* any way you find useful, provided that you agree to                        *
+* the Creative's Software Licensing Aggreement and you also agree that       *
+* Creative has no warranty obligations or liability for any Sample Files.    *
+*                                                                            *
+\****************************************************************************/
+
+/****************************************************************************\
+*      File name       : CTAWEAPI.H                                          *
+*                                                                            *
+*      Programmer      : Creative SB AWE32 Team                              *
+*                        Creative Technology Ltd, 1994. All rights reserved. *
+*                                                                            *
+*      Version         : 2.0b                                                *
+*                                                                            *
+\****************************************************************************/
+
+#ifndef _CTAWEAPI
+#define _CTAWEAPI
+
+
+#define MAXBANKS            64      /* maximum number of banks */
+#define MAXNRPN             32      /* maximum number of NRPN */
+
+
+#if defined(__FLAT__) || defined(__HIGHC__) || defined(DOS386)
+#define PACKETSIZE      8192        /* packet size for 32bit libraries */
+#else
+#define PACKETSIZE      512         /* packet size for real mode libraries */
+#endif
+
+
+#if defined(__FLAT__)
+    #define NEAR
+    #define FAR
+#endif
+
+
+#if defined(__SC__)
+    #pragma pack(1)
+    #if defined(DOS386)
+        #define NEAR
+        #define FAR
+    #endif
+#endif
+
+
+#if defined(__WATCOMC__)
+    #pragma pack(1)
+#endif
+
+
+#if defined(__HIGHC__)
+    #define NEAR
+    #define FAR
+    #define PASCAL  _DCC((_DEFAULT_CALLING_CONVENTION|_CALLEE_POPS_STACK) & \
+                         ~ (_REVERSE_PARMS|_OVERLOADED))
+    #pragma Push_align_members(1)
+    #pragma Global_aliasing_convention("_%r")
+#endif
+
+
+typedef int                     BOOL;
+#define FALSE                   0
+#define TRUE                    1
+
+typedef unsigned char		BYTE;
+typedef unsigned short		WORD;
+typedef unsigned long		DWORD;
+
+typedef short int               SHORT;
+typedef unsigned int		UINT;
+typedef signed long 		LONG;
+
+#ifndef FAR
+#define FAR                     __far
+#endif
+
+#ifndef HUGE
+#define HUGE                    __huge
+#endif
+
+#ifndef PASCAL
+#define PASCAL                  __pascal
+#endif
+
+typedef void FAR*               LPVOID;
+typedef BYTE FAR*               LPBYTE;
+typedef WORD FAR*               LPWORD;
+typedef DWORD FAR*              LPDWORD;
+
+#define LOBYTE(w)               ((BYTE)(w))
+#define HIBYTE(w)               ((BYTE)(((UINT)(w) >> 8) & 0xFF))
+
+#define LOWORD(l)               ((WORD)(DWORD)(l))
+#define HIWORD(l)               ((WORD)((((DWORD)(l)) >> 16) & 0xFFFF))
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* Start of modules */
+extern int* __midieng_code(void);
+extern int* __hardware_code(void);
+extern int* __sbkload_code(void);
+extern int* __nrpn_code(void);
+extern int __midivar_data;
+extern int __nrpnvar_data;
+extern int __embed_data;
+
+
+typedef char SCRATCH[702];
+typedef char SOUNDFONT[124];
+typedef char GCHANNEL[20];
+typedef char MIDICHANNEL[32];
+typedef char NRPNCHANNEL[96];
+
+typedef struct {
+    SHORT bank_no;          /* Slot number being used */
+    SHORT total_banks;      /* Total number of banks */
+    LONG FAR* banksizes;    /* Pointer to a list of bank sizes */
+    LONG file_size;         /* exact size of the sound font file */
+    char FAR* data;         /* Address of buffer of size >= PACKETSIZE */
+    char FAR* presets;      /* Allocated memory for preset data */
+
+    LONG total_patch_ram;   /* Total patch ram available */
+    SHORT no_sample_packets;/* Number of packets of sound sample to stream */
+    LONG sample_seek;       /* Start file location of sound sample */
+    LONG preset_seek;       /* Address of preset_seek location */
+    LONG preset_read_size;  /* Number of bytes from preset_seek to allocate and read */
+    LONG preset_size;       /* Preset actual size */
+} SOUND_PACKET;
+
+typedef struct {
+    SHORT tag;              /* Must be 0x100 or 0x101 */
+    SHORT preset_size;      /* Preset table of this size is required */
+    SHORT no_wave_packets;  /* Number of packets of Wave sample to stream. */
+    LONG reserved;
+
+    SHORT bank_no;          /* bank number */
+    char FAR* data;         /* Address of packet of size PACKETSIZE */
+    char FAR* presets;      /* Allocated memory for preset data */
+    LONG sample_size;       /* Sample size, i.e. number of samples */
+    LONG samples_per_sec;   /* Samples per second */
+    SHORT bits_per_sample;  /* Bits per sample, 8 or 16 */
+    SHORT no_channels;      /* Number of channels, 1=mono, 2=stereo */
+    SHORT looping;          /* Looping? 0=no, 1=yes */
+    LONG startloop;         /* if looping, then these are the addresses */
+    LONG endloop;
+    SHORT release;          /* release time, 0=24ms, 8191=23.78s */
+} WAVE_PACKET;
+
+typedef struct {
+    LPBYTE SPad1;
+    LPBYTE SPad2;
+    LPBYTE SPad3;
+    LPBYTE SPad4;
+    LPBYTE SPad5;
+    LPBYTE SPad6;
+    LPBYTE SPad7;
+} SOUNDPAD;
+
+/* AWE32 variables */
+extern WORD         awe32NumG;
+extern WORD         awe32BaseAddx;
+extern DWORD        awe32DramSize;
+
+/* MIDI variables */
+extern SCRATCH      awe32Scratch;
+extern SOUNDFONT    awe32SFont[4];
+extern GCHANNEL     awe32GChannel[32];
+extern MIDICHANNEL  awe32MIDIChannel[16];
+extern SOUNDPAD     awe32SoundPad;
+
+/* NRPN variables */
+extern NRPNCHANNEL  awe32NRPNChannel[16];
+
+/* SoundFont objects */
+extern BYTE awe32SPad1Obj[];
+extern BYTE awe32SPad2Obj[];
+extern BYTE awe32SPad3Obj[];
+extern BYTE awe32SPad4Obj[];
+extern BYTE awe32SPad5Obj[];
+extern BYTE awe32SPad6Obj[];
+extern BYTE awe32SPad7Obj[];
+
+/* AWE register functions */
+extern void PASCAL awe32RegW(WORD, WORD);
+extern WORD PASCAL awe32RegRW(WORD);
+extern void PASCAL awe32RegDW(WORD, DWORD);
+extern DWORD PASCAL awe32RegRDW(WORD);
+
+/* MIDI support functions */
+extern WORD PASCAL awe32InitMIDI(void);
+extern WORD PASCAL awe32NoteOn(WORD, WORD, WORD);
+extern WORD PASCAL awe32NoteOff(WORD, WORD, WORD);
+extern WORD PASCAL awe32ProgramChange(WORD, WORD);
+extern WORD PASCAL awe32Controller(WORD, WORD, WORD);
+extern WORD PASCAL awe32PolyKeyPressure(WORD, WORD, WORD);
+extern WORD PASCAL awe32ChannelPressure(WORD, WORD);
+extern WORD PASCAL awe32PitchBend(WORD, WORD, WORD);
+extern WORD PASCAL awe32Sysex(WORD, LPBYTE, WORD);
+extern WORD PASCAL __awe32NoteOff(WORD, WORD, WORD, WORD);
+extern WORD PASCAL __awe32IsPlaying(WORD, WORD, WORD, WORD);
+
+/* NRPN support functions */
+extern WORD PASCAL awe32InitNRPN(void);
+
+/* Hardware support functions */
+extern WORD PASCAL awe32Detect(WORD);
+extern WORD PASCAL awe32InitHardware(void);
+extern WORD PASCAL awe32Terminate(void);
+
+/* SoundFont support functions */
+extern WORD PASCAL awe32TotalPatchRam(SOUND_PACKET FAR*);
+extern WORD PASCAL awe32DefineBankSizes(SOUND_PACKET FAR*);
+extern WORD PASCAL awe32SFontLoadRequest(SOUND_PACKET FAR*);
+extern WORD PASCAL awe32StreamSample(SOUND_PACKET FAR*);
+extern WORD PASCAL awe32SetPresets(SOUND_PACKET FAR*);
+extern WORD PASCAL awe32ReleaseBank(SOUND_PACKET FAR*);
+extern WORD PASCAL awe32ReleaseAllBanks(SOUND_PACKET FAR*);
+extern WORD PASCAL awe32WPLoadRequest(WAVE_PACKET FAR*);
+extern WORD PASCAL awe32WPLoadWave(WAVE_PACKET FAR*);
+extern WORD PASCAL awe32WPStreamWave(WAVE_PACKET FAR*);
+extern WORD PASCAL awe32WPBuildSFont(WAVE_PACKET FAR*);
+
+/* End of modules */
+extern int* __midieng_ecode(void);
+extern int* __hardware_ecode(void);
+extern int* __sbkload_ecode(void);
+extern int* __nrpn_ecode(void);
+extern int __midivar_edata;
+extern int __nrpnvar_edata;
+extern int __embed_edata;
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#if defined(__SC__)
+    #pragma pack()
+#endif
+
+
+#if defined(__HIGHC__)
+    #pragma Pop_align_members
+    #pragma Global_aliasing_convention()
+    #pragma Alias(awe32RegW,"AWE32REGW")
+    #pragma Alias(awe32RegRW,"AWE32REGRW")
+    #pragma Alias(awe32RegDW,"AWE32REGDW")
+    #pragma Alias(awe32RegRDW,"AWE32REGRDW")
+    #pragma Alias(awe32InitMIDI,"AWE32INITMIDI")
+    #pragma Alias(awe32NoteOn,"AWE32NOTEON")
+    #pragma Alias(awe32NoteOff,"AWE32NOTEOFF")
+    #pragma Alias(awe32ProgramChange,"AWE32PROGRAMCHANGE")
+    #pragma Alias(awe32Controller,"AWE32CONTROLLER")
+    #pragma Alias(awe32PolyKeyPressure,"AWE32POLYKEYPRESSURE")
+    #pragma Alias(awe32ChannelPressure,"AWE32CHANNELPRESSURE")
+    #pragma Alias(awe32PitchBend,"AWE32PITCHBEND")
+    #pragma Alias(awe32Sysex,"AWE32SYSEX")
+    #pragma Alias(__awe32NoteOff,"__AWE32NOTEOFF")
+    #pragma Alias(__awe32IsPlaying,"__AWE32ISPLAYING")
+    #pragma Alias(awe32InitNRPN,"AWE32INITNRPN")
+    #pragma Alias(awe32Detect,"AWE32DETECT")
+    #pragma Alias(awe32InitHardware,"AWE32INITHARDWARE")
+    #pragma Alias(awe32Terminate,"AWE32TERMINATE")
+    #pragma Alias(awe32TotalPatchRam,"AWE32TOTALPATCHRAM")
+    #pragma Alias(awe32DefineBankSizes,"AWE32DEFINEBANKSIZES")
+    #pragma Alias(awe32SFontLoadRequest,"AWE32SFONTLOADREQUEST")
+    #pragma Alias(awe32StreamSample,"AWE32STREAMSAMPLE")
+    #pragma Alias(awe32SetPresets,"AWE32SETPRESETS")
+    #pragma Alias(awe32ReleaseBank,"AWE32RELEASEBANK")
+    #pragma Alias(awe32ReleaseAllBanks,"AWE32RELEASEALLBANKS")
+    #pragma Alias(awe32WPLoadRequest,"AWE32WPLOADREQUEST")
+    #pragma Alias(awe32WPLoadWave,"AWE32WPLOADWAVE")
+    #pragma Alias(awe32WPStreamWave,"AWE32WPSTREAMWAVE")
+    #pragma Alias(awe32WPBuildSFont,"AWE32WPBUILDSFONT")
+#endif
+
+
+#if defined(__WATCOMC__)
+    #pragma pack()
+    #pragma aux awe32NumG "_*"
+    #pragma aux awe32BaseAddx "_*"
+    #pragma aux awe32DramSize "_*"
+    #pragma aux awe32Scratch "_*"
+    #pragma aux awe32SFont "_*"
+    #pragma aux awe32GChannel "_*"
+    #pragma aux awe32MIDIChannel "_*"
+    #pragma aux awe32SoundPad "_*"
+    #pragma aux awe32NRPNChannel "_*"
+    #pragma aux awe32SPad1Obj "_*"
+    #pragma aux awe32SPad2Obj "_*"
+    #pragma aux awe32SPad3Obj "_*"
+    #pragma aux awe32SPad4Obj "_*"
+    #pragma aux awe32SPad5Obj "_*"
+    #pragma aux awe32SPad6Obj "_*"
+    #pragma aux awe32SPad7Obj "_*"
+    #pragma aux __midieng_code "_*"
+    #pragma aux __midieng_ecode "_*"
+    #pragma aux __hardware_code "_*"
+    #pragma aux __hardware_ecode "_*"
+    #pragma aux __sbkload_code "_*"
+    #pragma aux __sbkload_ecode "_*"
+    #pragma aux __nrpn_code "_*"
+    #pragma aux __nrpn_ecode "_*"
+    #pragma aux __midivar_data "_*"
+    #pragma aux __midivar_edata "_*"
+    #pragma aux __nrpnvar_data "_*"
+    #pragma aux __nrpnvar_edata "_*"
+    #pragma aux __embed_data "_*"
+    #pragma aux __embed_edata "_*"
+#endif
+
+
+#endif      /* _CTAWEAPI */

Added: tags/rott-1.1/rott/audiolib/debugio.c
===================================================================
--- tags/rott-1.1/rott/audiolib/debugio.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/debugio.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,251 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "debugio.h"
+
+static unsigned short disp_offset = 160 * 24;
+static void myutoa( unsigned num, char *string, int radix );
+static void myitoa( int num, char *string, int radix );
+
+void DB_SetXY
+   (
+   int x,
+   int y
+   )
+
+   {
+   disp_offset = ( x * 2 ) + ( y * 160 );
+   }
+
+void DB_PutChar
+   (
+   char ch
+   )
+
+   {
+   int j;
+   char *disp_start = (char *)( 0xb0000 );
+
+   if ( disp_offset >= 160 * 24 )
+      {
+      for ( j = 160; j < 160 * 24; j += 2 )
+         {
+         *( disp_start + j - 160 ) = *( disp_start + j );
+         }
+
+      disp_offset = 160 * 23;
+
+      for ( j = disp_offset; j < ( 160 * 24 ); j += 2 )
+         {
+         *( disp_start + j ) = ' ';
+         }
+      }
+
+   if ( ch >= 32 )
+      {
+      *( disp_start + disp_offset ) = ch;
+      disp_offset = disp_offset + 2;
+      }
+
+   if ( ch == '\r' )
+      {
+      disp_offset = disp_offset / 160;
+      disp_offset = disp_offset * 160;
+      }
+
+   if ( ch == '\n' )
+      {
+      disp_offset = disp_offset + 160;
+      if ( disp_offset < 160 * 24 )
+         {
+         for ( j = disp_offset; j < ( ( ( disp_offset / 160 ) + 1 ) *
+            160 ); j += 2 )
+            {
+            *( disp_start + j ) = ' ';
+            }
+         }
+      }
+   }
+
+int DB_PrintString
+   (
+   char *string
+   )
+
+   {
+   int count;
+   char *ptr;
+
+   ptr = string;
+   count = 0;
+
+   while ( *ptr )
+      {
+      DB_PutChar( *ptr );
+      count++;
+      ptr++;
+      }
+
+   return( count );
+   }
+
+static void myutoa
+   (
+   unsigned num,
+   char *string,
+   int radix
+   )
+
+   {
+   int val;
+   int length;
+   int pos;
+   char temp[ 100 ];
+
+   length = 0;
+   do
+      {
+      val = num % radix;
+      if ( val < 10 )
+         {
+         temp[ length ] = '0' + val;
+         }
+      else
+         {
+         temp[ length ] = 'A' + val - 10;
+         }
+      num /= radix;
+      length++;
+      }
+   while( num > 0 );
+
+   pos = 0;
+   while( length > 0 )
+      {
+      length--;
+      string[ length ] = temp[ pos ];
+      pos++;
+      }
+   string[ pos ] = 0;
+   }
+
+static void myitoa
+   (
+   int num,
+   char *string,
+   int radix
+   )
+
+   {
+   if ( num < 0 )
+      {
+      *string++ = '-';
+      num = -num;
+      }
+
+   myutoa( num, string, radix );
+   }
+
+int DB_PrintNum
+   (
+   int number
+   )
+
+   {
+   char string[ 100 ];
+   int  count;
+
+   myitoa( number, &string[ 0 ], 10 );
+   count = DB_PrintString( &string[ 0 ] );
+
+   return( count );
+   }
+
+int DB_PrintUnsigned
+   (
+   unsigned long number,
+   int radix
+   )
+
+   {
+   char string[ 100 ];
+   int  count;
+
+   myutoa( number, &string[ 0 ], radix );
+   count = DB_PrintString( &string[ 0 ] );
+
+   return( count );
+   }
+
+int DB_printf
+   (
+   char *fmt,
+   ...
+   )
+
+   {
+   va_list argptr;
+   int     count;
+   char    *ptr;
+
+   va_start( argptr, fmt );
+   ptr = fmt;
+   count = 0;
+
+   while( *ptr != 0 )
+      {
+      if ( *ptr == '%' )
+         {
+         ptr++;
+         switch( *ptr )
+            {
+            case 0 :
+               return( EOF );
+               break;
+            case 'd' :
+               count += DB_PrintNum( va_arg( argptr, int ) );
+               break;
+            case 's' :
+               count += DB_PrintString( va_arg( argptr, char * ) );
+               break;
+            case 'u' :
+               count += DB_PrintUnsigned( va_arg( argptr, int ), 10 );
+               break;
+            case 'x' :
+            case 'X' :
+               count += DB_PrintUnsigned( va_arg( argptr, int ), 16 );
+               break;
+            }
+         ptr++;
+         }
+      else
+         {
+         DB_PutChar( *ptr );
+         count++;
+         ptr++;
+         }
+      }
+
+   va_end( argptr );
+
+   return( count );
+   }

Added: tags/rott-1.1/rott/audiolib/debugio.h
===================================================================
--- tags/rott-1.1/rott/audiolib/debugio.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/debugio.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,30 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef __DEBUGIO_H
+#define __DEBUGIO_H
+
+void DB_SetXY( int x, int y );
+void DB_PutChar( char ch );
+int  DB_PrintString( char *string );
+int  DB_PrintNum( int number );
+int  DB_PrintUnsigned( unsigned long number, int radix );
+int  DB_printf( char *fmt, ... );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/dma.c
===================================================================
--- tags/rott-1.1/rott/audiolib/dma.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/dma.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,379 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: DMA.C
+
+   author: James R. Dose
+   date:   February 4, 1994
+
+   Low level routines to for programming the DMA controller for 8 bit
+   and 16 bit transfers.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <dos.h>
+#include <conio.h>
+#include <stdlib.h>
+#include "dma.h"
+
+#define DMA_MaxChannel 7
+
+#define VALID   ( 1 == 1 )
+#define INVALID ( !VALID )
+
+#define BYTE 0
+#define WORD 1
+
+typedef struct
+   {
+   int Valid;
+   int Width;
+   int Mask;
+   int Mode;
+   int Clear;
+   int Page;
+   int Address;
+   int Length;
+   } DMA_PORT;
+
+static const DMA_PORT DMA_PortInfo[ DMA_MaxChannel + 1 ] =
+   {
+      {   VALID, BYTE,  0xA,  0xB,  0xC, 0x87,  0x0,  0x1 },
+      {   VALID, BYTE,  0xA,  0xB,  0xC, 0x83,  0x2,  0x3 },
+      { INVALID, BYTE,  0xA,  0xB,  0xC, 0x81,  0x4,  0x5 },
+      {   VALID, BYTE,  0xA,  0xB,  0xC, 0x82,  0x6,  0x7 },
+      { INVALID, WORD, 0xD4, 0xD6, 0xD8, 0x8F, 0xC0, 0xC2 },
+      {   VALID, WORD, 0xD4, 0xD6, 0xD8, 0x8B, 0xC4, 0xC6 },
+      {   VALID, WORD, 0xD4, 0xD6, 0xD8, 0x89, 0xC8, 0xCA },
+      {   VALID, WORD, 0xD4, 0xD6, 0xD8, 0x8A, 0xCC, 0xCE },
+   };
+
+int DMA_ErrorCode = DMA_Ok;
+
+#define DMA_SetErrorCode( status ) \
+   DMA_ErrorCode   = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: DMA_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *DMA_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case DMA_Error :
+         ErrorString = DMA_ErrorString( DMA_ErrorCode );
+         break;
+
+      case DMA_Ok :
+         ErrorString = "DMA channel ok.";
+         break;
+
+      case DMA_ChannelOutOfRange :
+         ErrorString = "DMA channel out of valid range.";
+         break;
+
+      case DMA_InvalidChannel :
+         ErrorString = "Unsupported DMA channel.";
+         break;
+
+      default :
+         ErrorString = "Unknown DMA error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DMA_VerifyChannel
+
+   Verifies whether a DMA channel is available to transfer data.
+---------------------------------------------------------------------*/
+
+int DMA_VerifyChannel
+   (
+   int channel
+   )
+
+   {
+   int      status;
+   int      Error;
+
+   status = DMA_Ok;
+   Error  = DMA_Ok;
+
+   if ( ( channel < 0 ) || ( DMA_MaxChannel < channel ) )
+      {
+      Error = DMA_ChannelOutOfRange;
+      status = DMA_Error;
+      }
+   else if ( DMA_PortInfo[ channel ].Valid == INVALID )
+      {
+      Error = DMA_InvalidChannel;
+      status = DMA_Error;
+      }
+
+   DMA_SetErrorCode( Error );
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DMA_SetupTransfer
+
+   Programs the specified DMA channel to transfer data.
+---------------------------------------------------------------------*/
+
+int DMA_SetupTransfer
+   (
+   int  channel,
+   char *address,
+   int  length,
+   int  mode
+   )
+
+   {
+   DMA_PORT *Port;
+   int      addr;
+   int      ChannelSelect;
+   int      Page;
+   int      HiByte;
+   int      LoByte;
+   int      TransferLength;
+   int      status;
+
+   status = DMA_VerifyChannel( channel );
+
+   if ( status == DMA_Ok )
+      {
+      Port = &DMA_PortInfo[ channel ];
+      ChannelSelect = channel & 0x3;
+
+      addr = ( int )address;
+
+      if ( Port->Width == WORD )
+         {
+         Page   = ( addr >> 16 ) & 255;
+         HiByte = ( addr >> 9 ) & 255;
+         LoByte = ( addr >> 1 ) & 255;
+
+         // Convert the length in bytes to the length in words
+         TransferLength = ( length + 1 ) >> 1;
+
+         // The length is always one less the number of bytes or words
+         // that we're going to send
+         TransferLength--;
+         }
+      else
+         {
+         Page   = ( addr >> 16 ) & 255;
+         HiByte = ( addr >> 8 ) & 255;
+         LoByte = addr & 255;
+
+         // The length is always one less the number of bytes or words
+         // that we're going to send
+         TransferLength = length - 1;
+         }
+
+      // Mask off DMA channel
+      outp( Port->Mask, 4 | ChannelSelect );
+
+      // Clear flip-flop to lower byte with any data
+      outp( Port->Clear, 0 );
+
+      // Set DMA mode
+      switch( mode )
+         {
+         case DMA_SingleShotRead :
+            outp( Port->Mode, 0x48 | ChannelSelect );
+            break;
+
+         case DMA_SingleShotWrite :
+            outp( Port->Mode, 0x44 | ChannelSelect );
+            break;
+
+         case DMA_AutoInitRead :
+            outp( Port->Mode, 0x58 | ChannelSelect );
+            break;
+
+         case DMA_AutoInitWrite :
+            outp( Port->Mode, 0x54 | ChannelSelect );
+            break;
+         }
+
+      // Send address
+      outp( Port->Address, LoByte );
+      outp( Port->Address, HiByte );
+
+      // Send page
+      outp( Port->Page, Page );
+
+      // Send length
+      outp( Port->Length, TransferLength );
+      outp( Port->Length, TransferLength >> 8 );
+
+      // enable DMA channel
+      outp( Port->Mask, ChannelSelect );
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DMA_EndTransfer
+
+   Ends use of the specified DMA channel.
+---------------------------------------------------------------------*/
+
+int DMA_EndTransfer
+   (
+   int channel
+   )
+
+   {
+   DMA_PORT *Port;
+   int       ChannelSelect;
+   int       status;
+
+   status = DMA_VerifyChannel( channel );
+   if ( status == DMA_Ok )
+      {
+      Port = &DMA_PortInfo[ channel ];
+      ChannelSelect = channel & 0x3;
+
+      // Mask off DMA channel
+      outp( Port->Mask, 4 | ChannelSelect );
+
+      // Clear flip-flop to lower byte with any data
+      outp( Port->Clear, 0 );
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DMA_GetCurrentPos
+
+   Returns the position of the specified DMA transfer.
+---------------------------------------------------------------------*/
+
+char *DMA_GetCurrentPos
+   (
+   int channel
+   )
+
+   {
+   DMA_PORT      *Port;
+   unsigned long addr;
+   int           status;
+
+   addr   = NULL;
+   status = DMA_VerifyChannel( channel );
+
+   if ( status == DMA_Ok )
+      {
+      Port = &DMA_PortInfo[ channel ];
+
+      if ( Port->Width == WORD )
+         {
+         // Get address
+         addr  = inp( Port->Address ) << 1;
+         addr |= inp( Port->Address ) << 9;
+
+         // Get page
+         addr |= inp( Port->Page ) << 16;
+         }
+      else
+         {
+         // Get address
+         addr = inp( Port->Address );
+         addr |= inp( Port->Address ) << 8;
+
+         // Get page
+         addr |= inp( Port->Page ) << 16;
+         }
+      }
+
+   return( ( char * )addr );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DMA_GetTransferCount
+
+   Returns how many bytes are left in the DMA's transfer.
+---------------------------------------------------------------------*/
+
+int DMA_GetTransferCount
+   (
+   int channel
+   )
+
+   {
+   DMA_PORT      *Port;
+   int           count;
+   int           status;
+
+   status = DMA_Ok;
+
+   count = 0;
+
+   if ( ( channel < 0 ) || ( DMA_MaxChannel < channel ) )
+      {
+      status = DMA_ChannelOutOfRange;
+      }
+   else if ( DMA_PortInfo[ channel ].Valid == INVALID )
+      {
+      status = DMA_InvalidChannel;
+      }
+
+   if ( status == DMA_Ok )
+      {
+      Port = &DMA_PortInfo[ channel ];
+
+      outp( Port->Clear, 0 );
+      count  = inp( Port->Length );
+      count += inp( Port->Length ) << 8;
+
+      if ( Port->Width == WORD )
+         {
+         count <<= 1;
+         }
+      }
+
+   DMA_SetErrorCode( status );
+
+   return( count );
+   }

Added: tags/rott-1.1/rott/audiolib/dma.h
===================================================================
--- tags/rott-1.1/rott/audiolib/dma.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/dma.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,83 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   file:   DMA.H
+
+   author: James R. Dose
+   date:   February 4, 1994
+
+   Public header file for DMA.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __DMA_H
+#define __DMA_H
+
+enum DMA_ERRORS
+   {
+   DMA_Error = -1,
+   DMA_Ok    = 0,
+   DMA_ChannelOutOfRange,
+   DMA_InvalidChannel
+   };
+
+enum DMA_Modes
+   {
+   DMA_SingleShotRead,
+   DMA_SingleShotWrite,
+   DMA_AutoInitRead,
+   DMA_AutoInitWrite
+   };
+
+char *DMA_ErrorString
+   (
+   int ErrorNumber
+   );
+
+int DMA_VerifyChannel
+   (
+   int channel
+   );
+
+int DMA_SetupTransfer
+   (
+   int  channel,
+   char *address,
+   int  length,
+   int  mode
+   );
+
+int DMA_EndTransfer
+   (
+   int channel
+   );
+
+char *DMA_GetCurrentPos
+   (
+   int channel
+   );
+
+int DMA_GetTransferCount
+   (
+   int channel
+   );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/dpmi.c
===================================================================
--- tags/rott-1.1/rott/audiolib/dpmi.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/dpmi.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,250 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: DPMI.C
+
+   author: James R. Dose
+   date:   April 8, 1994
+
+   Functions for performing DPMI calls.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <dos.h>
+#include <string.h>
+#include "dpmi.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+static union  REGS  Regs;
+static struct SREGS SegRegs;
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_GetRealModeVector
+
+   Returns the vector of a real mode interrupt.
+---------------------------------------------------------------------*/
+
+unsigned long DPMI_GetRealModeVector
+   (
+   int num
+   )
+
+   {
+   unsigned long vector;
+
+   Regs.x.eax = 0x0200;
+   Regs.h.bl  = num;
+   int386( 0x31, &Regs, &Regs );
+
+   vector   = Regs.w.cx & 0xffff;
+   vector <<= 16;
+   vector  |= Regs.w.dx & 0xffff;
+
+   return( vector );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_SetRealModeVector
+
+   Sets the vector of a real mode interrupt.
+---------------------------------------------------------------------*/
+
+void DPMI_SetRealModeVector
+   (
+   int num,
+   unsigned long vector
+   )
+
+   {
+   Regs.x.eax = 0x0201;
+   Regs.h.bl  = num;
+   Regs.w.dx = vector & 0xffff;
+   Regs.w.cx = ( vector >> 16 ) & 0xffff;
+
+   int386( 0x31, &Regs, &Regs );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_CallRealModeFunction
+
+   Performs a call to a real mode function.
+---------------------------------------------------------------------*/
+
+int DPMI_CallRealModeFunction
+   (
+   dpmi_regs *callregs
+   )
+
+   {
+   // Setup our registers to call DPMI
+   Regs.w.ax = 0x0301;
+   Regs.h.bl = 0;
+   Regs.h.bh = 0;
+   Regs.w.cx = 0;
+
+   SegRegs.es = FP_SEG( callregs );
+   Regs.x.edi = FP_OFF( callregs );
+
+   // Call Real-mode procedure with Far Return Frame
+   int386x( 0x31, &Regs, &Regs, &SegRegs );
+
+   if ( Regs.x.cflag )
+      {
+      return( DPMI_Error );
+      }
+
+   return( DPMI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_LockMemory
+
+   Locks a region of memory to keep the virtual memory manager from
+   paging the region out.
+---------------------------------------------------------------------*/
+
+int DPMI_LockMemory
+   (
+   void *address,
+   unsigned length
+   )
+
+   {
+   unsigned linear;
+
+   // Thanks to DOS/4GW's zero-based flat memory model, converting
+   // a pointer of any type to a linear address is trivial.
+
+   linear = (unsigned) address;
+
+   // DPMI Lock Linear Region
+   Regs.w.ax = 0x600;
+
+   // Linear address in BX:CX
+   Regs.w.bx = (linear >> 16);
+   Regs.w.cx = (linear & 0xFFFF);
+
+   // Length in SI:DI
+   Regs.w.si = (length >> 16);
+   Regs.w.di = (length & 0xFFFF);
+
+   int386 (0x31, &Regs, &Regs);
+
+   // Return 0 if can't lock
+   if ( Regs.w.cflag )
+      {
+      return( DPMI_Error );
+      }
+
+   return ( DPMI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_LockMemoryRegion
+
+   Locks a region of memory to keep the virtual memory manager from
+   paging the region out.
+---------------------------------------------------------------------*/
+
+int DPMI_LockMemoryRegion
+   (
+   void *start,
+   void *end
+   )
+
+   {
+   int status;
+
+   status = DPMI_LockMemory( start, ( char * )end - ( char * )start );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_UnlockMemory
+
+   Unlocks a region of memory that was previously locked.
+---------------------------------------------------------------------*/
+
+int DPMI_UnlockMemory
+   (
+   void *address,
+   unsigned length
+   )
+
+   {
+   unsigned linear;
+
+   // Thanks to DOS/4GW's zero-based flat memory model, converting
+   // a pointer of any type to a linear address is trivial.
+
+   linear = (unsigned) address;
+
+   // DPMI Unlock Linear Region
+   Regs.w.ax = 0x601;
+
+   // Linear address in BX:CX
+   Regs.w.bx = (linear >> 16);
+   Regs.w.cx = (linear & 0xFFFF);
+
+   // Length in SI:DI
+   Regs.w.si = (length >> 16);
+   Regs.w.di = (length & 0xFFFF);
+
+   int386 (0x31, &Regs, &Regs);
+
+   // Return 0 if can't unlock
+   if ( Regs.w.cflag )
+      {
+      return( DPMI_Error );
+      }
+
+   return ( DPMI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_UnlockMemoryRegion
+
+   Unlocks a region of memory that was previously locked.
+---------------------------------------------------------------------*/
+
+int DPMI_UnlockMemoryRegion
+   (
+   void *start,
+   void *end
+   )
+
+   {
+   int status;
+
+   status = DPMI_UnlockMemory( start, ( char * )end - ( char * )start );
+
+   return( status );
+   }

Added: tags/rott-1.1/rott/audiolib/dpmi.h
===================================================================
--- tags/rott-1.1/rott/audiolib/dpmi.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/dpmi.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,102 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: DPMI.H
+
+   author: James R. Dose
+   date:   March 31, 1994
+
+   Inline functions for performing DPMI calls.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __DPMI_H
+#define __DPMI_H
+
+enum DPMI_Errors
+   {
+   DPMI_Warning = -2,
+   DPMI_Error   = -1,
+   DPMI_Ok      = 0
+   };
+
+typedef struct
+   {
+   unsigned long  EDI;
+   unsigned long  ESI;
+   unsigned long  EBP;
+   unsigned long  Reserved;
+   unsigned long  EBX;
+   unsigned long  EDX;
+   unsigned long  ECX;
+   unsigned long  EAX;
+   unsigned short Flags;
+   unsigned short ES;
+   unsigned short DS;
+   unsigned short FS;
+   unsigned short GS;
+   unsigned short IP;
+   unsigned short CS;
+   unsigned short SP;
+   unsigned short SS;
+   } dpmi_regs;
+
+unsigned long DPMI_GetRealModeVector( int num );
+void DPMI_SetRealModeVector( int num, unsigned long vector );
+int  DPMI_CallRealModeFunction( dpmi_regs *callregs );
+int  DPMI_GetDOSMemory( void **ptr, long *descriptor, unsigned length );
+int  DPMI_FreeDOSMemory( long descriptor );
+int  DPMI_LockMemory( void *address, unsigned length );
+int  DPMI_LockMemoryRegion( void *start, void *end );
+int  DPMI_UnlockMemory( void *address, unsigned length );
+int  DPMI_UnlockMemoryRegion( void *start, void *end );
+
+#define DPMI_Lock( variable ) \
+   ( DPMI_LockMemory( (void *) &( variable ), sizeof( variable ) ) )
+
+#define DPMI_Unlock( variable ) \
+   ( DPMI_UnlockMemory( (void *) &( variable ), sizeof( variable ) ) )
+
+#ifdef PLAT_DOS
+#pragma aux DPMI_GetDOSMemory = \
+   "mov    eax, 0100h",         \
+   "add    ebx, 15",            \
+   "shr    ebx, 4",             \
+   "int    31h",                \
+   "jc     DPMI_Exit",          \
+   "movzx  eax, ax",            \
+   "shl    eax, 4",             \
+   "mov    [ esi ], eax",       \
+   "mov    [ edi ], edx",       \
+   "sub    eax, eax",           \
+   "DPMI_Exit:",                \
+   parm [ esi ] [ edi ] [ ebx ] modify exact [ eax ebx edx ];
+
+#pragma aux DPMI_FreeDOSMemory = \
+   "mov    eax, 0101h",          \
+   "int    31h",                 \
+   "jc     DPMI_Exit",           \
+   "sub    eax, eax",            \
+   "DPMI_Exit:",                 \
+   parm [ edx ] modify exact [ eax ];
+#endif
+
+#endif

Added: tags/rott-1.1/rott/audiolib/dsl.c
===================================================================
--- tags/rott-1.1/rott/audiolib/dsl.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/dsl.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,235 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "dsl.h"
+#include "util.h"
+
+#include "SDL.h"
+#include "SDL_mixer.h"
+
+extern volatile int MV_MixPage;
+
+static int DSL_ErrorCode = DSL_Ok;
+
+static int mixer_initialized;
+
+static void ( *_CallBackFunc )( void );
+static volatile char *_BufferStart;
+static int _BufferSize;
+static int _NumDivisions;
+static int _SampleRate;
+static int _remainder;
+
+static Mix_Chunk *blank;
+static unsigned char *blank_buf;
+
+/*
+possible todo ideas: cache sdl/sdl mixer error messages.
+*/
+
+char *DSL_ErrorString( int ErrorNumber )
+{
+	char *ErrorString;
+	
+	switch (ErrorNumber) {
+		case DSL_Warning:
+		case DSL_Error:
+			ErrorString = DSL_ErrorString(DSL_ErrorCode);
+			break;
+		
+		case DSL_Ok:
+			ErrorString = "SDL Driver ok.";
+			break;
+		
+		case DSL_SDLInitFailure:
+			ErrorString = "SDL Audio initialization failed.";
+			break;
+		
+		case DSL_MixerActive:
+			ErrorString = "SDL Mixer already initialized.";
+			break;	
+	
+		case DSL_MixerInitFailure:
+			ErrorString = "SDL Mixer initialization failed.";
+			break;
+			
+		default:
+			ErrorString = "Unknown SDL Driver error.";
+			break;
+	}
+	
+	return ErrorString;
+}
+
+static void DSL_SetErrorCode(int ErrorCode)
+{
+	DSL_ErrorCode = ErrorCode;
+}
+
+int DSL_Init( void )
+{
+	DSL_SetErrorCode(DSL_Ok);
+	
+	if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
+		DSL_SetErrorCode(DSL_SDLInitFailure);
+		
+		return DSL_Error;
+	}
+	
+	return DSL_Ok;
+}
+
+void DSL_Shutdown( void )
+{
+	DSL_StopPlayback();
+}
+
+static void mixer_callback(int chan, void *stream, int len, void *udata)
+{
+	Uint8 *stptr;
+	Uint8 *fxptr;
+	int copysize;
+	
+	/* len should equal _BufferSize, else this is screwed up */
+
+	stptr = (Uint8 *)stream;
+	
+	if (_remainder > 0) {
+		copysize = min(len, _remainder);
+		
+		fxptr = (Uint8 *)(&_BufferStart[MV_MixPage * 
+			_BufferSize]);
+		
+		memcpy(stptr, fxptr+(_BufferSize-_remainder), copysize);
+		
+		len -= copysize;
+		_remainder -= copysize;
+		
+		stptr += copysize;
+	}
+	
+	while (len > 0) {
+		/* new buffer */
+		
+		_CallBackFunc();
+		
+		fxptr = (Uint8 *)(&_BufferStart[MV_MixPage * 
+			_BufferSize]);
+
+		copysize = min(len, _BufferSize);
+		
+		memcpy(stptr, fxptr, copysize);
+		
+		len -= copysize;
+		
+		stptr += copysize;
+	}
+	
+	_remainder = len;
+}
+
+int   DSL_BeginBufferedPlayback( char *BufferStart,
+      int BufferSize, int NumDivisions, unsigned SampleRate,
+      int MixMode, void ( *CallBackFunc )( void ) )
+{
+	Uint16 format;
+	Uint8 *tmp;
+	int channels;
+	int chunksize;
+		
+	if (mixer_initialized) {
+		DSL_SetErrorCode(DSL_MixerActive);
+		
+		return DSL_Error;
+	}
+	
+	_CallBackFunc = CallBackFunc;
+	_BufferStart = BufferStart;
+	_BufferSize = (BufferSize / NumDivisions);
+	_NumDivisions = NumDivisions;
+	_SampleRate = SampleRate;
+
+	_remainder = 0;
+	
+	format = (MixMode & SIXTEEN_BIT) ? AUDIO_S16SYS : AUDIO_U8;
+	channels = (MixMode & STEREO) ? 2 : 1;
+
+/*
+	23ms is typically ideal (11025,22050,44100)
+	46ms isn't bad
+*/
+	
+	chunksize = 512;
+	
+	if (SampleRate >= 16000) chunksize *= 2;
+	if (SampleRate >= 32000) chunksize *= 2;
+	
+/*	
+// SDL mixer does this already
+	if (MixMode & SIXTEEN_BIT) chunksize *= 2;
+	if (MixMode & STEREO) chunksize *= 2;
+*/
+	
+	if (Mix_OpenAudio(SampleRate, format, channels, chunksize) < 0) {
+		DSL_SetErrorCode(DSL_MixerInitFailure);
+		
+		return DSL_Error;
+	}
+
+/*
+	Mix_SetPostMix(mixer_callback, NULL);
+*/
+	/* have to use a channel because postmix will overwrite the music... */
+	Mix_RegisterEffect(0, mixer_callback, NULL, NULL);
+	
+	/* create a dummy sample just to allocate that channel */
+	blank_buf = (Uint8 *)malloc(4096);
+	memset(blank_buf, 0, 4096);
+	
+	blank = Mix_QuickLoad_RAW(blank_buf, 4096);
+		
+	Mix_PlayChannel(0, blank, -1);
+	
+	mixer_initialized = 1;
+	
+	return DSL_Ok;
+}
+
+void DSL_StopPlayback( void )
+{
+	if (mixer_initialized) {
+		Mix_HaltChannel(0);
+	}
+	
+	if (blank != NULL) {
+		Mix_FreeChunk(blank);
+	}
+	
+	blank = NULL;
+	
+	if (blank_buf  != NULL) {
+		free(blank_buf);
+	}
+	
+	blank_buf = NULL;
+	
+	if (mixer_initialized) {
+		Mix_CloseAudio();
+	}
+	
+	mixer_initialized = 0;
+}
+
+unsigned DSL_GetPlaybackRate( void )
+{
+	return _SampleRate;
+}
+
+unsigned long DisableInterrupts( void )
+{
+	return 0;
+}
+
+void RestoreInterrupts( unsigned long flags )
+{
+}

Added: tags/rott-1.1/rott/audiolib/dsl.h
===================================================================
--- tags/rott-1.1/rott/audiolib/dsl.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/dsl.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,28 @@
+#ifndef AUDIOLIB__DSL_H
+#define AUDIOLIB__DSL_H
+
+#define MONO_8BIT    0
+#define STEREO      1
+#define SIXTEEN_BIT 2
+#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
+
+enum DSL_ERRORS
+   {
+   DSL_Warning = -2,
+   DSL_Error = -1,
+   DSL_Ok = 0,
+   DSL_SDLInitFailure,
+   DSL_MixerActive,
+   DSL_MixerInitFailure
+   };
+
+char *DSL_ErrorString( int ErrorNumber );
+int   DSL_Init( void );
+void  DSL_StopPlayback( void );
+unsigned DSL_GetPlaybackRate( void );
+int   DSL_BeginBufferedPlayback( char *BufferStart,
+      int BufferSize, int NumDivisions, unsigned SampleRate,
+      int MixMode, void ( *CallBackFunc )( void ) );
+void  DSL_Shutdown( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/fx_man.c
===================================================================
--- tags/rott-1.1/rott/audiolib/fx_man.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/fx_man.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1376 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: FX_MAN.C
+
+   author: James R. Dose
+   date:   March 17, 1994
+
+   Device independant sound effect routines.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "sndcards.h"
+#include "multivoc.h"
+
+#ifdef PLAT_DOS
+#include "blaster.h"
+#include "pas16.h"
+#include "sndscape.h"
+#include "guswave.h"
+#include "sndsrc.h"
+#else
+#include "dsl.h"
+#endif
+
+#include "ll_man.h"
+#include "user.h"
+#include "fx_man.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+static unsigned FX_MixRate;
+
+int FX_SoundDevice = -1;
+int FX_ErrorCode = FX_Ok;
+int FX_Installed = FALSE;
+
+#define FX_SetErrorCode( status ) \
+   FX_ErrorCode = ( status );
+
+/*---------------------------------------------------------------------
+   Function: FX_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *FX_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case FX_Warning :
+      case FX_Error :
+         ErrorString = FX_ErrorString( FX_ErrorCode );
+         break;
+
+      case FX_Ok :
+         ErrorString = "Fx ok.";
+         break;
+
+      case FX_ASSVersion :
+         ErrorString = "Apogee Sound System Version " ASS_VERSION_STRING "  "
+            "Programmed by Jim Dose\n"
+            "(c) Copyright 1995 James R. Dose.  All Rights Reserved.\n";
+         break;
+
+#ifdef PLAT_DOS
+      case FX_BlasterError :
+         ErrorString = BLASTER_ErrorString( BLASTER_Error );
+         break;
+#endif
+
+      case FX_SoundCardError :
+#ifdef PLAT_DOS
+         switch( FX_SoundDevice )
+         {
+            case SoundBlaster :
+            case Awe32 :
+               ErrorString = BLASTER_ErrorString( BLASTER_Error );
+               break;
+
+            case ProAudioSpectrum :
+            case SoundMan16 :
+               ErrorString = PAS_ErrorString( PAS_Error );
+               break;
+
+            case SoundScape :
+               ErrorString = SOUNDSCAPE_ErrorString( SOUNDSCAPE_Error );
+               break;
+
+            case UltraSound :
+               ErrorString = GUSWAVE_ErrorString( GUSWAVE_Error );
+               break;
+
+            case SoundSource :
+            case TandySoundSource :
+               ErrorString = SS_ErrorString( SS_Error );
+               break;
+            }
+#else
+         ErrorString = DSL_ErrorString( DSL_Error );
+#endif
+         break;
+
+      case FX_InvalidCard :
+         ErrorString = "Invalid Sound Fx device.";
+         break;
+
+      case FX_MultiVocError :
+         ErrorString = MV_ErrorString( MV_Error );
+         break;
+
+      case FX_DPMI_Error :
+         ErrorString = "DPMI Error in FX_MAN.";
+         break;
+
+      default :
+         ErrorString = "Unknown Fx error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SetupCard
+
+   Sets the configuration of a sound device.
+---------------------------------------------------------------------*/
+
+int FX_SetupCard
+   (
+   int SoundCard,
+   fx_device *device
+   )
+
+   {
+   int status;
+   int DeviceStatus;
+
+   if ( USER_CheckParameter( "ASSVER" ) )
+      {
+      FX_SetErrorCode( FX_ASSVersion );
+      return( FX_Error );
+      }
+
+   FX_SoundDevice = SoundCard;
+
+   status = FX_Ok;
+   FX_SetErrorCode( FX_Ok );
+
+#ifdef PLAT_DOS
+   switch( SoundCard )
+      {
+      case SoundBlaster :
+      case Awe32 :
+         DeviceStatus = BLASTER_Init();
+         if ( DeviceStatus != BLASTER_Ok )
+            {
+            FX_SetErrorCode( FX_SoundCardError );
+            status = FX_Error;
+            break;
+            }
+
+         device->MaxVoices = 32;
+         BLASTER_GetCardInfo( &device->MaxSampleBits, &device->MaxChannels );
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         DeviceStatus = PAS_Init();
+         if ( DeviceStatus != PAS_Ok )
+            {
+            FX_SetErrorCode( FX_SoundCardError );
+            status = FX_Error;
+            break;
+            }
+
+         device->MaxVoices = 32;
+         PAS_GetCardInfo( &device->MaxSampleBits, &device->MaxChannels );
+         break;
+
+      case GenMidi :
+      case SoundCanvas :
+      case WaveBlaster :
+         device->MaxVoices     = 0;
+         device->MaxSampleBits = 0;
+         device->MaxChannels   = 0;
+         break;
+
+      case SoundScape :
+         device->MaxVoices = 32;
+         DeviceStatus = SOUNDSCAPE_GetCardInfo( &device->MaxSampleBits,
+            &device->MaxChannels );
+         if ( DeviceStatus != SOUNDSCAPE_Ok )
+            {
+            FX_SetErrorCode( FX_SoundCardError );
+            status = FX_Error;
+            }
+         break;
+
+      case UltraSound :
+         if ( GUSWAVE_Init( 8 ) != GUSWAVE_Ok )
+            {
+            FX_SetErrorCode( FX_SoundCardError );
+            status = FX_Error;
+            break;
+            }
+
+         device->MaxVoices     = 8;
+         device->MaxSampleBits = 0;
+         device->MaxChannels   = 0;
+         break;
+
+      case SoundSource :
+      case TandySoundSource :
+         DeviceStatus = SS_Init( SoundCard );
+         if ( DeviceStatus != SS_Ok )
+            {
+            FX_SetErrorCode( FX_SoundCardError );
+            status = FX_Error;
+            break;
+            }
+         SS_Shutdown();
+         device->MaxVoices     = 32;
+         device->MaxSampleBits = 8;
+         device->MaxChannels   = 1;
+         break;
+      default :
+         FX_SetErrorCode( FX_InvalidCard );
+         status = FX_Error;
+      }
+#else
+      DeviceStatus = DSL_Init();
+      if ( DeviceStatus != DSL_Ok )
+         {
+         FX_SetErrorCode( FX_SoundCardError );
+         status = FX_Error;
+         }
+         else
+         {
+         device->MaxVoices     = 32;
+         device->MaxSampleBits = 0;
+         device->MaxChannels   = 0;
+         }
+#endif
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_GetBlasterSettings
+
+   Returns the current BLASTER environment variable settings.
+---------------------------------------------------------------------*/
+
+int FX_GetBlasterSettings
+   (
+   fx_blaster_config *blaster
+   )
+
+   {
+#ifdef PLAT_DOS
+   int status;
+   BLASTER_CONFIG Blaster;
+
+   FX_SetErrorCode( FX_Ok );
+
+   status = BLASTER_GetEnv( &Blaster );
+   if ( status != BLASTER_Ok )
+      {
+      FX_SetErrorCode( FX_BlasterError );
+      return( FX_Error );
+      }
+
+   blaster->Type      = Blaster.Type;
+   blaster->Address   = Blaster.Address;
+   blaster->Interrupt = Blaster.Interrupt;
+   blaster->Dma8      = Blaster.Dma8;
+   blaster->Dma16     = Blaster.Dma16;
+   blaster->Midi      = Blaster.Midi;
+   blaster->Emu       = Blaster.Emu;
+#endif
+
+   return( FX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SetupSoundBlaster
+
+   Handles manual setup of the Sound Blaster information.
+---------------------------------------------------------------------*/
+
+int FX_SetupSoundBlaster
+   (
+   fx_blaster_config blaster,
+   int *MaxVoices,
+   int *MaxSampleBits,
+   int *MaxChannels
+   )
+
+   {
+#ifdef PLAT_DOS
+   int DeviceStatus;
+   BLASTER_CONFIG Blaster;
+
+   FX_SetErrorCode( FX_Ok );
+
+   FX_SoundDevice = SoundBlaster;
+
+   Blaster.Type      = blaster.Type;
+   Blaster.Address   = blaster.Address;
+   Blaster.Interrupt = blaster.Interrupt;
+   Blaster.Dma8      = blaster.Dma8;
+   Blaster.Dma16     = blaster.Dma16;
+   Blaster.Midi      = blaster.Midi;
+   Blaster.Emu       = blaster.Emu;
+
+   BLASTER_SetCardSettings( Blaster );
+
+   DeviceStatus = BLASTER_Init();
+   if ( DeviceStatus != BLASTER_Ok )
+      {
+      FX_SetErrorCode( FX_SoundCardError );
+      return( FX_Error );
+      }
+
+   *MaxVoices = 8;
+   BLASTER_GetCardInfo( MaxSampleBits, MaxChannels );
+#endif
+
+   return( FX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_Init
+
+   Selects which sound device to use.
+---------------------------------------------------------------------*/
+
+int FX_Init
+   (
+   int SoundCard,
+   int numvoices,
+   int numchannels,
+   int samplebits,
+   unsigned mixrate
+   )
+
+   {
+   int status;
+   int devicestatus;
+
+   if ( FX_Installed )
+      {
+      FX_Shutdown();
+      }
+
+   if ( USER_CheckParameter( "ASSVER" ) )
+      {
+      FX_SetErrorCode( FX_ASSVersion );
+      return( FX_Error );
+      }
+
+   status = LL_LockMemory();
+   if ( status != LL_Ok )
+      {
+      FX_SetErrorCode( FX_DPMI_Error );
+      return( FX_Error );
+      }
+
+   FX_MixRate = mixrate;
+
+   status = FX_Ok;
+   FX_SoundDevice = SoundCard;
+   switch( SoundCard )
+      {
+      case SoundBlaster :
+      case Awe32 :
+      case ProAudioSpectrum :
+      case SoundMan16 :
+      case SoundScape :
+      case SoundSource :
+      case TandySoundSource :
+      case UltraSound :
+         devicestatus = MV_Init( SoundCard, FX_MixRate, numvoices,
+            numchannels, samplebits );
+         if ( devicestatus != MV_Ok )
+            {
+            FX_SetErrorCode( FX_MultiVocError );
+            status = FX_Error;
+            }
+         break;
+
+      default :
+         FX_SetErrorCode( FX_InvalidCard );
+         status = FX_Error;
+      }
+
+   if ( status != FX_Ok )
+      {
+      LL_UnlockMemory();
+      }
+   else
+      {
+      FX_Installed = TRUE;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_Shutdown
+
+   Terminates use of sound device.
+---------------------------------------------------------------------*/
+
+int FX_Shutdown
+   (
+   void
+   )
+
+   {
+   int status;
+
+   if ( !FX_Installed )
+      {
+      return( FX_Ok );
+      }
+
+   status = FX_Ok;
+   switch( FX_SoundDevice )
+      {
+      case SoundBlaster :
+      case Awe32 :
+      case ProAudioSpectrum :
+      case SoundMan16 :
+      case SoundScape :
+      case SoundSource :
+      case TandySoundSource :
+      case UltraSound :
+         status = MV_Shutdown();
+         if ( status != MV_Ok )
+            {
+            FX_SetErrorCode( FX_MultiVocError );
+            status = FX_Error;
+            }
+         break;
+
+      default :
+         FX_SetErrorCode( FX_InvalidCard );
+         status = FX_Error;
+      }
+
+   FX_Installed = FALSE;
+   LL_UnlockMemory();
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SetCallback
+
+   Sets the function to call when a voice is done.
+---------------------------------------------------------------------*/
+
+int FX_SetCallBack
+   (
+   void ( *function )( unsigned long )
+   )
+
+   {
+   int status;
+
+   status = FX_Ok;
+
+   switch( FX_SoundDevice )
+      {
+      case SoundBlaster :
+      case Awe32 :
+      case ProAudioSpectrum :
+      case SoundMan16 :
+      case SoundScape :
+      case SoundSource :
+      case TandySoundSource :
+      case UltraSound :
+         MV_SetCallBack( function );
+         break;
+
+      default :
+         FX_SetErrorCode( FX_InvalidCard );
+         status = FX_Error;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SetVolume
+
+   Sets the volume of the current sound device.
+---------------------------------------------------------------------*/
+
+void FX_SetVolume
+   (
+   int volume
+   )
+
+   {
+   int status;
+
+#ifdef PLAT_DOS
+   switch( FX_SoundDevice )
+      {
+      case SoundBlaster :
+      case Awe32 :
+         if ( BLASTER_CardHasMixer() )
+            {
+            BLASTER_SetVoiceVolume( volume );
+            }
+         else
+            {
+            MV_SetVolume( volume );
+            }
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         status = PAS_SetPCMVolume( volume );
+         if ( status != PAS_Ok )
+            {
+            MV_SetVolume( volume );
+            }
+         break;
+
+      case GenMidi :
+      case SoundCanvas :
+      case WaveBlaster :
+         break;
+
+      case SoundScape :
+         MV_SetVolume( volume );
+         break;
+
+      case UltraSound :
+         GUSWAVE_SetVolume( volume );
+         break;
+
+      case SoundSource :
+      case TandySoundSource :
+         MV_SetVolume( volume );
+         break;
+      }
+#else
+   MV_SetVolume( volume );
+#endif
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_GetVolume
+
+   Returns the volume of the current sound device.
+---------------------------------------------------------------------*/
+
+int FX_GetVolume
+   (
+   void
+   )
+
+   {
+   int volume;
+
+#ifdef PLAT_DOS
+   switch( FX_SoundDevice )
+      {
+      case SoundBlaster :
+      case Awe32 :
+         if ( BLASTER_CardHasMixer() )
+            {
+            volume = BLASTER_GetVoiceVolume();
+            }
+         else
+            {
+            volume = MV_GetVolume();
+            }
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         volume = PAS_GetPCMVolume();
+         if ( volume == PAS_Error )
+            {
+            volume = MV_GetVolume();
+            }
+         break;
+
+      case GenMidi :
+      case SoundCanvas :
+      case WaveBlaster :
+         volume = 255;
+         break;
+
+      case SoundScape :
+         volume = MV_GetVolume();
+         break;
+
+      case UltraSound :
+         volume = GUSWAVE_GetVolume();
+         break;
+
+      case SoundSource :
+      case TandySoundSource :
+         volume = MV_GetVolume();
+         break;
+
+      default :
+         volume = 0;
+      }
+#else
+   volume = MV_GetVolume();
+#endif
+
+   return( volume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SetReverseStereo
+
+   Set the orientation of the left and right channels.
+---------------------------------------------------------------------*/
+
+void FX_SetReverseStereo
+   (
+   int setting
+   )
+
+   {
+   MV_SetReverseStereo( setting );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_GetReverseStereo
+
+   Returns the orientation of the left and right channels.
+---------------------------------------------------------------------*/
+
+int FX_GetReverseStereo
+   (
+   void
+   )
+
+   {
+   return MV_GetReverseStereo();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SetReverb
+
+   Sets the reverb level.
+---------------------------------------------------------------------*/
+
+void FX_SetReverb
+   (
+   int reverb
+   )
+
+   {
+   MV_SetReverb( reverb );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SetFastReverb
+
+   Sets the reverb level.
+---------------------------------------------------------------------*/
+
+void FX_SetFastReverb
+   (
+   int reverb
+   )
+
+   {
+   MV_SetFastReverb( reverb );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_GetMaxReverbDelay
+
+   Returns the maximum delay time for reverb.
+---------------------------------------------------------------------*/
+
+int FX_GetMaxReverbDelay
+   (
+   void
+   )
+
+   {
+   return MV_GetMaxReverbDelay();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_GetReverbDelay
+
+   Returns the current delay time for reverb.
+---------------------------------------------------------------------*/
+
+int FX_GetReverbDelay
+   (
+   void
+   )
+
+   {
+   return MV_GetReverbDelay();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SetReverbDelay
+
+   Sets the delay level of reverb to add to mix.
+---------------------------------------------------------------------*/
+
+void FX_SetReverbDelay
+   (
+   int delay
+   )
+
+   {
+   MV_SetReverbDelay( delay );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_VoiceAvailable
+
+   Checks if a voice can be play at the specified priority.
+---------------------------------------------------------------------*/
+
+int FX_VoiceAvailable
+   (
+   int priority
+   )
+
+   {
+   return MV_VoiceAvailable( priority );
+   }
+
+/*---------------------------------------------------------------------
+   Function: FX_EndLooping
+
+   Stops the voice associated with the specified handle from looping
+   without stoping the sound.
+---------------------------------------------------------------------*/
+
+int FX_EndLooping
+   (
+   int handle
+   )
+
+   {
+   int status;
+
+   status = MV_EndLooping( handle );
+   if ( status == MV_Error )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      status = FX_Warning;
+      }
+
+   return( status );
+   }
+
+/*---------------------------------------------------------------------
+   Function: FX_SetPan
+
+   Sets the stereo and mono volume level of the voice associated
+   with the specified handle.
+---------------------------------------------------------------------*/
+
+int FX_SetPan
+   (
+   int handle,
+   int vol,
+   int left,
+   int right
+   )
+
+   {
+   int status;
+
+   status = MV_SetPan( handle, vol, left, right );
+   if ( status == MV_Error )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      status = FX_Warning;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SetPitch
+
+   Sets the pitch of the voice associated with the specified handle.
+---------------------------------------------------------------------*/
+
+int FX_SetPitch
+   (
+   int handle,
+   int pitchoffset
+   )
+
+   {
+   int status;
+
+   status = MV_SetPitch( handle, pitchoffset );
+   if ( status == MV_Error )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      status = FX_Warning;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SetFrequency
+
+   Sets the frequency of the voice associated with the specified handle.
+---------------------------------------------------------------------*/
+
+int FX_SetFrequency
+   (
+   int handle,
+   int frequency
+   )
+
+   {
+   int status;
+
+   status = MV_SetFrequency( handle, frequency );
+   if ( status == MV_Error )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      status = FX_Warning;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_PlayVOC
+
+   Begin playback of sound data with the given volume and priority.
+---------------------------------------------------------------------*/
+
+int FX_PlayVOC
+   (
+   char *ptr,
+   int pitchoffset,
+   int vol,
+   int left,
+   int right,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   int handle;
+
+   handle = MV_PlayVOC( ptr, pitchoffset, vol, left, right,
+      priority, callbackval );
+   if ( handle < MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      handle = FX_Warning;
+      }
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_PlayLoopedVOC
+
+   Begin playback of sound data with the given volume and priority.
+---------------------------------------------------------------------*/
+
+int FX_PlayLoopedVOC
+   (
+   char *ptr,
+   long loopstart,
+   long loopend,
+   int pitchoffset,
+   int vol,
+   int left,
+   int right,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   int handle;
+
+   handle = MV_PlayLoopedVOC( ptr, loopstart, loopend, pitchoffset,
+      vol, left, right, priority, callbackval );
+   if ( handle < MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      handle = FX_Warning;
+      }
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_PlayWAV
+
+   Begin playback of sound data with the given volume and priority.
+---------------------------------------------------------------------*/
+
+int FX_PlayWAV
+   (
+   char *ptr,
+   int pitchoffset,
+   int vol,
+   int left,
+   int right,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   int handle;
+
+   handle = MV_PlayWAV( ptr, pitchoffset, vol, left, right,
+      priority, callbackval );
+   if ( handle < MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      handle = FX_Warning;
+      }
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_PlayWAV
+
+   Begin playback of sound data with the given volume and priority.
+---------------------------------------------------------------------*/
+
+int FX_PlayLoopedWAV
+   (
+   char *ptr,
+   long loopstart,
+   long loopend,
+   int pitchoffset,
+   int vol,
+   int left,
+   int right,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   int handle;
+
+   handle = MV_PlayLoopedWAV( ptr, loopstart, loopend,
+      pitchoffset, vol, left, right, priority, callbackval );
+   if ( handle < MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      handle = FX_Warning;
+      }
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_PlayVOC3D
+
+   Begin playback of sound data at specified angle and distance
+   from listener.
+---------------------------------------------------------------------*/
+
+int FX_PlayVOC3D
+   (
+   char *ptr,
+   int pitchoffset,
+   int angle,
+   int distance,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   int handle;
+
+   handle = MV_PlayVOC3D( ptr, pitchoffset, angle, distance,
+      priority, callbackval );
+   if ( handle < MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      handle = FX_Warning;
+      }
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_PlayWAV3D
+
+   Begin playback of sound data at specified angle and distance
+   from listener.
+---------------------------------------------------------------------*/
+
+int FX_PlayWAV3D
+   (
+   char *ptr,
+   int pitchoffset,
+   int angle,
+   int distance,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   int handle;
+
+   handle = MV_PlayWAV3D( ptr, pitchoffset, angle, distance,
+      priority, callbackval );
+   if ( handle < MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      handle = FX_Warning;
+      }
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_PlayRaw
+
+   Begin playback of raw sound data with the given volume and priority.
+---------------------------------------------------------------------*/
+
+int FX_PlayRaw
+   (
+   char *ptr,
+   unsigned long length,
+   unsigned rate,
+   int pitchoffset,
+   int vol,
+   int left,
+   int right,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   int handle;
+
+   handle = MV_PlayRaw( ptr, length, rate, pitchoffset,
+      vol, left, right, priority, callbackval );
+   if ( handle < MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      handle = FX_Warning;
+      }
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_PlayLoopedRaw
+
+   Begin playback of raw sound data with the given volume and priority.
+---------------------------------------------------------------------*/
+
+int FX_PlayLoopedRaw
+   (
+   char *ptr,
+   unsigned long length,
+   char *loopstart,
+   char *loopend,
+   unsigned rate,
+   int pitchoffset,
+   int vol,
+   int left,
+   int right,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   int handle;
+
+   handle = MV_PlayLoopedRaw( ptr, length, loopstart, loopend,
+      rate, pitchoffset, vol, left, right, priority, callbackval );
+   if ( handle < MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      handle = FX_Warning;
+      }
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_Pan3D
+
+   Set the angle and distance from the listener of the voice associated
+   with the specified handle.
+---------------------------------------------------------------------*/
+
+int FX_Pan3D
+   (
+   int handle,
+   int angle,
+   int distance
+   )
+
+   {
+   int status;
+
+   status = MV_Pan3D( handle, angle, distance );
+   if ( status != MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      status = FX_Warning;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SoundActive
+
+   Tests if the specified sound is currently playing.
+---------------------------------------------------------------------*/
+
+int FX_SoundActive
+   (
+   int handle
+   )
+
+   {
+   return( MV_VoicePlaying( handle ) );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_SoundsPlaying
+
+   Reports the number of voices playing.
+---------------------------------------------------------------------*/
+
+int FX_SoundsPlaying
+   (
+   void
+   )
+
+   {
+   return( MV_VoicesPlaying() );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_StopSound
+
+   Halts playback of a specific voice
+---------------------------------------------------------------------*/
+
+int FX_StopSound
+   (
+   int handle
+   )
+
+   {
+   int status;
+
+   status = MV_Kill( handle );
+   if ( status != MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      return( FX_Warning );
+      }
+
+   return( FX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_StopAllSounds
+
+   Halts playback of all sounds.
+---------------------------------------------------------------------*/
+
+int FX_StopAllSounds
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status = MV_KillAllVoices();
+   if ( status != MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      return( FX_Warning );
+      }
+
+   return( FX_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_StartDemandFeedPlayback
+
+   Plays a digitized sound from a user controlled buffering system.
+---------------------------------------------------------------------*/
+
+int FX_StartDemandFeedPlayback
+   (
+   void ( *function )( char **ptr, unsigned long *length ),
+   int rate,
+   int pitchoffset,
+   int vol,
+   int left,
+   int right,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   int handle;
+
+   handle = MV_StartDemandFeedPlayback( function, rate,
+      pitchoffset, vol, left, right, priority, callbackval );
+   if ( handle < MV_Ok )
+      {
+      FX_SetErrorCode( FX_MultiVocError );
+      handle = FX_Warning;
+      }
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_StartRecording
+
+   Starts the sound recording engine.
+---------------------------------------------------------------------*/
+
+int FX_StartRecording
+   (
+   int MixRate,
+   void ( *function )( char *ptr, int length )
+   )
+
+   {
+   int status;
+
+#ifdef PLAT_DOS
+   switch( FX_SoundDevice )
+      {
+      case SoundBlaster :
+      case Awe32 :
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         status = MV_StartRecording( MixRate, function );
+         if ( status != MV_Ok )
+            {
+            FX_SetErrorCode( FX_MultiVocError );
+            status = FX_Warning;
+            }
+         else
+            {
+            status = FX_Ok;
+            }
+         break;
+
+      default :
+         FX_SetErrorCode( FX_InvalidCard );
+         status = FX_Warning;
+         break;
+      }
+#else
+   FX_SetErrorCode( FX_InvalidCard );
+   status = FX_Warning;
+#endif
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: FX_StopRecord
+
+   Stops the sound record engine.
+---------------------------------------------------------------------*/
+
+void FX_StopRecord
+   (
+   void
+   )
+
+   {
+#ifdef PLAT_DOS
+   // Stop sound playback
+   switch( FX_SoundDevice )
+      {
+      case SoundBlaster :
+      case Awe32 :
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         MV_StopRecord();
+         break;
+      }
+#endif
+   }

Added: tags/rott-1.1/rott/audiolib/fx_man.h
===================================================================
--- tags/rott-1.1/rott/audiolib/fx_man.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/fx_man.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,135 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: FX_MAN.H
+
+   author: James R. Dose
+   date:   March 17, 1994
+
+   Public header for FX_MAN.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __FX_MAN_H
+#define __FX_MAN_H
+
+#include "sndcards.h"
+
+typedef struct
+   {
+   int MaxVoices;
+   int MaxSampleBits;
+   int MaxChannels;
+   } fx_device;
+
+#define MonoFx   1
+#define StereoFx 2
+
+typedef struct
+   {
+   unsigned long Address;
+   unsigned long Type;
+   unsigned long Interrupt;
+   unsigned long Dma8;
+   unsigned long Dma16;
+   unsigned long Midi;
+   unsigned long Emu;
+   } fx_blaster_config;
+
+enum FX_ERRORS
+   {
+   FX_Warning = -2,
+   FX_Error = -1,
+   FX_Ok = 0,
+   FX_ASSVersion,
+   FX_BlasterError,
+   FX_SoundCardError,
+   FX_InvalidCard,
+   FX_MultiVocError,
+   FX_DPMI_Error
+   };
+
+enum fx_BLASTER_Types
+   {
+   fx_SB     = 1,
+   fx_SBPro  = 2,
+   fx_SB20   = 3,
+   fx_SBPro2 = 4,
+   fx_SB16   = 6
+   };
+
+
+char *FX_ErrorString( int ErrorNumber );
+int   FX_SetupCard( int SoundCard, fx_device *device );
+int   FX_GetBlasterSettings( fx_blaster_config *blaster );
+int   FX_SetupSoundBlaster( fx_blaster_config blaster, int *MaxVoices, int *MaxSampleBits, int *MaxChannels );
+int   FX_Init( int SoundCard, int numvoices, int numchannels, int samplebits, unsigned mixrate );
+int   FX_Shutdown( void );
+int   FX_SetCallBack( void ( *function )( unsigned long ) );
+void  FX_SetVolume( int volume );
+int   FX_GetVolume( void );
+
+void  FX_SetReverseStereo( int setting );
+int   FX_GetReverseStereo( void );
+void  FX_SetReverb( int reverb );
+void  FX_SetFastReverb( int reverb );
+int   FX_GetMaxReverbDelay( void );
+int   FX_GetReverbDelay( void );
+void  FX_SetReverbDelay( int delay );
+
+int FX_VoiceAvailable( int priority );
+int FX_EndLooping( int handle );
+int FX_SetPan( int handle, int vol, int left, int right );
+int FX_SetPitch( int handle, int pitchoffset );
+int FX_SetFrequency( int handle, int frequency );
+
+int FX_PlayVOC( char *ptr, int pitchoffset, int vol, int left, int right,
+       int priority, unsigned long callbackval );
+int FX_PlayLoopedVOC( char *ptr, long loopstart, long loopend,
+       int pitchoffset, int vol, int left, int right, int priority,
+       unsigned long callbackval );
+int FX_PlayWAV( char *ptr, int pitchoffset, int vol, int left, int right,
+       int priority, unsigned long callbackval );
+int FX_PlayLoopedWAV( char *ptr, long loopstart, long loopend,
+       int pitchoffset, int vol, int left, int right, int priority,
+       unsigned long callbackval );
+int FX_PlayVOC3D( char *ptr, int pitchoffset, int angle, int distance,
+       int priority, unsigned long callbackval );
+int FX_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance,
+       int priority, unsigned long callbackval );
+int FX_PlayRaw( char *ptr, unsigned long length, unsigned rate,
+       int pitchoffset, int vol, int left, int right, int priority,
+       unsigned long callbackval );
+int FX_PlayLoopedRaw( char *ptr, unsigned long length, char *loopstart,
+       char *loopend, unsigned rate, int pitchoffset, int vol, int left,
+       int right, int priority, unsigned long callbackval );
+int FX_Pan3D( int handle, int angle, int distance );
+int FX_SoundActive( int handle );
+int FX_SoundsPlaying( void );
+int FX_StopSound( int handle );
+int FX_StopAllSounds( void );
+int FX_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ),
+       int rate, int pitchoffset, int vol, int left, int right,
+       int priority, unsigned long callbackval );
+int  FX_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) );
+void FX_StopRecord( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/gmtimbre.c
===================================================================
--- tags/rott-1.1/rott/audiolib/gmtimbre.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/gmtimbre.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,290 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+typedef struct
+   {
+   unsigned char SAVEK[ 2 ];
+   unsigned char Level[ 2 ];
+   unsigned char Env1[ 2 ];
+   unsigned char Env2[ 2 ];
+   unsigned char Wave[ 2 ];
+   unsigned char Feedback;
+   signed   char Transpose;
+   signed   char Velocity;
+   } TIMBRE;
+
+TIMBRE ADLIB_TimbreBank[ 256 ] =
+   {
+      { { 33, 33 }, { 143, 6 }, { 242, 242 }, { 69, 118 }, { 0, 0 }, 8, 0 },
+      { { 49, 33 }, { 75, 0 }, { 242, 242 }, { 84, 86 }, { 0, 0 }, 8, 0 },
+      { { 49, 33 }, { 73, 0 }, { 242, 242 }, { 85, 118 }, { 0, 0 }, 8, 0 },
+      { { 177, 97 }, { 14, 0 }, { 242, 243 }, { 59, 11 }, { 0, 0 }, 6, 0 },
+      { { 1, 33 }, { 87, 0 }, { 241, 241 }, { 56, 40 }, { 0, 0 }, 0, 0 },
+      { { 1, 33 }, { 147, 0 }, { 241, 241 }, { 56, 40 }, { 0, 0 }, 0, 0 },
+      { { 33, 54 }, { 128, 14 }, { 162, 241 }, { 1, 213 }, { 0, 0 }, 8, 0 },
+      { { 1, 1 }, { 146, 0 }, { 194, 194 }, { 168, 88 }, { 0, 0 }, 10, 0 },
+      { { 12, 129 }, { 92, 0 }, { 246, 243 }, { 84, 181 }, { 0, 0 }, 0, 0 },
+      { { 7, 17 }, { 151, 128 }, { 246, 245 }, { 50, 17 }, { 0, 0 }, 2, 0 },
+      { { 23, 1 }, { 33, 0 }, { 86, 246 }, { 4, 4 }, { 0, 0 }, 2, 0 },
+      { { 24, 129 }, { 98, 0 }, { 243, 242 }, { 230, 246 }, { 0, 0 }, 0, 0 },
+      { { 24, 33 }, { 35, 0 }, { 247, 229 }, { 85, 216 }, { 0, 0 }, 0, 0 },
+      { { 21, 1 }, { 145, 0 }, { 246, 246 }, { 166, 230 }, { 0, 0 }, 4, 0 },
+      { { 69, 129 }, { 89, 128 }, { 211, 163 }, { 130, 227 }, { 0, 0 }, 12, 0 },
+      { { 3, 129 }, { 73, 128 }, { 116, 179 }, { 85, 5 }, { 1, 0 }, 4, 0 },
+      { { 113, 49 }, { 146, 0 }, { 246, 241 }, { 20, 7 }, { 0, 0 }, 2, 0 },
+      { { 114, 48 }, { 20, 0 }, { 199, 199 }, { 88, 8 }, { 0, 0 }, 2, 0 },
+      { { 112, 177 }, { 68, 0 }, { 170, 138 }, { 24, 8 }, { 0, 0 }, 4, 0 },
+      { { 35, 177 }, { 147, 0 }, { 151, 85 }, { 35, 20 }, { 1, 0 }, 4, 0 },
+      { { 97, 177 }, { 19, 128 }, { 151, 85 }, { 4, 4 }, { 1, 0 }, 0, 0 },
+      { { 36, 177 }, { 72, 0 }, { 152, 70 }, { 42, 26 }, { 1, 0 }, 12, 0 },
+      { { 97, 33 }, { 19, 0 }, { 145, 97 }, { 6, 7 }, { 1, 0 }, 10, 0 },
+      { { 33, 161 }, { 19, 137 }, { 113, 97 }, { 6, 7 }, { 0, 0 }, 6, 0 },
+      { { 2, 65 }, { 156, 128 }, { 243, 243 }, { 148, 200 }, { 1, 0 }, 12, 0 },
+      { { 3, 17 }, { 84, 0 }, { 243, 241 }, { 154, 231 }, { 1, 0 }, 12, 0 },
+      { { 35, 33 }, { 95, 0 }, { 241, 242 }, { 58, 248 }, { 0, 0 }, 0, 0 },
+      { { 3, 33 }, { 135, 128 }, { 246, 243 }, { 34, 243 }, { 1, 0 }, 6, 0 },
+      { { 3, 33 }, { 71, 0 }, { 249, 246 }, { 84, 58 }, { 0, 0 }, 0, 0 },
+      { { 35, 33 }, { 72, 0 }, { 149, 132 }, { 25, 25 }, { 1, 0 }, 8, 0 },
+      { { 35, 33 }, { 74, 0 }, { 149, 148 }, { 25, 25 }, { 1, 0 }, 8, 0 },
+      { { 9, 132 }, { 161, 128 }, { 32, 209 }, { 79, 248 }, { 0, 0 }, 8, 0 },
+      { { 33, 162 }, { 30, 0 }, { 148, 195 }, { 6, 166 }, { 0, 0 }, 2, 0 },
+      { { 49, 49 }, { 18, 0 }, { 241, 241 }, { 40, 24 }, { 0, 0 }, 10, 0 },
+      { { 49, 49 }, { 141, 0 }, { 241, 241 }, { 232, 120 }, { 0, 0 }, 10, 0 },
+      { { 49, 50 }, { 91, 0 }, { 81, 113 }, { 40, 72 }, { 0, 0 }, 12, 0 },
+      { { 1, 33 }, { 139, 64 }, { 161, 242 }, { 154, 223 }, { 0, 0 }, 8, 0 },
+      { { 1, 33 }, { 137, 64 }, { 161, 242 }, { 154, 223 }, { 0, 0 }, 8, 0 },
+      { { 49, 49 }, { 139, 0 }, { 244, 241 }, { 232, 120 }, { 0, 0 }, 10, 0 },
+      { { 49, 49 }, { 18, 0 }, { 241, 241 }, { 40, 24 }, { 0, 0 }, 10, 0 },
+      { { 49, 33 }, { 21, 0 }, { 221, 86 }, { 19, 38 }, { 1, 0 }, 8, 0 },
+      { { 49, 33 }, { 22, 0 }, { 221, 102 }, { 19, 6 }, { 1, 0 }, 8, 0 },
+      { { 113, 49 }, { 73, 0 }, { 209, 97 }, { 28, 12 }, { 1, 0 }, 8, 0 },
+      { { 33, 35 }, { 77, 128 }, { 113, 114 }, { 18, 6 }, { 1, 0 }, 2, 0 },
+      { { 241, 225 }, { 64, 0 }, { 241, 111 }, { 33, 22 }, { 1, 0 }, 2, 0 },
+      { { 2, 1 }, { 26, 128 }, { 245, 133 }, { 117, 53 }, { 1, 0 }, 0, 0 },
+      { { 2, 1 }, { 29, 128 }, { 245, 243 }, { 117, 244 }, { 1, 0 }, 0, 0 },
+      { { 16, 17 }, { 65, 0 }, { 245, 242 }, { 5, 195 }, { 1, 0 }, 2, 0 },
+      { { 33, 162 }, { 155, 1 }, { 177, 114 }, { 37, 8 }, { 1, 0 }, 14, 0 },
+      { { 161, 33 }, { 152, 0 }, { 127, 63 }, { 3, 7 }, { 1, 1 }, 0, 0 },
+      { { 161, 97 }, { 147, 0 }, { 193, 79 }, { 18, 5 }, { 0, 0 }, 10, 0 },
+      { { 33, 97 }, { 24, 0 }, { 193, 79 }, { 34, 5 }, { 0, 0 }, 12, 0 },
+      { { 49, 114 }, { 91, 131 }, { 244, 138 }, { 21, 5 }, { 0, 0 }, 0, 0 },
+      { { 161, 97 }, { 144, 0 }, { 116, 113 }, { 57, 103 }, { 0, 0 }, 0, 0 },
+      { { 113, 114 }, { 87, 0 }, { 84, 122 }, { 5, 5 }, { 0, 0 }, 12, 0 },
+      { { 144, 65 }, { 0, 0 }, { 84, 165 }, { 99, 69 }, { 0, 0 }, 8, 0 },
+      { { 33, 33 }, { 146, 1 }, { 133, 143 }, { 23, 9 }, { 0, 0 }, 12, 0 },
+      { { 33, 33 }, { 148, 5 }, { 117, 143 }, { 23, 9 }, { 0, 0 }, 12, 0 },
+      { { 33, 97 }, { 148, 0 }, { 118, 130 }, { 21, 55 }, { 0, 0 }, 12, 0 },
+      { { 49, 33 }, { 67, 0 }, { 158, 98 }, { 23, 44 }, { 1, 1 }, 2, 0 },
+      { { 33, 33 }, { 155, 0 }, { 97, 127 }, { 106, 10 }, { 0, 0 }, 2, 0 },
+      { { 97, 34 }, { 138, 6 }, { 117, 116 }, { 31, 15 }, { 0, 0 }, 8, 0 },
+      { { 161, 33 }, { 134, 13 }, { 114, 113 }, { 85, 24 }, { 1, 0 }, 0, 0 },
+      { { 33, 33 }, { 77, 0 }, { 84, 166 }, { 60, 28 }, { 0, 0 }, 8, 0 },
+      { { 49, 97 }, { 143, 0 }, { 147, 114 }, { 2, 11 }, { 1, 0 }, 8, 0 },
+      { { 49, 97 }, { 142, 0 }, { 147, 114 }, { 3, 9 }, { 1, 0 }, 8, 0 },
+      { { 49, 97 }, { 145, 0 }, { 147, 130 }, { 3, 9 }, { 1, 0 }, 10, 0 },
+      { { 49, 97 }, { 142, 0 }, { 147, 114 }, { 15, 15 }, { 1, 0 }, 10, 0 },
+      { { 33, 33 }, { 75, 0 }, { 170, 143 }, { 22, 10 }, { 1, 0 }, 8, 0 },
+      { { 49, 33 }, { 144, 0 }, { 126, 139 }, { 23, 12 }, { 1, 1 }, 6, 0 },
+      { { 49, 50 }, { 129, 0 }, { 117, 97 }, { 25, 25 }, { 1, 0 }, 0, 0 },
+      { { 50, 33 }, { 144, 0 }, { 155, 114 }, { 33, 23 }, { 0, 0 }, 4, 0 },
+      { { 225, 225 }, { 31, 0 }, { 133, 101 }, { 95, 26 }, { 0, 0 }, 0, 0 },
+      { { 225, 225 }, { 70, 0 }, { 136, 101 }, { 95, 26 }, { 0, 0 }, 0, 0 },
+      { { 161, 33 }, { 156, 0 }, { 117, 117 }, { 31, 10 }, { 0, 0 }, 2, 0 },
+      { { 49, 33 }, { 139, 0 }, { 132, 101 }, { 88, 26 }, { 0, 0 }, 0, 0 },
+      { { 225, 161 }, { 76, 0 }, { 102, 101 }, { 86, 38 }, { 0, 0 }, 0, 0 },
+      { { 98, 161 }, { 203, 0 }, { 118, 85 }, { 70, 54 }, { 0, 0 }, 0, 0 },
+      { { 98, 161 }, { 153, 0 }, { 87, 86 }, { 7, 7 }, { 0, 0 }, 11, 0 },
+      { { 98, 161 }, { 147, 0 }, { 119, 118 }, { 7, 7 }, { 0, 0 }, 11, 0 },
+      { { 34, 33 }, { 89, 0 }, { 255, 255 }, { 3, 15 }, { 2, 0 }, 0, 0 },
+      { { 33, 33 }, { 14, 0 }, { 255, 255 }, { 15, 15 }, { 1, 1 }, 0, 0 },
+      { { 34, 33 }, { 70, 128 }, { 134, 100 }, { 85, 24 }, { 0, 0 }, 0, 0 },
+      { { 33, 161 }, { 69, 0 }, { 102, 150 }, { 18, 10 }, { 0, 0 }, 0, 0 },
+      { { 33, 34 }, { 139, 0 }, { 146, 145 }, { 42, 42 }, { 1, 0 }, 0, 0 },
+      { { 162, 97 }, { 158, 64 }, { 223, 111 }, { 5, 7 }, { 0, 0 }, 2, 0 },
+      { { 32, 96 }, { 26, 0 }, { 239, 143 }, { 1, 6 }, { 0, 2 }, 0, 0 },
+      { { 33, 33 }, { 143, 128 }, { 241, 244 }, { 41, 9 }, { 0, 0 }, 10, 0 },
+      { { 119, 161 }, { 165, 0 }, { 83, 160 }, { 148, 5 }, { 0, 0 }, 2, 0 },
+      { { 97, 177 }, { 31, 128 }, { 168, 37 }, { 17, 3 }, { 0, 0 }, 10, 0 },
+      { { 97, 97 }, { 23, 0 }, { 145, 85 }, { 52, 22 }, { 0, 0 }, 12, 0 },
+      { { 113, 114 }, { 93, 0 }, { 84, 106 }, { 1, 3 }, { 0, 0 }, 0, 0 },
+      { { 33, 162 }, { 151, 0 }, { 33, 66 }, { 67, 53 }, { 0, 0 }, 8, 0 },
+      { { 161, 33 }, { 28, 0 }, { 161, 49 }, { 119, 71 }, { 1, 1 }, 0, 0 },
+      { { 33, 97 }, { 137, 3 }, { 17, 66 }, { 51, 37 }, { 0, 0 }, 10, 0 },
+      { { 161, 33 }, { 21, 0 }, { 17, 207 }, { 71, 7 }, { 1, 0 }, 0, 0 },
+      { { 58, 81 }, { 206, 0 }, { 248, 134 }, { 246, 2 }, { 0, 0 }, 2, 0 },
+      { { 33, 33 }, { 21, 0 }, { 33, 65 }, { 35, 19 }, { 1, 0 }, 0, 0 },
+      { { 6, 1 }, { 91, 0 }, { 116, 165 }, { 149, 114 }, { 0, 0 }, 0, 0 },
+      { { 34, 97 }, { 146, 131 }, { 177, 242 }, { 129, 38 }, { 0, 0 }, 12, 0 },
+      { { 65, 66 }, { 77, 0 }, { 241, 242 }, { 81, 245 }, { 1, 0 }, 0, 0 },
+      { { 97, 163 }, { 148, 128 }, { 17, 17 }, { 81, 19 }, { 1, 0 }, 6, 0 },
+      { { 97, 161 }, { 140, 128 }, { 17, 29 }, { 49, 3 }, { 0, 0 }, 6, 0 },
+      { { 164, 97 }, { 76, 0 }, { 243, 129 }, { 115, 35 }, { 1, 0 }, 4, 0 },
+      { { 2, 7 }, { 133, 3 }, { 210, 242 }, { 83, 246 }, { 0, 1 }, 0, 0 },
+      { { 17, 19 }, { 12, 128 }, { 163, 162 }, { 17, 229 }, { 1, 0 }, 0, 0 },
+      { { 17, 17 }, { 6, 0 }, { 246, 242 }, { 65, 230 }, { 1, 2 }, 4, 0 },
+      { { 147, 145 }, { 145, 0 }, { 212, 235 }, { 50, 17 }, { 0, 1 }, 8, 0 },
+      { { 4, 1 }, { 79, 0 }, { 250, 194 }, { 86, 5 }, { 0, 0 }, 12, 0 },
+      { { 33, 34 }, { 73, 0 }, { 124, 111 }, { 32, 12 }, { 0, 1 }, 6, 0 },
+      { { 49, 33 }, { 133, 0 }, { 221, 86 }, { 51, 22 }, { 1, 0 }, 10, 0 },
+      { { 32, 33 }, { 4, 129 }, { 218, 143 }, { 5, 11 }, { 2, 0 }, 6, 0 },
+      { { 5, 3 }, { 106, 128 }, { 241, 195 }, { 229, 229 }, { 0, 0 }, 6, 0 },
+      { { 7, 2 }, { 21, 0 }, { 236, 248 }, { 38, 22 }, { 0, 0 }, 10, 0 },
+      { { 5, 1 }, { 157, 0 }, { 103, 223 }, { 53, 5 }, { 0, 0 }, 8, 0 },
+      { { 24, 18 }, { 150, 0 }, { 250, 248 }, { 40, 229 }, { 0, 0 }, 10, 0 },
+      { { 16, 0 }, { 134, 3 }, { 168, 250 }, { 7, 3 }, { 0, 0 }, 6, 0 },
+      { { 17, 16 }, { 65, 3 }, { 248, 243 }, { 71, 3 }, { 2, 0 }, 4, 0 },
+      { { 1, 16 }, { 142, 0 }, { 241, 243 }, { 6, 2 }, { 2, 0 }, 14, 0 },
+      { { 14, 192 }, { 0, 0 }, { 31, 31 }, { 0, 255 }, { 0, 3 }, 14, 0 },
+      { { 6, 3 }, { 128, 136 }, { 248, 86 }, { 36, 132 }, { 0, 2 }, 14, 0 },
+      { { 14, 208 }, { 0, 5 }, { 248, 52 }, { 0, 4 }, { 0, 3 }, 14, 0 },
+      { { 14, 192 }, { 0, 0 }, { 246, 31 }, { 0, 2 }, { 0, 3 }, 14, 0 },
+      { { 213, 218 }, { 149, 64 }, { 55, 86 }, { 163, 55 }, { 0, 0 }, 0, 0 },
+      { { 53, 20 }, { 92, 8 }, { 178, 244 }, { 97, 21 }, { 2, 0 }, 10, 0 },
+      { { 14, 208 }, { 0, 0 }, { 246, 79 }, { 0, 245 }, { 0, 3 }, 14, 0 },
+      { { 38, 228 }, { 0, 0 }, { 255, 18 }, { 1, 22 }, { 0, 1 }, 14, 0 },
+      { { 0, 0 }, { 0, 0 }, { 243, 246 }, { 240, 201 }, { 0, 2 }, 14, 0 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 0, 0 }, { 0, 0 }, { 252, 250 }, { 5, 23 }, { 2, 0 }, 14, 52 },
+      { { 0, 1 }, { 2, 0 }, { 255, 255 }, { 7, 8 }, { 0, 0 }, 0, 48 },
+      { { 0, 0 }, { 0, 0 }, { 252, 250 }, { 5, 23 }, { 2, 0 }, 14, 58 },
+      { { 0, 0 }, { 0, 0 }, { 246, 246 }, { 12, 6 }, { 0, 0 }, 4, 60 },
+      { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 47 },
+      { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43 },
+      { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 49 },
+      { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43 },
+      { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 51 },
+      { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43 },
+      { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 54 },
+      { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 57 },
+      { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 72 },
+      { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 60 },
+      { { 14, 208 }, { 0, 10 }, { 245, 159 }, { 48, 2 }, { 0, 0 }, 14, 76 },
+      { { 14, 7 }, { 10, 93 }, { 228, 245 }, { 228, 229 }, { 3, 1 }, 6, 84 },
+      { { 2, 5 }, { 3, 10 }, { 180, 151 }, { 4, 247 }, { 0, 0 }, 14, 36 },
+      { { 78, 158 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 14, 76 },
+      { { 17, 16 }, { 69, 8 }, { 248, 243 }, { 55, 5 }, { 2, 0 }, 8, 84 },
+      { { 14, 208 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 14, 83 },
+      { { 128, 16 }, { 0, 13 }, { 255, 255 }, { 3, 20 }, { 3, 0 }, 12, 84 },
+      { { 14, 7 }, { 8, 81 }, { 248, 244 }, { 66, 228 }, { 0, 3 }, 14, 24 },
+      { { 14, 208 }, { 0, 10 }, { 245, 159 }, { 48, 2 }, { 0, 0 }, 14, 77 },
+      { { 1, 2 }, { 0, 0 }, { 250, 200 }, { 191, 151 }, { 0, 0 }, 7, 60 },
+      { { 1, 1 }, { 81, 0 }, { 250, 250 }, { 135, 183 }, { 0, 0 }, 6, 65 },
+      { { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 59 },
+      { { 1, 2 }, { 89, 0 }, { 250, 248 }, { 136, 182 }, { 0, 0 }, 6, 51 },
+      { { 1, 0 }, { 0, 0 }, { 249, 250 }, { 10, 6 }, { 3, 0 }, 14, 45 },
+      { { 0, 0 }, { 128, 0 }, { 249, 246 }, { 137, 108 }, { 3, 0 }, 14, 71 },
+      { { 3, 12 }, { 128, 8 }, { 248, 246 }, { 136, 182 }, { 3, 0 }, 15, 60 },
+      { { 3, 12 }, { 133, 0 }, { 248, 246 }, { 136, 182 }, { 3, 0 }, 15, 58 },
+      { { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 53 },
+      { { 14, 3 }, { 64, 0 }, { 200, 155 }, { 73, 105 }, { 0, 2 }, 14, 64 },
+      { { 215, 199 }, { 220, 0 }, { 173, 141 }, { 5, 5 }, { 3, 0 }, 14, 71 },
+      { { 215, 199 }, { 220, 0 }, { 168, 136 }, { 4, 4 }, { 3, 0 }, 14, 61 },
+      { { 128, 17 }, { 0, 0 }, { 246, 103 }, { 6, 23 }, { 3, 3 }, 14, 61 },
+      { { 128, 17 }, { 0, 9 }, { 245, 70 }, { 5, 22 }, { 2, 3 }, 14, 48 },
+      { { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 48 },
+      { { 6, 18 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 3, 0 }, 0, 69 },
+      { { 6, 18 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 68 },
+      { { 1, 2 }, { 88, 0 }, { 103, 117 }, { 231, 7 }, { 0, 0 }, 0, 63 },
+      { { 65, 66 }, { 69, 8 }, { 248, 117 }, { 72, 5 }, { 0, 0 }, 0, 74 },
+      { { 10, 30 }, { 64, 78 }, { 224, 255 }, { 240, 5 }, { 3, 0 }, 8, 60 },
+      { { 10, 30 }, { 124, 82 }, { 224, 255 }, { 240, 2 }, { 3, 0 }, 8, 80 },
+      { { 14, 0 }, { 64, 8 }, { 122, 123 }, { 74, 27 }, { 0, 2 }, 14, 64 },
+      { { 14, 7 }, { 10, 64 }, { 228, 85 }, { 228, 57 }, { 3, 1 }, 6, 69 },
+      { { 5, 4 }, { 5, 64 }, { 249, 214 }, { 50, 165 }, { 3, 0 }, 14, 73 },
+      { { 2, 21 }, { 63, 0 }, { 0, 247 }, { 243, 245 }, { 3, 0 }, 8, 75 },
+      { { 1, 2 }, { 79, 0 }, { 250, 248 }, { 141, 181 }, { 0, 0 }, 7, 68 },
+      { { 0, 0 }, { 0, 0 }, { 246, 246 }, { 12, 6 }, { 0, 0 }, 4, 48 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 53 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 }
+   };

Added: tags/rott-1.1/rott/audiolib/gus.c
===================================================================
--- tags/rott-1.1/rott/audiolib/gus.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/gus.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,283 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   file:   GUS.C
+
+   author: James R. Dose
+   date:   September 7, 1994
+
+   Gravis Ultrasound initialization routines.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <conio.h>
+#include <dos.h>
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include "usrhooks.h"
+#include "interrup.h"
+#include "newgf1.h"
+#include "gusmidi.h"
+#include "guswave.h"
+#include "_guswave.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+// size of DMA buffer for patch loading
+#define DMABUFFSIZE 2048U
+
+struct gf1_dma_buff GUS_HoldBuffer;
+static int          HoldBufferAllocated = FALSE;
+
+static int GUS_Installed = 0;
+
+extern VoiceNode   GUSWAVE_Voices[ VOICES ];
+extern int GUSWAVE_Installed;
+
+unsigned long GUS_TotalMemory;
+int           GUS_MemConfig;
+
+int GUS_AuxError  = 0;
+
+int GUS_ErrorCode = GUS_Ok;
+
+#define GUS_SetErrorCode( status ) \
+   GUS_ErrorCode   = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: GUS_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *GUS_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case GUS_Warning :
+      case GUS_Error :
+         ErrorString = GUS_ErrorString( GUS_ErrorCode );
+         break;
+
+      case GUS_Ok :
+         ErrorString = "Ultrasound music ok.";
+         break;
+
+      case GUS_OutOfMemory :
+         ErrorString = "Out of memory in GusMidi.";
+         break;
+
+      case GUS_OutOfDosMemory :
+         ErrorString = "Out of conventional (640K) memory in GusMidi.";
+         break;
+
+      case GUS_GF1Error :
+         ErrorString = gf1_error_str( GUS_AuxError );
+         break;
+
+      case GUS_InvalidIrq :
+         ErrorString = "Ultrasound IRQ must be 7 or less.";
+         break;
+
+      case GUS_ULTRADIRNotSet :
+         ErrorString = "ULTRADIR environment variable not set.";
+         break;
+
+      case GUS_MissingConfig :
+//         ErrorString = "Can't find GUSMIDI.INI file.";
+         ErrorString = "Can't find ULTRAMID.INI file.";
+         break;
+
+      case GUS_FileError :
+         ErrorString = strerror( GUS_AuxError );
+         break;
+
+      default :
+         ErrorString = "Unknown Ultrasound error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+
+/*---------------------------------------------------------------------
+   Function: D32DosMemAlloc
+
+   Allocate a block of Conventional memory.
+---------------------------------------------------------------------*/
+
+void *D32DosMemAlloc
+   (
+   unsigned size
+   )
+
+   {
+   union REGS r;
+
+   // DPMI allocate DOS memory
+   r.x.eax = 0x0100;
+
+   // Number of paragraphs requested
+   r.x.ebx = ( size + 15 ) >> 4;
+   int386( 0x31, &r, &r );
+   if ( r.x.cflag )
+      {
+      // Failed
+      return( NULL );
+      }
+
+   return( ( void * )( ( r.x.eax & 0xFFFF ) << 4 ) );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUS_Init
+
+   Initializes the Gravis Ultrasound for sound and music playback.
+---------------------------------------------------------------------*/
+
+int GUS_Init
+   (
+   void
+   )
+
+   {
+   struct load_os os;
+   int ret;
+
+   if ( GUS_Installed > 0 )
+      {
+      GUS_Installed++;
+      return( GUS_Ok );
+      }
+
+   GUS_SetErrorCode( GUS_Ok );
+
+   GUS_Installed = 0;
+
+   GetUltraCfg( &os );
+
+   if ( os.forced_gf1_irq > 7 )
+      {
+      GUS_SetErrorCode( GUS_InvalidIrq );
+      return( GUS_Error );
+      }
+
+   if ( !HoldBufferAllocated )
+      {
+      GUS_HoldBuffer.vptr = D32DosMemAlloc( DMABUFFSIZE );
+      if ( GUS_HoldBuffer.vptr == NULL )
+         {
+         GUS_SetErrorCode( GUS_OutOfDosMemory );
+         return( GUS_Error );
+         }
+      GUS_HoldBuffer.paddr = ( unsigned long )GUS_HoldBuffer.vptr;
+
+      HoldBufferAllocated = TRUE;
+      }
+
+   os.voices = 24;
+   ret = gf1_load_os( &os );
+   if ( ret )
+      {
+      GUS_AuxError = ret;
+      GUS_SetErrorCode( GUS_GF1Error );
+      return( GUS_Error );
+      }
+
+   GUS_TotalMemory = gf1_mem_avail();
+   GUS_MemConfig   = ( GUS_TotalMemory - 1 ) >> 18;
+
+   GUS_Installed = 1;
+   return( GUS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUS_Shutdown
+
+   Ends use of the Gravis Ultrasound.  Must be called the same number
+   of times as GUS_Init.
+---------------------------------------------------------------------*/
+
+void GUS_Shutdown
+   (
+   void
+   )
+
+   {
+   if ( GUS_Installed > 0 )
+      {
+      GUS_Installed--;
+      if ( GUS_Installed == 0 )
+         {
+         gf1_unload_os();
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_Shutdown
+
+   Terminates use of the Gravis Ultrasound for digitized sound playback.
+---------------------------------------------------------------------*/
+
+void GUSWAVE_Shutdown
+   (
+   void
+   )
+
+   {
+   int i;
+
+   if ( GUSWAVE_Installed )
+      {
+      GUSWAVE_KillAllVoices();
+
+      // free memory
+      for ( i = 0; i < VOICES; i++ )
+         {
+         if ( GUSWAVE_Voices[ i ].mem != NULL )
+            {
+            gf1_free( GUSWAVE_Voices[ i ].mem );
+            GUSWAVE_Voices[ i ].mem = NULL;
+            }
+         }
+
+      GUS_Shutdown();
+      GUSWAVE_Installed = FALSE;
+      }
+   }

Added: tags/rott-1.1/rott/audiolib/gusmidi.c
===================================================================
--- tags/rott-1.1/rott/audiolib/gusmidi.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/gusmidi.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,561 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   file:   GUSMIDI.C
+
+   author: James R. Dose
+   date:   March 23, 1994
+
+   General MIDI playback functions for the Gravis Ultrasound
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+// Module MUST be compiled with structure allignment set to a maximum
+// of 1 byte ( zp1 ).
+
+#include <conio.h>
+#include <dos.h>
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include "usrhooks.h"
+#include "interrup.h"
+#include "newgf1.h"
+#include "gusmidi.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+// size of DMA buffer for patch loading
+#define DMABUFFSIZE 2048U
+
+#define MAX_MEM_CONFIG   3
+
+// size of patch array (128 perc, 128 melodic)
+#define NUM_PATCHES 256
+
+// size of largest patch name
+#define BIGGEST_NAME 9
+
+#define UNUSED_PATCH -1
+
+static struct patch   Patch[ NUM_PATCHES ];
+static unsigned char *PatchWaves[ NUM_PATCHES ];
+
+static int   PatchMap[ NUM_PATCHES ][ MAX_MEM_CONFIG + 1 ];
+static char  ProgramName[ NUM_PATCHES ][ BIGGEST_NAME ];
+static char  PatchLoaded[ NUM_PATCHES ];
+
+static char  ConfigFileName[] = "ULTRAMID.INI";
+static char  ConfigDirectory[ 80 ] = { '\0' };
+
+// The name of the configuration directory
+static char  InstrumentDirectory[ 80 ];
+
+extern struct gf1_dma_buff GUS_HoldBuffer;
+
+extern unsigned long GUS_TotalMemory;
+extern int           GUS_MemConfig;
+
+static int GUSMIDI_Volume = 255;
+
+extern int GUS_AuxError;
+extern int GUS_ErrorCode;
+
+int GUSMIDI_Installed = FALSE;
+
+#define GUS_SetErrorCode( status ) \
+   GUS_ErrorCode   = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: GUS_GetPatchMap
+
+   Reads the patch map from disk.
+---------------------------------------------------------------------*/
+
+int GUS_GetPatchMap
+   (
+   char *name
+   )
+
+   {
+   char text[ 80 ];
+   char *ud;
+   int  index;
+   int  ignore;
+   FILE *fp;
+
+   for( index = 0; index < NUM_PATCHES; index++ )
+      {
+      PatchMap[ index ][ 0 ] = UNUSED_PATCH;
+      PatchMap[ index ][ 1 ] = UNUSED_PATCH;
+      PatchMap[ index ][ 2 ] = UNUSED_PATCH;
+      PatchMap[ index ][ 3 ] = UNUSED_PATCH;
+      ProgramName[ index ][ 0 ] = 0;
+      }
+
+   ud = getenv( "ULTRADIR" );
+   if ( ud == NULL )
+      {
+      GUS_SetErrorCode( GUS_ULTRADIRNotSet );
+      return( GUS_Error );
+      }
+
+   strcpy( InstrumentDirectory, ud );
+   strcat( InstrumentDirectory, "\\midi\\" );
+   strcpy( ConfigDirectory, ud );
+   strcat( ConfigDirectory, "\\midi\\" );
+   strcpy( text, name );
+
+   fp = fopen( text, "r" );
+   if ( fp == NULL )
+      {
+      strcpy( text, InstrumentDirectory );
+      strcat( text, name );
+
+      fp = fopen( text, "r" );
+      if ( fp == NULL )
+         {
+         GUS_SetErrorCode( GUS_MissingConfig );
+         return( GUS_Error );
+         }
+      }
+
+   while( 1 )
+      {
+      if ( fgets( text, 80, fp ) == NULL )
+         {
+         break;
+         }
+
+      if ( text[ 0 ] == '#' )
+         {
+         continue;
+         }
+
+      if ( sscanf( text, "%d", &index ) != 1 )
+         {
+         continue;
+         }
+
+      sscanf( text, "%d, %d, %d, %d, %d, %s\n", &ignore,
+         &PatchMap[ index ][ 0 ],
+         &PatchMap[ index ][ 1 ],
+         &PatchMap[ index ][ 2 ],
+         &PatchMap[ index ][ 3 ],
+         ProgramName[ index ] );
+      }
+
+   fclose( fp );
+
+   return( GUS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_UnloadPatch
+
+   Unloads a patch from the GUS's memory.
+---------------------------------------------------------------------*/
+
+int GUSMIDI_UnloadPatch
+   (
+   int prognum
+   )
+
+   {
+   int      prog;
+   unsigned flags;
+
+   prog = PatchMap[ prognum ][ GUS_MemConfig ];
+
+   if ( PatchLoaded[ prog ] )
+      {
+      flags = DisableInterrupts();
+
+      gf1_unload_patch( &Patch[ prog ] );
+      if ( PatchWaves[ prog ] != NULL )
+         {
+         USRHOOKS_FreeMem( PatchWaves[ prog ] );
+         PatchWaves[ prog ] = NULL;
+         }
+
+      // just in case sequence is still playing
+      Patch[ prog ].nlayers = 0;
+      PatchLoaded[ prog ]   = FALSE;
+
+      RestoreInterrupts( flags );
+      }
+
+   return( GUS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_LoadPatch
+
+   Loads a patch into the GUS's memory.
+---------------------------------------------------------------------*/
+
+int GUSMIDI_LoadPatch
+   (
+   int prognum
+   )
+
+   {
+   int  prog;
+   char text[ 80 ];
+   int  ret;
+   unsigned char *wave_buff;
+   struct patchinfo  patchi;
+   int  status;
+
+   prog = PatchMap[ prognum ][ GUS_MemConfig ];
+
+   if ( ( PatchLoaded[ prog ] ) || ( prog == UNUSED_PATCH ) )
+      {
+      return( GUS_Ok );
+      }
+
+   if ( !ProgramName[ prog ][ 0 ] )
+      {
+      return( GUS_Ok );
+      }
+
+   strcpy( text, InstrumentDirectory );
+   strcat( text, ProgramName[ prog ] );
+   strcat( text, ".pat" );
+
+   ret = gf1_get_patch_info( text, &patchi );
+   if ( ret != OK )
+      {
+      GUS_AuxError = ret;
+      GUS_SetErrorCode( GUS_GF1Error );
+      return( GUS_Error );
+      }
+
+   status = USRHOOKS_GetMem( &wave_buff, patchi.header.wave_forms *
+      sizeof( struct wave_struct ) );
+   if ( status != USRHOOKS_Ok )
+      {
+      GUS_SetErrorCode( GUS_OutOfMemory );
+      return( GUS_Error );
+      }
+
+   ret = gf1_load_patch( text, &patchi, &Patch[ prog ], &GUS_HoldBuffer,
+      DMABUFFSIZE, ( unsigned char * )wave_buff, PATCH_LOAD_8_BIT );
+
+   if ( ret != OK )
+      {
+      USRHOOKS_FreeMem( wave_buff );
+      GUS_AuxError = ret;
+      GUS_SetErrorCode( GUS_GF1Error );
+      return( GUS_Error );
+      }
+
+   PatchWaves[ prog ] = wave_buff;
+   PatchLoaded[ prog ] = TRUE;
+
+   return( GUS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_ProgramChange
+
+   Selects the instrument to use on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void GUSMIDI_ProgramChange
+   (
+   int channel,
+   int prognum
+   )
+
+   {
+   int  prog;
+
+   prog = PatchMap[ prognum ][ GUS_MemConfig ];
+
+   if ( PatchLoaded[ prog ] )
+      {
+      gf1_midi_change_program( &Patch[ prog ], channel );
+      }
+   else
+      {
+      gf1_midi_change_program( NULL, channel );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_NoteOn
+
+   Plays a note on the specified channel.
+---------------------------------------------------------------------*/
+
+void GUSMIDI_NoteOn
+   (
+   int chan,
+   int note,
+   int velocity
+   )
+
+   {
+   int prog;
+
+   if ( chan == 9 )
+      {
+      prog = PatchMap[ note + 128 ][ GUS_MemConfig ];
+
+      if ( PatchLoaded[ prog ] )
+         {
+         gf1_midi_note_on( &Patch[ note + 128 ], 1,
+            note, velocity, 9 );
+         }
+      }
+   else
+      {
+      gf1_midi_note_on( 0L, 1, note, velocity, chan );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_NoteOff
+
+   Turns off a note on the specified channel.
+---------------------------------------------------------------------*/
+#pragma warn -par
+void GUSMIDI_NoteOff
+   (
+   int chan,
+   int note,
+   int velocity
+   )
+
+   {
+   gf1_midi_note_off( note, chan );
+   }
+#pragma warn .par
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_ControlChange
+
+   Sets the value of a controller on the specified channel.
+---------------------------------------------------------------------*/
+
+void GUSMIDI_ControlChange
+   (
+   int channel,
+   int number,
+   int value
+   )
+
+   {
+   gf1_midi_parameter( channel, number, value );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_PitchBend
+
+   Sets the pitch bend on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void GUSMIDI_PitchBend
+   (
+   int channel,
+   int lsb,
+   int msb
+   )
+
+   {
+   gf1_midi_pitch_bend( channel, lsb, msb );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_ReleasePatches
+
+   Removes all the instruments from the GUS's memory.
+---------------------------------------------------------------------*/
+
+void GUSMIDI_ReleasePatches
+   (
+   void
+   )
+
+   {
+   int i;
+
+   for( i = 0; i < 256; i++ )
+      {
+      GUSMIDI_UnloadPatch( i );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_SetVolume
+
+   Sets the total music volume.
+---------------------------------------------------------------------*/
+
+void GUSMIDI_SetVolume
+   (
+   int volume
+   )
+
+   {
+   // Set the minimum to 2 because 0 has a tremolo problem
+   volume = max( 2, volume );
+   volume = min( volume, 255 );
+
+   GUSMIDI_Volume = volume;
+
+   // range = 0 to 127
+   gf1_midi_synth_volume( 0, volume >> 1 );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_GetVolume
+
+   Returns the total music volume.
+---------------------------------------------------------------------*/
+
+int GUSMIDI_GetVolume
+   (
+   void
+   )
+
+   {
+   return( GUSMIDI_Volume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_Init
+
+   Initializes the Gravis Ultrasound for music playback.
+---------------------------------------------------------------------*/
+
+int GUSMIDI_Init
+   (
+   void
+   )
+
+   {
+   int ret;
+   int i;
+   int startmem;
+//   unsigned long mem;
+   extern int GUSWAVE_Installed;
+
+   if ( GUSMIDI_Installed )
+      {
+      GUSMIDI_Shutdown();
+      }
+
+   ret = GUS_Init();
+   if ( ret != GUS_Ok )
+      {
+      return( ret );
+      }
+
+   if ( GUS_MemConfig < 0 )
+      {
+      GUS_MemConfig = 0;
+      }
+
+   if ( GUS_MemConfig > MAX_MEM_CONFIG )
+      {
+      GUS_MemConfig = MAX_MEM_CONFIG;
+      }
+
+   for( i = 0; i < NUM_PATCHES; i++ )
+      {
+      ProgramName[ i ][ 0 ] = '\0';
+      PatchWaves[ i ]       = NULL;
+      PatchLoaded[ i ]      = FALSE;
+      }
+
+   GUSMIDI_SetVolume( 255 );
+
+   GUSMIDI_Installed = TRUE;
+
+   ret = GUS_GetPatchMap( ConfigFileName );
+   if ( ret != GUS_Ok )
+      {
+      GUSMIDI_Shutdown();
+      return( ret );
+      }
+
+//   if ( !GUSWAVE_Installed )
+//      {
+//      mem = gf1_malloc( 8192 );
+//      }
+
+   startmem = gf1_mem_avail();
+   for( i = 0; i < NUM_PATCHES; i++ )
+      {
+      ret = GUSMIDI_LoadPatch( i );
+      if ( ret != GUS_Ok )
+         {
+         }
+//      if ( ret != GUS_Ok )
+//         {
+//         return( ret );
+//         }
+      }
+
+//   if ( !GUSWAVE_Installed )
+//      {
+//      gf1_free( mem );
+//      }
+
+   GUSMIDI_Installed = TRUE;
+
+   return( GUS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSMIDI_Shutdown
+
+   Ends use of the Gravis Ultrasound for music playback.
+---------------------------------------------------------------------*/
+
+void GUSMIDI_Shutdown
+   (
+   void
+   )
+
+   {
+   GUSMIDI_ReleasePatches();
+   GUS_Shutdown();
+   GUSMIDI_Installed = FALSE;
+   }

Added: tags/rott-1.1/rott/audiolib/gusmidi.h
===================================================================
--- tags/rott-1.1/rott/audiolib/gusmidi.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/gusmidi.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,59 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef __GUSMIDI_H
+#define __GUSMIDI_H
+
+extern struct gf1_dma_buff GUS_HoldBuffer;
+
+enum GUS_Errors
+   {
+   GUS_Warning        = -2,
+   GUS_Error          = -1,
+   GUS_Ok             = 0,
+   GUS_OutOfMemory,
+   GUS_OutOfDosMemory,
+   GUS_OutOfDRAM,
+   GUS_GF1Error,
+   GUS_InvalidIrq,
+   GUS_ULTRADIRNotSet,
+   GUS_MissingConfig,
+   GUS_FileError
+   };
+
+char *GUS_ErrorString( int ErrorNumber );
+int   GUS_GetPatchMap( char *name );
+int   GUSMIDI_UnloadPatch( int prog );
+int   GUSMIDI_LoadPatch( int prog );
+void  GUSMIDI_ProgramChange( int channel, int prog );
+void  GUSMIDI_NoteOn( int chan, int note, int velocity );
+void  GUSMIDI_NoteOff( int chan, int note, int velocity );
+void  GUSMIDI_ControlChange( int channel, int number, int value );
+void  GUSMIDI_PitchBend( int channel, int lsb, int msb );
+void  GUSMIDI_ReleasePatches( void );
+void  GUSMIDI_SetVolume( int volume );
+int   GUSMIDI_GetVolume( void );
+int   GUS_Init( void );
+void  GUS_Shutdown( void );
+#pragma aux GUS_Shutdown frame;
+int   GUSMIDI_Init( void );
+void  GUSMIDI_Shutdown( void );
+void *D32DosMemAlloc( unsigned size );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/guswave.c
===================================================================
--- tags/rott-1.1/rott/audiolib/guswave.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/guswave.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1773 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   file:   GUSWAVE.C
+
+   author: James R. Dose
+   date:   March 23, 1994
+
+   Digitized sound playback routines for the Gravis Ultrasound.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <stdlib.h>
+#include <conio.h>
+#include <dos.h>
+#include <stdio.h>
+#include <io.h>
+#include <string.h>
+#include "debugio.h"
+#include "interrup.h"
+#include "ll_man.h"
+#include "pitch.h"
+#include "user.h"
+#include "multivoc.h"
+#include "_guswave.h"
+#include "newgf1.h"
+#include "gusmidi.h"
+#include "guswave.h"
+
+#define ATR_INDEX               0x3c0
+#define STATUS_REGISTER_1       0x3da
+
+#define SetBorderColor(color) \
+   { \
+   inp  (STATUS_REGISTER_1); \
+   outp (ATR_INDEX,0x31);    \
+   outp (ATR_INDEX,color);   \
+   }
+
+static const int GUSWAVE_PanTable[ 32 ] =
+   {
+      8,  9, 10, 11, 11, 12, 13, 14,
+     15, 14, 13, 12, 11, 10,  9,  8,
+      7,  6,  5,  4,  4,  3,  2,  1,
+      0,  1,  2,  3,  4,  5,  6,  7
+   };
+
+static voicelist VoiceList;
+static voicelist VoicePool;
+
+static voicestatus VoiceStatus[ MAX_VOICES ];
+//static
+VoiceNode GUSWAVE_Voices[ VOICES ];
+
+static int GUSWAVE_VoiceHandle  = GUSWAVE_MinVoiceHandle;
+static int GUSWAVE_MaxVoices = VOICES;
+//static
+int GUSWAVE_Installed = FALSE;
+
+static void ( *GUSWAVE_CallBackFunc )( unsigned long ) = NULL;
+
+// current volume for dig audio - from 0 to 4095
+static int GUSWAVE_Volume = MAX_VOLUME;
+
+static int GUSWAVE_SwapLeftRight = FALSE;
+
+static int GUS_Debug = FALSE;
+
+extern int GUSMIDI_Installed;
+
+int GUSWAVE_ErrorCode = GUSWAVE_Ok;
+
+#define GUSWAVE_SetErrorCode( status ) \
+   GUSWAVE_ErrorCode   = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *GUSWAVE_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case GUSWAVE_Warning :
+      case GUSWAVE_Error :
+         ErrorString = GUSWAVE_ErrorString( GUSWAVE_ErrorCode );
+         break;
+
+      case GUSWAVE_Ok :
+         ErrorString = "GUSWAVE ok.";
+         break;
+
+      case GUSWAVE_GUSError :
+         ErrorString = GUS_ErrorString( GUS_Error );
+         break;
+
+      case GUSWAVE_NotInstalled :
+         ErrorString = "GUSWAVE not installed.";
+         break;
+
+      case GUSWAVE_NoVoices :
+         ErrorString = "No free voices available to GUSWAVE.";
+         break;
+
+      case GUSWAVE_UltraNoMem :
+         ErrorString = "Not enough Ultrasound memory available for GUSWAVE.";
+         break;
+
+      case GUSWAVE_UltraNoMemMIDI :
+         ErrorString = "Not enough Ultrasound memory available for GUSWAVE.  "
+            "Try initializing Sound FX before Music.";
+         break;
+
+      case GUSWAVE_VoiceNotFound :
+         ErrorString = "No voice with matching handle found.";
+         break;
+
+      case GUSWAVE_InvalidVOCFile :
+         ErrorString = "Invalid VOC file passed in to GUSWAVE.";
+         break;
+
+      case GUSWAVE_InvalidWAVFile :
+         ErrorString = "Invalid WAV file passed in to GUSWAVE.";
+         break;
+
+      default :
+         ErrorString = "Unknown GUSWAVE error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_CallBack
+
+   GF1 callback service routine.
+---------------------------------------------------------------------*/
+
+char GUS_Silence8[ 1024 ] = //256 ] =
+   {
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+   0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
+
+
+   };
+
+//unsigned short GUS_Silence16[ 128 ] =
+unsigned short GUS_Silence16[ 512 ] =
+   {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+
+
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+   };
+
+static int LOADDS GUSWAVE_CallBack
+   (
+   int reason,
+   int voice,
+   unsigned char **buf,
+   unsigned long *size
+   )
+
+   {
+   VoiceNode *Voice;
+   playbackstatus status;
+
+   // this function is called from an interrupt
+   // remember not to make any DOS or BIOS calls from here
+   // also don't call any C library functions unless you are sure that
+   // they are reentrant
+   // restore our DS register
+
+   if ( VoiceStatus[ voice ].playing == FALSE )
+      {
+      return( DIG_DONE );
+      }
+
+   if ( reason == DIG_MORE_DATA )
+      {
+//      SetBorderColor(16);
+      Voice = VoiceStatus[ voice ].Voice;
+
+      if ( ( Voice != NULL ) && ( Voice->Playing ) )
+/*
+         {
+         *buf = ( unsigned char * )GUS_Silence16;
+         *size = 1024;
+
+         SetBorderColor(0);
+         return( DIG_MORE_DATA );
+         }
+ */
+         {
+         status = Voice->GetSound( Voice );
+         if ( status != SoundDone )
+            {
+            if ( ( Voice->sound == NULL ) || ( status == NoMoreData ) )
+               {
+               if ( Voice->bits == 8 )
+                  {
+                  *buf = GUS_Silence8;
+                  }
+               else
+                  {
+                  *buf = ( unsigned char * )GUS_Silence16;
+                  }
+               *size = 256;
+               }
+            else
+               {
+               *buf  = Voice->sound;
+               *size = Voice->length;
+               }
+            return( DIG_MORE_DATA );
+            }
+         }
+//      SetBorderColor(16);
+      return( DIG_DONE );
+      }
+
+   if ( reason == DIG_DONE )
+      {
+      Voice = VoiceStatus[ voice ].Voice;
+      VoiceStatus[ voice ].playing = FALSE;
+
+      if ( Voice != NULL )
+         {
+         Voice->Active   = FALSE;
+         Voice->Playing  = FALSE;
+
+// I'm commenting this out because a -1 could cause a crash if it
+// is sent to the GF1 code.  This shouldn't be necessary since
+// Active should be false when GF1voice is -1, but this is just
+// a precaution.  Adjust the pan on the wrong voice is a lot
+// more pleasant than a crash!
+//         Voice->GF1voice = -1;
+
+         LL_Remove( VoiceNode, &VoiceList, Voice );
+         LL_AddToTail( VoiceNode, &VoicePool, Voice );
+         }
+
+      if ( GUSWAVE_CallBackFunc )
+         {
+         GUSWAVE_CallBackFunc( Voice->callbackval );
+         }
+      }
+
+   return( DIG_DONE );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_DebugCallBack
+
+   GF1 callback service routine with debugging info.
+---------------------------------------------------------------------*/
+
+static int LOADDS GUSWAVE_DebugCallBack
+   (
+   int reason,
+   int voice,
+   unsigned char **buf,
+   unsigned long *size
+   )
+
+   {
+   VoiceNode *Voice;
+
+   // this function is called from an interrupt
+   // remember not to make any DOS or BIOS calls from here
+   // also don't call any C library functions unless you are sure that
+   // they are reentrant
+   // restore our DS register
+
+   if ( VoiceStatus[ voice ].playing == FALSE )
+      {
+//      DB_printf( "GUS Voice %d not playing.\n", voice );
+      DB_printf( "GUS Voice " );
+      DB_PrintNum( voice );
+      DB_printf( " not playing.\n" );
+      return( DIG_DONE );
+         }
+
+      if ( reason == DIG_MORE_DATA )
+         {
+         Voice = VoiceStatus[ voice ].Voice;
+
+//         DB_printf( "Voice %d : More data -- ", Voice );
+         DB_printf( "Voice " );
+         DB_PrintNum( voice );
+         DB_printf( " : More data -- " );
+         if ( Voice != NULL )
+            {
+            if ( Voice->Playing )
+               {
+               GUSWAVE_GetNextVOCBlock( Voice );
+               if ( Voice->Playing )
+                  {
+//                  DB_printf( "More data -- size = %u blocklength = %u\n",
+//                     Voice->length, Voice->BlockLength );
+                  DB_printf( "More data -- size = " );
+                  DB_PrintNum( Voice->length );
+                  DB_printf( " blocklength = " );
+                  DB_PrintNum( Voice->BlockLength );
+                  DB_printf( "\n" );
+                  *buf  = Voice->sound;
+                  *size = Voice->length;
+                  return( DIG_MORE_DATA );
+                  }
+               else
+                  {
+                  DB_printf( "Voice done.\n" );
+                  }
+               }
+            else
+               {
+               DB_printf( "Voice not active.\n" );
+               }
+            }
+         else
+            {
+            DB_printf( " NULL Voice\n" );
+            }
+
+         return( DIG_DONE );
+         }
+
+      if ( reason == DIG_DONE )
+         {
+         VoiceStatus[ voice ].playing = FALSE;
+         Voice = VoiceStatus[ voice ].Voice;
+//         DB_printf( "Voice %d : Done -- ", Voice );
+         DB_printf( "Voice " );
+         DB_PrintNum( voice );
+         DB_printf( " : Done -- " );
+
+         if ( Voice != NULL )
+            {
+            DB_printf( "Ok\n" );
+
+            Voice->Active   = FALSE;
+            Voice->Playing  = FALSE;
+
+// I'm commenting this out because a -1 could cause a crash if it
+// is sent to the GF1 code.  This shouldn't be necessary since
+// Active should be false when GF1voice is -1, but this is just
+// a precaution.  Adjust the pan on the wrong voice is a lot
+// more pleasant than a crash!
+//         Voice->GF1voice = -1;
+
+         LL_Remove( VoiceNode, &VoiceList, Voice );
+         LL_AddToTail( VoiceNode, &VoicePool, Voice );
+         }
+      else
+         {
+         DB_printf( "Null voice\n" );
+         }
+
+      if ( GUSWAVE_CallBackFunc )
+         {
+         GUSWAVE_CallBackFunc( Voice->callbackval );
+         }
+      }
+
+   return( DIG_DONE );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_GetVoice
+
+   Locates the voice with the specified handle.
+---------------------------------------------------------------------*/
+
+static VoiceNode *GUSWAVE_GetVoice
+   (
+   int handle
+   )
+
+   {
+   VoiceNode *voice;
+   unsigned  flags;
+
+   flags = DisableInterrupts();
+
+   voice = VoiceList.start;
+
+   while( voice != NULL )
+      {
+      if ( handle == voice->handle )
+         {
+         break;
+         }
+
+      voice = voice->next;
+      }
+
+   RestoreInterrupts( flags );
+
+   if ( voice == NULL )
+      {
+      GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
+      }
+
+   return( voice );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_VoicePlaying
+
+   Checks if the voice associated with the specified handle is
+   playing.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_VoicePlaying
+   (
+   int handle
+   )
+
+   {
+   VoiceNode   *voice;
+
+   voice = GUSWAVE_GetVoice( handle );
+   if ( voice != NULL )
+      {
+      return( voice->Active );
+      }
+
+   return( FALSE );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_VoicesPlaying
+
+   Determines the number of currently active voices.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_VoicesPlaying
+   (
+   void
+   )
+
+   {
+   int         index;
+   int         NumVoices = 0;
+   unsigned    flags;
+
+   flags = DisableInterrupts();
+
+   for( index = 0; index < GUSWAVE_MaxVoices; index++ )
+      {
+      if ( GUSWAVE_Voices[ index ].Active )
+         {
+         NumVoices++;
+         }
+      }
+
+   RestoreInterrupts( flags );
+
+   if ( GUS_Debug )
+      {
+      DB_printf( "Number of voices = %d.\n", NumVoices );
+      }
+
+   return( NumVoices );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_Kill
+
+   Stops output of the voice associated with the specified handle.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_Kill
+   (
+   int handle
+   )
+
+   {
+   VoiceNode *voice;
+   unsigned  flags;
+
+   flags = DisableInterrupts();
+
+   voice = GUSWAVE_GetVoice( handle );
+
+   if ( voice == NULL )
+      {
+      RestoreInterrupts( flags );
+      GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
+
+      if ( GUS_Debug )
+         {
+         DB_printf( "Could not find voice to kill.\n" );
+         }
+
+      return( GUSWAVE_Warning );
+      }
+
+   RestoreInterrupts( flags );
+
+   if ( !GUS_Debug )
+      {
+      if ( voice->Active )
+         {
+         gf1_stop_digital( voice->GF1voice );
+         }
+      }
+   else
+      {
+      DB_printf( "Kill - GUS Voice %d ", voice->GF1voice );
+      if ( voice->Active )
+         {
+         DB_printf( "active\n" );
+         gf1_stop_digital( voice->GF1voice );
+         }
+      else
+         {
+         DB_printf( "inactive\n" );
+         }
+      }
+
+//   RestoreInterrupts( flags );
+
+   return( GUSWAVE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_KillAllVoices
+
+   Stops output of all currently active voices.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_KillAllVoices
+   (
+   void
+   )
+
+   {
+   int i;
+   unsigned  flags;
+
+   if ( !GUSWAVE_Installed )
+      {
+      return( GUSWAVE_Ok );
+      }
+
+   if ( GUS_Debug )
+      {
+      DB_printf( "Kill All Voices\n" );
+      }
+
+   flags = DisableInterrupts();
+
+   // Remove all the voices from the list
+   for( i = 0; i < GUSWAVE_MaxVoices; i++ )
+      {
+      if ( GUSWAVE_Voices[ i ].Active )
+         {
+//         GUSWAVE_Kill( GUSWAVE_Voices[ i ].handle );
+
+         gf1_stop_digital( GUSWAVE_Voices[ i ].GF1voice );
+         }
+      }
+
+   for( i = 0; i < MAX_VOICES; i++ )
+      {
+      VoiceStatus[ i ].playing = FALSE;
+      VoiceStatus[ i ].Voice   = NULL;
+      }
+
+   VoicePool.start = NULL;
+   VoicePool.end   = NULL;
+   VoiceList.start = NULL;
+   VoiceList.end   = NULL;
+
+   for( i = 0; i < GUSWAVE_MaxVoices; i++ )
+      {
+      GUSWAVE_Voices[ i ].Active = FALSE;
+      if ( GUSWAVE_Voices[ i ].mem != NULL )
+         {
+         LL_AddToTail( VoiceNode, &VoicePool, &GUSWAVE_Voices[ i ] );
+         }
+      }
+
+   RestoreInterrupts( flags );
+
+   return( GUSWAVE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_SetPitch
+
+   Sets the pitch for the voice associated with the specified handle.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_SetPitch
+   (
+   int handle,
+   int pitchoffset
+   )
+
+   {
+   VoiceNode *voice;
+   unsigned  flags;
+
+   flags = DisableInterrupts();
+
+   voice = GUSWAVE_GetVoice( handle );
+
+   if ( voice == NULL )
+      {
+      RestoreInterrupts( flags );
+
+      GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
+      return( GUSWAVE_Warning );
+      }
+
+   if ( voice->Active )
+      {
+      voice->PitchScale  = PITCH_GetScale( pitchoffset );
+      voice->RateScale   = ( voice->SamplingRate * voice->PitchScale ) >> 16;
+      gf1_dig_set_freq( voice->GF1voice, voice->RateScale );
+      }
+
+   RestoreInterrupts( flags );
+
+   return( GUSWAVE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_SetPan3D
+
+   Sets the pan position of the voice with the specified handle.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_SetPan3D
+   (
+   int handle,
+   int angle,
+   int distance
+   )
+
+   {
+   VoiceNode *voice;
+   int        pan;
+   unsigned  flags;
+
+   flags = DisableInterrupts();
+
+   voice = GUSWAVE_GetVoice( handle );
+
+   if ( voice == NULL )
+      {
+      RestoreInterrupts( flags );
+
+      GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
+      return( GUSWAVE_Warning );
+      }
+
+   if ( voice->Active )
+      {
+      angle &= 31;
+
+      pan = GUSWAVE_PanTable[ angle ];
+      if ( GUSWAVE_SwapLeftRight )
+         {
+         pan = 15 - pan;
+         }
+
+      distance = max( 0, distance );
+      distance = min( 255, distance );
+
+      voice->Volume = 255 - distance;
+      voice->Pan    = pan;
+
+      gf1_dig_set_pan( voice->GF1voice, pan );
+      gf1_dig_set_vol( voice->GF1voice, GUSWAVE_Volume - distance * 4 );
+      }
+
+   RestoreInterrupts( flags );
+
+   return( GUSWAVE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_SetVolume
+
+   Sets the total volume of the digitized sounds.
+---------------------------------------------------------------------*/
+
+void GUSWAVE_SetVolume
+   (
+   int volume
+   )
+
+   {
+   int i;
+
+   volume = max( 0, volume );
+   volume = min( 255, volume );
+   GUSWAVE_Volume = MAX_VOLUME - ( 255 - volume ) * 4;
+
+   for( i = 0; i < GUSWAVE_MaxVoices; i++ )
+      {
+      if ( GUSWAVE_Voices[ i ].Active )
+         {
+         gf1_dig_set_vol( GUSWAVE_Voices[ i ].GF1voice,
+            GUSWAVE_Volume - ( 255 - GUSWAVE_Voices[ i ].Volume ) * 4 );
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_GetVolume
+
+   Returns the total volume of the digitized sounds.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_GetVolume
+   (
+   void
+   )
+
+   {
+   return( 255 - ( ( MAX_VOLUME - GUSWAVE_Volume ) / 4 ) );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_AllocVoice
+
+   Retrieve an inactive or lower priority voice for output.
+---------------------------------------------------------------------*/
+
+static VoiceNode *GUSWAVE_AllocVoice
+   (
+   int priority
+   )
+
+   {
+   VoiceNode   *voice;
+   VoiceNode   *node;
+   unsigned    flags;
+
+   // If we don't have any free voices, check if we have a higher
+   // priority than one that is playing.
+   if ( GUSWAVE_VoicesPlaying() >= GUSWAVE_MaxVoices )
+      {
+      flags = DisableInterrupts();
+
+      node = VoiceList.start;
+      voice = node;
+      while( node != NULL )
+         {
+         if ( node->priority < voice->priority )
+            {
+            voice = node;
+            }
+
+         node = node->next;
+         }
+
+      RestoreInterrupts( flags );
+
+      if ( priority >= voice->priority )
+         {
+         GUSWAVE_Kill( voice->handle );
+         }
+      }
+
+   // Check if any voices are in the voice pool
+   flags = DisableInterrupts();
+
+   voice = VoicePool.start;
+   if ( voice != NULL )
+      {
+      LL_Remove( VoiceNode, &VoicePool, voice );
+      }
+
+   RestoreInterrupts( flags );
+
+   if ( voice != NULL )
+      {
+      do
+         {
+         GUSWAVE_VoiceHandle++;
+         if ( GUSWAVE_VoiceHandle < GUSWAVE_MinVoiceHandle )
+            {
+            GUSWAVE_VoiceHandle = GUSWAVE_MinVoiceHandle;
+            }
+         }
+      while( GUSWAVE_VoicePlaying( GUSWAVE_VoiceHandle ) );
+
+      voice->handle = GUSWAVE_VoiceHandle;
+      }
+
+   return( voice );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_VoiceAvailable
+
+   Checks if a voice can be play at the specified priority.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_VoiceAvailable
+   (
+   int priority
+   )
+
+   {
+   VoiceNode   *voice;
+   VoiceNode   *node;
+   unsigned    flags;
+
+   if ( GUSWAVE_VoicesPlaying() < GUSWAVE_MaxVoices )
+      {
+      return( TRUE );
+      }
+
+   flags = DisableInterrupts();
+
+   node = VoiceList.start;
+   voice = node;
+   while( node != NULL )
+      {
+      if ( node->priority < voice->priority )
+         {
+         voice = node;
+         }
+
+      node = node->next;
+      }
+
+   RestoreInterrupts( flags );
+
+   if ( priority >= voice->priority )
+      {
+      return( TRUE );
+      }
+
+   return( FALSE );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_GetNextVOCBlock
+
+   Interperate the information of a VOC format sound file.
+---------------------------------------------------------------------*/
+
+playbackstatus GUSWAVE_GetNextVOCBlock
+   (
+   VoiceNode *voice
+   )
+
+   {
+   unsigned char *ptr;
+   int            blocktype;
+   int            lastblocktype;
+   unsigned long  blocklength;
+   unsigned long  samplespeed;
+   unsigned int   tc;
+   int            packtype;
+   int            voicemode;
+   int            done;
+   unsigned       BitsPerSample;
+   unsigned       Channels;
+   unsigned       Format;
+
+   if ( voice->BlockLength > 0 )
+      {
+      voice->sound       += MAX_BLOCK_LENGTH;
+      voice->length       = min( voice->BlockLength, MAX_BLOCK_LENGTH );
+      voice->BlockLength -= voice->length;
+      return( KeepPlaying );
+      }
+
+   ptr = ( unsigned char * )voice->NextBlock;
+
+   voice->Playing = TRUE;
+
+   voicemode = 0;
+   lastblocktype = 0;
+   packtype = 0;
+
+   done = FALSE;
+   while( !done )
+      {
+      // Stop playing if we get a NULL pointer
+      if ( ptr == NULL )
+         {
+         voice->Playing = FALSE;
+         done = TRUE;
+         break;
+         }
+
+      blocktype = ( int )*ptr;
+      blocklength = ( *( unsigned long * )( ptr + 1 ) ) & 0x00ffffff;
+      ptr += 4;
+
+      switch( blocktype )
+         {
+         case 0 :
+            // End of data
+            voice->Playing = FALSE;
+            done = TRUE;
+            break;
+
+         case 1 :
+            // Sound data block
+            voice->bits = 8;
+            if ( lastblocktype != 8 )
+               {
+               tc = ( unsigned int )*ptr << 8;
+               packtype = *( ptr + 1 );
+               }
+
+            ptr += 2;
+            blocklength -= 2;
+
+            samplespeed = 256000000L / ( 65536 - tc );
+
+            // Skip packed or stereo data
+            if ( ( packtype != 0 ) || ( voicemode != 0 ) )
+               {
+               ptr += blocklength;
+               }
+            else
+               {
+               done = TRUE;
+               }
+            voicemode = 0;
+            break;
+
+         case 2 :
+            // Sound continuation block
+            samplespeed = voice->SamplingRate;
+            done = TRUE;
+            break;
+
+         case 3 :
+            // Silence
+            // Not implimented.
+            ptr += blocklength;
+            break;
+
+         case 4 :
+            // Marker
+            // Not implimented.
+            ptr += blocklength;
+            break;
+
+         case 5 :
+            // ASCII string
+            // Not implimented.
+            ptr += blocklength;
+            break;
+
+         case 6 :
+            // Repeat begin
+            voice->LoopCount = *( unsigned short * )ptr;
+            ptr += blocklength;
+            voice->LoopStart = ptr;
+            break;
+
+         case 7 :
+            // Repeat end
+            ptr += blocklength;
+            if ( lastblocktype == 6 )
+               {
+               voice->LoopCount = 0;
+               }
+            else
+               {
+               if ( ( voice->LoopCount > 0 ) && ( voice->LoopStart != NULL ) )
+                  {
+                  ptr = voice->LoopStart;
+                  if ( voice->LoopCount < 0xffff )
+                     {
+                     voice->LoopCount--;
+                     if ( voice->LoopCount == 0 )
+                        {
+                        voice->LoopStart = NULL;
+                        }
+                     }
+                  }
+               }
+            break;
+
+         case 8 :
+            // Extended block
+            voice->bits = 8;
+            tc = *( unsigned short * )ptr;
+            packtype = *( ptr + 2 );
+            voicemode = *( ptr + 3 );
+            ptr += blocklength;
+            break;
+
+         case 9 :
+            // New sound data block
+            samplespeed = *( unsigned long * )ptr;
+            BitsPerSample = ( unsigned )*( ptr + 4 );
+            Channels = ( unsigned )*( ptr + 5 );
+            Format = ( unsigned )*( unsigned short * )( ptr + 6 );
+
+            if ( ( BitsPerSample == 8 ) && ( Channels == 1 ) &&
+               ( Format == VOC_8BIT ) )
+               {
+               ptr += 12;
+               blocklength -= 12;
+               voice->bits  = 8;
+               done = TRUE;
+               }
+            else if ( ( BitsPerSample == 16 ) && ( Channels == 1 ) &&
+               ( Format == VOC_16BIT ) )
+               {
+               ptr         += 12;
+               blocklength -= 12;
+               voice->bits  = 16;
+               done         = TRUE;
+               }
+            else
+               {
+               ptr += blocklength;
+               }
+            break;
+
+         default :
+            // Unknown data.  Probably not a VOC file.
+            voice->Playing = FALSE;
+            done = TRUE;
+            break;
+         }
+
+      lastblocktype = blocktype;
+      }
+
+   if ( voice->Playing )
+      {
+      voice->NextBlock    = ptr + blocklength;
+      voice->sound        = ptr;
+
+      voice->SamplingRate = samplespeed;
+      voice->RateScale    = ( voice->SamplingRate * voice->PitchScale ) >> 16;
+
+      voice->length       = min( blocklength, MAX_BLOCK_LENGTH );
+      voice->BlockLength  = blocklength - voice->length;
+
+      return( KeepPlaying );
+      }
+
+   return( SoundDone );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_GetNextWAVBlock
+
+   Controls playback of demand fed data.
+---------------------------------------------------------------------*/
+
+playbackstatus GUSWAVE_GetNextWAVBlock
+   (
+   VoiceNode *voice
+   )
+
+   {
+   if ( voice->BlockLength <= 0 )
+      {
+      if ( voice->LoopStart == NULL )
+         {
+         voice->Playing = FALSE;
+         return( SoundDone );
+         }
+
+      voice->BlockLength = voice->LoopSize;
+      voice->NextBlock   = voice->LoopStart;
+      voice->length      = 0;
+      }
+
+   voice->sound        = voice->NextBlock;
+   voice->length       = min( voice->BlockLength, 0x8000 );
+   voice->NextBlock   += voice->length;
+   voice->BlockLength -= voice->length;
+
+   return( KeepPlaying );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_GetNextDemandFeedBlock
+
+   Controls playback of demand fed data.
+---------------------------------------------------------------------*/
+
+playbackstatus GUSWAVE_GetNextDemandFeedBlock
+   (
+   VoiceNode *voice
+   )
+
+   {
+   if ( voice->BlockLength > 0 )
+      {
+      voice->sound       += voice->length;
+      voice->length       = min( voice->BlockLength, 0x8000 );
+      voice->BlockLength -= voice->length;
+
+      return( KeepPlaying );
+      }
+
+   if ( voice->DemandFeed == NULL )
+      {
+      return( SoundDone );
+      }
+
+   ( voice->DemandFeed )( &voice->sound, &voice->BlockLength );
+//   voice->sound = GUS_Silence16;
+//   voice->BlockLength = 256;
+
+   voice->length       = min( voice->BlockLength, 0x8000 );
+   voice->BlockLength -= voice->length;
+
+   if ( ( voice->length > 0 ) && ( voice->sound != NULL ) )
+      {
+      return( KeepPlaying );
+      }
+   return( NoMoreData );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_Play
+
+   Begins playback of digitized sound.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_Play
+   (
+   VoiceNode *voice,
+   int angle,
+   int volume,
+   int channels
+   )
+
+   {
+   int      VoiceNumber;
+   int      type;
+   int      pan;
+   unsigned flags;
+   int ( *servicefunction )( int reason, int voice, unsigned char **buf, unsigned long *size );
+
+   type = 0;
+   if ( channels != 1 )
+      {
+      type |= TYPE_STEREO;
+      }
+
+   if ( voice->bits == 8 )
+      {
+      type |= TYPE_8BIT;
+      type |= TYPE_INVERT_MSB;
+      }
+
+   voice->GF1voice  = -1;
+
+   angle &= 31;
+   pan = GUSWAVE_PanTable[ angle ];
+   if ( GUSWAVE_SwapLeftRight )
+      {
+      pan = 15 - pan;
+      }
+
+   voice->Pan = pan;
+
+   volume = max( 0, volume );
+   volume = min( 255, volume );
+   voice->Volume = volume;
+
+   if ( !GUS_Debug )
+      {
+      servicefunction = GUSWAVE_CallBack;
+      }
+   else
+      {
+      servicefunction = GUSWAVE_DebugCallBack;
+      }
+
+   VoiceNumber = gf1_play_digital( 0, voice->sound, voice->length,
+      voice->mem, GUSWAVE_Volume - ( 255 - volume ) * 4, pan,
+      voice->RateScale, type, &GUS_HoldBuffer, servicefunction );
+
+   if ( VoiceNumber == NO_MORE_VOICES )
+      {
+      if ( GUS_Debug )
+         {
+         DB_printf( "Out of voices.\n" );
+         }
+
+      flags = DisableInterrupts();
+      LL_AddToTail( VoiceNode, &VoicePool, voice );
+      RestoreInterrupts( flags );
+
+      GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
+      return( GUSWAVE_Warning );
+      }
+
+   flags = DisableInterrupts();
+   voice->GF1voice = VoiceNumber;
+   voice->Active   = TRUE;
+   LL_AddToTail( VoiceNode, &VoiceList, voice );
+   VoiceStatus[ VoiceNumber ].playing = TRUE;
+   VoiceStatus[ VoiceNumber ].Voice   = voice;
+
+   if ( GUS_Debug )
+      {
+      DB_printf( "GUS voice %d playing\n", VoiceNumber );
+      }
+
+   RestoreInterrupts( flags );
+
+   return( voice->handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_PlayVOC
+
+   Begins playback of digitized sound.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_PlayVOC
+   (
+   char *sample,
+   int   pitchoffset,
+   int   angle,
+   int   volume,
+   int   priority,
+   unsigned long callbackval
+   )
+
+   {
+   int handle;
+   int status;
+   playbackstatus soundstatus;
+   VoiceNode *voice;
+   unsigned flags;
+
+   // Make sure it's a valid VOC file.
+   status = strncmp( sample, "Creative Voice File", 19 );
+   if ( status != 0 )
+      {
+      // Tell multivoc that we had a bad VOC file
+      MV_ErrorCode = MV_InvalidVOCFile;
+
+      GUSWAVE_SetErrorCode( GUSWAVE_InvalidVOCFile );
+      return( GUSWAVE_Error );
+      }
+
+   // Request a voice from the voice pool
+   voice = GUSWAVE_AllocVoice( priority );
+   if ( voice == NULL )
+      {
+      if ( GUS_Debug )
+         {
+         DB_printf( "No more voices.  Skipping sound.\n" );
+         }
+      GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
+      return( GUSWAVE_Warning );
+      }
+
+   voice->NextBlock   = sample + *( unsigned short int * )( sample + 0x14 );
+   voice->LoopStart   = NULL;
+   voice->LoopCount   = 0;
+   voice->BlockLength = 0;
+   voice->PitchScale  = PITCH_GetScale( pitchoffset );
+   voice->wavetype    = VOC;
+   voice->bits        = 8;
+   voice->GetSound    = GUSWAVE_GetNextVOCBlock;
+   voice->length      = 0;
+   voice->next        = NULL;
+   voice->prev        = NULL;
+   voice->priority    = priority;
+   voice->callbackval = callbackval;
+
+   soundstatus = GUSWAVE_GetNextVOCBlock( voice );
+   if ( soundstatus == SoundDone )
+      {
+      flags = DisableInterrupts();
+      LL_AddToTail( VoiceNode, &VoicePool, voice );
+      RestoreInterrupts( flags );
+
+      if ( GUS_Debug )
+         {
+         DB_printf( "Voice ended before playback.\n" );
+         }
+
+      // Tell multivoc that we had a bad VOC file
+      MV_ErrorCode = MV_InvalidVOCFile;
+
+      GUSWAVE_SetErrorCode( GUSWAVE_InvalidVOCFile );
+      return( GUSWAVE_Error );
+      }
+
+   handle = GUSWAVE_Play( voice, angle, volume, 1 );
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_PlayWAV
+
+   Begins playback of digitized sound.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_PlayWAV
+   (
+   char *sample,
+   int   pitchoffset,
+   int   angle,
+   int   volume,
+   int   priority,
+   unsigned long callbackval
+   )
+
+   {
+   VoiceNode *voice;
+   int        handle;
+   int        channels;
+   int        bits;
+   int        length;
+   riff_header   *riff;
+   format_header *format;
+   data_header   *data;
+
+   riff = ( riff_header * )sample;
+
+   if ( ( strncmp( riff->RIFF, "RIFF", 4 ) != 0 ) ||
+      ( strncmp( riff->WAVE, "WAVE", 4 ) != 0 ) ||
+      ( strncmp( riff->fmt, "fmt ", 4) != 0 ) )
+      {
+      GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
+      return( GUSWAVE_Error );
+      }
+
+   format = ( format_header * )( riff + 1 );
+   data   = ( data_header * )( ( ( char * )format ) + riff->format_size );
+
+   if ( format->wFormatTag != 1 )
+      {
+      GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
+      return( GUSWAVE_Error );
+      }
+
+   channels = format->nChannels;
+   if ( ( channels != 1 ) && ( channels != 2 ) )
+      {
+      GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
+      return( GUSWAVE_Error );
+      }
+
+   bits = format->nBitsPerSample;
+   if ( ( bits != 8 ) && ( bits != 16 ) )
+      {
+      GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
+      return( GUSWAVE_Error );
+      }
+
+   if ( strncmp( data->DATA, "data", 4 ) != 0 )
+      {
+      GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
+      return( GUSWAVE_Error );
+      }
+
+   // Request a voice from the voice pool
+   voice = GUSWAVE_AllocVoice( priority );
+   if ( voice == NULL )
+      {
+      if ( GUS_Debug )
+         {
+         DB_printf( "No more voices.  Skipping sound.\n" );
+         }
+      GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
+      return( GUSWAVE_Warning );
+      }
+
+   voice->wavetype    = WAV;
+   voice->bits        = bits;
+   voice->GetSound    = GUSWAVE_GetNextWAVBlock;
+
+   length = data->size;
+
+   voice->Playing     = TRUE;
+   voice->DemandFeed  = NULL;
+   voice->LoopStart   = NULL;
+   voice->LoopCount   = 0;
+   voice->length      = min( length, 0x8000 );
+   voice->BlockLength = length - voice->length;//  min( loopend + 1, data->size );
+   voice->sound       = ( char * )( data + 1 );
+   voice->NextBlock   = voice->sound + voice->length;
+   voice->next        = NULL;
+   voice->prev        = NULL;
+   voice->priority    = priority;
+   voice->callbackval = callbackval;
+   voice->LoopStart   = NULL;// voice->NextBlock + loopstart;
+   voice->LoopEnd     = NULL;//voice->NextBlock + min( loopend, data->size - 1 );
+   voice->LoopSize    = 0;//( voice->LoopEnd - voice->LoopStart ) + 1;
+   voice->PitchScale  = PITCH_GetScale( pitchoffset );
+   voice->SamplingRate = format->nSamplesPerSec;
+   voice->RateScale   = ( voice->SamplingRate * voice->PitchScale ) >> 16;
+
+   handle = GUSWAVE_Play( voice, angle, volume, channels );
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_StartDemandFeedPlayback
+
+   Begins playback of digitized sound.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_StartDemandFeedPlayback
+   (
+   void ( *function )( char **ptr, unsigned long *length ),
+   int   channels,
+   int   bits,
+   int   rate,
+   int   pitchoffset,
+   int   angle,
+   int   volume,
+   int   priority,
+   unsigned long callbackval
+   )
+
+   {
+   VoiceNode *voice;
+   int        handle;
+
+   // Request a voice from the voice pool
+   voice = GUSWAVE_AllocVoice( priority );
+   if ( voice == NULL )
+      {
+      if ( GUS_Debug )
+         {
+         DB_printf( "No more voices.  Skipping sound.\n" );
+         }
+      GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
+      return( GUSWAVE_Warning );
+      }
+
+   voice->wavetype    = DemandFeed;
+   voice->bits        = bits;
+   voice->GetSound    = GUSWAVE_GetNextDemandFeedBlock;
+   voice->Playing     = TRUE;
+   voice->DemandFeed  = function;
+   voice->LoopStart   = NULL;
+   voice->LoopCount   = 0;
+   voice->BlockLength = 0;
+   voice->length      = 256;
+   voice->sound       = ( bits == 8 ) ? GUS_Silence8 : ( char * )GUS_Silence16;
+   voice->NextBlock   = NULL;
+   voice->next        = NULL;
+   voice->prev        = NULL;
+   voice->priority    = priority;
+   voice->callbackval = callbackval;
+   voice->PitchScale  = PITCH_GetScale( pitchoffset );
+   voice->SamplingRate = rate;
+   voice->RateScale   = ( voice->SamplingRate * voice->PitchScale ) >> 16;
+
+   handle = GUSWAVE_Play( voice, angle, volume, channels );
+
+   return( handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_SetReverseStereo
+
+   Set the orientation of the left and right channels.
+---------------------------------------------------------------------*/
+
+void GUSWAVE_SetReverseStereo
+   (
+   int setting
+   )
+
+   {
+   GUSWAVE_SwapLeftRight = setting;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_GetReverseStereo
+
+   Returns the orientation of the left and right channels.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_GetReverseStereo
+   (
+   void
+   )
+
+   {
+   return( GUSWAVE_SwapLeftRight );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_InitVoices
+
+   Begins playback of digitized sound.
+---------------------------------------------------------------------*/
+
+static int GUSWAVE_InitVoices
+   (
+   void
+   )
+
+   {
+   int i;
+
+   for( i = 0; i < MAX_VOICES; i++ )
+      {
+      VoiceStatus[ i ].playing = FALSE;
+      VoiceStatus[ i ].Voice   = NULL;
+      }
+
+   VoicePool.start = NULL;
+   VoicePool.end   = NULL;
+   VoiceList.start = NULL;
+   VoiceList.end   = NULL;
+
+   for( i = 0; i < VOICES; i++ )
+      {
+      GUSWAVE_Voices[ i ].num      = -1;
+      GUSWAVE_Voices[ i ].Active   = FALSE;
+      GUSWAVE_Voices[ i ].GF1voice = -1;
+      GUSWAVE_Voices[ i ].mem      = NULL;
+      }
+
+   for( i = 0; i < VOICES; i++ )
+      {
+      GUSWAVE_Voices[ i ].num      = i;
+      GUSWAVE_Voices[ i ].Active   = FALSE;
+      GUSWAVE_Voices[ i ].GF1voice = 0;
+
+      GUSWAVE_Voices[ i ].mem = gf1_malloc( GF1BSIZE );
+      if ( GUSWAVE_Voices[ i ].mem == NULL )
+         {
+         GUSWAVE_MaxVoices = i;
+         if ( i < 1 )
+            {
+            if ( GUSMIDI_Installed )
+               {
+               GUSWAVE_SetErrorCode( GUSWAVE_UltraNoMemMIDI );
+               }
+            else
+               {
+               GUSWAVE_SetErrorCode( GUSWAVE_UltraNoMem );
+               }
+            return( GUSWAVE_Error );
+            }
+
+         break;
+         }
+
+      LL_AddToTail( VoiceNode, &VoicePool, &GUSWAVE_Voices[ i ] );
+      }
+
+   return( GUSWAVE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_SetCallBack
+
+   Set the function to call when a voice stops.
+---------------------------------------------------------------------*/
+
+void GUSWAVE_SetCallBack
+   (
+   void ( *function )( unsigned long )
+   )
+
+   {
+   GUSWAVE_CallBackFunc = function;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: GUSWAVE_Init
+
+   Initializes the Gravis Ultrasound for digitized sound playback.
+---------------------------------------------------------------------*/
+
+int GUSWAVE_Init
+   (
+   int numvoices
+   )
+
+   {
+   int status;
+
+   if ( GUSWAVE_Installed )
+      {
+      GUSWAVE_Shutdown();
+      }
+
+   GUSWAVE_SetErrorCode( GUSWAVE_Ok );
+
+   status = GUS_Init();
+   if ( status != GUS_Ok )
+      {
+      GUSWAVE_SetErrorCode( GUSWAVE_GUSError );
+      return( GUSWAVE_Error );
+      }
+
+   GUS_Debug = USER_CheckParameter( "DEBUGGUS" );
+
+   GUSWAVE_MaxVoices = min( numvoices, VOICES );
+   GUSWAVE_MaxVoices = max( GUSWAVE_MaxVoices, 0 );
+
+   status = GUSWAVE_InitVoices();
+   if ( status != GUSWAVE_Ok )
+      {
+      GUS_Shutdown();
+      return( status );
+      }
+
+   GUSWAVE_SetReverseStereo( FALSE );
+
+   GUSWAVE_CallBackFunc = NULL;
+   GUSWAVE_Installed = TRUE;
+
+   return( GUSWAVE_Ok );
+   }

Added: tags/rott-1.1/rott/audiolib/guswave.h
===================================================================
--- tags/rott-1.1/rott/audiolib/guswave.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/guswave.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,75 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: GUSWAVE.H
+
+   author: James R. Dose
+   date:   March 23, 1994
+
+   Public header for for GUSWAVE.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __GUSWAVE_H
+#define __GUSWAVE_H
+
+#define GUSWAVE_MinVoiceHandle 1
+
+enum GUSWAVE_Errors
+   {
+   GUSWAVE_Warning  = -2,
+   GUSWAVE_Error    = -1,
+   GUSWAVE_Ok       = 0,
+   GUSWAVE_GUSError,
+   GUSWAVE_NotInstalled,
+   GUSWAVE_NoVoices,
+   GUSWAVE_UltraNoMem,
+   GUSWAVE_UltraNoMemMIDI,
+   GUSWAVE_VoiceNotFound,
+   GUSWAVE_InvalidVOCFile,
+   GUSWAVE_InvalidWAVFile
+   };
+
+char *GUSWAVE_ErrorString( int ErrorNumber );
+int   GUSWAVE_VoicePlaying( int handle );
+int   GUSWAVE_VoicesPlaying( void );
+int   GUSWAVE_Kill( int handle );
+int   GUSWAVE_KillAllVoices( void );
+int   GUSWAVE_SetPitch( int handle, int pitchoffset );
+int   GUSWAVE_SetPan3D( int handle, int angle, int distance );
+void  GUSWAVE_SetVolume( int volume );
+int   GUSWAVE_GetVolume( void );
+int   GUSWAVE_VoiceAvailable( int priority );
+int   GUSWAVE_PlayVOC( char *sample, int pitchoffset, int angle, int volume,
+         int priority, unsigned long callbackval );
+int   GUSWAVE_PlayWAV( char *sample, int pitchoffset, int angle, int volume,
+         int priority, unsigned long callbackval );
+int   GUSWAVE_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ),
+         int channels, int bits, int rate, int pitchoffset, int angle,
+         int volume, int priority, unsigned long callbackval );
+void  GUSWAVE_SetCallBack( void ( *function )( unsigned long ) );
+void  GUSWAVE_SetReverseStereo( int setting );
+int   GUSWAVE_GetReverseStereo( void );
+int   GUSWAVE_Init( int numvoices );
+void  GUSWAVE_Shutdown( void );
+#pragma aux GUSWAVE_Shutdown frame;
+
+#endif

Added: tags/rott-1.1/rott/audiolib/interrup.h
===================================================================
--- tags/rott-1.1/rott/audiolib/interrup.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/interrup.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,50 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: INTERRUP.H
+
+   author: James R. Dose
+   date:   March 31, 1994
+
+   Inline functions for disabling and restoring the interrupt flag.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __INTERRUPT_H
+#define __INTERRUPT_H
+
+unsigned long DisableInterrupts( void );
+void          RestoreInterrupts( unsigned long flags );
+
+#ifdef PLAT_DOS
+#pragma aux DisableInterrupts = \
+   "pushfd",                    \
+   "pop    eax",                \
+   "cli"                        \
+   modify [ eax ];
+
+#pragma aux RestoreInterrupts = \
+   "push   eax",                \
+   "popfd"                      \
+   parm [ eax ];
+#endif
+
+#endif

Added: tags/rott-1.1/rott/audiolib/irq.c
===================================================================
--- tags/rott-1.1/rott/audiolib/irq.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/irq.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,325 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: IRQ.C
+
+   author: James R. Dose
+   date:   August 26, 1994
+
+   Low level routines to set and restore IRQ's through DPMI.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <dos.h>
+#include <stdlib.h>
+#include "irq.h"
+
+#define D32RealSeg(P) ( ( ( ( unsigned long )( P ) ) >> 4 ) & 0xFFFF )
+#define D32RealOff(P) ( ( ( unsigned long )( P ) ) & 0xF )
+
+typedef struct
+   {
+   unsigned long  drdi;
+   unsigned long  drsi;
+   unsigned long  drbp;
+   unsigned long  drxx;
+   unsigned long  drbx;
+   unsigned long  drdx;
+   unsigned long  drcx;
+   unsigned long  drax;
+
+   unsigned short drflags;
+   unsigned short dres;
+   unsigned short drds;
+   unsigned short drfs;
+   unsigned short drgs;
+   unsigned short drip;
+   unsigned short drcs;
+   unsigned short drsp;
+   unsigned short drss;
+   } DPMI_REGS;
+
+static DPMI_REGS rmregs = { 0 };
+static void ( __interrupt __far *IRQ_Callback )( void ) = NULL;
+
+static char *IRQ_RealModeCode = NULL;
+
+static unsigned short IRQ_CallBackSegment;
+static unsigned short IRQ_CallBackOffset;
+static unsigned short IRQ_RealModeSegment;
+static unsigned short IRQ_RealModeOffset;
+static unsigned long  IRQ_ProtectedModeOffset;
+static unsigned short IRQ_ProtectedModeSelector;
+
+static union  REGS  Regs;
+static struct SREGS SegRegs;
+
+static void *D32DosMemAlloc
+   (
+   unsigned long size
+   )
+
+   {
+   // DPMI allocate DOS memory
+   Regs.x.eax = 0x0100;
+
+   // Number of paragraphs requested
+   Regs.x.ebx = ( size + 15 ) >> 4;
+
+   int386( 0x31, &Regs, &Regs );
+
+   if ( Regs.x.cflag != 0 )
+      {
+      // Failed
+      return ( ( unsigned long )0 );
+      }
+
+   return( ( void * )( ( Regs.x.eax & 0xFFFF ) << 4  ) );
+   }
+
+// Intermediary function: DPMI calls this, making it
+// easier to write in C
+// handle 16-bit incoming stack
+
+void fixebp
+   (
+   void
+   );
+
+#pragma aux fixebp = \
+        "mov   bx,  ss" \
+        "lar   ebx, ebx" \
+        "bt    ebx, 22" \
+        "jc    bigstk" \
+        "movzx esp, sp" \
+        "mov   ebp, esp" \
+        "bigstk:" \
+modify exact [ ebx ];
+
+#pragma aux rmcallback parm [];
+
+void rmcallback
+   (
+   unsigned short _far *stkp
+   )
+
+   {
+   // "Pop" the real mode return frame so we
+   // can resume where we left off
+   rmregs.drip = *stkp++;
+   rmregs.drcs = *stkp++;
+
+   rmregs.drsp = FP_OFF(stkp);
+
+   // Call protected-mode handler
+   IRQ_Callback();
+   }
+
+static void _interrupt _cdecl callback_x
+   (
+   // regs pushed in this order by prologue
+
+   int rgs,
+   int rfs,
+   int res,
+   int rds,
+   int rdi,
+   int rsi,
+   int rbp,
+   int rsp,
+   int rbx,
+   int rdx,
+   int rcx,
+   int rax
+   )
+
+   {
+//   unsigned short _far *stkp;
+//   return;
+
+   fixebp();
+   rmcallback (MK_FP(rds, rsi));
+   }
+
+/*
+static void _interrupt _cdecl callback_x
+   (
+   // regs pushed in this order by prologue
+
+   int rgs,
+   int rfs,
+   int res,
+   int rds,
+   int rdi,
+   int rsi,
+   int rbp,
+   int rsp,
+   int rbx,
+   int rdx,
+   int rcx,
+   int rax
+   )
+
+   {
+   unsigned short _far *stkp;
+
+   fixebp();
+   stkp = MK_FP(rds, rsi);
+
+   // "Pop" the real mode return frame so we
+   // can resume where we left off
+   rmregs.drip = *stkp++;
+   rmregs.drcs = *stkp++;
+
+   rmregs.drsp = FP_OFF(stkp);
+
+   // Call protected-mode handler
+   IRQ_Callback();
+   }
+*/
+
+
+int IRQ_SetVector
+   (
+   int vector,
+   void ( __interrupt __far *function )( void )
+   )
+
+   {
+   void far *fp;
+
+   IRQ_Callback = function;
+
+   // Save the starting real-mode and protected-mode handler addresses
+
+   // DPMI get protected mode vector */
+   Regs.w.ax = 0x0204;
+   Regs.w.bx = vector;
+   int386( 0x31, &Regs, &Regs );
+   IRQ_ProtectedModeSelector = Regs.w.cx;
+   IRQ_ProtectedModeOffset = Regs.x.edx;
+
+   // DPMI get real mode vector
+   Regs.w.ax = 0x0200;
+   Regs.w.bx = vector;
+   int386( 0x31, &Regs, &Regs );
+   IRQ_RealModeSegment = Regs.w.cx;
+   IRQ_RealModeOffset = Regs.w.dx;
+
+   // Set up callback
+   // DPMI allocate real mode callback
+   Regs.w.ax = 0x0303;
+   fp = ( void far * )callback_x;
+   SegRegs.ds   = FP_SEG( fp );
+   Regs.x.esi = FP_OFF( fp );
+   fp      = ( void _far * )&rmregs;
+   SegRegs.es   = FP_SEG( fp );
+   Regs.x.edi = FP_OFF( fp );
+   int386x( 0x31, &Regs, &Regs, &SegRegs );
+
+   IRQ_CallBackSegment = Regs.w.cx;
+   IRQ_CallBackOffset = Regs.w.dx;
+
+   if ( Regs.x.cflag != 0 )
+      {
+      return( IRQ_Error );
+      }
+
+   if ( IRQ_RealModeCode == NULL )
+      {
+      // Allocate 6 bytes of low memory for real mode interrupt handler
+      IRQ_RealModeCode = D32DosMemAlloc( 6 );
+      if ( IRQ_RealModeCode == NULL )
+         {
+         // Free callback
+         Regs.w.ax = 0x304;
+         Regs.w.cx = IRQ_CallBackSegment;
+         Regs.w.dx = IRQ_CallBackOffset;
+         int386x( 0x31, &Regs, &Regs, &SegRegs );
+
+         return( IRQ_Error );
+         }
+      }
+
+   // Poke code (to call callback) into real mode handler
+
+   // CALL FAR PTR (callback)
+   IRQ_RealModeCode[ 0 ] = '\x9A';
+   *( ( unsigned short * )&IRQ_RealModeCode[ 1 ] ) = IRQ_CallBackOffset;
+   *( ( unsigned short * )&IRQ_RealModeCode[ 3 ] ) = IRQ_CallBackSegment;
+
+   // IRET
+   IRQ_RealModeCode[ 5 ] = '\xCF';
+
+   // Install protected mode handler
+   // DPMI set protected mode vector
+   Regs.w.ax = 0x0205;
+   Regs.w.bx = vector;
+   fp = function;
+
+   Regs.w.cx  = FP_SEG( fp );
+   Regs.x.edx = FP_OFF( fp );
+   int386( 0x31, &Regs, &Regs );
+
+   // Install callback address as real mode handler
+   // DPMI set real mode vector
+   Regs.w.ax = 0x0201;
+   Regs.w.bx = vector;
+   Regs.w.cx = D32RealSeg( IRQ_RealModeCode );
+   Regs.w.dx = D32RealOff( IRQ_RealModeCode );
+   int386( 0x31, &Regs, &Regs );
+
+   return( IRQ_Ok );
+   }
+
+int IRQ_RestoreVector
+   (
+   int vector
+   )
+
+   {
+   // Restore original interrupt handlers
+   // DPMI set real mode vector
+   Regs.w.ax = 0x0201;
+   Regs.w.bx = vector;
+   Regs.w.cx = IRQ_RealModeSegment;
+   Regs.w.dx = IRQ_RealModeOffset;
+   int386( 0x31, &Regs, &Regs );
+
+   Regs.w.ax = 0x0205;
+   Regs.w.bx = vector;
+   Regs.w.cx = IRQ_ProtectedModeSelector;
+   Regs.x.edx = IRQ_ProtectedModeOffset;
+   int386( 0x31, &Regs, &Regs );
+
+   // Free callback
+   Regs.w.ax = 0x304;
+   Regs.w.cx = IRQ_CallBackSegment;
+   Regs.w.dx = IRQ_CallBackOffset;
+   int386x( 0x31, &Regs, &Regs, &SegRegs );
+
+   if ( Regs.x.cflag )
+      {
+      return( IRQ_Error );
+      }
+
+   return( IRQ_Ok );
+   }

Added: tags/rott-1.1/rott/audiolib/irq.h
===================================================================
--- tags/rott-1.1/rott/audiolib/irq.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/irq.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,54 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: IRQ.H
+
+   author: James R. Dose
+   date:   August 8, 1994
+
+   Public header for IRQ.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __IRQ_H
+#define __IRQ_H
+
+enum IRQ_ERRORS
+   {
+   IRQ_Warning = -2,
+   IRQ_Error = -1,
+   IRQ_Ok = 0,
+   };
+
+#define VALID_IRQ( irq )  ( ( ( irq ) >= 0 ) && ( ( irq ) <= 15 ) )
+
+int IRQ_SetVector
+   (
+   int vector,
+   void ( __interrupt *function )( void )
+   );
+int IRQ_RestoreVector
+   (
+   int vector
+   );
+
+
+#endif

Added: tags/rott-1.1/rott/audiolib/leetimbr.c
===================================================================
--- tags/rott-1.1/rott/audiolib/leetimbr.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/leetimbr.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,290 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+typedef struct
+   {
+   unsigned char SAVEK[ 2 ];
+   unsigned char Level[ 2 ];
+   unsigned char Env1[ 2 ];
+   unsigned char Env2[ 2 ];
+   unsigned char Wave[ 2 ];
+   unsigned char Feedback;
+   signed   char Transpose;
+   signed   char Velocity;
+   } TIMBRE;
+
+TIMBRE ADLIB_TimbreBank[ 256 ] =
+   {
+      { { 33, 49 }, { 79, 0 }, { 242, 210 }, { 82, 115 }, { 0, 0 }, 6, 0 },
+      { { 19, 17 }, { 198, 10 }, { 242, 241 }, { 245, 245 }, { 1, 0 }, 0, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 3, 18 }, { 48, 16 }, { 246, 242 }, { 25, 244 }, { 0, 0 }, 15, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 24, 129 }, { 98, 0 }, { 243, 242 }, { 230, 246 }, { 0, 0 }, 0, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 23, 2 }, { 79, 16 }, { 242, 242 }, { 96, 114 }, { 0, 0 }, 8, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 178, 176 }, { 192, 134 }, { 159, 148 }, { 6, 15 }, { 1, 1 }, 9, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 178, 176 }, { 192, 128 }, { 159, 148 }, { 6, 15 }, { 1, 1 }, 9, 0 },
+      { { 130, 128 }, { 192, 134 }, { 145, 145 }, { 246, 246 }, { 1, 1 }, 9, 0 },
+      { { 36, 49 }, { 79, 27 }, { 242, 82 }, { 11, 11 }, { 0, 0 }, 14, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 35, 33 }, { 72, 0 }, { 149, 132 }, { 25, 25 }, { 1, 0 }, 8, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 19, 49 }, { 150, 128 }, { 254, 242 }, { 33, 148 }, { 0, 0 }, 10, 0 },
+      { { 1, 17 }, { 77, 0 }, { 242, 245 }, { 83, 116 }, { 1, 1 }, 8, 0 },
+      { { 33, 40 }, { 1, 9 }, { 148, 148 }, { 25, 9 }, { 0, 0 }, 6, 0 },
+      { { 33, 40 }, { 1, 19 }, { 148, 148 }, { 25, 9 }, { 0, 0 }, 6, 0 },
+      { { 36, 194 }, { 138, 3 }, { 250, 145 }, { 111, 248 }, { 0, 0 }, 8, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 33 }, { 26, 0 }, { 241, 246 }, { 207, 72 }, { 0, 0 }, 10, 0 },
+      { { 1, 34 }, { 29, 0 }, { 183, 196 }, { 34, 55 }, { 0, 0 }, 14, 0 },
+      { { 49, 34 }, { 30, 0 }, { 242, 241 }, { 239, 104 }, { 0, 0 }, 14, 0 },
+      { { 49, 34 }, { 30, 0 }, { 242, 245 }, { 239, 120 }, { 0, 0 }, 14, 0 },
+      { { 49, 34 }, { 30, 0 }, { 242, 245 }, { 239, 120 }, { 0, 0 }, 14, 0 },
+      { { 17, 49 }, { 5, 9 }, { 249, 241 }, { 37, 52 }, { 0, 0 }, 10, 0 },
+      { { 17, 49 }, { 5, 0 }, { 249, 241 }, { 37, 52 }, { 0, 0 }, 10, 0 },
+      { { 49, 114 }, { 138, 0 }, { 213, 97 }, { 25, 27 }, { 0, 0 }, 12, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 17, 17 }, { 150, 128 }, { 165, 245 }, { 85, 179 }, { 2, 1 }, 12, 0 },
+      { { 1, 17 }, { 156, 128 }, { 128, 240 }, { 5, 6 }, { 0, 0 }, 0, 0 },
+      { { 17, 17 }, { 150, 128 }, { 165, 245 }, { 85, 179 }, { 2, 1 }, 12, 0 },
+      { { 2, 1 }, { 153, 128 }, { 245, 246 }, { 85, 83 }, { 0, 0 }, 0, 0 },
+      { { 192, 0 }, { 13, 0 }, { 165, 212 }, { 67, 35 }, { 2, 1 }, 0, 0 },
+      { { 33, 32 }, { 88, 0 }, { 194, 97 }, { 227, 22 }, { 1, 3 }, 0, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 34 }, { 22, 0 }, { 176, 179 }, { 129, 44 }, { 0, 1 }, 12, 0 },
+      { { 49, 114 }, { 91, 131 }, { 244, 138 }, { 21, 5 }, { 0, 0 }, 0, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 33 }, { 29, 0 }, { 113, 129 }, { 174, 158 }, { 0, 0 }, 14, 0 },
+      { { 49, 97 }, { 28, 128 }, { 65, 146 }, { 11, 59 }, { 0, 0 }, 14, 0 },
+      { { 49, 241 }, { 28, 0 }, { 65, 146 }, { 11, 27 }, { 0, 0 }, 10, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 33 }, { 155, 0 }, { 97, 127 }, { 106, 10 }, { 0, 0 }, 2, 0 },
+      { { 225, 226 }, { 21, 3 }, { 113, 129 }, { 174, 158 }, { 0, 0 }, 14, 0 },
+      { { 33, 33 }, { 29, 0 }, { 113, 129 }, { 174, 158 }, { 0, 0 }, 14, 0 },
+      { { 33, 33 }, { 77, 0 }, { 84, 166 }, { 60, 28 }, { 0, 0 }, 8, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 50 }, { 79, 0 }, { 113, 82 }, { 83, 76 }, { 0, 0 }, 10, 0 },
+      { { 33, 50 }, { 79, 0 }, { 113, 82 }, { 83, 76 }, { 0, 0 }, 10, 0 },
+      { { 32, 49 }, { 78, 0 }, { 113, 82 }, { 104, 94 }, { 0, 0 }, 10, 0 },
+      { { 33, 33 }, { 75, 0 }, { 170, 143 }, { 22, 10 }, { 1, 0 }, 8, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 50, 97 }, { 154, 130 }, { 81, 162 }, { 27, 59 }, { 0, 0 }, 12, 0 },
+      { { 50, 33 }, { 192, 0 }, { 155, 114 }, { 33, 7 }, { 0, 0 }, 4, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 162 }, { 131, 141 }, { 116, 101 }, { 23, 23 }, { 0, 0 }, 7, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 225, 98 }, { 236, 0 }, { 110, 101 }, { 143, 42 }, { 0, 0 }, 14, 0 },
+      { { 50, 33 }, { 144, 0 }, { 155, 114 }, { 33, 23 }, { 0, 0 }, 4, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 245, 242 }, { 154, 128 }, { 12, 96 }, { 199, 165 }, { 0, 0 }, 13, 0 },
+      { { 98, 161 }, { 147, 0 }, { 119, 118 }, { 7, 7 }, { 0, 0 }, 11, 0 },
+      { { 34, 33 }, { 89, 8 }, { 255, 255 }, { 3, 15 }, { 2, 0 }, 0, 0 },
+      { { 33, 33 }, { 29, 0 }, { 113, 129 }, { 14, 14 }, { 0, 0 }, 14, 0 },
+      { { 34, 33 }, { 70, 128 }, { 134, 100 }, { 85, 24 }, { 0, 0 }, 0, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 113, 114 }, { 93, 0 }, { 84, 106 }, { 1, 3 }, { 0, 0 }, 0, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 0, 17 }, { 13, 128 }, { 241, 80 }, { 255, 255 }, { 0, 0 }, 6, 0 },
+      { { 33, 97 }, { 137, 3 }, { 17, 66 }, { 51, 37 }, { 0, 0 }, 10, 0 },
+      { { 0, 49 }, { 16, 128 }, { 17, 176 }, { 239, 15 }, { 0, 0 }, 10, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 164, 97 }, { 76, 16 }, { 243, 129 }, { 115, 35 }, { 1, 0 }, 4, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 1, 1 }, { 0, 0 }, { 255, 255 }, { 7, 7 }, { 0, 0 }, 7, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 1, 221 }, { 0, 0 }, { 246, 31 }, { 0, 6 }, { 2, 3 }, 12, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 36 },
+      { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 36 },
+      { { 3, 15 }, { 0, 0 }, { 251, 245 }, { 43, 11 }, { 2, 0 }, 15, 36 },
+      { { 33, 0 }, { 128, 0 }, { 255, 249 }, { 7, 7 }, { 0, 1 }, 14, 36 },
+      { { 240, 229 }, { 192, 0 }, { 255, 251 }, { 255, 240 }, { 3, 0 }, 14, 48 },
+      { { 33, 0 }, { 128, 0 }, { 255, 248 }, { 10, 25 }, { 0, 1 }, 14, 36 },
+      { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 48 },
+      { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 69 },
+      { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 52 },
+      { { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 48 },
+      { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 55 },
+      { { 2, 5 }, { 3, 10 }, { 180, 151 }, { 4, 247 }, { 0, 0 }, 14, 57 },
+      { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 58 },
+      { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 60 },
+      { { 1, 221 }, { 12, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 12, 62 },
+      { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 63 },
+      { { 12, 18 }, { 0, 0 }, { 246, 203 }, { 2, 67 }, { 0, 2 }, 10, 70 },
+      { { 12, 18 }, { 0, 0 }, { 246, 203 }, { 2, 19 }, { 0, 2 }, 10, 70 },
+      { { 14, 7 }, { 6, 68 }, { 248, 244 }, { 66, 228 }, { 3, 3 }, 14, 53 },
+      { { 14, 0 }, { 64, 8 }, { 150, 183 }, { 79, 24 }, { 0, 2 }, 14, 48 },
+      { { 1, 221 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 2, 3 }, 12, 84 },
+      { { 2, 9 }, { 27, 0 }, { 245, 246 }, { 118, 214 }, { 2, 0 }, 4, 43 },
+      { { 0, 223 }, { 9, 0 }, { 246, 147 }, { 0, 67 }, { 0, 2 }, 14, 56 },
+      { { 128, 144 }, { 13, 0 }, { 248, 159 }, { 0, 4 }, { 2, 3 }, 14, 24 },
+      { { 12, 18 }, { 0, 0 }, { 246, 203 }, { 2, 67 }, { 0, 2 }, 10, 65 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 48 },
+      { { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 51 },
+      { { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 54 },
+      { { 2, 4 }, { 0, 0 }, { 250, 200 }, { 191, 151 }, { 0, 0 }, 11, 42 },
+      { { 2, 4 }, { 0, 0 }, { 250, 200 }, { 191, 151 }, { 0, 0 }, 11, 39 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 64 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 128, 17 }, { 0, 0 }, { 255, 111 }, { 6, 22 }, { 3, 0 }, 14, 52 },
+      { { 128, 17 }, { 0, 0 }, { 255, 79 }, { 6, 22 }, { 3, 0 }, 14, 52 },
+      { { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 60 },
+      { { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 66 },
+      { { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 59 },
+      { { 65, 66 }, { 69, 0 }, { 252, 105 }, { 69, 5 }, { 0, 0 }, 0, 91 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 23, 2 }, { 79, 16 }, { 242, 242 }, { 96, 114 }, { 0, 0 }, 8, 109 },
+      { { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 64 },
+      { { 133, 132 }, { 5, 64 }, { 249, 214 }, { 50, 165 }, { 3, 0 }, 14, 79 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
+      { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 }
+   };

Added: tags/rott-1.1/rott/audiolib/linklist.h
===================================================================
--- tags/rott-1.1/rott/audiolib/linklist.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/linklist.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,118 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef __linklist_h
+#define __linklist_h
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NewNode(type)  ((type*)SafeMalloc(sizeof(type)))
+
+
+#define LL_CreateNewLinkedList(rootnode,type,next,prev) 			\
+   { 																				\
+   (rootnode) = NewNode(type);                            		\
+   (rootnode)->prev = (rootnode);                         		\
+   (rootnode)->next = (rootnode);                         		\
+   }
+
+
+
+#define LL_AddNode(rootnode, newnode, next, prev) 			\
+   {                                              			\
+   (newnode)->next = (rootnode);                  			\
+   (newnode)->prev = (rootnode)->prev;                	\
+   (rootnode)->prev->next = (newnode);                	\
+   (rootnode)->prev = (newnode);                      	\
+   }
+
+#define LL_TransferList(oldroot,newroot,next,prev)  \
+   {                                                \
+   if ((oldroot)->prev != (oldroot))                    \
+      {                                             \
+      (oldroot)->prev->next = (newroot);                \
+      (oldroot)->next->prev = (newroot)->prev;          \
+      (newroot)->prev->next = (oldroot)->next;          \
+      (newroot)->prev = (oldroot)->prev;                \
+      (oldroot)->next = (oldroot);                      \
+      (oldroot)->prev = (oldroot);                      \
+      }                                             \
+   }
+
+#define LL_ReverseList(root,type,next,prev)              \
+   {                                                     \
+   type *newend,*trav,*tprev;                            \
+                                                         \
+   newend = (root)->next;                                  \
+   for(trav = (root)->prev; trav != newend; trav = tprev)  \
+      {                                                  \
+      tprev = trav->prev;                                \
+      LL_MoveNode(trav,newend,next,prev);                \
+      }                                                  \
+   }
+
+
+#define LL_RemoveNode(node,next,prev) \
+   {                                  \
+   (node)->prev->next = (node)->next;     \
+   (node)->next->prev = (node)->prev;     \
+   (node)->next = (node);                 \
+   (node)->prev = (node);                 \
+   }
+
+
+#define LL_SortedInsertion(rootnode,insertnode,next,prev,type,sortparm) \
+   {                                                                    \
+   type *hoya;                                                          \
+                                                                        \
+   hoya = (rootnode)->next;                                               \
+   while((hoya != (rootnode)) && ((insertnode)->sortparm > hoya->sortparm)) \
+      {                                                                 \
+      hoya = hoya->next;                                                \
+      }                                                                 \
+   LL_AddNode(hoya,(insertnode),next,prev);                               \
+   }
+
+#define LL_MoveNode(node,newroot,next,prev) \
+   {                                        \
+   LL_RemoveNode((node),next,prev);           \
+   LL_AddNode((newroot),(node),next,prev);      \
+   }
+
+#define LL_ListEmpty(list,next,prev) \
+   (                                 \
+   ((list)->next == (list)) &&       \
+   ((list)->prev == (list))          \
+   )
+
+#define LL_Free(list)   SafeFree(list)
+#define LL_Reset(list,next,prev)    (list)->next = (list)->prev = (list)
+#define LL_New      LL_CreateNewLinkedList
+#define LL_Remove   LL_RemoveNode
+#define LL_Add      LL_AddNode
+#define LL_Empty    LL_ListEmpty
+#define LL_Move     LL_MoveNode
+
+
+#ifdef __cplusplus
+};
+#endif
+#endif

Added: tags/rott-1.1/rott/audiolib/ll_man.c
===================================================================
--- tags/rott-1.1/rott/audiolib/ll_man.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/ll_man.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,173 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: LL_MAN.C
+
+   author: James R. Dose
+   date:   January 1, 1994
+
+   Linked list management routines.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#define LOCKMEMORY
+
+#include <stddef.h>
+#include "ll_man.h"
+
+#ifdef LOCKMEMORY
+#include "dpmi.h"
+#endif
+
+#define OFFSET( structure, offset ) \
+   ( *( ( char ** )&( structure )[ offset ] ) )
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define LL_LockStart LL_AddNode
+
+
+void LL_AddNode
+   (
+   char *item,
+   char **head,
+   char **tail,
+   int next,
+   int prev
+   )
+
+   {
+   OFFSET( item, prev ) = NULL;
+   OFFSET( item, next ) = *head;
+
+   if ( *head )
+      {
+      OFFSET( *head, prev ) = item;
+      }
+   else
+      {
+      *tail = item;
+      }
+
+   *head = item;
+   }
+
+void LL_RemoveNode
+   (
+   char *item,
+   char **head,
+   char **tail,
+   int next,
+   int prev
+   )
+
+   {
+   if ( OFFSET( item, prev ) == NULL )
+      {
+      *head = OFFSET( item, next );
+      }
+   else
+      {
+      OFFSET( OFFSET( item, prev ), next ) = OFFSET( item, next );
+      }
+
+   if ( OFFSET( item, next ) == NULL )
+      {
+      *tail = OFFSET( item, prev );
+      }
+   else
+      {
+      OFFSET( OFFSET( item, next ), prev ) = OFFSET( item, prev );
+      }
+
+   OFFSET( item, next ) = NULL;
+   OFFSET( item, prev ) = NULL;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: LL_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void LL_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: LL_UnlockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+void LL_UnlockMemory
+   (
+   void
+   )
+
+   {
+#ifdef LOCKMEMORY
+
+   DPMI_UnlockMemoryRegion( LL_LockStart, LL_LockEnd );
+
+#endif
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: LL_LockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+int LL_LockMemory
+   (
+   void
+   )
+
+   {
+
+#ifdef LOCKMEMORY
+
+   int status;
+
+   status = DPMI_LockMemoryRegion( LL_LockStart, LL_LockEnd );
+   if ( status != DPMI_Ok )
+      {
+      return( LL_Error );
+      }
+
+#endif
+
+   return( LL_Ok );
+   }

Added: tags/rott-1.1/rott/audiolib/ll_man.h
===================================================================
--- tags/rott-1.1/rott/audiolib/ll_man.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/ll_man.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,76 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: LL_MAN.H
+
+   author: James R. Dose
+   date:   February 4, 1994
+
+   Public header for LL_MAN.C.  Linked list management routines.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __LL_MAN_H
+#define __LL_MAN_H
+
+enum LL_Errors
+   {
+   LL_Warning = -2,
+   LL_Error   = -1,
+   LL_Ok      = 0
+   };
+
+typedef struct list
+   {
+   void *start;
+   void *end;
+   } list;
+
+void LL_AddNode( char *node, char **head, char **tail, int next, int prev );
+void LL_RemoveNode( char *node, char **head, char **tail, int next, int prev );
+void LL_UnlockMemory( void );
+int  LL_LockMemory( void );
+
+#define LL_AddToHead( type, listhead, node )         \
+    LL_AddNode( ( char * )( node ),                  \
+                ( char ** )&( ( listhead )->start ), \
+                ( char ** )&( ( listhead )->end ),   \
+                ( int )&( ( type * ) 0 )->next,      \
+                ( int )&( ( type * ) 0 )->prev )
+
+#define LL_AddToTail( type, listhead, node )         \
+    LL_AddNode( ( char * )( node ),                  \
+                ( char ** )&( ( listhead )->end ),   \
+                ( char ** )&( ( listhead )->start ), \
+                ( int )&( ( type * ) 0 )->prev,      \
+                ( int )&( ( type * ) 0 )->next )
+
+#define LL_Remove( type, listhead, node )               \
+    LL_RemoveNode( ( char * )( node ),                  \
+                   ( char ** )&( ( listhead )->start ), \
+                   ( char ** )&( ( listhead )->end ),   \
+                   ( int )&( ( type * ) 0 )->next,      \
+                   ( int )&( ( type * ) 0 )->prev )
+
+#define LL_NextNode( node )     ( ( node )->next )
+#define LL_PreviousNode( node ) ( ( node )->prev )
+
+#endif

Added: tags/rott-1.1/rott/audiolib/midi.c
===================================================================
--- tags/rott-1.1/rott/audiolib/midi.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/midi.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,2265 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: MIDI.C
+
+   author: James R. Dose
+   date:   May 25, 1994
+
+   Midi song file playback routines.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <stdlib.h>
+#include <time.h>
+#include <dos.h>
+#include <string.h>
+#include "sndcards.h"
+#include "interrup.h"
+#include "dpmi.h"
+#include "standard.h"
+#include "task_man.h"
+#include "ll_man.h"
+#include "usrhooks.h"
+#include "music.h"
+#include "_midi.h"
+#include "midi.h"
+#include "debugio.h"
+
+extern int MUSIC_SoundDevice;
+
+static const int _MIDI_CommandLengths[ NUM_MIDI_CHANNELS ] =
+   {
+   0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 2, 0
+   };
+
+static int cdecl ( *_MIDI_RerouteFunctions[ NUM_MIDI_CHANNELS ] )
+   (
+   int event,
+   int c1,
+   int c2
+   ) = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+         NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+
+static track *_MIDI_TrackPtr = NULL;
+static int    _MIDI_TrackMemSize;
+static int    _MIDI_NumTracks;
+
+static int _MIDI_SongActive = FALSE;
+static int _MIDI_SongLoaded = FALSE;
+static int _MIDI_Loop = FALSE;
+
+static task *_MIDI_PlayRoutine = NULL;
+
+static int  _MIDI_Division;
+static int  _MIDI_Tick    = 0;
+static int  _MIDI_Beat    = 1;
+static int  _MIDI_Measure = 1;
+static unsigned _MIDI_Time;
+static int  _MIDI_BeatsPerMeasure;
+static int  _MIDI_TicksPerBeat;
+static int  _MIDI_TimeBase;
+static long _MIDI_FPSecondsPerTick;
+static unsigned _MIDI_TotalTime;
+static int  _MIDI_TotalTicks;
+static int  _MIDI_TotalBeats;
+static int  _MIDI_TotalMeasures;
+
+static unsigned long _MIDI_PositionInTicks;
+
+static int  _MIDI_Context;
+
+static int _MIDI_ActiveTracks;
+static int _MIDI_TotalVolume = MIDI_MaxVolume;
+
+static int _MIDI_ChannelVolume[ NUM_MIDI_CHANNELS ];
+static int _MIDI_UserChannelVolume[ NUM_MIDI_CHANNELS ] =
+   {
+   256, 256, 256, 256, 256, 256, 256, 256,
+   256, 256, 256, 256, 256, 256, 256, 256
+   };
+
+static midifuncs *_MIDI_Funcs = NULL;
+
+static int Reset = FALSE;
+
+int MIDI_Tempo = 120;
+
+char MIDI_PatchMap[ 128 ];
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define MIDI_LockStart _MIDI_ReadNumber
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_ReadNumber
+
+   Reads a variable length number from a MIDI track.
+---------------------------------------------------------------------*/
+
+static long _MIDI_ReadNumber
+   (
+   void *from,
+   size_t size
+   )
+
+   {
+   unsigned char *FromPtr;
+   long          value;
+
+   if ( size > 4 )
+      {
+      size = 4;
+      }
+
+   FromPtr = ( unsigned char * )from;
+
+   value = 0;
+   while( size-- )
+      {
+      value <<= 8;
+      value += *FromPtr++;
+      }
+
+   return( value );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_ReadDelta
+
+   Reads a variable length encoded delta delay time from the MIDI data.
+---------------------------------------------------------------------*/
+
+static long _MIDI_ReadDelta
+   (
+   track *ptr
+   )
+
+   {
+   long          value;
+   unsigned char c;
+
+   GET_NEXT_EVENT( ptr, value );
+
+   if ( value & 0x80 )
+      {
+      value &= 0x7f;
+      do
+         {
+         GET_NEXT_EVENT( ptr, c );
+         value = ( value << 7 ) + ( c & 0x7f );
+         }
+      while ( c & 0x80 );
+      }
+
+   return( value );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_ResetTracks
+
+   Sets the track pointers to the beginning of the song.
+---------------------------------------------------------------------*/
+
+static void _MIDI_ResetTracks
+   (
+   void
+   )
+
+   {
+   int    i;
+   track *ptr;
+
+   _MIDI_Tick = 0;
+   _MIDI_Beat = 1;
+   _MIDI_Measure = 1;
+   _MIDI_Time = 0;
+   _MIDI_BeatsPerMeasure = 4;
+   _MIDI_TicksPerBeat = _MIDI_Division;
+   _MIDI_TimeBase = 4;
+
+   _MIDI_PositionInTicks = 0;
+   _MIDI_ActiveTracks    = 0;
+   _MIDI_Context         = 0;
+
+   ptr = _MIDI_TrackPtr;
+   for( i = 0; i < _MIDI_NumTracks; i++ )
+      {
+      ptr->pos                    = ptr->start;
+      ptr->delay                  = _MIDI_ReadDelta( ptr );
+      ptr->active                 = ptr->EMIDI_IncludeTrack;
+      ptr->RunningStatus          = 0;
+      ptr->currentcontext         = 0;
+      ptr->context[ 0 ].loopstart = ptr->start;
+      ptr->context[ 0 ].loopcount = 0;
+
+      if ( ptr->active )
+         {
+         _MIDI_ActiveTracks++;
+         }
+
+      ptr++;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_AdvanceTick
+
+   Increment tick counters.
+---------------------------------------------------------------------*/
+
+static void _MIDI_AdvanceTick
+   (
+   void
+   )
+
+   {
+   _MIDI_PositionInTicks++;
+   _MIDI_Time += _MIDI_FPSecondsPerTick;
+
+   _MIDI_Tick++;
+   while( _MIDI_Tick > _MIDI_TicksPerBeat )
+      {
+      _MIDI_Tick -= _MIDI_TicksPerBeat;
+      _MIDI_Beat++;
+      }
+   while( _MIDI_Beat > _MIDI_BeatsPerMeasure )
+      {
+      _MIDI_Beat -= _MIDI_BeatsPerMeasure;
+      _MIDI_Measure++;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_SysEx
+
+   Interpret SysEx Event.
+---------------------------------------------------------------------*/
+
+static void _MIDI_SysEx
+   (
+   track *Track
+   )
+
+   {
+   int length;
+
+   length = _MIDI_ReadDelta( Track );
+   Track->pos += length;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_MetaEvent
+
+   Interpret Meta Event.
+---------------------------------------------------------------------*/
+
+static void _MIDI_MetaEvent
+   (
+   track *Track
+   )
+
+   {
+   int   command;
+   int   length;
+   int   denominator;
+   long  tempo;
+
+   GET_NEXT_EVENT( Track, command );
+   GET_NEXT_EVENT( Track, length );
+
+   switch( command )
+      {
+      case MIDI_END_OF_TRACK :
+         Track->active = FALSE;
+
+         _MIDI_ActiveTracks--;
+         break;
+
+      case MIDI_TEMPO_CHANGE :
+         tempo = 60000000L / _MIDI_ReadNumber( Track->pos, 3 );
+         MIDI_SetTempo( tempo );
+         break;
+
+      case MIDI_TIME_SIGNATURE :
+         if ( ( _MIDI_Tick > 0 ) || ( _MIDI_Beat > 1 ) )
+            {
+            _MIDI_Measure++;
+            }
+
+         _MIDI_Tick = 0;
+         _MIDI_Beat = 1;
+
+         _MIDI_BeatsPerMeasure = (int)*Track->pos;
+         denominator = (int)*( Track->pos + 1 );
+         _MIDI_TimeBase = 1;
+         while( denominator > 0 )
+            {
+            _MIDI_TimeBase += _MIDI_TimeBase;
+            denominator--;
+            }
+         _MIDI_TicksPerBeat = ( _MIDI_Division * 4 ) / _MIDI_TimeBase;
+         break;
+      }
+
+   Track->pos += length;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_InterpretControllerInfo
+
+   Interprets the MIDI controller info.
+---------------------------------------------------------------------*/
+
+static int _MIDI_InterpretControllerInfo
+   (
+   track *Track,
+   int   TimeSet,
+   int   channel,
+   int   c1,
+   int   c2
+   )
+
+   {
+   track *trackptr;
+   int tracknum;
+   int loopcount;
+
+   switch( c1 )
+      {
+      case MIDI_MONO_MODE_ON :
+         Track->pos++;
+         break;
+
+      case MIDI_VOLUME :
+         if ( !Track->EMIDI_VolumeChange )
+            {
+            _MIDI_SetChannelVolume( channel, c2 );
+            }
+         break;
+
+      case EMIDI_INCLUDE_TRACK :
+      case EMIDI_EXCLUDE_TRACK :
+         break;
+
+      case EMIDI_PROGRAM_CHANGE :
+         if ( Track->EMIDI_ProgramChange )
+            {
+            _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] );
+            }
+         break;
+
+      case EMIDI_VOLUME_CHANGE :
+         if ( Track->EMIDI_VolumeChange )
+            {
+            _MIDI_SetChannelVolume( channel, c2 );
+            }
+         break;
+
+      case EMIDI_CONTEXT_START :
+         break;
+
+      case EMIDI_CONTEXT_END :
+         if ( ( Track->currentcontext == _MIDI_Context ) ||
+            ( _MIDI_Context < 0 ) ||
+            ( Track->context[ _MIDI_Context ].pos == NULL ) )
+            {
+            break;
+            }
+
+         Track->currentcontext = _MIDI_Context;
+         Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart;
+         Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount;
+         Track->pos           = Track->context[ _MIDI_Context ].pos;
+         Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus;
+
+         if ( TimeSet )
+            {
+            break;
+            }
+
+         _MIDI_Time             = Track->context[ _MIDI_Context ].time;
+         _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick;
+         _MIDI_Tick             = Track->context[ _MIDI_Context ].tick;
+         _MIDI_Beat             = Track->context[ _MIDI_Context ].beat;
+         _MIDI_Measure          = Track->context[ _MIDI_Context ].measure;
+         _MIDI_BeatsPerMeasure  = Track->context[ _MIDI_Context ].BeatsPerMeasure;
+         _MIDI_TicksPerBeat     = Track->context[ _MIDI_Context ].TicksPerBeat;
+         _MIDI_TimeBase         = Track->context[ _MIDI_Context ].TimeBase;
+         TimeSet = TRUE;
+         break;
+
+      case EMIDI_LOOP_START :
+      case EMIDI_SONG_LOOP_START :
+         if ( c2 == 0 )
+            {
+            loopcount = EMIDI_INFINITE;
+            }
+         else
+            {
+            loopcount = c2;
+            }
+
+         if ( c1 == EMIDI_SONG_LOOP_START )
+            {
+            trackptr = _MIDI_TrackPtr;
+            tracknum = _MIDI_NumTracks;
+            }
+         else
+            {
+            trackptr = Track;
+            tracknum = 1;
+            }
+
+         while( tracknum > 0 )
+            {
+            trackptr->context[ 0 ].loopcount        = loopcount;
+            trackptr->context[ 0 ].pos              = trackptr->pos;
+            trackptr->context[ 0 ].loopstart        = trackptr->pos;
+            trackptr->context[ 0 ].RunningStatus    = trackptr->RunningStatus;
+            trackptr->context[ 0 ].active           = trackptr->active;
+            trackptr->context[ 0 ].delay            = trackptr->delay;
+            trackptr->context[ 0 ].time             = _MIDI_Time;
+            trackptr->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
+            trackptr->context[ 0 ].tick             = _MIDI_Tick;
+            trackptr->context[ 0 ].beat             = _MIDI_Beat;
+            trackptr->context[ 0 ].measure          = _MIDI_Measure;
+            trackptr->context[ 0 ].BeatsPerMeasure  = _MIDI_BeatsPerMeasure;
+            trackptr->context[ 0 ].TicksPerBeat     = _MIDI_TicksPerBeat;
+            trackptr->context[ 0 ].TimeBase         = _MIDI_TimeBase;
+            trackptr++;
+            tracknum--;
+            }
+         break;
+
+      case EMIDI_LOOP_END :
+      case EMIDI_SONG_LOOP_END :
+         if ( ( c2 != EMIDI_END_LOOP_VALUE ) ||
+            ( Track->context[ 0 ].loopstart == NULL ) ||
+            ( Track->context[ 0 ].loopcount == 0 ) )
+            {
+            break;
+            }
+
+         if ( c1 == EMIDI_SONG_LOOP_END )
+            {
+            trackptr = _MIDI_TrackPtr;
+            tracknum = _MIDI_NumTracks;
+            _MIDI_ActiveTracks = 0;
+            }
+         else
+            {
+            trackptr = Track;
+            tracknum = 1;
+            _MIDI_ActiveTracks--;
+            }
+
+         while( tracknum > 0 )
+            {
+            if ( trackptr->context[ 0 ].loopcount != EMIDI_INFINITE )
+               {
+               trackptr->context[ 0 ].loopcount--;
+               }
+
+            trackptr->pos           = trackptr->context[ 0 ].loopstart;
+            trackptr->RunningStatus = trackptr->context[ 0 ].RunningStatus;
+            trackptr->delay         = trackptr->context[ 0 ].delay;
+            trackptr->active        = trackptr->context[ 0 ].active;
+            if ( trackptr->active )
+               {
+               _MIDI_ActiveTracks++;
+               }
+
+            if ( !TimeSet )
+               {
+               _MIDI_Time             = trackptr->context[ 0 ].time;
+               _MIDI_FPSecondsPerTick = trackptr->context[ 0 ].FPSecondsPerTick;
+               _MIDI_Tick             = trackptr->context[ 0 ].tick;
+               _MIDI_Beat             = trackptr->context[ 0 ].beat;
+               _MIDI_Measure          = trackptr->context[ 0 ].measure;
+               _MIDI_BeatsPerMeasure  = trackptr->context[ 0 ].BeatsPerMeasure;
+               _MIDI_TicksPerBeat     = trackptr->context[ 0 ].TicksPerBeat;
+               _MIDI_TimeBase         = trackptr->context[ 0 ].TimeBase;
+               TimeSet = TRUE;
+               }
+
+            trackptr++;
+            tracknum--;
+            }
+         break;
+
+      default :
+         if ( _MIDI_Funcs->ControlChange )
+            {
+            _MIDI_Funcs->ControlChange( channel, c1, c2 );
+            }
+      }
+
+   return TimeSet;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_ServiceRoutine
+
+   Task that interperates the MIDI data.
+---------------------------------------------------------------------*/
+// NOTE: We have to use a stack frame here because of a strange bug
+// that occurs with Watcom.  This means that we cannot access Task!
+//Turned off to test if it works with Watcom 10a
+//#pragma aux _MIDI_ServiceRoutine frame;
+/*
+static void test
+   (
+   task *Task
+   )
+   {
+   _MIDI_ServiceRoutine( Task );
+   _MIDI_ServiceRoutine( Task );
+   _MIDI_ServiceRoutine( Task );
+   _MIDI_ServiceRoutine( Task );
+   }
+*/
+static void _MIDI_ServiceRoutine
+   (
+   task *Task
+   )
+
+   {
+   int   event;
+   int   channel;
+   int   command;
+   track *Track;
+   int   tracknum;
+   int   status;
+   int   c1;
+   int   c2;
+   int   TimeSet = FALSE;
+
+   if ( !_MIDI_SongActive )
+      {
+      return;
+      }
+
+   Track = _MIDI_TrackPtr;
+   tracknum = 0;
+   while( tracknum < _MIDI_NumTracks )
+      {
+      while ( ( Track->active ) && ( Track->delay == 0 ) )
+         {
+         GET_NEXT_EVENT( Track, event );
+
+         if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL )
+            {
+            switch( event )
+               {
+               case MIDI_SYSEX :
+               case MIDI_SYSEX_CONTINUE :
+                  _MIDI_SysEx( Track );
+                  break;
+
+               case MIDI_META_EVENT :
+                  _MIDI_MetaEvent( Track );
+                  break;
+               }
+
+            if ( Track->active )
+               {
+               Track->delay = _MIDI_ReadDelta( Track );
+               }
+
+            continue;
+            }
+
+         if ( event & MIDI_RUNNING_STATUS )
+            {
+            Track->RunningStatus = event;
+            }
+         else
+            {
+            event = Track->RunningStatus;
+            Track->pos--;
+            }
+
+         channel = GET_MIDI_CHANNEL( event );
+         command = GET_MIDI_COMMAND( event );
+
+         if ( _MIDI_CommandLengths[ command ] > 0 )
+            {
+            GET_NEXT_EVENT( Track, c1 );
+            if ( _MIDI_CommandLengths[ command ] > 1 )
+               {
+               GET_NEXT_EVENT( Track, c2 );
+               }
+            }
+
+         if ( _MIDI_RerouteFunctions[ channel ] != NULL )
+            {
+            status = _MIDI_RerouteFunctions[ channel ]( event, c1, c2 );
+
+            if ( status == MIDI_DONT_PLAY )
+               {
+               Track->delay = _MIDI_ReadDelta( Track );
+               continue;
+               }
+            }
+
+         switch ( command )
+            {
+            case MIDI_NOTE_OFF :
+               if ( _MIDI_Funcs->NoteOff )
+                  {
+                  _MIDI_Funcs->NoteOff( channel, c1, c2 );
+                  }
+               break;
+
+            case MIDI_NOTE_ON :
+               if ( _MIDI_Funcs->NoteOn )
+                  {
+                  _MIDI_Funcs->NoteOn( channel, c1, c2 );
+                  }
+               break;
+
+            case MIDI_POLY_AFTER_TCH :
+               if ( _MIDI_Funcs->PolyAftertouch )
+                  {
+                  _MIDI_Funcs->PolyAftertouch( channel, c1, c2 );
+                  }
+               break;
+
+            case MIDI_CONTROL_CHANGE :
+               TimeSet = _MIDI_InterpretControllerInfo( Track, TimeSet,
+                  channel, c1, c2 );
+               break;
+
+            case MIDI_PROGRAM_CHANGE :
+               if ( ( _MIDI_Funcs->ProgramChange ) &&
+                  ( !Track->EMIDI_ProgramChange ) )
+                  {
+                  _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c1 & 0x7f ] );
+                  }
+               break;
+
+            case MIDI_AFTER_TOUCH :
+               if ( _MIDI_Funcs->ChannelAftertouch )
+                  {
+                  _MIDI_Funcs->ChannelAftertouch( channel, c1 );
+                  }
+               break;
+
+            case MIDI_PITCH_BEND :
+               if ( _MIDI_Funcs->PitchBend )
+                  {
+                  _MIDI_Funcs->PitchBend( channel, c1, c2 );
+                  }
+               break;
+
+            default :
+               break;
+            }
+
+         Track->delay = _MIDI_ReadDelta( Track );
+         }
+
+      Track->delay--;
+      Track++;
+      tracknum++;
+
+      if ( _MIDI_ActiveTracks == 0 )
+         {
+         _MIDI_ResetTracks();
+         if ( _MIDI_Loop )
+            {
+            tracknum = 0;
+            Track = _MIDI_TrackPtr;
+            }
+         else
+            {
+            _MIDI_SongActive = FALSE;
+            break;
+            }
+         }
+      }
+
+   _MIDI_AdvanceTick();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_SendControlChange
+
+   Sends a control change to the proper device
+---------------------------------------------------------------------*/
+
+static int _MIDI_SendControlChange
+   (
+   int channel,
+   int c1,
+   int c2
+   )
+
+   {
+   int status;
+
+   if ( _MIDI_RerouteFunctions[ channel ] != NULL )
+      {
+      status = _MIDI_RerouteFunctions[ channel ]( 0xB0 + channel,
+         c1, c2 );
+      if ( status == MIDI_DONT_PLAY )
+         {
+         return( MIDI_Ok );
+         }
+      }
+
+   if ( _MIDI_Funcs == NULL )
+      {
+      return( MIDI_Error );
+      }
+
+   if ( _MIDI_Funcs->ControlChange == NULL )
+      {
+      return( MIDI_Error );
+      }
+
+   _MIDI_Funcs->ControlChange( channel, c1, c2 );
+
+   return( MIDI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_RerouteMidiChannel
+
+   Sets callback function to reroute MIDI commands from specified
+   function.
+---------------------------------------------------------------------*/
+
+void MIDI_RerouteMidiChannel
+   (
+   int channel,
+   int cdecl ( *function )( int event, int c1, int c2 )
+   )
+
+   {
+   if ( ( channel >= 1 ) && ( channel <= 16 ) )
+      {
+      _MIDI_RerouteFunctions[ channel - 1 ] = function;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_AllNotesOff
+
+   Sends all notes off commands on all midi channels.
+---------------------------------------------------------------------*/
+
+int MIDI_AllNotesOff
+   (
+   void
+   )
+
+   {
+   int channel;
+
+   for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ )
+      {
+      _MIDI_SendControlChange( channel, 0x40, 0 );
+      _MIDI_SendControlChange( channel, MIDI_ALL_NOTES_OFF, 0 );
+      _MIDI_SendControlChange( channel, 0x78, 0 );
+      }
+
+   return( MIDI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_SetChannelVolume
+
+   Sets the volume of the specified midi channel.
+---------------------------------------------------------------------*/
+
+static void _MIDI_SetChannelVolume
+   (
+   int channel,
+   int volume
+   )
+
+   {
+   int status;
+   int remotevolume;
+
+   _MIDI_ChannelVolume[ channel ] = volume;
+
+   if ( _MIDI_RerouteFunctions[ channel ] != NULL )
+      {
+      remotevolume = volume * _MIDI_TotalVolume;
+      remotevolume *= _MIDI_UserChannelVolume[ channel ];
+      remotevolume /= MIDI_MaxVolume;
+      remotevolume >>= 8;
+
+      status = _MIDI_RerouteFunctions[ channel ]( 0xB0 + channel,
+         MIDI_VOLUME, remotevolume );
+      if ( status == MIDI_DONT_PLAY )
+         {
+         return;
+         }
+      }
+
+   if ( _MIDI_Funcs == NULL )
+      {
+      return;
+      }
+
+   if ( _MIDI_Funcs->ControlChange == NULL )
+      {
+      return;
+      }
+
+   // For user volume
+   volume *= _MIDI_UserChannelVolume[ channel ];
+
+   if ( _MIDI_Funcs->SetVolume == NULL )
+      {
+      volume *= _MIDI_TotalVolume;
+      volume /= MIDI_MaxVolume;
+      }
+
+   // For user volume
+   volume >>= 8;
+
+   _MIDI_Funcs->ControlChange( channel, MIDI_VOLUME, volume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_SetUserChannelVolume
+
+   Sets the volume of the specified midi channel.
+---------------------------------------------------------------------*/
+
+void MIDI_SetUserChannelVolume
+   (
+   int channel,
+   int volume
+   )
+
+   {
+   // Convert channel from 1-16 to 0-15
+   channel--;
+
+   volume = max( 0, volume );
+   volume = min( volume, 256 );
+
+   if ( ( channel >= 0 ) && ( channel < NUM_MIDI_CHANNELS ) )
+      {
+      _MIDI_UserChannelVolume[ channel ] = volume;
+      _MIDI_SetChannelVolume( channel, _MIDI_ChannelVolume[ channel ] );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_ResetUserChannelVolume
+
+   Sets the volume of the specified midi channel.
+---------------------------------------------------------------------*/
+
+void MIDI_ResetUserChannelVolume
+   (
+   void
+   )
+
+   {
+   int channel;
+
+   for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ )
+      {
+      _MIDI_UserChannelVolume[ channel ] = 256;
+      }
+
+   _MIDI_SendChannelVolumes();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_SendChannelVolumes
+
+   Sets the volume on all the midi channels.
+---------------------------------------------------------------------*/
+
+static void _MIDI_SendChannelVolumes
+   (
+   void
+   )
+
+   {
+   int channel;
+
+   for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ )
+      {
+      _MIDI_SetChannelVolume( channel, _MIDI_ChannelVolume[ channel ] );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_Reset
+
+   Resets the MIDI device to General Midi defaults.
+---------------------------------------------------------------------*/
+
+int MIDI_Reset
+   (
+   void
+   )
+
+   {
+   int channel;
+   long time;
+   unsigned flags;
+
+   MIDI_AllNotesOff();
+
+   flags = DisableInterrupts();
+   _enable();
+   time = clock() + CLOCKS_PER_SEC/24;
+   while(clock() < time)
+      ;
+
+   RestoreInterrupts( flags );
+
+   for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ )
+      {
+      _MIDI_SendControlChange( channel, MIDI_RESET_ALL_CONTROLLERS, 0 );
+      _MIDI_SendControlChange( channel, MIDI_RPN_MSB, MIDI_PITCHBEND_MSB );
+      _MIDI_SendControlChange( channel, MIDI_RPN_LSB, MIDI_PITCHBEND_LSB );
+      _MIDI_SendControlChange( channel, MIDI_DATAENTRY_MSB, 2 ); /* Pitch Bend Sensitivity MSB */
+      _MIDI_SendControlChange( channel, MIDI_DATAENTRY_LSB, 0 ); /* Pitch Bend Sensitivity LSB */
+      _MIDI_ChannelVolume[ channel ] = GENMIDI_DefaultVolume;
+      }
+
+   _MIDI_SendChannelVolumes();
+
+   Reset = TRUE;
+
+   return( MIDI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_SetVolume
+
+   Sets the total volume of the music.
+---------------------------------------------------------------------*/
+
+int MIDI_SetVolume
+   (
+   int volume
+   )
+
+   {
+   int i;
+
+   if ( _MIDI_Funcs == NULL )
+      {
+      return( MIDI_NullMidiModule );
+      }
+
+   volume = min( MIDI_MaxVolume, volume );
+   volume = max( 0, volume );
+
+   _MIDI_TotalVolume = volume;
+
+   if ( _MIDI_Funcs->SetVolume )
+      {
+      _MIDI_Funcs->SetVolume( volume );
+
+      for( i = 0; i < NUM_MIDI_CHANNELS; i++ )
+         {
+         if ( _MIDI_RerouteFunctions[ i ] != NULL )
+            {
+            _MIDI_SetChannelVolume( i, _MIDI_ChannelVolume[ i ] );
+            }
+         }
+      }
+   else
+      {
+      _MIDI_SendChannelVolumes();
+      }
+
+   return( MIDI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_GetVolume
+
+   Returns the total volume of the music.
+---------------------------------------------------------------------*/
+
+int MIDI_GetVolume
+   (
+   void
+   )
+
+   {
+   int volume;
+
+   if ( _MIDI_Funcs == NULL )
+      {
+      return( MIDI_NullMidiModule );
+      }
+
+   if ( _MIDI_Funcs->GetVolume )
+      {
+      volume = _MIDI_Funcs->GetVolume();
+      }
+   else
+      {
+      volume = _MIDI_TotalVolume;
+      }
+
+   return( volume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_SetContext
+
+   Sets the song context.
+---------------------------------------------------------------------*/
+
+void MIDI_SetContext
+   (
+   int context
+   )
+
+   {
+   if ( ( context > 0 ) && ( context < EMIDI_NUM_CONTEXTS ) )
+      {
+      _MIDI_Context = context;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_GetContext
+
+   Returns the current song context.
+---------------------------------------------------------------------*/
+
+int MIDI_GetContext
+   (
+   void
+   )
+
+   {
+   return _MIDI_Context;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_SetLoopFlag
+
+   Sets whether the song should loop when finished or not.
+---------------------------------------------------------------------*/
+
+void MIDI_SetLoopFlag
+   (
+   int loopflag
+   )
+
+   {
+   _MIDI_Loop = loopflag;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_ContinueSong
+
+   Continues playback of a paused song.
+---------------------------------------------------------------------*/
+
+void MIDI_ContinueSong
+   (
+   void
+   )
+
+   {
+   if ( _MIDI_SongLoaded )
+      {
+      _MIDI_SongActive = TRUE;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_PauseSong
+
+   Pauses playback of the current song.
+---------------------------------------------------------------------*/
+
+void MIDI_PauseSong
+   (
+   void
+   )
+
+   {
+   if ( _MIDI_SongLoaded )
+      {
+      _MIDI_SongActive = FALSE;
+      MIDI_AllNotesOff();
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_SongPlaying
+
+   Returns whether a song is playing or not.
+---------------------------------------------------------------------*/
+
+int MIDI_SongPlaying
+   (
+   void
+   )
+
+   {
+   return( _MIDI_SongActive );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_SetMidiFuncs
+
+   Selects the routines that send the MIDI data to the music device.
+---------------------------------------------------------------------*/
+
+void MIDI_SetMidiFuncs
+   (
+   midifuncs *funcs
+   )
+
+   {
+   _MIDI_Funcs = funcs;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_StopSong
+
+   Stops playback of the currently playing song.
+---------------------------------------------------------------------*/
+
+void MIDI_StopSong
+   (
+   void
+   )
+
+   {
+   if ( _MIDI_SongLoaded )
+      {
+      TS_Terminate( _MIDI_PlayRoutine );
+
+      _MIDI_PlayRoutine = NULL;
+      _MIDI_SongActive = FALSE;
+      _MIDI_SongLoaded = FALSE;
+
+      MIDI_Reset();
+      _MIDI_ResetTracks();
+
+      if ( _MIDI_Funcs->ReleasePatches )
+         {
+         _MIDI_Funcs->ReleasePatches();
+         }
+
+      DPMI_UnlockMemory( _MIDI_TrackPtr, _MIDI_TrackMemSize );
+      USRHOOKS_FreeMem( _MIDI_TrackPtr );
+
+      _MIDI_TrackPtr     = NULL;
+      _MIDI_NumTracks    = 0;
+      _MIDI_TrackMemSize = 0;
+
+      _MIDI_TotalTime     = 0;
+      _MIDI_TotalTicks    = 0;
+      _MIDI_TotalBeats    = 0;
+      _MIDI_TotalMeasures = 0;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_PlaySong
+
+   Begins playback of a MIDI song.
+---------------------------------------------------------------------*/
+
+int MIDI_PlaySong
+   (
+   unsigned char *song,
+   int loopflag
+   )
+
+   {
+   int    numtracks;
+   int    format;
+   long   headersize;
+   long   tracklength;
+   track *CurrentTrack;
+   unsigned char *ptr;
+   int    status;
+
+   if ( _MIDI_SongLoaded )
+      {
+      MIDI_StopSong();
+      }
+
+   _MIDI_Loop = loopflag;
+
+   if ( _MIDI_Funcs == NULL )
+      {
+      return( MIDI_NullMidiModule );
+      }
+
+   if ( *( unsigned long * )song != MIDI_HEADER_SIGNATURE )
+      {
+      return( MIDI_InvalidMidiFile );
+      }
+
+   song += 4;
+
+   headersize      = _MIDI_ReadNumber( song, 4 );
+   song += 4;
+   format          = _MIDI_ReadNumber( song, 2 );
+   _MIDI_NumTracks = _MIDI_ReadNumber( song + 2, 2 );
+   _MIDI_Division  = _MIDI_ReadNumber( song + 4, 2 );
+   if ( _MIDI_Division < 0 )
+      {
+      // If a SMPTE time division is given, just set to 96 so no errors occur
+      _MIDI_Division = 96;
+      }
+
+   if ( format > MAX_FORMAT )
+      {
+      return( MIDI_UnknownMidiFormat );
+      }
+
+   ptr = song + headersize;
+
+   if ( _MIDI_NumTracks == 0 )
+      {
+      return( MIDI_NoTracks );
+      }
+
+   _MIDI_TrackMemSize = _MIDI_NumTracks  * sizeof( track );
+   status = USRHOOKS_GetMem( &_MIDI_TrackPtr, _MIDI_TrackMemSize );
+   if ( status != USRHOOKS_Ok )
+      {
+      return( MIDI_NoMemory );
+      }
+
+   status = DPMI_LockMemory( _MIDI_TrackPtr, _MIDI_TrackMemSize );
+   if ( status != DPMI_Ok )
+      {
+      USRHOOKS_FreeMem( _MIDI_TrackPtr );
+
+      _MIDI_TrackPtr     = NULL;
+      _MIDI_TrackMemSize = 0;
+      _MIDI_NumTracks    = 0;
+//      MIDI_SetErrorCode( MIDI_DPMI_Error );
+      return( MIDI_Error );
+      }
+
+   CurrentTrack = _MIDI_TrackPtr;
+   numtracks    = _MIDI_NumTracks;
+   while( numtracks-- )
+      {
+      if ( *( unsigned long * )ptr != MIDI_TRACK_SIGNATURE )
+         {
+         DPMI_UnlockMemory( _MIDI_TrackPtr, _MIDI_TrackMemSize );
+
+         USRHOOKS_FreeMem( _MIDI_TrackPtr );
+
+         _MIDI_TrackPtr = NULL;
+         _MIDI_TrackMemSize = 0;
+
+         return( MIDI_InvalidTrack );
+         }
+
+      tracklength = _MIDI_ReadNumber( ptr + 4, 4 );
+      ptr += 8;
+      CurrentTrack->start = ptr;
+      ptr += tracklength;
+      CurrentTrack++;
+      }
+
+   if ( _MIDI_Funcs->GetVolume != NULL )
+      {
+      _MIDI_TotalVolume = _MIDI_Funcs->GetVolume();
+      }
+
+   _MIDI_InitEMIDI();
+
+   if ( _MIDI_Funcs->LoadPatch )
+      {
+      MIDI_LoadTimbres();
+      }
+
+   _MIDI_ResetTracks();
+
+   if ( !Reset )
+      {
+      MIDI_Reset();
+      }
+
+   Reset = FALSE;
+
+   _MIDI_PlayRoutine = TS_ScheduleTask( _MIDI_ServiceRoutine, 100, 1, NULL );
+//   _MIDI_PlayRoutine = TS_ScheduleTask( test, 100, 1, NULL );
+   MIDI_SetTempo( 120 );
+   TS_Dispatch();
+
+   _MIDI_SongLoaded = TRUE;
+   _MIDI_SongActive = TRUE;
+
+   return( MIDI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_SetTempo
+
+   Sets the song tempo.
+---------------------------------------------------------------------*/
+
+void MIDI_SetTempo
+   (
+   int tempo
+   )
+
+   {
+   long tickspersecond;
+
+   MIDI_Tempo = tempo;
+   tickspersecond = ( tempo * _MIDI_Division ) / 60;
+   if ( _MIDI_PlayRoutine != NULL )
+      {
+      TS_SetTaskRate( _MIDI_PlayRoutine, tickspersecond );
+//      TS_SetTaskRate( _MIDI_PlayRoutine, tickspersecond / 4 );
+      }
+   _MIDI_FPSecondsPerTick = ( 1 << TIME_PRECISION ) / tickspersecond;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_GetTempo
+
+   Returns the song tempo.
+---------------------------------------------------------------------*/
+
+int MIDI_GetTempo
+   (
+   void
+   )
+
+   {
+   return( MIDI_Tempo );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: _MIDI_ProcessNextTick
+
+   Sets the position of the song pointer.
+---------------------------------------------------------------------*/
+
+static int _MIDI_ProcessNextTick
+   (
+   void
+   )
+
+   {
+   int   event;
+   int   channel;
+   int   command;
+   track *Track;
+   int   tracknum;
+   int   status;
+   int   c1;
+   int   c2;
+   int   TimeSet = FALSE;
+
+   Track = _MIDI_TrackPtr;
+   tracknum = 0;
+   while( ( tracknum < _MIDI_NumTracks ) && ( Track != NULL ) )
+      {
+      while ( ( Track->active ) && ( Track->delay == 0 ) )
+         {
+         GET_NEXT_EVENT( Track, event );
+
+         if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL )
+            {
+            switch( event )
+               {
+               case MIDI_SYSEX :
+               case MIDI_SYSEX_CONTINUE :
+                  _MIDI_SysEx( Track );
+                  break;
+
+               case MIDI_META_EVENT :
+                  _MIDI_MetaEvent( Track );
+                  break;
+               }
+
+            if ( Track->active )
+               {
+               Track->delay = _MIDI_ReadDelta( Track );
+               }
+
+            continue;
+            }
+
+         if ( event & MIDI_RUNNING_STATUS )
+            {
+            Track->RunningStatus = event;
+            }
+         else
+            {
+            event = Track->RunningStatus;
+            Track->pos--;
+            }
+
+         channel = GET_MIDI_CHANNEL( event );
+         command = GET_MIDI_COMMAND( event );
+
+         if ( _MIDI_CommandLengths[ command ] > 0 )
+            {
+            GET_NEXT_EVENT( Track, c1 );
+            if ( _MIDI_CommandLengths[ command ] > 1 )
+               {
+               GET_NEXT_EVENT( Track, c2 );
+               }
+            }
+
+         if ( _MIDI_RerouteFunctions[ channel ] != NULL )
+            {
+            status = _MIDI_RerouteFunctions[ channel ]( event, c1, c2 );
+
+            if ( status == MIDI_DONT_PLAY )
+               {
+               Track->delay = _MIDI_ReadDelta( Track );
+               continue;
+               }
+            }
+
+         switch ( command )
+            {
+            case MIDI_NOTE_OFF :
+               break;
+
+            case MIDI_NOTE_ON :
+               break;
+
+            case MIDI_POLY_AFTER_TCH :
+               if ( _MIDI_Funcs->PolyAftertouch )
+                  {
+                  _MIDI_Funcs->PolyAftertouch( channel, c1, c2 );
+                  }
+               break;
+
+            case MIDI_CONTROL_CHANGE :
+               TimeSet = _MIDI_InterpretControllerInfo( Track, TimeSet,
+                  channel, c1, c2 );
+               break;
+
+            case MIDI_PROGRAM_CHANGE :
+               if ( ( _MIDI_Funcs->ProgramChange ) &&
+                  ( !Track->EMIDI_ProgramChange ) )
+                  {
+                  _MIDI_Funcs->ProgramChange( channel, c1 );
+                  }
+               break;
+
+            case MIDI_AFTER_TOUCH :
+               if ( _MIDI_Funcs->ChannelAftertouch )
+                  {
+                  _MIDI_Funcs->ChannelAftertouch( channel, c1 );
+                  }
+               break;
+
+            case MIDI_PITCH_BEND :
+               if ( _MIDI_Funcs->PitchBend )
+                  {
+                  _MIDI_Funcs->PitchBend( channel, c1, c2 );
+                  }
+               break;
+
+            default :
+               break;
+            }
+
+         Track->delay = _MIDI_ReadDelta( Track );
+         }
+
+      Track->delay--;
+      Track++;
+      tracknum++;
+
+      if ( _MIDI_ActiveTracks == 0 )
+         {
+         break;
+         }
+      }
+
+   _MIDI_AdvanceTick();
+
+   return( TimeSet );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_SetSongTick
+
+   Sets the position of the song pointer.
+---------------------------------------------------------------------*/
+
+void MIDI_SetSongTick
+   (
+   unsigned long PositionInTicks
+   )
+
+   {
+   if ( !_MIDI_SongLoaded )
+      {
+      return;
+      }
+
+   MIDI_PauseSong();
+
+   if ( PositionInTicks < _MIDI_PositionInTicks )
+      {
+      _MIDI_ResetTracks();
+      MIDI_Reset();
+      }
+
+   while( _MIDI_PositionInTicks < PositionInTicks )
+      {
+      if ( _MIDI_ProcessNextTick() )
+         {
+         break;
+         }
+      if ( _MIDI_ActiveTracks == 0 )
+         {
+         _MIDI_ResetTracks();
+         if ( !_MIDI_Loop )
+            {
+            return;
+            }
+         break;
+         }
+      }
+
+   MIDI_SetVolume( _MIDI_TotalVolume );
+   MIDI_ContinueSong();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_SetSongTime
+
+   Sets the position of the song pointer.
+---------------------------------------------------------------------*/
+
+void MIDI_SetSongTime
+   (
+   unsigned long milliseconds
+   )
+
+   {
+   unsigned long mil;
+   unsigned long sec;
+   unsigned long newtime;
+
+   if ( !_MIDI_SongLoaded )
+      {
+      return;
+      }
+
+   MIDI_PauseSong();
+
+   mil = ( ( milliseconds % 1000 ) << TIME_PRECISION ) / 1000;
+   sec = ( milliseconds / 1000 ) << TIME_PRECISION;
+   newtime = sec + mil;
+
+   if ( newtime < _MIDI_Time )
+      {
+      _MIDI_ResetTracks();
+      MIDI_Reset();
+      }
+
+   while( _MIDI_Time < newtime )
+      {
+      if ( _MIDI_ProcessNextTick() )
+         {
+         break;
+         }
+      if ( _MIDI_ActiveTracks == 0 )
+         {
+         _MIDI_ResetTracks();
+         if ( !_MIDI_Loop )
+            {
+            return;
+            }
+         break;
+         }
+      }
+
+   MIDI_SetVolume( _MIDI_TotalVolume );
+   MIDI_ContinueSong();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_SetSongPosition
+
+   Sets the position of the song pointer.
+---------------------------------------------------------------------*/
+
+void MIDI_SetSongPosition
+   (
+   int measure,
+   int beat,
+   int tick
+   )
+
+   {
+   unsigned long pos;
+
+   if ( !_MIDI_SongLoaded )
+      {
+      return;
+      }
+
+   MIDI_PauseSong();
+
+   pos = RELATIVE_BEAT( measure, beat, tick );
+
+   if ( pos < RELATIVE_BEAT( _MIDI_Measure, _MIDI_Beat, _MIDI_Tick ) )
+      {
+      _MIDI_ResetTracks();
+      MIDI_Reset();
+      }
+
+   while( RELATIVE_BEAT( _MIDI_Measure, _MIDI_Beat, _MIDI_Tick ) < pos )
+      {
+      if ( _MIDI_ProcessNextTick() )
+         {
+         break;
+         }
+      if ( _MIDI_ActiveTracks == 0 )
+         {
+         _MIDI_ResetTracks();
+         if ( !_MIDI_Loop )
+            {
+            return;
+            }
+         break;
+         }
+      }
+
+   MIDI_SetVolume( _MIDI_TotalVolume );
+   MIDI_ContinueSong();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_GetSongPosition
+
+   Returns the position of the song pointer in Measures, beats, ticks.
+---------------------------------------------------------------------*/
+
+void MIDI_GetSongPosition
+   (
+   songposition *pos
+   )
+
+   {
+   unsigned long mil;
+   unsigned long sec;
+
+   mil = ( _MIDI_Time & ( ( 1 << TIME_PRECISION ) - 1 ) ) * 1000;
+   sec = _MIDI_Time >> TIME_PRECISION;
+   pos->milliseconds = ( mil >> TIME_PRECISION ) + ( sec * 1000 );
+   pos->tickposition = _MIDI_PositionInTicks;
+   pos->measure      = _MIDI_Measure;
+   pos->beat         = _MIDI_Beat;
+   pos->tick         = _MIDI_Tick;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_GetSongLength
+
+   Returns the length of the song.
+---------------------------------------------------------------------*/
+
+void MIDI_GetSongLength
+   (
+   songposition *pos
+   )
+
+   {
+   unsigned long mil;
+   unsigned long sec;
+
+   mil = ( _MIDI_TotalTime & ( ( 1 << TIME_PRECISION ) - 1 ) ) * 1000;
+   sec = _MIDI_TotalTime >> TIME_PRECISION;
+
+   pos->milliseconds = ( mil >> TIME_PRECISION ) + ( sec * 1000 );
+   pos->measure      = _MIDI_TotalMeasures;
+   pos->beat         = _MIDI_TotalBeats;
+   pos->tick         = _MIDI_TotalTicks;
+   pos->tickposition = 0;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_InitEMIDI
+
+   Sets up the EMIDI
+---------------------------------------------------------------------*/
+
+static void _MIDI_InitEMIDI
+   (
+   void
+   )
+
+   {
+   int    event;
+   int    command;
+   int    channel;
+   int    length;
+   int    IncludeFound;
+   track *Track;
+   int    tracknum;
+   int    type;
+   int    c1;
+   int    c2;
+
+   type = EMIDI_GeneralMIDI;
+   switch( MUSIC_SoundDevice )
+      {
+      case SoundBlaster :
+         type = EMIDI_SoundBlaster;
+         break;
+
+      case ProAudioSpectrum :
+         type = EMIDI_ProAudio;
+         break;
+
+      case SoundMan16 :
+         type = EMIDI_SoundMan16;
+         break;
+
+      case Adlib :
+         type = EMIDI_Adlib;
+         break;
+
+      case GenMidi :
+         type = EMIDI_GeneralMIDI;
+         break;
+
+      case SoundCanvas :
+         type = EMIDI_SoundCanvas;
+         break;
+
+      case Awe32 :
+         type = EMIDI_AWE32;
+         break;
+
+      case WaveBlaster :
+         type = EMIDI_WaveBlaster;
+         break;
+
+      case SoundScape :
+         type = EMIDI_Soundscape;
+         break;
+
+      case UltraSound :
+         type = EMIDI_Ultrasound;
+         break;
+      }
+
+   _MIDI_ResetTracks();
+
+   _MIDI_TotalTime     = 0;
+   _MIDI_TotalTicks    = 0;
+   _MIDI_TotalBeats    = 0;
+   _MIDI_TotalMeasures = 0;
+
+   Track = _MIDI_TrackPtr;
+   tracknum = 0;
+   while( ( tracknum < _MIDI_NumTracks ) && ( Track != NULL ) )
+      {
+      _MIDI_Tick = 0;
+      _MIDI_Beat = 1;
+      _MIDI_Measure = 1;
+      _MIDI_Time = 0;
+      _MIDI_BeatsPerMeasure = 4;
+      _MIDI_TicksPerBeat = _MIDI_Division;
+      _MIDI_TimeBase = 4;
+
+      _MIDI_PositionInTicks = 0;
+      _MIDI_ActiveTracks    = 0;
+      _MIDI_Context         = -1;
+
+      Track->RunningStatus = 0;
+      Track->active        = TRUE;
+
+      Track->EMIDI_ProgramChange = FALSE;
+      Track->EMIDI_VolumeChange  = FALSE;
+      Track->EMIDI_IncludeTrack  = TRUE;
+
+      memset( Track->context, 0, sizeof( Track->context ) );
+
+      while( Track->delay > 0 )
+         {
+         _MIDI_AdvanceTick();
+         Track->delay--;
+         }
+
+      IncludeFound = FALSE;
+      while ( Track->active )
+         {
+         GET_NEXT_EVENT( Track, event );
+
+         if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL )
+            {
+            switch( event )
+               {
+               case MIDI_SYSEX :
+               case MIDI_SYSEX_CONTINUE :
+                  _MIDI_SysEx( Track );
+                  break;
+
+               case MIDI_META_EVENT :
+                  _MIDI_MetaEvent( Track );
+                  break;
+               }
+
+            if ( Track->active )
+               {
+               Track->delay = _MIDI_ReadDelta( Track );
+               while( Track->delay > 0 )
+                  {
+                  _MIDI_AdvanceTick();
+                  Track->delay--;
+                  }
+               }
+
+            continue;
+            }
+
+         if ( event & MIDI_RUNNING_STATUS )
+            {
+            Track->RunningStatus = event;
+            }
+         else
+            {
+            event = Track->RunningStatus;
+            Track->pos--;
+            }
+
+         channel = GET_MIDI_CHANNEL( event );
+         command = GET_MIDI_COMMAND( event );
+         length = _MIDI_CommandLengths[ command ];
+
+         if ( command == MIDI_CONTROL_CHANGE )
+            {
+            if ( *Track->pos == MIDI_MONO_MODE_ON )
+               {
+               length++;
+               }
+            GET_NEXT_EVENT( Track, c1 );
+            GET_NEXT_EVENT( Track, c2 );
+            length -= 2;
+
+            switch( c1 )
+               {
+               case EMIDI_LOOP_START :
+               case EMIDI_SONG_LOOP_START :
+                  if ( c2 == 0 )
+                     {
+                     Track->context[ 0 ].loopcount = EMIDI_INFINITE;
+                     }
+                  else
+                     {
+                     Track->context[ 0 ].loopcount = c2;
+                     }
+
+                  Track->context[ 0 ].pos              = Track->pos;
+                  Track->context[ 0 ].loopstart        = Track->pos;
+                  Track->context[ 0 ].RunningStatus    = Track->RunningStatus;
+                  Track->context[ 0 ].time             = _MIDI_Time;
+                  Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
+                  Track->context[ 0 ].tick             = _MIDI_Tick;
+                  Track->context[ 0 ].beat             = _MIDI_Beat;
+                  Track->context[ 0 ].measure          = _MIDI_Measure;
+                  Track->context[ 0 ].BeatsPerMeasure  = _MIDI_BeatsPerMeasure;
+                  Track->context[ 0 ].TicksPerBeat     = _MIDI_TicksPerBeat;
+                  Track->context[ 0 ].TimeBase         = _MIDI_TimeBase;
+                  break;
+
+               case EMIDI_LOOP_END :
+               case EMIDI_SONG_LOOP_END :
+                  if ( c2 == EMIDI_END_LOOP_VALUE )
+                     {
+                     Track->context[ 0 ].loopstart = NULL;
+                     Track->context[ 0 ].loopcount = 0;
+                     }
+                  break;
+
+               case EMIDI_INCLUDE_TRACK :
+                  if ( EMIDI_AffectsCurrentCard( c2, type ) )
+                     {
+                     //printf( "Include track %d on card %d\n", tracknum, c2 );
+                     IncludeFound = TRUE;
+                     Track->EMIDI_IncludeTrack = TRUE;
+                     }
+                  else if ( !IncludeFound )
+                     {
+                     //printf( "Track excluded %d on card %d\n", tracknum, c2 );
+                     IncludeFound = TRUE;
+                     Track->EMIDI_IncludeTrack = FALSE;
+                     }
+                  break;
+
+               case EMIDI_EXCLUDE_TRACK :
+                  if ( EMIDI_AffectsCurrentCard( c2, type ) )
+                     {
+                     //printf( "Exclude track %d on card %d\n", tracknum, c2 );
+                     Track->EMIDI_IncludeTrack = FALSE;
+                     }
+                  break;
+
+               case EMIDI_PROGRAM_CHANGE :
+                  if ( !Track->EMIDI_ProgramChange )
+                     //printf( "Program change on track %d\n", tracknum );
+                  Track->EMIDI_ProgramChange = TRUE;
+                  break;
+
+               case EMIDI_VOLUME_CHANGE :
+                  if ( !Track->EMIDI_VolumeChange )
+                     //printf( "Volume change on track %d\n", tracknum );
+                  Track->EMIDI_VolumeChange = TRUE;
+                  break;
+
+               case EMIDI_CONTEXT_START :
+                  if ( ( c2 > 0 ) && ( c2 < EMIDI_NUM_CONTEXTS ) )
+                     {
+                     Track->context[ c2 ].pos              = Track->pos;
+                     Track->context[ c2 ].loopstart        = Track->context[ 0 ].loopstart;
+                     Track->context[ c2 ].loopcount        = Track->context[ 0 ].loopcount;
+                     Track->context[ c2 ].RunningStatus    = Track->RunningStatus;
+                     Track->context[ c2 ].time             = _MIDI_Time;
+                     Track->context[ c2 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
+                     Track->context[ c2 ].tick             = _MIDI_Tick;
+                     Track->context[ c2 ].beat             = _MIDI_Beat;
+                     Track->context[ c2 ].measure          = _MIDI_Measure;
+                     Track->context[ c2 ].BeatsPerMeasure  = _MIDI_BeatsPerMeasure;
+                     Track->context[ c2 ].TicksPerBeat     = _MIDI_TicksPerBeat;
+                     Track->context[ c2 ].TimeBase         = _MIDI_TimeBase;
+                     }
+                  break;
+
+               case EMIDI_CONTEXT_END :
+                  break;
+               }
+            }
+
+         Track->pos += length;
+         Track->delay = _MIDI_ReadDelta( Track );
+
+         while( Track->delay > 0 )
+            {
+            _MIDI_AdvanceTick();
+            Track->delay--;
+            }
+         }
+
+      _MIDI_TotalTime = max( _MIDI_TotalTime, _MIDI_Time );
+      if ( RELATIVE_BEAT( _MIDI_Measure, _MIDI_Beat, _MIDI_Tick ) >
+         RELATIVE_BEAT( _MIDI_TotalMeasures, _MIDI_TotalBeats,
+         _MIDI_TotalTicks ) )
+         {
+         _MIDI_TotalTicks    = _MIDI_Tick;
+         _MIDI_TotalBeats    = _MIDI_Beat;
+         _MIDI_TotalMeasures = _MIDI_Measure;
+         }
+
+      Track++;
+      tracknum++;
+      }
+
+   _MIDI_ResetTracks();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_LoadTimbres
+
+   Preloads the timbres on cards that use patch-caching.
+---------------------------------------------------------------------*/
+
+void MIDI_LoadTimbres
+   (
+   void
+   )
+
+   {
+   int    event;
+   int    command;
+   int    channel;
+   int    length;
+   int    Finished;
+   track *Track;
+   int    tracknum;
+
+   Track = _MIDI_TrackPtr;
+   tracknum = 0;
+   while( ( tracknum < _MIDI_NumTracks ) && ( Track != NULL ) )
+      {
+      Finished = FALSE;
+      while ( !Finished )
+         {
+         GET_NEXT_EVENT( Track, event );
+
+         if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL )
+            {
+            switch( event )
+               {
+               case MIDI_SYSEX :
+               case MIDI_SYSEX_CONTINUE :
+                  length = _MIDI_ReadDelta( Track );
+                  Track->pos += length;
+                  break;
+
+               case MIDI_META_EVENT :
+                  GET_NEXT_EVENT( Track, command );
+                  GET_NEXT_EVENT( Track, length );
+
+                  if ( command == MIDI_END_OF_TRACK )
+                     {
+                     Finished = TRUE;
+                     }
+
+                  Track->pos += length;
+                  break;
+               }
+
+            if ( !Finished )
+               {
+               _MIDI_ReadDelta( Track );
+               }
+
+            continue;
+            }
+
+         if ( event & MIDI_RUNNING_STATUS )
+            {
+            Track->RunningStatus = event;
+            }
+         else
+            {
+            event = Track->RunningStatus;
+            Track->pos--;
+            }
+
+         channel = GET_MIDI_CHANNEL( event );
+         command = GET_MIDI_COMMAND( event );
+         length = _MIDI_CommandLengths[ command ];
+
+         if ( command == MIDI_CONTROL_CHANGE )
+            {
+            if ( *Track->pos == MIDI_MONO_MODE_ON )
+               {
+               length++;
+               }
+
+            if ( *Track->pos == EMIDI_PROGRAM_CHANGE )
+               {
+               _MIDI_Funcs->LoadPatch( *( Track->pos + 1 ) );
+               }
+            }
+
+         if ( channel == MIDI_RHYTHM_CHANNEL )
+            {
+            if ( command == MIDI_NOTE_ON )
+               {
+               _MIDI_Funcs->LoadPatch( 128 + *Track->pos );
+               }
+            }
+         else
+            {
+            if ( command == MIDI_PROGRAM_CHANGE )
+               {
+               _MIDI_Funcs->LoadPatch( *Track->pos );
+               }
+            }
+         Track->pos += length;
+         _MIDI_ReadDelta( Track );
+         }
+      Track++;
+      tracknum++;
+      }
+
+   _MIDI_ResetTracks();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void MIDI_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_UnlockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+void MIDI_UnlockMemory
+   (
+   void
+   )
+
+   {
+   DPMI_UnlockMemoryRegion( MIDI_LockStart, MIDI_LockEnd );
+   DPMI_UnlockMemory( ( void * )&_MIDI_CommandLengths[ 0 ],
+      sizeof( _MIDI_CommandLengths ) );
+   DPMI_Unlock( _MIDI_TrackPtr );
+   DPMI_Unlock( _MIDI_NumTracks );
+   DPMI_Unlock( _MIDI_SongActive );
+   DPMI_Unlock( _MIDI_SongLoaded );
+   DPMI_Unlock( _MIDI_Loop );
+   DPMI_Unlock( _MIDI_PlayRoutine );
+   DPMI_Unlock( _MIDI_Division );
+   DPMI_Unlock( _MIDI_ActiveTracks );
+   DPMI_Unlock( _MIDI_TotalVolume );
+   DPMI_Unlock( _MIDI_ChannelVolume );
+   DPMI_Unlock( _MIDI_Funcs );
+   DPMI_Unlock( _MIDI_PositionInTicks );
+   DPMI_Unlock( _MIDI_Division );
+   DPMI_Unlock( _MIDI_Tick );
+   DPMI_Unlock( _MIDI_Beat );
+   DPMI_Unlock( _MIDI_Measure );
+   DPMI_Unlock( _MIDI_Time );
+   DPMI_Unlock( _MIDI_BeatsPerMeasure );
+   DPMI_Unlock( _MIDI_TicksPerBeat );
+   DPMI_Unlock( _MIDI_TimeBase );
+   DPMI_Unlock( _MIDI_FPSecondsPerTick );
+   DPMI_Unlock( _MIDI_Context );
+   DPMI_Unlock( _MIDI_TotalTime );
+   DPMI_Unlock( _MIDI_TotalTicks );
+   DPMI_Unlock( _MIDI_TotalBeats );
+   DPMI_Unlock( _MIDI_TotalMeasures );
+   DPMI_Unlock( MIDI_Tempo );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MIDI_LockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+int MIDI_LockMemory
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status  = DPMI_LockMemoryRegion( MIDI_LockStart, MIDI_LockEnd );
+   status |= DPMI_LockMemory( ( void * )&_MIDI_CommandLengths[ 0 ],
+      sizeof( _MIDI_CommandLengths ) );
+   status |= DPMI_Lock( _MIDI_TrackPtr );
+   status |= DPMI_Lock( _MIDI_NumTracks );
+   status |= DPMI_Lock( _MIDI_SongActive );
+   status |= DPMI_Lock( _MIDI_SongLoaded );
+   status |= DPMI_Lock( _MIDI_Loop );
+   status |= DPMI_Lock( _MIDI_PlayRoutine );
+   status |= DPMI_Lock( _MIDI_Division );
+   status |= DPMI_Lock( _MIDI_ActiveTracks );
+   status |= DPMI_Lock( _MIDI_TotalVolume );
+   status |= DPMI_Lock( _MIDI_ChannelVolume );
+   status |= DPMI_Lock( _MIDI_Funcs );
+   status |= DPMI_Lock( _MIDI_PositionInTicks );
+   status |= DPMI_Lock( _MIDI_Division );
+   status |= DPMI_Lock( _MIDI_Tick );
+   status |= DPMI_Lock( _MIDI_Beat );
+   status |= DPMI_Lock( _MIDI_Measure );
+   status |= DPMI_Lock( _MIDI_Time );
+   status |= DPMI_Lock( _MIDI_BeatsPerMeasure );
+   status |= DPMI_Lock( _MIDI_TicksPerBeat );
+   status |= DPMI_Lock( _MIDI_TimeBase );
+   status |= DPMI_Lock( _MIDI_FPSecondsPerTick );
+   status |= DPMI_Lock( _MIDI_Context );
+   status |= DPMI_Lock( _MIDI_TotalTime );
+   status |= DPMI_Lock( _MIDI_TotalTicks );
+   status |= DPMI_Lock( _MIDI_TotalBeats );
+   status |= DPMI_Lock( _MIDI_TotalMeasures );
+   status |= DPMI_Lock( MIDI_Tempo );
+
+   if ( status != DPMI_Ok )
+      {
+      MIDI_UnlockMemory();
+//      MIDI_SetErrorCode( MIDI_DPMI_Error );
+      return( MIDI_Error );
+      }
+
+   return( MIDI_Ok );
+   }

Added: tags/rott-1.1/rott/audiolib/midi.h
===================================================================
--- tags/rott-1.1/rott/audiolib/midi.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/midi.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,98 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: MIDI.H
+
+   author: James R. Dose
+   date:   May 25, 1994
+
+   Public header for MIDI.C.  Midi song file playback routines.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __MIDI_H
+#define __MIDI_H
+
+enum MIDI_Errors
+   {
+   MIDI_Warning = -2,
+   MIDI_Error   = -1,
+   MIDI_Ok      = 0,
+   MIDI_NullMidiModule,
+   MIDI_InvalidMidiFile,
+   MIDI_UnknownMidiFormat,
+   MIDI_NoTracks,
+   MIDI_InvalidTrack,
+   MIDI_NoMemory,
+   MIDI_DPMI_Error
+   };
+
+
+#define MIDI_PASS_THROUGH 1
+#define MIDI_DONT_PLAY    0
+
+#define MIDI_MaxVolume 255
+
+extern char MIDI_PatchMap[ 128 ];
+
+typedef struct
+   {
+   void ( *NoteOff )( int channel, int key, int velocity );
+   void ( *NoteOn )( int channel, int key, int velocity );
+   void ( *PolyAftertouch )( int channel, int key, int pressure );
+   void ( *ControlChange )( int channel, int number, int value );
+   void ( *ProgramChange )( int channel, int program );
+   void ( *ChannelAftertouch )( int channel, int pressure );
+   void ( *PitchBend )( int channel, int lsb, int msb );
+   void ( *ReleasePatches )( void );
+   void ( *LoadPatch )( int number );
+   void ( *SetVolume )( int volume );
+   int  ( *GetVolume )( void );
+   } midifuncs;
+
+void MIDI_RerouteMidiChannel( int channel, int cdecl ( *function )( int event, int c1, int c2 ) );
+int  MIDI_AllNotesOff( void );
+void MIDI_SetUserChannelVolume( int channel, int volume );
+void MIDI_ResetUserChannelVolume( void );
+int  MIDI_Reset( void );
+int  MIDI_SetVolume( int volume );
+int  MIDI_GetVolume( void );
+void MIDI_SetMidiFuncs( midifuncs *funcs );
+void MIDI_SetContext( int context );
+int  MIDI_GetContext( void );
+void MIDI_SetLoopFlag( int loopflag );
+void MIDI_ContinueSong( void );
+void MIDI_PauseSong( void );
+int  MIDI_SongPlaying( void );
+void MIDI_StopSong( void );
+int  MIDI_PlaySong( unsigned char *song, int loopflag );
+void MIDI_SetTempo( int tempo );
+int  MIDI_GetTempo( void );
+void MIDI_SetSongTick( unsigned long PositionInTicks );
+void MIDI_SetSongTime( unsigned long milliseconds );
+void MIDI_SetSongPosition( int measure, int beat, int tick );
+void MIDI_GetSongPosition( songposition *pos );
+void MIDI_GetSongLength( songposition *pos );
+void MIDI_LoadTimbres( void );
+void MIDI_UnlockMemory( void );
+int  MIDI_LockMemory( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/mpu401.c
===================================================================
--- tags/rott-1.1/rott/audiolib/mpu401.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/mpu401.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,451 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: MPU401.C
+
+   author: James R. Dose
+   date:   January 1, 1994
+
+   Low level routines to support sending of MIDI data to MPU401
+   compatible MIDI interfaces.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <conio.h>
+#include <dos.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "dpmi.h"
+#include "user.h"
+#include "mpu401.h"
+
+#define MIDI_NOTE_OFF         0x80
+#define MIDI_NOTE_ON          0x90
+#define MIDI_POLY_AFTER_TCH   0xA0
+#define MIDI_CONTROL_CHANGE   0xB0
+#define MIDI_PROGRAM_CHANGE   0xC0
+#define MIDI_AFTER_TOUCH      0xD0
+#define MIDI_PITCH_BEND       0xE0
+#define MIDI_META_EVENT       0xFF
+#define MIDI_END_OF_TRACK     0x2F
+#define MIDI_TEMPO_CHANGE     0x51
+#define MIDI_MONO_MODE_ON     0x7E
+#define MIDI_ALL_NOTES_OFF    0x7B
+
+int MPU_BaseAddr = MPU_DefaultAddress;
+
+//unsigned MPU_Delay = 500;
+//unsigned MPU_Delay = 5000;
+unsigned MPU_Delay = 0x5000;
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define MPU_LockStart MPU_SendMidi
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_SendMidi
+
+   Sends a byte of MIDI data to the music device.
+---------------------------------------------------------------------*/
+
+void MPU_SendMidi
+   (
+   int data
+   )
+
+   {
+   int      port = MPU_BaseAddr + 1;
+   unsigned count;
+
+   count = MPU_Delay;
+   while( count > 0 )
+      {
+      // check if status port says we're ready for write
+      if ( !( inp( port ) & MPU_ReadyToWrite ) )
+         {
+         break;
+         }
+
+      count--;
+      }
+
+   port--;
+
+   // Send the midi data
+   outp( port, data );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_NoteOff
+
+   Sends a full MIDI note off event out to the music device.
+---------------------------------------------------------------------*/
+
+void MPU_NoteOff
+   (
+   int channel,
+   int key,
+   int velocity
+   )
+
+   {
+   MPU_SendMidi( MIDI_NOTE_OFF | channel );
+   MPU_SendMidi( key );
+   MPU_SendMidi( velocity );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_NoteOn
+
+   Sends a full MIDI note on event out to the music device.
+---------------------------------------------------------------------*/
+
+void MPU_NoteOn
+   (
+   int channel,
+   int key,
+   int velocity
+   )
+
+   {
+   MPU_SendMidi( MIDI_NOTE_ON | channel );
+   MPU_SendMidi( key );
+   MPU_SendMidi( velocity );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_PolyAftertouch
+
+   Sends a full MIDI polyphonic aftertouch event out to the music device.
+---------------------------------------------------------------------*/
+
+void MPU_PolyAftertouch
+   (
+   int channel,
+   int key,
+   int pressure
+   )
+
+   {
+   MPU_SendMidi( MIDI_POLY_AFTER_TCH | channel );
+   MPU_SendMidi( key );
+   MPU_SendMidi( pressure );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_ControlChange
+
+   Sends a full MIDI control change event out to the music device.
+---------------------------------------------------------------------*/
+
+void MPU_ControlChange
+   (
+   int channel,
+   int number,
+   int value
+   )
+
+   {
+   MPU_SendMidi( MIDI_CONTROL_CHANGE | channel );
+   MPU_SendMidi( number );
+   MPU_SendMidi( value );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_ProgramChange
+
+   Sends a full MIDI program change event out to the music device.
+---------------------------------------------------------------------*/
+
+void MPU_ProgramChange
+   (
+   int channel,
+   int program
+   )
+
+   {
+   MPU_SendMidi( MIDI_PROGRAM_CHANGE | channel );
+   MPU_SendMidi( program );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_ChannelAftertouch
+
+   Sends a full MIDI channel aftertouch event out to the music device.
+---------------------------------------------------------------------*/
+
+void MPU_ChannelAftertouch
+   (
+   int channel,
+   int pressure
+   )
+
+   {
+   MPU_SendMidi( MIDI_AFTER_TOUCH | channel );
+   MPU_SendMidi( pressure );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_PitchBend
+
+   Sends a full MIDI pitch bend event out to the music device.
+---------------------------------------------------------------------*/
+
+void MPU_PitchBend
+   (
+   int channel,
+   int lsb,
+   int msb
+   )
+
+   {
+   MPU_SendMidi( MIDI_PITCH_BEND | channel );
+   MPU_SendMidi( lsb );
+   MPU_SendMidi( msb );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_SendCommand
+
+   Sends a command to the MPU401 card.
+---------------------------------------------------------------------*/
+
+void MPU_SendCommand
+   (
+   int data
+   )
+
+   {
+   int      port = MPU_BaseAddr + 1;
+   unsigned count;
+
+   count = 0xffff;
+   while( count > 0 )
+      {
+      // check if status port says we're ready for write
+      if ( !( inp( port ) & MPU_ReadyToWrite ) )
+         {
+         break;
+         }
+      count--;
+      }
+
+   outp( port, data );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_Reset
+
+   Resets the MPU401 card.
+---------------------------------------------------------------------*/
+
+int MPU_Reset
+   (
+   void
+   )
+
+   {
+   int      port = MPU_BaseAddr + 1;
+   unsigned count;
+
+   // Output "Reset" command via Command port
+   MPU_SendCommand( MPU_CmdReset );
+
+   // Wait for status port to be ready for read
+   count = 0xffff;
+   while( count > 0 )
+      {
+      if ( !( inp( port ) & MPU_ReadyToRead ) )
+         {
+         port--;
+
+         // Check for a successful reset
+         if ( inp( port ) == MPU_CmdAcknowledge )
+            {
+            return( MPU_Ok );
+            }
+
+         port++;
+         }
+      count--;
+      }
+
+   // Failed to reset : MPU-401 not detected
+   return( MPU_NotFound );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_EnterUART
+
+   Sets the MPU401 card to operate in UART mode.
+---------------------------------------------------------------------*/
+
+int MPU_EnterUART
+   (
+   void
+   )
+
+   {
+   int      port = MPU_BaseAddr + 1;
+   unsigned count;
+
+   // Output "Enter UART" command via Command port
+   MPU_SendCommand( MPU_CmdEnterUART );
+
+   // Wait for status port to be ready for read
+   count = 0xffff;
+   while( count > 0 )
+      {
+      if ( !( inp( port ) & MPU_ReadyToRead ) )
+         {
+         port--;
+
+         // Check for a successful reset
+         if ( inp( port ) == MPU_CmdAcknowledge )
+            {
+            return( MPU_Ok );
+            }
+
+         port++;
+         }
+      count--;
+      }
+
+   // Failed to reset : MPU-401 not detected
+   return( MPU_UARTFailed );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_Init
+
+   Detects and initializes the MPU401 card.
+---------------------------------------------------------------------*/
+
+int MPU_Init
+   (
+   int addr
+   )
+
+   {
+   int status;
+   int count;
+   char *ptr;
+
+   ptr = USER_GetText( "MPUDELAY" );
+   if ( ptr != NULL )
+      {
+      MPU_Delay = ( unsigned )atol( ptr );
+      }
+
+   MPU_BaseAddr = addr;
+
+   count = 4;
+   while( count > 0 )
+      {
+      status = MPU_Reset();
+      if ( status == MPU_Ok )
+         {
+         return( MPU_EnterUART() );
+         }
+      count--;
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void MPU_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_UnlockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+void MPU_UnlockMemory
+   (
+   void
+   )
+
+   {
+   DPMI_UnlockMemoryRegion( MPU_LockStart, MPU_LockEnd );
+   DPMI_Unlock( MPU_BaseAddr );
+   DPMI_Unlock( MPU_Delay );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MPU_LockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+int MPU_LockMemory
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status  = DPMI_LockMemoryRegion( MPU_LockStart, MPU_LockEnd );
+   status |= DPMI_Lock( MPU_BaseAddr );
+   status |= DPMI_Lock( MPU_Delay );
+
+   if ( status != DPMI_Ok )
+      {
+      MPU_UnlockMemory();
+      return( MPU_Error );
+      }
+
+   return( MPU_Ok );
+   }

Added: tags/rott-1.1/rott/audiolib/mpu401.h
===================================================================
--- tags/rott-1.1/rott/audiolib/mpu401.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/mpu401.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,61 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef __MPU401_H
+#define __MPU401_H
+
+#define MPU_DefaultAddress 0x330
+
+enum MPU_ERRORS
+   {
+   MPU_Warning = -2,
+   MPU_Error = -1,
+   MPU_Ok = 0,
+   MPU_DPMI_Error
+   };
+
+#define MPU_NotFound       -1
+#define MPU_UARTFailed     -2
+
+#define MPU_ReadyToWrite   0x40
+#define MPU_ReadyToRead    0x80
+#define MPU_CmdEnterUART   0x3f
+#define MPU_CmdReset       0xff
+#define MPU_CmdAcknowledge 0xfe
+
+extern int MPU_BaseAddr;
+extern unsigned MPU_Delay;
+
+void MPU_SendCommand( int data );
+void MPU_SendMidi( int data );
+int  MPU_Reset( void );
+int  MPU_EnterUART( void );
+int  MPU_Init( int addr );
+void MPU_ResetMidi( void );
+void MPU_NoteOff( int channel, int key, int velocity );
+void MPU_NoteOn( int channel, int key, int velocity );
+void MPU_PolyAftertouch( int channel, int key, int pressure );
+void MPU_ControlChange( int channel, int number, int value );
+void MPU_ProgramChange( int channel, int program );
+void MPU_ChannelAftertouch( int channel, int pressure );
+void MPU_PitchBend( int channel, int lsb, int msb );
+void MPU_UnlockMemory( void );
+int  MPU_LockMemory( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/multivoc.c
===================================================================
--- tags/rott-1.1/rott/audiolib/multivoc.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/multivoc.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,3555 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: MULTIVOC.C
+
+   author: James R. Dose
+   date:   December 20, 1993
+
+   Routines to provide multichannel digitized sound playback for
+   Sound Blaster compatible sound cards.
+
+   (c) Copyright 1993 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifdef PLAT_DOS
+#include <dos.h>
+#include <conio.h>
+#endif
+
+#include "util.h"
+#include "dpmi.h"
+#include "usrhooks.h"
+#include "interrup.h"
+#include "dma.h"
+#include "linklist.h"
+#include "sndcards.h"
+
+#ifdef PLAT_DOS
+#include "blaster.h"
+#include "sndscape.h"
+#include "sndsrc.h"
+#include "pas16.h"
+#include "guswave.h"
+#else
+#include "dsl.h"
+#endif
+
+#include "pitch.h"
+#include "multivoc.h"
+#include "_multivc.h"
+#include "debugio.h"
+
+#define RoundFixed( fixedval, bits )            \
+        (                                       \
+          (                                     \
+            (fixedval) + ( 1 << ( (bits) - 1 ) )\
+          ) >> (bits)                           \
+        )
+
+#define IS_QUIET( ptr )  ( ( void * )( ptr ) == ( void * )&MV_VolumeTable[ 0 ] )
+
+static int       MV_ReverbLevel;
+static int       MV_ReverbDelay;
+static VOLUME16 *MV_ReverbTable = NULL;
+
+//static signed short MV_VolumeTable[ MV_MaxVolume + 1 ][ 256 ];
+static signed short MV_VolumeTable[ 63 + 1 ][ 256 ];
+
+//static Pan MV_PanTable[ MV_NumPanPositions ][ MV_MaxVolume + 1 ];
+static Pan MV_PanTable[ MV_NumPanPositions ][ 63 + 1 ];
+
+static int MV_Installed   = FALSE;
+static int MV_SoundCard   = SoundBlaster;
+static int MV_TotalVolume = MV_MaxTotalVolume;
+static int MV_MaxVoices   = 1;
+static int MV_Recording;
+
+static int MV_BufferSize = MixBufferSize;
+static int MV_BufferLength;
+
+static int MV_NumberOfBuffers = NumberOfBuffers;
+
+static int MV_MixMode    = MONO_8BIT;
+static int MV_Channels   = 1;
+static int MV_Bits       = 8;
+
+static int MV_Silence    = SILENCE_8BIT;
+static int MV_SwapLeftRight = FALSE;
+
+static int MV_RequestedMixRate;
+static int MV_MixRate;
+
+static int MV_DMAChannel = -1;
+static int MV_BuffShift;
+
+static int MV_TotalMemory;
+
+static long   MV_BufferDescriptor;
+static int   MV_BufferEmpty[ NumberOfBuffers ];
+char *MV_MixBuffer[ NumberOfBuffers + 1 ];
+
+static VoiceNode *MV_Voices = NULL;
+
+static volatile VoiceNode VoiceList;
+static volatile VoiceNode VoicePool;
+
+/*static*/ int MV_MixPage      = 0;
+static int MV_VoiceHandle  = MV_MinVoiceHandle;
+
+static void ( *MV_CallBackFunc )( unsigned long ) = NULL;
+static void ( *MV_RecordFunc )( char *ptr, int length ) = NULL;
+static void ( *MV_MixFunction )( VoiceNode *voice, int buffer );
+
+static int MV_MaxVolume = 63;
+
+char  *MV_HarshClipTable;
+char  *MV_MixDestination;
+short *MV_LeftVolume;
+short *MV_RightVolume;
+int    MV_SampleSize = 1;
+int    MV_RightChannelOffset;
+
+unsigned long MV_MixPosition;
+
+int MV_ErrorCode = MV_Ok;
+
+#define MV_SetErrorCode( status ) \
+   MV_ErrorCode   = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: MV_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *MV_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case MV_Warning :
+      case MV_Error :
+         ErrorString = MV_ErrorString( MV_ErrorCode );
+         break;
+
+      case MV_Ok :
+         ErrorString = "Multivoc ok.";
+         break;
+
+      case MV_UnsupportedCard :
+         ErrorString = "Selected sound card is not supported by Multivoc.";
+         break;
+
+      case MV_NotInstalled :
+         ErrorString = "Multivoc not installed.";
+         break;
+
+      case MV_NoVoices :
+         ErrorString = "No free voices available to Multivoc.";
+         break;
+
+      case MV_NoMem :
+         ErrorString = "Out of memory in Multivoc.";
+         break;
+
+      case MV_VoiceNotFound :
+         ErrorString = "No voice with matching handle found.";
+         break;
+
+#ifdef PLAT_DOS
+      case MV_BlasterError :
+         ErrorString = BLASTER_ErrorString( BLASTER_Error );
+         break;
+
+      case MV_PasError :
+         ErrorString = PAS_ErrorString( PAS_Error );
+         break;
+
+      case MV_SoundScapeError :
+         ErrorString = SOUNDSCAPE_ErrorString( SOUNDSCAPE_Error );
+         break;
+
+      #ifndef SOUNDSOURCE_OFF
+      case MV_SoundSourceError :
+         ErrorString = SS_ErrorString( SS_Error );
+         break;
+      #endif
+#endif
+
+      case MV_DPMI_Error :
+         ErrorString = "DPMI Error in Multivoc.";
+         break;
+
+      case MV_InvalidVOCFile :
+         ErrorString = "Invalid VOC file passed in to Multivoc.";
+         break;
+
+      case MV_InvalidWAVFile :
+         ErrorString = "Invalid WAV file passed in to Multivoc.";
+         break;
+
+      case MV_InvalidMixMode :
+         ErrorString = "Invalid mix mode request in Multivoc.";
+         break;
+
+      case MV_SoundSourceFailure :
+         ErrorString = "Sound Source playback failed.";
+         break;
+
+      case MV_IrqFailure :
+         ErrorString = "Playback failed, possibly due to an invalid or conflicting IRQ.";
+         break;
+
+      case MV_DMAFailure :
+         ErrorString = "Playback failed, possibly due to an invalid or conflicting DMA channel.";
+         break;
+
+      case MV_DMA16Failure :
+         ErrorString = "Playback failed, possibly due to an invalid or conflicting DMA channel.  \n"
+                       "Make sure the 16-bit DMA channel is correct.";
+         break;
+
+      case MV_NullRecordFunction :
+         ErrorString = "Null record function passed to MV_StartRecording.";
+         break;
+
+      default :
+         ErrorString = "Unknown Multivoc error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define MV_LockStart MV_Mix
+
+
+/*---------------------------------------------------------------------
+   Function: MV_Mix
+
+   Mixes the sound into the buffer.
+---------------------------------------------------------------------*/
+
+static void MV_Mix
+   (
+   VoiceNode *voice,
+   int        buffer
+   )
+
+   {
+   char          *start;
+   int            length;
+   long           voclength;
+   unsigned long  position;
+   unsigned long  rate;
+   unsigned long  FixedPointBufferSize;
+
+   if ( ( voice->length == 0 ) &&
+        ( voice->GetSound != NULL ) &&
+        ( voice->GetSound( voice ) != KeepPlaying ) )
+      {
+      return;
+      }
+
+   length               = MixBufferSize;
+   FixedPointBufferSize = voice->FixedPointBufferSize;
+
+   MV_MixDestination    = MV_MixBuffer[ buffer ];
+   MV_LeftVolume        = voice->LeftVolume;
+   MV_RightVolume       = voice->RightVolume;
+
+   if ( ( MV_Channels == 2 ) && ( IS_QUIET( MV_LeftVolume ) ) )
+      {
+      MV_LeftVolume      = MV_RightVolume;
+      MV_MixDestination += MV_RightChannelOffset;
+      }
+
+   // Add this voice to the mix
+   while( length > 0 )
+      {
+      start    = voice->sound;
+      rate     = voice->RateScale;
+      position = voice->position;
+
+      // Check if the last sample in this buffer would be
+      // beyond the length of the sample block
+      if ( ( position + FixedPointBufferSize ) >= voice->length )
+         {
+         if ( position < voice->length )
+            {
+            voclength = ( voice->length - position + rate - 1 ) / rate;
+            }
+         else
+            {
+            voice->GetSound( voice );
+            return;
+            }
+         }
+      else
+         {
+         voclength = length;
+         }
+
+      voice->mix( position, rate, start, voclength );
+
+      if ( voclength & 1 )
+         {
+         MV_MixPosition += rate;
+         voclength -= 1;
+         }
+      voice->position = MV_MixPosition;
+
+      length -= voclength;
+
+      if ( voice->position >= voice->length )
+         {
+         // Get the next block of sound
+         if ( voice->GetSound( voice ) != KeepPlaying )
+            {
+            return;
+            }
+
+         if ( length > 0 )
+            {
+            // Get the position of the last sample in the buffer
+            FixedPointBufferSize = voice->RateScale * ( length - 1 );
+            }
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_PlayVoice
+
+   Adds a voice to the play list.
+---------------------------------------------------------------------*/
+
+void MV_PlayVoice
+   (
+   VoiceNode *voice
+   )
+
+   {
+   unsigned flags;
+
+   flags = DisableInterrupts();
+   LL_SortedInsertion( &VoiceList, voice, prev, next, VoiceNode, priority );
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_StopVoice
+
+   Removes the voice from the play list and adds it to the free list.
+---------------------------------------------------------------------*/
+
+void MV_StopVoice
+   (
+   VoiceNode *voice
+   )
+
+   {
+   unsigned  flags;
+
+   flags = DisableInterrupts();
+
+   // move the voice from the play list to the free list
+   LL_Remove( voice, next, prev );
+   LL_Add( (VoiceNode *)&VoicePool, voice, next, prev );
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_ServiceVoc
+
+   Starts playback of the waiting buffer and mixes the next one.
+---------------------------------------------------------------------*/
+
+// static int backcolor = 1;
+
+void MV_ServiceVoc
+   (
+   void
+   )
+
+   {
+   VoiceNode *voice;
+   VoiceNode *next;
+   char      *buffer;
+
+#ifdef PLAT_DOS
+   if ( MV_DMAChannel >= 0 )
+      {
+      // Get the currently playing buffer
+      buffer = ( char * )DMA_GetCurrentPos( MV_DMAChannel );
+      MV_MixPage   = ( unsigned )( buffer - MV_MixBuffer[ 0 ] );
+      MV_MixPage >>= MV_BuffShift;
+      }
+#endif
+
+   // Toggle which buffer we'll mix next
+   MV_MixPage++;
+   if ( MV_MixPage >= MV_NumberOfBuffers )
+      {
+      MV_MixPage -= MV_NumberOfBuffers;
+      }
+
+   if ( MV_ReverbLevel == 0 )
+      {
+      // Initialize buffer
+      //Commented out so that the buffer is always cleared.
+      //This is so the guys at Echo Speech can mix into the
+      //buffer even when no sounds are playing.
+      //if ( !MV_BufferEmpty[ MV_MixPage ] )
+         {
+         ClearBuffer_DW( MV_MixBuffer[ MV_MixPage ], MV_Silence, MV_BufferSize >> 2 );
+         if ( ( MV_SoundCard == UltraSound ) && ( MV_Channels == 2 ) )
+            {
+            ClearBuffer_DW( MV_MixBuffer[ MV_MixPage ] + MV_RightChannelOffset,
+               MV_Silence, MV_BufferSize >> 2 );
+            }
+         MV_BufferEmpty[ MV_MixPage ] = TRUE;
+         }
+      }
+   else
+      {
+      char *end;
+      char *source;
+      char *dest;
+      int   count;
+      int   length;
+
+      end = MV_MixBuffer[ 0 ] + MV_BufferLength;;
+      dest = MV_MixBuffer[ MV_MixPage ];
+      source = MV_MixBuffer[ MV_MixPage ] - MV_ReverbDelay;
+      if ( source < MV_MixBuffer[ 0 ] )
+         {
+         source += MV_BufferLength;
+         }
+
+      length = MV_BufferSize;
+      while( length > 0 )
+         {
+         count = length;
+         if ( source + count > end )
+            {
+            count = end - source;
+            }
+
+         if ( MV_Bits == 16 )
+            {
+            if ( MV_ReverbTable != NULL )
+               {
+               MV_16BitReverb( source, dest, (const VOLUME16 *)MV_ReverbTable, count / 2 );
+               if ( ( MV_SoundCard == UltraSound ) && ( MV_Channels == 2 ) )
+                  {
+                  MV_16BitReverb( source + MV_RightChannelOffset,
+                     dest + MV_RightChannelOffset, (const VOLUME16 *)MV_ReverbTable, count / 2 );
+                  }
+               }
+            else
+               {
+               MV_16BitReverbFast( source, dest, count / 2, MV_ReverbLevel );
+               if ( ( MV_SoundCard == UltraSound ) && ( MV_Channels == 2 ) )
+                  {
+                  MV_16BitReverbFast( source + MV_RightChannelOffset,
+                     dest + MV_RightChannelOffset, count / 2, MV_ReverbLevel );
+                  }
+               }
+            }
+         else
+            {
+            if ( MV_ReverbTable != NULL )
+               {
+               MV_8BitReverb( source, dest, (const VOLUME16 *)MV_ReverbTable, count );
+               if ( ( MV_SoundCard == UltraSound ) && ( MV_Channels == 2 ) )
+                  {
+                  MV_8BitReverb( source + MV_RightChannelOffset,
+                     dest + MV_RightChannelOffset, (const VOLUME16 *)MV_ReverbTable, count );
+                  }
+               }
+            else
+               {
+               MV_8BitReverbFast( source, dest, count, MV_ReverbLevel );
+               if ( ( MV_SoundCard == UltraSound ) && ( MV_Channels == 2 ) )
+                  {
+                  MV_8BitReverbFast( source + MV_RightChannelOffset,
+                     dest + MV_RightChannelOffset, count, MV_ReverbLevel );
+                  }
+               }
+            }
+
+         // if we go through the loop again, it means that we've wrapped around the buffer
+         source  = MV_MixBuffer[ 0 ];
+         dest   += count;
+         length -= count;
+         }
+      }
+
+   // Play any waiting voices
+   for( voice = VoiceList.next; voice != &VoiceList; voice = next )
+      {
+//      if ( ( voice < &MV_Voices[ 0 ] ) || ( voice > &MV_Voices[ 8 ] ) )
+//         {
+//         SetBorderColor(backcolor++);
+//         break;
+//         }
+
+      MV_BufferEmpty[ MV_MixPage ] = FALSE;
+
+      MV_MixFunction( voice, MV_MixPage );
+
+      next = voice->next;
+
+      // Is this voice done?
+      if ( !voice->Playing )
+         {
+         MV_StopVoice( voice );
+
+         if ( MV_CallBackFunc )
+            {
+            MV_CallBackFunc( voice->callbackval );
+            }
+         }
+      }
+   }
+
+
+int leftpage  = -1;
+int rightpage = -1;
+
+void MV_ServiceGus( char **ptr, unsigned long *length )
+   {
+   if ( leftpage == MV_MixPage )
+      {
+      MV_ServiceVoc();
+      }
+
+   leftpage = MV_MixPage;
+
+   *ptr = MV_MixBuffer[ MV_MixPage ];
+   *length = MV_BufferSize;
+   }
+
+void MV_ServiceRightGus( char **ptr, unsigned long *length )
+   {
+   if ( rightpage == MV_MixPage )
+      {
+      MV_ServiceVoc();
+      }
+
+   rightpage = MV_MixPage;
+
+   *ptr = MV_MixBuffer[ MV_MixPage ] + MV_RightChannelOffset;
+   *length = MV_BufferSize;
+   }
+
+/*---------------------------------------------------------------------
+   Function: MV_GetNextVOCBlock
+
+   Interperate the information of a VOC format sound file.
+---------------------------------------------------------------------*/
+static __inline unsigned int get_le32(void *p0)
+{
+	//unsigned char *p = p0;
+	//return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
+	unsigned int val = *((unsigned int *) p0);
+	return(BUILDSWAP_INTEL32(val));
+}
+
+static __inline unsigned int get_le16(void *p0)
+{
+	//unsigned char *p = p0;
+	//return p[0] | (p[1]<<8);
+	unsigned short val = *((unsigned short *) p0);
+	return( (unsigned int) (BUILDSWAP_INTEL16(val)) );
+}
+
+playbackstatus MV_GetNextVOCBlock
+   (
+   VoiceNode *voice
+   )
+
+   {
+   unsigned char *ptr;
+   int            blocktype=0;
+   int            lastblocktype=0;
+   unsigned long  blocklength=0l;
+   unsigned long  samplespeed=0l;
+   unsigned int   tc=0;
+   int            packtype=0;
+   int            voicemode=0;
+   int            done=0;
+   unsigned       BitsPerSample;
+   unsigned       Channels;
+   unsigned       Format;
+
+   if ( voice->BlockLength > 0 )
+      {
+      voice->position    -= voice->length;
+      voice->sound       += voice->length >> 16;
+      if ( voice->bits == 16 )
+         {
+         voice->sound += voice->length >> 16;
+         }
+      voice->length       = min( voice->BlockLength, 0x8000 );
+      voice->BlockLength -= voice->length;
+      voice->length     <<= 16;
+      return( KeepPlaying );
+      }
+
+   if ( ( voice->length > 0 ) && ( voice->LoopEnd != NULL ) &&
+      ( voice->LoopStart != NULL ) )
+      {
+      voice->BlockLength  = voice->LoopSize;
+      voice->sound        = voice->LoopStart;
+      voice->position     = 0;
+      voice->length       = min( voice->BlockLength, 0x8000 );
+      voice->BlockLength -= voice->length;
+      voice->length     <<= 16;
+      return( KeepPlaying );
+      }
+
+   ptr = ( unsigned char * )voice->NextBlock;
+
+   voice->Playing = TRUE;
+
+   voicemode = 0;
+   lastblocktype = 0;
+   packtype = 0;
+
+   done = FALSE;
+   while( !done )
+      {
+      // Stop playing if we get a NULL pointer
+      if ( ptr == NULL )
+         {
+         voice->Playing = FALSE;
+         done = TRUE;
+         break;
+         }
+
+      {
+      unsigned tmp = get_le32(ptr);
+      blocktype = tmp&255;
+      blocklength = tmp>>8;
+      }
+      ptr += 4;
+
+      switch( blocktype )
+         {
+         case 0 :
+            // End of data
+            if ( ( voice->LoopStart == NULL ) ||
+               ( (unsigned char *)voice->LoopStart >= ( ptr - 4 ) ) )
+               {
+               voice->Playing = FALSE;
+               done = TRUE;
+               }
+            else
+               {
+               voice->BlockLength  = ( ptr - 4 ) - (unsigned char *)voice->LoopStart;
+               voice->sound        = voice->LoopStart;
+               voice->position     = 0;
+               voice->length       = min( voice->BlockLength, 0x8000 );
+               voice->BlockLength -= voice->length;
+               voice->length     <<= 16;
+               return( KeepPlaying );
+               }
+            break;
+
+         case 1 :
+            // Sound data block
+            voice->bits  = 8;
+            if ( lastblocktype != 8 )
+               {
+               tc = ( unsigned int )*ptr << 8;
+               packtype = *( ptr + 1 );
+               }
+
+            ptr += 2;
+            blocklength -= 2;
+
+            samplespeed = 256000000L / ( 65536 - tc );
+
+            // Skip packed or stereo data
+            if ( ( packtype != 0 ) || ( voicemode != 0 ) )
+               {
+               ptr += blocklength;
+               }
+            else
+               {
+               done = TRUE;
+               }
+            voicemode = 0;
+            break;
+
+         case 2 :
+            // Sound continuation block
+            samplespeed = voice->SamplingRate;
+            done = TRUE;
+            break;
+
+         case 3 :
+            // Silence
+            // Not implimented.
+            ptr += blocklength;
+            break;
+
+         case 4 :
+            // Marker
+            // Not implimented.
+            ptr += blocklength;
+            break;
+
+         case 5 :
+            // ASCII string
+            // Not implimented.
+            ptr += blocklength;
+            break;
+
+         case 6 :
+            // Repeat begin
+            if ( voice->LoopEnd == NULL )
+               {
+               voice->LoopCount = get_le16(ptr);
+               voice->LoopStart = ptr + blocklength;
+               }
+            ptr += blocklength;
+            break;
+
+         case 7 :
+            // Repeat end
+            ptr += blocklength;
+            if ( lastblocktype == 6 )
+               {
+               voice->LoopCount = 0;
+               }
+            else
+               {
+               if ( ( voice->LoopCount > 0 ) && ( voice->LoopStart != NULL ) )
+                  {
+                  ptr = voice->LoopStart;
+                  if ( voice->LoopCount < 0xffff )
+                     {
+                     voice->LoopCount--;
+                     if ( voice->LoopCount == 0 )
+                        {
+                        voice->LoopStart = NULL;
+                        }
+                     }
+                  }
+               }
+            break;
+
+         case 8 :
+            // Extended block
+            voice->bits  = 8;
+            tc = get_le16(ptr);
+            packtype = *( ptr + 2 );
+            voicemode = *( ptr + 3 );
+            ptr += blocklength;
+            break;
+
+         case 9 :
+            // New sound data block
+            samplespeed = get_le32(ptr);
+            BitsPerSample = ptr[4];
+            Channels = ptr[5];
+            Format = get_le16(ptr+6);
+
+            if ( ( BitsPerSample == 8 ) && ( Channels == 1 ) &&
+               ( Format == VOC_8BIT ) )
+               {
+               ptr         += 12;
+               blocklength -= 12;
+               voice->bits  = 8;
+               done         = TRUE;
+               }
+            else if ( ( BitsPerSample == 16 ) && ( Channels == 1 ) &&
+               ( Format == VOC_16BIT ) )
+               {
+               ptr         += 12;
+               blocklength -= 12;
+               voice->bits  = 16;
+               done         = TRUE;
+               }
+            else
+               {
+               ptr += blocklength;
+               }
+            break;
+
+         default :
+            // Unknown data.  Probably not a VOC file.
+            voice->Playing = FALSE;
+            done = TRUE;
+            break;
+         }
+
+      lastblocktype = blocktype;
+      }
+
+   if ( voice->Playing )
+      {
+      voice->NextBlock    = ptr + blocklength;
+      voice->sound        = ptr;
+
+      voice->SamplingRate = samplespeed;
+      voice->RateScale    = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate;
+
+      // Multiply by MixBufferSize - 1
+      voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) -
+         voice->RateScale;
+
+      if ( voice->LoopEnd != NULL )
+         {
+         if ( blocklength > ( unsigned long )voice->LoopEnd )
+            {
+            blocklength = ( unsigned long )voice->LoopEnd;
+            }
+         else
+            {
+            voice->LoopEnd = ( char * )blocklength;
+            }
+
+         voice->LoopStart = voice->sound + ( unsigned long )voice->LoopStart;
+         voice->LoopEnd   = voice->sound + ( unsigned long )voice->LoopEnd;
+         voice->LoopSize  = voice->LoopEnd - voice->LoopStart;
+         }
+
+      if ( voice->bits == 16 )
+         {
+         blocklength /= 2;
+         }
+
+      voice->position     = 0;
+      voice->length       = min( blocklength, 0x8000 );
+      voice->BlockLength  = blocklength - voice->length;
+      voice->length     <<= 16;
+
+      MV_SetVoiceMixMode( voice );
+
+      return( KeepPlaying );
+      }
+
+   return( NoMoreData );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_GetNextDemandFeedBlock
+
+   Controls playback of demand fed data.
+---------------------------------------------------------------------*/
+
+playbackstatus MV_GetNextDemandFeedBlock
+   (
+   VoiceNode *voice
+   )
+
+   {
+   if ( voice->BlockLength > 0 )
+      {
+      voice->position    -= voice->length;
+      voice->sound       += voice->length >> 16;
+      voice->length       = min( voice->BlockLength, 0x8000 );
+      voice->BlockLength -= voice->length;
+      voice->length     <<= 16;
+
+      return( KeepPlaying );
+      }
+
+   if ( voice->DemandFeed == NULL )
+      {
+      return( NoMoreData );
+      }
+
+   voice->position     = 0;
+   ( voice->DemandFeed )( &voice->sound, &voice->BlockLength );
+   voice->length       = min( voice->BlockLength, 0x8000 );
+   voice->BlockLength -= voice->length;
+   voice->length     <<= 16;
+
+   if ( ( voice->length > 0 ) && ( voice->sound != NULL ) )
+      {
+      return( KeepPlaying );
+      }
+   return( NoMoreData );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_GetNextRawBlock
+
+   Controls playback of demand fed data.
+---------------------------------------------------------------------*/
+
+playbackstatus MV_GetNextRawBlock
+   (
+   VoiceNode *voice
+   )
+
+   {
+   if ( voice->BlockLength <= 0 )
+      {
+      if ( voice->LoopStart == NULL )
+         {
+         voice->Playing = FALSE;
+         return( NoMoreData );
+         }
+
+      voice->BlockLength = voice->LoopSize;
+      voice->NextBlock   = voice->LoopStart;
+      voice->length = 0;
+      voice->position = 0;
+      }
+
+   voice->sound        = voice->NextBlock;
+   voice->position    -= voice->length;
+   voice->length       = min( voice->BlockLength, 0x8000 );
+   voice->NextBlock   += voice->length;
+   if ( voice->bits == 16 )
+      {
+      voice->NextBlock += voice->length;
+      }
+   voice->BlockLength -= voice->length;
+   voice->length     <<= 16;
+
+   return( KeepPlaying );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_GetNextWAVBlock
+
+   Controls playback of demand fed data.
+---------------------------------------------------------------------*/
+
+playbackstatus MV_GetNextWAVBlock
+   (
+   VoiceNode *voice
+   )
+
+   {
+   if ( voice->BlockLength <= 0 )
+      {
+      if ( voice->LoopStart == NULL )
+         {
+         voice->Playing = FALSE;
+         return( NoMoreData );
+         }
+
+      voice->BlockLength = voice->LoopSize;
+      voice->NextBlock   = voice->LoopStart;
+      voice->length      = 0;
+      voice->position    = 0;
+      }
+
+   voice->sound        = voice->NextBlock;
+   voice->position    -= voice->length;
+   voice->length       = min( voice->BlockLength, 0x8000 );
+   voice->NextBlock   += voice->length;
+   if ( voice->bits == 16 )
+      {
+      voice->NextBlock += voice->length;
+      }
+   voice->BlockLength -= voice->length;
+   voice->length     <<= 16;
+
+   return( KeepPlaying );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_ServiceRecord
+
+   Starts recording of the waiting buffer.
+---------------------------------------------------------------------*/
+
+static void MV_ServiceRecord
+   (
+   void
+   )
+
+   {
+   if ( MV_RecordFunc )
+      {
+      MV_RecordFunc( MV_MixBuffer[ 0 ] + MV_MixPage * MixBufferSize,
+         MixBufferSize );
+      }
+
+   // Toggle which buffer we'll mix next
+   MV_MixPage++;
+   if ( MV_MixPage >= NumberOfBuffers )
+      {
+      MV_MixPage = 0;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_GetVoice
+
+   Locates the voice with the specified handle.
+---------------------------------------------------------------------*/
+
+VoiceNode *MV_GetVoice
+   (
+   int handle
+   )
+
+   {
+   VoiceNode *voice;
+   unsigned  flags;
+
+   flags = DisableInterrupts();
+
+   for( voice = VoiceList.next; voice != &VoiceList; voice = voice->next )
+      {
+      if ( handle == voice->handle )
+         {
+         break;
+         }
+      }
+
+   RestoreInterrupts( flags );
+
+   if ( voice == &VoiceList )
+      {
+      MV_SetErrorCode( MV_VoiceNotFound );
+      
+      // SBF - should this return null?
+      return NULL;
+      }
+
+   return( voice );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_VoicePlaying
+
+   Checks if the voice associated with the specified handle is
+   playing.
+---------------------------------------------------------------------*/
+
+int MV_VoicePlaying
+   (
+   int handle
+   )
+
+   {
+   VoiceNode *voice;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( FALSE );
+      }
+
+   voice = MV_GetVoice( handle );
+
+   if ( voice == NULL )
+      {
+      return( FALSE );
+      }
+
+   return( TRUE );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_KillAllVoices
+
+   Stops output of all currently active voices.
+---------------------------------------------------------------------*/
+
+int MV_KillAllVoices
+   (
+   void
+   )
+
+   {
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   // Remove all the voices from the list
+   while( VoiceList.next != &VoiceList )
+      {
+      MV_Kill( VoiceList.next->handle );
+      }
+
+   return( MV_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_Kill
+
+   Stops output of the voice associated with the specified handle.
+---------------------------------------------------------------------*/
+
+int MV_Kill
+   (
+   int handle
+   )
+
+   {
+   VoiceNode *voice;
+   unsigned  flags;
+   unsigned  long callbackval;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   flags = DisableInterrupts();
+
+   voice = MV_GetVoice( handle );
+   if ( voice == NULL )
+      {
+      RestoreInterrupts( flags );
+      MV_SetErrorCode( MV_VoiceNotFound );
+      return( MV_Error );
+      }
+
+   callbackval = voice->callbackval;
+
+   MV_StopVoice( voice );
+
+   RestoreInterrupts( flags );
+
+   if ( MV_CallBackFunc )
+      {
+      MV_CallBackFunc( callbackval );
+      }
+
+   return( MV_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_VoicesPlaying
+
+   Determines the number of currently active voices.
+---------------------------------------------------------------------*/
+
+int MV_VoicesPlaying
+   (
+   void
+   )
+
+   {
+   VoiceNode   *voice;
+   int         NumVoices = 0;
+   unsigned    flags;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( 0 );
+      }
+
+   flags = DisableInterrupts();
+
+   for( voice = VoiceList.next; voice != &VoiceList; voice = voice->next )
+      {
+      NumVoices++;
+      }
+
+   RestoreInterrupts( flags );
+
+   return( NumVoices );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_AllocVoice
+
+   Retrieve an inactive or lower priority voice for output.
+---------------------------------------------------------------------*/
+
+VoiceNode *MV_AllocVoice
+   (
+   int priority
+   )
+
+   {
+   VoiceNode   *voice;
+   VoiceNode   *node;
+   unsigned    flags;
+
+//return( NULL );
+   if ( MV_Recording )
+      {
+      return( NULL );
+      }
+
+   flags = DisableInterrupts();
+
+   // Check if we have any free voices
+   if ( LL_Empty( &VoicePool, next, prev ) )
+      {
+      // check if we have a higher priority than a voice that is playing.
+      voice = VoiceList.next;
+      for( node = voice->next; node != &VoiceList; node = node->next )
+         {
+         if ( node->priority < voice->priority )
+            {
+            voice = node;
+            }
+         }
+
+      if ( priority >= voice->priority )
+         {
+         MV_Kill( voice->handle );
+         }
+      }
+
+   // Check if any voices are in the voice pool
+   if ( LL_Empty( &VoicePool, next, prev ) )
+      {
+      // No free voices
+      RestoreInterrupts( flags );
+      return( NULL );
+      }
+
+   voice = VoicePool.next;
+   LL_Remove( voice, next, prev );
+   RestoreInterrupts( flags );
+
+   // Find a free voice handle
+   do
+      {
+      MV_VoiceHandle++;
+      if ( MV_VoiceHandle < MV_MinVoiceHandle )
+         {
+         MV_VoiceHandle = MV_MinVoiceHandle;
+         }
+      }
+   while( MV_VoicePlaying( MV_VoiceHandle ) );
+
+   voice->handle = MV_VoiceHandle;
+
+   return( voice );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_VoiceAvailable
+
+   Checks if a voice can be play at the specified priority.
+---------------------------------------------------------------------*/
+
+int MV_VoiceAvailable
+   (
+   int priority
+   )
+
+   {
+   VoiceNode   *voice;
+   VoiceNode   *node;
+   unsigned    flags;
+
+   // Check if we have any free voices
+   if ( !LL_Empty( &VoicePool, next, prev ) )
+      {
+      return( TRUE );
+      }
+
+   flags = DisableInterrupts();
+
+   // check if we have a higher priority than a voice that is playing.
+   voice = VoiceList.next;
+   for( node = VoiceList.next; node != &VoiceList; node = node->next )
+      {
+      if ( node->priority < voice->priority )
+         {
+         voice = node;
+         }
+      }
+
+   RestoreInterrupts( flags );
+
+   if ( ( voice != &VoiceList ) && ( priority >= voice->priority ) )
+      {
+      return( TRUE );
+      }
+
+   return( FALSE );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetVoicePitch
+
+   Sets the pitch for the specified voice.
+---------------------------------------------------------------------*/
+
+void MV_SetVoicePitch
+   (
+   VoiceNode *voice,
+   unsigned long rate,
+   int pitchoffset
+   )
+
+   {
+   voice->SamplingRate = rate;
+   voice->PitchScale   = PITCH_GetScale( pitchoffset );
+   voice->RateScale    = ( rate * voice->PitchScale ) / MV_MixRate;
+
+   // Multiply by MixBufferSize - 1
+   voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) -
+      voice->RateScale;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetPitch
+
+   Sets the pitch for the voice associated with the specified handle.
+---------------------------------------------------------------------*/
+
+int MV_SetPitch
+   (
+   int handle,
+   int pitchoffset
+   )
+
+   {
+   VoiceNode *voice;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   voice = MV_GetVoice( handle );
+   if ( voice == NULL )
+      {
+      MV_SetErrorCode( MV_VoiceNotFound );
+      return( MV_Error );
+      }
+
+   MV_SetVoicePitch( voice, voice->SamplingRate, pitchoffset );
+
+   return( MV_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetFrequency
+
+   Sets the frequency for the voice associated with the specified handle.
+---------------------------------------------------------------------*/
+
+int MV_SetFrequency
+   (
+   int handle,
+   int frequency
+   )
+
+   {
+   VoiceNode *voice;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   voice = MV_GetVoice( handle );
+   if ( voice == NULL )
+      {
+      MV_SetErrorCode( MV_VoiceNotFound );
+      return( MV_Error );
+      }
+
+   MV_SetVoicePitch( voice, frequency, 0 );
+
+   return( MV_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_GetVolumeTable
+
+   Returns a pointer to the volume table associated with the specified
+   volume.
+---------------------------------------------------------------------*/
+
+static short *MV_GetVolumeTable
+   (
+   int vol
+   )
+
+   {
+   int volume;
+   short *table;
+
+   volume = MIX_VOLUME( vol );
+
+   table = (short *)&MV_VolumeTable[ volume ];
+
+   return( table );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetVoiceMixMode
+
+   Selects which method should be used to mix the voice.
+---------------------------------------------------------------------*/
+
+static void MV_SetVoiceMixMode
+   (
+   VoiceNode *voice
+   )
+
+   {
+   unsigned flags;
+   int test;
+
+   flags = DisableInterrupts();
+
+   test = T_DEFAULT;
+   if ( MV_Bits == 8 )
+      {
+      test |= T_8BITS;
+      }
+
+   if ( voice->bits == 16 )
+      {
+      test |= T_16BITSOURCE;
+      }
+
+   if ( MV_Channels == 1 )
+      {
+      test |= T_MONO;
+      }
+   else
+      {
+      if ( IS_QUIET( voice->RightVolume ) )
+         {
+         test |= T_RIGHTQUIET;
+         }
+      else if ( IS_QUIET( voice->LeftVolume ) )
+         {
+         test |= T_LEFTQUIET;
+         }
+      }
+
+   // Default case
+   voice->mix = MV_Mix8BitMono;
+
+   switch( test )
+      {
+      case T_8BITS | T_MONO | T_16BITSOURCE :
+         voice->mix = MV_Mix8BitMono16;
+         break;
+
+      case T_8BITS | T_MONO :
+         voice->mix = MV_Mix8BitMono;
+         break;
+
+      case T_8BITS | T_16BITSOURCE | T_LEFTQUIET :
+         MV_LeftVolume = MV_RightVolume;
+         voice->mix = MV_Mix8BitMono16;
+         break;
+
+      case T_8BITS | T_LEFTQUIET :
+         MV_LeftVolume = MV_RightVolume;
+         voice->mix = MV_Mix8BitMono;
+         break;
+
+      case T_8BITS | T_16BITSOURCE | T_RIGHTQUIET :
+         voice->mix = MV_Mix8BitMono16;
+         break;
+
+      case T_8BITS | T_RIGHTQUIET :
+         voice->mix = MV_Mix8BitMono;
+         break;
+
+      case T_8BITS | T_16BITSOURCE :
+         voice->mix = MV_Mix8BitStereo16;
+         break;
+
+      case T_8BITS :
+         voice->mix = MV_Mix8BitStereo;
+         break;
+
+      case T_MONO | T_16BITSOURCE :
+         voice->mix = MV_Mix16BitMono16;
+         break;
+
+      case T_MONO :
+         voice->mix = MV_Mix16BitMono;
+         break;
+
+      case T_16BITSOURCE | T_LEFTQUIET :
+         MV_LeftVolume = MV_RightVolume;
+         voice->mix = MV_Mix16BitMono16;
+         break;
+
+      case T_LEFTQUIET :
+         MV_LeftVolume = MV_RightVolume;
+         voice->mix = MV_Mix16BitMono;
+         break;
+
+      case T_16BITSOURCE | T_RIGHTQUIET :
+         voice->mix = MV_Mix16BitMono16;
+         break;
+
+      case T_RIGHTQUIET :
+         voice->mix = MV_Mix16BitMono;
+         break;
+
+      case T_16BITSOURCE :
+         voice->mix = MV_Mix16BitStereo16;
+         break;
+
+      case T_SIXTEENBIT_STEREO :
+         voice->mix = MV_Mix16BitStereo;
+         break;
+
+      default :
+         voice->mix = MV_Mix8BitMono;
+      }
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetVoiceVolume
+
+   Sets the stereo and mono volume level of the voice associated
+   with the specified handle.
+---------------------------------------------------------------------*/
+
+void MV_SetVoiceVolume
+   (
+   VoiceNode *voice,
+   int vol,
+   int left,
+   int right
+   )
+
+   {
+   if ( MV_Channels == 1 )
+      {
+      left  = vol;
+      right = vol;
+      }
+
+   if ( MV_SwapLeftRight )
+      {
+      // SBPro uses reversed panning
+      voice->LeftVolume  = MV_GetVolumeTable( right );
+      voice->RightVolume = MV_GetVolumeTable( left );
+      }
+   else
+      {
+      voice->LeftVolume  = MV_GetVolumeTable( left );
+      voice->RightVolume = MV_GetVolumeTable( right );
+      }
+
+   MV_SetVoiceMixMode( voice );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_EndLooping
+
+   Stops the voice associated with the specified handle from looping
+   without stoping the sound.
+---------------------------------------------------------------------*/
+
+int MV_EndLooping
+   (
+   int handle
+   )
+
+   {
+   VoiceNode *voice;
+   unsigned flags;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   flags = DisableInterrupts();
+
+   voice = MV_GetVoice( handle );
+   if ( voice == NULL )
+      {
+      RestoreInterrupts( flags );
+      MV_SetErrorCode( MV_VoiceNotFound );
+      return( MV_Warning );
+      }
+
+   voice->LoopCount = 0;
+   voice->LoopStart = NULL;
+   voice->LoopEnd   = NULL;
+
+   RestoreInterrupts( flags );
+
+   return( MV_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetPan
+
+   Sets the stereo and mono volume level of the voice associated
+   with the specified handle.
+---------------------------------------------------------------------*/
+
+int MV_SetPan
+   (
+   int handle,
+   int vol,
+   int left,
+   int right
+   )
+
+   {
+   VoiceNode *voice;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   voice = MV_GetVoice( handle );
+   if ( voice == NULL )
+      {
+      MV_SetErrorCode( MV_VoiceNotFound );
+      return( MV_Warning );
+      }
+
+   MV_SetVoiceVolume( voice, vol, left, right );
+
+   return( MV_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_Pan3D
+
+   Set the angle and distance from the listener of the voice associated
+   with the specified handle.
+---------------------------------------------------------------------*/
+
+int MV_Pan3D
+   (
+   int handle,
+   int angle,
+   int distance
+   )
+
+   {
+   int left;
+   int right;
+   int mid;
+   int volume;
+   int status;
+
+   if ( distance < 0 )
+      {
+      distance  = -distance;
+      angle    += MV_NumPanPositions / 2;
+      }
+
+   volume = MIX_VOLUME( distance );
+
+   // Ensure angle is within 0 - 31
+   angle &= MV_MaxPanPosition;
+
+   left  = MV_PanTable[ angle ][ volume ].left;
+   right = MV_PanTable[ angle ][ volume ].right;
+   mid   = max( 0, 255 - distance );
+
+   status = MV_SetPan( handle, mid, left, right );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetReverb
+
+   Sets the level of reverb to add to mix.
+---------------------------------------------------------------------*/
+
+void MV_SetReverb
+   (
+   int reverb
+   )
+
+   {
+   MV_ReverbLevel = MIX_VOLUME( reverb );
+   MV_ReverbTable = &MV_VolumeTable[ MV_ReverbLevel ];
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetFastReverb
+
+   Sets the level of reverb to add to mix.
+---------------------------------------------------------------------*/
+
+void MV_SetFastReverb
+   (
+   int reverb
+   )
+
+   {
+   MV_ReverbLevel = max( 0, min( 16, reverb ) );
+   MV_ReverbTable = NULL;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_GetMaxReverbDelay
+
+   Returns the maximum delay time for reverb.
+---------------------------------------------------------------------*/
+
+int MV_GetMaxReverbDelay
+   (
+   void
+   )
+
+   {
+   int maxdelay;
+
+   maxdelay = MixBufferSize * MV_NumberOfBuffers;
+
+   return maxdelay;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_GetReverbDelay
+
+   Returns the current delay time for reverb.
+---------------------------------------------------------------------*/
+
+int MV_GetReverbDelay
+   (
+   void
+   )
+
+   {
+   return MV_ReverbDelay / MV_SampleSize;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetReverbDelay
+
+   Sets the delay level of reverb to add to mix.
+---------------------------------------------------------------------*/
+
+void MV_SetReverbDelay
+   (
+   int delay
+   )
+
+   {
+   int maxdelay;
+
+   maxdelay = MV_GetMaxReverbDelay();
+   MV_ReverbDelay = max( MixBufferSize, min( delay, maxdelay ) );
+   MV_ReverbDelay *= MV_SampleSize;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetMixMode
+
+   Prepares Multivoc to play stereo of mono digitized sounds.
+---------------------------------------------------------------------*/
+
+int MV_SetMixMode
+   (
+   int numchannels,
+   int samplebits
+   )
+
+   {
+   int mode;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   mode = 0;
+   if ( numchannels == 2 )
+      {
+      mode |= STEREO;
+      }
+   if ( samplebits == 16 )
+      {
+      mode |= SIXTEEN_BIT;
+      }
+
+#ifdef PLAT_DOS
+   switch( MV_SoundCard )
+      {
+      case UltraSound :
+         MV_MixMode = mode;
+         break;
+
+      case SoundBlaster :
+      case Awe32 :
+         MV_MixMode = BLASTER_SetMixMode( mode );
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         MV_MixMode = PAS_SetMixMode( mode );
+         break;
+
+      case SoundScape :
+         MV_MixMode = SOUNDSCAPE_SetMixMode( mode );
+         break;
+
+      #ifndef SOUNDSOURCE_OFF
+      case SoundSource :
+      case TandySoundSource :
+         MV_MixMode = SS_SetMixMode( mode );
+         break;
+      #endif
+      }
+#else
+   MV_MixMode = mode;
+#endif
+
+   MV_Channels = 1;
+   if ( MV_MixMode & STEREO )
+      {
+      MV_Channels = 2;
+      }
+
+   MV_Bits = 8;
+   if ( MV_MixMode & SIXTEEN_BIT )
+      {
+      MV_Bits = 16;
+      }
+
+   MV_BuffShift  = 7 + MV_Channels;
+   MV_SampleSize = sizeof( MONO8 ) * MV_Channels;
+
+   if ( MV_Bits == 8 )
+      {
+      MV_Silence = SILENCE_8BIT;
+      }
+   else
+      {
+      MV_Silence     = SILENCE_16BIT;
+      MV_BuffShift  += 1;
+      MV_SampleSize *= 2;
+      }
+
+   MV_BufferSize = MixBufferSize * MV_SampleSize;
+   MV_NumberOfBuffers = TotalBufferSize / MV_BufferSize;
+   MV_BufferLength = TotalBufferSize;
+
+   MV_RightChannelOffset = MV_SampleSize / 2;
+   if ( ( MV_SoundCard == UltraSound ) && ( MV_Channels == 2 ) )
+      {
+      MV_SampleSize         /= 2;
+      MV_BufferSize         /= 2;
+      MV_RightChannelOffset  = MV_BufferSize * MV_NumberOfBuffers;
+      MV_BufferLength       /= 2;
+      }
+
+   return( MV_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_StartPlayback
+
+   Starts the sound playback engine.
+---------------------------------------------------------------------*/
+
+int MV_StartPlayback
+   (
+   void
+   )
+
+   {
+   int status;
+   int buffer;
+
+   // Initialize the buffers
+   ClearBuffer_DW( MV_MixBuffer[ 0 ], MV_Silence, TotalBufferSize >> 2 );
+   for( buffer = 0; buffer < MV_NumberOfBuffers; buffer++ )
+      {
+      MV_BufferEmpty[ buffer ] = TRUE;
+      }
+
+   // Set the mix buffer variables
+   MV_MixPage = 1;
+
+   MV_MixFunction = MV_Mix;
+
+//JIM
+//   MV_MixRate = MV_RequestedMixRate;
+//   return( MV_Ok );
+
+   // Start playback
+#ifdef PLAT_DOS
+   switch( MV_SoundCard )
+      {
+      case SoundBlaster :
+      case Awe32 :
+         status = BLASTER_BeginBufferedPlayback( MV_MixBuffer[ 0 ],
+            TotalBufferSize, MV_NumberOfBuffers,
+            MV_RequestedMixRate, MV_MixMode, MV_ServiceVoc );
+
+         if ( status != BLASTER_Ok )
+            {
+            MV_SetErrorCode( MV_BlasterError );
+            return( MV_Error );
+            }
+
+         MV_MixRate = BLASTER_GetPlaybackRate();
+         MV_DMAChannel = BLASTER_DMAChannel;
+         break;
+
+      case UltraSound :
+
+         status = GUSWAVE_StartDemandFeedPlayback( MV_ServiceGus, 1,
+            MV_Bits, MV_RequestedMixRate, 0, ( MV_Channels == 1 ) ?
+            0 : 24, 255, 0xffff, 0 );
+         if ( status < GUSWAVE_Ok )
+            {
+            MV_SetErrorCode( MV_BlasterError );
+            return( MV_Error );
+            }
+
+         if ( MV_Channels == 2 )
+            {
+            status = GUSWAVE_StartDemandFeedPlayback( MV_ServiceRightGus, 1,
+               MV_Bits, MV_RequestedMixRate, 0, 8, 255, 0xffff, 0 );
+            if ( status < GUSWAVE_Ok )
+               {
+               GUSWAVE_KillAllVoices();
+               MV_SetErrorCode( MV_BlasterError );
+               return( MV_Error );
+               }
+            }
+
+         MV_MixRate = MV_RequestedMixRate;
+         MV_DMAChannel = -1;
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         status = PAS_BeginBufferedPlayback( MV_MixBuffer[ 0 ],
+            TotalBufferSize, MV_NumberOfBuffers,
+            MV_RequestedMixRate, MV_MixMode, MV_ServiceVoc );
+
+         if ( status != PAS_Ok )
+            {
+            MV_SetErrorCode( MV_PasError );
+            return( MV_Error );
+            }
+
+         MV_MixRate = PAS_GetPlaybackRate();
+         MV_DMAChannel = PAS_DMAChannel;
+         break;
+
+      case SoundScape :
+         status = SOUNDSCAPE_BeginBufferedPlayback( MV_MixBuffer[ 0 ],
+            TotalBufferSize, MV_NumberOfBuffers, MV_RequestedMixRate,
+            MV_MixMode, MV_ServiceVoc );
+
+         if ( status != SOUNDSCAPE_Ok )
+            {
+            MV_SetErrorCode( MV_SoundScapeError );
+            return( MV_Error );
+            }
+
+         MV_MixRate = SOUNDSCAPE_GetPlaybackRate();
+         MV_DMAChannel = SOUNDSCAPE_DMAChannel;
+         break;
+
+      #ifndef SOUNDSOURCE_OFF
+      case SoundSource :
+      case TandySoundSource :
+         SS_BeginBufferedPlayback( MV_MixBuffer[ 0 ],
+            TotalBufferSize, MV_NumberOfBuffers,
+            MV_ServiceVoc );
+         MV_MixRate = SS_SampleRate;
+         MV_DMAChannel = -1;
+         break;
+      #endif
+      }
+#else
+    status = DSL_BeginBufferedPlayback( MV_MixBuffer[ 0 ],
+            TotalBufferSize, MV_NumberOfBuffers,
+            MV_RequestedMixRate, MV_MixMode, MV_ServiceVoc );
+
+    if ( status != DSL_Ok )
+       {
+       MV_SetErrorCode( MV_BlasterError );
+       return( MV_Error );
+       }
+
+    MV_MixRate = DSL_GetPlaybackRate();
+#endif
+
+   return( MV_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_StopPlayback
+
+   Stops the sound playback engine.
+---------------------------------------------------------------------*/
+
+void MV_StopPlayback
+   (
+   void
+   )
+
+   {
+   VoiceNode   *voice;
+   VoiceNode   *next;
+   unsigned    flags;
+
+#ifdef PLAT_DOS
+   // Stop sound playback
+   switch( MV_SoundCard )
+      {
+      case SoundBlaster :
+      case Awe32 :
+         BLASTER_StopPlayback();
+         break;
+
+      case UltraSound :
+         GUSWAVE_KillAllVoices();
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         PAS_StopPlayback();
+         break;
+
+      case SoundScape :
+         SOUNDSCAPE_StopPlayback();
+         break;
+
+      #ifndef SOUNDSOURCE_OFF
+      case SoundSource :
+      case TandySoundSource :
+         SS_StopPlayback();
+         break;
+      #endif
+      }
+#else
+   DSL_StopPlayback();
+#endif
+
+   // Make sure all callbacks are done.
+   flags = DisableInterrupts();
+
+   for( voice = VoiceList.next; voice != &VoiceList; voice = next )
+      {
+      next = voice->next;
+
+      MV_StopVoice( voice );
+
+      if ( MV_CallBackFunc )
+         {
+         MV_CallBackFunc( voice->callbackval );
+         }
+      }
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_StartRecording
+
+   Starts the sound recording engine.
+---------------------------------------------------------------------*/
+
+int MV_StartRecording
+   (
+   int MixRate,
+   void ( *function )( char *ptr, int length )
+   )
+
+   {
+#ifdef PLAT_DOS
+   int status;
+
+   switch( MV_SoundCard )
+      {
+      case SoundBlaster :
+      case Awe32 :
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         break;
+
+      default :
+         MV_SetErrorCode( MV_UnsupportedCard );
+         return( MV_Error );
+         break;
+      }
+
+   if ( function == NULL )
+      {
+      MV_SetErrorCode( MV_NullRecordFunction );
+      return( MV_Error );
+      }
+
+   MV_StopPlayback();
+
+   // Initialize the buffers
+   ClearBuffer_DW( MV_MixBuffer[ 0 ], SILENCE_8BIT, TotalBufferSize >> 2 );
+
+   // Set the mix buffer variables
+   MV_MixPage  = 0;
+
+   MV_RecordFunc = function;
+
+   // Start playback
+   switch( MV_SoundCard )
+      {
+      case SoundBlaster :
+      case Awe32 :
+         status = BLASTER_BeginBufferedRecord( MV_MixBuffer[ 0 ],
+            TotalBufferSize, NumberOfBuffers, MixRate, MONO_8BIT,
+            MV_ServiceRecord );
+
+         if ( status != BLASTER_Ok )
+            {
+            MV_SetErrorCode( MV_BlasterError );
+            return( MV_Error );
+            }
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         status = PAS_BeginBufferedRecord( MV_MixBuffer[ 0 ],
+            TotalBufferSize, NumberOfBuffers, MixRate, MONO_8BIT,
+            MV_ServiceRecord );
+
+         if ( status != PAS_Ok )
+            {
+            MV_SetErrorCode( MV_PasError );
+            return( MV_Error );
+            }
+         break;
+      }
+
+   MV_Recording = TRUE;
+   return( MV_Ok );
+#else
+   MV_SetErrorCode( MV_UnsupportedCard );
+   return( MV_Error );
+#endif
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_StopRecord
+
+   Stops the sound record engine.
+---------------------------------------------------------------------*/
+
+void MV_StopRecord
+   (
+   void
+   )
+
+   {
+#ifdef PLAT_DOS
+   // Stop sound playback
+   switch( MV_SoundCard )
+      {
+      case SoundBlaster :
+      case Awe32 :
+         BLASTER_StopPlayback();
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         PAS_StopPlayback();
+         break;
+      }
+
+   MV_Recording = FALSE;
+   MV_StartPlayback();
+#endif
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_StartDemandFeedPlayback
+
+   Plays a digitized sound from a user controlled buffering system.
+---------------------------------------------------------------------*/
+
+int MV_StartDemandFeedPlayback
+   (
+   void ( *function )( char **ptr, unsigned long *length ),
+   int rate,
+   int pitchoffset,
+   int vol,
+   int left,
+   int right,
+   int priority,
+   unsigned long callbackval
+   )
+
+   {
+   VoiceNode *voice;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   // Request a voice from the voice pool
+   voice = MV_AllocVoice( priority );
+   if ( voice == NULL )
+      {
+      MV_SetErrorCode( MV_NoVoices );
+      return( MV_Error );
+      }
+
+   voice->wavetype    = DemandFeed;
+   voice->bits        = 8;
+   voice->GetSound    = MV_GetNextDemandFeedBlock;
+   voice->NextBlock   = NULL;
+   voice->DemandFeed  = function;
+   voice->LoopStart   = NULL;
+   voice->LoopCount   = 0;
+   voice->BlockLength = 0;
+   voice->position    = 0;
+   voice->sound       = NULL;
+   voice->length      = 0;
+   voice->BlockLength = 0;
+   voice->Playing     = TRUE;
+   voice->next        = NULL;
+   voice->prev        = NULL;
+   voice->priority    = priority;
+   voice->callbackval = callbackval;
+
+   MV_SetVoicePitch( voice, rate, pitchoffset );
+   MV_SetVoiceVolume( voice, vol, left, right );
+   MV_PlayVoice( voice );
+
+   return( voice->handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_PlayRaw
+
+   Begin playback of sound data with the given sound levels and
+   priority.
+---------------------------------------------------------------------*/
+
+int MV_PlayRaw
+   (
+   char *ptr,
+   unsigned long length,
+   unsigned rate,
+   int   pitchoffset,
+   int   vol,
+   int   left,
+   int   right,
+   int   priority,
+   unsigned long callbackval
+   )
+
+   {
+   int status;
+
+   status = MV_PlayLoopedRaw( ptr, length, NULL, NULL, rate, pitchoffset,
+      vol, left, right, priority, callbackval );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_PlayLoopedRaw
+
+   Begin playback of sound data with the given sound levels and
+   priority.
+---------------------------------------------------------------------*/
+
+int MV_PlayLoopedRaw
+   (
+   char *ptr,
+   unsigned long length,
+   char *loopstart,
+   char *loopend,
+   unsigned rate,
+   int   pitchoffset,
+   int   vol,
+   int   left,
+   int   right,
+   int   priority,
+   unsigned long callbackval
+   )
+
+   {
+   VoiceNode *voice;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   // Request a voice from the voice pool
+   voice = MV_AllocVoice( priority );
+   if ( voice == NULL )
+      {
+      MV_SetErrorCode( MV_NoVoices );
+      return( MV_Error );
+      }
+
+   voice->wavetype    = Raw;
+   voice->bits        = 8;
+   voice->GetSound    = MV_GetNextRawBlock;
+   voice->Playing     = TRUE;
+   voice->NextBlock   = ptr;
+   voice->position    = 0;
+   voice->BlockLength = length;
+   voice->length      = 0;
+   voice->next        = NULL;
+   voice->prev        = NULL;
+   voice->priority    = priority;
+   voice->callbackval = callbackval;
+   voice->LoopStart   = loopstart;
+   voice->LoopEnd     = loopend;
+   voice->LoopSize    = ( voice->LoopEnd - voice->LoopStart ) + 1;
+
+   MV_SetVoicePitch( voice, rate, pitchoffset );
+   MV_SetVoiceVolume( voice, vol, left, right );
+   MV_PlayVoice( voice );
+
+   return( voice->handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_PlayWAV
+
+   Begin playback of sound data with the given sound levels and
+   priority.
+---------------------------------------------------------------------*/
+
+int MV_PlayWAV
+   (
+   char *ptr,
+   int   pitchoffset,
+   int   vol,
+   int   left,
+   int   right,
+   int   priority,
+   unsigned long callbackval
+   )
+
+   {
+   int status;
+
+   status = MV_PlayLoopedWAV( ptr, -1, -1, pitchoffset, vol, left, right,
+      priority, callbackval );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_PlayWAV3D
+
+   Begin playback of sound data at specified angle and distance
+   from listener.
+---------------------------------------------------------------------*/
+
+int MV_PlayWAV3D
+   (
+   char *ptr,
+   int  pitchoffset,
+   int  angle,
+   int  distance,
+   int  priority,
+   unsigned long callbackval
+   )
+
+   {
+   int left;
+   int right;
+   int mid;
+   int volume;
+   int status;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   if ( distance < 0 )
+      {
+      distance  = -distance;
+      angle    += MV_NumPanPositions / 2;
+      }
+
+   volume = MIX_VOLUME( distance );
+
+   // Ensure angle is within 0 - 31
+   angle &= MV_MaxPanPosition;
+
+   left  = MV_PanTable[ angle ][ volume ].left;
+   right = MV_PanTable[ angle ][ volume ].right;
+   mid   = max( 0, 255 - distance );
+
+   status = MV_PlayWAV( ptr, pitchoffset, mid, left, right, priority,
+      callbackval );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_PlayLoopedWAV
+
+   Begin playback of sound data with the given sound levels and
+   priority.
+---------------------------------------------------------------------*/
+
+int MV_PlayLoopedWAV
+   (
+   char *ptr,
+   long  loopstart,
+   long  loopend,
+   int   pitchoffset,
+   int   vol,
+   int   left,
+   int   right,
+   int   priority,
+   unsigned long callbackval
+   )
+
+   {
+   riff_header   *riff;
+   format_header *format;
+   data_header   *data;
+   VoiceNode     *voice;
+   int length;
+   int absloopend;
+   int absloopstart;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   riff = ( riff_header * )ptr;
+
+   if ( ( strncmp( riff->RIFF, "RIFF", 4 ) != 0 ) ||
+      ( strncmp( riff->WAVE, "WAVE", 4 ) != 0 ) ||
+      ( strncmp( riff->fmt, "fmt ", 4) != 0 ) )
+      {
+      MV_SetErrorCode( MV_InvalidWAVFile );
+      return( MV_Error );
+      }
+
+   format = ( format_header * )( riff + 1 );
+   data   = ( data_header * )( ( ( char * )format ) + riff->format_size );
+
+   // Check if it's PCM data.
+   if ( format->wFormatTag != 1 )
+      {
+      MV_SetErrorCode( MV_InvalidWAVFile );
+      return( MV_Error );
+      }
+
+   if ( format->nChannels != 1 )
+      {
+      MV_SetErrorCode( MV_InvalidWAVFile );
+      return( MV_Error );
+      }
+
+   if ( ( format->nBitsPerSample != 8 ) &&
+      ( format->nBitsPerSample != 16 ) )
+      {
+      MV_SetErrorCode( MV_InvalidWAVFile );
+      return( MV_Error );
+      }
+
+   if ( strncmp( data->DATA, "data", 4 ) != 0 )
+      {
+      MV_SetErrorCode( MV_InvalidWAVFile );
+      return( MV_Error );
+      }
+
+   // Request a voice from the voice pool
+   voice = MV_AllocVoice( priority );
+   if ( voice == NULL )
+      {
+      MV_SetErrorCode( MV_NoVoices );
+      return( MV_Error );
+      }
+
+   voice->wavetype    = WAV;
+   voice->bits        = format->nBitsPerSample;
+   voice->GetSound    = MV_GetNextWAVBlock;
+
+   length = data->size;
+   absloopstart = loopstart;
+   absloopend   = loopend;
+   if ( voice->bits == 16 )
+      {
+      loopstart  *= 2;
+      data->size &= ~1;
+      loopend    *= 2;
+      length     /= 2;
+      }
+
+   loopend    = min( loopend, (long)data->size );
+   absloopend = min( absloopend, length );
+
+   voice->Playing     = TRUE;
+   voice->DemandFeed  = NULL;
+   voice->LoopStart   = NULL;
+   voice->LoopCount   = 0;
+   voice->position    = 0;
+   voice->length      = 0;
+   voice->BlockLength = absloopend;
+   voice->NextBlock   = ( char * )( data + 1 );
+   voice->next        = NULL;
+   voice->prev        = NULL;
+   voice->priority    = priority;
+   voice->callbackval = callbackval;
+   voice->LoopStart   = voice->NextBlock + loopstart;
+   voice->LoopEnd     = voice->NextBlock + loopend;
+   voice->LoopSize    = absloopend - absloopstart;
+
+   if ( ( loopstart >= (long)data->size ) || ( loopstart < 0 ) )
+      {
+      voice->LoopStart = NULL;
+      voice->LoopEnd   = NULL;
+      voice->BlockLength = length;
+      }
+
+   MV_SetVoicePitch( voice, format->nSamplesPerSec, pitchoffset );
+   MV_SetVoiceVolume( voice, vol, left, right );
+   MV_PlayVoice( voice );
+
+   return( voice->handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_PlayVOC3D
+
+   Begin playback of sound data at specified angle and distance
+   from listener.
+---------------------------------------------------------------------*/
+
+int MV_PlayVOC3D
+   (
+   char *ptr,
+   int  pitchoffset,
+   int  angle,
+   int  distance,
+   int  priority,
+   unsigned long callbackval
+   )
+
+   {
+   int left;
+   int right;
+   int mid;
+   int volume;
+   int status;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   if ( distance < 0 )
+      {
+      distance  = -distance;
+      angle    += MV_NumPanPositions / 2;
+      }
+
+   volume = MIX_VOLUME( distance );
+
+   // Ensure angle is within 0 - 31
+   angle &= MV_MaxPanPosition;
+
+   left  = MV_PanTable[ angle ][ volume ].left;
+   right = MV_PanTable[ angle ][ volume ].right;
+   mid   = max( 0, 255 - distance );
+
+   status = MV_PlayVOC( ptr, pitchoffset, mid, left, right, priority,
+      callbackval );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_PlayVOC
+
+   Begin playback of sound data with the given sound levels and
+   priority.
+---------------------------------------------------------------------*/
+
+int MV_PlayVOC
+   (
+   char *ptr,
+   int   pitchoffset,
+   int   vol,
+   int   left,
+   int   right,
+   int   priority,
+   unsigned long callbackval
+   )
+
+   {
+   int status;
+
+   status = MV_PlayLoopedVOC( ptr, -1, -1, pitchoffset, vol, left, right,
+      priority, callbackval );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_PlayLoopedVOC
+
+   Begin playback of sound data with the given sound levels and
+   priority.
+---------------------------------------------------------------------*/
+
+int MV_PlayLoopedVOC
+   (
+   char *ptr,
+   long  loopstart,
+   long  loopend,
+   int   pitchoffset,
+   int   vol,
+   int   left,
+   int   right,
+   int   priority,
+   unsigned long callbackval
+   )
+
+   {
+   VoiceNode   *voice;
+   int          status;
+   unsigned short nextpos;
+
+   if ( !MV_Installed )
+      {
+      MV_SetErrorCode( MV_NotInstalled );
+      return( MV_Error );
+      }
+
+   // Make sure it's a valid VOC file.
+   status = strncmp( ptr, "Creative Voice File", 19 );
+   if ( status != 0 )
+      {
+      MV_SetErrorCode( MV_InvalidVOCFile );
+      return( MV_Error );
+      }
+
+   // Request a voice from the voice pool
+   voice = MV_AllocVoice( priority );
+   if ( voice == NULL )
+      {
+      MV_SetErrorCode( MV_NoVoices );
+      return( MV_Error );
+      }
+
+   voice->wavetype    = VOC;
+   voice->bits        = 8;
+   voice->GetSound    = MV_GetNextVOCBlock;
+
+   nextpos = *( unsigned short * )( ptr + 0x14 );
+   voice->NextBlock   = ptr + BUILDSWAP_INTEL16(nextpos);
+
+   voice->DemandFeed  = NULL;
+   voice->LoopStart   = NULL;
+   voice->LoopCount   = 0;
+   voice->BlockLength = 0;
+   voice->PitchScale  = PITCH_GetScale( pitchoffset );
+   voice->length      = 0;
+   voice->next        = NULL;
+   voice->prev        = NULL;
+   voice->priority    = priority;
+   voice->callbackval = callbackval;
+   voice->LoopStart   = ( char * )loopstart;
+   voice->LoopEnd     = ( char * )loopend;
+   voice->LoopSize    = loopend - loopstart + 1;
+
+   if ( loopstart < 0 )
+      {
+      voice->LoopStart = NULL;
+      voice->LoopEnd   = NULL;
+      }
+
+   MV_SetVoiceVolume( voice, vol, left, right );
+   MV_PlayVoice( voice );
+
+   return( voice->handle );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void MV_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_CreateVolumeTable
+
+   Create the table used to convert sound data to a specific volume
+   level.
+---------------------------------------------------------------------*/
+
+void MV_CreateVolumeTable
+   (
+   int index,
+   int volume,
+   int MaxVolume
+   )
+
+   {
+   int val;
+   int level;
+   int i;
+
+   level = ( volume * MaxVolume ) / MV_MaxTotalVolume;
+   if ( MV_Bits == 16 )
+      {
+      for( i = 0; i < 65536; i += 256 )
+         {
+         val   = i - 0x8000;
+         val  *= level;
+         val  /= MV_MaxVolume;
+         MV_VolumeTable[ index ][ i / 256 ] = val;
+         }
+      }
+   else
+      {
+      for( i = 0; i < 256; i++ )
+         {
+         val   = i - 0x80;
+         val  *= level;
+         val  /= MV_MaxVolume;
+         MV_VolumeTable[ volume ][ i ] = val;
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_CalcVolume
+
+   Create the table used to convert sound data to a specific volume
+   level.
+---------------------------------------------------------------------*/
+
+void MV_CalcVolume
+   (
+   int MaxVolume
+   )
+
+   {
+   int volume;
+
+   for( volume = 0; volume < 128; volume++ )
+      {
+      MV_HarshClipTable[ volume ] = 0;
+      MV_HarshClipTable[ volume + 384 ] = 255;
+      }
+   for( volume = 0; volume < 256; volume++ )
+      {
+      MV_HarshClipTable[ volume + 128 ] = volume;
+      }
+
+   // For each volume level, create a translation table with the
+   // appropriate volume calculated.
+   for( volume = 0; volume <= MV_MaxVolume; volume++ )
+      {
+      MV_CreateVolumeTable( volume, volume, MaxVolume );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_CalcPanTable
+
+   Create the table used to determine the stereo volume level of
+   a sound located at a specific angle and distance from the listener.
+---------------------------------------------------------------------*/
+
+void MV_CalcPanTable
+   (
+   void
+   )
+
+   {
+   int   level;
+   int   angle;
+   int   distance;
+   int   HalfAngle;
+   int   ramp;
+
+   HalfAngle = ( MV_NumPanPositions / 2 );
+
+   for( distance = 0; distance <= MV_MaxVolume; distance++ )
+      {
+      level = ( 255 * ( MV_MaxVolume - distance ) ) / MV_MaxVolume;
+      for( angle = 0; angle <= HalfAngle / 2; angle++ )
+         {
+         ramp = level - ( ( level * angle ) /
+            ( MV_NumPanPositions / 4 ) );
+
+         MV_PanTable[ angle ][ distance ].left = ramp;
+         MV_PanTable[ HalfAngle - angle ][ distance ].left = ramp;
+         MV_PanTable[ HalfAngle + angle ][ distance ].left = level;
+         MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].left = level;
+
+         MV_PanTable[ angle ][ distance ].right = level;
+         MV_PanTable[ HalfAngle - angle ][ distance ].right = level;
+         MV_PanTable[ HalfAngle + angle ][ distance ].right = ramp;
+         MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].right = ramp;
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetVolume
+
+   Sets the volume of digitized sound playback.
+---------------------------------------------------------------------*/
+
+void MV_SetVolume
+   (
+   int volume
+   )
+
+   {
+   volume = max( 0, volume );
+   volume = min( volume, MV_MaxTotalVolume );
+
+   MV_TotalVolume = volume;
+
+   // Calculate volume table
+   MV_CalcVolume( volume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_GetVolume
+
+   Returns the volume of digitized sound playback.
+---------------------------------------------------------------------*/
+
+int MV_GetVolume
+   (
+   void
+   )
+
+   {
+   return( MV_TotalVolume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetCallBack
+
+   Set the function to call when a voice stops.
+---------------------------------------------------------------------*/
+
+void MV_SetCallBack
+   (
+   void ( *function )( unsigned long )
+   )
+
+   {
+   MV_CallBackFunc = function;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_SetReverseStereo
+
+   Set the orientation of the left and right channels.
+---------------------------------------------------------------------*/
+
+void MV_SetReverseStereo
+   (
+   int setting
+   )
+
+   {
+   MV_SwapLeftRight = setting;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_GetReverseStereo
+
+   Returns the orientation of the left and right channels.
+---------------------------------------------------------------------*/
+
+int MV_GetReverseStereo
+   (
+   void
+   )
+
+   {
+   return( MV_SwapLeftRight );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_TestPlayback
+
+   Checks if playback has started.
+---------------------------------------------------------------------*/
+
+int MV_TestPlayback
+   (
+   void
+   )
+
+   {
+#ifdef PLAT_DOS
+   unsigned flags;
+   long time;
+   int  start;
+   int  status;
+   int  pos;
+
+   if ( MV_SoundCard == UltraSound )
+      {
+      return( MV_Ok );
+      }
+
+   flags = DisableInterrupts();
+   _enable();
+
+   status = MV_Error;
+   start  = MV_MixPage;
+   time   = clock() + CLOCKS_PER_SEC * 2;
+
+   while( clock() < time )
+      {
+      if ( MV_MixPage != start )
+         {
+         status = MV_Ok;
+         }
+      }
+
+   RestoreInterrupts( flags );
+
+   if ( status != MV_Ok )
+      {
+      // Just in case an error doesn't get reported
+      MV_SetErrorCode( MV_DMAFailure );
+
+      switch( MV_SoundCard )
+         {
+         case SoundBlaster :
+         case Awe32 :
+            pos = BLASTER_GetCurrentPos();
+            break;
+
+         case ProAudioSpectrum :
+         case SoundMan16 :
+            pos = PAS_GetCurrentPos();
+            break;
+
+         case SoundScape :
+            pos = SOUNDSCAPE_GetCurrentPos();
+            break;
+
+         #ifndef SOUNDSOURCE_OFF
+         case SoundSource :
+         case TandySoundSource :
+            MV_SetErrorCode( MV_SoundSourceFailure );
+            pos = -1;
+            break;
+         #endif
+
+         default :
+            MV_SetErrorCode( MV_UnsupportedCard );
+            pos = -2;
+            break;
+         }
+
+      if ( pos > 0 )
+         {
+         MV_SetErrorCode( MV_IrqFailure );
+         }
+      else if ( pos == 0 )
+         {
+         if ( MV_Bits == 16 )
+            {
+            MV_SetErrorCode( MV_DMA16Failure );
+            }
+         else
+            {
+            MV_SetErrorCode( MV_DMAFailure );
+            }
+         }
+      }
+
+   return( status );
+#else
+   return MV_Ok;
+#endif
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_Init
+
+   Perform the initialization of variables and memory used by
+   Multivoc.
+---------------------------------------------------------------------*/
+
+int MV_Init
+   (
+   int soundcard,
+   int MixRate,
+   int Voices,
+   int numchannels,
+   int samplebits
+   )
+
+   {
+   char *ptr;
+   int  status;
+   int  buffer;
+   int  index;
+
+   if ( MV_Installed )
+      {
+      MV_Shutdown();
+      }
+
+   MV_SetErrorCode( MV_Ok );
+
+   status = MV_LockMemory();
+   if ( status != MV_Ok )
+      {
+      return( status );
+      }
+
+   MV_TotalMemory = Voices * sizeof( VoiceNode ) + sizeof( HARSH_CLIP_TABLE_8 );
+   status = USRHOOKS_GetMem( ( void ** )&ptr, MV_TotalMemory );
+   if ( status != USRHOOKS_Ok )
+      {
+      MV_UnlockMemory();
+      MV_SetErrorCode( MV_NoMem );
+      return( MV_Error );
+      }
+
+   status = DPMI_LockMemory( ptr, MV_TotalMemory );
+   if ( status != DPMI_Ok )
+      {
+      USRHOOKS_FreeMem( ptr );
+      MV_UnlockMemory();
+      MV_SetErrorCode( MV_DPMI_Error );
+      return( MV_Error );
+      }
+
+   MV_Voices = ( VoiceNode * )ptr;
+   MV_HarshClipTable = ptr + ( MV_TotalMemory - sizeof( HARSH_CLIP_TABLE_8 ) );
+
+   // Set number of voices before calculating volume table
+   MV_MaxVoices = Voices;
+
+   LL_Reset( (VoiceNode *)&VoiceList, next, prev );
+   LL_Reset( (VoiceNode *)&VoicePool, next, prev );
+
+   for( index = 0; index < Voices; index++ )
+      {
+      LL_Add( (VoiceNode *)&VoicePool, &MV_Voices[ index ], next, prev );
+      }
+
+   // Allocate mix buffer within 1st megabyte
+   status = DPMI_GetDOSMemory( ( void ** )&ptr, &MV_BufferDescriptor,
+      2 * TotalBufferSize );
+
+   if ( status )
+      {
+      DPMI_UnlockMemory( MV_Voices, MV_TotalMemory );
+      USRHOOKS_FreeMem( MV_Voices );
+      MV_Voices      = NULL;
+      MV_TotalMemory = 0;
+      MV_UnlockMemory();
+
+      MV_SetErrorCode( MV_NoMem );
+      return( MV_Error );
+      }
+
+   MV_SetReverseStereo( FALSE );
+
+   // Initialize the sound card
+#ifdef PLAT_DOS
+   switch( soundcard )
+      {
+      case UltraSound :
+         status = GUSWAVE_Init( 2 );
+         if ( status != GUSWAVE_Ok )
+            {
+            //JIM
+            MV_SetErrorCode( MV_BlasterError );
+            }
+         break;
+
+      case SoundBlaster :
+      case Awe32 :
+         status = BLASTER_Init();
+         if ( status != BLASTER_Ok )
+            {
+            MV_SetErrorCode( MV_BlasterError );
+            }
+
+         if ( ( BLASTER_Config.Type == SBPro ) ||
+            ( BLASTER_Config.Type == SBPro2 ) )
+            {
+            MV_SetReverseStereo( TRUE );
+            }
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         status = PAS_Init();
+         if ( status != PAS_Ok )
+            {
+            MV_SetErrorCode( MV_PasError );
+            }
+         break;
+
+      case SoundScape :
+         status = SOUNDSCAPE_Init();
+         if ( status != SOUNDSCAPE_Ok )
+            {
+            MV_SetErrorCode( MV_SoundScapeError );
+            }
+         break;
+
+      #ifndef SOUNDSOURCE_OFF
+      case SoundSource :
+      case TandySoundSource :
+         status = SS_Init( soundcard );
+         if ( status != SS_Ok )
+            {
+            MV_SetErrorCode( MV_SoundSourceError );
+            }
+         break;
+      #endif
+
+      default :
+         MV_SetErrorCode( MV_UnsupportedCard );
+         break;
+      }
+#else
+   status = DSL_Init();
+   if ( status != DSL_Ok )
+      {
+      MV_SetErrorCode( MV_BlasterError );
+      }
+#endif
+
+   if ( MV_ErrorCode != MV_Ok )
+      {
+      status = MV_ErrorCode;
+
+      DPMI_UnlockMemory( MV_Voices, MV_TotalMemory );
+      USRHOOKS_FreeMem( MV_Voices );
+      MV_Voices      = NULL;
+      MV_TotalMemory = 0;
+
+      DPMI_FreeDOSMemory( MV_BufferDescriptor );
+      MV_UnlockMemory();
+
+      MV_SetErrorCode( status );
+      return( MV_Error );
+      }
+
+   MV_SoundCard    = soundcard;
+   MV_Installed    = TRUE;
+   MV_CallBackFunc = NULL;
+   MV_RecordFunc   = NULL;
+   MV_Recording    = FALSE;
+   MV_ReverbLevel  = 0;
+   MV_ReverbTable  = NULL;
+
+   // Set the sampling rate
+   MV_RequestedMixRate = MixRate;
+
+   // Set Mixer to play stereo digitized sound
+   MV_SetMixMode( numchannels, samplebits );
+   MV_ReverbDelay = MV_BufferSize * 3;
+
+#ifdef PLAT_DOS
+   // Make sure we don't cross a physical page
+   if ( ( ( unsigned long )ptr & 0xffff ) + TotalBufferSize > 0x10000 )
+      {
+      ptr = ( char * )( ( ( unsigned long )ptr & 0xff0000 ) + 0x10000 );
+      }
+#endif
+
+   MV_MixBuffer[ MV_NumberOfBuffers ] = ptr;
+   for( buffer = 0; buffer < MV_NumberOfBuffers; buffer++ )
+      {
+      MV_MixBuffer[ buffer ] = ptr;
+      ptr += MV_BufferSize;
+      }
+
+   // Calculate pan table
+   MV_CalcPanTable();
+
+   MV_SetVolume( MV_MaxTotalVolume );
+
+   // Start the playback engine
+   status = MV_StartPlayback();
+   if ( status != MV_Ok )
+      {
+      // Preserve error code while we shutdown.
+      status = MV_ErrorCode;
+      MV_Shutdown();
+      MV_SetErrorCode( status );
+      return( MV_Error );
+      }
+
+   if ( MV_TestPlayback() != MV_Ok )
+      {
+      status = MV_ErrorCode;
+      MV_Shutdown();
+      MV_SetErrorCode( status );
+      return( MV_Error );
+      }
+
+   return( MV_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_Shutdown
+
+   Restore any resources allocated by Multivoc back to the system.
+---------------------------------------------------------------------*/
+
+int MV_Shutdown
+   (
+   void
+   )
+
+   {
+   int      buffer;
+   unsigned flags;
+
+   if ( !MV_Installed )
+      {
+      return( MV_Ok );
+      }
+
+   flags = DisableInterrupts();
+
+   MV_KillAllVoices();
+
+   MV_Installed = FALSE;
+
+   // Stop the sound recording engine
+   if ( MV_Recording )
+      {
+      MV_StopRecord();
+      }
+
+   // Stop the sound playback engine
+   MV_StopPlayback();
+
+   // Shutdown the sound card
+#ifdef PLAT_DOS
+   switch( MV_SoundCard )
+      {
+      case UltraSound :
+         GUSWAVE_Shutdown();
+         break;
+
+      case SoundBlaster :
+      case Awe32 :
+         BLASTER_Shutdown();
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         PAS_Shutdown();
+         break;
+
+      case SoundScape :
+         SOUNDSCAPE_Shutdown();
+         break;
+
+      #ifndef SOUNDSOURCE_OFF
+      case SoundSource :
+      case TandySoundSource :
+         SS_Shutdown();
+         break;
+      #endif
+      }
+#else
+   DSL_Shutdown();
+#endif
+
+   RestoreInterrupts( flags );
+
+   // Free any voices we allocated
+   DPMI_UnlockMemory( MV_Voices, MV_TotalMemory );
+   USRHOOKS_FreeMem( MV_Voices );
+   MV_Voices      = NULL;
+   MV_TotalMemory = 0;
+
+   LL_Reset( (VoiceNode *)&VoiceList, next, prev );
+   LL_Reset( (VoiceNode *)&VoicePool, next, prev );
+
+   MV_MaxVoices = 1;
+
+   // Release the descriptor from our mix buffer
+   DPMI_FreeDOSMemory( MV_BufferDescriptor );
+   for( buffer = 0; buffer < NumberOfBuffers; buffer++ )
+      {
+      MV_MixBuffer[ buffer ] = NULL;
+      }
+
+   return( MV_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_UnlockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+void MV_UnlockMemory
+   (
+   void
+   )
+
+   {
+   PITCH_UnlockMemory();
+
+   DPMI_UnlockMemoryRegion( MV_LockStart, MV_LockEnd );
+   DPMI_Unlock( MV_VolumeTable );
+   DPMI_Unlock( MV_PanTable );
+   DPMI_Unlock( MV_Installed );
+   DPMI_Unlock( MV_SoundCard );
+   DPMI_Unlock( MV_TotalVolume );
+   DPMI_Unlock( MV_MaxVoices );
+   DPMI_Unlock( MV_BufferSize );
+   DPMI_Unlock( MV_BufferLength );
+   DPMI_Unlock( MV_SampleSize );
+   DPMI_Unlock( MV_NumberOfBuffers );
+   DPMI_Unlock( MV_MixMode );
+   DPMI_Unlock( MV_Channels );
+   DPMI_Unlock( MV_Bits );
+   DPMI_Unlock( MV_Silence );
+   DPMI_Unlock( MV_SwapLeftRight );
+   DPMI_Unlock( MV_RequestedMixRate );
+   DPMI_Unlock( MV_MixRate );
+   DPMI_Unlock( MV_BufferDescriptor );
+   DPMI_Unlock( MV_MixBuffer );
+   DPMI_Unlock( MV_BufferEmpty );
+   DPMI_Unlock( MV_Voices );
+   DPMI_Unlock( VoiceList );
+   DPMI_Unlock( VoicePool );
+   DPMI_Unlock( MV_MixPage );
+   DPMI_Unlock( MV_VoiceHandle );
+   DPMI_Unlock( MV_CallBackFunc );
+   DPMI_Unlock( MV_RecordFunc );
+   DPMI_Unlock( MV_Recording );
+   DPMI_Unlock( MV_MixFunction );
+   DPMI_Unlock( MV_HarshClipTable );
+   DPMI_Unlock( MV_MixDestination );
+   DPMI_Unlock( MV_LeftVolume );
+   DPMI_Unlock( MV_RightVolume );
+   DPMI_Unlock( MV_MixPosition );
+   DPMI_Unlock( MV_ErrorCode );
+   DPMI_Unlock( MV_DMAChannel );
+   DPMI_Unlock( MV_BuffShift );
+   DPMI_Unlock( MV_ReverbLevel );
+   DPMI_Unlock( MV_ReverbDelay );
+   DPMI_Unlock( MV_ReverbTable );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MV_LockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+int MV_LockMemory
+   (
+   void
+   )
+
+   {
+   int status;
+   int pitchstatus;
+
+   status  = DPMI_LockMemoryRegion( MV_LockStart, MV_LockEnd );
+   status |= DPMI_Lock( MV_VolumeTable );
+   status |= DPMI_Lock( MV_PanTable );
+   status |= DPMI_Lock( MV_Installed );
+   status |= DPMI_Lock( MV_SoundCard );
+   status |= DPMI_Lock( MV_TotalVolume );
+   status |= DPMI_Lock( MV_MaxVoices );
+   status |= DPMI_Lock( MV_BufferSize );
+   status |= DPMI_Lock( MV_BufferLength );
+   status |= DPMI_Lock( MV_SampleSize );
+   status |= DPMI_Lock( MV_NumberOfBuffers );
+   status |= DPMI_Lock( MV_MixMode );
+   status |= DPMI_Lock( MV_Channels );
+   status |= DPMI_Lock( MV_Bits );
+   status |= DPMI_Lock( MV_Silence );
+   status |= DPMI_Lock( MV_SwapLeftRight );
+   status |= DPMI_Lock( MV_RequestedMixRate );
+   status |= DPMI_Lock( MV_MixRate );
+   status |= DPMI_Lock( MV_BufferDescriptor );
+   status |= DPMI_Lock( MV_MixBuffer );
+   status |= DPMI_Lock( MV_BufferEmpty );
+   status |= DPMI_Lock( MV_Voices );
+   status |= DPMI_Lock( VoiceList );
+   status |= DPMI_Lock( VoicePool );
+   status |= DPMI_Lock( MV_MixPage );
+   status |= DPMI_Lock( MV_VoiceHandle );
+   status |= DPMI_Lock( MV_CallBackFunc );
+   status |= DPMI_Lock( MV_RecordFunc );
+   status |= DPMI_Lock( MV_Recording );
+   status |= DPMI_Lock( MV_MixFunction );
+   status |= DPMI_Lock( MV_HarshClipTable );
+   status |= DPMI_Lock( MV_MixDestination );
+   status |= DPMI_Lock( MV_LeftVolume );
+   status |= DPMI_Lock( MV_RightVolume );
+   status |= DPMI_Lock( MV_MixPosition );
+   status |= DPMI_Lock( MV_ErrorCode );
+   status |= DPMI_Lock( MV_DMAChannel );
+   status |= DPMI_Lock( MV_BuffShift );
+   status |= DPMI_Lock( MV_ReverbLevel );
+   status |= DPMI_Lock( MV_ReverbDelay );
+   status |= DPMI_Lock( MV_ReverbTable );
+
+   pitchstatus = PITCH_LockMemory();
+   if ( ( pitchstatus != PITCH_Ok ) || ( status != DPMI_Ok ) )
+      {
+      MV_UnlockMemory();
+      MV_SetErrorCode( MV_DPMI_Error );
+      return( MV_Error );
+      }
+
+   return( MV_Ok );
+   }
+
+#ifndef PLAT_DOS
+void ClearBuffer_DW( void *ptr, unsigned data, int length )
+{
+	unsigned *d = (unsigned *)ptr;
+	
+	while (length--) {
+		*d = data;
+		
+		d++;
+	}
+}
+#endif

Added: tags/rott-1.1/rott/audiolib/multivoc.h
===================================================================
--- tags/rott-1.1/rott/audiolib/multivoc.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/multivoc.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,123 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   file:   MULTIVOC.H
+
+   author: James R. Dose
+   date:   December 20, 1993
+
+   Public header for MULTIVOC.C
+
+   (c) Copyright 1993 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __MULTIVOC_H
+#define __MULTIVOC_H
+
+// platform.h is in buildengine, but I need the byteswapping macros... --ryan.
+#include "platform.h"
+
+#define MV_MinVoiceHandle  1
+
+extern int MV_ErrorCode;
+
+enum MV_Errors
+   {
+   MV_Warning = -2,
+   MV_Error   = -1,
+   MV_Ok      = 0,
+   MV_UnsupportedCard,
+   MV_NotInstalled,
+   MV_NoVoices,
+   MV_NoMem,
+   MV_VoiceNotFound,
+   MV_BlasterError,
+   MV_PasError,
+   MV_SoundScapeError,
+   MV_SoundSourceError,
+   MV_DPMI_Error,
+   MV_InvalidVOCFile,
+   MV_InvalidWAVFile,
+   MV_InvalidMixMode,
+   MV_SoundSourceFailure,
+   MV_IrqFailure,
+   MV_DMAFailure,
+   MV_DMA16Failure,
+   MV_NullRecordFunction
+   };
+
+char *MV_ErrorString( int ErrorNumber );
+int   MV_VoicePlaying( int handle );
+int   MV_KillAllVoices( void );
+int   MV_Kill( int handle );
+int   MV_VoicesPlaying( void );
+int   MV_VoiceAvailable( int priority );
+int   MV_SetPitch( int handle, int pitchoffset );
+int   MV_SetFrequency( int handle, int frequency );
+int   MV_EndLooping( int handle );
+int   MV_SetPan( int handle, int vol, int left, int right );
+int   MV_Pan3D( int handle, int angle, int distance );
+void  MV_SetReverb( int reverb );
+void  MV_SetFastReverb( int reverb );
+int   MV_GetMaxReverbDelay( void );
+int   MV_GetReverbDelay( void );
+void  MV_SetReverbDelay( int delay );
+int   MV_SetMixMode( int numchannels, int samplebits );
+int   MV_StartPlayback( void );
+void  MV_StopPlayback( void );
+int   MV_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) );
+void  MV_StopRecord( void );
+int   MV_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ),
+         int rate, int pitchoffset, int vol, int left, int right,
+         int priority, unsigned long callbackval );
+int   MV_PlayRaw( char *ptr, unsigned long length,
+         unsigned rate, int pitchoffset, int vol, int left,
+         int right, int priority, unsigned long callbackval );
+int   MV_PlayLoopedRaw( char *ptr, unsigned long length,
+         char *loopstart, char *loopend, unsigned rate, int pitchoffset,
+         int vol, int left, int right, int priority,
+         unsigned long callbackval );
+int   MV_PlayWAV( char *ptr, int pitchoffset, int vol, int left,
+         int right, int priority, unsigned long callbackval );
+int   MV_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance,
+         int priority, unsigned long callbackval );
+int   MV_PlayLoopedWAV( char *ptr, long loopstart, long loopend,
+         int pitchoffset, int vol, int left, int right, int priority,
+         unsigned long callbackval );
+int   MV_PlayVOC3D( char *ptr, int pitchoffset, int angle, int distance,
+         int priority, unsigned long callbackval );
+int   MV_PlayVOC( char *ptr, int pitchoffset, int vol, int left, int right,
+         int priority, unsigned long callbackval );
+int   MV_PlayLoopedVOC( char *ptr, long loopstart, long loopend,
+         int pitchoffset, int vol, int left, int right, int priority,
+         unsigned long callbackval );
+void  MV_CreateVolumeTable( int index, int volume, int MaxVolume );
+void  MV_SetVolume( int volume );
+int   MV_GetVolume( void );
+void  MV_SetCallBack( void ( *function )( unsigned long ) );
+void  MV_SetReverseStereo( int setting );
+int   MV_GetReverseStereo( void );
+int   MV_Init( int soundcard, int MixRate, int Voices, int numchannels,
+         int samplebits );
+int   MV_Shutdown( void );
+void  MV_UnlockMemory( void );
+int   MV_LockMemory( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/music.c
===================================================================
--- tags/rott-1.1/rott/audiolib/music.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/music.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1035 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: MUSIC.C
+
+   author: James R. Dose
+   date:   March 25, 1994
+
+   Device independant music playback routines.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "task_man.h"
+#include "sndcards.h"
+#include "music.h"
+#include "midi.h"
+#include "al_midi.h"
+#include "pas16.h"
+#include "blaster.h"
+#include "gusmidi.h"
+#include "mpu401.h"
+#include "awe32.h"
+#include "sndscape.h"
+#include "ll_man.h"
+#include "user.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+void TextMode( void );
+#pragma aux TextMode =  \
+    "mov    ax, 0003h", \
+    "int    10h"        \
+    modify [ ax ];
+
+int MUSIC_SoundDevice = -1;
+int MUSIC_ErrorCode = MUSIC_Ok;
+
+static midifuncs MUSIC_MidiFunctions;
+
+static int       MUSIC_FadeLength;
+static int       MUSIC_FadeRate;
+static unsigned  MUSIC_CurrentFadeVolume;
+static unsigned  MUSIC_LastFadeVolume;
+static int       MUSIC_EndingFadeVolume;
+static task     *MUSIC_FadeTask = NULL;
+
+int MUSIC_InitAWE32( midifuncs *Funcs );
+int MUSIC_InitFM( int card, midifuncs *Funcs );
+int MUSIC_InitMidi( int card, midifuncs *Funcs, int Address );
+int MUSIC_InitGUS( midifuncs *Funcs );
+
+#define MUSIC_SetErrorCode( status ) \
+   MUSIC_ErrorCode = ( status );
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *MUSIC_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case MUSIC_Warning :
+      case MUSIC_Error :
+         ErrorString = MUSIC_ErrorString( MUSIC_ErrorCode );
+         break;
+
+      case MUSIC_Ok :
+         ErrorString = "Music ok.";
+         break;
+
+      case MUSIC_ASSVersion :
+         ErrorString = "Apogee Sound System Version " ASS_VERSION_STRING "  "
+            "Programmed by Jim Dose\n"
+            "(c) Copyright 1996 James R. Dose.  All Rights Reserved.\n";
+         break;
+
+      case MUSIC_SoundCardError :
+         switch( MUSIC_SoundDevice )
+         {
+            case SoundBlaster :
+            case WaveBlaster :
+               ErrorString = BLASTER_ErrorString( BLASTER_Error );
+               break;
+
+            case ProAudioSpectrum :
+            case SoundMan16 :
+               ErrorString = PAS_ErrorString( PAS_Error );
+               break;
+
+            case Adlib :
+               ErrorString = "Adlib error.";
+               break;
+
+            case GenMidi :
+            case SoundCanvas :
+               ErrorString = "Could not detect MPU-401.";
+               break;
+
+            case SoundScape :
+               ErrorString = SOUNDSCAPE_ErrorString( SOUNDSCAPE_Error );
+               break;
+
+            case Awe32 :
+               ErrorString = AWE32_ErrorString( AWE32_Error );
+               break;
+
+            case UltraSound :
+               ErrorString = GUS_ErrorString( GUS_Error );
+               break;
+
+            default :
+               ErrorString = MUSIC_ErrorString( MUSIC_InvalidCard );
+               break;
+            }
+         break;
+
+      case MUSIC_MPU401Error :
+         ErrorString = "Could not detect MPU-401.";
+         break;
+
+      case MUSIC_InvalidCard :
+         ErrorString = "Invalid Music device.";
+         break;
+
+      case MUSIC_MidiError :
+         ErrorString = "Error playing MIDI file.";
+         break;
+
+      case MUSIC_TaskManError :
+         ErrorString = "TaskMan error.";
+         break;
+
+      case MUSIC_FMNotDetected :
+         ErrorString = "Could not detect FM chip.";
+         break;
+
+      case MUSIC_DPMI_Error :
+         ErrorString = "DPMI Error in MUSIC.";
+         break;
+
+      default :
+         ErrorString = "Unknown Music error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_Init
+
+   Selects which sound device to use.
+---------------------------------------------------------------------*/
+
+int MUSIC_Init
+   (
+   int SoundCard,
+   int Address
+   )
+
+   {
+   int i;
+   int status;
+
+   if ( USER_CheckParameter( "ASSVER" ) )
+      {
+      MUSIC_SetErrorCode( MUSIC_ASSVersion );
+      return( MUSIC_Error );
+      }
+
+   status = LL_LockMemory();
+   if ( status != LL_Ok )
+      {
+      MUSIC_SetErrorCode( MUSIC_DPMI_Error );
+      return( MUSIC_Error );
+      }
+
+   for( i = 0; i < 128; i++ )
+      {
+      MIDI_PatchMap[ i ] = i;
+      }
+
+   status = MUSIC_Ok;
+   MUSIC_SoundDevice = SoundCard;
+
+   switch( SoundCard )
+      {
+      case SoundBlaster :
+      case Adlib :
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         status = MUSIC_InitFM( SoundCard, &MUSIC_MidiFunctions );
+         break;
+
+      case GenMidi :
+      case SoundCanvas :
+      case WaveBlaster :
+      case SoundScape :
+         status = MUSIC_InitMidi( SoundCard, &MUSIC_MidiFunctions, Address );
+         break;
+
+      case Awe32 :
+         status = MUSIC_InitAWE32( &MUSIC_MidiFunctions );
+         break;
+
+      case UltraSound :
+         status = MUSIC_InitGUS( &MUSIC_MidiFunctions );
+         break;
+
+      case SoundSource :
+      case PC :
+      default :
+         MUSIC_SetErrorCode( MUSIC_InvalidCard );
+         status = MUSIC_Error;
+      }
+
+   if ( status != MUSIC_Ok )
+      {
+      LL_UnlockMemory();
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_Shutdown
+
+   Terminates use of sound device.
+---------------------------------------------------------------------*/
+
+int MUSIC_Shutdown
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status = MUSIC_Ok;
+
+   MIDI_StopSong();
+
+   if ( MUSIC_FadeTask != NULL )
+      {
+      MUSIC_StopFade();
+      }
+
+   switch ( MUSIC_SoundDevice )
+      {
+      case Adlib :
+         AL_Shutdown();
+         break;
+
+      case SoundBlaster :
+         AL_Shutdown();
+         BLASTER_RestoreMidiVolume();
+         break;
+
+      case GenMidi :
+      case SoundCanvas :
+      case SoundScape :
+         MPU_Reset();
+         break;
+
+      case WaveBlaster :
+         BLASTER_ShutdownWaveBlaster();
+         MPU_Reset();
+         BLASTER_RestoreMidiVolume();
+         break;
+
+      case Awe32 :
+         AWE32_Shutdown();
+         BLASTER_RestoreMidiVolume();
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         AL_Shutdown();
+         PAS_RestoreMusicVolume();
+         break;
+
+      case UltraSound :
+         GUSMIDI_Shutdown();
+         break;
+      }
+
+   LL_UnlockMemory();
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_SetMaxFMMidiChannel
+
+   Sets the maximum MIDI channel that FM cards respond to.
+---------------------------------------------------------------------*/
+
+void MUSIC_SetMaxFMMidiChannel
+   (
+   int channel
+   )
+
+   {
+   AL_SetMaxMidiChannel( channel );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_SetVolume
+
+   Sets the volume of music playback.
+---------------------------------------------------------------------*/
+
+void MUSIC_SetVolume
+   (
+   int volume
+   )
+
+   {
+   volume = max( 0, volume );
+   volume = min( volume, 255 );
+
+   if ( MUSIC_SoundDevice != -1 )
+      {
+      MIDI_SetVolume( volume );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_SetMidiChannelVolume
+
+   Sets the volume of music playback on the specified MIDI channel.
+---------------------------------------------------------------------*/
+
+void MUSIC_SetMidiChannelVolume
+   (
+   int channel,
+   int volume
+   )
+
+   {
+   MIDI_SetUserChannelVolume( channel, volume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_ResetMidiChannelVolumes
+
+   Sets the volume of music playback on all MIDI channels to full volume.
+---------------------------------------------------------------------*/
+
+void MUSIC_ResetMidiChannelVolumes
+   (
+   void
+   )
+
+   {
+   MIDI_ResetUserChannelVolume();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_GetVolume
+
+   Returns the volume of music playback.
+---------------------------------------------------------------------*/
+
+int MUSIC_GetVolume
+   (
+   void
+   )
+
+   {
+   if ( MUSIC_SoundDevice == -1 )
+      {
+      return( 0 );
+      }
+   return( MIDI_GetVolume() );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_SetLoopFlag
+
+   Set whether the music will loop or end when it reaches the end of
+   the song.
+---------------------------------------------------------------------*/
+
+void MUSIC_SetLoopFlag
+   (
+   int loopflag
+   )
+
+   {
+   MIDI_SetLoopFlag( loopflag );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_SongPlaying
+
+   Returns whether there is a song playing.
+---------------------------------------------------------------------*/
+
+int MUSIC_SongPlaying
+   (
+   void
+   )
+
+   {
+   return( MIDI_SongPlaying() );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_Continue
+
+   Continues playback of a paused song.
+---------------------------------------------------------------------*/
+
+void MUSIC_Continue
+   (
+   void
+   )
+
+   {
+   MIDI_ContinueSong();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_Pause
+
+   Pauses playback of a song.
+---------------------------------------------------------------------*/
+
+void MUSIC_Pause
+   (
+   void
+   )
+
+   {
+   MIDI_PauseSong();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_StopSong
+
+   Stops playback of current song.
+---------------------------------------------------------------------*/
+
+int MUSIC_StopSong
+   (
+   void
+   )
+
+   {
+   MUSIC_StopFade();
+   MIDI_StopSong();
+   MUSIC_SetErrorCode( MUSIC_Ok );
+   return( MUSIC_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_PlaySong
+
+   Begins playback of MIDI song.
+---------------------------------------------------------------------*/
+
+int MUSIC_PlaySong
+   (
+   unsigned char *song,
+   int loopflag
+   )
+
+   {
+   int status;
+
+   switch( MUSIC_SoundDevice )
+      {
+      case SoundBlaster :
+      case Adlib :
+      case ProAudioSpectrum :
+      case SoundMan16 :
+      case GenMidi :
+      case SoundCanvas :
+      case WaveBlaster :
+      case SoundScape :
+      case Awe32 :
+      case UltraSound :
+         MIDI_StopSong();
+         status = MIDI_PlaySong( song, loopflag );
+         if ( status != MIDI_Ok )
+            {
+            MUSIC_SetErrorCode( MUSIC_MidiError );
+            return( MUSIC_Warning );
+            }
+         break;
+
+      case SoundSource :
+      case PC :
+      default :
+         MUSIC_SetErrorCode( MUSIC_InvalidCard );
+         return( MUSIC_Warning );
+         break;
+      }
+
+   return( MUSIC_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_SetContext
+
+   Sets the song context.
+---------------------------------------------------------------------*/
+
+void MUSIC_SetContext
+   (
+   int context
+   )
+
+   {
+   MIDI_SetContext( context );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_GetContext
+
+   Returns the current song context.
+---------------------------------------------------------------------*/
+
+int MUSIC_GetContext
+   (
+   void
+   )
+
+   {
+   return MIDI_GetContext();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_SetSongTick
+
+   Sets the position of the song pointer.
+---------------------------------------------------------------------*/
+
+void MUSIC_SetSongTick
+   (
+   unsigned long PositionInTicks
+   )
+
+   {
+   MIDI_SetSongTick( PositionInTicks );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_SetSongTime
+
+   Sets the position of the song pointer.
+---------------------------------------------------------------------*/
+
+void MUSIC_SetSongTime
+   (
+   unsigned long milliseconds
+   )
+
+   {
+   MIDI_SetSongTime( milliseconds );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_SetSongPosition
+
+   Sets the position of the song pointer.
+---------------------------------------------------------------------*/
+
+void MUSIC_SetSongPosition
+   (
+   int measure,
+   int beat,
+   int tick
+   )
+
+   {
+   MIDI_SetSongPosition( measure, beat, tick );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_GetSongPosition
+
+   Returns the position of the song pointer.
+---------------------------------------------------------------------*/
+
+void MUSIC_GetSongPosition
+   (
+   songposition *pos
+   )
+
+   {
+   MIDI_GetSongPosition( pos );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_GetSongLength
+
+   Returns the length of the song.
+---------------------------------------------------------------------*/
+
+void MUSIC_GetSongLength
+   (
+   songposition *pos
+   )
+
+   {
+   MIDI_GetSongLength( pos );
+   }
+
+
+int MUSIC_InitAWE32
+   (
+   midifuncs *Funcs
+   )
+
+   {
+   int status;
+
+   status = AWE32_Init();
+   if ( status != AWE32_Ok )
+      {
+      MUSIC_SetErrorCode( MUSIC_SoundCardError );
+      return( MUSIC_Error );
+      }
+
+   Funcs->NoteOff           = AWE32_NoteOff;
+   Funcs->NoteOn            = AWE32_NoteOn;
+   Funcs->PolyAftertouch    = AWE32_PolyAftertouch;
+   Funcs->ControlChange     = AWE32_ControlChange;
+   Funcs->ProgramChange     = AWE32_ProgramChange;
+   Funcs->ChannelAftertouch = AWE32_ChannelAftertouch;
+   Funcs->PitchBend         = AWE32_PitchBend;
+   Funcs->ReleasePatches    = NULL;
+   Funcs->LoadPatch         = NULL;
+   Funcs->SetVolume         = NULL;
+   Funcs->GetVolume         = NULL;
+
+   if ( BLASTER_CardHasMixer() )
+      {
+      BLASTER_SaveMidiVolume();
+      Funcs->SetVolume = BLASTER_SetMidiVolume;
+      Funcs->GetVolume = BLASTER_GetMidiVolume;
+      }
+
+   status = MUSIC_Ok;
+   MIDI_SetMidiFuncs( Funcs );
+
+   return( status );
+   }
+
+
+int MUSIC_InitFM
+   (
+   int card,
+   midifuncs *Funcs
+   )
+
+   {
+   int status;
+   int passtatus;
+
+   status = MIDI_Ok;
+
+   if ( !AL_DetectFM() )
+      {
+      MUSIC_SetErrorCode( MUSIC_FMNotDetected );
+      return( MUSIC_Error );
+      }
+
+   // Init the fm routines
+   AL_Init( card );
+
+   Funcs->NoteOff           = AL_NoteOff;
+   Funcs->NoteOn            = AL_NoteOn;
+   Funcs->PolyAftertouch    = NULL;
+   Funcs->ControlChange     = AL_ControlChange;
+   Funcs->ProgramChange     = AL_ProgramChange;
+   Funcs->ChannelAftertouch = NULL;
+   Funcs->PitchBend         = AL_SetPitchBend;
+   Funcs->ReleasePatches    = NULL;
+   Funcs->LoadPatch         = NULL;
+   Funcs->SetVolume         = NULL;
+   Funcs->GetVolume         = NULL;
+
+   switch( card )
+      {
+      case SoundBlaster :
+         if ( BLASTER_CardHasMixer() )
+            {
+            BLASTER_SaveMidiVolume();
+            Funcs->SetVolume = BLASTER_SetMidiVolume;
+            Funcs->GetVolume = BLASTER_GetMidiVolume;
+            }
+         else
+            {
+            Funcs->SetVolume = NULL;
+            Funcs->GetVolume = NULL;
+            }
+         break;
+
+      case Adlib :
+         Funcs->SetVolume = NULL;
+         Funcs->GetVolume = NULL;
+         break;
+
+      case ProAudioSpectrum :
+      case SoundMan16 :
+         Funcs->SetVolume = NULL;
+         Funcs->GetVolume = NULL;
+
+         passtatus = PAS_SaveMusicVolume();
+         if ( passtatus == PAS_Ok )
+            {
+            Funcs->SetVolume = PAS_SetFMVolume;
+            Funcs->GetVolume = PAS_GetFMVolume;
+            }
+         break;
+      }
+
+   MIDI_SetMidiFuncs( Funcs );
+
+   return( status );
+   }
+
+int MUSIC_InitMidi
+   (
+   int        card,
+   midifuncs *Funcs,
+   int        Address
+   )
+
+   {
+   int status;
+
+   status = MUSIC_Ok;
+
+   if ( ( card == WaveBlaster ) || ( card == SoundCanvas ) ||
+      ( card == GenMidi ) )
+      {
+      // Setup WaveBlaster Daughterboard clone
+      // (ie. SoundCanvas DB, TurtleBeach Rio)
+      BLASTER_SetupWaveBlaster();
+      }
+
+   if ( card == SoundScape )
+      {
+      Address = SOUNDSCAPE_GetMIDIPort();
+      if ( Address < SOUNDSCAPE_Ok )
+         {
+         MUSIC_SetErrorCode( MUSIC_SoundCardError );
+         return( MUSIC_Error );
+         }
+      }
+
+   if ( MPU_Init( Address ) != MPU_Ok )
+      {
+      MUSIC_SetErrorCode( MUSIC_MPU401Error );
+      return( MUSIC_Error );
+      }
+
+   Funcs->NoteOff           = MPU_NoteOff;
+   Funcs->NoteOn            = MPU_NoteOn;
+   Funcs->PolyAftertouch    = MPU_PolyAftertouch;
+   Funcs->ControlChange     = MPU_ControlChange;
+   Funcs->ProgramChange     = MPU_ProgramChange;
+   Funcs->ChannelAftertouch = MPU_ChannelAftertouch;
+   Funcs->PitchBend         = MPU_PitchBend;
+   Funcs->ReleasePatches    = NULL;
+   Funcs->LoadPatch         = NULL;
+   Funcs->SetVolume         = NULL;
+   Funcs->GetVolume         = NULL;
+
+   if ( card == WaveBlaster )
+      {
+      if ( BLASTER_CardHasMixer() )
+         {
+         BLASTER_SaveMidiVolume();
+         Funcs->SetVolume = BLASTER_SetMidiVolume;
+         Funcs->GetVolume = BLASTER_GetMidiVolume;
+         }
+      }
+
+   MIDI_SetMidiFuncs( Funcs );
+
+   return( status );
+   }
+
+int MUSIC_InitGUS
+   (
+   midifuncs *Funcs
+   )
+
+   {
+   int status;
+
+   status = MUSIC_Ok;
+
+   if ( GUSMIDI_Init() != GUS_Ok )
+      {
+      MUSIC_SetErrorCode( MUSIC_SoundCardError );
+      return( MUSIC_Error );
+      }
+
+   Funcs->NoteOff           = GUSMIDI_NoteOff;
+   Funcs->NoteOn            = GUSMIDI_NoteOn;
+   Funcs->PolyAftertouch    = NULL;
+   Funcs->ControlChange     = GUSMIDI_ControlChange;
+   Funcs->ProgramChange     = GUSMIDI_ProgramChange;
+   Funcs->ChannelAftertouch = NULL;
+   Funcs->PitchBend         = GUSMIDI_PitchBend;
+   Funcs->ReleasePatches    = NULL;//GUSMIDI_ReleasePatches;
+   Funcs->LoadPatch         = NULL;//GUSMIDI_LoadPatch;
+   Funcs->SetVolume         = GUSMIDI_SetVolume;
+   Funcs->GetVolume         = GUSMIDI_GetVolume;
+
+   MIDI_SetMidiFuncs( Funcs );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_FadeRoutine
+
+   Fades music volume from current level to another over a specified
+   period of time.
+---------------------------------------------------------------------*/
+
+static void MUSIC_FadeRoutine
+   (
+   task *Task
+   )
+
+   {
+   int volume;
+
+   MUSIC_CurrentFadeVolume += MUSIC_FadeRate;
+   if ( MUSIC_FadeLength == 0 )
+      {
+      MIDI_SetVolume( MUSIC_EndingFadeVolume );
+      TS_Terminate( Task );
+      MUSIC_FadeTask = NULL;
+      }
+   else
+      {
+      MUSIC_FadeLength--;
+//      if ( ( MUSIC_SoundDevice == GenMidi ) &&
+//         ( ( MUSIC_FadeLength % 12 ) != 0 ) )
+//         {
+//         return;
+//         }
+
+      volume = MUSIC_CurrentFadeVolume >> 7;
+      if ( MUSIC_LastFadeVolume != volume )
+         {
+         MUSIC_LastFadeVolume = volume;
+         MIDI_SetVolume( volume );
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_FadeVolume
+
+   Fades music volume from current level to another over a specified
+   period of time.
+---------------------------------------------------------------------*/
+
+int MUSIC_FadeVolume
+   (
+   int tovolume,
+   int milliseconds
+   )
+
+   {
+   int fromvolume;
+
+   if ( ( MUSIC_SoundDevice == ProAudioSpectrum ) ||
+      ( MUSIC_SoundDevice == SoundMan16 ) ||
+      ( MUSIC_SoundDevice == GenMidi ) ||
+      ( MUSIC_SoundDevice == SoundScape ) ||
+      ( MUSIC_SoundDevice == SoundCanvas ) )
+      {
+      MIDI_SetVolume( tovolume );
+      return( MUSIC_Ok );
+      }
+
+   if ( MUSIC_FadeTask != NULL )
+      {
+      MUSIC_StopFade();
+      }
+
+   tovolume = max( 0, tovolume );
+   tovolume = min( 255, tovolume );
+   fromvolume = MUSIC_GetVolume();
+
+   MUSIC_FadeLength = milliseconds / 25;
+   MUSIC_FadeRate   = ( ( tovolume - fromvolume ) << 7 ) / MUSIC_FadeLength;
+   MUSIC_LastFadeVolume = fromvolume;
+   MUSIC_CurrentFadeVolume = fromvolume << 7;
+   MUSIC_EndingFadeVolume = tovolume;
+
+   MUSIC_FadeTask = TS_ScheduleTask( MUSIC_FadeRoutine, 40, 1, NULL );
+   if ( MUSIC_FadeTask == NULL )
+      {
+      MUSIC_SetErrorCode( MUSIC_TaskManError );
+      return( MUSIC_Warning );
+      }
+
+   TS_Dispatch();
+   return( MUSIC_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_FadeActive
+
+   Returns whether the fade routine is active.
+---------------------------------------------------------------------*/
+
+int MUSIC_FadeActive
+   (
+   void
+   )
+
+   {
+   return( MUSIC_FadeTask != NULL );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_StopFade
+
+   Stops fading the music.
+---------------------------------------------------------------------*/
+
+void MUSIC_StopFade
+   (
+   void
+   )
+
+   {
+   if ( MUSIC_FadeTask != NULL )
+      {
+      TS_Terminate( MUSIC_FadeTask );
+      MUSIC_FadeTask = NULL;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_RerouteMidiChannel
+
+   Sets callback function to reroute MIDI commands from specified
+   function.
+---------------------------------------------------------------------*/
+
+void MUSIC_RerouteMidiChannel
+   (
+   int channel,
+   int cdecl ( *function )( int event, int c1, int c2 )
+   )
+
+   {
+   MIDI_RerouteMidiChannel( channel, function );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: MUSIC_RegisterTimbreBank
+
+   Halts playback of all sounds.
+---------------------------------------------------------------------*/
+
+void MUSIC_RegisterTimbreBank
+   (
+   unsigned char *timbres
+   )
+
+   {
+   AL_RegisterTimbreBank( timbres );
+   }

Added: tags/rott-1.1/rott/audiolib/music.h
===================================================================
--- tags/rott-1.1/rott/audiolib/music.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/music.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,96 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: MUSIC.H
+
+   author: James R. Dose
+   date:   March 25, 1994
+
+   Public header for MUSIC.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __MUSIC_H
+#define __MUSIC_H
+
+#include "sndcards.h"
+
+#ifndef PLAT_DOS
+#define cdecl
+#endif
+
+extern int MUSIC_ErrorCode;
+
+enum MUSIC_ERRORS
+   {
+   MUSIC_Warning = -2,
+   MUSIC_Error   = -1,
+   MUSIC_Ok      = 0,
+   MUSIC_ASSVersion,
+   MUSIC_SoundCardError,
+   MUSIC_MPU401Error,
+   MUSIC_InvalidCard,
+   MUSIC_MidiError,
+   MUSIC_TaskManError,
+   MUSIC_FMNotDetected,
+   MUSIC_DPMI_Error
+   };
+
+typedef struct
+   {
+   unsigned long tickposition;
+   unsigned long milliseconds;
+   unsigned int  measure;
+   unsigned int  beat;
+   unsigned int  tick;
+   } songposition;
+
+#define MUSIC_LoopSong ( 1 == 1 )
+#define MUSIC_PlayOnce ( !MUSIC_LoopSong )
+
+char *MUSIC_ErrorString( int ErrorNumber );
+int   MUSIC_Init( int SoundCard, int Address );
+int   MUSIC_Shutdown( void );
+void  MUSIC_SetMaxFMMidiChannel( int channel );
+void  MUSIC_SetVolume( int volume );
+void  MUSIC_SetMidiChannelVolume( int channel, int volume );
+void  MUSIC_ResetMidiChannelVolumes( void );
+int   MUSIC_GetVolume( void );
+void  MUSIC_SetLoopFlag( int loopflag );
+int   MUSIC_SongPlaying( void );
+void  MUSIC_Continue( void );
+void  MUSIC_Pause( void );
+int   MUSIC_StopSong( void );
+int   MUSIC_PlaySong( unsigned char *song, int loopflag );
+void  MUSIC_SetContext( int context );
+int   MUSIC_GetContext( void );
+void  MUSIC_SetSongTick( unsigned long PositionInTicks );
+void  MUSIC_SetSongTime( unsigned long milliseconds );
+void  MUSIC_SetSongPosition( int measure, int beat, int tick );
+void  MUSIC_GetSongPosition( songposition *pos );
+void  MUSIC_GetSongLength( songposition *pos );
+int   MUSIC_FadeVolume( int tovolume, int milliseconds );
+int   MUSIC_FadeActive( void );
+void  MUSIC_StopFade( void );
+void  MUSIC_RerouteMidiChannel( int channel, int cdecl ( *function )( int event, int c1, int c2 ) );
+void  MUSIC_RegisterTimbreBank( unsigned char *timbres );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/mv_mix.asm
===================================================================
--- tags/rott-1.1/rott/audiolib/mv_mix.asm	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/mv_mix.asm	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,505 @@
+        IDEAL
+
+        p386
+        MODEL  flat
+
+        dataseg
+        CODESEG
+
+        MASM
+        ALIGN 4
+
+EXTRN   _MV_HarshClipTable:DWORD
+EXTRN   _MV_MixDestination:DWORD
+EXTRN   _MV_MixPosition:DWORD
+EXTRN   _MV_LeftVolume:DWORD
+EXTRN   _MV_RightVolume:DWORD
+EXTRN   _MV_SampleSize:DWORD
+EXTRN   _MV_RightChannelOffset:DWORD
+
+;================
+;
+; MV_Mix8BitMono
+;
+;================
+
+; eax - position
+; edx - rate
+; ebx - start
+; ecx - number of samples to mix
+
+PROC    MV_Mix8BitMono_
+PUBLIC  MV_Mix8BitMono_
+; Two at once
+        pushad
+
+        mov     ebp, eax
+
+        mov     esi, ebx                        ; Source pointer
+
+        ; Sample size
+        mov     ebx, _MV_SampleSize
+        mov     eax,OFFSET apatch7+2            ; convice tasm to modify code...
+        mov     [eax],bl
+        mov     eax,OFFSET apatch8+2            ; convice tasm to modify code...
+        mov     [eax],bl
+        mov     eax,OFFSET apatch9+3            ; convice tasm to modify code...
+        mov     [eax],bl
+
+        ; Volume table ptr
+        mov     ebx, _MV_LeftVolume             ; Since we're mono, use left volume
+        mov     eax,OFFSET apatch1+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET apatch2+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Harsh Clip table ptr
+        mov     ebx, _MV_HarshClipTable
+        add     ebx, 128
+        mov     eax,OFFSET apatch3+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET apatch4+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Rate scale ptr
+        mov     eax,OFFSET apatch5+2            ; convice tasm to modify code...
+        mov     [eax],edx
+        mov     eax,OFFSET apatch6+2            ; convice tasm to modify code...
+        mov     [eax],edx
+
+        mov     edi, _MV_MixDestination         ; Get the position to write to
+
+        ; Number of samples to mix
+        shr     ecx, 1                          ; double sample count
+        cmp     ecx, 0
+        je      short exit8m
+
+;     eax - scratch
+;     ebx - scratch
+;     edx - scratch
+;     ecx - count
+;     edi - destination
+;     esi - source
+;     ebp - frac pointer
+; apatch1 - volume table
+; apatch2 - volume table
+; apatch3 - harsh clip table
+; apatch4 - harsh clip table
+; apatch5 - sample rate
+; apatch6 - sample rate
+
+        mov     eax,ebp                         ; begin calculating first sample
+        add     ebp,edx                         ; advance frac pointer
+        shr     eax,16                          ; finish calculation for first sample
+
+        mov     ebx,ebp                         ; begin calculating second sample
+        add     ebp,edx                         ; advance frac pointer
+        shr     ebx,16                          ; finish calculation for second sample
+
+        movzx   eax, byte ptr [esi+eax]         ; get first sample
+        movzx   ebx, byte ptr [esi+ebx]         ; get second sample
+
+        ALIGN 4
+mix8Mloop:
+        movzx   edx, byte ptr [edi]             ; get current sample from destination
+apatch1:
+        movsx   eax, byte ptr [2*eax+12345678h] ; volume translate first sample
+apatch2:
+        movsx   ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample
+        add     eax, edx                        ; mix first sample
+apatch9:
+        movzx   edx, byte ptr [edi + 1]         ; get current sample from destination
+apatch3:
+        mov     eax, [eax + 12345678h]          ; harsh clip new sample
+        add     ebx, edx                        ; mix second sample
+        mov     [edi], al                       ; write new sample to destination
+        mov     edx, ebp                        ; begin calculating third sample
+apatch4:
+        mov     ebx, [ebx + 12345678h]          ; harsh clip new sample
+apatch5:
+        add     ebp,12345678h                   ; advance frac pointer
+        shr     edx, 16                         ; finish calculation for third sample
+        mov     eax, ebp                        ; begin calculating fourth sample
+apatch7:
+        add     edi, 1                          ; move destination to second sample
+        shr     eax, 16                         ; finish calculation for fourth sample
+        mov     [edi], bl                       ; write new sample to destination
+apatch6:
+        add     ebp,12345678h                   ; advance frac pointer
+        movzx   ebx, byte ptr [esi+eax]         ; get fourth sample
+        movzx   eax, byte ptr [esi+edx]         ; get third sample
+apatch8:
+        add     edi, 2                          ; move destination to third sample
+        dec     ecx                             ; decrement count
+        jnz     mix8Mloop                       ; loop
+
+        mov     _MV_MixDestination, edi         ; Store the current write position
+        mov     _MV_MixPosition, ebp            ; return position
+exit8m:
+        popad
+        ret
+ENDP    MV_Mix8BitMono_
+
+;================
+;
+; MV_Mix8BitStereo
+;
+;================
+
+; eax - position
+; edx - rate
+; ebx - start
+; ecx - number of samples to mix
+
+PROC    MV_Mix8BitStereo_
+PUBLIC  MV_Mix8BitStereo_
+
+        pushad
+        mov     ebp, eax
+
+        mov     esi, ebx                        ; Source pointer
+
+        ; Sample size
+        mov     ebx, _MV_SampleSize
+        mov     eax,OFFSET bpatch8+2            ; convice tasm to modify code...
+        mov     [eax],bl
+
+        ; Right channel offset
+        mov     ebx, _MV_RightChannelOffset
+        mov     eax,OFFSET bpatch6+3            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET bpatch7+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Volume table ptr
+        mov     ebx, _MV_LeftVolume
+        mov     eax,OFFSET bpatch1+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        mov     ebx, _MV_RightVolume
+        mov     eax,OFFSET bpatch2+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Rate scale ptr
+        mov     eax,OFFSET bpatch3+2            ; convice tasm to modify code...
+        mov     [eax],edx
+
+        ; Harsh Clip table ptr
+        mov     ebx, _MV_HarshClipTable
+        add     ebx,128
+        mov     eax,OFFSET bpatch4+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET bpatch5+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        mov     edi, _MV_MixDestination         ; Get the position to write to
+
+        ; Number of samples to mix
+        cmp     ecx, 0
+        je      short exit8S
+
+;     eax - scratch
+;     ebx - scratch
+;     edx - scratch
+;     ecx - count
+;     edi - destination
+;     esi - source
+;     ebp - frac pointer
+; bpatch1 - left volume table
+; bpatch2 - right volume table
+; bpatch3 - sample rate
+; bpatch4 - harsh clip table
+; bpatch5 - harsh clip table
+
+        mov     eax,ebp                         ; begin calculating first sample
+        shr     eax,16                          ; finish calculation for first sample
+
+        movzx   ebx, byte ptr [esi+eax]         ; get first sample
+
+        ALIGN 4
+mix8Sloop:
+bpatch1:
+        movsx   eax, byte ptr [2*ebx+12345678h] ; volume translate left sample
+        movzx   edx, byte ptr [edi]             ; get current sample from destination
+bpatch2:
+        movsx   ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample
+        add     eax, edx                        ; mix left sample
+bpatch3:
+        add     ebp,12345678h                   ; advance frac pointer
+bpatch6:
+        movzx   edx, byte ptr [edi+12345678h]   ; get current sample from destination
+bpatch4:
+        mov     eax, [eax + 12345678h]          ; harsh clip left sample
+        add     ebx, edx                        ; mix right sample
+        mov     [edi], al                       ; write left sample to destination
+bpatch5:
+        mov     ebx, [ebx + 12345678h]          ; harsh clip right sample
+        mov     edx, ebp                        ; begin calculating second sample
+bpatch7:
+        mov     [edi+12345678h], bl             ; write right sample to destination
+        shr     edx, 16                         ; finish calculation for second sample
+bpatch8:
+        add     edi, 2                          ; move destination to second sample
+        movzx   ebx, byte ptr [esi+edx]         ; get second sample
+        dec     ecx                             ; decrement count
+        jnz     mix8Sloop                       ; loop
+
+        mov     _MV_MixDestination, edi         ; Store the current write position
+        mov     _MV_MixPosition, ebp            ; return position
+
+EXIT8S:
+        popad
+        ret
+ENDP    MV_Mix8BitStereo_
+
+;================
+;
+; MV_Mix16BitMono
+;
+;================
+
+; eax - position
+; edx - rate
+; ebx - start
+; ecx - number of samples to mix
+
+PROC    MV_Mix16BitMono_
+PUBLIC  MV_Mix16BitMono_
+; Two at once
+        pushad
+
+        mov     ebp, eax
+
+        mov     esi, ebx                        ; Source pointer
+
+        ; Sample size
+        mov     ebx, _MV_SampleSize
+        mov     eax,OFFSET cpatch5+3            ; convice tasm to modify code...
+        mov     [eax],bl
+        mov     eax,OFFSET cpatch6+3            ; convice tasm to modify code...
+        mov     [eax],bl
+        mov     eax,OFFSET cpatch7+2            ; convice tasm to modify code...
+        add     bl,bl
+        mov     [eax],bl
+
+        ; Volume table ptr
+        mov     ebx, _MV_LeftVolume
+        mov     eax,OFFSET cpatch1+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET cpatch2+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Rate scale ptr
+        mov     eax,OFFSET cpatch3+2            ; convice tasm to modify code...
+        mov     [eax],edx
+        mov     eax,OFFSET cpatch4+2            ; convice tasm to modify code...
+        mov     [eax],edx
+
+        mov     edi, _MV_MixDestination         ; Get the position to write to
+
+        ; Number of samples to mix
+        shr     ecx, 1                          ; double sample count
+        cmp     ecx, 0
+        je      exit16M
+
+;     eax - scratch
+;     ebx - scratch
+;     edx - scratch
+;     ecx - count
+;     edi - destination
+;     esi - source
+;     ebp - frac pointer
+; cpatch1 - volume table
+; cpatch2 - volume table
+; cpatch3 - sample rate
+; cpatch4 - sample rate
+
+        mov     eax,ebp                         ; begin calculating first sample
+        add     ebp,edx                         ; advance frac pointer
+        shr     eax,16                          ; finish calculation for first sample
+
+        mov     ebx,ebp                         ; begin calculating second sample
+        add     ebp,edx                         ; advance frac pointer
+        shr     ebx,16                          ; finish calculation for second sample
+
+        movzx   eax, byte ptr [esi+eax]         ; get first sample
+        movzx   ebx, byte ptr [esi+ebx]         ; get second sample
+
+        ALIGN 4
+mix16Mloop:
+        movsx   edx, word ptr [edi]             ; get current sample from destination
+cpatch1:
+        movsx   eax, word ptr [2*eax+12345678h] ; volume translate first sample
+cpatch2:
+        movsx   ebx, word ptr [2*ebx+12345678h] ; volume translate second sample
+        add     eax, edx                        ; mix first sample
+cpatch5:
+        movsx   edx, word ptr [edi + 2]         ; get current sample from destination
+
+        cmp     eax, -32768                     ; Harsh clip sample
+        jge     short m16skip1
+        mov     eax, -32768
+        jmp     short m16skip2
+m16skip1:
+        cmp     eax, 32767
+        jle     short m16skip2
+        mov     eax, 32767
+m16skip2:
+        add     ebx, edx                        ; mix second sample
+        mov     [edi], ax                       ; write new sample to destination
+        mov     edx, ebp                        ; begin calculating third sample
+
+        cmp     ebx, -32768                     ; Harsh clip sample
+        jge     short m16skip3
+        mov     ebx, -32768
+        jmp     short m16skip4
+m16skip3:
+        cmp     ebx, 32767
+        jle     short m16skip4
+        mov     ebx, 32767
+m16skip4:
+cpatch3:
+        add     ebp,12345678h                   ; advance frac pointer
+        shr     edx, 16                         ; finish calculation for third sample
+        mov     eax, ebp                        ; begin calculating fourth sample
+cpatch6:
+        mov     [edi + 2], bx                   ; write new sample to destination
+        shr     eax, 16                         ; finish calculation for fourth sample
+
+cpatch4:
+        add     ebp,12345678h                   ; advance frac pointer
+        movzx   ebx, byte ptr [esi+eax]         ; get fourth sample
+cpatch7:
+        add     edi, 4                          ; move destination to third sample
+        movzx   eax, byte ptr [esi+edx]         ; get third sample
+        dec     ecx                             ; decrement count
+        jnz     mix16Mloop                      ; loop
+
+        mov     _MV_MixDestination, edi         ; Store the current write position
+        mov     _MV_MixPosition, ebp            ; return position
+EXIT16M:
+        popad
+        ret
+ENDP    MV_Mix16BitMono_
+
+;================
+;
+; MV_Mix16BitStereo
+;
+;================
+
+; eax - position
+; edx - rate
+; ebx - start
+; ecx - number of samples to mix
+
+PROC    MV_Mix16BitStereo_
+PUBLIC  MV_Mix16BitStereo_
+
+        pushad
+        mov     ebp, eax
+
+        mov     esi, ebx                        ; Source pointer
+
+        ; Sample size
+        mov     ebx, _MV_SampleSize
+        mov     eax,OFFSET dpatch6+2            ; convice tasm to modify code...
+        mov     [eax],bl
+
+        ; Right channel offset
+        mov     ebx, _MV_RightChannelOffset
+        mov     eax,OFFSET dpatch4+3            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET dpatch5+3            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Volume table ptr
+        mov     ebx, _MV_LeftVolume
+        mov     eax,OFFSET dpatch1+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        mov     ebx, _MV_RightVolume
+        mov     eax,OFFSET dpatch2+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Rate scale ptr
+        mov     eax,OFFSET dpatch3+2            ; convice tasm to modify code...
+        mov     [eax],edx
+
+        mov     edi, _MV_MixDestination         ; Get the position to write to
+
+        ; Number of samples to mix
+        cmp     ecx, 0
+        je      exit16S
+
+;     eax - scratch
+;     ebx - scratch
+;     edx - scratch
+;     ecx - count
+;     edi - destination
+;     esi - source
+;     ebp - frac pointer
+; dpatch1 - left volume table
+; dpatch2 - right volume table
+; dpatch3 - sample rate
+
+        mov     eax,ebp                         ; begin calculating first sample
+        shr     eax,16                          ; finish calculation for first sample
+
+        movzx   ebx, byte ptr [esi+eax]         ; get first sample
+
+        ALIGN 4
+mix16Sloop:
+dpatch1:
+        movsx   eax, word ptr [2*ebx+12345678h] ; volume translate left sample
+        movsx   edx, word ptr [edi]             ; get current sample from destination
+dpatch2:
+        movsx   ebx, word ptr [2*ebx+12345678h] ; volume translate right sample
+        add     eax, edx                        ; mix left sample
+dpatch3:
+        add     ebp,12345678h                   ; advance frac pointer
+dpatch4:
+        movsx   edx, word ptr [edi+12345678h]   ; get current sample from destination
+
+        cmp     eax, -32768                     ; Harsh clip sample
+        jge     short s16skip1
+        mov     eax, -32768
+        jmp     short s16skip2
+s16skip1:
+        cmp     eax, 32767
+        jle     short s16skip2
+        mov     eax, 32767
+s16skip2:
+        add     ebx, edx                        ; mix right sample
+        mov     [edi], ax                       ; write left sample to destination
+
+        cmp     ebx, -32768                     ; Harsh clip sample
+        jge     short s16skip3
+        mov     ebx, -32768
+        jmp     short s16skip4
+s16skip3:
+        cmp     ebx, 32767
+        jle     short s16skip4
+        mov     ebx, 32767
+s16skip4:
+
+        mov     edx, ebp                        ; begin calculating second sample
+dpatch5:
+        mov     [edi+12345678h], bx             ; write right sample to destination
+        shr     edx, 16                         ; finish calculation for second sample
+dpatch6:
+        add     edi, 4                          ; move destination to second sample
+        movzx   ebx, byte ptr [esi+edx]         ; get second sample
+        dec     ecx                             ; decrement count
+        jnz     mix16Sloop                      ; loop
+
+        mov     _MV_MixDestination, edi         ; Store the current write position
+        mov     _MV_MixPosition, ebp            ; return position
+exit16S:
+        popad
+        ret
+ENDP    MV_Mix16BitStereo_
+
+        ENDS
+
+        END

Added: tags/rott-1.1/rott/audiolib/mv_mix.c
===================================================================
--- tags/rott-1.1/rott/audiolib/mv_mix.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/mv_mix.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,293 @@
+#include "multivoc.h"
+
+extern char  *MV_MixDestination;
+extern unsigned long MV_MixPosition;
+
+extern char *MV_LeftVolume;
+extern char *MV_RightVolume;
+
+extern unsigned char *MV_HarshClipTable;
+
+extern int MV_RightChannelOffset;
+extern int MV_SampleSize;
+
+void MV_Mix8BitMono( unsigned long position, unsigned long rate,
+   const char *start, unsigned long length )
+{
+	const unsigned char *src;
+	unsigned char *dest;
+	unsigned int i;
+
+	src = (const unsigned char *)start;
+	dest = (unsigned char *)MV_MixDestination;
+
+	for (i = 0; i < length; i++) {
+		int s = src[position >> 16];
+		int d = *dest;
+		
+		s = MV_LeftVolume[s * 2];
+
+		s += d;
+		
+		s = MV_HarshClipTable[s + 0x80];
+		
+		*dest = (s & 0xff);
+		
+		position += rate;
+		dest += MV_SampleSize;
+	}
+	
+	MV_MixPosition = position;
+	MV_MixDestination = (char *)dest;
+}
+
+void MV_Mix8BitStereo( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length )
+{
+	const unsigned char *src;
+	unsigned char *dest;
+	unsigned int i;
+	
+	src = (const unsigned char *)start;
+	dest = (unsigned char *)MV_MixDestination;
+
+	for (i = 0; i < length; i++) {
+		int s = src[(position >> 16)];
+		int dl = dest[0];
+		int dr = dest[MV_RightChannelOffset];
+		
+		dl += MV_LeftVolume[s * 2];
+		dr += MV_RightVolume[s * 2];
+		
+		dl = MV_HarshClipTable[dl + 0x80];
+		dr = MV_HarshClipTable[dr + 0x80];
+		
+		dest[0] = (dl & 0xff);
+		dest[MV_RightChannelOffset] = (dr & 0xff);
+		
+		position += rate;
+		dest += MV_SampleSize;
+	}
+	
+	MV_MixPosition = position;
+	MV_MixDestination = (char *)dest;
+}
+
+void MV_Mix16BitMono( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length )
+{
+	const short *MV_LeftVolumeS;
+	const unsigned char *src;
+	short *dest;
+	unsigned int i;
+
+	src = (const unsigned char *)start;
+	dest = (short *)MV_MixDestination;
+	
+	MV_LeftVolumeS = (const short *)MV_LeftVolume;
+	
+	for (i = 0; i < length; i++) {
+		int s = src[position >> 16];
+		int d = dest[0];
+		
+		s = MV_LeftVolumeS[s];
+		
+		s += d;
+		
+		if (s < -32768) s = -32768;
+		if (s >  32767) s =  32767;
+		
+		*dest = (short) s;
+		
+		position += rate;
+		dest += MV_SampleSize/2;
+	}
+	
+	MV_MixPosition = position;
+	MV_MixDestination = (char *)dest;
+}
+
+void MV_Mix16BitStereo( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length )
+{
+	const short *MV_LeftVolumeS;
+	const short *MV_RightVolumeS;
+	const unsigned char *src;
+	short *dest;
+	unsigned int i;
+
+	src = (unsigned char *)start;
+	dest = (short *)MV_MixDestination;
+	
+	MV_LeftVolumeS = (const short *)MV_LeftVolume;
+	MV_RightVolumeS = (const short *)MV_RightVolume;
+	
+	for (i = 0; i < length; i++) {
+		int s = src[position >> 16];
+		int dl = dest[0];
+		int dr = dest[MV_RightChannelOffset/2];
+		
+		dl += MV_LeftVolumeS[s];
+		dr += MV_RightVolumeS[s];
+		
+		if (dl < -32768) dl = -32768;
+		if (dl >  32767) dl =  32767;
+		if (dr < -32768) dr = -32768;
+		if (dr >  32767) dr =  32767;
+		
+		dest[0] = (short) dl;
+		dest[MV_RightChannelOffset/2] = (short) dr;
+		
+		position += rate;
+		dest += MV_SampleSize/2;
+	}
+	
+	MV_MixPosition = position;
+	MV_MixDestination = (char *)dest;
+}
+
+void MV_Mix8BitMono16( unsigned long position, unsigned long rate,
+   const char *start, unsigned long length )
+{
+	const char *src;
+	unsigned char *dest;
+	unsigned int i;
+
+	src = (const char *)start + 1;
+	dest = (unsigned char *)MV_MixDestination;
+
+	for (i = 0; i < length; i++) {
+		int s = (int)src[(position >> 16) * 2] + 0x80;
+		int d = *dest;
+		
+		s = MV_LeftVolume[s * 2];
+		
+		s += d;
+		
+		s = MV_HarshClipTable[s + 0x80];
+		
+		*dest = (s & 0xff);
+		
+		position += rate;
+		dest += MV_SampleSize;
+	}
+	
+	MV_MixPosition = position;
+	MV_MixDestination = (char *)dest;
+}
+
+void MV_Mix8BitStereo16( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length )
+{
+	const char *src;
+	unsigned char *dest;
+	unsigned int i;
+	
+	src = (const char *)start + 1;
+	dest = (unsigned char *)MV_MixDestination;
+	
+	for (i = 0; i < length; i++) {
+		int s = src[(position >> 16) * 2] + 0x80;
+		int dl = dest[0];
+		int dr = dest[MV_RightChannelOffset];
+		
+		dl += MV_LeftVolume[s * 2];
+		dr += MV_RightVolume[s * 2];
+		
+		dl = MV_HarshClipTable[dl + 0x80];
+		dr = MV_HarshClipTable[dr + 0x80];
+		
+		dest[0] = (dl & 0xff);
+		dest[MV_RightChannelOffset] = (dr & 0xff);
+		
+		position += rate;
+		dest += MV_SampleSize;
+	}
+	
+	MV_MixPosition = position;
+	MV_MixDestination = (char *)dest;
+}
+
+void MV_Mix16BitMono16( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length )
+{
+	const short *MV_LeftVolumeS;
+	const unsigned char *src;
+	short *dest;
+	unsigned int i;
+	
+	src = (const unsigned char *)start;
+	dest = (short *)MV_MixDestination;
+	
+	MV_LeftVolumeS = (const short *)MV_LeftVolume;
+	
+	for (i = 0; i < length; i++) {
+		int sl = src[(position >> 16) * 2 + 0];
+		int sh = src[(position >> 16) * 2 + 1] ^ 0x80;
+		
+		int d = *dest;
+		
+		sl = MV_LeftVolume[sl * 2 + 1];
+		sh = MV_LeftVolumeS[sh];
+		
+		d = sl + sh + 0x80 + d;
+		
+		if (d < -32768) d = -32768;
+		if (d >  32767) d =  32767;
+		
+		*dest = (short) d;
+		
+		position += rate;
+		dest += MV_SampleSize/2;
+	}
+	
+	MV_MixPosition = position;
+	MV_MixDestination = (char *)dest;
+}
+
+void MV_Mix16BitStereo16( unsigned long position,
+   unsigned long rate, const char *start, unsigned long length )
+{
+	const short *MV_LeftVolumeS;
+	const short *MV_RightVolumeS;
+	const unsigned char *src;
+	short *dest;
+	unsigned int i;
+	
+	src = (const unsigned char *)start;
+	dest = (short *)MV_MixDestination;
+	
+	MV_LeftVolumeS = (const short *)MV_LeftVolume;
+	MV_RightVolumeS = (const short *)MV_RightVolume;
+	
+	for (i = 0; i < length; i++) {
+		int sl = src[(position >> 16) * 2 + 0];
+		int sh = src[(position >> 16) * 2 + 1] ^ 0x80;
+		
+		int dl = dest[0];
+		int dr = dest[MV_RightChannelOffset/2];
+		
+		int sll = MV_LeftVolume[sl * 2 + 1];
+		int slh = MV_LeftVolumeS[sh];
+		
+		int srl = MV_RightVolume[sl * 2 + 1];
+		int srh = MV_RightVolumeS[sh];
+		
+		dl = sll + slh + 0x80 + dl;
+		dr = srl + srh + 0x80 + dr;
+		
+		if (dl < -32768) dl = -32768;
+		if (dl >  32767) dl =  32767;
+		if (dr < -32768) dr = -32768;
+		if (dr >  32767) dr =  32767;
+		
+		dest[0] = (short) dl;
+		dest[MV_RightChannelOffset/2] = (short) dr;
+		
+		position += rate;
+		dest += MV_SampleSize/2;
+	}
+	
+	MV_MixPosition = position;
+	MV_MixDestination = (char *)dest;
+}

Added: tags/rott-1.1/rott/audiolib/mv_mix16.asm
===================================================================
--- tags/rott-1.1/rott/audiolib/mv_mix16.asm	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/mv_mix16.asm	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,524 @@
+        IDEAL
+
+        p386
+        MODEL  flat
+
+        dataseg
+        CODESEG
+
+        MASM
+        ALIGN 4
+
+EXTRN   _MV_HarshClipTable:DWORD
+EXTRN   _MV_MixDestination:DWORD
+EXTRN   _MV_MixPosition:DWORD
+EXTRN   _MV_LeftVolume:DWORD
+EXTRN   _MV_RightVolume:DWORD
+EXTRN   _MV_SampleSize:DWORD
+EXTRN   _MV_RightChannelOffset:DWORD
+
+;================
+;
+; MV_Mix8BitMono16
+;
+;================
+
+; eax - position
+; edx - rate
+; ebx - start
+; ecx - number of samples to mix
+
+PROC    MV_Mix8BitMono16_
+PUBLIC  MV_Mix8BitMono16_
+; Two at once
+        pushad
+        mov     ebp, eax
+
+        mov     esi, ebx                        ; Source pointer
+        inc     esi
+
+        ; Sample size
+        mov     ebx, _MV_SampleSize
+        mov     eax,OFFSET apatch7+2            ; convice tasm to modify code...
+        mov     [eax],bl
+        mov     eax,OFFSET apatch8+2            ; convice tasm to modify code...
+        mov     [eax],bl
+        mov     eax,OFFSET apatch9+3            ; convice tasm to modify code...
+        mov     [eax],bl
+
+        ; Volume table ptr
+        mov     ebx, _MV_LeftVolume             ; Since we're mono, use left volume
+        mov     eax,OFFSET apatch1+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET apatch2+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Harsh Clip table ptr
+        mov     ebx, _MV_HarshClipTable
+        add     ebx, 128
+        mov     eax,OFFSET apatch3+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET apatch4+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Rate scale ptr
+        mov     eax,OFFSET apatch5+2            ; convice tasm to modify code...
+        mov     [eax],edx
+        mov     eax,OFFSET apatch6+2            ; convice tasm to modify code...
+        mov     [eax],edx
+
+        mov     edi, _MV_MixDestination         ; Get the position to write to
+
+        ; Number of samples to mix
+        shr     ecx, 1                          ; double sample count
+        cmp     ecx, 0
+        je      exit8m
+
+;     eax - scratch
+;     ebx - scratch
+;     edx - scratch
+;     ecx - count
+;     edi - destination
+;     esi - source
+;     ebp - frac pointer
+; apatch1 - volume table
+; apatch2 - volume table
+; apatch3 - harsh clip table
+; apatch4 - harsh clip table
+; apatch5 - sample rate
+; apatch6 - sample rate
+
+        mov     eax,ebp                         ; begin calculating first sample
+        add     ebp,edx                         ; advance frac pointer
+        shr     eax,16                          ; finish calculation for first sample
+
+        mov     ebx,ebp                         ; begin calculating second sample
+        add     ebp,edx                         ; advance frac pointer
+        shr     ebx,16                          ; finish calculation for second sample
+
+        movsx   eax, byte ptr [esi+2*eax]       ; get first sample
+        movsx   ebx, byte ptr [esi+2*ebx]       ; get second sample
+        add     eax, 80h
+        add     ebx, 80h
+
+        ALIGN 4
+mix8Mloop:
+        movzx   edx, byte ptr [edi]             ; get current sample from destination
+apatch1:
+        movsx   eax, byte ptr [2*eax+12345678h] ; volume translate first sample
+apatch2:
+        movsx   ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample
+        add     eax, edx                        ; mix first sample
+apatch9:
+        movzx   edx, byte ptr [edi + 1]         ; get current sample from destination
+apatch3:
+        mov     eax, [eax + 12345678h]          ; harsh clip new sample
+        add     ebx, edx                        ; mix second sample
+        mov     [edi], al                       ; write new sample to destination
+        mov     edx, ebp                        ; begin calculating third sample
+apatch4:
+        mov     ebx, [ebx + 12345678h]          ; harsh clip new sample
+apatch5:
+        add     ebp,12345678h                   ; advance frac pointer
+        shr     edx, 16                         ; finish calculation for third sample
+        mov     eax, ebp                        ; begin calculating fourth sample
+apatch7:
+        add     edi, 2                          ; move destination to second sample
+        shr     eax, 16                         ; finish calculation for fourth sample
+        mov     [edi], bl                       ; write new sample to destination
+apatch6:
+        add     ebp,12345678h                   ; advance frac pointer
+        movsx   ebx, byte ptr [esi+2*eax]         ; get fourth sample
+        movsx   eax, byte ptr [esi+2*edx]         ; get third sample
+        add     ebx, 80h
+        add     eax, 80h
+apatch8:
+        add     edi, 2                          ; move destination to third sample
+        dec     ecx                             ; decrement count
+        jnz     mix8Mloop                       ; loop
+
+        mov     _MV_MixDestination, edi         ; Store the current write position
+        mov     _MV_MixPosition, ebp            ; return position
+exit8m:
+        popad
+        ret
+ENDP    MV_Mix8BitMono16_
+
+;================
+;
+; MV_Mix8BitStereo16
+;
+;================
+
+; eax - position
+; edx - rate
+; ebx - start
+; ecx - number of samples to mix
+
+PROC    MV_Mix8BitStereo16_
+PUBLIC  MV_Mix8BitStereo16_
+
+        pushad
+        mov     ebp, eax
+
+        mov     esi, ebx                        ; Source pointer
+        inc     esi
+
+        ; Sample size
+        mov     ebx, _MV_SampleSize
+        mov     eax,OFFSET bpatch8+2            ; convice tasm to modify code...
+        mov     [eax],bl
+ ;       mov     eax,OFFSET bpatch9+2            ; convice tasm to modify code...
+ ;       mov     [eax],bl
+
+        ; Right channel offset
+        mov     ebx, _MV_RightChannelOffset
+        mov     eax,OFFSET bpatch6+3            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET bpatch7+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Volume table ptr
+        mov     ebx, _MV_LeftVolume
+        mov     eax,OFFSET bpatch1+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        mov     ebx, _MV_RightVolume
+        mov     eax,OFFSET bpatch2+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Rate scale ptr
+        mov     eax,OFFSET bpatch3+2            ; convice tasm to modify code...
+        mov     [eax],edx
+
+        ; Harsh Clip table ptr
+        mov     ebx, _MV_HarshClipTable
+        add     ebx,128
+        mov     eax,OFFSET bpatch4+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET bpatch5+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        mov     edi, _MV_MixDestination         ; Get the position to write to
+
+        ; Number of samples to mix
+        cmp     ecx, 0
+        je      short exit8S
+
+;     eax - scratch
+;     ebx - scratch
+;     edx - scratch
+;     ecx - count
+;     edi - destination
+;     esi - source
+;     ebp - frac pointer
+; bpatch1 - left volume table
+; bpatch2 - right volume table
+; bpatch3 - sample rate
+; bpatch4 - harsh clip table
+; bpatch5 - harsh clip table
+
+        mov     eax,ebp                         ; begin calculating first sample
+        shr     eax,16                          ; finish calculation for first sample
+
+        movsx   ebx, byte ptr [esi+2*eax]       ; get first sample
+        add     ebx, 80h
+
+        ALIGN 4
+mix8Sloop:
+bpatch1:
+        movsx   eax, byte ptr [2*ebx+12345678h] ; volume translate left sample
+        movzx   edx, byte ptr [edi]             ; get current sample from destination
+bpatch2:
+        movsx   ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample
+        add     eax, edx                        ; mix left sample
+bpatch3:
+        add     ebp,12345678h                   ; advance frac pointer
+bpatch6:
+        movzx   edx, byte ptr [edi+12345678h]   ; get current sample from destination
+bpatch4:
+        mov     eax, [eax + 12345678h]          ; harsh clip left sample
+        add     ebx, edx                        ; mix right sample
+        mov     [edi], al                       ; write left sample to destination
+bpatch5:
+        mov     ebx, [ebx + 12345678h]          ; harsh clip right sample
+        mov     edx, ebp                        ; begin calculating second sample
+bpatch7:
+        mov     [edi+12345678h], bl             ; write right sample to destination
+        shr     edx, 16                         ; finish calculation for second sample
+bpatch8:
+        add     edi, 1                          ; move destination to second sample
+        movsx   ebx, byte ptr [esi+2*edx]       ; get second sample
+        add     ebx, 80h
+        dec     ecx                             ; decrement count
+        jnz     mix8Sloop                       ; loop
+
+        mov     _MV_MixDestination, edi         ; Store the current write position
+        mov     _MV_MixPosition, ebp            ; return position
+
+EXIT8S:
+        popad
+        ret
+ENDP    MV_Mix8BitStereo16_
+
+;================
+;
+; MV_Mix16BitMono16
+;
+;================
+
+; eax - position
+; edx - rate
+; ebx - start
+; ecx - number of samples to mix
+
+PROC    MV_Mix16BitMono16_
+PUBLIC  MV_Mix16BitMono16_
+
+        pushad
+        mov     ebp, eax
+
+        mov     esi, ebx                        ; Source pointer
+
+        ; Sample size
+        mov     ebx, _MV_SampleSize
+        mov     eax,OFFSET cpatch4+2            ; convice tasm to modify code...
+        mov     [eax],bl
+        mov     eax,OFFSET cpatch5+3            ; convice tasm to modify code...
+        mov     [eax],bl
+
+        ; Volume table ptr
+        mov     ebx, _MV_LeftVolume
+        mov     eax,OFFSET cpatch2+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET cpatch1+4            ; convice tasm to modify code...
+        inc     ebx
+        mov     [eax],ebx
+
+        ; Rate scale ptr
+        mov     eax,OFFSET cpatch3+2            ; convice tasm to modify code...
+        mov     [eax],edx
+
+        mov     edi, _MV_MixDestination         ; Get the position to write to
+
+        ; Number of samples to mix
+        cmp     ecx, 0
+        je exit16M
+
+;     eax - scratch
+;     ebx - scratch
+;     edx - scratch
+;     ecx - count
+;     edi - destination
+;     esi - source
+;     ebp - frac pointer
+; cpatch1 - volume table
+; cpatch2 - volume table
+; cpatch3 - sample rate
+; cpatch4 - sample rate
+
+        mov     ebx,ebp                         ; begin calculating first sample
+        add     ebp,edx                         ; advance frac pointer
+        shr     ebx,16                          ; finish calculation for first sample
+        movzx   eax, word ptr [esi+2*ebx]       ; get low byte of sample
+        xor     eax, 8000h
+        movzx   ebx, ah
+        sub     ah, ah
+
+        movsx   edx, word ptr [edi]             ; get current sample from destination
+
+        ALIGN 4
+mix16Mloop:
+cpatch1:
+        movsx   eax, byte ptr [2*eax+12345678h] ; volume translate low byte of sample
+cpatch2:
+        movsx   ebx, word ptr [2*ebx+12345678h] ; volume translate high byte of sample
+        lea     eax, [ eax + ebx + 80h ]        ; mix high byte of sample
+        add     eax, edx                        ; mix low byte of sample
+cpatch5:
+        movsx   edx, word ptr [edi + 2]         ; get current sample from destination
+
+        cmp     eax, -32768                     ; Harsh clip sample
+        jge     short m16skip1
+        mov     eax, -32768
+        jmp     short m16skip2
+m16skip1:
+        cmp     eax, 32767
+        jle     short m16skip2
+        mov     eax, 32767
+m16skip2:
+        mov     ebx, ebp                        ; begin calculating second sample
+        mov     [edi], ax                       ; write new sample to destination
+
+        shr     ebx, 16                         ; finish calculation for second sample
+cpatch3:
+        add     ebp, 12345678h                  ; advance frac pointer
+
+        movzx   eax, word ptr [esi+2*ebx]       ; get second sample
+cpatch4:
+        add     edi, 2                          ; move destination to second sample
+        xor     eax, 8000h
+        movzx   ebx, ah
+        sub     ah, ah
+
+        dec     ecx                             ; decrement count
+        jnz     mix16Mloop                      ; loop
+
+        mov     _MV_MixDestination, edi         ; Store the current write position
+        mov     _MV_MixPosition, ebp            ; return position
+EXIT16M:
+        popad
+        ret
+ENDP    MV_Mix16BitMono16_
+
+;================
+;
+; MV_Mix16BitStereo16
+;
+;================
+
+; eax - position
+; edx - rate
+; ebx - start
+; ecx - number of samples to mix
+
+PROC    MV_Mix16BitStereo16_
+PUBLIC  MV_Mix16BitStereo16_
+
+        pushad
+        mov     ebp, eax
+
+        mov     esi, ebx                        ; Source pointer
+
+        ; Sample size
+        mov     ebx, _MV_SampleSize
+        mov     eax,OFFSET dpatch9+2            ; convice tasm to modify code...
+        mov     [eax],bl
+
+        ; Right channel offset
+        mov     ebx, _MV_RightChannelOffset
+        mov     eax,OFFSET dpatch7+3            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET dpatch8+3            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+        ; Volume table ptr
+        mov     ebx, _MV_LeftVolume
+        mov     eax,OFFSET dpatch1+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET dpatch2+4            ; convice tasm to modify code...
+        inc     ebx
+        mov     [eax],ebx
+
+        mov     ebx, _MV_RightVolume
+        mov     eax,OFFSET dpatch3+4            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET dpatch4+4            ; convice tasm to modify code...
+        inc     ebx
+        mov     [eax],ebx
+
+        ; Rate scale ptr
+        mov     eax,OFFSET dpatch5+2            ; convice tasm to modify code...
+        mov     [eax],edx
+
+        ; Source ptr
+        mov     eax,OFFSET dpatch6+4            ; convice tasm to modify code...
+        mov     [eax],esi
+
+        mov     edi, _MV_MixDestination         ; Get the position to write to
+
+        ; Number of samples to mix
+        cmp     ecx, 0
+        je      exit16S
+
+;     eax - scratch
+;     ebx - scratch
+;     edx - scratch
+;     esi - scratch
+;     ecx - count
+;     edi - destination
+;     ebp - frac pointer
+; dpatch1 - left volume table
+; dpatch2 - right volume table
+; dpatch3 - sample rate
+
+        mov     ebx,ebp                         ; begin calculating first sample
+        shr     ebx,16                          ; finish calculation for first sample
+
+        movzx   edx, word ptr [esi+2*ebx]       ; get first sample
+        xor     edx, 8000h                      ; Change from signed to unsigned
+        movzx   esi, dh                         ; put high byte in esi
+        sub     dh, dh                          ; lo byte in edx
+
+        ALIGN 4
+mix16Sloop:
+        ; Left channel
+dpatch1:
+        movsx   eax, word ptr [2*esi+12345678h] ; volume translate high byte of sample
+dpatch2:
+        movsx   ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample
+        lea     eax, [ eax + ebx + 80h ]        ; mix high byte of sample
+
+        ; Right channel
+dpatch3:
+        movsx   esi, word ptr [2*esi+12345678h] ; volume translate high byte of sample
+dpatch4:
+        movsx   ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample
+        lea     ebx, [ esi + ebx + 80h ]        ; mix high byte of sample
+
+dpatch7:
+        movsx   edx, word ptr [edi+12345678h]   ; get current sample from destination
+dpatch5:
+        add     ebp,12345678h                   ; advance frac pointer
+
+        add     eax, edx                        ; mix left sample
+
+        cmp     eax, -32768                     ; Harsh clip sample
+        jge     short s16skip1
+        mov     eax, -32768
+        jmp     short s16skip2
+s16skip1:
+        cmp     eax, 32767
+        jle     short s16skip2
+        mov     eax, 32767
+s16skip2:
+        movsx   edx, word ptr [edi+2]           ; get current sample from destination
+        mov     [edi], ax                       ; write left sample to destination
+        add     ebx, edx                        ; mix right sample
+
+        cmp     ebx, -32768                     ; Harsh clip sample
+        jge     short s16skip3
+        mov     ebx, -32768
+        jmp     short s16skip4
+s16skip3:
+        cmp     ebx, 32767
+        jle     short s16skip4
+        mov     ebx, 32767
+s16skip4:
+
+        mov     edx, ebp                        ; begin calculating second sample
+dpatch8:
+        mov     [edi+12345678h], bx             ; write right sample to destination
+        shr     edx, 16                         ; finish calculation for second sample
+dpatch9:
+        add     edi, 4                          ; move destination to second sample
+
+dpatch6:
+        movzx   edx, word ptr [2*edx+12345678h] ; get second sample
+        xor     edx, 8000h                      ; Change from signed to unsigned
+        movzx   esi, dh                         ; put high byte in esi
+        sub     dh, dh                          ; lo byte in edx
+
+        dec     ecx                             ; decrement count
+        jnz     mix16Sloop                      ; loop
+
+        mov     _MV_MixDestination, edi         ; Store the current write position
+        mov     _MV_MixPosition, ebp            ; return position
+exit16S:
+        popad
+        ret
+ENDP    MV_Mix16BitStereo16_
+
+        ENDS
+
+        END

Added: tags/rott-1.1/rott/audiolib/mvreverb.asm
===================================================================
--- tags/rott-1.1/rott/audiolib/mvreverb.asm	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/mvreverb.asm	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,181 @@
+        IDEAL
+
+        p386
+        MODEL  flat
+
+        dataseg
+        CODESEG
+
+        MASM
+        ALIGN 4
+
+;================
+;
+; MV_16BitReverb
+;
+;================
+
+; eax - source position
+; edx - destination position
+; ebx - Volume table
+; ecx - number of samples
+
+PROC    MV_16BitReverb_
+PUBLIC  MV_16BitReverb_
+
+        mov     esi, eax
+        lea     edi, [edx - 2]
+
+        ALIGN 4
+rev16loop:
+        movzx   eax, word ptr [esi]             ; get sample
+        add     edi, 2
+
+        movzx   edx, ah
+        sub     ah, ah
+
+        movsx   eax, byte ptr [2*eax+ebx+1]     ; volume translate low byte of sample
+        xor     edx, 80h
+
+        movsx   edx, word ptr [2*edx+ebx]       ; volume translate high byte of sample
+        add     esi, 2
+
+        lea     eax, [ eax + edx + 80h ]        ; mix high byte of sample
+        dec     ecx                             ; decrement count
+
+        mov     [edi], ax                       ; write new sample to destination
+        jnz     rev16loop                       ; loop
+
+        ret
+ENDP    MV_16BitReverb_
+
+;================
+;
+; MV_8BitReverb
+;
+;================
+
+; eax - source position
+; edx - destination position
+; ebx - Volume table
+; ecx - number of samples
+
+PROC    MV_8BitReverb_
+PUBLIC  MV_8BitReverb_
+
+        mov     esi, eax
+        lea     edi, [edx - 1]
+
+        xor     eax, eax
+
+        ALIGN 4
+rev8loop:
+;        movzx   eax, byte ptr [esi]             ; get sample
+        mov     al, byte ptr [esi]              ; get sample
+        inc     edi
+
+;        movsx   eax, byte ptr [2*eax+ebx]       ; volume translate sample
+        mov     al, byte ptr [2*eax+ebx]        ; volume translate sample
+        inc     esi
+
+;        add     eax, 80h
+        add     al, 80h
+        dec     ecx                             ; decrement count
+
+        mov     [edi], al                       ; write new sample to destination
+        jnz     rev8loop                        ; loop
+
+        ret
+ENDP    MV_8BitReverb_
+
+;================
+;
+; MV_16BitReverbFast
+;
+;================
+
+; eax - source position
+; edx - destination position
+; ebx - number of samples
+; ecx - shift
+
+PROC    MV_16BitReverbFast_
+PUBLIC  MV_16BitReverbFast_
+
+        mov     esi, eax
+        mov     eax,OFFSET rpatch16+3
+
+        mov     [eax],cl
+        lea     edi, [edx - 2]
+
+        ALIGN 4
+frev16loop:
+        mov     ax, word ptr [esi]             ; get sample
+        add     edi, 2
+
+rpatch16:
+        sar     ax, 5    ;;;;Add 1 before shift
+        add     esi, 2
+
+        mov     [edi], ax                       ; write new sample to destination
+        dec     ebx                             ; decrement count
+
+        jnz     frev16loop                      ; loop
+
+        ret
+ENDP    MV_16BITREVERBFAST_
+
+;================
+;
+; MV_8BitReverbFast
+;
+;================
+
+; eax - source position
+; edx - destination position
+; ebx - number of samples
+; ecx - shift
+
+PROC    MV_8BitReverbFast_
+PUBLIC  MV_8BitReverbFast_
+        mov     esi, eax
+        mov     eax,OFFSET rpatch8+2
+
+        mov     edi, edx
+        mov     edx, 80h
+
+        mov     [eax],cl
+        mov     eax, 80h
+
+        shr     eax, cl
+
+        dec     edi
+        sub     edx, eax
+
+        ALIGN 4
+frev8loop:
+        mov     al, byte ptr [esi]             ; get sample
+        inc     esi
+
+        mov     ecx, eax
+        inc     edi
+
+rpatch8:
+        shr     eax, 3
+        xor     ecx, 80h                        ; flip the sign bit
+
+        shr     ecx, 7                          ; shift the sign down to 1
+        add     eax, edx
+
+        add     eax, ecx                        ; add sign bit to round to 0
+        dec     ebx                             ; decrement count
+
+        mov     [edi], al                       ; write new sample to destination
+        jnz     frev8loop                       ; loop
+
+        ret
+ENDP    MV_8BITREVERBFAST_
+
+        ENDS
+
+        END

Added: tags/rott-1.1/rott/audiolib/mvreverb.c
===================================================================
--- tags/rott-1.1/rott/audiolib/mvreverb.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/mvreverb.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,58 @@
+#include "multivoc.h"
+#include "_multivc.h"
+
+void MV_16BitReverb( const char *src, char *dest, const VOLUME16 *volume, int count )
+{
+	int i;
+
+	short *pdest = (short *)dest;
+	
+	for (i = 0; i < count; i++) {
+		int sl = src[i*2+0];
+		int sh = src[i*2+1] ^ 0x80;
+		
+		sl = (*volume)[sl] >> 8;
+		sh = (*volume)[sh];
+		
+		pdest[i] = (short)(sl + sh + 0x80);
+	}
+}
+
+void MV_8BitReverb( const signed char *src, signed char *dest, const VOLUME16 *volume, int count )
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		unsigned char s = (unsigned char) src[i];
+		
+		s = (*volume)[s] & 0xff;
+		
+		dest[i] = (char)(s + 0x80);
+	}
+}
+
+void MV_16BitReverbFast( const char *src, char *dest, int count, int shift )
+{
+	int i;
+
+	short *pdest = (short *)dest;
+	const short *psrc = (const short *)src;
+	
+	for (i = 0; i < count; i++) {
+		pdest[i] = psrc[i] >> shift;
+	}
+}
+
+void MV_8BitReverbFast( const signed char *src, signed char *dest, int count, int shift )
+{
+	int i;
+
+	unsigned char sh = 0x80 - (0x80 >> shift);
+	
+	for (i = 0; i < count; i++) {
+		unsigned char a = ((unsigned char) src[i]) >> shift;
+		unsigned char c = (((unsigned char) src[i]) ^ 0x80) >> 7;
+		
+		dest[i] = (signed char) (a + sh + c);
+	}
+}

Added: tags/rott-1.1/rott/audiolib/myprint.c
===================================================================
--- tags/rott-1.1/rott/audiolib/myprint.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/myprint.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,310 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "myprint.h"
+
+static unsigned short disp_offset = 160 * 24;
+
+void DrawText
+   (
+   int x,
+   int y,
+   int ch,
+   int foreground,
+   int background
+   )
+
+   {
+   char *vid;
+
+   vid  = ( char * )( 0xb0000 );
+   vid += y * 160;
+   vid += x * 2;
+
+   if ( ch != NONE )
+      {
+      *vid = ch;
+      }
+   vid++;
+   *vid = ( ( background & 0x0f ) << 4 ) | ( foreground & 0x0f );
+   }
+
+void TextBox
+   (
+   int  x1,
+   int  y1,
+   int  x2,
+   int  y2,
+   int ch,
+   int  foreground,
+   int  background
+   )
+
+   {
+   int x;
+   int y;
+
+   for( x = x1; x <= x2; x++ )
+      {
+      for( y = y1; y <= y2; y++ )
+         {
+         DrawText( x, y, ch, foreground, background );
+         }
+      }
+   }
+
+void TextFrame
+   (
+   int x1,
+   int y1,
+   int x2,
+   int y2,
+   int type,
+   int foreground,
+   int background
+   )
+
+   {
+   int x;
+   int y;
+
+   if ( type == 0 )
+      {
+      for( x = x1 + 1; x < x2; x++ )
+         {
+         DrawText( x, y1, type, foreground, background );
+         DrawText( x, y2, type, foreground, background );
+         }
+      for( y = y1 + 1; y < y2; y++ )
+         {
+         DrawText( x1, y, type, foreground, background );
+         DrawText( x2, y, type, foreground, background );
+         }
+      }
+   if ( type == SINGLE_FRAME )
+      {
+      DrawText( x1, y1, 'Ú', foreground, background );
+      DrawText( x2, y1, '¿', foreground, background );
+      DrawText( x1, y2, 'À', foreground, background );
+      DrawText( x2, y2, 'Ù', foreground, background );
+      for( x = x1 + 1; x < x2; x++ )
+         {
+         DrawText( x, y1, 'Ä', foreground, background );
+         DrawText( x, y2, 'Ä', foreground, background );
+         }
+      for( y = y1 + 1; y < y2; y++ )
+         {
+         DrawText( x1, y, '³', foreground, background );
+         DrawText( x2, y, '³', foreground, background );
+         }
+      }
+   if ( type == DOUBLE_FRAME )
+      {
+      DrawText( x1, y1, 'É', foreground, background );
+      DrawText( x2, y1, '»', foreground, background );
+      DrawText( x1, y2, 'È', foreground, background );
+      DrawText( x2, y2, '¼', foreground, background );
+      for( x = x1 + 1; x < x2; x++ )
+         {
+         DrawText( x, y1, 'Í', foreground, background );
+         DrawText( x, y2, 'Í', foreground, background );
+         }
+      for( y = y1 + 1; y < y2; y++ )
+         {
+         DrawText( x1, y, 'º', foreground, background );
+         DrawText( x2, y, 'º', foreground, background );
+         }
+      }
+   }
+
+void mysetxy
+   (
+   int x,
+   int y
+   )
+
+   {
+   disp_offset = ( x * 2 ) + ( y * 160 );
+   }
+
+void myputch
+   (
+   char ch
+   )
+
+   {
+   int j;
+   char *disp_start = (char *)( 0xb0000 );
+
+   if ( disp_offset >= 160 * 24 )
+      {
+      for ( j = 160; j < 160 * 24; j += 2 )
+         {
+         *( disp_start + j - 160 ) = *( disp_start + j );
+         }
+
+      disp_offset = 160 * 23;
+
+      for ( j = disp_offset; j < ( 160 * 24 ); j += 2 )
+         {
+         *( disp_start + j ) = ' ';
+         }
+      }
+
+   if ( ch >= 32 )
+      {
+      *( disp_start + disp_offset ) = ch;
+      disp_offset = disp_offset + 2;
+      }
+
+   if ( ch == '\r' )
+      {
+      disp_offset = disp_offset / 160;
+      disp_offset = disp_offset * 160;
+      }
+
+   if ( ch == '\n' )
+      {
+      disp_offset = disp_offset + 160;
+      if ( disp_offset < 160 * 24 )
+         {
+         for ( j = disp_offset; j < ( ( ( disp_offset / 160 ) + 1 ) *
+            160 ); j += 2 )
+            {
+            *( disp_start + j ) = ' ';
+            }
+         }
+      }
+   }
+
+int printstring
+   (
+   char *string
+   )
+
+   {
+   int count;
+   char *ptr;
+
+   ptr = string;
+   count = 0;
+
+   while ( *ptr )
+      {
+      myputch( *ptr );
+      count++;
+      ptr++;
+      }
+
+   return( count );
+   }
+
+
+int printnum
+   (
+   int number
+   )
+
+   {
+   char string[ 100 ];
+   int  count;
+
+   itoa( number, string, 10 );
+   count = printstring( string );
+
+   return( count );
+   }
+
+int printunsigned
+   (
+   unsigned long number,
+   int radix
+   )
+
+   {
+   char string[ 100 ];
+   int  count;
+
+   ultoa( number, string, radix );
+   count = printstring( string );
+
+   return( count );
+   }
+
+int myprintf
+   (
+   char *fmt,
+   ...
+   )
+
+   {
+   va_list argptr;
+   int     count;
+   char    *ptr;
+
+   return( 0 );
+
+   // DEBUG
+   mysetxy( 0, 0 );
+
+   va_start( argptr, fmt );
+   ptr = fmt;
+   count = 0;
+
+   while( *ptr != 0 )
+      {
+      if ( *ptr == '%' )
+         {
+         ptr++;
+         switch( *ptr )
+            {
+            case 0 :
+               return( EOF );
+               break;
+            case 'd' :
+               count += printnum( va_arg( argptr, int ) );
+               break;
+            case 's' :
+               count += printstring( va_arg( argptr, char * ) );
+               break;
+            case 'u' :
+               count += printunsigned( va_arg( argptr, int ), 10 );
+               break;
+            case 'x' :
+            case 'X' :
+               count += printunsigned( va_arg( argptr, int ), 16 );
+               break;
+            }
+         ptr++;
+         }
+      else
+         {
+         myputch( *ptr );
+         count++;
+         ptr++;
+         }
+      }
+
+   va_end( argptr );
+
+   return( count );
+   }

Added: tags/rott-1.1/rott/audiolib/myprint.h
===================================================================
--- tags/rott-1.1/rott/audiolib/myprint.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/myprint.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef __MYPRINT_H
+#define __MYPRINT_H
+
+enum COLORS
+   {
+   BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY,
+   LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE
+   };
+
+#define NONE         -1
+#define SINGLE_FRAME -1
+#define DOUBLE_FRAME -2
+
+void DrawText( int x, int y, int ch, int foreground, int background );
+void TextBox( int x1, int y1, int x2, int y2, int ch, int foreground, int background );
+void TextFrame( int x1, int y1, int x2, int y2, int type, int foreground, int background );
+void mysetxy( int x, int y );
+void myputch( char ch );
+int  printstring( char *string );
+int  printnum( int number );
+int  printunsigned( unsigned long number, int radix );
+int  myprintf( char *fmt, ... );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/newgf1.h
===================================================================
--- tags/rott-1.1/rott/audiolib/newgf1.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/newgf1.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,431 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/***************************************************************************
+*	NAME:  GF1.H
+**	COPYRIGHT:
+**	"Copyright (c) 1991,1992, by FORTE
+**
+**       "This software is furnished under a license and may be used,
+**       copied, or disclosed only in accordance with the terms of such
+**       license and with the inclusion of the above copyright notice.
+**       This software or any other copies thereof may not be provided or
+**       otherwise made available to any other person. No title to and
+**       ownership of the software is hereby transfered."
+****************************************************************************
+*  CREATION DATE: 07/01/92
+*--------------------------------------------------------------------------*
+*     VERSION	DATE	   NAME		DESCRIPTION
+*>	1.0	07/01/92		Original
+***************************************************************************/
+
+#ifndef	_GF1_H		/* allow header to be processed only once */
+#define _GF1_H
+
+/* error codes */
+#define OK			0
+#define NO_MORE_VOICES		-1
+#define	BASE_NOT_FOUND		1
+#define BAD_IRQ			2
+#define BAD_DMA			3
+#define OS_LOADED		4
+#define NOT_LOADED		5
+#define NO_MEMORY		6
+#define DMA_BUSY		7
+#define NO_MORE_HANDLERS	8
+#define DMA_HUNG		9
+#define CARD_NOT_FOUND		10
+#define CARD_BEING_USED		11
+#define NO_MORE_INTERRUPTS	12
+#define BAD_TIMER		13
+#define BAD_PATCH		14
+#define OLD_PATCH		15
+#define DOS_ERROR		16
+#define FILE_NOT_FOUND		17
+
+/* bits */
+#define	BIT0	0x01
+#define	BIT1	0x02
+#define	BIT2	0x04
+#define	BIT3	0x08
+#define	BIT4	0x10
+#define	BIT5	0x20
+#define	BIT6	0x40
+#define	BIT7	0x80
+
+/* bounds for volume enveloping functions */
+#define MIN_OFFSET      5U
+#define MAX_OFFSET      251U
+
+/* bounds for voice allocation */
+#define MIN_VOICES	14
+#define MAX_VOICES	32
+
+/* DMA control bits */
+#define DMA_ENABLE		BIT0
+#define DMA_READ		BIT1
+#define DMA_WIDTH_16		BIT2 /* width of DMA channel */
+#define DMA_RATE_DIV_1		BIT3
+#define DMA_RATE_DIV_2		BIT4
+#define DMA_IRQ_ENABLE		BIT5
+#define DMA_IRQ_PRESENT		BIT6
+#define DMA_DATA_16		BIT6 /* width of data */
+#define DMA_INVERT_MSB		BIT7
+
+/* SAMPLE control bits */
+#define DMA_STEREO		2
+
+/* DMA flags */
+#define GF1_RECORD	0 /* use dma control or sample control */
+#define GF1_DMA		1
+
+/* MIDI control register */
+#define MIDI_RESET	(BIT0|BIT1)
+#define MIDI_TD_INT	BIT5
+#define MIDI_RD_INT	BIT7
+
+/* MIDI_STATUS_REGISTER */
+#define MIDI_RD		BIT0
+#define MIDI_TD		BIT1
+#define MIDI_ERR_FRAMING BIT4
+#define MIDI_ERR_OVERRUN BIT5
+
+/* digital playback flags */
+#define TYPE_8BIT	BIT0	/* 1 use 8 bit data */
+				/* 0 use 16 bit data */
+#define TYPE_PRELOAD	BIT1	/* preload data */
+#define TYPE_INVERT_MSB BIT2	/* invert most significant bit during dma */
+#define TYPE_STEREO	BIT3	/* 1 for stereo data */
+
+/* sound effects and digital music types */
+#define SND_LOOP_MASK		(BIT0|BIT1)
+#define SND_LOOP_NONE		0
+#define SND_LOOP		1
+#define SND_LOOP_BIDIR		2
+#define SND_8BIT		(BIT2)
+#define SND_BACKWARD		(BIT3)
+
+#define SOUND_PLAYING		2
+#define SOUND_ACTIVE		1
+
+/* patch macros */
+#define HEADER_SIZE	           12
+#define ID_SIZE		           10
+#define DESC_SIZE 	           60
+#define RESERVED_SIZE	           40
+#define PATCH_HEADER_RESERVED_SIZE 36
+#define LAYER_RESERVED_SIZE	   40
+#define PATCH_DATA_RESERVED_SIZE   36
+#define GF1_HEADER_TEXT            "GF1PATCH110"
+#define INST_NAME_SIZE		   16
+#define ENVELOPES		   6
+#define MAX_LAYERS		   4
+
+/* patch modes */
+#define PATCH_16		BIT0
+#define PATCH_UNSIGNED		BIT1
+#define PATCH_LOOPEN		BIT2
+#define PATCH_BIDIR		BIT3
+#define PATCH_BACKWARD  	BIT4
+#define PATCH_SUSTAIN   	BIT5
+#define PATCH_NO_SRELEASE	BIT6
+#define PATCH_FAST_REL		BIT7
+
+/* flags for patch loading */
+#define PATCH_LOAD_8_BIT BIT0
+
+/* digital playback callback reasons & return values */
+#define	DIG_DONE	   0
+#define DIG_MORE_DATA	   1
+#define DIG_BUFFER_DONE    2
+#define DIG_PAUSE          3
+
+/* log table used for vibrato and pitch bend.  log table made public for
+** developers use */
+#define LOG_TAB_SIZE 12
+extern long gf1_log_table[LOG_TAB_SIZE];
+
+#if defined(__BORLANDC__)
+#undef RFAR
+#define RFAR far
+#elif defined(_MSC_VER) && (_MSC_VER <= 600)
+#define RFAR far
+#elif defined(_MSC_VER) && (_MSC_VER > 600)
+#define RFAR __far
+#else
+#undef RFAR
+#define RFAR
+#endif
+
+/* structure definitions */
+struct	load_os	
+{
+	unsigned short 	voices;
+	unsigned short	forced_base_port;
+	unsigned char	forced_gf1_irq;
+	unsigned char	forced_midi_irq;
+	unsigned char	forced_channel_in;
+	unsigned char	forced_channel_out;
+};
+
+struct	patchheader
+{
+	char		header[ HEADER_SIZE ];	
+	char		gravis_id[ ID_SIZE ];	/* Id = "ID#000002" */
+	char		description[ DESC_SIZE ];
+	unsigned char	instruments;
+	char		voices;
+	char		channels;
+	unsigned short	wave_forms;
+	unsigned short	master_volume;
+	unsigned long	data_size;
+	char		reserved[ PATCH_HEADER_RESERVED_SIZE ];
+};
+
+struct	instrumentdata
+{
+	unsigned short	instrument;
+	char		instrument_name[ INST_NAME_SIZE ];
+	long		instrument_size;
+	char		layers;
+	char		reserved[ RESERVED_SIZE ];	
+};
+
+struct	layerdata
+{
+	char		layer_duplicate;
+	char		layer;
+	long		layer_size;
+	char		samples;
+	char		reserved[ LAYER_RESERVED_SIZE ];	
+};
+
+struct	patchdata
+{
+	char		wave_name[7];
+	unsigned char	fractions;
+	long		wave_size;
+	long		start_loop;
+	long		end_loop;
+	unsigned short	sample_rate;
+	long		low_frequency;
+	long		high_frequency;
+	long		root_frequency;
+	short		tune;
+	unsigned char	balance;
+	unsigned char	envelope_rate[ ENVELOPES ];
+	unsigned char	envelope_offset[ ENVELOPES ];	
+	unsigned char	tremolo_sweep;
+	unsigned char	tremolo_rate;
+	unsigned char	tremolo_depth;
+	unsigned char	vibrato_sweep;
+	unsigned char	vibrato_rate;
+	unsigned char	vibrato_depth;
+	char		modes;
+	short		scale_frequency;
+	unsigned short	scale_factor;		/* from 0 to 2048 or 0 to 2 */
+	char		reserved[ PATCH_DATA_RESERVED_SIZE ];
+};
+
+struct wave_struct
+{
+	unsigned long		start_loop;
+	unsigned long		end_loop;
+	long		low_frequency;
+	long		high_frequency;
+	long		root_frequency;
+	unsigned long	mem;
+	unsigned short	scale_frequency;
+	unsigned short	sample_rate;
+	unsigned short	scale_factor;
+	unsigned short	start_acc_low;
+	unsigned short	start_acc_high;
+	unsigned short	start_low;
+	unsigned short	start_high;
+	unsigned short	end_low;
+	unsigned short	end_high;
+	unsigned short	end_acc_low;
+	unsigned short	end_acc_high;
+	unsigned short	sample_ratio;
+	unsigned long	wave_size;
+	unsigned char	fractions;
+	unsigned char	balance;
+	unsigned char	envelope_rate[ ENVELOPES ];
+	unsigned char	envelope_offset[ ENVELOPES ];	
+	unsigned char	tremolo_sweep;
+	unsigned char	tremolo_rate;
+	unsigned char	tremolo_depth;
+	unsigned char	vibrato_sweep;
+	unsigned char	vibrato_rate;
+	unsigned char	vibrato_depth;
+	unsigned char	modes;
+};
+
+struct patchinfo {
+	struct patchheader header;
+	struct instrumentdata idata;
+};
+
+struct patch {
+	short nlayers;
+	struct wave_struct RFAR *layer_waves[MAX_LAYERS];
+	short layer_nwaves[MAX_LAYERS];
+	unsigned short detune;
+};
+
+struct gf1_dma_buff {
+	unsigned char RFAR *vptr;
+	unsigned long paddr;
+};
+
+struct gf1_sound {
+	unsigned long mem_pos;
+	unsigned long start_loop;
+	unsigned long end_loop;
+	unsigned char type;
+};
+
+/* GLOBAL VARIABLES (flags) */
+extern char gf1_linear_volumes;
+extern char gf1_dig_use_extra_voice;
+
+/* FUNCTION PROTOTYPES */
+/* Initializeation routines */
+int	gf1_init_ports(int);
+int	gf1_load_os(struct load_os RFAR *os);
+int	gf1_unload_os(void);
+void	gf1_set_appname(char RFAR *);
+void	reset_ultra(int);
+int	gf1_asm_init(void);
+unsigned char gf1_peek(unsigned long address);
+void gf1_poke(unsigned long address, unsigned char data);
+void gf1_poke_block(unsigned char RFAR *data, unsigned long address, unsigned long len, unsigned char dma_control);
+char gf1_good_dram(unsigned long address);
+int GetUltraCfg(struct load_os RFAR *os);
+unsigned long gf1_malloc(unsigned long);
+void gf1_free(unsigned long);
+unsigned long gf1_mem_avail(void);
+unsigned long gf1_mem_largest_avail(void);
+void gf1_delay(void);
+int gf1_allocate_voice(int priority, void (RFAR *steal_notify)(int));
+void gf1_free_voice(unsigned int i);
+void gf1_adjust_priority(int voice, int priority);
+int gf1_dram_xfer(struct gf1_dma_buff RFAR *dptr, unsigned long size, unsigned long dram_address, unsigned char dma_control, unsigned short flags);
+void gf1_stop_dma(void);
+long convert_to_16bit(long address);
+int gf1_wait_dma(void);
+int gf1_dma_ready(void);
+unsigned long gf1_amount_xferred(void);
+int gf1_detect_card(unsigned short port);
+char *gf1_error_str(int);
+int gf1_play_digital(unsigned short priority, unsigned char RFAR *buffer,
+	unsigned long size, unsigned long gf1_addr, unsigned short volume,
+	unsigned short pan, unsigned short frequency, unsigned char type,
+	struct gf1_dma_buff RFAR *dptr,
+	int (RFAR *callback)(int, int, unsigned char RFAR * RFAR *, unsigned long RFAR *));
+void gf1_restart_digital(int voice);
+void gf1_start_digital(int voice);
+void gf1_pause_digital(int voice);
+void RFAR gf1_stop_digital(int voice);
+void gf1_dig_set_dma_rate(unsigned short rate);
+unsigned long gf1_digital_position(int voice);
+int gf1_myatoi(void);
+int gf1_update_waveform(struct wave_struct RFAR *wave_info);
+int gf1_get_patch_info(char RFAR *patch_file, struct patchinfo RFAR *patch);
+int gf1_load_patch(char RFAR *patch_file, struct patchinfo RFAR *patchinfo,
+	struct patch RFAR *patch,
+	struct gf1_dma_buff RFAR *dptr, unsigned short size,
+	unsigned char RFAR *wavemem, int flags);
+void gf1_unload_patch(struct patch RFAR *patch);
+void gf1_detune_patch(struct patch RFAR *patch, unsigned short detune);
+unsigned short gf1_calc_fc(unsigned int sample_ratio,long root,long frequency);
+void gf1_midi_stop_voice(int voice);
+void gf1_midi_wait_voice(int voice);
+unsigned short gf1_midi_status_note(int voice);
+unsigned short gf1_midi_status_voice(int voice);
+void RFAR gf1_midi_stop_note(int note_voice);
+void gf1_midi_note_on(struct patch RFAR *patch, int priority, int note, int velocity, int channel);
+void gf1_midi_note_off(int note, int channel);
+void gf1_midi_silence_patch_notes(struct patch RFAR *patch);
+void gf1_midi_patch_removed(struct patch RFAR *patch);
+int gf1_enable_timer1(int (RFAR *callback)(void), int resolution);
+int gf1_enable_timer2(int (RFAR *callback)(void), int resolution);
+void gf1_disable_timer1(void);
+void gf1_disable_timer2(void);
+void gf1_channel_pitch_bend(int channel, unsigned int bend);
+void gf1_midi_synth_volume(unsigned short synth, int master_volume);
+void gf1_midi_change_program(struct patch RFAR *patch, int channel);
+void gf1_midi_set_vibrato(int channel, int value);
+void gf1_midi_change_volume(int channel, unsigned int volume);
+void gf1_midi_set_balance(int balance, int channel);
+void gf1_midi_channel_sustain(int channel, int sustain);
+void gf1_midi_all_notes_off(int channel);
+void gf1_midi_pitch_bend(int channel, int lsb, int msb);
+void gf1_midi_parameter(int channel, int control, int value);
+int gf1_midi_get_channel_notes(int channel, int notes[]);
+int gf1_midi_get_channel_volume(int channel);
+int gf1_midi_get_master_volume(void);
+int gf1_midi_get_volume(int voice);
+unsigned short gf1_read(int handle, void RFAR *io_buffer, unsigned short size);
+unsigned short gf1_close_file(int handle);
+unsigned int gf1_seek(int handle, unsigned long offset, int method);
+int gf1_open(char RFAR *name);
+#ifdef __FLAT__
+int gf1_atoi(char RFAR **str, int base);
+#else
+int gf1_atoi(void);
+#endif
+void gf1_leave(void);
+short gf1_enter(void);
+void gf1_enter1(void);
+int gf1_play_next_buffer(int voice, unsigned char RFAR *buff, unsigned long size);
+void gf1_dig_set_vol(unsigned short voice, unsigned short vol);
+void gf1_dig_set_pan(unsigned short voice, unsigned short pan);
+int gf1_set_external_semaphore(void RFAR *addr);
+int gf1_clear_external_semaphore(void RFAR *addr);
+void gf1_midi_reset(int c);
+int gf1_add_midi_recv_handler(int (RFAR *handler)());
+int gf1_add_dma_handler(int (*handler)());
+int gf1_add_voice_handler(int (*handler)(int));
+int gf1_add_volume_handler(int (*handler)(int));
+int gf1_add_timer_handler(int timer, int (RFAR *handler)(void));
+void gf1_set_record_rate(unsigned long rate);
+void gf1_create_patch(struct patch RFAR *patch);
+int gf1_add_layer(struct patch RFAR *patch, int layer, char RFAR *wavemem);
+void gf1_get_waveform_info(struct patch RFAR *patch, int layer, int waven,
+	struct wave_struct RFAR *wave);
+void gf1_set_waveform_info(struct patch RFAR *patch, int layer, int waven,
+	struct wave_struct RFAR *wave);
+void gf1_enable_line_in(void);
+void gf1_disable_line_in(void);
+void gf1_enable_mic_in(void);
+void gf1_disable_mic_in(void);
+void gf1_enable_output(void);
+void gf1_disable_output(void);
+void gf1_sound_volume(unsigned short voice, int volume,
+	unsigned long period /* us*10 */);
+void gf1_sound_pan(unsigned short voice, unsigned short pan);
+void gf1_sound_frequency(unsigned short voice, unsigned long freq);
+void RFAR gf1_sound_stop(int voice);
+void gf1_sound_mode(int voice, struct gf1_sound RFAR *sound,
+	unsigned char type);
+int gf1_sound_start(unsigned short priority, struct gf1_sound RFAR *sound,
+	short volume, unsigned long period, short pan, unsigned long freq);
+int gf1_sound_playing(int voice);
+#endif

Added: tags/rott-1.1/rott/audiolib/nodpmi.c
===================================================================
--- tags/rott-1.1/rott/audiolib/nodpmi.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/nodpmi.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,179 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: DPMI.C
+
+   author: James R. Dose
+   date:   April 8, 1994
+
+   Functions for performing DPMI calls.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "dpmi.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+/*---------------------------------------------------------------------
+   Function: DPMI_GetRealModeVector
+
+   Returns the vector of a real mode interrupt.
+---------------------------------------------------------------------*/
+
+unsigned long DPMI_GetRealModeVector
+   (
+   int num
+   )
+
+   {
+   return 0;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_SetRealModeVector
+
+   Sets the vector of a real mode interrupt.
+---------------------------------------------------------------------*/
+
+void DPMI_SetRealModeVector
+   (
+   int num,
+   unsigned long vector
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_CallRealModeFunction
+
+   Performs a call to a real mode function.
+---------------------------------------------------------------------*/
+
+int DPMI_CallRealModeFunction
+   (
+   dpmi_regs *callregs
+   )
+
+   {
+   return( DPMI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_LockMemory
+
+   Locks a region of memory to keep the virtual memory manager from
+   paging the region out.
+---------------------------------------------------------------------*/
+
+int DPMI_LockMemory
+   (
+   void *address,
+   unsigned length
+   )
+
+   {
+   return ( DPMI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_LockMemoryRegion
+
+   Locks a region of memory to keep the virtual memory manager from
+   paging the region out.
+---------------------------------------------------------------------*/
+
+int DPMI_LockMemoryRegion
+   (
+   void *start,
+   void *end
+   )
+
+   {
+   int status;
+
+   status = DPMI_LockMemory( start, ( char * )end - ( char * )start );
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_UnlockMemory
+
+   Unlocks a region of memory that was previously locked.
+---------------------------------------------------------------------*/
+
+int DPMI_UnlockMemory
+   (
+   void *address,
+   unsigned length
+   )
+
+   {
+   return ( DPMI_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: DPMI_UnlockMemoryRegion
+
+   Unlocks a region of memory that was previously locked.
+---------------------------------------------------------------------*/
+
+int DPMI_UnlockMemoryRegion
+   (
+   void *start,
+   void *end
+   )
+
+   {
+   int status;
+
+   status = DPMI_UnlockMemory( start, ( char * )end - ( char * )start );
+
+   return( status );
+   }
+
+int DPMI_GetDOSMemory( void **ptr, long *descriptor, unsigned length )
+{
+	/* Lovely... */
+	
+	*ptr = (void *)malloc(length);
+	
+	*descriptor = (long) *ptr;
+	
+	return (descriptor == 0) ? DPMI_Error : DPMI_Ok;
+}
+
+int DPMI_FreeDOSMemory( long descriptor )
+{
+	free((void *)descriptor);
+	
+	return (descriptor == 0) ? DPMI_Error : DPMI_Ok;
+}

Added: tags/rott-1.1/rott/audiolib/nomusic.c
===================================================================
--- tags/rott-1.1/rott/audiolib/nomusic.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/nomusic.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,115 @@
+#include "music.h"
+
+char *MUSIC_ErrorString(int ErrorNumber)
+{
+	return "";
+}
+
+int MUSIC_Init(int SoundCard, int Address)
+{
+	return 0;
+}
+
+int MUSIC_Shutdown(void)
+{
+	return 0;
+}
+
+void MUSIC_SetMaxFMMidiChannel(int channel)
+{
+}
+
+void MUSIC_SetVolume(int volume)
+{
+}
+
+void MUSIC_SetMidiChannelVolume(int channel, int volume)
+{
+}
+
+void MUSIC_ResetMidiChannelVolumes(void)
+{
+}
+
+int MUSIC_GetVolume(void)
+{
+	return 0;
+}
+
+void MUSIC_SetLoopFlag(int loopflag)
+{
+}
+
+int MUSIC_SongPlaying(void)
+{
+	return 0;
+}
+
+void MUSIC_Continue(void)
+{
+}
+
+void MUSIC_Pause(void)
+{
+}
+
+int MUSIC_StopSong(void)
+{
+	return 0;
+}
+
+int MUSIC_PlaySong(unsigned char *song, int loopflag)
+{
+	return 0;
+}
+
+void MUSIC_SetContext(int context)
+{
+}
+
+int MUSIC_GetContext(void)
+{
+	return 0;
+}
+
+void MUSIC_SetSongTick(unsigned long PositionInTicks)
+{
+}
+
+void MUSIC_SetSongTime(unsigned long milliseconds)
+{
+}
+
+void MUSIC_SetSongPosition(int measure, int beat, int tick)
+{
+}
+
+void MUSIC_GetSongPosition(songposition *pos)
+{
+}
+
+void MUSIC_GetSongLength(songposition *pos)
+{
+}
+
+int MUSIC_FadeVolume(int tovolume, int milliseconds)
+{
+	return 0;
+}
+
+int MUSIC_FadeActive(void)
+{
+	return 0;
+}
+
+void MUSIC_StopFade(void)
+{
+}
+
+void MUSIC_RerouteMidiChannel(int channel, int cdecl function( int event, int c1, int c2 ))
+{
+}
+
+void MUSIC_RegisterTimbreBank(unsigned char *timbres)
+{
+}

Added: tags/rott-1.1/rott/audiolib/pas16.c
===================================================================
--- tags/rott-1.1/rott/audiolib/pas16.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/pas16.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1924 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: PAS16.C
+
+   author: James R. Dose
+   date:   March 27, 1994
+
+   Low level routines to support Pro AudioSpectrum and compatible
+   sound cards.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <dos.h>
+#include <conio.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "dpmi.h"
+#include "dma.h"
+#include "interrup.h"
+#include "irq.h"
+#include "pas16.h"
+#include "_pas16.h"
+
+#define USESTACK
+
+static const int PAS_Interrupts[ PAS_MaxIrq + 1 ]  =
+   {
+   INVALID, INVALID,     0xa,     0xb,
+   INVALID,     0xd, INVALID,     0xf,
+   INVALID, INVALID,    0x72,    0x73,
+      0x74, INVALID, INVALID,    0x77
+   };
+
+static void    ( interrupt far *PAS_OldInt )( void );
+
+static int PAS_IntController1Mask;
+static int PAS_IntController2Mask;
+
+static int PAS_Installed = FALSE;
+static int PAS_TranslateCode = DEFAULT_BASE;
+
+static int PAS_OriginalPCMLeftVolume  = 75;
+static int PAS_OriginalPCMRightVolume = 75;
+
+static int PAS_OriginalFMLeftVolume  = 75;
+static int PAS_OriginalFMRightVolume = 75;
+
+unsigned int PAS_DMAChannel;
+static int PAS_Irq;
+
+static MVState *PAS_State = NULL;
+static MVFunc  *PAS_Func  = NULL;
+
+static MVState PAS_OriginalState;
+static int     PAS_SampleSizeConfig;
+
+static char   *PAS_DMABuffer;
+static char   *PAS_DMABufferEnd;
+static char   *PAS_CurrentDMABuffer;
+static int     PAS_TotalDMABufferSize;
+
+static int      PAS_TransferLength   = 0;
+static int      PAS_MixMode          = PAS_DefaultMixMode;
+static unsigned PAS_SampleRate       = PAS_DefaultSampleRate;
+static int      PAS_TimeInterval     = 0;
+
+volatile int   PAS_SoundPlaying;
+
+void ( *PAS_CallBack )( void );
+
+// adequate stack size
+#define kStackSize 2048
+
+static unsigned short StackSelector = NULL;
+static unsigned long  StackPointer;
+
+static unsigned short oldStackSelector;
+static unsigned long  oldStackPointer;
+
+// This is defined because we can't create local variables in a
+// function that switches stacks.
+static int irqstatus;
+
+// These declarations are necessary to use the inline assembly pragmas.
+
+extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
+extern void SetStack(unsigned short selector,unsigned long stackptr);
+
+// This function will get the current stack selector and pointer and save
+// them off.
+#pragma aux GetStack =  \
+   "mov  [edi],esp"     \
+   "mov  ax,ss"         \
+   "mov  [esi],ax"      \
+   parm [esi] [edi]     \
+   modify [eax esi edi];
+
+// This function will set the stack selector and pointer to the specified
+// values.
+#pragma aux SetStack =  \
+   "mov  ss,ax"         \
+   "mov  esp,edx"       \
+   parm [ax] [edx]      \
+   modify [eax edx];
+
+int PAS_ErrorCode = PAS_Ok;
+
+#define PAS_SetErrorCode( status ) \
+   PAS_ErrorCode   = ( status );
+
+/*---------------------------------------------------------------------
+   Function: PAS_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *PAS_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case PAS_Warning :
+      case PAS_Error :
+         ErrorString = PAS_ErrorString( PAS_ErrorCode );
+         break;
+
+      case PAS_Ok :
+         ErrorString = "Pro AudioSpectrum ok.";
+         break;
+
+      case PAS_DriverNotFound :
+         ErrorString = "MVSOUND.SYS not loaded.";
+         break;
+
+      case PAS_DmaError :
+         ErrorString = DMA_ErrorString( DMA_Error );
+         break;
+
+      case PAS_InvalidIrq :
+         ErrorString = "Invalid Pro AudioSpectrum Irq.";
+         break;
+
+      case PAS_UnableToSetIrq :
+         ErrorString = "Unable to set Pro AudioSpectrum IRQ.  Try selecting an IRQ of 7 or below.";
+         break;
+
+      case PAS_Dos4gwIrqError :
+         ErrorString = "Unsupported Pro AudioSpectrum Irq.";
+         break;
+
+      case PAS_NoSoundPlaying :
+         ErrorString = "No sound playing on Pro AudioSpectrum.";
+         break;
+
+      case PAS_CardNotFound :
+         ErrorString = "Could not find Pro AudioSpectrum.";
+         break;
+
+      case PAS_DPMI_Error :
+         ErrorString = "DPMI Error in PAS16.";
+         break;
+
+      case PAS_OutOfMemory :
+         ErrorString = "Out of conventional memory in PAS16.";
+         break;
+
+      default :
+         ErrorString = "Unknown Pro AudioSpectrum error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define PAS_LockStart PAS_CheckForDriver
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_CheckForDriver
+
+   Checks to see if MVSOUND.SYS is installed.
+---------------------------------------------------------------------*/
+
+int PAS_CheckForDriver
+   (
+   void
+   )
+
+   {
+   union REGS regs;
+   unsigned   result;
+
+   regs.w.ax = MV_CheckForDriver;
+   regs.w.bx = 0x3f3f;
+
+   #ifdef __386__
+      int386( MV_SoundInt, &regs, &regs );
+   #else
+      int86( MV_SoundInt, &regs, &regs );
+   #endif
+
+   if ( regs.w.ax != MV_CheckForDriver )
+      {
+      PAS_SetErrorCode( PAS_DriverNotFound );
+      return( PAS_Error );
+      }
+
+   result = regs.w.bx ^ regs.w.cx ^ regs.w.dx;
+   if ( result != MV_Signature )
+      {
+      PAS_SetErrorCode( PAS_DriverNotFound );
+      return( PAS_Error );
+      }
+
+   return( PAS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_GetStateTable
+
+   Returns a pointer to the state table containing hardware state
+   information.  The state table is necessary because the Pro Audio-
+   Spectrum contains only write-only registers.
+---------------------------------------------------------------------*/
+
+MVState *PAS_GetStateTable
+   (
+   void
+   )
+
+   {
+   union REGS   regs;
+   MVState *ptr;
+
+   regs.w.ax = MV_GetPointerToStateTable;
+
+   #ifdef __386__
+      int386( MV_SoundInt, &regs, &regs );
+   #else
+      int86( MV_SoundInt, &regs, &regs );
+   #endif
+
+   if ( regs.w.ax != MV_Signature )
+      {
+      PAS_SetErrorCode( PAS_DriverNotFound );
+      return( NULL );
+      }
+
+   #if defined(__WATCOMC__) && defined(__FLAT__)
+      ptr = ( MVState * )( ( ( ( unsigned )regs.w.dx ) << 4 ) +
+         ( ( unsigned )regs.w.bx ) );
+   #else
+      ptr = MK_FP( regs.w.dx, regs.w.bx );
+   #endif
+
+   return( ptr );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_GetFunctionTable
+
+   Returns a pointer to the function table containing addresses of
+   driver functions.
+---------------------------------------------------------------------*/
+
+MVFunc *PAS_GetFunctionTable
+   (
+   void
+   )
+
+   {
+   union REGS   regs;
+   MVFunc *ptr;
+
+   regs.w.ax = MV_GetPointerToFunctionTable;
+
+   #ifdef __386__
+      int386( MV_SoundInt, &regs, &regs );
+   #else
+      int86( MV_SoundInt, &regs, &regs );
+   #endif
+
+   if ( regs.w.ax != MV_Signature )
+      {
+      PAS_SetErrorCode( PAS_DriverNotFound );
+      return( NULL );
+      }
+
+   #if defined(__WATCOMC__) && defined(__FLAT__)
+      ptr = ( MVFunc * )( ( ( ( unsigned )regs.w.dx ) << 4 ) +
+         ( ( unsigned )regs.w.bx ) );
+   #else
+      ptr = MK_FP( regs.w.dx, regs.w.bx );
+   #endif
+
+   return( ptr );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_GetCardSettings
+
+   Returns the DMA and the IRQ channels of the sound card.
+---------------------------------------------------------------------*/
+
+int PAS_GetCardSettings
+   (
+   void
+   )
+
+   {
+   union REGS   regs;
+   int          status;
+
+   regs.w.ax = MV_GetDmaIrqInt;
+
+   #ifdef __386__
+      int386( MV_SoundInt, &regs, &regs );
+   #else
+      int86( MV_SoundInt, &regs, &regs );
+   #endif
+
+   if ( regs.w.ax != MV_Signature )
+      {
+      PAS_SetErrorCode( PAS_DriverNotFound );
+      return( PAS_Error );
+      }
+
+   PAS_DMAChannel = regs.w.bx;
+   PAS_Irq        = regs.w.cx;
+
+   if ( PAS_Irq > PAS_MaxIrq )
+      {
+      PAS_SetErrorCode( PAS_Dos4gwIrqError );
+      return( PAS_Error );
+      }
+
+   if ( !VALID_IRQ( PAS_Irq ) )
+      {
+      PAS_SetErrorCode( PAS_InvalidIrq );
+      return( PAS_Error );
+      }
+
+   if ( PAS_Interrupts[ PAS_Irq ] == INVALID )
+      {
+      PAS_SetErrorCode( PAS_InvalidIrq );
+      return( PAS_Error );
+      }
+
+   status = DMA_VerifyChannel( PAS_DMAChannel );
+   if ( status == DMA_Error )
+      {
+      PAS_SetErrorCode( PAS_DmaError );
+      return( PAS_Error );
+      }
+
+   return( PAS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_EnableInterrupt
+
+   Enables the triggering of the sound card interrupt.
+---------------------------------------------------------------------*/
+
+void PAS_EnableInterrupt
+   (
+   void
+   )
+
+   {
+   int mask;
+   int data;
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   if ( PAS_Irq < 8 )
+      {
+      mask = inp( 0x21 ) & ~( 1 << PAS_Irq );
+      outp( 0x21, mask  );
+      }
+   else
+      {
+      mask = inp( 0xA1 ) & ~( 1 << ( PAS_Irq - 8 ) );
+      outp( 0xA1, mask  );
+
+      mask = inp( 0x21 ) & ~( 1 << 2 );
+      outp( 0x21, mask  );
+      }
+
+   // Flush any pending interrupts
+   PAS_Write( InterruptStatus, PAS_Read( InterruptStatus ) & 0x40 );
+
+   // Enable the interrupt on the PAS
+   data = PAS_State->intrctlr;
+   data |= SampleBufferInterruptFlag;
+   PAS_Write( InterruptControl, data );
+   PAS_State->intrctlr = data;
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_DisableInterrupt
+
+   Disables the triggering of the sound card interrupt.
+---------------------------------------------------------------------*/
+
+void PAS_DisableInterrupt
+   (
+   void
+   )
+
+   {
+   int mask;
+   int data;
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   // Disable the interrupt on the PAS
+   data = PAS_State->intrctlr;
+   data &= ~( SampleRateInterruptFlag | SampleBufferInterruptFlag );
+   PAS_Write( InterruptControl, data );
+   PAS_State->intrctlr = data;
+
+   // Restore interrupt mask
+   if ( PAS_Irq < 8 )
+      {
+      mask  = inp( 0x21 ) & ~( 1 << PAS_Irq );
+      mask |= PAS_IntController1Mask & ( 1 << PAS_Irq );
+      outp( 0x21, mask  );
+      }
+   else
+      {
+      mask  = inp( 0x21 ) & ~( 1 << 2 );
+      mask |= PAS_IntController1Mask & ( 1 << 2 );
+      outp( 0x21, mask  );
+
+      mask  = inp( 0xA1 ) & ~( 1 << ( PAS_Irq - 8 ) );
+      mask |= PAS_IntController2Mask & ( 1 << ( PAS_Irq - 8 ) );
+      outp( 0xA1, mask  );
+      }
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_ServiceInterrupt
+
+   Handles interrupt generated by sound card at the end of a voice
+   transfer.  Calls the user supplied callback function.
+---------------------------------------------------------------------*/
+
+void interrupt far PAS_ServiceInterrupt
+   (
+   void
+   )
+
+   {
+   #ifdef USESTACK
+   // save stack
+   GetStack( &oldStackSelector, &oldStackPointer );
+
+   // set our stack
+   SetStack( StackSelector, StackPointer );
+   #endif
+
+   irqstatus = PAS_Read( InterruptStatus );
+   if ( ( irqstatus & SampleBufferInterruptFlag ) == 0 )
+      {
+      #ifdef USESTACK
+      // restore stack
+      SetStack( oldStackSelector, oldStackPointer );
+      #endif
+
+      _chain_intr( PAS_OldInt );
+      }
+
+   // Clear the interrupt
+   irqstatus &= ~SampleBufferInterruptFlag;
+   PAS_Write( InterruptStatus, irqstatus );
+
+   // send EOI to Interrupt Controller
+   if ( PAS_Irq > 7 )
+      {
+      outp( 0xA0, 0x20 );
+      }
+   outp( 0x20, 0x20 );
+
+
+   // Keep track of current buffer
+   PAS_CurrentDMABuffer += PAS_TransferLength;
+   if ( PAS_CurrentDMABuffer >= PAS_DMABufferEnd )
+      {
+      PAS_CurrentDMABuffer = PAS_DMABuffer;
+      }
+
+   // Call the caller's callback function
+   if ( PAS_CallBack != NULL )
+      {
+      PAS_CallBack();
+      }
+
+   #ifdef USESTACK
+   // restore stack
+   SetStack( oldStackSelector, oldStackPointer );
+   #endif
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_Write
+
+   Writes a byte of data to the sound card.
+---------------------------------------------------------------------*/
+
+void PAS_Write
+   (
+   int Register,
+   int Data
+   )
+
+   {
+   int port;
+
+   port = Register ^ PAS_TranslateCode;
+   outp( port, Data );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_Read
+
+   Reads a byte of data from the sound card.
+---------------------------------------------------------------------*/
+
+int PAS_Read
+   (
+   int Register
+   )
+
+   {
+   int port;
+   int data;
+
+   port = Register ^ PAS_TranslateCode;
+   data = inp( port );
+   return( data );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_SetSampleRateTimer
+
+   Programs the Sample Rate Timer.
+---------------------------------------------------------------------*/
+
+void PAS_SetSampleRateTimer
+   (
+   void
+   )
+
+   {
+   int LoByte;
+   int HiByte;
+   int data;
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   // Disable the Sample Rate Timer
+   data = PAS_State->audiofilt;
+   data &= ~SampleRateTimerGateFlag;
+   PAS_Write( AudioFilterControl, data );
+   PAS_State->audiofilt = data;
+
+   // Select the Sample Rate Timer
+   data = SelectSampleRateTimer;
+   PAS_Write( LocalTimerControl, data );
+   PAS_State->tmrctlr = data;
+
+   LoByte = lobyte( PAS_TimeInterval );
+   HiByte = hibyte( PAS_TimeInterval );
+
+   // Program the Sample Rate Timer
+   PAS_Write( SampleRateTimer, LoByte );
+   PAS_Write( SampleRateTimer, HiByte );
+   PAS_State->samplerate = PAS_TimeInterval;
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_SetSampleBufferCount
+
+   Programs the Sample Buffer Count.
+---------------------------------------------------------------------*/
+
+void PAS_SetSampleBufferCount
+   (
+   void
+   )
+
+   {
+   int LoByte;
+   int HiByte;
+   int count;
+   int data;
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   // Disable the Sample Buffer Count
+   data = PAS_State->audiofilt;
+   data &= ~SampleBufferCountGateFlag;
+   PAS_Write( AudioFilterControl, data );
+   PAS_State->audiofilt = data;
+
+   // Select the Sample Buffer Count
+   data = SelectSampleBufferCount;
+   PAS_Write( LocalTimerControl, data );
+   PAS_State->tmrctlr = data;
+
+   count = PAS_TransferLength;
+
+   // Check if we're using a 16-bit DMA channel
+   if ( PAS_DMAChannel > 3 )
+      {
+      count >>= 1;
+      }
+
+   LoByte = lobyte( count );
+   HiByte = hibyte( count );
+
+   // Program the Sample Buffer Count
+   PAS_Write( SampleBufferCount, LoByte );
+   PAS_Write( SampleBufferCount, HiByte );
+   PAS_State->samplecnt = count;
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_SetPlaybackRate
+
+   Sets the rate at which the digitized sound will be played in
+   hertz.
+---------------------------------------------------------------------*/
+
+void PAS_SetPlaybackRate
+   (
+   unsigned rate
+   )
+
+   {
+   if ( rate < PAS_MinSamplingRate )
+      {
+      rate = PAS_MinSamplingRate;
+      }
+
+   if ( rate > PAS_MaxSamplingRate )
+      {
+      rate = PAS_MaxSamplingRate;
+      }
+
+   PAS_TimeInterval = ( unsigned )CalcTimeInterval( rate );
+   if ( PAS_MixMode & STEREO )
+      {
+      PAS_TimeInterval /= 2;
+      }
+
+   // Keep track of what the actual rate is
+   PAS_SampleRate = CalcSamplingRate( PAS_TimeInterval );
+   if ( PAS_MixMode & STEREO )
+      {
+      PAS_SampleRate /= 2;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_GetPlaybackRate
+
+   Returns the rate at which the digitized sound will be played in
+   hertz.
+---------------------------------------------------------------------*/
+
+unsigned PAS_GetPlaybackRate
+   (
+   void
+   )
+
+   {
+   return( PAS_SampleRate );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_SetMixMode
+
+   Sets the sound card to play samples in mono or stereo.
+---------------------------------------------------------------------*/
+
+int PAS_SetMixMode
+   (
+   int mode
+   )
+
+   {
+   mode &= PAS_MaxMixMode;
+
+   // Check board revision.  Revision # 0 can't play 16-bit data.
+   if ( ( PAS_State->intrctlr & 0xe0 ) == 0 )
+      {
+      // Force the mode to 8-bit data.
+      mode &= ~SIXTEEN_BIT;
+      }
+
+   PAS_MixMode = mode;
+
+   PAS_SetPlaybackRate( PAS_SampleRate );
+
+   return( mode );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_StopPlayback
+
+   Ends the DMA transfer of digitized sound to the sound card.
+---------------------------------------------------------------------*/
+
+void PAS_StopPlayback
+   (
+   void
+   )
+
+   {
+   int data;
+
+   // Don't allow anymore interrupts
+   PAS_DisableInterrupt();
+
+   // Stop the transfer of digital data
+   data = PAS_State->crosschannel;
+   data &= PAS_PCMStopMask;
+   PAS_Write( CrossChannelControl, data );
+   PAS_State->crosschannel = data;
+
+   // Turn off 16-bit unsigned data
+   data = PAS_Read( SampleSizeConfiguration );
+   data &= PAS_SampleSizeMask;
+   PAS_Write( SampleSizeConfiguration, data );
+
+   // Disable the DMA channel
+   DMA_EndTransfer( PAS_DMAChannel );
+
+   PAS_SoundPlaying = FALSE;
+
+   PAS_DMABuffer = NULL;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_SetupDMABuffer
+
+   Programs the DMAC for sound transfer.
+---------------------------------------------------------------------*/
+
+int PAS_SetupDMABuffer
+   (
+   char *BufferPtr,
+   int   BufferSize,
+   int   mode
+   )
+
+   {
+   int DmaStatus;
+   int data;
+
+   // Enable PAS Dma
+   data  = PAS_State->crosschannel;
+   data |= PAS_DMAEnable;
+   PAS_Write( CrossChannelControl, data );
+   PAS_State->crosschannel = data;
+
+   DmaStatus = DMA_SetupTransfer( PAS_DMAChannel, BufferPtr, BufferSize, mode );
+   if ( DmaStatus == DMA_Error )
+      {
+      PAS_SetErrorCode( PAS_DmaError );
+      return( PAS_Error );
+      }
+
+   PAS_DMABuffer          = BufferPtr;
+   PAS_CurrentDMABuffer   = BufferPtr;
+   PAS_TotalDMABufferSize = BufferSize;
+   PAS_DMABufferEnd       = BufferPtr + BufferSize;
+
+   return( PAS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_GetCurrentPos
+
+   Returns the offset within the current sound being played.
+---------------------------------------------------------------------*/
+
+int PAS_GetCurrentPos
+   (
+   void
+   )
+
+   {
+   char *CurrentAddr;
+   int   offset;
+
+   if ( !PAS_SoundPlaying )
+      {
+      PAS_SetErrorCode( PAS_NoSoundPlaying );
+      return( PAS_Error );
+      }
+
+   CurrentAddr = DMA_GetCurrentPos( PAS_DMAChannel );
+   if ( CurrentAddr == NULL )
+      {
+      PAS_SetErrorCode( PAS_DmaError );
+      return( PAS_Error );
+      }
+
+   offset = ( int )( ( ( unsigned long )CurrentAddr ) -
+      ( ( unsigned long )PAS_CurrentDMABuffer ) );
+
+   if ( PAS_MixMode & SIXTEEN_BIT )
+      {
+      offset >>= 1;
+      }
+
+   if ( PAS_MixMode & STEREO )
+      {
+      offset >>= 1;
+      }
+
+   return( offset );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_GetFilterSetting
+
+   Returns the bit settings for the appropriate filter level.
+---------------------------------------------------------------------*/
+
+int PAS_GetFilterSetting
+   (
+   int rate
+   )
+
+   {
+   /* CD Quality 17897hz */
+   if ( ( unsigned long )rate > ( unsigned long )17897L * 2 )
+      {
+      /* 00001b 20hz to 17.8khz */
+      return( 0x01 );
+      }
+
+   /* Cassette Quality 15090hz */
+   if ( ( unsigned long )rate > ( unsigned long )15909L * 2 )
+      {
+      /* 00010b 20hz to 15.9khz */
+      return( 0x02 );
+      }
+
+   /* FM Radio Quality 11931hz */
+   if ( ( unsigned long )rate > ( unsigned long )11931L * 2 )
+      {
+      /* 01001b 20hz to 11.9khz */
+      return( 0x09 );
+      }
+
+   /* AM Radio Quality  8948hz */
+   if ( ( unsigned long )rate > ( unsigned long )8948L * 2 )
+      {
+      /* 10001b 20hz to 8.9khz */
+      return( 0x11 );
+      }
+
+   /* Telphone Quality  5965hz */
+   if ( ( unsigned long )rate > ( unsigned long )5965L * 2 )
+      {
+      /* 00100b 20hz to 5.9khz */
+      return( 0x19 );
+      }
+
+   /* Male voice quality 2982hz */
+   /* 111001b 20hz to 2.9khz */
+   return( 0x04 );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_BeginTransfer
+
+   Starts playback of digitized sound on the sound card.
+---------------------------------------------------------------------*/
+
+void PAS_BeginTransfer
+   (
+   int mode
+   )
+
+   {
+   int data;
+
+   PAS_SetSampleRateTimer();
+
+   PAS_SetSampleBufferCount();
+
+   PAS_EnableInterrupt();
+
+   // Get sample size configuration
+   data = PAS_Read( SampleSizeConfiguration );
+
+   // Check board revision.  Revision # 0 can't play 16-bit data.
+   if ( PAS_State->intrctlr & 0xe0 )
+      {
+      data &= PAS_SampleSizeMask;
+
+      // set sample size bit
+      if ( PAS_MixMode & SIXTEEN_BIT )
+         {
+         data |= PAS_16BitSampleFlag;
+         }
+      }
+
+   // set oversampling rate
+   data &= PAS_OverSamplingMask;
+   data |= PAS_4xOverSampling;
+
+   // Set sample size configuration
+   PAS_Write( SampleSizeConfiguration, data );
+
+   // Get Cross channel setting
+   data  = PAS_State->crosschannel;
+   data &= PAS_ChannelConnectMask;
+   if ( mode == RECORD )
+      {
+      data |= PAS_PCMStartADC;
+      }
+   else
+      {
+      data |= PAS_PCMStartDAC;
+      }
+
+   // set stereo mode bit
+   if ( !( PAS_MixMode & STEREO ) )
+      {
+      data |= PAS_StereoFlag;
+      }
+
+   PAS_Write( CrossChannelControl, data );
+   PAS_State->crosschannel = data;
+
+   // Get the filter appropriate filter setting
+   data = PAS_GetFilterSetting( PAS_SampleRate );
+
+   // Enable the Sample Rate Timer and Sample Buffer Count
+   data |= SampleRateTimerGateFlag | SampleBufferCountGateFlag;
+
+   if ( mode != RECORD )
+      {
+      // Enable audio (not Audio Mute)
+      data |= PAS_AudioMuteFlag;
+      }
+
+   PAS_Write( AudioFilterControl, data );
+   PAS_State->audiofilt = data;
+
+   PAS_SoundPlaying = TRUE;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_BeginBufferedPlayback
+
+   Begins multibuffered playback of digitized sound on the sound card.
+---------------------------------------------------------------------*/
+
+int PAS_BeginBufferedPlayback
+   (
+   char *BufferStart,
+   int   BufferSize,
+   int   NumDivisions,
+   unsigned SampleRate,
+   int   MixMode,
+   void ( *CallBackFunc )( void )
+   )
+
+   {
+   int DmaStatus;
+
+   PAS_StopPlayback();
+
+   PAS_SetMixMode( MixMode );
+   PAS_SetPlaybackRate( SampleRate );
+
+   PAS_TransferLength = BufferSize / NumDivisions;
+   PAS_SetCallBack( CallBackFunc );
+
+   DmaStatus = PAS_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitRead );
+   if ( DmaStatus == PAS_Error )
+      {
+      return( PAS_Error );
+      }
+
+   PAS_BeginTransfer( PLAYBACK );
+
+   return( PAS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_BeginBufferedRecord
+
+   Begins multibuffered recording of digitized sound on the sound card.
+---------------------------------------------------------------------*/
+
+int PAS_BeginBufferedRecord
+   (
+   char *BufferStart,
+   int   BufferSize,
+   int   NumDivisions,
+   unsigned SampleRate,
+   int   MixMode,
+   void ( *CallBackFunc )( void )
+   )
+
+   {
+   int DmaStatus;
+
+   PAS_StopPlayback();
+
+   PAS_SetMixMode( MixMode );
+   PAS_SetPlaybackRate( SampleRate );
+
+   PAS_TransferLength = BufferSize / NumDivisions;
+   PAS_SetCallBack( CallBackFunc );
+
+   DmaStatus = PAS_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitWrite );
+   if ( DmaStatus == PAS_Error )
+      {
+      return( PAS_Error );
+      }
+
+   PAS_BeginTransfer( RECORD );
+
+   return( PAS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_CallInt
+
+   Calls interrupt 2fh.
+---------------------------------------------------------------------*/
+
+int PAS_CallInt( int ebx, int ecx, int edx );
+#pragma aux PAS_CallInt = \
+   "int 2fh",         \
+   parm [ ebx ] [ ecx ] [ edx ] modify exact [ eax ebx ecx edx esi edi ] value [ ebx ];
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_CallMVFunction
+
+   Performs a call to a real mode function.
+---------------------------------------------------------------------*/
+
+int PAS_CallMVFunction
+   (
+   unsigned long function,
+   int ebx,
+   int ecx,
+   int edx
+   )
+
+   {
+   dpmi_regs callregs;
+   int       status;
+
+   callregs.EBX = ebx;
+   callregs.ECX = ecx;
+   callregs.EDX = edx;
+
+   callregs.SS  = 0;
+   callregs.SP  = 0;
+
+   callregs.DS  = 0;
+   callregs.ES  = 0;
+   callregs.FS  = 0;
+   callregs.GS  = 0;
+
+   callregs.IP = function;
+   callregs.CS = function >> 16;
+
+   status = DPMI_CallRealModeFunction( &callregs );
+   if ( status != DPMI_Ok )
+      {
+      return( PAS_Error );
+      }
+
+   return( callregs.EBX & 0xff );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_SetPCMVolume
+
+   Sets the volume of digitized sound playback.
+---------------------------------------------------------------------*/
+
+int PAS_SetPCMVolume
+   (
+   int volume
+   )
+
+   {
+   int status;
+
+   volume = max( 0, volume );
+   volume = min( volume, 255 );
+
+   volume *= 100;
+   volume /= 255;
+
+   status = PAS_CallMVFunction( PAS_Func->SetMixer, volume,
+      OUTPUTMIXER, L_PCM );
+   if ( status == PAS_Error )
+      {
+      return( status );
+      }
+
+   status = PAS_CallMVFunction( PAS_Func->SetMixer, volume,
+      OUTPUTMIXER, R_PCM );
+   if ( status == PAS_Error )
+      {
+      return( status );
+      }
+
+   return( PAS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_GetPCMVolume
+
+   Returns the current volume of digitized sound playback.
+---------------------------------------------------------------------*/
+
+int PAS_GetPCMVolume
+   (
+   void
+   )
+
+   {
+   int leftvolume;
+   int rightvolume;
+   int totalvolume;
+
+   if ( PAS_Func == NULL )
+      {
+      return( PAS_Error );
+      }
+
+   leftvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
+      OUTPUTMIXER, L_PCM );
+   rightvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
+      OUTPUTMIXER, R_PCM );
+
+   if ( ( leftvolume == PAS_Error ) || ( rightvolume == PAS_Error ) )
+      {
+      return( PAS_Error );
+      }
+
+   leftvolume  &= 0xff;
+   rightvolume &= 0xff;
+
+   totalvolume = ( rightvolume + leftvolume ) / 2;
+   totalvolume *= 255;
+   totalvolume /= 100;
+   return( totalvolume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_SetFMVolume
+
+   Sets the volume of FM sound playback.
+---------------------------------------------------------------------*/
+
+void PAS_SetFMVolume
+   (
+   int volume
+   )
+
+   {
+   volume = max( 0, volume );
+   volume = min( volume, 255 );
+
+   volume *= 100;
+   volume /= 255;
+   if ( PAS_Func )
+      {
+      PAS_CallMVFunction( PAS_Func->SetMixer, volume, OUTPUTMIXER, L_FM );
+      PAS_CallMVFunction( PAS_Func->SetMixer, volume, OUTPUTMIXER, R_FM );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_GetFMVolume
+
+   Returns the current volume of FM sound playback.
+---------------------------------------------------------------------*/
+
+int PAS_GetFMVolume
+   (
+   void
+   )
+
+   {
+   int leftvolume;
+   int rightvolume;
+   int totalvolume;
+
+   if ( PAS_Func == NULL )
+      {
+      return( 255 );
+      }
+
+   leftvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
+      OUTPUTMIXER, L_FM ) & 0xff;
+   rightvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
+      OUTPUTMIXER, R_FM ) & 0xff;
+
+   totalvolume  = ( rightvolume + leftvolume ) / 2;
+   totalvolume *= 255;
+   totalvolume /= 100;
+   totalvolume  = min( 255, totalvolume );
+
+   return( totalvolume );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_GetCardInfo
+
+   Returns the maximum number of bits that can represent a sample
+   (8 or 16) and the number of channels (1 for mono, 2 for stereo).
+---------------------------------------------------------------------*/
+
+int PAS_GetCardInfo
+   (
+   int *MaxSampleBits,
+   int *MaxChannels
+   )
+
+   {
+   int status;
+
+   if ( PAS_State == NULL )
+      {
+      status = PAS_CheckForDriver();
+      if ( status != PAS_Ok )
+         {
+         return( status );
+         }
+
+      PAS_State = PAS_GetStateTable();
+      if ( PAS_State == NULL )
+         {
+         return( PAS_Error );
+         }
+      }
+
+   *MaxChannels = 2;
+
+   // Check board revision.  Revision # 0 can't play 16-bit data.
+   if ( ( PAS_State->intrctlr & 0xe0 ) == 0 )
+      {
+      *MaxSampleBits = 8;
+      }
+   else
+      {
+      *MaxSampleBits = 16;
+      }
+
+   return( PAS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_SetCallBack
+
+   Specifies the user function to call at the end of a sound transfer.
+---------------------------------------------------------------------*/
+
+void PAS_SetCallBack
+   (
+   void ( *func )( void )
+   )
+
+   {
+   PAS_CallBack = func;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_FindCard
+
+   Auto-detects the port the Pro AudioSpectrum is set for.
+---------------------------------------------------------------------*/
+
+int PAS_FindCard
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status = PAS_TestAddress( DEFAULT_BASE );
+   if ( status == 0 )
+      {
+      PAS_TranslateCode = DEFAULT_BASE;
+      return( PAS_Ok );
+      }
+
+   status = PAS_TestAddress( ALT_BASE_1 );
+   if ( status == 0 )
+      {
+      PAS_TranslateCode = ALT_BASE_1;
+      return( PAS_Ok );
+      }
+
+   status = PAS_TestAddress( ALT_BASE_2 );
+   if ( status == 0 )
+      {
+      PAS_TranslateCode = ALT_BASE_2;
+      return( PAS_Ok );
+      }
+
+   status = PAS_TestAddress( ALT_BASE_3 );
+   if ( status == 0 )
+      {
+      PAS_TranslateCode = ALT_BASE_3;
+      return( PAS_Ok );
+      }
+
+   PAS_SetErrorCode( PAS_CardNotFound );
+   return( PAS_Error );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_SaveMusicVolume
+
+   Saves the user's FM mixer settings.
+---------------------------------------------------------------------*/
+
+int PAS_SaveMusicVolume
+   (
+   void
+   )
+
+   {
+   int status;
+   int data;
+
+   if ( !PAS_Installed )
+      {
+      status = PAS_CheckForDriver();
+      if ( status != PAS_Ok )
+         {
+         return( status );
+         }
+
+      PAS_State = PAS_GetStateTable();
+      if ( PAS_State == NULL )
+         {
+         return( PAS_Error );
+         }
+
+      PAS_Func = PAS_GetFunctionTable();
+      if ( PAS_Func == NULL )
+         {
+         return( PAS_Error );
+         }
+
+      status = PAS_GetCardSettings();
+      if ( status != PAS_Ok )
+         {
+         return( status );
+         }
+
+      status = PAS_FindCard();
+      if ( status != PAS_Ok )
+         {
+         return( status );
+         }
+
+      // Enable PAS Sound
+      data  = PAS_State->audiofilt;
+      data |= PAS_AudioMuteFlag;
+
+      PAS_Write( AudioFilterControl, data );
+      PAS_State->audiofilt = data;
+      }
+
+   status = PAS_CallMVFunction( PAS_Func->GetMixer, 0, OUTPUTMIXER, L_FM );
+   if ( status != PAS_Error )
+      {
+      PAS_OriginalFMLeftVolume  = PAS_CallMVFunction( PAS_Func->GetMixer,
+         0, OUTPUTMIXER, L_FM ) & 0xff;
+
+      PAS_OriginalFMRightVolume = PAS_CallMVFunction( PAS_Func->GetMixer,
+         0, OUTPUTMIXER, R_FM ) & 0xff;
+
+      return( PAS_Ok );
+      }
+
+   return( PAS_Warning );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_RestoreMusicVolume
+
+   Restores the user's FM mixer settings.
+---------------------------------------------------------------------*/
+
+void PAS_RestoreMusicVolume
+   (
+   void
+   )
+
+   {
+   if ( PAS_Func )
+      {
+      PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalFMLeftVolume,
+         OUTPUTMIXER, L_FM );
+      PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalFMRightVolume,
+         OUTPUTMIXER, R_FM );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_SaveState
+
+   Saves the original state of the PAS prior to use.
+---------------------------------------------------------------------*/
+
+void PAS_SaveState
+   (
+   void
+   )
+
+   {
+   PAS_OriginalState.intrctlr     = PAS_State->intrctlr;
+   PAS_OriginalState.audiofilt    = PAS_State->audiofilt;
+   PAS_OriginalState.tmrctlr      = PAS_State->tmrctlr;
+   PAS_OriginalState.samplerate   = PAS_State->samplerate;
+   PAS_OriginalState.samplecnt    = PAS_State->samplecnt;
+   PAS_OriginalState.crosschannel = PAS_State->crosschannel;
+   PAS_SampleSizeConfig = PAS_Read( SampleSizeConfiguration );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_RestoreState
+
+   Restores the original state of the PAS after use.
+---------------------------------------------------------------------*/
+
+void PAS_RestoreState
+   (
+   void
+   )
+
+   {
+   int LoByte;
+   int HiByte;
+
+   // Select the Sample Rate Timer
+   PAS_Write( LocalTimerControl, SelectSampleRateTimer );
+   PAS_State->tmrctlr = SelectSampleRateTimer;
+
+   PAS_Write( SampleRateTimer, PAS_OriginalState.samplerate );
+   PAS_State->samplerate = PAS_OriginalState.samplerate;
+
+   // Select the Sample Buffer Count
+   PAS_Write( LocalTimerControl, SelectSampleBufferCount );
+   PAS_State->tmrctlr = SelectSampleBufferCount;
+
+   LoByte = lobyte( PAS_OriginalState.samplecnt );
+   HiByte = hibyte( PAS_OriginalState.samplecnt );
+   PAS_Write( SampleRateTimer, LoByte );
+   PAS_Write( SampleRateTimer, HiByte );
+   PAS_State->samplecnt = PAS_OriginalState.samplecnt;
+
+   PAS_Write( CrossChannelControl, PAS_OriginalState.crosschannel );
+   PAS_State->crosschannel = PAS_OriginalState.crosschannel;
+
+   PAS_Write( SampleSizeConfiguration, PAS_SampleSizeConfig );
+
+   PAS_Write( InterruptControl, PAS_OriginalState.intrctlr );
+   PAS_State->intrctlr = PAS_OriginalState.intrctlr;
+
+   PAS_Write( AudioFilterControl, PAS_OriginalState.audiofilt );
+   PAS_State->audiofilt = PAS_OriginalState.audiofilt;
+
+   PAS_Write( LocalTimerControl, PAS_OriginalState.tmrctlr );
+   PAS_State->tmrctlr = PAS_OriginalState.tmrctlr;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void PAS_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: allocateTimerStack
+
+   Allocate a block of memory from conventional (low) memory and return
+   the selector (which can go directly into a segment register) of the
+   memory block or 0 if an error occured.
+---------------------------------------------------------------------*/
+
+static unsigned short allocateTimerStack
+   (
+   unsigned short size
+   )
+
+   {
+   union REGS regs;
+
+   // clear all registers
+   memset( &regs, 0, sizeof( regs ) );
+
+   // DPMI allocate conventional memory
+   regs.w.ax = 0x100;
+
+   // size in paragraphs
+   regs.w.bx = ( size + 15 ) / 16;
+
+   int386( 0x31, &regs, &regs );
+   if (!regs.w.cflag)
+      {
+      // DPMI call returns selector in dx
+      // (ax contains real mode segment
+      // which is ignored here)
+
+      return( regs.w.dx );
+      }
+
+   // Couldn't allocate memory.
+   return( NULL );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: deallocateTimerStack
+
+   Deallocate a block of conventional (low) memory given a selector to
+   it.  Assumes the block was allocated with DPMI function 0x100.
+---------------------------------------------------------------------*/
+
+static void deallocateTimerStack
+   (
+   unsigned short selector
+   )
+
+   {
+   union REGS regs;
+
+   if ( selector != NULL )
+      {
+      // clear all registers
+      memset( &regs, 0, sizeof( regs ) );
+
+      regs.w.ax = 0x101;
+      regs.w.dx = selector;
+      int386( 0x31, &regs, &regs );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_Init
+
+   Initializes the sound card and prepares the module to play
+   digitized sounds.
+---------------------------------------------------------------------*/
+
+int PAS_Init
+   (
+   void
+   )
+
+   {
+   int Interrupt;
+   int status;
+   int data;
+
+   if ( PAS_Installed )
+      {
+      return( PAS_Ok );
+      }
+
+   PAS_IntController1Mask = inp( 0x21 );
+   PAS_IntController2Mask = inp( 0xA1 );
+
+   status = PAS_CheckForDriver();
+   if ( status != PAS_Ok )
+      {
+      return( status );
+      }
+
+   PAS_State = PAS_GetStateTable();
+   if ( PAS_State == NULL )
+      {
+      return( PAS_Error );
+      }
+
+   PAS_Func = PAS_GetFunctionTable();
+   if ( PAS_Func == NULL )
+      {
+      return( PAS_Error );
+      }
+
+   status = PAS_GetCardSettings();
+   if ( status != PAS_Ok )
+      {
+      return( status );
+      }
+
+   status = PAS_FindCard();
+   if ( status != PAS_Ok )
+      {
+      return( status );
+      }
+
+   PAS_SaveState();
+
+   PAS_OriginalPCMLeftVolume  = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
+      OUTPUTMIXER, L_PCM ) & 0xff;
+   PAS_OriginalPCMRightVolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
+      OUTPUTMIXER, R_PCM ) & 0xff;
+
+   PAS_SoundPlaying = FALSE;
+
+   PAS_SetCallBack( NULL );
+
+   PAS_DMABuffer = NULL;
+
+   status = PAS_LockMemory();
+   if ( status != PAS_Ok )
+      {
+      PAS_UnlockMemory();
+      return( status );
+      }
+
+   StackSelector = allocateTimerStack( kStackSize );
+   if ( StackSelector == NULL )
+      {
+      PAS_UnlockMemory();
+      PAS_SetErrorCode( PAS_OutOfMemory );
+      return( PAS_Error );
+      }
+
+   // Leave a little room at top of stack just for the hell of it...
+   StackPointer = kStackSize - sizeof( long );
+
+   // Install our interrupt handler
+   Interrupt = PAS_Interrupts[ PAS_Irq ];
+   PAS_OldInt = _dos_getvect( Interrupt );
+   if ( PAS_Irq < 8 )
+      {
+      _dos_setvect( Interrupt, PAS_ServiceInterrupt );
+      }
+   else
+      {
+      status = IRQ_SetVector( Interrupt, PAS_ServiceInterrupt );
+      if ( status != IRQ_Ok )
+         {
+         PAS_UnlockMemory();
+         deallocateTimerStack( StackSelector );
+         StackSelector = NULL;
+         PAS_SetErrorCode( PAS_UnableToSetIrq );
+         return( PAS_Error );
+         }
+      }
+
+   // Enable PAS Sound
+   data  = PAS_State->audiofilt;
+   data |= PAS_AudioMuteFlag;
+
+   PAS_Write( AudioFilterControl, data );
+   PAS_State->audiofilt = data;
+
+   PAS_SetPlaybackRate( PAS_DefaultSampleRate );
+   PAS_SetMixMode( PAS_DefaultMixMode );
+
+   PAS_Installed = TRUE;
+
+   PAS_SetErrorCode( PAS_Ok );
+   return( PAS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_Shutdown
+
+   Ends transfer of sound data to the sound card and restores the
+   system resources used by the card.
+---------------------------------------------------------------------*/
+
+void PAS_Shutdown
+   (
+   void
+   )
+
+   {
+   int Interrupt;
+
+   if ( PAS_Installed )
+      {
+      // Halt the DMA transfer
+      PAS_StopPlayback();
+
+      // Restore the original interrupt
+      Interrupt = PAS_Interrupts[ PAS_Irq ];
+      if ( PAS_Irq >= 8 )
+         {
+         IRQ_RestoreVector( Interrupt );
+         }
+      _dos_setvect( Interrupt, PAS_OldInt );
+
+      PAS_SoundPlaying = FALSE;
+
+      PAS_DMABuffer = NULL;
+
+      PAS_SetCallBack( NULL );
+
+      PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalPCMLeftVolume,
+         OUTPUTMIXER, L_PCM );
+      PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalPCMRightVolume,
+         OUTPUTMIXER, R_PCM );
+
+// DEBUG
+//      PAS_RestoreState();
+
+      PAS_UnlockMemory();
+
+      deallocateTimerStack( StackSelector );
+      StackSelector = NULL;
+
+      PAS_Installed = FALSE;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_UnlockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+void PAS_UnlockMemory
+   (
+   void
+   )
+
+   {
+   DPMI_UnlockMemoryRegion( PAS_LockStart, PAS_LockEnd );
+   DPMI_Unlock( PAS_Interrupts );
+   DPMI_Unlock( PAS_OldInt );
+   DPMI_Unlock( PAS_IntController1Mask );
+   DPMI_Unlock( PAS_IntController2Mask  );
+   DPMI_Unlock( PAS_Installed );
+   DPMI_Unlock( PAS_TranslateCode );
+   DPMI_Unlock( PAS_OriginalPCMLeftVolume );
+   DPMI_Unlock( PAS_OriginalPCMRightVolume );
+   DPMI_Unlock( PAS_OriginalFMLeftVolume );
+   DPMI_Unlock( PAS_OriginalFMRightVolume );
+   DPMI_Unlock( PAS_DMAChannel );
+   DPMI_Unlock( PAS_Irq );
+   DPMI_Unlock( PAS_State );
+   DPMI_Unlock( PAS_Func );
+   DPMI_Unlock( PAS_OriginalState );
+   DPMI_Unlock( PAS_SampleSizeConfig );
+   DPMI_Unlock( PAS_DMABuffer );
+   DPMI_Unlock( PAS_DMABufferEnd );
+   DPMI_Unlock( PAS_CurrentDMABuffer );
+   DPMI_Unlock( PAS_TotalDMABufferSize );
+   DPMI_Unlock( PAS_TransferLength );
+   DPMI_Unlock( PAS_MixMode );
+   DPMI_Unlock( PAS_SampleRate );
+   DPMI_Unlock( PAS_TimeInterval );
+   DPMI_Unlock( PAS_SoundPlaying );
+   DPMI_Unlock( PAS_CallBack );
+   DPMI_Unlock( PAS_ErrorCode );
+   DPMI_Unlock( irqstatus );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PAS_LockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+int PAS_LockMemory
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status  = DPMI_LockMemoryRegion( PAS_LockStart, PAS_LockEnd );
+   status |= DPMI_Lock( PAS_Interrupts );
+   status |= DPMI_Lock( PAS_OldInt );
+   status |= DPMI_Lock( PAS_IntController1Mask );
+   status |= DPMI_Lock( PAS_IntController2Mask  );
+   status |= DPMI_Lock( PAS_Installed );
+   status |= DPMI_Lock( PAS_TranslateCode );
+   status |= DPMI_Lock( PAS_OriginalPCMLeftVolume );
+   status |= DPMI_Lock( PAS_OriginalPCMRightVolume );
+   status |= DPMI_Lock( PAS_OriginalFMLeftVolume );
+   status |= DPMI_Lock( PAS_OriginalFMRightVolume );
+   status |= DPMI_Lock( PAS_DMAChannel );
+   status |= DPMI_Lock( PAS_Irq );
+   status |= DPMI_Lock( PAS_State );
+   status |= DPMI_Lock( PAS_Func );
+   status |= DPMI_Lock( PAS_OriginalState );
+   status |= DPMI_Lock( PAS_SampleSizeConfig );
+   status |= DPMI_Lock( PAS_DMABuffer );
+   status |= DPMI_Lock( PAS_DMABufferEnd );
+   status |= DPMI_Lock( PAS_CurrentDMABuffer );
+   status |= DPMI_Lock( PAS_TotalDMABufferSize );
+   status |= DPMI_Lock( PAS_TransferLength );
+   status |= DPMI_Lock( PAS_MixMode );
+   status |= DPMI_Lock( PAS_SampleRate );
+   status |= DPMI_Lock( PAS_TimeInterval );
+   status |= DPMI_Lock( PAS_SoundPlaying );
+   status |= DPMI_Lock( PAS_CallBack );
+   status |= DPMI_Lock( PAS_ErrorCode );
+   status |= DPMI_Lock( irqstatus );
+
+   if ( status != DPMI_Ok )
+      {
+      PAS_UnlockMemory();
+      PAS_SetErrorCode( PAS_DPMI_Error );
+      return( PAS_Error );
+      }
+
+   return( PAS_Ok );
+   }

Added: tags/rott-1.1/rott/audiolib/pas16.h
===================================================================
--- tags/rott-1.1/rott/audiolib/pas16.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/pas16.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,81 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: PAS16.H
+
+   author: James R. Dose
+   date:   March 27, 1994
+
+   Public header for for PAS16.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __PAS16_H
+#define __PAS16_H
+
+enum PAS_ERRORS
+   {
+   PAS_Warning = -2,
+   PAS_Error   = -1,
+   PAS_Ok      = 0,
+   PAS_DriverNotFound,
+   PAS_DmaError,
+   PAS_InvalidIrq,
+   PAS_UnableToSetIrq,
+   PAS_Dos4gwIrqError,
+   PAS_NoSoundPlaying,
+   PAS_CardNotFound,
+   PAS_DPMI_Error,
+   PAS_OutOfMemory
+   };
+
+#define PAS_MaxMixMode        STEREO_16BIT
+#define PAS_DefaultSampleRate 11000
+#define PAS_DefaultMixMode    MONO_8BIT
+#define PAS_MaxIrq            15
+
+#define PAS_MinSamplingRate   4000
+#define PAS_MaxSamplingRate   44000
+
+extern unsigned int PAS_DMAChannel;
+
+char *PAS_ErrorString( int ErrorNumber );
+void  PAS_SetPlaybackRate( unsigned rate );
+unsigned PAS_GetPlaybackRate( void );
+int   PAS_SetMixMode( int mode );
+void  PAS_StopPlayback( void );
+int   PAS_GetCurrentPos( void );
+int   PAS_BeginBufferedPlayback( char *BufferStart, int BufferSize, int NumDivisions, unsigned SampleRate, int MixMode, void ( *CallBackFunc )( void ) );
+int   PAS_BeginBufferedRecord( char *BufferStart, int BufferSize, int NumDivisions, unsigned SampleRate, int MixMode, void ( *CallBackFunc )( void ) );
+int   PAS_SetPCMVolume( int volume );
+int   PAS_GetPCMVolume( void );
+void  PAS_SetFMVolume( int volume );
+int   PAS_GetFMVolume( void );
+int   PAS_GetCardInfo( int *MaxSampleBits, int *MaxChannels );
+void  PAS_SetCallBack( void ( *func )( void ) );
+int   PAS_SaveMusicVolume( void );
+void  PAS_RestoreMusicVolume( void );
+int   PAS_Init( void );
+void  PAS_Shutdown( void );
+void  PAS_UnlockMemory( void );
+int   PAS_LockMemory( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/pitch.c
===================================================================
--- tags/rott-1.1/rott/audiolib/pitch.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/pitch.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,258 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: PITCH.C
+
+   author: James R. Dose
+   date:   June 14, 1993
+
+   Routines for pitch scaling.
+
+   (c) Copyright 1993 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <stdlib.h>
+//#include <math.h>
+#include "dpmi.h"
+#include "standard.h"
+#include "pitch.h"
+
+#define MAXDETUNE 25
+
+static unsigned long PitchTable[ 12 ][ MAXDETUNE ] =
+   {
+      { 0x10000, 0x10097, 0x1012f, 0x101c7, 0x10260, 0x102f9, 0x10392, 0x1042c,
+      0x104c6, 0x10561, 0x105fb, 0x10696, 0x10732, 0x107ce, 0x1086a, 0x10907,
+      0x109a4, 0x10a41, 0x10adf, 0x10b7d, 0x10c1b, 0x10cba, 0x10d59, 0x10df8,
+      0x10e98 },
+      { 0x10f38, 0x10fd9, 0x1107a, 0x1111b, 0x111bd, 0x1125f, 0x11302, 0x113a5,
+      0x11448, 0x114eb, 0x1158f, 0x11634, 0x116d8, 0x1177e, 0x11823, 0x118c9,
+      0x1196f, 0x11a16, 0x11abd, 0x11b64, 0x11c0c, 0x11cb4, 0x11d5d, 0x11e06,
+      0x11eaf },
+      { 0x11f59, 0x12003, 0x120ae, 0x12159, 0x12204, 0x122b0, 0x1235c, 0x12409,
+      0x124b6, 0x12563, 0x12611, 0x126bf, 0x1276d, 0x1281c, 0x128cc, 0x1297b,
+      0x12a2b, 0x12adc, 0x12b8d, 0x12c3e, 0x12cf0, 0x12da2, 0x12e55, 0x12f08,
+      0x12fbc },
+      { 0x1306f, 0x13124, 0x131d8, 0x1328d, 0x13343, 0x133f9, 0x134af, 0x13566,
+      0x1361d, 0x136d5, 0x1378d, 0x13846, 0x138fe, 0x139b8, 0x13a72, 0x13b2c,
+      0x13be6, 0x13ca1, 0x13d5d, 0x13e19, 0x13ed5, 0x13f92, 0x1404f, 0x1410d,
+      0x141cb },
+      { 0x1428a, 0x14349, 0x14408, 0x144c8, 0x14588, 0x14649, 0x1470a, 0x147cc,
+      0x1488e, 0x14951, 0x14a14, 0x14ad7, 0x14b9b, 0x14c5f, 0x14d24, 0x14dea,
+      0x14eaf, 0x14f75, 0x1503c, 0x15103, 0x151cb, 0x15293, 0x1535b, 0x15424,
+      0x154ee },
+      { 0x155b8, 0x15682, 0x1574d, 0x15818, 0x158e4, 0x159b0, 0x15a7d, 0x15b4a,
+      0x15c18, 0x15ce6, 0x15db4, 0x15e83, 0x15f53, 0x16023, 0x160f4, 0x161c5,
+      0x16296, 0x16368, 0x1643a, 0x1650d, 0x165e1, 0x166b5, 0x16789, 0x1685e,
+      0x16934 },
+      { 0x16a09, 0x16ae0, 0x16bb7, 0x16c8e, 0x16d66, 0x16e3e, 0x16f17, 0x16ff1,
+      0x170ca, 0x171a5, 0x17280, 0x1735b, 0x17437, 0x17513, 0x175f0, 0x176ce,
+      0x177ac, 0x1788a, 0x17969, 0x17a49, 0x17b29, 0x17c09, 0x17cea, 0x17dcc,
+      0x17eae },
+      { 0x17f91, 0x18074, 0x18157, 0x1823c, 0x18320, 0x18406, 0x184eb, 0x185d2,
+      0x186b8, 0x187a0, 0x18888, 0x18970, 0x18a59, 0x18b43, 0x18c2d, 0x18d17,
+      0x18e02, 0x18eee, 0x18fda, 0x190c7, 0x191b5, 0x192a2, 0x19391, 0x19480,
+      0x1956f },
+      { 0x1965f, 0x19750, 0x19841, 0x19933, 0x19a25, 0x19b18, 0x19c0c, 0x19d00,
+      0x19df4, 0x19ee9, 0x19fdf, 0x1a0d5, 0x1a1cc, 0x1a2c4, 0x1a3bc, 0x1a4b4,
+      0x1a5ad, 0x1a6a7, 0x1a7a1, 0x1a89c, 0x1a998, 0x1aa94, 0x1ab90, 0x1ac8d,
+      0x1ad8b },
+      { 0x1ae89, 0x1af88, 0x1b088, 0x1b188, 0x1b289, 0x1b38a, 0x1b48c, 0x1b58f,
+      0x1b692, 0x1b795, 0x1b89a, 0x1b99f, 0x1baa4, 0x1bbaa, 0x1bcb1, 0x1bdb8,
+      0x1bec0, 0x1bfc9, 0x1c0d2, 0x1c1dc, 0x1c2e6, 0x1c3f1, 0x1c4fd, 0x1c609,
+      0x1c716 },
+      { 0x1c823, 0x1c931, 0x1ca40, 0x1cb50, 0x1cc60, 0x1cd70, 0x1ce81, 0x1cf93,
+      0x1d0a6, 0x1d1b9, 0x1d2cd, 0x1d3e1, 0x1d4f6, 0x1d60c, 0x1d722, 0x1d839,
+      0x1d951, 0x1da69, 0x1db82, 0x1dc9c, 0x1ddb6, 0x1ded1, 0x1dfec, 0x1e109,
+      0x1e225 },
+      { 0x1e343, 0x1e461, 0x1e580, 0x1e6a0, 0x1e7c0, 0x1e8e0, 0x1ea02, 0x1eb24,
+      0x1ec47, 0x1ed6b, 0x1ee8f, 0x1efb4, 0x1f0d9, 0x1f1ff, 0x1f326, 0x1f44e,
+      0x1f576, 0x1f69f, 0x1f7c9, 0x1f8f3, 0x1fa1e, 0x1fb4a, 0x1fc76, 0x1fda3,
+      0x1fed1 }
+   };
+
+
+//static int PITCH_Installed = FALSE;
+
+
+/*---------------------------------------------------------------------
+   Function: PITCH_Init
+
+   Initializes pitch table.
+---------------------------------------------------------------------*/
+/*
+void PITCH_Init
+   (
+   void
+   )
+
+   {
+   int note;
+   int detune;
+
+   if ( !PITCH_Installed )
+      {
+      for( note = 0; note < 12; note++ )
+         {
+         for( detune = 0; detune < MAXDETUNE; detune++ )
+            {
+            PitchTable[ note ][ detune ] = 0x10000 *
+               pow( 2, ( note * MAXDETUNE + detune ) / ( 12.0 * MAXDETUNE ) );
+            }
+         }
+
+      PITCH_Installed = TRUE;
+      }
+   }
+*/
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define PITCH_LockStart PITCH_GetScale
+
+
+/*---------------------------------------------------------------------
+   Function: PITCH_GetScale
+
+   Returns a fixed-point value to scale number the specified amount.
+---------------------------------------------------------------------*/
+
+unsigned long PITCH_GetScale
+   (
+   int pitchoffset
+   )
+
+   {
+   unsigned long scale;
+   int octaveshift;
+   int noteshift;
+   int note;
+   int detune;
+
+//   if ( !PITCH_Installed )
+//      {
+//      PITCH_Init();
+//      }
+
+   if ( pitchoffset == 0 )
+      {
+      return( PitchTable[ 0 ][ 0 ] );
+      }
+
+   noteshift = pitchoffset % 1200;
+   if ( noteshift < 0 )
+      {
+      noteshift += 1200;
+      }
+
+   note   = noteshift / 100;
+   detune = ( noteshift % 100 ) / ( 100 / MAXDETUNE );
+   octaveshift = ( pitchoffset - noteshift ) / 1200;
+
+   if ( detune < 0 )
+      {
+      detune += ( 100 / MAXDETUNE );
+      note--;
+      if ( note < 0 )
+         {
+         note += 12;
+         octaveshift--;
+         }
+      }
+
+   scale = PitchTable[ note ][ detune ];
+
+   if ( octaveshift < 0 )
+      {
+      scale >>= -octaveshift;
+      }
+   else
+      {
+      scale <<= octaveshift;
+      }
+
+   return( scale );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PITCH_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void PITCH_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PITCH_UnlockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+void PITCH_UnlockMemory
+   (
+   void
+   )
+
+   {
+   DPMI_UnlockMemoryRegion( PITCH_LockStart, PITCH_LockEnd );
+   DPMI_Unlock( PitchTable );
+//   DPMI_Unlock( PITCH_Installed );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: PITCH_LockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+int PITCH_LockMemory
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status  = DPMI_LockMemoryRegion( PITCH_LockStart, PITCH_LockEnd );
+   status |= DPMI_Lock( PitchTable );
+//   status |= DPMI_Lock( PITCH_Installed );
+
+   if ( status != DPMI_Ok )
+      {
+      PITCH_UnlockMemory();
+      return( PITCH_Error );
+      }
+
+   return( PITCH_Ok );
+   }

Added: tags/rott-1.1/rott/audiolib/pitch.h
===================================================================
--- tags/rott-1.1/rott/audiolib/pitch.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/pitch.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,45 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: PITCH.H
+
+   author: James R. Dose
+   date:   June 14, 1994
+
+   Public header for PITCH.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __PITCH_H
+#define __PITCH_H
+
+enum PITCH_ERRORS
+   {
+   PITCH_Warning = -2,
+   PITCH_Error = -1,
+   PITCH_Ok = 0,
+   };
+
+//void          PITCH_Init( void );
+unsigned long PITCH_GetScale( int pitchoffset );
+void          PITCH_UnlockMemory( void );
+int           PITCH_LockMemory( void );
+#endif

Added: tags/rott-1.1/rott/audiolib/platform.h
===================================================================
--- tags/rott-1.1/rott/audiolib/platform.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/platform.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,77 @@
+#ifndef _INCLUDE_PLATFORM_H_
+#define _INCLUDE_PLATFORM_H_
+
+/* this file originally from buildengine */
+#ifdef BUILDENGINE
+
+#if (defined PLATFORM_WIN32)
+#include "win32_compat.h"
+#elif (defined PLATFORM_UNIX)
+#include "unix_compat.h"
+#elif (defined PLATFORM_DOS)
+#include "doscmpat.h"
+#else
+#error Define your platform!
+#endif
+
+#if (!defined __EXPORT__)
+#define __EXPORT__
+#endif
+
+#if ((defined PLATFORM_SUPPORTS_SDL) && (!defined PLATFORM_TIMER_HZ))
+#define PLATFORM_TIMER_HZ 100
+#endif
+
+#if (!defined PLATFORM_TIMER_HZ)
+#error You need to define PLATFORM_TIMER_HZ for your platform.
+#endif
+
+#if (defined __WATCOMC__)
+#define snprintf _snprintf
+#endif
+
+#endif
+
+static __inline unsigned short _swap16(unsigned short D)
+{
+#if PLATFORM_MACOSX
+    register unsigned short returnValue;
+    __asm__ volatile("lhbrx %0,0,%1"
+        : "=r" (returnValue)
+        : "r" (&D)
+    );
+    return returnValue;
+#else
+    return((D<<8)|(D>>8));
+#endif
+}
+
+static __inline unsigned int _swap32(unsigned int D)
+{
+#if PLATFORM_MACOSX
+    register unsigned int returnValue;
+    __asm__ volatile("lwbrx %0,0,%1"
+        : "=r" (returnValue)
+        : "r" (&D)
+    );
+    return returnValue;
+#else
+    return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24));
+#endif
+}
+
+#if PLATFORM_MACOSX
+#define PLATFORM_BIGENDIAN 1
+#define BUILDSWAP_INTEL16(x) _swap16(x)
+#define BUILDSWAP_INTEL32(x) _swap32(x)
+#else
+#define PLATFORM_LITTLEENDIAN 1
+#define BUILDSWAP_INTEL16(x) (x)
+#define BUILDSWAP_INTEL32(x) (x)
+#endif
+
+#endif  /* !defined _INCLUDE_PLATFORM_H_ */
+
+/* end of platform.h ... */
+
+

Added: tags/rott-1.1/rott/audiolib/sndcards.h
===================================================================
--- tags/rott-1.1/rott/audiolib/sndcards.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/sndcards.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,55 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: SNDCARDS.H
+
+   author: James R. Dose
+   date:   March 31, 1994
+
+   Contains enumerated type definitions for sound cards.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __SNDCARDS_H
+#define __SNDCARDS_H
+
+#define ASS_VERSION_STRING "1.12"
+
+typedef enum
+   {
+//   ASS_NoSound,
+   SoundBlaster,
+   ProAudioSpectrum,
+   SoundMan16,
+   Adlib,
+   GenMidi,
+   SoundCanvas,
+   Awe32,
+   WaveBlaster,
+   SoundScape,
+   UltraSound,
+   SoundSource,
+   TandySoundSource,
+   PC,
+   NumSoundCards
+   } soundcardnames;
+
+#endif

Added: tags/rott-1.1/rott/audiolib/sndscape.c
===================================================================
--- tags/rott-1.1/rott/audiolib/sndscape.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/sndscape.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1661 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: SNDSCAPE.C
+
+   author: James R. Dose
+   date:   October 25, 1994
+
+   Low level routines to support the Ensoniq Soundscape.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#include <dos.h>
+#include <conio.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include "interrup.h"
+#include "dpmi.h"
+#include "dma.h"
+#include "irq.h"
+#include "sndscape.h"
+#include "_sndscap.h"
+
+const int SOUNDSCAPE_Interrupts[ SOUNDSCAPE_MaxIrq + 1 ]  =
+   {
+   INVALID, INVALID,     0xa, INVALID,
+   INVALID,     0xd, INVALID,     0xf,
+   INVALID, INVALID,    0x72, INVALID,
+   INVALID, INVALID, INVALID, INVALID
+   };
+
+const int SOUNDSCAPE_SampleSize[ SOUNDSCAPE_MaxMixMode + 1 ] =
+   {
+   MONO_8BIT_SAMPLE_SIZE,  STEREO_8BIT_SAMPLE_SIZE,
+   MONO_16BIT_SAMPLE_SIZE, STEREO_16BIT_SAMPLE_SIZE
+   };
+
+static void ( __interrupt __far *SOUNDSCAPE_OldInt )( void );
+
+static int SOUNDSCAPE_Installed = FALSE;
+static int SOUNDSCAPE_FoundCard = FALSE;
+
+static char   *SOUNDSCAPE_DMABuffer;
+static char   *SOUNDSCAPE_DMABufferEnd;
+static char   *SOUNDSCAPE_CurrentDMABuffer;
+static int     SOUNDSCAPE_TotalDMABufferSize;
+
+static int      SOUNDSCAPE_TransferLength   = 0;
+static int      SOUNDSCAPE_MixMode          = SOUNDSCAPE_DefaultMixMode;
+static int      SOUNDSCAPE_SamplePacketSize = MONO_16BIT_SAMPLE_SIZE;
+static unsigned SOUNDSCAPE_SampleRate       = SOUNDSCAPE_DefaultSampleRate;
+
+volatile int   SOUNDSCAPE_SoundPlaying;
+
+void ( *SOUNDSCAPE_CallBack )( void );
+
+static int  SOUNDSCAPE_IntController1Mask;
+static int  SOUNDSCAPE_IntController2Mask;
+
+// some globals for chip type, ports, DMA, IRQs ... and stuff
+static struct
+   {
+   int BasePort;  // base address of the Ensoniq gate-array chip
+   int WavePort;  // the AD-1848 base address
+   int DMAChan;   // the DMA channel used for PCM
+   int WaveIRQ;   // the PCM IRQ
+   int MIDIIRQ;   // the MPU-401 IRQ
+   int ChipID;    // the Ensoniq chip type
+   int SBEmul;    // SoundBlaster emulation flag
+   int CDROM;     // CD-ROM flag
+   int IRQIndx;   // the Wave IRQ index - for hardware regs
+   int OldIRQs;   // Old IRQs flag to support older HW
+   } SOUNDSCAPE_Config;
+
+// adequate stack size
+#define kStackSize 2048
+
+static unsigned short StackSelector = NULL;
+static unsigned long  StackPointer;
+
+static unsigned short oldStackSelector;
+static unsigned long  oldStackPointer;
+
+// These declarations are necessary to use the inline assembly pragmas.
+
+extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
+extern void SetStack(unsigned short selector,unsigned long stackptr);
+
+// This function will get the current stack selector and pointer and save
+// them off.
+#pragma aux GetStack =	\
+	"mov  [edi],esp"		\
+	"mov	ax,ss"	 		\
+	"mov  [esi],ax" 		\
+	parm [esi] [edi]		\
+	modify [eax esi edi];
+
+// This function will set the stack selector and pointer to the specified
+// values.
+#pragma aux SetStack =	\
+	"mov  ss,ax"			\
+	"mov  esp,edx"			\
+	parm [ax] [edx]		\
+	modify [eax edx];
+
+int SOUNDSCAPE_DMAChannel = -1;
+
+int SOUNDSCAPE_ErrorCode = SOUNDSCAPE_Ok;
+
+#define SOUNDSCAPE_SetErrorCode( status ) \
+   SOUNDSCAPE_ErrorCode   = ( status );
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *SOUNDSCAPE_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case SOUNDSCAPE_Warning :
+      case SOUNDSCAPE_Error :
+         ErrorString = SOUNDSCAPE_ErrorString( SOUNDSCAPE_ErrorCode );
+         break;
+
+      case SOUNDSCAPE_Ok :
+         ErrorString = "SoundScape ok.";
+         break;
+
+      case SOUNDSCAPE_EnvNotFound :
+         ErrorString = "SNDSCAPE environment variable not set.  This is used to locate \n"
+                       "SNDSCAPE.INI which is used to describe your sound card setup.";
+         break;
+
+      case SOUNDSCAPE_InitFileNotFound :
+         ErrorString = "Missing SNDSCAPE.INI file for SoundScape.  This file should be \n"
+                       "located in the directory indicated by the SNDSCAPE environment \n"
+                       "variable or in 'C:\SNDSCAPE' if SNDSCAPE is not set.";
+         break;
+
+      case SOUNDSCAPE_MissingProductInfo :
+         ErrorString = "Missing 'Product' field in SNDSCAPE.INI file for SoundScape.";
+         break;
+
+      case SOUNDSCAPE_MissingPortInfo :
+         ErrorString = "Missing 'Port' field in SNDSCAPE.INI file for SoundScape.";
+         break;
+
+      case SOUNDSCAPE_MissingDMAInfo :
+         ErrorString = "Missing 'DMA' field in SNDSCAPE.INI file for SoundScape.";
+         break;
+
+      case SOUNDSCAPE_MissingIRQInfo :
+         ErrorString = "Missing 'IRQ' field in SNDSCAPE.INI file for SoundScape.";
+         break;
+
+      case SOUNDSCAPE_MissingSBIRQInfo :
+         ErrorString = "Missing 'SBIRQ' field in SNDSCAPE.INI file for SoundScape.";
+         break;
+
+      case SOUNDSCAPE_MissingSBENABLEInfo :
+         ErrorString = "Missing 'SBEnable' field in SNDSCAPE.INI file for SoundScape.";
+         break;
+
+      case SOUNDSCAPE_MissingWavePortInfo :
+         ErrorString = "Missing 'WavePort' field in SNDSCAPE.INI file for SoundScape.";
+         break;
+
+      case SOUNDSCAPE_HardwareError :
+         ErrorString = "Could not detect SoundScape.  Make sure your SNDSCAPE.INI file \n"
+                       "contains correct information about your hardware setup.";
+         break;
+
+      case SOUNDSCAPE_NoSoundPlaying :
+         ErrorString = "No sound playing on SoundScape.";
+         break;
+
+      case SOUNDSCAPE_InvalidSBIrq :
+         ErrorString = "Invalid SoundScape Irq in SBIRQ field of SNDSCAPE.INI.";
+         break;
+
+      case SOUNDSCAPE_UnableToSetIrq :
+         ErrorString = "Unable to set SoundScape IRQ.  Try selecting an IRQ of 7 or below.";
+         break;
+
+      case SOUNDSCAPE_DmaError :
+         ErrorString = DMA_ErrorString( DMA_Error );
+         break;
+
+      case SOUNDSCAPE_DPMI_Error :
+         ErrorString = "DPMI Error in SoundScape.";
+         break;
+
+      case SOUNDSCAPE_OutOfMemory :
+         ErrorString = "Out of conventional memory in SoundScape.";
+         break;
+
+      default :
+         ErrorString = "Unknown SoundScape error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define SOUNDSCAPE_LockStart SOUNDSCAPE_EnableInterrupt
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_EnableInterrupt
+
+   Enables the triggering of the sound card interrupt.
+---------------------------------------------------------------------*/
+
+static void SOUNDSCAPE_EnableInterrupt
+   (
+   void
+   )
+
+   {
+   int mask;
+
+   // Unmask system interrupt
+   if ( SOUNDSCAPE_Config.WaveIRQ < 8 )
+      {
+      mask = inp( 0x21 ) & ~( 1 << SOUNDSCAPE_Config.WaveIRQ );
+      outp( 0x21, mask  );
+      }
+   else
+      {
+      mask = inp( 0xA1 ) & ~( 1 << ( SOUNDSCAPE_Config.WaveIRQ - 8 ) );
+      outp( 0xA1, mask  );
+
+      mask = inp( 0x21 ) & ~( 1 << 2 );
+      outp( 0x21, mask  );
+      }
+
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_DisableInterrupt
+
+   Disables the triggering of the sound card interrupt.
+---------------------------------------------------------------------*/
+
+static void SOUNDSCAPE_DisableInterrupt
+   (
+   void
+   )
+
+   {
+   int mask;
+
+   // Restore interrupt mask
+   if ( SOUNDSCAPE_Config.WaveIRQ < 8 )
+      {
+      mask  = inp( 0x21 ) & ~( 1 << SOUNDSCAPE_Config.WaveIRQ );
+      mask |= SOUNDSCAPE_IntController1Mask & ( 1 << SOUNDSCAPE_Config.WaveIRQ );
+      outp( 0x21, mask  );
+      }
+   else
+      {
+      mask  = inp( 0x21 ) & ~( 1 << 2 );
+      mask |= SOUNDSCAPE_IntController1Mask & ( 1 << 2 );
+      outp( 0x21, mask  );
+
+      mask  = inp( 0xA1 ) & ~( 1 << ( SOUNDSCAPE_Config.WaveIRQ - 8 ) );
+      mask |= SOUNDSCAPE_IntController2Mask & ( 1 << ( SOUNDSCAPE_Config.WaveIRQ - 8 ) );
+      outp( 0xA1, mask  );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_ServiceInterrupt
+
+   Handles interrupt generated by sound card at the end of a voice
+   transfer.  Calls the user supplied callback function.
+---------------------------------------------------------------------*/
+
+static void __interrupt __far SOUNDSCAPE_ServiceInterrupt
+   (
+   void
+   )
+
+   {
+   // save stack
+   GetStack( &oldStackSelector, &oldStackPointer );
+
+   // set our stack
+   SetStack( StackSelector, StackPointer );
+
+	if ( !( inp( SOUNDSCAPE_Config.WavePort + AD_STATUS ) & 0x01 ) )
+      {
+      // restore stack
+      SetStack( oldStackSelector, oldStackPointer );
+
+      // Wasn't our interrupt.  Call the old one.
+      _chain_intr( SOUNDSCAPE_OldInt );
+      }
+
+   // clear the AD-1848 interrupt
+	outp( SOUNDSCAPE_Config.WavePort + AD_STATUS, 0x00 );
+
+   // Keep track of current buffer
+   SOUNDSCAPE_CurrentDMABuffer += SOUNDSCAPE_TransferLength;
+   if ( SOUNDSCAPE_CurrentDMABuffer >= SOUNDSCAPE_DMABufferEnd )
+      {
+      SOUNDSCAPE_CurrentDMABuffer = SOUNDSCAPE_DMABuffer;
+      }
+
+   // Call the caller's callback function
+   if ( SOUNDSCAPE_CallBack != NULL )
+      {
+      SOUNDSCAPE_CallBack();
+      }
+
+   // restore stack
+   SetStack( oldStackSelector, oldStackPointer );
+
+   // send EOI to Interrupt Controller
+   if ( SOUNDSCAPE_Config.WaveIRQ > 7 )
+      {
+      outp( 0xA0, 0x20 );
+      }
+   outp( 0x20, 0x20 );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ga_read
+
+   Reads Ensoniq indirect registers.
+---------------------------------------------------------------------*/
+
+static int ga_read
+   (
+   int rnum
+   )
+
+   {
+   int data;
+
+   outp( SOUNDSCAPE_Config.BasePort + GA_REGADDR, rnum );
+   data = inp( SOUNDSCAPE_Config.BasePort + GA_REGDATA );
+   return( data );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ga_write
+
+   Writes to Ensoniq indirect registers.
+---------------------------------------------------------------------*/
+
+static void ga_write
+   (
+   int rnum,
+   int value
+   )
+
+   {
+	outp( SOUNDSCAPE_Config.BasePort + GA_REGADDR, rnum );
+	outp( SOUNDSCAPE_Config.BasePort + GA_REGDATA, value );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ad_read
+
+   Reads the AD-1848 indirect registers.  This function should not be
+   used while the AD-1848 mode change is enabled
+---------------------------------------------------------------------*/
+
+static int ad_read
+   (
+   int rnum
+   )
+
+   {
+   int data;
+
+	outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, rnum );
+	data = inp( SOUNDSCAPE_Config.WavePort + AD_REGDATA );
+   return( data );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: ad_write
+
+   Writes to the AD-1848 indirect registers.  This function should
+   not be used while the AD-1848 mode change is enabled.
+---------------------------------------------------------------------*/
+
+static void ad_write
+   (
+   int rnum,
+   int value
+   )
+
+   {
+   outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, rnum );
+   outp( SOUNDSCAPE_Config.WavePort + AD_REGDATA, value );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: tdelay
+
+   Delay function - 250ms - for AD-1848 re-synch and autocalibration.
+---------------------------------------------------------------------*/
+
+static void tdelay
+   (
+   void
+   )
+
+   {
+	long time;
+   unsigned flags;
+
+   flags = DisableInterrupts();
+   _enable();
+	time = clock() + CLOCKS_PER_SEC/4;
+	while(clock() < time)
+		;
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: pcm_format
+
+   Sets the PCM data format.
+---------------------------------------------------------------------*/
+
+static void pcm_format
+   (
+   void
+   )
+
+   {
+	int format;
+
+	// build the register value based on format
+	format = 0;
+
+   switch( SOUNDSCAPE_SampleRate )
+      {
+      case 11025:
+         format = 0x03;
+         break;
+
+      case 22050:
+         format = 0x07;
+         break;
+
+      case 44100:
+         format = 0x0b;
+         break;
+
+      default:
+         // Set it to 11025 hz
+         format = 0x03;
+         break;
+      }
+
+	// set other format bits and format globals
+   if ( SOUNDSCAPE_MixMode & SIXTEEN_BIT )
+      {
+      format |= 0x40;
+      }
+
+   if ( SOUNDSCAPE_MixMode & STEREO )
+      {
+      format |= 0x10;
+      }
+
+	// enable mode change, point to format reg
+	outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, 0x40 | AD_FORMAT );
+
+	// write the format
+	outp( SOUNDSCAPE_Config.WavePort + AD_REGDATA, format );
+
+	// delay for internal re-synch
+	tdelay();
+
+	// exit mode change state
+	outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, 0x00 );
+
+	// delay for autocalibration
+	tdelay();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_SetPlaybackRate
+
+   Sets the rate at which the digitized sound will be played in
+   hertz.
+---------------------------------------------------------------------*/
+
+void SOUNDSCAPE_SetPlaybackRate
+   (
+   unsigned rate
+   )
+
+   {
+   if ( rate < 20000 )
+      {
+      rate = 11025;
+      }
+   else if ( rate < 30000 )
+      {
+      rate = 22050;
+      }
+   else
+      {
+      rate = 44100;
+      }
+
+   SOUNDSCAPE_SampleRate = rate;
+
+   // Set the rate
+   pcm_format();
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_GetPlaybackRate
+
+   Returns the rate at which the digitized sound will be played in
+   hertz.
+---------------------------------------------------------------------*/
+
+unsigned SOUNDSCAPE_GetPlaybackRate
+   (
+   void
+   )
+
+   {
+   return( SOUNDSCAPE_SampleRate );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_SetMixMode
+
+   Sets the sound card to play samples in mono or stereo.
+---------------------------------------------------------------------*/
+
+int SOUNDSCAPE_SetMixMode
+   (
+   int mode
+   )
+
+   {
+   SOUNDSCAPE_MixMode = mode & SOUNDSCAPE_MaxMixMode;
+   SOUNDSCAPE_SamplePacketSize = SOUNDSCAPE_SampleSize[ SOUNDSCAPE_MixMode ];
+
+   // Set the mixmode
+   pcm_format();
+
+   return( mode );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_StopPlayback
+
+   Ends the DMA transfer of digitized sound to the sound card.
+---------------------------------------------------------------------*/
+
+void SOUNDSCAPE_StopPlayback
+   (
+   void
+   )
+
+   {
+   // Don't allow anymore interrupts
+   SOUNDSCAPE_DisableInterrupt();
+
+	/* stop the AD-1848 */
+	ad_write( AD_CONFIG, 0x00 );
+
+	/* let it finish it's cycles */
+	tdelay();
+
+   // Disable the DMA channel
+   DMA_EndTransfer( SOUNDSCAPE_Config.DMAChan );
+
+   SOUNDSCAPE_SoundPlaying = FALSE;
+
+   SOUNDSCAPE_DMABuffer = NULL;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_SetupDMABuffer
+
+   Programs the DMAC for sound transfer.
+---------------------------------------------------------------------*/
+
+static int SOUNDSCAPE_SetupDMABuffer
+   (
+   char *BufferPtr,
+   int   BufferSize,
+   int   mode
+   )
+
+   {
+   int DmaStatus;
+
+   DmaStatus = DMA_SetupTransfer( SOUNDSCAPE_Config.DMAChan, BufferPtr, BufferSize, mode );
+   if ( DmaStatus == DMA_Error )
+      {
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_DmaError );
+      return( SOUNDSCAPE_Error );
+      }
+
+   SOUNDSCAPE_DMAChannel         = SOUNDSCAPE_Config.DMAChan;
+   SOUNDSCAPE_DMABuffer          = BufferPtr;
+   SOUNDSCAPE_CurrentDMABuffer   = BufferPtr;
+   SOUNDSCAPE_TotalDMABufferSize = BufferSize;
+   SOUNDSCAPE_DMABufferEnd       = BufferPtr + BufferSize;
+
+   return( SOUNDSCAPE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_GetCurrentPos
+
+   Returns the offset within the current sound being played.
+---------------------------------------------------------------------*/
+
+int SOUNDSCAPE_GetCurrentPos
+   (
+   void
+   )
+
+   {
+   char *CurrentAddr;
+   int   offset;
+
+   if ( !SOUNDSCAPE_SoundPlaying )
+      {
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_NoSoundPlaying );
+      return( SOUNDSCAPE_Error );
+      }
+
+   CurrentAddr = DMA_GetCurrentPos( SOUNDSCAPE_Config.DMAChan );
+
+   offset = ( int )( ( ( unsigned long )CurrentAddr ) -
+      ( ( unsigned long )SOUNDSCAPE_CurrentDMABuffer ) );
+
+   if ( SOUNDSCAPE_MixMode & SIXTEEN_BIT )
+      {
+      offset >>= 1;
+      }
+
+   if ( SOUNDSCAPE_MixMode & STEREO )
+      {
+      offset >>= 1;
+      }
+
+   return( offset );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_BeginPlayback
+
+   Starts playback of digitized sound.
+---------------------------------------------------------------------*/
+
+static int SOUNDSCAPE_BeginPlayback
+   (
+   int length
+   )
+
+   {
+   int SampleLength;
+   int LoByte;
+   int HiByte;
+
+   if ( SOUNDSCAPE_MixMode & SIXTEEN_BIT )
+      {
+      SampleLength = length / 2;
+      }
+   else
+      {
+      SampleLength = length;
+      }
+
+   if ( SOUNDSCAPE_MixMode & STEREO )
+      {
+      SampleLength >>= 1;
+      }
+
+   SampleLength--;
+
+	// setup the AD-1848 interrupt count
+	// set the interrupt count value based on the format.
+	// count will decrement every sample period and generate
+	// an interrupt when in rolls over. we want this always
+	// to be at every 1/2 buffer, regardless of the data format,
+	// so the count must be adjusted accordingly.
+   HiByte = hibyte( SampleLength );
+   LoByte = lobyte( SampleLength );
+	ad_write( AD_LCOUNT, LoByte );
+	ad_write( AD_UCOUNT, HiByte );
+
+	/* unmask the host DMA controller */
+   SOUNDSCAPE_EnableInterrupt();
+
+	/* start the AD-1848 */
+	ad_write(AD_CONFIG, 0x01);
+
+   SOUNDSCAPE_SoundPlaying = TRUE;
+
+   return( SOUNDSCAPE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_BeginBufferedPlayback
+
+   Begins multibuffered playback of digitized sound on the sound card.
+---------------------------------------------------------------------*/
+
+int SOUNDSCAPE_BeginBufferedPlayback
+   (
+   char    *BufferStart,
+   int      BufferSize,
+   int      NumDivisions,
+   unsigned SampleRate,
+   int      MixMode,
+   void  ( *CallBackFunc )( void )
+   )
+
+   {
+   int DmaStatus;
+   int TransferLength;
+
+   if ( SOUNDSCAPE_SoundPlaying )
+      {
+      SOUNDSCAPE_StopPlayback();
+      }
+
+   SOUNDSCAPE_SetMixMode( MixMode );
+
+   DmaStatus = SOUNDSCAPE_SetupDMABuffer( BufferStart, BufferSize,
+      DMA_AutoInitRead );
+   if ( DmaStatus == SOUNDSCAPE_Error )
+      {
+      return( SOUNDSCAPE_Error );
+      }
+
+   SOUNDSCAPE_SetPlaybackRate( SampleRate );
+
+   SOUNDSCAPE_SetCallBack( CallBackFunc );
+
+   SOUNDSCAPE_EnableInterrupt();
+
+   TransferLength = BufferSize / NumDivisions;
+   SOUNDSCAPE_TransferLength = TransferLength;
+
+   SOUNDSCAPE_BeginPlayback( TransferLength );
+
+   return( SOUNDSCAPE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_GetCardInfo
+
+   Returns the maximum number of bits that can represent a sample
+   (8 or 16) and the number of channels (1 for mono, 2 for stereo).
+---------------------------------------------------------------------*/
+
+int SOUNDSCAPE_GetCardInfo
+   (
+   int *MaxSampleBits,
+   int *MaxChannels
+   )
+
+   {
+   int status;
+
+   status = SOUNDSCAPE_FindCard();
+   if ( status == SOUNDSCAPE_Ok )
+      {
+      *MaxChannels = 2;
+      *MaxSampleBits = 16;
+      return( SOUNDSCAPE_Ok );
+      }
+
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_SetCallBack
+
+   Specifies the user function to call at the end of a sound transfer.
+---------------------------------------------------------------------*/
+
+void SOUNDSCAPE_SetCallBack
+   (
+   void ( *func )( void )
+   )
+
+   {
+   SOUNDSCAPE_CallBack = func;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void SOUNDSCAPE_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_UnlockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+static void SOUNDSCAPE_UnlockMemory
+   (
+   void
+   )
+
+   {
+   DPMI_UnlockMemoryRegion( SOUNDSCAPE_LockStart, SOUNDSCAPE_LockEnd );
+   DPMI_Unlock( SOUNDSCAPE_Config );
+   DPMI_Unlock( SOUNDSCAPE_OldInt );
+   DPMI_Unlock( SOUNDSCAPE_Installed );
+   DPMI_Unlock( SOUNDSCAPE_DMABuffer );
+   DPMI_Unlock( SOUNDSCAPE_DMABufferEnd );
+   DPMI_Unlock( SOUNDSCAPE_CurrentDMABuffer );
+   DPMI_Unlock( SOUNDSCAPE_TotalDMABufferSize );
+   DPMI_Unlock( SOUNDSCAPE_TransferLength );
+   DPMI_Unlock( SOUNDSCAPE_MixMode );
+   DPMI_Unlock( SOUNDSCAPE_SamplePacketSize );
+   DPMI_Unlock( SOUNDSCAPE_SampleRate );
+   DPMI_Unlock( SOUNDSCAPE_SoundPlaying );
+   DPMI_Unlock( SOUNDSCAPE_CallBack );
+   DPMI_Unlock( SOUNDSCAPE_IntController1Mask );
+   DPMI_Unlock( SOUNDSCAPE_IntController2Mask );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_LockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+static int SOUNDSCAPE_LockMemory
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status  = DPMI_LockMemoryRegion( SOUNDSCAPE_LockStart, SOUNDSCAPE_LockEnd );
+   status |= DPMI_Lock( SOUNDSCAPE_Config );
+   status |= DPMI_Lock( SOUNDSCAPE_OldInt );
+   status |= DPMI_Lock( SOUNDSCAPE_Installed );
+   status |= DPMI_Lock( SOUNDSCAPE_DMABuffer );
+   status |= DPMI_Lock( SOUNDSCAPE_DMABufferEnd );
+   status |= DPMI_Lock( SOUNDSCAPE_CurrentDMABuffer );
+   status |= DPMI_Lock( SOUNDSCAPE_TotalDMABufferSize );
+   status |= DPMI_Lock( SOUNDSCAPE_TransferLength );
+   status |= DPMI_Lock( SOUNDSCAPE_MixMode );
+   status |= DPMI_Lock( SOUNDSCAPE_SamplePacketSize );
+   status |= DPMI_Lock( SOUNDSCAPE_SampleRate );
+   status |= DPMI_Lock( SOUNDSCAPE_SoundPlaying );
+   status |= DPMI_Lock( SOUNDSCAPE_CallBack );
+   status |= DPMI_Lock( SOUNDSCAPE_IntController1Mask );
+   status |= DPMI_Lock( SOUNDSCAPE_IntController2Mask );
+
+   if ( status != DPMI_Ok )
+      {
+      SOUNDSCAPE_UnlockMemory();
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_DPMI_Error );
+      return( SOUNDSCAPE_Error );
+      }
+
+   return( SOUNDSCAPE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: allocateTimerStack
+
+   Allocate a block of memory from conventional (low) memory and return
+   the selector (which can go directly into a segment register) of the
+   memory block or 0 if an error occured.
+---------------------------------------------------------------------*/
+
+static unsigned short allocateTimerStack
+   (
+   unsigned short size
+   )
+
+   {
+   union REGS regs;
+
+   // clear all registers
+   memset( &regs, 0, sizeof( regs ) );
+
+   // DPMI allocate conventional memory
+   regs.w.ax = 0x100;
+
+   // size in paragraphs
+   regs.w.bx = ( size + 15 ) / 16;
+
+   int386( 0x31, &regs, &regs );
+   if (!regs.w.cflag)
+      {
+      // DPMI call returns selector in dx
+      // (ax contains real mode segment
+      // which is ignored here)
+
+      return( regs.w.dx );
+      }
+
+   // Couldn't allocate memory.
+   return( NULL );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: deallocateTimerStack
+
+   Deallocate a block of conventional (low) memory given a selector to
+   it.  Assumes the block was allocated with DPMI function 0x100.
+---------------------------------------------------------------------*/
+
+static void deallocateTimerStack
+   (
+   unsigned short selector
+   )
+
+   {
+   union REGS regs;
+
+   if ( selector != NULL )
+      {
+      // clear all registers
+      memset( &regs, 0, sizeof( regs ) );
+
+      regs.w.ax = 0x101;
+      regs.w.dx = selector;
+      int386( 0x31, &regs, &regs );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: parse
+
+   Parses for the right hand string of an .INI file equate.
+---------------------------------------------------------------------*/
+
+static int parse
+   (
+   char *val,
+   char *str,
+   FILE *p1
+   )
+
+   {
+	int  i;
+	int  j;
+   char tmpstr[ 81 ];
+
+	rewind( p1 );
+
+	while( !feof( p1 ) )
+      {
+      // get a new string
+      fgets( tmpstr, 81, p1 );
+      if( ( tmpstr[ 0 ] == '[' ) || ( tmpstr[ 0 ] == ';' ) ||
+         ( tmpstr[ 0 ] == '\n' ) )
+         {
+         continue;
+         }
+
+		// parse up to the '='
+      i = 0;
+      while( ( tmpstr[ i ] != '=' ) && ( tmpstr[ i ] != '\n' ) )
+         {
+         i++;
+         }
+
+		if( tmpstr[ i ] != '=' )
+         {
+         continue;
+         }
+
+		tmpstr[ i ] = '\0';
+
+		// see if it's the one we want
+		if ( strcmp( tmpstr, str ) )
+         {
+         continue;
+         }
+
+		// copy the right hand value to the destination string
+      i++;
+		for( j = 0; j < 32; j++ )
+         {
+         if ( ( tmpstr[ i ] == ' ' ) || ( tmpstr[ i ] == '\t' ) ||
+            ( tmpstr[ i ] == ',' ) || ( tmpstr[ i ] == '\n' ) )
+            {
+            break;
+            }
+
+			val[ j ] = tmpstr[ i ];
+         i++;
+         }
+		val[j] = '\0';
+
+      return( TRUE );
+      }
+
+   return( FALSE );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_FindCard
+
+   Determines if a SoundScape is present and where it is located.
+---------------------------------------------------------------------*/
+
+static int SOUNDSCAPE_FindCard
+   (
+   void
+   )
+
+   {
+   int   found;
+   int   status;
+   int   tmp;
+	char *cp;
+   char  str[ 33 ];
+	FILE *fp;
+
+   if ( SOUNDSCAPE_FoundCard )
+      {
+      return( SOUNDSCAPE_Ok );
+      }
+
+	cp = getenv( "SNDSCAPE" );
+   if ( cp == NULL )
+      {
+      strcpy( str, "C:\\SNDSCAPE" );
+      }
+   else
+      {
+      strcpy( str, cp );
+      }
+
+   strcat(str, "\\SNDSCAPE.INI");
+
+	fp = fopen( str, "r" );
+   if ( fp == NULL )
+      {
+      if ( cp == NULL )
+         {
+         SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_EnvNotFound );
+         return( SOUNDSCAPE_Error );
+         }
+
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_InitFileNotFound );
+      return( SOUNDSCAPE_Error );
+      }
+
+	found = parse( str, "Product", fp );
+   if ( !found )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingProductInfo );
+      return( SOUNDSCAPE_Error );
+      }
+
+	if( strstr( str, "SoundFX" ) == NULL )
+      {
+      SOUNDSCAPE_Config.OldIRQs = FALSE;
+      }
+	else
+      {
+		SOUNDSCAPE_Config.OldIRQs = TRUE;
+      }
+
+	found = parse( str, "Port", fp );
+   if ( !found )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingPortInfo );
+      return( SOUNDSCAPE_Error );
+      }
+
+	SOUNDSCAPE_Config.BasePort = strtol( str, ( char ** )0, 16);
+
+	found = parse( str, "DMA", fp );
+   if ( !found )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingDMAInfo );
+      return( SOUNDSCAPE_Error );
+      }
+
+	SOUNDSCAPE_Config.DMAChan = ( int )strtol( str, ( char ** )0, 10 );
+   status = DMA_VerifyChannel( SOUNDSCAPE_Config.DMAChan );
+   if ( status == DMA_Error )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_DmaError );
+      return( SOUNDSCAPE_Error );
+      }
+
+	found = parse( str, "IRQ", fp );
+   if ( !found )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingIRQInfo );
+      return( SOUNDSCAPE_Error );
+      }
+
+	SOUNDSCAPE_Config.MIDIIRQ = ( int )strtol( str, ( char ** )0, 10 );
+   if ( SOUNDSCAPE_Config.MIDIIRQ == 2 )
+      {
+      SOUNDSCAPE_Config.MIDIIRQ = 9;
+      }
+
+	found = parse( str, "SBIRQ", fp );
+   if ( !found )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingSBIRQInfo );
+      return( SOUNDSCAPE_Error );
+      }
+
+	SOUNDSCAPE_Config.WaveIRQ = ( int )strtol( str, ( char ** )0, 10 );
+	if ( SOUNDSCAPE_Config.WaveIRQ == 2 )
+      {
+		SOUNDSCAPE_Config.WaveIRQ = 9;
+      }
+
+   if ( !VALID_IRQ( SOUNDSCAPE_Config.WaveIRQ ) )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_InvalidSBIrq );
+      return( SOUNDSCAPE_Error );
+      }
+
+   if ( SOUNDSCAPE_Interrupts[ SOUNDSCAPE_Config.WaveIRQ ] == INVALID )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_InvalidSBIrq );
+      return( SOUNDSCAPE_Error );
+      }
+
+	found = parse( str, "SBEnable", fp );
+   if ( !found )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingSBENABLEInfo );
+      return( SOUNDSCAPE_Error );
+      }
+
+	if( !strcmp( str, "false" ) )
+      {
+      SOUNDSCAPE_Config.SBEmul = FALSE;
+      }
+	else
+      {
+      SOUNDSCAPE_Config.SBEmul = TRUE;
+      }
+
+	// do a hardware test
+	outp( SOUNDSCAPE_Config.BasePort + GA_REGADDR, 0x00f5 );
+	tmp = inp( SOUNDSCAPE_Config.BasePort + GA_REGADDR );
+	if ( ( tmp & 0x000f ) != 0x0005 )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_HardwareError );
+      return( SOUNDSCAPE_Error );
+      }
+
+	if( ( tmp & 0x00f0 ) == 0x00f0 )
+      {
+      fclose( fp );
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_HardwareError );
+      return( SOUNDSCAPE_Error );
+      }
+
+	// formulate the chip ID
+	tmp >>= 4;
+	if( tmp == 0 )
+      {
+      SOUNDSCAPE_Config.ChipID = ODIE;
+      }
+	else if ( !( tmp & 0x0008 ) )
+      {
+		SOUNDSCAPE_Config.ChipID = OPUS;
+      }
+	else
+      {
+		SOUNDSCAPE_Config.ChipID = MMIC;
+      }
+
+	// parse for the AD-1848 address if necessary
+	if( SOUNDSCAPE_Config.ChipID == ODIE )
+      {
+      found = parse( str, "WavePort", fp );
+      if ( !found )
+         {
+         fclose( fp );
+         SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingWavePortInfo );
+         return( SOUNDSCAPE_Error );
+         }
+
+      SOUNDSCAPE_Config.WavePort = strtol( str, ( char ** )0, 16 );
+      }
+	else
+      {
+      // otherwise, the base address is fixed
+      SOUNDSCAPE_Config.WavePort = SOUNDSCAPE_Config.BasePort + AD_OFFSET;
+      }
+
+	// we're done with the file
+	fclose( fp );
+
+	// if it's an ODIE board, note CD-ROM decode enable
+	if ( SOUNDSCAPE_Config.ChipID == ODIE )
+      {
+		SOUNDSCAPE_Config.CDROM = ga_read( GA_CDCFG ) & 0x80;
+      }
+
+	// build the Wave IRQ index value
+	if( !SOUNDSCAPE_Config.OldIRQs )
+      {
+      switch( SOUNDSCAPE_Config.WaveIRQ )
+         {
+         case 9 :
+            SOUNDSCAPE_Config.IRQIndx = 0;
+            break;
+
+         case 5 :
+            SOUNDSCAPE_Config.IRQIndx = 1;
+            break;
+
+         case 7 :
+            SOUNDSCAPE_Config.IRQIndx = 2;
+            break;
+
+         default :
+            SOUNDSCAPE_Config.IRQIndx = 3;
+            break;
+         }
+      }
+   else
+      {
+      switch( SOUNDSCAPE_Config.WaveIRQ )
+         {
+         case 9 :
+            SOUNDSCAPE_Config.IRQIndx = 0;
+            break;
+
+         case 5 :
+            SOUNDSCAPE_Config.IRQIndx = 2;
+            break;
+
+         case 7 :
+            SOUNDSCAPE_Config.IRQIndx = 1;
+            break;
+
+         default :
+            SOUNDSCAPE_Config.IRQIndx = 3;
+            break;
+         }
+      }
+
+   SOUNDSCAPE_FoundCard = TRUE;
+   SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_Ok );
+   return( SOUNDSCAPE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_Setup
+
+   Setup the Soundscape card for native mode PCM.
+---------------------------------------------------------------------*/
+
+static int SOUNDSCAPE_Setup
+   (
+   void
+   )
+
+   {
+   int tmp;
+   int Interrupt;
+   int status;
+
+	// if necessary, clear any pending SB ints
+	if ( SOUNDSCAPE_Config.SBEmul )
+      {
+      inp( SB_IACK );
+      }
+
+   SOUNDSCAPE_DisableInterrupt();
+
+	// make sure the AD-1848 is not running
+	if ( ad_read( AD_CONFIG ) & 0x01 )
+      {
+      SOUNDSCAPE_StopPlayback();
+      }
+
+	// if necessary, do some signal re-routing
+	if( SOUNDSCAPE_Config.ChipID != MMIC )
+      {
+      // get the gate-array off of the DMA channel
+		ga_write( GA_DMACHB, 0x20 );
+
+      if ( !SOUNDSCAPE_Config.OldIRQs )
+         {
+         switch( SOUNDSCAPE_Config.MIDIIRQ )
+            {
+            case 5 :
+               tmp = 1;
+               break;
+
+            case 7 :
+               tmp = 2;
+               break;
+
+            case 9 :
+               tmp = 0;
+               break;
+
+            default :
+               tmp = 3;
+               break;
+            }
+         }
+      else
+         {
+         switch( SOUNDSCAPE_Config.MIDIIRQ )
+            {
+            case 5 :
+               tmp = 2;
+               break;
+
+            case 7 :
+               tmp = 1;
+               break;
+
+            case 9 :
+               tmp = 0;
+               break;
+
+            default :
+               tmp = 3;
+               break;
+            }
+         }
+
+      // set HostIRQ to MIDIIRQ for now
+      ga_write( GA_INTCFG, 0xf0 | ( tmp << 2 ) | tmp );
+
+      // now, route the AD-1848 stuff ...
+		if ( SOUNDSCAPE_Config.ChipID == OPUS )
+         {
+         // set the AD-1848 chip decode
+         ga_write( GA_HMCTL, ( ga_read( GA_HMCTL ) & 0xcf ) | 0x10 );
+         }
+      // setup the DMA polarity
+		ga_write( GA_DMACFG, 0x50 );
+
+		// init the CD-ROM (AD-1848) config register
+		ga_write( GA_CDCFG, 0x89 | ( SOUNDSCAPE_Config.DMAChan << 4 ) | ( SOUNDSCAPE_Config.IRQIndx << 1 ) );
+
+      // enable mode change, point to config reg
+		outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, 0x40 | AD_CONFIG );
+
+      // set interf cnfg reg for DMA mode, single chan, autocal on
+		outp( SOUNDSCAPE_Config.WavePort + AD_REGDATA, 0x0c );
+
+      // exit mode change state
+		outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, 0x00 );
+
+      // delay for autocalibration
+      tdelay();
+      }
+
+   // Install our interrupt handler
+   Interrupt = SOUNDSCAPE_Interrupts[ SOUNDSCAPE_Config.WaveIRQ ];
+   SOUNDSCAPE_OldInt = _dos_getvect( Interrupt );
+   if ( SOUNDSCAPE_Config.WaveIRQ < 8 )
+      {
+      _dos_setvect( Interrupt, SOUNDSCAPE_ServiceInterrupt );
+      }
+   else
+      {
+      status = IRQ_SetVector( Interrupt, SOUNDSCAPE_ServiceInterrupt );
+      if ( status != IRQ_Ok )
+         {
+         SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_UnableToSetIrq );
+         return( SOUNDSCAPE_Error );
+         }
+      }
+
+	// max left and right volumes
+	ad_write( AD_LEFTOUT, 0 );
+	ad_write( AD_RIGHTOUT, 0 );
+
+	// clear any pending interrupt condition
+	outp( SOUNDSCAPE_Config.WavePort + AD_STATUS, 0x00 );
+
+	// enable the interrupt pin
+	ad_write( AD_PINCTRL, ad_read( AD_PINCTRL ) | 0x02 );
+
+   SOUNDSCAPE_EnableInterrupt();
+
+   SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_Ok );
+   return( SOUNDSCAPE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_GetMIDIPort
+
+   Gets the address of the SoundScape MIDI port.
+---------------------------------------------------------------------*/
+
+int SOUNDSCAPE_GetMIDIPort
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status = SOUNDSCAPE_FindCard();
+   if ( status != SOUNDSCAPE_Ok )
+      {
+      return( status );
+      }
+
+   return( SOUNDSCAPE_Config.BasePort );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_Init
+
+   Initializes the sound card and prepares the module to play
+   digitized sounds.
+---------------------------------------------------------------------*/
+
+int SOUNDSCAPE_Init
+   (
+   void
+   )
+
+   {
+   int status;
+
+   if ( SOUNDSCAPE_Installed )
+      {
+      SOUNDSCAPE_Shutdown();
+      }
+
+   // Save the interrupt masks
+   SOUNDSCAPE_IntController1Mask = inp( 0x21 );
+   SOUNDSCAPE_IntController2Mask = inp( 0xA1 );
+
+   SOUNDSCAPE_SoundPlaying = FALSE;
+   SOUNDSCAPE_SetCallBack( NULL );
+   SOUNDSCAPE_DMABuffer = NULL;
+
+   status = SOUNDSCAPE_FindCard();
+   if ( status != SOUNDSCAPE_Ok )
+      {
+      return( status );
+      }
+
+   status = SOUNDSCAPE_LockMemory();
+   if ( status != SOUNDSCAPE_Ok )
+      {
+      SOUNDSCAPE_UnlockMemory();
+      return( status );
+      }
+
+   StackSelector = allocateTimerStack( kStackSize );
+   if ( StackSelector == NULL )
+      {
+      SOUNDSCAPE_UnlockMemory();
+      SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_OutOfMemory );
+      return( SOUNDSCAPE_Error );
+      }
+
+   // Leave a little room at top of stack just for the hell of it...
+   StackPointer = kStackSize - sizeof( long );
+
+   SOUNDSCAPE_Installed = TRUE;
+
+   status = SOUNDSCAPE_Setup();
+   if ( status != SOUNDSCAPE_Ok )
+      {
+      SOUNDSCAPE_Shutdown();
+      return( status );
+      }
+
+//	printf("Testing DMA and IRQ ...\n");
+//	if( test_dma_irq() )
+//      {
+//      printf("\t\007Hardware Not Responding\n\n");
+//      close_soundscape();
+//      return( SOUNDSCAPE_Error );
+//      }
+
+   SOUNDSCAPE_SetPlaybackRate( SOUNDSCAPE_DefaultSampleRate );
+   SOUNDSCAPE_SetMixMode( SOUNDSCAPE_DefaultMixMode );
+
+   SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_Ok );
+   return( SOUNDSCAPE_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SOUNDSCAPE_Shutdown
+
+   Ends transfer of sound data to the sound card and restores the
+   system resources used by the card.
+---------------------------------------------------------------------*/
+
+void SOUNDSCAPE_Shutdown
+   (
+   void
+   )
+
+   {
+   int Interrupt;
+
+   // Halt the DMA transfer
+   SOUNDSCAPE_StopPlayback();
+
+	// disable the AD-1848 interrupt pin
+	ad_write( AD_PINCTRL, ad_read( AD_PINCTRL ) & 0xfd );
+
+	// if necessary, do some signal re-routing
+	if ( SOUNDSCAPE_Config.ChipID != MMIC )
+      {
+		// re-init the CD-ROM (AD-1848) config register as needed.
+		// this will disable the AD-1848 interface.
+		if ( SOUNDSCAPE_Config.ChipID == ODIE )
+         {
+         ga_write( GA_CDCFG, SOUNDSCAPE_Config.CDROM );
+         }
+		else
+         {
+         ga_write( GA_CDCFG, ga_read( GA_CDCFG ) & 0x7f);
+         }
+
+		// if necessary, reset the SoundBlaster IRQ
+		if ( SOUNDSCAPE_Config.SBEmul )
+         {
+         ga_write( GA_INTCFG, ( ga_read( GA_INTCFG ) & 0xf3 ) |
+            ( SOUNDSCAPE_Config.IRQIndx << 2 ) );
+         }
+
+      // re-assign the gate-array DMA channel
+		ga_write( GA_DMACHB, 0x80 | ( SOUNDSCAPE_Config.DMAChan << 4 ) );
+      }
+
+   // Restore the original interrupt
+   Interrupt = SOUNDSCAPE_Interrupts[ SOUNDSCAPE_Config.WaveIRQ ];
+   if ( SOUNDSCAPE_Config.WaveIRQ >= 8 )
+      {
+      IRQ_RestoreVector( Interrupt );
+      }
+   _dos_setvect( Interrupt, SOUNDSCAPE_OldInt );
+
+   SOUNDSCAPE_SoundPlaying = FALSE;
+
+   SOUNDSCAPE_DMABuffer = NULL;
+
+   SOUNDSCAPE_SetCallBack( NULL );
+
+   SOUNDSCAPE_UnlockMemory();
+
+   if ( StackSelector != NULL )
+      {
+      deallocateTimerStack( StackSelector );
+      StackSelector = NULL;
+      }
+
+   SOUNDSCAPE_Installed = FALSE;
+   }

Added: tags/rott-1.1/rott/audiolib/sndscape.h
===================================================================
--- tags/rott-1.1/rott/audiolib/sndscape.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/sndscape.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,73 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: SNDSCAPE.H
+
+   author: James R. Dose
+   date:   October 26, 1994
+
+   Public header for SNDSCAPE.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __SNDSCAPE_H
+#define __SNDSCAPE_H
+
+extern int SOUNDSCAPE_DMAChannel;
+extern int SOUNDSCAPE_ErrorCode;
+
+enum SOUNDSCAPE_ERRORS
+   {
+   SOUNDSCAPE_Warning = -2,
+   SOUNDSCAPE_Error = -1,
+   SOUNDSCAPE_Ok = 0,
+   SOUNDSCAPE_EnvNotFound,
+   SOUNDSCAPE_InitFileNotFound,
+   SOUNDSCAPE_MissingProductInfo,
+   SOUNDSCAPE_MissingPortInfo,
+   SOUNDSCAPE_MissingDMAInfo,
+   SOUNDSCAPE_MissingIRQInfo,
+   SOUNDSCAPE_MissingSBIRQInfo,
+   SOUNDSCAPE_MissingSBENABLEInfo,
+   SOUNDSCAPE_MissingWavePortInfo,
+   SOUNDSCAPE_HardwareError,
+   SOUNDSCAPE_NoSoundPlaying,
+   SOUNDSCAPE_InvalidSBIrq,
+   SOUNDSCAPE_UnableToSetIrq,
+   SOUNDSCAPE_DmaError,
+   SOUNDSCAPE_DPMI_Error,
+   SOUNDSCAPE_OutOfMemory
+   };
+
+char    *SOUNDSCAPE_ErrorString( int ErrorNumber );
+void     SOUNDSCAPE_SetPlaybackRate( unsigned rate );
+unsigned SOUNDSCAPE_GetPlaybackRate( void );
+int      SOUNDSCAPE_SetMixMode( int mode );
+void     SOUNDSCAPE_StopPlayback( void );
+int      SOUNDSCAPE_GetCurrentPos( void );
+int      SOUNDSCAPE_BeginBufferedPlayback( char *BufferStart, int BufferSize, int NumDivisions, unsigned SampleRate, int MixMode, void ( *CallBackFunc )( void ) );
+int      SOUNDSCAPE_GetCardInfo( int *MaxSampleBits, int *MaxChannels );
+void     SOUNDSCAPE_SetCallBack( void ( *func )( void ) );
+int      SOUNDSCAPE_GetMIDIPort( void );
+int      SOUNDSCAPE_Init( void );
+void     SOUNDSCAPE_Shutdown( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/sndsrc.c
===================================================================
--- tags/rott-1.1/rott/audiolib/sndsrc.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/sndsrc.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,658 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: SNDSRC.C
+
+   author: James R. Dose
+   date:   March 26, 1994
+
+   Low level routines to support the Disney Sound Source.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#define STEREO      1
+#define SIXTEEN_BIT 2
+
+#define MONO_8BIT    0
+#define STEREO_8BIT  ( STEREO )
+#define MONO_16BIT   ( SIXTEEN_BIT )
+#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
+
+#include <stdlib.h>
+#include <dos.h>
+#include <conio.h>
+#include "dpmi.h"
+#include "task_man.h"
+#include "sndcards.h"
+#include "user.h"
+#include "sndsrc.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+static int SS_Installed = FALSE;
+
+static int SS_Port = SS_DefaultPort;
+static int SS_OffCommand = 0xc;
+
+static char   *SS_BufferStart;
+static char   *SS_BufferEnd;
+static char   *SS_CurrentBuffer;
+static int     SS_BufferNum = 0;
+static int     SS_NumBuffers = 0;
+static int     SS_TotalBufferSize = 0;
+static int     SS_TransferLength  = 0;
+static int     SS_CurrentLength   = 0;
+
+static char   *SS_SoundPtr;
+volatile int   SS_SoundPlaying;
+
+static task   *SS_Timer;
+
+void ( *SS_CallBack )( void );
+
+int SS_ErrorCode = SS_Ok;
+
+#define SS_SetErrorCode( status ) \
+   SS_ErrorCode   = ( status );
+
+/*---------------------------------------------------------------------
+   Function: SS_ErrorString
+
+   Returns a pointer to the error message associated with an error
+   number.  A -1 returns a pointer the current error.
+---------------------------------------------------------------------*/
+
+char *SS_ErrorString
+   (
+   int ErrorNumber
+   )
+
+   {
+   char *ErrorString;
+
+   switch( ErrorNumber )
+      {
+      case SS_Error :
+         ErrorString = SS_ErrorString( SS_ErrorCode );
+         break;
+
+      case SS_Ok :
+         ErrorString = "Sound Source ok.";
+         break;
+
+      case SS_NotFound :
+         ErrorString = "Could not detect Sound Source.";
+         break;
+
+      case SS_NoSoundPlaying :
+         ErrorString = "No sound playing in SndSrc.";
+         break;
+
+      case SS_DPMI_Error :
+         ErrorString = "DPMI Error in SndSrc.";
+         break;
+
+      default :
+         ErrorString = "Unknown Sound Source error code.";
+         break;
+      }
+
+   return( ErrorString );
+   }
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define SS_LockStart SS_ServiceInterrupt
+
+
+/*---------------------------------------------------------------------
+   Function: SS_ServiceInterrupt
+
+   Handles interrupt generated by sound card at the end of a voice
+   transfer.  Calls the user supplied callback function.
+---------------------------------------------------------------------*/
+
+static void SS_ServiceInterrupt
+   (
+   task *Task
+   )
+
+   {
+   int port = SS_Port;
+   int count;
+
+   count = 0;
+   while( ( inp( port + 1 ) & 0x40 ) == 0 )
+      {
+      outp( port, *SS_SoundPtr++ );
+      outp( port + 2, SS_OffCommand );
+      outp( port + 2, 4 );
+
+      SS_CurrentLength--;
+      if ( SS_CurrentLength == 0 )
+         {
+         // Keep track of current buffer
+         SS_CurrentBuffer += SS_TransferLength;
+         SS_BufferNum++;
+         if ( SS_BufferNum >= SS_NumBuffers )
+            {
+            SS_BufferNum = 0;
+            SS_CurrentBuffer = SS_BufferStart;
+            }
+
+         SS_CurrentLength = SS_TransferLength;
+         SS_SoundPtr = SS_CurrentBuffer;
+
+         // Call the caller's callback function
+         if ( SS_CallBack != NULL )
+            {
+            SS_CallBack();
+            }
+         }
+
+      count++;
+      // Only do at most 14 samples per tick
+      if ( count > 13 )
+         {
+         break;
+         }
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_StopPlayback
+
+   Ends the transfer of digitized sound to the Sound Source.
+---------------------------------------------------------------------*/
+
+void SS_StopPlayback
+   (
+   void
+   )
+
+   {
+   if ( SS_SoundPlaying )
+      {
+      TS_Terminate( SS_Timer );
+
+      outp( SS_Port, 0x80 );
+      outp( SS_Port + 2, SS_OffCommand );
+      outp( SS_Port + 2, 4 );
+
+      SS_SoundPlaying = FALSE;
+
+      SS_BufferStart = NULL;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_GetCurrentPos
+
+   Returns the offset within the current sound being played.
+---------------------------------------------------------------------*/
+
+int SS_GetCurrentPos
+   (
+   void
+   )
+
+   {
+   int offset;
+
+   if ( !SS_SoundPlaying )
+      {
+      SS_SetErrorCode( SS_NoSoundPlaying );
+      return( SS_Warning );
+      }
+
+   offset = ( int )( ( ( unsigned long )SS_SoundPtr ) -
+      ( ( unsigned long )SS_CurrentBuffer ) );
+
+   return( offset );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void SS_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_BeginBufferedPlayback
+
+   Begins multibuffered playback of digitized sound on the Sound Source.
+---------------------------------------------------------------------*/
+
+int SS_BeginBufferedPlayback
+   (
+   char *BufferStart,
+   int   BufferSize,
+   int   NumDivisions,
+   void ( *CallBackFunc )( void )
+   )
+
+   {
+   if ( SS_SoundPlaying )
+      {
+      SS_StopPlayback();
+      }
+
+   SS_SetCallBack( CallBackFunc );
+
+   SS_BufferStart     = BufferStart;
+   SS_CurrentBuffer   = BufferStart;
+   SS_SoundPtr        = BufferStart;
+   SS_TotalBufferSize = BufferSize;
+   SS_BufferEnd       = BufferStart + BufferSize;
+   SS_TransferLength  = BufferSize / NumDivisions;
+   SS_CurrentLength   = SS_TransferLength;
+   SS_BufferNum       = 0;
+   SS_NumBuffers      = NumDivisions;
+
+   SS_SoundPlaying = TRUE;
+
+//   SS_Timer = TS_ScheduleTask( SS_ServiceInterrupt, 438, 1, NULL );
+   SS_Timer = TS_ScheduleTask( SS_ServiceInterrupt, 510, 1, NULL );
+   TS_Dispatch();
+
+   return( SS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_GetPlaybackRate
+
+   Returns the rate at which the digitized sound will be played in
+   hertz.
+---------------------------------------------------------------------*/
+
+int SS_GetPlaybackRate
+   (
+   void
+   )
+
+   {
+   return( SS_SampleRate );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_SetMixMode
+
+   Sets the sound card to play samples in mono or stereo.
+---------------------------------------------------------------------*/
+
+int SS_SetMixMode
+   (
+   int mode
+   )
+
+   {
+   mode = MONO_8BIT;
+   return( mode );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_SetPort
+
+   Selects which port to use to write to the Sound Source.
+---------------------------------------------------------------------*/
+
+int SS_SetPort
+   (
+   int port
+   )
+
+   {
+   if ( SS_Installed )
+      {
+      SS_Shutdown();
+      }
+
+   SS_Port = port;
+
+   return( SS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_SetCallBack
+
+   Specifies the user function to call at the end of a sound transfer.
+---------------------------------------------------------------------*/
+
+void SS_SetCallBack
+   (
+   void ( *func )( void )
+   )
+
+   {
+   SS_CallBack = func;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_TestTimer
+
+   Used as a delay in SS_TestSoundSource.
+---------------------------------------------------------------------*/
+
+void SS_TestTimer
+   (
+   task *Task
+   )
+
+   {
+   ( *( int * )( Task->data ) )++;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_TestSoundSource
+
+   Detect if the Sound Source is located at the specified port.
+---------------------------------------------------------------------*/
+
+int SS_TestSoundSource
+   (
+   int port
+   )
+
+   {
+   int   present;
+   task *timer;
+   volatile int ticks;
+   int   i;
+
+   present = FALSE;
+
+   timer = TS_ScheduleTask( SS_TestTimer, 140, 1, &ticks );
+   TS_Dispatch();
+
+   outp( port + 2, 4 );
+
+   ticks = 0;
+
+   while( ticks < 4 )
+      {
+      // Do nothing for a while
+      }
+
+   TS_Terminate( timer );
+
+   if ( ( inp( port + 1 ) & 0x40 ) == 0 )
+      {
+      for( i = 32; i > 0; i-- )
+         {
+         outp( port, 0x80 );
+         outp( port + 2, SS_OffCommand );
+         outp( port + 2, 4 );
+         }
+
+      if ( inp( port + 1 ) & 0x40 )
+         {
+         present = TRUE;
+         }
+      }
+
+   outp( port + 2, SS_OffCommand );
+
+   return( present );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_DetectSoundSource
+
+   Detects which port the Sound Source is located.
+---------------------------------------------------------------------*/
+
+int SS_DetectSoundSource
+   (
+   void
+   )
+
+   {
+   if ( USER_CheckParameter( SELECT_SOUNDSOURCE_PORT1 ) )
+      {
+      SS_Port = SS_Port1;
+      return( TRUE );
+      }
+
+   if ( USER_CheckParameter( SELECT_SOUNDSOURCE_PORT2 ) )
+      {
+      SS_Port = SS_Port2;
+      return( TRUE );
+      }
+
+   if ( USER_CheckParameter( SELECT_SOUNDSOURCE_PORT3 ) )
+      {
+      SS_Port = SS_Port3;
+      return( TRUE );
+      }
+
+   if ( SS_TestSoundSource( SS_Port1 ) )
+      {
+      SS_Port = SS_Port1;
+      return( TRUE );
+      }
+
+   if ( SS_TestSoundSource( SS_Port2 ) )
+      {
+      SS_Port = SS_Port2;
+      return( TRUE );
+      }
+
+   if ( SS_TestSoundSource( SS_Port3 ) )
+      {
+      SS_Port = SS_Port3;
+      return( TRUE );
+      }
+
+   return( FALSE );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_Init
+
+   Initializes the Sound Source prepares the module to play digitized
+   sounds.
+---------------------------------------------------------------------*/
+
+int SS_Init
+   (
+   int soundcard
+   )
+
+   {
+   int status;
+
+   if ( SS_Installed )
+      {
+      SS_Shutdown();
+      }
+
+   if ( ( soundcard == TandySoundSource ) ||
+      ( USER_CheckParameter( SELECT_TANDY_SOUNDSOURCE ) ) )
+      {
+      // Tandy
+      SS_OffCommand = 0x0e;
+      }
+   else
+      {
+      // Disney
+      SS_OffCommand = 0x0c;
+      }
+
+   status = SS_DetectSoundSource();
+   if ( !status )
+      {
+      SS_SetErrorCode( SS_NotFound );
+      return( SS_Warning );
+      }
+
+   status = SS_LockMemory();
+   if ( status != SS_Ok )
+      {
+      SS_UnlockMemory();
+      return( status );
+      }
+
+   status = SS_Ok;
+
+   outp( SS_Port + 2, 4 );
+
+   SS_SoundPlaying = FALSE;
+
+   SS_SetCallBack( NULL );
+
+   SS_BufferStart = NULL;
+
+   SS_Installed = TRUE;
+
+   SS_SetErrorCode( status );
+   return( status );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_Shutdown
+
+   Ends transfer of sound data to the Sound Source.
+---------------------------------------------------------------------*/
+
+void SS_Shutdown
+   (
+   void
+   )
+
+   {
+   // Halt the transfer
+   SS_StopPlayback();
+
+   outp( SS_Port + 2, SS_OffCommand );
+
+   SS_SoundPlaying = FALSE;
+
+   SS_BufferStart = NULL;
+
+   SS_SetCallBack( NULL );
+
+   SS_UnlockMemory();
+
+   SS_Installed = FALSE;
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_UnlockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+void SS_UnlockMemory
+   (
+   void
+   )
+
+   {
+   DPMI_UnlockMemoryRegion( SS_LockStart, SS_LockEnd );
+   DPMI_Unlock( SS_Installed );
+   DPMI_Unlock( SS_Port );
+   DPMI_Unlock( SS_OffCommand );
+   DPMI_Unlock( SS_BufferStart );
+   DPMI_Unlock( SS_BufferEnd );
+   DPMI_Unlock( SS_CurrentBuffer );
+   DPMI_Unlock( SS_BufferNum );
+   DPMI_Unlock( SS_NumBuffers );
+   DPMI_Unlock( SS_TotalBufferSize );
+   DPMI_Unlock( SS_TransferLength );
+   DPMI_Unlock( SS_CurrentLength );
+   DPMI_Unlock( SS_SoundPtr );
+   DPMI_Unlock( SS_SoundPlaying );
+   DPMI_Unlock( SS_Timer );
+   DPMI_Unlock( SS_CallBack );
+   DPMI_Unlock( SS_ErrorCode );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: SS_LockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+int SS_LockMemory
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status  = DPMI_LockMemoryRegion( SS_LockStart, SS_LockEnd );
+   status |= DPMI_Lock( SS_Installed );
+   status |= DPMI_Lock( SS_Port );
+   status |= DPMI_Lock( SS_OffCommand );
+   status |= DPMI_Lock( SS_BufferStart );
+   status |= DPMI_Lock( SS_BufferEnd );
+   status |= DPMI_Lock( SS_CurrentBuffer );
+   status |= DPMI_Lock( SS_BufferNum );
+   status |= DPMI_Lock( SS_NumBuffers );
+   status |= DPMI_Lock( SS_TotalBufferSize );
+   status |= DPMI_Lock( SS_TransferLength );
+   status |= DPMI_Lock( SS_CurrentLength );
+   status |= DPMI_Lock( SS_SoundPtr );
+   status |= DPMI_Lock( SS_SoundPlaying );
+   status |= DPMI_Lock( SS_Timer );
+   status |= DPMI_Lock( SS_CallBack );
+   status |= DPMI_Lock( SS_ErrorCode );
+
+   if ( status != DPMI_Ok )
+      {
+      SS_UnlockMemory();
+      SS_SetErrorCode( SS_DPMI_Error );
+      return( SS_Error );
+      }
+
+   return( SS_Ok );
+   }

Added: tags/rott-1.1/rott/audiolib/sndsrc.h
===================================================================
--- tags/rott-1.1/rott/audiolib/sndsrc.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/sndsrc.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,70 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: SNDSRC.H
+
+   author: James R. Dose
+   date:   March 26, 1994
+
+   Public header for for SNDSRC.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __SNDSRC_H
+#define __SNDSRC_H
+
+enum SS_ERRORS
+   {
+   SS_Warning = -2,
+   SS_Error   = -1,
+   SS_Ok      = 0,
+   SS_NotFound,
+   SS_NoSoundPlaying,
+   SS_DPMI_Error
+   };
+
+#define SELECT_SOUNDSOURCE_PORT1 "ss1"
+#define SELECT_SOUNDSOURCE_PORT2 "ss2"
+#define SELECT_SOUNDSOURCE_PORT3 "ss3"
+#define SELECT_TANDY_SOUNDSOURCE "sst"
+
+#define SS_Port1 0x3bc
+#define SS_Port2 0x378
+#define SS_Port3 0x278
+
+#define SS_DefaultPort 0x378
+#define SS_SampleRate  7000
+#define SS_DMAChannel  -1
+
+char *SS_ErrorString( int ErrorNumber );
+void  SS_StopPlayback( void );
+int   SS_GetCurrentPos( void );
+int   SS_BeginBufferedPlayback( char *BufferStart, int BufferSize, int NumDivisions, void ( *CallBackFunc )( void ) );
+int   SS_GetPlaybackRate( void );
+int   SS_SetMixMode( int mode );
+int   SS_SetPort( int port );
+void  SS_SetCallBack( void ( *func )( void ) );
+int   SS_Init( int soundcard );
+void  SS_Shutdown( void );
+void  SS_UnlockMemory( void );
+int   SS_LockMemory( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/standard.h
===================================================================
--- tags/rott-1.1/rott/audiolib/standard.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/standard.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,72 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: STANDARD.H
+
+   author: James R. Dose
+   date:   May 25, 1994
+
+   Header containing standard definitions.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __STANDARD_H
+#define __STANDARD_H
+
+typedef int boolean;
+typedef int errorcode;
+
+#ifndef TRUE
+   #define TRUE ( 1 == 1 )
+   #define FALSE ( !TRUE )
+#endif
+
+enum STANDARD_ERRORS
+   {
+   Warning = -2,
+   FatalError = -1,
+   Success = 0
+   };
+
+#define BITSET( data, bit ) \
+   ( ( ( data ) & ( bit ) ) == ( bit ) )
+
+#define ARRAY_LENGTH( array ) \
+   ( sizeof( array ) / sizeof( ( array )[ 0 ] ) )
+
+#define WITHIN_BOUNDS( array, index ) \
+   ( ( 0 <= ( index ) ) && ( ( index ) < ARRAY_LENGTH( array ) ) )
+
+#define FOREVER    for( ; ; )
+
+#ifdef NDEBUG
+   #define DEBUGGING 0
+#else
+   #define DEBUGGING 1
+#endif
+
+#define DEBUG_CODE \
+   if ( DEBUGGING == 0 ) \
+      { \
+      } \
+   else
+
+#endif

Added: tags/rott-1.1/rott/audiolib/task_man.c
===================================================================
--- tags/rott-1.1/rott/audiolib/task_man.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/task_man.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,976 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: TASK_MAN.C
+
+   author: James R. Dose
+   date:   July 25, 1994
+
+   Low level timer task scheduler.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+//#define USESTACK
+#define LOCKMEMORY
+#define NOINTS
+#define USE_USRHOOKS
+
+#include <stdlib.h>
+#include <dos.h>
+#include <conio.h>
+#include <string.h>
+#include "interrup.h"
+#include "linklist.h"
+#include "task_man.h"
+
+#ifdef USESTACK
+#include "dpmi.h"
+#endif
+#ifdef LOCKMEMORY
+#include "dpmi.h"
+#endif
+
+#ifdef USE_USRHOOKS
+#include "usrhooks.h"
+#define FreeMem( ptr )   USRHOOKS_FreeMem( ( ptr ) )
+#else
+#define FreeMem( ptr )   free( ( ptr ) )
+#endif
+
+typedef struct
+   {
+   task *start;
+   task *end;
+   } tasklist;
+
+
+/*---------------------------------------------------------------------
+   Global variables
+---------------------------------------------------------------------*/
+
+#ifdef USESTACK
+
+// adequate stack size
+#define kStackSize 2048
+
+static unsigned short StackSelector = NULL;
+static unsigned long  StackPointer;
+
+static unsigned short oldStackSelector;
+static unsigned long  oldStackPointer;
+
+#endif
+
+static task HeadTask;
+static task *TaskList = &HeadTask;
+
+static void ( __interrupt __far *OldInt8 )( void );
+
+static volatile long TaskServiceRate  = 0x10000L;
+static volatile long TaskServiceCount = 0;
+
+#ifndef NOINTS
+static volatile int  TS_TimesInInterrupt;
+#endif
+
+static char TS_Installed = FALSE;
+
+volatile int TS_InInterrupt = FALSE;
+
+/*---------------------------------------------------------------------
+   Function prototypes
+---------------------------------------------------------------------*/
+
+static void TS_FreeTaskList( void );
+static void TS_SetClockSpeed( long speed );
+static long TS_SetTimer( long TickBase );
+static void TS_SetTimerToMaxTaskRate( void );
+static void __interrupt __far TS_ServiceSchedule( void );
+static void __interrupt __far TS_ServiceScheduleIntEnabled( void );
+static void TS_AddTask( task *ptr );
+static int  TS_Startup( void );
+static void RestoreRealTimeClock( void );
+
+// These declarations are necessary to use the inline assembly pragmas.
+
+extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
+extern void SetStack(unsigned short selector,unsigned long stackptr);
+
+// This function will get the current stack selector and pointer and save
+// them off.
+#pragma aux GetStack =	\
+	"mov  [edi],esp"		\
+	"mov	ax,ss"	 		\
+	"mov  [esi],ax" 		\
+	parm [esi] [edi]		\
+	modify [eax esi edi];
+
+// This function will set the stack selector and pointer to the specified
+// values.
+#pragma aux SetStack =	\
+	"mov  ss,ax"			\
+	"mov  esp,edx"			\
+	parm [ax] [edx]		\
+	modify [eax edx];
+
+
+/**********************************************************************
+
+   Memory locked functions:
+
+**********************************************************************/
+
+
+#define TS_LockStart TS_FreeTaskList
+
+
+/*---------------------------------------------------------------------
+   Function: TS_FreeTaskList
+
+   Terminates all tasks and releases any memory used for control
+   structures.
+---------------------------------------------------------------------*/
+
+static void TS_FreeTaskList
+   (
+   void
+   )
+
+   {
+   task *node;
+   task *next;
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   node = TaskList->next;
+   while( node != TaskList )
+      {
+      next = node->next;
+      FreeMem( node );
+      node = next;
+      }
+
+   TaskList->next = TaskList;
+   TaskList->prev = TaskList;
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_SetClockSpeed
+
+   Sets the rate of the 8253 timer.
+---------------------------------------------------------------------*/
+
+static void TS_SetClockSpeed
+   (
+   long speed
+   )
+
+   {
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   if ( ( speed > 0 ) && ( speed < 0x10000L ) )
+      {
+      TaskServiceRate = speed;
+      }
+   else
+      {
+      TaskServiceRate = 0x10000L;
+      }
+
+   outp( 0x43, 0x36 );
+   outp( 0x40, TaskServiceRate );
+   outp( 0x40, TaskServiceRate >> 8 );
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_SetTimer
+
+   Calculates the rate at which a task will occur and sets the clock
+   speed if necessary.
+---------------------------------------------------------------------*/
+
+static long TS_SetTimer
+   (
+   long TickBase
+   )
+
+   {
+   long speed;
+
+   speed = 1192030L / TickBase;
+   if ( speed < TaskServiceRate )
+      {
+      TS_SetClockSpeed( speed );
+      }
+
+   return( speed );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_SetTimerToMaxTaskRate
+
+   Finds the fastest running task and sets the clock to operate at
+   that speed.
+---------------------------------------------------------------------*/
+
+static void TS_SetTimerToMaxTaskRate
+   (
+   void
+   )
+
+   {
+   task     *ptr;
+   long      MaxServiceRate;
+   unsigned  flags;
+
+   flags = DisableInterrupts();
+
+   MaxServiceRate = 0x10000L;
+
+   ptr = TaskList->next;
+   while( ptr != TaskList )
+      {
+      if ( ptr->rate < MaxServiceRate )
+         {
+         MaxServiceRate = ptr->rate;
+         }
+
+      ptr = ptr->next;
+      }
+
+   if ( TaskServiceRate != MaxServiceRate )
+      {
+      TS_SetClockSpeed( MaxServiceRate );
+      }
+
+   RestoreInterrupts( flags );
+   }
+
+
+#ifdef NOINTS
+/*---------------------------------------------------------------------
+   Function: TS_ServiceSchedule
+
+   Interrupt service routine
+---------------------------------------------------------------------*/
+
+static void __interrupt __far TS_ServiceSchedule
+   (
+   void
+   )
+
+   {
+   task *ptr;
+   task *next;
+
+
+   TS_InInterrupt = TRUE;
+
+   #ifdef USESTACK
+   // save stack
+   GetStack( &oldStackSelector, &oldStackPointer );
+
+   // set our stack
+   SetStack( StackSelector, StackPointer );
+   #endif
+
+   ptr = TaskList->next;
+   while( ptr != TaskList )
+      {
+      next = ptr->next;
+
+      if ( ptr->active )
+         {
+         ptr->count += TaskServiceRate;
+//JIM
+//         if ( ptr->count >= ptr->rate )
+         while( ptr->count >= ptr->rate )
+            {
+            ptr->count -= ptr->rate;
+            ptr->TaskService( ptr );
+            }
+         }
+      ptr = next;
+      }
+
+   #ifdef USESTACK
+   // restore stack
+   SetStack( oldStackSelector, oldStackPointer );
+   #endif
+
+   TaskServiceCount += TaskServiceRate;
+   if ( TaskServiceCount > 0xffffL )
+      {
+      TaskServiceCount &= 0xffff;
+      _chain_intr( OldInt8 );
+      }
+
+   outp( 0x20,0x20 );
+
+   TS_InInterrupt = FALSE;
+   }
+
+#else
+
+/*---------------------------------------------------------------------
+   Function: TS_ServiceScheduleIntEnabled
+
+   Interrupt service routine with interrupts enabled.
+---------------------------------------------------------------------*/
+
+static void __interrupt __far TS_ServiceScheduleIntEnabled
+   (
+   void
+   )
+
+   {
+   task *ptr;
+   task *next;
+
+   TS_TimesInInterrupt++;
+   TaskServiceCount += TaskServiceRate;
+   if ( TaskServiceCount > 0xffffL )
+      {
+      TaskServiceCount &= 0xffff;
+      _chain_intr( OldInt8 );
+      }
+
+   outp( 0x20,0x20 );
+
+   if ( TS_InInterrupt )
+      {
+      return;
+      }
+
+   TS_InInterrupt = TRUE;
+   _enable();
+
+   #ifdef USESTACK
+   // save stack
+   GetStack( &oldStackSelector, &oldStackPointer );
+
+   // set our stack
+   SetStack( StackSelector, StackPointer );
+   #endif
+
+   while( TS_TimesInInterrupt )
+      {
+      ptr = TaskList->next ;
+      while( ptr != TaskList )
+         {
+         next = ptr->next;
+
+         if ( ptr->active )
+            {
+            ptr->count += TaskServiceRate;
+            if ( ptr->count >= ptr->rate )
+               {
+               ptr->count -= ptr->rate;
+               ptr->TaskService( ptr );
+               }
+            }
+         ptr = next;
+         }
+      TS_TimesInInterrupt--;
+      }
+
+   _disable();
+
+   #ifdef USESTACK
+   // restore stack
+   SetStack( oldStackSelector, oldStackPointer );
+   #endif
+
+   TS_InInterrupt = FALSE;
+   }
+#endif
+
+
+#ifdef USESTACK
+
+/*---------------------------------------------------------------------
+   Function: allocateTimerStack
+
+   Allocate a block of memory from conventional (low) memory and return
+   the selector (which can go directly into a segment register) of the
+   memory block or 0 if an error occured.
+---------------------------------------------------------------------*/
+
+static unsigned short allocateTimerStack
+   (
+   unsigned short size
+   )
+
+   {
+   union REGS regs;
+
+   // clear all registers
+   memset( &regs, 0, sizeof( regs ) );
+
+   // DPMI allocate conventional memory
+   regs.w.ax = 0x100;
+
+   // size in paragraphs
+   regs.w.bx = ( size + 15 ) / 16;
+
+   int386( 0x31, &regs, &regs );
+   if (!regs.w.cflag)
+      {
+      // DPMI call returns selector in dx
+      // (ax contains real mode segment
+      // which is ignored here)
+
+      return( regs.w.dx );
+      }
+
+   // Couldn't allocate memory.
+   return( NULL );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: deallocateTimerStack
+
+   Deallocate a block of conventional (low) memory given a selector to
+   it.  Assumes the block was allocated with DPMI function 0x100.
+---------------------------------------------------------------------*/
+
+static void deallocateTimerStack
+   (
+   unsigned short selector
+   )
+
+   {
+	union REGS regs;
+
+	if ( selector != NULL )
+      {
+      // clear all registers
+      memset( &regs, 0, sizeof( regs ) );
+
+      regs.w.ax = 0x101;
+      regs.w.dx = selector;
+      int386( 0x31, &regs, &regs );
+      }
+   }
+
+#endif
+
+/*---------------------------------------------------------------------
+   Function: TS_Startup
+
+   Sets up the task service routine.
+---------------------------------------------------------------------*/
+
+static int TS_Startup
+   (
+   void
+   )
+
+   {
+   if ( !TS_Installed )
+      {
+#ifdef LOCKMEMORY
+
+      int status;
+
+      status = TS_LockMemory();
+      if ( status != TASK_Ok )
+         {
+         TS_UnlockMemory();
+         return( status );
+         }
+
+#endif
+
+#ifdef USESTACK
+
+	   StackSelector = allocateTimerStack( kStackSize );
+      if ( StackSelector == NULL )
+         {
+
+#ifdef LOCKMEMORY
+
+         TS_UnlockMemory();
+
+#endif
+         return( TASK_Error );
+         }
+
+      // Leave a little room at top of stack just for the hell of it...
+      StackPointer = kStackSize - sizeof( long );
+
+#endif
+
+//static const task *TaskList = &HeadTask;
+      TaskList->next = TaskList;
+      TaskList->prev = TaskList;
+
+      TaskServiceRate  = 0x10000L;
+      TaskServiceCount = 0;
+
+#ifndef NOINTS
+      TS_TimesInInterrupt = 0;
+#endif
+
+      OldInt8 = _dos_getvect( 0x08 );
+      #ifdef NOINTS
+         _dos_setvect( 0x08, TS_ServiceSchedule );
+      #else
+         _dos_setvect( 0x08, TS_ServiceScheduleIntEnabled );
+      #endif
+
+      TS_Installed = TRUE;
+      }
+
+   return( TASK_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_Shutdown
+
+   Ends processing of all tasks.
+---------------------------------------------------------------------*/
+
+void TS_Shutdown
+   (
+   void
+   )
+
+   {
+   if ( TS_Installed )
+      {
+      TS_FreeTaskList();
+
+      TS_SetClockSpeed( 0 );
+
+      _dos_setvect( 0x08, OldInt8 );
+
+#ifdef USESTACK
+
+      deallocateTimerStack( StackSelector );
+      StackSelector = NULL;
+
+#endif
+
+      // Set Date and Time from CMOS
+//      RestoreRealTimeClock();
+
+#ifdef LOCKMEMORY
+
+      TS_UnlockMemory();
+
+#endif
+      TS_Installed = FALSE;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_ScheduleTask
+
+   Schedules a new task for processing.
+---------------------------------------------------------------------*/
+
+task *TS_ScheduleTask
+   (
+   void  ( *Function )( task * ),
+   int   rate,
+   int   priority,
+   void *data
+   )
+
+   {
+   task *ptr;
+
+#ifdef USE_USRHOOKS
+   int   status;
+
+   ptr = NULL;
+
+   status = USRHOOKS_GetMem( &ptr, sizeof( task ) );
+   if ( status == USRHOOKS_Ok )
+#else
+   ptr = malloc( sizeof( task ) );
+   if ( ptr != NULL )
+#endif
+      {
+      if ( !TS_Installed )
+         {
+         status = TS_Startup();
+         if ( status != TASK_Ok )
+            {
+            FreeMem( ptr );
+            return( NULL );
+            }
+         }
+
+      ptr->TaskService = Function;
+      ptr->data = data;
+      ptr->rate = TS_SetTimer( rate );
+      ptr->count = 0;
+      ptr->priority = priority;
+      ptr->active = FALSE;
+
+      TS_AddTask( ptr );
+      }
+
+   return( ptr );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_AddTask
+
+   Adds a new task to our list of tasks.
+---------------------------------------------------------------------*/
+
+static void TS_AddTask
+   (
+   task *node
+   )
+
+   {
+   LL_SortedInsertion( TaskList, node, next, prev, task, priority );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_Terminate
+
+   Ends processing of a specific task.
+---------------------------------------------------------------------*/
+
+int TS_Terminate
+   (
+   task *NodeToRemove
+   )
+
+   {
+   task *ptr;
+   task *next;
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   ptr = TaskList->next;
+   while( ptr != TaskList )
+      {
+      next = ptr->next;
+
+      if ( ptr == NodeToRemove )
+         {
+         LL_RemoveNode( NodeToRemove, next, prev );
+         NodeToRemove->next = NULL;
+         NodeToRemove->prev = NULL;
+         FreeMem( NodeToRemove );
+
+         TS_SetTimerToMaxTaskRate();
+
+         RestoreInterrupts( flags );
+
+         return( TASK_Ok );
+         }
+
+      ptr = next;
+      }
+
+   RestoreInterrupts( flags );
+
+   return( TASK_Warning );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_Dispatch
+
+   Begins processing of all inactive tasks.
+---------------------------------------------------------------------*/
+
+void TS_Dispatch
+   (
+   void
+   )
+
+   {
+   task *ptr;
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   ptr = TaskList->next;
+   while( ptr != TaskList )
+      {
+      ptr->active = TRUE;
+      ptr = ptr->next;
+      }
+
+   RestoreInterrupts( flags );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_SetTaskRate
+
+   Sets the rate at which the specified task is serviced.
+---------------------------------------------------------------------*/
+
+void TS_SetTaskRate
+   (
+   task *Task,
+   int rate
+   )
+
+   {
+   unsigned flags;
+
+   flags = DisableInterrupts();
+
+   Task->rate = TS_SetTimer( rate );
+   TS_SetTimerToMaxTaskRate();
+
+   RestoreInterrupts( flags );
+   }
+
+
+#ifdef LOCKMEMORY
+
+/*---------------------------------------------------------------------
+   Function: TS_LockEnd
+
+   Used for determining the length of the functions to lock in memory.
+---------------------------------------------------------------------*/
+
+static void TS_LockEnd
+   (
+   void
+   )
+
+   {
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_UnlockMemory
+
+   Unlocks all neccessary data.
+---------------------------------------------------------------------*/
+
+void TS_UnlockMemory
+   (
+   void
+   )
+
+   {
+   DPMI_UnlockMemoryRegion( TS_LockStart, TS_LockEnd );
+   DPMI_Unlock( TaskList );
+   DPMI_Unlock( OldInt8 );
+   DPMI_Unlock( TaskServiceRate );
+   DPMI_Unlock( TaskServiceCount );
+   DPMI_Unlock( TS_Installed );
+
+#ifndef NOINTS
+   DPMI_Unlock( TS_TimesInInterrupt );
+#endif
+
+#ifdef USESTACK
+   DPMI_Unlock( StackSelector );
+   DPMI_Unlock( StackPointer );
+   DPMI_Unlock( oldStackSelector );
+   DPMI_Unlock( oldStackPointer );
+#endif
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: TS_LockMemory
+
+   Locks all neccessary data.
+---------------------------------------------------------------------*/
+
+int TS_LockMemory
+   (
+   void
+   )
+
+   {
+   int status;
+
+   status  = DPMI_LockMemoryRegion( TS_LockStart, TS_LockEnd );
+   status |= DPMI_Lock( TaskList );
+   status |= DPMI_Lock( OldInt8 );
+   status |= DPMI_Lock( TaskServiceRate );
+   status |= DPMI_Lock( TaskServiceCount );
+   status |= DPMI_Lock( TS_Installed );
+
+#ifndef NOINTS
+   status |= DPMI_Lock( TS_TimesInInterrupt );
+#endif
+
+#ifdef USESTACK
+   status |= DPMI_Lock( StackSelector );
+   status |= DPMI_Lock( StackPointer );
+   status |= DPMI_Lock( oldStackSelector );
+   status |= DPMI_Lock( oldStackPointer );
+#endif
+
+   if ( status != DPMI_Ok )
+      {
+      TS_UnlockMemory();
+      return( TASK_Error );
+      }
+
+   return( TASK_Ok );
+   }
+
+#endif
+
+/*
+// Converts a hex byte to an integer
+
+static int btoi
+   (
+   unsigned char bcd
+   )
+
+   {
+   unsigned b;
+   unsigned c;
+   unsigned d;
+
+   b = bcd / 16;
+   c = bcd - b * 16;
+   d = b * 10 + c;
+   return( d );
+   }
+
+
+static void RestoreRealTimeClock
+   (
+   void
+   )
+
+   {
+   int read;
+   int i;
+   int hr;
+   int min;
+   int sec;
+   int cent;
+   int yr;
+   int mo;
+   int day;
+   int year;
+   union REGS inregs;
+
+   // Read Real Time Clock Time.
+   read = FALSE;
+	inregs.h.ah = 0x02;
+   for( i = 1; i <= 3; i++ )
+      {
+      int386( 0x1A, &inregs, &inregs );
+      if ( inregs.x.cflag == 0 )
+         {
+         read = TRUE;
+         }
+      }
+
+   if ( read )
+      {
+      //and convert BCD to integer format
+      hr  = btoi( inregs.h.ch );
+      min = btoi( inregs.h.cl );
+      sec = btoi( inregs.h.dh );
+
+      // Read Real Time Clock Date.
+      inregs.h.ah = 0x04;
+      int386( 0x1A, &inregs, &inregs );
+      if ( inregs.x.cflag == 0 )
+         {
+         //and convert BCD to integer format
+         cent = btoi( inregs.h.ch );
+         yr   = btoi( inregs.h.cl );
+         mo   = btoi( inregs.h.dh );
+         day  = btoi( inregs.h.dl );
+         year = cent * 100 + yr;
+
+         // Set System Time.
+         inregs.h.ch = hr;
+         inregs.h.cl = min;
+         inregs.h.dh = sec;
+         inregs.h.dl = 0;
+         inregs.h.ah = 0x2D;
+         int386( 0x21, &inregs, &inregs );
+
+         // Set System Date.
+         inregs.w.cx = year;
+         inregs.h.dh = mo;
+         inregs.h.dl = day;
+         inregs.h.ah = 0x2B;
+         int386( 0x21, &inregs, &inregs );
+         }
+      }
+   }
+*/
+/*
+   struct dostime_t time;
+   struct dosdate_t date;
+
+   outp(0x70,0);
+   time.second=inp(0x71);
+   outp(0x70,2);
+   time.minute=inp(0x71);
+   outp(0x70,4);
+   time.hour=inp(0x71);
+
+   outp(0x70,7);
+   date.day=inp(0x71);
+   outp(0x70,8);
+   date.month=inp(0x71);
+   outp(0x70,9);
+   date.year=inp(0x71);
+
+   time.second=(time.second&0x0f)+((time.second>>4)*10);
+   time.minute=(time.minute&0x0f)+((time.minute>>4)*10);
+   time.hour=(time.hour&0x0f)+((time.hour>>4)*10);
+
+   date.day=(date.day&0x0f)+((date.day>>4)*10);
+   date.month=(date.month&0x0f)+((date.month>>4)*10);
+   date.year=(date.year&0x0f)+((date.year>>4)*10);
+
+   _dos_settime(&time);
+   _dos_setdate(&date);
+
+*/

Added: tags/rott-1.1/rott/audiolib/task_man.h
===================================================================
--- tags/rott-1.1/rott/audiolib/task_man.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/task_man.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,68 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: TASK_MAN.C
+
+   author: James R. Dose
+   date:   July 25, 1994
+
+   Public header for TASK_MAN.C, a low level timer task scheduler.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __TASK_MAN_H
+#define __TASK_MAN_H
+
+enum TASK_ERRORS
+   {
+   TASK_Warning = -2,
+   TASK_Error = -1,
+   TASK_Ok = 0
+   };
+
+typedef struct task
+{
+    struct   task *next;
+    struct   task *prev;
+    void          ( *TaskService )( struct task * );
+    void          *data;
+    long          rate;
+    volatile long count;
+    int           priority;
+    int           active;
+} task;
+
+// TS_InInterrupt is TRUE during a taskman interrupt.
+// Use this if you have code that may be used both outside
+// and within interrupts.
+
+extern volatile int TS_InInterrupt;
+
+void    TS_Shutdown( void );
+task    *TS_ScheduleTask( void ( *Function )( task * ), int rate,
+                          int priority, void *data );
+int     TS_Terminate( task *ptr );
+void    TS_Dispatch( void );
+void    TS_SetTaskRate( task *Task, int rate );
+void    TS_UnlockMemory( void );
+int     TS_LockMemory( void );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/user.c
===================================================================
--- tags/rott-1.1/rott/audiolib/user.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/user.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,133 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: USER.C
+
+   author: James R. Dose
+   date:   April 26, 1994
+
+   Routines to parse command line options.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifdef PLAT_DOS
+#include <dos.h>
+#endif
+
+#include <string.h>
+#include "user.h"
+
+#define TRUE  ( 1 == 1 )
+#define FALSE ( !TRUE )
+
+#ifdef PLAT_DOS
+extern int   _argc;
+extern char **_argv;
+#endif
+
+/*---------------------------------------------------------------------
+   Function: USER_CheckParameter
+
+   Checks if the specified string is present in the command line.
+---------------------------------------------------------------------*/
+
+int USER_CheckParameter
+   (
+   const char *parameter
+   )
+
+   {
+#ifdef PLAT_DOS
+   int i;
+   int found;
+   char *ptr;
+
+   found = FALSE;
+   i = 1;
+   while( i < _argc )
+      {
+      ptr = _argv[ i ];
+
+      // Only check parameters preceded by - or /
+      if ( ( *ptr == '-' ) || ( *ptr == '/' ) )
+         {
+         ptr++;
+         if ( stricmp( parameter, ptr ) == 0 )
+            {
+            found = TRUE;
+            break;
+            }
+         }
+
+      i++;
+      }
+
+   return( found );
+#else
+   return FALSE;
+#endif
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: USER_GetText
+
+   Checks if the specified string is present in the command line
+   and returns a pointer to the text following it.
+---------------------------------------------------------------------*/
+
+char *USER_GetText
+   (
+   const char *parameter
+   )
+
+   {
+#ifdef PLAT_DOS
+   int i;
+   char *text;
+   char *ptr;
+
+   text = NULL;
+   i = 1;
+   while( i < _argc )
+      {
+      ptr = _argv[ i ];
+
+      // Only check parameters preceded by - or /
+      if ( ( *ptr == '-' ) || ( *ptr == '/' ) )
+         {
+         ptr++;
+         if ( stricmp( parameter, ptr ) == 0 )
+            {
+            i++;
+            text = _argv[ i ];
+            break;
+            }
+         }
+
+      i++;
+      }
+
+   return( text );
+#else
+   return NULL;
+#endif
+   }

Added: tags/rott-1.1/rott/audiolib/user.h
===================================================================
--- tags/rott-1.1/rott/audiolib/user.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/user.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: USER.H
+
+   author: James R. Dose
+   phone:  (214)-271-1365 Ext #221
+   date:   April 26, 1994
+
+   Public header for USER.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __USER_H
+#define __USER_H
+
+int   USER_CheckParameter( const char *parameter );
+char *USER_GetText( const char *parameter );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/usrhooks.c
===================================================================
--- tags/rott-1.1/rott/audiolib/usrhooks.c	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/usrhooks.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,84 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: USRHOOKS.C
+
+   author: James R. Dose
+   date:   July 26, 1994
+
+   This module contains cover functions for operations the library
+   needs that may be restricted by the calling program.  This code
+   is left public for you to modify.
+**********************************************************************/
+
+#include <stdlib.h>
+#include "usrhooks.h"
+
+
+/*---------------------------------------------------------------------
+   Function: USRHOOKS_GetMem
+
+   Allocates the requested amount of memory and returns a pointer to
+   its location, or NULL if an error occurs.  NOTE: pointer is assumed
+   to be dword aligned.
+---------------------------------------------------------------------*/
+
+int USRHOOKS_GetMem
+   (
+   void **ptr,
+   unsigned long size
+   )
+
+   {
+   void *memory;
+
+   memory = malloc( size );
+   if ( memory == NULL )
+      {
+      return( USRHOOKS_Error );
+      }
+
+   *ptr = memory;
+
+   return( USRHOOKS_Ok );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: USRHOOKS_FreeMem
+
+   Deallocates the memory associated with the specified pointer.
+---------------------------------------------------------------------*/
+
+int USRHOOKS_FreeMem
+   (
+   void *ptr
+   )
+
+   {
+   if ( ptr == NULL )
+      {
+      return( USRHOOKS_Error );
+      }
+
+   free( ptr );
+
+   return( USRHOOKS_Ok );
+   }

Added: tags/rott-1.1/rott/audiolib/usrhooks.h
===================================================================
--- tags/rott-1.1/rott/audiolib/usrhooks.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/usrhooks.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,55 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: USRHOOKS.H
+
+   author: James R. Dose
+   date:   July 26, 1994
+
+   Public header file for USRHOOKS.C.
+
+   This module contains cover functions for operations the library
+   needs that may be restricted by the calling program.  The function
+   prototypes in this header should not be modified.
+**********************************************************************/
+
+#ifndef __USRHOOKS_H
+#define __USRHOOKS_H
+
+/*---------------------------------------------------------------------
+   Error definitions
+---------------------------------------------------------------------*/
+
+enum USRHOOKS_Errors
+   {
+   USRHOOKS_Warning = -2,
+   USRHOOKS_Error   = -1,
+   USRHOOKS_Ok      = 0
+   };
+
+
+/*---------------------------------------------------------------------
+   Function Prototypes
+---------------------------------------------------------------------*/
+
+int USRHOOKS_GetMem( void **ptr, unsigned long size );
+int USRHOOKS_FreeMem( void *ptr );
+
+#endif

Added: tags/rott-1.1/rott/audiolib/util.h
===================================================================
--- tags/rott-1.1/rott/audiolib/util.h	                        (rev 0)
+++ tags/rott-1.1/rott/audiolib/util.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,13 @@
+#ifndef AUDIOLIB__UTIL_H
+#define AUDIOLIB__UTIL_H
+
+#ifndef min
+#define min(a, b)  ((a) < (b) ? (a) : (b))
+#endif
+
+#ifndef max
+#define max(a, b)  ((a) > (b) ? (a) : (b))
+#endif
+
+#endif
+

Added: tags/rott-1.1/rott/byteordr.c
===================================================================
--- tags/rott-1.1/rott/byteordr.c	                        (rev 0)
+++ tags/rott-1.1/rott/byteordr.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,84 @@
+/*
+Copyright (C) 2002 John R. Hall
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    byteordr.c - Byte order conversion routines.
+//
+//***************************************************************************
+
+#include "rt_def.h"
+#include "rt_util.h"
+#include "byteordr.h"
+#include "lumpy.h"
+
+#define DEFINE_CONVERTER(type)            \
+void Cvt_##type(void *lmp, int num)       \
+{                                         \
+    int i;                                \
+    type *recs = (type *)lmp;             \
+    for (i = 0; i < num; i++, recs++) {   \
+        CONVERT_ENDIAN_##type(recs);      \
+    }                                     \
+}
+
+DEFINE_CONVERTER(pic_t);
+DEFINE_CONVERTER(lpic_t);
+DEFINE_CONVERTER(font_t);
+DEFINE_CONVERTER(lbm_t);
+DEFINE_CONVERTER(patch_t);
+DEFINE_CONVERTER(transpatch_t);
+DEFINE_CONVERTER(cfont_t);
+
+
+void CvtNull(void *lmp, int num)
+{
+    Debug("No-op endian converter on %p.\n", lmp);
+}
+
+// Returns converter for the designated type
+converter_t CvtForType(int type)
+{
+  switch(type) {
+    case cache_pic_t:
+      return Cvt_pic_t;
+      break;
+    case cache_lpic_t:
+      return Cvt_lpic_t;
+      break;
+    case cache_font_t:
+      return Cvt_font_t;
+      break;
+    case cache_lbm_t:
+      return Cvt_lbm_t;
+      break;
+    case cache_patch_t:
+      return Cvt_patch_t;
+      break;
+    case cache_transpatch_t:
+      return Cvt_transpatch_t;
+      break;
+    case cache_cfont_t:
+      return Cvt_cfont_t;
+      break;
+    default:
+      return CvtNull;
+      break;
+  }
+}

Added: tags/rott-1.1/rott/byteordr.h
===================================================================
--- tags/rott-1.1/rott/byteordr.h	                        (rev 0)
+++ tags/rott-1.1/rott/byteordr.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 2002 John R. Hall
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    byteordr.c - Byte order conversion routines.
+//
+//***************************************************************************
+
+#ifndef BYTEORDER_H
+#define BYTEORDER_H
+
+typedef void (*converter_t)(void *, int);
+
+#define DECLARE_CONVERTER(type) void Cvt_##type(void *lmp, int num);
+
+DECLARE_CONVERTER(pic_t);
+DECLARE_CONVERTER(lpic_t);
+DECLARE_CONVERTER(font_t);
+DECLARE_CONVERTER(lbm_t);
+DECLARE_CONVERTER(patch_t);
+DECLARE_CONVERTER(transpatch_t);
+DECLARE_CONVERTER(cfont_t);
+void CvtNull(void *lmp, int num);
+converter_t CvtForType(int type);
+
+#endif

Added: tags/rott-1.1/rott/cin_actr.c
===================================================================
--- tags/rott-1.1/rott/cin_actr.c	                        (rev 0)
+++ tags/rott-1.1/rott/cin_actr.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,305 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#include "cin_glob.h"
+#include "cin_def.h"
+#include "cin_actr.h"
+#include "cin_efct.h"
+#include "modexlib.h"
+//MED
+#include "memcheck.h"
+
+actortype * firstcinematicactor;
+actortype * lastcinematicactor;
+
+
+// LOCALS
+
+boolean cinematicactorsystemstarted=false;
+static int numcinematicactors;
+
+/*
+===============
+=
+= AddCinematicActor
+=
+===============
+*/
+
+void AddCinematicActor ( actortype * actor )
+{
+   if (!firstcinematicactor)
+      {
+      firstcinematicactor  = actor;
+      }
+   else
+      {
+      actor->prev = lastcinematicactor;
+      lastcinematicactor->next = actor;
+      }
+   lastcinematicactor = actor;
+}
+
+
+/*
+===============
+=
+= DeleteCinematicActor
+=
+===============
+*/
+
+void DeleteCinematicActor ( actortype * actor)
+{
+   if (actor == lastcinematicactor)
+      {
+      lastcinematicactor = actor->prev;
+      }
+   else
+      {
+      actor->next->prev = actor->prev;
+      }
+
+   if (actor == firstcinematicactor)
+      {
+      firstcinematicactor = actor->next;
+      }
+   else
+      {
+      actor->prev->next = actor->next;
+      }
+
+   actor->prev = NULL;
+   actor->next = NULL;
+
+   if (actor->effect != NULL)
+      SafeFree(actor->effect);
+   SafeFree(actor);
+}
+
+/*
+===============
+=
+= GetNewCinematicActor
+=
+===============
+*/
+
+actortype * GetNewCinematicActor ( void )
+{
+   actortype * actor;
+
+   numcinematicactors++;
+
+   if ( numcinematicactors > MAXCINEMATICACTORS )
+      Error ("Too many Cinematic actors\n");
+
+   actor = SafeMalloc( sizeof (actortype) );
+
+   actor->next=NULL;
+   actor->prev=NULL;
+
+   AddCinematicActor ( actor );
+
+   return actor;
+}
+
+/*
+===============
+=
+= StartupCinematicActors
+=
+===============
+*/
+
+void StartupCinematicActors ( void )
+{
+   if (cinematicactorsystemstarted==true)
+      return;
+   cinematicactorsystemstarted=true;
+   firstcinematicactor = NULL;
+   lastcinematicactor  = NULL;
+
+   numcinematicactors=0;
+}
+
+/*
+===============
+=
+= ShutdownCinematicActors
+=
+===============
+*/
+
+void ShutdownCinematicActors ( void )
+{
+   actortype * actor;
+   if (cinematicactorsystemstarted==false)
+      return;
+   cinematicactorsystemstarted=false;
+
+   actor=firstcinematicactor;
+   while (actor != NULL)
+      {
+      actortype * nextactor;
+
+      nextactor=actor->next;
+      DeleteCinematicActor(actor);
+      actor=nextactor;
+      }
+}
+
+/*
+===============
+=
+= SpawnCinematicActor
+=
+===============
+*/
+
+void SpawnCinematicActor ( enum_eventtype type, void * effect )
+{
+   actortype * actor;
+
+   actor = GetNewCinematicActor ();
+   actor->effecttype=type;
+   actor->effect=effect;
+}
+
+/*
+===============
+=
+= UpdateCinematicActors
+=
+===============
+*/
+void UpdateCinematicActors ( void )
+{
+   actortype * actor;
+
+   for (actor=firstcinematicactor;actor != NULL;)
+      {
+      if (UpdateCinematicEffect ( actor->effecttype, actor->effect ) == false)
+         {
+         actortype * nextactor;
+
+         nextactor=actor->next;
+         DeleteCinematicActor(actor);
+         actor=nextactor;
+         }
+      else
+         actor=actor->next;
+      }
+}
+
+/*
+===============
+=
+= DrawCinematicActors
+=
+===============
+*/
+typedef enum {
+        screenfunctions,
+        background,
+        backgroundsprites,
+        backdrop,
+        foregroundsprites,
+        palettefunctions,
+        numdrawphases
+} enum_drawphases;
+
+void DrawCinematicActors ( void )
+{
+   actortype * actor;
+   actortype * nextactor;
+   boolean draw;
+   enum_drawphases sequence;
+#if DUMP
+   int numactors=0;
+#endif
+   boolean flippage=true;
+
+   for (sequence=screenfunctions;sequence<numdrawphases;sequence++)
+      {
+      for (actor=firstcinematicactor;actor != NULL;)
+         {
+         draw=false;
+         switch (actor->effecttype)
+            {
+            case fadeout:
+            case blankscreen:
+            case clearbuffer:
+            case cinematicend:
+            case flic:
+               if (sequence==screenfunctions)
+                  draw=true;
+               flippage=false;
+               break;
+            case palette:
+               if (sequence==palettefunctions)
+                  draw=true;
+               flippage=false;
+               break;
+            case background_noscrolling:
+            case background_scrolling:
+            case background_multi:
+               if (sequence==background)
+                  draw=true;
+               break;
+            case sprite_background:
+               if (sequence==backgroundsprites)
+                  draw=true;
+               break;
+            case backdrop_noscrolling:
+            case backdrop_scrolling:
+               if (sequence==backdrop)
+                  draw=true;
+               break;
+            case sprite_foreground:
+               if (sequence==foregroundsprites)
+                  draw=true;
+               break;
+            }
+         nextactor=actor->next;
+         if (draw==true)
+            {
+#if DUMP
+            printf("drawing type=%ld\n",actor->effecttype);
+#endif
+            if (DrawCinematicEffect ( actor->effecttype, actor->effect ) == false)
+               {
+               DeleteCinematicActor(actor);
+               }
+#if DUMP
+            numactors++;
+#endif
+            }
+         actor=nextactor;
+         }
+      }
+      if (flippage==true)
+         XFlipPage ();
+#if DUMP
+      printf("Total actors drawn=%ld\n",numactors);
+#endif
+}
+
+

Added: tags/rott-1.1/rott/cin_actr.h
===================================================================
--- tags/rott-1.1/rott/cin_actr.h	                        (rev 0)
+++ tags/rott-1.1/rott/cin_actr.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _cin_actr_public
+#define _cin_actr_public
+
+#include "cin_glob.h"
+#include "cin_def.h"
+
+extern actortype * firstcinematicactor;
+extern actortype * lastcinematicactor;
+
+void AddCinematicActor ( actortype * actor );
+void DeleteCinematicActor ( actortype * actor);
+
+actortype * GetNewCinematicActor ( void );
+void StartupCinematicActors ( void );
+void ShutdownCinematicActors ( void );
+void SpawnCinematicActor ( enum_eventtype type, void * effect );
+void DrawCinematicActors ( void );
+void UpdateCinematicActors ( void );
+
+#endif
+

Added: tags/rott-1.1/rott/cin_def.h
===================================================================
--- tags/rott-1.1/rott/cin_def.h	                        (rev 0)
+++ tags/rott-1.1/rott/cin_def.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,104 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _cin_def_public
+#define _cin_def_public
+
+#define MAXCINEMATICEVENTS 100
+#define MAXCINEMATICACTORS 30
+
+#define FRACTIONBITS (16)
+#define FRACTIONUNIT (1<<FRACTIONBITS)
+
+typedef enum {
+        background_noscrolling,
+        background_scrolling,
+        background_multi,
+        sprite_background,
+        sprite_foreground,
+        backdrop_scrolling,
+        backdrop_noscrolling,
+        palette,
+        flic,
+        fadeout,
+        cinematicend,
+        blankscreen,
+        clearbuffer
+} enum_eventtype;
+
+typedef struct eventtype
+   {
+   int time;
+   enum_eventtype effecttype;
+   void * effect;
+   struct eventtype * next;
+   struct eventtype * prev;
+   } eventtype;
+
+typedef struct actortype
+   {
+   enum_eventtype effecttype;
+   void * effect;
+   struct actortype * next;
+   struct actortype * prev;
+   } actortype;
+
+typedef struct
+   {
+   char name[10];
+   boolean loop;
+   boolean usefile;
+   } flicevent;
+
+typedef struct
+   {
+   char name[10];
+   int duration;
+   int frame;
+   int frametime;
+   int numframes;
+   int framedelay;
+   int x;
+   int y;
+   int scale;
+   int dx;
+   int dy;
+   int dscale;
+   } spriteevent;
+
+typedef struct
+   {
+   char name[10];
+   int duration;
+   int backdropwidth;
+   int currentoffset;
+   int dx;
+   int yoffset;
+   int height;
+   byte * data;
+   } backevent;
+
+typedef struct
+   {
+   char name[10];
+   } paletteevent;
+
+
+#endif
+

Added: tags/rott-1.1/rott/cin_efct.c
===================================================================
--- tags/rott-1.1/rott/cin_efct.c	                        (rev 0)
+++ tags/rott-1.1/rott/cin_efct.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,957 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#include "cin_glob.h"
+#include "cin_util.h"
+#include "cin_def.h"
+#include "cin_main.h"
+#include "f_scale.h"
+#include "watcom.h"
+#include "lumpy.h"
+#include "w_wad.h"
+#include "z_zone.h"
+#include <string.h>
+
+#ifdef DOS
+#include <conio.h>
+#endif
+
+#include "modexlib.h"
+#include "fli_glob.h"
+//MED
+#include "memcheck.h"
+
+static int cin_sprtopoffset;
+static int cin_invscale;
+
+void DrawFadeout ( void );
+void DrawBlankScreen ( void );
+void DrawClearBuffer ( void );
+
+/*
+===============
+=
+= SpawnCinematicFlic
+=
+===============
+*/
+
+flicevent * SpawnCinematicFlic ( char * name, boolean loop, boolean usefile )
+{
+   flicevent * flic;
+
+   flic = SafeMalloc ( sizeof(flicevent) );
+
+   // copy name of flic
+
+   strcpy ( flic->name, name );
+
+   flic->loop=loop;
+
+   flic->usefile=usefile;
+
+   return flic;
+}
+
+/*
+===============
+=
+= SpawnCinematicSprite
+=
+===============
+*/
+
+spriteevent * SpawnCinematicSprite ( char * name,
+                                     int duration,
+                                     int numframes,
+                                     int framedelay,
+                                     int x,
+                                     int y,
+                                     int scale,
+                                     int endx,
+                                     int endy,
+                                     int endscale
+                                   )
+{
+   spriteevent * sprite;
+   patch_t *p;
+
+   sprite = SafeMalloc ( sizeof (spriteevent) );
+
+   // copy name of sprite
+
+   strcpy ( sprite->name, name );
+
+   // copy rest of sprite information
+
+   sprite->duration = duration;
+   sprite->numframes = numframes;
+   sprite->framedelay = framedelay;
+   sprite->frame=0;
+   sprite->frametime=framedelay;
+
+   p=(patch_t *)W_CacheLumpNum( W_GetNumForName(sprite->name), PU_CACHE, Cvt_patch_t, 1);
+
+   sprite->x=x << FRACTIONBITS;
+   sprite->y=y << FRACTIONBITS;
+
+//   sprite->y+=(p->width-p->height)<<(FRACTIONBITS-1);
+
+   sprite->scale=scale << FRACTIONBITS;
+   sprite->dx= ( (endx-x) << FRACTIONBITS ) / duration;
+   sprite->dy= ( (endy-y) << FRACTIONBITS ) / duration;
+   sprite->dscale= ( (endscale-scale) << FRACTIONBITS ) / duration;
+
+   return sprite;
+}
+
+/*
+===============
+=
+= SpawnCinematicBack
+=
+===============
+*/
+
+backevent * SpawnCinematicBack ( char * name,
+                                 int duration,
+                                 int width,
+                                 int startx,
+                                 int endx,
+                                 int yoffset
+                               )
+{
+   backevent * back;
+
+   back = SafeMalloc ( sizeof (backevent) );
+
+   // copy name of back
+
+   strcpy ( back->name, name );
+
+   // copy rest of back information
+
+   back->duration = duration;
+   back->backdropwidth = width;
+   back->dx = ((endx-startx) << FRACTIONBITS)/duration;
+   back->currentoffset = startx << FRACTIONBITS;
+   back->yoffset=yoffset;
+
+   return back;
+}
+
+/*
+===============
+=
+= SpawnCinematicMultiBack
+=
+===============
+*/
+
+backevent * SpawnCinematicMultiBack ( char * name,
+                                      char * name2,
+                                      int duration,
+                                      int startx,
+                                      int endx,
+                                      int yoffset
+                                    )
+{
+   backevent * back;
+   lpic_t * pic1;
+   lpic_t * pic2;
+
+   pic1=(lpic_t *)W_CacheLumpName(name,PU_CACHE, Cvt_lpic_t, 1);
+   pic2=(lpic_t *)W_CacheLumpName(name2,PU_CACHE, Cvt_lpic_t, 1);
+
+   back = SafeMalloc ( sizeof (backevent) );
+
+   // copy name of back
+
+   strcpy ( back->name, name );
+
+   // copy rest of back information
+
+   back->duration = duration;
+   back->dx = ((endx-startx) << FRACTIONBITS)/duration;
+   back->currentoffset = startx << FRACTIONBITS;
+   back->yoffset=yoffset;
+   if (pic1->height != pic2->height)
+      {
+      Error("SpawnCinematicMultiBack: heights are not the same\n"
+            "                         name1=%s name2=%s\n",name,name2);
+      }
+   back->backdropwidth=pic1->width+pic2->width;
+   back->height=pic1->height;
+   back->data=SafeMalloc (back->backdropwidth*back->height);
+   memcpy( back->data, &(pic1->data), pic1->width*pic1->height);
+   memcpy( back->data+(pic1->width*pic1->height),
+           &(pic2->data),
+           pic2->width*pic2->height
+         );
+   return back;
+}
+
+/*
+===============
+=
+= SpawnCinematicPalette
+=
+===============
+*/
+
+paletteevent * SpawnCinematicPalette ( char * name )
+{
+   paletteevent * palette;
+
+   palette = SafeMalloc ( sizeof (paletteevent) );
+
+   // copy name of palette
+
+   strcpy ( palette->name, name );
+
+   return palette;
+}
+
+
+/*
+=================
+=
+= ScaleFilmPost
+=
+=================
+*/
+void ScaleFilmPost (byte * src, byte * buf)
+{
+   int  offset;
+   int  length;
+   int  topscreen;
+   int  bottomscreen;
+
+
+   offset=*(src++);
+   for (;offset!=255;)
+      {
+      length=*(src++);
+      topscreen = cin_sprtopoffset + (cin_invscale*offset);
+      bottomscreen = topscreen + (cin_invscale*length);
+      cin_yl = (topscreen+FRACTIONUNIT-1)>>FRACTIONBITS;
+      cin_yh = (bottomscreen-FRACTIONUNIT)>>FRACTIONBITS;
+      if (cin_yh >= iGLOBAL_SCREENHEIGHT)
+         cin_yh = iGLOBAL_SCREENHEIGHT-1;
+      if (cin_yl < 0)
+         cin_yl = 0;
+      if (cin_yl <= cin_yh)
+         {
+         cin_source=src-offset;
+         R_DrawFilmColumn (buf);
+         }
+      src+=length;
+      offset=*(src++);
+      }
+
+}
+
+/*
+=================
+=
+= DrawFlic
+=
+=================
+*/
+void DrawFlic ( flicevent * flic )
+{
+   byte * curpal;
+   byte * buf;
+   char flicname[40];
+
+   curpal = SafeMalloc (768);
+
+   CinematicGetPalette (curpal);
+
+   DrawFadeout ( );
+
+   if (flic->usefile==false)
+      {
+      buf=W_CacheLumpName(flic->name,PU_CACHE, CvtNull, 1);
+      strcpy(flicname,flic->name);
+      }
+   else
+      {
+      strcpy(flicname,flic->name);
+      strcat(flicname,".fli");
+      }
+
+// med
+//   PlayFlic ( flicname, buf, flic->usefile, flic->loop);
+
+   if (flic->loop==true)
+      ClearCinematicAbort();
+
+   DrawFadeout ( );
+
+   DrawBlankScreen ( );
+
+#ifdef DOS
+   VL_SetVGAPlaneMode ();
+#endif
+
+   CinematicSetPalette (curpal);
+
+   SafeFree (curpal);
+   GetCinematicTics ();
+   GetCinematicTics ();
+}
+
+/*
+=================
+=
+= PrecacheFlic
+=
+=================
+*/
+
+void PrecacheFlic (flicevent * flic)
+{
+   if (flic->usefile==false)
+      {
+      W_CacheLumpName(flic->name,PU_CACHE, CvtNull, 1);
+      }
+}
+
+/*
+===============
+=
+= DrawCinematicBackground
+=
+===============
+*/
+
+void DrawCinematicBackground ( backevent * back )
+{
+   byte * src;
+   byte * buf;
+   lpic_t * pic;
+   int i;
+   int plane;
+   int offset;
+   int height;
+
+   pic=(lpic_t *)W_CacheLumpName(back->name,PU_CACHE, Cvt_lpic_t, 1);
+
+   height = pic->height;
+   if (height+back->yoffset>iGLOBAL_SCREENHEIGHT)
+      height=iGLOBAL_SCREENHEIGHT-back->yoffset;
+
+   if (height!=iGLOBAL_SCREENHEIGHT)
+      DrawClearBuffer ();
+
+   plane = 0;
+   
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+      buf=(byte *)bufferofs+ylookup[back->yoffset];
+      offset=(back->currentoffset>>FRACTIONBITS)+plane;
+
+      VGAWRITEMAP(plane);
+
+#ifdef DOS
+      for (i=plane;i<iGLOBAL_SCREENWIDTH;i+=4,offset+=4,buf++)
+#else
+      for (i=0;i<iGLOBAL_SCREENWIDTH;i++,offset++,buf++)
+#endif
+         {
+         if (offset>=back->backdropwidth)
+            src=&(pic->data) + ( (offset - back->backdropwidth) * (pic->height) );
+         else if (offset<0)
+            src=&(pic->data) + ( (offset + back->backdropwidth) * (pic->height) );
+         else
+            src=&(pic->data) + ( offset * (pic->height) );
+         DrawFilmPost(buf,src,height);
+         }
+      }
+}
+
+/*
+===============
+=
+= DrawCinematicMultiBackground
+=
+===============
+*/
+
+void DrawCinematicMultiBackground ( backevent * back )
+{
+   byte * src;
+   byte * buf;
+   int i;
+   int plane;
+   int offset;
+   int height;
+
+   height = back->height;
+   if (height+back->yoffset>iGLOBAL_SCREENHEIGHT)
+      height=iGLOBAL_SCREENHEIGHT-back->yoffset;
+
+   if (height!=iGLOBAL_SCREENHEIGHT)
+      DrawClearBuffer ();
+
+   plane = 0;
+   
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+      buf=(byte *)bufferofs+ylookup[back->yoffset];
+      offset=(back->currentoffset>>FRACTIONBITS)+plane;
+
+      VGAWRITEMAP(plane);
+
+#ifdef DOS
+      for (i=plane;i<iGLOBAL_SCREENWIDTH;i+=4,offset+=4,buf++)
+#else
+      for (i=0;i<iGLOBAL_SCREENWIDTH;i++,offset++,buf++)
+#endif
+         {
+         if (offset>=back->backdropwidth)
+            src=back->data + ( (offset - back->backdropwidth) * (back->height) );
+         else if (offset<0)
+            src=back->data + ( (offset + back->backdropwidth) * (back->height) );
+         else
+            src=back->data + ( offset * (back->height) );
+         DrawFilmPost(buf,src,height);
+         }
+      }
+}
+
+/*
+===============
+=
+= DrawCinematicBackdrop
+=
+===============
+*/
+
+void DrawCinematicBackdrop ( backevent * back )
+{
+   byte * src;
+   byte * shape;
+   byte * buf;
+   patch_t * p;
+   int i;
+   int plane;
+   int offset;
+   int postoffset;
+   int postlength;
+   int toppost;
+
+   shape=W_CacheLumpName(back->name,PU_CACHE, Cvt_patch_t, 1);
+   p=(patch_t *)shape;
+
+   toppost=-p->topoffset+back->yoffset;
+
+   plane = 0;
+
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+      buf=(byte *)bufferofs;
+      offset=(back->currentoffset>>FRACTIONBITS)+plane;
+
+      VGAWRITEMAP(plane);
+
+#ifdef DOS
+      for (i=plane;i<iGLOBAL_SCREENWIDTH;i+=4,offset+=4,buf++)
+#else
+      for (i=0;i<iGLOBAL_SCREENWIDTH;i++,offset++,buf++)
+#endif
+         {
+         if (offset>=back->backdropwidth)
+            src = shape + p->collumnofs[offset - back->backdropwidth];
+         else if (offset<0)
+            src=shape + p->collumnofs[offset + back->backdropwidth];
+         else
+            src = shape + p->collumnofs[offset];
+
+         postoffset=*(src++);
+         for (;postoffset!=255;)
+            {
+            postlength=*(src++);
+            DrawFilmPost(buf + ylookup[toppost+postoffset],src,postlength);
+            src+=postlength;
+            postoffset=*(src++);
+            }
+         }
+      }
+}
+
+/*
+=================
+=
+= PrecacheBack
+=
+=================
+*/
+void PrecacheBack ( backevent * back )
+{
+   W_CacheLumpName( back->name, PU_CACHE, CvtNull, 1);
+}
+
+
+/*
+=================
+=
+= DrawCinematicSprite
+=
+=================
+*/
+void DrawCinematicSprite ( spriteevent * sprite )
+{
+   byte   *shape;
+   int    frac;
+   patch_t *p;
+   int    x1,x2;
+   int    tx;
+   int    xcent;
+   byte * buf;
+   int    height;
+
+   height = sprite->scale >> FRACTIONBITS;
+
+   if (height<2)
+      return;
+
+   shape=W_CacheLumpNum( W_GetNumForName(sprite->name)+sprite->frame, PU_CACHE, Cvt_patch_t, 1);
+   p=(patch_t *)shape;
+   
+
+   cin_ycenter=sprite->y >> FRACTIONBITS;
+   cin_invscale = (height<<FRACTIONBITS)/p->origsize;
+   buf=(byte *)bufferofs;
+   tx=-p->leftoffset;
+   xcent=(sprite->x & 0xffff0000)-(height<<(FRACTIONBITS-1))+(FRACTIONUNIT>>1);
+
+//
+// calculate edges of the shape
+//
+   x1 = (xcent+(tx*cin_invscale))>>FRACTIONBITS;
+   if (x1 >= iGLOBAL_SCREENWIDTH)
+      return;               // off the right side
+   tx+=p->width;
+   x2 = ((xcent+(tx*cin_invscale)) >>FRACTIONBITS) - 1 ;
+   if (x2 < 0)
+      return;         // off the left side
+
+   cin_iscale=(p->origsize<<FRACTIONBITS)/height;
+
+   if (x1<0)
+      {
+      frac=cin_iscale*(-x1);
+      x1=0;
+      }
+   else
+      frac=0;
+   x2 = x2 >= iGLOBAL_SCREENWIDTH ? (iGLOBAL_SCREENWIDTH-1) : x2;
+
+   cin_texturemid = (((p->origsize>>1)+p->topoffset)<<FRACTIONBITS)+(FRACTIONUNIT>>1);
+   cin_sprtopoffset = (cin_ycenter<<16) - FixedMul(cin_texturemid,cin_invscale);
+
+   for (; x1<=x2 ; x1++, frac += cin_iscale)
+     {
+     VGAWRITEMAP(x1&3);
+#ifdef DOS
+     ScaleFilmPost(((p->collumnofs[frac>>FRACTIONBITS])+shape),buf+(x1>>2));
+#else
+     ScaleFilmPost(((p->collumnofs[frac>>FRACTIONBITS])+shape),buf+x1);
+#endif
+     }
+}
+
+/*
+=================
+=
+= PrecacheCinematicSprite
+=
+=================
+*/
+void PrecacheCinematicSprite ( spriteevent * sprite )
+{
+   int i;
+
+   for (i=0;i<sprite->numframes;i++)
+      {
+      W_CacheLumpNum( W_GetNumForName(sprite->name)+i, PU_CACHE, Cvt_patch_t, 1);
+      }
+}
+
+
+/*
+=================
+=
+= DrawPalette
+=
+=================
+*/
+
+void DrawPalette (paletteevent * event)
+{
+   byte * pal;
+
+   pal=W_CacheLumpName(event->name,PU_CACHE, CvtNull, 1);
+   XFlipPage ();
+   CinematicSetPalette (pal);
+}
+
+/*
+=================
+=
+= PrecachePalette
+=
+=================
+*/
+
+void PrecachePalette (paletteevent * event)
+{
+   W_CacheLumpName(event->name,PU_CACHE, CvtNull, 1);
+}
+
+
+/*
+=================
+=
+= DrawFadeout
+=
+=================
+*/
+#define FADEOUTTIME 20
+
+void DrawFadeout ( void )
+{
+   byte origpal[768];
+   byte newpal[768];
+   int      i,j;
+
+   CinematicGetPalette (&origpal[0]);
+   for (j = 0; j < FADEOUTTIME; j++)
+      {
+      for (i = 0; i < 768; i++)
+         {
+         newpal[i] = ( origpal[i] * (FADEOUTTIME - j - 1) ) / FADEOUTTIME;
+         }
+      WaitVBL();
+      CinematicSetPalette (&newpal[0]);
+      CinematicDelay();
+      }
+   VL_ClearVideo (0);
+   GetCinematicTics ();
+   GetCinematicTics ();
+}
+
+/*
+=================
+=
+= DrawBlankScreen
+=
+=================
+*/
+void DrawBlankScreen ( void )
+{
+   VL_ClearVideo (0);
+}
+
+/*
+=================
+=
+= DrawClearBuffer
+=
+=================
+*/
+void DrawClearBuffer ( void )
+{
+#ifdef DOS
+  VGAMAPMASK(15);
+  memset((byte *)bufferofs,0,iGLOBAL_SCREENBWIDE*iGLOBAL_SCREENHEIGHT);
+#else
+  memset((byte *)bufferofs,0,iGLOBAL_SCREENWIDTH*iGLOBAL_SCREENHEIGHT);
+#endif
+}
+
+/*
+===============
+=
+= UpdateCinematicBack
+=
+===============
+*/
+
+boolean UpdateCinematicBack ( backevent * back )
+{
+   back->duration--;
+
+   if (back->duration<0)
+      return false;
+
+   back->currentoffset += back->dx;
+
+   return true;
+}
+
+/*
+=================
+=
+= UpdateCinematicSprite
+=
+=================
+*/
+boolean UpdateCinematicSprite ( spriteevent * sprite )
+{
+   sprite->duration--;
+
+   if (sprite->duration<0)
+      return false;
+
+   sprite->framedelay--;
+
+   if (sprite->framedelay==0)
+      {
+      sprite->frame++;
+      if (sprite->frame==sprite->numframes)
+         sprite->frame=0;
+      sprite->framedelay=sprite->frametime;
+      }
+
+   sprite->x+=sprite->dx;
+   sprite->y+=sprite->dy;
+   sprite->scale+=sprite->dscale;
+
+   return true;
+}
+
+/*
+=================
+=
+= UpdateCinematicEffect
+=
+=================
+*/
+boolean UpdateCinematicEffect ( enum_eventtype type, void * effect )
+{
+   switch (type)
+      {
+      case background_noscrolling:
+      case background_scrolling:
+      case backdrop_scrolling:
+      case backdrop_noscrolling:
+      case background_multi:
+         return UpdateCinematicBack ( (backevent *) effect );
+         break;
+      case sprite_background:
+      case sprite_foreground:
+         return UpdateCinematicSprite ( (spriteevent *) effect );
+         break;
+      case flic:
+         return true;
+         break;
+      case palette:
+      case fadeout:
+      case blankscreen:
+      case clearbuffer:
+         return true;
+         break;
+      case cinematicend:
+         cinematicdone=true;
+         return true;
+         break;
+      }
+   return true;
+}
+/*
+=================
+=
+= DrawCinematicEffect
+=
+=================
+*/
+boolean DrawCinematicEffect ( enum_eventtype type, void * effect )
+{
+   switch (type)
+      {
+      case background_noscrolling:
+      case background_scrolling:
+         DrawCinematicBackground ( (backevent *) effect );
+         return true;
+         break;
+      case background_multi:
+         DrawCinematicMultiBackground ( (backevent *) effect );
+         return true;
+         break;
+      case backdrop_scrolling:
+      case backdrop_noscrolling:
+         DrawCinematicBackdrop ( (backevent *) effect );
+         return true;
+         break;
+      case sprite_background:
+      case sprite_foreground:
+         DrawCinematicSprite ( (spriteevent *) effect );
+         return true;
+         break;
+      case flic:
+         DrawFlic ( (flicevent *) effect );
+         return false;
+         break;
+      case palette:
+         DrawPalette ( (paletteevent *) effect );
+         return false;
+         break;
+      case fadeout:
+         DrawFadeout ();
+         return false;
+         break;
+      case blankscreen:
+         DrawBlankScreen ();
+         return false;
+         break;
+      case clearbuffer:
+         DrawClearBuffer ();
+         return false;
+         break;
+      case cinematicend:
+         return true;
+         break;
+      }
+   return true;
+}
+
+/*
+=================
+=
+= PrecacheCinematicEffect
+=
+=================
+*/
+void PrecacheCinematicEffect ( enum_eventtype type, void * effect )
+{
+   switch (type)
+      {
+      case background_noscrolling:
+      case background_scrolling:
+      case backdrop_scrolling:
+      case backdrop_noscrolling:
+         PrecacheBack ( (backevent *) effect );
+         break;
+      case sprite_background:
+      case sprite_foreground:
+         PrecacheCinematicSprite ( (spriteevent *) effect );
+         break;
+      case palette:
+         PrecachePalette ( (paletteevent *) effect );
+         break;
+      case flic:
+         PrecacheFlic ( (flicevent *) effect );
+         break;
+      default:
+	  ;
+      }
+}
+
+/*
+===============
+=
+= ProfileDisplay
+=
+===============
+*/
+
+void ProfileDisplay ( void )
+{
+   byte * buf;
+   int i;
+   int plane;
+   byte src[200];
+   int width = StretchScreen? 320:iGLOBAL_SCREENWIDTH;
+
+   DrawClearBuffer ();
+
+   plane = 0;
+   
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+      buf=(byte *)bufferofs;
+      VGAWRITEMAP(plane);
+
+#ifdef DOS
+      for (i=plane;i<width;i+=4,buf++)
+#else
+      for (i=0;i<width;i++,buf++)
+#endif
+         {
+         DrawFilmPost(buf,&src[0],200);
+         }
+      }
+}
+
+/*
+===============
+=
+= DrawPostPic
+=
+===============
+*/
+
+void DrawPostPic ( int lumpnum )
+{
+   byte * src;
+   byte * buf;
+   lpic_t * pic;
+   int i;
+   int plane;
+   int height;
+   int width = StretchScreen? 320:iGLOBAL_SCREENWIDTH;
+
+   pic=(lpic_t *)W_CacheLumpNum(lumpnum,PU_CACHE, Cvt_lpic_t, 1);
+
+   height = pic->height;
+
+   plane = 0;
+   
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+      buf=(byte *)bufferofs;
+
+      src=&(pic->data) + (plane*pic->height);
+
+      VGAWRITEMAP(plane);
+
+#ifdef DOS
+      for (i=plane;i<width;i+=4,src+=(pic->height<<2),buf++)
+#else
+      for (i=0;i<width;i++,src+=pic->height,buf++)
+#endif
+         {
+         DrawFilmPost(buf,src,height);
+         }
+      }
+}

Added: tags/rott-1.1/rott/cin_efct.h
===================================================================
--- tags/rott-1.1/rott/cin_efct.h	                        (rev 0)
+++ tags/rott-1.1/rott/cin_efct.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,70 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _cin_efct_public
+#define _cin_efct_public
+
+#include "cin_glob.h"
+#include "cin_def.h"
+
+flicevent * SpawnCinematicFlic ( char * name, boolean loop, boolean usefile );
+spriteevent * SpawnCinematicSprite ( char * name,
+                                     int duration,
+                                     int numframes,
+                                     int framedelay,
+                                     int x,
+                                     int y,
+                                     int scale,
+                                     int endx,
+                                     int endy,
+                                     int endscale
+                                   );
+backevent * SpawnCinematicBack ( char * name,
+                                 int duration,
+                                 int width,
+                                 int startx,
+                                 int endx,
+                                 int yoffset
+                               );
+
+backevent * SpawnCinematicMultiBack ( char * name,
+                                      char * name2,
+                                      int duration,
+                                      int startx,
+                                      int endx,
+                                      int yoffset
+                                    );
+paletteevent * SpawnCinematicPalette ( char * name );
+void DrawFlic ( flicevent * flic );
+void DrawCinematicBackdrop ( backevent * back );
+void DrawCinematicBackground ( backevent * back );
+void DrawPalette (paletteevent * event);
+void DrawCinematicSprite ( spriteevent * sprite );
+void DrawClearBuffer ( void );
+void DrawBlankScreen ( void );
+boolean DrawCinematicEffect ( enum_eventtype type, void * effect );
+boolean UpdateCinematicBack ( backevent * back );
+boolean UpdateCinematicSprite ( spriteevent * sprite );
+boolean UpdateCinematicEffect ( enum_eventtype type, void * effect );
+void PrecacheCinematicEffect ( enum_eventtype type, void * effect );
+void ProfileDisplay ( void );
+void DrawPostPic ( int lumpnum );
+
+#endif
+

Added: tags/rott-1.1/rott/cin_evnt.c
===================================================================
--- tags/rott-1.1/rott/cin_evnt.c	                        (rev 0)
+++ tags/rott-1.1/rott/cin_evnt.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,530 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#include "cin_glob.h"
+#include "cin_evnt.h"
+#include "cin_efct.h"
+#include "cin_actr.h"
+#include "cin_def.h"
+#include "scriplib.h"
+#include "lumpy.h"
+#include "w_wad.h"
+#include "z_zone.h"
+#include <string.h>
+//MED
+#include "memcheck.h"
+
+eventtype * firstevent;
+eventtype * lastevent;
+
+// LOCALS
+
+static int numevents=0;
+static boolean eventsystemstarted=false;
+
+
+/*
+===============
+=
+= AddEvent
+=
+===============
+*/
+
+void AddEvent (eventtype * event)
+{
+   if (!firstevent)
+      firstevent  = event;
+   else
+      {
+      event->prev = lastevent;
+      lastevent->next = event;
+      }
+   lastevent = event;
+}
+
+
+/*
+===============
+=
+= DeleteEvent
+=
+===============
+*/
+
+void DeleteEvent(eventtype * event)
+{
+   if (event == lastevent)
+      lastevent = event->prev;
+   else
+      event->next->prev = event->prev;
+
+   if (event == firstevent)
+      firstevent = event->next;
+   else
+      event->prev->next = event->next;
+
+   event->prev = NULL;
+   event->next = NULL;
+
+   SafeFree ( event );
+}
+
+/*
+===============
+=
+= GetNewEvent
+=
+===============
+*/
+
+eventtype * GetNewEvent ( void )
+{
+   eventtype * event;
+
+   numevents++;
+
+   if ( numevents > MAXCINEMATICEVENTS )
+      Error ("Too many Cinematic events\n");
+
+   event = SafeMalloc( sizeof (eventtype) );
+
+   event->next=NULL;
+   event->prev=NULL;
+
+   return event;
+}
+
+/*
+===============
+=
+= StartupEvents
+=
+===============
+*/
+
+void StartupEvents ( void )
+{
+   if (eventsystemstarted==true)
+      return;
+   eventsystemstarted=true;
+   firstevent = NULL;
+   lastevent  = NULL;
+
+   numevents=0;
+}
+
+/*
+===============
+=
+= ShutdownEvents
+=
+===============
+*/
+
+void ShutdownEvents ( void )
+{
+   eventtype * event;
+
+   if (eventsystemstarted==false)
+      return;
+   eventsystemstarted=false;
+
+   event=firstevent;
+   while (event != NULL)
+      {
+      eventtype * nextevent;
+
+      nextevent=event->next;
+      DeleteEvent(event);
+      event=nextevent;
+      }
+}
+
+/*
+===============
+=
+= CreateEvent
+=
+===============
+*/
+eventtype * CreateEvent ( int time, int type )
+{
+   eventtype * event;
+
+   event = GetNewEvent ();
+
+   event->time = time;
+   event->effecttype = type;
+   event->effect = NULL;
+
+   AddEvent (event);
+
+   return event;
+}
+
+/*
+===============
+=
+= GetEventType
+=
+= Gets event type from token
+=
+===============
+*/
+enum_eventtype GetEventType ( void )
+{
+   // Get Event Token
+
+   GetToken (false);
+
+   if (!strcmpi (token,"BACKGROUND"))
+      {
+      GetToken (false);
+      if (!strcmpi (token,"SCROLL"))
+         {
+         return background_scrolling;
+         }
+      else if (!strcmpi (token,"NOSCROLL"))
+         {
+         return background_noscrolling;
+         }
+      else if (!strcmpi (token,"MULTISCROLL"))
+         {
+         return background_multi;
+         }
+      else
+         {
+         Error("Illegal Background Scrolling token\n");
+         }
+      }
+   else if (!strcmpi (token,"BACKDROP"))
+      {
+      GetToken (false);
+      if (!strcmpi (token,"SCROLL"))
+         {
+         return backdrop_scrolling;
+         }
+      else if (!strcmpi (token,"NOSCROLL"))
+         {
+         return backdrop_noscrolling;
+         }
+      else
+         {
+         Error("Illegal Backdrop Scrolling token\n");
+         }
+      }
+   else if (!strcmpi (token,"BACKGROUNDSPRITE"))
+      {
+      return sprite_background;
+      }
+   else if (!strcmpi (token,"FOREGROUNDSPRITE"))
+      {
+      return sprite_foreground;
+      }
+   else if (!strcmpi (token,"PALETTE"))
+      {
+      return palette;
+      }
+   else if (!strcmpi (token,"FADEOUT"))
+      {
+      return fadeout;
+      }
+   else if (!strcmpi (token,"FLIC"))
+      {
+      return flic;
+      }
+   else if (!strcmpi (token,"MOVIEEND"))
+      {
+      return cinematicend;
+      }
+   else if (!strcmpi (token,"BLANKSCREEN"))
+      {
+      return blankscreen;
+      }
+   else if (!strcmpi (token,"CLEARBUFFER"))
+      {
+      return clearbuffer;
+      }
+   else
+      {
+      Error("GetEventType: Illegal Token %s\n",token);
+      }
+   return -1;
+}
+
+/*
+===============
+=
+= ParseBack
+=
+===============
+*/
+void ParseBack ( eventtype * event )
+{
+   char name[10];
+   char name2[10];
+   int duration;
+   int yoffset;
+   int width;
+   int startx;
+   int endx;
+
+   GetToken (false);
+   strcpy(&(name[0]),token);
+
+   if (event->effecttype==background_multi)
+      {
+      GetToken (false);
+      strcpy(&(name2[0]),token);
+      }
+
+   GetToken (false);
+   duration=ParseNum(token);
+   GetToken (false);
+   yoffset=ParseNum(token);
+   if (
+       (event->effecttype==background_noscrolling) ||
+       (event->effecttype==background_scrolling)
+      )
+      {
+      lpic_t * lpic;
+
+      lpic = (lpic_t *)W_CacheLumpName(name,PU_CACHE, Cvt_lpic_t, 1);
+      width = lpic->width;
+      }
+   else if (event->effecttype!=background_multi)
+      {
+      patch_t * patch;
+
+      patch = (patch_t *)W_CacheLumpName(name,PU_CACHE, Cvt_lpic_t, 1);
+      width = patch->width;
+      }
+
+   startx=0;
+   endx=0;
+   if (
+       (event->effecttype==backdrop_scrolling) ||
+       (event->effecttype==background_scrolling) ||
+       (event->effecttype==background_multi)
+      )
+      {
+      GetToken (false);
+      startx=ParseNum(token);
+      GetToken (false);
+      endx=ParseNum(token);
+      }
+
+   if (event->effecttype==background_multi)
+      event->effect = SpawnCinematicMultiBack ( name, name2, duration, startx, endx, yoffset);
+   else
+      event->effect = SpawnCinematicBack ( name, duration, width, startx, endx, yoffset);
+}
+
+/*
+===============
+=
+= ParseSprite
+=
+===============
+*/
+void ParseSprite ( eventtype * event )
+{
+   char name[10];
+   int duration;
+   int numframes;
+   int framedelay;
+   int x,y,scale;
+   int endx,endy,endscale;
+
+   GetToken (false);
+   strcpy(&(name[0]),token);
+   GetToken (false);
+   duration=ParseNum(token);
+   GetToken (false);
+   numframes=ParseNum(token);
+   GetToken (false);
+   framedelay=ParseNum(token);
+   GetToken (false);
+   x=ParseNum(token);
+   GetToken (false);
+   y=ParseNum(token);
+   GetToken (false);
+   scale=ParseNum(token);
+   GetToken (false);
+   endx=ParseNum(token);
+   GetToken (false);
+   endy=ParseNum(token);
+   GetToken (false);
+   endscale=ParseNum(token);
+
+   event->effect = SpawnCinematicSprite ( name, duration, numframes,
+                                          framedelay, x, y, scale,
+                                          endx, endy, endscale
+                                        );
+}
+
+/*
+===============
+=
+= ParseFlic
+=
+===============
+*/
+void ParseFlic ( eventtype * event )
+{
+   char name[10];
+   boolean loop;
+   boolean usefile;
+
+   GetToken (false);
+   strcpy(&(name[0]),token);
+
+   GetToken (false);
+   if (!strcmpi (token,"LOOP"))
+      {
+      loop = true;
+      }
+   else if (!strcmpi (token,"NOLOOP"))
+      {
+      loop = false;
+      }
+   else
+      Error("ParseFlic: Illegal or missing flic loop token %s\n",token);
+
+   GetToken (false);
+   if (!strcmpi (token,"FILE"))
+      {
+      usefile=true;
+      }
+   else if (!strcmpi (token,"LUMP"))
+      {
+      usefile=false;
+      }
+   else
+      Error("ParseFlic: Illegal or missing flic use token %s\n",token);
+
+   event->effect = SpawnCinematicFlic ( name, loop, usefile );
+}
+
+/*
+===============
+=
+= ParsePalette
+=
+===============
+*/
+void ParsePalette ( eventtype * event )
+{
+   char name[10];
+
+   GetToken (false);
+   strcpy(&(name[0]),token);
+
+   event->effect = SpawnCinematicPalette ( name );
+}
+
+/*
+===============
+=
+= ParseEvent
+=
+===============
+*/
+void ParseEvent ( int time )
+{
+   eventtype * event;
+
+   event = CreateEvent ( time, GetEventType() );
+
+   switch (event->effecttype)
+      {
+      case background_noscrolling:
+      case background_scrolling:
+      case background_multi:
+      case backdrop_scrolling:
+      case backdrop_noscrolling:
+         ParseBack(event);
+         break;
+      case sprite_background:
+      case sprite_foreground:
+         ParseSprite(event);
+         break;
+      case palette:
+         ParsePalette(event);
+         break;
+      case flic:
+         ParseFlic(event);
+         break;
+      case fadeout:
+      case blankscreen:
+      case clearbuffer:
+      case cinematicend:
+         break;
+      }
+}
+
+/*
+===============
+=
+= UpdateCinematicEvents
+=
+===============
+*/
+void UpdateCinematicEvents ( int time )
+{
+   eventtype * event;
+
+   for (event=firstevent;event != NULL;)
+      {
+      if (event->time==time)
+         {
+         eventtype * nextevent;
+
+         nextevent=event->next;
+         SpawnCinematicActor ( event->effecttype, event->effect );
+         DeleteEvent(event);
+         event=nextevent;
+         }
+      else if (event->time>time)
+         break;
+      else
+         event=event->next;
+      }
+}
+
+/*
+===============
+=
+= PrecacheCinematic
+=
+===============
+*/
+void PrecacheCinematic ( void )
+{
+   eventtype * event;
+
+   for (event=firstevent;event != NULL;)
+      {
+      PrecacheCinematicEffect ( event->effecttype, event->effect );
+      event=event->next;
+      }
+}
+

Added: tags/rott-1.1/rott/cin_evnt.h
===================================================================
--- tags/rott-1.1/rott/cin_evnt.h	                        (rev 0)
+++ tags/rott-1.1/rott/cin_evnt.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,41 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _cin_evnt_public
+#define _cin_evnt_public
+
+#include "cin_glob.h"
+#include "cin_def.h"
+
+extern eventtype * firstevent;
+extern eventtype * lastevent;
+
+void AddEvent (eventtype * event);
+void DeleteEvent(eventtype * event);
+
+eventtype * GetNewEvent ( void );
+void StartupEvents ( void );
+void ShutdownEvents ( void );
+eventtype * CreateEvent ( int time, int type );
+void ParseEvent ( int time );
+void UpdateCinematicEvents ( int time );
+void PrecacheCinematic ( void );
+
+#endif
+

Added: tags/rott-1.1/rott/cin_glob.c
===================================================================
--- tags/rott-1.1/rott/cin_glob.c	                        (rev 0)
+++ tags/rott-1.1/rott/cin_glob.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,45 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "cin_glob.h"
+#include "rt_in.h"
+#include "rt_draw.h"
+//MED
+#include "memcheck.h"
+
+void CinematicDelay ( void )
+{
+   CalcTics();
+}
+
+int GetCinematicTime ( void )
+{
+   return GetTicCount ();
+}
+
+boolean CinematicAbort( void )
+{
+   return (IN_CheckAck ());
+}
+
+void ClearCinematicAbort( void )
+{
+   IN_StartAck ();
+}
+

Added: tags/rott-1.1/rott/cin_glob.h
===================================================================
--- tags/rott-1.1/rott/cin_glob.h	                        (rev 0)
+++ tags/rott-1.1/rott/cin_glob.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,37 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "rt_util.h"
+#include "isr.h"
+#include <time.h>
+
+#ifndef CIN_GLOB_H
+#define CIN_GLOB_H
+
+#define DUMP 0
+
+#define CLOCKSPEED (VBLCOUNTER)
+
+void CinematicDelay( void );
+int GetCinematicTime( void );
+boolean CinematicAbort( void );
+void ClearCinematicAbort( void );
+
+#endif

Added: tags/rott-1.1/rott/cin_main.c
===================================================================
--- tags/rott-1.1/rott/cin_main.c	                        (rev 0)
+++ tags/rott-1.1/rott/cin_main.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,286 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#ifdef DOS
+#include <malloc.h>
+#include <dos.h>
+#include <io.h>
+#include <conio.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include "cin_glob.h"
+#include "scriplib.h"
+#include "watcom.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "cin_main.h"
+#include "modexlib.h"
+#include "lumpy.h"
+
+#include "cin_actr.h"
+#include "cin_evnt.h"
+#include "cin_efct.h"
+//MED
+#include "memcheck.h"
+
+boolean cinematicdone;
+static int cinematictime;
+static int cinematictics;
+static int cinematictictime;
+static int profiletics=-1;
+
+/*
+================
+=
+= ProfileMachine
+=
+================
+*/
+void ProfileMachine ( void )
+{
+   int i;
+   int time;
+   int endtime;
+
+   if (profiletics>0)
+      return;
+   time=GetCinematicTime();
+   for (i=0;i<4;i++)
+      {
+      ProfileDisplay();
+      }
+   endtime=GetCinematicTime();
+
+   profiletics = (endtime-time)>>2;
+   if (profiletics<1)
+      profiletics=1;
+}
+
+/*
+================
+=
+= StartupCinematic
+=
+================
+*/
+void StartupCinematic ( void )
+{
+   StartupEvents ();
+   StartupCinematicActors ();
+   cinematicdone=false;
+   cinematictime=0;
+   GetCinematicTics ();
+   ClearCinematicAbort();
+   ProfileMachine();
+}
+
+
+/*
+================
+=
+= ShutdownCinematic
+=
+================
+*/
+void ShutdownCinematic ( void )
+{
+   ShutdownEvents ();
+   ShutdownCinematicActors ();
+}
+
+
+/*
+================
+=
+= ParseCinematicScript
+=
+================
+*/
+
+void ParseCinematicScript (void)
+{
+   int time;
+
+   time=0;
+   do
+      {
+      //
+      // get next command time
+      //
+      GetToken (true);
+      if (endofscript)
+         break;
+      time+=ParseNum(token);
+      ParseEvent ( time );
+      }
+   while (script_p < scriptend_p);
+}
+
+
+/*
+==============
+=
+= CacheScriptFile
+=
+==============
+*/
+
+void CacheScriptFile (char *filename)
+{
+	long            size;
+   int lump;
+
+   lump=W_GetNumForName(filename);
+
+   scriptbuffer=W_CacheLumpNum(lump,PU_CACHE, CvtNull, 1);
+	size = W_LumpLength(lump);
+
+	script_p = scriptbuffer;
+	scriptend_p = script_p + size;
+	scriptline = 1;
+	endofscript = false;
+	tokenready = false;
+}
+
+
+/*
+=================
+=
+= GrabCinematicScript
+=
+=================
+*/
+
+void GrabCinematicScript (char const *basename, boolean uselumpy)
+{
+   char script[256];
+
+//
+// read in the script file
+//
+   strcpy (script, basename);
+   strcat (script,".ms");
+   if (uselumpy==false)
+      LoadScriptFile (script);
+   else
+      CacheScriptFile ((char *)basename);
+
+   ParseCinematicScript ();
+}
+
+/*
+==============
+=
+= GetCinematicTics
+=
+==============
+*/
+
+void GetCinematicTics ( void )
+{
+   int time;
+
+   time=GetCinematicTime();
+   while (time==cinematictictime)
+      {
+      time=GetCinematicTime();
+      }
+   cinematictics=(time-cinematictictime);
+   cinematictictime=time;
+   cinematictics=profiletics;
+}
+
+
+void PlayMovie ( char * name, boolean uselumpy )
+{
+   int i;
+
+   StartupCinematic ( );
+   GrabCinematicScript (name, uselumpy);
+
+   PrecacheCinematic ( );
+   GetCinematicTics();
+   while (cinematicdone==false)
+      {
+      cinematicdone=CinematicAbort();
+#if DUMP
+      printf("time=%ld\n",cinematictime);
+#endif
+      for (i=0;i<cinematictics;i++)
+         {
+         UpdateCinematicEvents ( cinematictime );
+         UpdateCinematicActors ( );
+         cinematictime++;
+         }
+      DrawCinematicActors ();
+      GetCinematicTics();
+      }
+
+   ShutdownCinematic ();
+}
+
+#ifndef DOS
+int cin_iscale;
+byte *cin_source;
+int cin_texturemid;
+int cin_ycenter;
+int cin_yh;
+int cin_yl;
+
+/* f_scale.asm */
+
+void R_DrawFilmColumn (byte * buf)
+{
+	// This is *NOT* 100% correct - DDOI
+	int count;
+	int frac, fracstep;
+	byte *dest;
+
+	count = cin_yh - cin_yl;
+	if (count < 0) return;
+
+	dest = buf + ylookup[cin_yl];
+
+	fracstep = cin_iscale;
+	frac = cin_texturemid + (cin_yl-cin_ycenter)*fracstep;
+
+	while (count--) {
+		*dest = cin_source[(frac>>SFRACBITS)];
+		dest += iGLOBAL_SCREENWIDTH;
+		frac += fracstep;
+	}
+}
+
+void DrawFilmPost (byte * buf, byte * src, int height)
+{
+	while (height--) { 
+		*buf = *src;
+		
+		src++;
+		
+		buf += linewidth;
+	}
+}
+#endif
+

Added: tags/rott-1.1/rott/cin_main.h
===================================================================
--- tags/rott-1.1/rott/cin_main.h	                        (rev 0)
+++ tags/rott-1.1/rott/cin_main.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,36 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _cin_main_public
+#define _cin_main_public
+
+//***************************************************************************
+//
+// CIN_MAIN.H
+//
+//***************************************************************************
+#include "cin_glob.h"
+
+void GrabMovieScript (char const *basename, boolean uselumpy);
+void PlayMovie (char * name, boolean uselumpy);
+void GetCinematicTics ( void );
+
+extern boolean cinematicdone;
+
+#endif

Added: tags/rott-1.1/rott/cin_util.c
===================================================================
--- tags/rott-1.1/rott/cin_util.c	                        (rev 0)
+++ tags/rott-1.1/rott/cin_util.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,72 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "cin_glob.h"
+#include "modexlib.h"
+
+#ifdef DOS
+#include <conio.h>
+#endif
+
+//MED
+#include "memcheck.h"
+
+/*
+==============
+=
+= CinematicGetPalette
+=
+= Return an 8 bit / color palette
+=
+==============
+*/
+
+void CinematicGetPalette (byte *pal)
+{
+#ifdef DOS
+	int	i;
+
+   outp (PEL_READ_ADR,0);
+	for (i=0 ; i<768 ; i++)
+      pal[i] = ((inp (PEL_DATA))<<2);
+#else
+#endif
+}
+
+/*
+==============
+=
+= CinematicSetPalette
+=
+= Sets an 8 bit / color palette
+=
+==============
+*/
+
+void CinematicSetPalette (byte *pal)
+{
+#ifdef DOS
+	int	i;
+
+   outp (PEL_WRITE_ADR,0);
+	for (i=0 ; i<768 ; i++)
+      outp (PEL_DATA, pal[i]>>2);
+#else
+#endif
+}

Added: tags/rott-1.1/rott/cin_util.h
===================================================================
--- tags/rott-1.1/rott/cin_util.h	                        (rev 0)
+++ tags/rott-1.1/rott/cin_util.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,28 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _cin_util_public
+#define _cin_util_public
+
+
+void CinematicGetPalette (byte *pal);
+void CinematicSetPalette (byte *pal);
+
+#endif
+

Added: tags/rott-1.1/rott/develop.h
===================================================================
--- tags/rott-1.1/rott/develop.h	                        (rev 0)
+++ tags/rott-1.1/rott/develop.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,82 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _develop_public
+#define _develop_public
+
+#define NOMEMCHECK
+#define DEBUG 0
+#define DEVELOPMENT 0
+#define BETA 0
+#define SOUNDTEST 0
+#define PRECACHETEST 0
+#define ELEVATORTEST 0
+#define TEAMTEST     0
+#define LOADSAVETEST 0
+#define WEAPONCHEAT  1
+#define MEMORYCORRUPTIONTEST  0
+#define SYNCCHECK    1
+#define DATACORRUPTIONTEST    0
+#define BATTLECHECK 0 // This should be turned off for release, on for beta
+#define BATTLEINFO  0 // This should be turned off for release
+
+#define DELUXE   0
+#define LOWCOST  0
+
+#define BNACRASHPREVENT  1 //bna added 
+// Make sure only one of the following are on at one time
+#define SHAREWARE   1
+#define SUPERROTT   0
+#define SITELICENSE 0
+
+// cute little dopefish thing, only works with special patch?
+#define DOPEFISH 0
+
+// okay?
+
+#define TEDLAUNCH   0
+#define SOFTERROR   0
+#define RANDOMTEST  0
+#define WHEREAMI    0
+
+
+
+
+#if (WHEREAMI==1)
+
+#define wami(val)      \
+   {                   \
+   programlocation=val;\
+   }
+
+#define waminot()
+/*
+   {                  \
+   programlocation=-1;\
+   }
+*/
+
+#else
+
+#define wami(val)
+#define waminot()
+
+#endif
+
+#endif

Added: tags/rott-1.1/rott/dosutil.c
===================================================================
--- tags/rott-1.1/rott/dosutil.c	                        (rev 0)
+++ tags/rott-1.1/rott/dosutil.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,394 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <sys/stat.h>
+#if PLATFORM_UNIX
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#endif
+
+#include <fcntl.h>
+
+#include "rt_def.h"
+
+#if defined(USE_SDL)
+#include "SDL.h"
+#endif
+              
+/* 
+  Copied over from Wolf3D Linux: http://www.icculus.org/wolf3d/
+  Modified for ROTT.
+ */
+ 
+int _argc;
+char **_argv;
+
+#if PLATFORM_UNIX
+long filelength(int handle)
+{
+	struct stat buf;
+	
+	if (fstat(handle, &buf) == -1) {
+		perror("filelength");
+		exit(EXIT_FAILURE);
+	}
+	
+	return buf.st_size;
+}
+
+char *strlwr(char *s)
+{
+	char *p = s;
+	
+	while (*p) {
+		*p = tolower(*p);
+		p++;
+	}
+	
+	return s;
+}
+
+char *strupr(char *s)
+{
+	char *p = s;
+	
+	while (*p) {
+		*p = toupper(*p);
+		p++;
+	}
+	
+	return s;
+}
+	
+char *itoa(int value, char *string, int radix)
+{
+	switch (radix) {
+		case 10:
+			sprintf(string, "%d", value);
+			break;
+		case 16:
+			sprintf(string, "%x", value);
+			break;
+		default:
+			STUB_FUNCTION;
+			break;
+	}
+	
+	return string;
+}
+
+char *ltoa(long value, char *string, int radix)
+{
+	switch (radix) {
+		case 10:
+			sprintf(string, "%ld", value);
+			break;
+		case 16:
+			sprintf(string, "%lx", value);
+			break;
+		default:
+			STUB_FUNCTION;
+			break;
+	}
+	
+	return string;
+}
+
+char *ultoa(unsigned long value, char *string, int radix)
+{
+	switch (radix) {
+		case 10:
+			sprintf(string, "%lu", value);
+			break;
+		case 16:
+			sprintf(string, "%lux", value);
+			break;
+		default:
+			STUB_FUNCTION;
+			break;
+	}
+	
+	return string;
+}
+#endif
+
+char getch(void)
+{
+	getchar();
+	return 0;
+}
+
+extern char ApogeePath[256];
+
+int setup_homedir (void)
+{
+#if PLATFORM_UNIX
+	int err;
+
+	/* try to create the root directory */
+	snprintf (ApogeePath, sizeof (ApogeePath), "%s/.rott/", getenv ("HOME"));
+	err = mkdir (ApogeePath, S_IRWXU);
+	
+/* keep the shareware and registered game data separated */
+#if (SHAREWARE == 1)
+	snprintf (ApogeePath, sizeof (ApogeePath), "%s/.rott/", getenv ("HOME"));
+#else
+	snprintf (ApogeePath, sizeof (ApogeePath), "%s/.rott/darkwar/", getenv ("HOME"));
+#endif
+
+	err = mkdir (ApogeePath, S_IRWXU);
+	if (err == -1 && errno != EEXIST)
+	{
+		fprintf (stderr, "Couldn't create preferences directory: %s\n", 
+				strerror (errno));
+		return -1;
+	}
+#else
+    sprintf(ApogeePath, ".%s", PATH_SEP_STR);
+#endif
+
+	return 0;
+}
+
+/* from Dan Olson */
+void put_dos2ansi(byte attrib)
+{
+	int lookup[] = {30,34,32,36,31,35,33,37};
+	byte fore,back,blink=0,intens=0;
+	
+	fore = attrib&15;	/* bits 0-3 */
+	back = attrib&112; /* bits 4-6 */
+       	blink = attrib&128; /* bit 7 */
+	
+	/* Fix background, blink is either on or off. */
+	back = back>>4;
+ 
+	/* Fix foreground */
+	if (fore > 7) {
+		intens = 1;
+		fore-=8;
+	}
+
+	/* Convert fore/back */
+	fore = lookup[fore];
+	back = lookup[back]+10;
+
+	// 'Render"
+	if (blink)
+		printf ("\033[%d;5;%dm\033[%dm", intens, fore, back);
+	else
+		printf ("\033[%d;25;%dm\033[%dm", intens, fore, back);
+}
+
+void DisplayTextSplash(byte *text, int l)
+{
+	int i;
+	int bound = 80*l*2;
+
+	for (i=0;i<bound;i+=2)
+	{
+		put_dos2ansi(text[i+1]);
+		putchar (text[i]);
+	}
+
+	printf ("\033[m");
+}
+
+#if (USE_EXECINFO == 1)
+#include <execinfo.h>
+
+void print_stack (int level)
+{
+	void *array[64];
+	char **syms;
+	int size, i;
+
+	printf ("Stack dump:\n");
+	printf ("{\n");
+	size = backtrace (array, (sizeof (array))/(sizeof (array[0])));
+	syms = backtrace_symbols (array, size);
+	for (i=level+1; i<size;++i) {
+		printf ("\t%s\n",syms[i]);
+	}
+	free (syms);
+	/*
+	for (i = 2; i <size; ++i) {
+		printf ("\t%p\n", array[i]);
+	}
+	*/
+	printf ("}\n");
+}
+#else
+
+void print_stack (int level)
+{
+        printf("Stack dump not implemented.\n");
+}
+
+#endif
+
+void crash_print (int sig)
+{
+	printf ("OH NO OH NO ROTT CRASHED!\n");
+	printf ("Here is where:\n");
+	print_stack (1);
+#if defined(USE_SDL)
+	SDL_Quit ();
+#endif
+	exit (1);
+}
+
+#if 0
+/* ** */
+
+uint16_t SwapInt16L(uint16_t i)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+	return ((uint16_t)i >> 8) | ((uint16_t)i << 8);
+#else
+	return i;
+#endif
+}
+
+uint32_t SwapInt32L(uint32_t i)
+{
+#if BYTE_ORDER == BIG_ENDIAN
+	return	((uint32_t)(i & 0xFF000000) >> 24) | 
+		((uint32_t)(i & 0x00FF0000) >>  8) |
+		((uint32_t)(i & 0x0000FF00) <<  8) | 
+		((uint32_t)(i & 0x000000FF) << 24);
+#else
+	return i;
+#endif
+}
+
+/* ** */
+
+int OpenWrite(char *_fn)
+{
+	int fp;
+    char fn[MAX_PATH];
+    strncpy(fn, _fn, sizeof (fn));
+    fn[sizeof (fn) - 1] = '\0';
+    FixFilePath(fn);
+
+	fp = open(fn, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+	return fp;
+}
+
+int OpenWriteAppend(char *_fn)
+{
+	int fp;
+    char fn[MAX_PATH];
+    strncpy(fn, _fn, sizeof (fn));
+    fn[sizeof (fn) - 1] = '\0';
+    FixFilePath(fn);
+
+	fp = open(fn, O_CREAT|O_WRONLY|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+	return fp;
+}
+
+void CloseWrite(int fp)
+{
+	close(fp);
+}
+
+int WriteSeek(int fp, int offset, int whence)
+{
+	return lseek(fp, offset, whence);
+}
+
+int WritePos(int fp)
+{
+	return lseek(fp, 0, SEEK_CUR);
+}
+
+int WriteInt8(int fp, int8_t d)
+{
+	return write(fp, &d, 1);
+}
+
+int WriteInt16(int fp, int16_t d)
+{
+	int16_t b = SwapInt16L(d);
+	
+	return write(fp, &b, 2) / 2;
+}
+
+int WriteInt32(int fp, int32_t d)
+{
+	int32_t b = SwapInt32L(d);
+	
+	return write(fp, &b, 4) / 4;
+}
+
+int WriteBytes(int fp, byte *d, int len)
+{
+	return write(fp, d, len);
+}
+
+
+int OpenRead(char *_fn)
+{
+	int fp;
+    char fn[MAX_PATH];
+    strncpy(fn, _fn, sizeof (fn));
+    fn[sizeof (fn) - 1] = '\0';
+    FixFilePath(fn);
+	
+	fp = open(fn, O_RDONLY | O_BINARY);
+	
+	return fp;
+}
+
+void CloseRead(int fp)
+{
+	close(fp);
+}
+
+int ReadSeek(int fp, int offset, int whence)
+{
+	return lseek(fp, offset, whence);
+}
+
+int ReadLength(int fp)
+{
+	return filelength(fp);
+}
+
+int8_t ReadInt8(int fp)
+{
+	byte d[1];
+	
+	read(fp, d, 1);
+	
+	return d[0];
+}
+
+int16_t ReadInt16(int fp)
+{
+	byte d[2];
+	
+	read(fp, d, 2);
+	
+	return (d[0]) | (d[1] << 8);
+}
+
+int32_t ReadInt32(int fp)
+{
+	byte d[4];
+	
+	read(fp, d, 4);
+	
+	return (d[0]) | (d[1] << 8) | (d[2] << 16) | (d[3] << 24);
+}
+
+int ReadBytes(int fp, byte *d, int len)
+{
+	return read(fp, d, len);
+}
+
+#endif

Added: tags/rott-1.1/rott/dukemusc.c
===================================================================
--- tags/rott-1.1/rott/dukemusc.c	                        (rev 0)
+++ tags/rott-1.1/rott/dukemusc.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,507 @@
+/*
+ * A reimplementation of Jim Dose's FX_MAN routines, using  SDL_mixer 1.2.
+ *   Whee. FX_MAN is also known as the "Apogee Sound System", or "ASS" for
+ *   short. How strangely appropriate that seems.
+ *
+ * Written by Ryan C. Gordon. (icculus at clutteredmind.org)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+
+#define ROTT
+
+#ifdef DUKE3D
+#include "duke3d.h"
+#include "buildengine/cache1d.h"
+#endif
+
+#if PLATFORM_DOS
+// Use the original Apogee Sound System libs instead.  --ryan.
+#error you probably should not compile this.
+#endif
+
+#if (defined __WATCOMC__)
+// This is probably out of date.  --ryan.
+#include "dukesnd_watcom.h"
+#endif
+
+#if (!defined __WATCOMC__)
+#define cdecl
+#endif
+
+#include "SDL.h"
+#include "SDL_mixer.h"
+#ifdef ROTT
+#include "rt_def.h"      // ROTT music hack
+#include "rt_cfg.h"      // ROTT music hack
+#include "rt_util.h"     // ROTT music hack
+#endif
+#include "music.h"
+
+#define __FX_TRUE  (1 == 1)
+#define __FX_FALSE (!__FX_TRUE)
+
+#define DUKESND_DEBUG       "DUKESND_DEBUG"
+
+#ifndef min
+#define min(a, b)  (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef max
+#define max(a, b)  (((a) > (b)) ? (a) : (b))
+#endif
+
+int MUSIC_ErrorCode = MUSIC_Ok;
+
+static char warningMessage[80];
+static char errorMessage[80];
+static int fx_initialized = 0;
+static int numChannels = MIX_CHANNELS;
+static void (*callback)(unsigned long);
+static int reverseStereo = 0;
+static int reverbDelay = 256;
+static int reverbLevel = 0;
+static int fastReverb = 0;
+static FILE *debug_file = NULL;
+static int initialized_debugging = 0;
+static int mixerIsStereo = 1;
+
+// This gets called all over the place for information and debugging messages.
+//  If the user set the DUKESND_DEBUG environment variable, the messages
+//  go to the file that is specified in that variable. Otherwise, they
+//  are ignored for the expense of the function call. If DUKESND_DEBUG is
+//  set to "-" (without the quotes), then the output goes to stdout.
+static void musdebug(const char *fmt, ...)
+{
+    va_list ap;
+
+    if (debug_file)
+    {
+        fprintf(debug_file, "DUKEMUS: ");
+        va_start(ap, fmt);
+        vfprintf(debug_file, fmt, ap);
+        va_end(ap);
+        fprintf(debug_file, "\n");
+        fflush(debug_file);
+    } // if
+} // musdebug
+
+static void init_debugging(void)
+{
+    const char *envr;
+
+    if (initialized_debugging)
+        return;
+
+    envr = getenv(DUKESND_DEBUG);
+    if (envr != NULL)
+    {
+        if (strcmp(envr, "-") == 0)
+            debug_file = stdout;
+        else
+            debug_file = fopen(envr, "w");
+
+        if (debug_file == NULL)
+            fprintf(stderr, "DUKESND: -WARNING- Could not open debug file!\n");
+        else
+            setbuf(debug_file, NULL);
+    } // if
+
+    initialized_debugging = 1;
+} // init_debugging
+
+static void setWarningMessage(const char *msg)
+{
+    strncpy(warningMessage, msg, sizeof (warningMessage));
+    // strncpy() doesn't add the null char if there isn't room...
+    warningMessage[sizeof (warningMessage) - 1] = '\0';
+    musdebug("Warning message set to [%s].", warningMessage);
+} // setErrorMessage
+
+
+static void setErrorMessage(const char *msg)
+{
+    strncpy(errorMessage, msg, sizeof (errorMessage));
+    // strncpy() doesn't add the null char if there isn't room...
+    errorMessage[sizeof (errorMessage) - 1] = '\0';
+    musdebug("Error message set to [%s].", errorMessage);
+} // setErrorMessage
+
+// The music functions...
+
+char *MUSIC_ErrorString(int ErrorNumber)
+{
+    switch (ErrorNumber)
+    {
+        case MUSIC_Warning:
+            return(warningMessage);
+
+        case MUSIC_Error:
+            return(errorMessage);
+
+        case MUSIC_Ok:
+            return("OK; no error.");
+
+        case MUSIC_ASSVersion:
+            return("Incorrect sound library version.");
+
+        case MUSIC_SoundCardError:
+            return("General sound card error.");
+
+        case MUSIC_InvalidCard:
+            return("Invalid sound card.");
+
+        case MUSIC_MidiError:
+            return("MIDI error.");
+
+        case MUSIC_MPU401Error:
+            return("MPU401 error.");
+
+        case MUSIC_TaskManError:
+            return("Task Manager error.");
+
+        case MUSIC_FMNotDetected:
+            return("FM not detected error.");
+
+        case MUSIC_DPMI_Error:
+            return("DPMI error.");
+
+        default:
+            return("Unknown error.");
+    } // switch
+
+    assert(0);    // shouldn't hit this point.
+    return(NULL);
+} // MUSIC_ErrorString
+
+
+static int music_initialized = 0;
+static int music_context = 0;
+static int music_loopflag = MUSIC_PlayOnce;
+static char *music_songdata = NULL;
+static Mix_Music *music_musicchunk = NULL;
+
+int MUSIC_Init(int SoundCard, int Address)
+{
+    init_debugging();
+
+    musdebug("INIT! card=>%d, address=>%d...", SoundCard, Address);
+
+    if (music_initialized)
+    {
+        setErrorMessage("Music system is already initialized.");
+        return(MUSIC_Error);
+    } // if
+    
+    if (SoundCard != SoundScape) // We pretend there's a SoundScape installed.
+    {
+        setErrorMessage("Card not found.");
+        musdebug("We pretend to be an Ensoniq SoundScape only.");
+        return(MUSIC_Error);
+    } // if
+
+    music_initialized = 1;
+    return(MUSIC_Ok);
+} // MUSIC_Init
+
+
+int MUSIC_Shutdown(void)
+{
+    musdebug("shutting down sound subsystem.");
+
+    if (!music_initialized)
+    {
+        setErrorMessage("Music system is not currently initialized.");
+        return(MUSIC_Error);
+    } // if
+
+    MUSIC_StopSong();
+    music_context = 0;
+    music_initialized = 0;
+    music_loopflag = MUSIC_PlayOnce;
+
+    return(MUSIC_Ok);
+} // MUSIC_Shutdown
+
+
+void MUSIC_SetMaxFMMidiChannel(int channel)
+{
+    musdebug("STUB ... MUSIC_SetMaxFMMidiChannel(%d).\n", channel);
+} // MUSIC_SetMaxFMMidiChannel
+
+
+void MUSIC_SetVolume(int volume)
+{
+    Mix_VolumeMusic(volume >> 1);  // convert 0-255 to 0-128.
+} // MUSIC_SetVolume
+
+
+void MUSIC_SetMidiChannelVolume(int channel, int volume)
+{
+    musdebug("STUB ... MUSIC_SetMidiChannelVolume(%d, %d).\n", channel, volume);
+} // MUSIC_SetMidiChannelVolume
+
+
+void MUSIC_ResetMidiChannelVolumes(void)
+{
+    musdebug("STUB ... MUSIC_ResetMidiChannelVolumes().\n");
+} // MUSIC_ResetMidiChannelVolumes
+
+
+int MUSIC_GetVolume(void)
+{
+    return(Mix_VolumeMusic(-1) << 1);  // convert 0-128 to 0-255.
+} // MUSIC_GetVolume
+
+
+void MUSIC_SetLoopFlag(int loopflag)
+{
+    music_loopflag = loopflag;
+} // MUSIC_SetLoopFlag
+
+
+int MUSIC_SongPlaying(void)
+{
+    return((Mix_PlayingMusic()) ? __FX_TRUE : __FX_FALSE);
+} // MUSIC_SongPlaying
+
+
+void MUSIC_Continue(void)
+{
+    if (Mix_PausedMusic())
+        Mix_ResumeMusic();
+    else if (music_songdata)
+        MUSIC_PlaySong(music_songdata, MUSIC_PlayOnce);
+} // MUSIC_Continue
+
+
+void MUSIC_Pause(void)
+{
+    Mix_PauseMusic();
+} // MUSIC_Pause
+
+
+int MUSIC_StopSong(void)
+{
+    //if (!fx_initialized)
+    if (!Mix_QuerySpec(NULL, NULL, NULL))
+    {
+        setErrorMessage("Need FX system initialized, too. Sorry.");
+        return(MUSIC_Error);
+    } // if
+
+    if ( (Mix_PlayingMusic()) || (Mix_PausedMusic()) )
+        Mix_HaltMusic();
+
+    if (music_musicchunk)
+        Mix_FreeMusic(music_musicchunk);
+
+    music_songdata = NULL;
+    music_musicchunk = NULL;
+    return(MUSIC_Ok);
+} // MUSIC_StopSong
+
+
+int MUSIC_PlaySong(unsigned char *song, int loopflag)
+{
+    //SDL_RWops *rw;
+
+    MUSIC_StopSong();
+
+    music_songdata = song;
+
+    // !!! FIXME: This could be a problem...SDL/SDL_mixer wants a RWops, which
+    // !!! FIXME:  is an i/o abstraction. Since we already have the MIDI data
+    // !!! FIXME:  in memory, we fake it with a memory-based RWops. None of
+    // !!! FIXME:  this is a problem, except the RWops wants to know how big
+    // !!! FIXME:  its memory block is (so it can do things like seek on an
+    // !!! FIXME:  offset from the end of the block), and since we don't have
+    // !!! FIXME:  this information, we have to give it SOMETHING.
+
+    /* !!! ARGH! There's no LoadMUS_RW  ?!
+    rw = SDL_RWFromMem((void *) song, (10 * 1024) * 1024);  // yikes.
+    music_musicchunk = Mix_LoadMUS_RW(rw);
+    Mix_PlayMusic(music_musicchunk, (loopflag == MUSIC_PlayOnce) ? 0 : -1);
+    */
+
+musdebug("Need to use PlaySongROTT.  :(");
+
+    return(MUSIC_Ok);
+} // MUSIC_PlaySong
+
+
+extern char ApogeePath[256];
+
+#ifdef DUKE3D
+// Duke3D-specific.  --ryan.
+void PlayMusic(char *_filename)
+{
+    //char filename[MAX_PATH];
+    //strcpy(filename, _filename);
+    //FixFilePath(filename);
+
+    char filename[MAX_PATH];
+    long handle;
+    long size;
+    void *song;
+    long rc;
+
+    MUSIC_StopSong();
+
+    // Read from a groupfile, write it to disk so SDL_mixer can read it.
+    //   Lame.  --ryan.
+    handle = kopen4load(_filename, 0);
+    if (handle == -1)
+        return;
+
+    size = kfilelength(handle);
+    if (size == -1)
+    {
+        kclose(handle);
+        return;
+    } // if
+
+    song = malloc(size);
+    if (song == NULL)
+    {
+        kclose(handle);
+        return;
+    } // if
+
+    rc = kread(handle, song, size);
+    kclose(handle);
+    if (rc != size)
+    {
+        free(song);
+        return;
+    } // if
+
+    // save the file somewhere, so SDL_mixer can load it
+    GetPathFromEnvironment(filename, MAX_PATH, "tmpsong.mid");
+    handle = SafeOpenWrite(filename, filetype_binary);
+    
+    SafeWrite(handle, song, size);
+    close(handle);
+    free(song);
+    
+    //music_songdata = song;
+
+    music_musicchunk = Mix_LoadMUS(filename);
+    if (music_musicchunk != NULL)
+    {
+        // !!! FIXME: I set the music to loop. Hope that's okay. --ryan.
+        Mix_PlayMusic(music_musicchunk, -1);
+    } // if
+}
+#endif
+
+#ifdef ROTT
+// ROTT Special - SBF
+int MUSIC_PlaySongROTT(unsigned char *song, int size, int loopflag)
+{
+    char filename[MAX_PATH];
+    int handle;
+    
+    MUSIC_StopSong();
+
+    // save the file somewhere, so SDL_mixer can load it
+    GetPathFromEnvironment(filename, ApogeePath, "tmpsong.mid");
+    handle = SafeOpenWrite(filename);
+    
+    SafeWrite(handle, song, size);
+    close(handle);
+    
+    music_songdata = song;
+
+    // finally, we can load it with SDL_mixer
+    music_musicchunk = Mix_LoadMUS(filename);
+    if (music_musicchunk == NULL) {
+        return MUSIC_Error;
+    }
+    
+    Mix_PlayMusic(music_musicchunk, (loopflag == MUSIC_PlayOnce) ? 0 : -1);
+
+    return(MUSIC_Ok);
+} // MUSIC_PlaySongROTT
+#endif
+
+
+void MUSIC_SetContext(int context)
+{
+    musdebug("STUB ... MUSIC_SetContext().\n");
+    music_context = context;
+} // MUSIC_SetContext
+
+
+int MUSIC_GetContext(void)
+{
+    return(music_context);
+} // MUSIC_GetContext
+
+
+void MUSIC_SetSongTick(unsigned long PositionInTicks)
+{
+    musdebug("STUB ... MUSIC_SetSongTick().\n");
+} // MUSIC_SetSongTick
+
+
+void MUSIC_SetSongTime(unsigned long milliseconds)
+{
+    musdebug("STUB ... MUSIC_SetSongTime().\n");
+}// MUSIC_SetSongTime
+
+
+void MUSIC_SetSongPosition(int measure, int beat, int tick)
+{
+    musdebug("STUB ... MUSIC_SetSongPosition().\n");
+} // MUSIC_SetSongPosition
+
+
+void MUSIC_GetSongPosition(songposition *pos)
+{
+    musdebug("STUB ... MUSIC_GetSongPosition().\n");
+} // MUSIC_GetSongPosition
+
+
+void MUSIC_GetSongLength(songposition *pos)
+{
+    musdebug("STUB ... MUSIC_GetSongLength().\n");
+} // MUSIC_GetSongLength
+
+
+int MUSIC_FadeVolume(int tovolume, int milliseconds)
+{
+    Mix_FadeOutMusic(milliseconds);
+    return(MUSIC_Ok);
+} // MUSIC_FadeVolume
+
+
+int MUSIC_FadeActive(void)
+{
+    return((Mix_FadingMusic() == MIX_FADING_OUT) ? __FX_TRUE : __FX_FALSE);
+} // MUSIC_FadeActive
+
+
+void MUSIC_StopFade(void)
+{
+    musdebug("STUB ... MUSIC_StopFade().\n");
+} // MUSIC_StopFade
+
+
+void MUSIC_RerouteMidiChannel(int channel, int cdecl (*function)( int event, int c1, int c2 ))
+{
+    musdebug("STUB ... MUSIC_RerouteMidiChannel().\n");
+} // MUSIC_RerouteMidiChannel
+
+
+void MUSIC_RegisterTimbreBank(unsigned char *timbres)
+{
+    musdebug("STUB ... MUSIC_RegisterTimbreBank().\n");
+} // MUSIC_RegisterTimbreBank
+
+
+// end of fx_man.c ...

Added: tags/rott-1.1/rott/engine.c
===================================================================
--- tags/rott-1.1/rott/engine.c	                        (rev 0)
+++ tags/rott-1.1/rott/engine.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,419 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "watcom.h"
+#include "engine.h"
+#include "_engine.h"
+#include "rt_draw.h"
+#include "rt_door.h"
+#include "rt_stat.h"
+#include "rt_ted.h"
+#include "rt_view.h"
+#include <stdlib.h>
+//MED
+#include "memcheck.h"
+
+
+/*
+=============================================================================
+
+Global Variables                                                                                                                                 GLOBAL VARIABLES
+
+=============================================================================
+*/
+//wallcast_t posts[642];//bna++
+wallcast_t posts[800+2];//bna++
+//wallcast_t posts[321];
+int lasttilex;
+int lasttiley;
+/*
+=============================================================================
+
+Local Variables                                                                                                                                 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+static int xtilestep,ytilestep;
+static int c_vx,c_vy;
+
+void InitialCast ( void );
+void Cast ( int curx );
+
+void Interpolate (int x1, int x2)
+{
+   int i;
+   int dtexture;
+   int frac;
+   int dheight;
+   int hfrac;
+   int dx;
+
+   dx=x2-x1;
+   dtexture=(((posts[x2].texture-posts[x1].texture)<<12)+0x800)/dx;
+   dheight=(((posts[x2].wallheight-posts[x1].wallheight)<<8)+0x80)/dx;
+   frac=dtexture+(posts[x1].texture<<12);
+   hfrac=dheight+(posts[x1].wallheight<<8);
+   for (i=x1+1;i<=x2-1;i++,frac+=dtexture,hfrac+=dheight)
+      {
+      posts[i].lump=posts[x1].lump;
+      posts[i].posttype=posts[x1].posttype;
+      posts[i].offset=posts[x1].offset;
+      posts[i].alttile=posts[x1].alttile;
+      posts[i].texture=(frac>>12);
+      posts[i].wallheight=hfrac>>8;
+      }
+}
+
+void Refresh ( void )
+{
+   int x;
+
+// Cast Initial comb filter
+
+   InitialCast();
+
+   for (x=0;x<=viewwidth-4;x+=4)
+      {
+      if NOTSAMETILE(x,x+4)
+         {
+         Cast(x+2);
+         if NOTSAMETILE(x,x+2)
+            {
+            Cast(x+1);
+            }
+         else
+            Interpolate (x,x+2);
+         if NOTSAMETILE(x+2,x+4)
+            {
+            Cast(x+3);
+            }
+         else
+            Interpolate (x+2,x+4);
+         }
+      else
+         Interpolate(x,x+4);
+      }
+}
+
+
+void HitWall(int curx, int vertical, int xtile, int ytile)
+{
+   int num;
+
+   posts[curx].offset=(xtile<<7)+ytile;
+   posts[curx].lump = tilemap[xtile][ytile];
+   posts[curx].alttile=0;
+   posts[curx].posttype=0;
+
+   if (vertical<0)
+      {
+      xintercept=xtile<<16;
+      if (xtilestep<0)
+         xintercept+=0xffff;
+      yintercept=FixedScale(xintercept-viewx,c_vy,c_vx)+viewy;
+      if (posts[curx].lump & 0x4000)
+   	   {
+         if (tilemap[xtile-(xtilestep>>7)][ytile]&0x8000)
+            {
+            num=tilemap[xtile-(xtilestep>>7)][ytile];
+            if (num&0x4000)
+               {
+               if (maskobjlist[num&0x3ff]->sidepic)
+   	    	      posts[curx].lump = maskobjlist[num&0x3ff]->sidepic;
+               else
+   	            posts[curx].lump &= 0x3ff;
+               }
+            else
+   		 	   posts[curx].lump = doorobjlist[num&0x3ff]->sidepic;
+            }
+         else
+            {
+            if (posts[curx].lump&0x1000)
+               posts[curx].lump=animwalls[posts[curx].lump&0x3ff].texture;
+            else
+   		      posts[curx].lump &= 0x3ff;
+            }
+       	}
+      else if (posts[curx].lump & 0x2000)
+         {
+         if (IsWindow(xtile,ytile))
+            posts[curx].alttile=-1;
+         else
+            posts[curx].alttile=(MAPSPOT(xtile,ytile,2))+1;
+   		posts[curx].lump &= 0x3ff;
+         }
+      else if (posts[curx].lump & 0x1000)
+         posts[curx].lump=animwalls[posts[curx].lump&0x3ff].texture;
+      else if (posts[curx].lump & 0x800)
+         {
+         posts[curx].lump &= 0x3ff;
+         posts[curx].posttype=2;
+         }
+      posts[curx].texture=yintercept-(ytile<<16);
+//      posts[curx].texture&=0xffff;
+      if (posts[curx].texture<0)
+         posts[curx].texture=0;
+      if (posts[curx].texture>65535)
+         posts[curx].texture=65535;
+      if (xtilestep<0)
+         posts[curx].texture^=0xffff;
+      posts[curx].posttype+=1;
+//      posts[curx].texture=(posts[curx].texture+firstcoloffset)&65535;
+      }
+   else
+      {
+      yintercept=ytile<<16;
+      if (ytilestep<0)
+         yintercept+=0xffff;
+      xintercept=FixedScale(yintercept-viewy,c_vx,c_vy)+viewx;
+      if (posts[curx].lump & 0x4000)
+	      {    // check for adjacent doors
+         if (tilemap[xtile][ytile-ytilestep]&0x8000)
+            {
+            num=tilemap[xtile][ytile-ytilestep];
+            if (num&0x4000)
+               {
+               if (maskobjlist[num&0x3ff]->sidepic)
+		    	      posts[curx].lump = maskobjlist[num&0x3ff]->sidepic;
+               else
+			         posts[curx].lump &= 0x3ff;
+               }
+            else
+		    	   posts[curx].lump = doorobjlist[num&0x3ff]->sidepic;
+            }
+         else
+            {
+            if (posts[curx].lump&0x1000)
+               posts[curx].lump=animwalls[posts[curx].lump&0x3ff].texture;
+            else
+   		      posts[curx].lump &= 0x3ff;
+            }
+    		}
+      else if (posts[curx].lump & 0x2000)
+         {
+         if (IsWindow(xtile,ytile))
+            posts[curx].alttile=-1;
+         else
+            posts[curx].alttile=(MAPSPOT(xtile,ytile,2))+1;
+   		posts[curx].lump &= 0x3ff;
+         }
+      else if (posts[curx].lump & 0x1000)
+         posts[curx].lump=animwalls[posts[curx].lump&0x3ff].texture;
+      else if (posts[curx].lump & 0x800)
+         {
+         posts[curx].lump &= 0x3ff;
+         posts[curx].posttype=2;
+         }
+      posts[curx].texture=xintercept-(xtile<<16);
+//      posts[curx].texture&=0xffff;
+      if (posts[curx].texture<0)
+         posts[curx].texture=0;
+      if (posts[curx].texture>65535)
+         posts[curx].texture=65535;
+      if (ytilestep>0)
+         posts[curx].texture^=0xffff;
+//      posts[curx].posttype+=0;
+//      posts[curx].texture=(posts[curx].texture+firstcoloffset)&65535;
+      }
+   posts[curx].wallheight=CalcHeight();
+}
+
+void InitialCast ( void )
+{
+   int snx,sny;
+   int incr[2];
+   int thedir[2];
+   int cnt;
+   int grid[2];
+   int index;
+   int curx;
+
+   c_vx=c_startx;
+   c_vy=c_starty;
+   for (curx=0;curx<=viewwidth;curx+=4)
+      {
+      snx=viewx&0xffff;
+      sny=viewy&0xffff;
+
+      if (c_vx>0)
+         {
+         thedir[0]=1;
+         xtilestep=0x80;
+         snx^=0xffff;
+         incr[1]=-c_vx;
+         }
+      else
+         {
+         thedir[0]=-1;
+         xtilestep=-0x80;
+         incr[1]=c_vx;
+         }
+      if (c_vy>0)
+         {
+         thedir[1]=1;
+         ytilestep=1;
+         sny^=0xffff;
+         incr[0]=c_vy;
+         }
+      else
+         {
+         thedir[1]=-1;
+         ytilestep=-1;
+         incr[0]=-c_vy;
+         }
+      cnt=FixedMul(snx,incr[0])+FixedMul(sny,incr[1]);
+      grid[0]=viewx>>16;
+      grid[1]=viewy>>16;
+      do
+         {
+         int tile;
+
+         index=(cnt>=0);
+         cnt+=incr[index];
+         spotvis[grid[0]][grid[1]]=1;
+         grid[index]+=thedir[index];
+
+         if ((tile=tilemap[grid[0]][grid[1]])!=0)
+            {
+            if (tile&0x8000)
+               {
+               if ( (!(tile&0x4000)) && (doorobjlist[tile&0x3ff]->action==dr_closed))
+                  {
+                  spotvis[grid[0]][grid[1]]=1;
+                  if (doorobjlist[tile&0x3ff]->flags&DF_MULTI)
+                     MakeWideDoorVisible(tile&0x3ff);
+                  do
+                     {
+                     index=(cnt>=0);
+                     cnt+=incr[index];
+                     grid[index]+=thedir[index];
+                     if ((tilemap[grid[0]][grid[1]]!=0) &&
+                        (!(tilemap[grid[0]][grid[1]]&0x8000)) )
+                        break;
+                     }
+                  while (1);
+                  break;
+                  }
+               else
+                  continue;
+               }
+            else
+               {
+               mapseen[grid[0]][grid[1]]=1;
+               break;
+               }
+            }
+         }
+      while (1);
+      HitWall(curx, cnt-incr[index], grid[0], grid[1]);
+      c_vx+=viewsin<<2;
+      c_vy+=viewcos<<2;
+      }
+}
+
+
+void Cast ( int curx )
+{
+   int snx,sny;
+   int incr[2];
+   int thedir[2];
+   int cnt;
+   int grid[2];
+   int index;
+
+   c_vx=c_startx+(curx*viewsin);
+   c_vy=c_starty+(curx*viewcos);
+   snx=viewx&0xffff;
+   sny=viewy&0xffff;
+
+   if (c_vx>0)
+      {
+      thedir[0]=1;
+      xtilestep=0x80;
+      snx^=0xffff;
+      incr[1]=-c_vx;
+      }
+   else
+      {
+      thedir[0]=-1;
+      xtilestep=-0x80;
+      incr[1]=c_vx;
+      }
+   if (c_vy>0)
+      {
+      thedir[1]=1;
+      ytilestep=1;
+      sny^=0xffff;
+      incr[0]=c_vy;
+      }
+   else
+      {
+      thedir[1]=-1;
+      ytilestep=-1;
+      incr[0]=-c_vy;
+      }
+   cnt=FixedMul(snx,incr[0])+FixedMul(sny,incr[1]);
+   grid[0]=viewx>>16;
+   grid[1]=viewy>>16;
+   do
+      {
+      int tile;
+
+      index=(cnt>=0);
+      cnt+=incr[index];
+      spotvis[grid[0]][grid[1]]=1;
+      grid[index]+=thedir[index];
+
+      if ((tile=tilemap[grid[0]][grid[1]])!=0)
+         {
+         if (tile&0x8000)
+            {
+            if ( (!(tile&0x4000)) && (doorobjlist[tile&0x3ff]->action==dr_closed))
+               {
+               spotvis[grid[0]][grid[1]]=1;
+               if (doorobjlist[tile&0x3ff]->flags&DF_MULTI)
+                  MakeWideDoorVisible(tile&0x3ff);
+               do
+                  {
+                  index=(cnt>=0);
+                  cnt+=incr[index];
+                  grid[index]+=thedir[index];
+                  if ((tilemap[grid[0]][grid[1]]!=0) &&
+                     (!(tilemap[grid[0]][grid[1]]&0x8000)) )
+                     break;
+                  }
+               while (1);
+               break;
+               }
+            else
+               continue;
+            }
+         else
+            {
+            mapseen[grid[0]][grid[1]]=1;
+            break;
+            }
+         }
+      }
+   while (1);
+   HitWall(curx, cnt-incr[index], grid[0], grid[1]);
+}
+

Added: tags/rott-1.1/rott/engine.h
===================================================================
--- tags/rott-1.1/rott/engine.h	                        (rev 0)
+++ tags/rott-1.1/rott/engine.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,52 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _engine_public
+#define _engine_public
+
+#include "modexlib.h"
+//***************************************************************************
+//
+// ENGINE.C
+//
+//***************************************************************************
+
+typedef struct
+{
+  int      offset;
+  int      wallheight;
+  int      ceilingclip;
+  int      floorclip;
+  int      texture;
+  int      lump;
+  int      posttype;
+  int      alttile;
+} wallcast_t;
+extern wallcast_t posts[800+2];//bna++ JUST MAKE IT MAX RES
+//extern wallcast_t posts[642];//bna++
+//extern wallcast_t posts[321];
+
+extern int lasttilex;
+extern int lasttiley;
+
+void Refresh ( void );
+
+#define IsWindow(x,y)       (MAPSPOT((x),(y),2)==13)
+
+#endif

Added: tags/rott-1.1/rott/f_scale.asm
===================================================================
--- tags/rott-1.1/rott/f_scale.asm	                        (rev 0)
+++ tags/rott-1.1/rott/f_scale.asm	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,162 @@
+        .386
+        .MODEL  flat
+
+SCREENROW = 96
+
+;================
+;
+; R_DrawFilmColumn
+;
+;================
+
+SCREENWIDTH = 96
+
+
+.data
+
+loopcount       dd      0
+pixelcount      dd      0
+
+_cin_yl          dd      0
+_cin_yh          dd      0
+_cin_ycenter     dd      0
+_cin_iscale      dd      0
+_cin_texturemid  dd      0
+_cin_source      dd      0
+
+PUBLIC _cin_yl       
+PUBLIC _cin_yh         
+PUBLIC _cin_ycenter    
+PUBLIC _cin_iscale     
+PUBLIC _cin_texturemid 
+PUBLIC _cin_source   
+
+EXTRN   _ylookup:DWORD
+
+.code
+SEGMENT text USE32
+        ALIGN   16
+
+PROC   R_DrawFilmColumn_
+PUBLIC   R_DrawFilmColumn_
+        push    ebp
+        mov     ebp,[_cin_yl]
+        mov     ebx,ebp
+        add     edi,[_ylookup+ebx*4]
+        mov     eax,[_cin_yh]
+        inc     eax
+        sub     eax,ebp                         ; pixel count
+        mov     [pixelcount],eax                ; save for final pixel
+        js      done                            ; nothing to scale
+        shr     eax,1                           ; double pixel count
+        mov     [loopcount],eax
+
+        mov     ecx,[_cin_iscale]
+
+        mov     eax,[_cin_ycenter]
+        sub     eax,ebp
+        imul    ecx
+        mov     ebp,[_cin_texturemid]
+        sub     ebp,eax
+
+        mov     esi,[_cin_source]
+
+
+        mov     ebx,[_cin_iscale]
+        mov     eax,OFFSET patch1+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET patch2+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+
+; eax           aligned colormap
+; ebx           aligned colormap
+; ecx,edx       scratch
+; esi           virtual source
+; edi           moving destination pointer
+; ebp           frac
+
+        mov     ecx,ebp                                 ; begin calculating first pixel
+        add     ebp,ebx                                 ; advance frac pointer
+        shr     ecx,16                                      ; finish calculation for first pixel
+        mov     edx,ebp                                 ; begin calculating second pixel
+        add     ebp,ebx                                 ; advance frac pointer
+        shr     edx,16                                      ; finish calculation for second pixel
+        mov     al,[esi+ecx]                    ; get first pixel
+        mov     bl,[esi+edx]                    ; get second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     doubleloop                              ; at least two pixels to map
+        jmp     checklast
+
+        ALIGN   16
+doubleloop:
+        mov     ecx,ebp                                 ; begin calculating third pixel
+patch1:
+        add     ebp,12345678h                   ; advance frac pointer
+        mov     [edi],al                                ; write first pixel
+        shr     ecx,16                                      ; finish calculation for third pixel
+        mov     edx,ebp                                 ; begin calculating fourth pixel
+patch2:
+        add     ebp,12345678h                   ; advance frac pointer
+        mov     [edi+SCREENWIDTH],bl    ; write second pixel
+        shr     edx,16                                      ; finish calculation for fourth pixel
+        mov     al,[esi+ecx]                    ; get third pixel
+        add     edi,SCREENWIDTH*2               ; advance to third pixel destination
+        mov     bl,[esi+edx]                    ; get fourth pixel
+        dec     [loopcount]                             ; done with loop?
+        jnz     doubleloop
+
+; check for final pixel
+checklast:
+        test    [pixelcount],1
+        jz      done
+        mov     [edi],al                                ; write final pixel
+done:
+        pop     ebp
+        ret
+
+ENDP
+
+
+
+;============================
+;
+; DrawFilmPost
+;
+;
+;============================
+
+IDEAL
+PROC	DrawFilmPost_
+PUBLIC	DrawFilmPost_
+
+;EDI - Destination for post
+;ESI - Source data
+;ECX - Length of post
+
+        mov     ebx,ecx
+        shr     ebx,1
+        jz      dfextra
+dfloop:
+        mov     ax,[esi]
+        mov     [edi],al
+        add     esi,2
+        add     edi,SCREENROW*2
+        mov     [edi-SCREENROW],ah
+        dec     ebx
+        jnz     dfloop
+        MASKFLAG ecx,1
+        jz      dfdone
+dfextra:
+        mov     al,[esi]
+        mov     [edi],al
+dfdone:
+	ret
+
+ENDP
+
+ENDS
+
+
+END
+

Added: tags/rott-1.1/rott/f_scale.h
===================================================================
--- tags/rott-1.1/rott/f_scale.h	                        (rev 0)
+++ tags/rott-1.1/rott/f_scale.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _f_scale_public
+#define _f_scale_public
+
+extern int cin_yl;
+extern int cin_yh;
+extern int cin_ycenter;
+extern int cin_iscale;
+extern int cin_texturemid;
+extern byte * cin_source;
+
+void R_DrawFilmColumn (byte * buf);
+void DrawFilmPost (byte * buf, byte * src, int height);
+
+#if (defined __WATCOMC__)
+#pragma aux R_DrawFilmColumn parm [EDI] modify exact [eax ebx ecx edx esi edi]
+#pragma aux DrawFilmPost parm [EDI] [ESI] [ECX] modify exact [eax ecx edx edi esi ebx]
+#endif
+
+#endif

Added: tags/rott-1.1/rott/fli_def.h
===================================================================
--- tags/rott-1.1/rott/fli_def.h	                        (rev 0)
+++ tags/rott-1.1/rott/fli_def.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,104 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/* Flic.h - header file containing structure of a flic file.
+ *
+ * Copyright (c) 1992 Jim Kent.  This file may be freely used, modified,
+ * copied and distributed.  This file was first published as part of
+ * an article for Dr. Dobb's Journal March 1993 issue.
+ */
+
+#ifndef FLIC_H		/* Keep this from being included twice */
+#define FLIC_H
+
+#pragma pack (1)
+	/* Flic Header */
+
+#warning fli_def structures need to be packed
+
+typedef struct
+	{
+	Long	size;		/* Size of flic including this header. */
+	Ushort 	type;		/* Either FLI_TYPE or FLC_TYPE below. */
+	Ushort	frames;		/* Number of frames in flic. */
+	Ushort	width;		/* Flic width in pixels. */
+	Ushort	height;		/* Flic height in pixels. */
+	Ushort	depth;		/* Bits per pixel.  (Always 8 now.) */
+	Ushort	flags;		/* FLI_FINISHED | FLI_LOOPED ideally. */
+	Long 	speed;		/* Delay between frames. */
+	Short	reserved1;	/* Set to zero. */
+	Ulong	created;	/* Date of flic creation. (FLC only.) */
+	Ulong	creator;	/* Serial # of flic creator. (FLC only.) */
+	Ulong	updated;	/* Date of flic update. (FLC only.) */
+	Ulong	updater;	/* Serial # of flic updater. (FLC only.) */
+	Ushort	aspect_dx;	/* Width of square rectangle. (FLC only.) */
+	Ushort	aspect_dy;	/* Height of square rectangle. (FLC only.) */
+	Char 	reserved2[38];/* Set to zero. */
+	Long 	oframe1;	/* Offset to frame 1. (FLC only.) */
+	Long 	oframe2;	/* Offset to frame 2. (FLC only.) */
+	Char 	reserved3[40];/* Set to zero. */
+	} FlicHead;
+	/* Values for FlicHead.type */
+#define FLI_TYPE 0xAF11u	/* 320x200 .FLI type ID */
+#define FLC_TYPE 0xAF12u	/* Variable rez .FLC type ID */
+	/* Values for FlicHead.flags */
+#define FLI_FINISHED 0x0001
+#define FLI_LOOPED	 0x0002
+
+	/* Optional Prefix Header */
+typedef struct
+	{
+	Long size;		/* Size of prefix including header. */
+	Ushort type;	/* Always PREFIX_TYPE. */
+	Short chunks;	/* Number of subchunks in prefix. */
+	Char reserved[8];/* Always 0. */
+	} PrefixHead;
+	/* Value for PrefixHead.type */
+#define PREFIX_TYPE  0xF100u
+
+	/* Frame Header */
+typedef struct
+	{
+	Long size;		/* Size of frame including header. */
+	Ushort type;	/* Always FRAME_TYPE */
+	Short chunks;	/* Number of chunks in frame. */
+	Char reserved[8];/* Always 0. */
+	} FrameHead;
+	/* Value for FrameHead.type */
+#define FRAME_TYPE 0xF1FAu
+
+	/* Chunk Header */
+typedef struct
+	{
+	Long size;		/* Size of chunk including header. */
+	Ushort type;	/* Value from ChunkTypes below. */
+	} ChunkHead;
+enum ChunkTypes
+	{
+	COLOR_256 = 4,	/* 256 level color pallette info. (FLC only.) */
+	DELTA_FLC = 7,	/* Word-oriented delta compression. (FLC only.) */
+	COLOR_64 = 11,	/* 64 level color pallette info. */
+	DELTA_FLI = 12,	/* Byte-oriented delta compression. */
+	BLACK = 13,		/* whole frame is color 0 */
+	BYTE_RUN = 15,	/* Byte run-length compression. */
+	LITERAL = 16,	/* Uncompressed pixels. */
+	PSTAMP = 18,	/* "Postage stamp" chunk. (FLC only.) */
+	};
+
+#endif /* FLIC_H */

Added: tags/rott-1.1/rott/fli_glob.h
===================================================================
--- tags/rott-1.1/rott/fli_glob.h	                        (rev 0)
+++ tags/rott-1.1/rott/fli_glob.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,22 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+void PlayFlic ( char * name, unsigned char * buffer, int usefile, int loop);
+
+

Added: tags/rott-1.1/rott/fli_main.c
===================================================================
--- tags/rott-1.1/rott/fli_main.c	                        (rev 0)
+++ tags/rott-1.1/rott/fli_main.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,598 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/* readflic.c - This module contains the routines to read and decompress
+ * a flic.  They assume Intel byte ordering,  but otherwise should be
+ * fairly portable.  They call machine specific stuff in pcclone.c.
+ * This file starts with the low level decompression routines - first
+ * for colors and then for pixels.  Then it goes to the higher level
+ * exported flic_xxxx routines as prototyped in readflic.h.
+ *
+ * Copyright (c) 1992 Jim Kent.  This file may be freely used, modified,
+ * copied and distributed.  This file was first published as part of
+ * an article for Dr. Dobb's Journal March 1993 issue.
+ */
+
+#include "cin_glob.h"
+#include <errno.h>
+#include <string.h>
+#include <io.h>
+#include "fli_type.h"
+#include "fli_util.h"
+#include "fli_def.h"
+#include "fli_main.h"
+//MED
+#include "memcheck.h"
+
+
+
+typedef void ColorOut(Screen *s, int start, Color  *colors, int count);
+	/* This is the type of output parameter to our decode_color below.
+	 * Not coincedently screen_put_color is of this type. */
+
+static void decode_color(Uchar  *data
+, Flic *flic, Screen *s, ColorOut *output)
+	/* Decode color map.  Put results into output.  The two color
+	 * compressions are identical except for whether the RGB values
+	 * are 0-63 or 0-255.  Passing in an output that does the appropriate
+	 * shifting on the way to the real pallete lets us use the same
+	 * code for both COLOR_64 and COLOR_256 compression.
+	 */
+{
+int start = 0;
+Uchar  *cbuf = (Uchar  *)data;
+Short  *wp = (Short  *)cbuf;
+Short ops;
+int count;
+
+ops = *wp;
+cbuf += sizeof(*wp);
+while (--ops >= 0)
+	{
+	start += *cbuf++;
+	if ((count = *cbuf++) == 0)
+		count = 256;
+   (*output)(s, start, (Color  *)cbuf, count);
+	cbuf += 3*count;
+	start += count;
+	}
+}
+
+static void decode_color_256(Uchar  *data, Flic *flic, Screen *s)
+	/* Decode COLOR_256 chunk. */
+{
+decode_color(data, flic, s, screen_put_colors);
+}
+
+static void decode_color_64(Uchar  *data, Flic *flic, Screen *s)
+	/* Decode COLOR_64 chunk. */
+{
+decode_color(data, flic, s, screen_put_colors_64);
+}
+
+
+static void decode_byte_run(Uchar  *data, Flic *flic, Screen *s)
+	/* Byte-run-length decompression. */
+{
+int x,y;
+int width = flic->head.width;
+int height = flic->head.height;
+Char psize;
+Char  *cpt = data;
+int end;
+
+y = flic->yoff;
+end = flic->xoff + width;
+while (--height >= 0)
+	{
+	x = flic->xoff;
+	cpt += 1;	/* skip over obsolete opcount byte */
+	psize = 0;
+	while ((x+=psize) < end)
+		{
+		psize = *cpt++;
+		if (psize >= 0)
+			{
+			screen_repeat_one(s, x, y, *cpt++, psize);
+			}
+		else
+			{
+			psize = -psize;
+         screen_copy_seg(s, x, y, (Pixel  *)cpt, psize);
+			cpt += psize;
+			}
+		}
+	y++;
+	}
+}
+
+static void decode_delta_fli(Uchar  *data, Flic *flic, Screen *s)
+	/* Fli style delta decompression. */
+{
+int xorg = flic->xoff;
+int yorg = flic->yoff;
+Short  *wpt = (Short  *)data;
+Uchar  *cpt = (Uchar  *)(wpt + 2);
+int x,y;
+Short lines;
+Uchar opcount;
+Char psize;
+
+y = yorg + *wpt++;
+lines = *wpt;
+while (--lines >= 0)
+	{
+	x = xorg;
+	opcount = *cpt++;
+	while (opcount > 0)
+		{
+		x += *cpt++;
+		psize = *cpt++;
+		if (psize < 0)
+			{
+			psize = -psize;
+			screen_repeat_one(s, x, y, *cpt++, psize);
+			x += psize;
+			opcount-=1;
+			}
+		else
+			{
+         screen_copy_seg(s, x, y, (Pixel  *)cpt, psize);
+			cpt += psize;
+			x += psize;
+			opcount -= 1;
+			}
+		}
+	y++;
+	}
+}
+
+
+static void decode_delta_flc(Uchar  *data, Flic *flic, Screen *s)
+	/* Flc-style delta decompression.  The data is word oriented though
+    * a lot of the control info (how  to skip, how many words to
+	 * copy) are byte oriented still to save space. */
+{
+int xorg = flic->xoff;
+int yorg = flic->yoff;
+int width = flic->head.width;
+int x,y;
+Short lp_count;
+Short opcount;
+int psize;
+union {Short  *w; Uchar  *ub; Char  *b; Pixels2  *p2;} wpt;
+int lastx;
+
+
+	lastx = xorg + width - 1;
+	wpt.ub = data;
+	lp_count = *wpt.w++;
+	y = yorg;
+	goto LPACK;
+
+SKIPLINES:	/* Advance over some lines. */
+	y -= opcount;
+
+LPACK:		/* do next line */
+	if ((opcount = *wpt.w++) >= 0)
+		goto DO_SS2OPS;
+	if( ((Ushort)opcount) & 0x4000) /* skip lines */
+		goto SKIPLINES;
+	screen_put_dot(s,(Uchar)opcount,lastx,y); /* put dot at eol with low byte */
+	if((opcount = *wpt.w++) == 0)
+	{
+		++y;
+		if (--lp_count > 0)
+			goto LPACK;
+		goto OUT;
+	}
+DO_SS2OPS:
+	x = xorg;
+
+PPACK:				/* do next packet */
+	x += *wpt.ub++;
+	psize = *wpt.b++;
+	if ((psize += psize) >= 0)
+	{
+      screen_copy_seg(s, x, y, (Pixel  *)wpt.ub, psize);
+		x += psize;
+		wpt.ub += psize;
+		if (--opcount != 0)
+			goto PPACK;
+		++y;
+		if (--lp_count > 0)
+			goto LPACK;
+	}
+	else
+	{
+		psize = -psize;
+		screen_repeat_two(s, x, y, *wpt.p2++, psize>>1);
+		x += psize;
+		if (--opcount != 0)
+			goto PPACK;
+		++y;
+		if (--lp_count > 0)
+			goto LPACK;
+	}
+OUT:
+	return;
+}
+
+static void decode_black(Uchar  *data, Flic *flic, Screen *s)
+	/* Decode a BLACK chunk.  Set frame to solid color 0 one
+	 * line at a time. */
+{
+Pixels2 black;
+int i;
+int height = flic->head.height;
+int width = flic->head.width;
+int x = flic->xoff;
+int y = flic->yoff;
+
+black.pixels[0] = black.pixels[1] = 0;
+for (i=0; i<height; ++i)
+	{
+	screen_repeat_two(s, x, y+i, black, width/2);
+	if (width & 1)	/* if odd set last pixel */
+		screen_put_dot(s, x+width-1, y+i, 0);
+	}
+}
+
+static void decode_literal(Uchar  *data, Flic *flic, Screen *s)
+	/* Decode a LITERAL chunk.  Just copy data to screen one line at
+	 * a time. */
+{
+int i;
+int height = flic->head.height;
+int width = flic->head.width;
+int x = flic->xoff;
+int y = flic->yoff;
+
+for (i=0; i<height; ++i)
+	{
+   screen_copy_seg(s, x, y+i, (Pixel  *)data, width);
+	data += width;
+	}
+}
+
+ErrCode SetupFlicAccess (Flic * flic)
+{
+if (flic->usefile==TRUE)
+   {
+   return file_open_to_read(&flic->handle, flic->name);
+   }
+else
+   {
+   flic->flicoffset=0;
+   return Success;
+   }
+}
+
+ErrCode CopyNextFlicBlock (Flic * flic, MemPtr buf, Ulong size)
+{
+ErrCode err;
+
+if (flic->usefile==TRUE)
+   {
+   err = file_read_big_block(flic->handle, buf, size);
+   return err;
+   }
+else
+   {
+   memcpy(buf, flic->flicbuffer+flic->flicoffset, size);
+   flic->flicoffset+=size;
+   return Success;
+   }
+}
+
+void    SetFlicOffset (Flic * flic, Ulong offset )
+{
+if (flic->usefile==TRUE)
+   {
+   lseek(flic->handle,offset,SEEK_SET);
+   }
+else
+   {
+   flic->flicoffset = offset;
+   }
+}
+
+
+ErrCode flic_open(Flic *flic, char *name, MemPtr buf, Boolean usefile)
+	/* Open flic file.  Read header and verify it's a flic.
+	 * Seek to first frame. */
+{
+ErrCode err;
+
+ClearStruct(flic);		/* Start at a known state. */
+flic->usefile=usefile;  /* use file or buffer */
+flic->name = name;      /* Save name for future use. */
+flic->flicbuffer=buf;   /* save address of flicbuffer */
+
+if ((err = SetupFlicAccess (flic)) >= Success)
+   {
+   if ((err = CopyNextFlicBlock (flic, (Uchar *)&flic->head, sizeof(flic->head)))
+      >= Success)
+      {
+      if (flic->head.type == FLC_TYPE)
+         {
+         /* Seek frame 1. */
+         SetFlicOffset (flic, flic->head.oframe1 );
+         return Success;
+         }
+      if (flic->head.type == FLI_TYPE)
+         {
+         /* Do some conversion work here. */
+         flic->head.oframe1 = sizeof(flic->head);
+         flic->head.speed = flic->head.speed * 1000L / 70L;
+         return Success;
+         }
+      else
+         {
+         err = ErrBadFlic;
+         }
+      }
+   }
+flic_close(flic);    /* Close down and scrub partially opened flic. */
+return err;
+}
+
+
+void flic_close(Flic *flic)
+	/* Close flic file and scrub flic. */
+{
+if (flic->usefile==TRUE)
+   {
+   close(flic->handle);
+   }
+ClearStruct(flic);		/* Discourage use after close. */
+}
+
+static ErrCode decode_frame(Flic *flic
+, FrameHead *frame, Uchar  *data, Screen *s)
+	/* Decode a frame that is in memory already into screen.
+	 * Here we just loop through each chunk calling appropriate
+	 * chunk decoder.
+	 */
+{
+int i;
+ChunkHead  *chunk;
+
+for (i=0; i<frame->chunks; ++i)
+	{
+   chunk = (ChunkHead  *)data;
+	data += chunk->size;
+	switch (chunk->type)
+		{
+		case COLOR_256:
+         decode_color_256((Uchar  *)(chunk+1), flic, s);
+			break;
+		case DELTA_FLC:
+         decode_delta_flc((Uchar  *)(chunk+1), flic, s);
+			break;
+		case COLOR_64:
+         decode_color_64((Uchar  *)(chunk+1), flic, s);
+			break;
+		case DELTA_FLI:
+         decode_delta_fli((Uchar  *)(chunk+1), flic, s);
+			break;
+		case BLACK:
+         decode_black((Uchar  *)(chunk+1), flic, s);
+			break;
+		case BYTE_RUN:
+         decode_byte_run((Uchar  *)(chunk+1), flic, s);
+			break;
+		case LITERAL:
+         decode_literal((Uchar  *)(chunk+1), flic, s);
+			break;
+		default:
+			break;
+		}
+	}
+return Success;
+}
+
+ErrCode flic_next_frame(Flic *flic, Screen *screen)
+	/* Advance to next frame of flic. */
+{
+FrameHead head;
+ErrCode err;
+MemPtr bb;
+long size;
+
+if ((err = CopyNextFlicBlock (flic, (Uchar *)&head, sizeof(head))) >= Success)
+	{
+	if (head.type == FRAME_TYPE)
+		{
+		size = head.size - sizeof(head);	/* Don't include head. */
+		if (size > 0)
+			{
+         if ((err = big_alloc(&bb, size)) >= Success)
+				{
+            if ((err = CopyNextFlicBlock (flic, bb, size)) >= Success)
+					{
+               err = decode_frame(flic, &head, bb, screen);
+					}
+            big_free(&bb);
+				}
+			}
+		}
+	else
+		{
+		err = ErrBadFrame;
+		}
+	}
+return err;
+}
+
+
+static Ulong calc_end_time(Ulong millis)
+	/* Little helper subroutine to find out when to start on next
+	 * frame. */
+{
+return (GetCinematicTime() + ( (millis * CLOCKSPEED) / 4000l) );
+}
+
+static ErrCode wait_til(Ulong end_time, Machine *machine)
+	/* This waits until key is hit or end_time arrives.
+	 * Return Success if timed out,  ErrCancel if key hit.
+	 * Insures keyboard will be polled at least once.
+	 */
+{
+   do
+     {
+     if (CinematicAbort()!=0)
+        return ErrCancel;
+     }
+   while (GetCinematicTime() < end_time);
+	return Success;
+}
+
+ErrCode flic_play_once(Flic *flic, Machine *machine)
+	/* Play a flic through once. */
+{
+ErrCode err;
+int i;
+Ulong end_time;
+
+for (i=0; i<flic->head.frames; ++i)
+	{
+   end_time = calc_end_time(flic->head.speed);
+	if ((err = flic_next_frame(flic, &machine->screen)) < Success)
+		break;
+	if ((err = wait_til(end_time, machine)) < Success)
+		break;
+	}
+return err;
+}
+
+static ErrCode fill_in_frame2(Flic *flic)
+	/* This figures out where the second frame of the flic is
+	 * (useful for playing in a loop).  */
+{
+FrameHead head;
+ErrCode err;
+
+SetFlicOffset (flic, flic->head.oframe1 );
+if ((err = CopyNextFlicBlock (flic, (MemPtr)&head, sizeof(head))) < Success)
+	return err;
+flic->head.oframe2 = flic->head.oframe1 + head.size;
+return Success;
+}
+
+ErrCode flic_play_loop(Flic *flic, Machine *machine)
+	/* Play a flic until key is pressed. */
+{
+int i;
+Ulong end_time;
+ErrCode err;
+
+if (flic->head.oframe2 == 0)
+	{
+	fill_in_frame2(flic);
+	}
+	/* Seek to first frame. */
+SetFlicOffset (flic, flic->head.oframe1 );
+	/* Save time to move on. */
+end_time = calc_end_time(flic->head.speed);
+	/* Display first frame. */
+if ((err = flic_next_frame(flic, &machine->screen)) < Success)
+	return err;
+for (;;)
+	{
+		/* Seek to second frame */
+   SetFlicOffset (flic, flic->head.oframe2 );
+		/* Loop from 2nd frame thru ring frame*/
+	for (i=0; i<flic->head.frames; ++i)
+		{
+		if (wait_til(end_time, machine) < Success)
+			return Success;		/* Time out is a success here. */
+		if ((err = flic_next_frame(flic, &machine->screen)) < Success)
+			return err;
+      end_time = calc_end_time(flic->head.speed);
+		}
+	}
+}
+
+
+static char *err_strings[] =
+	{
+	"Unspecified error",
+	"Not enough memory",
+	"Not a flic file",
+	"Bad frame in flic",
+	NULL,
+	NULL,
+	"Couldn't open display",
+	"Couldn't open keyboard",
+	"User canceled action",
+	};
+
+char *flic_err_string(ErrCode err)
+	/* Return a string that describes an error. */
+{
+	if (err >= Success)
+		return "Success";		/* Shouldn't happen really... */
+	if (err == ErrOpen || err == ErrRead)
+		return strerror(errno);	/* Get Disk IO error from DOS. */
+	err = -err;
+	err -= 1;
+	if (err > ArrayEls(err_strings))
+		return "Unknown error";
+	return err_strings[err];
+}
+
+
+static void center_flic(Flic *flic, Screen *s)
+	/* Set flic.xoff and flic.yoff so flic plays centered rather
+	 * than in upper left corner of display. */
+{
+	flic->xoff = (screen_width(s) - (signed)flic->head.width)/2;
+	flic->yoff = (screen_height(s) - (signed)flic->head.height)/2;
+}
+
+void PlayFlic ( char * name, unsigned char * buffer, int usefile, int loop)
+{
+ErrCode err;
+Flic flic;
+Machine machine;
+
+if ((err = machine_open(&machine)) >= Success)
+	{
+   if ((err = flic_open(&flic, name, buffer, usefile)) >= Success)
+      {
+      center_flic(&flic, &machine.screen);
+      if (loop==0)
+         {
+         err = flic_play_once(&flic, &machine);
+         }
+      else
+         {
+         err = flic_play_loop(&flic, &machine);
+         }
+      flic_close(&flic);
+      }
+	machine_close(&machine);
+	}
+if (err < Success && err != ErrCancel)
+   {
+   Error("Play Flic had troubles with %s.\n%s.\n",name, flic_err_string(err));
+	}
+}
+

Added: tags/rott-1.1/rott/fli_main.h
===================================================================
--- tags/rott-1.1/rott/fli_main.h	                        (rev 0)
+++ tags/rott-1.1/rott/fli_main.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,92 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/* Readflic.h - file containing prototypes and other
+ * structural info for readflic program.
+ *
+ * Copyright (c) 1992 Jim Kent.  This file may be freely used, modified,
+ * copied and distributed.  This file was first published as part of
+ * an article for Dr. Dobb's Journal March 1993 issue.
+ */
+
+/* Some handy macros I use in lots of programs: */
+
+#define ArrayEls(a) (sizeof(a)/sizeof((a)[0]))
+	/* Count up number of elements in an array */
+
+#define ClearMem(buf,size)	memset(buf, 0, size)
+	/* Clear a block of memory. */
+
+#define ClearStruct(pt)	ClearMem(pt, sizeof(*(pt)))
+	/* Clear a structure (pass in pointer) */
+
+
+/* Data structures peculiar to readflic program: */
+
+typedef struct
+	{
+	FlicHead head;	/* Flic file header. */
+	int handle;		/* File handle. */
+	int frame;		/* Current frame in flic. */
+	char *name;		/* Name from flic_open.  Helps error reporting. */
+	int xoff,yoff;	/* Offset to display flic at. */
+   MemPtr flicbuffer; // address of flicbuffer in memory
+   int flicoffset;
+   Boolean usefile;
+	} Flic;
+
+
+/* Prototypes peculiar to readflic program: */
+
+ErrCode flic_open(Flic *flic, char *name, MemPtr buf, Boolean usefile);
+	/* Open flic file.  Read header and verify it's a flic. */
+
+void flic_close(Flic *flic);
+	/* Close flic file and scrub flic. */
+
+ErrCode flic_play_once(Flic *flic, Machine *machine);
+	/* Play a flic through once. */
+
+ErrCode flic_play_loop(Flic *flic, Machine *machine);
+	/* Play a flic until key is pressed. */
+
+ErrCode flic_next_frame(Flic *flic, Screen *screen);
+	/* Advance to next frame of flic. */
+
+ErrCode SetupFlicAccess (Flic * flic);
+
+ErrCode CopyNextFlicBlock (Flic * flic, MemPtr buf, Ulong size);
+
+void    SetFlicOffset (Flic * flic, Ulong offset );
+
+
+char *flic_err_string(ErrCode err);
+
+/* Various error codes flic reader can get. */
+#define ErrNoMemory	-2		/* Not enough memory. */
+#define ErrBadFlic	-3		/* File isn't a flic. */
+#define ErrBadFrame	-4		/* Bad frame in flic. */
+#define ErrOpen		-5		/* Couldn't open file.  Check errno. */
+#define ErrRead		-6		/* Couldn't read file.  Check errno. */
+#define ErrDisplay	-7		/* Couldn't open display. */
+#define ErrClock	-8		/* Couldn't open clock. */
+#define ErrKey		-9		/* Couldn't open keyboard. */
+#define ErrCancel	-10		/* User cancelled. */
+
+

Added: tags/rott-1.1/rott/fli_type.h
===================================================================
--- tags/rott-1.1/rott/fli_type.h	                        (rev 0)
+++ tags/rott-1.1/rott/fli_type.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,53 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/* Types.h - integer types defined for portability between compilers and
+ * notational convenience.
+ *
+ * Copyright (c) 1992 Jim Kent.  This file may be freely used, modified,
+ * copied and distributed.  This file was first published as part of
+ * an article for Dr. Dobb's Journal March 1993 issue.
+ */
+
+#ifndef TYPES_H		/* Prevent file from being included twice. */
+#define TYPES_H
+
+typedef signed char Char;		/* Signed 8 bits. */
+typedef unsigned char Uchar;	/* Unsigned 8 bits. */
+typedef short Short;			/* Signed 16 bits please. */
+typedef unsigned short Ushort;	/* Unsigned 16 bits please. */
+typedef int Long;				/* Signed 32 bits. */
+typedef unsigned int Ulong;	/* Unsigned 32 bits. */
+
+typedef int Boolean;			/* TRUE or FALSE value. */
+typedef int ErrCode;			/* ErrXXX or Success. */
+typedef int FileHandle;			/* OS file handle. */
+
+	/* Values for Boolean types */
+#define FALSE 0
+#define TRUE (!FALSE)
+
+	/* Values for ErrCodes */
+#define Success		0		/* Things are fine. */
+#define AError     -1    /* Unclassified error. */
+
+#define int86 int386
+#define inportb inp
+#define outportb outp
+#endif /* TYPES_H */

Added: tags/rott-1.1/rott/fli_util.c
===================================================================
--- tags/rott-1.1/rott/fli_util.c	                        (rev 0)
+++ tags/rott-1.1/rott/fli_util.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,414 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/* pcclone.c - This file contains all the machine specific bits of the
+ * flic reader.  It's job is to set up data structures and routines for
+ * the Screen, Clock, and Key structures,  and the Machine structure
+ * that contains them all.
+ *
+ * For optimum performance a flic-reader should be coded in assembler.
+ * However you can get significantly greater performance merely by
+ * recoding in assembler the three routines: screen_copy_seg(),
+ * screen_repeat_one() and screen_repeat_two().
+ *
+ * Copyright (c) 1992 Jim Kent.  This file may be freely used, modified,
+ * copied and distributed.  This file was first published as part of
+ * an article for Dr. Dobb's Journal March 1993 issue.
+ */
+
+#include "cin_glob.h"
+#include <bios.h>
+#include <dos.h>
+#include <time.h>
+#include <stdlib.h>
+#include <mem.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <io.h>
+#include <conio.h>
+#include "fli_type.h"
+#include "fli_util.h"
+#include "fli_def.h"
+#include "fli_main.h"
+//MED
+#include "memcheck.h"
+
+static Ushort screenlookup[200];
+
+/** Screen oriented stuff. **/
+
+static Boolean set_vmode(Uchar mode)
+	/* Ask bios to set video mode. */
+{
+union REGS regs;
+
+regs.h.ah = 0;		/* Set Video Mode request. */
+regs.h.al = mode;	/* For our specific mode. */
+int86(0x10, &regs, &regs);
+return TRUE;
+// return (regs.x.cflag == 0);	/* Carry flag clear? */
+}
+
+static Uchar get_vmode()
+	/* Ask bios for current video mode. */
+{
+union REGS regs;
+
+regs.h.ah = 0xF;			/* Get Video Mode request. */
+int86(0x10, &regs, &regs);
+return regs.h.al;
+}
+
+ErrCode screen_open(Screen *s)
+	/* Put machine into graphics mode and fill out screen structure. */
+{
+ClearStruct(s);			/* Start in a known state... */
+s->old_mode = get_vmode();
+if (set_vmode(0x13))
+	{
+	if (get_vmode() == 0x13)
+		{
+      int i;
+
+		s->is_open = TRUE;	/* Now it's open. */
+		s->width = 320;
+		s->height = 200;
+      for (i=0;i<200;i++)
+         screenlookup[i]=320*i;
+      s->pixels = (unsigned char *)0xA0000;  /* Base video screen address. */
+		return Success;
+		}
+	}
+/* If got to here have failed.  Restore old video mode and return
+ * failure code. */
+set_vmode(s->old_mode);
+return ErrDisplay;
+}
+
+void screen_close(Screen *s)
+	/* Close screen.  Restore original display mode. */
+{
+if (s->is_open)		/* Don't do this twice... */
+	{
+//   set_vmode(s->old_mode);
+	ClearStruct(s);		/* Discourage use after it's closed... */
+	}
+}
+
+int screen_width(Screen *s)
+	/* Return width of screen. */
+{
+return s->width;
+}
+
+int screen_height(Screen *s)
+	/* Return height of screen. */
+{
+return s->height;
+}
+
+void screen_put_dot(Screen *s, int x, int y, Pixel color)
+	/* Set one dot. */
+{
+	/* First clip it. */
+if (x < 0 || y < 0 || x >= s->width || y >= s->height)
+	return;
+
+	/* Then set it. */
+s->pixels[screenlookup[y] + x] = color;
+}
+
+static Boolean line_clip(Screen *s, int *px, int *py, int *pwidth)
+	/* Clip a horizontal line segment so that it fits on the screen.
+	 * Return FALSE if clipped out entirely. */
+{
+int x = *px;
+int y = *py;
+int width = *pwidth;
+int xend = x + width;
+
+if (y < 0 || y >= s->height || xend < 0 || x >= s->width)
+	return FALSE;	/* Clipped off screen. */
+if (x < 0)
+	{
+	*pwidth = width = width + x;		/* and shortens width. */
+	*px = 0;
+	}
+if (xend > s->width)
+	{
+	*pwidth = width = width - (xend - s->width);
+	}
+if (width < 0)
+	return FALSE;
+return TRUE;
+}
+
+void screen_copy_seg(Screen *s, int x, int y, Pixel  *pixels, int count)
+	/* Copy pixels from memory into screen. */
+{
+Pixel  *pt;
+int unclipped_x = x;
+
+	/* First let's do some clipping. */
+if (!line_clip(s, &x, &y, &count))
+	return;
+
+pixels += (x - unclipped_x);   /* Clipping change in start position. */
+
+	/* Calculate start screen address. */
+pt = s->pixels + (unsigned)screenlookup[y] + (unsigned)x;
+
+	/* Copy pixels to display. */
+memcpy (pt,pixels,count);
+}
+
+void screen_repeat_one(Screen *s, int x, int y, Pixel color, int count)
+	/* Draw a horizontal line of a solid color */
+{
+Pixel  *pt;
+
+	/* First let's do some clipping. */
+if (!line_clip(s, &x, &y, &count))
+	return;
+
+	/* Calculate start screen address. */
+pt = s->pixels + (unsigned)screenlookup[y] + (unsigned)x;
+
+	/* Repeat pixel on display. */
+   memset (pt,color,count);
+}
+
+void screen_repeat_two(Screen *s, int x, int y, Pixels2 pixels2, int count)
+	/* Repeat 2 pixels count times on screen. */
+{
+Pixels2  *pt;
+int is_odd;
+
+	/* First let's do some clipping. */
+count <<= 1;		/* Convert from word to pixel count. */
+if (!line_clip(s, &x, &y, &count))
+	return;
+is_odd = (count&1);		/* Did it turn odd after clipping?  Ack! */
+count >>= 1;			/* Convert back to word count. */
+
+	/* Calculate start screen address. */
+pt = (Pixels2  *)(s->pixels + (unsigned)screenlookup[y] + (unsigned)x);
+
+while (--count >= 0)	/* Go set screen 2 pixels at a time. */
+	*pt++ = pixels2;
+
+if (is_odd)				/* Deal with pixel at end of screen if needed. */
+	{
+   Pixel  *end = (Pixel  *)pt;
+	*end = pixels2.pixels[0];
+	}
+}
+
+
+void screen_put_colors(Screen *s, int start, Color  *colors, int count)
+	/* Set count colors in color map starting at start.  RGB values
+	 * go from 0 to 255. */
+{
+int end = start + count;
+int ix;
+
+for (ix = start; ix < end; ++ix)
+	{
+	outportb(0x3C8, ix);
+	outportb(0x3C9, colors->r>>2);
+	outportb(0x3C9, colors->g>>2);
+	outportb(0x3C9, colors->b>>2);
+	++colors;
+	}
+}
+
+void screen_put_colors_64(Screen *s, int start, Color  *colors, int count)
+	/* Set count colors in color map starting at start.  RGB values
+	 * go from 0 to 64. */
+{
+int end = start + count;
+int ix;
+
+for (ix = start; ix < end; ++ix)
+	{
+	outportb(0x3C8, ix);
+	outportb(0x3C9, colors->r);
+	outportb(0x3C9, colors->g);
+	outportb(0x3C9, colors->b);
+	++colors;
+	}
+}
+
+#if 0
+/** Clock oriented stuff. **/
+
+#define CMODE	0x43
+#define CDATA	0x40
+
+ErrCode clock_open(Clock *c)
+	/* Set up clock and store speed of clock.  */
+{
+c->speed = 4608;        /* Our peculiar speed.  */
+outportb(CMODE, 0x34);  /* Change from divide by two to linear. */
+outportb(CDATA, 0);     /* Set period to highest available. */
+outportb(CDATA, 0);
+return Success;
+}
+
+void clock_close(Clock *c)
+	/* Return clock to normal. */
+{
+outportb(CMODE, 0x36);  /* Change from linear to divide by two. */
+outportb(CDATA, 0);     /* Set period to highest available. */
+outportb(CDATA, 0);
+}
+
+Ulong clock_ticks(Clock *c)
+	/* Get current clock tick. */
+{
+/* This routine returns a clock with occassional spikes where time will
+ * look like its running backwards 1/18th of a second.  The resolution
+ * of the clock is 1/(18*256) = 1/4608 second.  The spikes are ok for
+ * our purposes since the wait loop will just ignore them. */
+union REGS regs;
+Uchar chip_time;
+Ulong time;
+
+regs.h.ah = 0;				/* Go ask BIOS timer services */
+int86(0x1A, &regs, &regs);	/* for time in 1/18ths second. */
+outportb(CMODE,0);			/* Latch time at timer chip. */
+inportb(CDATA);				/* Read in LSB of chip time and discard. */
+chip_time = inportb(CDATA);	/* Read in MSB of chip time and save. */
+chip_time = -(signed char)chip_time;
+	/* We calculate the time using 3 bytes from the BIOS 18hz counter
+	 * and one byte from the timer chip itself.  We discard the hi
+	 * byte of the BIOS time,  shift the rest left by 8, and
+	 * fill in the low byte with the MSB from the chip timer.
+	 * This looks a little more complicated than this because
+	 * the bios time is in various registers - cx for the hi word
+	 * and dx for the low word. */
+time = (Ulong)regs.h.cl << 24L;		/* Get MSB of our final time. */
+time += (Ulong)regs.w.dx << 8L;     /* Fold in middle two bytes. */
+time += (Ulong)chip_time;			/* Add in LSB from chip. */
+return time;
+}
+
+
+/** Keyboard oriented stuff. **/
+
+ErrCode key_open(Key *key)
+	/* Set up keyboard. */
+{
+return Success;		/* Pretty easy on a PC. */
+}
+
+void key_close(Key *key)
+	/* Close keyboard. */
+{
+return;				/* Also very easy under DOS. */
+}
+
+Boolean key_ready(Key *key)
+	/* See if a key is ready. */
+{
+unsigned val;
+
+if ((val = _bios_keybrd(_KEYBRD_READY)) == 0)
+	return FALSE;
+else
+	{
+	key->ascii = val;
+	key->scancode = val;
+	return TRUE;
+	}
+}
+
+Uchar key_read(Key *key)
+	/* Get next key. */
+{
+unsigned val;
+
+val = _bios_keybrd(_KEYBRD_READ);
+key->ascii = val;
+key->scancode = val;
+return key->ascii;
+}
+
+#endif
+
+/** MemPtr stuff - to allocate and free blocks of memory > 64K. */
+
+ErrCode big_alloc(MemPtr *bb, Ulong size)
+	/* Allocate a big block. */
+{
+   (*bb) = SafeMalloc (size);
+   return Success;
+}
+
+void big_free(MemPtr *bb)
+	/* Free up a big block. */
+{
+   SafeFree(*bb);
+}
+
+/** Stuff for reading files - regular and over 64k blocks at a time. **/
+
+ErrCode file_open_to_read(FileHandle *phandle, char *name)
+	/* Open a binary file to read. */
+{
+   *phandle = SafeOpenRead(name);
+	return Success;
+}
+
+ErrCode file_read_big_block(FileHandle handle, MemPtr bb, Ulong size)
+	/* Read in a big block.  Could be bigger than 64K. */
+{
+   SafeRead (handle,bb,size);
+   return Success;
+}
+
+
+/** Machine oriented stuff - open and close the whole banana. **/
+
+ErrCode machine_open(Machine *machine)
+	/* Open up machine: keyboard, clock, and screen. */
+{
+ErrCode err;
+
+ClearStruct(machine);	/* Start it in a known state. */
+//if ((err = key_open(&machine->key)) >= Success)
+   {
+//   if ((err = clock_open(&machine->clock)) >= Success)
+		{
+		if ((err = screen_open(&machine->screen)) >= Success)
+			return Success;
+//      clock_close(&machine->clock);
+		}
+//   key_close(&machine->key);
+	}
+return err;
+}
+
+void machine_close(Machine *machine)
+	/* Close down machine. */
+{
+screen_close(&machine->screen);
+//clock_close(&machine->clock);
+//key_close(&machine->key);
+}

Added: tags/rott-1.1/rott/fli_util.h
===================================================================
--- tags/rott-1.1/rott/fli_util.h	                        (rev 0)
+++ tags/rott-1.1/rott/fli_util.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,164 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/* pcclone.h - machine specific parts of readflic.  Structures and
+ * prototypes for polling the keyboard,  checking the time,
+ * writing to the video screen, allocating large blocks of memory
+ * and reading files.
+ *
+ * Copyright (c) 1992 Jim Kent.  This file may be freely used, modified,
+ * copied and distributed.  This file was first published as part of
+ * an article for Dr. Dobb's Journal March 1993 issue.
+ */
+
+#ifndef PCCLONE_H	/* Prevent file from being included twice. */
+#define PCCLONE_H
+
+typedef Uchar Pixel;			/* Pixel type. */
+
+typedef struct
+	{
+	Uchar r,g,b;
+	} Color;					/* One color map entry r,g,b 0-255. */
+
+typedef struct
+	{
+	Pixel pixels[2];
+	} Pixels2;					/* For word-oriented run length encoding */
+
+typedef struct
+	{
+   Pixel  *pixels;   /* Set to AOOO:0000 for hardware. */
+	int width, height;	/* Dimensions of screen. (320x200) */
+	int old_mode;		/* Mode screen was in originally. */
+	Boolean is_open;	/* Is screen open? */
+	} Screen;					/* Device specific screen type. */
+
+
+	/* Prototypes for routines that work on display screen. */
+
+ErrCode screen_open(Screen *s);
+	/* Put machine into graphics mode and fill out screen structure. */
+
+void screen_close(Screen *s);
+	/* Close screen.  Restore original display mode. */
+
+int screen_width(Screen *s);
+	/* Return width of screen. */
+
+int screen_height(Screen *s);
+	/* Return height of screen. */
+
+void screen_put_dot(Screen *s, int x, int y, Pixel color);
+	/* Set one dot. */
+
+void screen_copy_seg(Screen *s, int x, int y, Pixel  *pixels, int count);
+	/* Copy pixels from memory into screen. */
+
+void screen_repeat_one(Screen *s, int x, int y, Pixel color, int count);
+	/* Draw a horizontal line of a solid color */
+
+void screen_repeat_two(Screen *s, int x,int y, Pixels2 pixels2, int count);
+	/* Repeat 2 pixels count times on screen. */
+
+void screen_put_colors(Screen *s, int start, Color  *colors, int count);
+	/* Set count colors in color map starting at start.  RGB values
+	 * go from 0 to 255. */
+
+void screen_put_colors_64(Screen *s, int start, Color  *colors, int count);
+	/* Set count colors in color map starting at start.  RGB values
+	 * go from 0 to 64. */
+
+
+/* Clock structure and routines. */
+
+typedef struct
+	{
+	Ulong speed;	/* Number of clock ticks per second. */
+	} Clock;
+
+ErrCode clock_open(Clock *clock);
+	/* Set up millisecond clock. */
+
+void clock_close(Clock *clock);
+	/* Return clock to normal. */
+
+Ulong clock_ticks(Clock *clock);
+	/* Get time in terms of clock->speed. */
+
+/* Keyboard structure and routines. */
+
+typedef struct
+	{
+	Uchar ascii;
+	Ushort scancode;
+	} Key;
+
+ErrCode key_open(Key *key);
+	/* Set up keyboard. */
+
+void key_close(Key *key);
+	/* Close keyboard. */
+
+Boolean key_ready(Key *key);
+	/* See if a key is ready. */
+
+Uchar key_read(Key *key);
+	/* Get next key. */
+
+
+/** MemPtr - handles allocating big blocks of memory (>64K) on the
+ ** PC.  On other machines may be much simpler. */
+
+typedef Uchar * MemPtr;
+
+ErrCode big_alloc(MemPtr *bb, Ulong size);
+	/* Allocate a big block. */
+
+void big_free(MemPtr *bb);
+	/* Free up a big block. */
+
+/** Stuff for reading files - regular and over 64k blocks at a time. **/
+
+ErrCode file_open_to_read(FileHandle *phandle, char *name);
+	/* Open a binary file to read. */
+
+ErrCode file_read_block(FileHandle handle, void  *block, unsigned size);
+	/* Read in a block.  If read less than size return error code. */
+
+ErrCode file_read_big_block(FileHandle handle, MemPtr bb, Ulong size);
+	/* Read in a big block.  Could be bigger than 64K. */
+
+
+
+/** Machine structure - contains all the machine dependent stuff. **/
+
+typedef struct
+	{
+	Screen screen;
+	Clock clock;
+	Key key;
+	} Machine;
+
+ErrCode machine_open(Machine *machine);
+	/* Open up machine: keyboard, clock, screen. */
+
+void machine_close(Machine *machine);
+	/* Close down machine. */
+#endif /* PCCLONE_H */

Added: tags/rott-1.1/rott/fx_man.c
===================================================================
--- tags/rott-1.1/rott/fx_man.c	                        (rev 0)
+++ tags/rott-1.1/rott/fx_man.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1307 @@
+/*
+ * A reimplementation of Jim Dose's FX_MAN routines, using  SDL_mixer 1.2.
+ *   Whee. FX_MAN is also known as the "Apogee Sound System", or "ASS" for
+ *   short. How strangely appropriate that seems.
+ *
+ * Written by Ryan C. Gordon. (icculus at clutteredmind.org)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+
+#if (defined __WATCOMC__)
+#include "dukesnd_watcom.h"
+#endif
+
+#if (!defined __WATCOMC__)
+#define cdecl
+#endif
+
+#include "SDL.h"
+#include "SDL_mixer.h"
+#include "rt_def.h"      // ROTT music hack
+#include "rt_cfg.h"      // ROTT music hack
+#include "rt_util.h"     // ROTT music hack
+#include "fx_man.h"
+#include "music.h"
+
+#define __FX_TRUE  (1 == 1)
+#define __FX_FALSE (!__FX_TRUE)
+
+#define DUKESND_DEBUG       "DUKESND_DEBUG"
+
+#ifndef min
+#define min(a, b)  (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef max
+#define max(a, b)  (((a) > (b)) ? (a) : (b))
+#endif
+
+typedef struct __DUKECHANINFO
+{
+    int in_use;                 // 1 or 0.
+    int priority;               // priority, defined by application.
+    Uint32 birthday;            // ticks when channel was grabbed.
+    unsigned long callbackval;  // callback value from application.
+} duke_channel_info;
+
+
+static char warningMessage[80];
+static char errorMessage[80];
+static int fx_initialized = 0;
+static int numChannels = MIX_CHANNELS;
+static void (*callback)(unsigned long);
+static int reverseStereo = 0;
+static int reverbDelay = 256;
+static int reverbLevel = 0;
+static int fastReverb = 0;
+static FILE *debug_file = NULL;
+static int initialized_debugging = 0;
+static int maxReverbDelay = 256;
+static int mixerIsStereo = 1;
+static duke_channel_info *chaninfo = NULL;
+
+#define HandleOffset       1
+
+/* these come from the real ASS */
+#define MV_MaxPanPosition  31
+#define MV_NumPanPositions ( MV_MaxPanPosition + 1 )
+#define MV_MaxVolume       63
+
+#define MIX_VOLUME( volume ) \
+   ( ( max( 0, min( ( volume ), 255 ) ) * ( MV_MaxVolume + 1 ) ) >> 8 )
+   
+typedef struct
+{
+    unsigned char left;
+    unsigned char right;
+} Pan;
+    
+static Pan MV_PanTable[ MV_NumPanPositions ][ MV_MaxVolume + 1 ];
+
+static void MV_CalcPanTable
+   (
+   void
+   )
+
+   {
+   int   level;
+   int   angle;
+   int   distance;
+   int   HalfAngle;
+   int   ramp;
+
+   HalfAngle = ( MV_NumPanPositions / 2 );
+
+   for( distance = 0; distance <= MV_MaxVolume; distance++ )
+      {
+      level = ( 255 * ( MV_MaxVolume - distance ) ) / MV_MaxVolume;
+      for( angle = 0; angle <= HalfAngle / 2; angle++ )
+         {
+         ramp = level - ( ( level * angle ) /
+            ( MV_NumPanPositions / 4 ) );
+
+         MV_PanTable[ angle ][ distance ].left = ramp;
+         MV_PanTable[ HalfAngle - angle ][ distance ].left = ramp;
+         MV_PanTable[ HalfAngle + angle ][ distance ].left = level;
+         MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].left = level;
+
+         MV_PanTable[ angle ][ distance ].right = level;
+         MV_PanTable[ HalfAngle - angle ][ distance ].right = level;
+         MV_PanTable[ HalfAngle + angle ][ distance ].right = ramp;
+         MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].right = ramp;
+         }
+      }
+   }
+/* end ASS copy-pastage */
+
+#ifdef __WATCOMC__
+#pragma aux (__cdecl) channelDoneCallback;
+#endif
+
+// This function is called whenever an SDL_mixer channel completes playback.
+//  We use this for state management and calling the application's callback.
+static void channelDoneCallback(int channel)
+{
+    Mix_FreeChunk(Mix_GetChunk(channel));
+    if (callback)
+    {
+        callback(chaninfo[channel].callbackval);
+        chaninfo[channel].in_use = 0;
+    } // if
+} // channelDoneCallback
+
+
+// This gets called all over the place for information and debugging messages.
+//  If the user set the DUKESND_DEBUG environment variable, the messages
+//  go to the file that is specified in that variable. Otherwise, they
+//  are ignored for the expense of the function call. If DUKESND_DEBUG is
+//  set to "-" (without the quotes), then the output goes to stdout.
+static void snddebug(const char *fmt, ...) __attribute__((format(printf,1,2)));
+static void snddebug(const char *fmt, ...)
+{
+    va_list ap;
+
+    if (debug_file)
+    {
+        fprintf(debug_file, "DUKESND: ");
+        va_start(ap, fmt);
+        vfprintf(debug_file, fmt, ap);
+        va_end(ap);
+        fprintf(debug_file, "\n");
+        fflush(debug_file);
+    } // if
+} // snddebug
+
+
+// FIXME: Consolidate this code.
+// Same as snddebug(), but a different tag is put on each line.
+static void musdebug(const char *fmt, ...) __attribute__((format(printf,1,2)));
+static void musdebug(const char *fmt, ...)
+{
+    va_list ap;
+
+    if (debug_file)
+    {
+        fprintf(debug_file, "DUKEMUS: ");
+        va_start(ap, fmt);
+        vfprintf(debug_file, fmt, ap);
+        va_end(ap);
+        fprintf(debug_file, "\n");
+        fflush(debug_file);
+    } // if
+} // snddebug
+
+
+static void init_debugging(void)
+{
+    const char *envr;
+
+    if (initialized_debugging)
+        return;
+
+    envr = getenv(DUKESND_DEBUG);
+    if (envr != NULL)
+    {
+        if (strcmp(envr, "-") == 0)
+            debug_file = stdout;
+        else
+            debug_file = fopen(envr, "w");
+
+        if (debug_file == NULL)
+            fprintf(stderr, "DUKESND: -WARNING- Could not open debug file!\n");
+        else
+            setbuf(debug_file, NULL);
+    } // if
+
+    initialized_debugging = 1;
+} // init_debugging
+
+
+// find an available SDL_mixer channel, and reserve it.
+//  This would be a race condition, but hey, it's for a DOS game.  :)
+static int grabMixerChannel(int priority)
+{
+    int replaceable = -1;
+    int i;
+
+    for (i = 0; i < numChannels; i++)
+    {
+        if (chaninfo[i].in_use == 0)
+        {
+            chaninfo[i].in_use = 1;
+            chaninfo[i].priority = priority;
+            chaninfo[i].birthday = SDL_GetTicks();
+            return(i);
+        } // if
+
+        // !!! FIXME: Should this just be lower priority, or equal too?
+        if (chaninfo[i].priority <= priority)
+        {
+            if ((replaceable == -1) ||
+                (chaninfo[i].birthday < chaninfo[replaceable].birthday))
+            {
+                replaceable = i;
+            } // if
+        } // if
+    } // for
+
+    // if you land here, all mixer channels are playing...
+    if (replaceable != -1)  // nothing expendable right now.
+    {
+        chaninfo[replaceable].in_use = 1;
+        chaninfo[replaceable].priority = priority;
+        chaninfo[replaceable].birthday = SDL_GetTicks();
+    } // if
+
+    return(replaceable);
+} // grabMixerChannel
+
+
+// !!! FIXME: Is this correct behaviour?
+char *FX_ErrorString( int ErrorNumber )
+{
+    switch (ErrorNumber)
+    {
+        case FX_Warning:
+            return(warningMessage);
+
+        case FX_Error:
+            return(errorMessage);
+
+        case FX_Ok:
+            return("OK; no error.");
+
+        case FX_ASSVersion:
+            return("Incorrect sound library version.");
+
+        case FX_BlasterError:
+            return("SoundBlaster Error.");
+
+        case FX_SoundCardError:
+            return("General sound card error.");
+
+        case FX_InvalidCard:
+            return("Invalid sound card.");
+
+        case FX_MultiVocError:
+            return("Multiple voc error.");
+
+        case FX_DPMI_Error:
+            return("DPMI error.");
+
+        default:
+            return("Unknown error.");
+    } // switch
+
+    assert(0);    // shouldn't hit this point.
+    return(NULL);
+} // FX_ErrorString
+
+
+static void setWarningMessage(const char *msg)
+{
+    strncpy(warningMessage, msg, sizeof (warningMessage));
+    // strncpy() doesn't add the null char if there isn't room...
+    warningMessage[sizeof (warningMessage) - 1] = '\0';
+    snddebug("Warning message set to [%s].", warningMessage);
+} // setErrorMessage
+
+
+static void setErrorMessage(const char *msg)
+{
+    strncpy(errorMessage, msg, sizeof (errorMessage));
+    // strncpy() doesn't add the null char if there isn't room...
+    errorMessage[sizeof (errorMessage) - 1] = '\0';
+    snddebug("Error message set to [%s].", errorMessage);
+} // setErrorMessage
+
+int FX_SetupCard( int SoundCard, fx_device *device )
+{
+    init_debugging();
+
+    snddebug("FX_SetupCard looking at card id #%d...", SoundCard);
+
+    if (device == NULL)  // sanity check.
+    {
+        setErrorMessage("fx_device is NULL in FX_SetupCard!");
+        return(FX_Error);
+    } // if
+
+        // Since the actual hardware is abstracted out on modern operating
+        //  systems, we just pretend that the system's got a SoundScape.
+        //  I always liked that card, even though Ensoniq screwed me on OS/2
+        //  drivers back in the day.  :)
+    if (SoundCard != SoundScape)
+    {
+        setErrorMessage("Card not found.");
+        snddebug("We pretend to be an Ensoniq SoundScape only.");
+        return(FX_Error);
+    } // if
+
+    device->MaxVoices = 8;
+    device->MaxSampleBits = 16;       // SDL_mixer downsamples if needed.
+    device->MaxChannels = 2;          // SDL_mixer converts to mono if needed.
+
+    return(FX_Ok);
+} // FX_SetupCard
+
+
+static void output_versions(const char *libname, const SDL_version *compiled,
+							const SDL_version *linked)
+{
+    snddebug("This program was compiled against %s %d.%d.%d,\n"
+             " and is dynamically linked to %d.%d.%d.\n", libname,
+             compiled->major, compiled->minor, compiled->patch,
+             linked->major, linked->minor, linked->patch);
+}
+
+
+static void output_version_info(void)
+{
+    SDL_version compiled;
+    const SDL_version *linked;
+
+    snddebug("Library check...");
+
+    SDL_VERSION(&compiled);
+    linked = SDL_Linked_Version();
+    output_versions("SDL", &compiled, linked);
+
+    MIX_VERSION(&compiled);
+    linked = Mix_Linked_Version();
+    output_versions("SDL_mixer", &compiled, linked);
+} // output_version_info
+
+
+int FX_Init(int SoundCard, int numvoices, int numchannels,
+            int samplebits, unsigned mixrate)
+{
+    Uint16 audio_format = 0;
+    int blocksize;
+
+    init_debugging();
+
+    snddebug("INIT! card=>%d, voices=>%d, chan=>%d, bits=>%d, rate=>%du...",
+                SoundCard, numvoices, numchannels, samplebits, mixrate);
+
+    if (fx_initialized)
+    {
+        setErrorMessage("Sound system is already initialized.");
+        return(FX_Error);
+    } // if
+
+    if (SoundCard != SoundScape) // We pretend there's a SoundScape installed.
+    {
+        setErrorMessage("Card not found.");
+        snddebug("We pretend to be an Ensoniq SoundScape only.");
+        return(FX_Error);
+    } // if
+
+        // other sanity checks...
+    if ((numvoices < 0) || (numvoices > 8))
+    {
+        setErrorMessage("Invalid number of voices to mix (must be 0-8).");
+        return(FX_Error);
+    } // if
+
+    if ((numchannels != MonoFx) && (numchannels != StereoFx))
+    {
+        setErrorMessage("Invalid number of channels (must be 1 or 2).");
+        return(FX_Error);
+    } // if
+
+    if ((samplebits != 8) && (samplebits != 16))
+    {
+        setErrorMessage("Invalid sample size (must be 8 or 16).");
+        return(FX_Error);
+    } // if
+
+    // build pan tables
+    MV_CalcPanTable();
+    
+    SDL_ClearError();
+    if (SDL_Init(SDL_INIT_AUDIO) < 0)
+    {
+        setErrorMessage("SDL_Init(SDL_INIT_AUDIO) failed!");
+        snddebug("SDL_GetError() reports: [%s].", SDL_GetError());
+        return(FX_Error);
+    } // if
+
+    audio_format = (samplebits == 8) ? AUDIO_U8 : AUDIO_S16SYS;
+    if (Mix_OpenAudio(mixrate, audio_format, numchannels, 256) < 0)
+    {
+        setErrorMessage(SDL_GetError());
+        return(FX_Error);
+    } // if
+
+    output_version_info();
+
+    numChannels = Mix_AllocateChannels(numvoices);
+    if (numChannels != numvoices)
+    {
+        setErrorMessage(SDL_GetError());
+        Mix_CloseAudio();
+        return(FX_Error);
+    } // if
+
+    blocksize = sizeof (duke_channel_info) * numvoices;
+    chaninfo = malloc(blocksize);
+    if (chaninfo == NULL)  // uhoh.
+    {
+        setErrorMessage("Out of memory");
+        Mix_CloseAudio();
+        return(FX_Error);
+    } // if
+    memset(chaninfo, '\0', blocksize);
+
+    Mix_ChannelFinished(channelDoneCallback);
+    maxReverbDelay = (int) (((float) mixrate) * 0.5);
+
+    Mix_QuerySpec(NULL, NULL, &mixerIsStereo);
+    mixerIsStereo = (mixerIsStereo == 2);
+
+    fx_initialized = 1;
+    return(FX_Ok);
+} // FX_Init
+
+
+int FX_Shutdown( void )
+{
+    snddebug("shutting down sound subsystem.");
+
+    if (!fx_initialized)
+    {
+        setErrorMessage("Sound system is not currently initialized.");
+        return(FX_Error);
+    } // if
+
+    Mix_CloseAudio();
+    callback = NULL;
+    free(chaninfo);
+    chaninfo = NULL;
+    reverseStereo = 0;
+    reverbLevel = 0;
+    fastReverb = 0;
+    fx_initialized = 0;
+    maxReverbDelay = 256;
+    return(FX_Ok);
+} // FX_Shutdown
+
+
+int FX_SetCallBack(void (*func)(unsigned long))
+{
+    callback = func;
+    return(FX_Ok);
+} // FX_SetCallBack
+
+
+void FX_SetVolume(int volume)
+{
+    snddebug("setting master volume to %f.2 percent.", (volume / 255.0) * 100);
+    Mix_Volume(-1, volume >> 1);  // it's 0-128 in SDL_mixer, not 0-255.
+} // FX_SetVolume
+
+
+int FX_GetVolume(void)
+{
+    return(Mix_Volume(-1, -1) << 1);
+} // FX_GetVolume
+
+
+void FX_SetReverseStereo(int setting)
+{
+    snddebug("Reverse stereo set to %s.\n", setting ? "ON" : "OFF");
+    Mix_SetReverseStereo(MIX_CHANNEL_POST, setting);
+    reverseStereo = setting;
+} // FX_SetReverseStereo
+
+
+int FX_GetReverseStereo(void)
+{
+    return(reverseStereo);
+} // FX_GetReverseStereo
+
+
+void FX_SetReverb(int reverb)
+{
+    reverbLevel = reverb;
+    fastReverb = 0;
+
+#if 1
+    // !!! FIXME
+    if (reverbLevel)
+        setWarningMessage("reverb filter is not yet implemented!");
+#endif
+} // FX_SetReverb
+
+
+void FX_SetFastReverb(int reverb)
+{
+    reverbLevel = reverb;
+    fastReverb = 1;
+
+#if 1
+    // !!! FIXME
+    if (reverbLevel)
+        setWarningMessage("fast reverb filter is not yet implemented!");
+#endif
+} // FX_SetFastReverb
+
+
+int FX_GetMaxReverbDelay(void)
+{
+    return(maxReverbDelay);
+} // FX_GetMaxReverbDelay
+
+
+int FX_GetReverbDelay(void)
+{
+    return(reverbDelay);
+} // FX_GetReverbDelay
+
+
+void FX_SetReverbDelay(int delay)
+{
+        // !!! FIXME: Should I be clamping these values?
+    if (delay < 256)
+        delay = 256;
+
+    if (delay > maxReverbDelay)
+        delay = maxReverbDelay;
+
+    reverbDelay = delay;
+
+#if 1
+    // !!! FIXME
+    setWarningMessage("reverb delay is not yet implemented!");
+#endif
+} // FX_SetReverbDelay
+
+
+int FX_VoiceAvailable(int priority)
+{
+    int chan = grabMixerChannel(priority);
+    int rc = (chan != -1);
+
+    if (rc)
+        chaninfo[chan].in_use = 0;
+
+    return(rc);
+} // FX_VoiceAvailable
+
+
+static int doSetPan(int handle, int vol, int left,
+                    int right, int checkIfPlaying)
+{
+    int retval = FX_Warning;
+
+    if ((handle < 0) || (handle >= numChannels))
+        setWarningMessage("Invalid handle in doSetPan().");
+    else if ((checkIfPlaying) && (!Mix_Playing(handle)))
+        setWarningMessage("voice is no longer playing in doSetPan().");
+    else
+    {
+        if (mixerIsStereo)
+        {
+            if ((left < 0) || (left > 255) ||
+                (right < 0) || (right > 255))
+            {
+                setErrorMessage("Invalid argument to FX_SetPan().");
+                retval = FX_Error;
+            } // if
+
+            else
+            {
+                Mix_SetPanning(handle, left, right);
+            } // else
+        } // if
+        else
+        {
+            if ((vol < 0) || (vol > 255))
+            {
+                setErrorMessage("Invalid argument to FX_SetPan().");
+                retval = FX_Error;
+            } // if
+            else
+            {
+                // volume must be from 0-128, so the ">> 1" converts.
+                Mix_Volume(handle, vol >> 1);
+            } // else
+        } // else
+
+        retval = FX_Ok;
+    } // else
+
+    return(retval);
+} // doSetPan
+
+
+int FX_SetPan(int handle, int vol, int left, int right)
+{
+    return(doSetPan(handle - HandleOffset, vol, left, right, 1));
+} // FX_SetPan
+
+
+int FX_SetPitch(int handle, int pitchoffset)
+{
+    snddebug("FX_SetPitch() ... NOT IMPLEMENTED YET!");
+    return(FX_Ok);
+} // FX_SetPitch
+
+
+int FX_SetFrequency(int handle, int frequency)
+{
+    snddebug("FX_SetFrequency() ... NOT IMPLEMENTED YET!");
+    return(FX_Ok);
+} // FX_SetFrequency
+
+
+
+// If this returns FX_Ok, then chunk and chan will be filled with the
+//  the block of audio data in the format desired by the audio device
+//  and the SDL_mixer channel it will play on, respectively.
+//  If the value is not FX_Ok, then the warning or error message is set,
+//  and you should bail.
+// size added by SBF for ROTT
+static int setupVocPlayback(char *ptr, int size, int priority, unsigned long callbackval,
+                            int *chan, Mix_Chunk **chunk)
+{
+    SDL_RWops *rw;
+
+    *chan = grabMixerChannel(priority);
+    if (*chan == -1)
+    {
+        setErrorMessage("No available channels");
+        return(FX_Error);
+    } // if
+
+    if (size == -1) {
+        // !!! FIXME: This could be a problem...SDL/SDL_mixer wants a RWops, which
+        // !!! FIXME:  is an i/o abstraction. Since we already have the VOC data
+        // !!! FIXME:  in memory, we fake it with a memory-based RWops. None of
+        // !!! FIXME:  this is a problem, except the RWops wants to know how big
+        // !!! FIXME:  its memory block is (so it can do things like seek on an
+        // !!! FIXME:  offset from the end of the block), and since we don't have
+        // !!! FIXME:  this information, we have to give it SOMETHING. My VOC
+        // !!! FIXME:  decoder never does seeks from EOF, nor checks for
+        // !!! FIXME:  end-of-file, so we should be fine. However, we've got a
+        // !!! FIXME:  limit of 10 megs for one file. I hope that'll cover it. :)
+
+        rw = SDL_RWFromMem((void *) ptr, (10 * 1024) * 1024);  /* yikes. */
+    } else {
+        // A valid file size! Excellent.
+        rw = SDL_RWFromMem((void *) ptr, size);
+    }
+    
+    *chunk = Mix_LoadWAV_RW(rw, 1);
+    if (*chunk == NULL)
+    {
+        setErrorMessage("Couldn't decode voice sample.");
+        chaninfo[*chan].in_use = 0;
+        return(FX_Error);
+    } // if
+
+    chaninfo[*chan].callbackval = callbackval;
+    return(FX_Ok);
+} // setupVocPlayback
+
+static int _FX_SetPosition(int chan, int angle, int distance)
+{
+    int left;
+    int right;
+    int mid;
+    int volume;
+    int status;
+ 
+    if ( distance < 0 ) {
+        distance  = -distance;
+        angle    += MV_NumPanPositions / 2;
+    }
+    
+    volume = MIX_VOLUME( distance );
+    
+    // Ensure angle is within 0 - 31
+    angle &= MV_MaxPanPosition;
+    
+    left  = MV_PanTable[ angle ][ volume ].left;
+    right = MV_PanTable[ angle ][ volume ].right;
+    mid   = max( 0, 255 - distance );
+
+    status = doSetPan( chan, mid, left, right, 0 );
+    
+    return status;
+}
+
+int FX_PlayVOC(char *ptr, int pitchoffset,
+               int vol, int left, int right,
+               int priority, unsigned long callbackval)
+{
+    int rc;
+    int chan;
+    Mix_Chunk *chunk;
+
+    snddebug("Playing voice: mono (%d), left (%d), right (%d), priority (%d).\n",
+                vol, left, right, priority);
+
+    rc = setupVocPlayback(ptr, -1, priority, callbackval, &chan, &chunk);
+    if (rc != FX_Ok)
+        return(rc);
+
+    // !!! FIXME: Need to do something with pitchoffset.
+
+    rc = doSetPan(chan, vol, left, right, 0);
+    if (rc != FX_Ok)
+    {
+        chaninfo[chan].in_use = 0;
+        return(rc);
+    } // if
+
+    Mix_PlayChannel(chan, chunk, 0);
+    return(HandleOffset + chan);
+} // FX_PlayVOC
+
+
+// get the size of a single sample, in bytes.
+static int getSampleSize(void)
+{
+    Uint16 format;
+    int channels;
+
+    Mix_QuerySpec(NULL, &format, &channels);
+    return( ((format & 0xFF) / 8) * channels );
+} // getSampleSize
+
+
+int FX_PlayLoopedVOC(char *ptr, long loopstart, long loopend,
+       int pitchoffset, int vol, int left, int right, int priority,
+       unsigned long callbackval)
+{
+    int rc;
+    int chan;
+    int samplesize = getSampleSize();
+    Uint32 totalsamples;
+    Mix_Chunk *chunk;
+
+    snddebug("Playing voice: mono (%d), left (%d), right (%d), priority (%d).\n",
+                vol, left, right, priority);
+    snddebug("Looping: start (%ld), end (%ld).\n", loopstart, loopend);
+
+    rc = setupVocPlayback(ptr, -1, priority, callbackval, &chan, &chunk);
+    if (rc != FX_Ok)
+        return(rc);
+
+    // !!! FIXME: Need to do something with pitchoffset.
+
+    totalsamples = chunk->alen / samplesize;
+
+    if ((loopstart >= 0) && ((unsigned int)loopstart < totalsamples))
+    {
+        if (loopend < 0) loopend = 0;
+        if ((unsigned int)loopend > totalsamples) loopend = totalsamples;
+
+        if (loopend < loopstart)
+        {
+            Mix_FreeChunk(chunk);
+            chaninfo[chan].in_use = 0;
+            setErrorMessage("Loop end is before loop start.");
+            return(FX_Error);
+        } // if
+
+        chunk->alen = loopend * samplesize;
+
+        if (loopstart > 0)
+        {
+            loopstart *= samplesize;
+            memcpy(chunk->abuf, ((Uint8 *) chunk->abuf) + loopstart,
+                    chunk->alen - loopstart);
+            chunk->alen -= loopstart;
+        } // if
+    } // if
+
+    Mix_PlayChannel(chan, chunk, -1);  /* -1 == looping. */
+    return(HandleOffset + chan);
+} // FX_PlayLoopedVOC
+
+int FX_PlayVOC3D(char *ptr, int pitchoffset, int angle, int distance,
+       int priority, unsigned long callbackval)
+{
+    int rc;
+    int chan;
+    Mix_Chunk *chunk;
+
+    snddebug("Playing voice at angle (%d), distance (%d), priority (%d).\n",
+                angle, distance, priority);
+
+    rc = setupVocPlayback(ptr, -1, priority, callbackval, &chan, &chunk);
+    if (rc != FX_Ok)
+        return(rc);
+
+    // !!! FIXME: Need to do something with pitchoffset.
+    
+    _FX_SetPosition(chan, angle, distance);
+
+    Mix_PlayChannel(chan, chunk, 0);
+    return(HandleOffset + chan);
+} // FX_PlayVOC3D
+
+// ROTT Special - SBF
+int FX_PlayVOC3D_ROTT(char *ptr, int size, int pitchoffset, int angle, int distance,
+       int priority, unsigned long callbackval)
+{
+    int rc;
+    int chan;
+    Mix_Chunk *chunk;
+
+    snddebug("Playing voice at angle (%d), distance (%d), priority (%d).\n",
+                angle, distance, priority);
+
+    rc = setupVocPlayback(ptr, size, priority, callbackval, &chan, &chunk);
+    if (rc != FX_Ok)
+        return(rc);
+
+    // !!! FIXME: Need to do something with pitchoffset.
+
+    _FX_SetPosition(chan, angle, distance);
+
+    Mix_PlayChannel(chan, chunk, 0);
+
+    return(HandleOffset + chan);
+} // FX_PlayVOC3D_ROTT
+
+
+    // it's all the same to SDL_mixer.  :)
+int FX_PlayWAV( char *ptr, int pitchoffset, int vol, int left, int right,
+       int priority, unsigned long callbackval )
+{
+    return(FX_PlayVOC(ptr, pitchoffset, vol, left, right, priority, callbackval));
+} // FX_PlayWAV
+
+
+int FX_PlayLoopedWAV( char *ptr, long loopstart, long loopend,
+       int pitchoffset, int vol, int left, int right, int priority,
+       unsigned long callbackval )
+{
+    return(FX_PlayLoopedVOC(ptr, loopstart, loopend, pitchoffset, vol, left,
+                             right, priority, callbackval));
+} // FX_PlayLoopedWAV
+
+
+int FX_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance,
+       int priority, unsigned long callbackval )
+{
+    return(FX_PlayVOC3D(ptr, pitchoffset, angle, distance, priority, callbackval));
+} // FX_PlayWAV3D
+
+// ROTT Special - SBF
+int FX_PlayWAV3D_ROTT( char *ptr, int size, int pitchoffset, int angle, int distance,
+       int priority, unsigned long callbackval )
+{
+    return(FX_PlayVOC3D_ROTT(ptr, size, pitchoffset, angle, distance, priority, callbackval));
+} // FX_PlayWAV3D_ROTT
+
+
+int FX_PlayRaw( char *ptr, unsigned long length, unsigned rate,
+       int pitchoffset, int vol, int left, int right, int priority,
+       unsigned long callbackval )
+{
+    setErrorMessage("FX_PlayRaw() ... NOT IMPLEMENTED!");
+    return(FX_Error);
+} // FX_PlayRaw
+
+
+int FX_PlayLoopedRaw( char *ptr, unsigned long length, char *loopstart,
+       char *loopend, unsigned rate, int pitchoffset, int vol, int left,
+       int right, int priority, unsigned long callbackval )
+{
+    setErrorMessage("FX_PlayLoopedRaw() ... NOT IMPLEMENTED!");
+    return(FX_Error);
+} // FX_PlayLoopedRaw
+
+
+int FX_Pan3D(int handle, int angle, int distance)
+{
+    int retval = FX_Warning;
+
+    handle -= HandleOffset;
+
+    if ((handle < 0) || (handle >= numChannels))
+        setWarningMessage("Invalid handle in FX_Pan3D().");
+    else if (!Mix_Playing(handle))
+        setWarningMessage("voice is no longer playing in FX_Pan3D().");
+    else
+    {
+        _FX_SetPosition(handle, angle, distance);
+        
+        retval = FX_Ok;
+    } // else
+
+    return(retval);
+} // FX_Pan3D
+
+
+int FX_SoundActive(int handle)
+{
+    handle -= HandleOffset;
+
+    if (chaninfo == NULL)
+        return(__FX_FALSE);
+
+    if ((handle < 0) || (handle >= numChannels))
+    {
+        setWarningMessage("Invalid handle in FX_SoundActive().");
+        return(__FX_FALSE);
+    } // if
+
+    return(chaninfo[handle].in_use != 0);
+} // FX_SoundActive
+
+
+int FX_SoundsPlaying(void)
+{
+    return(Mix_Playing(-1));
+} // FX_SoundsPlaying
+
+
+int FX_StopSound(int handle)
+{
+    int retval = FX_Ok;
+
+    snddebug("explicitly halting channel (%d).", handle);
+        // !!! FIXME: Should the user callback fire for this?
+
+    handle -= HandleOffset;
+
+    if ((handle < 0) || (handle >= numChannels))
+    {
+        setWarningMessage("Invalid handle in FX_Pan3D().");
+        retval = FX_Warning;
+    } // if
+    else
+    {
+        Mix_HaltChannel(handle);
+    } // else
+
+    return(retval);
+} // FX_StopSound
+
+
+int FX_StopAllSounds(void)
+{
+    snddebug("halting all channels.");
+        // !!! FIXME: Should the user callback fire for this?
+    Mix_HaltGroup(-1);
+    return(FX_Ok);
+} // FX_StopAllSounds
+
+
+int FX_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ),
+       int rate, int pitchoffset, int vol, int left, int right,
+       int priority, unsigned long callbackval )
+{
+    setErrorMessage("FX_StartDemandFeedPlayback() ... NOT IMPLEMENTED!");
+    return(FX_Error);
+}
+
+
+int FX_StartRecording(int MixRate, void (*function)(char *ptr, int length))
+{
+    setErrorMessage("FX_StartRecording() ... NOT IMPLEMENTED!");
+    return(FX_Error);
+} // FX_StartRecording
+
+
+void FX_StopRecord( void )
+{
+    setErrorMessage("FX_StopRecord() ... NOT IMPLEMENTED!");
+} // FX_StopRecord
+
+
+
+// The music functions...
+
+
+char *MUSIC_ErrorString(int ErrorNumber)
+{
+    switch (ErrorNumber)
+    {
+        case MUSIC_Warning:
+            return(warningMessage);
+
+        case MUSIC_Error:
+            return(errorMessage);
+
+        case MUSIC_Ok:
+            return("OK; no error.");
+
+        case MUSIC_ASSVersion:
+            return("Incorrect sound library version.");
+
+        case MUSIC_SoundCardError:
+            return("General sound card error.");
+
+        case MUSIC_InvalidCard:
+            return("Invalid sound card.");
+
+        case MUSIC_MidiError:
+            return("MIDI error.");
+
+        case MUSIC_MPU401Error:
+            return("MPU401 error.");
+
+        case MUSIC_TaskManError:
+            return("Task Manager error.");
+
+        case MUSIC_FMNotDetected:
+            return("FM not detected error.");
+
+        case MUSIC_DPMI_Error:
+            return("DPMI error.");
+
+        default:
+            return("Unknown error.");
+    } // switch
+
+    assert(0);    // shouldn't hit this point.
+    return(NULL);
+} // MUSIC_ErrorString
+
+
+static int music_initialized = 0;
+static int music_context = 0;
+static int music_loopflag = MUSIC_PlayOnce;
+static char *music_songdata = NULL;
+static Mix_Music *music_musicchunk = NULL;
+
+int MUSIC_Init(int SoundCard, int Address)
+{
+    init_debugging();
+
+    musdebug("INIT! card=>%d, address=>%d...", SoundCard, Address);
+
+    if (music_initialized)
+    {
+        setErrorMessage("Music system is already initialized.");
+        return(MUSIC_Error);
+    } // if
+    
+    if (SoundCard != SoundScape) // We pretend there's a SoundScape installed.
+    {
+        setErrorMessage("Card not found.");
+        musdebug("We pretend to be an Ensoniq SoundScape only.");
+        return(MUSIC_Error);
+    } // if
+
+    music_initialized = 1;
+    return(MUSIC_Ok);
+} // MUSIC_Init
+
+
+int MUSIC_Shutdown(void)
+{
+    musdebug("shutting down sound subsystem.");
+
+    if (!music_initialized)
+    {
+        setErrorMessage("Music system is not currently initialized.");
+        return(MUSIC_Error);
+    } // if
+
+    MUSIC_StopSong();
+    music_context = 0;
+    music_initialized = 0;
+    music_loopflag = MUSIC_PlayOnce;
+
+    return(MUSIC_Ok);
+} // MUSIC_Shutdown
+
+
+void MUSIC_SetMaxFMMidiChannel(int channel)
+{
+    musdebug("STUB ... MUSIC_SetMaxFMMidiChannel(%d).\n", channel);
+} // MUSIC_SetMaxFMMidiChannel
+
+
+void MUSIC_SetVolume(int volume)
+{
+    Mix_VolumeMusic(volume >> 1);  // convert 0-255 to 0-128.
+} // MUSIC_SetVolume
+
+
+void MUSIC_SetMidiChannelVolume(int channel, int volume)
+{
+    musdebug("STUB ... MUSIC_SetMidiChannelVolume(%d, %d).\n", channel, volume);
+} // MUSIC_SetMidiChannelVolume
+
+
+void MUSIC_ResetMidiChannelVolumes(void)
+{
+    musdebug("STUB ... MUSIC_ResetMidiChannelVolumes().\n");
+} // MUSIC_ResetMidiChannelVolumes
+
+
+int MUSIC_GetVolume(void)
+{
+    return(Mix_VolumeMusic(-1) << 1);  // convert 0-128 to 0-255.
+} // MUSIC_GetVolume
+
+
+void MUSIC_SetLoopFlag(int loopflag)
+{
+    music_loopflag = loopflag;
+} // MUSIC_SetLoopFlag
+
+
+int MUSIC_SongPlaying(void)
+{
+    return((Mix_PlayingMusic()) ? __FX_TRUE : __FX_FALSE);
+} // MUSIC_SongPlaying
+
+
+void MUSIC_Continue(void)
+{
+    if (Mix_PausedMusic())
+        Mix_ResumeMusic();
+    else if (music_songdata)
+        MUSIC_PlaySong(music_songdata, MUSIC_PlayOnce);
+} // MUSIC_Continue
+
+
+void MUSIC_Pause(void)
+{
+    Mix_PauseMusic();
+} // MUSIC_Pause
+
+
+int MUSIC_StopSong(void)
+{
+    if (!fx_initialized)
+    {
+        setErrorMessage("Need FX system initialized, too. Sorry.");
+        return(MUSIC_Error);
+    } // if
+
+    if ( (Mix_PlayingMusic()) || (Mix_PausedMusic()) )
+        Mix_HaltMusic();
+
+    if (music_musicchunk)
+        Mix_FreeMusic(music_musicchunk);
+
+    music_songdata = NULL;
+    music_musicchunk = NULL;
+    return(MUSIC_Ok);
+} // MUSIC_StopSong
+
+
+int MUSIC_PlaySong(unsigned char *song, int loopflag)
+{
+    //SDL_RWops *rw;
+
+    MUSIC_StopSong();
+
+    music_songdata = song;
+
+    // !!! FIXME: This could be a problem...SDL/SDL_mixer wants a RWops, which
+    // !!! FIXME:  is an i/o abstraction. Since we already have the MIDI data
+    // !!! FIXME:  in memory, we fake it with a memory-based RWops. None of
+    // !!! FIXME:  this is a problem, except the RWops wants to know how big
+    // !!! FIXME:  its memory block is (so it can do things like seek on an
+    // !!! FIXME:  offset from the end of the block), and since we don't have
+    // !!! FIXME:  this information, we have to give it SOMETHING.
+
+    /* !!! ARGH! There's no LoadMUS_RW  ?!
+    rw = SDL_RWFromMem((void *) song, (10 * 1024) * 1024);  // yikes.
+    music_musicchunk = Mix_LoadMUS_RW(rw);
+    Mix_PlayMusic(music_musicchunk, (loopflag == MUSIC_PlayOnce) ? 0 : -1);
+    */
+
+    return(MUSIC_Ok);
+} // MUSIC_PlaySong
+
+// ROTT Special - SBF
+int MUSIC_PlaySongROTT(unsigned char *song, int size, int loopflag)
+{
+    char filename[MAX_PATH];
+    int handle;
+    
+    MUSIC_StopSong();
+
+    // save the file somewhere, so SDL_mixer can load it
+    GetPathFromEnvironment(filename, ApogeePath, "tmpsong.mid");
+    handle = SafeOpenWrite(filename);
+    
+    SafeWrite(handle, song, size);
+    close(handle);
+    
+    music_songdata = song;
+
+    // finally, we can load it with SDL_mixer
+    music_musicchunk = Mix_LoadMUS(filename);
+    if (music_musicchunk == NULL) {
+        return MUSIC_Error;
+    }
+    
+    Mix_PlayMusic(music_musicchunk, (loopflag == MUSIC_PlayOnce) ? 0 : -1);
+
+    return(MUSIC_Ok);
+} // MUSIC_PlaySongROTT
+
+void MUSIC_SetContext(int context)
+{
+    musdebug("STUB ... MUSIC_SetContext().\n");
+    music_context = context;
+} // MUSIC_SetContext
+
+
+int MUSIC_GetContext(void)
+{
+    return(music_context);
+} // MUSIC_GetContext
+
+
+void MUSIC_SetSongTick(unsigned long PositionInTicks)
+{
+    musdebug("STUB ... MUSIC_SetSongTick().\n");
+} // MUSIC_SetSongTick
+
+
+void MUSIC_SetSongTime(unsigned long milliseconds)
+{
+    musdebug("STUB ... MUSIC_SetSongTime().\n");
+}// MUSIC_SetSongTime
+
+
+void MUSIC_SetSongPosition(int measure, int beat, int tick)
+{
+    musdebug("STUB ... MUSIC_SetSongPosition().\n");
+} // MUSIC_SetSongPosition
+
+
+void MUSIC_GetSongPosition(songposition *pos)
+{
+    musdebug("STUB ... MUSIC_GetSongPosition().\n");
+} // MUSIC_GetSongPosition
+
+
+void MUSIC_GetSongLength(songposition *pos)
+{
+    musdebug("STUB ... MUSIC_GetSongLength().\n");
+} // MUSIC_GetSongLength
+
+
+int MUSIC_FadeVolume(int tovolume, int milliseconds)
+{
+    Mix_FadeOutMusic(milliseconds);
+    return(MUSIC_Ok);
+} // MUSIC_FadeVolume
+
+
+int MUSIC_FadeActive(void)
+{
+    return((Mix_FadingMusic() == MIX_FADING_OUT) ? __FX_TRUE : __FX_FALSE);
+} // MUSIC_FadeActive
+
+
+void MUSIC_StopFade(void)
+{
+    musdebug("STUB ... MUSIC_StopFade().\n");
+} // MUSIC_StopFade
+
+
+void MUSIC_RerouteMidiChannel(int channel, int cdecl function( int event, int c1, int c2 ))
+{
+    musdebug("STUB ... MUSIC_RerouteMidiChannel().\n");
+} // MUSIC_RerouteMidiChannel
+
+
+void MUSIC_RegisterTimbreBank(unsigned char *timbres)
+{
+    musdebug("STUB ... MUSIC_RegisterTimbreBank().\n");
+} // MUSIC_RegisterTimbreBank
+
+
+// end of fx_man.c ...

Added: tags/rott-1.1/rott/fx_man.h
===================================================================
--- tags/rott-1.1/rott/fx_man.h	                        (rev 0)
+++ tags/rott-1.1/rott/fx_man.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,132 @@
+
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: FX_MAN.H
+
+   author: James R. Dose
+   date:   March 17, 1994
+
+   Public header for FX_MAN.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __FX_MAN_H
+#define __FX_MAN_H
+
+#include "sndcards.h"
+
+typedef struct
+   {
+   int MaxVoices;
+   int MaxSampleBits;
+   int MaxChannels;
+   } fx_device;
+
+#define MonoFx   1
+#define StereoFx 2
+
+enum FX_ERRORS
+   {
+   FX_Warning = -2,
+   FX_Error = -1,
+   FX_Ok = 0,
+   FX_ASSVersion,
+   FX_BlasterError,
+   FX_SoundCardError,
+   FX_InvalidCard,
+   FX_MultiVocError,
+   FX_DPMI_Error
+   };
+
+#ifdef DOS
+enum fx_BLASTER_Types
+   {
+   fx_SB     = 1,
+   fx_SBPro  = 2,
+   fx_SB20   = 3,
+   fx_SBPro2 = 4,
+   fx_SB16   = 6
+   };
+#endif
+
+
+char *FX_ErrorString( int ErrorNumber );
+int   FX_SetupCard( int SoundCard, fx_device *device );
+int   FX_Init( int SoundCard, int numvoices, int numchannels, int samplebits, unsigned mixrate );
+int   FX_Shutdown( void );
+int   FX_SetCallBack( void ( *function )( unsigned long ) );
+void  FX_SetVolume( int volume );
+int   FX_GetVolume( void );
+
+void  FX_SetReverseStereo( int setting );
+int   FX_GetReverseStereo( void );
+void  FX_SetReverb( int reverb );
+void  FX_SetFastReverb( int reverb );
+int   FX_GetMaxReverbDelay( void );
+int   FX_GetReverbDelay( void );
+void  FX_SetReverbDelay( int delay );
+
+int FX_VoiceAvailable( int priority );
+int FX_EndLooping( int handle );
+int FX_SetPan( int handle, int vol, int left, int right );
+int FX_SetPitch( int handle, int pitchoffset );
+int FX_SetFrequency( int handle, int frequency );
+
+int FX_PlayVOC( char *ptr, int pitchoffset, int vol, int left, int right,
+       int priority, unsigned long callbackval );
+int FX_PlayLoopedVOC( char *ptr, long loopstart, long loopend,
+       int pitchoffset, int vol, int left, int right, int priority,
+       unsigned long callbackval );
+int FX_PlayWAV( char *ptr, int pitchoffset, int vol, int left, int right,
+       int priority, unsigned long callbackval );
+int FX_PlayLoopedWAV( char *ptr, long loopstart, long loopend,
+       int pitchoffset, int vol, int left, int right, int priority,
+       unsigned long callbackval );
+int FX_PlayVOC3D( char *ptr, int pitchoffset, int angle, int distance,
+       int priority, unsigned long callbackval );
+int FX_PlayWAV3D( char *ptr, int pitchoffset, int angle, int distance,
+       int priority, unsigned long callbackval );
+int FX_PlayRaw( char *ptr, unsigned long length, unsigned rate,
+       int pitchoffset, int vol, int left, int right, int priority,
+       unsigned long callbackval );
+int FX_PlayLoopedRaw( char *ptr, unsigned long length, char *loopstart,
+       char *loopend, unsigned rate, int pitchoffset, int vol, int left,
+       int right, int priority, unsigned long callbackval );
+int FX_Pan3D( int handle, int angle, int distance );
+int FX_SoundActive( int handle );
+int FX_SoundsPlaying( void );
+int FX_StopSound( int handle );
+int FX_StopAllSounds( void );
+int FX_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ),
+       int rate, int pitchoffset, int vol, int left, int right,
+       int priority, unsigned long callbackval );
+int  FX_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) );
+void FX_StopRecord( void );
+
+// ROTT Special - SBF
+int FX_PlayVOC3D_ROTT( char *ptr, int size, int pitchoffset, int angle, int distance,
+       int priority, unsigned long callbackval );
+int FX_PlayWAV3D_ROTT( char *ptr, int size, int pitchoffset, int angle, int distance,
+       int priority, unsigned long callbackval );
+// End ROTT hacks
+
+#endif

Added: tags/rott-1.1/rott/gmove.h
===================================================================
--- tags/rott-1.1/rott/gmove.h	                        (rev 0)
+++ tags/rott-1.1/rott/gmove.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,25 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _gmove
+#define _gmove
+
+#define GMOVE 8
+
+#endif

Added: tags/rott-1.1/rott/isr.c
===================================================================
--- tags/rott-1.1/rott/isr.c	                        (rev 0)
+++ tags/rott-1.1/rott/isr.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,842 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+
+
+/*
+============================================================================
+
+													 TIMER INTERRUPT
+
+============================================================================
+*/
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef DOS
+#include <dos.h>
+#include <mem.h>
+#include <conio.h>
+#endif
+
+#include "rt_def.h"
+#include "task_man.h"
+#include "isr.h"
+#include "_isr.h"
+#include "rt_in.h"
+#include "rt_util.h"
+#include "profile.h"
+#include "develop.h"
+#include "rt_main.h"
+
+#if (DEVELOPMENT == 1)
+
+#include "rt_vid.h"
+
+#endif
+//MED
+#include "memcheck.h"
+
+// Global Variables
+
+static volatile boolean ExtendedKeyFlag;
+
+volatile int Keyboard[MAXKEYBOARDSCAN];
+volatile int KeyboardQueue[KEYQMAX];
+volatile int Keystate[MAXKEYBOARDSCAN];
+volatile int Keyhead;
+volatile int Keytail;
+
+#ifdef DOS
+volatile int ticcount;
+volatile int fasttics;
+#endif
+
+volatile boolean PausePressed = false;
+volatile boolean PanicPressed = false;
+int KeyboardStarted=false;
+
+const int ASCIINames[] =          // Unshifted ASCII for scan codes
+{
+//       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+		  0  ,27 ,'1','2','3','4','5','6','7','8','9','0','-','=',8  ,9  ,        // 0
+		  'q','w','e','r','t','y','u','i','o','p','[',']',13 ,0  ,'a','s',        // 1
+		  'd','f','g','h','j','k','l',';',39 ,'`',0  ,92 ,'z','x','c','v',        // 2
+		  'b','n','m',',','.','/',0  ,'*',0  ,' ',0  ,0  ,0  ,0  ,0  ,0  ,        // 3
+		  0  ,0  ,0  ,0  ,0  ,0  ,0  ,'7','8','9','-','4','5','6','+','1',        // 4
+		  '2','3','0',127,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 5
+		  0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 6
+		  0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0           // 7
+};
+
+const int ShiftNames[] =              // Shifted ASCII for scan codes
+{
+//       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+		  0  ,27 ,'!','@','#','$','%','^','&','*','(',')','_','+',8  ,9  ,        // 0
+		  'Q','W','E','R','T','Y','U','I','O','P','{','}',13 ,0  ,'A','S',        // 1
+		  'D','F','G','H','J','K','L',':',34 ,'~',0  ,'|','Z','X','C','V',        // 2
+		  'B','N','M','<','>','?',0  ,'*',0  ,' ',0  ,0  ,0  ,0  ,0  ,0  ,        // 3
+		  0  ,0  ,0  ,0  ,0  ,0  ,0  ,'7','8','9','-','4','5','6','+','1',        // 4
+		  '2','3','0',127,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 5
+		  0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 6
+		  0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0           // 7
+};
+
+#ifdef DOS
+
+// Local Variables
+
+static task * timertask;
+#if (DEVELOPMENT == 1)
+static task * fasttimertask;
+#endif
+static int TimerStarted=false;
+static volatile int pausecount=0;
+static struct dostime_t starttime;
+
+void (__interrupt __far *oldtimerisr) ();
+void (__interrupt __far *oldkeyboardisr) () = NULL;
+
+static int LEDs;
+static volatile int KBFlags;
+
+/*
+================
+=
+= I_TimerISR
+=
+================
+*/
+
+void __interrupt I_TimerISR (void)
+{
+// acknowledge the interrupt
+
+		  OUTP(0x20,0x20);
+		  ticcount++;
+}
+
+/*
+================
+=
+= ISR_Timer
+=
+================
+*/
+#if 0
+#if (DEVELOPMENT == 1)
+static int time=0;
+static int t1=0;
+static int t2=0;
+static int t3=0;
+static int insettime=0;
+#endif
+#endif
+/*
+================
+=
+= ISR_SetTime
+=
+================
+*/
+void ISR_SetTime(int settime)
+{
+#if 0
+#if (DEVELOPMENT == 1)
+   int i;
+   int t;
+   int savetime;
+#endif
+#endif
+
+   ticcount=settime;
+#if 0
+#if (DEVELOPMENT == 1)
+      {
+      insettime=1;
+      savetime=time;
+      t1=0;
+      t2=0;
+      t3=0;
+      t=0;
+
+      for (i=0;i<settime;i++)
+         {
+         t++;
+         if (t==VBLCOUNTER)
+            {
+            t=0;
+            t1++;
+            if (t1==2)
+               {
+               t1=0;
+               t2++;
+               if (t2==2)
+                  {
+                  t2=0;
+                  t3++;
+                  if (t3==2)
+                     t3=0;
+                  }
+               }
+            }
+         }
+      time=t+(time-savetime);
+      if (time>=VBLCOUNTER)
+         {
+         time-=VBLCOUNTER;
+         t1++;
+         if (t1==2)
+            {
+            t1=0;
+            t2++;
+            if (t2==2)
+               {
+               t2=0;
+               t3++;
+               if (t3==2)
+                  t3=0;
+               }
+            }
+         }
+      insettime=0;
+      }
+#endif
+#endif
+}
+
+static void ISR_Timer (task *Task)
+{
+//	(*(int *)(Task->data))=((*(int *)(Task->data))+1)&0xffff;
+	(*(int *)(Task->data))++;
+
+#if 0
+#if (DEVELOPMENT == 1)
+      {
+      if (Task==timertask)
+         {
+         time++;
+         if ((time==VBLCOUNTER) && (insettime==0))
+            {
+            time=0;
+            VL_SetColor(0,(t1<<5)+20,(t2<<5)+20,(t3<<5)+20);
+            t1++;
+            if (t1==2)
+               {
+               t1=0;
+               t2++;
+               if (t2==2)
+                  {
+                  t2=0;
+                  t3++;
+                  if (t3==2)
+                     t3=0;
+                  }
+               }
+            }
+         }
+      }
+#endif
+#endif
+}
+
+
+/*
+=====================
+=
+= I_SetTimer0
+=
+= Sets system timer 0 to the specified speed
+=
+=====================
+*/
+
+void I_SetTimer0(int speed)
+{
+	unsigned s;
+		  if (!((speed > 0 && speed < 150)))
+					 Error ("INT_SetTimer0: %i is a bad value",speed);
+		  s=1192030U/(unsigned)speed;
+		  OUTP(0x43,0x36);                            // Change timer 0
+		  OUTP(0x40,s);
+		  OUTP(0x40,s >> 8);
+}
+
+/*
+================
+=
+= I_Delay
+=
+================
+*/
+
+void I_Delay ( int delay )
+{
+   int time;
+
+   delay=(VBLCOUNTER*delay)/10;
+   IN_ClearKeysDown();
+   time=ticcount;
+   while (ticcount<time+delay)
+      {
+      if (LastScan)
+         break;
+      }
+}
+
+/*
+===============
+=
+= I_StartupTimer
+=
+===============
+*/
+
+void I_StartupTimer (void)
+{
+#if PROFILE
+   return;
+#else
+   struct dostime_t cmostime;
+
+   if (TimerStarted==true)
+      return;
+   TimerStarted=true;
+
+   I_GetCMOSTime ( &cmostime );
+   _dos_settime  ( &cmostime );
+
+//      I_SetTimer0(VBLCOUNTER);
+//      oldtimerisr = _dos_getvect(TIMERINT);
+//      _dos_setvect (TIMERINT, I_TimerISR);
+
+   timertask=TS_ScheduleTask( &ISR_Timer, VBLCOUNTER, 10, &ticcount);
+#if (DEVELOPMENT == 1)
+   fasttimertask=TS_ScheduleTask( &ISR_Timer, VBLCOUNTER*4, 10, &fasttics);
+#endif
+   TS_Dispatch();
+   I_GetCMOSTime ( &cmostime );
+   memcpy(&starttime,&cmostime,sizeof(starttime));
+   ticcount=0;
+   if (!quiet)
+      printf("I_StartupTimer: Timer Started\n");
+#endif
+}
+
+void I_ShutdownTimer (void)
+{
+#if PROFILE
+   return;
+#else
+   struct dostime_t dostime;
+   struct dostime_t cmostime;
+#if (DEVELOPMENT == 1)
+   int totaltime;
+#endif
+
+   if (TimerStarted==false)
+      return;
+   TimerStarted=false;
+
+//      OUTP(0x43,0x36);                            // Change timer 0
+//      OUTP(0x40,0);
+//      OUTP(0x40,0);
+//      _dos_setvect (TIMERINT, oldtimerisr);
+
+   I_GetCMOSTime ( &cmostime );
+   _dos_gettime  ( &dostime  );
+
+#if (DEVELOPMENT == 1)
+   SoftError("Time difference in seconds (DOS-CMOS) %ld\n",dostime.second-cmostime.second);
+   SoftError("Time difference in minutes (DOS-CMOS) %ld\n",dostime.minute-cmostime.minute);
+   SoftError("Time difference in hour (DOS-CMOS) %ld\n",dostime.hour-cmostime.hour);
+   totaltime=( ((cmostime.hour-starttime.hour)*3600) +
+               ((cmostime.minute-starttime.minute)*60) +
+                (cmostime.second-starttime.second)
+             );
+   SoftError("Total seconds = %ld Total Tics = %ld Game Tics = %ld\n",totaltime,totaltime*VBLCOUNTER,ticcount);
+#endif
+
+   TS_Terminate( timertask );
+#if (DEVELOPMENT == 1)
+   TS_Terminate( fasttimertask );
+#endif
+   TS_Shutdown();
+//   TS_Halt();
+/*
+   if (oldtimerisr)
+      {
+      OUTP(0x43,0x36);                            // Change timer 0
+      OUTP(0x40,0);
+      OUTP(0x40,0);
+      _dos_setvect (TIMERINT, oldtimerisr);
+      // Set Date and Time from CMOS
+
+      OUTP(0x70,0);
+      time.second=inp(0x71);
+      OUTP(0x70,2);
+      time.minute=inp(0x71);
+      OUTP(0x70,4);
+      time.hour=inp(0x71);
+      time.second=(time.second&0x0f)+((time.second>>4)*10);
+      time.minute=(time.minute&0x0f)+((time.minute>>4)*10);
+      time.hour=(time.hour&0x0f)+((time.hour>>4)*10);
+      _dos_settime(&time);
+
+      OUTP(0x70,7);
+      date.day=inp(0x71);
+      OUTP(0x70,8);
+      date.month=inp(0x71);
+      OUTP(0x70,9);
+      date.year=inp(0x71);
+      date.day=(date.day&0x0f)+((date.day>>4)*10);
+      date.month=(date.month&0x0f)+((date.month>>4)*10);
+      date.year=(date.year&0x0f)+((date.year>>4)*10);
+      _dos_setdate(&date);
+//      }
+*/
+#endif
+}
+
+/*
+===============
+=
+= I_GetCMOSTime
+=
+===============
+*/
+void I_GetCMOSTime ( struct dostime_t * cmostime )
+{
+   OUTP(0x70,0);
+   cmostime->second=inp(0x71);
+   OUTP(0x70,2);
+   cmostime->minute=inp(0x71);
+   OUTP(0x70,4);
+   cmostime->hour=inp(0x71);
+   cmostime->second=(cmostime->second&0x0f)+((cmostime->second>>4)*10);
+   cmostime->minute=(cmostime->minute&0x0f)+((cmostime->minute>>4)*10);
+   cmostime->hour=(cmostime->hour&0x0f)+((cmostime->hour>>4)*10);
+}
+
+/*
+============================================================================
+
+																KEYBOARD
+
+============================================================================
+*/
+#define ena_kbd           0xae
+#define caps_state        0x40
+#define num_state         0x20
+#define scroll_state      0x10
+
+#define kb_resend         0xfe
+#define kb_ack            0xfa
+#define kb_pr_led         0x40
+#define kb_error          0x80
+#define kb_fe             0x20
+#define kb_fa             0x10
+
+#define porta             0x60
+#define kb_status_port    0x64
+#define input_buffer_full 0x02
+#define led_cmd           0xed
+#define kb_enable         0xf4
+#define leds_off          0
+#define caps_led_on       0x04
+#define num_led_on        0x02
+#define scroll_led_on     0x01
+
+/*
+================
+=
+= I_SendKeyboardData
+=
+================
+*/
+
+void I_SendKeyboardData
+   (
+   int val
+   )
+
+   {
+   int retry;
+   volatile int count;
+
+   _disable();
+
+   KBFlags &= ~( kb_fe | kb_fa );
+
+   count = 0xffff;
+   while( count-- )
+      {
+      if ( !( inp( kb_status_port ) & input_buffer_full ) )
+         {
+         break;
+         }
+      }
+
+   outp( porta, val );
+
+   _enable();
+
+   retry = 3;
+   while( retry-- )
+      {
+      count = 0x1a00;
+      while( count-- )
+         {
+         if ( KBFlags & kb_fe )
+            {
+            break;
+            }
+
+         if ( KBFlags & kb_fa )
+            {
+            return;
+            }
+         }
+      }
+
+   KBFlags |= kb_error;
+   }
+
+/*
+================
+=
+= I_SetKeyboardLEDs
+=
+================
+*/
+
+void I_SetKeyboardLEDs
+   (
+   int which,
+   boolean val
+   )
+
+   {
+   int mask;
+   int count;
+
+   _disable();
+   KBFlags |= kb_pr_led;
+
+   switch( which )
+      {
+      case scroll_lock :
+         mask = scroll_led_on;
+         break;
+
+      case num_lock :
+         mask = num_led_on;
+         break;
+
+      case caps_lock :
+         mask = caps_led_on;
+         break;
+
+      default :
+         mask = 0;
+         break;
+      }
+
+   if ( val )
+      {
+      LEDs |= mask;
+      }
+   else
+      {
+      LEDs &= ~mask;
+      }
+
+   count = 0;
+   do
+      {
+      if ( count > 3 )
+         {
+         break;
+         }
+
+      I_SendKeyboardData( led_cmd );
+      _disable();
+      I_SendKeyboardData( LEDs );
+      _disable();
+      I_SendKeyboardData( kb_enable );
+      _disable();
+      count++;
+      }
+   while( KBFlags & kb_error );
+
+   _enable();
+   KBFlags &= ~(kb_pr_led|kb_error);
+   }
+
+
+/*
+================
+=
+= I_KeyboardISR
+=
+================
+*/
+void __interrupt I_KeyboardISR (void)
+{
+	int k;
+   int temp;
+   int keyon;
+   int strippedkey;
+
+   // Get the scan code
+   k = inp( 0x60 );
+
+   // Tell the XT keyboard controller to clear the key
+	temp = inp( 0x61 );
+	OUTP ( 0x61, temp | 0x80 );
+	OUTP ( 0x61, temp );
+
+   if ( KBFlags & kb_pr_led )
+      {
+      if ( k == kb_resend )
+         {
+         // Handle resend
+         KBFlags |= kb_fe;
+         }
+      else if (k == kb_ack)
+         {
+         // Handle ack
+         KBFlags |= kb_fa;
+         }
+      }
+   else if ( pausecount )
+      {
+      pausecount--;
+      }
+   else if ( k == 0xe1 )         // Handle Pause key
+      {
+      PausePressed = true;
+      pausecount = 5;
+      }
+   else if ( k == 0x46 )         // Handle Panic key (Scroll Lock)
+      {
+      PanicPressed = true;
+      }
+   else
+      {
+      if ( k == 0xE0 )
+         {
+         ExtendedKeyFlag = true;
+         }
+      else
+         {
+         keyon = k & 0x80;
+         strippedkey = k & 0x7f;
+
+         if ( ExtendedKeyFlag )
+            {
+            if ( ( strippedkey == sc_LShift ) ||
+               ( strippedkey == sc_RShift ) )
+               {
+               k = sc_None;
+               }
+/*
+            else
+               {
+               if ( strippedkey == sc_Alt )
+                  {
+                  k = sc_RightAlt | keyon;
+                  }
+               if ( strippedkey == sc_Control )
+                  {
+                  k = sc_RightCtrl | keyon;
+                  }
+               }
+*/
+            }
+
+         if ( k != sc_None )
+            {
+            if ( strippedkey == sc_LShift )
+               {
+               k = sc_RShift | keyon;
+               }
+
+            if ( !keyon )
+               {
+               LastScan = k;
+               }
+
+            if (k & 0x80)        // Up event
+               {
+               Keystate[k&0x7f]=0;
+               }
+            else                 // Down event
+               {
+               Keystate[k]=1;
+               }
+
+            KeyboardQueue[ Keytail ] = k;
+            Keytail = ( Keytail + 1 )&( KEYQMAX - 1 );
+            }
+
+         ExtendedKeyFlag = false;
+         }
+      }
+
+   // acknowledge the interrupt
+   OUTP ( 0x20, 0x20 );
+   }
+
+
+/*
+===============
+=
+= I_StartupKeyboard
+=
+===============
+*/
+
+void I_StartupKeyboard (void)
+{
+   if (KeyboardStarted==true)
+      return;
+   KeyboardStarted=true;
+
+   LEDs = 0;
+   KBFlags = 0;
+   ExtendedKeyFlag = false;
+
+	oldkeyboardisr = _dos_getvect(KEYBOARDINT);
+	_dos_setvect (0x8000 | KEYBOARDINT, I_KeyboardISR);
+
+//   I_SetKeyboardLEDs( scroll_lock, 0 );
+
+   Keyhead = Keytail = 0;
+   memset(Keystate,0,sizeof(Keystate));
+   if (!quiet)
+      printf("I_StartupKeyboard: Keyboard Started\n");
+}
+
+void I_ShutdownKeyboard (void)
+{
+   if (KeyboardStarted==false)
+      return;
+   KeyboardStarted=false;
+
+   // Clear LEDS
+//   *( (byte *)0x417 ) &= ~0x70;
+
+	_dos_setvect (KEYBOARDINT, oldkeyboardisr);
+	*(short *)0x41c = *(short *)0x41a;      // clear bios key buffer
+}
+#else
+
+#include "SDL.h"
+
+static int ticoffset;    /* offset for SDL_GetTicks() */
+static int ticbase;      /* game-supplied base */
+
+int GetTicCount (void)
+{
+	return ((SDL_GetTicks() - ticoffset) * VBLCOUNTER) / 1000 + ticbase;
+}
+
+/*
+================
+=
+= ISR_SetTime
+=
+================
+*/
+void ISR_SetTime(int settime)
+{
+	ticoffset = SDL_GetTicks();
+	ticbase = settime;
+}
+
+/* developer-only */
+
+int GetFastTics (void)
+{
+	/* STUB_FUNCTION; */
+	
+	return 0;
+}
+
+void SetFastTics (int settime)
+{
+	/* STUB_FUNCTION; */
+}
+
+/*
+================
+=
+= I_Delay
+=
+================
+*/
+
+void I_Delay ( int delay )
+{
+   int time;
+
+   delay=(VBLCOUNTER*delay)/10;
+   IN_ClearKeysDown();
+   time=GetTicCount();
+   while (!LastScan && !IN_GetMouseButtons() && GetTicCount()<time+delay)
+      {
+      	IN_UpdateKeyboard();
+      }
+}
+
+/*
+===============
+=
+= I_StartupTimer
+=
+===============
+*/
+
+void I_StartupTimer (void)
+{
+}
+
+void I_ShutdownTimer (void)
+{
+}
+
+/*
+===============
+=
+= I_StartupKeyboard
+=
+===============
+*/
+
+void I_StartupKeyboard (void)
+{
+}
+
+
+void I_ShutdownKeyboard (void)
+{
+}
+#endif

Added: tags/rott-1.1/rott/isr.h
===================================================================
--- tags/rott-1.1/rott/isr.h	                        (rev 0)
+++ tags/rott-1.1/rott/isr.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,89 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _isr_public
+#define _isr_public
+
+#include "keyb.h"
+
+//***************************************************************************
+//
+//    ISR.C - Interrupt Service Routines (Keyboard, timer)
+//
+//***************************************************************************
+
+//***************************************************************************
+//
+//    ISR Constants
+//
+//***************************************************************************
+
+#define VBLCOUNTER   35
+
+
+#define KEYQMAX      256
+#define MAXKEYBOARDSCAN         128
+
+#define scroll_lock  0
+#define num_lock     1
+#define caps_lock    2
+
+extern volatile int KeyboardQueue[KEYQMAX];
+extern volatile int Keyhead;
+extern volatile int Keytail;
+
+extern volatile int Keyboard[MAXKEYBOARDSCAN];   // Keyboard status array
+extern volatile int Keystate[MAXKEYBOARDSCAN];   // Keyboard state array
+
+#ifdef DOS
+extern volatile int ticcount;     // Current ticcount (usually 70Hz)
+extern volatile int fasttics;
+
+#define GetTicCount()	ticcount
+#define GetFastTics()	fasttics
+
+#define SetFastTics(a) {fasttics=a;}
+#else
+int GetTicCount (void);
+int GetFastTics (void);
+
+void SetFastTics(int);
+#endif
+
+extern int KeyboardStarted;
+
+extern const int ASCIINames[];   // Ascii -> scan code conversion
+extern const int ShiftNames[];   // Shifted Ascii->scancode conversion
+extern volatile boolean PausePressed;  //Game paused variable
+extern volatile boolean PanicPressed;  //Panic key variable
+
+void I_StartupTimer (void);        // Start up timer isr
+void I_SetTimer0(int speed);       // Set the timer to a given speed
+void I_ShutdownTimer (void);       // Shutdown timer isr
+void I_SetKeyboardLEDs( int which, boolean val ); // Turns LED's on or off
+void I_StartupKeyboard (void);     // Startup Keyboard isr
+void I_ShutdownKeyboard (void);    // Shutdown keyboard isr
+void I_Delay ( int delay );
+void ISR_SetTime(int settime);
+void I_SendKeyboardData
+   (
+   int val
+   );
+
+#endif

Added: tags/rott-1.1/rott/keyb.h
===================================================================
--- tags/rott-1.1/rott/keyb.h	                        (rev 0)
+++ tags/rott-1.1/rott/keyb.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,106 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _keyb
+#define _keyb
+
+#define	sc_None			0
+#define	sc_Bad			0xff
+#define	sc_Comma    	0x33
+#define	sc_Period		0x34
+#define	sc_Return		0x1c
+#define	sc_Enter		   sc_Return
+#define	sc_Escape		0x01
+#define	sc_Space		   0x39
+#define	sc_BackSpace	0x0e
+#define	sc_Tab			0x0f
+#define	sc_Alt			0x38
+#define	sc_Control		0x1d
+#define	sc_CapsLock		0x3a
+#define	sc_LShift		0x2a
+#define	sc_RShift		0x36
+#define	sc_UpArrow		0x48
+#define	sc_DownArrow	0x50
+#define	sc_LeftArrow	0x4b
+#define	sc_RightArrow	0x4d
+#define	sc_Insert		0x52
+#define	sc_Delete		0x53
+#define	sc_Home			0x47
+#define	sc_End			0x4f
+#define	sc_PgUp			0x49
+#define	sc_PgDn			0x51
+#define	sc_F1				0x3b
+#define	sc_F2				0x3c
+#define	sc_F3				0x3d
+#define	sc_F4				0x3e
+#define	sc_F5				0x3f
+#define	sc_F6				0x40
+#define	sc_F7				0x41
+#define	sc_F8				0x42
+#define	sc_F9				0x43
+#define	sc_F10			0x44
+#define	sc_F11			0x57
+#define	sc_F12			0x58
+#define  sc_PrintScreen 0x37
+
+#define  sc_OpenBracket      0x1a
+#define  sc_CloseBracket     0x1b
+
+#define  sc_1           0x02
+#define	sc_2				0x03
+#define	sc_3				0x04
+#define	sc_4				0x05
+#define	sc_5				0x06
+#define	sc_6				0x07
+#define	sc_7				0x08
+#define	sc_8				0x09
+#define	sc_9				0x0a
+#define	sc_0				0x0b
+#define	sc_Minus       0x0c
+#define	sc_Equals      0x0d
+#define	sc_Plus        0x0d
+
+#define	sc_A				0x1e
+#define	sc_B				0x30
+#define	sc_C				0x2e
+#define	sc_D				0x20
+#define	sc_E				0x12
+#define	sc_F				0x21
+#define	sc_G				0x22
+#define	sc_H				0x23
+#define	sc_I				0x17
+#define	sc_J				0x24
+#define	sc_K				0x25
+#define	sc_L				0x26
+#define	sc_M				0x32
+#define	sc_N				0x31
+#define	sc_O				0x18
+#define	sc_P				0x19
+#define	sc_Q				0x10
+#define	sc_R				0x13
+#define	sc_S				0x1f
+#define	sc_T				0x14
+#define	sc_U				0x16
+#define	sc_V				0x2f
+#define	sc_W				0x11
+#define	sc_X				0x2d
+#define	sc_Y				0x15
+#define	sc_Z				0x2c
+
+#endif

Added: tags/rott-1.1/rott/lookups.c
===================================================================
--- tags/rott-1.1/rott/lookups.c	                        (rev 0)
+++ tags/rott-1.1/rott/lookups.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,223 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "rt_util.h"
+#include "rt_view.h"
+#include <math.h>
+#include <dos.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <conio.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <io.h>
+#include <stdlib.h>
+#include <sys\stat.h>
+
+//MED
+#include "memcheck.h"
+
+#define PANGLES 512
+#define NUMSINANGLES FINEANGLES+FINEANGLEQUAD+1
+
+fixed  pangle[PANGLES];
+long   sintable[NUMSINANGLES];
+short  tantable[FINEANGLES];
+byte   gammatable[GAMMAENTRIES];
+
+extern  int      _argc;
+extern  char **  _argv;
+
+/*
+=================
+=
+= Error
+=
+= For abnormal program terminations
+=
+=================
+*/
+
+void Error (char *error, ...)
+{
+	va_list	argptr;
+
+	va_start (argptr,error);
+	vprintf (error,argptr);
+	va_end (argptr);
+	printf ("\n");
+	exit (1);
+}
+
+
+int SafeOpenWrite (char *_filename)
+{
+	int	handle;
+    char filename[MAX_PATH];
+    strncpy(filename, _filename, sizeof (filename));
+    filename[sizeof (filename) - 1] = '\0';
+    FixFilePath(filename);
+
+	handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_TRUNC
+	, S_IREAD | S_IWRITE);
+
+	if (handle == -1)
+		Error ("Error opening %s: %s",filename,strerror(errno));
+
+	return handle;
+}
+
+
+void SafeWrite (int handle, void *buffer, long count)
+{
+	unsigned	iocount;
+
+	while (count)
+	{
+		iocount = count > 0x8000 ? 0x8000 : count;
+		if (write (handle,buffer,iocount) != iocount)
+			Error ("File write failure");
+		buffer = (void *)( (byte *)buffer + iocount );
+		count -= iocount;
+	}
+}
+
+
+
+
+void CalcPixelAngles ( void )
+{
+    int   i;
+    long  intang;
+    double  angle;
+    double  tang;
+
+    const   double radtoint = (double)FINEANGLES/2/PI;
+
+
+    for (i=0;i<PANGLES;i++)
+       {
+       // start 1/2 pixel over, so viewangle bisects two middle pixels
+       //tang = ((((double)i*160.0)+80.0)/(FPFOCALWIDTH*(double)PANGLES));
+       tang = ((((double)i*160.0)+80.0)/(dGLOBAL_FPFOCALWIDTH*(double)PANGLES));
+       angle = atan(tang);
+       intang = ((long)(angle*radtoint));
+       pangle[i] = intang;
+       }
+}
+
+
+
+void BuildSinTable (void)
+{
+   int   i;
+   double  angle,anglestep;
+   double  sinangle;
+   fixed  value;
+
+   angle = 0;
+   anglestep = (double)(PI/2/FINEANGLEQUAD);
+   for (i=0;i<=FINEANGLEQUAD;i++)
+      {
+      sinangle=sin(angle);
+      value=(fixed)((double)GLOBAL1*sinangle);
+      sintable[i]     =
+      sintable[i+FINEANGLES]  =
+      sintable[FINEANGLES/2-i] = value;
+      sintable[FINEANGLES-i] = -value;
+      sintable[FINEANGLES/2+i] = -value;
+      angle += anglestep;
+      }
+}
+
+void BuildTanTable (void)
+{
+   int   i;
+   double  angle,anglestep;
+   double  tanangle;
+   fixed  value;
+
+   angle = 0;
+   anglestep = (double)(PI*2/FINEANGLES);
+   for (i=0;i<FINEANGLES;i++)
+      {
+      tanangle=tan(angle);
+      value=(fixed)((double)GLOBAL1*tanangle);
+      tantable[i] =(short) (value>>1);
+      angle += anglestep;
+      }
+}
+
+void BuildGammaTable (void)
+{
+   int     l, i, inf;
+   int     j;
+   int     gGamma=0x100;
+   j=0;
+   for (l=0 ; l<NUMGAMMALEVELS ; l++,gGamma+=32)
+      {
+      double nGamma = (double)256 / gGamma;
+      double nScale = (double)63  / pow(63, nGamma);
+
+      for ( i = 0; i < 64; i++ )
+         {
+         inf = pow(i, nGamma) * nScale;
+         if (inf < 0)
+            inf = 0;
+         if (inf > 63)
+            inf = 63;
+         gammatable[j++]=inf;
+         }
+      }
+}
+
+void main ()
+{
+   int handle;
+   int size;
+
+   if (_argc!=2)
+      {
+      printf("LOOKUPS -- Apogee Software (c) 1994\n");
+      printf("\n USAGE:    lookups <name.dat>\n");
+      exit(0);
+      }
+   handle=SafeOpenWrite (_argv[1]);
+   CalcPixelAngles();
+   BuildSinTable();
+   BuildTanTable();
+   BuildGammaTable();
+   size=PANGLES;
+   SafeWrite(handle,&size,sizeof(int));
+   SafeWrite(handle,&pangle[0],sizeof(fixed)*size);
+   size=NUMSINANGLES;
+   SafeWrite(handle,&size,sizeof(int));
+   SafeWrite(handle,&sintable[0],sizeof(fixed)*size);
+   size=FINEANGLES;
+   SafeWrite(handle,&size,sizeof(int));
+   SafeWrite(handle,&tantable[0],sizeof(short)*size);
+   size=GAMMAENTRIES;
+   SafeWrite(handle,&size,sizeof(int));
+   SafeWrite(handle,&gammatable[0],sizeof(byte)*size);
+   close (handle);
+}

Added: tags/rott-1.1/rott/lumpy.h
===================================================================
--- tags/rott-1.1/rott/lumpy.h	                        (rev 0)
+++ tags/rott-1.1/rott/lumpy.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,151 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _lumpy_
+#define _lumpy_
+
+//****************************************************************************
+//
+// Public header for LUMPY typedefs
+//
+//****************************************************************************
+
+
+typedef struct
+{
+   byte     width,height;
+   byte     data;
+} pic_t;
+
+#define CONVERT_ENDIAN_pic_t(pp) { }
+
+typedef struct
+{
+   short     width,height;
+   short     orgx,orgy;
+   byte     data;
+} lpic_t;
+
+#define CONVERT_ENDIAN_lpic_t(lp)            \
+    {                                        \
+        SwapIntelShort(&lp->width);          \
+        SwapIntelShort(&lp->height);         \
+        SwapIntelShort(&lp->orgx);           \
+        SwapIntelShort(&lp->orgy);           \
+    }
+    
+typedef struct
+{
+	short height;
+   char  width[256];
+   short charofs[256];
+   byte  data;       // as much as required
+} font_t;
+
+#define CONVERT_ENDIAN_font_t(fp)            \
+    {                                        \
+        int i;                               \
+        SwapIntelShort(&fp->height);         \
+        for (i = 0; i < 256; i++) {          \
+            SwapIntelShort(&fp->charofs[i]); \
+        }                                    \
+    }
+
+typedef struct
+{
+   short width;
+   short height;
+   byte palette[768];
+   byte data;
+} lbm_t;
+
+#define CONVERT_ENDIAN_lbm_t(lp)             \
+    {                                        \
+        SwapIntelShort(&lp->width);          \
+        SwapIntelShort(&lp->height);         \
+    }
+ 
+typedef struct
+{
+   short          origsize;         // the orig size of "grabbed" gfx
+   short          width;            // bounding box size
+   short          height;
+   short          leftoffset;       // pixels to the left of origin
+   short          topoffset;        // pixels above the origin
+   unsigned short collumnofs[320];  // only [width] used, the [0] is &collumnofs[width]
+} patch_t;
+
+#define CONVERT_ENDIAN_patch_t(pp)           \
+    {                                        \
+        int i;                               \
+        SwapIntelShort(&pp->origsize);       \
+        SwapIntelShort(&pp->width);          \
+        SwapIntelShort(&pp->height);         \
+        SwapIntelShort(&pp->leftoffset);     \
+        SwapIntelShort(&pp->topoffset);      \
+        for (i = 0; i < pp->width; i++) {          \
+            SwapIntelShort((short*)&pp->collumnofs[i]); \
+        }                                    \
+    }
+
+typedef struct
+{
+   short origsize;         // the orig size of "grabbed" gfx
+   short width;            // bounding box size
+   short height;
+   short leftoffset;       // pixels to the left of origin
+   short topoffset;        // pixels above the origin
+   short translevel;
+   short collumnofs[320];  // only [width] used, the [0] is &collumnofs[width]
+} transpatch_t;
+
+#define CONVERT_ENDIAN_transpatch_t(pp)      \
+    {                                        \
+        int i;                               \
+        SwapIntelShort(&pp->origsize);       \
+        SwapIntelShort(&pp->width);          \
+        SwapIntelShort(&pp->height);         \
+        SwapIntelShort(&pp->leftoffset);     \
+        SwapIntelShort(&pp->topoffset);      \
+        SwapIntelShort(&pp->translevel);     \
+        for (i = 0; i < pp->width; i++) {          \
+            SwapIntelShort((short*)&pp->collumnofs[i]); \
+        }                                    \
+    }
+
+typedef struct
+{
+   byte  color;
+   short height;
+   char  width[256];
+   short charofs[256];
+   byte  pal[0x300];
+   byte  data;       // as much as required
+} cfont_t;
+
+#define CONVERT_ENDIAN_cfont_t(pp)           \
+    {                                        \
+        int i;                               \
+        SwapIntelShort(&pp->height);         \
+        for (i = 0; i < 256; i++) {          \
+            SwapIntelShort(&pp->charofs[i]); \
+        }                                    \
+    }
+
+#endif

Added: tags/rott-1.1/rott/memcheck.h
===================================================================
--- tags/rott-1.1/rott/memcheck.h	                        (rev 0)
+++ tags/rott-1.1/rott/memcheck.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1 @@
+/* old header removed */

Added: tags/rott-1.1/rott/modexlib.c
===================================================================
--- tags/rott-1.1/rott/modexlib.c	                        (rev 0)
+++ tags/rott-1.1/rott/modexlib.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,838 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#include <stdarg.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#ifdef DOS
+#include <malloc.h>
+#include <dos.h>
+#include <conio.h>
+#include <io.h>
+#endif
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include "modexlib.h"
+//MED
+#include "memcheck.h"
+#include "rt_util.h"
+#include "rt_net.h" // for GamePaused
+
+static void StretchMemPicture ();
+// GLOBAL VARIABLES
+
+boolean StretchScreen=0;//bná++
+extern boolean iG_aimCross;
+extern boolean sdl_fullscreen;
+extern int iG_X_center;
+extern int iG_Y_center;
+char 	   *iG_buf_center;
+  
+int    linewidth;
+//int    ylookup[MAXSCREENHEIGHT];
+int    ylookup[600];//just set to max res
+byte  *page1start;
+byte  *page2start;
+byte  *page3start;
+int    screensize;
+byte  *bufferofs;
+byte  *displayofs;
+boolean graphicsmode=false;
+char        *bufofsTopLimit;
+char        *bufofsBottomLimit;
+
+void DrawCenterAim ();
+
+#ifdef DOS
+
+/*
+====================
+=
+= GraphicsMode
+=
+====================
+*/
+void GraphicsMode ( void )
+{
+union REGS regs;
+
+regs.w.ax = 0x13;
+int386(0x10,&regs,&regs);
+graphicsmode=true;
+}
+
+/*
+====================
+=
+= SetTextMode
+=
+====================
+*/
+void SetTextMode ( void )
+{
+
+union REGS regs;
+
+regs.w.ax = 0x03;
+int386(0x10,&regs,&regs);
+graphicsmode=false;
+
+}
+
+/*
+====================
+=
+= TurnOffTextCursor
+=
+====================
+*/
+void TurnOffTextCursor ( void )
+{
+
+union REGS regs;
+
+regs.w.ax = 0x0100;
+regs.w.cx = 0x2000;
+int386(0x10,&regs,&regs);
+
+}
+
+#if 0
+/*
+====================
+=
+= TurnOnTextCursor
+=
+====================
+*/
+void TurnOnTextCursor ( void )
+{
+
+union REGS regs;
+
+regs.w.ax = 0x03;
+int386(0x10,&regs,&regs);
+
+}
+#endif
+
+/*
+====================
+=
+= WaitVBL
+=
+====================
+*/
+void WaitVBL( void )
+{
+   unsigned char i;
+
+   i=inp(0x03da);
+   while ((i&8)==0)
+      i=inp(0x03da);
+   while ((i&8)==1)
+      i=inp(0x03da);
+}
+
+
+/*
+====================
+=
+= VL_SetLineWidth
+=
+= Line witdh is in WORDS, 40 words is normal width for vgaplanegr
+=
+====================
+*/
+
+void VL_SetLineWidth (unsigned width)
+{
+   int i,offset;
+
+//
+// set wide virtual screen
+//
+   outpw (CRTC_INDEX,CRTC_OFFSET+width*256);
+
+//
+// set up lookup tables
+//
+   linewidth = width*2;
+
+   offset = 0;
+
+   for (i=0;i<iGLOBAL_SCREENHEIGHT;i++)
+      {
+      ylookup[i]=offset;
+      offset += linewidth;
+      }
+}
+
+/*
+=======================
+=
+= VL_SetVGAPlaneMode
+=
+=======================
+*/
+
+void VL_SetVGAPlaneMode ( void )
+{
+    GraphicsMode();
+    VL_DePlaneVGA ();
+    VL_SetLineWidth (48);
+    screensize=208*iGLOBAL_SCREENBWIDE*2;//bna++ *2
+    page1start=0xa0200;
+    page2start=0xa0200+screensize;
+    page3start=0xa0200+(2u*screensize);
+    displayofs = page1start;
+    bufferofs = page2start;
+    XFlipPage ();
+}
+
+/*
+=======================
+=
+= VL_CopyPlanarPage
+=
+=======================
+*/
+void VL_CopyPlanarPage ( byte * src, byte * dest )
+{
+   int plane;
+
+   for (plane=0;plane<4;plane++)
+      {
+      VGAREADMAP(plane);
+      VGAWRITEMAP(plane);
+      memcpy(dest,src,screensize);
+      }
+}
+
+/*
+=======================
+=
+= VL_CopyPlanarPageToMemory
+=
+=======================
+*/
+void VL_CopyPlanarPageToMemory ( byte * src, byte * dest )
+{
+   byte * ptr;
+   int plane,a,b;
+
+   for (plane=0;plane<4;plane++)
+      {
+      ptr=dest+plane;
+      VGAREADMAP(plane);
+      for (a=0;a<200;a++)
+         for (b=0;b<80;b++,ptr+=4)
+            *(ptr)=*(src+(a*linewidth)+b);
+      }
+}
+
+/*
+=======================
+=
+= VL_CopyBufferToAll
+=
+=======================
+*/
+void VL_CopyBufferToAll ( byte *buffer )
+{
+   int plane;
+
+   for (plane=0;plane<4;plane++)
+      {
+      VGAREADMAP(plane);
+      VGAWRITEMAP(plane);
+      if (page1start!=buffer)
+         memcpy((byte *)page1start,(byte *)buffer,screensize);
+      if (page2start!=buffer)
+         memcpy((byte *)page2start,(byte *)buffer,screensize);
+      if (page3start!=buffer)
+         memcpy((byte *)page3start,(byte *)buffer,screensize);
+      }
+}
+
+/*
+=======================
+=
+= VL_CopyDisplayToHidden
+=
+=======================
+*/
+void VL_CopyDisplayToHidden ( void )
+{
+   VL_CopyBufferToAll ( displayofs );
+}
+
+/*
+=================
+=
+= VL_ClearBuffer
+=
+= Fill the entire video buffer with a given color
+=
+=================
+*/
+
+void VL_ClearBuffer (unsigned buf, byte color)
+{
+  VGAMAPMASK(15);
+  memset((byte *)buf,color,screensize);
+}
+
+/*
+=================
+=
+= VL_ClearVideo
+=
+= Fill the entire video buffer with a given color
+=
+=================
+*/
+
+void VL_ClearVideo (byte color)
+{
+  VGAMAPMASK(15);
+  memset((byte *)(0xa000<<4),color,0x10000);
+}
+
+/*
+=================
+=
+= VL_DePlaneVGA
+=
+=================
+*/
+
+void VL_DePlaneVGA (void)
+{
+
+//
+// change CPU addressing to non linear mode
+//
+
+//
+// turn off chain 4 and odd/even
+//
+        outp (SC_INDEX,SC_MEMMODE);
+        outp (SC_DATA,(inp(SC_DATA)&~8)|4);
+
+        outp (SC_INDEX,SC_MAPMASK);         // leave this set throughout
+
+//
+// turn off odd/even and set write mode 0
+//
+        outp (GC_INDEX,GC_MODE);
+        outp (GC_DATA,inp(GC_DATA)&~0x13);
+
+//
+// turn off chain
+//
+        outp (GC_INDEX,GC_MISCELLANEOUS);
+        outp (GC_DATA,inp(GC_DATA)&~2);
+
+//
+// clear the entire buffer space, because int 10h only did 16 k / plane
+//
+        VL_ClearVideo (0);
+
+//
+// change CRTC scanning from doubleword to byte mode, allowing >64k scans
+//
+        outp (CRTC_INDEX,CRTC_UNDERLINE);
+        outp (CRTC_DATA,inp(CRTC_DATA)&~0x40);
+
+        outp (CRTC_INDEX,CRTC_MODE);
+        outp (CRTC_DATA,inp(CRTC_DATA)|0x40);
+}
+
+
+/*
+=================
+=
+= XFlipPage
+=
+=================
+*/
+
+void XFlipPage ( void )
+{
+   displayofs=bufferofs;
+
+//   _disable();
+
+   outp(CRTC_INDEX,CRTC_STARTHIGH);
+   outp(CRTC_DATA,((displayofs&0x0000ffff)>>8));
+
+//   _enable();
+
+   bufferofs += screensize;
+   if (bufferofs > page3start)
+      bufferofs = page1start;
+}
+
+#else
+
+#include "SDL.h"
+
+#ifndef STUB_FUNCTION
+
+/* rt_def.h isn't included, so I just put this here... */
+#if !defined(ANSIESC)
+#define STUB_FUNCTION fprintf(stderr,"STUB: %s at " __FILE__ ", line %d, thread %d\n",__FUNCTION__,__LINE__,getpid())
+#else
+#define STUB_FUNCTION
+#endif
+
+#endif
+
+/*
+====================
+=
+= GraphicsMode
+=
+====================
+*/
+static SDL_Surface *sdl_surface = NULL;
+static SDL_Surface *unstretch_sdl_surface = NULL;
+
+void GraphicsMode ( void )
+{
+    Uint32 flags = 0;
+
+	if (SDL_InitSubSystem (SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
+	{
+	    Error ("Could not initialize SDL\n");
+	}
+
+    #if defined(PLATFORM_WIN32) || defined(PLATFORM_MACOSX)
+        // FIXME: remove this.  --ryan.
+        flags = SDL_FULLSCREEN;
+        SDL_WM_GrabInput(SDL_GRAB_ON);
+    #endif
+
+    SDL_WM_SetCaption ("Rise of the Triad", "ROTT");
+    SDL_ShowCursor (0);
+//    sdl_surface = SDL_SetVideoMode (320, 200, 8, flags);
+    if (sdl_fullscreen)
+        flags = SDL_FULLSCREEN;
+    sdl_surface = SDL_SetVideoMode (iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT, 8, flags);    
+	if (sdl_surface == NULL)
+	{
+		Error ("Could not set video mode\n");
+	} 
+}
+
+/*
+====================
+=
+= SetTextMode
+=
+====================
+*/
+void SetTextMode ( void )
+{
+	if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO) {
+		if (sdl_surface != NULL) {
+			SDL_FreeSurface(sdl_surface);
+	
+			sdl_surface = NULL;
+		}
+		
+		SDL_QuitSubSystem (SDL_INIT_VIDEO);
+	}
+}
+
+/*
+====================
+=
+= TurnOffTextCursor
+=
+====================
+*/
+void TurnOffTextCursor ( void )
+{
+}
+
+/*
+====================
+=
+= WaitVBL
+=
+====================
+*/
+void WaitVBL( void )
+{
+	SDL_Delay (16667/1000);
+}
+
+/*
+=======================
+=
+= VL_SetVGAPlaneMode
+=
+=======================
+*/
+
+void VL_SetVGAPlaneMode ( void )
+{
+   int i,offset;
+
+    GraphicsMode();
+
+//
+// set up lookup tables
+//
+//bna--   linewidth = 320;
+   linewidth = iGLOBAL_SCREENWIDTH;
+
+   offset = 0;
+
+   for (i=0;i<iGLOBAL_SCREENHEIGHT;i++)
+      {
+      ylookup[i]=offset;
+      offset += linewidth;
+      }
+
+//    screensize=MAXSCREENHEIGHT*MAXSCREENWIDTH;
+    screensize=iGLOBAL_SCREENHEIGHT*iGLOBAL_SCREENWIDTH;
+
+
+
+    page1start=sdl_surface->pixels;
+    page2start=sdl_surface->pixels;
+    page3start=sdl_surface->pixels;
+    displayofs = page1start;
+    bufferofs = page2start;
+
+	iG_X_center = iGLOBAL_SCREENWIDTH / 2;
+	iG_Y_center = (iGLOBAL_SCREENHEIGHT / 2)+10 ;//+10 = move aim down a bit
+
+	iG_buf_center = bufferofs + (screensize/2);//(iG_Y_center*iGLOBAL_SCREENWIDTH);//+iG_X_center;
+
+	bufofsTopLimit =  bufferofs + screensize - iGLOBAL_SCREENWIDTH;
+	bufofsBottomLimit = bufferofs + iGLOBAL_SCREENWIDTH;
+
+    // start stretched
+    EnableScreenStretch();
+    XFlipPage ();
+}
+
+/*
+=======================
+=
+= VL_CopyPlanarPage
+=
+=======================
+*/
+void VL_CopyPlanarPage ( byte * src, byte * dest )
+{
+#ifdef DOS
+   int plane;
+
+   for (plane=0;plane<4;plane++)
+      {
+      VGAREADMAP(plane);
+      VGAWRITEMAP(plane);
+      memcpy(dest,src,screensize);
+      }
+#else
+      memcpy(dest,src,screensize);
+#endif
+}
+
+/*
+=======================
+=
+= VL_CopyPlanarPageToMemory
+=
+=======================
+*/
+void VL_CopyPlanarPageToMemory ( byte * src, byte * dest )
+{
+#ifdef DOS
+   byte * ptr;
+   int plane,a,b;
+
+   for (plane=0;plane<4;plane++)
+      {
+      ptr=dest+plane;
+      VGAREADMAP(plane);
+      for (a=0;a<200;a++)
+         for (b=0;b<80;b++,ptr+=4)
+            *(ptr)=*(src+(a*linewidth)+b);
+      }
+#else
+      memcpy(dest,src,screensize);
+#endif
+}
+
+/*
+=======================
+=
+= VL_CopyBufferToAll
+=
+=======================
+*/
+void VL_CopyBufferToAll ( byte *buffer )
+{
+#ifdef DOS
+   int plane;
+
+   for (plane=0;plane<4;plane++)
+      {
+      VGAREADMAP(plane);
+      VGAWRITEMAP(plane);
+      if (page1start!=buffer)
+         memcpy((byte *)page1start,(byte *)buffer,screensize);
+      if (page2start!=buffer)
+         memcpy((byte *)page2start,(byte *)buffer,screensize);
+      if (page3start!=buffer)
+         memcpy((byte *)page3start,(byte *)buffer,screensize);
+      }
+#endif
+}
+
+/*
+=======================
+=
+= VL_CopyDisplayToHidden
+=
+=======================
+*/
+void VL_CopyDisplayToHidden ( void )
+{
+   VL_CopyBufferToAll ( displayofs );
+}
+
+/*
+=================
+=
+= VL_ClearBuffer
+=
+= Fill the entire video buffer with a given color
+=
+=================
+*/
+
+void VL_ClearBuffer (byte *buf, byte color)
+{
+#ifdef DOS
+  VGAMAPMASK(15);
+  memset((byte *)buf,color,screensize);
+#else
+  memset((byte *)buf,color,screensize);
+#endif
+}
+
+/*
+=================
+=
+= VL_ClearVideo
+=
+= Fill the entire video buffer with a given color
+=
+=================
+*/
+
+void VL_ClearVideo (byte color)
+{
+#ifdef DOS
+  VGAMAPMASK(15);
+  memset((byte *)(0xa000<<4),color,0x10000);
+#else
+  memset (sdl_surface->pixels, color, iGLOBAL_SCREENWIDTH*iGLOBAL_SCREENHEIGHT);
+#endif
+}
+
+/*
+=================
+=
+= VL_DePlaneVGA
+=
+=================
+*/
+
+void VL_DePlaneVGA (void)
+{
+}
+
+
+/* C version of rt_vh_a.asm */
+
+void VH_UpdateScreen (void)
+{ 	
+
+	if (StretchScreen){//bna++
+		StretchMemPicture ();
+	}else{
+		DrawCenterAim ();
+	}
+	SDL_UpdateRect (SDL_GetVideoSurface (), 0, 0, 0, 0);
+}
+
+
+/*
+=================
+=
+= XFlipPage
+=
+=================
+*/
+
+void XFlipPage ( void )
+{
+#ifdef DOS
+   displayofs=bufferofs;
+
+//   _disable();
+
+   outp(CRTC_INDEX,CRTC_STARTHIGH);
+   outp(CRTC_DATA,((displayofs&0x0000ffff)>>8));
+
+//   _enable();
+
+   bufferofs += screensize;
+   if (bufferofs > page3start)
+      bufferofs = page1start;
+#else
+ 	if (StretchScreen){//bna++
+		StretchMemPicture ();
+	}else{
+		DrawCenterAim ();
+	}
+   SDL_UpdateRect (sdl_surface, 0, 0, 0, 0);
+ 
+#endif
+}
+
+#endif
+
+
+void EnableScreenStretch(void)
+{
+   int i,offset;
+   
+   if (iGLOBAL_SCREENWIDTH <= 320 || StretchScreen) return;
+   
+   if (unstretch_sdl_surface == NULL)
+   {
+      /* should really be just 320x200, but there is code all over the
+         places which crashes then */
+      unstretch_sdl_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
+         iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT, 8, 0, 0, 0, 0);
+   }
+	
+   displayofs = unstretch_sdl_surface->pixels +
+	(displayofs - (byte *)sdl_surface->pixels);
+   bufferofs  = unstretch_sdl_surface->pixels;
+   page1start = unstretch_sdl_surface->pixels;
+   page2start = unstretch_sdl_surface->pixels;
+   page3start = unstretch_sdl_surface->pixels;
+   StretchScreen = 1;	
+}
+
+void DisableScreenStretch(void)
+{
+   if (iGLOBAL_SCREENWIDTH <= 320 || !StretchScreen) return;
+	
+   displayofs = sdl_surface->pixels +
+	(displayofs - (byte *)unstretch_sdl_surface->pixels);
+   bufferofs  = sdl_surface->pixels;
+   page1start = sdl_surface->pixels;
+   page2start = sdl_surface->pixels;
+   page3start = sdl_surface->pixels;
+   StretchScreen = 0;
+}
+
+
+// bna section -------------------------------------------
+static void StretchMemPicture ()
+{
+  SDL_Rect src;
+  SDL_Rect dest;
+	
+  src.x = 0;
+  src.y = 0;
+  src.w = 320;
+  src.h = 200;
+  
+  dest.x = 0;
+  dest.y = 0;
+  dest.w = iGLOBAL_SCREENWIDTH;
+  dest.h = iGLOBAL_SCREENHEIGHT;
+  SDL_SoftStretch(unstretch_sdl_surface, &src, sdl_surface, &dest);
+}
+
+// bna function added start
+extern	boolean ingame;
+int		iG_playerTilt;
+
+void DrawCenterAim ()
+{
+	int x;
+	if (iG_aimCross && !GamePaused){
+		if (( ingame == true )&&(iGLOBAL_SCREENWIDTH>320)){
+			  if ((iG_playerTilt <0 )||(iG_playerTilt >iGLOBAL_SCREENHEIGHT/2)){
+					iG_playerTilt = -(2048 - iG_playerTilt);
+			  }
+			  if (iGLOBAL_SCREENWIDTH == 640){ x = iG_playerTilt;iG_playerTilt=x/2; }
+			  iG_buf_center = bufferofs + ((iG_Y_center-iG_playerTilt)*iGLOBAL_SCREENWIDTH);//+iG_X_center;
+
+			  for (x=iG_X_center-10;x<=iG_X_center-4;x++){
+				  if ((iG_buf_center+x < bufofsTopLimit)&&(iG_buf_center+x > bufofsBottomLimit)){
+					 *(iG_buf_center+x) = 75;
+				  }
+			  }
+			  for (x=iG_X_center+4;x<=iG_X_center+10;x++){
+				  if ((iG_buf_center+x < bufofsTopLimit)&&(iG_buf_center+x > bufofsBottomLimit)){
+					 *(iG_buf_center+x) = 75;
+				  }
+			  }
+			  for (x=10;x>=4;x--){
+				  if (((iG_buf_center-(x*iGLOBAL_SCREENWIDTH)+iG_X_center) < bufofsTopLimit)&&((iG_buf_center-(x*iGLOBAL_SCREENWIDTH)+iG_X_center) > bufofsBottomLimit)){
+					 *(iG_buf_center-(x*iGLOBAL_SCREENWIDTH)+iG_X_center) = 75;
+				  }
+			  }
+			  for (x=4;x<=10;x++){
+				  if (((iG_buf_center+(x*iGLOBAL_SCREENWIDTH)+iG_X_center) < bufofsTopLimit)&&((iG_buf_center+(x*iGLOBAL_SCREENWIDTH)+iG_X_center) > bufofsBottomLimit)){
+					 *(iG_buf_center+(x*iGLOBAL_SCREENWIDTH)+iG_X_center) = 75;
+				  }
+			  }
+		}
+	}
+}
+// bna function added end
+
+
+
+
+// bna section -------------------------------------------
+
+
+

Added: tags/rott-1.1/rott/modexlib.h
===================================================================
--- tags/rott-1.1/rott/modexlib.h	                        (rev 0)
+++ tags/rott-1.1/rott/modexlib.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,173 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    MODEXLIB.C - various utils palette funcs and modex stuff
+//
+//***************************************************************************
+
+#ifndef _modexlib_public
+#define _modexlib_public
+
+#include "WinRott.h"
+#include "rt_def.h"
+/*
+int iGLOBAL_SCREENWIDTH;//bna val 800
+int iGLOBAL_SCREENHEIGHT;//bna val 600
+
+
+#define MAXSCREENHEIGHT    600//     200*2
+#define MAXSCREENWIDTH     800//     320*2
+#define SCREENBWIDE        800*(96/320)//     96*2
+#define MAXVIEWWIDTH       800//     320*2
+#define SCREENWIDTH        800*(96/320)//     96*2              // default screen width in bytes
+*/
+//***************************************************************************
+//
+//    Video (ModeX) Constants
+//
+//***************************************************************************
+
+#ifdef DOS
+#define SC_INDEX                0x3C4
+#define SC_DATA                 0x3C5
+#define SC_RESET                0
+#define SC_CLOCK                1
+#define SC_MAPMASK              2
+#define SC_CHARMAP              3
+#define SC_MEMMODE              4
+
+#define CRTC_INDEX              0x3D4
+#define CRTC_DATA               0x3D5
+#define CRTC_H_TOTAL            0
+#define CRTC_H_DISPEND          1
+#define CRTC_H_BLANK            2
+#define CRTC_H_ENDBLANK         3
+#define CRTC_H_RETRACE          4
+#define CRTC_H_ENDRETRACE       5
+#define CRTC_V_TOTAL            6
+#define CRTC_OVERFLOW           7
+#define CRTC_ROWSCAN            8
+#define CRTC_MAXSCANLINE        9
+#define CRTC_CURSORSTART        10
+#define CRTC_CURSOREND          11
+#define CRTC_STARTHIGH          12
+#define CRTC_STARTLOW           13
+#define CRTC_CURSORHIGH         14
+#define CRTC_CURSORLOW          15
+#define CRTC_V_RETRACE          16
+#define CRTC_V_ENDRETRACE       17
+#define CRTC_V_DISPEND          18
+#define CRTC_OFFSET             19
+#define CRTC_UNDERLINE          20
+#define CRTC_V_BLANK            21
+#define CRTC_V_ENDBLANK         22
+#define CRTC_MODE               23
+#define CRTC_LINECOMPARE        24
+
+#define GC_INDEX                0x3CE
+#define GC_DATA                 0x3CF
+#define GC_SETRESET             0
+#define GC_ENABLESETRESET       1
+#define GC_COLORCOMPARE         2
+#define GC_DATAROTATE           3
+#define GC_READMAP              4
+#define GC_MODE                 5
+#define GC_MISCELLANEOUS        6
+#define GC_COLORDONTCARE        7
+#define GC_BITMASK              8
+
+#define ATR_INDEX               0x3c0
+#define ATR_MODE                16
+#define ATR_OVERSCAN            17
+#define ATR_COLORPLANEENABLE      18
+#define ATR_PELPAN              19
+#define ATR_COLORSELECT         20
+
+#define STATUS_REGISTER_1       0x3da
+
+#define PEL_WRITE_ADR           0x3c8
+#define PEL_READ_ADR            0x3c7
+#define PEL_DATA                0x3c9
+#endif
+
+extern  boolean StretchScreen;//bná++
+
+//extern  int      ylookup[MAXSCREENHEIGHT];      // Table of row offsets
+extern  int      ylookup[600];      // just set to max res
+extern  int      linewidth;
+extern  byte    *page1start;
+extern  byte    *page2start;
+extern  byte    *page3start;
+extern  int      screensize;
+extern  byte    *bufferofs;
+extern  byte    *displayofs;
+extern  boolean  graphicsmode;
+
+
+void  GraphicsMode ( void );
+void  SetTextMode ( void );
+void  VL_SetVGAPlaneMode ( void );
+void  VL_ClearBuffer (byte *buf, byte color);
+void  VL_ClearVideo (byte color);
+void  VL_DePlaneVGA (void);
+void  VL_CopyDisplayToHidden ( void );
+void  VL_CopyBufferToAll ( byte *buffer );
+void  VL_CopyPlanarPage ( byte * src, byte * dest );
+void  VL_CopyPlanarPageToMemory ( byte * src, byte * dest );
+void  XFlipPage ( void );
+void  WaitVBL( void );
+void  TurnOffTextCursor ( void );
+
+#ifdef __WATCOMC__
+#pragma aux VGAWRITEMAP =      \
+        "mov    eax,01H"       \
+        "mov    edx,03c5h"     \
+        "shl    eax,cl"        \
+        "out    dx,al"         \
+        parm    [ecx]          \
+        modify exact [eax edx]
+
+#pragma aux VGAMAPMASK =       \
+        "mov    edx,03c5h"     \
+        "out    dx,al"         \
+        parm    [eax]          \
+        modify exact [edx]
+
+#pragma aux VGAREADMAP =      \
+        "shl    eax,08H"      \
+        "mov    edx,03ceh"    \
+        "add    eax,04H"      \
+        "out    dx,ax"        \
+        parm    [eax]         \
+        modify exact [eax edx]
+#endif
+
+#ifdef DOS
+void  VGAMAPMASK (int x);
+void  VGAREADMAP (int x);
+void  VGAWRITEMAP(int x);
+#else
+#define VGAMAPMASK(a)
+#define VGAREADMAP(a)
+#define VGAWRITEMAP(a)
+#endif
+
+#endif

Added: tags/rott-1.1/rott/music.h
===================================================================
--- tags/rott-1.1/rott/music.h	                        (rev 0)
+++ tags/rott-1.1/rott/music.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,96 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: MUSIC.H
+
+   author: James R. Dose
+   date:   March 25, 1994
+
+   Public header for MUSIC.C
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __MUSIC_H
+#define __MUSIC_H
+
+#include "sndcards.h"
+
+extern int MUSIC_ErrorCode;
+
+enum MUSIC_ERRORS
+   {
+   MUSIC_Warning = -2,
+   MUSIC_Error   = -1,
+   MUSIC_Ok      = 0,
+   MUSIC_ASSVersion,
+   MUSIC_SoundCardError,
+   MUSIC_MPU401Error,
+   MUSIC_InvalidCard,
+   MUSIC_MidiError,
+   MUSIC_TaskManError,
+   MUSIC_FMNotDetected,
+   MUSIC_DPMI_Error
+   };
+
+typedef struct
+   {
+   unsigned long tickposition;
+   unsigned long milliseconds;
+   unsigned int  measure;
+   unsigned int  beat;
+   unsigned int  tick;
+   } songposition;
+
+#define MUSIC_LoopSong ( 1 == 1 )
+#define MUSIC_PlayOnce ( !MUSIC_LoopSong )
+
+char *MUSIC_ErrorString( int ErrorNumber );
+int   MUSIC_Init( int SoundCard, int Address );
+int   MUSIC_Shutdown( void );
+void  MUSIC_SetMaxFMMidiChannel( int channel );
+void  MUSIC_SetVolume( int volume );
+void  MUSIC_SetMidiChannelVolume( int channel, int volume );
+void  MUSIC_ResetMidiChannelVolumes( void );
+int   MUSIC_GetVolume( void );
+void  MUSIC_SetLoopFlag( int loopflag );
+int   MUSIC_SongPlaying( void );
+void  MUSIC_Continue( void );
+void  MUSIC_Pause( void );
+int   MUSIC_StopSong( void );
+int   MUSIC_PlaySong( unsigned char *song, int loopflag );
+
+// ROTT Special - SBF
+int   MUSIC_PlaySongROTT(unsigned char *song, int size, int loopflag);
+
+void  MUSIC_SetContext( int context );
+int   MUSIC_GetContext( void );
+void  MUSIC_SetSongTick( unsigned long PositionInTicks );
+void  MUSIC_SetSongTime( unsigned long milliseconds );
+void  MUSIC_SetSongPosition( int measure, int beat, int tick );
+void  MUSIC_GetSongPosition( songposition *pos );
+void  MUSIC_GetSongLength( songposition *pos );
+int   MUSIC_FadeVolume( int tovolume, int milliseconds );
+int   MUSIC_FadeActive( void );
+void  MUSIC_StopFade( void );
+void  MUSIC_RerouteMidiChannel( int channel, int cdecl ( *function )( int event, int c1, int c2 ) );
+void  MUSIC_RegisterTimbreBank( unsigned char *timbres );
+
+#endif

Added: tags/rott-1.1/rott/myprint.h
===================================================================
--- tags/rott-1.1/rott/myprint.h	                        (rev 0)
+++ tags/rott-1.1/rott/myprint.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef __MYPRINT_H
+#define __MYPRINT_H
+
+enum COLORS
+   {
+   BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY,
+   LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE
+   };
+
+#define NONE         -1
+#define SINGLE_FRAME -1
+#define DOUBLE_FRAME -2
+
+void DrawRottText( int x, int y, int ch, int foreground, int background );
+void TextBox( int x1, int y1, int x2, int y2, int ch, int foreground, int background );
+void TextFrame( int x1, int y1, int x2, int y2, int type, int foreground, int background );
+void mysetxy( int x, int y );
+void myputch( char ch );
+int  printstring( char *string );
+int  printnum( int number );
+int  printunsigned( unsigned long number, int radix );
+int  myprintf( char *fmt, ... ) __attribute__((format(printf,1,2)));
+
+#endif

Added: tags/rott-1.1/rott/profile.h
===================================================================
--- tags/rott-1.1/rott/profile.h	                        (rev 0)
+++ tags/rott-1.1/rott/profile.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,26 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _profile
+#define _profile
+
+#define PROFILE 0
+#define PROFILETICS 2
+
+#endif

Added: tags/rott-1.1/rott/r_scale.asm
===================================================================
--- tags/rott-1.1/rott/r_scale.asm	                        (rev 0)
+++ tags/rott-1.1/rott/r_scale.asm	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,111 @@
+        .386
+        .MODEL  flat
+
+;================
+;
+; R_DrawFilmColumn
+;
+;================
+
+SCREENWIDTH = 96               
+
+
+.data  
+loopcount       dd      0
+pixelcount      dd      0
+EXTRN   _dc_yl:DWORD
+EXTRN   _dc_yh:DWORD
+EXTRN   _dc_ycenter:DWORD
+EXTRN   _dc_iscale:DWORD
+EXTRN   _dc_texturemid:DWORD
+EXTRN   _ylookup:DWORD
+EXTRN   _dc_source:DWORD
+
+.code
+SEGMENT text USE32 
+        ALIGN   16
+
+PROC   R_DrawFilmColumn_
+PUBLIC   R_DrawFilmColumn_
+        push    ebp
+        mov     ebp,[_dc_yl]
+        mov     ebx,ebp
+        add     edi,[_ylookup+ebx*4]
+        mov     eax,[_dc_yh]
+        inc     eax
+        sub     eax,ebp                         ; pixel count
+        mov     [pixelcount],eax                ; save for final pixel
+        js      done                            ; nothing to scale
+        shr     eax,1                           ; double pixel count
+        mov     [loopcount],eax
+
+        mov     ecx,[_dc_iscale]
+
+        mov     eax,[_dc_ycenter]
+        sub     eax,ebp
+        imul    ecx
+        mov     ebp,[_dc_texturemid]
+        sub     ebp,eax
+
+        mov     esi,[_dc_source]
+
+
+        mov     ebx,[_dc_iscale]
+        mov     eax,OFFSET patch1+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET patch2+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+
+; eax           aligned colormap
+; ebx           aligned colormap
+; ecx,edx       scratch
+; esi           virtual source
+; edi           moving destination pointer
+; ebp           frac
+
+        mov     ecx,ebp                                 ; begin calculating first pixel
+        add     ebp,ebx                                 ; advance frac pointer
+        shr     ecx,16                                      ; finish calculation for first pixel
+        mov     edx,ebp                                 ; begin calculating second pixel
+        add     ebp,ebx                                 ; advance frac pointer
+        shr     edx,16                                      ; finish calculation for second pixel
+        mov     al,[esi+ecx]                    ; get first pixel
+        mov     bl,[esi+edx]                    ; get second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     doubleloop                              ; at least two pixels to map
+        jmp     checklast
+
+        ALIGN   16
+doubleloop:
+        mov     ecx,ebp                                 ; begin calculating third pixel
+patch1:
+        add     ebp,12345678h                   ; advance frac pointer
+        mov     [edi],al                                ; write first pixel
+        shr     ecx,16                                      ; finish calculation for third pixel
+        mov     edx,ebp                                 ; begin calculating fourth pixel
+patch2:
+        add     ebp,12345678h                   ; advance frac pointer
+        mov     [edi+SCREENWIDTH],bl    ; write second pixel
+        shr     edx,16                                      ; finish calculation for fourth pixel
+        mov     al,[esi+ecx]                    ; get third pixel
+        add     edi,SCREENWIDTH*2               ; advance to third pixel destination
+        mov     bl,[esi+edx]                    ; get fourth pixel
+        dec     [loopcount]                             ; done with loop?
+        jnz     doubleloop
+
+; check for final pixel
+checklast:
+        test    [pixelcount],1
+        jz      done
+        mov     [edi],al                                ; write final pixel
+done:
+        pop     ebp
+        ret
+
+ENDP
+ENDS
+
+
+END
+

Added: tags/rott-1.1/rott/rottnet.h
===================================================================
--- tags/rott-1.1/rott/rottnet.h	                        (rev 0)
+++ tags/rott-1.1/rott/rottnet.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,102 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// rottnet.h
+#ifndef rottnet_public
+#define rottnet_public
+
+#include "develop.h"
+
+#ifdef DOS
+#define PEL_WRITE_ADR   0x3c8
+#define PEL_DATA        0x3c9
+
+#define I_ColorBlack(r,g,b) {outp(PEL_WRITE_ADR,0);outp(PEL_DATA,r);outp(PEL_DATA,g);outp(PEL_DATA,b);};
+#endif
+
+#define	MAXNETNODES		14			// max computers in a game
+
+#if ( SHAREWARE == 1 )
+   #define  MAXPLAYERS     5        // 5 players max + drones
+#else
+   #define	MAXPLAYERS		11			// 11 players max + drones
+#endif
+
+#define	CMD_SEND	   1
+#define	CMD_GET		2
+#define  CMD_OUTQUEBUFFERSIZE 3
+#define  CMD_INQUEBUFFERSIZE  4
+
+#define	ROTTCOM_ID		0x12345678l
+
+#define  MAXPACKETSIZE 2048
+#define	MAXCOMBUFFERSIZE 2048
+
+#if __WATCOMC__
+#pragma pack (1)
+#endif
+
+typedef struct
+{
+	short	intnum;			// ROTT executes an int to send commands
+
+// communication between ROTT and the driver
+	short	command;	    	// CMD_SEND or CMD_GET
+	short	remotenode;		// dest for send, set by get (-1 = no packet)
+	short	datalength;		// bytes in rottdata to be sent / bytes read
+
+// info specific to this node
+	short	consoleplayer;	// 0-3 = player number
+	short	numplayers;		// 1-4
+   short   client;         // 0 = server 1 = client
+   short   gametype;       // 0 = modem  1 = network
+   short   ticstep;        // 1 for every tic 2 for every other tic ...
+   short   remoteridicule; // 0 = remote ridicule is off 1= rr is on
+
+// packet data to be sent
+	char	data[MAXPACKETSIZE];
+} rottcom_t;
+
+#if __WATCOMC__
+#pragma pack (4)
+#endif
+
+#define  MODEM_GAME   0
+#define	NETWORK_GAME 1
+
+#define	ROTTLAUNCHER ("ROTT.EXE")
+
+#if defined(DOS) && (__WATCOMC__ == 0)
+
+extern   rottcom_t   rottcom;
+extern   boolean     pause;
+
+void ShutdownROTTCOM ( void );
+int  CheckParm (char *check);
+void LaunchROTT (void);
+void NetISR (void);
+long GetVector (void);
+
+#else
+
+extern   rottcom_t   * rottcom;
+
+#endif
+
+#endif

Added: tags/rott-1.1/rott/rt_actor.c
===================================================================
--- tags/rott-1.1/rott/rt_actor.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_actor.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,13637 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+
+#include <string.h>
+#include <stdlib.h>
+#include "rt_def.h"
+#include "rt_sound.h"
+#include "rt_door.h"
+#include "rt_ted.h"
+#include "rt_draw.h"
+#include "watcom.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "lumpy.h"
+#include "gmove.h"
+#include "states.h"
+#include "rt_sqrt.h"
+#include "rt_stat.h"
+#include "sprites.h"
+#include "rt_actor.h"
+#include "rt_game.h"
+#include "rt_main.h"
+#include "rt_playr.h"
+#include "rt_util.h"
+#include "rt_rand.h"
+#include "rt_menu.h"
+#include "rt_swift.h"
+#include "_rt_acto.h"
+#include "rt_cfg.h"
+#include "rt_floor.h"
+#include "engine.h"
+#include "develop.h"
+#include "rt_view.h"
+#include "isr.h"
+#include "rt_com.h"
+#include "rt_scale.h"
+#include "modexlib.h"
+#include "rt_net.h"
+#include "rt_msg.h"
+#include "fx_man.h"
+//MED
+#include "memcheck.h"
+
+
+
+
+#define SGN(x)  (((x) > 0)?(1):(-1))
+
+
+
+#define WILEYBLITZCHANCE  20
+#define GIBSOUND       SD_GIBSPLASHSND
+#define ACTORTHUDSND   SD_BODYLANDSND
+#define ACTORLANDSND   SD_PLAYERLANDSND
+
+//========================== Global Variables ===================================================
+
+#define SHP(difficulty,ob)  (starthitpoints[difficulty][ob->obclass])
+
+#define CAP_OSCUROS_HITPOINTS(ob)                         \
+   {                                                      \
+   if (ob->hitpoints > (SHP(gamestate.difficulty,ob)<<1)) \
+      ob->hitpoints = (SHP(gamestate.difficulty,ob)<<1);  \
+   }
+
+
+boolean           ludicrousgibs=false;
+
+short             colheight[15];
+
+byte              deathshapeoffset[8] = {0,7,7,8,8,9,8,7};
+
+unsigned long     MAXFUNCTION,MINFUNCTION,MAXSTATE,MINSTATE;
+
+objtype           *PLAYER0MISSILE;
+objtype           *SCREENEYE;
+objtype           *FIRSTACTOR,*LASTACTOR;
+
+objtype           *FIRSTFREE,*LASTFREE;
+objtype           *lastactive,*firstactive,**objlist;
+objtype           *firstareaactor[NUMAREAS+1],*lastareaactor[NUMAREAS+1];
+int               objcount;
+
+byte              RANDOMACTORTYPE[10];
+
+#if (SHAREWARE == 0)
+_2Dpoint          SNAKEPATH[512];
+#endif
+misc_stuff        mstruct,*MISCVARS = &mstruct;
+int               angletodir[ANGLES];
+objtype           *new;
+
+void              *actorat[MAPSIZE][MAPSIZE];
+#if (DEVELOPMENT == 1)
+FILE *            williamdebug;
+#endif
+exit_t            playstate;
+
+void              T_SlideDownScreen(objtype*);
+
+basic_actor_sounds  BAS[NUMCLASSES+3] =
+		  {{0,0,0,0,0},
+			{0,0,0,0,0},
+         {0,SD_LOWGUARD1SEESND,SD_LOWGUARDFIRESND,SD_LOWGUARDOUCHSND,SD_LOWGUARD1DIESND},
+			{0,SD_HIGHGUARD1SEESND,SD_HIGHGUARDFIRESND,SD_HIGHGUARDOUCHSND,SD_HIGHGUARDDIESND},
+			{0,SD_OVERP1SEESND,SD_OVERPFIRESND,SD_OVERPOUCHSND,SD_OVERPDIESND},
+			{0,SD_STRIKE1SEESND,SD_STRIKEFIRESND,SD_STRIKEOUCHSND,SD_STRIKEDIESND},
+			{0,SD_BLITZ1SEESND,SD_BLITZFIRESND,SD_BLITZOUCHSND,SD_BLITZDIESND},
+			{0,SD_ENFORCERSEESND,SD_ENFORCERFIRESND,SD_ENFORCEROUCHSND,SD_ENFORCERDIESND} ,
+			{0,SD_MONKSEESND,SD_MONKGRABSND,SD_MONKOUCHSND,SD_MONKDIESND},
+			{0,SD_FIREMONKSEESND,SD_FIREMONKFIRESND,SD_FIREMONKOUCHSND,SD_FIREMONKDIESND},
+         {0,SD_ROBOTSEESND,SD_ROBOTFIRESND,0,SD_ROBOTDIESND},
+
+			//bosses
+         {SD_DARIANSAY1,SD_DARIANSEESND,SD_DARIANFIRESND,0,SD_DARIANDIESND},
+         {SD_KRISTSAY1,SD_KRISTSEESND,SD_KRISTFIRESND,0,SD_KRISTDIESND},
+         {0,SD_NMESEESND,SD_NMEFIRE1SND,0,SD_NMEDIESND},
+         {SD_DARKMONKSAY1,SD_DARKMONKSEESND,SD_DARKMONKFIRE1SND,0,SD_DARKMONKDIESND},
+         {SD_SNAKESAY1,SD_SNAKESEESND,SD_SNAKESPITSND,0,SD_SNAKEDIESND},
+
+			//specials
+			{0,SD_EMPLACEMENTSEESND,SD_EMPLACEMENTFIRESND,0,0},
+         {0,SD_ROBOTSEESND,SD_ROBOTFIRESND,0,SD_ROBOTDIESND}, //wallop
+			{0,0,0,0,0}, //pillar
+			{SD_FIREJETSND,0,0,0,0}, //firejet
+			{SD_BLADESPINSND,0,0,0,0}, //blade
+			{SD_CYLINDERMOVESND,0,0,0,0}, //crushcol
+			{SD_BOULDERROLLSND,0,0,SD_BOULDERHITSND,0}, //boulder
+			{SD_SPEARSTABSND,0,0,0,0}, //spear
+			{0,0,0,0,0}, //gasgrate
+			{SD_SPRINGBOARDSND,0,0,0,0}, //spring
+			{0,0,0,0,0}, //shuriken
+			{SD_FIREBALLSND,0,0,SD_FIREBALLHITSND,0}, //wallfire
+			{0,0,0,0,0}, //net
+			{SD_KRISTMINEBEEPSND,0,0,0,0}, //h_mine
+			{0,0,0,0,0}, //grenade
+			{0,0,0,0,0}, //fireball
+			{0,0,0,0,0}, //dmfball
+			{0,0,0,0,0}, //bigshuriken
+			{0,0,0,0,0}, //missile
+			{0,0,0,0,0}, //NMEsaucer
+			{0,0,0,0,0}, //dm_weapon
+			{0,0,0,0,0}, //dm_heatseek
+			{0,0,0,0,0}, //dm_spit
+         {SD_MISSILEFLYSND,0,SD_BAZOOKAFIRESND,SD_MISSILEHITSND,0},
+			{SD_MISSILEFLYSND,0,SD_FIREBOMBFIRESND,SD_MISSILEHITSND,0},
+			{SD_MISSILEFLYSND,0,SD_HEATSEEKFIRESND,SD_MISSILEHITSND,0},
+			{SD_MISSILEFLYSND,0,SD_DRUNKFIRESND,SD_MISSILEHITSND,0},
+			{SD_FLAMEWALLSND,0,SD_FLAMEWALLFIRESND,SD_FIREHITSND,0},
+			{SD_MISSILEFLYSND,0,SD_SPLITFIRESND,SD_MISSILEHITSND,0},
+			{SD_GRAVSND,0,SD_GRAVFIRESND,SD_GRAVHITSND,0},
+			{SD_GRAVSND,0,SD_GODMODEFIRESND,SD_GRAVHITSND,0}
+
+		  };
+
+
+//========================== Local Variables ==================================================
+
+extern boolean dopefish;
+
+
+boolean Masterdisk;
+
+static objtype    *SNAKEHEAD,*SNAKEEND,*PARTICLE_GENERATOR,*EXPLOSIONS;
+#if (SHAREWARE == 0)
+  static int        OLDTILEX,OLDTILEY;
+#endif
+
+
+static char *debugstr[] = {
+
+		  "inerttype",
+		  "player",
+		  "lowguard",
+		  "highguard",
+		  "overpatrol",
+		  "strikeguard",
+		  "blitzguard",
+		  "triadenforcer",
+		  "deathmonk",
+		  "dfiremonk",
+		  "roboguard",
+		  "b_darian",
+		  "b_heinrich",
+		  "b_darkmonk",
+		  "b_roboboss",
+		  "b_darksnake",
+		  "patrolgun",
+		  "wallop",
+		  "pillar",
+		  "firejet",
+		  "blade",
+		  "crushcol",
+		  "boulder",
+		  "spear",
+		  "gasgrate",
+		  "spring",
+		  "shuriken",
+		  "wallfire",
+		  "net",
+		  "h_mine",
+		  "grenade",
+		  "fireball",
+		  "dmfball",
+		  "bigshuriken",
+		  "missile",
+		  "NMEsaucer",
+		  "dm_weapon",
+		  "dm_heatseek",
+		  "dm_spit",
+		  "p_bazooka",
+		  "p_firebomb",
+		  "p_heatseek",
+		  "p_drunkmissile",
+		  "p_firewall",
+		  "p_splitmissile",
+		  "p_kes",
+		  "p_godball",
+		  "collectorobj"
+		  };
+
+
+
+
+
+
+
+static int        starthitpoints[4][NUMENEMIES+2] =
+
+                  {{0,0,30,35,50,40,45,425,200,200,100,1500,2500,3000,3000,-1,200,2},
+                   {0,0,40,50,55,50,50,475,250,250,125,2300,3400,4500,3600,-1,250,2},
+                   {0,0,50,65,60,60,60,525,275,300,150,2400,3600,5000,4500,-1,300,2},
+                   {0,0,60,80,70,70,75,525,300,350,175,2800,3800,5900,4800,-1,350,2}};
+
+
+static statobj_t  *touchsprite;
+
+
+static const byte dirdiff[8][8] = {{0,1,2,3,4,3,2,1},{1,0,1,2,3,4,3,2},
+				{2,1,0,1,2,3,4,3},{3,2,1,0,1,2,3,4},
+				{4,3,2,1,0,1,2,3},{3,4,3,2,1,0,1,2},
+				{2,3,4,3,2,1,0,1},{1,2,3,4,3,2,1,0}};
+
+static const byte dirorder[8][2] = {{southeast,northeast},{east,north},
+				 {northeast,northwest},{north,west},
+				 {northwest,southwest},{west,south},
+				 {southwest,southeast},{south,east}};
+
+#if (SHAREWARE == 0)
+
+static const byte dirdiff16[16][16] = {
+				{0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1},
+				{1,0,1,2,3,4,5,6,7,8,7,6,5,4,3,2},
+				{2,1,0,1,2,3,4,5,6,7,8,7,6,5,4,3},
+				{3,2,1,0,1,2,3,4,5,6,7,8,7,6,5,4},
+				{4,3,2,1,0,1,2,3,4,5,6,7,8,7,6,5},
+				{5,4,3,2,1,0,1,2,3,4,5,6,7,8,7,6},
+				{6,5,4,3,2,1,0,1,2,3,4,5,6,7,8,7},
+				{7,6,5,4,3,2,1,0,1,2,3,4,5,6,7,8},
+				{8,7,6,5,4,3,2,1,0,1,2,3,4,5,6,7},
+				{7,8,7,6,5,4,3,2,1,0,1,2,3,4,5,6},
+				{6,7,8,7,6,5,4,3,2,1,0,1,2,3,4,5},
+				{5,6,7,8,7,6,5,4,3,2,1,0,1,2,3,4},
+				{4,5,6,7,8,7,6,5,4,3,2,1,0,1,2,3},
+				{3,4,5,6,7,8,7,6,5,4,3,2,1,0,1,2},
+				{2,3,4,5,6,7,8,7,6,5,4,3,2,1,0,1},
+				{1,2,3,4,5,6,7,8,7,6,5,4,3,2,1,0}};
+#endif
+
+static const byte dirorder16[16][2] = {
+						 {15,1}  ,   {0,2},   {1,3},   {2,4},
+						  {3,5}  ,   {4,6},   {5,7},   {6,8},
+						  {7,9}  ,  {8,10},  {9,11}, {10,12},
+						  {11,13}, {12,14}, {13,15},  {14,0}};
+
+//static byte opposite16[16] = {8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7};
+
+#if (SHAREWARE == 0)
+
+static statetype * UPDATE_STATES[NUMSTATES][NUMENEMIES] =
+
+ { {&s_lowgrdstand,&s_highgrdstand,&s_opstand,&s_strikestand,
+	 &s_blitzstand,&s_enforcerstand,&s_dmonkstand,&s_firemonkstand,
+	 &s_robogrdstand,&s_darianstand,&s_heinrichstand,NULL,
+	 &s_darkmonkstand,NULL,&s_gunstand,&s_wallstand},
+
+	{&s_lowgrdpath1,&s_highgrdpath1,&s_oppath1,&s_strikepath1,
+	 &s_blitzpath1,&s_enforcerpath1,&s_dmonkpath1,&s_firemonkpath1,
+	 &s_robogrdpath1,NULL,NULL,NULL,
+	 NULL,NULL,NULL,&s_wallpath},
+
+	{&s_lowgrdcollide,&s_highgrdcollide,&s_opcollide,&s_strikecollide,
+	 &s_blitzcollide,&s_enforcercollide,&s_dmonkcollide,&s_firemonkcollide,
+	 &s_robogrdcollide,&s_dariancollide,NULL,NULL,
+	 NULL,NULL,NULL,&s_wallcollide},
+
+	{&s_lowgrdcollide2,&s_highgrdcollide2,&s_opcollide2,&s_strikecollide2,
+	 &s_blitzcollide2,&s_enforcercollide2,&s_dmonkcollide2,&s_firemonkcollide2,
+	 &s_robogrdcollide2,&s_dariancollide2,NULL,NULL,
+	 NULL,NULL,NULL,&s_wallcollide},
+
+	{&s_lowgrdchase1,&s_highgrdchase1,&s_opchase1,&s_strikechase1,
+	 &s_blitzchase1,&s_enforcerchase1,&s_dmonkchase1,&s_firemonkchase1,
+	 NULL/*se1*/,&s_darianchase1,&s_heinrichchase,&s_NMEchase,
+	 &s_darkmonkchase1,NULL,&s_gunstand,&s_wallpath},
+
+	/*
+	{&s_lowgrduse1,&s_highgrduse1,&s_opuse1,&s_strikeuse1,
+	 &s_blitzuse,&s_enforceruse1,NULL,NULL,
+	 NULL,&s_darianuse1,NULL,NULL,
+	 NULL,NULL,NULL,NULL},*/
+	 {0},
+
+	{&s_lowgrdshoot1,&s_highgrdshoot1,&s_opshoot1,&s_strikeshoot1,
+	 &s_blitzshoot1,&s_enforcershoot1,NULL,&s_firemonkcast1,
+    &s_robogrdshoot1,&s_darianshoot1,&s_heinrichshoot1,NULL,
+	 NULL,NULL,&s_gunfire1,&s_wallshoot},
+
+	{&s_lowgrddie1,&s_highgrddie1,&s_opdie1,&s_strikedie1,
+	 &s_blitzdie1,&s_enforcerdie1,&s_dmonkdie1,&s_firemonkdie1,
+	 &s_robogrddie1,&s_dariandie1,&s_heinrichdie1,&s_NMEdie,
+	 &s_darkmonkdie1,NULL,&s_gundie1,NULL},
+
+	{0},
+
+	{NULL,NULL,NULL,&s_strikewait,
+	 &s_blitzstand,&s_enforcerdie1,&s_dmonkdie1,&s_firemonkdie1,
+	 &s_robogrddie1,&s_dariandie1,&s_heinrichdie1,NULL,
+	 &s_darkmonkdie1,NULL,NULL,NULL},
+
+	{&s_lowgrdcrushed1,&s_highgrdcrushed1,&s_opcrushed1,&s_strikecrushed1,
+	 &s_blitzcrushed1,&s_enforcercrushed1,&s_dmonkcrushed1,&s_firemonkcrushed1,
+	 &s_robogrddie1,NULL,NULL,NULL,
+	 NULL,NULL,NULL,NULL}
+
+	};
+
+#else
+
+static statetype * UPDATE_STATES[NUMSTATES][NUMENEMIES] =
+
+ { {&s_lowgrdstand,&s_highgrdstand,NULL,&s_strikestand,
+    &s_blitzstand,&s_enforcerstand,NULL,NULL,
+    &s_robogrdstand,NULL,NULL,NULL,
+    NULL,NULL,NULL,NULL},
+
+   {&s_lowgrdpath1,&s_highgrdpath1,NULL,&s_strikepath1,
+    &s_blitzpath1,&s_enforcerpath1,NULL,NULL,
+	 &s_robogrdpath1,NULL,NULL,NULL,
+    NULL,NULL,NULL,NULL},
+
+   {&s_lowgrdcollide,&s_highgrdcollide,NULL,&s_strikecollide,
+    &s_blitzcollide,&s_enforcercollide,NULL,NULL,
+    NULL,NULL,NULL,NULL,
+    NULL,NULL,NULL,NULL},
+
+   {&s_lowgrdcollide2,&s_highgrdcollide2,NULL,&s_strikecollide2,
+    &s_blitzcollide2,&s_enforcercollide2,NULL,NULL,
+    &s_robogrdcollide2,NULL,NULL,NULL,
+    NULL,NULL,NULL,NULL},
+
+   {&s_lowgrdchase1,&s_highgrdchase1,NULL,&s_strikechase1,
+    &s_blitzchase1,&s_enforcerchase1,NULL,NULL,
+    NULL,NULL,NULL,NULL,
+    NULL,NULL,NULL,NULL},
+
+	/*
+	{&s_lowgrduse1,&s_highgrduse1,&s_opuse1,&s_strikeuse1,
+	 &s_blitzuse,&s_enforceruse1,NULL,NULL,
+	 NULL,&s_darianuse1,NULL,NULL,
+	 NULL,NULL,NULL,NULL},*/
+	 {0},
+
+   {&s_lowgrdshoot1,&s_highgrdshoot1,NULL,&s_strikeshoot1,
+    &s_blitzshoot1,&s_enforcershoot1,NULL,NULL,
+    &s_robogrdshoot1,NULL,NULL,NULL,
+    NULL,NULL,NULL,NULL},
+
+   {&s_lowgrddie1,&s_highgrddie1,NULL,&s_strikedie1,
+    &s_blitzdie1,&s_enforcerdie1,NULL,NULL,
+    &s_robogrddie1,NULL,NULL,NULL,
+    NULL,NULL,NULL,NULL},
+
+	{0},
+
+	{NULL,NULL,NULL,&s_strikewait,
+    &s_blitzstand,&s_enforcerdie1,NULL,NULL,
+    &s_robogrddie1,NULL,NULL,NULL,
+    NULL,NULL,NULL,NULL},
+
+   {&s_lowgrdcrushed1,&s_highgrdcrushed1,NULL,&s_strikecrushed1,
+    &s_blitzcrushed1,&s_enforcercrushed1,NULL,NULL,
+	 &s_robogrddie1,NULL,NULL,NULL,
+	 NULL,NULL,NULL,NULL}
+
+	};
+
+#endif
+
+
+
+#define TABLE_ACTOR(ob)  ((ob->obclass >= lowguardobj) && (ob->obclass <= wallopobj))
+
+
+void T_Reset(objtype*ob);
+void ApplyGravity(objtype *ob);
+void BeginEnemyHurt(objtype *ob);
+void T_PlayDead(objtype *ob);
+void SpawnFirewall(objtype*ob,int which,int newz);
+void SelectKristChaseDir(objtype*ob);
+void ExplodeStatic(statobj_t*tempstat);
+void AvoidPlayerMissile(objtype*ob);
+int EnvironmentDamage(objtype *ob);
+
+static int     STOPSPEED         =    0x200;
+static int     PLAYERFRICTION    =    0xe000;
+static int     ACTORFRICTION     =    0xf000;
+static int     DIAGADJUST        =    0xb504;
+static boolean MissileSound      =    true;
+
+
+
+
+boolean FirstExplosionState(statetype *state)
+   {
+   if (DoPanicMapping())
+      {
+      if (state == &s_altexplosion1)
+         return true;
+      else
+         return false;
+      }
+   else
+      {
+      if ((state == &s_explosion1) ||
+          (state == &s_grexplosion1) ||
+          (state == &s_staticexplosion1)
+         )
+         return true;
+      else
+         return false;
+      }
+
+   }
+
+
+
+
+
+void SetGibSpeed(int speed)
+   {
+   MISCVARS->gibspeed = speed;
+   }
+
+void ResetGibSpeed(void)
+   {
+   MISCVARS->gibspeed = NORMALGIBSPEED;
+   }
+
+int ValidAreanumber (int areanumber)
+{ if ((areanumber >=0) && (areanumber <= NUMAREAS))
+	return 1;
+  return 0;
+}
+
+int GetIndexForState (statetype * state)
+{
+	int i;
+
+   if (state == NULL)
+      return -1;
+
+   for (i=0;i<MAXSTATES;i++)
+		{
+		if (statetable[i]==state)
+			return i;
+		}
+   Error("Cannot find the state in 'GetIndexForState', state->shapenum = %d\n",state->shapenum);
+	return -1;
+}
+
+
+
+statetype * GetStateForIndex (int index)
+{
+   if (index == -1)
+      return NULL;
+
+   return statetable[index];
+}
+
+
+statobj_t* GetStaticForIndex(int index)
+{statobj_t* temp;
+
+ for(temp=FIRSTSTAT;temp;temp=temp->statnext)
+  if (index == temp->whichstat)
+	 return temp;
+
+ Error("Cannot find the static in 'GetStaticForIndex', statindex %d\n",index);
+ return NULL;
+
+}
+
+
+
+void SaveActors(byte **buffer,int*size)
+{objtype*temp,*tact;
+ saved_actor_type dummy;
+ byte*tptr;
+ int actorcount;
+
+
+ for(actorcount=0,temp=FIRSTACTOR;temp;temp=temp->next)
+    temp->whichactor = actorcount++;
+
+
+
+ *size = sizeof(int) + sizeof(numplayers) + sizeof(misc_stuff) + objcount*sizeof(saved_actor_type);
+ *buffer = (byte*)SafeMalloc(*size);
+ tptr = *buffer;
+
+ memcpy(tptr,MISCVARS,sizeof(misc_stuff));
+ tptr += sizeof(misc_stuff);
+
+ memcpy(tptr,&numplayers,sizeof(numplayers));
+ tptr += sizeof(numplayers);
+
+ memcpy(tptr,&consoleplayer,sizeof(consoleplayer));
+ tptr += sizeof(consoleplayer);
+
+ for(temp=FIRSTACTOR;temp;temp=temp->next)
+  {dummy.x = temp->x;
+	dummy.y = temp->y;
+	dummy.z = temp->z;
+	dummy.flags = temp->flags;
+	dummy.areanumber = temp->areanumber;
+	//dummy.whichactor = temp->whichactor;
+	dummy.hitpoints = temp->hitpoints;
+	dummy.ticcount = temp->ticcount;
+	dummy.obclass = (byte)(temp->obclass);
+	dummy.stateindex = GetIndexForState(temp->state);
+	dummy.shapeoffset = temp->shapeoffset;
+	dummy.dirchoosetime = temp->dirchoosetime;
+	dummy.door_to_open = temp->door_to_open;
+	dummy.targetx = temp->targettilex;
+	dummy.targety = temp->targettiley;
+	dummy.dir = (signed char)temp->dir;
+	dummy.angle = temp->angle;
+	dummy.yzangle = temp->yzangle;
+	dummy.speed = temp->speed;
+	dummy.momentumx = temp->momentumx;
+	dummy.momentumy = temp->momentumy;
+	dummy.momentumz = temp->momentumz;
+
+	dummy.temp1 = temp->temp1;
+	dummy.temp2 = temp->temp2;
+	dummy.temp3 = temp->temp3;
+	if (temp->whatever)
+	  {/*if ((temp->flags & FL_USE) && (temp!=player))
+		  {dummy.whateverindex = (GetIndexForState((statetype*)(temp->whatever))|SG_PSTATE);
+			if ((dummy.whateverindex < 0) && (dummy.whateverindex != -1))
+			  Error("Bad actor whatever save value of %d\n",dummy.whateverindex);
+		  }
+		else*/
+		  {tact = (objtype*)(temp->whatever);
+			if (tact->which == ACTOR)
+			  dummy.whateverindex = tact->whichactor;
+			else
+			  {statobj_t *tstat;
+
+				tstat = (statobj_t*)(temp->whatever);
+				dummy.whateverindex = (tstat->whichstat|SG_PSTAT);
+
+			  }
+		  }
+	  }
+	else
+	 dummy.whateverindex = -1;
+
+
+	if (temp->target)
+	  {tact = (objtype*)(temp->target);
+		if (tact->which == ACTOR)
+		  {dummy.targetindex = tact->whichactor;
+			Debug("\nsave actor %d, type %d has target %d",temp->whichactor,temp->obclass,tact->whichactor);
+		  }
+		else if (tact->which == SPRITE)
+		  {statobj_t *tstat;
+
+			tstat = (statobj_t*)(temp->target);
+			dummy.targetindex = (tstat->whichstat|SG_PSTAT);
+		  }
+      else // It must be a push wall, and we don't save that
+        dummy.targetindex=-1;
+	  }
+	else
+	  dummy.targetindex = -1;
+
+
+	memcpy(tptr,&(dummy.x),sizeof(saved_actor_type));
+	tptr += sizeof(saved_actor_type);
+
+  }
+
+}
+
+
+
+void LoadActors(byte *buffer,int size)
+   {
+   int numactors,i,playerindex;
+   saved_actor_type dummy;
+   objtype *temp;
+   short *targetindices,*whateverindices;
+
+   InitActorList();
+
+   memcpy(MISCVARS,buffer,sizeof(misc_stuff));
+   buffer += sizeof(misc_stuff);
+
+   memcpy(&numplayers,buffer,sizeof(numplayers));
+   buffer += sizeof(numplayers);
+
+   memcpy(&playerindex,buffer,sizeof(playerindex));
+   buffer += sizeof(playerindex);
+
+   size -= (sizeof(misc_stuff)+sizeof(numplayers)+sizeof(playerindex));
+   numactors = size/sizeof(saved_actor_type);
+
+
+   objlist = (objtype**)SafeMalloc(numactors*sizeof(objtype*));
+   targetindices = (short*)SafeMalloc(numactors*sizeof(short));
+   whateverindices = (short*)SafeMalloc(numactors*sizeof(short));
+
+   for(i=0;i<numactors;i++)
+      {
+      targetindices[i] = 0;
+      whateverindices[i] = 0;
+      objlist[i] = NULL;
+      }
+
+
+   for(i=0;i<numactors;i++)
+      {
+      GetNewActor();
+      objlist[i] = new;
+      if (i < numplayers)
+         {
+         PLAYER[i]=new;
+         if (i==playerindex)
+            player=new;
+         }
+
+      memcpy(&(dummy.x),buffer,sizeof(saved_actor_type));
+
+      //new->x = dummy.x;
+      //new->y = dummy.y;
+      SetFinePosition(new,dummy.x,dummy.y);
+      SetVisiblePosition(new,dummy.x,dummy.y);
+      new->z = dummy.z;
+      new->flags = dummy.flags;
+      new->hitpoints = dummy.hitpoints;
+      new->ticcount = dummy.ticcount;
+      new->shapeoffset = dummy.shapeoffset;
+      new->obclass = (classtype)(dummy.obclass);
+
+
+      new->state = GetStateForIndex(dummy.stateindex);
+      if (new->state == &s_superparticles)
+         PARTICLE_GENERATOR = new;
+      else if
+         (new->state->think == T_SlideDownScreen)
+         SCREENEYE = new;
+      new->dirchoosetime = dummy.dirchoosetime;
+      new->door_to_open = dummy.door_to_open;
+      new->targettilex = dummy.targetx;
+      new->targettiley = dummy.targety;
+      new->dir = (dirtype)(dummy.dir);
+      new->angle = dummy.angle;
+      new->yzangle = dummy.yzangle;
+      new->speed = dummy.speed;
+      new->momentumx = dummy.momentumx;
+      new->momentumy = dummy.momentumy;
+      new->momentumz = dummy.momentumz;
+      new->temp1 = dummy.temp1;
+      new->temp2 = dummy.temp2;
+      new->temp3 = dummy.temp3;
+      if (dummy.whateverindex == -1)
+         new->whatever = NULL;
+
+      else if (dummy.whateverindex & SG_PSTAT)
+         new->whatever = GetStaticForIndex(dummy.whateverindex & ~SG_PSTAT);
+      else
+         whateverindices[i] = dummy.whateverindex+1;
+
+
+      if (dummy.targetindex == -1)
+         new->target = NULL;
+      else if (dummy.targetindex & SG_PSTAT)
+         new->target = GetStaticForIndex(dummy.targetindex & ~SG_PSTAT);
+      else
+         {
+         targetindices[i] = dummy.targetindex+1;
+         Debug("\nload actor %d, type %d has target %d",i,new->obclass,dummy.targetindex);
+         }
+
+
+      new->areanumber = dummy.areanumber;
+      new->shapenum = new->state->shapenum + new->shapeoffset;
+      new->which = ACTOR;
+      if (new->flags & FL_ABP)
+         MakeActive(new);
+      if (new->obclass != inertobj)
+         MakeLastInArea(new);
+
+      if (!(new->flags & (FL_NEVERMARK|FL_NONMARK)))
+         actorat[new->tilex][new->tiley] = new;
+
+      PreCacheActor(new->obclass,-1);
+      buffer += sizeof(saved_actor_type);
+      }
+
+
+   // find unique links between actors,
+   // searching list AFTER all have been spawned
+
+   for(i=0;i<numactors;i++)
+      {temp=objlist[i];
+      if (whateverindices[i])
+         temp->whatever = objlist[whateverindices[i]-1];
+      if (targetindices[i])
+         temp->target = objlist[targetindices[i]-1];
+      }
+
+
+   for(temp=FIRSTACTOR;temp;temp=temp->next)
+      {if (temp->obclass == b_darksnakeobj)
+         {if (!SNAKEHEAD)
+            SNAKEHEAD = temp;
+         else if (!temp->whatever)
+            SNAKEEND = temp;
+         }
+
+      }
+
+   if (SNAKEHEAD)
+      for(temp=FIRSTACTOR;temp;temp=temp->next)
+         {if (temp->state == &s_megaexplosions)
+            EXPLOSIONS = temp;
+         }
+
+   //SafeFree(objlist);
+   SafeFree(targetindices);
+   SafeFree(whateverindices);
+
+   }
+
+
+
+int RandomSign(void)
+   {
+   if (GameRandomNumber("random sign",0) < 128)
+      return -1;
+   return 1;
+
+
+   }
+
+
+void AddToFreeList(objtype*ob)
+{ if (!FIRSTFREE)
+	 FIRSTFREE = ob;
+  else
+	 {ob->prev = LASTFREE;
+	  LASTFREE->next = ob;
+	 }
+  LASTFREE = ob;
+
+}
+
+void RemoveFromFreeList(objtype*ob)
+{
+  if (ob == LASTFREE)
+		LASTFREE = ob->prev;
+  else
+		ob->next->prev = ob->prev;
+
+  if (ob == FIRSTFREE)
+		FIRSTFREE = ob->next;
+  else
+		ob->prev->next = ob->next;
+
+  ob->prev = NULL;
+  ob->next = NULL;
+
+}
+
+
+void MakeActive(objtype *ob)
+ {if ((ob == firstactive) || (ob->prevactive) || (ob->nextactive))
+	 {
+	 SoftError("\ndouble make active try");
+	 //AddEndGameCommand ();
+	 return;
+	 }
+
+  if (!firstactive)
+	 firstactive = ob;
+  else
+	 {ob->prevactive = lastactive;
+	  lastactive->nextactive = ob;
+	 }
+  lastactive = ob;
+
+  #if ((DEVELOPMENT == 1))
+  #if ((LOADSAVETEST == 1))
+  if (!lastactive)
+	Debug("\nlastactive = NULL !");
+  else
+	Debug("\nlastactive = %8x",lastactive);
+
+  #endif
+  #endif
+ }
+
+
+
+void MakeLastInArea(objtype *ob)
+ {
+  if (!ValidAreanumber(ob->areanumber))
+     Error("\n ob type %s at %d,%d has illegal areanumber of %d",
+           debugstr[ob->obclass],ob->tilex,ob->tiley,ob->areanumber);
+
+
+  if ((ob == firstareaactor[ob->areanumber]) || (ob->previnarea) || (ob->nextinarea))
+	 {
+	 SoftError("\ndouble make last in area try");
+	 //AddEndGameCommand ();
+	 return;
+	 }
+  if (!firstareaactor[ob->areanumber])
+	 firstareaactor[ob->areanumber]	= ob;
+  else
+	  {ob->previnarea = lastareaactor[ob->areanumber];
+		lastareaactor[ob->areanumber]->nextinarea = ob;
+	  }
+  lastareaactor[ob->areanumber] = ob;
+ }
+
+
+
+void RemoveFromArea(objtype*ob)
+ {
+  if (!((ob == firstareaactor[ob->areanumber]) || (ob->previnarea) || (ob->nextinarea)))
+	 {
+	 SoftError("\ndouble remove from area try");
+	 //AddEndGameCommand ();
+	 return;
+	 }
+
+  if (ob == lastareaactor[ob->areanumber])     // remove from master list
+		lastareaactor[ob->areanumber] = ob->previnarea;
+  else
+		ob->nextinarea->previnarea = ob->previnarea;
+
+  if (ob == firstareaactor[ob->areanumber])
+		firstareaactor[ob->areanumber] = ob->nextinarea;
+  else
+		ob->previnarea->nextinarea = ob->nextinarea;
+
+  ob->previnarea = NULL;
+  ob->nextinarea = NULL;
+ }
+
+
+void MakeInactive(objtype*ob)
+{
+  if (!ACTIVE(ob))
+//  if (!((ob == firstactive) || (ob->prevactive) || (ob->nextactive)))
+	 {
+	 SoftError("\n trying to remove inactive object");
+	 //AddEndGameCommand ();
+	 return;
+	 }
+
+  //if (ob->flags & FL_ABP)
+	  {
+
+		if (ob == lastactive)     // remove from master list
+			lastactive = ob->prevactive;
+		else
+			ob->nextactive->prevactive = ob->prevactive;
+
+		if (ob == firstactive)
+			firstactive = ob->nextactive;
+		else
+			ob->prevactive->nextactive = ob->nextactive;
+
+
+		ob->prevactive = NULL;
+		ob->nextactive = NULL;
+	  }
+
+}
+
+
+
+void A_Steal(objtype*ob)
+   {
+   int dx,dy,dz;
+
+   ActorMovement(ob);
+
+   dx = abs(ob->x - PLAYER[0]->x);
+   dy = abs(ob->y - PLAYER[0]->y);
+   dz = abs(ob->z - PLAYER[0]->z);
+
+   if ((dx > TOUCHDIST) || (dy > TOUCHDIST) || (dz > (TOUCHDIST >> 10)))
+      {
+      NewState(ob,&s_blitzchase1);
+      return;
+      }
+
+   if (ob->ticcount)
+      return;
+
+   SD_PlaySoundRTP(SD_BLITZSTEALSND,ob->x,ob->y);
+   if (PLAYER[0]->flags & FL_GASMASK)
+      {
+      PLAYER[0]->flags &= ~FL_GASMASK;
+      PLAYERSTATE[0].protectiontime = 1;
+      ob->temp3 = stat_gasmask;
+      GM_UpdateBonus (PLAYERSTATE[0].poweruptime, true);
+
+      }
+   else if(PLAYER[0]->flags & FL_BPV)
+      {
+      PLAYER[0]->flags &= ~FL_BPV;
+      PLAYERSTATE[0].protectiontime = 1;
+      ob->temp3 = stat_bulletproof;
+      GM_UpdateBonus (PLAYERSTATE[0].poweruptime, true);
+
+      }
+   else if(PLAYER[0]->flags & FL_AV)
+      {
+      PLAYER[0]->flags &= ~FL_AV;
+      PLAYERSTATE[0].protectiontime = 1;
+      ob->temp3 = stat_asbesto;
+      GM_UpdateBonus (PLAYERSTATE[0].poweruptime, true);
+
+      }
+   else if (PLAYERSTATE[0].missileweapon != -1)
+      {
+      NewState(PLAYER[0],&s_player);
+      PLAYERSTATE[0].attackframe = PLAYERSTATE[0].weaponframe = 0;
+      PLAYERSTATE[0].new_weapon = PLAYERSTATE[0].bulletweapon;
+      ob->temp3 = GetItemForWeapon(PLAYERSTATE[0].missileweapon);
+      ob->temp2 = PLAYERSTATE[0].ammo;
+      //ob->temp1 = oldpolltime;
+      PLAYERSTATE[0].ammo = -1;
+
+      if (PLAYERSTATE[0].weapon == PLAYERSTATE[0].missileweapon)
+         PLAYERSTATE[0].weapondowntics = WEAPONS[PLAYERSTATE[0].weapon].screenheight/GMOVE;
+      PLAYERSTATE[0].missileweapon = -1;
+
+      if ( SHOW_BOTTOM_STATUS_BAR() )
+         DrawBarAmmo (false);
+
+      }
+   }
+
+
+void FindAddresses(void)
+{
+ int i;
+ unsigned long tstate,tfunct;
+
+ MINFUNCTION = -1l;
+ MAXFUNCTION = 0x00000000;
+ MINSTATE = -1l;
+ MAXSTATE = 0x00000000;
+
+ for(i=0;i<MAXSTATES;i++)
+   {
+   tstate = (unsigned long)(statetable[i]);
+   if (tstate < MINSTATE)
+      MINSTATE = tstate;
+
+   if (tstate > MAXSTATE)
+      MAXSTATE = tstate;
+   if (statetable[i]!=NULL)
+      {
+      tfunct = (unsigned long)(statetable[i]->think);
+      if (tfunct < MINFUNCTION)
+         MINFUNCTION = tfunct;
+
+      if (tfunct > MAXFUNCTION)
+         MAXFUNCTION = tfunct;
+      }
+   }
+}
+
+void CheckBounds(objtype*ob)
+{
+ unsigned long tstate,tfunct;
+
+  tstate = (unsigned long)(ob->state);
+  tfunct = (unsigned long)(ob->state->think);
+
+ if ((tfunct < MINFUNCTION) || (tfunct > MAXFUNCTION) ||
+	  (tstate < MINSTATE) || (tstate > MAXSTATE))
+	{
+	 if (tfunct < MINFUNCTION)
+		Error("%s has thinking function less than MINFUNCTION",debugstr[ob->obclass]);
+
+	 else if (tfunct > MAXFUNCTION)
+		Error("%s has thinking function greater than MAXFUNCTION",debugstr[ob->obclass]);
+
+	 if (tstate < MINSTATE)
+		Error("%s has state less than MINSTATE",debugstr[ob->obclass]);
+
+	 else if (tstate > MAXSTATE)
+		Error("%s has state greater than MAXSTATE",debugstr[ob->obclass]);
+
+	}
+
+
+}
+
+/*************************************************************/
+
+
+/*
+=====================
+=
+= DoActor
+=
+=====================
+*/
+
+void DoActor (objtype *ob)
+   {
+	void (*think)(objtype *);
+	int door;
+
+
+//  for(i=0;i<tics;i++)
+//	{
+
+#if (BNACRASHPREVENT == 1)//
+		if (ob->state == 0){return;}
+#endif
+    ApplyGravity(ob);
+	 M_CheckDoor(ob);
+	 M_CheckBossSounds(ob);
+    if ((ob->obclass >= b_darianobj) &&
+        (ob->obclass < b_darksnakeobj) &&
+        MISCVARS->REDTIME
+       )
+       {
+       MISCVARS->REDTIME --;
+       MISCVARS->redindex = (MISCVARS->REDTIME  & 15);
+       }
+
+	 if (ob->obclass == playerobj)
+		 ControlPlayerObj(ob);
+
+	 think = ob->state->think;
+	 if (think)
+		 {
+		 //CheckBounds(ob);
+       think (ob);
+
+		 if (!ob->state)
+          {
+          RemoveObj (ob);
+			 return;
+          }
+       }
+
+	 if (ob->ticcount)
+       ob->ticcount --;
+
+	 else
+       {
+       if (!(ob->state->next))
+          {
+          RemoveObj (ob);
+			 return;
+          }
+       else
+          NewState(ob,ob->state->next);
+       }
+
+
+    if (ob->flags&FL_NEVERMARK)
+       return;
+
+    if ((ob->flags&FL_NONMARK) && actorat[ob->tilex][ob->tiley])
+       return;
+
+    actorat[ob->tilex][ob->tiley] = ob;
+    }
+
+
+
+
+
+void ApplyGravity(objtype *ob)
+   {
+   int oldmomentumz;
+
+   if (((ob->momentumz) || (ob->z != nominalheight)) &&
+       (ob->obclass > playerobj) &&
+       ((ob->obclass <= roboguardobj) || (ob->obclass == collectorobj) ||
+        (ob->obclass == b_heinrichobj)) &&
+       (ob->state->think != T_Stand)
+      )
+      {
+      ob->z += (ob->momentumz>>16);
+      ob->momentumz += GRAVITY;
+      if (ob->z >= nominalheight)
+         {
+         ob->z = nominalheight;
+         oldmomentumz = ob->momentumz;
+         ob->momentumz = 0;
+         if (oldmomentumz > 2*GRAVITY)
+            {
+            if (ob->flags & FL_DYING)
+               SD_PlaySoundRTP(ACTORTHUDSND,ob->x,ob->y);
+            else
+               {
+               int oldviolence = gamestate.violence;
+
+               SD_PlaySoundRTP(ACTORLANDSND,ob->x,ob->y);
+               gamestate.violence = vl_low;
+               BeginEnemyHurt(ob);
+               gamestate.violence = oldviolence;
+               }
+            }
+         if (ob->flags&FL_FALLINGOBJECT)
+            {
+            RemoveObj(ob);
+            return;
+            }
+         }
+      }
+   }
+
+
+
+/*
+===================
+=
+= NewState
+=
+= Changes ob to a new state, setting ticcount to the max for that state
+=
+===================
+*/
+
+void NewState (objtype *ob, statetype *newstate)
+{
+   if (DoPanicMapping() &&
+       ((newstate == &s_explosion1) ||
+        (newstate == &s_grexplosion1) ||
+        (newstate == &s_staticexplosion1)
+       )
+      )
+      ob->state = &s_altexplosion1;
+   else{
+#if (BNACRASHPREVENT == 1)//crashed here when oscuro and larves were all killed
+		if (ob == 0){return;}
+#endif
+      ob->state = newstate;
+   }
+   SetVisiblePosition(ob,ob->x,ob->y);
+#if (BNACRASHPREVENT == 1)
+		if (ob->state == 0){return;}
+#endif
+
+	ob->ticcount = (ob->state->tictime>>1);
+	ob->shapenum = ob->state->shapenum + ob->shapeoffset;
+
+}
+
+
+/*
+=========================
+=
+= InitActorList
+=
+= Call to clear out the actor object lists returning them all to the free
+= list.  Allocates a special spot for the player.
+=
+=========================
+*/
+
+
+
+void InitActorList (void)
+{
+	//====== NETWORK STUFF =======================================
+	memset(&DEADPLAYER[0],0,sizeof(DEADPLAYER));
+	NUMDEAD = 0;
+
+
+
+	//======= NULLIFY GLOBAL POINTERS ============================
+
+	LASTACTOR=FIRSTACTOR=NULL;
+	FIRSTFREE = LASTFREE = NULL;
+	firstactive = lastactive = NULL;
+	memset(firstareaactor,0,sizeof(firstareaactor));
+	memset(lastareaactor,0,sizeof(lastareaactor));
+   NUMSPAWNLOCATIONS = 0;
+
+
+	PARTICLE_GENERATOR = NULL;
+	EXPLOSIONS = NULL;
+	SNAKEEND=SNAKEHEAD=NULL;
+   SCREENEYE = NULL;
+   PLAYER0MISSILE = NULL;
+
+	//============================================================
+
+	objcount = 0;
+	memset(MISCVARS,0,sizeof(misc_stuff));
+   MISCVARS->gibgravity = -1;
+   MISCVARS->gibspeed = NORMALGIBSPEED;
+
+   memset(&RANDOMACTORTYPE[0],0,sizeof(RANDOMACTORTYPE));
+   FindAddresses();
+   MissileSound = true;
+   Masterdisk = false;
+
+}
+
+//===========================================================================
+
+/*
+=========================
+=
+= GetNewActor
+=
+= Sets the global variable new to point to a free spot in objlist.
+= The free spot is inserted at the end of the liked list
+=
+= When the object list is full, the caller can either have it bomb out ot
+= return a dummy object pointer that will never get used
+=
+=========================
+*/
+
+void GetNewActor (void)
+   {
+   objtype *temp;
+
+   if (!FIRSTFREE)
+      {
+      temp = (objtype*)Z_LevelMalloc(sizeof(objtype),PU_LEVELSTRUCT,NULL);
+      //SoftError("\nMalloc-ing actor");
+      //if (insetupgame)
+      //  SoftError("in setup");
+      }
+
+   else
+      {
+      temp = LASTFREE;
+      //SoftError("\nfree actor available");
+      RemoveFromFreeList(LASTFREE);
+      }
+
+   if (temp)
+      {
+      new = temp;
+      memset(new,0,sizeof(*new));
+
+      if (FIRSTACTOR)
+         {
+         new->prev = LASTACTOR;
+         LASTACTOR->next = new;
+         }
+      else
+         FIRSTACTOR = new;
+      LASTACTOR = new;
+
+      new->door_to_open = -1;
+      new->soundhandle = -1;
+      objcount ++;
+      }
+   else
+      Error("Z_LevelMalloc failed in GetNewActor");
+   }
+
+
+
+
+//===========================================================================
+
+
+
+
+/*
+=========================
+=
+= RemoveObj
+=
+= Add the given object back into the free list, and unlink it from it's
+= neighbors
+=
+=========================
+*/
+
+
+void RemoveObj (objtype *gone)
+{
+	if (gone == PLAYER[0])
+		Error ("RemoveObj: Tried to remove the player!");
+
+	gone->state=NULL;
+
+	MakeInactive(gone);
+
+	if (gone->obclass!=inertobj) {
+	    if (ValidAreanumber(gone->areanumber))
+		 RemoveFromArea(gone);
+	  else
+		 Error("tried to remove an instance of %s with invalid areanumber %d",debugstr[gone->obclass],gone->areanumber);
+	}
+
+	if (gone == LASTACTOR)
+	  LASTACTOR = gone->prev;
+	else
+	  gone->next->prev = gone->prev;
+
+	if (gone == FIRSTACTOR)
+	  FIRSTACTOR = gone->next;
+	else
+	  gone->prev->next = gone->next;
+
+	if (gone == EXPLOSIONS)
+	 EXPLOSIONS = NULL;
+	gone->next = NULL;
+	gone->prev = NULL;
+//	SoftError("\nremoving instance of %s",debugstr[gone->obclass]);
+	if (actorat[gone->tilex][gone->tiley] == (void*)gone)
+	 actorat[gone->tilex][gone->tiley] = NULL;
+
+	gone->flags |= FL_NEVERMARK;
+
+   if (gone->flags & FL_TARGET)
+      UnTargetActor(gone);
+
+	//Add_To_Delete_Array(gone);
+	//Z_Free(gone);
+	AddToFreeList(gone);
+
+	objcount--;
+}
+
+
+//============== World Physics Model Functions =========================
+
+
+void ParseMomentum(objtype *ob,int angle)
+   {
+   ob->momentumx += FixedMul(ob->speed,costable[angle]);
+   ob->momentumy -= FixedMul(ob->speed,sintable[angle]);
+   }
+
+void Set_3D_Momenta(objtype *ob, int speed, int theta, int phi)
+   {
+   int _2Ddiag;
+
+   ob->momentumz = -FixedMul(speed,sintable[phi]);
+   _2Ddiag = FixedMul(speed,costable[phi]);
+   ob->momentumx = FixedMul(_2Ddiag,costable[theta]);
+   ob->momentumy = -FixedMul(_2Ddiag,sintable[theta]);
+
+
+   }
+
+
+int AngleBetween(objtype *source,objtype*target)
+   {
+   int dx,dy;
+
+   dx = target->x - source->x;
+   dy = source->y - target->y;
+   return (atan2_appx(dx,dy));
+   }
+
+
+void GetMomenta(objtype *target, objtype *source, int *newmomx,
+                int *newmomy, int *newmomz, int magnitude
+               )
+   {
+   int angle,dx,dy,dz,yzangle,xydist,_2Ddiag;
+
+   dx = target->x - source->x;
+   dy = source->y - target->y;
+   dz = source->z - target->z;
+   xydist = FindDistance(dx,dy);
+   angle = atan2_appx(dx,dy);
+   yzangle = atan2_appx(xydist,(dz<<10));
+   _2Ddiag = FixedMul(magnitude,costable[yzangle]);
+
+   *newmomz = -FixedMul(magnitude,sintable[yzangle]);
+   *newmomx = FixedMul(_2Ddiag,costable[angle]);
+   *newmomy = -FixedMul(_2Ddiag,sintable[angle]);
+   }
+
+//=======================================================================
+
+
+
+
+
+void SpawnNewObj (unsigned tilex, unsigned tiley, statetype *state, classtype which)
+   {
+   int newarea;
+
+   GetNewActor ();
+	new->obclass = which;
+   SetTilePosition(new,tilex,tiley);
+   SetVisiblePosition(new,new->x,new->y);
+	new->dir = nodir;
+	new->which = ACTOR;
+   if (FirstExplosionState(state))
+      new->flags |= (FL_NEVERMARK|FL_NOFRICTION);
+
+   if ((which != inertobj) && (which != diskobj))
+      actorat[tilex][tiley] = new;
+
+   newarea = AREANUMBER(tilex,tiley);
+   if ((which <= springobj) && (which != inertobj))
+      {
+      if (ValidAreanumber(newarea))
+         new->areanumber = newarea;
+      else
+         Error("illegal initial areanumber of %d for actor type %s"
+               "trying to spawn at %d, %d",newarea,debugstr[which],tilex,tiley);
+      }
+   else
+      new->areanumber = newarea;
+
+   if ((which != inertobj) && (!Masterdisk))
+      MakeLastInArea(new);
+	NewState(new,state);
+	new->z = nominalheight;
+	if (which==springobj)
+		new->z+=2;
+
+   }
+
+
+//====================================================================
+
+void ConsiderAlternateActor(objtype *ob,classtype which)
+   {
+   if (((which >= lowguardobj) && (which <= blitzguardobj)) ||
+		 (which == dfiremonkobj))
+		{if (GameRandomNumber("SpawnStand",which) < 128)
+			{switch(which)
+				{case lowguardobj:
+               ob->shapeoffset =  W_GetNumForName("MARSHOO1") -
+                                  W_GetNumForName("LWGSHOO1");
+					break;
+				 case highguardobj:
+               ob->shapeoffset =  W_GetNumForName("HIGSHOO1") -
+                                  W_GetNumForName("HG2SHOO1");
+					break;
+				 case overpatrolobj:
+               ob->shapeoffset =  W_GetNumForName("PATSHOO1") -
+                                  W_GetNumForName("OBPSHOO1");
+					break;
+				 case strikeguardobj:
+               ob->shapeoffset =  W_GetNumForName("XYGSHOO1") -
+                                  W_GetNumForName("ANGSHOO1");
+					break;
+				 /*case blitzguardobj:
+					altstartlabel = "WIGSHOO1";
+					new->shapeoffset = 80;
+					break;*/
+				 case dfiremonkobj:
+               ob->shapeoffset =  W_GetNumForName("MRKKSH1") -
+                                  W_GetNumForName("ALLKSH1");
+					break;
+				default:
+				    ;
+				}
+			}
+
+		}
+
+   //if (new->shapeoffset)
+   //  {if (W_CheckNumForName(altstartlabel) == -1)
+   //     new->shapeoffset = 0;
+   //  }
+
+   }
+
+
+
+
+
+/*
+===================
+=
+= StandardEnemyInit
+=
+===================
+*/
+
+void StandardEnemyInit(objtype *ob,int dir)
+   {
+   int zoffset;
+
+   if ((ob->obclass == deathmonkobj) || (ob->obclass == dfiremonkobj))
+      ob->temp2 = DRAINTIME;
+
+   else if ((ob->obclass == highguardobj) || (ob->obclass == triadenforcerobj))
+      ob->flags |= FL_HASAUTO;
+
+   ob->hitpoints = starthitpoints[gamestate.difficulty][ob->obclass];
+   ob->dir = dir*2;
+   ob->flags |= (FL_SHOOTABLE|FL_BLOCK);
+   ob->speed = ENEMYRUNSPEED;
+   ob->dirchoosetime = 0;
+   ob->door_to_open = -1;
+
+   zoffset = MAPSPOT(ob->tilex,ob->tiley,2);
+   if ((zoffset&0xff00)==0xb000)
+      Set_NewZ_to_MapValue(&(ob->z),zoffset,"standard enemy",ob->tilex,ob->tiley);
+   else
+      ob->z = PlatformHeight(ob->tilex,ob->tiley);
+
+   }
+
+
+
+
+void ConsiderOutfittingBlitzguard(objtype *ob)
+   {
+   if ((GameRandomNumber("wiley blitzguard",0) < WILEYBLITZCHANCE) &&
+       (gamestate.difficulty >= gd_medium)
+      )
+      {
+      ob->temp3 = stat_bazooka;
+      ob->temp2 = 3;
+      }
+   }
+
+
+
+/*
+===============
+=
+= SpawnStand
+=
+===============
+*/
+
+
+void SpawnStand (classtype which, int tilex, int tiley, int dir, int ambush)
+{statetype *temp;
+
+ #if (SHAREWARE == 1)
+   switch(which)
+      {
+       case overpatrolobj:
+       case wallopobj:
+       case deathmonkobj:
+       case dfiremonkobj:
+       case b_darianobj:
+       case b_heinrichobj:
+       case b_darkmonkobj:
+         Error("\n%s actor at %d,%d not allowed in shareware !",debugstr[which],tilex,tiley);
+         break;
+      default:
+	  ;
+      }
+
+
+
+ #endif
+
+ if ((which == lowguardobj) && (GameRandomNumber("SpawnStand",which) < 128))
+    which = blitzguardobj;
+
+
+ if ((temp = UPDATE_STATES[STAND][which-lowguardobj]) != NULL)
+   {
+   SpawnNewObj(tilex,tiley,temp,which);
+   if (!loadedgame)
+      gamestate.killtotal++;
+
+
+   if (ambush)
+      new->flags |= FL_AMBUSH;
+
+
+ #if 0
+ #if (SUPERROTT == 1)
+
+   ConsiderAlternateActor(new,which);
+
+ #endif
+ #endif
+
+   StandardEnemyInit(new,dir);
+
+   if (which == b_darkmonkobj)
+      {
+      new->flags |= (FL_NOFRICTION);//|FL_INVULNERABLE);
+      new->speed = ENEMYRUNSPEED*2;
+      }
+
+   if (which == blitzguardobj)
+      ConsiderOutfittingBlitzguard(new);
+
+
+   if ((new->obclass >= lowguardobj) && (new->obclass <= dfiremonkobj))
+      RANDOMACTORTYPE[new->obclass]++;
+
+   if (MAPSPOT(tilex,tiley,2) == 0xdead)
+      {
+      new->flags |= FL_KEYACTOR;
+      MISCVARS->KEYACTORSLEFT++;
+      }
+
+   PreCacheActor(which,0);
+   }
+ //else
+   //Error("NULL initialization error");
+}
+
+
+
+
+
+/*
+===============
+=
+= SpawnPatrol
+=
+===============
+*/
+
+void SpawnPatrol (classtype which, int tilex, int tiley, int dir)
+{statetype *temp;
+ int path=PATH;
+#if 0
+#if (SUPERROTT == 1)
+ char *altstartlabel;
+#endif
+#endif
+
+
+
+ #if (SHAREWARE==1)
+   switch(which)
+      {
+       case overpatrolobj:
+       case wallopobj:
+       case deathmonkobj:
+       case dfiremonkobj:
+       case b_darianobj:
+       case b_heinrichobj:
+       case b_darkmonkobj:
+         Error("\n%s actor at %d,%d not allowed in shareware !",debugstr[which],tilex,tiley);
+         break;
+      default:
+	  ;
+      }
+
+ #endif
+
+ if ((which == lowguardobj) && (GameRandomNumber("SpawnStand",which) < 128))
+    which = blitzguardobj;
+
+
+
+
+ if ((temp= UPDATE_STATES[path][(int)(which-lowguardobj)]) != NULL)
+   {
+   SpawnNewObj(tilex,tiley,temp,which);
+
+   if (!loadedgame)
+      gamestate.killtotal++;
+
+
+   #if 0
+   #if (SUPERROTT == 1)
+   ConsiderAlternateActor(new,which);
+   #endif
+   #endif
+
+   StandardEnemyInit(new,dir);
+
+   if ((which == wallopobj) || (which == roboguardobj))
+      {new->flags |= FL_NOFRICTION;
+      //new->flags &= ~FL_SHOOTABLE;
+      new->dir <<= 1;
+      ParseMomentum(new,dirangle16[new->dir]);
+      }
+   else
+      ParseMomentum(new,dirangle8[new->dir]);
+
+
+   if (which == blitzguardobj)
+      ConsiderOutfittingBlitzguard(new);
+
+
+   if (MAPSPOT(tilex,tiley,2) == 0xdead)
+      {new->flags |= FL_KEYACTOR;
+      MISCVARS->KEYACTORSLEFT++;
+      }
+
+   PreCacheActor(which,0);
+   }
+
+}
+
+
+
+
+//==========================================================================
+
+
+
+void SpawnDisk(int tilex, int tiley, int type, boolean master)
+{int zoffset;
+
+
+
+ if (master == true)
+   {
+   Masterdisk = true;
+   SpawnNewObj(tilex,tiley,&s_diskmaster,diskobj);
+   Masterdisk = false;
+   new->flags |= FL_MASTER;
+   new->momentumz = -(DISKMOMZ << 16);
+   new->flags |= FL_SYNCED;
+   new->flags |= FL_NEVERMARK;
+   new->temp1 = 1;
+   //RemoveFromArea(new);
+
+   }
+
+ else
+   {
+   if (!type)
+      {
+      SpawnNewObj(tilex,tiley,&s_elevdisk,diskobj);
+      new->momentumz = -(DISKMOMZ << 16);
+      //new->flags |= FL_SYNCED;
+      zoffset = MAPSPOT(tilex,tiley,2);
+      if ((zoffset&0xff00)==0xb000)
+         Set_NewZ_to_MapValue((fixed*)(&(new->temp2)),zoffset,"elev disk",tilex,tiley);
+      else
+         new->temp2 = 32;
+      new->temp1 = 1;
+      }
+   else
+      {
+      SpawnNewObj(tilex,tiley,&s_pathdisk,diskobj);
+      zoffset = MAPSPOT(tilex,tiley,2);
+      if ((zoffset&0xff00)==0xb000)
+         Set_NewZ_to_MapValue((fixed*)(&(new->z)),zoffset,"path disk",tilex,tiley);
+
+      new->dir = (type-1) << 1;
+      new->speed = 0x1000;
+
+      //ParseMomentum(new,dirangle8[new->dir]);
+      }
+   actorat[tilex][tiley] = NULL;
+   new->flags |= FL_BLOCK;
+   new->flags |= (FL_NOFRICTION|FL_ACTIVE|FL_NEVERMARK);
+   }
+}
+
+
+
+
+objtype* DiskAt(int tilex,int tiley)
+{int area;
+ objtype *temp;
+ statobj_t *tstat;
+
+ area = AREANUMBER(tilex,tiley);
+ for(temp = firstareaactor[area];temp;temp = temp->nextinarea)
+   {if ((temp->tilex != tilex) || (temp->tiley != tiley) ||
+        (temp->obclass != diskobj))
+      continue;
+    return temp;
+
+   }
+
+ for(tstat = firstactivestat;tstat;tstat = tstat->nextactive)
+    {
+    if ((tstat->tilex != tilex) || (tstat->tiley != tiley) ||
+       (tstat->itemnumber != stat_disk))
+       continue;
+    return (objtype*)tstat;
+    }
+
+
+ return NULL;
+
+}
+
+
+void SetElevatorDiskVariables(objtype *ob,int newz, int newmomentumz,
+                              int newtemp1,int newtemp3,int newdirchoose)
+   {
+   ob->z = newz;
+   ob->momentumz = newmomentumz;
+   ob->temp1 = newtemp1;
+   ob->temp3 = newtemp3;
+   ob->dirchoosetime = newdirchoose;
+   }
+
+
+void T_ElevDisk(objtype*ob)
+   {
+   objtype *temp = (objtype*)(actorat[ob->tilex][ob->tiley]);
+   objtype *master;
+
+   if (ob->flags & FL_MASTER)
+      goto masterlabel;
+
+   master = (objtype*)(ob->target);
+   if (!master)
+   Error("disk without master !");
+
+
+   //SoftError("\n ob->z:%d %s, master z:%d",ob->z,
+   //        (ob->flags & FL_SYNCED)?("SYNCED"):("UNSYNCED"),master->z);
+
+
+   if (M_ISACTOR(temp) && (temp != ob) && (!(temp->flags & FL_DYING)))
+      {
+      int dz = abs(ob->z - temp->z),
+          dx = abs(ob->x - temp->x),
+          dy = abs(ob->y - temp->y);
+
+      if ((dx < 0x7000) && (dy < 0x7000) && (dz < 68) && (temp->z > ob->z))
+         {
+         ob->flags &= ~FL_SYNCED;
+         return;
+         }
+      }
+
+   if (master && (!(ob->flags & FL_SYNCED)))
+      {
+      int dz;
+
+      dz = abs(master->z - ob->z);
+      if ((dz > 0) && (dz < 8))
+         {
+         SetElevatorDiskVariables(ob,master->z,master->momentumz,master->temp1,
+                                    master->temp3,master->dirchoosetime);
+         ob->flags |= FL_SYNCED;
+         //return;
+         }
+      return;
+      }
+
+
+ masterlabel:
+
+   if (ob->dirchoosetime)
+      {
+      ob->dirchoosetime --;
+      return;
+      }
+
+
+   if (ob->temp1) // moving
+      {
+      ob->z += (ob->momentumz >> 16);
+      if (ob->momentumz > 0) // down
+         {
+         if (ob->z >= nominalheight + 40 + DISKMOMZ)
+            SetElevatorDiskVariables(ob,ob->z - (ob->momentumz>>16),0,0,0,35);
+         }
+      else
+         {
+         if (ob->z < ob->temp2) // temp2 has max height
+            SetElevatorDiskVariables(ob,ob->z - (ob->momentumz>>16),0,0,1,35);
+         }
+      }
+   else
+      {
+      if (ob->temp3)
+         ob->momentumz = (DISKMOMZ << 16);
+      else
+         ob->momentumz = -(DISKMOMZ << 16);
+      ob->temp1 = 1;
+      }
+   }
+
+
+
+
+void SpawnInertActor(int newx,int newy, int newz)
+   {
+	GetNewActor ();
+   MakeActive(new);
+
+   new->obclass = inertobj;
+   new->which = ACTOR;
+   SetFinePosition(new,newx,newy);
+   SetVisiblePosition(new,new->x,new->y);
+   new->z = newz;
+   new->dir = 0;
+   new->speed = 0;
+   new->flags = (FL_NEVERMARK|FL_ABP);
+
+   }
+
+
+
+
+#if (SHAREWARE == 0)
+void SpawnGroundExplosion(int x, int y, int z)
+{
+   SpawnInertActor(x,y,z);
+   NewState(new,&s_grexplosion1);
+   new->temp2 = GameRandomNumber("SpawnGroundExplosion",0)>>2;
+
+}
+#endif
+
+void SpawnSlowParticles(int which, int numgibs, int x,int y,int z)
+{objtype *prevlast,*temp;
+ int tilex,tiley;
+
+ tilex = x>>16;
+ tiley = y>>16;
+
+ SpawnNewObj(tilex,tiley,&s_gibs1,inertobj);
+ SetFinePosition(new,x,y);
+ SetVisiblePosition(new,x,y);
+ prevlast = new;
+ prevlast->flags |= FL_ABP;
+ MakeActive(prevlast);
+ SpawnParticles(new,which,numgibs);
+
+ for(temp = prevlast->next;temp;temp=temp->next)
+    {temp->z = z;
+     temp->momentumx >>= 1;
+     temp->momentumy >>= 1;
+     temp->momentumz >>= 1;
+    }
+ RemoveObj(prevlast);
+
+}
+
+
+void ResolveDoorSpace(int tilex,int tiley)
+   {
+   statobj_t* tstat,*temp;
+
+   for(tstat = firstactivestat;tstat;)
+      {
+      temp = tstat->nextactive;
+
+      if (tstat->flags & FL_DEADBODY)
+         {
+         if ((tstat->tilex == tilex) && (tstat->tiley == tiley))
+            {
+            if ((tstat->flags & FL_DEADBODY) && (tstat->linked_to != -1))
+                DEADPLAYER[tstat->linked_to] = NULL;
+            RemoveStatic(tstat);
+            if (tstat->flags & FL_DEADBODY)
+               SpawnSlowParticles(GUTS,8,tstat->x,tstat->y,tstat->z);
+            else
+               SpawnSlowParticles(gt_sparks,8,tstat->x,tstat->y,tstat->z);
+            SD_PlaySoundRTP(SD_ACTORSQUISHSND,tstat->x,tstat->y);
+            }
+         }
+      tstat = temp;
+      }
+   }
+
+
+void SpawnSpear(int tilex,int tiley,int up)
+   {
+   int count,i;
+   statetype *tstate;
+
+
+   if (BATTLEMODE && (!gamestate.BattleOptions.SpawnDangers))
+      return;
+
+   if (!up)
+      {
+#if (SHAREWARE == 1)
+      Error("\ndownspear at %d,%d in shareware!",tilex,tiley);
+#else
+      SpawnNewObj(tilex,tiley,&s_speardown1,spearobj);
+      new->z = 0;
+#endif
+      }
+   else
+
+      SpawnNewObj(tilex,tiley,&s_spearup1,spearobj);
+
+   count = (int)(GameRandomNumber("Spawn Spear",0) % 16);
+   for(i=0,tstate = new->state;i<count;i++,tstate=tstate->next);
+   NewState(new,tstate);
+
+   PreCacheActor(spearobj,up);
+   new->flags |= (FL_ABP);//|FL_INVULNERABLE);
+   MakeActive(new);
+   }
+
+
+
+void SpawnSpring(int tilex,int tiley)
+   {
+   int iconvalue;
+
+   iconvalue = MAPSPOT(tilex,tiley,2);
+   if (iconvalue == 3)
+      {
+      SpawnNewObj(tilex,tiley,&s_autospring1,springobj);
+      new->ticcount = (GameRandomNumber("Spawn Spring",0) % new->ticcount)+1;
+      new->temp1 = iconvalue;
+      }
+   else
+      {
+      SpawnNewObj(tilex,tiley,&s_spring1,springobj);
+      if (iconvalue == 2)
+         new->temp1 = iconvalue;
+      }
+
+   PreCacheActor(springobj,0);
+   new->flags &= ~(FL_SHOOTABLE|FL_BLOCK);
+   }
+
+
+
+
+void T_Spring(objtype*ob)
+   {
+   objtype *temp;
+   int op,dx,dy,dz;
+
+
+   if ((ob->state->condition & SF_DOWN) && (ob->temp1))
+      {
+      if (ob->ticcount)
+         return;
+      ob->shapenum++;
+      TurnActorIntoSprite(ob);
+      return;
+      }
+
+   for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
+      {
+      if (temp == ob)
+         continue;
+
+      if (temp->obclass >= roboguardobj)
+         continue;
+
+      dx = abs(ob->x-temp->x);
+      dy = abs(ob->y-temp->y);
+      dz = abs(ob->z-temp->z);
+      if ((dx > ACTORSIZE+0x2800) || (dy > ACTORSIZE+0x2800) || (dz > 40))
+         continue;
+      if (!temp->momentumz)
+         {
+         op = FixedMul(GRAVITY,(temp->z-5)<<16) << 1;
+         temp->momentumz = -FixedSqrtHP(op);
+         SD_PlaySoundRTP(SD_SPRINGBOARDSND,ob->x,ob->y);
+         }
+      }
+   }
+
+
+
+void T_Count(objtype*ob)
+   {
+   int index;
+   wall_t* tswitch;
+   touchplatetype *temp;
+   objtype* tempactor;
+
+   if (ob->dirchoosetime)
+      {
+      ob->dirchoosetime --;
+      if (ob->dirchoosetime>980)
+         MISCVARS->gasindex=((1050-ob->dirchoosetime)<<4)/70;
+      else if (ob->dirchoosetime<35)
+         MISCVARS->gasindex=(ob->dirchoosetime<<4)/35;
+      if (ob->temp3)
+         {
+         ob->temp3 --;
+         if (ob->temp3 & 1)
+            SD_PlaySoundRTP(SD_GASHISSSND,ob->x,ob->y);
+         }
+      else
+         {
+         ob->temp3 = 105;
+         for(tempactor=firstareaactor[ob->areanumber];tempactor;tempactor=tempactor->nextinarea)
+            {
+            if (tempactor == ob)
+               continue;
+            if (!(tempactor->flags & FL_SHOOTABLE))
+               continue;
+            if (tempactor->obclass != playerobj)
+               {
+               if ((tempactor->obclass >= lowguardobj) &&
+                   (tempactor->obclass <= dfiremonkobj))
+                  {
+                  int oldviolence = gamestate.violence;
+
+                  gamestate.violence = vl_low;
+                  DamageThing(tempactor,EnvironmentDamage(ob));
+                  Collision(tempactor,ob,-(tempactor->momentumx),-(tempactor->momentumy));
+                  gamestate.violence = oldviolence;
+
+                  }
+               }
+            else if (!(tempactor->flags & FL_GASMASK))
+               {
+               DamageThing(tempactor,EnvironmentDamage(ob));
+               Collision(tempactor,ob,0,0);
+               M_CheckPlayerKilled(tempactor);
+               }
+            }
+         }
+      }
+
+   else
+      {
+      int i;
+      playertype *pstate;
+
+      for(i=0;i<numplayers;i++)
+         {
+         M_LINKSTATE(PLAYER[i],pstate);
+         PLAYER[i]->flags &= ~FL_GASMASK;
+         pstate->protectiontime = 1;
+         }
+
+      NewState(ob,&s_gas1);
+      SD_PlaySoundRTP(SD_GASENDSND,ob->x,ob->y);
+      ob->flags &= ~FL_ACTIVE;
+      MISCVARS->gasindex=0;
+      MU_StartSong(song_level);
+      MU_RestoreSongPosition();
+      MISCVARS->GASON = 0;
+
+      index = touchindices[ob->temp1][ob->temp2]-1;
+      TRIGGER[index] = 0;
+      for(temp = touchplate[index];temp;temp = temp->nextaction)
+         if (temp->action == EnableObject)
+            {
+            tempactor = (objtype*)(temp->whichobj);
+            tempactor->flags &= ~FL_ACTIVE;
+            }
+
+      tswitch = (wall_t*)actorat[ob->temp1][ob->temp2];
+      /*
+      if (tswitch && (tswitch->which != ACTOR))
+         {
+         tilemap[ob->temp1][ob->temp2]--;
+         tswitch->flags &= ~FL_ON;
+         }
+      */
+
+      }
+   }
+
+
+
+
+void SpawnBlade(int tilex, int tiley,int dir,int upordown,int moving)
+{int count,i;
+ statetype *nstate;
+
+ #if (SHAREWARE == 1)
+   if (!upordown)
+     Error("\ndown spinblade at %d,%d not allowed in shareware !",tilex,tiley);
+   if (moving)
+     Error("\nupdown spinblade at %d,%d not allowed in shareware !",tilex,tiley);
+
+ #endif
+
+
+ if (BATTLEMODE && (!gamestate.BattleOptions.SpawnDangers))
+	return;
+
+ if (moving)
+
+  {
+#if (SHAREWARE == 0)
+
+  if (upordown)
+	  SpawnNewObj(tilex,tiley,&s_spinupblade1,bladeobj);
+   else
+	  {SpawnNewObj(tilex,tiley,&s_spindownblade1,bladeobj);
+		new->z = 0;
+	  }
+#endif
+  }
+ else
+  {if (upordown)
+	  SpawnNewObj(tilex,tiley,&s_upblade1,bladeobj);
+
+#if (SHAREWARE == 0)
+
+   else
+	  {SpawnNewObj(tilex,tiley,&s_downblade1,bladeobj);
+		new->z = 0;
+	  }
+#endif
+  }
+
+
+ count = (int)(GameRandomNumber("SpawnBlade",0) % 16);
+ for(nstate=new->state,i=0;i<count;nstate = nstate->next,i++);
+ NewState(new,nstate);
+
+ new->flags |= (FL_BLOCK);
+ new->flags &= ~FL_SHOOTABLE;
+ new->dir = dir;
+ if (dir != nodir)
+  {new->flags |= FL_NOFRICTION;
+	new->speed = ENEMYRUNSPEED;
+
+  }
+ if (!MAPSPOT(tilex,tiley,2))
+	{new->flags |= FL_ACTIVE;
+	 ParseMomentum(new,dirangle8[new->dir]);
+	}
+ PreCacheActor(bladeobj,(moving<<1)+upordown);
+}
+
+
+void SpawnCrushingColumn(int tilex, int tiley, int upordown)
+{int i,count;
+ statetype * nstate;
+
+
+ #if (SHAREWARE == 1)
+  if (!upordown)
+    Error("\ncrush-up column at %d,%d not allowed in shareware!",tilex,tiley);
+ #endif
+
+
+ if (BATTLEMODE && (!gamestate.BattleOptions.SpawnDangers))
+	return;
+#if (SHAREWARE == 0)
+ if (!upordown)
+  SpawnNewObj(tilex,tiley,&s_columnupup1,crushcolobj);
+ else
+#endif
+  {SpawnNewObj(tilex,tiley,&s_columndowndown1,crushcolobj);
+	new->z = 0;
+  }
+
+ count = (int)(GameRandomNumber("SpawnCrushingColumn",0) % 8);
+ for(nstate=new->state,i=0;i<count;nstate = nstate->next,i++)
+	{if ((!upordown) && (nstate->condition & SF_UP))
+		new->temp1 += (((nstate->tictime>>1) + 1)<<2);
+
+	}
+ NewState(new,nstate);
+ new->flags |= (FL_BLOCK);
+
+ new->flags &= ~FL_SHOOTABLE;
+ PreCacheActor(crushcolobj,upordown);
+}
+
+
+
+void SpawnFirejet(int tilex, int tiley, int dir, int upordown)
+   {
+   int statecount,i;
+   statetype *tstate;
+
+
+   statecount = (int)(GameRandomNumber("SpawnFirejet",0) % 22);
+
+   if (upordown)
+      {
+      for(i=0,tstate=&s_firejetup1;i<statecount;i++,tstate=tstate->next);
+      SpawnNewObj(tilex,tiley,tstate,firejetobj);
+      }
+   else
+      {
+#if (SHAREWARE == 1)
+      Error("\ndown firejet at %d,%d not allowed in shareware",tilex,tiley);
+#else
+      for(i=0,tstate=&s_firejetdown1;i<statecount;i++,tstate=tstate->next);
+      SpawnNewObj(tilex,tiley,tstate,firejetobj);
+      new->z = 0;
+#endif
+      }
+
+   PreCacheActor(firejetobj,upordown);
+
+   new->flags &= ~FL_SHOOTABLE;
+
+   if (dir != nodir)
+      {
+      new->dir = dir*2;
+      new->flags |= FL_NOFRICTION;
+      new->speed = ENEMYRUNSPEED;
+      ParseMomentum(new,dirangle8[new->dir]);
+      }
+   else
+      new->dir = dir;
+   }
+
+
+void SpawnFirebomb(objtype*ob,int damage,int which)
+   {
+   int i,low,high,doorat;
+   wall_t *tempwall;
+   doorobj_t*tempdoor;
+
+   if (which == 0)
+      {
+      low = (ob->dir>>1);
+      high = low;
+      }
+   else
+      {
+      low = 0;
+      high = which-1;
+
+      if ((FindDistance((ob->x-player->x), (ob->y-player->y))<0x120000) &&
+          (player->z==nominalheight)
+         )
+         SHAKETICS = 35;
+      }
+
+   for (i=low;i<=high;i++)
+      {
+      MissileSound = false;
+      /*
+      if (((which == 0) && ((low == 5) || (low == 6))) ||
+          ((which == 6) && ((i==4) || (i==5)))
+         )
+         {
+
+         if (((which == 0) && (low == 5)) ||
+             ((which == 6) && (i == 4))
+            )
+            {
+            newz = ob->z + 64;
+            if (newz > maxheight)
+               continue;
+            SpawnMissile(ob,p_firebombobj,0,0,&s_grexplosion1,0);
+            new->z = newz;
+            new->dir = 10;
+
+
+            }
+         else
+            {
+            newz = ob->z - 64;
+            if ((sky == 0) && (newz < 0))
+               continue;
+            SpawnMissile(ob,p_firebombobj,0,0,&s_grexplosion1,0);
+            new->z = newz;
+            new->dir = 12;
+
+            }
+
+
+         }
+      else */
+         {
+         SpawnMissile(ob,p_firebombobj,0,dirangle8[2*i],&s_grexplosion1,0x10000);
+         new->z = ob->z;
+         new->dir = (i<<1);
+
+         }
+
+      MissileSound = true;
+
+
+      SD_PlaySoundRTP(SD_EXPLODEFLOORSND,ob->x,ob->y);
+      new->temp2 = FixedMul(damage,DIAGADJUST);
+
+
+      tempwall = (wall_t*)actorat[new->tilex][new->tiley];
+      doorat= 0;
+      if (M_ISDOOR(new->tilex,new->tiley))
+         {
+         tempdoor = doorobjlist[tilemap[new->tilex][new->tiley]&0x3ff];
+         if (tempdoor->position<0x8000)
+            doorat = 1;
+         }
+
+      if ((tempwall && M_ISWALL(tempwall)) || doorat ||
+          (new->tilex <=0) || (new->tilex > MAPSIZE-1) ||
+          (new->tiley <=0) || (new->tiley > MAPSIZE-1)
+         )
+         {
+         new->z = ob->z;
+         SetFinePosition(new,ob->x,ob->y);
+         SetVisiblePosition(new,ob->x,ob->y);
+         }
+      new->whatever = ob->whatever;
+      new->temp3 = ob->temp3 - 1;
+      }
+   }
+
+
+
+
+
+
+void MissileHitActor(objtype *owner, objtype *missile, objtype *victim,
+                     int damage, int hitmomx, int hitmomy
+                    )
+   {
+   int tcl = victim->obclass;
+   int ocl = missile->obclass;
+
+   if (
+         (victim->flags & FL_DYING) || // hey, they're dying already;
+         (victim->flags & FL_HEAD)  || // don't hurt overrobot's head, wheels
+         (tcl == wallopobj)            || // bcraft is invulnerable
+         (tcl == b_darkmonkobj)        || // darkmonk is invulnerable
+         (!(victim->flags & FL_SHOOTABLE)) || // don't hurt environment dangers, dead guys
+         ((tcl == b_darksnakeobj) &&
+         ((SNAKELEVEL != 3) || (!victim->temp3))// return for non-red snake
+         )
+      )
+      return;
+
+
+   if ((tcl == playerobj) || (tcl == b_heinrichobj))
+      victim->target = owner;
+
+
+   if (tcl == NMEsaucerobj)  // can shoot over's saucer
+      {
+      NewState(victim,&s_explosion1);
+      victim->flags &= ~FL_SHOOTABLE;
+      victim->temp2 = damage;
+      return;
+      }
+
+   else if (tcl == roboguardobj)       // check roboguard
+      {
+      DamageThing(victim,damage);
+      Collision(victim,owner,0,0);
+      }
+
+   else if (tcl == collectorobj)
+      {
+      if (gamestate.SpawnEluder)
+         return;
+
+      DamageThing(victim,damage);
+      Collision(victim,owner,0,0);
+      }
+
+   else if (tcl == patrolgunobj)
+      {
+      DamageThing(victim,damage);
+      if (victim->hitpoints <= 0)
+         {
+         victim->momentumx = victim->momentumy = victim->momentumz = 0;
+         victim->flags |= FL_DYING;
+         if (victim->temp1 == -1)  // this is 4-way gun
+            NewState(victim,&s_robogrddie1);
+#if (SHAREWARE == 0)
+         else                         // this is normal
+            NewState(victim,&s_gundie1);
+#endif
+         }
+      }
+
+// bosses are "special" ==========================
+
+   else if ((tcl >= b_darianobj) && (tcl < b_darkmonkobj))
+
+      {
+      DamageThing(victim,damage);
+      if (!(victim->flags & FL_ATTACKMODE))
+         FirstSighting (victim);     // put into combat mode
+      if (victim->hitpoints <= 0)
+         {
+         victim->momentumx = victim->momentumy = victim->momentumz = 0;
+         victim->flags |= FL_DYING;
+         NewState(victim,UPDATE_STATES[DIE][victim->obclass-lowguardobj]);
+         switch (victim->obclass)
+            {
+            case b_darianobj:
+               AddMessage("Darian defeated!",MSG_CHEAT);
+               break;
+
+            case b_heinrichobj:
+               AddMessage("Krist defeated!",MSG_CHEAT);
+               break;
+
+            case b_robobossobj:
+               AddMessage("NME defeated!",MSG_CHEAT);
+               break;
+	    default:
+		;
+            }
+         MU_StartSong(song_bossdie);
+         }
+#if (SHAREWARE == 0)
+      else
+         {
+         MISCVARS->REDTIME = (damage >> 1);
+         if (victim->obclass == b_heinrichobj)
+            {
+            NewState(victim,&s_heinrichdefend);
+            if (Near(victim,PLAYER[0],3))
+               {
+               MISCVARS->HRAMMING = 1;
+               MISCVARS->HMINING = 0;
+               victim->dirchoosetime = 0;
+               }
+            else
+               {
+               MISCVARS->HMINING = 1;
+               MISCVARS->HRAMMING = 0;
+               victim->dirchoosetime = 5;//10;
+               }
+            victim->targettilex = victim->targettiley = 0;
+            victim->target = NULL;
+            }
+         }
+#endif
+      }
+
+#if (SHAREWARE == 0)
+   else if ((tcl == b_darksnakeobj) && (victim->temp3)) // red snake
+      {
+      DamageThing(SNAKEEND,damage);
+      if (victim->state->think == T_DarkSnakeChase)
+         NewState(victim,&s_redheadhit);
+      else
+         NewState(victim,&s_redlinkhit);
+      victim->temp3 = 0;
+      }
+#endif
+
+//===============================================
+   else // all other actors
+      {
+
+      if ((tcl == playerobj) &&
+          (victim->flags & FL_AV) &&
+          (ocl != p_godballobj)
+         )
+         {
+         playertype *pstate;
+
+         M_LINKSTATE(victim,pstate);
+         pstate->protectiontime -= ((damage<<1) + damage);
+         if (pstate->protectiontime < 1)
+            pstate->protectiontime = 1;
+         if (victim==player)
+            GM_UpdateBonus (pstate->protectiontime, false);
+
+         return;  // asbestos vest prevents victim damage
+         }
+
+      DamageThing(victim,damage);
+
+
+
+      if ((tcl < roboguardobj) && (victim->hitpoints <= 0))
+         {
+         if (ocl != p_godballobj)
+            victim->flags |= FL_HBM;
+         else
+            victim->flags |= (FL_GODSTRUCK | FL_FULLLIGHT);
+         }
+
+      if (tcl == playerobj)
+         {
+         playertype *pstate;
+
+         M_LINKSTATE(victim,pstate);
+         if (pstate->health <= 0)
+            {
+            if (ocl != p_godballobj)
+               victim->flags |= FL_HBM;
+            else
+               victim->flags |= (FL_GODSTRUCK | FL_FULLLIGHT);
+
+            if (M_ISACTOR(owner))
+               {
+               if (owner->obclass == playerobj)
+                  {
+                  if (!victim->momentumz)
+                     BATTLE_PlayerKilledPlayer(battle_kill_with_missile,owner->dirchoosetime,victim->dirchoosetime);
+                  else
+                     BATTLE_PlayerKilledPlayer(battle_kill_with_missile_in_air,owner->dirchoosetime,victim->dirchoosetime);
+                  }
+               else
+                  BATTLE_CheckGameStatus(battle_player_killed,missile->dirchoosetime);
+               }
+            else
+                  BATTLE_CheckGameStatus(battle_player_killed,missile->dirchoosetime);
+            }
+         }
+
+
+
+      if ((owner->obclass == playerobj) && (victim->flags & FL_HBM))
+         {
+            MISCVARS->supergibflag = true;
+         //GivePoints(starthitpoints[gamestate.difficulty][victim->obclass]*5);
+         }
+
+      Collision(victim,owner,hitmomx,hitmomy);
+      MISCVARS->supergibflag = false;
+      if ((tcl == blitzguardobj) && (owner->obclass == playerobj))
+         victim->flags |= FL_TARGET;
+
+      }
+
+   }
+
+
+
+void MissileHit (objtype *ob,void *hitwhat)
+   {
+   int damage=0, random,tcl=0,ocl,fireweapon=0,sound,hitmomx,hitmomy;
+   objtype* tempactor=NULL,*owner;
+
+
+
+   if (ob==missobj)
+       missobj=NULL;
+
+   if (ob == PLAYER0MISSILE)
+      PLAYER0MISSILE = NULL;
+
+
+   ob->momentumz = 0;
+   hitmomx = ob->momentumx;
+   hitmomy = ob->momentumy;
+   if (ob->soundhandle != -1)
+      SD_StopSound(ob->soundhandle);
+
+   ob->flags &= ~FL_SHOOTABLE;
+   if (FirstExplosionState(ob->state))
+      return;
+
+   /*
+   if ((ob->z < -28) || (IsWindow(ob->tilex,ob->tiley)))
+      {
+      NewState(ob,&s_megaremove);
+      return;
+      }
+   */
+
+   tempactor = (objtype*)hitwhat;
+   owner = (objtype*)(ob->whatever);
+
+   random = GameRandomNumber("MissileHit",0);
+   ocl = ob->obclass;
+   if (tempactor)
+      {
+      if (tempactor->which == ACTOR)
+         tcl = tempactor->obclass;
+      else if (tempactor->which == SPRITE)
+         tcl = -1;
+      }
+
+   if ((!tcl) && (ob->z < -30))
+      {
+      if (ob->soundhandle != -1)
+         SD_StopSound(ob->soundhandle);
+
+      NewState(ob,&s_megaremove);
+      return;
+
+      }
+
+
+   if (((ocl != p_kesobj) && (ocl != p_godballobj)) || (!tcl))
+      ZEROMOM;
+
+   if (tcl == b_darianobj)
+      MISCVARS->ESAU_SHOOTING  = false;
+
+   switch(ocl)
+      {
+
+
+      case p_bazookaobj:
+         NewState(ob,&s_explosion1);
+         if (M_ISACTOR(owner) && (owner->obclass == blitzguardobj))
+            damage = 30 + (random >> 4);
+         else
+            damage = 2*((random>>3)+80);
+         break;
+
+      case p_heatseekobj:
+         NewState(ob,&s_explosion1);
+         damage = 2*((random>>3)+50);
+         break;
+
+
+      case p_drunkmissileobj:
+         NewState(ob,&s_explosion1);
+         damage = ((random>>3)+25);
+         break;
+
+      case p_firebombobj:
+         NewState(ob,&s_explosion1);
+         damage = 2*((random>>3)+90);
+         ob->temp3 = 4;
+         SpawnFirebomb(ob,damage,4);
+         break;
+
+      case p_firewallobj:
+
+         if (tcl == playerobj)
+            gamestate.DOGROUNDZEROBONUS = true;
+         NewState(ob,&s_explosion1);
+         damage = 2*((random>>3)+50);
+         break;
+
+
+      case p_godballobj:
+         if ((tcl >= pillarobj) || (!tcl) || ((tcl == -1) && (!(tempactor->flags & FL_SHOOTABLE))))
+            NewState(ob,&s_explosion1);
+         ob->target = NULL;
+         damage = 500;
+         break;
+
+
+      case shurikenobj:
+         NewState(ob,&s_explosion1);
+         damage = ((random >>3) + 30)>>2;
+         break;
+
+
+      case grenadeobj:
+         NewState(ob,&s_explosion1);
+         damage = (random >>3) + 20;
+         break;
+
+      case fireballobj:
+         NewState(ob,&s_explosion1);
+         damage = (random >> 3) + 10;
+         fireweapon = 1;
+         break;
+
+      case missileobj:
+         NewState(ob,&s_explosion1);
+         if (M_ISACTOR(owner) && (owner->obclass == wallopobj))
+            damage = (random >> 5);
+         else
+            damage = (random >>3) + 30;
+         if (tcl && (tcl != b_heinrichobj))
+            damage = 3*damage>>3;
+         break;
+
+      case wallfireobj:
+         if ((!tempactor) ||
+             (tempactor->which == ACTOR) ||
+             (tempactor->which == SPRITE)
+            )
+            NewState(ob,&s_explosion1);
+         else if (M_ISWALL(tempactor) || (tempactor->which == DOOR))
+            NewState(ob,&s_crossdone1);
+         damage = EnvironmentDamage(ob);
+         fireweapon = 1;
+         break;
+
+
+
+      case inertobj:
+         ob->state = NULL;
+         return;
+         break;
+
+
+#if (SHAREWARE == 0)
+
+
+      case p_splitmissileobj:
+         NewState(ob,&s_explosion1);
+         damage = 2*((random>>3)+50);
+         break;
+
+
+      case p_kesobj:
+         if ((tcl >= pillarobj) ||
+             (!tcl) ||
+             ((tcl == -1) && (!(tempactor->flags & FL_SHOOTABLE)))
+            )
+            NewState(ob,&s_explosion1);
+         damage = 2*((random>>3)+140);
+         break;
+
+
+      case netobj:
+         ob->state=NULL;
+         MISCVARS->NET_IN_FLIGHT = false;
+         if (tempactor == PLAYER[0])
+            {
+            if ((tempactor->flags & FL_GODMODE) ||
+                (tempactor->flags & FL_DOGMODE) ||
+                godmode
+               )
+               damage = 0;
+            else
+               {
+               damage = (random >>4) + 5;
+               PLAYERSTATE[0].NETCAPTURED = -1;
+               PLAYERSTATE[0].weapondowntics = WEAPONS[PLAYERSTATE[0].weapon].screenheight/GMOVE;
+               NewState(PLAYER[0],&s_player);
+               PLAYERSTATE[0].attackframe = PLAYERSTATE[0].weaponframe = 0;
+               PLAYERSTATE[0].batblast = 0;
+               if (PLAYERSTATE[0].HASKNIFE == false)
+                  AddMessage("Wiggle left and right to get out of net!",
+                             MSG_GAME);
+               }
+            }
+         break;
+
+
+      case bigshurikenobj:
+         NewState(ob,&s_oshurikenhit1);
+         if (owner->obclass == wallopobj)
+            damage = (random >> 5);
+         else
+            damage = 4*((random >>3) + 30)/10;
+
+         break;
+
+
+      case dm_spitobj:
+         NewState(ob,&s_spithit1);
+         damage = 30;
+         if (gamestate.difficulty == gd_hard)
+            damage += 15;
+         break;
+
+      case dm_weaponobj:
+         damage = 20;
+         NewState(ob,&s_explosion1);
+         break;
+
+      case dm_heatseekobj:
+         damage = 20;
+         NewState(ob,&s_explosion1);
+         break;
+
+      case dmfballobj:
+         NewState(ob,&s_explosion1);
+         damage = (random >>3) + 20;
+         fireweapon = 1;
+         break;
+
+      case h_mineobj:
+         NewState(ob,&s_explosion1);
+         damage = (random >>3) + 20;
+         break;
+
+      case NMEsaucerobj:
+         NewState(ob,&s_explosion1);
+         damage = 2*((random>>3)+30);
+         break;
+
+
+#endif
+
+
+    //default:
+       //Error("Unknown ob %d called MissileHit",ob->obclass);
+      }
+
+  //if (!ob->state)
+	 //return;
+   if ((sound = BAS[ob->obclass].hit)!=0)
+      SD_PlaySoundRTP(sound,ob->x,ob->y);
+
+
+   if (FirstExplosionState(ob->state))
+      SD_PlaySoundRTP(SD_EXPLODESND,ob->x,ob->y);
+
+
+   if (tcl>0) // actors
+      {
+      MissileHitActor(owner,ob,tempactor,damage,hitmomx,hitmomy);
+      if ((ocl == p_kesobj) && (tcl < roboguardobj))
+         {
+         tempactor->momentumx = hitmomx; // kes gives wus targets its momentum
+         tempactor->momentumy = hitmomy;
+         //missile->flags |= FL_NOFRICTION;
+         }
+      }
+
+   else if (tcl < 0)  // static
+      {
+      DamageThing(hitwhat,damage);
+      if (FirstExplosionState(new->state))
+         new->whatever = ob->whatever;
+      }
+
+
+   }
+
+
+
+
+void T_Spears(objtype*ob)
+{int dx,dy,dz,i;
+
+
+ for(i=0;i<numplayers;i++)
+   {if (PLAYER[i]->flags & FL_DYING)
+     continue;
+
+    dx = abs(PLAYER[i]->x - ob->x);
+	 dy = abs(PLAYER[i]->y - ob->y);
+	 dz = abs(PLAYER[i]->z - ob->z);
+
+
+	 if ((!ob->ticcount)&&(ob->state->condition&SF_SOUND) &&
+		  areabyplayer[ob->areanumber])
+		  SD_PlaySoundRTP(BAS[ob->obclass].operate,ob->x,ob->y);
+
+	 if ((dx < STANDDIST) && (dy < STANDDIST) && (dz < 20))
+		{ob->flags &= ~FL_BLOCK;
+		 if ((!ob->ticcount) && (ob->state->condition & SF_CRUSH))
+			{DamageThing(PLAYER[i],EnvironmentDamage(ob));
+          Collision(PLAYER[i],ob,0,0);
+			 M_CheckPlayerKilled(PLAYER[i]);
+			 return;
+			}
+		}
+	 else
+		{if (ob->state->condition & SF_DOWN)
+			ob->flags &= ~FL_BLOCK;
+		 else
+			ob->flags |= FL_BLOCK;
+		}
+	}
+}
+
+
+
+void T_CrushUp(objtype*ob)
+{int dx, dy,dist,dz,i,playeron;
+
+
+  if ((!ob->ticcount) && (ob->state->condition & SF_SOUND) &&
+		areabyplayer[ob->areanumber])
+	SD_PlaySoundRTP(BAS[ob->obclass].operate,ob->x,ob->y);
+  dist = ACTORSIZE+0x2000;
+  if (ob->state->condition & SF_UP)
+	 {ob->temp1 += 4;
+ //	  Debug("\ncol momz = 4");
+	 }
+  else if (ob->state->condition & SF_DOWN)
+	 {ob->temp1 -= 4;
+ //      Debug("\ncol mom z = -4");
+	 }
+  else
+	 {//ob->momentumz = 0;
+  //	  Debug("\ncol mom z = 0");
+	 }
+
+  ob->temp2 = maxheight - ob->temp1 + 32;
+
+
+  playeron = 0;
+  for(i=0;i<numplayers;i++)
+	 {dx = abs(PLAYER[i]->x - ob->x);
+	  dy = abs(PLAYER[i]->y - ob->y);
+	  dz = abs(ob->temp2-PLAYER[i]->z);
+
+	  if ((dx < dist) && (dy < dist) && (dz < 65))
+		  {ob->flags &= ~FL_BLOCK;
+		  //player->temp2 = 0;
+			playeron  = 1;
+			if ((!ob->ticcount) && (ob->state->condition & SF_CRUSH) &&
+             (levelheight<2) && (!(ob->flags & FL_DYING)))
+			  {DamageThing(PLAYER[i],EnvironmentDamage(ob));
+            if (PLAYER[i]->hitpoints <= 0)
+               PLAYER[i]->flags |= FL_HBM;
+            Collision(PLAYER[i],ob,0,0);
+				M_CheckPlayerKilled(PLAYER[i]);
+            //NewState(ob,ob->state); //reset ticcount
+				return;
+			  }
+			if (ob->state->condition & SF_UP)
+			  {
+				PLAYER[i]->momentumz = -(4<<16);
+				if (PLAYER[i]->z < -30)
+               PLAYER[i]->z = -30;
+			  }
+			else if (ob->state->condition & SF_DOWN)
+				{PLAYER[i]->momentumz = (4<<16);
+				 if (PLAYER[i]->z >= nominalheight)
+					 PLAYER[i]->z = nominalheight;
+				}
+			else
+				PLAYER[i]->momentumz = 0;
+			PLAYER[i]->whatever = ob;
+			ob->whatever = PLAYER[i];
+         //PLAYER[i]->flags |= FL_RIDING;
+
+		  }
+
+	}
+
+  //if (!playeron)
+	 {if (ob->state->condition & SF_BLOCK)
+		 ob->flags |= FL_BLOCK;
+	  else
+		 ob->flags &= ~FL_BLOCK;
+
+	 }
+
+
+}
+
+
+void T_CrushDown(objtype*ob)
+{int dx,dy,dz,i,playeron;
+
+
+  if ((!ob->ticcount) && (ob->state->condition & SF_SOUND)&&
+		areabyplayer[ob->areanumber])
+	SD_PlaySoundRTP(BAS[ob->obclass].operate,ob->x,ob->y);
+
+  ob->temp2 = ob->z;
+  playeron = 0;
+  for(i=0;i<numplayers;i++)
+	  {dx = abs(PLAYER[i]->x - ob->x);
+		dy = abs(PLAYER[i]->y - ob->y);
+		dz = abs(PLAYER[i]->z - ob->z);
+
+		 if ((dx < STANDDIST) && (dy < STANDDIST) && (dz < 20))
+			 {//PLAYER[i]->temp2 = 0;
+			  playeron = 1;
+			  ob->flags &= ~FL_BLOCK;
+           if ((!ob->ticcount) && (ob->state->condition & SF_CRUSH) &&
+               (!(ob->flags & FL_DYING)))
+				 {DamageThing(PLAYER[i],EnvironmentDamage(ob));
+              if (PLAYER[i]->hitpoints <= 0)
+                 PLAYER[i]->flags |= FL_HBM;
+              Collision(PLAYER[i],ob,0,0);
+				  M_CheckPlayerKilled(PLAYER[i]);
+              //NewState(ob,ob->state); //reset ticcount
+				  return;
+				 }
+			  if ((ob->state->condition & SF_DOWN) &&
+					((ob->state != &s_columndowndown1) &&
+					(ob->state != s_columndowndown1.next)))
+				{PLAYER[i]->temp2 = COLUMNCRUSH;
+				 PLAYER[i]->whatever = ob;
+				}
+			 }
+
+	  }
+  //if (!playeron)
+	 {if (ob->state->condition & SF_BLOCK)
+			ob->flags |= FL_BLOCK;
+	  else
+			ob->flags &= ~FL_BLOCK;
+	 }
+
+
+}
+
+
+void T_Explosion(objtype* ob)
+   {
+   int momx,momy,momz;
+   int dx,dy,dz;
+   int pdamage,dist,blastradius=0x20000,
+       fatalradius=0x9000,impulse,damage,
+       scalefactor;
+
+
+
+   statobj_t* checkstat;
+   objtype* check,*owner;
+
+   if (ob->ticcount)
+      return;
+
+   damage = EXPLOSION_DAMAGE;
+   owner = (objtype*)(ob->whatever);
+   if ((ob->temp3) && (ob->obclass == p_firebombobj))
+      {
+      SpawnFirebomb(ob,damage,0);
+      ob->temp3 = 0;
+      }
+ //================== check surrounding actors ============================//
+
+
+   for(check = firstactive;check;check=check->nextactive)
+      {
+      if (check == ob)
+         continue;
+
+//	  if (check == owner)
+//		continue;
+
+      dx = abs(check->x - ob->x);
+      if (dx > blastradius)
+         continue;
+
+      dy = abs(ob->y - check->y);
+      if (dy > blastradius)
+         continue;
+
+      dz = ((abs(ob->z - check->z))<<10);
+      if (dz > blastradius)
+         continue;
+
+
+      if (check->flags & FL_HEAD)
+         continue;
+
+      if (check->flags & FL_DYING)
+         continue;
+
+      if (!(check->flags & FL_SHOOTABLE))
+         continue;
+
+
+
+      if ((check->obclass >= roboguardobj) && (check->obclass != b_darkmonkobj))
+			//(check->obclass <= wallopobj))
+         continue;
+
+
+      if (!CheckLine(ob,check,SIGHT))
+         continue;
+
+
+      if (check->obclass == NMEsaucerobj)
+         {
+         NewState(check,&s_explosion1);
+         check->flags &= ~FL_SHOOTABLE;
+         return;
+         }
+#if 0
+      dist = FindDistance(dx,dy);
+      scalefactor = (blastradius-dist)>>4;
+      if (scalefactor > 0xffff)
+         scalefactor = 0xffff;
+      pdamage = FixedMul(damage,scalefactor);
+#endif
+//#if 0
+     //magdx = abs(dx);
+     //magdy = abs(dy);
+
+      dist = Find_3D_Distance(dx,dy,dz);
+      SoftError("\ndist: %x\n",dist);
+
+
+      //if (dist < 0x10000)
+        // dist = 0x10000;
+
+      scalefactor = FixedDiv2(1<<16,FixedMul(dist,dist));
+     //scalefactor = FixedDiv2(1<<16,dist);
+
+      if (scalefactor > 0x12000)
+         scalefactor = 0x12000;
+      pdamage = FixedMul(damage,scalefactor);
+      SoftError("\ndamage: %d, scalefactor: %x\n",pdamage,scalefactor);
+//#endif
+      impulse = FixedMul(EXPLOSION_IMPULSE,scalefactor);
+      if (check->obclass == playerobj)
+         {
+         check->target = owner;
+         if (check->flags & FL_AV)
+            pdamage = 0;
+         }
+
+      if (check->obclass < roboguardobj)
+         {
+         SoftError("\nhitpoints before: %d",check->hitpoints);
+         DamageThing(check,pdamage);
+         SoftError("\nhitpoints after: %d",check->hitpoints);
+         if ((check->hitpoints <= 0) && (gamestate.violence == vl_excessive) &&
+             ((ob->obclass == p_firebombobj) ||
+             ((dx < fatalradius) && (dy < fatalradius) && (dz < 20)))
+            )
+            check->flags |= FL_HBM;
+
+         GetMomenta(check,ob,&momx,&momy,&momz,impulse);
+            //Debug("\nhitmomx = %d, hitmomy = %d",momx,momy);
+
+        /*if (M_ISACTOR(owner) &&
+            (owner->obclass == playerobj) &&
+            (check->hitpoints <=0)
+           )
+           GivePoints(starthitpoints[gamestate.difficulty][check->obclass]*5);
+        */
+         Collision(check,owner,momx,momy);
+         check->momentumz += (momz<<6);
+         if ((check->obclass == playerobj) && (check->flags & FL_DYING) &&
+             M_ISACTOR(owner))
+            {
+            if (owner->obclass == playerobj)
+               {
+               if (check->z != nominalheight)
+                  BATTLE_PlayerKilledPlayer(battle_kill_with_missile_in_air,owner->dirchoosetime,check->dirchoosetime);
+               else
+                  BATTLE_PlayerKilledPlayer(battle_kill_with_missile,owner->dirchoosetime,check->dirchoosetime);
+               }
+            else
+               BATTLE_CheckGameStatus(battle_player_killed,check->dirchoosetime);
+            }
+
+         }
+      else
+         {
+	     if (check->obclass != b_darkmonkobj) {
+		 SoftError("non-darkmonk actor %d being helped by explosion",check->obclass);
+	     }
+         check->hitpoints += pdamage;
+         }
+      }
+
+ //======================== check surrounding statics ================
+
+
+	for(checkstat = firstactivestat;checkstat;checkstat=checkstat->nextactive)
+      {
+
+      if ((!(checkstat->flags & FL_SHOOTABLE)) && (checkstat->itemnumber != stat_priestporridge))
+         continue;
+
+      if ((checkstat->itemnumber >= stat_lifeitem1) &&
+          (checkstat->itemnumber <= stat_lifeitem4))
+         continue;
+
+      dx = abs(checkstat->x - ob->x);
+      dy = abs(checkstat->y - ob->y);
+      dz = ((abs(checkstat->z - ob->z))<<10);
+
+      if ((dx < blastradius) && (dy < blastradius) && (dz < blastradius))
+         {
+         dist = Find_3D_Distance(dx,dy,dz)+0xc00;
+
+         if (dist < 0x10000)
+            dist = 0x10000;
+
+         scalefactor = FixedDiv2(1<<16,FixedMul(dist,dist));
+         pdamage = FixedMul(damage,scalefactor);
+
+         if (checkstat->itemnumber != stat_priestporridge)
+            DamageThing(checkstat,pdamage);
+         else if (!(checkstat->flags & FL_ACTIVE))
+            {
+            checkstat->flags |= FL_ACTIVE;
+            checkstat->count = 1;
+            //checkstat->numanims = 6;
+            SD_PlaySoundRTP(SD_COOKHEALTHSND,ob->x,ob->y);
+            }
+         }
+      }
+
+ //======================== check surrounding walls ================
+	{
+	int tilexlow,tilexhigh;
+	int tileylow,tileyhigh;
+	int radius =0x10000;
+	int x,y;
+
+	tilexlow = (int)((ob->x-radius) >>TILESHIFT);
+	tileylow = (int)((ob->y-radius) >>TILESHIFT);
+
+	tilexhigh = (int)((ob->x+radius) >>TILESHIFT);
+	tileyhigh = (int)((ob->y+radius) >>TILESHIFT);
+
+	for (y=tileylow;y<=tileyhigh;y++)
+		{
+		for (x=tilexlow;x<=tilexhigh;x++)
+			{
+			if ((tilemap[x][y]&0x8000) && (tilemap[x][y]&0x4000) && (abs(ob->z - nominalheight) < 32))
+				{
+				maskedwallobj_t * mw;
+
+				mw=maskobjlist[tilemap[x][y]&0x3ff];
+				if (mw->flags&MW_SHOOTABLE)
+					UpdateMaskedWall(tilemap[x][y]&0x3ff);
+				}
+			}
+		}
+	}
+
+}
+
+
+
+void SpawnScreenEye(objtype *ob)
+   {
+   SpawnNewObj(ob->tilex,ob->tiley,&s_eye1,inertobj);
+   new->targettiley = 0;
+   new->targettilex = GameRandomNumber("eye position",0) + 20;
+   SCREENEYE = new;
+   //RemoveFromArea(new);
+   new->flags |= FL_ABP;
+   MakeActive(new);
+
+   }
+
+
+
+
+
+
+void SpawnSuperFatalityGibs(objtype *ob,objtype *attacker)
+   {
+   int crazygibs = (GameRandomNumber("crazy gibs",0) % 6) + 4;
+   int i;
+
+
+   if ((MISCVARS->supergibflag == true) &&
+       ((crazygibs == 9) || (ludicrousgibs == true))
+      )
+
+      {
+      int olddirect = MISCVARS->directgibs;
+
+      MISCVARS->directgibs = false;
+      if (ludicrousgibs == false)
+         {
+         if (attacker == player)
+            {
+            AddMessage("Ludicrous Gibs!",MSG_GAME);
+            if (!(attacker->flags&FL_DOGMODE))
+               SD_Play(PlayerSnds[locplayerstate->player]);
+            }
+         }
+      else
+         {
+         MISCVARS->randgibspeed = true;
+
+#ifdef MEDGIBS
+         SpawnParticles(ob,GUTS,150);
+#else
+         SpawnParticles(ob,GUTS,75);
+#endif
+         
+         MISCVARS->randgibspeed = false;
+         }
+      SpawnParticles(ob,GUTS,40);
+      MISCVARS->directgibs = olddirect;
+
+      }
+
+   for (i=gt_head;i<=crazygibs;i++)
+      {
+
+      if (((ob->obclass == dfiremonkobj) || (ob->obclass == deathmonkobj)) &&
+          (i == gt_leg)
+         )
+         SpawnParticles(ob,gt_arm,1);
+      else
+         SpawnParticles(ob,i,1);
+      }
+
+
+   }
+
+
+
+
+
+boolean Vicious_Annihilation(objtype *ob, objtype *attacker)
+   {
+   if ((ob->flags & FL_HBM) && (gamestate.violence >= vl_high))
+      {
+      ob->shapeoffset = 0;
+      ob->flags &= ~FL_FULLLIGHT;
+      NewState(ob,(ob->obclass == playerobj)?(&s_remoteguts1):(&s_guts1));
+      SD_PlaySoundRTP(SD_ACTORSQUISHSND,ob->x,ob->y);
+      if (gamestate.violence == vl_excessive)
+         {
+         int numgibs;
+         objtype *prevlast;
+
+         numgibs = (GameRandomNumber("excessive guts",0) & 7) + 4;
+         //SoftError("\nnumgibs = %d,gamestate.difficulty = %d",numgibs,gamestate.difficulty);
+         prevlast = LASTACTOR;
+         MISCVARS->fulllightgibs = true;
+         SpawnParticles(ob,GUTS,numgibs);
+         MISCVARS->fulllightgibs = false;
+         for(prevlast = prevlast->next;prevlast;prevlast = prevlast->next)
+            prevlast->momentumz += (prevlast->momentumz >> 1);
+
+         if ((GameRandomNumber("super gib chance",0) < 100) ||
+             (ludicrousgibs == true)
+            )
+            {
+            MISCVARS->directgibs = true;
+//MED
+            MISCVARS->gibgravity = GRAVITY/2;
+//            MISCVARS->gibgravity = GRAVITY*2;           
+            MISCVARS->fulllightgibs = true;
+            SpawnSuperFatalityGibs(ob,attacker);
+            MISCVARS->fulllightgibs = false;
+            MISCVARS->gibgravity = -1;
+            MISCVARS->directgibs = false;
+            }
+         }
+      return true;
+
+      }
+
+
+   if (ob->flags & FL_GODSTRUCK)
+      {
+      ob->shapeoffset = 0;
+      ob->flags |= (FL_FULLLIGHT);
+      ob->flags &= ~FL_COLORED;
+      ob->momentumx = ob->momentumy = ob->momentumz = 0;
+      KillActor(ob);
+      NewState(ob,&s_vaporized1);
+      return true;
+      }
+
+   if (ob->flags & FL_SKELETON)
+      {
+      KillActor(ob);
+      ob->shapeoffset = 0;
+      ob->flags &= ~FL_COLORED;
+      ob->momentumx = ob->momentumy = ob->momentumz = 0;
+      NewState(ob,&s_skeleton1);
+      SD_PlaySoundRTP(SD_ACTORBURNEDSND,ob->x,ob->y);
+      return true;
+      }
+
+   return false;
+
+   }
+
+
+/*
+========================
+=
+= BeginEnemyFatality
+=
+========================
+*/
+
+
+
+void BeginEnemyFatality(objtype *ob,objtype *attacker)
+   {
+
+
+   if ((attacker == player) && (ob->obclass < (NUMENEMIES + 2)))
+      {
+      GivePoints(starthitpoints[gamestate.difficulty][ob->obclass]*5);
+      if (timelimitenabled)
+         timelimit+=VBLCOUNTER;
+      }
+
+   ob->flags |= FL_DYING;
+   ob->soundhandle = -1;
+
+#if 0
+   if ((ob->obclass == blitzguardobj) &&
+       (ob->state->condition & SF_DOWN)
+      )
+
+      SD_Play(PlayerSnds[locplayerstate->player]);
+#endif
+
+   if (Vicious_Annihilation(ob,attacker))
+      return;
+
+   if ((ob->obclass == patrolgunobj) && (ob->temp1 == -1))
+      NewState(ob,&s_robogrddie1);
+   else if (ob->obclass == collectorobj)
+      {
+      if ((!M_ISACTOR(attacker)) || (attacker->obclass != playerobj))
+         RespawnEluder();
+      else
+         BATTLE_CheckGameStatus(battle_shot_deluder,attacker->dirchoosetime);
+
+      NewState(ob,&s_explosion1);
+      MISCVARS->gibgravity = GRAVITY/2;
+      MISCVARS->fulllightgibs = true;
+      SpawnParticles(ob,gt_sparks,100);
+      MISCVARS->fulllightgibs = false;
+      MISCVARS->gibgravity = -1;
+      }
+   else
+      {
+      statetype *temp;
+
+      if ((ob->obclass == blitzguardobj) &&
+            (ob->state->condition & SF_FAKING)
+         )
+         {
+         NewState(ob,&s_blitzstruggledie1);
+         ob->flags &= ~FL_FULLLIGHT;
+         }
+      else if
+         ((ob->obclass == blitzguardobj) &&
+            (ob->state->condition & SF_DOWN)
+         )
+         {
+         NewState(ob,&s_blitzplead7);
+         ob->flags &= ~FL_FULLLIGHT;
+         }
+
+      else if
+         ((temp= M_S(DIE)) != NULL)
+         {
+         if (LOW_VIOLENCE_DEATH_SHOULD_BE_SET(ob))
+            SET_DEATH_SHAPEOFFSET(ob);
+         NewState(ob,temp);
+         ob->flags &= ~FL_FULLLIGHT;
+         }
+      else
+         Error("Null dead state called in Collision, obclass %d",ob->obclass);
+      }
+
+
+   }
+
+
+
+/*
+========================
+=
+= BeginPlayerFatality
+=
+========================
+*/
+
+
+
+
+void BeginPlayerFatality(objtype *ob,objtype *attacker)
+   {
+   playertype *pstate;
+   M_LINKSTATE(ob,pstate);
+
+
+   ob->flags &= ~(FL_ELASTO|FL_GODMODE|FL_DOGMODE|FL_NOFRICTION|FL_RIDING);
+
+   ob->flags |= FL_DYING;
+   pstate->weapon = -1;
+
+
+   if (BATTLEMODE)
+      SD_PlaySoundRTP (SD_PLAYERTCDEATHSND+(pstate->player),ob->x,ob->y);
+
+   if (Vicious_Annihilation(ob,attacker) == false)
+      {
+      if (LOW_VIOLENCE_DEATH_SHOULD_BE_SET(ob))
+         SET_DEATH_SHAPEOFFSET(ob);
+
+      NewState(ob,&s_remotedie1);
+      ob->flags &= ~FL_FULLLIGHT;
+      }
+
+
+
+   }
+
+
+
+/*
+========================
+=
+= BeginEnemyHurt
+=
+========================
+*/
+
+
+void BeginEnemyHurt(objtype *ob)
+   {
+   statetype *temp;
+
+   if ((temp= M_S(COLLIDE1)) != NULL)
+      {
+
+
+      if ((ob->obclass == blitzguardobj) &&
+            (ob->state->condition & SF_FAKING)
+         )
+         {
+         ob->temp1 = 1;
+         ob->dirchoosetime = 0;
+         T_PlayDead(ob);
+
+         }
+
+      else
+         {
+         if ((ob->obclass == triadenforcerobj) &&
+             (GameRandomNumber("george pain chance",0) <
+              (50 + (gamestate.difficulty<<6))
+             )
+            )
+            {
+            ob->flags &= ~FL_FULLLIGHT;
+            return;
+
+            }
+
+
+         if (LOW_VIOLENCE_PAIN_SHOULD_BE_SET(ob))
+            SET_PAIN_SHAPEOFFSET(ob);
+
+         if (GameRandomNumber("Collision",0) < 128)
+            NewState(ob,temp);
+         else
+            NewState(ob,M_S(COLLIDE2));
+         }
+
+      ob->flags &= ~FL_FULLLIGHT;
+      ob->ticcount = PAINTIME;
+      if (ob->obclass == strikeguardobj)
+         ob->ticcount >>= 1;
+      }
+   }
+
+
+void  Collision(objtype*ob,objtype *attacker,int hitmomentumx,int hitmomentumy)
+   {
+   int ocl;
+
+   if ((!(ob->flags & FL_SHOOTABLE)) || (ob->flags & FL_DYING))
+   return;
+
+   ocl = ob->obclass;
+
+   ob->momentumx += hitmomentumx;
+   ob->momentumy += hitmomentumy;
+
+   if ((ocl == playerobj) && (gamestate.battlemode == battle_Eluder))
+      return;
+
+   //insertion 5
+
+   if (ocl != playerobj)
+      {
+      if ((!(ob->flags & FL_ATTACKMODE)) && (TABLE_ACTOR(ob)))
+         ActivateEnemy(ob);
+
+
+      if (ob->hitpoints <= 0)
+         BeginEnemyFatality(ob,attacker);
+
+      else if (ocl != roboguardobj)// && (ob->state->think != T_Collide))
+         BeginEnemyHurt(ob);
+      }
+   else
+      {
+      playertype *pstate;
+
+      if ((ob->flags & FL_GODMODE) || (ob->flags & FL_DOGMODE) || godmode)
+         return;
+
+      M_LINKSTATE(ob,pstate);
+      if (pstate->health<=0)
+         BeginPlayerFatality(ob,attacker);
+      else
+         ob->flags |= FL_PAIN;
+
+      }
+
+}
+
+
+
+
+void T_BossExplosions(objtype*ob)
+{
+
+ if (ob->temp1)
+	 {if (ob->dirchoosetime)
+		 ob->dirchoosetime --;
+	  else
+		 {int randtime,randangle,randdist,sound;
+		  statetype *nstate;
+
+		  ob->temp1 --;
+		  randtime = GameRandomNumber("Boss Explosion Time",0);
+		  ob->dirchoosetime = 10;
+		  if (randtime < 128)
+			ob->dirchoosetime >>= 1;
+		  randangle = (GameRandomNumber("Boss Explosion Angle",0) << 3);
+		  randdist = (GameRandomNumber("Boss Explosion Distance",0) << 7)+0x4000;
+		  sound = SD_EXPLODEFLOORSND;
+		  if (randtime < 128)
+			 {nstate = &s_explosion1;
+			  sound++;
+			 }
+#if (SHAREWARE == 0)
+		  else
+			 nstate = &s_grexplosion1;
+#endif
+
+
+		  SpawnMissile(ob,inertobj,0,randangle,nstate,randdist);
+		  SD_PlaySoundRTP(sound,new->x,new->y);
+		 }
+	 }
+}
+
+
+
+
+gib_t RandomGutsType(void)
+   {
+   int rand = GameRandomNumber("gut random",0);
+
+
+   if (rand < 128)
+      return gt_organ;
+
+   //if (rand < 160)
+      return gt_rib;
+
+   //return gt_pinkorgan;
+
+
+   }
+
+
+//MED
+void SpawnParticles(objtype*ob,int which,int numparticles)
+   {
+   int randphi,randtheta,i,nspeed;
+   boolean eyespawned = false;
+   int gibtype;
+   int randadj;
+
+
+   if ((ob->z <= -64) && (sky == 0)) //shouldn't happen
+      return;
+
+
+   if (((which == GUTS) || (which == RANDOM)) && (gamestate.violence < vl_high))
+      which = gt_sparks;
+
+   gibtype = which;
+
+
+   for(i=0;i<numparticles;i++)
+      {
+      int ordertemp;	/* DDOI - Watcom evaluates the mult order diff */
+      randphi = (GameRandomNumber("particle generate phi",0) << 3);
+      // randadj = RandomSign() * (GameRandomNumber("rand gib adjust",0) >> 4);
+      ordertemp = (GameRandomNumber("rand gib adjust",0) >> 4);
+      randadj = RandomSign() * ordertemp;
+
+
+
+      if (ob->z > (nominalheight - 32))
+         randphi &= ((ANGLES/2) - 1);
+
+      randtheta = (GameRandomNumber("particle generate theta",0) << 3);
+      nspeed = MISCVARS->gibspeed;
+
+
+      if (which == RANDOM)
+         {
+         if (GameRandomNumber("random gib",0) < 128)
+            gibtype = RandomGutsType();
+         else
+            gibtype = gt_sparks;
+
+         }
+
+      if ((which == GUTS) || (which == DISEMBOWEL))
+         {
+
+         gibtype = RandomGutsType();
+         if (which == DISEMBOWEL)
+            {
+            randphi>>=2;
+            randtheta=ob->temp1+(randtheta>>3)-(randtheta>>4);
+            }
+
+         }
+
+      if (lowmemory && (gibtype >= gt_rib) && (gibtype <= gt_limb))
+         gibtype = gt_organ;
+
+      if
+         (
+        // (gibtype >= gt_organ) && (gibtype <= gt_limb) &&
+         (MISCVARS->numgibs >= MAXGIBS)
+         )
+         return;
+
+
+
+      if (gibtype == gt_lsoul)
+         {
+         SpawnNewObj(ob->tilex,ob->tiley,&s_littlesoul,inertobj);
+         randphi = 0;
+         }
+
+
+   #if (SHAREWARE == 0)
+      else if (gibtype == gt_spit)
+
+         SpawnNewObj(ob->tilex,ob->tiley,&s_slop1,inertobj);
+   #endif
+      else
+         {
+         SpawnNewObj(ob->tilex,ob->tiley,&s_gibs1,inertobj);
+         new->shapeoffset = gibtype*12;
+         NewState(new,new->state);
+         }
+
+      if (MISCVARS->directgibs == true)
+         {
+         int dx,dy,dz;
+
+         dx = PLAYER[0]->x - ob->x;
+         dy = ob->y - PLAYER[0]->y;
+         randtheta = AngleBetween(ob,PLAYER[0]) +
+                     (randadj<<4);
+         dz = 100 + (randadj<<3);
+
+#ifdef MEDGIBS
+         nspeed = 0x2800;
+#else
+         nspeed = 0x2800 + (randadj<<7);
+#endif
+
+         randphi = atan2_appx(FindDistance(dx,dy),dz<<10);
+         }
+
+
+      if ((eyespawned == false) && (which == GUTS) &&
+            (ob->obclass != playerobj)
+         )
+         {
+         eyespawned = true;
+         new->flags |= FL_EYEBALL;
+         }
+
+      if ((gibtype >= gt_organ) && (gibtype <= gt_limb))
+         {
+         new->dirchoosetime = GIBVALUE;
+         MISCVARS->numgibs ++;
+         }
+      new->temp2 = gibtype;
+      new->temp3 = (MISCVARS->gibgravity == -1)?(GRAVITY):(MISCVARS->gibgravity);
+
+      new->speed = nspeed>>1;
+
+#ifndef MEDGIBS
+      if (MISCVARS->randgibspeed == true)
+         new->speed += (randadj << 11);
+#endif
+
+//      if (ob->state == &s_snakefireworks)
+         new->z = ob->z;
+
+      Fix(randphi);
+      Fix(randtheta);
+
+      Set_3D_Momenta(new,new->speed,randtheta,randphi);
+      new->momentumz <<= 6;
+      new->flags |= (FL_NOFRICTION|FL_CRAZY|FL_ABP|FL_NEVERMARK);
+      if (MISCVARS->fulllightgibs == true)
+         new->flags |= FL_FULLLIGHT;
+      new->dir = west;
+      new->whatever = ob;
+      MakeActive(new);
+      }
+   }
+
+
+
+void T_SlideDownScreen(objtype *ob)
+{
+
+ ob->targettiley += 12;
+ if (ob->targettiley > 300)
+    {
+    NewState(ob,&s_megaremove);
+    SCREENEYE = NULL;
+    }
+
+}
+
+void T_SpawnSoul(objtype*ob)
+{
+ if (ob->ticcount)
+  return;
+
+ SpawnNewObj(ob->tilex,ob->tiley,&s_bigsoul,inertobj);
+ new->momentumz = -4000;
+ new->flags |= (FL_NOFRICTION|FL_CRAZY|FL_ABP|FL_NEVERMARK);
+ new->z = ob->z;
+ new->dir = west;
+ MakeActive(new);
+
+ SpawnParticles(ob,gt_lsoul,6);
+
+
+}
+
+
+void BloodDrip(objtype *ob,int tilex,int tiley)
+{int dx,dy,x,y,scale;
+
+ dx = ob->tilex - tilex;
+ dy = ob->tiley - tiley;
+
+ if (!dy)
+   {
+   scale = (ob->momentumx)?(FixedDiv2(ob->momentumy,ob->momentumx)):(0);
+   x = (dx < 0)?(tilex << 16):((tilex+1) << 16);
+   y = FixedMul(x - ob->x,scale) + ob->y;
+   }
+
+ else if (!dx)
+   {
+   scale = (ob->momentumy)?(FixedDiv2(ob->momentumx,ob->momentumy)):(0);
+   y = (dy < 0)?(tiley << 16):((tiley+1) << 16);
+   x = FixedMul(y - ob->y,scale) + ob->x;
+   }
+
+ ob->temp2 = (GameRandomNumber("BloodDrip",0) << 9) + 0xc000;
+ ob->temp1 = (ob->z<<16);
+ SetFinePosition(ob,x,y);
+ ob->shapeoffset = 0;
+ NewState(ob,&s_blooddrip1);
+
+}
+
+
+
+void T_BloodFall(objtype*ob)
+{
+ ob->temp1 += ob->temp2;
+ ob->z = (ob->temp1 >> 16);
+ if (ob->z >= maxheight)
+    {
+    ob->shapeoffset = 12;
+    MISCVARS->numgibs--;
+    NewState(ob,&s_gibsdone1);
+    ob->z = nominalheight;
+    }
+
+}
+
+
+
+
+void T_Xylophone(objtype*ob)
+   {
+   if (!ob->ticcount)
+      SD_PlaySoundRTP(SD_ACTORSKELETONSND,ob->x,ob->y);
+   }
+
+
+
+void T_ParticleGenerate(objtype*ob)
+{
+
+ if (ob->dirchoosetime)
+	ob->dirchoosetime--;
+ else
+	{
+    SetGibSpeed(0x3000);
+    SpawnParticles(ob,gt_sparks,(GameRandomNumber("particle count",0) % 10) + 7);
+    ResetGibSpeed();
+	 ob->dirchoosetime = 10;
+	 if (GameRandomNumber("particle generator choose time",0) < 128)
+		ob->dirchoosetime >>= 1;
+	}
+
+}
+
+
+
+void T_Particle(objtype*ob)
+{int dx,dy,dz;
+
+ ob->z += (ob->momentumz>>16);
+
+ if ((ob->z >= nominalheight) || (!ob->momentumz))
+
+    {
+    if (ob->z >= nominalheight)
+       ob->z = nominalheight;
+//done:
+    if (ob->temp2 == gt_spit)
+       ob->state = NULL;
+    else
+       {
+       if (ob->dirchoosetime == GIBVALUE)
+          {
+          MISCVARS->numgibs--;
+          SD_PlaySoundRTP(GIBSOUND,ob->x,ob->y);
+          }
+       NewState(ob,&s_gibsdone1);
+       }
+    return;
+    }
+ else if ((ob->z < -64) && (sky == 0))
+    {
+    ob->momentumz = 1; //any positive value will do
+    ob->z = -64;
+
+    }
+
+
+ ob->momentumz += ob->temp3;
+ ActorMovement(ob);
+
+
+ if (!BATTLEMODE)
+    {
+    dx = abs(ob->x - PLAYER[0]->x);
+    dy = abs(ob->y - PLAYER[0]->y);
+    dz = abs(ob->z - PLAYER[0]->z);
+
+#if (SHAREWARE==0)
+    if ((ob->flags & FL_EYEBALL) && (dx < 0x20000) && (dy < 0x20000) &&
+        (dz < 64) && (GameRandomNumber("eye chance",0) < 15) &&
+        (SCREENEYE == NULL) && (locplayerstate->weapon != wp_dog)
+       )
+#else
+    if ((ob->flags & FL_EYEBALL) && (dx < 0x20000) && (dy < 0x20000) &&
+        (dz < 64) && (GameRandomNumber("eye chance",0) < 15) &&
+        (SCREENEYE == NULL)
+       )
+#endif
+       SpawnScreenEye(ob);
+    }
+
+ //MoveActor(ob);
+ //if ((!ob->momentumx) && (!ob->momentumy))
+	//goto done;
+
+
+}
+
+
+
+void DropItemInEmptyTile(int item,int tilex,int tiley)
+   {
+   int stilex = tilex;
+   int stiley = tiley;
+
+   FindEmptyTile(&stilex,&stiley);
+   SpawnStatic(stilex,stiley,item,9);
+   LASTSTAT->flags |= FL_ABP;
+   MakeStatActive(LASTSTAT);
+
+   }
+
+
+void KillActor(objtype*ob)
+{int ocl;
+
+ ocl = ob->obclass;
+
+
+ //GivePoints(starthitpoints[gamestate.difficulty][ob->obclass]*5);
+ if ((ocl == highguardobj) &&
+	  (GameRandomNumber("Drop mp40 chance",0) < 25))
+    {
+    DropItemInEmptyTile(stat_mp40,ob->tilex,ob->tiley);
+    }
+
+ else if ((ocl == blitzguardobj) && (ob->temp3))
+    {
+    DropItemInEmptyTile(ob->temp3,ob->tilex,ob->tiley);
+    LASTSTAT->ammo = ob->temp2;
+    }
+
+  if (actorat[ob->tilex][ob->tiley] == (void*)ob)
+	 actorat[ob->tilex][ob->tiley] = NULL;
+
+  gamestate.killcount++;
+  ob->flags &= ~FL_SHOOTABLE;
+  ob->flags &= ~FL_BLOCK;
+  ob->flags |= FL_NEVERMARK;
+#if (SHAREWARE == 0)
+  if (ocl == b_darksnakeobj)
+	 {if (ob == SNAKEHEAD)
+		 {SpawnNewObj(ob->tilex,ob->tiley,&s_megaexplosions,inertobj);
+		  new->temp1 = 7000;
+		  new->flags |= FL_ABP;
+		  EXPLOSIONS = new;
+		  NewState(ob,&s_darkmonkheaddie1);
+		  MakeActive(new);
+		  ob->dirchoosetime = 0;
+
+		 }
+	  else
+		{objtype *temp;
+
+		 SNAKEEND = (objtype*)(ob->target);
+		 SNAKEEND->whatever = NULL;
+		 NewState(ob,&s_explosion1);
+		 for(temp=SNAKEHEAD;temp;temp = (objtype*)(temp->whatever))
+			temp->speed += 0x500;
+		}
+	 }
+  else
+#endif
+	 {ob->whatever = NULL;
+     if (ob->obclass!=playerobj)
+		  ob->target   = NULL;
+	 }
+
+  if ((ob->flags & FL_KEYACTOR) && (ocl!=playerobj) && (ocl != blitzguardobj))
+	 {MISCVARS->KEYACTORSLEFT --;
+	  if (!MISCVARS->KEYACTORSLEFT)
+		 {SpawnNewObj(ob->tilex,ob->tiley,&s_timekeeper,inertobj);
+		  new->flags |= FL_ABP;
+		  MakeActive(new);
+		 }
+	 }
+
+}
+
+
+void T_End(objtype *ob)
+{
+ if (ob->ticcount)
+	return;
+
+ if (MAPSPOT(0,5,2) == LASTLEVELVALUE)
+	playstate = ex_gameover;
+ else
+	playstate = ex_bossdied;
+
+}
+
+
+
+void T_Convert(objtype*ob)
+   {
+   if (ob->ticcount)
+      return;
+
+   if (ob->obclass == playerobj)
+      {
+      if (ob->state == &s_vaporized8)
+         {
+         T_SpawnSoul(ob);
+         NewState(ob,&s_voidwait);
+         }
+      else if (ob->state == &s_skeleton48)
+         {
+         playertype *pstate;
+
+         M_LINKSTATE(ob,pstate);
+         if ((pstate->falling == true) ||
+             (!ob->momentumz)
+            )
+            NewState(ob,&s_ashwait);
+         else
+            CheckPlayerSpecials(ob);
+
+
+         }
+      }
+   else
+      {
+      if (ob->state == &s_vaporized8)
+         T_SpawnSoul(ob);
+      else if (ob->state == &s_skeleton48)
+         TurnActorIntoSprite(ob);
+      }
+   }
+
+void TurnActorIntoSprite(objtype *ob)
+{statobj_t*temp;
+ objtype *tactor;
+
+
+ if (!firstemptystat)
+   temp = (statobj_t*)Z_LevelMalloc(sizeof(statobj_t),PU_LEVELSTRUCT,NULL);
+
+ else
+	{temp = lastemptystat;
+	 //SoftError("\nfree actor available");
+	 RemoveFromFreeStaticList(lastemptystat);
+	}
+
+
+ if (temp)
+  {
+   if ((ob->obclass == blitzguardobj) &&
+       ((ob->flags & FL_PLEADING) || (ob->flags & FL_UNDEAD))
+      )
+      MISCVARS->NUMBEGGINGKEVINS = 0;
+
+
+   if (ob->obclass == roboguardobj)
+	  {for(tactor=firstareaactor[ob->areanumber];tactor;tactor=tactor->nextinarea)
+		  {if (tactor == ob)
+			  continue;
+			if (tactor->obclass != ob->obclass)
+			  continue;
+
+			if (tactor->flags & FL_DYING)
+			  continue;
+			if (!tactor->state->think)
+			  NewState(tactor,UPDATE_STATES[PATH][tactor->obclass-lowguardobj]);
+
+		  }
+	  }
+
+   memset(temp,0,sizeof(*temp));
+	temp->shapenum = ob->shapenum;
+	temp->linked_to = -1;
+	temp->whichstat = statcount ++;
+   SetFinePosition(temp,ob->x,ob->y);
+   temp->areanumber = MAPSPOT(temp->tilex,temp->tiley,0)-AREATILE;
+//	if ((temp->areanumbers<=0) || (temp->areanumber>NUMAREAS))
+  //		  Error ("Sprite at x=%ld y=%ld type=%ld has an illegal areanumber\n",tilex,tiley,mtype);
+
+	temp->visspot = &spotvis[temp->tilex][temp->tiley];
+	temp->which = SPRITE;
+	temp->itemnumber = -1;
+	temp->flags = FL_DEADBODY;
+	if (ob->flags & FL_COLORED)
+	  {playertype *pstate;
+
+		M_LINKSTATE(ob,pstate);
+		temp->flags |= FL_COLORED;
+		temp->hitpoints = pstate->uniformcolor;
+	  }
+	temp->z = ob->z;
+	AddStatic(temp);
+//	sprites[temp->tilex][temp->tiley] = temp;
+
+	if (areabyplayer[temp->areanumber])
+	 {temp->flags |= FL_ABP;
+	  MakeStatActive(temp);
+	 }
+	if (ob->state != &s_guts12)
+	 actorat[ob->tilex][ob->tiley] = temp;
+	ob->state = NULL; // say goodbye actor
+  }
+ else
+	Error("Z_LevelMalloc failed in TurnActorIntoSprite!");
+
+}
+
+
+void T_Blood(objtype*ob)
+{
+  if (ob->dirchoosetime)
+	 {ob->dirchoosetime --;
+	  return;
+	 }
+
+  ob->dirchoosetime = 35 + (GameRandomNumber("blood time",0) % 20);
+  NewState(ob,&s_deadblood1);
+
+}
+
+
+
+
+void ActorDeath(objtype*ob)
+   {
+#if (SHAREWARE == 0)
+   if (ob->obclass == b_heinrichobj)
+      {
+      KillActor(ob);
+      ob->temp1 = ob->dirchoosetime = 5;//10; // init. spin counter for heinrich
+      ob->temp3 = 7; //number of times to stay at fast spin
+      ob->temp2 = ob->dir; //temp2 holds orig. dir.
+      }
+
+   else if (ob->obclass == b_robobossobj)
+      {
+      objtype *wheels,*head;
+
+
+      head = (objtype*)(ob->whatever);
+      wheels = (objtype*)(ob->target);
+      head->flags &= ~(FL_HEAD|FL_SHOOTABLE|FL_BLOCK);
+      head->temp2 = 5;
+      head->flags |= (FL_NOFRICTION|FL_CRAZY);
+//      head->obclass = inertobj;
+      //RemoveObj(wheels);   // remove wheels
+      KillActor(ob);
+      ob->whatever = head;
+      ob->target = wheels;
+      //ob->temp1 = 25;
+      //ob->shapeoffset = 0;
+      SpawnNewObj(ob->tilex,ob->tiley,&s_megaexplosions,inertobj);
+      new->temp1 = 18;
+      new->flags |= FL_ABP;
+      MakeActive(new);
+      //ob->state = NULL;
+      NewState(ob,&s_NMEdeathbuildup);
+      }
+   else
+#endif
+      if ((ob->state == ob->state->next) &&
+          (ob->flags & FL_DYING)
+         )
+      {
+      KillActor(ob);
+      TurnActorIntoSprite(ob);
+      if (LASTSTAT->z < nominalheight)
+         {
+         if ((!IsPlatform(LASTSTAT->tilex,LASTSTAT->tiley)) &&
+            (DiskAt(LASTSTAT->tilex,LASTSTAT->tiley) == NULL)
+            )
+            {
+            SpawnParticles(ob,GUTS,10 + gamestate.difficulty);
+            RemoveStatic(LASTSTAT);
+            }
+         }
+      /*
+      else if ((GameRandomNumber("blood spray",0) < 300) && areabyplayer[ob->areanumber])
+         {ob->shapeoffset = 0;
+         ob->temp2 = ob->temp3 = 0;
+         ob->temp1 = 10;
+         NewState(ob,&s_deadblood1);
+         return;
+         }
+         */
+      }
+   }
+
+
+
+
+void BeginPostPainAction(objtype *ob)
+   {
+
+   if ((ob->obclass == strikeguardobj) &&
+       (ob->target == (void*)PLAYER[0])
+      )
+      {//ob->target = NULL;
+      if (LOW_VIOLENCE_DEATH_IS_SET(ob))
+         RESET_DEATH_SHAPEOFFSET(ob);
+
+      if (GameRandomNumber("T_Collide",0) < 128)
+         NewState(ob,&s_strikerollright1);
+      else
+         NewState(ob,&s_strikerollleft1);
+
+      SelectRollDir(ob);
+
+      if (ob->dirchoosetime)
+         {
+         SD_PlaySoundRTP(SD_STRIKEROLLSND,ob->x,ob->y);
+         return;
+         }
+
+      }
+
+   if (LOW_VIOLENCE_PAIN_IS_SET(ob))
+      RESET_PAIN_SHAPEOFFSET(ob);
+
+   if (ob->obclass < roboguardobj)
+      ob->flags &= ~FL_NOFRICTION;
+
+   if (
+      (ob->obclass == blitzguardobj) &&
+      (gamestate.violence == vl_excessive) &&
+      (GameRandomNumber("blitzplead",0) < 128) &&
+      (MISCVARS->NUMBEGGINGKEVINS == 0) &&
+      (ob->flags & FL_TARGET) &&
+
+      (ob->hitpoints < (starthitpoints[gamestate.difficulty][ob->obclass] >> 1)) &&
+      (ob->momentumz == 0) &&
+      (!(ob->flags & FL_UNDEAD))
+      )
+
+      {
+      NewState(ob,&s_blitzplead1);
+      MISCVARS->NUMBEGGINGKEVINS = 1;
+      ob->momentumx = ob->momentumy = 0;
+      ob->flags |= FL_PLEADING;
+      ob->flags &= ~FL_TARGET;
+      ob->dirchoosetime = 165;
+      ob->hitpoints = 1;
+      }
+
+   else
+      {
+      NewState(ob,M_S(CHASE));
+      ob->targettilex = ob->targettiley = 0;
+      ob->dirchoosetime = 0;
+      }
+
+   }
+
+
+
+void T_Collide(objtype*ob)
+   {
+	if (!(ob->flags & FL_SHOOTABLE))
+	 return;
+
+	ActorMovement(ob);
+
+	if (ob->state == NULL)
+	  return;
+
+	if (ob->ticcount)
+	  return;
+
+	if (ob->hitpoints <= 0)
+      {
+
+      if ((ob->soundhandle == -1) &&
+          (!ob->ticcount) &&
+          (ob->state->next->tictime == 0)
+         )
+         {
+         ob->soundhandle = SD_PlaySoundRTP(ACTORTHUDSND,ob->x,ob->y);
+
+         }
+
+      if (ob->momentumx || ob->momentumy || ob->momentumz)
+         return;
+
+      ActorDeath(ob);
+      return;
+      }
+
+   BeginPostPainAction(ob);
+
+   }
+
+
+
+/*
+=========================================================================
+=
+=                Special Blitzguard Functions
+=
+=========================================================================
+*/
+
+
+/*
+=================
+=
+=   T_Plead
+=
+=================
+*/
+
+
+
+void T_Plead(objtype*ob)
+{
+ int handle;
+
+ ActorMovement(ob);
+ if (ob->dirchoosetime)
+   {
+   if (!(ob->dirchoosetime & 31))
+      {
+      int random = GameRandomNumber("blitz plead sound",0);
+      if (random < 80)
+         SD_PlaySoundRTP(SD_BLITZPLEADSND,ob->x,ob->y);
+      else if (random < 160)
+         SD_PlaySoundRTP(SD_BLITZPLEAD1SND,ob->x,ob->y);
+      else
+         SD_PlaySoundRTP(SD_BLITZPLEAD2SND,ob->x,ob->y);
+      }
+   ob->dirchoosetime --;
+   return;
+	}
+ ob->hitpoints = (starthitpoints[gamestate.difficulty][blitzguardobj]>>1);
+ //ob->flags |= FL_DYING;
+ ob->flags |= FL_UNDEAD;
+ SET_DEATH_SHAPEOFFSET(ob);
+ NewState(ob,&s_blitzfakedie1);
+ ob->flags &= ~FL_PLEADING;
+ ob->dirchoosetime = (GameRandomNumber("blitz fake time",0) >> 2) + 70;
+ handle = SD_PlaySoundRTP(SD_BLITZOUCHSND,ob->x,ob->y);
+ SD_SetSoundPitch (handle,-500);
+ ob->temp1 = 0;
+ ob->temp1 = (GameRandomNumber("blitz visible rise",0) < 60);
+
+}
+
+
+
+/*
+=================
+=
+=   T_ReallyDead
+=
+=================
+*/
+
+
+void T_ReallyDead(objtype *ob)
+   {
+   ActorMovement(ob);
+   if ((!ob->ticcount) && (LOW_VIOLENCE_DEATH_SHOULD_BE_SET(ob)))
+      SET_DEATH_SHAPEOFFSET(ob);
+
+
+   }
+
+
+
+/*
+=================
+=
+=   T_PlayDead
+=
+=================
+*/
+
+
+
+void T_PlayDead(objtype *ob)
+   {
+   int dangle;
+
+   ob->flags &= ~FL_DYING;
+
+   ActorMovement(ob);
+   if (ob->dirchoosetime)
+      {
+      ob->dirchoosetime--;
+      return;
+      }
+
+   dangle = abs(player->angle - AngleBetween(player,ob));
+   if (dangle > ANGLES/2)
+      dangle = ANGLES - dangle;
+
+   if (ob->temp1 || (dangle > ANGLES/4))
+      {
+      if (LOW_VIOLENCE_DEATH_IS_SET(ob))
+         RESET_DEATH_SHAPEOFFSET(ob);
+      ob->temp1 = 0;
+
+      NewState(ob,&s_blitzrise2);
+
+      }
+
+   }
+
+
+void AdjustAngle(int maxadjust, short int *currangle,int targetangle)
+   {
+   int dangle,i,magangle;
+
+   for(i=0;i<maxadjust;i++)
+      {
+      dangle = *currangle - targetangle;
+
+      if (dangle)
+         {
+         magangle = abs(dangle);
+         if (magangle > (ANGLES/2))
+            {
+            if (dangle > 0)
+               (*currangle) ++;
+            else
+               (*currangle) --;
+            }
+         else
+            {
+            if (dangle > 0)
+               (*currangle) --;
+            else
+               (*currangle) ++;
+            }
+         Fix(*currangle);
+         }
+      }
+   }
+
+
+void ResolveMinimumDistance(objtype *heatseeker, objtype *potential_target,
+                            int *currmin)
+   {
+   int currdist,angle,magangle;
+
+
+   currdist = FindDistance((heatseeker->x-potential_target->x),
+                           (heatseeker->y-potential_target->y));
+   angle = AngleBetween(heatseeker,potential_target);
+
+
+   if (heatseeker->obclass != p_godballobj)
+      {
+      magangle = abs(heatseeker->angle - angle);
+      if (magangle > VANG180)
+         magangle = ANGLES - magangle;
+      if (magangle > ANGLESDIV8)
+         return;
+      }
+
+   if (currdist > LOOKAHEAD)
+      return;
+
+   if (currdist < (*currmin))
+      {
+      *currmin = currdist;
+      heatseeker->target = potential_target;
+      }
+   }
+
+
+
+
+void HeatSeek(objtype*ob)
+{int        xydist;
+
+ int        mindist;
+ objtype*   tactor;
+ objtype*   owner;
+ statobj_t* tstat;
+ int        angle,dz,yzangle,adjust;
+ int        dx,dy;
+
+
+ owner=(objtype *)ob->whatever;
+
+ if (ob->dirchoosetime)
+    ob->dirchoosetime --;
+
+ else
+    {
+    if (!ob->target)
+        {mindist = 0x7fffffff;
+
+         for (tactor=firstactive;tactor;tactor=tactor->nextactive)
+            {
+            if (tactor == owner)
+               continue;
+
+            if (tactor->flags & FL_HEAD)
+               continue;
+
+            if ((tactor == ob) ||
+                (!(tactor->flags & FL_SHOOTABLE)) ||
+                (tactor->flags & FL_DYING))
+               continue;
+
+            if (!CheckLine(ob,tactor,SIGHT))
+               continue;
+
+            if ((tactor->obclass == bladeobj) || (tactor->obclass == NMEsaucerobj))
+               continue;
+
+
+            ResolveMinimumDistance(ob,tactor,&mindist);
+
+				}
+
+			if (ob->obclass != p_godballobj)
+            {
+            for(tstat=firstactivestat;tstat;tstat=tstat->nextactive)
+               {
+               if (!(tstat->flags & FL_HEAT))
+                  continue;
+
+               if (!CheckLine(ob,tstat,SHOOT))
+                  continue;
+
+               ResolveMinimumDistance(ob,(objtype*)tstat,&mindist);
+               }
+            }
+
+
+			if (!ob->target)
+				ob->dirchoosetime = 5;
+		  }
+
+	 else //if (ob->target != owner)
+       {
+       tactor = (objtype*)ob->target;
+
+       if ((!tactor->nextactive) && (!tactor->prevactive))
+          {
+          ob->target = NULL;
+          return;
+			 }
+       dx = tactor->x - ob->x;
+       dy = ob->y - tactor->y;
+       dz = ob->z - tactor->z;
+       //xydist = FixedSqrtHP((FixedMul(dx,dx) + FixedMul(dy,dy))>>16);
+       xydist = FindDistance(dx,dy);
+       angle = atan2_appx(dx,dy);
+       adjust = (ob->obclass == p_godballobj)?(GODHAPT):(HAAPT);
+       AdjustAngle(adjust,&(ob->angle),angle);
+       ob->dir = angletodir[ob->angle];
+       ob->momentumx = FixedMul(ob->speed,costable[ob->angle]);
+       ob->momentumy = -FixedMul(ob->speed,sintable[ob->angle]);
+
+       yzangle = atan2_appx(xydist,(dz<<10));
+       adjust = (ob->obclass == p_godballobj)?(GODVAPT):(VAAPT);
+       AdjustAngle(adjust,&(ob->yzangle),yzangle);
+       ob->momentumz = -(FixedMul(ob->speed,sintable[ob->yzangle]));
+
+		 }
+    }
+
+}
+
+
+void Stagger(objtype*ob)
+   {
+   int randadj;
+
+
+   randadj = (int)(GameRandomNumber("Stagger",1) >> 3);
+
+   if (!ob->dirchoosetime)
+      {
+      ob->momentumz = ob->temp1 + (RandomSign() << 12);
+      ob->dirchoosetime = 6;
+      }
+   else
+      ob->dirchoosetime --;
+
+   if ((ob->z + (ob->momentumz >> 10)) > (maxheight-12))
+      ob->momentumz = -ob->momentumz;
+   else if ((ob->z < 5) && (!sky))
+      ob->z = 5;
+
+   ob->angle += (RandomSign()*randadj);
+   Fix(ob->angle);
+   ob->momentumx = FixedMul(ob->speed,costable[ob->angle]);
+   ob->momentumy = -FixedMul(ob->speed,sintable[ob->angle]);
+   ob->dir = angletodir[ob->angle];
+
+   }
+
+
+
+
+void SpawnSplit(objtype *ob,int angle)
+   {
+   Fix(angle);
+   SpawnMissile(ob,p_heatseekobj,ob->speed,angle,&s_p_bazooka1,0x4000);
+   new->momentumz = ob->momentumz;
+   new->whatever = ob->whatever;
+
+   }
+
+
+
+void SplitMissile(objtype*ob)
+   {
+
+   SD_PlaySoundRTP(SD_SPLITSND,ob->x,ob->y);
+   if (ob->soundhandle != -1)
+      SD_StopSound(ob->soundhandle);
+
+   SpawnSplit(ob,ob->angle + ANGLES/12);
+   SpawnSplit(ob,ob->angle - ANGLES/12);
+
+   if (missobj == ob)
+      {
+      if (GameRandomNumber("split misscam",0)<128)
+         missobj = LASTACTOR;
+      else
+         missobj = LASTACTOR->prev;
+      }
+
+   ob->state=NULL; // get rid of current missile
+
+   }
+
+
+
+
+void SpawnMissileSmoke(objtype *ob)
+   {
+   if (!ValidAreanumber(AREANUMBER(ob->tilex,ob->tiley)))
+      return;
+
+   SpawnStatic(ob->tilex,ob->tiley,stat_missmoke,-1);
+   LASTSTAT->flags |= FL_ABP;
+   MakeStatActive(LASTSTAT);
+   SetFinePosition(LASTSTAT,ob->x,ob->y);
+   LASTSTAT->z = ob->z+3;
+
+   }
+
+
+void T_Projectile (objtype *ob)
+   {
+   objtype *owner;
+   playertype * pstate;
+
+   owner = (objtype*)(ob->whatever);
+
+   if (owner->obclass == playerobj)
+      M_LINKSTATE(owner,pstate);
+
+   if ((ob->soundhandle != -1) &&
+       (!(oldpolltime & 7))
+      )
+      SD_PanRTP(ob->soundhandle,ob->x,ob->y);
+#if (SHAREWARE == 0)
+   if (ob->obclass == h_mineobj)
+      {
+      if (!ob->dirchoosetime)
+         {
+         NewState(ob,&s_grexplosion1);
+         SD_PlaySoundRTP(SD_KRISTMINEHITSND,ob->x,ob->y);
+         }
+		else
+         ob->dirchoosetime --;
+      if (
+         (ob->state == &s_mine1) &&
+         (!ob->ticcount)
+         )
+         SD_PlaySoundRTP(BAS[ob->obclass].operate,ob->x,ob->y);
+
+      }
+#endif
+
+
+	if (!ob->ticcount)
+      {
+      if (ob->state == &s_p_grenade)
+         ob->momentumz += (GRAVITY>>6);
+      else if
+         (ob->state == &s_grenade_fall6)
+         {
+         NewState(ob,&s_explosion1);
+         return;
+         }
+      }
+
+
+
+
+   if (ob->obclass == p_drunkmissileobj)
+      {
+      if (ob->temp3 > 0)
+         {
+         ob->temp3 --;
+         Stagger(ob);
+         }
+      else
+         {
+         if (ob->target == NULL)
+            Stagger(ob);
+         HeatSeek(ob);
+         }
+
+      }
+
+   else if (ob->temp1 == NME_DRUNKTYPE)
+
+      Stagger(ob);
+
+
+   else if ((ob->obclass == p_heatseekobj) ||
+       (ob->obclass == dm_heatseekobj) ||
+       (ob->temp1 == NME_HEATSEEKINGTYPE) ||
+       (ob->obclass == p_godballobj)
+      )
+      HeatSeek(ob);
+
+
+   else if
+      ((ob->obclass == p_splitmissileobj) &&
+       (!pstate->buttonstate[bt_attack])
+      )
+      {
+      SplitMissile(ob);
+      return;
+      }
+
+
+
+
+   if ((!BATTLEMODE) &&
+       (!(ob->ticcount & 7)) &&
+       (ob->obclass != p_firewallobj) &&
+       (ob->obclass != p_kesobj) &&
+       (ob->obclass != p_godballobj) &&
+       ((ob->obclass >= p_bazookaobj) ||  (ob->obclass == missileobj))
+      )// &&
+
+      SpawnMissileSmoke(ob);
+
+	MissileMovement(ob);
+
+	if (ob->obclass == grenadeobj)
+
+      {
+      if (ob->temp1 > 0)
+         ob->temp1 -= ob->speed;
+      else if (!(ob->flags & FL_DONE))
+         {
+         NewState(ob,&s_grenade_fall1);
+         ob->flags |= FL_DONE;
+         }
+      }
+   }
+
+
+
+void StartFirewall(objtype*ob, int newz)
+   {
+   objtype *owner = (objtype*)(ob->whatever);
+
+   MISCVARS->firespawned = 0;
+   owner->temp1 = 0;
+   SpawnFirewall(ob,2,newz);
+   if (missobj == ob)
+      missobj = LASTACTOR;
+   NewState(ob,&s_megaremove);
+
+   }
+
+
+
+void MissileMovement(objtype*ob)
+{int tryx, tryy,tryz;
+
+ tryx = ob->x + ob->momentumx;
+ tryy = ob->y + ob->momentumy;
+ tryz = ob->z + (ob->momentumz >> 10);
+ if (!MissileTryMove (ob, tryx, tryy, tryz))
+    return;
+ ob->z += (ob->momentumz >> 10);
+ MoveActor(ob);
+}
+
+
+
+#define DetonateMissile(x,y) \
+{MissileHit(x,y);             \
+ return false;                 \
+}                                \
+
+#define QuietDetonate(ob)            \
+   {                                 \
+   if (ob->soundhandle != -1)        \
+      SD_StopSound(ob->soundhandle); \
+   if (ob == missobj)                \
+      missobj = NULL;                \
+   NewState(ob,&s_megaremove);       \
+   return false;                     \
+   }
+
+boolean MissileTryMove(objtype*ob,int tryx,int tryy,int tryz)
+{
+ int             tilexlow,tileylow,tilexhigh,tileyhigh,x,y,
+                 trytilex,trytiley,dx,dy,dzt,dztp1,radius,
+					  sprrad,actrad,tcl,ocl,oldsrad,area,zdist,
+                 wall;
+
+ objtype         *temp;
+ wall_t          *tempwall;
+ doorobj_t       *tempdoor;
+ int             doorn;
+ statobj_t       *tempstat;
+ boolean         areatried[NUMAREAS] = {0};
+
+ sprrad = 0x4500;
+ actrad = ACTORSIZE+0x2800;
+ ocl = ob->obclass;
+ radius = PROJSIZE-0x2200;
+ if (ocl==wallfireobj)
+	 radius-=0x3000;
+ trytilex = (tryx >> TILESHIFT);
+ trytiley = (tryy >> TILESHIFT);
+
+
+ if (IsWindow(trytilex,trytiley) || (!InMapBounds((tryx>>16),(tryy>>16))))
+    {
+    QuietDetonate(ob);
+    }
+
+
+
+ /*
+ */
+ //==== ceiling/floor clipping =================//
+
+ if (tryz < -30)
+    {if ((sky==0) || (ocl == inertobj))
+        {
+        DetonateMissile(ob,NULL);
+        }
+     /*
+     else
+        return true;
+        */
+     /*
+     else
+        {
+        NewState(ob,&s_megaremove);
+        if (missobj == ob)
+           missobj = NULL;
+
+        return false;
+        }
+      */
+    }
+
+
+ if (tryz > (maxheight-10))
+    {
+    if ((ocl == p_firewallobj) && (!(ob->flags & FL_ISFIRE)))
+       StartFirewall(ob,nominalheight);
+    else
+       MissileHit(ob,NULL);
+    return false;
+    }
+
+ //=============================================//
+
+ sprrad = PROJSIZE+0x1000;
+
+
+ tilexlow = (int)((tryx-radius) >>TILESHIFT);
+ tileylow = (int)((tryy-radius) >>TILESHIFT);
+
+ tilexhigh = (int)((tryx+radius) >>TILESHIFT);
+ tileyhigh = (int)((tryy+radius) >>TILESHIFT);
+
+ oldsrad = sprrad;
+
+
+ if (ocl == inertobj)
+  goto walls;
+
+ area = ob->areanumber;
+ areatried[area] = true;
+actors:
+ for(temp=firstareaactor[area];temp;temp=temp->nextinarea)
+      {
+      if (temp == ob)
+         continue;
+
+      dx = abs(tryx - temp->x);
+      dy = abs(tryy - temp->y);
+      if ((dx > actrad) || (dy > actrad))
+         continue;
+
+      if (temp->flags & FL_HEAD)
+         continue;
+
+      if ((!(temp->flags & FL_BLOCK)) || (temp->flags & FL_DYING))
+         continue;
+
+      tcl = temp->obclass;
+
+
+      zdist = 32;
+      dzt = abs(tryz - temp->z);
+
+      if ((tcl == playerobj) && (temp->flags & FL_DOGMODE))
+         {
+         dzt = abs(tryz - (temp->z + 30));
+         zdist = 10;
+         }
+      else if (tcl == diskobj)
+         {
+         zdist = 50;
+         }
+
+      if (dzt > zdist)
+         continue;
+
+
+
+      //if ((ocl==wallfireobj) && (tcl==playerobj) && (temp->flags&FL_DOGMODE) && (dz>15))
+         // continue;
+
+      //if ((ocl==playerobj) &&
+         //  (ob->whatever == (void*)temp))
+         //continue;
+
+      if (ob->whatever && (ob->whatever == temp->whatever))// &&
+   //      (ocl == tcl))// missiles with same owner
+                                                         // go through each other
+         continue;
+
+      if (!(ob->flags & FL_ISFIRE))
+            {
+
+            int random;
+
+            if (tcl != b_darkmonkobj)
+               {
+               MissileHit(ob,temp);
+               ob->target = NULL;
+               if (tcl == wallfireobj)
+                  MissileHit(temp,NULL);
+               if (((ocl == p_kesobj) || (ocl == p_godballobj)) && (tcl < pillarobj))
+                  continue;
+               else
+                  return false;
+               }
+            random = GameRandomNumber("empower darkmonk",0);
+#if (SHAREWARE == 0)
+
+            if (ocl == p_kesobj)
+               {
+               NewState(ob,&s_megaremove);
+               //ob->state = NULL;
+               temp->hitpoints += (((random>>3)+140)<<1);
+               CAP_OSCUROS_HITPOINTS(temp);
+               }
+            else if (ocl == p_firebombobj)
+               {
+               NewState(ob,&s_explosion1);
+               temp->hitpoints += (((random>>3)+70)<<1);
+               CAP_OSCUROS_HITPOINTS(temp);
+
+               ob->target = NULL;
+               }
+            else
+               {
+               NewState(ob,&s_explosion1);
+               temp->hitpoints += (((random>>3)+50)<<1);
+               CAP_OSCUROS_HITPOINTS(temp);
+
+               ob->target = NULL;
+               }
+            temp->temp3 = ocl;
+            temp->speed = 5*SPDPATROL;
+            NewState(temp,&s_darkmonkreact);
+#endif
+            return false;
+            }
+
+      else if (tcl < roboguardobj)
+         {if ((temp->z == nominalheight) &&
+            (!((tcl == playerobj) && ((temp->flags & FL_GODMODE) || (temp->flags & FL_DOGMODE) || godmode))))
+            {
+            if (tcl == playerobj)
+               {
+               playertype *pstate;
+               objtype *owner = (objtype*)(ob->whatever);
+
+               M_LINKSTATE(temp,pstate);
+               if (temp->flags & FL_AV)
+                  {pstate->protectiontime = 1;
+                  if (temp==player)
+                     GM_UpdateBonus (pstate->protectiontime, false);
+                  continue;
+                  }
+
+
+               //temp->flags &= ~FL_COLORED;
+               pstate->health = 0;
+               pstate->weapon = -1;
+               if (owner->obclass == playerobj)
+                  BATTLE_PlayerKilledPlayer(battle_kill_with_missile,owner->dirchoosetime,temp->dirchoosetime);
+
+
+               }
+
+
+            temp->flags |= FL_SKELETON;
+            temp->hitpoints = 0;
+            Collision(temp,ob->whatever,-temp->momentumx,-temp->momentumy);
+            }
+         continue;
+         }
+
+
+
+      else
+         {
+         NewState(ob,&s_megaremove);
+         ob->target = NULL;
+#if (SHAREWARE == 0)
+         if (tcl == b_darkmonkobj)
+            NewState(temp,&s_darkmonkfspark1);
+#endif
+         }
+
+      return false;
+
+      }
+
+
+   for (y=tileylow;y<=tileyhigh;y++)
+      for (x=tilexlow;x<=tilexhigh;x++)
+         {
+         area = AREANUMBER(x,y);
+         if (ValidAreanumber(area) && (areatried[area]==false))
+            {
+            areatried[area] = true;
+            goto actors;
+            }
+         }
+
+
+/******************* WALLS/PWALLS *****************************************/
+
+walls:
+
+ for (y=tileylow;y<=tileyhigh;y++)
+  for (x=tilexlow;x<=tilexhigh;x++)
+	 {
+
+
+	  tempwall = (wall_t*)actorat[x][y];
+	  wall=tilemap[x][y];
+
+     if (tempwall && M_ISWALL(tempwall) && (tempwall->which!=MWALL))
+		  {if (ocl == h_mineobj)
+				{
+				if (WallCheck(ob->x-ob->momentumx, tryy))
+					{ob->momentumx = -ob->momentumx;
+					  continue;
+					 }
+				else if (WallCheck(tryx, ob->y-ob->momentumy))
+					 {ob->momentumy = -ob->momentumy;
+					  continue;
+					 }
+				}
+
+         DetonateMissile(ob,tempwall);
+         //MissileHit(ob,tempwall);
+         //return false;
+			}
+
+
+     tempstat = sprites[x][y];
+     sprrad = oldsrad;
+
+     if (tempstat &&
+			((tempstat->flags & FL_SHOOTABLE) || (tempstat->flags & FL_BLOCK)))
+        {
+
+		  if ((tempstat->itemnumber >= stat_bcolumn) &&
+				(tempstat->itemnumber <= stat_icolumn))
+			 sprrad += 0x5000;
+
+		  dx = tryx - tempstat->x;
+		  if ((dx < -sprrad) || (dx > sprrad))
+           continue;
+
+        dy = tryy - tempstat->y;
+		  if ((dy < -sprrad) || (dy > sprrad))
+           continue;
+
+//#define MINSTATZDIFF 60
+
+        dzt = abs(ob->z - tempstat->z);
+        dztp1 = abs(tryz - tempstat->z);
+      /*
+        if (ocl == p_firewallobj)// && (dztp1 <= MINSTATZDIFF))
+           {
+           if (ob->flags & FL_ISFIRE)
+              {
+              int cz = (ob->z - tempstat->z + MINSTATZDIFF);
+
+              if ((cz >= -MAXSTEPHEIGHT) && (cz <= 0))
+                 {
+                 ob->z = tempstat->z - MINSTATZDIFF;
+                 tryz = ob->z + (ob->momentumz >> 16);
+                 dzt = MINSTATZDIFF;
+                 }
+              }
+
+           if ((dztp1 >= MINSTATZDIFF) || (dzt >= MINSTATZDIFF))
+              continue;
+
+           if (!(ob->flags & FL_ISFIRE))
+              {
+              StartFirewall(ob,tempstat->z - MINSTATZDIFF);
+              return false;
+              }
+           }
+
+
+        else*/
+           {
+           if (dztp1 > 50)
+              continue;
+
+           DetonateMissile(ob,tempstat);
+           }
+        //MissileHit(ob,tempstat);
+        //return false;
+        }
+	 }
+
+
+//mwalls:
+
+
+
+ if (M_ISMWALL(trytilex,trytiley))
+      {
+      maskedwallobj_t * mw;
+
+      wall=tilemap[trytilex][trytiley];
+      //tempwall = (wall_t*)actorat[trytilex][trytiley];
+
+
+      mw=maskobjlist[wall&0x3ff];
+
+      if (!(mw->flags&MW_BLOCKING))
+         {
+
+         if ((levelheight > 1) &&
+            (((!(mw->flags & MW_ABOVEPASSABLE)) && (tryz <= 32)) ||
+             ((!(mw->flags & MW_MIDDLEPASSABLE)) && (tryz > 25) && (tryz < nominalheight-32)) ||
+             ((!(mw->flags & MW_BOTTOMPASSABLE)) && (tryz > maxheight - 74))
+            )
+            )
+            DetonateMissile(ob,NULL);
+
+         }
+
+      else if (mw->flags&MW_SHOOTABLE)
+         {
+         if (ob->z >= maxheight-64)
+            {
+            UpdateMaskedWall(tilemap[trytilex][trytiley]&0x3ff);
+            }
+         else
+            DetonateMissile(ob,NULL);
+
+         }
+
+      else
+         DetonateMissile(ob,NULL);
+      //MissileHit(ob,tempwall);
+      //return false;
+      }
+
+
+
+/******************* DOOR STUFF ******************************************/
+
+
+  else if (M_ISDOOR(trytilex,trytiley))
+     {
+     doorn = tilemap[trytilex][trytiley];
+     tempdoor = doorobjlist[doorn&0x3ff];
+     if (tempdoor->position>=0x8000)
+			 {
+			 if (ob->z>maxheight-64)
+				 return true;
+			 }
+     DetonateMissile(ob,tempdoor);
+     }
+
+  return true;
+
+
+}
+
+
+
+void SpawnFirewall(objtype*ob,int which,int newz)
+{int i,j,count,newx,newy;
+ objtype* owner;
+ wall_t*tempwall;
+ statetype* frame;
+ int offset;
+
+ owner = (objtype*)(ob->whatever);
+
+ if ((owner->temp1 < 2) && (MISCVARS->firespawned < 14))
+    {for(i=0;i<=which;i++)
+        {
+        GetNewActor ();
+        MakeActive(new);
+        MISCVARS->firespawned ++;
+        new->obclass = p_firewallobj;
+        new->which = ACTOR;
+        new->areanumber = ob->areanumber;
+        MakeLastInArea(new);
+        offset = 0x6000;
+        if (!which)
+           new->temp1 = ob->temp1;
+        else if (i==1)
+           new->temp1 = ob->angle + ANGLES/4;
+        else if (i==2)
+           new->temp1 = ob->angle - ANGLES/4;
+        else
+           {
+           new->temp1 = 0;
+           offset = 0;
+           new->flags |= FL_DONE;
+           }
+
+        Fix(new->temp1);
+
+        new->speed = 0x8000;
+        new->angle = ob->angle;
+        ParseMomentum(new,new->angle);
+        newx = ob->x + FixedMul(offset,costable[new->temp1]);
+        newy = ob->y - FixedMul(offset,sintable[new->temp1]);
+        SetFinePosition(new,newx,newy);
+        SetVisiblePosition(new,newx,newy);
+        new->whatever = ob->whatever;
+        new->dirchoosetime = 2;
+        new->flags |= (FL_NEVERMARK|FL_ABP|FL_NOFRICTION);
+        count = (int)(GameRandomNumber("SpawFireWall",0) & 15);
+
+        for(frame = &s_fireunit1,j=0;j<count;frame = frame->next,j++);
+
+        NewState(new,frame);
+        new->flags |= FL_ISFIRE;
+         //SD_Play(SD_EXPL);
+        tempwall = (wall_t*)actorat[new->tilex][new->tiley];
+        new->z = newz;
+        if (tempwall && M_ISWALL(tempwall))
+            {
+            SetFinePosition(new,ob->x,ob->y);
+            SetVisiblePosition(new,ob->x,ob->y);
+            owner->temp1++;
+            }
+        }
+    }
+
+}
+
+
+void T_Firethink(objtype*ob)
+  {
+
+  if (ob->dirchoosetime)
+     ob->dirchoosetime--;
+  else if (!(ob->flags & FL_DONE))
+     {
+     SpawnFirewall(ob,0,ob->z);
+	  ob->flags |= FL_DONE;
+     }
+
+  MissileMovement(ob);
+
+  }
+
+
+
+void ResolveRide(objtype *ob)
+   {
+   objtype *ride = (objtype*)(ob->whatever);
+
+   if (M_ISACTOR(ride) && (ob->obclass != playerobj))
+      {
+      if (ob->flags & FL_RIDING)
+         {
+         int dx,dy;
+
+         dx = ob->x - ride->x;
+         dy = ob->y - ride->y;
+         if ((dx < -MINACTORDIST) || (dx > MINACTORDIST) ||
+             (dy < -MINACTORDIST) || (dy > MINACTORDIST) )
+            {
+            ride->whatever = NULL;
+            ob->whatever = NULL;
+            ob->flags &= ~FL_RIDING;
+            }
+			}
+      }
+
+   }
+
+
+
+
+void MoveActor(objtype*ob)
+   {
+   int linked,oldarea,newarea,
+       tilex,tiley,oldtilex,oldtiley;
+
+	linked = 0;
+
+   ResolveRide(ob);
+
+	oldtilex = ob->tilex;
+	oldtiley = ob->tiley;
+
+   SetFinePosition(ob,ob->x+ob->momentumx,ob->y+ob->momentumy);
+  /*
+	if (ob->state == &s_explosion1)
+	 Error("moving explosion"); */
+
+   if ((ob->obclass == playerobj) || (ob->flags & FL_NOFRICTION) || (ob->state->think == T_Collide) ||
+       (ob->obclass == b_heinrichobj) || (ob->obclass == h_mineobj))
+
+     SetVisiblePosition(ob,ob->x,ob->y);
+
+
+
+	if (ob->obclass == inertobj)
+	 return;
+
+   if ((ob->obclass == b_darksnakeobj) && (ob != SNAKEHEAD))
+      {
+      oldarea = ob->areanumber;
+      newarea = SNAKEHEAD->areanumber;
+      if (oldarea != newarea)
+         {
+         RemoveFromArea(ob);
+         ob->areanumber = newarea;
+         MakeLastInArea(ob);
+         }
+      return;
+
+      }
+
+
+   oldarea = ob->areanumber;
+   newarea = AREANUMBER(ob->tilex,ob->tiley);
+	if (!(ob->flags & (FL_NONMARK|FL_NEVERMARK)))
+      {
+      if ((oldtilex != ob->tilex) || (oldtiley != ob->tiley))
+         {
+         if (actorat[oldtilex][oldtiley] == (void*)ob)
+            actorat[oldtilex][oldtiley] = NULL;
+         if (actorat[ob->tilex][ob->tiley])
+            {
+            objtype* temp;
+
+            temp = (objtype*)actorat[ob->tilex][ob->tiley];
+            if (temp->which != SPRITE)
+               actorat[ob->tilex][ob->tiley] = ob;
+            }
+         else
+            actorat[ob->tilex][ob->tiley] = ob;
+         }
+      }
+
+
+#define CheckAdjacentArea(x,y)        \
+   {                                  \
+   if (InMapBounds(x,y))              \
+      {                               \
+      temparea = AREANUMBER(x,y);     \
+      if (ValidAreanumber(temparea))  \
+         newarea = temparea;          \
+      }                               \
+   }
+
+
+   if (!ValidAreanumber(newarea)) //find empty tile
+     {
+     int temparea;
+     tilex = ob->tilex;
+	  tiley = ob->tiley;
+
+     CheckAdjacentArea(tilex+1,tiley);
+     CheckAdjacentArea(tilex-1,tiley);
+     CheckAdjacentArea(tilex,tiley+1);
+     CheckAdjacentArea(tilex,tiley-1);
+
+     }
+	  //Error("new area invalid for actor %d, class %d",
+		//	  ob-&objlist[0],ob->obclass);
+
+
+//======================  swap in linked lists =====================
+	if (oldarea != newarea)
+      {
+      RemoveFromArea(ob);
+      ob->areanumber = newarea;
+      MakeLastInArea(ob);
+      }
+}
+
+
+
+void SpawnPushColumn(int tilex,int tiley,int which,int dir, int linked)
+{
+  if (which==0)
+	  {
+	  SpawnNewObj(tilex,tiley,&s_pushcolumn1,pillarobj);
+//     for (i=0;i<(levelheight-1);i++)
+//        SpawnStatic(tilex,tiley,stat_bcolumn,-(i<<6));
+	  }
+  else if (which==1)
+	  {
+	  SpawnNewObj(tilex,tiley,&s_pushcolumn2,pillarobj);
+//     for (i=0;i<(levelheight-1);i++)
+//        SpawnStatic(tilex,tiley,stat_gcolumn,-(i<<6));
+	  }
+  else
+	  {
+	  SpawnNewObj(tilex,tiley,&s_pushcolumn3,pillarobj);
+//     for (i=0;i<(levelheight-1);i++)
+//        SpawnStatic(tilex,tiley,stat_icolumn,-(i<<6));
+	  }
+  PreCacheActor(pillarobj,which);
+
+  gamestate.secrettotal++;
+  new->speed = PILLARMOM;
+  new->temp1 = 0x20000;
+  new->temp2 = linked;
+  new->flags |= (FL_BLOCK|FL_NOFRICTION);
+  new->flags &= ~FL_SHOOTABLE;
+  new->flags |= FL_HEIGHTFLIPPABLE;
+  new->dir = dir;
+  if (dir != nodir)
+	ParseMomentum(new,dirangle8[new->dir]);
+
+
+}
+
+
+
+void SpawnWallfire(int tilex, int tiley, int dir)
+{int offx,offy;
+
+
+  GetNewActor();
+  new->speed = 0x2000;
+  SetTilePosition(new,tilex,tiley);
+  SetVisiblePosition(new,new->x,new->y);
+  new->obclass = wallfireobj;
+  new->dir = dir*2;
+  new->flags |= (FL_BLOCK|FL_NOFRICTION|FL_NEVERMARK);
+  new->flags &= ~FL_SHOOTABLE;
+  new->which = ACTOR;
+  new->angle = dirangle8[new->dir];
+  offx = FixedMul(0x10000,costable[new->angle])>>TILESHIFT;
+  offy = -(FixedMul(0x10000,sintable[new->angle])>>TILESHIFT);
+
+  new->areanumber = MAPSPOT(new->tilex+offx,new->tiley+offy,0)-AREATILE;
+  MakeLastInArea(new);
+
+  NewState(new,&s_wallfireball);
+
+}
+
+
+
+void SpawnSneaky(int tilex,int tiley)
+   {
+
+   SpawnNewObj(tilex,tiley,&s_sneakydown,lowguardobj);
+   new->temp3 = SNEAKY;
+   if (!loadedgame)
+      gamestate.killtotal++;
+   StandardEnemyInit(new,north>>1);
+
+   PreCacheActor(lowguardobj,0);
+   }
+
+
+void RespawnEluder(void)
+   {
+   int rand,count;
+   int nx,ny;
+
+   rand = (GameRandomNumber("eluder respawn",0) % NUMSPAWNLOCATIONS);
+
+   for(count=0;count < NUMSPAWNLOCATIONS;count++)
+      {
+      if (!actorat[SPAWNLOC[rand].x][SPAWNLOC[rand].y])
+         {
+         SpawnCollector(SPAWNLOC[rand].x,SPAWNLOC[rand].y);
+         return;
+         }
+      rand= ((rand + 1) % NUMSPAWNLOCATIONS);
+
+      }
+
+//MED
+   nx = SPAWNLOC[rand].x;
+   ny = SPAWNLOC[rand].y;
+   FindEmptyTile(&nx,&ny);
+   SpawnCollector(nx,ny);
+   }
+
+//****************************************************************************
+//
+//
+//
+//****************************************************************************
+
+void SpawnCollector(int tilex, int tiley)
+{
+ #if (SHAREWARE == 0)
+ if ( dopefish==true )
+    {
+    SpawnNewObj(tilex,tiley,&s_scottwander1,collectorobj);
+    }
+ else
+ #endif
+    {
+    SpawnNewObj(tilex,tiley,&s_collectorwander1,collectorobj);
+    }
+
+ new->flags |= (FL_SHOOTABLE|FL_BLOCK|FL_NOFRICTION|FL_FULLLIGHT);
+ new->hitpoints = 500;
+ new->speed = 0x3000;
+ new->dir = north;
+ new->dirchoosetime = 175;
+ new->z = PlatformHeight(tilex,tiley);
+ if (new->z == -10)
+   new->z = 0;
+ if (areabyplayer[new->areanumber])
+	{new->flags |= FL_ABP;
+	 MakeActive(new);
+	}
+
+}
+
+
+
+void SelectDoorDir(objtype*ob)
+{int dx,dy,actrad;
+ dirtype dtry1,dtry2,tdir,olddir;
+
+ dx= ob->targettilex - ob->x;
+ dy= ob->y - ob->targettiley;
+ olddir = ob->dir;
+ if ((abs(dx) < 0x4000) && (abs(dy) < 0x4000))
+	 {ZEROMOM;
+     SetFinePosition(ob,ob->targettilex,ob->targettiley);
+     SetVisiblePosition(ob,ob->x,ob->y);
+     ParseMomentum(ob,dirangle8[ob->temp2]);
+	  ActorMovement(ob);
+	  ob->temp2 = 0;
+	  ob->temp1 = 20;
+    #if (SHAREWARE == 0)
+    if ( dopefish==true )
+       {
+       NewState(ob,&s_scottwander1);
+       }
+    else
+    #endif
+       {
+       NewState(ob,&s_collectorwander1);
+       }
+	  ob->targettilex = ob->targettiley = 0;
+	  ob->dirchoosetime = 165;
+	  return;
+	 }
+
+
+ ZEROMOM;
+
+ ParseMomentum(ob,atan2_appx(dx,dy));
+ ActorMovement(ob);
+ if (ob->momentumx || ob->momentumy)
+	return;
+ actrad = ACTORSIZE;
+ dtry1=nodir;
+ dtry2=nodir;
+
+ if (dx> actrad)
+	dtry1= east;
+ else if (dx< -actrad)
+	dtry1= west;
+ if (dy> actrad)
+	dtry2= north;
+ else if (dy < -actrad)
+	dtry2= south;
+
+
+ if (abs(dy)>abs(dx))
+	 {tdir=dtry1;
+	  dtry1=dtry2;
+	  dtry2=tdir;
+	 }
+
+
+ if (dtry1 != nodir)
+	M_CHECKDIR(ob,dtry1);
+
+ if (dtry2 != nodir)
+	M_CHECKDIR(ob,dtry2);
+
+ if (dtry1 != nodir)
+	M_CHECKDIR(ob,dirorder[dtry1][NEXT]);
+
+ if (dtry2 != nodir)
+	M_CHECKDIR(ob,dirorder[dtry2][NEXT]);
+
+ for(tdir = dirorder[olddir][NEXT];tdir != olddir;tdir = dirorder[tdir][NEXT])
+	M_CHECKDIR(ob,tdir);
+ ob->dir = olddir;
+
+}
+
+
+boolean EluderCaught(objtype*ob)
+{
+ objtype *temp;
+ int dx,dy,dz;
+ playertype *pstate;
+ int dist = 0xc000;
+
+ for(temp = PLAYER[0];temp != PLAYER[numplayers-1]->next;temp=temp->next)
+	{
+#if (SHAREWARE == 0)
+     if (temp->state != &s_doguse)
+		 continue;
+#endif
+
+	  dx = M_ABS(temp->x - ob->x);
+	  if (dx > dist)
+		 continue;
+
+	  dy = M_ABS(temp->y - ob->y);
+	  if (dy > dist)
+		 continue;
+
+	  dz = M_ABS(temp->z - ob->z);
+	  if (dz > (dist>>10))
+		 continue;
+
+	  M_LINKSTATE(temp,pstate);
+	  //if (DOGSCRATCH.attackinfo[pstate->attackframe].attack == at_pulltrigger)
+		 {BATTLE_CheckGameStatus(battle_caught_eluder,temp->dirchoosetime);
+		  SpawnNewObj(ob->tilex,ob->tiley,&s_itemspawn1,inertobj);
+		  new->flags |= FL_ABP;
+        SetFinePosition(new,ob->x,ob->y);
+        SetVisiblePosition(new,ob->x,ob->y);
+		  new->z = ob->z;
+		  SD_PlaySoundRTP(SD_GETBONUSSND,ob->x,ob->y);
+		  MakeActive(new);
+		  NewState(ob,&s_megaremove);
+		  return true;
+		 }
+
+	}
+
+ return false;
+}
+
+
+void T_CollectorFindDoor(objtype*ob)
+{
+
+ if (EluderCaught(ob))
+	return;
+
+ if (!(gamestate.TimeCount % 17))
+	SD_PlaySoundRTP(SD_MONKGRABSND,ob->x,ob->y);
+
+
+ if ((ob->z != nominalheight) && (!IsPlatform(ob->tilex,ob->tiley)))
+	ZEROMOM;
+
+
+
+ if (ob->dirchoosetime)
+    ob->dirchoosetime --;
+ else
+    {
+    #if (SHAREWARE == 0)
+    if ( dopefish==true )
+       {
+       NewState(ob,&s_scottwander1);
+       }
+    else
+    #endif
+       {
+       NewState(ob,&s_collectorwander1);
+       }
+	  ob->dirchoosetime = 165;
+	  ob->targettilex = ob->targettiley = 0;
+	  return;
+	 }
+
+ if (ob->temp1)
+	{int dx,dy;
+
+	 ob->temp1 --;
+	 ActorMovement(ob);
+	 dx = ob->targettilex-ob->x;
+	 dy = ob->targettiley-ob->y;
+	 if ((abs(dx) < 0x4000) && (abs(dy) < 0x4000))
+		 {ZEROMOM;
+        SetFinePosition(ob,ob->targettilex,ob->targettiley);
+        SetVisiblePosition(ob,ob->x,ob->y);
+
+		  ParseMomentum(ob,dirangle8[ob->temp2]);
+		  ActorMovement(ob);
+		  ob->temp2 = 0;
+		  ob->temp1 = 35;
+        #if (SHAREWARE == 0)
+        if ( dopefish==true )
+           {
+           NewState(ob,&s_scottwander1);
+           }
+        else
+        #endif
+           {
+           NewState(ob,&s_collectorwander1);
+           }
+		  ob->targettilex = ob->targettiley = 0;
+		  ob->dirchoosetime = 165;
+		  return;
+		 }
+	 if (NOMOM)
+		ob->temp1 = 0;
+	 return;
+	}
+
+
+
+ ob->temp1 = 5;
+
+ if (ob->targettilex || ob->targettiley)
+	SelectDoorDir(ob);
+
+ else
+	{int i;
+	 doorobj_t* dptr;
+
+//==========================================================================
+#define SetCollectorTarget(xoffset,yoffset,newdir)                         \
+   {                                                                       \
+   ob->targettilex = ((dptr->tilex + (xoffset)) << TILESHIFT) + HALFGLOBAL1; \
+   ob->targettiley = ((dptr->tiley + (yoffset)) << TILESHIFT) + HALFGLOBAL1; \
+   ob->temp2 = newdir;                                                     \
+   if (GameRandomNumber("collector door search",0) < 100)                  \
+      return;                                                              \
+   }
+//==========================================================================
+
+   for(i=0;i<doornum;i++)
+	  {dptr = doorobjlist[i];
+		if (dptr->vertical)
+        {
+        int area1 = AREANUMBER(dptr->tilex-1,dptr->tiley),
+            area2 = AREANUMBER(dptr->tilex+1,dptr->tiley);
+
+        if (area1 == ob->areanumber)
+           SetCollectorTarget(-1,0,east)
+
+        else if (area2 == ob->areanumber)
+           SetCollectorTarget(1,0,west);
+
+		  }
+		else
+        {
+        int area1 = AREANUMBER(dptr->tilex,dptr->tiley-1),
+            area2 = AREANUMBER(dptr->tilex,dptr->tiley+1);
+
+        if (area1 == ob->areanumber)
+           SetCollectorTarget(0,-1,south)
+
+        else if (area2 == ob->areanumber)
+           SetCollectorTarget(0,1,north);
+
+		  }
+	  }
+  }
+
+}
+
+
+void T_CollectorWander(objtype*ob)
+{
+
+   int newtilex,newtiley;
+
+   if (EluderCaught(ob))
+      return;
+
+   if ((ob->z != nominalheight) && (!IsPlatform(ob->tilex,ob->tiley)))
+      ZEROMOM;
+
+   if (!(gamestate.TimeCount & 15))//%17
+      SD_PlaySoundRTP(SD_MONKGRABSND,ob->x,ob->y);
+
+   if (ob->dirchoosetime)
+      {
+      if (doornum > 0)
+         ob->dirchoosetime --;
+      }
+
+   else
+      {
+      #if (SHAREWARE == 0)
+      if ( dopefish==true )
+         {
+         NewState(ob,&s_scottwanderdoor1);
+         }
+      else
+      #endif
+         {
+         NewState(ob,&s_collectorfdoor1);
+         }
+      ob->temp1 = 0;
+      ob->dirchoosetime = 165;
+      ob->targettilex = ob->targettiley = 0;
+      return;
+      }
+
+   if (ob->temp1) // temp1 holds direction time
+      ob->temp1 --;
+   else
+      {
+      dirtype bestdir,tempdir;
+
+      bestdir = angletodir[GameRandomNumber("collector theta",0) << 3];
+
+      for(tempdir = bestdir;tempdir != dirorder[bestdir][PREV];tempdir = dirorder[tempdir][NEXT])
+         {
+         ParseMomentum(ob,dirangle8[tempdir]);
+         newtilex = ((ob->x + ob->momentumx)>>16);
+         newtiley = ((ob->y + ob->momentumy)>>16);
+         if (IsWindow(newtilex,newtiley))
+            continue;
+         ActorMovement(ob);
+         if (ob->momentumx || ob->momentumy)
+            {
+            ob->temp1 = (GameRandomNumber("collector choose time",0) >> 2);
+            return;
+            }
+         }
+
+      }
+
+   newtilex = ((ob->x + ob->momentumx)>>16);
+   newtiley = ((ob->y + ob->momentumy)>>16);
+
+
+   if (IsWindow(newtilex,newtiley))
+      {
+      ob->temp1 = 0;
+      return;
+      }
+
+
+   ActorMovement(ob);
+
+   if (NOMOM)
+      ob->temp1 = 0;
+   }
+
+
+
+
+
+boolean CheckDoor(objtype *ob,doorobj_t * door,int trytilex,int trytiley)
+{boolean doorok=false;
+
+
+ switch(ob->dir)
+	{case north:
+	  if ((ob->tiley == (door->tiley + 1)) && (trytilex == ob->tilex))
+		 doorok = true;
+	  break;
+
+	 case east:
+	  if ((ob->tilex == (door->tilex - 1)) &&	(trytiley == ob->tiley))
+		doorok = true;
+	  break;
+
+	 case south:
+	  if ((ob->tiley == (door->tiley - 1)) &&	(trytilex == ob->tilex))
+		doorok = true;
+	  break;
+
+	 case west:
+	  if ((ob->tilex == (door->tilex + 1)) &&	(trytiley == ob->tiley))
+		doorok = true;
+	  break;
+	default:
+	    ;
+	}
+
+
+  if (doorok)
+   {SetTilePosition(ob,ob->tilex,ob->tiley);
+    SetVisiblePosition(ob,ob->x,ob->y);
+	 return true;
+	}
+  return false;
+}
+
+
+boolean WallCheck(int tryx,int tryy)
+{int tilexlow,tilexhigh,tileylow,tileyhigh,y,x;
+
+ tilexlow = (int)((tryx -PLAYERSIZE) >>TILESHIFT);
+ tileylow = (int)((tryy -PLAYERSIZE) >>TILESHIFT);
+
+ tilexhigh = (int)((tryx + PLAYERSIZE) >>TILESHIFT);
+ tileyhigh = (int)((tryy + PLAYERSIZE) >>TILESHIFT);
+
+
+ for (y=tileylow;y<=tileyhigh;y++)
+  for (x=tilexlow;x<=tilexhigh;x++)
+	{//tempwall = (wall_t*)actorat[x][y];
+	 //if (tempwall && M_ISWALL(tempwall))
+	 if (tilemap[x][y])
+	  return false;
+	}
+
+ return true;
+
+}
+
+
+boolean QuickSpaceCheck(objtype*ob,int tryx, int tryy)
+{int xlow,xhigh,ylow,yhigh,x,y,dx,dy;
+ objtype* temp;
+
+ xlow = (int)((tryx-ACTORSIZE) >>TILESHIFT);
+ ylow = (int)((tryy-ACTORSIZE) >>TILESHIFT);
+
+ xhigh = (int)((tryx+ACTORSIZE) >>TILESHIFT);
+ yhigh = (int)((tryy+ACTORSIZE) >>TILESHIFT);
+/******************* WALLS/PWALLS *****************************************/
+
+ for (y=ylow;y<=yhigh;y++)
+  for (x=xlow;x<=xhigh;x++)
+	{temp = (objtype*)actorat[x][y];
+	 if ((temp && (temp->which != ACTOR)) ||
+		  (sprites[x][y] && (sprites[x][y]->flags & FL_BLOCK))
+
+			|| tilemap[x][y])
+		return false;
+	}
+
+ for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
+	{if (temp == ob)
+		continue;
+	 if ((temp->flags & FL_NONMARK) || (temp->flags & FL_NEVERMARK))
+	  continue;
+	 dx = tryx - temp->x;
+	 if ((dx < -MINACTORDIST) || (dx > MINACTORDIST))
+		continue;
+	 dy = tryy - temp->y;
+	 if ((dy < -MINACTORDIST) || (dy > MINACTORDIST))
+		continue;
+	 if (ob->whatever == (void*)temp)
+		continue;
+	 if (temp->whatever == ob->whatever)
+		continue;
+	 return false;
+	}
+
+ return true;
+
+
+}
+
+
+//=========================================================================
+//
+//                    ACTOR TRY MOVE MADNESS
+//
+//=========================================================================
+
+typedef enum
+{
+ NO_MOVEMENT,
+ Z_MOVEMENT_ONLY,
+ OK_TO_CONTINUE
+
+}movement_status;
+
+
+
+//==================== Some ActorTryMove macros ==============================
+
+#define CheckProximitySpecials(ob,temp)                             \
+{                                                                   \
+   if (ocl == b_heinrichobj)                                       \
+      {                                                            \
+      if (tcl == playerobj)                                        \
+         {                                                         \
+         playertype *pstate;                                      \
+                                                                     \
+         M_LINKSTATE(temp,pstate);                                \
+         DamageThing(temp,5);                                     \
+         temp->whatever = ob;                                     \
+         temp->temp2 = COLUMNCRUSH;                               \
+         pstate->heightoffset += 4;                               \
+         if (pstate->heightoffset >= 30)                          \
+            pstate->heightoffset = 30;                           \
+         pstate->oldheightoffset = pstate->heightoffset;          \
+         }                                                         \
+      else                                                         \
+         {                                                         \
+         temp->momentumx = temp->momentumy = temp->momentumz = 0; \
+         temp->hitpoints = 0;                                     \
+         }                                                         \
+      if (temp->hitpoints <= 0)                                    \
+         temp->flags |= FL_HBM;                                     \
+      Collision(temp,ob,0,0);                                      \
+      continue;                                                    \
+      }                                                             \
+                                                                    \
+   else if ((ocl == b_darksnakeobj) && (tcl == playerobj)) \
+      {                                                     \
+      DamageThing(temp,1);                                      \
+      Collision(temp,ob,0,0);     \
+      M_CheckPlayerKilled(temp);                                   \
+      } \
+        \
+   if ((ocl == boulderobj) && (tcl >= lowguardobj) && (tcl < roboguardobj))\
+      {temp->momentumx = temp->momentumy = temp->momentumz = 0;     \
+       temp->hitpoints = 0;                                         \
+       temp->flags |= FL_HBM;                                       \
+       Collision(temp,ob,0,0);                                      \
+       SD_PlaySoundRTP(SD_ACTORSQUISHSND,temp->x,temp->y);          \
+       continue;                                                    \
+      }                                                             \
+                                                                    \
+   if (pusher && (ocl != tcl) && (!(temp->flags & FL_DYING))  &&    \
+       (tcl < roboguardobj)                                         \
+      )                                                             \
+      {if ((!ob->ticcount) && (ocl != collectorobj) && (ocl != diskobj))\
+          DamageThing(temp,5);                                      \
+                                                                    \
+       if (tcl == playerobj)                                        \
+         temp->flags |= FL_PUSHED;                                  \
+       Collision(temp,ob,ob->momentumx-temp->momentumx,ob->momentumy-temp->momentumy);\
+       M_CheckPlayerKilled(temp);                                   \
+       continue;                                                    \
+      }                                                             \
+                                                                    \
+   if (bouncer)                                                    \
+      {ob->momentumx = -ob->momentumx;                              \
+       continue;                                                    \
+      }                                                             \
+   }
+
+
+
+#define CheckStepping(ob,step,minzdiff)                         \
+{                                                               \
+ int cz = (ob->z - step->z + minzdiff);                         \
+                                                                \
+ if ((cz >= -MAXSTEPHEIGHT) && (cz <= MAXSTEPHEIGHT))           \
+      {if ((ob->obclass == playerobj) && (ob->temp2 == 0) &&    \
+           (ob->z != (step->z - minzdiff))                      \
+          )                                                     \
+         {                                                      \
+         playertype *pstate;                                    \
+                                                                \
+         M_LINKSTATE(ob,pstate);                                \
+                                                                \
+         pstate->heightoffset = pstate->oldheightoffset + cz;   \
+         ob->temp2 = (cz >= 0)?(STEPUP):(STEPDOWN);             \
+         }                                                      \
+      ob->z = step->z - minzdiff;                               \
+      tryz = ob->z + (ob->momentumz >> 16);                     \
+      dzt = minzdiff;                                           \
+      }                                                         \
+}                                                               \
+
+
+
+
+//============ Players crushing other players =====================
+
+void BattleCrushCheck(objtype *ob,objtype *listrover)                              \
+   {
+   if ((ob->obclass == playerobj) && (listrover->obclass == playerobj))
+      {
+      playertype * pstate;
+
+      M_LINKSTATE(listrover,pstate);
+      if (pstate->health <= 0)
+         BATTLE_PlayerKilledPlayer(battle_kill_by_crushing,ob->dirchoosetime,
+                                    listrover->dirchoosetime);
+      }
+   }
+
+
+//=================================================================
+
+
+
+
+
+movement_status CheckOtherActors(objtype*ob,int tryx,int tryy,int tryz)
+   {
+   objtype *listrover;
+   int area;
+   int op;
+   int areatried[NUMAREAS]={0};
+   int tilexlow,tilexhigh,tileylow,tileyhigh;
+   int radius,actrad,oldrad;
+   boolean bouncer,pusher,thinkingactor,zstoppable,ACTORSTOP;
+   int dzt,dztp1,checkz;
+   int x,y,dx,dy;
+   int ocl,tcl;
+   int ISPLAYER = 0;
+   int hoffset;
+
+   ocl = ob->obclass;
+
+   actrad = MINACTORDIST;//ACTORSIZE+0x2800;
+   pusher =  ((ocl == wallopobj) || (ocl == pillarobj) ||
+              (ocl == roboguardobj) || (ocl == collectorobj) ||
+              (ocl == boulderobj) || (ocl == diskobj)
+             );
+
+   thinkingactor = ((ocl != playerobj) && (ob->state->think != T_Collide) &&
+                    (ocl < roboguardobj)
+                   );
+
+   zstoppable = (!(ob->flags & FL_DYING));
+   bouncer = ((ocl == playerobj) && (ob->flags & FL_ELASTO));
+   radius = ACTORSIZE;
+
+
+   if (ocl != playerobj)
+         {
+         //actrad = MINACTORDIST;
+         //if ((ob->dir == nodir) && (ocl != b_robobossobj) &&
+          //   (ocl != wallopobj) && (ocl != roboguardobj) && (ocl != diskobj)
+           // )
+           // Error("ob called with nodir");
+         if (ocl == boulderobj)
+            radius += (ACTORSIZE/4);
+         else if (ocl == b_darksnakeobj)
+            radius -= 6000;
+         else if (ocl == inertobj)
+            radius -= 0x2000;
+         }
+
+   else
+         {
+         ISPLAYER = 1;
+         if (ob->flags & FL_DOGMODE)
+            hoffset = 10;
+         }
+
+
+
+   tilexlow = (int)((tryx-radius) >>TILESHIFT);
+   tileylow = (int)((tryy-radius) >>TILESHIFT);
+
+   tilexhigh = (int)((tryx+radius) >>TILESHIFT);
+   tileyhigh = (int)((tryy+radius) >>TILESHIFT);
+
+   area = ob->areanumber;
+   areatried[area] = 1;
+   ACTORSTOP = false;
+   oldrad = actrad;
+
+ actors:
+   for(listrover=firstareaactor[area];listrover;listrover=listrover->nextinarea)
+         {
+         actrad = oldrad;
+
+         if (listrover == ob)
+            continue;
+
+
+         tcl = listrover->obclass;
+
+         if ((tcl == b_darksnakeobj) && (listrover != SNAKEHEAD))
+            continue;
+
+         if (((tcl == bladeobj) || (tcl == firejetobj)) && thinkingactor)
+
+            actrad += 0x3000;
+
+
+         dx = tryx - listrover->x;
+         if ((dx < -actrad) || (dx > actrad))
+            continue;
+
+         dy = tryy - listrover->y;
+         if ((dy < -actrad) || (dy > actrad))
+            continue;
+
+
+         if ((ocl == b_darksnakeobj) && (tcl == ocl))
+            continue;
+
+         if ((tcl == springobj) && (listrover->state->condition & SF_UP) &&
+             (listrover->temp1!=3) && (levelheight > 1) &&
+             (abs(listrover->z - ob->z) < 5) && (!ob->momentumz)
+            )
+            {
+               {
+               op = (FixedMul((int)GRAVITY,(int)((ob->z-10)<<16))<<1);
+               ob->momentumz = -FixedSqrtHP(op);
+               }
+               SD_PlaySoundRTP(SD_SPRINGBOARDSND,listrover->x,listrover->y);
+               NewState(listrover,&s_spring2);
+
+            }
+
+
+
+         if ((tcl == firejetobj) && (ob->z < listrover->z))
+            continue;
+
+         if ((!(listrover->flags & FL_BLOCK)) && (actrad == oldrad)) // if not blocking
+                                                   // and actor not avoiding
+                                                   // env. danger
+            continue;
+
+
+
+         if (tcl == crushcolobj)
+            checkz = listrover->temp2;
+         else
+            checkz = listrover->z;
+
+      #define  MINACTORZDIFF 58
+
+         dzt = abs(checkz - ob->z);
+         dztp1 = abs(checkz - tryz);
+
+         if ((tcl == diskobj) && (dztp1 <= MINACTORZDIFF) && zstoppable &&
+             (ocl != b_heinrichobj)
+            )
+            CheckStepping(ob,listrover,MINACTORZDIFF);
+
+         dztp1 = abs(checkz - tryz);
+
+
+
+         if ((dzt > (MINACTORZDIFF - 25)) && (dzt < MINACTORZDIFF) &&
+             (dztp1 < MINACTORZDIFF) && (tcl < roboguardobj) &&
+             (ocl < roboguardobj)
+            )
+            {
+            int rdx,rdy;
+
+            rdx = abs(ob->x - listrover->x);
+            rdy = abs(ob->y - listrover->y);
+            if ((rdx < actrad) && (rdy < actrad))
+               {
+               if (ob->z > listrover->z)
+                  listrover->z = ob->z - MINACTORZDIFF;
+               else
+                  ob->z = listrover->z - MINACTORZDIFF;
+
+               dzt = dztp1 = MINACTORZDIFF;
+               }
+
+            }
+
+
+         if ((dztp1 >= MINACTORZDIFF) || (dzt >= MINACTORZDIFF))
+            {
+            if ((dzt >= MINACTORZDIFF) && (dztp1 <= MINACTORZDIFF) &&
+                zstoppable
+               )
+               {//ob->momentumz = 0;
+               if (ob->z < listrover->z)
+                  {
+                  ob->z = listrover->z - MINACTORZDIFF;
+                  ob->momentumz = 0;
+                  }
+               else
+                  ob->momentumz = 2*GRAVITY;
+               if ((listrover->z > ob->z) && (tcl < roboguardobj) && (ocl < roboguardobj) &&
+                     (!(listrover->flags & FL_DYING))
+                  )
+
+                  {
+                  DamageThing(listrover,5);
+                  BattleCrushCheck(ob,listrover);
+                  Collision(listrover,ob,listrover->momentumx,listrover->momentumy);
+                  /*
+                  if ((ocl == playerobj) && (listrover->flags & FL_DYING))
+                     GivePoints(starthitpoints[gamestate.difficulty][tcl]);
+                  */
+                  }
+
+               if (((tcl == bladeobj) || (tcl == diskobj)) && (ob->z < listrover->z))
+                  {
+                  ob->whatever = listrover;
+                  if (listrover->flags & FL_ACTIVE)
+                     ob->flags |= FL_RIDING;
+                  listrover->whatever = ob;
+                  }
+
+               //Debug("\nplayerz %d, tryz %d momz zeroed at %d, clearances %d and %d",
+                  //   ob->z,tryz,listrover->z-64 + (listrover->momentumz >> 16),dzt,dztp1);
+
+               }
+
+            continue;
+            }
+
+
+         CheckProximitySpecials(ob,listrover);
+
+
+         ACTORSTOP = true;
+         if (!ob->momentumz)
+            return NO_MOVEMENT;
+
+         }
+
+
+   for (y=tileylow;y<=tileyhigh;y++)
+      for (x=tilexlow;x<=tilexhigh;x++)
+         {
+         area = AREANUMBER(x,y);
+         if (ValidAreanumber(area) && (areatried[area]==0))
+            {
+            areatried[area] = 1;
+            goto actors;
+            }
+         }
+
+
+
+   if (ACTORSTOP==true)
+     return Z_MOVEMENT_ONLY;
+
+   return OK_TO_CONTINUE;
+   }
+
+
+
+movement_status CheckRegularWalls(objtype *ob,int tryx,int tryy,int tryz)
+   {
+   int tilexlow,tilexhigh,tileylow,tileyhigh,x,y,radius;
+   classtype ocl;
+   boolean WALLSTOP,ISPLAYER=false;
+
+   ocl = ob->obclass;
+   tryz=tryz;
+
+
+   if (ocl != playerobj)
+         {
+         radius = ACTORSIZE - 0x1000;
+         //actrad = MINACTORDIST;
+         //if ((ob->dir == nodir) && (ocl != b_robobossobj) &&
+          //   (ocl != wallopobj) && (ocl != roboguardobj) && (ocl != diskobj)
+          //  )
+           // Error("ob called with nodir");
+         if (ocl == boulderobj)
+            radius += (ACTORSIZE/4);
+         else if (ocl == b_darksnakeobj)
+            radius -= 6000;
+         else if (ocl == inertobj)
+            radius -= 0x2000;
+         }
+
+   else
+         {
+         radius = PLAYERSIZE;
+         ISPLAYER = true;
+         }
+
+
+   tilexlow = (int)((tryx-radius) >>TILESHIFT);
+   tileylow = (int)((tryy-radius) >>TILESHIFT);
+
+   tilexhigh = (int)((tryx+radius) >>TILESHIFT);
+   tileyhigh = (int)((tryy+radius) >>TILESHIFT);
+
+
+   WALLSTOP = false;
+
+   for (y=tileylow;y<=tileyhigh;y++)
+      for (x=tilexlow;x<=tilexhigh;x++)
+         {
+         wall_t          *tempwall;
+         int             wall;
+
+         tempwall = (wall_t*)actorat[x][y];
+         wall=tilemap[x][y];
+         if (tempwall)
+            {
+            if (tempwall->which==WALL)// && IsWindow(x,y)==false)
+               {
+               if (ocl == boulderobj)
+                  {
+#if (SHAREWARE == 0)
+                  NewState(ob,&s_bouldersink1);
+#endif
+                  SD_PlaySoundRTP(SD_BOULDERHITSND,ob->x,ob->y);
+                  }
+               else if (ISPLAYER && (!(ob->flags & FL_DYING)) &&
+                     (!(ob->flags & FL_AV)) &&
+                     (tempwall->flags & FL_W_DAMAGE))
+                  {
+                  DamageThing(ob,5);
+                  Collision(ob,(objtype*)tempwall,0,0);
+                  M_CheckPlayerKilled(ob);
+                  SD_PlaySoundRTP(SD_PLAYERBURNEDSND,ob->x,ob->y);
+                  }
+
+               //return false;
+               WALLSTOP = true;
+               if ((ocl == inertobj) &&
+                   (ob->dirchoosetime == GIBVALUE) &&
+
+                   (((ob->tilex - x) == 0) != ((ob->tiley - y) == 0)) &&
+                   (ob->z > -28)
+
+                  )
+                  {
+   //                SoftError ("Blood Dripping oldpolltime=%ld\n",oldpolltime);
+                  BloodDrip(ob,x,y);
+                  return NO_MOVEMENT;
+                  }
+
+               if (!ob->momentumz)
+                  return NO_MOVEMENT;
+               else// if (ocl != inertobj)
+                  return Z_MOVEMENT_ONLY;
+               //else
+               //goto doors;
+               }
+
+            else if (tempwall->which==PWALL)
+                  {
+                  pwallobj_t*pw;
+                  int dx,dy;
+
+                  pw=(pwallobj_t *)tempwall;
+                  dx = abs(pw->x - tryx);
+                  if (dx > PWALLRAD+0x5000)
+                     continue;
+
+                  dy = abs(pw->y - tryy);
+                  if (dy > PWALLRAD+0x5000)
+                     continue;
+
+                  return NO_MOVEMENT;
+                  }
+
+            }
+         }
+
+   return OK_TO_CONTINUE;
+
+   }
+
+
+
+movement_status CheckStaticObjects(objtype *ob,int tryx,int tryy,int tryz)
+  {
+  int dx,dy,dzt,dztp1,x,y;
+  statobj_t*tempstat;
+  int sprrad,oldsrad,sprtrad;
+  boolean specialstat=false,widestat=false,zstoppable;
+  int sprxlow,sprxhigh,sprylow,spryhigh;
+  boolean SPRSTOP;
+  classtype ocl;
+
+  ocl = ob->obclass;
+
+  if (ocl != playerobj)
+     sprtrad = ACTORSIZE - 0x1000;
+  else
+     sprtrad = ACTORSIZE - 0x1000 + 0x10000;
+
+
+
+  sprxlow = (int)((tryx-sprtrad) >>TILESHIFT);
+  sprylow = (int)((tryy-sprtrad) >>TILESHIFT);
+
+  sprxhigh = (int)((tryx+sprtrad) >>TILESHIFT);
+  spryhigh = (int)((tryy+sprtrad) >>TILESHIFT);
+
+  if (sprxlow < 0)
+     sprxlow = 0;
+
+  if (sprxhigh > (MAPSIZE-1))
+     sprxhigh = MAPSIZE-1;
+
+  if (sprylow < 0)
+     sprylow = 0;
+
+  if (spryhigh > (MAPSIZE-1))
+     spryhigh = MAPSIZE-1;
+
+  SPRSTOP = false;
+  sprrad = 0x4500;
+  zstoppable = (!(ob->flags & FL_DYING));
+  oldsrad = sprrad;
+
+  for (y=sprylow;y<=spryhigh;y++)
+      for (x=sprxlow;x<=sprxhigh;x++)
+         {
+         tempstat = sprites[x][y];
+         sprrad = oldsrad;
+
+         if (tempstat)
+            {
+            specialstat = ((tempstat->itemnumber == stat_heatgrate) ||
+                           (tempstat->itemnumber == stat_pit)
+                          );
+
+            widestat = (((tempstat->itemnumber >= stat_bcolumn) &&
+                        (tempstat->itemnumber <= stat_icolumn)) ||
+                        (tempstat->itemnumber == stat_disk)
+                       );
+
+            if ((tempstat->flags & FL_BLOCK) || (specialstat==true))
+               {
+               if ((specialstat==true) && (ocl !=playerobj) &&
+                   (ob->state->think != T_Collide)
+                  )
+                  sprrad += 0x5000;
+
+               if (widestat==true)
+                  sprrad += 0x3b00;
+
+
+               if ((tempstat->itemnumber == stat_ironbarrel) ||
+                     (tempstat->itemnumber == stat_bonusbarrel))
+                  sprrad += 0x5000;
+
+               dx = abs(tryx - tempstat->x);
+               if (dx > sprrad)
+                  continue;
+               dy = abs(tryy - tempstat->y);
+               if (dy > sprrad)
+                  continue;
+
+      #define MINSTATZDIFF 58
+
+               dzt = abs(ob->z - tempstat->z);
+               dztp1 = abs(tryz - tempstat->z);
+
+               if (widestat && (dztp1 <= MINSTATZDIFF) && zstoppable &&
+                   (ocl != b_heinrichobj)
+                  )
+                  CheckStepping(ob,tempstat,MINSTATZDIFF);
+
+
+               dztp1 = abs(tryz - tempstat->z);
+
+#if (SHAREWARE == 0)
+               if ((ocl == b_darksnakeobj) && (tempstat->itemnumber == stat_heatgrate))
+                  {
+                  if (ob->state->think == T_DarkSnakeChase)
+                     NewState(ob,&s_darkmonkredhead);
+                  else
+                     NewState(ob,&s_darkmonkredlink);
+                  ob->temp3 ++; // make shootable
+                  }
+#endif
+
+               if (specialstat==true)
+                  continue;
+
+
+               if ((dztp1 >= MINSTATZDIFF) || (dzt >= MINSTATZDIFF))
+                  {if ((dzt >= MINSTATZDIFF) && (dztp1 <= MINSTATZDIFF) && zstoppable)
+                     {//ob->momentumz = 0;
+                     if (ob->z <= tempstat->z)
+                        {
+                        ob->z = tempstat->z - MINSTATZDIFF;
+                        ob->momentumz = 0;
+                        }
+                     else
+                        ob->momentumz = 2*GRAVITY; // ((2*GRAVITY + GRAVITY) >> 16) = 1
+                     }
+                  continue;
+                  }
+
+
+               if (ocl == boulderobj)
+                  {if ((tempstat->itemnumber < stat_bcolumn) ||
+                       (tempstat->itemnumber > stat_icolumn)
+                      )
+                     {
+                     tempstat->flags |= FL_SHOOTABLE;
+                     DamageThing(tempstat,tempstat->hitpoints);
+                     continue;
+                     }
+#if (SHAREWARE == 0)
+                  else
+                     NewState(ob,&s_bouldersink1);
+#endif
+                  }
+               //ob->momentumz=0;
+               //return false;
+               SPRSTOP=true;
+               if (!ob->momentumz)
+                  return NO_MOVEMENT;
+               }
+            }
+         }
+  if (SPRSTOP == true)
+     return Z_MOVEMENT_ONLY;
+
+  return OK_TO_CONTINUE;
+
+  }
+
+
+
+
+
+//============== Platform craziness ======================================
+
+
+#define ClipHeight(ob,clipz)                                \
+{  ob->momentumz = 0;                                       \
+                                                            \
+   if (ISPLAYER && (ob->z != clipz) && (ob->temp2 == 0))    \
+      {playertype *pstate;                                  \
+       int dz = ob->z - clipz;                              \
+                                                            \
+       M_LINKSTATE(ob,pstate);                              \
+                                                            \
+       pstate->heightoffset = pstate->oldheightoffset + dz; \
+       ob->temp2 = (dz >= 0)?(STEPUP):(STEPDOWN);           \
+      }                                                     \
+                                                            \
+   ob->z = clipz;                                           \
+}
+
+//======================
+
+#define CheckSpecialGibMovement(blocker)            \
+   {                                                \
+   int centerx = ((trytilex<<16) + 0x8000);         \
+   int centery = ((trytiley<<16) + 0x8000);         \
+                                                    \
+   if (blocker->vertical==false)                    \
+      {                                             \
+      int dyt = centery - ob->y;                    \
+      int dytp1 = centery - tryy;                   \
+                                                    \
+      if ((abs(dytp1) > abs(dyt)) &&                \
+         (SGN(dyt) == SGN(dytp1))                   \
+         )                                          \
+         return OK_TO_CONTINUE;                     \
+                                                    \
+      }                                             \
+   else                                             \
+      {                                             \
+      int dxt = centerx - ob->x;                    \
+      int dxtp1 = centerx - tryx;                   \
+                                                    \
+      if ((abs(dxtp1) > abs(dxt)) &&                \
+         (SGN(dxt) == SGN(dxtp1))                   \
+         )                                          \
+         return OK_TO_CONTINUE;                     \
+                                                    \
+      }                                             \
+   }
+
+
+movement_status CheckMaskedWalls(objtype *ob,int tryx,int tryy,int tryz)
+  {
+  int trytilex,trytiley;
+  boolean MWALLSTOP;
+  int ISPLAYER = (ob->obclass == playerobj);
+  classtype ocl = ob->obclass;
+
+  trytilex = (tryx >> TILESHIFT);
+  trytiley = (tryy >> TILESHIFT);
+  MWALLSTOP = false;
+ //for (y=tileylow;y<=tileyhigh;y++)
+ // for (x=tilexlow;x<=tilexhigh;x++)
+
+   if (M_ISMWALL(trytilex,trytiley))
+       {
+       int wall = tilemap[trytilex][trytiley];
+       maskedwallobj_t * mw;
+
+       mw=maskobjlist[wall&0x3ff];
+
+       if (ocl == inertobj)
+          CheckSpecialGibMovement(mw);
+
+       if (!(mw->flags&MW_BLOCKING))
+			  {
+			  if (mw->flags&MW_NONDOGBLOCKING)
+				  {
+				  if ((ocl==playerobj)&&(ob->flags&FL_DOGMODE))
+					  {
+					  if (ob->z < nominalheight)
+                    {
+                    MWALLSTOP = true;
+                    if (!ob->momentumz)
+                       return NO_MOVEMENT;
+						  }
+					  }
+				  else
+                 {
+                 MWALLSTOP = true;
+                 if (!ob->momentumz)
+                    return NO_MOVEMENT;
+					  }
+				  }
+
+
+           else
+				  {
+					if (mw->flags & MW_ABOVEPASSABLE)
+						{if (mw->flags & MW_MIDDLEPASSABLE) // ==> not bottom
+                      {if (ob->z > LOWFALLCLIPZ+MAXSTEPHEIGHT)
+                         MWALLSTOP = true;
+                       else if (tryz >= LOWFALLCLIPZ)
+                         ClipHeight(ob,LOWFALLCLIPZ);
+							 }
+						 else if (mw->flags & MW_BOTTOMPASSABLE)
+                      {if ((ob->z > HIGHFALLCLIPZ+MAXSTEPHEIGHT) && (ob->z < LOWRISECLIPZ))
+                         MWALLSTOP = true;
+                       else if (ob->z <= HIGHFALLCLIPZ+MAXSTEPHEIGHT)
+                         {if (tryz >= HIGHFALLCLIPZ)
+                            ClipHeight(ob,HIGHFALLCLIPZ);
+                         }
+                       else if (tryz <= LOWRISECLIPZ)
+								 ob->momentumz = 0;
+
+							 }
+						 else // ==> above only
+                      {if (ob->z > HIGHFALLCLIPZ+MAXSTEPHEIGHT)
+                         MWALLSTOP = true;
+                       else if (tryz >= HIGHFALLCLIPZ)
+                         ClipHeight(ob,HIGHFALLCLIPZ);
+                      }
+
+						}
+					else if (mw->flags & MW_MIDDLEPASSABLE)
+						{if (mw->flags & MW_BOTTOMPASSABLE) //==> not above passable
+                     {if (ob->z >= HIGHRISECLIPZ)
+                        {if (tryz <= HIGHRISECLIPZ)
+									ob->momentumz = 0;
+								}
+                      else if (tryz <= HIGHRISECLIPZ)
+                        MWALLSTOP = true;
+							}
+
+						 else  //==> middle only
+                     {if (ob->z > LOWFALLCLIPZ+MAXSTEPHEIGHT)
+                         MWALLSTOP = true;
+                      else if (tryz >= LOWFALLCLIPZ)
+                         ClipHeight(ob,LOWFALLCLIPZ)
+                      else
+                        {if (ob->z >= HIGHRISECLIPZ)
+                          {if (tryz <= HIGHRISECLIPZ)
+									  ob->momentumz = 0;
+								  }
+                         else if (tryz <= HIGHRISECLIPZ)
+                           MWALLSTOP = true;
+								}
+							}
+
+						}
+					else // ==> bottompassable only
+                  {if (ob->z < LOWRISECLIPZ)
+                         MWALLSTOP = true;
+                   else if (tryz < LOWRISECLIPZ)
+							 ob->momentumz = 0;
+						}
+
+				  }
+			  }
+       else
+			 {
+          if ( (mw->flags&MW_SHOOTABLE) &&
+                (mw->flags&MW_BLOCKINGCHANGES) &&
+                (ob->z >= nominalheight)
+
+              )
+              {
+              int speed=FindDistance(ob->momentumx,ob->momentumy);
+              if ((speed>0x2800) && (!(ob->flags & FL_DYING)))
+                 {
+                 if (ob->obclass == playerobj)
+                    {
+                    DamageThing(ob,10);
+                    Collision(ob,(objtype*)mw,0,0);
+                    }
+                 UpdateMaskedWall(wall&0x3ff);
+                 if (tryz < nominalheight)
+                    ob->momentumz = 0;
+                 }
+              else
+                 {
+                 MWALLSTOP = true;
+                 if (!ob->momentumz)
+                    return NO_MOVEMENT;
+                 }
+              }
+          else
+              {
+              MWALLSTOP = true;
+              if (!ob->momentumz)
+                 return NO_MOVEMENT;
+              }
+			 }
+       }
+
+  if (MWALLSTOP == true)
+    return Z_MOVEMENT_ONLY;
+
+  return OK_TO_CONTINUE;
+
+  }
+
+
+
+movement_status CheckDoors(objtype *ob,int tryx,int tryy,int tryz)
+  {
+  int trytilex,trytiley;
+  int ocl;
+
+
+  trytilex = (tryx >> TILESHIFT);
+  trytiley = (tryy >> TILESHIFT);
+  ocl = ob->obclass;
+
+
+  if (M_ISDOOR(trytilex,trytiley))
+       {
+       doorobj_t*tempdoor;
+       int doorn;
+
+       doorn = tilemap[trytilex][trytiley];
+
+       tempdoor = doorobjlist[doorn&0x3ff];
+		 if (tempdoor->action == dr_open)
+         {
+
+         if (ob->z >= nominalheight)
+            {
+            if (tryz < nominalheight)
+					ob->momentumz = 0;
+            return OK_TO_CONTINUE;
+				}
+
+         }
+       if (ocl == inertobj)
+          {
+          CheckSpecialGibMovement(tempdoor);
+          }
+       else if ((ocl == playerobj) || (ocl > b_darksnakeobj))
+          return NO_MOVEMENT;
+		 else if (ob->state->think != T_Collide)
+			{
+
+#define DOOR_LOCKED(door)                                      \
+           (((door->flags & DF_ELEVLOCKED) || (door->lock)) && \
+             (ob->obclass != b_darianobj)                       \
+           )
+#define GAS_DOOR(x,y) (MISCVARS->GASON && (MAPSPOT(x,y,1) == GASVALUE))
+
+         if ((!DOOR_LOCKED(tempdoor)) &&
+             (!GAS_DOOR(trytilex,trytiley))
+            )
+
+
+            //)
+            {
+            ob->door_to_open = doorn&0x3ff;
+            LinkedOpenDoor(ob->door_to_open);
+            if (tempdoor->eindex != -1)
+					OperateElevatorDoor(doorn&0x3ff);
+				}
+
+			 //if ((nstate = M_S(USE)) != NULL)
+			  //{ob->whatever = ob->state;
+			 //	NewState(ob,nstate);
+			 //	ob->flags |= FL_USE;
+			 // }
+         return NO_MOVEMENT;
+			}
+		 else
+          return NO_MOVEMENT;
+      }
+
+   return OK_TO_CONTINUE;
+  }
+
+
+
+boolean ActorTryMove(objtype*ob,int tryx, int tryy, int tryz)
+   {
+
+   movement_status (*reduced_movement_check[3])(objtype*,int,int,int)=
+                   {
+                   CheckRegularWalls,
+                   CheckMaskedWalls,
+                   CheckDoors,
+                   };
+
+
+   movement_status (*complete_movement_check[5])(objtype*,int,int,int)=
+                   {
+                   CheckOtherActors,
+                   CheckRegularWalls,
+                   CheckStaticObjects,
+                   CheckMaskedWalls,
+                   CheckDoors,
+                   };
+
+   movement_status (**movement_function)(objtype*,int,int,int);
+   movement_status movement_check_result;
+   int             numcheckfunctions;
+   int             i;
+   boolean         xyblocked;
+
+
+
+
+   if ((tryz < -30) && (sky==0) && (ob->obclass != inertobj))
+      {
+      ob->z = -28;
+      ob->momentumz = 0;
+      return false;
+      }
+
+   if ((!InMapBounds(tryx>>16,tryy>>16)) ||
+       ((ob->obclass != playerobj) && (IsWindow((tryx>>16),(tryy>>16))))
+      )
+      return false;
+
+   switch(ob->obclass)
+      {
+      case inertobj:
+      case bladeobj:
+      case firejetobj:
+         movement_function = &reduced_movement_check[0];
+         numcheckfunctions = 3;
+         break;
+
+      default:
+         movement_function = &complete_movement_check[0];
+         numcheckfunctions = 5;
+         break;
+      }
+
+
+   for(xyblocked=false,i=0;i<numcheckfunctions;i++)
+      {
+      movement_check_result = movement_function[i](ob,tryx,tryy,tryz);
+      if (movement_check_result == Z_MOVEMENT_ONLY)
+         xyblocked = true;
+
+      else if (movement_check_result == NO_MOVEMENT)
+         return false;
+      }
+
+   if (xyblocked == true)
+      return false;
+
+
+   return true;
+
+   }
+
+
+void PushWallMove(int num)
+{
+ int             tcl;
+ pwallobj_t      *pwall;
+ int             dx,dy;
+ int             actrad;
+ objtype         *temp;
+ boolean         pushem;
+ int             tryx,tryy,areanumber,trytilex,trytiley;
+
+
+ pwall=pwallobjlist[num];
+
+ actrad = PWALLRAD + 0x5000;
+ tryx = (pwall->x + pwall->momentumx);
+ tryy = (pwall->y + pwall->momentumy);
+ trytilex = (tryx >> 16);
+ trytiley = (tryy >> 16);
+
+ areanumber = AREANUMBER(trytilex,trytiley);
+
+
+ for(temp=firstareaactor[areanumber];temp;temp=temp->nextinarea)
+	 {
+	 tcl = temp->obclass;
+
+	 if (temp->flags & FL_HEAD)  //ignore NME's head and wheels
+		continue;
+
+	 if ((temp->flags & FL_DYING) || (!(temp->flags & FL_SHOOTABLE)))
+		continue;
+
+    if (tcl > b_darianobj)
+       continue;
+
+
+    dx = abs(tryx - temp->x);
+	 if (dx > actrad)
+		 continue;
+
+    dy = abs(tryy - temp->y);
+	 if (dy > actrad)
+		 continue;
+
+	 if (pwall->flags&PW_DAMAGE)
+		 {if (!((tcl == playerobj) && (temp->flags & FL_AV)))
+			 DamageThing(temp,5);
+
+        Collision(temp,(objtype*)pwall,0,0);
+		  M_CheckPlayerKilled(temp);
+		  if (temp->flags & FL_DYING)
+			 return;
+
+		 }
+
+	 pushem=false;
+	 switch (pwall->dir)
+			{
+
+#define PWALLTOL (0xc000)
+
+			case north:
+            if ((temp->y<pwall->y) && (dx<PWALLTOL))
+					pushem=true;
+				break;
+			case east:
+            if ((temp->x>pwall->x) && (dy<PWALLTOL))
+					pushem=true;
+				break;
+			case northeast:
+            if ((temp->y<pwall->y) && (dx<PWALLTOL))
+					pushem=true;
+            else if ((temp->x>pwall->x) && (dy<PWALLTOL))
+					pushem=true;
+				break;
+			case northwest:
+            if ((temp->y<pwall->y) && (dx<PWALLTOL))
+					pushem=true;
+            else if ((temp->x<pwall->x) && (dy<PWALLTOL))
+					pushem=true;
+				break;
+			case south:
+            if ((temp->y>pwall->y) && (dx<PWALLTOL))
+					pushem=true;
+				break;
+			case west:
+            if ((temp->x<pwall->x) && (dy<PWALLTOL))
+					pushem=true;
+				break;
+			case southeast:
+            if ((temp->y>pwall->y) && (dx<PWALLTOL))
+					pushem=true;
+            else if ((temp->x>pwall->x) && (dy<PWALLTOL))
+					pushem=true;
+				break;
+			case southwest:
+            if ((temp->y>pwall->y) && (dx<PWALLTOL))
+					pushem=true;
+            else if ((temp->x<pwall->x) && (dy<PWALLTOL))
+					pushem=true;
+				break;
+			default:
+            //Error ("Pushwall #%d has an illegal direction %d \n",num,pwall->dir);
+				break;
+			}
+
+
+	 //if (!pushem)
+		//continue;
+
+	 //temp->momentumx = temp->momentumy = 0;
+	 if (temp->obclass==playerobj)
+			 temp->flags|=FL_PUSHED;
+
+	 if (!pushem)
+      {
+       Collision(temp,(objtype*)pwall,-temp->momentumx,-temp->momentumy);
+		 continue;
+		}
+
+	 if ((temp->obclass >= lowguardobj) && (temp->obclass < roboguardobj))
+       {
+
+		  temp->momentumx = temp->momentumy = temp->momentumz = 0;
+		  temp->hitpoints = 0;
+
+		  if (gamestate.violence >= vl_high)
+			 temp->flags |= FL_HBM;
+        Collision(temp,(objtype*)pwall,0,0);
+		  /*
+				 if (gamestate.violence < vl_high)
+					{if ((tstate = UPDATE_STATES[CRUSH][temp->obclass - lowguardobj])!=NULL)
+						 NewState(temp,tstate);
+
+					 else
+						 Error("\n\Null low-violence crush state in push wall crush, instance of %s",debugstr[temp->obclass]);
+					}
+				 else
+					{temp->shapeoffset = 0;
+					 //tactor->flags|=FL_HBM;
+					 NewState(temp,&s_guts1);
+					 //KillActor(temp);
+					}*/
+
+		  SD_PlaySoundRTP(SD_ACTORSQUISHSND,temp->x,temp->y);
+		 }
+	 else
+       {
+       if (!ActorTryMove(temp,temp->x + temp->momentumx,temp->y + temp->momentumy,
+                         temp->z + (temp->momentumz >> 16))
+          )
+          {
+          DamageThing(temp,30);
+          if ((temp->obclass==playerobj) && (temp->hitpoints <= 0))
+             temp->target = (objtype *)pwall;
+          }
+
+       Collision(temp,(objtype*)pwall,pwall->momentumx-temp->momentumx,pwall->momentumy-temp->momentumy);
+       M_CheckPlayerKilled(temp);
+		 }
+
+
+
+	 }
+}
+
+void ActorMovement (objtype *ob)
+{int tryx,tryy,tryz,limitok,max,friction,ocl;
+
+
+
+ if ((ob->obclass == strikeguardobj) && (!(ob->flags & FL_DYING)) &&
+     (gamestate.difficulty > gd_easy)
+    )
+    {
+    AvoidPlayerMissile(ob);
+    ob->flags &= ~FL_FULLLIGHT;
+    }
+
+
+ if ((!ob->momentumx) && (!ob->momentumy) && (!ob->momentumz))
+	{if (ob->flags & FL_RIDING)
+		goto ride;
+	 else
+		return;
+	}
+
+
+ limitok = 1;
+
+ friction = ACTORFRICTION;
+ if (!(ob->flags & FL_DYING))
+    friction >>= 1;
+ ocl = ob->obclass;
+ if (ocl == playerobj)
+    {
+    playertype *pstate;
+
+    M_LINKSTATE(ob,pstate);
+    max = pstate->topspeed;
+	 friction = PLAYERFRICTION;
+	 if ((ob->temp2 == PITFALL) || (ob->temp2 == PITRISE))
+       friction >>= 4;
+    }
+
+
+ else if (/*(ob->state->think != T_Collide) &&*/ (ocl != b_robobossobj) &&
+		  (ocl != boulderobj) && (ocl !=b_darkmonkobj) && (ocl != b_darksnakeobj) &&
+		  (ocl != inertobj) && (ocl != collectorobj))
+	 max = MAXMOVE;
+
+ else
+  limitok = 0;
+
+ if (limitok)
+  {if (ocl == playerobj)
+     {int dist,scale;
+
+      dist = FindDistance(ob->momentumx,ob->momentumy);
+      if (dist > max)
+        {scale = FixedDiv2(max,dist);
+         ob->momentumx = FixedMul(ob->momentumx,scale);
+         ob->momentumy = FixedMul(ob->momentumy,scale);
+        }
+     }
+   else
+     {
+      if (ob->momentumx > max)
+        ob->momentumx = max;
+      else if (ob->momentumx < -max)
+        ob->momentumx = -max;
+      if (ob->momentumy > max)
+        ob->momentumy = max;
+      else if (ob->momentumy < -max)
+        ob->momentumy = -max;
+     }
+
+  }
+
+  tryx = ob->x + ob->momentumx;
+  tryy = ob->y + ob->momentumy;
+  tryz = ob->z + (ob->momentumz >> 16);
+
+ if (ocl != playerobj)
+	 ob->flags &= ~FL_STUCK;
+
+
+ if (!ActorTryMove (ob, tryx, tryy, tryz))
+	{if (ocl == playerobj)
+	  {if (!(ob->flags & FL_ELASTO))
+			PlayerSlideMove (ob);
+		else
+        {if (ActorTryMove(ob,tryx, ob->y-ob->momentumy,tryz))
+				ob->momentumy = -(ob->momentumy);
+         else if (ActorTryMove(ob,ob->x-ob->momentumx,tryy,tryz))
+				ob->momentumx = -(ob->momentumx);
+			else
+				ZEROMOM;
+		  }
+	  }
+
+	 else
+	  {ZEROMOM;
+		ob->flags |= FL_STUCK;
+		return;
+	  }
+	}
+
+ MoveActor(ob);
+
+
+ride:
+
+ if (ob->flags & FL_RIDING)
+    {
+    objtype *ride = (objtype*)(ob->whatever);
+
+    ob->z += (ride->momentumz >> 16);
+
+    if ((ride->momentumx || ride->momentumy) &&
+        ActorTryMove(ob,ob->x+ride->momentumx,ob->y+ride->momentumy,tryz)
+       )
+       SetFinePosition(ob,ob->x+ride->momentumx,ob->y+ride->momentumy);
+	 }
+
+
+#define SLIDER(ob)  ((ob->flags & FL_NOFRICTION) && (ob->state->think != T_Collide))
+#define AIRBORNE(ob) ((ob->obclass != playerobj) && (ob->z != nominalheight) &&\
+                      (!IsPlatform(ob->tilex,ob->tiley)) && \
+                      (DiskAt(ob->tilex,ob->tiley) == NULL) \
+                     )
+
+  if (SLIDER(ob) || AIRBORNE(ob))
+     return;
+
+  if ( (abs(ob->momentumx) < STOPSPEED) &&
+		 (abs(ob->momentumy) < STOPSPEED)
+	  )
+	  {
+	  ZEROMOM;
+	  }
+
+  else if ((ob->flags & FL_DYING) && (ob->state == ob->state->next))
+	{ob->momentumx = FixedMul (ob->momentumx, DEADFRICTION);
+	 ob->momentumy = FixedMul (ob->momentumy, DEADFRICTION);
+
+	}
+
+  else
+	{ob->momentumx = FixedMul (ob->momentumx, friction);
+	 ob->momentumy = FixedMul (ob->momentumy, friction);
+
+	}
+
+
+
+}
+
+
+
+
+void T_Guts(objtype*ob)
+{if (ob->ticcount)
+  return;
+ SpawnParticles(ob,GUTS,50);
+
+}
+
+
+void T_Special(objtype*ob)
+   {
+   if (ob->ticcount)
+      return;
+
+#if (SHAREWARE == 0)
+   if (ob->state == &s_NMEheadexplosion)
+      {
+      ob->z -= 42;
+      SetGibSpeed(0x4000);
+      SpawnParticles(ob,gt_sparks,100);
+      ResetGibSpeed();
+      SD_PlaySoundRTP(SD_EXPLODESND,ob->x,ob->y);
+      return;
+      }
+#endif
+   if (ob->obclass != b_robobossobj)
+      return;
+
+   NewState(ob,&s_bossdeath);
+   }
+
+
+
+
+void SpawnBoulder(int tilex,int tiley,int dir)
+{
+  #if (SHAREWARE == 1)
+    tilex = tilex;
+    tiley = tiley;
+    dir = dir;
+    Error("Boulders aren't allowed in shareware!");
+  #endif
+#if (SHAREWARE == 0)
+  SpawnNewObj(tilex,tiley,&s_boulderspawn,inertobj);
+  new->z = 0;
+  PreCacheActor(boulderobj,0);
+  new->dir = 2*dir;
+#endif
+
+}
+
+
+
+#define InitSprayPart(newflags)                                          \
+   {                                                                     \
+   new->hitpoints = starthitpoints[gamestate.difficulty][b_robobossobj]; \
+   new->dir = dir*4;                                                     \
+   new->speed = 7*SPDPATROL;                                             \
+   new->door_to_open = -1;                                               \
+   new->flags |= (newflags);                                             \
+   }                                                                     \
+
+
+void SpawnMultiSpriteActor(classtype actorclass, int tilex,int tiley,int dir)
+{
+
+
+
+#if (SHAREWARE==1)
+
+      actorclass = actorclass;
+      tilex = tilex;
+      tiley = tiley;
+      dir  = dir;
+      Error("\nSPRAY not allowed in shareware !");
+
+#else
+
+   {
+   objtype *temp;
+
+   gamestate.killtotal++;
+
+   SpawnNewObj(tilex,tiley,&s_NMEstand,actorclass);
+   InitSprayPart(FL_BLOCK|FL_NOFRICTION|FL_SHOOTABLE);
+
+   new->temp1 = -1; // temp1 used as one-event queue for directions when chasing
+						  // -1 when isn't waiting to try new dir, dirnumber when waiting
+	temp = new;
+
+   SpawnNewObj(tilex,tiley,&s_NMEhead1,actorclass);
+   InitSprayPart(FL_NOFRICTION|FL_SHOOTABLE|FL_HEAD|FL_NEVERMARK);
+
+	//new->whatever = temp;  // head points to body
+
+	temp->whatever = new;  // body points to head
+
+   SpawnNewObj(tilex,tiley,&s_NMEwheels2,actorclass);
+   InitSprayPart(FL_NOFRICTION|FL_SHOOTABLE|FL_HEAD|FL_NEVERMARK);
+
+
+	//new->whatever = temp;  // head points to body
+	temp->target = new;     // body also points to wheels
+	actorat[tilex][tiley] = NULL;
+   PreCacheActor(b_robobossobj,0);
+   }
+#endif
+}
+
+
+void SpawnSnake(int tilex,int tiley)
+{
+
+#if (SHAREWARE == 1)
+   tilex = tilex;
+   tiley = tiley;
+   Error("snake not allowed in shareware!");
+#else
+
+   GetNewActor();
+	MakeActive(new);
+	new->flags |= (FL_DONE|FL_ABP|FL_NEVERMARK);
+   SetTilePosition(new,tilex,tiley);
+   SetVisiblePosition(new,new->x,new->y);
+	new->obclass = b_darkmonkobj;
+	new->which = ACTOR;
+	new->z = nominalheight;
+	if (SNAKELEVEL == 2)
+	 NewState(new,&s_darkmonkfastspawn);
+	else
+	 NewState(new,&s_darkmonkhspawn);
+#endif
+
+}
+
+void SpawnGunThingy(classtype which, int tilex, int tiley, int dir)
+   {
+#if (SHAREWARE == 1)
+   which = which;
+   tilex = tilex;
+   tiley = tiley;
+   dir  = dir;
+
+   Error("no emplacements allowed in shareware!");
+#else
+   SpawnNewObj(tilex,tiley,&s_gunstand,which);
+
+
+   if (!loadedgame)
+      gamestate.killtotal++;
+
+   PreCacheActor(patrolgunobj,0);
+
+   new->hitpoints = starthitpoints[gamestate.difficulty][which];
+   new->dir = dir*2;
+//  new->speed = 0x500;
+//  ParseMomentum(new,dirangle8[new->dir]);
+   new->flags |= (FL_BLOCK|FL_SHOOTABLE);
+#endif
+}
+
+
+void SpawnFourWayGun(int tilex, int tiley)
+{
+#if (SHAREWARE == 1)
+   tilex = tilex;
+   tiley = tiley;
+   Error("no 4-way emplacements allowed in shareware!");
+#else
+
+
+  SpawnNewObj(tilex,tiley,&s_4waygun,patrolgunobj);
+  if (!loadedgame)
+	  gamestate.killtotal++;
+
+  PreCacheActor(patrolgunobj,0);
+  new->temp1 = -1;
+  new->hitpoints = starthitpoints[gamestate.difficulty][patrolgunobj]*3;
+  new->flags |= (FL_BLOCK|FL_SHOOTABLE);
+#endif
+}
+
+
+
+
+/*
+=======================================================================
+=
+=                          NON-SHAREWARE CODE
+=
+=======================================================================
+*/
+
+#if (SHAREWARE == 0)
+
+void T_BoulderSpawn(objtype*ob)
+{objtype *tactor;
+ int dx,dy,cl;
+
+ if (!(ob->flags & FL_ACTIVE))
+  return;
+
+ else if (!ob->ticcount)
+  {for(tactor = firstareaactor[ob->areanumber];tactor;tactor = tactor->nextinarea)
+	 {cl = tactor->obclass;
+	  if (tactor == ob)
+		continue;
+
+	  if (!(tactor->flags & FL_SHOOTABLE))
+		continue;
+	  dx = abs(tactor->x - ob->x);
+	  if (dx > MINACTORDIST)
+		continue;
+	  dy = abs(tactor->y - ob->y);
+	  if (dy > MINACTORDIST)
+		continue;
+	  if ((cl == b_heinrichobj) || (cl== b_darkmonkobj) ||
+			(cl == b_darianobj) || (cl == b_robobossobj) ||
+			(cl == pillarobj) || (cl == wallopobj) ||
+			(cl == boulderobj))
+		 return;
+	  else break;
+	 }
+
+
+	SpawnNewObj(ob->tilex,ob->tiley,&s_boulderdrop1,boulderobj);
+	new->z = 0;
+	new->dir = ob->dir;
+	//new->angle = dirangle8[new->dir];
+	new->speed = 0x4000;
+	ParseMomentum(new,dirangle8[new->dir]);
+	new->flags |= (FL_BLOCK|FL_NOFRICTION);
+	new->flags &= ~FL_SHOOTABLE;
+	new->whatever = ob;
+	if (tactor)
+	 new->target = tactor;
+	MakeActive(new);
+	new->flags |= FL_ABP;
+
+  }
+
+}
+
+void T_BoulderDrop(objtype*ob)
+{int dx,dy,dz;
+ objtype * tactor;
+ statetype *tstate;
+
+
+ if (ob->state == &s_boulderdrop12)
+  {
+
+	if (ob->z == nominalheight)
+	 NewState(ob,&s_boulderroll1);
+	else if (ob->momentumz)
+	 {ob->z += (ob->momentumz>>16);
+	  ob->momentumz += (GRAVITY<<1);
+	  if (ob->z > nominalheight)
+		 {ob->z = nominalheight;
+		  ob->momentumz = 0;
+		  //ob->flags &= ~FL_NOFRICTION;
+		 }
+	 }
+	else if (!ob->temp1)
+	 {ob->momentumz = (GRAVITY<<6);
+	  ob->temp1  = 1;
+	 }
+
+  }
+
+ if (ob->ticcount)
+  return;
+ if (ob->state->condition & SF_SOUND)
+
+  SD_PlaySoundRTP(SD_BOULDERFALLSND,ob->x,ob->y);
+ tactor = (objtype*)(ob->target);
+ if (tactor && (!(tactor->flags & FL_DYING)))
+  {dx = tactor->x - ob->x;
+	dy = tactor->y - ob->y;
+	dz = tactor->z - ob->z;
+	if ((abs(dx) < MINACTORDIST) && (abs(dy) < MINACTORDIST) &&
+		 (abs(dz) < 50))
+	  {if (tactor->obclass != playerobj)
+		  {tactor->momentumx = tactor->momentumy = tactor->momentumz = 0;
+			tactor->flags |= FL_DYING;
+			tactor->hitpoints = 0;
+			if (gamestate.violence < vl_high)
+			  {if ((tstate = UPDATE_STATES[CRUSH][tactor->obclass - lowguardobj])!=NULL)
+				  NewState(tactor,tstate);
+
+            //else
+              //Error("\n\Null low-violence crush state in boulder drop, instance of %s",debugstr[tactor->obclass]);
+			  }
+			else
+			 {tactor->shapeoffset = 0;
+			  //tactor->flags|=FL_HBM;
+			  NewState(tactor,&s_guts1);
+			 }
+		  }
+		else
+		  {DamageThing(tactor,200);
+         Collision(tactor,ob,0,0);
+			M_CheckPlayerKilled(tactor);
+		  }
+		SD_PlaySoundRTP(SD_ACTORSQUISHSND,tactor->x,tactor->y);
+		ob->target = NULL;
+	  }
+
+  }
+}
+
+
+void CheckCrush(objtype*ob)
+{
+ objtype *temp;
+ int dx,dy,dz;
+
+ for(temp = PLAYER[0];temp != PLAYER[numplayers-1]->next;temp=temp->next)
+	{
+     if (ob->flags & FL_DYING)
+       continue;
+
+     dx = abs(temp->x - ob->x);
+	  if (dx > MINACTORDIST)
+		 continue;
+
+     dy = abs(temp->y - ob->y);
+	  if (dy > MINACTORDIST)
+		 continue;
+
+     dz = abs(temp->z - ob->z);
+	  if (dz > (MINACTORDIST>>10))
+		 continue;
+
+	  if (!ob->ticcount)
+			DamageThing(temp,EnvironmentDamage(ob));
+     Collision(temp,ob,ob->momentumx-temp->momentumx,ob->momentumy-temp->momentumy);
+	  M_CheckPlayerKilled(temp);
+	}
+}
+
+
+void T_BoulderMove(objtype*ob)
+{
+
+
+ if (MAPSPOT(ob->tilex,ob->tiley,1) == 395)
+  {NewState(ob,&s_bouldersink1);
+	return;
+  }
+ if (NOMOM)
+  ParseMomentum(ob,dirangle8[ob->dir]);
+ if ((!ob->ticcount) && (ob->state->condition & SF_SOUND) &&
+	  areabyplayer[ob->areanumber])
+  SD_PlaySoundRTP(BAS[ob->obclass].operate,ob->x,ob->y);
+ SelectPathDir(ob);
+
+}
+
+
+/*
+=========================================================================
+=
+=                           Boss Functions
+=
+=========================================================================
+*/
+
+//***************************** Esau ************************************
+
+
+enum {
+  ESAU_USING_HOLES=1,
+  ESAU_LEAVING_CONTROL_ROOM,
+  ESAU_USING_TOUCH_PEDASTALS,
+  ESAU_CHASING_PLAYER
+  };
+
+
+
+
+void T_EsauWait(objtype*ob)
+   {
+   int dist;
+
+   dist = FindDistance(ob->tilex-PLAYER[0]->tilex,ob->tiley-PLAYER[0]->tiley);
+   MISCVARS->ESAU_SHOOTING = false;
+
+   if (ob->dirchoosetime)
+      ob->dirchoosetime --;
+
+   if ((dist>81) || (dist<36))
+      {
+      if (CheckLine(ob,PLAYER[0],MISSILE))
+         {
+         NewState(ob,&s_darianshoot1);
+         ob->momentumx = ob->momentumy = 0;
+         }
+      return;
+      }
+   else if ((!ob->dirchoosetime) && (CheckLine(ob,PLAYER[0],SHOOT)))
+      {
+      NewState(ob,&s_dariandefend1);
+      ob->dirchoosetime = (GameRandomNumber("T_EsauWait",0) % 35) + 17;//35;
+      return;
+      }
+   }
+
+
+void T_EsauRise(objtype*ob)
+   {
+   int newarea,oldarea;
+
+   // if (gamestate.victoryflag)
+   // return;
+
+   if (!ob->ticcount)
+      {//Debug("\n tx before: %d, ty before: %d",
+         //         ob->targettilex,ob->targettiley);
+
+      SelectTouchDir(ob);
+      if (ob->targettilex || ob->targettiley)
+         {//Debug("\n ob->tilex: %d, ob->tiley: %d, targettilex: %d, targettiley: %d",
+            //         ob->tilex, ob->tiley, ob->targettilex, ob->targettiley);
+
+         SetTilePosition(ob,ob->targettilex,ob->targettiley);
+         SetVisiblePosition(ob,ob->x,ob->y);
+         oldarea = ob->areanumber;
+         newarea = AREANUMBER(ob->tilex,ob->tiley);
+         if (oldarea != newarea)
+            {
+            RemoveFromArea(ob);
+            ob->areanumber = newarea;
+            MakeLastInArea(ob);
+            }
+         }
+      else
+         MISCVARS->EPOP[ob->temp3].x = MISCVARS->EPOP[ob->temp3].y = 0;
+
+      ob->dirchoosetime= (GameRandomNumber("T_EsauRise",0) % 35) + 17;
+      MISCVARS->ESAU_HIDING = false;
+      MISCVARS->ESAU_SHOOTING = true;
+      ob->flags |= FL_SHOOTABLE;
+      }
+   }
+
+
+
+void T_EsauChase(objtype*ob)
+   {
+   int dx,dy,chance,dist;
+   statetype *temp;
+
+
+
+   if ((ob->tilex == ob->targettilex) && (ob->tiley == ob->targettiley))
+      {
+      if (MISCVARS->DSTATE == ESAU_USING_HOLES)
+         {
+         MISCVARS->ESAU_HIDING = true;
+         MISCVARS->ESAU_SHOOTING = false;
+         SD_PlaySoundRTP(SD_DARIANHIDESND,ob->x,ob->y);
+         NewState(ob,&s_dariansink1);
+         ob->flags &= ~FL_SHOOTABLE;
+         return;
+         }
+      else if (MISCVARS->DSTATE == ESAU_LEAVING_CONTROL_ROOM)
+         {
+         if (!MISCVARS->doorcount)
+            {
+            SetTilePosition(ob,ob->tilex,ob->tiley);
+            SetVisiblePosition(ob,ob->x,ob->y);
+            }
+         MISCVARS->doorcount ++;
+         if (MISCVARS->doorcount == 4)
+            MISCVARS->DSTATE = ESAU_USING_HOLES;
+         else // hack to FORCE esau to walk through door
+            {
+            switch (ob->temp1)
+               {
+               case east:
+                  ob->targettilex ++;
+                  break;
+               case west:
+                  ob->targettilex --;
+                  break;
+               case north:
+                  ob->targettiley --;
+                  break;
+               case south:
+                  ob->targettiley ++;
+                  break;
+               }
+            }
+         SelectTouchDir(ob);
+         return;
+         }
+      }
+
+   if (touchsprite && (touchsprite->itemnumber == stats[stat_dariantouch].type))
+      {
+      dx = touchsprite->x - ob->x;
+      dy = touchsprite->y - ob->y;
+
+      if (((dx > -0x5000) && (dx < 0x5000)) &&
+          ((dy > -0x5000) && (dy < 0x5000)))
+         {
+         SD_PlaySoundRTP(SD_DARIANGONNAUSESND,ob->x,ob->y);
+         NewState(ob,&s_darianuse1);
+         return;
+         }
+      }
+
+   if (ob->dirchoosetime)
+      ob->dirchoosetime --;
+
+   if (NOMOM || (!ob->dirchoosetime))
+      {
+      SelectTouchDir(ob);
+      ob->dirchoosetime = M_CHOOSETIME(ob);
+      }
+   else
+      ActorMovement(ob);
+
+
+   if (!ob->ticcount)
+      {
+      if (CheckLine(ob,PLAYER[0],MISSILE))   // got a shot at player?
+         {
+         if (Near(ob,PLAYER[0],1))
+            chance = 300;
+         else
+            {
+            dx = abs(PLAYER[0]->tilex-ob->tilex);
+            dy = abs(PLAYER[0]->tiley-ob->tiley);
+            dist = (dx>dy)?dx:dy;
+            chance = 400/dist;
+            }
+         if (GameRandomNumber("T_EsauChase",0) <chance)
+            {
+            if ((temp=M_S(AIM)) != NULL)
+               {
+               NewState(ob,temp);
+               ob->dirchoosetime = 0;
+               ob->momentumx = ob->momentumy = 0;
+               SetVisiblePosition(ob,ob->x,ob->y);
+               return;
+               }
+            }
+         if (MISCVARS->ESAU_SHOOTING)
+            {
+            SetVisiblePosition(ob,ob->x,ob->y);
+            return;
+            }
+         }
+      }
+   }
+
+
+void T_EsauSpears(objtype*ob)
+   {
+
+   if (ob->ticcount == (ob->state->tictime>>1)-1)
+      {
+      OLDTILEX = PLAYER[0]->tilex;
+      OLDTILEY = PLAYER[0]->tiley;
+      }
+
+   else if (!ob->ticcount)
+      {
+      SpawnNewObj(OLDTILEX,OLDTILEY,&s_speardown1,spearobj);
+      new->flags |= FL_ABP;
+      MakeActive(new);
+      }
+   }
+
+
+
+void FindDoor(objtype*ob)
+   {
+   int i,area1,area2,min,curr,
+       dest1x,dest1y,dest2x,dest2y,
+       d1,d2;
+
+   dirtype tdir1,tdir2;
+   doorobj_t*dr;
+
+   min = 0x7fffffff;
+   for(i=0;i<doornum;i++)
+      {
+      dr = doorobjlist[i];
+      if (dr->vertical)
+         {
+         area1 = MAPSPOT(dr->tilex-1,dr->tiley,0)-AREATILE;
+         dest1x = dr->tilex-1;
+         dest1y = dr->tiley;
+         tdir1 = east;
+         area2 = MAPSPOT(dr->tilex+1,dr->tiley,0)-AREATILE;
+         dest2x = dr->tilex+1;
+         dest2y = dr->tiley;
+         tdir2 = west;
+         }
+      else
+         {
+         area1 = MAPSPOT(dr->tilex,dr->tiley-1,0)-AREATILE;
+         dest1x = dr->tilex;
+         dest1y = dr->tiley-1;
+         tdir1 = south;
+         area2 = MAPSPOT(dr->tilex,dr->tiley+1,0)-AREATILE;
+         dest2x = dr->tilex;
+         dest2y = dr->tiley+1;
+         tdir2 = north;
+         }
+
+//============================================================
+#define CheckMinDist(destx,desty,dir)                    \
+   {                                                     \
+   curr = FindDistance(destx-ob->tilex,desty-ob->tiley); \
+   if (curr < min)                                       \
+      {                                                  \
+      min = curr;                                        \
+      ob->targettilex = destx;                           \
+      ob->targettiley = desty;                           \
+      ob->temp1 = dir;                                   \
+      }                                                  \
+   }
+//============================================================
+
+      if (area1 == ob->areanumber)
+         {
+         if (area1 == area2)
+            {
+            d1 = FindDistance(dest1x-ob->tilex,dest1y-ob->tiley);
+            d2 = FindDistance(dest2x-ob->tilex,dest2y-ob->tiley);
+            if (d2 < d1) //swap areas
+               {
+               CheckMinDist(dest2x,dest2y,tdir2);
+               continue;
+               }
+            }
+
+         CheckMinDist(dest1x,dest1y,tdir1);
+
+         }
+      else if (area2 == ob->areanumber)
+         CheckMinDist(dest2x,dest2y,tdir2);
+
+      }
+   }
+
+
+int FindTouch(objtype *ob)
+   {
+   int i,curr,min,tx,ty,noneleft;
+   statobj_t* tempstat;
+
+
+   min = 0x7fffffff;
+   noneleft = 1;
+   for(i=0;i<MISCVARS->nexttouch;i++)
+      {
+      if (MISCVARS->ETOUCH[i].x || MISCVARS->ETOUCH[i].y)
+         {
+         noneleft = 0;
+         tx = MISCVARS->ETOUCH[i].x;
+         ty = MISCVARS->ETOUCH[i].y;
+         tempstat = sprites[tx][ty];
+         curr = FindDistance(tx-ob->tilex,ty-ob->tiley);
+
+         if (curr < min)
+            {
+            min = curr;
+            ob->targettilex = tx;
+            ob->targettiley = ty;
+            touchsprite = tempstat;
+            }
+         }
+      }
+   return (!noneleft);
+   }
+
+
+
+
+typedef enum
+   {
+   down_in_a_hole=-1,
+   no_holes_available=0,
+   holes_unreachable=1,
+   hole_targetted=2
+
+   }hiding_status;
+
+
+
+hiding_status HoleStatus(objtype*ob)
+   {
+   int i,tx,ty,dist,noneleft,invisible,curr,min;
+   tpoint dummy,*dptr = &dummy;
+   objtype *tactor;
+   _2Dpoint *tdptr;
+
+   min = 0x7fffffff;
+   noneleft = 1;
+
+
+
+   for(i=0;i<MISCVARS->nextpop;i++)
+      {
+      tdptr = &(MISCVARS->EPOP[i]);
+
+      if (tdptr->x || tdptr->y)
+         {
+         tactor = (objtype*)actorat[tdptr->x][tdptr->y];
+         if (tactor && (tactor->obclass == pillarobj))
+            {
+            tdptr->x = 0;
+            tdptr->y = 0;
+            MISCVARS->popsleft --;
+            }
+         }
+      }
+
+
+   if (MISCVARS->popsleft > 1)
+      {
+      for(i=0;i<MISCVARS->nextpop;i++)
+         {
+         tdptr = &(MISCVARS->EPOP[i]);
+
+         if (tdptr->x || tdptr->y)
+            {
+            tx = tdptr->x;
+            ty = tdptr->y;
+
+            if ((PLAYER[0]->tilex == tx) || (PLAYER[0]->tiley == ty))
+               continue;
+
+            if (MISCVARS->ESAU_HIDING)
+               {
+               dist = FindDistance(PLAYER[0]->tilex-tx,PLAYER[0]->tiley-ty);
+               if ((ob->tilex == tx) && (ob->tiley == ty) && (MISCVARS->popsleft != 1))
+                  continue;
+               noneleft = 0;
+               if ((MAPSPOT(tx,ty,0)-AREATILE) == ob->areanumber)
+                  {
+                  ob->targettilex = tx;
+                  ob->targettiley = ty;
+                  ob->temp3 = i;
+                  if ((dist < 81) && (dist > 36))
+                     return down_in_a_hole;
+                  }
+               }
+
+            else if (!MISCVARS->ESAU_SHOOTING)
+               {
+               curr = FindDistance(tx-ob->tilex,ty-ob->tiley);
+               if (curr < min)
+                  {
+                  min = curr;
+                  noneleft = 0;
+                  dptr->which = ACTOR;
+                  SetTilePosition(dptr,tx,ty);
+                  //dptr->x = (tx << TILESHIFT) + TILEGLOBAL/2;
+                  //dptr->y = (ty << TILESHIFT) + TILEGLOBAL/2;
+                  dptr->z = ob->z;
+                  invisible = 0;
+                  if ((!CheckLine(ob,dptr,SHOOT)) && (MISCVARS->DSTATE != ESAU_USING_HOLES))
+                     {
+                     invisible = 1;
+                     MISCVARS->DSTATE = ESAU_LEAVING_CONTROL_ROOM;
+                     }
+                  else
+                     MISCVARS->DSTATE = ESAU_USING_HOLES;
+                  ob->targettilex = tx;
+                  ob->targettiley = ty;
+                  }
+               }
+            }
+         }
+      }
+
+   if (MISCVARS->ESAU_HIDING)
+      return down_in_a_hole;
+
+   if (noneleft)
+      {
+      MISCVARS->DSTATE = ESAU_CHASING_PLAYER;
+      return  no_holes_available;
+      }
+
+   if (invisible) //leave present room
+      return holes_unreachable;
+
+   return hole_targetted;
+   }
+
+
+void SelectTouchDir (objtype *ob)
+   {
+   int dx,dy,noneleft,invisible;
+   hiding_status hole;
+
+
+   dirtype d[3];
+   dirtype tdir, olddir, turnaround;
+
+
+   olddir=ob->dir;
+   turnaround= opposite[olddir];
+
+
+   invisible = 0;
+   noneleft = 1;
+
+   if (!MISCVARS->notouch)
+      {
+      if (!FindTouch(ob))
+         MISCVARS->notouch = 1;
+      else
+         MISCVARS->DSTATE = ESAU_USING_TOUCH_PEDASTALS;
+      }
+
+   else if ((!MISCVARS->noholes) && (MISCVARS->DSTATE != ESAU_LEAVING_CONTROL_ROOM))
+      {
+      hole = HoleStatus(ob);
+
+      switch(hole)
+         {
+         case down_in_a_hole:
+            return;
+
+         case no_holes_available:
+            MISCVARS->noholes = 1;
+            break;
+
+         case holes_unreachable:
+            FindDoor(ob);
+            break;
+            
+         default:
+            break;
+         }
+      }
+
+   else if (MISCVARS->DSTATE == ESAU_CHASING_PLAYER)
+
+   // only gets here if all gimmicks (touch tables,
+                  // holes) are inoperative
+      {
+      ob->flags |= FL_SHOOTABLE;
+      ob->targettilex = PLAYER[0]->tilex;
+      ob->targettiley = PLAYER[0]->tiley;
+      }
+   /*
+   if (DSTATE == SDOOR)
+   {dx = ((ob->targettilex<<16)+TILEGLOBAL/2) - ob->x;
+      dy = ob->y - ((ob->targettiley<<16)+TILEGLOBAL/2);
+      angle = atan2_appx(dx,dy);
+      ZEROMOM;
+      ParseMomentum(ob,angle);
+      ActorMovement(ob);
+      if (ob->momentumx || ob->momentumy)
+      {ob->angle = angle;
+      ob->dir = angletodir[ob->angle];
+      return;
+      }
+   }
+   else */
+   dx = ob->targettilex - ob->tilex;
+   dy = ob->tiley - ob->targettiley;
+
+
+
+
+   d[1]=nodir;
+   d[2]=nodir;
+
+
+   if (dx>0)
+      d[1]= east;
+   else if (dx<0)
+      d[1]= west;
+   if (dy>0)
+      d[2]=north;
+   else if (dy<0)
+      d[2]=south;
+
+
+   if (GameRandomNumber("SelectTouchDir",0)<128)
+      {
+      tdir=d[1];
+      d[1]=d[2];
+      d[2]=tdir;
+      }
+
+   ZEROMOM;
+
+
+   if (d[1]!=nodir)
+      M_CHECKDIR(ob,d[1]);
+
+
+   if (d[2]!=nodir)
+      M_CHECKDIR(ob,d[2]);
+
+
+
+   if (GameRandomNumber("SelectTouchDir",ob->obclass)>128)   //randomly determine direction of search
+      {
+      for (tdir=north;tdir<=west;tdir++)
+         {
+         if (tdir!=turnaround)
+            M_CHECKDIR(ob,tdir);
+         }
+      }
+   else
+      {
+      for (tdir=west;tdir>=north;tdir--)
+         {
+         if (tdir!=turnaround)
+            M_CHECKDIR(ob,tdir);
+         }
+      }
+
+   if (turnaround !=  nodir)
+      M_CHECKDIR(ob,turnaround);
+
+
+   if (olddir!=nodir)
+      M_CHECKDIR(ob,olddir);
+
+   }
+
+
+
+
+//************** Krist ****************************************************
+
+
+
+void CheckRunover(objtype*ob)
+{int dx,dy,dz;
+
+ dx = abs(PLAYER[0]->x - ob->x);
+ if (dx > MINACTORDIST)
+	return;
+
+ dy = abs(PLAYER[0]->y - ob->y);
+ if (dy > MINACTORDIST)
+	return;
+
+ dz = abs(PLAYER[0]->z - ob->z);
+ if (dz > 10)
+	return;
+
+ locplayerstate->heightoffset = 18 + locplayerstate->playerheight;
+ locplayerstate->oldheightoffset = locplayerstate->heightoffset;
+ PLAYER[0]->temp2 = RENORMALIZE;
+ DamageThing(PLAYER[0],30);
+ Collision(PLAYER[0],ob,0,0);
+ M_CheckPlayerKilled(PLAYER[0]);
+
+}
+
+
+void T_HeinrichChase(objtype*ob)
+{
+ int   dx,dy,dist,chance,perpangle;
+// statetype *temp;
+ boolean doorok;
+
+ CheckRunover(ob);
+
+  //	ob->flags &= ~FL_DODGE;
+	if (CheckLine(ob,PLAYER[0],SIGHT))
+		{ob->targettilex = PLAYER[0]->x;
+		 ob->targettiley = PLAYER[0]->y;
+		}
+
+	if (!ob->ticcount)
+	 {
+
+//	  if (gamestate.victoryflag)
+//		return;
+
+
+	  if (CheckLine(ob,PLAYER[0],SHOOT))   // got a shot at PLAYER[0]?
+		 {dx = abs(ob->tilex - PLAYER[0]->tilex);
+		  dy = abs(ob->tiley - PLAYER[0]->tiley);
+		  dist = dx>dy ? dx : dy;
+		  if (!dist || dist==1)
+				chance = 300;
+		  else
+           chance = 2400/dist;
+
+		  if (GameRandomNumber("T_HeinrichChase",0) <chance)
+          {tpoint dummy,*dptr=&dummy;
+
+           if (Near(ob,PLAYER[0],2))
+				 goto cdoor;
+
+
+			  perpangle = AngleBetween(ob,PLAYER[0]) + ANGLES/4;
+			  Fix(perpangle);
+           dptr->which = ACTOR;
+           dptr->x = ob->x + FixedMul(0x10000l,costable[perpangle]);
+           dptr->y = ob->y - FixedMul(0x10000l,sintable[perpangle]);
+
+           dptr->z = ob->z;
+           if (!CheckLine(dptr,PLAYER[0],SHOOT))
+				  goto cdoor;
+
+			  ob->target = PLAYER[0];
+			  NewState(ob,M_S(AIM));
+			  ob->dirchoosetime = 0;
+			  return;
+
+
+			 }
+		 }
+
+	 }
+
+cdoor:
+	doorok = NextToDoor(ob);
+
+
+	if (ob->dirchoosetime)
+	 ob->dirchoosetime--;
+
+	if ((ob->flags & FL_STUCK) || (!ob->dirchoosetime) || doorok)
+	  {/*if ((ob->flags & FL_DODGE) && (!doorok))
+		 SelectKristDodgeDir (ob);
+		else */
+		 SD_PlaySoundRTP(SD_KRISTMOTORSND,ob->x,ob->y);
+		 SelectKristChaseDir(ob);
+
+      ob->dirchoosetime = 4*M_CHOOSETIME(ob);
+
+	  }
+
+	else
+	 {if (NOMOM)
+		ParseMomentum(ob,dirangle8[ob->dir]);
+	  ActorMovement(ob);
+
+	 }
+
+}
+
+void T_Heinrich_Defend (objtype*ob)
+{
+  CheckRunover(ob);
+
+  if (ob->dirchoosetime)
+	ob->dirchoosetime--;
+
+
+  if (MISCVARS->HRAMMING)
+	ParseMomentum(ob,dirangle8[ob->dir]);
+
+
+  if ((ob->flags & FL_STUCK) || (!ob->dirchoosetime))
+	 {if (MISCVARS->HRAMMING)
+		 {if (!Near(ob,PLAYER[0],3))
+			{NewState(ob,M_S(CHASE));
+			 ob->dirchoosetime = 0;
+			 return;
+			}
+		  SelectKristChaseDir(ob);
+		 }
+	  else if (MISCVARS->HMINING)
+		 {SelectMineDir(ob);
+		  if (!MISCVARS->HMINING)
+			 goto hchase;
+		  ob->dirchoosetime = 5;//10;
+		  return;
+		 }
+	  else
+  hchase:
+		 NewState(ob,M_S(CHASE));
+		 ob->dirchoosetime = 0;
+	 }
+  else
+	{if (NOMOM)
+	  ParseMomentum(ob,dirangle8[ob->dir]);
+	 ActorMovement(ob);
+	}
+}
+
+
+void T_Heinrich_Out_of_Control(objtype*ob)
+{
+   if (ob->dirchoosetime)
+      ob->dirchoosetime --;
+   else
+      {
+      if (!ob->temp1)
+         {
+         SetGibSpeed(0x4000);
+         SpawnParticles(ob,RANDOM,120);
+         ResetGibSpeed();
+
+         NewState(ob,&s_dexplosion1);
+         SD_PlaySoundRTP(SD_EXPLODESND,ob->x,ob->y);
+         }
+      else
+         {
+         ob->dir = dirorder[ob->dir][PREV];
+         ob->angle = dirangle8[ob->dir];
+         if (ob->dir == (unsigned)ob->temp2)
+            {
+            if (ob->temp1 > 1)
+               ob->temp1--;
+            else
+               {
+               if (ob->temp3 == 7)
+                  {
+                  SpawnNewObj(ob->tilex,ob->tiley,&s_megaexplosions,inertobj);
+                  new->temp1 = 25;
+                  new->flags |= FL_ABP;
+                  MakeActive(new);
+                  SpawnNewObj(ob->tilex,ob->tiley,&s_superparticles,inertobj);
+                  new->flags |= FL_ABP;
+                  PARTICLE_GENERATOR = new;
+                  MakeActive(new);
+                  }
+               if (ob->temp3)
+                  ob->temp3 --;
+               else
+                  ob->temp1 --;
+               }
+            }
+
+         if (ob->temp1)
+            ob->dirchoosetime = ob->temp1;
+         else
+            {
+            ob->dirchoosetime = 70; // end of spin wait for megaexplosion
+            if (PARTICLE_GENERATOR)
+               {
+               NewState(PARTICLE_GENERATOR,&s_megaremove);
+               PARTICLE_GENERATOR = NULL;
+               }
+            }
+         }
+      }
+   }
+
+
+
+
+void SelectKristChaseDir(objtype*ob)
+{int dx,dy,tx,ty,angle;
+ dirtype dtry1,dtry2,tdir,olddir,next,prev,straight;
+ //tpoint dummy,*dptr=&dummy;
+
+ olddir=ob->dir;
+
+
+ //dptr->which = ACTOR;
+ //dptr->z = ob->z;
+ if (ob->targettilex || ob->targettiley)
+	{tx = ob->targettilex;
+	 ty = ob->targettiley;
+	 dx= tx - ob->x;
+	 dy= ob->y - ty;
+   // SetFinePosition(dptr,tx,ty);
+	 if ( ((dx < 0x20000) && (dx > -0x20000)) &&
+			((dy < 0x20000) && (dy > -0x20000)))
+      {
+      dx= PLAYER[0]->x-ob->x;
+      dy= ob->y-PLAYER[0]->y;
+     // SetFinePosition(dptr,PLAYER[0]->x,PLAYER[0]->y);
+      }
+	}
+ else
+    {
+    dx= PLAYER[0]->x-ob->x;
+    dy= ob->y-PLAYER[0]->y;
+    //SetFinePosition(dptr,PLAYER[0]->x,PLAYER[0]->y);
+
+	 }
+
+ angle = atan2_appx(dx,dy);
+ straight = angletodir[angle];
+ /*
+ if (ob->areanumber == PLAYER[0]->areanumber)
+	  {//tpoint newpos1,newpos2;
+		//dirtype leftdir;
+		//int leftangle1,leftangle2;
+
+		if (CheckLine(ob,&dummy,DIRCHECK))
+		  {//Debug("\ntrying straight dir %d",straight);
+			M_CHECKTURN(ob,straight);
+			//Debug("\nstraight dir %d failed",straight);
+		  }
+		//leftdir = dirorder[straight][PREV];
+		//leftangle1 = dirangle8[leftdir];
+		//newpos1.which = ACTOR;
+		//rightangle = dirangle[dirorder[straight][NEXT]];
+		//newpos1.x = ob->x + FixedMul(0x10000,costable[leftangle1]);
+		//newpos1.y = ob->y - FixedMul(0x10000,sintable[leftangle1]);
+		//newpos1.z = ob->z;
+
+		//leftangle2 = dirangle8[dirorder[leftdir][PREV]];
+		//newpos2.which = ACTOR;
+		//rightangle = dirangle[dirorder[straight][NEXT]];
+		//newpos2.x = ob->x + FixedMul(0x10000,costable[leftangle2]);
+		//newpos2.y = ob->y - FixedMul(0x10000,sintable[leftangle2]);
+		//newpos2.z = ob->z;
+		//if (CheckLine(&newpos1,&dummy,SHOOT))// || CheckLine(&newpos2,&dummy,SHOOT))
+			{for(tdir = dirorder[straight][PREV];tdir != dirorder[straight][NEXT];tdir = dirorder[tdir][PREV])
+				{//Debug("\ntried left-hand rule dir %d",tdir);
+				 M_CHECKTURN(ob,tdir);
+				}
+			}
+		//else
+		  //{for(tdir = dirorder[straight][NEXT];tdir != dirorder[straight][PREV];tdir = dirorder[tdir][NEXT])
+			 // {//Debug("\ntrying right-hand rule dir %d",tdir);
+			 //	M_CHECKTURN(ob,tdir);
+				//Debug("\nright-hand rule dir %d failed\n",tdir);
+		  //	  }
+		 // }
+	  }
+ else*/
+	 {dtry1=nodir;
+	  dtry2=nodir;
+
+	  if (dx> ACTORSIZE)
+		  dtry1= east;
+	  else if (dx< -ACTORSIZE)
+		  dtry1= west;
+	  if (dy> ACTORSIZE)
+		  dtry2=north;
+	  else if (dy < -ACTORSIZE)
+		  dtry2= south;
+
+
+	  if (abs(dy)>abs(dx))
+		 {tdir=dtry1;
+		  dtry1=dtry2;
+		  dtry2=tdir;
+		 }
+
+	  //	ZEROMOM;
+	  ob->momentumx = FixedMul (ob->momentumx, DEADFRICTION>>gamestate.difficulty);
+	  ob->momentumy = FixedMul (ob->momentumy, DEADFRICTION>>gamestate.difficulty);
+
+
+	  M_CHECKTURN(ob,straight);
+
+	  if (dtry1 != nodir)
+		  M_CHECKTURN(ob,dtry1);
+
+	  if (dtry2 != nodir)
+		  M_CHECKTURN(ob,dtry2);
+
+	  if (dtry1 != nodir)
+		  {M_CHECKTURN(ob,dirorder[dtry1][NEXT]);
+			M_CHECKTURN(ob,dirorder[dtry1][PREV]);
+		  }
+
+	  for(tdir = dirorder[olddir][NEXT];tdir != olddir;tdir = dirorder[tdir][NEXT])
+		  M_CHECKTURN(ob,tdir);
+
+	  ob->dir = olddir;
+	 }
+
+
+
+}
+
+
+
+void T_KristLeft(objtype*ob)
+{CheckRunover(ob);
+ ActorMovement(ob);
+ if (!ob->ticcount)
+  {SD_PlaySoundRTP(SD_KRISTTURNSND,ob->x,ob->y);
+	if (ob->dir != (unsigned)ob->temp1)
+	 ob->dir = dirorder[ob->dir][NEXT];
+	else
+	 {ob->temp1 = 0;
+	  NewState(ob,&s_heinrichchase);
+	 }
+  }
+
+}
+
+void T_KristRight(objtype*ob)
+{CheckRunover(ob);
+ ActorMovement(ob);
+ if (!ob->ticcount)
+  {SD_PlaySoundRTP(SD_KRISTTURNSND,ob->x,ob->y);
+	if (ob->dir != (unsigned)ob->temp1)
+	 ob->dir = dirorder[ob->dir][PREV];
+	else
+	 {ob->temp1 = 0;
+	  NewState(ob,&s_heinrichchase);
+	 }
+  }
+}
+
+
+void T_KristCheckFire(objtype*ob)
+{int perpangle,angle;
+ tpoint dummy;
+
+ if (!ob->ticcount)
+  {angle = AngleBetween(ob,PLAYER[0]);
+
+	if (ob->state == &s_heinrichshoot1)
+	 perpangle = angle + ANGLES/4;
+	else
+	 perpangle = angle - ANGLES/4;
+
+	Fix(perpangle);
+
+
+	dummy.which = ACTOR;
+	dummy.x = ob->x + FixedMul(0x4000,costable[angle]) + FixedMul(0x4000l,costable[perpangle]) +
+				 FixedMul(PROJSIZE,costable[perpangle]); // offset ahead plus
+				 // offset for left/right missile plus offset for missile
+				 // radius (will missile reach player without hitting wall,etc.)
+
+	dummy.y = ob->y - FixedMul(0x4000,sintable[angle]) - FixedMul(0x4000l,sintable[perpangle]) -
+				 FixedMul(PROJSIZE,sintable[perpangle]);
+
+	dummy.x -= (FixedMul(PROJSIZE,costable[perpangle])<<1);
+
+	dummy.y += (FixedMul(PROJSIZE,sintable[perpangle])<<1);
+	dummy.z = ob->z;
+
+	if (!CheckLine(&dummy,PLAYER[0],SHOOT))
+	 {NewState(ob,&s_heinrichchase);
+	  return;
+	 }
+
+
+  }
+}
+
+
+
+void SelectMineDir(objtype*ob)
+{int angle,missangle;
+ dirtype olddir,tdir,next,prev,destdir;
+ static int nummines=0;
+
+ if (!CheckLine(ob,PLAYER[0],SIGHT))
+  {NewState(ob,M_S(CHASE));
+	MISCVARS->HMINING = 0;
+	return;
+  }
+
+ olddir = ob->dir;
+
+ angle = AngleBetween(ob,PLAYER[0]);
+ tdir = angletodir[angle];
+ destdir = opposite[tdir];
+
+ if (destdir != olddir)
+  {next = dirorder[olddir][NEXT];
+	prev = dirorder[olddir][PREV];
+	if (dirdiff[destdir][next] < dirdiff[destdir][prev])
+	 ob->dir = next;
+	else
+	 ob->dir = prev;
+	return;
+  }
+
+ nummines ++;
+ missangle  = angle;
+ if (nummines == 2)
+  missangle -= (ANGLES/36);
+ else if (nummines == 3)
+  missangle += (ANGLES/36);
+
+ Fix(missangle);
+// if (missangle > (ANGLES - 1))
+//  missangle -= ANGLES;
+// else if (missangle < 0)
+//  missangle += ANGLES;
+
+
+ SpawnMissile(ob,h_mineobj,0x2000,missangle,&s_mine1,0xa000);
+ new->dirchoosetime = 140;
+ SD_PlaySoundRTP(SD_KRISTDROPSND,ob->x,ob->y);
+
+ if (nummines == 3)
+  {MISCVARS->HMINING = 0;
+	nummines = 0;
+  }
+}
+
+
+
+void  A_HeinrichShoot(objtype* ob)
+{int angle,perpangle;
+
+ if (!ob->ticcount)
+  {angle = AngleBetween(ob,PLAYER[0]);
+	if (ob->state == &s_heinrichshoot4)
+	 perpangle = angle + ANGLES/4;
+	else
+	 perpangle = angle - ANGLES/4;
+
+	Fix(perpangle);
+
+	SpawnMissile(ob,missileobj,0x4000,angle,&s_missile1,0x8000);
+	SD_PlaySoundRTP(BAS[ob->obclass].fire,ob->x,ob->y);
+
+   SetFinePosition(new,new->x + FixedMul(0x4000l,costable[perpangle]),
+                       new->y - FixedMul(0x4000l,sintable[perpangle]));
+   SetVisiblePosition(new,new->x,new->y);
+  }
+
+
+}
+
+
+//***************************///////**************************************
+//***************************/ NME /**************************************
+//***************************///////**************************************
+
+
+
+
+
+void UpdateNMELinkedActors(objtype*ob)
+   {
+   objtype *head,*wheels;
+   int oldarea;
+
+
+   head = (objtype*)(ob->whatever);
+   wheels = (objtype*)(ob->target);
+
+   oldarea = head->areanumber;
+
+   SetFinePosition(head,ob->x,ob->y);
+   SetFinePosition(wheels,ob->x,ob->y);
+   SetVisiblePosition(head,ob->x,ob->y);
+   SetVisiblePosition(wheels,ob->x,ob->y);
+
+   if (oldarea != ob->areanumber)
+      {
+      RemoveFromArea(head);
+      head->areanumber = ob->areanumber;
+      MakeLastInArea(head);
+      RemoveFromArea(wheels);
+      wheels->areanumber = ob->areanumber;
+      MakeLastInArea(wheels);
+      }
+
+   }
+
+
+void T_OrobotChase(objtype*ob)
+   {
+   int dx,dy;
+
+
+   if (CheckLine(ob,PLAYER[0],SIGHT))
+      {
+
+      ob->targettilex = PLAYER[0]->tilex;
+      ob->targettiley = PLAYER[0]->tiley;
+      }
+
+
+
+   if (!ob->ticcount)
+      {
+      if (NMEspincheck(ob))
+         return;
+
+      dx = PLAYER[0]->x - ob->x;
+      dy = ob->y - PLAYER[0]->y;
+      /*
+      if ((dx > -0x18000) && (dx < 0x18000) && (dy > -0x18000) && (dy < 0x18000))
+         {NewState(ob,&s_NMEavoid);
+         return;
+         }
+      */
+
+      if (CheckLine(ob,PLAYER[0],SIGHT))
+         {
+         int inrange;
+
+         switch(gamestate.difficulty)
+            {
+            case gd_baby: inrange = Near(ob,PLAYER[0],6);break;
+            case gd_easy: inrange = Near(ob,PLAYER[0],9);break;
+            case gd_medium: inrange = Near(ob,PLAYER[0],12);break;
+            case gd_hard: inrange = 1;break;
+            }
+
+         if ((!Near(ob,PLAYER[0],3)) && inrange)
+            {
+            SD_PlaySoundRTP(SD_NMEREADYSND,ob->x,ob->y);
+            if ((ob->hitpoints < 2000) && (GameRandomNumber("NME special attack",0) < 120))
+               {
+               int next,prev;
+
+               next = dirorder16[ob->dir][NEXT];
+               prev = dirorder16[ob->dir][PREV];
+               ob->targettilex = (angletodir[atan2_appx(dx,dy)]<<1);
+
+               if (dirdiff16[prev][ob->targettilex] < dirdiff16[next][ob->targettiley])
+                  ob->temp3 = PREV;
+               else
+                  ob->temp3 = NEXT;
+               NewState(ob,&s_NMEspinfire);
+               }
+            else
+               {
+               NewState(ob,&s_NMEwindup);
+               ob->temp3 = 0;
+               }
+         //NewState((objtype*)(ob->target),&s_NMEwheelspin);
+
+            NewState((objtype*)(ob->target),&s_NMEwheels120);
+            return;
+            }
+         }
+      }
+
+   if (ob->dirchoosetime)
+      ob->dirchoosetime --;
+
+   if ((ob->flags & FL_STUCK) || (!ob->dirchoosetime))
+      {
+      SelectOrobotChaseDir(ob);
+      ob->dirchoosetime = 4;//8;
+      }
+
+   else
+      {
+      ActorMovement(ob);
+      UpdateNMELinkedActors(ob);
+      }
+   }
+
+
+
+void T_Saucer(objtype*ob)
+{int angle,dangle;
+
+ if (!ob->ticcount)  // if on track at end of each state, accelerate
+							// towards PLAYER[0]
+  {if (ob->state->condition & SF_SOUND)
+	  SD_PlaySoundRTP(SD_NMEREADYSND,ob->x,ob->y);
+	angle = AngleBetween(ob,PLAYER[0]);
+	dangle = ob->angle - angle;
+	if ((dangle > -(ANGLES/72)) && (dangle < (ANGLES/72)))
+	 {if (ob->speed < 0x10000)
+		{ob->speed += 0x200;
+		 ZEROMOM;
+		 ParseMomentum(ob,ob->angle);
+		}
+	 }
+	else // off track; zero mom. and select new dir.
+	 {ob->speed = 0x1000;
+	  ZEROMOM;
+	  ob->angle = angle;
+	  ParseMomentum(ob,ob->angle);
+	 }
+  }
+ MissileMovement(ob);
+
+
+}
+
+
+void T_NME_WindUp(objtype*ob)
+{objtype *head,*wheels;
+
+ head = (objtype*)(ob->whatever);
+ wheels = (objtype*)(ob->target);
+
+ if (ob->dirchoosetime)
+  {ob->dirchoosetime--;
+	return;
+  }
+
+ ob->dirchoosetime = 0;//3;
+
+ if (MISCVARS->NMErotate < 3)
+  {head->dir = dirorder16[head->dir][NEXT];
+	MISCVARS->NMErotate ++;
+  }
+ else if (MISCVARS->NMErotate < 6)
+  {head->dir = dirorder16[head->dir][PREV];
+	MISCVARS->NMErotate ++;
+  }
+ else if (MISCVARS->NMErotate < 9)
+  {ob->dir = dirorder16[ob->dir][NEXT];
+	wheels->dir = ob->dir;
+	MISCVARS->NMErotate++;
+  }
+ else if (MISCVARS->NMErotate < 12)
+  {ob->dir = dirorder16[ob->dir][PREV];
+	wheels->dir = ob->dir;
+	MISCVARS->NMErotate ++;
+  }
+ else
+  {MISCVARS->NMErotate = 0;
+
+	NewState(ob,&s_NMEattack);
+	ob->dirchoosetime = 0;
+	//ob->dirchoosetime = 50 - (ob->shapeoffset >> 2) - (gamestate.difficulty << 2);//70;
+	if (!ob->temp2)
+	  NewState((objtype*)(ob->whatever),&s_NMEhead1rl);
+	else
+	  NewState((objtype*)(ob->whatever),&s_NMEhead2rl);
+	NewState(wheels,&s_NMEwheels2);
+  }
+
+}
+
+#define SPRAYDIST 0x12000
+
+void SelectOrobotChaseDir(objtype*ob)     // this code is for head
+   {
+   int dx,dy,angle,tx,ty;
+   int tdir,olddir,nextdir,prevdir;
+   objtype* head,*wheels;
+
+
+
+   head = (objtype*)(ob->whatever);
+   wheels = (objtype*)(ob->target);
+   olddir=head->dir;
+
+findplayer:
+   if (ob->temp1 == -1)
+      {
+      if (ob->targettilex || ob->targettiley)
+         {
+         tx = (int)((ob->targettilex << TILESHIFT) + HALFGLOBAL1);
+         ty = (int)((ob->targettiley << TILESHIFT) + HALFGLOBAL1);
+         dx= tx - ob->x;
+         dy= ob->y - ty;
+         if (((dx <SPRAYDIST ) && (dx > -SPRAYDIST)) &&
+             ((dy <SPRAYDIST ) && (dy > -SPRAYDIST)))
+            {
+            dx= PLAYER[0]->x-ob->x;
+            dy= ob->y - PLAYER[0]->y;
+            }
+         }
+      else
+         {
+         dx= PLAYER[0]->x - ob->x;
+         dy= ob->y - PLAYER[0]->y;
+         }
+
+      angle = atan2_appx(dx,dy);
+
+      tdir = (((angletodir[angle])<<1) & 0xf);
+      }
+   else
+      {
+      tdir = (ob->temp1 & 0xf);
+
+      if ((head->dir == (unsigned)tdir) && (ob->dir == (unsigned)tdir)) // increment
+      // tried dir if robot will attempt to move at tdir =>
+      // head and body are at move try dir
+         {//Debug("\ntrying next queue dir %d",tdir);
+         MISCVARS->NMEdirstried ++;
+         if (MISCVARS->NMEdirstried == MISCVARS->NMEqueuesize) //gone through all queue entries
+            {//Debug("\nqueue exhausted");
+            ob->temp1 = -1;
+            MISCVARS->NMEdirstried = 0;
+            goto findplayer;
+            }
+         }
+      }
+
+
+   if (tdir != olddir) //rotate head to new chase direction
+      {
+      nextdir = dirorder16[olddir][NEXT];
+      prevdir = dirorder16[olddir][PREV];
+      if (dirdiff16[tdir][nextdir] < dirdiff16[tdir][prevdir])
+         head->dir = nextdir;
+      else
+         head->dir = prevdir;
+      return;
+      }
+   //Debug("\nhead aligned to dir %d",tdir);
+
+   //oddir = ob->dir;
+   if (ob->dir != head->dir)   // align body and wheels with head
+      {
+      ZEROMOM;
+      NewState(wheels,&s_NMEwheels120);  //rotate wheels for spinning
+      nextdir = dirorder16[ob->dir][NEXT];
+      prevdir = dirorder16[ob->dir][PREV];
+      if (dirdiff16[head->dir][nextdir] < dirdiff16[head->dir][prevdir])
+         ob->dir = nextdir;
+      else
+         ob->dir = prevdir;
+      wheels->dir = ob->dir;
+      return;
+      }
+
+   // Debug("\nbody aligned to head at dir %d",ob->dir);
+
+   ZEROMOM;
+   ParseMomentum(ob,dirangle16[head->dir]);
+   // Debug("\ntrying to move at dir %d",head->dir);
+   ActorMovement(ob);
+   UpdateNMELinkedActors(ob);
+
+   if (ob->momentumx || ob->momentumy)
+      {
+      NewState(wheels,&s_NMEwheels2); // align wheels for movement
+      //Debug("\nmove at dir %d succesful, resetting queue",head->dir);
+      ob->temp1 = -1; //clear direction queue
+      return;
+      }
+   else if (ob->temp1 == -1) // if queue is empty
+                           //make a queue of directions (byte packed)
+      {
+      //Debug("\nmove at dir %d failed and queue empty",head->dir);
+      ob->temp1 = 0;
+      MISCVARS->NMEdirstried = 0;
+      MISCVARS->NMEqueuesize = 0;
+
+      nextdir = ((tdir + 6) & 0xf);
+      prevdir = ((tdir - 6) & 0xf);
+
+      for(; MISCVARS->NMEqueuesize < 6;MISCVARS->NMEqueuesize += 2)
+         {
+         ob->temp1 <<= 4;
+         ob->temp1 += nextdir;
+         ob->temp1 <<= 4;
+         ob->temp1 += prevdir;
+         nextdir = ((nextdir-2) & 0xf);
+         prevdir = ((prevdir+2) & 0xf);
+
+         }
+   #if 0
+      SoftError("\n straight dir: %d\n queue dirs ",tdir);
+      for(count = 0;count < MISCVARS->NMEqueuesize;count++)
+         {
+         SoftError("\n dir %d: %d",MISCVARS->NMEqueuesize-count,
+                   ((ob->temp1 >> (4*count)) &0xf)
+                  );
+
+         }
+   #endif
+      }
+   else             // else goto next queue dir;
+      {
+      ob->temp1 >>= 4;
+      }
+
+   }
+
+
+
+void T_NME_Explode(objtype*ob)
+{
+
+ if (ob->ticcount == 35)
+	 {objtype*head;
+	  int op;
+
+	  head = (objtype*)(ob->whatever);
+
+	  op = FixedMul(GRAVITY,(head->z-25)<<16) << 1;
+	  head->momentumz = -FixedSqrtHP(op);
+	  head->momentumx = (GameRandomNumber("NME head momx",0) << 2);
+	  head->momentumy = (GameRandomNumber("NME head momy",0) << 2);
+     head->hitpoints = 0;
+     head->flags |= FL_DYING;
+	  NewState(head,&s_shootinghead);
+
+			 //RemoveObj((objtype*)(ob->whatever)); // remove head
+	 }
+ else if (!ob->ticcount)
+	 {ob->shapeoffset = 0;
+	  NewState(ob,&s_explosion1);
+     SetGibSpeed(0x4000);
+     SpawnParticles(ob,gt_sparks,200);
+     ResetGibSpeed();
+	  RemoveObj((objtype*)(ob->target));
+	 }
+
+}
+
+void T_NME_HeadShoot(objtype*ob)
+{//int randtheta,i,offx,offy;
+
+ ob->z += (ob->momentumz>>16);
+
+ /*if (ob->momentumz < 0)
+  {for(i=0;i<3;i++)
+	 {randtheta = (GameRandomNumber("NME spark drop",0) << 3);
+	  SpawnNewObj(ob->tilex,ob->tiley,&s_particle1,inertobj);
+	  new->temp2 = 1;
+	  offx = FixedMul(0x400,costable[randtheta]);
+	  offy = -FixedMul(0x400,sintable[randtheta]);
+	  new->x = new->drawx = ob->x + offx;
+	  new->y = new->drawy = ob->y + offy;
+	  new->z = ob->z-15;
+	  new->flags |= (FL_NOFRICTION|FL_CRAZY|FL_ABP);
+	  new->dir = west;
+	  MakeActive(new);
+	 }
+  }*/
+
+ ob->momentumz += GRAVITY;
+ if (ob->z >= (nominalheight+45))
+  {ob->z = nominalheight+45;
+	if (ob->temp2)
+	 {ob->momentumz = -30000*ob->temp2;
+	  ob->temp2--;
+	 }
+	else
+	 {ob->momentumx = ob->momentumy = ob->momentumz = 0;
+	  ob->shapeoffset = 0;
+	  NewState(ob,&s_NMEheadexplosion);
+
+	  return;
+	 }
+  }
+ ActorMovement(ob);
+
+}
+
+
+boolean NMEspincheck(objtype*ob)
+   {
+   int dx,dy,dz;
+
+   dx = abs(PLAYER[0]->x - ob->x);
+   dy = abs(PLAYER[0]->y - ob->y);
+   dz = abs(PLAYER[0]->z - ob->z);
+   if ((dx < 0x10000) && (dy < 0x10000) && (dz < 32))
+      {
+      NewState(ob,&s_NMEspinattack);
+      NewState((objtype*)(ob->target),&s_NMEwheelspin);
+      if (!ob->temp2)
+         NewState((objtype*)(ob->whatever),&s_NMEhead1);
+      else
+         NewState((objtype*)(ob->whatever),&s_NMEhead2);
+      ob->dirchoosetime = 1;
+      return true;
+      }
+   return false;
+   }
+
+
+
+
+
+void T_NME_SpinAttack(objtype* ob)
+{int mx,my,mz;
+ objtype*head,*wheels;
+
+
+
+ if (ob->ticcount == 30)  // knock player back
+  {GetMomenta(PLAYER[0],ob,&mx,&my,&mz,0x4000);
+	DamageThing(PLAYER[0],20);
+   Collision(PLAYER[0],ob,mx,my);
+	M_CheckPlayerKilled(PLAYER[0]);
+  }
+ if (ob->dirchoosetime)
+  ob->dirchoosetime --;
+ else
+  {head = (objtype*)(ob->whatever);
+	wheels = (objtype*)(ob->target);
+	wheels->dir = head->dir = ob->dir = dirorder16[dirorder16[ob->dir][NEXT]][NEXT];
+
+	ob->dirchoosetime = 1;
+  }
+
+
+}
+
+
+void T_NME_SpinFire(objtype*ob)
+{
+ int randtheta,oldyzangle,dx,dy,xydist,dz;
+ objtype *head,*wheels;
+
+
+ head = (objtype*)(ob->whatever);
+ wheels = (objtype*)(ob->target);
+
+ if (ob->dir != (unsigned)ob->targettilex)
+  {ob->dir = head->dir = wheels->dir = dirorder16[ob->dir][ob->temp3];
+	return;
+  }
+
+ if (ob->dirchoosetime)
+  {ob->dirchoosetime --;
+	return;
+  }
+
+ if (ob->temp3 < 20)
+	{//randphi = (GameRandomNumber("NME generate phi",0) << 3) & ((ANGLES/2) -1);
+	 if (GameRandomNumber("NME generate theta",0) < 128)
+		 randtheta = (GameRandomNumber("NME generate theta",0)>>4);
+	 else
+		 randtheta = -(GameRandomNumber("NME generate theta",0)>>4);
+	 dx = PLAYER[0]->x-ob->x;
+	 dy = ob->y-PLAYER[0]->y;
+	 if (GameRandomNumber("bcraft shoot up/down",0) < 128)
+	  dz = 5;
+	 else
+	  dz = -5;
+	 xydist = FindDistance(dx,dy);
+	 randtheta += atan2_appx(dx,dy);
+	 Fix(randtheta);
+	 oldyzangle = ob->yzangle;
+	 ob->yzangle = atan2_appx(xydist,dz<<10);
+	 //ob->yzangle = randphi;
+	 SD_PlaySoundRTP(BAS[ob->obclass].fire+1,ob->x,ob->y);
+	 //wheels->dir = head->dir = ob->dir = dirorder16[dirorder16[ob->dir][NEXT]][NEXT];
+	 SpawnMissile(ob,fireballobj,0x6000,randtheta,&s_NMEminiball1,0x10000);
+	 ob->dirchoosetime = 1;
+	 ob->yzangle = oldyzangle;
+	 ob->temp3 ++;
+	}
+ else
+  {ob->temp3 = 0;
+	NewState(ob,&s_NMEchase);
+	NewState((objtype*)(ob->target),&s_NMEwheels2);
+	if (!ob->temp2)
+		NewState((objtype*)(ob->whatever),&s_NMEhead1);
+	else
+		NewState((objtype*)(ob->whatever),&s_NMEhead2);
+
+
+  }
+
+
+}
+
+void T_NME_Attack(objtype*ob)
+{int angle,perpangle,i;
+
+
+
+  if (NMEspincheck(ob))
+	{//ob->temp3 = 0;
+	 return;
+	}
+  if (ob->dirchoosetime)
+	  {ob->dirchoosetime --;
+		return;
+	  }
+
+
+  if (!CheckLine(ob,PLAYER[0],SIGHT))
+	{//ob->temp3 = 0;
+    //#if ((DEVELOPMENT == 1))
+	 //Debug("\nCheckLine failed in NME Attack");
+	 //#endif
+	 NewState(ob,&s_NMEchase);
+	 NewState((objtype*)(ob->target),&s_NMEwheels2);
+	 if (!ob->temp2)
+		NewState((objtype*)(ob->whatever),&s_NMEhead1);
+	 else
+		NewState((objtype*)(ob->whatever),&s_NMEhead2);
+	 return;
+	}
+  //sound = BAS[ob->obclass].fire;
+  angle = AngleBetween(ob,PLAYER[0]);
+
+
+
+  if ((ob->temp3 == 0) || (ob->temp3 == 1)) //heatseek
+
+		{SD_PlaySoundRTP(BAS[ob->obclass].fire+2,ob->x,ob->y);
+		 angle = AngleBetween(ob,PLAYER[0]);
+       SpawnMissile(ob,missileobj,0x6000,angle,&s_missile1,0x8000);
+		 if (ob->temp3 == 3)
+			perpangle = angle + ANGLES/4;
+		 else
+			perpangle = angle - ANGLES/4;
+		 Fix(perpangle);
+
+		 new->temp1 = NME_HEATSEEKINGTYPE;
+       SetFinePosition(new,new->x + FixedMul(0x8000l,costable[perpangle]),
+                           new->y - FixedMul(0x8000l,sintable[perpangle]));
+       SetVisiblePosition(new,new->x,new->y);
+		 if (!ob->temp3)
+			ob->dirchoosetime = 20;
+		 else
+			{ob->dirchoosetime = 35 - (ob->shapeoffset >> 2) - (gamestate.difficulty << 2);//70;
+			 if (!ob->temp2)
+				 NewState((objtype*)(ob->whatever),&s_NMEhead1);
+			 else
+				 NewState((objtype*)(ob->whatever),&s_NMEhead2);
+			}
+		 ob->temp3 ++;
+
+		}
+
+  else if (ob->temp3 == 2)          // saucer
+	  { SpawnMissile(ob,NMEsaucerobj,0x1000,angle,&s_NMEsaucer1,0xc000);
+		 new->flags |= FL_SHOOTABLE;
+		 ob->temp3++;
+		 ob->dirchoosetime = 35 - (ob->shapeoffset >> 2) - (gamestate.difficulty << 2);//70;
+		 if (!ob->temp2)
+			NewState((objtype*)(ob->whatever),&s_NMEhead1rl);
+		 else
+			NewState((objtype*)(ob->whatever),&s_NMEhead2rl);
+	  }
+
+  else if ((ob->temp3 == 3) || (ob->temp3 == 4))    // drunk
+		{SD_PlaySoundRTP(BAS[ob->obclass].fire+2,ob->x,ob->y);
+		 if (!ob->temp3)
+		  perpangle = angle + ANGLES/4;
+		 else
+		  perpangle = angle - ANGLES/4;
+		 Fix(perpangle);
+		 for(i=0;i<(2+gamestate.difficulty);i++)
+          {
+          SpawnMissile(ob,missileobj,0x6000,angle,&s_missile1,0x8000);
+			 new->temp1 = NME_DRUNKTYPE;
+          SetFinePosition(new,new->x + FixedMul(0x8000l,costable[perpangle]),
+                              new->y - FixedMul(0x8000l,sintable[perpangle]));
+          SetVisiblePosition(new,new->x,new->y);
+          }
+
+		 if (ob->temp3 == 3)
+			ob->dirchoosetime = 20;
+		 else
+			{ob->temp3 = 0;
+			 NewState(ob,&s_NMEchase);
+			 if (!ob->temp2)
+				NewState((objtype*)(ob->whatever),&s_NMEhead1);
+			 else
+				NewState((objtype*)(ob->whatever),&s_NMEhead2);
+			}
+
+		 ob->temp3 ++;
+
+		}
+
+
+
+}
+
+
+
+//================== Tom/Snake ============================================
+
+
+
+
+
+void T_DarkSnakeSpawn(objtype*ob)
+   {
+   objtype * linkinfront;
+
+   if (((ob->state == &s_darkmonkhspawn) && (!(ob->ticcount%8))) ||
+       ((ob->state == &s_darkmonkfastspawn) && (!(ob->ticcount%4))))
+      {
+      GetNewActor();
+      MakeActive(new);
+      SetFinePosition(new,ob->x,ob->y);
+      SetVisiblePosition(new,ob->x,ob->y);
+      new->z = nominalheight;
+      new->areanumber = MAPSPOT(new->tilex,new->tiley,0)-AREATILE;
+      MakeLastInArea(new);
+      new->obclass = b_darksnakeobj;
+      new->which = ACTOR;
+      new->angle = AngleBetween(ob,PLAYER[0]);
+      new->dir = angletodir[new->angle];
+      if (SNAKELEVEL == 1)
+         new->speed = 0x5000;
+      else if (SNAKELEVEL == 2)
+         new->speed = 0x5800;
+      else
+         new->speed = 0x2000;
+
+
+      new->hitpoints = 1000;
+      new->dirchoosetime = 0;
+      new->door_to_open = -1;
+
+      new->flags |= (FL_ABP|FL_NOFRICTION|FL_SHOOTABLE|FL_BLOCK);
+
+      if (ob->whatever)
+         {
+         linkinfront = (objtype*)(ob->whatever);
+         linkinfront->whatever = new;
+         new->target = linkinfront;
+         new->targettilex = linkinfront->x;
+         new->targettiley = linkinfront->y;
+         new->angle = AngleBetween(new,linkinfront);
+         new->dir = angletodir[new->angle];
+         new->flags |= FL_NEVERMARK;
+         ParseMomentum(new,new->angle);
+         NewState(new,&s_darkmonksnakelink);
+         }
+
+      else
+         {
+         SNAKEHEAD = new;
+         if (SNAKELEVEL == 3)
+            NewState(new,&s_darkmonkhead);
+         else if (SNAKELEVEL == 1)
+            {
+            NewState(new,&s_snakefindpath);
+            new->flags |= FL_ATTACKMODE;
+            }
+         else if (SNAKELEVEL == 2)
+            {
+            NewState(new,&s_snakepath);
+            new->angle = 3*ANGLES/4;
+            new->dir = angletodir[new->angle];
+            new->flags |= FL_ATTACKMODE;
+
+            }
+         ob->targettilex = ob->targettiley = 0;
+         ParseMomentum(new,new->angle);
+         }
+
+      if (!ob->ticcount)
+         SNAKEEND = new;
+
+      ob->whatever = new;
+
+      }
+   }
+
+
+void T_GenericMove(objtype*ob)
+{int dx,dy;
+
+ if (ob->temp3 == -1)
+  return;
+
+
+ if (!(SNAKEHEAD->flags & FL_ATTACKMODE))
+    return;
+
+ if (ob->hitpoints <= 0)
+  {KillActor(ob);
+	ob->temp3 = 0;
+	return;
+  }
+
+ if (!ob->ticcount)
+  {if (ob->state == &s_darkmonkredlink)
+	  ob->temp3 = 0;
+	else if ((ob!=SNAKEEND) && (ob->state == &s_redlinkhit))
+	 NewState((objtype*)(ob->whatever),&s_redlinkhit);
+  }
+
+ dx = ob->targettilex-ob->x;
+ dy = ob->y-ob->targettiley;
+ if ((dx > -0xa000) && (dx < 0xa000) && (dy > -0xa000) && (dy < 0xa000))
+	{if (ob->temp1 && ob->temp2)
+		 {dx = ob->temp1 - ob->x;
+		  dy = ob->y - ob->temp2;
+		  ZEROMOM;
+		 /*
+		 if ((ob->targettilex == ob->temp1) && (ob->targettiley == ob->temp2))
+			return; */
+		  //ob->x = ob->drawx = ob->targettilex;
+		  //ob->y = ob->drawy = ob->targettiley;
+		  //ob->tilex = ob->x >> TILESHIFT;
+		  //ob->tiley = ob->y >> TILESHIFT;
+        //#if ((DEVELOPMENT == 1))
+		  //	Debug("\nfollower %d being moved to targetx %4x and targety %4x",
+		//	  ob-SNAKEHEAD,ob->x,ob->y);
+		 // #endif
+		  ob->targettilex = ob->temp1;
+		  ob->targettiley = ob->temp2;
+		  #if (0)
+			Debug("\nfollower %d's new targetx %4x, targety %4x",
+			 ob-SNAKEHEAD,ob->temp1,ob->temp2);
+		  #endif
+		  ob->angle = atan2_appx(dx,dy);
+		  ob->dir = angletodir[ob->angle];
+		  ParseMomentum(ob,ob->angle);
+		 }
+	}
+ else if (NOMOM)
+  {//SNAKEHEAD->dirchoosetime = 0;
+	ParseMomentum(ob,ob->angle);
+  }
+ if (ob->momentumx || ob->momentumy)
+  MoveActor(ob);
+
+// ActorMovement(ob);
+
+}
+
+
+/*
+===============
+=
+= SelectSnakeDir
+=
+===============
+*/
+
+
+void SelectSnakeDir (objtype *ob)
+{
+ int spot,centerx,centery,dx,dy;
+
+ spot = MAPSPOT(ob->tilex,ob->tiley,1)-ICONARROWS;
+
+ if ((spot >= 0) && (spot<= 7) && ((ob->dir!=(unsigned)spot)||(!(ob->flags & FL_DONE))))
+	{ centerx= (ob->tilex << 16) + HALFGLOBAL1;
+	  centery= (ob->tiley << 16) + HALFGLOBAL1;
+	  dx = abs(centerx - ob->x);
+	  dy = abs(centery - ob->y);
+
+	  if ((dx < SNAKERAD) && (dy < SNAKERAD))
+	// new direction
+		{ZEROMOM;
+		 ob->dir = spot;
+		 ob->flags |= FL_DONE;
+		 ParseMomentum(ob,dirangle8[ob->dir]);
+       SetFinePosition(ob,centerx,centery);
+       SetVisiblePosition(ob,ob->x,ob->y);
+
+		 if (ob==SNAKEHEAD) {
+                     SoftError("\n path changed at %d, %d",ob->tilex,ob->tiley);
+                 }
+		}
+	}
+
+  MoveActor(ob);
+
+}
+
+
+void T_SnakePath(objtype*ob)
+{objtype*temp,*follower;
+
+ if (SNAKEEND && (SNAKELEVEL == 2))
+  {if (CheckLine(SNAKEEND,PLAYER[0],SIGHT))
+	 {if (ob->temp3 == -1)               //if snake can see player
+													 //and he's presently stopped, restart
+		{for(temp=ob;temp;temp=(objtype*)(temp->whatever))
+		  {temp->temp3 = 0;
+			temp->momentumx = temp->temp1;
+			temp->momentumy = temp->temp2;
+		  }
+		 ob->dirchoosetime = 0;
+		}
+	 }
+	else if (ob->temp3 != -1)     //else if he hasn't been stopped, stop him
+	 {for(temp=ob;temp;temp = (objtype*)(temp->whatever))
+		{temp->temp1 = temp->momentumx;
+		 temp->temp2 = temp->momentumy;
+		 temp->temp3 = -1;
+		 temp->momentumx = temp->momentumy = 0;
+		}
+	 }
+	else
+	 return;
+  }
+
+
+ if (ob->dirchoosetime)
+  ob->dirchoosetime--;
+
+ else
+     {int count = 0;
+
+      for(temp=ob;temp->whatever;temp=(objtype*)(temp->whatever))
+			{follower = (objtype*)(temp->whatever);
+			 follower->temp1 = temp->x;
+			 follower->temp2 = temp->y;
+
+          SoftError("\n follower %d temp1 set to %4x, temp2 set to %4x",
+					  count,temp->x,temp->y);
+          count ++;
+			}
+		ob->dirchoosetime = 2 ;//15
+	  }
+
+ if (ob->momentumx || ob->momentumy)
+  SelectSnakeDir(ob);
+ //else
+ // {ParseMomentum(ob,ob->angle);
+ //	MoveActor(ob);
+ // }
+
+
+}
+
+void FindClosestPath(objtype*ob)
+{int tx,ty,dx,dy,angle;
+
+
+ tx = (ob->targettilex << 16) + TILEGLOBAL/2;
+ ty = (ob->targettiley << 16) + TILEGLOBAL/2;
+
+ dx= tx - ob->x;
+ dy= ob->y - ty;
+ angle = atan2_appx(dx,dy);
+
+ ZEROMOM;
+ ParseMomentum(ob,angle);
+ MoveActor(ob);
+
+}
+
+
+void T_SnakeFindPath(objtype*ob)
+{int i,dx,dy,currdist,mindist,map;
+ tpoint dstruct,*dummy=&dstruct;
+ objtype*temp,*follower;
+
+	if (ob->targettilex || ob->targettiley)
+	 {FindClosestPath(ob);
+	  dx = ob->targettilex - ob->tilex;
+	  dy = ob->targettiley - ob->tiley;
+	  if ((!dx) && (!dy))
+         {SetTilePosition(ob,ob->tilex,ob->tiley);
+          SetVisiblePosition(ob,ob->x,ob->y);
+			 ob->y = ob->drawy = (ob->tiley << TILESHIFT) + TILEGLOBAL/2;
+			 NewState(ob,&s_snakepath);
+			 return;
+			}
+	 }
+
+	else
+    {dummy->which = ACTOR;
+	  mindist = 0x7fffffff;
+	  for(i=0;i<whichpath;i++)
+      {
+       SetTilePosition(dummy,SNAKEPATH[i].x,SNAKEPATH[i].y);
+       dummy->z = ob->z;
+       if (CheckLine(ob,dummy,SIGHT))
+        {currdist = FindDistance(ob->tilex-dummy->tilex,ob->tiley-dummy->tiley);
+			map = MAPSPOT(ob->tilex,ob->tiley,0)-AREATILE;
+			if ((currdist < mindist) && (map >= 0) && (map <= NUMAREAS))
+          {ob->targettilex = dummy->tilex;
+           ob->targettiley = dummy->tiley;
+			  mindist = currdist;
+			 }
+		  }
+		}
+	 }
+
+	if (ob->dirchoosetime)
+	 ob->dirchoosetime--;
+	else
+	  {for(temp=ob;temp->whatever;temp=(objtype*)(temp->whatever))
+			{follower = (objtype*)(temp->whatever);
+			 follower->temp1 = temp->x;
+			 follower->temp2 = temp->y;
+			}
+		ob->dirchoosetime = 2 ;//15
+	  }
+}
+
+
+
+void T_SnakeFinale(objtype*ob)
+{
+
+   if ((ob->state == &s_snakefireworks1)||(ob->state == &s_snakefireworks2))
+      {
+      if (ob->z != (maxheight-200))
+         {
+         ob->z --;
+         return;
+         }
+      SetGibSpeed(0x4500);
+      SpawnParticles(ob,RANDOM,100);
+
+      SpawnParticles(ob,gt_spit,100);
+      ResetGibSpeed();
+      NewState(ob,&s_dexplosion1);
+      }
+
+   else
+      {
+      if (!ob->ticcount)
+         {
+         NewState(EXPLOSIONS,&s_megaremove);
+      //  SpawnParticles(ob,RANDOM,100);
+         // SpawnParticles(ob,SPIT,100);
+         return;
+         }
+
+      if (ob->dirchoosetime)
+         ob->dirchoosetime --;
+      else
+         {
+         ob->dirchoosetime = (GameRandomNumber("snake finale choose",0) % 7) + 15;
+         SetGibSpeed(0x3000);
+         SpawnParticles(ob,RANDOM,30);
+         SpawnParticles(ob,gt_spit,20);
+         ResetGibSpeed();
+         }
+      }
+   }
+
+
+
+void T_DarkSnakeChase(objtype*ob)
+   {
+   objtype* temp,*follower;
+   int tdir,angle;
+
+
+   if (!(ob->flags & FL_ATTACKMODE))
+      {
+      if (!(CheckSight(ob,player) || Near(ob,player,4)))
+         return;
+      else
+         {
+         ob->flags |= FL_ATTACKMODE;
+         MU_StartSong(song_bosssee);
+         }
+
+      }
+
+
+
+   if (ob->hitpoints <= 0)
+      {
+      MU_StartSong(song_bossdie);
+      KillActor(ob);
+      AddMessage("Oscuro defeated!",MSG_CHEAT);
+      return;
+      }
+
+   angle = AngleBetween(ob,PLAYER[0]);
+   tdir = angletodir[angle];
+   if (Near(ob,PLAYER[0],6) && (ob->dir == (unsigned)tdir) && (!(ob->state->condition & SF_DOWN)))
+      {
+      NewState(ob,&s_snakefire1);
+      SD_PlaySoundRTP(SD_SNAKEREADYSND,ob->x,ob->y);
+      }
+
+   if (!ob->ticcount)
+      {
+      if (ob->state == &s_darkmonkredhead)
+         ob->temp3 = 0; // no longer hitable
+      else if ((ob->state == &s_redheadhit) && (ob != SNAKEEND))
+         NewState((objtype*)(ob->whatever),&s_redlinkhit);
+      else if (ob->state->condition & SF_UP)
+         {
+         SpawnMissile(ob,dm_spitobj,0x6000,angle,&s_spit1,0x6000);
+         SD_PlaySoundRTP(BAS[ob->obclass].fire,ob->x,ob->y);
+         //new->z -= 5;
+         }
+         //spawn spit;
+      }
+
+   if (CheckLine(ob,PLAYER[0],SIGHT))
+      {
+      ob->targettilex = PLAYER[0]->x;
+      ob->targettiley = PLAYER[0]->y;
+      }
+
+   if (ob->dirchoosetime)
+      {
+      ob->dirchoosetime--;
+      ActorMovement(ob);
+      if (NOMOM)
+         ob->dirchoosetime = 0;
+      }
+
+   else
+      {//if (ob)
+      for(temp=ob;temp->whatever;temp=(objtype*)(temp->whatever))
+         {
+         follower = (objtype*)(temp->whatever);
+         follower->temp1 = temp->x;
+         follower->temp2 = temp->y;
+         }
+      SelectChaseDir(ob);
+      ob->dirchoosetime = 7 ;//15
+      }
+   }
+
+
+
+void T_DarkmonkReact(objtype*ob)
+{
+ if (ob->z < nominalheight)
+	  {MISCVARS->monkz += MZADJUST;
+		ob->z = nominalheight + (MISCVARS->monkz >> 16);
+		//ob->z++;
+		return;
+	  }
+
+ else
+  {int ocl;
+
+	ocl = ob->temp3;
+
+	if (ocl == p_kesobj)
+	  NewState(ob,&s_darkmonkabsorb1);
+	else if (ocl == p_heatseekobj)
+	  NewState(ob,&s_darkmonkhball1);
+	else if (ocl == p_firebombobj)
+	  NewState(ob,&s_darkmonkbreathe1);
+	else
+	  NewState(ob,&s_darkmonkchase1);
+	ob->dirchoosetime = 0;
+  }
+
+}
+
+
+
+void T_DarkmonkCharge(objtype*ob)
+{int dx,dy;
+
+ dx = abs(PLAYER[0]->x - ob->x);
+ dy = abs(PLAYER[0]->y - ob->y);
+ if ((dx < 0xa000) && (dy < 0xa000))
+  {DamageThing(PLAYER[0],10);
+   Collision(PLAYER[0],ob,0,0);
+	M_CheckPlayerKilled(PLAYER[0]);
+  }
+
+ if (!ob->ticcount)
+  ob->speed >>= 1;
+
+ if (ob->dirchoosetime)
+  ob->dirchoosetime --;
+
+ if (NOMOM || (!ob->dirchoosetime))
+	{ob->angle = AngleBetween(ob,PLAYER[0]);
+	 ob->dir = angletodir[ob->angle];
+	 ParseMomentum(ob,ob->angle);
+	 ob->dirchoosetime = 5;
+	}
+
+ ActorMovement(ob);
+
+
+}
+
+
+void T_DarkmonkLandAndFire(objtype*ob)
+{
+
+  if (ob->z < nominalheight)
+	  {MISCVARS->monkz += MZADJUST;
+		ob->z = nominalheight + (MISCVARS->monkz >> 16);
+		//ob->z++;
+		return;
+	  }
+  if (Near(ob,PLAYER[0],3))
+	 {if (GameRandomNumber("darkmonkland",0)<128)
+		NewState(ob,&s_darkmonkbball1);
+	  else
+		{ob->angle = AngleBetween(ob,PLAYER[0]);
+		 ob->dir = angletodir[ob->angle];
+		 ob->speed <<= 1;       // goes twice as fast
+		 ZEROMOM;
+		 ParseMomentum(ob,ob->angle);
+		 ob->dirchoosetime = 5; // change dir every 5 tics
+		 ob->hitpoints -= 200; // big penalty for charging
+		 if (ob->hitpoints <= 0)
+			{objtype*column = (objtype*)(ob->whatever);
+
+          EnableObject((long)column);
+			 ob->whatever = NULL;
+
+			 KillActor(ob);
+			 NewState(ob,&s_darkmonkfastspawn);
+          AddMessage("Oscuro flees!",MSG_CHEAT);
+			 return;
+			}
+		 NewState(ob,&s_darkmonkcharge1);
+		}
+
+	 }
+  else if (ob->temp1)
+	 NewState(ob,&s_darkmonklightning1);
+  else
+	 NewState(ob,&s_dmgreenthing1);
+  ob->temp1 ^= 1;
+  ob->dirchoosetime = 0;
+
+}
+
+
+void T_DarkmonkChase(objtype*ob)
+{int chance,dx,dy,dist;
+
+
+  if (!Near(ob,PLAYER[0],2))
+	{if (ob->z > (maxheight - 100))
+	  {MISCVARS->monkz -= MZADJUST;
+		ob->z = nominalheight + (MISCVARS->monkz >> 16);
+		//ob->z--;
+		return;
+	  }
+	}
+  else if (ob->z < nominalheight)
+	  {MISCVARS->monkz += MZADJUST;
+		ob->z = nominalheight + (MISCVARS->monkz >> 16);
+		//ob->z++;
+		return;
+	  }
+
+
+  if (CheckLine(ob,PLAYER[0],SIGHT))
+	 {ob->targettilex = PLAYER[0]->x;
+	  ob->targettiley = PLAYER[0]->y;
+	 }
+
+  if (!ob->ticcount)
+	 {
+	  if (CheckLine(ob,PLAYER[0],SHOOT))   // got a shot at player?
+		 {dx = abs(ob->tilex - PLAYER[0]->tilex);
+		  dy = abs(ob->tiley - PLAYER[0]->tiley);
+		  dist = dx>dy ? dx : dy;
+		  if (!dist || dist==1)
+			  chance = 300;//300;
+		  else
+			  chance = 400/dist;//300/dist;
+
+		  if (GameRandomNumber("T_DarkMonkChase",0) < chance)
+			 {NewState(ob,&s_dmlandandfire);
+			  return;
+			 }
+		 }
+	 }
+
+	if (ob->dirchoosetime)
+	 ob->dirchoosetime--;
+
+	if ((ob->flags & FL_STUCK) || (!ob->dirchoosetime))
+	  {SelectChaseDir(ob);
+		ob->dirchoosetime = M_CHOOSETIME(ob);
+	  }
+
+	else
+	 {if (NOMOM)
+		ParseMomentum(ob,dirangle8[ob->dir]);
+	  ActorMovement(ob);
+
+	 }
+
+}
+
+
+//====================== End of Boss Functions ===========================//
+
+
+
+
+
+
+void T_GunStand(objtype*ob)
+{int dy,dx,infrontof,dz;
+ objtype* temp;
+
+// if (ob->target)
+//  Error("gun reset with non-null target");
+ for(temp = firstareaactor[ob->areanumber];temp;temp= temp->nextinarea)
+	{if (temp == ob)
+		continue;
+	 if (temp->obclass == ob->obclass)
+	  continue;
+	 if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
+	  continue;
+
+	 dy = ob->y - temp->y;
+	 dx = ob->x - temp->x;
+	 dz = ob->z - temp->z;
+	 if ((abs(dy)>0x40000) || (abs(dx)>0x40000) || (abs(dz) > 20))
+	  continue;
+
+
+	 infrontof = 0;
+
+	 switch (ob->dir)
+	  {case north:
+		if ((dy > 0) && (abs(dx)<0x8000))
+		  infrontof = 1;
+		break;
+
+		case east:
+		if ((dx < 0) && (abs(dy)<0x8000))
+		  infrontof = 1;
+		break;
+
+		case south:
+		if ((dy < 0) && (abs(dx)<0x8000))
+		  infrontof = 1;
+		break;
+
+		case west:
+		if ((dx > 0) && (abs(dy)<0x8000))
+		  infrontof = 1;
+		break;
+		
+		default:
+		break;
+	  }
+
+	 if (infrontof && CheckLine(ob,temp,SHOOT))
+		{ob->target = temp;
+		 NewState(ob,&s_gunraise1);
+		 return;
+		}
+	}
+
+}
+
+
+void T_4WayGunStand(objtype*ob)
+   {
+   int dy,dx,dz;
+   objtype* temp;
+
+   if (ob->target)
+   Error("gun reset with non-null target");
+   for(temp = firstareaactor[ob->areanumber];temp;temp= temp->nextinarea)
+      {
+      if (temp == ob)
+         continue;
+
+      if (temp->obclass == ob->obclass)
+         continue;
+
+      if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
+         continue;
+
+      dy = abs(ob->x-temp->x);
+      dx = abs(ob->y-temp->y);
+      dz = abs(ob->z-temp->z);
+      if ((dx < 0x40000) && (dy < 0x40000) && (dz< 20) && CheckLine(ob,temp,SHOOT))
+         {//if ((dx < 0x8000) || (dy <0x8000))
+         ob->target = temp;
+         NewState(ob,&s_4waygunfire1);
+         return;
+         }
+      }
+   }
+
+
+void A_GunShoot(objtype*ob)
+{ int   dx,dy,dz,damage,infrontof,tnear,savedangle;
+  objtype * target;
+
+ if (!ob->ticcount)
+  {target = (objtype*)(ob->target);
+   if (!target)
+      Error("an instance of %s called gunshoot without a target\n",debugstr[ob->obclass]);
+   if ((!(target->flags & FL_SHOOTABLE)) || (target->flags & FL_DYING))
+	 {NewState(ob,&s_gunlower1);
+	  ob->target = NULL;
+	  return;
+	 }
+
+   dx = target->x-ob->x;
+	dy = ob->y-target->y;
+	dz = ob->z-target->z;
+
+
+	tnear = ((abs(dy)<0x40000) && (abs(dx)<0x40000) && (abs(dz) < 20));
+	infrontof = 0;
+
+	 switch (ob->dir)
+	  {case north:
+		if ((dy > 0) && (abs(dx)<0x8000))
+		  infrontof = 1;
+		break;
+
+		case east:
+		if ((dx < 0) && (abs(dy)<0x8000))
+		  infrontof = 1;
+		break;
+
+		case south:
+		if ((dy < 0) && (abs(dx)<0x8000))
+		  infrontof = 1;
+		break;
+
+		case west:
+		if ((dx > 0) && (abs(dy)<0x8000))
+		  infrontof = 1;
+		break;
+		
+		default:
+		break;
+	  }
+
+	if ((!infrontof) || (!CheckLine(ob,target,SHOOT)) ||
+		 (!tnear))
+	 {NewState(ob,&s_gunlower1);
+	  ob->target = NULL;
+	  return;
+	 }
+
+	//SD_PlaySoundRTP(SD_FIRE,PLAYER[0]->x,PLAYER[0]->y,ob->x,ob->y);
+	//hitchance = 128;
+
+//	if (!target)
+  //		Error("object called shoot without a target\n");
+
+
+	damage = DMG_AHGUN;
+
+
+	if (target->obclass == playerobj)
+	  {target->target = ob;
+		if (target->flags & FL_BPV)
+		  damage >>= 1;
+
+	  }
+	savedangle = ob->angle;
+	ob->angle = atan2_appx(dx,dy);
+	RayShoot(ob,damage,GameRandomNumber("A_GunShoot Accuracy",0) % 20);
+	ob->angle = savedangle;
+	SD_PlaySoundRTP(SD_BIGEMPLACEFIRESND,ob->x,ob->y);
+  }
+
+}
+
+
+void A_4WayGunShoot(objtype*ob)
+   {
+   int   dx,dy,dz,damage,savedangle;
+   objtype * target;
+
+   if (ob->ticcount == (ob->state->tictime >> 1))
+      {
+      target = (objtype*)(ob->target);
+      if (!target)
+         Error("an instance of %s called 4waygunshoot without a target\n",debugstr[ob->obclass]);
+      dx = abs(target->x-ob->x);
+      dy = abs(ob->y-target->y);
+      dz = abs(ob->z-target->z);
+      if ((dx > 0x40000) || (dy > 0x40000) || (dz > 20) ||
+          (!CheckLine(ob,target,SHOOT)) ||
+          (!(target->flags & FL_SHOOTABLE)) ||
+          (target->flags & FL_DYING)
+         )
+         {
+         ob->target = NULL;
+         NewState(ob,&s_4waygun);
+         return;
+         }
+
+
+      //SD_PlaySoundRTP(SD_FIRE,PLAYER[0]->x,PLAYER[0]->y,ob->x,ob->y);
+      //hitchance = 128;
+
+      // if (!target)
+      //     Error("object called shoot without a target\n");
+
+
+      damage = DMG_AHGUN;
+      SD_PlaySoundRTP(BAS[ob->obclass].fire,ob->x,ob->y);
+
+      if (target->obclass == playerobj)
+         {
+         target->target = ob;
+         if (target->flags & FL_BPV)
+            damage >>= 1;
+         }
+
+      savedangle = ob->angle;
+      ob->angle = 0;
+      RayShoot(ob,damage,GameRandomNumber("A_4WayGunShoot Accuracy",0) % 20);
+      ob->angle = ANG90;
+      RayShoot(ob,damage,GameRandomNumber("A_4WayGunShoot Accuracy",0) % 20);
+      ob->angle = ANG180;
+      RayShoot(ob,damage,GameRandomNumber("A_4WayGunShoot Accuracy",0) % 20);
+      ob->angle = ANG270;
+      RayShoot(ob,damage,GameRandomNumber("A_4WayGunShoot Accuracy",0) % 20);
+      ob->angle = savedangle;
+      }
+   }
+
+
+void A_Drain (objtype *ob)
+   {
+   int dx,dy,dz,damage;
+
+	dx = abs(PLAYER[0]->x - ob->x);
+	dy = abs(PLAYER[0]->y - ob->y);
+	dz = abs(PLAYER[0]->z - ob->z);
+
+	if ((dx > TOUCHDIST) || (dy > TOUCHDIST) || (dz > (TOUCHDIST>>10)))
+      {
+      NewState(ob,&s_dmonkshoot5);
+      return;
+      }
+
+	if (ob->ticcount)
+      return;
+
+	else
+      {
+      damage = (GameRandomNumber("A_Drain",ob->obclass) >> 3);
+      DamageThing (PLAYER[0],damage);
+      ob->hitpoints += damage;
+      if (ob->hitpoints > starthitpoints[gamestate.difficulty][ob->obclass])
+         ob->hitpoints = starthitpoints[gamestate.difficulty][ob->obclass];
+
+      Collision(PLAYER[0],ob,0,0);
+      if (PLAYER[0]->flags & FL_DYING)
+         PLAYER[0]->target = ob;
+      M_CheckPlayerKilled(PLAYER[0]);
+      SD_PlaySoundRTP(SD_MONKGRABSND,ob->x,ob->y);
+      }
+   }
+
+
+
+
+
+
+void  A_DmonkAttack(objtype*ob)
+{int angle,nobclass,nspeed,altangle1=0,altangle2=0,zoff=0,sound;
+ statetype *nstate;
+
+
+  if (!ob->ticcount)
+     {
+     ob->hitpoints -= 120;//120;
+     if (ob->hitpoints <= 0)
+        {
+        objtype*column = (objtype*)(ob->whatever);
+
+        EnableObject((long)column);
+        ob->whatever = NULL;
+
+        KillActor(ob);
+        NewState(ob,&s_darkmonkfastspawn);
+        return;
+        }
+     }
+
+
+ if (ob->dirchoosetime)
+  ob->dirchoosetime --;
+
+ else
+  {sound = BAS[ob->obclass].fire;
+	angle = AngleBetween(ob,PLAYER[0]);
+   nspeed = 0x6000;
+
+	if (ob->state == &s_darkmonksphere8)
+		{nstate = &s_kessphere1;
+		 nobclass = p_kesobj;
+		 ob->dirchoosetime = 70;
+		}
+
+	else if (ob->state == &s_darkmonkhball7)
+		{nstate = &s_handball1;
+		 nobclass = dm_heatseekobj;
+		 nspeed = 0x3000;
+		 ob->dirchoosetime = 5;
+		}
+
+	else if (ob->state == &s_darkmonkbball7)
+		{nstate = &s_faceball1;
+		 nobclass = dm_weaponobj;
+		 nspeed = 0x3000;
+		 ob->dirchoosetime = 5;
+		}
+
+	else if (ob->state == &s_darkmonklightning9)
+		{nstate = &s_lightning;
+		 nobclass = dm_weaponobj;
+		 ob->dirchoosetime = 3;
+		 sound++;
+		}
+
+	else if (ob->state == &s_dmgreenthing8)
+		{nstate = &s_energysphere1;
+		 nobclass = dm_weaponobj;
+		 sound +=2;
+		 ob->dirchoosetime = 70;
+		}
+
+	else if (ob->state == &s_darkmonkfspark5)
+		{nstate = &s_floorspark1;
+
+		 altangle1 = angle + ANGLES/24;
+		 altangle2 = angle - ANGLES/24;
+		 Fix(altangle1);
+		 Fix(altangle2);
+		 nobclass = dm_weaponobj;
+		 ob->dirchoosetime = 3;
+		 sound += 3;
+		}
+
+	else if (ob->state == &s_darkmonkbreathe6)
+		{nstate = &s_crossfire1;
+		 ob->dirchoosetime = 3;
+		 nobclass = dm_weaponobj;
+		 zoff = -15;
+		 sound += 3;
+		}
+
+	SpawnMissile(ob,nobclass,nspeed,angle,nstate,0xb000);
+	SD_PlaySoundRTP(sound,ob->x,ob->y);
+
+	new->z = ob->z+zoff;
+	if (altangle1)
+      {
+      SpawnMissile(ob,nobclass,nspeed,altangle1,nstate,0xb000);
+      SpawnMissile(ob,nobclass,nspeed,altangle2,nstate,0xb000);
+      }
+  }
+
+
+
+}
+
+
+
+#endif // SHAREWARE endif
+
+
+
+
+//=====================================================================//
+
+
+
+
+/*
+===============
+=
+= T_Stand
+=
+===============
+*/
+
+void T_Stand (objtype *ob)
+   {
+   if (!ob->ticcount)
+      SightPlayer (ob);
+   else
+      SoftError("\n ob type %s ticcount of %d in T_Stand",debugstr[ob->obclass],
+                ob->ticcount);
+   }
+
+
+
+
+
+void DamagePlayerActor(objtype *ob, int damage)
+
+   {
+   playertype *pstate;
+
+   switch (gamestate.difficulty)
+      {
+      case 0:  damage >>= 1;
+               break;
+      case 1:  damage -= (damage >> 2);
+               break;
+      case 2:  break;
+      case 3:  //damage += (damage>>2);
+               break;
+      //default: Error("Um, Gamestate.Difficulty, uh, has problems.\n");
+      }
+
+   if (!damage) damage++;
+
+   M_LINKSTATE(ob,pstate);
+
+
+   pstate->health -= damage;
+   ob->hitpoints = pstate->health;
+
+   SD_PlaySoundRTP(SD_PLAYERTCHURTSND+(pstate->player),ob->x,ob->y);
+   if (ob==player)
+      {
+      damagecount += damage;
+      if (cybermanenabled)
+         SWIFT_TactileFeedback (10*damage, 15, 15);
+      if ( SHOW_BOTTOM_STATUS_BAR() )
+         DrawBarHealth (false);
+      }
+
+   if (pstate->health<=0)
+      {
+      pstate->health = 0;
+      ob->hitpoints = 0;
+      }
+   }
+
+
+
+
+void DamageNonPlayerActor(objtype *ob,int damage)
+   {
+   //if ((ob->obclass == b_darksnakeobj) && (!ob->temp3))
+     // return;
+
+   if (!(ob->flags & FL_ATTACKMODE))
+      damage <<= 1;
+
+   ob->hitpoints -= damage;
+   if (ob->hitpoints <= 0)
+      {
+      int sound;
+
+      sound = BAS[ob->obclass].die;
+      if (ob->obclass == lowguardobj)
+         {
+         if (ob->shapeoffset)
+            sound ++;
+         }
+      SD_PlaySoundRTP(sound,ob->x,ob->y);
+      }
+   else
+      SD_PlaySoundRTP(BAS[ob->obclass].hit,ob->x,ob->y);
+
+#if (SHAREWARE == 0)
+   if ((ob->obclass == b_robobossobj) && (ob->temp2 <= 2))
+      {
+      if (ob->hitpoints <
+          ((3-ob->temp2)*starthitpoints[gamestate.difficulty][ob->obclass]>>2)
+         )
+         {
+         SD_PlaySoundRTP(SD_NMEAPARTSND,ob->x,ob->y);
+         ob->temp2++;
+         ob->shapeoffset += 16;
+         ob->speed += 0x500;
+         SpawnNewObj(ob->tilex,ob->tiley,&s_megaexplosions,inertobj);
+         new->temp1 = 3;
+         new->flags |= FL_ABP;
+         MakeActive(new);
+         }
+      if (ob->temp2 == 1)
+         NewState((objtype*)(ob->whatever),&s_NMEhead2);
+      }
+#endif
+   MISCVARS->madenoise = true;
+   }
+
+
+
+void DamageStaticObject(statobj_t*tempstat,int damage)
+   {
+
+
+   tempstat->hitpoints -= damage;
+   if (tempstat->hitpoints <= 0)
+      {
+      sprites[tempstat->tilex][tempstat->tiley]=NULL;
+      tempstat->flags |= FL_NONMARK;
+      if (tempstat->flags&FL_LIGHT)
+         {
+
+         if (MAPSPOT(tempstat->tilex,tempstat->tiley,2))
+            {touchplatetype *tplate;
+
+             for(tplate=touchplate[tempstat->linked_to];tplate;tplate = tplate->nextaction)
+                if (tplate->whichobj == (long)(tempstat))
+                   RemoveTouchplateAction(tplate,tempstat->linked_to);
+            }
+
+         if (tempstat->flags & FL_LIGHTON)
+            TurnOffLight(tempstat->tilex,tempstat->tiley);
+
+
+         if (tempstat->itemnumber<=stat_chandelier)
+            //SpawnFallingDebris(tempstat->x,tempstat->y,tempstat->z-32);
+            {
+            objtype *prevlast = LASTACTOR;
+
+            SpawnSlowParticles(gt_sparks,4,tempstat->x,tempstat->y,tempstat->z-32);
+            for(prevlast = prevlast->next;prevlast;prevlast= prevlast->next)
+               {
+               prevlast->momentumz = 1; // any positive value will do
+               prevlast->momentumx >>= 1;
+               prevlast->momentumy >>= 1;
+               }
+            }
+         else
+            {
+
+            SpawnStatic(tempstat->tilex,tempstat->tiley,stat_metalshards,-1);
+            LASTSTAT->flags |= (FL_ABP|FL_NONMARK);
+            sprites[tempstat->tilex][tempstat->tiley] = NULL;
+            MakeStatActive(LASTSTAT);
+            switch (tempstat->itemnumber)
+               {
+               case stat_lamp:
+               case stat_altbrazier1:
+               case stat_altbrazier2:
+               case stat_torch:
+                  SpawnSlowParticles(gt_sparks,5,tempstat->x,tempstat->y,tempstat->z-32);
+                  break;
+               case stat_floorfire:
+                  SpawnSlowParticles(gt_sparks,5,tempstat->x,tempstat->y,tempstat->z);
+                  break;
+	       default:
+		   ;
+               }
+            }
+         SpawnSolidStatic(tempstat);
+         SD_PlaySoundRTP(SD_ITEMBLOWSND,tempstat->x,tempstat->y);
+         }
+      else
+         {
+         switch (tempstat->itemnumber)
+            {
+            case stat_dariantouch:
+               MISCVARS->ETOUCH[tempstat->linked_to].x = MISCVARS->ETOUCH[tempstat->linked_to].y = 0;
+            case stat_tntcrate:
+            case stat_bonusbarrel:
+               SpawnNewObj(tempstat->tilex,tempstat->tiley,&s_staticexplosion1,inertobj);
+               MakeActive(new);
+               new->flags |= FL_ABP;
+               new->whatever = tempstat;
+               new->temp2 = damage;
+
+               if (tempstat->itemnumber == stat_bonusbarrel)
+                  {
+                  int rand = GameRandomNumber("DamageThing",0);
+
+                  if (rand < 80)
+                     {
+                     if (rand & 1)
+                        SpawnStatic(tempstat->tilex,tempstat->tiley,stat_monkmeal,-1);
+                     else
+                        SpawnStatic(tempstat->tilex,tempstat->tiley,stat_priestporridge,-1);
+                     gamestate.healthtotal ++;
+                     }
+                  else if (rand < 160)
+                     {
+                     if (rand & 1)
+                        SpawnStatic(tempstat->tilex,tempstat->tiley,stat_lifeitem1,-1);
+                     else
+                        SpawnStatic(tempstat->tilex,tempstat->tiley,stat_lifeitem3,-1);
+                     }
+                  else
+                     {
+                     if (rand & 1)
+                        SpawnStatic(tempstat->tilex,tempstat->tiley,stat_mp40,-1);
+                     else
+                        {
+                        SpawnStatic(tempstat->tilex,tempstat->tiley,stat_heatseeker,-1);
+                        gamestate.missiletotal ++;
+                        }
+                     LASTSTAT->flags &= ~FL_RESPAWN;
+                     }
+                  //LASTSTAT->flags &= ~FL_SHOOTABLE;
+                  LASTSTAT->flags |= FL_ABP;
+                  MakeStatActive(LASTSTAT);
+                  SD_PlaySoundRTP(SD_BONUSBARRELSND,tempstat->x,tempstat->y);
+                  }
+               else
+                  {
+                  ExplodeStatic(tempstat);
+                  if (tempstat == touchsprite)
+                     touchsprite = NULL;
+                  }
+               SpawnSolidStatic(tempstat);
+         //SD_Play(SD_EXPL);
+               break;
+   #if (SHAREWARE == 0)
+            case stat_mine:
+               SpawnNewObj(tempstat->tilex,tempstat->tiley,&s_grexplosion1,inertobj);
+               MakeActive(new);
+               new->flags |= FL_ABP;
+               new->whatever = tempstat;
+               new->temp2 = damage;
+               RemoveStatic(tempstat);
+               break;
+
+            case stat_tomlarva:
+               SD_PlaySoundRTP(SD_ACTORSQUISHSND,tempstat->x,tempstat->y);
+               SpawnGroundExplosion(tempstat->x,tempstat->y,tempstat->z);
+               //MISCVARS->gibgravity = GRAVITY/2;
+               MISCVARS->fulllightgibs = true;
+               SetGibSpeed(0x4000);
+               SpawnSlowParticles(GUTS,30,tempstat->x, tempstat->y,tempstat->z);
+               ResetGibSpeed();
+               MISCVARS->fulllightgibs = false;
+               //MISCVARS->gibgravity = -1;
+               RemoveStatic(tempstat);
+               break;
+   #endif
+
+            case stat_lifeitem1:
+            case stat_lifeitem2:
+            case stat_lifeitem3:
+            case stat_lifeitem4:
+               SD_PlaySoundRTP(SD_ITEMBLOWSND,tempstat->x,tempstat->y);
+               gamestate.treasurecount ++;
+               SpawnSlowParticles(gt_sparks,10,tempstat->x,tempstat->y,tempstat->z);
+               SpawnSolidStatic(tempstat);
+               break;
+
+            default:
+
+               if ((tempstat->itemnumber == stat_plant) ||
+                     (tempstat->itemnumber == stat_tree))
+                  gamestate.plantcount++;
+
+               //tempstat->shapenum = -1;
+               //tempstat->flags &= ~FL_SHOOTABLE;
+               ExplodeStatic(tempstat);
+               SpawnSolidStatic(tempstat);
+               break;
+            }
+         }
+      }
+   }
+
+
+void DamageThing (void *thing, int damage)
+   {
+   objtype* tempactor;
+   statobj_t* tempstat;
+
+
+   tempactor = (objtype*)thing;
+   if (!tempactor)
+      return;
+
+   if ((tempactor->which == ACTOR) && (!(tempactor->flags & FL_SHOOTABLE)))
+      return;
+
+   if ((tempactor->which == ACTOR) || (tempactor->which == SPRITE))
+      {
+      if (tempactor->which == ACTOR)
+         {
+         if (tempactor->obclass == playerobj)
+            {
+            if ((tempactor->flags & FL_GODMODE) ||
+                (tempactor->flags & FL_DOGMODE) ||
+                godmode ||
+                (gamestate.battlemode == battle_Eluder)
+               )
+               return;
+            DamagePlayerActor(tempactor,damage);
+            }
+
+         else
+            {
+            if ((tempactor->obclass == collectorobj) && (gamestate.SpawnEluder))
+               return;
+            if (tempactor->hitpoints <= 0)
+               return;
+            DamageNonPlayerActor(tempactor,damage);
+            }
+         }
+      else
+         {
+         tempstat = (statobj_t*)thing;
+
+         MISCVARS->madenoise = true;
+         if (!(tempstat->flags & FL_SHOOTABLE))
+            return;
+         DamageStaticObject(tempstat,damage);
+         }
+      }
+   }
+
+
+void ExplodeStatic(statobj_t*tempstat)
+{
+ //SpawnSolidStatic(tempstat);
+
+ if (tempstat->flags & FL_WOODEN)
+   {
+   SpawnStatic(tempstat->tilex,tempstat->tiley,stat_woodfrag,-1);
+   if ((gamestate.BattleOptions.RespawnItems) &&
+       (tempstat->itemnumber == stat_tntcrate)
+      )
+      {
+      tempstat->linked_to = (long)(LASTSTAT);
+      tempstat->flags |= FL_RESPAWN;
+      }
+
+   }
+ else if (tempstat->flags & FL_METALLIC)
+	SpawnStatic(tempstat->tilex,tempstat->tiley,stat_metalfrag,-1);
+ else
+	SpawnStatic(tempstat->tilex,tempstat->tiley,stat_rubble,-1);
+ LASTSTAT->flags |= (FL_ABP|FL_NONMARK);
+ sprites[tempstat->tilex][tempstat->tiley] = NULL;
+ MakeStatActive(LASTSTAT);
+ SD_PlaySoundRTP(SD_ITEMBLOWSND,tempstat->x,tempstat->y);
+
+
+}
+
+
+
+
+
+void EnableObject(long object)
+   {
+   objtype* ob;
+   int i,gasicon;
+   doorobj_t*tdoor;
+
+   ob = (objtype*)object;
+
+#if (BNACRASHPREVENT == 1)//
+		if (ob == 0){return;}
+#endif
+
+   ob->flags |= FL_ACTIVE;
+   if (ob->obclass == bladeobj)
+      {
+      ParseMomentum(ob,dirangle8[ob->dir]);
+      if (ob->whatever)
+         {
+         objtype *passenger=(objtype*)(ob->whatever);
+
+         passenger->momentumx += ob->momentumx;
+         passenger->momentumy += ob->momentumy;
+         }
+      }
+
+   if (ob->obclass == gasgrateobj)
+      {
+      NewState(ob,&s_gas2);
+      SD_PlaySoundRTP(SD_GASSTARTSND,ob->x,ob->y);
+      ob->dirchoosetime = GASTICS;
+      for(i=0;i<doornum;i++)
+         {
+
+         tdoor = doorobjlist[i];
+         gasicon = MAPSPOT(tdoor->tilex,tdoor->tiley,1);
+         if (gasicon == GASVALUE)
+            LinkedCloseDoor(i);
+         }
+
+      MU_StoreSongPosition();
+      MU_StartSong(song_gason);
+      MISCVARS->GASON = 1;
+      ob->temp3 = 105;
+      }
+   else if (ob->obclass == pillarobj)
+      {
+      ob->flags |= FL_FLIPPED;
+      gamestate.secretcount++;
+      }
+   if (!(ob->flags & FL_ABP))
+      {
+      ob->flags |= FL_ABP;
+      MakeActive(ob);
+      }
+   }
+
+void DisableObject(long object)
+{objtype*ob;
+
+ ob = (objtype*)object;
+ ob->flags &= ~FL_ACTIVE;
+}
+
+
+void T_MoveColumn(objtype* ob)
+{int spot,index;
+
+
+ if (!(ob->flags & FL_ACTIVE))
+  return;
+/*
+ switch (ob->dir)
+  {case north:
+	 ob->momentumy = -PILLARMOM;
+	 break;
+	case south:
+	 ob->momentumy =  PILLARMOM;
+	 break;
+	case east:
+	 ob->momentumx =  PILLARMOM;
+	 break;
+	case west:
+	 ob->momentumx = -PILLARMOM;
+	 break;
+  }
+
+*/
+ ActorMovement(ob);
+ index = touchindices[ob->tilex][ob->tiley];
+ if (index)
+  TRIGGER[index-1] = 1;
+ ob->temp1 -= PILLARMOM;
+
+ if ((ob->temp1 <= 0) || NOMOM)
+  {ZEROMOM;
+	ob->temp1 = 0x20000;
+	ob->flags &= ~FL_ACTIVE;
+	spot = MAPSPOT(ob->tilex,ob->tiley,1)-ICONARROWS;
+	if ((spot >= 0) && (spot <= 7))
+	 {ob->dir = spot;
+     if (!ob->temp2)
+        {
+        gamestate.secrettotal++;
+        }
+     else
+        {
+        ob->flags |= FL_ACTIVE;
+        }
+	  ParseMomentum(ob,dirangle8[ob->dir]);
+	 }
+	else
+	 ob->flags |= FL_DONE;
+
+  }
+}
+
+
+
+boolean NextToDoor(objtype*ob)
+{
+  int tilex,tiley,centerx,centery,dx,dy;
+
+  tilex = ob->tilex;
+  tiley = ob->tiley;
+
+
+  if (M_ISDOOR(tilex+1,tiley) || M_ISDOOR(tilex-1,tiley))
+	{centery = (tiley << TILESHIFT) + HALFGLOBAL1;
+	 dy = abs(ob->y - centery);
+	 if (dy < 0x2000)
+		return true;
+	}
+
+  if (M_ISDOOR(tilex,tiley+1) || M_ISDOOR(tilex,tiley-1))
+	{centerx = (tilex << TILESHIFT) + HALFGLOBAL1;
+	 dx = abs(ob->x - centerx);
+	 if (dx < 0x2000)
+		return true;
+	}
+
+  return false;
+}
+
+
+/*
+=================
+=
+= T_Use
+=
+=================
+*/
+
+
+void T_Use(objtype*ob)
+{if (ob->ticcount)
+	return;
+
+ switch (ob->obclass)
+  {
+#if (SHAREWARE == 0)
+   case b_darianobj:
+    if (!DoPanicMapping())
+       touchsprite->flags |= FL_ACTIVE;
+	 if ((!sprites[PLAYER[0]->tilex][PLAYER[0]->tiley]) && (ob->areanumber == PLAYER[0]->areanumber))
+	  {SpawnNewObj(PLAYER[0]->tilex,PLAYER[0]->tiley,&s_dspear1,spearobj);
+		new->flags |= (FL_ABP);//|FL_INVULNERABLE);
+		new->z = 0;
+		MakeActive(new);
+	  }
+	 ZEROMOM;
+	 ob->flags |= FL_STUCK;
+	 SD_PlaySoundRTP(SD_DARIANUSESND,ob->x,ob->y);
+	 //NewState(ob,&s_darianspears);
+	 break;
+#endif
+  default:
+      ;
+  }
+
+
+}
+
+
+
+
+
+#define RollStart(ob,state,angle)     \
+   {                                  \
+   int oldspeed = ob->speed;          \
+                                      \
+   ob->speed = ROLLMOMENTUM+0x200;    \
+   NewState(ob,state);                \
+   ParseMomentum(ob,angle);           \
+   ob->speed = oldspeed;              \
+   }                                  \
+
+
+
+
+
+void AvoidPlayerMissile(objtype*ob)
+   {
+   objtype *temp;
+   int dx,dy,dz;
+   int magangle,angle1,rollangle1,rollangle2,dangle1,dangle2;
+
+   if (PLAYER0MISSILE == NULL)
+      return;
+
+   if (GameRandomNumber("scott missile avoid",0) > 160)
+      return;
+
+   if (ob->momentumz)
+      return;
+
+   if ((ob->state->think == T_Roll) || (ob->state->think == T_Reset))
+      return;
+
+   temp = PLAYER0MISSILE;
+
+   dx = abs(temp->x - ob->x);
+   dy = abs(ob->y - temp->y);
+   dz = abs(ob->z - temp->z);
+   angle1 = AngleBetween(temp,ob);
+   magangle = abs(temp->angle - angle1);
+
+   if (magangle > VANG180)
+      magangle = ANGLES - magangle;
+
+
+   if ((magangle > ANGLES/48) || (dx > 0x50000) || (dy > 0x50000) ||
+       (dz > 32))
+      return;
+
+   rollangle1 = angle1 + ANGLES/4;
+   Fix(rollangle1);
+   dangle1 = abs(temp->angle - rollangle1);
+   if (dangle1 > VANG180)
+      dangle1 = ANGLES - dangle1;
+
+   rollangle2 = angle1 - ANGLES/4;
+   Fix(rollangle2);
+   dangle2 = abs(temp->angle - rollangle2);
+   if (dangle2 > VANG180)
+      dangle2 = ANGLES - dangle2;
+
+   ob->momentumx = ob->momentumy = 0;
+
+   if (dangle1 > dangle2)
+      {
+      RollStart(ob,&s_strikerollleft1,rollangle1);
+      }
+   else
+      {
+      RollStart(ob,&s_strikerollright1,rollangle2);
+      }
+   ob->flags |= FL_NOFRICTION;
+
+   ob->target = PLAYER[0];
+   //SelectRollDir(ob);
+
+
+   }
+
+
+
+
+/*
+=================
+=
+= T_Chase
+=
+=================
+*/
+
+void T_Chase (objtype *ob)
+{
+	int   dx,dy,dz,dist,chance;
+	classtype ocl;
+	statetype *temp;
+	boolean doorok;
+
+	ocl = ob->obclass;
+
+
+   if ((ocl == deathmonkobj) || (ocl == blitzguardobj))
+	 {dx = abs(PLAYER[0]->x - ob->x);
+	  dy = abs(ob->y - PLAYER[0]->y);
+	  dz = abs(ob->z - PLAYER[0]->z);
+
+	  if ((dx < TOUCHDIST) && (dy < TOUCHDIST) && (dz < (TOUCHDIST >> 10)))
+       {
+#if (SHAREWARE == 0)
+        if (ocl == deathmonkobj)
+           {NewState(ob,&s_dmonkshoot1);
+            STOPACTOR(ob);
+            return;
+
+           }
+        else
+#endif
+          if ((!ob->temp3) && (PLAYERSTATE[0].missileweapon != -1) &&
+                 (PLAYERSTATE[0].missileweapon < wp_godhand))
+           {NewState(ob,&s_blitzsteal1);
+            STOPACTOR(ob);
+            return;
+           }
+       }
+	 }
+
+	ob->flags &= ~FL_DODGE;
+
+	//if (CheckLine(ob,PLAYER[0],DIRCHECK) && (ocl != roboguardobj))
+
+	if (!ob->ticcount)
+	 {if (CheckLine(ob,PLAYER[0],SIGHT))   // got a shot at player?
+		 {if (ocl != roboguardobj)
+			 {ob->targettilex = PLAYER[0]->x;
+			  ob->targettiley = PLAYER[0]->y;
+			 }
+		 }
+
+     if (CheckLine(ob,PLAYER[0],SHOOT) && (!(player->flags&FL_DYING)))   // got a shot at player?
+		 {
+		  dx = abs(ob->tilex - PLAYER[0]->tilex);
+		  dy = abs(ob->tiley - PLAYER[0]->tiley);
+		  dist = (dx>dy)?(dx):(dy);
+		  if ((!dist) || (dist==1))
+				chance = 300;
+		  else if (ocl >= b_darianobj)
+				chance = 400/dist;
+		  else
+				chance = 300/dist;
+
+		  if (GameRandomNumber("T_Chase",ocl) <chance)
+			 {if ((ocl == b_heinrichobj) && (Near(ob,PLAYER[0],4)))
+				 goto cdoor;
+
+			  ob->dir = angletodir[AngleBetween(ob,PLAYER[0])];
+			  STOPACTOR(ob);
+#if (SHAREWARE == 0)
+			  if ((ocl == overpatrolobj) && (!Near(ob,PLAYER[0],3)) &&
+					(!PLAYERSTATE[0].NETCAPTURED) && (!MISCVARS->NET_IN_FLIGHT))
+				  {NewState(ob,&s_opbolo1);
+					MISCVARS->NET_IN_FLIGHT = true;
+					return;
+				  }
+#endif
+			  if ((ocl == triadenforcerobj) && (!Near(ob,PLAYER[0],3)))
+				 {NewState(ob,&s_enforcerthrow1);
+				  return;
+				 }
+
+			  if ((temp=M_S(AIM)) != NULL)
+				 {if ((ob->flags & FL_HASAUTO) && (!ob->temp3))
+					 ob->temp3 = (GameRandomNumber("T_Chase FL_HASAUTO",ocl) % 5) + 3;
+				  ob->target = PLAYER[0];
+				  NewState(ob,temp);
+				  return;
+				 }
+
+			 }
+		  //if ((CheckSight(ob,PLAYER[0])) && (!ob->angle))// &&
+				//(ocl != b_heinrichobj))
+			 //ob->flags |= FL_DODGE;
+		 }
+
+	 }
+cdoor:
+	doorok = NextToDoor(ob);
+
+
+	if (ob->dirchoosetime)
+	  ob->dirchoosetime--;
+
+	if ((ob->flags & FL_STUCK) || (!ob->dirchoosetime) || doorok)
+	  {//if (ob->flags & FL_DODGE)
+		// SelectDodgeDir(ob);
+		//else
+		SelectChaseDir(ob);
+		ob->dirchoosetime = M_CHOOSETIME(ob);
+	  }
+
+	else
+	  {if (NOMOM)
+		  ParseMomentum(ob,dirangle8[ob->dir]);
+		ActorMovement(ob);
+	  }
+}
+
+
+
+void SpawnMissile(objtype* shooter,classtype nobclass,int nspeed,int nangle,statetype*nstate,int offset)
+   {
+   GetNewActor();
+   MakeActive(new);
+   new->which = ACTOR;
+   new->obclass = nobclass;
+   new->angle = nangle;
+   new->speed = nspeed;
+   if (shooter->obclass == playerobj)
+      offset += FindDistance(shooter->momentumx,shooter->momentumy);
+
+   SetFinePosition(new,shooter->x + FixedMul(offset,costable[nangle]),
+                      shooter->y - FixedMul(offset,sintable[nangle]));
+   SetVisiblePosition(new,new->x,new->y);
+  //SoftError("\n missx:%d, missy:%d, speed:%d, offset:%d, angle%d, drawx:%d, drawy:%d",
+    //         new->x,new->y,nspeed,offset,nangle,new->drawx,new->drawy);
+
+   new->z = shooter->z;
+   new->areanumber = shooter->areanumber;
+   new->soundhandle = -1;
+   if (nobclass != inertobj)
+      {
+      MakeLastInArea(new);
+      if (MissileSound == true)
+         new->soundhandle = SD_PlaySoundRTP(BAS[new->obclass].operate,new->x,new->y);
+      }
+
+   if ((shooter->obclass == playerobj) || (shooter->obclass == wallopobj) ||
+       (shooter->obclass == b_robobossobj))
+      {
+      Set_3D_Momenta(new,new->speed,new->angle,shooter->yzangle);
+
+      if (nobclass == p_drunkmissileobj)
+         new->temp1 = new->momentumz;
+
+      new->z -= FixedMulShift(offset,sintable[shooter->yzangle],26);
+      if ((shooter->obclass == playerobj) && (shooter->flags & FL_GODMODE))
+         new->z -= 10;
+      }
+   else
+      ParseMomentum(new,new->angle);
+
+   if (nobclass == p_drunkmissileobj)
+      new->temp3 = VBLCOUNTER/3;
+
+
+   new->flags |= (FL_NEVERMARK|FL_ABP|FL_NOFRICTION|FL_FULLLIGHT);
+   new->whatever = shooter; // keep track of missile possession
+   NewState(new,nstate);
+   }
+
+
+
+/*
+=================
+=
+= T_Roll
+=
+=================
+*/
+
+
+void T_Roll (objtype *ob)
+{
+  ActorMovement(ob);
+
+}
+
+
+
+
+/*
+===============
+=
+= T_Path
+=
+===============
+*/
+
+void T_Path (objtype *ob)
+   {int dx,dy,dz,ocl,damage=1;
+   objtype*temp,*ttarg,*twhat;
+
+
+   ocl = ob->obclass;
+
+   if (((ocl == firejetobj) || (ocl == bladeobj)) && (!ob->ticcount))
+      {
+      if (ocl == bladeobj)
+         {
+         if (ob->state->condition & SF_DOWN )
+            ob->flags &= ~FL_BLOCK;
+         else if (ob->state->condition & SF_UP)
+            {
+            ob->flags |= FL_BLOCK;
+            damage = 0;
+            }
+         }
+
+      if ((ob->state->condition & SF_SOUND) && areabyplayer[ob->areanumber])
+         SD_PlaySoundRTP(BAS[ob->obclass].operate,ob->x,ob->y);
+
+      if (damage)
+         {
+         for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
+            {
+            if (temp == ob)
+               continue;
+
+            if (temp->obclass >= roboguardobj)
+               continue;
+
+            //WAS
+            ttarg = (objtype*)(temp->target);
+            twhat = (objtype*)(temp->whatever);
+
+            if ((M_ISACTOR(ttarg) && (ttarg->obclass == b_robobossobj)) ||
+                (M_ISACTOR(twhat) && (twhat->obclass == b_robobossobj))
+               )
+               continue;
+
+            if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
+               continue;
+
+            if (temp->obclass == playerobj)
+               {
+               if ((temp->flags & FL_GODMODE) || (temp->flags & FL_DOGMODE))
+                  continue;
+               if ((temp->flags & FL_AV) && (ocl == firejetobj))
+                  continue;
+               }
+            dx = temp->x - ob->x;
+            if (abs(dx) > 0xa000)
+               continue;
+            dy = temp->y - ob->y;
+            if (abs(dy) > 0xa000)
+               continue;
+
+            //if (temp->obclass == playerobj)
+            //Collision(temp,-temp->momentumx+ob->momentumx,-temp->momentumy + ob->momentumy);
+            dz = temp->z - ob->z;
+            if (abs(dz) > 32)
+               continue;
+
+            DamageThing(temp,EnvironmentDamage(ob));
+            if ((ocl == firejetobj) && (temp->obclass < roboguardobj))
+               SD_PlaySoundRTP(SD_PLAYERBURNEDSND,temp->x,temp->y);
+
+            if ((gamestate.violence == vl_excessive) && (temp->obclass < roboguardobj))
+               {
+               if (ocl == bladeobj)
+                  {
+                  SpawnParticles(temp,GUTS,1);
+                  if (temp->hitpoints <= 0)
+                     temp->flags |= FL_HBM;
+                  }
+               else if (ocl == firejetobj)
+                  {
+                  if ((temp->hitpoints <= 0) && (temp->z == nominalheight))
+                     {
+
+                     temp->hitpoints = 0;
+                     temp->flags |= FL_SKELETON;
+                     if (temp->obclass == playerobj)
+                        {
+                        playertype *pstate;
+
+                        temp->flags &= ~FL_COLORED;
+                        M_LINKSTATE(temp,pstate);
+                        pstate->health = 0;
+                        pstate->weapon = -1;
+                        }
+
+                     Collision(temp,ob,-temp->momentumx,-temp->momentumy);
+                     M_CheckPlayerKilled(temp);
+
+                     continue;
+                     }
+                  }
+               }
+               //SD_PlaySoundRTP(SD_ACTORBURNEDSND,temp->x,temp->y);
+
+   //        if ((ocl == bladeobj) || (ob->state->condition == SF_CRUSH))
+            Collision(temp,ob,-temp->momentumx,-temp->momentumy);
+            M_CheckPlayerKilled(temp);
+
+            }
+         }
+      }
+
+
+   if (ob->dir == nodir)
+      return;
+
+   if ((ocl != firejetobj) && (ocl != bladeobj) && (ocl != diskobj))
+      {
+       if (!ob->ticcount)
+          {
+          if (SightPlayer (ob))
+             return;
+          }
+       else
+          SoftError("\n ob type %s with ticcount %d in T_Path",
+                     debugstr[ob->obclass],ob->ticcount);
+      }
+
+   SelectPathDir (ob);
+   if (NOMOM)
+      ParseMomentum(ob,dirangle8[ob->dir]);
+   }
+
+
+
+int EnvironmentDamage(objtype *ob)
+   {
+   if (BATTLEMODE && (gamestate.BattleOptions.DangerDamage != bo_danger_normal))
+      {
+      return(gamestate.BattleOptions.DangerDamage);
+      }
+   else
+      {
+      int damage = 1;
+
+      switch(ob->obclass)
+         {
+         case firejetobj:
+         case bladeobj:
+            damage = 6;
+            break;
+
+         case boulderobj:
+            damage = 50;
+            break;
+
+         case spearobj:
+            damage = 7;
+            break;
+
+         case gasgrateobj:
+            damage = 20;
+            break;
+
+         case wallfireobj:
+            damage = ((GameRandomNumber("wallfire damage",0) >>3) + 10);
+            break;
+
+         case crushcolobj:
+            damage = 10;
+            break;
+	 default:
+	     ;
+         }
+
+      if (gamestate.difficulty < gd_hard)
+         damage >>= 1;
+
+      return damage;
+      }
+   //SoftError("unknown environment danger");
+
+   }
+
+
+
+
+void T_AutoShootAlign(objtype*ob)
+{
+  if (ob->dir != (dirtype)ob->temp1)
+	 ob->dir = dirorder16[ob->dir][NEXT];
+  else
+	 NewState(ob,M_S(AIM));
+
+}
+
+
+void T_AutoRealign(objtype*ob)
+{
+  if (ob->dir != (dirtype)ob->targettilex)
+	 ob->dir = dirorder16[ob->dir][NEXT];
+  else
+	 {objtype *temp;
+
+	  NewState(ob,M_S(PATH));
+	  for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
+		  {if (temp == ob)
+			  continue;
+			if (temp->obclass != ob->obclass)
+			  continue;
+			if (!temp->state->think)
+			  NewState(temp,UPDATE_STATES[PATH][temp->obclass-lowguardobj]);
+		  }
+	 }
+}
+
+
+/*
+===============
+=
+= T_AutoPath
+=
+===============
+*/
+
+void T_AutoPath (objtype *ob)
+{objtype *temp;
+
+	// ob->temp3 holds random number of shots before resuming path
+
+  if (CheckLine(ob,PLAYER[0],SIGHT) && (Near(ob,PLAYER[0],4) || MISCVARS->madenoise))
+
+	 {int dx,dy,destdir,ocl;
+	  statetype *align,*wait;
+
+	  ocl = ob->obclass;
+	  dx = player->x - ob->x;
+	  dy = ob->y - player->y;
+	  destdir = (angletodir[atan2_appx(dx,dy)] << 1);
+	  ob->temp1 = destdir;
+	  ob->targettilex = ob->dir; //save old dir
+#if (SHAREWARE == 0)
+     if (ocl == wallopobj)
+		  {//if (ob->temp3)
+			 // Error("may be writing over temp3");
+			ob->temp3 = (GameRandomNumber("T_WallPath",0)%4) + 1;
+			align = &s_wallalign;
+			wait = &s_wallwait;
+		  }
+	  else
+#endif
+        {align = &s_roboalign;
+			wait = &s_robowait;
+		  }
+
+	  NewState(ob,align);
+	  for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
+		 {if (temp == ob)
+			 continue;
+
+		  if (temp->obclass != ob->obclass)
+			 continue;
+
+		  if (temp->flags & FL_DYING)
+			 continue;
+
+		  if (CheckLine(temp,PLAYER[0],SIGHT) && (Near(temp,PLAYER[0],4) || MISCVARS->madenoise))
+			 {dx = PLAYER[0]->x - temp->x;
+			  dy = temp->y - PLAYER[0]->y;
+			  destdir = (angletodir[atan2_appx(dx,dy)] << 1);
+
+			  temp->temp1 = destdir;
+			  temp->targettilex = temp->dir;
+			  NewState(temp,align);
+			  temp->temp3 = ob->temp3;
+			 }
+		  else
+			 NewState(temp,wait);
+		 }
+	  return;
+	 }
+
+  SD_PlaySoundRTP(SD_ROBOTMOVESND,ob->x,ob->y);
+
+  SelectPathDir(ob);
+
+}
+
+
+
+
+/*
+===============
+=
+= A_Shoot
+=
+= Try to damage the player, based on skill level and player's speed
+=
+===============
+*/
+
+void A_Shoot (objtype *ob)
+{
+	int   dx,dy,dz,dist;
+	int   accuracy,damage,sound;
+	objtype * target;
+	int   num;
+	int   savedangle;
+
+ ActorMovement(ob);
+
+ ob->flags |= FL_FULLLIGHT;
+ //if (!(ob->flags & FL_SHOOTABLE))
+  //Error("\na dead instance of %s is shooting at you",debugstr[ob->obclass]);
+
+ if (!ob->ticcount)
+  {if (ob->obclass == strikeguardobj)
+	 ob->flags &= ~FL_NOFRICTION;
+
+	target = (objtype*)(ob->target);
+   if (!target)
+      Error("an instance of %s called shoot without a target\n",debugstr[ob->obclass]);
+
+
+   ob->flags &= ~FL_FULLLIGHT;
+
+
+	dx = (target->x - ob->x);
+	dy = (ob->y - target->y);
+	dz = target->z-ob->z;
+
+
+   if ((ob->obclass == blitzguardobj) && (ob->temp3) &&
+       (ob->temp3 != stat_gasmask) && (ob->temp3 != stat_asbesto) &&
+       (ob->temp3 != stat_bulletproof) &&
+       (gamestate.difficulty >= gd_medium) &&
+       ((abs(dx) > 0xc000) || (abs(dy) > 0xc000))
+      )
+      {
+      int i;
+      missile_stats* newmissiledata;
+
+      newmissiledata = &PlayerMissileData[GetWeaponForItem(ob->temp3)];
+
+      // ready to annihilate this poor bastard
+
+      SpawnMissile(ob,newmissiledata->obclass,newmissiledata->speed,
+                   AngleBetween(ob,player), newmissiledata->state,
+                   newmissiledata->offset);
+
+      if (newmissiledata->obclass == p_drunkmissileobj)
+         {
+         for(i=0;i<4;i++)
+            {
+            SpawnMissile(ob,newmissiledata->obclass,newmissiledata->speed,
+                        AngleBetween(ob,player), newmissiledata->state,
+                        newmissiledata->offset);
+            }
+         }
+      ob->target = NULL;
+      ob->temp2 --;
+      if (ob->temp2 == 0)
+         ob->temp3 = 0;
+      return;
+      }
+
+
+   if ((!areabyplayer[ob->areanumber]) && (target->obclass ==  playerobj))
+		return;
+
+	//if (!CheckLine(ob,target,SHOOT))       // player is behind a wall
+	  //return;
+
+
+	savedangle=ob->angle;
+	ob->angle = atan2_appx (dx,dy);
+	dist = FindDistance(dx,dy);
+	ob->yzangle = FINEANGLES-atan2_appx(dist, dz<<10);
+
+	if ((ob->yzangle>MAXYZANGLE) && (ob->yzangle<FINEANGLES-MAXYZANGLE))
+		ob->yzangle=MAXYZANGLE;
+
+	dist>>=16;
+
+   accuracy=(WHICHACTOR<<4)+((gamestate.difficulty) << 6);
+
+	num = GameRandomNumber("A_Shoot3",ob->obclass);
+
+	if (num<128) num=128; // Don't let accuracy fall below 50% original
+
+	accuracy=FixedMulShift(num,accuracy,8); // scale accuracy based off randomness
+
+	// check for maximum accuracy;
+
+	if (accuracy>255) accuracy=255;
+
+	if (ob->obclass==highguardobj)
+		damage=DMG_MP40;
+	else if (ob->obclass == triadenforcerobj)
+		damage=DMG_MP40;
+	else
+      damage=DMG_ENEMYBULLETWEAPON;
+
+
+	RayShoot (ob, damage, 255-accuracy);
+
+	ob->angle=savedangle;
+	sound = BAS[ob->obclass].fire;
+	SD_PlaySoundRTP(sound,ob->x,ob->y);
+	MISCVARS->madenoise = true;
+	if ((!(ob->flags& FL_HASAUTO)) || (!ob->temp3))
+	 ob->target = NULL;
+  }
+}
+
+
+
+
+void A_Repeat(objtype*ob)
+{
+ ActorMovement(ob);
+
+ if (!ob->ticcount)
+  {ob->temp3 --;
+   if (ob->temp3 <= 0)
+	  NewState(ob,M_S(CHASE));
+  }
+
+}
+
+
+void  A_MissileWeapon(objtype *ob)
+{
+ int    sound,nspeed,noffset,zoffset;
+
+#if (SHAREWARE == 0)
+ int oldyzangle;
+#endif
+ classtype nobclass;
+ statetype*nstate;
+
+
+ if ((ob->obclass == wallopobj) || (ob->obclass == roboguardobj));
+	//SelectPathDir(ob);
+ else
+	ActorMovement(ob);
+
+ if (!ob->ticcount)
+  {
+#if (SHAREWARE == 0)
+   if ((ob->obclass == wallopobj) && (!ob->temp3))
+      {
+      NewState(ob,&s_wallrestore);
+      return;
+      }
+#endif
+	if ((ob->obclass == b_darianobj) && (!CheckLine(ob,PLAYER[0],SHOOT)))
+	 {NewState(ob,M_S(CHASE));
+	  return;
+	 }
+ // Move sounds, flags into switch cases
+
+	sound = BAS[ob->obclass].fire;
+	nspeed = 0x4000;
+	noffset = 0x8000;
+	zoffset = 0;
+	switch (ob->obclass)
+    {
+
+	  case triadenforcerobj:
+		nobclass = grenadeobj;
+		nstate= &s_grenade1;
+		sound++;
+		break;
+
+
+	  case roboguardobj:
+		nobclass = shurikenobj;
+		nspeed = 0x2000;
+		noffset = 0x10000;
+		nstate = &s_robogrdshuriken1;
+		break;
+
+	 /*
+	  case b_darkmonkobj:
+		nobclass = dmfballobj;
+		nstate = &s_dmfball1;
+		break;
+	  */
+	  /*
+	  case b_robobossobj:
+		nobclass = bigshurikenobj;
+		nstate = &s_oshuriken1;
+		break;
+		 */
+#if (SHAREWARE == 0)
+	  case b_darianobj:
+		nobclass = missileobj;
+		//nspeed = 0x100;
+		//noffset = 0x18000;
+		nstate = &s_missile1;
+		zoffset = -20;
+		break;
+
+
+     case dfiremonkobj:
+		nobclass = fireballobj;
+		nstate = &s_monkfire1;
+		break;
+
+
+     case overpatrolobj:
+		nobclass = netobj;
+		nstate = &s_bolocast1;
+		sound ++;
+		break;
+
+
+     case wallopobj:
+		 {int dx,dy,dz,xydist;
+
+		  ob->temp2 ^= 1; // increment numfired
+		  ob->temp3 --; // decrement random fire no.
+
+
+		  dx = PLAYER[0]->x-ob->x;
+		  dy = ob->y-PLAYER[0]->y;
+		  if (GameRandomNumber("bcraft shoot up/down",0) < 128)
+			 dz = 10;
+		  else
+			 dz = -10;
+		  xydist = FindDistance(dx,dy);
+		  oldyzangle = ob->yzangle;
+		  ob->yzangle = atan2_appx(xydist,dz<<10);
+		  if (ob->temp2)
+			 {nobclass = missileobj;
+			  nstate = &s_missile1;
+			 }
+		  else
+			 {nobclass = bigshurikenobj;
+			  nstate = &s_bstar1;
+			 }
+		 }
+		break;
+#endif
+    default:
+	;
+    }
+
+	SpawnMissile(ob,nobclass,nspeed,AngleBetween(ob,PLAYER[0]),nstate,noffset);
+	new->z += zoffset;
+	SD_PlaySoundRTP(sound,ob->x,ob->y);
+	MISCVARS->madenoise = true;
+	if (ob->obclass == triadenforcerobj)
+	  {//new->flags |= (FL_SHOOTABLE);
+		new->temp1 = 0x50000;
+	  }
+#if (SHAREWARE == 0)
+	else if (ob->obclass == wallopobj)
+	  ob->yzangle = oldyzangle;
+#endif
+
+
+  }
+}
+
+
+void   A_Wallfire(objtype *ob)
+{
+ if (!(ob->flags & FL_ACTIVE))
+  return;
+
+ if (!ob->ticcount)
+  {SpawnMissile(ob,wallfireobj,0x4000,ob->angle,&s_crossfire1,0xa000);
+	if (areabyplayer[ob->areanumber])
+	  SD_PlaySoundRTP(SD_FIRECHUTESND,ob->x,ob->y);
+	new->dir = angletodir[new->angle];
+	new->z = nominalheight;
+  }
+
+}
+
+
+void T_Reset(objtype *ob)
+{
+ ActorMovement(ob);
+
+ if (ob->ticcount)
+	return;
+
+ ob->momentumx = ob->momentumy = ob->dirchoosetime = 0;
+ ob->flags &= ~FL_NOFRICTION;
+
+
+
+}
+
+void SelectRollDir(objtype *ob)
+{int angle,tryx,tryy;
+
+
+ if (ob->state == &s_strikerollright1)
+  angle = AngleBetween(ob,PLAYER[0]) + ANGLES/4;
+ else
+  angle = AngleBetween(ob,PLAYER[0]) - ANGLES/4;
+
+ Fix(angle);
+ tryx = ob->x + FixedMul(0x20000l,costable[angle]);
+ tryy = ob->y - FixedMul(0x20000l,sintable[angle]);
+ ZEROMOM;
+ if (QuickSpaceCheck(ob,tryx,tryy))
+	{int oldspeed;
+
+	 oldspeed = ob->speed;
+	 ob->speed = ROLLMOMENTUM;
+	 ParseMomentum(ob,angle);
+	 ob->speed = oldspeed;
+	 ob->dirchoosetime = 5;
+	 ob->flags |= FL_NOFRICTION;
+	}
+ else
+  ob->dirchoosetime = 0;
+
+
+}
+
+
+void SelectDodgeDir (objtype *ob)
+{
+	int      dx,dy,i,tx,ty;
+	unsigned absdx,absdy;
+	dirtype  dirtry[5];
+	dirtype  turnaround,tdir,olddir;
+
+
+	olddir = ob->dir;
+	if (ob->flags & FL_FIRSTATTACK)
+	{
+	//
+	// turning around is only ok the very first time after noticing the
+	// player
+	//
+		turnaround = nodir;
+		ob->flags &= ~FL_FIRSTATTACK;
+	}
+	else
+		turnaround=opposite[ob->dir];
+
+
+	if (ob->targettilex || ob->targettiley)
+		{tx = ob->targettilex;
+		 ty = ob->targettiley;
+		 dx= tx - ob->x;
+		 dy= ty - ob->y;
+		 if ( ((dx < MINACTORDIST) && (dx > -MINACTORDIST)) &&
+				((dy < MINACTORDIST) && (dy > -MINACTORDIST)))
+		  {dx= PLAYER[0]->x-ob->x;
+			dy= PLAYER[0]->y-ob->y;
+		  }
+		}
+	  else
+   	  {dx= PLAYER[0]->x-ob->x;
+			dy= PLAYER[0]->y-ob->y;
+		  }
+
+
+
+//
+// arange 5 direction choices in order of preference
+// the four cardinal directions plus the diagonal straight towards
+// the player
+//
+	if (dx>ACTORSIZE)
+	{
+		dirtry[1]= east;
+		dirtry[3]= west;
+	}
+	else if (dx < -ACTORSIZE)
+	{
+		dirtry[1]= west;
+		dirtry[3]= east;
+	}
+
+	if (dy>ACTORSIZE)
+	{
+		dirtry[2]= south; // south
+		dirtry[4]= north; // north
+	}
+	else if (dy <-ACTORSIZE)
+	{
+		dirtry[2]= north; // north
+		dirtry[4]= south; // south
+	}
+
+//
+// randomize a bit for dodging
+//
+	absdx = abs(dx);
+	absdy = abs(dy);
+
+	if (absdx > absdy)
+	{
+		tdir = dirtry[1];
+		dirtry[1] = dirtry[2];
+		dirtry[2] = tdir;
+		tdir = dirtry[3];
+		dirtry[3] = dirtry[4];
+		dirtry[4] = tdir;
+	}
+
+	if (GameRandomNumber("SelectDogeDir",ob->obclass) < 128)
+	{
+		tdir = dirtry[1];
+		dirtry[1] = dirtry[2];
+		dirtry[2] = tdir;
+		tdir = dirtry[3];
+		dirtry[3] = dirtry[4];
+		dirtry[4] = tdir;
+	}
+
+	dirtry[0] = diagonal [dirtry[1]] [dirtry[2]];
+
+	ZEROMOM;
+
+	for (i=0;i<5;i++)
+	  {if ((dirtry[i] == nodir) || (dirdiff[dirtry[i]][olddir] > 1))
+		 continue;
+
+		M_CHECKDIR(ob,dirtry[i]);
+	}
+
+//
+// turn around only as a last resort
+//
+//	for(tdir = east;tdir<=southeast;tdir++)
+	//if (tdir != turnaround)
+//	 M_CHECKDIR(ob,tdir);
+
+	if (turnaround != nodir)
+	 M_CHECKDIR(ob,turnaround);
+
+}
+
+
+
+
+#define TryAbruptProximalDirections(trydir)             \
+   {                                                    \
+   next = dirorder[trydir][NEXT];                       \
+   prev = dirorder[trydir][PREV];                       \
+   if (GameRandomNumber("actor choose dir",0) < 128)    \
+      {                                                 \
+      dirtype temp = next;                              \
+                                                        \
+      next = prev;                                      \
+      prev = temp;                                      \
+      }                                                 \
+                                                        \
+   if (!dirtried[next])                                 \
+      {                                                 \
+      M_CHECKDIR(ob,next);                              \
+      dirtried[next]=1;                                 \
+      }                                                 \
+                                                        \
+   if (!dirtried[prev])                                 \
+      {                                                 \
+      M_CHECKDIR(ob,prev);                              \
+      dirtried[prev]=1;                                 \
+      }                                                 \
+                                                        \
+   }
+
+
+#define TrySmoothProximalDirections(trydir)                        \
+   {                                                               \
+                                                                   \
+   if (((trydir == olddir) || (dirdiff[trydir][olddir] < 2)) &&    \
+      (!dirtried[trydir]))                                         \
+      {                                                            \
+      M_CHECKDIR(ob,trydir);                                       \
+      dirtried[trydir] = 1;                                        \
+      }                                                            \
+   next = dirorder[olddir][NEXT];                                  \
+   prev = dirorder[olddir][PREV];                                  \
+                                                                   \
+   if (dirdiff[trydir][next] <= dirdiff[trydir][prev])             \
+      {                                                            \
+      start = next;                                                \
+      whichway = NEXT;                                             \
+      }                                                            \
+   else                                                            \
+      {                                                            \
+      start = prev;                                                \
+      whichway = PREV;                                             \
+      }                                                            \
+                                                                   \
+   for (tdir= start; tdir != dirorder[trydir][whichway];           \
+        tdir = dirorder[tdir][whichway]                            \
+       )                                                           \
+      {                                                            \
+      if (dirtried[tdir])                                          \
+         continue;                                                 \
+      M_CHECKDIR(ob,tdir);                                         \
+      dirtried[tdir]=1;                                            \
+      }                                                            \
+                                                                   \
+   }
+
+
+
+#define ChasePlayer(ob)                          \
+   {                                             \
+   dx= player->x-ob->x;                          \
+   dy= ob->y-player->y;                          \
+   if ((abs(dx) < 0xb000) && (abs(dy) < 0xb000)) \
+      return;                                    \
+   dummy.x = player->x;                          \
+   dummy.y = player->y;                          \
+   }
+
+
+void SelectChaseDir (objtype *ob)
+   {
+	int dx,dy,whichway,tx,ty,actrad,visible,
+		 realdiff;
+	dirtype dtry1,dtry2,tdir,olddir,next,prev,start,straight;
+	tpoint dummy;
+	byte dirtried[9] = {0};
+
+	olddir=ob->dir;
+	visible = CheckLine(ob,PLAYER[0],SIGHT);
+
+	/*
+	if (ob->flags & FL_FIRSTATTACK)
+	{
+	//
+	// turning around is only ok the very first time after noticing the
+	// player
+	//
+		turnaround = opposite[ob->dir];
+		ob->flags &= ~FL_FIRSTATTACK;
+	}
+	else
+		turnaround=nodir;
+	*/
+	dummy.which = ACTOR;
+	dummy.z = ob->z;
+	if (ob->targettilex || ob->targettiley)
+      {
+      tx = ob->targettilex;
+      ty = ob->targettiley;
+      dx= tx - ob->x;
+      dy= ob->y - ty;
+      dummy.x = tx;
+      dummy.y = ty;
+      if ((abs(dx) < 0x2000) && (abs(dy) < 0x2000))
+         ChasePlayer(ob);
+		}
+	else
+      ChasePlayer(ob);
+
+	//if ((abs(dx) < 0x10000) && (abs(dy) < 0x10000))
+	 //return;
+	straight = angletodir[atan2_appx(dx,dy)];
+	realdiff = dirdiff[straight][ob->dir];
+	ZEROMOM;
+
+   //insertion 20
+
+	actrad = ACTORSIZE;
+	dtry1=nodir;
+	dtry2=nodir;
+
+	if (dx> actrad)
+		dtry1= east;
+	else if (dx< -actrad)
+		dtry1= west;
+	if (dy> actrad)
+		dtry2=north;
+	else if (dy < -actrad)
+		dtry2= south;
+
+
+	if (abs(dy)>abs(dx))
+      {
+      tdir=dtry1;
+      dtry1=dtry2;
+      dtry2=tdir;
+      }
+
+	if (GameRandomNumber("chase minor",0) < 80)
+      {
+      tdir=dtry1;
+      dtry1=dtry2;
+      dtry2=tdir;
+      }
+
+	ZEROMOM;
+
+	if ((!visible) || (realdiff > 2))  // don't worry about abrupt or unrealistic turns if player
+						// can't see guards
+      {
+      M_CHECKDIR(ob,straight);
+      dirtried[straight]=1;
+      next = dirorder[straight][NEXT];
+      prev = dirorder[straight][PREV];
+
+      if ((dtry1 != nodir) && (dtry1 != straight))
+         {
+         M_CHECKDIR(ob,dtry1);
+         dirtried[dtry1]=1;
+         }
+
+
+      if ((dtry2 != nodir) && (!dirtried[dtry2]))
+         {
+         M_CHECKDIR(ob,dtry2);
+         dirtried[dtry2]=1;
+         }
+
+      if (dtry1 != nodir)
+         TryAbruptProximalDirections(dtry1);
+
+      if (dtry2 != nodir)
+         TryAbruptProximalDirections(dtry2);
+		}
+
+   else
+      {
+      if (realdiff < 2)
+         {
+         M_CHECKDIR(ob,straight);
+         dirtried[straight]=1;
+         }
+
+      if (dtry1 != nodir)
+         TrySmoothProximalDirections(dtry1);
+
+      if (dtry2 != nodir)
+         TrySmoothProximalDirections(dtry2);
+
+		}
+
+	if ((dtry1!=nodir) || (dtry2!=nodir))
+      {
+      if (GameRandomNumber("actor choose dir",0) < 128)
+         whichway = NEXT;
+      else
+         whichway = PREV;
+
+      for(tdir = dirorder[olddir][whichway];tdir != olddir;tdir = dirorder[tdir][whichway])
+         {
+         if (dirtried[tdir])
+            continue;
+         M_CHECKDIR(ob,tdir);
+         }
+      }
+
+   ob->dir = olddir;
+   }
+
+
+
+int Near(objtype *ob,void* what,int distance)
+
+{
+ objtype *aw;
+
+ aw = (objtype*) what;
+
+ if (FindDistance((aw->x - ob->x),(aw->y - ob->y)) <= (distance<<16))
+    return 1;
+ return 0;
+
+}
+
+
+
+/*
+===============
+=
+= SelectPathDir
+=
+===============
+*/
+
+void SelectPathDir (objtype *ob)
+   {
+	int spot,centerx,centery,dx,dy,set,done,radius,ocl;
+
+	ocl = ob->obclass;
+
+
+	if ((ocl == bladeobj) && (!(ob->flags & FL_ACTIVE)))
+	  return;
+
+	spot = MAPSPOT(ob->tilex,ob->tiley,1)-ICONARROWS;
+	set = ((ocl == wallopobj) || (ocl == roboguardobj));
+	done = (((!set) && (ob->dir == (dirtype)spot)) ||
+			  (set && (ob->dir == (dirtype)(spot<<1))));
+
+	if ((spot >= 0) && (spot<= 7) && (!done))
+      {
+      centerx= (ob->tilex << 16) + HALFGLOBAL1;
+      centery= (ob->tiley << 16) + HALFGLOBAL1;
+      dx = abs(centerx - ob->x);
+      dy = abs(centery - ob->y);
+      //radius = (ob->speed > 0x4800)?(0xb000):(0x4000);
+      radius = 0x4000;
+
+      if ((dx < radius) && (dy < radius))
+	// new direction
+         {
+         ZEROMOM;
+         if ((ocl == wallopobj) || (ocl == roboguardobj))
+           {
+           ob->dir = spot<<1;
+           ParseMomentum(ob,dirangle16[ob->dir]);
+           }
+         else
+           {
+           ob->dir = spot;
+           ParseMomentum(ob,dirangle8[ob->dir]);
+           }
+         dx = centerx - ob->x;
+         dy = centery - ob->y;
+         SetFinePosition(ob,centerx,centery);
+         SetVisiblePosition(ob,centerx,centery);
+		 /*
+		 if (((ocl == bladeobj) || (ocl == diskobj)) && ob->whatever)
+			{objtype*passenger = (objtype*)(ob->whatever);
+
+			 passenger->x += dx;
+			 passenger->y += dy;
+			 passenger->drawx = passenger->x;
+			 passenger->drawy = passenger->y;
+			 passenger->tilex = passenger->x >> 16;
+			 passenger->tiley = passenger->y >> 16;
+			}*/
+//		 if (ob==SNAKEHEAD)
+//		  Debug("\n path changed at %d, %d",
+//			ob->tilex,ob->tiley);
+         }
+      }
+	if (NOMOM)
+      {
+      if ((ocl == wallopobj) || (ocl == roboguardobj))
+         ParseMomentum(ob,dirangle16[ob->dir]);
+		else
+         ParseMomentum(ob,dirangle8[ob->dir]);
+      }
+
+	//if ((ob->obclass == firejetobj) || (ob->obclass == bladeobj))
+	 //MoveActor(ob);
+	//else
+   ActorMovement(ob);
+
+   }
+
+
+
+/*
+================
+=
+= CheckSight
+=
+= Checks a straight line between player and current object
+=
+= If the sight is ok, check alertness and angle to see if they notice
+=
+= returns true if the player has been spoted
+=
+================
+*/
+
+
+boolean CheckSight (objtype *ob,void *atwhat)
+{
+	long     deltax,deltay;
+	objtype * what;
+//
+// don't bother tracing a line if the area isn't connected to the player's
+//
+	if (!areabyplayer[ob->areanumber])
+		return false;
+
+//
+// if the player is real close, sight is automatic
+//
+	what = (objtype*)atwhat;
+	deltax = what->x - ob->x;
+	deltay = what->y - ob->y;
+
+	if ((deltax > -MINSIGHT) && (deltax < MINSIGHT)	&&
+		 (deltay > -MINSIGHT) && (deltay < MINSIGHT))
+		return true;
+
+//
+// see if they are looking in the right direction
+//
+	switch (ob->dir)
+	{
+	case north:
+		if (deltay > 0)
+			return false;
+		break;
+
+	case east:
+		if (deltax < 0)
+			return false;
+		break;
+
+	case south:
+		if (deltay < 0)
+			return false;
+		break;
+
+	case west:
+		if (deltax > 0)
+			return false;
+		break;
+	default:
+	    ;
+	}
+
+//
+// trace a line to check for blocking tiles (corners)
+//
+	return CheckLine (ob,atwhat,SIGHT);
+
+}
+
+
+
+void ActivateEnemy(objtype*ob)
+{statetype *temp;
+
+
+ ob->flags |= (FL_ATTACKMODE|FL_FIRSTATTACK);
+ if (ob->obclass == roboguardobj)
+	return;
+
+ if (ob->temp3 == SNEAKY)
+	{ NewState(ob,&s_sneakyrise1);
+	  ob->temp3=0;
+	}
+ else if ((temp = M_S(CHASE)) != NULL)
+	NewState(ob,temp);
+ /*
+ ob->speed = ENEMYRUNSPEED;
+ */
+ if (ob->obclass == b_heinrichobj)
+    ob->speed = 7*ob->speed/2;
+ else if (ob->obclass == b_darianobj)
+    ob->speed = 3*SPDPATROL;
+ if (ob->door_to_open != -1)
+	ob->door_to_open = -1; // ignore the door opening command
+ ob->dirchoosetime = 0;
+
+
+}
+
+
+/*
+===============
+=
+= FirstSighting
+=
+= Puts an actor into attack mode and possibly reverses the direction
+= if the player is behind it
+=
+===============
+*/
+
+void FirstSighting (objtype *ob)
+   {
+   statetype *temp;
+   int sound;
+
+   if (ob->temp3 == SNEAKY)
+      {
+      NewState(ob,&s_sneakyrise1);
+      ob->temp3=0;
+      if (ob->shapeoffset==0)
+      SD_PlaySoundRTP(SD_SNEAKYSPRINGMSND,ob->x,ob->y);
+      else
+      SD_PlaySoundRTP(SD_SNEAKYSPRINGFSND,ob->x,ob->y);
+      }
+   else if ((temp = M_S(CHASE)) != NULL)
+      {
+      int rand;
+
+      NewState(ob,temp);
+      sound = BAS[ob->obclass].see;
+      rand = GameRandomNumber("FirstSighting low",0);
+      if ((ob->obclass > lowguardobj) && (ob->obclass <= blitzguardobj) && (rand < 128)) //hack for alternate
+         sound++;
+         //if ((ob->obclass == lowguardobj) && (rand < 80))
+         //sound ++;
+      else if (ob->obclass == lowguardobj)
+         {if (rand < 128)
+         {if ((PLAYERSTATE[0].player == 1) || (PLAYERSTATE[0].player == 3))
+            sound++;
+         }
+         else
+         sound += 2;
+
+         if (ob->shapeoffset)
+         sound += 4;
+
+         }
+      SD_PlaySoundRTP(sound,ob->x,ob->y);
+      if ((ob->obclass>=b_darianobj) && (ob->obclass<=b_darksnakeobj))
+         {
+         MU_StartSong(song_bosssee);
+         }
+      }
+
+   /*
+   ob->speed = ENEMYRUNSPEED;*/
+   if (ob->obclass == b_heinrichobj)
+      ob->speed = 7*ob->speed/2;
+   else if (ob->obclass == b_darianobj)
+      ob->speed = 3*SPDPATROL;
+   if (ob->door_to_open != -1)
+   ob->door_to_open = -1; // ignore the door opening command
+   ob->dirchoosetime = 0;
+   ob->flags |= (FL_ATTACKMODE|FL_FIRSTATTACK);
+
+   }
+
+
+/*
+===============
+=
+= SightPlayer
+=
+= Called by actors that ARE NOT chasing the player.  If the player
+= is detected (by sight, noise, or proximity), the actor is put into
+= it's combat frame and true is returned.
+=
+= Incorporates a random reaction delay
+=
+===============
+*/
+
+boolean SightPlayer (objtype *ob)
+   {
+	//if (ob->flags & FL_ATTACKMODE)
+	  //Error ("An instance of %s in ATTACKMODE called SightPlayer!",debugstr[ob->obclass]);
+
+	if (!areabyplayer[ob->areanumber])
+      return false;
+
+   if (ob->obclass == b_robobossobj)
+      {
+      if (!(CheckSight(ob,player) || Near(ob,player,6)))
+         return false;
+
+      }
+
+
+   else if (ob->flags & FL_AMBUSH)
+      {
+      if (!CheckSight (ob,PLAYER[0]))
+         {
+         //SoftError("\n failed from ambush in SightPlayer");
+         return false;
+         }
+      ob->flags &= ~FL_AMBUSH;
+      }
+	else
+      {
+      if (ob->temp3 == SNEAKY)
+         {
+         if (!Near(ob,PLAYER[0],2))
+            return false;
+         }
+      else if (!((MISCVARS->madenoise) ||
+                 (CheckSight (ob,player)) ||
+                 (Near(ob,player,4))
+                )
+              )
+         {
+         //SoftError("\n failed from SightPlayer");
+         return false;
+         }
+      }
+
+	FirstSighting (ob);
+
+	return true;
+   }
+
+
+/*
+=====================
+=
+= CheckLine
+=
+= Returns true if a straight line between two obs is unobstructed
+=
+=====================
+*/
+
+
+
+boolean CheckLine (void *from, void *to, int condition)
+{
+	objtype   *tempactor,*ob,*orig;
+	statobj_t *checksprite;
+	int destx,desty,destz;
+	int desttilex,desttiley;
+	int snx,sny;
+	int incr[2];
+	int thedir[2];
+	int cnt;
+	int grid[2];
+	int index;
+	int vx,vy;
+	int yzangle;
+	int value;
+	int dx,dy,dz;
+	int xydist;
+	int otx,oty,count=0;
+
+
+
+   ob = (objtype*)to;
+	orig = (objtype*)from;
+	if (ob->which == SPRITE)
+		{
+		destx = ((statobj_t*)to)->x;
+		desty = ((statobj_t*)to)->y;
+		destz = ((statobj_t*)to)->z;
+		}
+	else
+		{
+		destx = ob->x;
+		desty = ob->y;
+		destz = ob->z;
+		}
+
+	desttilex=destx>>16;
+	desttiley=desty>>16;
+
+	if ((desttilex == orig->tilex) && (desttiley == orig->tiley))
+	  return true;
+
+
+	dx=destx-orig->x;
+	dy=orig->y-desty;
+   dz=orig->z-destz;
+	xydist = FindDistance(dx,dy);
+	yzangle = atan2_appx(xydist,dz<<10);
+
+	if ((yzangle>MAXYZANGLE) && (yzangle<FINEANGLES-MAXYZANGLE))
+	  {
+		#if (0)
+		 Debug("\nfailed from yzangle");
+		#endif
+		return false;
+	  }
+
+	//angle = atan2_appx(dx,dy);
+	otx = orig->x >> TILESHIFT;
+	oty = orig->y >> TILESHIFT;
+
+	if (xydist==0)
+		{
+      /*
+      SoftError("\nCheckLine:xydist=0");
+		if (orig->which == ACTOR)
+		  SoftError("shooter: %s",debugstr[orig->obclass]);
+		if (ob->which == ACTOR)
+        SoftError("target: %s",debugstr[ob->obclass]);*/
+		vy=-dy;
+		vx=dx;
+		}
+	else
+		{
+		vy = -FixedDiv2(dy,xydist);
+		vx = FixedDiv2(dx,xydist);
+		}
+	snx=orig->x&0xffff;
+	sny=orig->y&0xffff;
+
+	grid[0]=otx;
+	grid[1]=oty;
+
+	if (vx>0)
+		{
+		thedir[0]=1;
+		snx^=0xffff;
+		incr[1]=-vx;
+		}
+	else
+		{
+		thedir[0]=-1;
+		incr[1]=vx;
+		}
+	if (vy>0)
+		{
+		thedir[1]=1;
+		sny^=0xffff;
+		incr[0]=vy;
+		}
+	else
+		{
+		thedir[1]=-1;
+		incr[0]=-vy;
+		}
+	cnt=FixedMul(snx,incr[0])+FixedMul(sny,incr[1]);
+
+
+   do
+		{count ++;
+       /*
+       if (count > 1000)
+         Error("possible infinite loop in CheckLine");
+		 if ((grid[0] < 0) || (grid[0] > (MAPSIZE-1)) ||
+			  (grid[1] < 0) || (grid[1] > (MAPSIZE-1)))
+			Error("out of bounds in check line, grid[0] = %d, grid[1] = %d",grid[0],grid[1]);
+        */
+		if ((grid[0]==desttilex) && (grid[1]==desttiley))
+			return true;
+		tempactor = (objtype*)actorat[grid[0]][grid[1]];
+		value = tilemap[grid[0]][grid[1]];
+		checksprite = sprites[grid[0]][grid[1]];
+		if (value)
+			{
+			if (value&0x8000)
+				{
+				if (!(value&0x4000))
+					{
+               doorobj_t*dptr = doorobjlist[value&0x3ff];
+
+               if (dptr->position < 0x8000)
+						{
+
+                  int x = (grid[0] << 16) + 0x8000;
+                  int y = (grid[1] << 16) + 0x8000;
+
+                  if (dptr->vertical)
+                     {
+                     if (abs(dx) > abs(x-orig->x))
+                        return false;
+                     }
+                  else
+                     {
+                     if (abs(dy) > abs(orig->y-y))
+                        return false;
+                     }
+						}
+					}
+				else
+					{
+					if (condition == SHOOT)
+						{
+                  if ( maskobjlist[value&0x3ff]->flags & MW_SHOOTABLE )
+							{
+                      #if (0)
+                      SoftError("\nfailed from shootable mask");
+                    #endif
+							 return false;
+							}
+                  else if ( maskobjlist[value&0x3ff]->flags & MW_WEAPONBLOCKING )
+							{
+                      #if (0)
+                      SoftError("\nfailed from block mask");
+                      #endif
+							 return false;
+							}
+						}
+               else if ((condition == MISSILE) &&
+                        ( maskobjlist[value&0x3ff]->flags & MW_BLOCKING )
+                       )
+                  return false;
+					}
+				}
+			else
+				{
+             #if (0)
+            SoftError("\n obx %d, oby %d, origx %d, origy %d"
+                      "\n xydist %d, vx %d, vy %d",ob->x,ob->y,orig->x,
+                      orig->y,xydist,vx,vy);
+
+            SoftError("\nfailed from normal wall");
+             #endif
+            return false;
+				}
+			}
+		if (condition == SHOOT)
+			{
+			if (tempactor && (tempactor->which == ACTOR) &&
+				(tempactor->flags & FL_BLOCK) && (tempactor != orig) &&
+				(tempactor != ob)) //&&
+//   			(InRange(orig,tempactor,
+//             FindDistance(orig->x-tempactor->x,orig->y-tempactor->y) )
+//             ==true) )
+			  {
+            #if (0)
+             SoftError("\nfailed from actor");
+            #endif
+				return false;
+			  }
+			}
+
+		if (checksprite && (checksprite->flags & FL_BLOCK) && (condition == SHOOT) &&
+			 ((void *)checksprite != to) &&
+          (checksprite->itemnumber!=stat_disk) &&
+         (InRange(orig,(objtype *)checksprite,
+			 FindDistance(orig->x-checksprite->x,orig->y-checksprite->y) )
+			 ==true) )
+
+			{
+          #if (0)
+          SoftError("\nfailed from sprite");
+          #endif
+			 return false;
+			}
+
+		if (tempactor && (tempactor->which == PWALL))
+			{
+        #if (0)
+          SoftError("\nfailed from pushwall");
+          #endif
+			 return false;
+			}
+		index=(cnt>=0);
+		cnt+=incr[index];
+		grid[index]+=thedir[index];
+		}
+	while (1);
+}
+
+
+
+
+
+
+
+/*
+=====================
+=
+= ShootActor
+=
+= Shoot an actor.
+=
+=====================
+*/
+void ShootActor(objtype * shooter, objtype * target, int damage, int accuracy, int angle)
+{
+	int dx,dy,dist;
+	int newmomx, newmomy;
+	int tcl;
+
+
+	if (target->flags & FL_DYING)
+	  return;
+
+	dx = abs(shooter->x - target->x);
+	dy = abs(shooter->y - target->y);
+	dist = FindDistance(dx,dy)>>16;
+
+	tcl=target->obclass;
+
+	if (tcl==playerobj)
+		{
+		target->target=shooter;
+		if (target->flags&FL_BPV)
+         {
+         playertype *pstate;
+
+         M_LINKSTATE(target,pstate);
+         pstate->protectiontime -= (damage<<1);
+         if (pstate->protectiontime < 1)
+            pstate->protectiontime = 1;
+         if (target==player)
+            GM_UpdateBonus (pstate->protectiontime, false);
+         return;
+         }
+		else if ((target->flags&FL_GODMODE) || (target->flags&FL_DOGMODE) || godmode)
+			return;
+		//damage=FixedMulShift((gamestate.difficulty+1),damage,2); // player object difficulty
+		}
+
+	else if (tcl == NMEsaucerobj)
+		{
+		target->momentumx = target->momentumy = 0;
+		NewState(target,&s_explosion1);
+		target->flags &= ~FL_SHOOTABLE;
+		return;
+		}
+	else if (tcl == b_darianobj)
+		 MISCVARS->ESAU_SHOOTING = false;
+	else if ((tcl == strikeguardobj) || (tcl == b_heinrichobj))
+		 target->target = shooter;
+
+	if ((  (!(target->flags & FL_SHOOTABLE)) ||
+			(tcl == roboguardobj) || (tcl == wallopobj) ||
+			(tcl == patrolgunobj) ) &&
+		 (tcl!=playerobj)  )
+		SpawnMetalSparks(target,angle);
+
+   else if ((tcl < b_darianobj) || (tcl > b_darksnakeobj))
+		{
+
+		//target->flags &= ~FL_USE;
+
+		damage=FixedMulShift(511-accuracy,damage,9); // Min half damage
+		if (dist<64)
+			{
+			if (dist>2)
+				damage=FixedMulShift(63-dist,damage,6);
+			if (damage<1)
+				damage=1;
+			}
+		else
+			damage=1;
+
+		if (damage>MAXDAMAGE) damage=MAXDAMAGE; // absolutely clip it
+
+		DamageThing(target,damage);
+		if ((tcl == collectorobj) && gamestate.SpawnDeluder)
+         {
+         Collision(target,shooter,0,0);
+         if (target->hitpoints <= 0)
+            BATTLE_CheckGameStatus(battle_shot_deluder,shooter->dirchoosetime);
+         }
+
+		else
+		  {newmomx = FixedMul(damage<<7,costable[angle]);
+			newmomy = -FixedMul(damage<<7,sintable[angle]);
+         Collision(target,shooter,-(target->momentumx)+newmomx,-(target->momentumy)+newmomy);
+			if (tcl == playerobj)
+				{
+				 playertype * pstate;
+
+				 M_LINKSTATE(target,pstate);
+				 if (pstate->health <= 0)
+					{
+
+					    if (shooter->obclass == playerobj) {
+						if (!target->momentumz)
+						  BATTLE_PlayerKilledPlayer(battle_kill_with_bullet,shooter->dirchoosetime,target->dirchoosetime);
+						else
+						  BATTLE_PlayerKilledPlayer(battle_kill_with_bullet_in_air,shooter->dirchoosetime,target->dirchoosetime);
+					    }
+					}
+				}
+//      SoftError("ShootActor: damage=%ld dist=%ld\n",damage,dist);
+
+			if ((GameRandomNumber("disembowel",0)<64) && (gamestate.violence == vl_excessive))
+			  {
+			  int temp;
+			  temp=target->temp1;
+			  target->temp1=angle;
+
+           SpawnParticles(target,DISEMBOWEL,damage>>3);
+			  target->temp1=temp;
+			  }
+			else if (gamestate.violence > 0)
+			  SpawnBlood(target,angle);
+		  }
+		}
+}
+
+
+/*
+=====================
+=
+= ShootSprite
+=
+= Shoot a sprite.
+=
+=====================
+*/
+void ShootSprite(objtype * shooter, statobj_t * target, int damage, int accuracy, int angle)
+{
+   int dx,dy,dist;
+
+
+   if (!(target->flags & FL_SHOOTABLE))
+// Watchout for sprite being passed in as actor WARNING
+      SpawnMetalSparks((objtype *)target,angle);
+
+   else
+      {
+      dx = abs(shooter->x - target->x);
+      dy = abs(shooter->y - target->y);
+      dist = FindDistance(dx,dy)>>16;
+
+      damage=FixedMulShift(511-accuracy,damage,9); // Min half damage
+      if (dist<64)
+         {
+         if (dist>2)
+            damage=FixedMulShift(63-dist,damage,6);
+         if (damage<1)
+            damage=1;
+         }
+      else
+         damage=1;
+
+      if (damage>MAXDAMAGE) damage=MAXDAMAGE; // absolutely clip it
+
+   //   SoftError("ShootSprite: damage=%ld dist=%ld\n",damage,dist);
+
+      DamageThing((objtype *)target,damage);
+      if (FirstExplosionState(new->state))
+         new->whatever = shooter;
+
+      SpawnStaticDamage(target, angle);
+      }
+}
+
+
+/*
+=====================
+=
+= RayShoot
+=
+= Cast a ray out at the shooter's angle and yzangle, return
+=
+=====================
+*/
+
+
+
+void RayShoot (objtype * shooter, int damage, int accuracy)
+{
+	objtype   *tempactor;
+	statobj_t *checksprite;
+	int snx,sny;
+	int incr[2];
+	int zincr[2];
+	int thedir[2];
+	int cnt;
+	int grid[2];
+	int index;
+	int vx,vy;
+	int angle;
+	int yzangle;
+	int value;
+	int offset;
+	int z;
+	int lastcnt;
+   int bullethole=0;
+	enum {gs_door, gs_wall, gs_floor, gs_ceiling, gs_pushwall};
+	int smokecondition=0;
+
+
+   if ((shooter->areanumber==player->areanumber) && (Near(shooter,player,3)))
+      SetIllumination(2);
+
+	offset = ((GameRandomNumber("RayShoot",0)-128)>>MAXSHOOTSHIFT);
+	offset = FixedMulShift(accuracy,offset,8);
+
+	if (offset>MAXSHOOTOFFSET)
+		offset=MAXSHOOTOFFSET;
+
+	else if (offset<-MAXSHOOTOFFSET)
+		offset=-MAXSHOOTOFFSET;
+
+	angle=(shooter->angle+offset)&(FINEANGLES-1);
+
+   offset = ((GameRandomNumber("RayShoot",1)-128)>>MAXSHOOTSHIFT);
+	offset = FixedMulShift(accuracy,offset,8);
+
+	if (offset>MAXSHOOTOFFSET)
+		offset=MAXSHOOTOFFSET;
+
+	else if (offset<-MAXSHOOTOFFSET)
+		offset=-MAXSHOOTOFFSET;
+
+	yzangle=(shooter->yzangle+offset)&(FINEANGLES-1);
+
+	vy = -sintable[angle];
+	vx = costable[angle];
+	snx=shooter->x&0xffff;
+	sny=shooter->y&0xffff;
+	grid[0]=shooter->tilex;
+	grid[1]=shooter->tiley;
+	if (shooter->obclass==playerobj)
+		{
+		playertype * pstate;
+
+		M_LINKSTATE(shooter,pstate);
+		z=shooter->z+pstate->playerheight-32;
+		}
+	else
+      z=shooter->z-7;
+	if (vx>0)
+		{
+		thedir[0]=1;
+		snx^=0xffff;
+		incr[1]=-vx;
+		}
+	else
+		{
+		thedir[0]=-1;
+		incr[1]=vx;
+		}
+	if (vy>0)
+		{
+		thedir[1]=1;
+		sny^=0xffff;
+		incr[0]=vy;
+		}
+	else
+		{
+		thedir[1]=-1;
+		incr[0]=-vy;
+		}
+	zincr[0]=-FixedMulShift(sintable[yzangle],abs(vx),26);
+	zincr[1]=-FixedMulShift(sintable[yzangle],abs(vy),26);
+
+	cnt=FixedMul(snx,incr[0])+FixedMul(sny,incr[1]);
+	index= (cnt >= 0);
+	do
+		{
+		tempactor = (objtype*)actorat[grid[0]][grid[1]];
+		value = tilemap[grid[0]][grid[1]];
+		checksprite = sprites[grid[0]][grid[1]];
+		if (value)
+			{
+			if (value&0x8000)
+				{
+				if (!(value&0x4000))
+					{
+					if ((doorobjlist[value&0x3ff]->action==dr_closed) || (z<maxheight-64))
+						{
+						smokecondition=gs_door;
+						break;
+						}
+					else if (doorobjlist[value&0x3ff]->position<=0x8000)
+						{
+						smokecondition=gs_door;
+						break;
+						}
+					}
+				else
+					{
+					if ( maskobjlist[value&0x3ff]->flags & MW_SHOOTABLE )
+						{
+						if (z>maxheight-64) // Are we shooting above the glass
+							{
+							UpdateMaskedWall(value&0x3ff);
+							return;
+							}
+						}
+					else if ( maskobjlist[value&0x3ff]->flags & MW_WEAPONBLOCKING )
+						{
+						smokecondition=gs_door;
+						break;
+						}
+					}
+				}
+			else
+				{
+				smokecondition=gs_wall;
+				break;
+				}
+			}
+
+      if (checksprite &&
+          ((checksprite->flags & FL_BLOCK)||(checksprite->flags & FL_SHOOTABLE)) &&
+          (abs(checksprite->z-z)<32) &&
+          (InRange(shooter,(objtype *)checksprite,
+			 FindDistance(shooter->x-checksprite->x,shooter->y-checksprite->y) )
+          ==true
+          )
+         )
+			{
+			ShootSprite(shooter, checksprite, damage, accuracy, angle);
+			return;
+			}
+
+
+      if (tempactor)
+        {if (tempactor->which == ACTOR)
+            {if ((abs(tempactor->z-z)<32 ) && (!(tempactor->flags & FL_DYING)) &&
+                (tempactor->flags & FL_BLOCK) && (tempactor != shooter) &&
+                (tempactor->obclass!=diskobj) &&
+                (InRange(shooter,tempactor,
+                 FindDistance(shooter->x-tempactor->x,shooter->y-tempactor->y) )
+                 ==true
+                )
+               )
+              {ShootActor(shooter, tempactor, damage, accuracy, angle);
+               return;
+              }
+            }
+          else if (tempactor->which == PWALL)
+            return;
+        }
+
+		if (z<-32)
+			{
+			smokecondition=gs_ceiling;
+			break;
+			}
+		else if (z>maxheight)
+			{
+			smokecondition=gs_floor;
+			break;
+			}
+		index= (cnt >= 0);
+		cnt+=incr[index];
+		z  +=zincr[index];
+		grid[index]+=thedir[index];
+		}
+	while (1);
+
+	if (IsWindow(grid[0],grid[1]))
+		return;
+
+	lastcnt=cnt-incr[index];
+
+	if (smokecondition==gs_floor)
+		{
+		int dist;
+		int tangentangle;
+
+		tangentangle=tantable[yzangle];
+		if (tangentangle!=0)
+			{
+         dist=FixedDiv2(((shooter->z-maxheight)<<10),(tangentangle<<1));
+			xintercept=shooter->x+FixedMul(dist,costable[angle]);
+			yintercept=shooter->y-FixedMul(dist,sintable[angle]);
+			}
+		z=maxheight;
+//      bullethole=5;
+		}
+	else if (smokecondition==gs_ceiling)
+		{
+		int dist;
+		int tangentangle;
+
+		if (sky!=0)
+			return;
+		tangentangle=tantable[yzangle];
+		if (tangentangle!=0)
+			{
+         dist=FixedDiv2(((shooter->z+32)<<10),(tangentangle<<1));
+			xintercept=shooter->x+FixedMul(dist,costable[angle]);
+			yintercept=shooter->y-FixedMul(dist,sintable[angle]);
+			}
+		z=-32;
+//      bullethole=5;
+		}
+	else
+		{
+		int dx,dy,xydist;
+
+
+#define CORNERVALUE  0x500
+
+
+		if (IsWindow(grid[0],grid[1]))
+			return;
+		if (lastcnt<0)
+			{
+			xintercept=grid[0]<<16;
+			if (smokecondition==gs_door)
+				{
+				if (thedir[0]<0)
+					xintercept+=0x9fff;
+				else
+					xintercept+=0x5fff;
+				yintercept=FixedScale(xintercept-shooter->x,vy,vx)+shooter->y;
+				if ((yintercept>>16)!=grid[1])
+					{
+					if ((yintercept>>16)>grid[1])
+						yintercept=(grid[1]<<16)+0xffff;
+					else
+						yintercept=(grid[1]<<16);
+					}
+				}
+			else if (smokecondition==gs_wall)
+				{
+				if (thedir[0]<0)
+					{
+					objtype * ta;
+
+               xintercept += 0x10000;
+               yintercept=FixedScale(xintercept-shooter->x,vy,vx)+shooter->y;
+
+               xintercept += SMOKEWALLOFFSET;
+					bullethole=1;
+               if (yintercept < ((grid[1] << 16) + CORNERVALUE))
+                 bullethole = 0;
+               else if (yintercept > ((grid[1] << 16) + 0x10000 - CORNERVALUE))
+                 bullethole = 0;
+
+					ta = (objtype*)actorat[grid[0]][grid[1]];
+					if ((ta) && (ta->which==PWALL))
+						bullethole=0;
+					}
+				else
+					{
+					objtype * ta;
+
+               yintercept=FixedScale(xintercept-shooter->x,vy,vx)+shooter->y;
+               xintercept-=SMOKEWALLOFFSET;
+					bullethole=2;
+               if (yintercept < ((grid[1] << 16) + CORNERVALUE))
+                 bullethole = 0;
+               else if (yintercept > ((grid[1] << 16) + 0x10000 - CORNERVALUE))
+                 bullethole = 0;
+
+					ta = (objtype*)actorat[grid[0]][grid[1]];
+					if ((ta) && (ta->which==PWALL))
+						bullethole=0;
+					}
+				}
+			}
+		else
+			{
+			yintercept=grid[1]<<16;
+			if (smokecondition==gs_door)
+				{
+				if (thedir[1]<0)
+					yintercept+=0x9fff;
+				else
+					yintercept+=0x5fff;
+				xintercept=FixedScale(yintercept-shooter->y,vx,vy)+shooter->x;
+				if ((xintercept>>16)!=grid[0])
+					{
+					if ((xintercept>>16)>grid[0])
+						xintercept=(grid[0]<<16)+0xffff;
+					else
+						xintercept=(grid[0]<<16);
+					}
+				}
+			else if (smokecondition==gs_wall)
+				{
+				if (thedir[1]<0)
+					{
+					objtype * ta;
+
+
+               yintercept += 0x10000;
+               xintercept=FixedScale(yintercept-shooter->y,vx,vy)+shooter->x;
+
+               yintercept += SMOKEWALLOFFSET;
+					bullethole=3;
+               if (xintercept < ((grid[0] << 16) + CORNERVALUE))
+                 bullethole = 0;
+               else if (xintercept > ((grid[0] << 16) + 0x10000 - CORNERVALUE))
+                 bullethole = 0;
+
+					ta = (objtype*)actorat[grid[0]][grid[1]];
+					if ((ta) && (ta->which==PWALL))
+						bullethole=0;
+					}
+				else
+					{
+					objtype * ta;
+
+               xintercept=FixedScale(yintercept-shooter->y,vx,vy)+shooter->x;
+               yintercept-=SMOKEWALLOFFSET;
+					bullethole=4;
+               if (xintercept < ((grid[0] << 16) + CORNERVALUE))
+                 bullethole = 0;
+               else if (xintercept > ((grid[0] << 16) + 0x10000 - CORNERVALUE))
+                 bullethole = 0;
+
+					ta = (objtype*)actorat[grid[0]][grid[1]];
+					if ((ta) && (ta->which==PWALL))
+						bullethole=0;
+					}
+				}
+			}
+		dx = xintercept - shooter->x;
+		dy = shooter->y - yintercept;
+		xydist = FindDistance(dx,dy);
+		if (shooter->obclass==playerobj)
+			{
+			playertype * pstate;
+
+			M_LINKSTATE(shooter,pstate);
+         z=shooter->z-FixedMulShift(xydist,tantable[yzangle],25)+pstate->playerheight-32;
+			}
+		else
+         z=shooter->z-FixedMulShift(xydist,tantable[yzangle],25);
+		if (smokecondition==gs_wall)
+			{
+			if (z<-32)
+				z=-32;
+			}
+		}
+	SpawnGunSmoke(xintercept,yintercept,z,angle,bullethole);
+}
+
+
+/*
+=====================
+=
+= T_BossDied ()
+=
+=====================
+*/
+
+void T_BossDied (objtype *ob)
+{
+
+ if (ob->ticcount)
+  return;
+
+	switch (ob->obclass)
+	{
+		case b_darianobj:
+		case b_heinrichobj:
+		case b_darkmonkobj:
+		case b_robobossobj:
+		case b_darksnakeobj:
+			playstate = ex_bossdied;
+		break;
+	default:
+	    ;
+	}
+}
+
+
+/*
+=====================
+=
+= T_Wind ()
+=
+=====================
+*/
+
+static int WindDistance = 1000;
+static int WindCurrentDistance = 1000;
+static int WindHandle = -1;
+static int WindLastTic = -1;
+static int WindPlaying = false;
+static int WindPitch = 0;
+static int WindDestPitch = 0;
+static int WindPitchRate = 0;
+
+void T_Wind
+	(
+	objtype *ob
+	)
+
+	{
+	int distance;
+	int dx;
+	int dy;
+
+	if ( ( GetTicCount() - WindLastTic ) > 0 )
+		{
+		WindDistance = 1000;
+
+		WindPitch += WindPitchRate;
+		if ( WindPitch == WindDestPitch )
+			{
+			WindDestPitch = ( RandomNumber( "Wind Pitch", 0 ) - 128 ) << 3;
+			WindPitchRate = 1;
+			if ( WindDestPitch < WindPitch )
+				{
+				WindPitchRate = -WindPitchRate;
+				}
+			}
+		}
+	WindLastTic = GetTicCount();
+
+	dx = ( ob->x - PLAYER[0]->x );
+	dy = ( PLAYER[0]->y - ob->y );
+
+	distance = 1000;
+   if ( areabyplayer[ ob->areanumber ] )
+      {
+      distance = ( FindDistance( dx, dy ) ) >> 13;
+      }
+
+   if ( distance < WindDistance )
+      {
+      WindDistance = distance;
+      }
+
+   if ( WindDistance < 255 )
+      {
+      WindPlaying = true;
+      WindCurrentDistance = WindDistance;
+      }
+   else
+      {
+      if ( WindPlaying )
+         {
+         WindCurrentDistance += 3;
+         }
+      }
+
+   if ( WindPlaying )
+      {
+      if ( WindCurrentDistance < 255 )
+         {
+         if ( !SD_SoundActive( WindHandle ) )
+            {
+            WindHandle = SD_PlayPitchedSound( SD_WINDSND,
+               255 - WindCurrentDistance, WindPitch );
+            }
+         else
+            {
+            SD_SetSoundPitch( WindHandle, WindPitch );
+            SD_SetPan( WindHandle, 255 - WindCurrentDistance, 255 - WindCurrentDistance,
+               255 - WindCurrentDistance );
+            }
+         }
+      else
+         {
+         SD_StopSound( WindHandle );
+         WindPlaying = false;
+         }
+      }
+   }
+
+/*
+=====================
+=
+= StopWind ()
+=
+=====================
+*/
+
+void StopWind
+   (
+   void
+   )
+
+   {
+   objtype *temp;
+
+   FX_SetReverb( 0 );
+
+   SD_StopSound( WindHandle );
+   WindDistance        = 1000;
+   WindCurrentDistance = 1000;
+   WindHandle          = -1;
+   WindLastTic         = -1;
+   WindPlaying         = false;
+   WindPitch           = 0;
+   WindDestPitch       = 0;
+   WindPitchRate       = 0;
+
+
+   for(temp=FIRSTACTOR;temp;temp=temp->next)
+      {
+      if (temp->soundhandle != -1)
+         SD_StopSound(temp->soundhandle);
+      }
+   }
+

Added: tags/rott-1.1/rott/rt_actor.h
===================================================================
--- tags/rott-1.1/rott/rt_actor.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_actor.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,436 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_actor_public
+#define _rt_actor_public
+
+//***************************************************************************
+//
+//                            RT_ACTOR.C (actor functions)
+//
+//***************************************************************************
+
+#include "states.h"
+
+
+#define FL_SYNCED          0x400
+#define FL_MASTER          0x800
+#define FL_SKELETON        0x02
+#define GASTICS            1050
+
+
+#define M_ISACTOR(x)     ((x!=NULL) && (x->which == ACTOR))
+
+#define SF_GUTS          0x20
+
+#define NUMENEMIES       16
+#define NUMCLASSES       51
+#define MAXTOUCH         10
+#define MAXPOP           32
+#define MAXDELETE        512
+
+#define InMapBounds(x,y) (((x) >= 0) && ((x) < MAPSIZE) && ((y) >= 0) && ((y) < MAPSIZE))
+
+
+#define ACTIVE(ob)       ((ob == firstactive) || (ob->prevactive) || (ob->nextactive))
+
+enum {SHOOT,SIGHT,DIRCHECK,EXPLOSION,MISSILE};
+
+
+typedef enum
+   {
+   gt_sparks,
+   gt_organ,
+   gt_rib,
+   gt_pinkorgan,
+   gt_head,
+   gt_arm,
+   gt_leg,
+   gt_humerus,
+   gt_pelvis,
+   gt_limb,
+   gt_bsoul,
+   gt_lsoul,
+   gt_spit,
+   NumGibTypes
+   }gib_t;
+
+#define GUTS         (NumGibTypes)
+#define RANDOM       (NumGibTypes + 1)
+#define DISEMBOWEL   (NumGibTypes + 2)
+
+
+#define GASVALUE               192
+
+#define PAINOFFSET             2
+#define PMFOFFSET              50
+#define REMOTEOFFSET           86
+
+#define ACTORSIZE              0x5800
+#define PWALLRAD               0xa000
+
+#ifdef __WATCOMC__
+int M_ABS(int value);
+#pragma aux M_ABS =  \
+		  "test eax,eax",                     \
+		  "jge done", \
+		  "neg eax",\
+		  "done: "         \
+		  parm    [eax] \
+		  value   [eax]           \
+		  modify exact [eax]
+#else
+#define M_ABS abs
+#endif
+
+#define M_CheckPlayerKilled(ob) \
+{ if ((ob->obclass == playerobj) && (ob->flags & FL_DYING)) \
+	 BATTLE_CheckGameStatus(battle_player_killed,ob->dirchoosetime);\
+}
+
+
+
+#define SetTilePosition(ob, newtilex, newtiley)    \
+  {                                                \
+  ob->tilex = newtilex;                            \
+  ob->tiley = newtiley;                            \
+  ob->x = (ob->tilex << TILESHIFT) + TILEGLOBAL/2; \
+  ob->y = (ob->tiley << TILESHIFT) + TILEGLOBAL/2; \
+  }
+
+
+#define SetFinePosition(ob, newx, newy)            \
+  {                                                \
+  ob->x = newx;                                    \
+  ob->y = newy;                                    \
+  ob->tilex = (ob->x >> TILESHIFT);                \
+  ob->tiley = (ob->y >> TILESHIFT);                \
+  }
+
+#define SetVisiblePosition(ob, x, y)               \
+  {                                                \
+  ob->drawx = x;                                   \
+  ob->drawy = y;                                   \
+  }
+
+
+//***************************************************************************
+//
+//    WeaponDamages
+//
+//***************************************************************************
+#define DMG_PISTOL    13
+#define DMG_MP40      10
+#define DMG_AHGUN     10
+#define DMG_ENEMYBULLETWEAPON     10
+
+
+
+
+typedef struct bas
+ {
+  short operate,
+        see,
+        fire,
+        hit,
+        die;
+ } basic_actor_sounds;
+
+extern basic_actor_sounds  BAS[NUMCLASSES+3];
+
+
+typedef struct
+ {int x,y;
+ }_2Dpoint;
+
+typedef enum {
+		  inertobj,
+		  playerobj,
+		  lowguardobj,
+		  highguardobj,
+		  overpatrolobj,
+		  strikeguardobj,
+		  blitzguardobj,
+		  triadenforcerobj,
+		  deathmonkobj,
+		  dfiremonkobj,
+		  roboguardobj,
+
+		  b_darianobj,
+		  b_heinrichobj,
+		  b_robobossobj,
+		  b_darkmonkobj,
+		  b_darksnakeobj,
+		  patrolgunobj,
+		  wallopobj,
+
+
+		  //specials
+
+		  pillarobj,
+		  firejetobj,
+		  bladeobj,
+		  crushcolobj,
+		  boulderobj,
+		  spearobj,
+		  gasgrateobj,
+		  springobj,
+
+		  // Missile weapon types
+
+		  shurikenobj,
+		  wallfireobj,
+		  netobj,
+		  h_mineobj,
+		  grenadeobj,
+		  fireballobj,
+		  dmfballobj,
+		  bigshurikenobj,
+		  missileobj,
+		  NMEsaucerobj,
+		  dm_weaponobj,
+		  dm_heatseekobj,
+		  dm_spitobj,
+		  p_bazookaobj,
+		  p_firebombobj,
+		  p_heatseekobj,
+		  p_drunkmissileobj,
+		  p_firewallobj,
+		  p_splitmissileobj,
+		  p_kesobj,
+		  p_godballobj,
+		  collectorobj,
+        diskobj,
+        rainobj
+
+
+		  }classtype;
+
+
+typedef struct objstruct
+{
+		  thingtype                     which;
+		  byte                     tilex,tiley;
+		  fixed                    x,y,z;
+        int                      shapenum;
+		  unsigned                 flags;
+		  short                    ticcount;
+		  signed short             hitpoints;
+		  word                     whichactor;
+
+		  signed short             dirchoosetime;
+		  fixed                    drawx,drawy;
+		  classtype                obclass;
+		  statetype *              state;
+		  signed char              door_to_open;
+		  byte                     areanumber;
+		  signed short             shapeoffset;
+		  int                      targettilex,targettiley;
+
+
+		  dirtype                  dir;
+		  short int                angle;
+		  short int                yzangle;
+
+		  int                      soundhandle;
+		  int                      speed;
+		  int                      momentumx, momentumy, momentumz;
+		  int                      temp1,temp2,temp3;
+		  void                     *whatever,*target;
+		  struct objstruct         *next, *prev;
+		  struct objstruct         *nextactive, *prevactive;
+		  struct objstruct         *nextinarea, *previnarea;
+
+} objtype;
+
+
+
+
+typedef struct b_struct
+ {int   NMErotate;
+  int   NMEdirstried;
+  int   NMEqueuesize;
+  int   ESAU_HIDING,ESAU_SHOOTING;
+  int   HRAMMING, HMINING;
+  int   SOUNDTIME;
+  int   redindex,REDTIME;
+  int   monkz;
+  int   monkup;
+  int   firespawned;
+  int   notouch,noholes;
+  int   nexttouch,nextpop;
+  int   popsleft;
+  int   DSTATE;
+  int   doorcount;
+  int   KEYACTORSLEFT;
+  int      GASON;
+  int      gasindex;
+  boolean  NET_IN_FLIGHT;
+  boolean  madenoise;
+  _2Dpoint ETOUCH[MAXTOUCH],EPOP[MAXPOP],TOMLOC;
+  int   NUMWEAPONS;
+  int   BulletHoleNum;
+  int   NUMBEGGINGKEVINS;
+  boolean fulllightgibs;
+  boolean directgibs;
+  int     gibgravity;
+  int     gibspeed;
+  boolean supergibflag;
+  boolean randgibspeed;
+  int     numgibs;
+  boolean elevatormusicon;
+ }misc_stuff;
+
+
+extern  boolean          ludicrousgibs;
+extern  objtype*         PLAYER0MISSILE;
+extern  byte             deathshapeoffset[8];
+extern  byte             RANDOMACTORTYPE[10];
+extern  objtype*         FIRSTACTOR,*LASTACTOR;
+extern  objtype          *FIRSTRAIN,*LASTRAIN;
+extern  objtype*         SCREENEYE;
+extern  objtype          *firstareaactor[NUMAREAS+1],*lastareaactor[NUMAREAS+1];
+extern  misc_stuff       mstruct,*MISCVARS;
+extern  int              actorstart,actorstop;
+extern  exit_t           playstate;
+extern  objtype          *lastactive,*firstactive;
+extern  objtype          *new,**objlist,
+								 *killerobj;
+extern  void             *actorat[MAPSIZE][MAPSIZE];
+extern  int              angletodir[ANGLES];
+extern _2Dpoint          SNAKEPATH[512];
+/* extern  int              STOPSPEED; */
+extern  int              FRICTION;
+
+extern  int              objcount;
+
+void     SpawnInertActor(int,int,int);
+objtype* DiskAt(int tilex,int tiley);
+void     GetRainActors(void);
+void     DoRain(void);
+void     SpawnDisk(int,int,int,boolean);
+void     T_ElevDisk(objtype*);
+void     Add_To_Delete_Array(void*);
+void     Remove_Delete_Array_Entries(void);
+void     MakeInactive(objtype*ob);
+void     RespawnEluder(void);
+void     SpawnCollector(int,int);
+void     MakeLastInArea(objtype*);
+void     RemoveFromArea(objtype*);
+void     GetMomenta(objtype*,objtype*,int*,int*,int*,int);
+int      AngleBetween(objtype*,objtype*);
+void     TurnActorIntoSprite(objtype*);
+void     ResolveDoorSpace(int,int);
+void     RemoveObj(objtype*);
+void     SpawnParticles(objtype*,int,int);
+void     MakeActive(objtype*);
+void     SpawnSpear(int,int,int);
+void     SpawnBoulder(int,int,int);
+void     SpawnCrushingColumn(int,int,int);
+void     SpawnFirejet(int,int,int,int);
+void     T_Firethink(objtype*);
+void     SpawnBlade(int,int,int,int,int);
+void     T_OrobotChase(objtype*);
+void     SpawnMultiSpriteActor(classtype,int,int,int);
+boolean  ActorTryMove(objtype*,int,int,int);
+void     A_Repeat(objtype*);
+void     T_Heinrich_Defend(objtype*);
+void     T_Heinrich_Out_of_Control(objtype*);
+void     A_HeinrichShoot(objtype*);
+void     T_EsauWait(objtype*);
+void     T_EsauRise(objtype*);
+void     A_Drain(objtype*ob);
+void     T_Explosion(objtype*ob);
+void     T_MoveColumn(objtype*);
+void     EnableObject(long object);
+void     DisableObject(long object);
+
+void     T_Collide(objtype*);
+void  Collision(objtype*ob,objtype *attacker,int hitmomentumx,int hitmomentumy);
+void     ActorMovement (objtype *);
+void     MoveActor(objtype*);
+
+void     InitActorList(void);
+void     NewState(objtype*,statetype*);
+void     DoActor(objtype*);
+
+void     SpawnPushColumn(int tilex,int tiley,int which,int dir, int linked);
+void     SpawnGunThingy(classtype which, int tilex, int tiley, int dir);
+void     SpawnStand (classtype which, int tilex, int tiley, int dir, int ambush);
+void     SpawnPatrol (classtype which, int tilex, int tiley, int dir);
+void     SpawnDeadGuard (int tilex, int tiley);
+void     SpawnWallfire(int tilex, int tiley, int dir);
+void     SpawnMissile(objtype*,classtype,int,int,statetype*,int);
+
+void     InitHitRect (objtype *ob, unsigned radius);
+void     NewState (objtype *ob, statetype *state);
+void     SelectPathDir(objtype*);
+void     SelectChaseDir (objtype *ob);
+boolean  SightPlayer (objtype *ob);
+boolean  CheckLine (void*,void *,int);
+boolean  CheckSight (objtype *ob,void*);
+void     KillActor (objtype *ob);
+void     DamageThing (void *, int);
+void     MissileHit (objtype *,void*);
+void     GetNewActor(void);
+
+void     T_WallPath(objtype*);
+void     T_Path (objtype *ob);   //done
+void     T_RoboChase(objtype*ob);
+void     T_RoboPath(objtype*ob);
+void     T_Chase (objtype *ob);      //done
+void     T_EsauChase(objtype*ob); //done
+void     T_Spears(objtype*);
+void     T_Projectile (objtype *ob); //done
+void     T_Stand (objtype *ob);      //done
+void     T_GunStand(objtype *ob); //done
+void     T_Use(objtype *ob);         // done
+void     A_Shoot (objtype *ob);        // done
+void     A_MissileWeapon(objtype*);    // done
+void     A_Wallfire(objtype*);
+
+void     A_Steal(objtype*);
+
+void     T_Roll(objtype*);
+void     T_BossDied (objtype *ob);
+boolean  QuickSpaceCheck(objtype*,int,int);
+void     PushWallMove(int num);
+void     SpawnNewObj(unsigned,unsigned,statetype*,classtype);
+void     SpawnSpring(int,int);
+void     SpawnFourWayGun(int,int);
+void     SpawnSnake(int tilex,int tiley);
+void     SpawnSneaky(int,int);
+boolean  MissileTryMove(objtype*ob,int,int,int);
+
+void     SaveActors(byte ** buf, int * size);
+void     LoadActors(byte * buf, int size);
+
+boolean  TurnOffLight0 (int tilex, int tiley);
+boolean  TurnOffLight1 (int tilex, int tiley, int i, int j);
+boolean  TurnOffLight2 (int tilex, int tiley, int j);
+boolean  TurnOffLight3 (int tilex, int tiley, int i);
+
+void     ParseMomentum(objtype *ob,int angle);
+void     SpawnGroundExplosion(int x, int y, int z);
+void     RayShoot (objtype * shooter, int damage, int accuracy);
+void FindEmptyTile(int *stilex, int *stiley);
+void T_Wind( objtype *ob );
+void StopWind( void );
+
+#endif

Added: tags/rott-1.1/rott/rt_battl.c
===================================================================
--- tags/rott-1.1/rott/rt_battl.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_battl.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1129 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: RT_BATTL.C
+
+   author: James R. Dose
+   phone:  (214)-271-1365 Ext #221
+   date:   September 8, 1994
+
+   Battle mode support routines for Rise of the Triad.
+
+   (c) Copyright 1994 Apogee Software.  All Rights Reserved.
+**********************************************************************/
+
+#include <string.h>
+#include "rt_def.h"
+#include "rottnet.h"
+#include "isr.h"
+#include "rt_battl.h"
+#include "rt_actor.h"
+#include "rt_rand.h"
+#include "rt_playr.h"
+#include "rt_game.h"
+#include "rt_sound.h"
+#include "rt_com.h"
+#include "rt_msg.h"
+#include "rt_view.h"
+
+#include "rt_util.h"
+#include "rt_main.h"
+//MED
+#include "memcheck.h"
+
+#define INFINITE -1
+
+static battle_status BATTLE_StartRound( void );
+
+static int Timer;
+static int TimeLimit;
+static int NumberOfPlayers;
+static int BattleRound;
+static int BattleMode;
+
+static boolean RoundOver;
+static boolean KillsEndGame;
+static boolean KeepTrackOfKills;
+boolean UpdateKills;
+
+static boolean SwapFlag;
+
+static battle_type BattleOptions;
+
+specials BattleSpecialsTimes =
+      {
+      60, // god
+      60, // dog
+      20, // shrooms
+      20, // elasto
+      60, // asbestos vest
+      60, // bullet proof vest
+      GASTICS / VBLCOUNTER, // gas mask
+      60, // mercury mode
+
+      300, // god respawn
+      60, // dog respawn
+      60, // shrooms respawn
+      60, // elasto respawn
+      60, // asbestos vest respawn
+      60, // bullet proof vest respawn
+      60, // gas mask respawn
+      60  // mercury mode respawn
+      };
+
+short WhoKilledWho[ MAXPLAYERS ][ MAXPLAYERS ];
+short BATTLE_Points[ MAXPLAYERS ];
+short BATTLE_PlayerOrder[ MAXPLAYERS ];
+short BATTLE_Team[ MAXPLAYERS ];
+short BATTLE_TeamLeader[ MAXPLAYERS ];
+int   BATTLE_NumberOfTeams;
+int   BATTLE_NumCollectorItems;
+int   PointGoal;
+int   DisplayPoints;
+int   BATTLE_It;
+
+boolean BATTLE_ShowKillCount;
+
+boolean BATTLEMODE = false;
+
+/*---------------------------------------------------------------------
+	Function Prototypes:
+---------------------------------------------------------------------*/
+
+static int BATTLE_CheckKills
+	(
+	battle_event reason,
+	int player
+	);
+
+/*---------------------------------------------------------------------
+	Function: BATTLE_Init
+
+	Initializes the battle information.
+---------------------------------------------------------------------*/
+
+void BATTLE_Init
+	(
+	int battlemode,
+	int numplayers
+	)
+
+	{
+	int index;
+   int index2;
+   int team;
+   int TeamNumber[ MAXPLAYERCOLORS ];
+
+   #if (BATTLECHECK == 1)
+      if ( ( gamestate.teamplay ) && ( BattleMode == battle_Tag ) )
+         {
+         Error( "BATTLE_Init : Cannot play Tag in team mode.\n" );
+         }
+
+      if ( ( gamestate.teamplay ) && ( BattleMode == battle_CaptureTheTriad ) )
+         {
+         Error( "BATTLE_Init : Can only play Capture the Triad in team mode.\n" );
+         }
+   #endif
+
+	Timer   = 0;
+	RoundOver = false;
+
+	BattleRound = -1;
+   BATTLE_It = 0;
+
+	BattleMode = battlemode;
+
+	BATTLEMODE = false;
+
+   UpdateKills = true;
+
+	gamestate.BattleOptions.Gravity       = NORMAL_GRAVITY;
+	gamestate.BattleOptions.Speed         = bo_normal_speed;
+	gamestate.BattleOptions.Ammo          = bo_normal_shots;
+	gamestate.BattleOptions.HitPoints     = bo_character_hitpoints;
+	gamestate.BattleOptions.LightLevel    = bo_light_normal;
+   gamestate.BattleOptions.Kills         = bo_kills_default;
+	gamestate.BattleOptions.DangerDamage  = bo_danger_normal;
+	gamestate.BattleOptions.TimeLimit     = bo_time_infinite;
+   gamestate.BattleOptions.RespawnTime   = bo_normal_respawn_time;
+   gamestate.BattleOptions.RandomWeapons = false;
+   gamestate.BattleOptions.FriendlyFire  = true;
+   gamestate.BattleOptions.WeaponPersistence = false;
+	gamestate.BattleOptions.SpawnMines    = false;
+
+	if ( BattleMode != battle_StandAloneGame )
+		{
+		BATTLEMODE = true;
+
+      if ( gamestate.Product == ROTT_SHAREWARE )
+         {
+         switch( battlemode )
+            {
+            case battle_Normal :
+            case battle_Collector :
+            case battle_Hunter :
+               break;
+
+            default :
+               Error( "Shareware version can only play Normal, Collector, "
+                  "or Hunter in Comm-bat game." );
+            }
+         }
+
+		gamestate.BattleOptions.Gravity       = BattleOptions.Gravity;
+		gamestate.BattleOptions.Speed         = BattleOptions.Speed;
+		gamestate.BattleOptions.Ammo          = BattleOptions.Ammo;
+		gamestate.BattleOptions.HitPoints     = BattleOptions.HitPoints;
+		gamestate.BattleOptions.LightLevel    = BattleOptions.LightLevel;
+		gamestate.BattleOptions.Kills         = BattleOptions.Kills;
+		gamestate.BattleOptions.DangerDamage  = BattleOptions.DangerDamage;
+		gamestate.BattleOptions.TimeLimit     = BattleOptions.TimeLimit;
+      gamestate.BattleOptions.RespawnTime   = BattleOptions.RespawnTime;
+      gamestate.BattleOptions.RandomWeapons = BattleOptions.RandomWeapons;
+      gamestate.BattleOptions.FriendlyFire  = BattleOptions.FriendlyFire;
+      gamestate.BattleOptions.SpawnMines    = BattleOptions.SpawnMines;
+      gamestate.BattleOptions.WeaponPersistence = BattleOptions.WeaponPersistence;
+      }
+
+	gamestate.ShowScores                 = true;
+	gamestate.BattleOptions.SpawnHealth  = true;
+	gamestate.BattleOptions.SpawnWeapons = true;
+   gamestate.BattleOptions.SpawnDangers = true;
+	gamestate.SpawnCollectItems          = false;
+	gamestate.SpawnEluder                = false;
+	gamestate.SpawnDeluder               = false;
+	gamestate.BattleOptions.RespawnItems = false;
+
+	NumberOfPlayers = numplayers;
+
+
+   BATTLE_NumberOfTeams = numplayers;
+	for( index = 0; index < MAXPLAYERS; index++ )
+		{
+      BATTLE_PlayerOrder[ index ] = index;
+		BATTLE_Points[ index ] = 0;
+      for( index2 = 0; index2 < MAXPLAYERS; index2++ )
+         {
+         WhoKilledWho[ index ][ index2 ] = 0;
+         }
+
+      BATTLE_Team[ index ] = index;
+      BATTLE_TeamLeader[ index ] = index;
+      }
+
+
+   if ( gamestate.teamplay )
+      {
+      for( index = 0; index < MAXPLAYERCOLORS; index++ )
+         {
+         TeamNumber[ index ] = -1;
+         }
+
+      BATTLE_NumberOfTeams = 0;
+
+      for( index = 0; index < numplayers; index++ )
+         {
+         team = PLAYERSTATE[ index ].uniformcolor;
+         if ( TeamNumber[ team ] == -1 )
+            {
+            TeamNumber[ team ] = BATTLE_NumberOfTeams;
+            BATTLE_TeamLeader[ BATTLE_NumberOfTeams ] = index;
+            BATTLE_NumberOfTeams++;
+            }
+         BATTLE_Team[ index ] = TeamNumber[ team ];
+         }
+      }
+
+	PointGoal = gamestate.BattleOptions.Kills;
+	if ( ( gamestate.BattleOptions.Kills == bo_kills_random ) ||
+		( gamestate.BattleOptions.Kills == bo_kills_blind ) )
+		{
+		// Possibility of playing from 5 to 50 kills
+		PointGoal = ( GameRandomNumber( "BATTLE_Init", 0 ) % 46 ) + 5;
+		}
+
+   DisplayPoints = PointGoal;
+
+	for( index = 0; index < MAXPLAYERS; index++ )
+		{
+		gamestate.PlayerHasGun[ index ] = true;
+		}
+
+	KillsEndGame = true;
+	KeepTrackOfKills = true;
+
+	switch( BattleMode )
+		{
+		case battle_StandAloneGame :
+			KillsEndGame      = false;
+			KeepTrackOfKills  = false;
+			break;
+
+		case battle_Normal :
+			break;
+
+		case battle_ScoreMore :
+			break;
+
+		case battle_Collector :
+			for( index = 0; index < MAXPLAYERS; index++ )
+				{
+				gamestate.PlayerHasGun[ index ] = false;
+				}
+			KillsEndGame     = false;
+			KeepTrackOfKills = false;
+			gamestate.BattleOptions.SpawnHealth  = false;
+			gamestate.BattleOptions.SpawnWeapons = false;
+			gamestate.SpawnCollectItems          = true;
+			break;
+
+		case battle_Scavenger :
+			KillsEndGame     = false;
+			KeepTrackOfKills = false;
+			gamestate.BattleOptions.SpawnWeapons = true;
+			gamestate.BattleOptions.SpawnHealth  = true;
+			gamestate.SpawnCollectItems          = true;
+			break;
+
+		case battle_Hunter :
+         PointGoal *= BATTLE_NumberOfTeams;
+			KillsEndGame      = false;
+			KeepTrackOfKills  = true;
+         BATTLE_It = 0;
+         for( index = 0; index < NumberOfPlayers; index++ )
+            {
+            if ( BATTLE_Team[ index ] == 0 )
+               {
+               gamestate.PlayerHasGun[ index ] = false;
+               }
+            }
+			break;
+
+		case battle_Tag :
+			for( index = 0; index < MAXPLAYERS; index++ )
+				{
+				gamestate.PlayerHasGun[ index ] = false;
+				}
+
+			gamestate.BattleOptions.SpawnHealth  = false;
+			gamestate.BattleOptions.SpawnWeapons = false;
+			gamestate.BattleOptions.SpawnDangers = true;
+			KeepTrackOfKills = true;
+			KillsEndGame     = true;
+			break;
+
+		case battle_Eluder :
+			KeepTrackOfKills   = false;
+			KillsEndGame       = false;
+
+			for( index = 0; index < MAXPLAYERS; index++ )
+				{
+				gamestate.PlayerHasGun[ index ] = false;
+				}
+
+			gamestate.BattleOptions.SpawnWeapons = false;
+			gamestate.SpawnEluder                = true;
+			break;
+
+		case battle_Deluder :
+			KeepTrackOfKills    = false;
+			KillsEndGame        = false;
+			gamestate.SpawnDeluder = true;
+			break;
+
+		case battle_CaptureTheTriad :
+         KillsEndGame     = false;
+         KeepTrackOfKills = false;
+			break;
+		}
+
+	if ( BattleMode != battle_StandAloneGame )
+		{
+		if ( BattleOptions.RespawnItems )
+			{
+			gamestate.BattleOptions.RespawnItems = true;
+			}
+
+		if ( !BattleOptions.SpawnDangers )
+			{
+			gamestate.BattleOptions.SpawnDangers = false;
+			}
+
+		if ( !BattleOptions.SpawnHealth )
+			{
+			gamestate.BattleOptions.SpawnHealth = false;
+			}
+
+		if ( !BattleOptions.SpawnWeapons )
+			{
+			gamestate.BattleOptions.SpawnWeapons = false;
+			}
+
+		if ( gamestate.BattleOptions.Kills == bo_kills_blind )
+			{
+			gamestate.ShowScores = false;
+			}
+
+      GRAVITY = gamestate.BattleOptions.Gravity;
+
+      if ( gamestate.BattleOptions.Kills == bo_kills_infinite )
+         {
+         KillsEndGame = false;
+         }
+		}
+
+	BATTLE_StartRound();
+
+   #if (BATTLEINFO == 1)
+      SoftError( "GRAVITY      = %d\n", GRAVITY );
+      SoftError( "BO_Gravity   = %d\n", BattleOptions.Gravity );
+      SoftError( "BO_Speed     = %d\n", BattleOptions.Speed );
+      SoftError( "BO_Ammo      = %d\n", BattleOptions.Ammo );
+      SoftError( "BO_HitPoints = %d\n", BattleOptions.HitPoints );
+      SoftError( "BO_Dangers   = %d\n", BattleOptions.SpawnDangers );
+      SoftError( "BO_Health    = %d\n", BattleOptions.SpawnHealth );
+      SoftError( "BO_Weapons   = %d\n", BattleOptions.SpawnWeapons );
+      SoftError( "BO_Respawn   = %d\n", BattleOptions.RespawnItems );
+      SoftError( "BO_Light     = %d\n", BattleOptions.LightLevel );
+      SoftError( "BO_Kills     = %d\n", BattleOptions.Kills );
+      SoftError( "BO_DangerDam = %d\n", BattleOptions.DangerDamage );
+      SoftError( "BO_TimeLimit = %d\n", BattleOptions.TimeLimit );
+   #endif
+	}
+
+
+/*---------------------------------------------------------------------
+   Function: BATTLE_GetSpecials
+
+   Set the battle special times.
+---------------------------------------------------------------------*/
+
+void BATTLE_GetSpecials
+	(
+   void
+	)
+
+   {
+   int *src;
+   int *dest;
+
+   src  = ( int * )&BattleSpecialsTimes;
+   dest = ( int * )&gamestate.SpecialsTimes;
+
+   while( src < ( int * )( &BattleSpecialsTimes + 1 ) )
+      {
+      *dest = *src * VBLCOUNTER;
+      dest++;
+      src++;
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+	Function: BATTLE_SetOptions
+
+	Set the battle options.
+---------------------------------------------------------------------*/
+
+void BATTLE_SetOptions
+	(
+	battle_type *options
+	)
+
+	{
+	memcpy( &BattleOptions, options, sizeof( battle_type ) );
+	}
+
+
+/*---------------------------------------------------------------------
+   Function: BATTLE_GetOptions
+
+   Returns the battle options.
+---------------------------------------------------------------------*/
+
+void BATTLE_GetOptions
+   (
+   battle_type *options
+   )
+
+   {
+	memcpy( options, &BattleOptions, sizeof( battle_type ) );
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BATTLE_Shutdown
+
+   Shutsdown the battle information.
+---------------------------------------------------------------------*/
+
+void BATTLE_Shutdown
+   (
+   void
+   )
+
+   {
+   int index;
+   int index2;
+
+   Timer             = 0;
+   RoundOver         = false;
+   BattleRound       = 0;
+   BattleMode        = battle_StandAloneGame;
+   BATTLEMODE        = false;
+   NumberOfPlayers   = 1;
+   BATTLE_NumberOfTeams = 1;
+   PointGoal         = 0;
+   KillsEndGame      = false;
+   KeepTrackOfKills  = false;
+
+   for( index = 0; index < MAXPLAYERS; index++ )
+      {
+      BATTLE_Points[ index ] = 0;
+      for( index2 = 0; index2 < MAXPLAYERS; index2++ )
+         {
+         WhoKilledWho[ index ][ index2 ] = 0;
+         }
+		gamestate.PlayerHasGun[ index ] = true;
+		}
+	gamestate.BattleOptions.SpawnHealth  = true;
+	gamestate.BattleOptions.SpawnWeapons = true;
+	gamestate.BattleOptions.SpawnDangers = true;
+   gamestate.BattleOptions.RandomWeapons = false;
+   gamestate.BattleOptions.FriendlyFire  = true;
+   gamestate.BattleOptions.WeaponPersistence = false;
+	gamestate.BattleOptions.SpawnMines    = false;
+
+	gamestate.ShowScores        = true;
+	gamestate.SpawnCollectItems = false;
+	gamestate.SpawnEluder       = false;
+	gamestate.SpawnDeluder      = false;
+	}
+
+
+
+/*---------------------------------------------------------------------
+	Function: BATTLE_StartRound
+
+	Begins a round of battle.
+---------------------------------------------------------------------*/
+
+static battle_status BATTLE_StartRound
+	(
+	void
+	)
+
+	{
+	int index;
+
+	Timer     = 0;
+	TimeLimit = INFINITE;
+	RoundOver = false;
+
+	if ( !BATTLEMODE )
+		{
+		return( battle_no_event );
+		}
+
+	BattleRound++;
+
+	if ( gamestate.BattleOptions.TimeLimit == bo_time_infinite )
+      {
+		if ( BattleMode == battle_Hunter )
+			{
+	      TimeLimit = MINUTES_TO_GAMECOUNT( 99 );
+         }
+      else
+         {
+         TimeLimit = INFINITE;
+         }
+      }
+   else
+      {
+      TimeLimit = MINUTES_TO_GAMECOUNT( gamestate.BattleOptions.TimeLimit );
+      }
+
+	if ( BattleMode == battle_Hunter )
+		{
+		for( index = 0; index < MAXPLAYERS; index++ )
+			{
+			gamestate.PlayerHasGun[ index ] = true;
+			}
+
+		if ( ( gamestate.BattleOptions.Kills != bo_kills_infinite ) &&
+         ( BattleRound >= PointGoal ) )
+			{
+			return( battle_end_game );
+			}
+
+      BATTLE_It = BattleRound % BATTLE_NumberOfTeams;
+      for( index = 0; index < NumberOfPlayers; index++ )
+         {
+         if ( BATTLE_Team[ index ] == BATTLE_It )
+            {
+            gamestate.PlayerHasGun[ index ] = false;
+            }
+         }
+		}
+
+	return( battle_no_event );
+	}
+
+/*---------------------------------------------------------------------
+	Function: BATTLE_CheckGameStatus
+
+	Checks if certain battle mode conditions have been met and
+	determines the appropriate response.
+---------------------------------------------------------------------*/
+
+battle_status BATTLE_CheckGameStatus
+   (
+   battle_event reason,
+   int player
+   )
+
+   {
+   battle_status status;
+   int team;
+
+   if ( ( player < 0 ) || ( player >= MAXPLAYERS ) )
+      {
+      #if (BATTLECHECK == 1)
+         Error( "BATTLE_CheckGameStatus - reason %d : Player out of range!\n",
+            reason );
+      #else
+         return( battle_no_event );
+      #endif
+      }
+
+   if ( !BATTLEMODE )
+      {
+      return( battle_no_event );
+      }
+
+   team = BATTLE_Team[ player ];
+
+   status = battle_no_event;
+
+   switch( reason )
+      {
+      case battle_refresh :
+         Timer++;
+         if ( ( TimeLimit != INFINITE ) &&
+            ( Timer > TimeLimit ) )
+            {
+            RoundOver = true;
+
+            if ( BattleMode == battle_Hunter )
+               {
+               status = BATTLE_StartRound();
+               if ( status == battle_no_event )
+                  {
+                  status = battle_end_round;
+                  }
+               }
+            else
+               {
+               status = battle_out_of_time;
+               }
+
+            UpdateKills = true;
+            }
+
+         if ( UpdateKills )
+            {
+            BATTLE_SortPlayerRanks();
+            if ( gamestate.ShowScores )
+               {
+               DrawKills (false);
+               }
+            UpdateKills = false;
+            }
+
+         if ( RoundOver )
+            {
+            return( battle_end_game );
+            }
+         break;
+
+      case battle_player_killed :
+         #if (BATTLEINFO == 1)
+            SoftError( "BATTLE_CheckGameStatus: Player %d Died", player );
+            SoftError( "---ticks = %d\n", Timer );
+         #endif
+
+         switch( BattleMode )
+            {
+            case battle_Normal :
+            case battle_ScoreMore :
+            case battle_Hunter :
+               if ( BattleOptions.FriendlyFire )
+                  {
+                  BATTLE_Points[ team ]--;
+                  UpdateKills = true;
+                  }
+               break;
+
+            case battle_Tag :
+               // Same as being tagged
+               if ( BattleOptions.FriendlyFire )
+                  {
+                  BATTLE_Points[ team ]++;
+                  UpdateKills = true;
+                  }
+               break;
+            }
+
+         WhoKilledWho[ player ][ player ]++;
+         break;
+
+      case battle_get_collector_item :
+
+         if ( ( BattleMode != battle_Collector ) &&
+            ( BattleMode != battle_Scavenger ) )
+            {
+            #if (BATTLECHECK == 1)
+               Error( "BATTLE_CheckGameStatus : Got collector item on wrong battle mode!" );
+            #else
+               return( battle_no_event );
+            #endif
+            }
+         BATTLE_Points[ team ]++;
+         UpdateKills = true;
+
+         BATTLE_NumCollectorItems--;
+         if ( BATTLE_NumCollectorItems <= 0 )
+            {
+            RoundOver = true;
+            return( battle_end_game );
+            }
+         break;
+
+      case battle_caught_eluder :
+         if ( BattleMode == battle_Deluder )
+            {
+            return( battle_no_event );
+            }
+
+         if ( BattleMode != battle_Eluder )
+            {
+            #if (BATTLECHECK == 1)
+               Error( "BATTLE_CheckGameStatus : Caught Eluder on non-Eluder battle mode!" );
+            #else
+               return( battle_no_event );
+            #endif
+            }
+
+         BATTLE_Points[ team ]++;
+         UpdateKills = true;
+
+         if ( ( gamestate.BattleOptions.Kills != bo_kills_infinite ) &&
+            ( BATTLE_Points[ team ] >= PointGoal ) )
+            {
+            RoundOver = true;
+            return( battle_end_game );
+            }
+         RespawnEluder();
+         break;
+
+      case battle_shot_deluder :
+         if ( BattleMode == battle_Eluder )
+            {
+            return( battle_no_event );
+            }
+
+         if ( BattleMode != battle_Deluder )
+            {
+            #if (BATTLECHECK == 1)
+               Error( "BATTLE_CheckGameStatus : Shot Eluder on non-Eluder battle mode!" );
+            #else
+               return( battle_no_event );
+            #endif
+            }
+
+         BATTLE_Points[ team ]++;
+         UpdateKills = true;
+
+         if ( ( gamestate.BattleOptions.Kills != bo_kills_infinite ) &&
+            ( BATTLE_Points[ team ] >= PointGoal ) )
+            {
+            RoundOver = true;
+            return( battle_end_game );
+            }
+         RespawnEluder();
+         break;
+
+      case battle_captured_triad :
+         if ( BattleMode != battle_CaptureTheTriad )
+            {
+            #if (BATTLECHECK == 1)
+               Error( "BATTLE_CheckGameStatus : Triad Captured on invalid battle mode!" );
+            #else
+               return( battle_no_event );
+            #endif
+            }
+
+         if ( consoleplayer == player )
+            {
+            AddMessage( "You captured a triad!  You rule!", MSG_GAME );
+            }
+
+         BATTLE_Points[ team ]++;
+         UpdateKills = true;
+
+         if ( ( gamestate.BattleOptions.Kills != bo_kills_infinite ) &&
+            ( BATTLE_Points[ team ] >= PointGoal ) )
+            {
+            RoundOver = true;
+            return( battle_end_game );
+            }
+         break;
+
+      default :
+         #if (BATTLECHECK == 1)
+            Error( "BATTLE_CheckGameStatus called with a reason of %d.",
+               reason );
+         #else
+            return( battle_no_event );
+         #endif
+         break;
+      }
+
+   return( status );
+   }
+
+/*---------------------------------------------------------------------
+   Function: BATTLE_SortPlayerRanks
+
+   Sorts the players in order of score.
+---------------------------------------------------------------------*/
+
+void BATTLE_SortPlayerRanks
+   (
+   void
+   )
+
+   {
+   int i;
+   int j;
+   int temp;
+
+   SwapFlag = false;
+
+   if ( BattleMode == battle_Tag )
+      {
+      for( i = 0; i < BATTLE_NumberOfTeams - 1; i++ )
+         {
+         for( j = i + 1; j < BATTLE_NumberOfTeams; j++ )
+            {
+            if ( BATTLE_Points[ BATTLE_PlayerOrder[ i ] ] >
+               BATTLE_Points[ BATTLE_PlayerOrder[ j ] ] )
+               {
+               SwapFlag = true;
+               temp = BATTLE_PlayerOrder[ i ];
+               BATTLE_PlayerOrder[ i ] = BATTLE_PlayerOrder[ j ];
+               BATTLE_PlayerOrder[ j ] = temp;
+               }
+            }
+         }
+      }
+   else
+      {
+      for( i = 0; i < BATTLE_NumberOfTeams - 1; i++ )
+         {
+         for( j = i + 1; j < BATTLE_NumberOfTeams; j++ )
+            {
+            if ( BATTLE_Points[ BATTLE_PlayerOrder[ i ] ] <
+               BATTLE_Points[ BATTLE_PlayerOrder[ j ] ] )
+               {
+               SwapFlag = true;
+               temp = BATTLE_PlayerOrder[ i ];
+               BATTLE_PlayerOrder[ i ] = BATTLE_PlayerOrder[ j ];
+               BATTLE_PlayerOrder[ j ] = temp;
+               }
+            }
+
+         if ( BattleMode != battle_Hunter )
+            {
+            BATTLE_It = BATTLE_PlayerOrder[ 0 ];
+            }
+         }
+      }
+
+   #if (BATTLEINFO == 1)
+      for( i = 0; i < BATTLE_NumberOfTeams; i++ )
+         {
+         SoftError( "Sorted rank %d = player %d : Score = %d\n", i,
+            BATTLE_PlayerOrder[ i ], BATTLE_Points[ BATTLE_PlayerOrder[ i ] ] );
+         }
+   #endif
+
+   if ( ( SwapFlag == true ) && ( gamestate.ShowScores ) &&
+      ( SHOW_TOP_STATUS_BAR() || SHOW_KILLS() ) )
+      {
+      SD_Play ( SD_ENDBONUS1SND );
+      }
+   }
+
+
+/*---------------------------------------------------------------------
+   Function: BATTLE_PlayerKilledPlayer
+
+   Increases the number of kills a player has.
+---------------------------------------------------------------------*/
+
+battle_status BATTLE_PlayerKilledPlayer
+   (
+   battle_event reason,
+   int killer,
+   int victim
+   )
+
+   {
+   int points;
+   int status;
+   int killerteam;
+   int victimteam;
+
+   #if (BATTLEINFO == 1)
+      SoftError( "PlayerKilledPlayer:\nMode = %d\n", BattleMode );
+      SoftError( "Reason = %d\n", reason );
+      SoftError( "killer = %d, team = %d\n", killer, killerteam );
+      SoftError( "victim = %d, team = %d\n", victim, victimteam );
+      SoftError( "---ticks = %d\n", Timer );
+   #endif
+
+   if ( ( killer < 0 ) || ( killer >= MAXPLAYERS ) )
+      {
+      #if (BATTLECHECK == 1)
+         Error( "BATTLE_PlayerKilledPlayer - reason %d : Killer out of range!\n",
+            reason );
+      #else
+         return( battle_no_event );
+      #endif
+      }
+   if ( ( victim < 0 ) || ( victim >= MAXPLAYERS ) )
+      {
+      #if (BATTLECHECK == 1)
+         Error( "BATTLE_PlayerKilledPlayer - reason %d : Victim out of range!\n",
+            reason );
+      #else
+         return( battle_no_event );
+      #endif
+      }
+
+   if ( ( killer == victim ) && ( reason != battle_kill_with_missile ) &&
+      ( reason != battle_kill_with_missile_in_air ) )
+      {
+      #if (BATTLECHECK == 1)
+         Error( "BATTLE_PlayerKilledPlayer : Player "
+         "killed self with illegal reason of %d.", reason );
+      #else
+         return( battle_no_event );
+      #endif
+      }
+
+   killerteam = BATTLE_Team[ killer ];
+   victimteam = BATTLE_Team[ victim ];
+
+   if ( ( killerteam < 0 ) || ( killerteam >= BATTLE_NumberOfTeams ) ||
+      ( victimteam < 0 ) || ( victimteam >= BATTLE_NumberOfTeams ) )
+      {
+      #if (BATTLECHECK == 1)
+         Error( "BATTLE_PlayerKilledPlayer - reason %d : Team out of range!\n",
+            reason );
+      #else
+         return( battle_no_event );
+      #endif
+      }
+
+   if ( !BATTLEMODE )
+      {
+      return( battle_no_event );
+      }
+
+   if ( ( consoleplayer == victim ) &&
+      ( reason == battle_kill_by_crushing ) )
+      {
+      AddMessage( "Oh yeah.  You've been crushed.", MSG_GAME );
+      }
+
+   status = battle_no_event;
+   if ( BattleMode == battle_ScoreMore )
+      {
+      points = 0;
+      switch( reason )
+         {
+         case battle_kill_with_missile :
+            points = 1;
+            break;
+
+         case battle_kill_with_bullet :
+            points = 2;
+            break;
+
+         case battle_kill_with_missile_in_air :
+            points = 2;
+            break;
+
+         case battle_kill_with_bullet_in_air :
+            points = 3;
+            break;
+
+         case battle_kill_by_crushing :
+            points = 4;
+            break;
+
+         default :
+            #if (BATTLECHECK == 1)
+               Error( "BATTLE_PlayerKilledPlayer called with a reason of %d.",
+                  reason );
+            #else
+               return( battle_no_event );
+            #endif
+         }
+
+      if ( killerteam == victimteam )
+         {
+         if ( BattleOptions.FriendlyFire )
+            {
+            BATTLE_Points[ killerteam ]--;
+            WhoKilledWho[ killer ][ victim ]++;
+            }
+         }
+      else
+         {
+         BATTLE_Points[ killerteam ]      += points;
+         WhoKilledWho[ killer ][ victim ] += points;
+         }
+      UpdateKills = true;
+      }
+   else if ( BattleMode == battle_Tag )
+      {
+      if ( reason == battle_player_tagged )
+         {
+         WhoKilledWho[ killer ][ victim ]++;
+         BATTLE_Points[ victimteam ]++;
+         UpdateKills = true;
+         BATTLE_It   = victimteam;
+
+         if ( ( gamestate.BattleOptions.Kills != bo_kills_infinite ) &&
+            ( BATTLE_Points[ victimteam ] >= PointGoal ) )
+            {
+            RoundOver = true;
+            status = battle_end_game;
+            }
+         }
+      #if (BATTLECHECK == 1)
+      else if ( reason != battle_kill_by_crushing )
+         {
+         Error( "BATTLE_PlayerKilledPlayer - reason %d : "
+            "Illegal reason in Tag!\n", reason );
+         }
+      #endif
+
+      return( status );
+      }
+   else if ( BattleMode == battle_Hunter )
+      {
+      switch( reason )
+         {
+         case battle_kill_with_missile :
+         case battle_kill_with_bullet :
+         case battle_kill_with_missile_in_air :
+         case battle_kill_with_bullet_in_air :
+         case battle_kill_by_crushing :
+            if ( victimteam == BATTLE_It )
+               {
+               WhoKilledWho[ killer ][ victim ]++;
+               if ( killerteam == victimteam )
+                  {
+                  if ( BattleOptions.FriendlyFire )
+                     {
+                     BATTLE_Points[ killerteam ]--;
+                     UpdateKills = true;
+                     }
+                  }
+               else
+                  {
+                  BATTLE_Points[ killerteam ]++;
+                  UpdateKills = true;
+                  }
+               }
+            break;
+         default :
+         #if (BATTLECHECK == 1)
+            Error( "BATTLE_PlayerKilledPlayer called with a "
+               "reason of %d in Hunter.", reason );
+         #else
+	    ;
+         #endif
+         }
+      }
+   else
+      {
+      switch( reason )
+         {
+         case battle_kill_with_missile :
+         case battle_kill_with_bullet :
+         case battle_kill_with_missile_in_air :
+         case battle_kill_with_bullet_in_air :
+         case battle_kill_by_crushing :
+            WhoKilledWho[ killer ][ victim ]++;
+            if ( KeepTrackOfKills )
+               {
+               if ( killerteam == victimteam )
+                  {
+                  if ( BattleMode == battle_Normal )
+                     {
+                     if ( BattleOptions.FriendlyFire )
+                        {
+                        BATTLE_Points[ killerteam ]--;
+                        UpdateKills = true;
+                        }
+                     }
+                  }
+               else
+                  {
+                  BATTLE_Points[ killerteam ]++;
+                  UpdateKills = true;
+                  }
+               }
+            break;
+
+         default :
+            #if (BATTLECHECK == 1)
+               Error( "BATTLE_PlayerKilledPlayer called with a reason of %d.",
+                  reason );
+            #else
+               return( battle_no_event );
+            #endif
+         }
+      }
+
+   if ( ( KillsEndGame ) && ( BATTLE_Points[ killerteam ] >= PointGoal ) )
+      {
+      RoundOver = true;
+      status = battle_end_game;
+      }
+
+   return( status );
+   }

Added: tags/rott-1.1/rott/rt_battl.h
===================================================================
--- tags/rott-1.1/rott/rt_battl.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_battl.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,224 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: RT_BATTL.H
+
+   author: James R. Dose
+   phone:  (214)-271-1365 Ext #221
+   date:   September 8, 1994
+
+   Public header for RT_BATTL.C
+
+   (c) Copyright 1994 Apogee Software.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __RT_BATTLE_public
+#define __RT_BATTLE_public
+
+
+#define BIT_MASK( bit_number )   ( 1 << ( bit_number ) )
+#define MINUTES_TO_GAMECOUNT( minutes ) \
+   ( ( minutes ) * 60 * VBLCOUNTER )
+
+//
+// Return codes
+//
+
+typedef enum
+   {
+   battle_no_event,
+   battle_end_game,
+   battle_end_round,
+   battle_out_of_time
+   } battle_status;
+
+//
+// Types of battle events
+//
+
+typedef enum
+   {
+   battle_refresh,
+	battle_player_killed,
+	battle_player_tagged,
+	battle_kill_with_missile,
+   battle_kill_with_bullet,
+   battle_kill_with_missile_in_air,
+   battle_kill_with_bullet_in_air,
+   battle_kill_by_crushing,
+   battle_get_collector_item,
+   battle_caught_eluder,
+	battle_shot_deluder,
+   battle_captured_triad
+   } battle_event;
+
+//
+// Battle modes
+//
+
+enum
+   {
+   battle_StandAloneGame,
+   battle_Normal,
+   battle_ScoreMore,
+   battle_Collector,
+   battle_Scavenger,
+   battle_Hunter,
+   battle_Tag,
+   battle_Eluder,
+   battle_Deluder,
+	battle_CaptureTheTriad,
+   battle_NumBattleModes
+   };
+
+//
+// Battle mode option : Gravity
+//
+
+//enum
+//   {
+//   bo_low_gravity,
+//   bo_normal_gravity,
+//   bo_high_gravity
+//   };
+
+//
+// Battle mode option : Speed
+//
+
+enum
+   {
+   bo_normal_speed,
+   bo_fast_speed
+   };
+
+//
+// Battle mode option : Ammo
+//
+
+enum
+   {
+   bo_one_shot,
+   bo_normal_shots,
+   bo_infinite_shots
+   };
+
+//
+// Battle mode option : Hit points
+//
+
+#define bo_character_hitpoints 0
+#define bo_default_hitpoints   250
+
+//
+// Battle mode option : Light levels
+//
+
+enum
+   {
+   bo_light_dark,
+   bo_light_normal,
+   bo_light_bright,
+   bo_light_fog,
+   bo_light_periodic,
+   bo_light_lightning
+   };
+
+//
+// Battle mode option : Number of kills
+//
+
+enum
+   {
+   bo_kills_random   = -2,
+   bo_kills_blind    = -1,
+   bo_kills_infinite = 0,
+   bo_kills_default  = 21
+   };
+
+//
+// Battle mode option : Environment danger damage
+//
+
+enum
+   {
+   bo_danger_normal = -1,
+   bo_danger_low    = 1,
+   bo_danger_kill   = 30000
+   };
+
+//
+// Battle mode option : Time limit
+//
+#define bo_time_infinite 0
+
+//
+// Battle mode configuration
+//
+typedef struct
+	{
+	unsigned Gravity;
+	unsigned Speed;
+	unsigned Ammo;
+	unsigned HitPoints;
+	unsigned SpawnDangers;
+	unsigned SpawnHealth;
+	unsigned SpawnWeapons;
+   unsigned SpawnMines;
+   unsigned RespawnItems;
+   unsigned WeaponPersistence;
+   unsigned RandomWeapons;
+   unsigned FriendlyFire;
+	unsigned LightLevel;
+	int      Kills;
+	int      DangerDamage;
+	unsigned TimeLimit;
+   unsigned RespawnTime;
+   } battle_type;
+
+#define bo_normal_respawn_time 30
+
+extern boolean  BATTLEMODE;
+extern short    WhoKilledWho[ MAXPLAYERS ][ MAXPLAYERS ];
+extern short    BATTLE_Points[ MAXPLAYERS ];
+extern short    BATTLE_PlayerOrder[ MAXPLAYERS ];
+extern int      BATTLE_NumCollectorItems;
+extern int      PointGoal;
+extern int      DisplayPoints;
+extern int      BATTLE_It;
+extern boolean  BATTLE_ShowKillCount;
+extern short    BATTLE_Team[ MAXPLAYERS ];
+extern short    BATTLE_TeamLeader[ MAXPLAYERS ];
+extern int      BATTLE_NumberOfTeams;
+extern boolean  UpdateKills;
+
+// Located in RT_MENU.C
+extern battle_type    BATTLE_Options[ battle_NumBattleModes ];
+
+void          BATTLE_Init( int battlemode, int numplayers );
+void          BATTLE_GetSpecials( void );
+void          BATTLE_SetOptions( battle_type *options );
+void          BATTLE_GetOptions( battle_type *options );
+battle_status BATTLE_CheckGameStatus( battle_event reason, int player );
+void          BATTLE_SortPlayerRanks( void );
+battle_status BATTLE_PlayerKilledPlayer( battle_event reason, int killer, int victim );
+void          BATTLE_Shutdown( void );
+
+#endif

Added: tags/rott-1.1/rott/rt_build.c
===================================================================
--- tags/rott-1.1/rott/rt_build.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_build.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1572 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// RT_BUILD.C
+
+#include "rt_def.h"
+#include <string.h>
+#include "watcom.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef DOS
+#include <dos.h>
+#include <conio.h>
+#endif
+
+#include "rt_build.h"
+#include "_rt_buil.h"
+#include "rt_dr_a.h"
+#include "rt_draw.h"
+#include "rt_scale.h"
+#include "rt_menu.h"
+#include "rt_main.h"
+#include "isr.h"
+#include "rt_util.h"
+#include "engine.h"
+#include "lumpy.h"
+#include "rt_fc_a.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "rt_view.h"
+#include "rt_cfg.h"
+#include "rt_vid.h"
+
+#include "rt_sound.h"
+#include "modexlib.h"
+#include "rt_str.h"
+//MED
+#include "memcheck.h"
+
+byte * intensitytable;
+
+
+// LOCAL VARIABLES
+
+static byte * menubuf;
+static byte * menubuffers[2];
+static char menutitles[2][40];
+static int alternatemenubuf=0;
+static int titleshade=16;
+static int titleshadedir=1;
+static int titleyoffset=0;
+static char titlestring[40]="\0";
+static int readytoflip;
+static boolean MenuBufStarted=false;
+static int mindist=0x2700;
+static boolean BackgroundDrawn=false;
+
+static plane_t planelist[MAXPLANES],*planeptr;
+
+static int StringShade=16;
+
+extern void (*USL_MeasureString)(const char *, int *, int *, font_t *);
+
+static char strbuf[MaxString];
+
+//******************************************************************************
+//
+// DrawRotPost
+//
+//******************************************************************************
+
+void DrawRotPost ( int height, byte * src, byte * buf, int origheight)
+{
+   int y1;
+   int y2;
+
+   hp_srcstep=(origheight<<18)/height;
+   y1 = (((centery<<8)-(height<<5)+(MENUOFFY<<8)));
+   y2 = (((height<<6)+y1)>>8);
+
+   if (((y1>>8)>=200) || (y2<0))
+      return;
+   if (y1<0)
+      {
+      hp_startfrac=FixedMulShift(-y1,hp_srcstep,8);
+      y2 = (((height<<6)+y1)>>8);
+      y1=0;
+      }
+   else
+      {
+      hp_startfrac=FixedMulShift(255-(y1&0xff),hp_srcstep,8);
+      y1>>=8;
+      }
+   if (y2>200)
+      {
+      DrawMenuPost(200-y1, src, buf+ylookup[y1]);
+      }
+   else
+      {
+      DrawMenuPost(y2-y1, src, buf+ylookup[y1]);
+      }
+}
+
+
+
+/*
+========================
+=
+= GetPoint
+=
+========================
+*/
+
+void GetPoint (int x1, int y1, int px, int py, int * screenx, int * height, int angle)
+{
+
+  fixed gxt,gyt,nx,ny;
+  fixed gxtt,gytt;
+  int gx,gy;
+
+
+//
+// translate point to view centered coordinates
+//
+  gx = x1-px;
+  gy = y1-py;
+
+//
+// calculate newx
+//
+  gxt = FixedMul(gx,costable[angle]);
+  gyt = FixedMul(gy,sintable[angle]);
+  nx =gxt-gyt;
+
+  if (nx<mindist)
+	  nx=mindist;
+
+
+//
+// calculate newy
+//
+  gxtt = FixedMul(gx,sintable[angle]);
+  gytt = FixedMul(gy,costable[angle]);
+  ny = gytt+gxtt;
+
+// too close, don't overflow the divid'
+
+
+  *screenx = 160 + ((ny*NORMALWIDTHMULTIPLIER)/nx);            // DEBUG: use assembly divide
+
+  *height = NORMALHEIGHTDIVISOR/nx;
+
+  if (*screenx<0) *screenx=0;
+
+}
+
+
+/*
+========================
+=
+= InterpolatePlane
+=
+========================
+*/
+
+void InterpolatePlane (visobj_t * plane)
+{
+   int d1,d2;
+   int top;
+   int topinc;
+   int bot;
+   int botinc;
+   int i;
+   int texture;
+   int dh;
+   int dx;
+   int height;
+
+
+   dx=(plane->x2-plane->x1+1);
+   if (plane->h1<=0 || plane->h2<=0 || (dx==0))
+      return;
+   d1=65536/plane->h1;
+   d2=65536/plane->h2;
+   dh=((plane->h2-plane->h1)<<8)/dx;
+   top=0;
+   topinc=(d1)*((plane->textureend-plane->texturestart)>>4);
+   bot=d2*dx;
+   botinc=d1-d2;
+   height=(plane->h1<<8);
+   if (plane->x1>=viewwidth)
+      return;
+   for (i=plane->x1;i<=plane->x2;i++)
+      {
+      if ((i>=0 && i<viewwidth)&&(posts[i].wallheight<(height>>8)))
+         {
+         if (bot)
+            {
+            texture=((top/bot)+(plane->texturestart>>4))>>6;
+            posts[i].texture=texture*plane->viewx;
+            posts[i].lump=plane->shapenum;
+            posts[i].wallheight=(height>>8);
+            posts[i].offset=plane->viewx;
+            }
+         }
+      top+=topinc;
+      bot+=botinc;
+      height+=dh;
+      }
+}
+
+//******************************************************************************
+//
+// DrawPlanePosts
+//
+//******************************************************************************
+
+void   DrawPlanePosts (void)
+{
+   int height;
+   char * buf;
+   byte * shape;
+   int lastwall=-2;
+   int plane;
+   int i;
+
+   shadingtable=colormap+(16<<8);
+
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+
+      {
+      VGAWRITEMAP(plane);
+      buf=(byte *)(bufferofs);
+
+#ifdef DOS
+      for (i=plane;i<viewwidth;i+=4,buf++)
+#else
+      for (i=0;i<viewwidth;i++,buf++)
+#endif
+         {
+         height=(posts[i].wallheight);
+         if (height<=4)
+            continue;
+         if (lastwall!=posts[i].lump)
+            {
+            lastwall=posts[i].lump;
+            if (lastwall==-1)
+               shape=menubuf;
+            else
+               shape=W_CacheLumpNum(lastwall,PU_CACHE, Cvt_patch_t, 1);
+            }
+         DrawRotPost (height,shape+posts[i].texture,buf,posts[i].offset);
+         }
+      }
+}
+
+//******************************************************************************
+//
+// NextPlaneptr
+//
+//******************************************************************************
+
+void NextPlaneptr ( void )
+{
+   if (planeptr < &planelist[MAXPLANES-1]) // don't let it overflo'
+  		planeptr++;
+}
+
+//******************************************************************************
+//
+// RestPlaneptr
+//
+//******************************************************************************
+
+void ResetPlaneptr ( void )
+{
+   planeptr = &planelist[0];
+}
+
+//******************************************************************************
+//
+// NextVisptr
+//
+//******************************************************************************
+
+void NextVisptr ( void )
+{
+   if (visptr < &vislist[MAXVISIBLE-1]) // don't let it overflo'
+  		visptr++;
+}
+
+//******************************************************************************
+//
+// ResetVisptr
+//
+//******************************************************************************
+
+void ResetVisptr ( void )
+{
+   visptr = &vislist[0];
+}
+
+//******************************************************************************
+//
+// SetupPlanes
+//
+//******************************************************************************
+
+void SetupPlanes ( void )
+{
+   int i;
+
+   for (i=0;i<320;i++)
+      posts[i].wallheight=-1;
+}
+
+
+
+//******************************************************************************
+//
+// CalcPlanes
+//
+//******************************************************************************
+
+void CalcPlanes ( int px, int py, int angle )
+{
+   plane_t * pptr;
+
+   ResetVisptr();
+   for (pptr = &planelist[0]; pptr<planeptr; pptr++)
+      {
+      if (SideOfLine(pptr->x1,pptr->y1,pptr->x2,pptr->y2,px,py)<0)
+         {
+         GetPoint (pptr->x1,pptr->y1,px,py,&visptr->x1,&visptr->h1,angle);
+         GetPoint (pptr->x2,pptr->y2,px,py,&visptr->x2,&visptr->h2,angle);
+         visptr->textureend=0x0;
+         visptr->texturestart=pptr->texturewidth;
+         }
+      else
+         {
+         GetPoint (pptr->x2,pptr->y2,px,py,&visptr->x1,&visptr->h1,angle);
+         GetPoint (pptr->x1,pptr->y1,px,py,&visptr->x2,&visptr->h2,angle);
+         visptr->texturestart=0x0;
+         visptr->textureend=pptr->texturewidth;
+         }
+      visptr->shapenum=pptr->texture;
+      visptr->viewx=pptr->origheight;
+      visptr->viewheight=MAX(visptr->h1,visptr->h2);
+      NextVisptr();
+      }
+}
+
+
+//******************************************************************************
+//
+// DrawTransformedPlanes
+//
+//******************************************************************************
+
+void DrawTransformedPlanes ( void )
+{
+   int numvisible;
+   int greatest;
+   int height;
+   int i;
+   visobj_t * closest;
+
+   numvisible = visptr-&vislist[0];
+   if (!numvisible)
+      return;                                     // no visible objects
+   for (i = 0; i<numvisible; i++)
+      {
+      greatest = 0;
+      for (visstep=&vislist[0] ; visstep<visptr ; visstep++)
+         {
+         height = visstep->viewheight;
+         if (height > greatest)
+            {
+            greatest = height;
+            closest = visstep;
+            }
+         }
+      InterpolatePlane(closest);
+      closest->viewheight = 0;
+      }
+}
+
+
+//******************************************************************************
+//
+// ClearMenuBuf
+//
+//******************************************************************************
+
+void ClearMenuBuf ( void )
+{
+   byte * shape;
+
+   if (MenuBufStarted==false)
+      Error("Called ClearMenuBuf without menubuf started\n");
+
+   shape=W_CacheLumpName(MENUBACKNAME,PU_CACHE, Cvt_patch_t, 1);
+   shape+=8;
+   memcpy (menubuf,shape,TEXTUREW*TEXTUREHEIGHT);
+}
+
+//******************************************************************************
+//
+// ShutdownMenuBuf
+//
+//******************************************************************************
+
+void ShutdownMenuBuf ( void )
+{
+   if (MenuBufStarted==false)
+      return;
+   MenuBufStarted=false;
+   SafeFree(menubuffers[0]);
+   SafeFree(menubuffers[1]);
+   if (loadedgame==false)
+      SetViewSize(viewsize);
+}
+
+//******************************************************************************
+//
+// SetupMenuBuf
+//
+//******************************************************************************
+
+void SetupMenuBuf ( void )
+{
+#define SRCH 148
+#define SRCW 258
+#define PLANEX1 (-0x24000)
+#define PLANEX2 (0x23fff)
+#define PLANEW (16<<10)
+#define PLANEY (0x40000)
+#define PLANEW2 (0x5a827)
+
+   if (MenuBufStarted==true)
+      return;
+   MenuBufStarted=true;
+
+   // No top offsets like in game
+
+   centery=100;
+   centeryfrac=centery<<16;
+
+   strcpy(titlestring,menutitles[0]);
+
+   screenofs=0;
+   viewwidth=320;
+   viewheight=200;
+
+   alternatemenubuf=0;
+
+   ResetPlaneptr();
+   planeptr->texture=-1;
+   planeptr->y1=PLANEX1;
+   planeptr->x1=PLANEW;
+   planeptr->y2=PLANEX2;
+   planeptr->x2=PLANEW;
+   planeptr->origheight=TEXTUREHEIGHT;
+   planeptr->texturewidth=TEXTUREWIDTH;
+   NextPlaneptr();
+   planeptr->texture=-1;
+   planeptr->y1=PLANEX1;
+   planeptr->x1=-PLANEW;
+   planeptr->y2=PLANEX2;
+   planeptr->x2=-PLANEW;
+   planeptr->origheight=TEXTUREHEIGHT;
+   planeptr->texturewidth=TEXTUREWIDTH;
+   NextPlaneptr();
+   planeptr->texture=W_GetNumForName(MENUBACKNAME);
+   planeptr->y1=PLANEX1;
+   planeptr->x1=PLANEW;
+   planeptr->y2=PLANEX1;
+   planeptr->x2=-PLANEW;
+   planeptr->origheight=TEXTUREHEIGHT;
+   planeptr->texturewidth=TEXTUREWIDTH;
+   NextPlaneptr();
+   planeptr->texture=W_GetNumForName(MENUBACKNAME);
+   planeptr->y1=PLANEX2;
+   planeptr->x1=PLANEW;
+   planeptr->y2=PLANEX2;
+   planeptr->x2=-PLANEW;
+   planeptr->origheight=TEXTUREHEIGHT;
+   planeptr->texturewidth=TEXTUREWIDTH;
+   NextPlaneptr();
+
+   menubuffers[0]=SafeMalloc(TEXTUREW*TEXTUREHEIGHT);
+   menubuffers[1]=SafeMalloc(TEXTUREW*TEXTUREHEIGHT);
+   menubuf=menubuffers[0];
+   ClearMenuBuf();
+   BackgroundDrawn=false;
+}
+
+
+//******************************************************************************
+//
+// PositionMenuBuf
+//
+//******************************************************************************
+
+void PositionMenuBuf( int angle, int distance, boolean drawbackground )
+{
+   int px,py;
+   font_t * oldfont;
+   int width,height;
+
+
+   if (MenuBufStarted==false)
+      Error("Called PositionMenuBuf without menubuf started\n");
+   CalcTics();
+   SetupPlanes();
+   if ((drawbackground==true) || (BackgroundDrawn==false))
+      {
+      VL_DrawPostPic (W_GetNumForName("trilogo"));
+      }
+   px=FixedMulShift(distance,costable[angle&(FINEANGLES-1)],16);
+   py=FixedMulShift(-distance,sintable[angle&(FINEANGLES-1)],16);
+   CalcPlanes(px,py,(angle+ANG180)&(FINEANGLES-1));
+   DrawTransformedPlanes();
+   DrawPlanePosts();
+   oldfont=CurrentFont;
+   CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
+   US_MeasureStr (&width, &height, titlestring);
+   US_ClippedPrint ((320-width)>>1, MENUTITLEY-titleyoffset, titlestring);
+   CurrentFont=oldfont;
+   FlipPage();
+   titleshade+=titleshadedir;
+   if (abs(titleshade-16)>6)
+      titleshadedir=-titleshadedir;
+   if (BackgroundDrawn==false)
+      {
+      VL_CopyDisplayToHidden();
+      BackgroundDrawn=true;
+      }
+}
+
+//******************************************************************************
+//
+// RefreshMenuBuf
+//
+//******************************************************************************
+
+void RefreshMenuBuf( int time )
+{
+   int i;
+
+   if (MenuBufStarted==false)
+      Error("Called RefreshMenuBuf without menubuf started\n");
+
+   if (readytoflip)
+      return;
+
+   for (i=0;i<=time;i+=tics)
+      {
+      //PositionMenuBuf (0,NORMALVIEW,false);
+      PositionMenuBuf (0,NORMALVIEW,true);//bna++ in not true bg in menu is no redrawn
+      }
+}
+
+//******************************************************************************
+//
+// ScaleMenuBufPost
+//
+//******************************************************************************
+
+void ScaleMenuBufPost (byte * src, int topoffset, byte * buf)
+{
+   int  d;
+   int  offset;
+   int  length;
+   int  s;
+
+
+   while (1)
+      {
+      offset=*(src++);
+      if (offset==0xff)
+         return;
+      else
+         {
+         d=offset-topoffset;
+         length=*(src++);
+         for (s=0;s<length;s++,d++)
+            *(buf+d)=*(src+s);
+         src+=length;
+         }
+      }
+}
+
+//******************************************************************************
+//
+// SetAlternateMenuBuf
+//
+//******************************************************************************
+
+void SetAlternateMenuBuf ( void )
+{
+  if (MenuBufStarted==false)
+     Error("Called SetAlternateMenuBuf without menubuf started\n");
+
+  alternatemenubuf^=1;
+  readytoflip=1;
+  menubuf=menubuffers[alternatemenubuf];
+}
+
+//******************************************************************************
+//
+// SetMenuTitle
+//
+//******************************************************************************
+
+void SetMenuTitle ( const char * menutitle )
+{
+  if (MenuBufStarted==false)
+     Error("Called SetMenuTitle without menubuf started\n");
+  strcpy(menutitles[alternatemenubuf],menutitle);
+  if (readytoflip==0)
+     strcpy(titlestring,menutitle);
+}
+
+//******************************************************************************
+//
+// DrawMenuBufPicture
+//
+//******************************************************************************
+
+void DrawMenuBufPicture (int x, int y, const byte * pic, int w, int h)
+{
+   byte *buffer;
+   int i;
+
+   if (MenuBufStarted==false)
+      Error("Called DrawMenuBufPictoure without menubuf started\n");
+
+   if ((x<0) || (x+w>=TEXTUREW))
+      Error ("DrawMenuBufPicture: x is out of range\n");
+   if ((y<0) || (y+h>=TEXTUREHEIGHT))
+      Error ("DrawMenuBufPicture: y is out of range\n");
+
+   for (i=0;i<w;i++)
+      {
+      buffer = (byte*)menubuf+y+((x+i)*TEXTUREHEIGHT);
+      memcpy(buffer,pic,h);
+      pic+=h;
+      }
+}
+
+//******************************************************************************
+//
+// DrawMenuBufItem
+//
+//******************************************************************************
+
+void DrawMenuBufItem (int x, int y, int shapenum)
+{
+   byte *buffer;
+   int cnt;
+   byte *shape;
+   patch_t *p;
+
+   if (MenuBufStarted==false)
+      Error("Called DrawMenuBufItem without menubuf started\n");
+
+   shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
+   p = (patch_t *)shape;
+
+   if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
+      Error ("DrawMenuBufItem: x is out of range\n");
+   if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
+      Error ("DrawMenuBufItem: y is out of range\n");
+
+   buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
+
+   for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
+      ScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
+                        p->topoffset, buffer);
+}
+
+//******************************************************************************
+//
+// IScaleMenuBufPost
+//
+//******************************************************************************
+
+void IScaleMenuBufPost (byte * src, int topoffset, byte * buf, int color)
+{
+   int  d;
+   int  offset;
+   int  length;
+   int  s;
+
+
+   while (1)
+      {
+      offset=*(src++);
+      if (offset==0xff)
+         return;
+      else
+         {
+         d=offset-topoffset;
+         length=*(src++);
+         for (s=0;s<length;s++,d++)
+            *(buf+d)=*(intensitytable+((*(src+s))<<8)+color);
+         src+=length;
+         }
+      }
+}
+
+
+//******************************************************************************
+//
+// DrawIMenuBufItem
+//
+//******************************************************************************
+
+void DrawIMenuBufItem (int x, int y, int shapenum, int color)
+{
+   byte *buffer;
+   int cnt;
+   byte *shape;
+   patch_t *p;
+
+
+   if (MenuBufStarted==false)
+      Error("Called DrawIMenuBufItem without menubuf started\n");
+
+   shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
+   p = (patch_t *)shape;
+
+   if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
+      Error ("DrawIMenuBufItem: x is out of range\n");
+   if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
+      Error ("DrawIMenuBufItem: y is out of range\n");
+
+   buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
+
+   for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
+      IScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
+                        p->topoffset, buffer, color);
+}
+
+
+//******************************************************************************
+//
+// TScaleMenuBufPost
+//
+//******************************************************************************
+void TScaleMenuBufPost (byte * src, int topoffset, byte * buf)
+{
+   int  d;
+   int  offset;
+   int  length;
+   byte pixel;
+   int  s;
+
+
+   while (1)
+      {
+      offset=*(src++);
+      if (offset==0xff)
+         return;
+      else
+         {
+         d=offset-topoffset;
+         length=*(src++);
+         for (s=0;s<length;s++,d++)
+            {
+            pixel = *(buf+d);
+            pixel = *(shadingtable+pixel);
+            *(buf+d) = pixel;
+            }
+         src+=length;
+         }
+      }
+}
+
+
+//******************************************************************************
+//
+// CScaleMenuBufPost
+//
+//******************************************************************************
+void CScaleMenuBufPost (byte * src, int topoffset, byte * buf)
+{
+   int  d;
+   int  offset;
+   int  length;
+   byte pixel;
+   int  s;
+
+
+   while (1)
+      {
+      offset=*(src++);
+      if (offset==0xff)
+         return;
+      else
+         {
+         d=offset-topoffset;
+         length=*(src++);
+         for (s=0;s<length;s++,d++)
+            {
+            pixel = *(src+s);
+            pixel = *(shadingtable+pixel);
+            *(buf+d) = pixel;
+            }
+         src+=length;
+         }
+      }
+}
+
+
+//******************************************************************************
+//
+// EraseMenuBufRegion
+//
+//******************************************************************************
+
+void EraseMenuBufRegion (int x, int y, int width, int height)
+{
+   byte *buffer;
+   int xx,yy;
+   byte * shape;
+
+   if (MenuBufStarted==false)
+      Error("Called EraseMenuBufRegion without menubuf started\n");
+
+   if ((x<0) || (x+width>=TEXTUREW))
+      Error ("EraseMenuBufRegion: x is out of range\n");
+   if ((y<0) || (y+height>=TEXTUREHEIGHT))
+      Error ("EraseMenuBufRegion: y is out of range\n");
+
+   shape=W_CacheLumpName(MENUBACKNAME,PU_CACHE, Cvt_patch_t, 1);
+   shape+=8;
+   shape+=(x*TEXTUREHEIGHT)+y;
+   buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
+
+   for (xx = 0; xx < width; xx++)
+      {
+      for (yy = 0; yy < height; yy++)
+         *(buffer+yy)=*(shape+yy);
+      buffer+=TEXTUREHEIGHT;
+      shape+=TEXTUREHEIGHT;
+      }
+}
+
+
+//******************************************************************************
+//
+// DrawTMenuBufPic
+//
+//******************************************************************************
+
+void DrawTMenuBufPic (int x, int y, int shapenum)
+{
+   byte *buffer;
+   byte *buf;
+   int xx,yy;
+   int plane;
+   int pixel;
+   byte *shape;
+   byte *src;
+   pic_t *p;
+
+   if (MenuBufStarted==false)
+      Error("Called DrawTMenuBufPic without menubuf started\n");
+
+   shadingtable=colormap+(25<<8);
+
+   shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_pic_t, 1);
+   p = (pic_t *)shape;
+
+   if ((x<0) || ((x+(p->width<<2))>=TEXTUREW))
+      Error ("DrawTMenuBufPic: x is out of range\n");
+   if ((y<0) || ((y+p->height)>=TEXTUREHEIGHT))
+      Error ("DrawTMenuBufPic: y is out of range\n");
+
+   buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
+
+   src=(byte *)&p->data;
+   for (plane=0;plane<4;plane++,buffer+=TEXTUREHEIGHT)
+      {
+      for (yy = 0; yy < p->height; yy++)
+         {
+         buf=buffer+yy;
+         for (xx = 0; xx < p->width; xx++,buf+=TEXTUREHEIGHT<<2)
+            {
+            pixel = *(buf);
+            pixel = *(shadingtable+pixel);
+            *(buf) = pixel;
+            }
+         }
+      }
+}
+
+
+//******************************************************************************
+//
+// DrawTMenuBufItem
+//
+//******************************************************************************
+
+void DrawTMenuBufItem (int x, int y, int shapenum)
+{
+   byte *buffer;
+   int cnt;
+   byte *shape;
+   patch_t *p;
+
+
+   if (MenuBufStarted==false)
+      Error("Called DrawTMenuBufItem without menubuf started\n");
+
+   shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
+   p = (patch_t *)shape;
+
+   shadingtable=colormap+(25<<8);
+
+   if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
+      Error ("DrawTMenuBufItem: x is out of range\n");
+   if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
+      Error ("DrawTMenuBufItem: y is out of range\n");
+
+   buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
+
+   for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
+      TScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
+                        p->topoffset, buffer);
+}
+
+//******************************************************************************
+//
+// DrawColoredMenuBufItem
+//
+//******************************************************************************
+
+void DrawColoredMenuBufItem (int x, int y, int shapenum, int color)
+{
+   byte *buffer;
+   int cnt;
+   byte *shape;
+   patch_t *p;
+
+
+   if (MenuBufStarted==false)
+      Error("Called DrawColoredMenuBufItem without menubuf started\n");
+
+   shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
+   p = (patch_t *)shape;
+
+   shadingtable=playermaps[color]+(16<<8);
+
+   if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>=TEXTUREW))
+      Error ("DrawColoredMenuBufItem: x is out of range\n");
+   if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>=TEXTUREHEIGHT))
+      Error ("DrawColoredMenuBufItem: y is out of range\n");
+
+   buffer = (byte*)menubuf+y+((x-p->leftoffset)*TEXTUREHEIGHT);
+
+   for (cnt = 0; cnt < p->width; cnt++,buffer+=TEXTUREHEIGHT)
+      CScaleMenuBufPost ((byte *)(p->collumnofs[cnt]+shape),
+                        p->topoffset, buffer);
+}
+
+//******************************************************************************
+//
+// DrawMenuBufPic
+//
+//******************************************************************************
+
+void DrawMenuBufPic (int x, int y, int shapenum)
+{
+   byte *buffer;
+   byte *buf;
+   int xx,yy;
+   int plane;
+   byte *shape;
+   byte *src;
+   pic_t *p;
+
+   if (MenuBufStarted==false)
+      Error("Called DrawMenuBufPic without menubuf started\n");
+
+   shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_pic_t, 1);
+   p = (pic_t *)shape;
+
+   if ((x<0) || ((x+(p->width<<2))>=TEXTUREW))
+      Error ("DrawTMenuBufPic: x is out of range\n");
+   if ((y<0) || ((y+p->height)>=TEXTUREHEIGHT))
+      Error ("DrawTMenuBufPic: y is out of range\n");
+
+
+   buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
+
+   src=(byte *)&p->data;
+   for (plane=0;plane<4;plane++,buffer+=TEXTUREHEIGHT)
+      {
+      for (yy = 0; yy < p->height; yy++)
+         {
+         buf=buffer+yy;
+         for (xx = 0; xx < p->width; xx++,buf+=TEXTUREHEIGHT<<2)
+            *(buf)=*(src++);
+         }
+      }
+}
+
+
+
+
+//******************************************************************************
+//
+// DrawTMenuBufBox
+//
+//******************************************************************************
+
+
+void DrawTMenuBufBox ( int x, int y, int width, int height )
+   {
+   byte *buffer;
+   int   xx;
+   int   yy;
+   int   pixel;
+
+   if (MenuBufStarted==false)
+      Error("Called DrawTMenuBufBox without menubuf started\n");
+
+   shadingtable = colormap + ( 25 << 8 );
+
+   if ( ( x < 0 ) || ( ( x + width ) >= TEXTUREW ) )
+      Error ("DrawTMenuBar : x is out of range\n");
+   if ( ( y < 0 ) || ( y + height ) >= TEXTUREHEIGHT )
+      Error ("DrawTMenuBar : y is out of range\n");
+
+   buffer = ( byte * )menubuf + ( x * TEXTUREHEIGHT ) + y;
+
+   for ( xx = 0; xx < width; xx++ )
+      {
+      for ( yy = 0; yy < height; yy++ )
+         {
+         pixel = *( buffer + yy );
+         pixel = *( shadingtable + pixel );
+         *( buffer + yy ) = pixel;
+         }
+
+      buffer += TEXTUREHEIGHT;
+      }
+   }
+
+
+//******************************************************************************
+//
+// DrawTMenuBufHLine
+//
+//******************************************************************************
+
+void DrawTMenuBufHLine (int x, int y, int width, boolean up)
+{
+   byte *buffer;
+   byte *buf;
+   int xx;
+   int plane;
+   int pixel;
+   int w = width>>2;
+   int ww = w;
+
+   if ((x<0) || ((x+(width))>=TEXTUREW))
+      Error ("DrawTMenuBufBox: x is out of range\n");
+   if (y<0)
+      Error ("DrawTMenuBufBox: y is out of range\n");
+
+   buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
+
+   if (up)
+      shadingtable=colormap+(13<<8);
+   else
+      shadingtable=colormap+(25<<8);
+
+   for (plane = 0; plane < 4; plane++, buffer += TEXTUREHEIGHT)
+   {
+      w = ww;
+      switch (plane)
+      {
+         case 0:
+            if (width % 4)
+               w++;
+         break;
+         case 1:
+            if ((width % 4) > 1)
+               w++;
+         break;
+         case 2:
+            if ((width % 4) > 2)
+               w++;
+         break;
+      }
+
+
+      buf = buffer;
+      for (xx = 0; xx < w; xx++, buf += (TEXTUREHEIGHT<<2))
+      {
+         pixel = *(buf);
+         pixel = *(shadingtable+pixel);
+         *(buf) = pixel;
+      }
+   }
+}
+
+//******************************************************************************
+//
+// DrawTMenuBufVLine
+//
+//******************************************************************************
+
+void DrawTMenuBufVLine (int x, int y, int height, boolean up)
+{
+   byte *buffer;
+   byte *buf;
+   int yy;
+   int pixel;
+
+   if (x<0)
+      Error ("DrawTMenuBufBox: x is out of range\n");
+   if ((y<0) || ((y+height)>=TEXTUREHEIGHT))
+      Error ("DrawTMenuBufBox: y is out of range\n");
+
+   buffer = (byte*)menubuf+(x*TEXTUREHEIGHT)+y;
+
+   if (up)
+      shadingtable=colormap+(13<<8);
+   else
+      shadingtable=colormap+(25<<8);
+
+   for (yy = 0; yy < height; yy++)
+   {
+      buf = buffer+yy;
+      pixel = *(buf);
+      pixel = *(shadingtable+pixel);
+      *(buf) = pixel;
+   }
+}
+
+//******************************************************************************
+//******************************************************************************
+//
+// STRING ROUTINES
+//
+//******************************************************************************
+//******************************************************************************
+
+
+//******************************************************************************
+//
+// DrawMenuBufPropString ()
+//
+//******************************************************************************
+
+void DrawMenuBufPropString (int px, int py, const char *string)
+{
+   byte  pix;
+   int   width,height,ht;
+   byte  *source, *dest, *origdest;
+   int   ch;
+
+
+   if (MenuBufStarted==false)
+      Error("Called DrawMenuBufPropString without menubuf started\n");
+
+   ht = CurrentFont->height;
+   dest = origdest = (byte*)menubuf+(px*TEXTUREHEIGHT)+py;
+
+   while ((ch = (unsigned char)*string++)!=0)
+   {
+      ch -= 31;
+      width = CurrentFont->width[ch];
+      source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
+      while (width--)
+      {
+         height = ht;
+         while (height--)
+         {
+            pix = *source;
+            if (pix)
+               *dest = pix;
+
+            source++;
+            dest ++;
+         }
+
+         PrintX++;
+         origdest+=TEXTUREHEIGHT;
+         dest = origdest;
+      }
+   }
+
+}
+
+
+//******************************************************************************
+//
+// DrawMenuBufIString ()
+//
+//******************************************************************************
+
+void DrawMenuBufIString (int px, int py, const char *string, int color)
+{
+   byte  pix;
+   int   width,height,ht;
+   byte  *source, *dest, *origdest;
+   int   ch;
+
+   if (MenuBufStarted==false)
+      Error("Called DrawMenuBufPropString without menubuf started\n");
+
+   if ( ( color < 0 ) || ( color > 255 ) )
+      {
+      Error( "Intensity Color out of range\n" );
+      }
+
+   ht = IFont->height;
+   dest = origdest = (byte*)menubuf+(px*TEXTUREHEIGHT)+py;
+
+   PrintX = px;
+   PrintY = py;
+
+   while ((ch = (unsigned char)*string++)!=0)
+   {
+      // Tab
+      if ( ch == '\x9' )
+         {
+         int offset;
+
+         PrintX   -= px;
+         offset    = 4 * 5 - PrintX % ( 4 * 5 );
+         PrintX   += offset + px;
+         origdest += offset * TEXTUREHEIGHT;
+         dest      = origdest;
+         continue;
+         }
+
+      ch -= 31;
+      width = IFont->width[ ch ];
+
+      source = ( ( byte * )IFont ) + IFont->charofs[ ch ];
+
+      while (width--)
+      {
+         height = ht;
+         while (height--)
+         {
+            pix = *source;
+            if ( pix != 0xFE )
+               {
+               *dest = ( ( byte )intensitytable[ ( pix << 8 ) + color ] );
+               GetIntensityColor( pix );
+               }
+
+            source++;
+            dest ++;
+         }
+
+         PrintX++;
+         origdest+=TEXTUREHEIGHT;
+         dest = origdest;
+      }
+   }
+
+}
+
+
+//******************************************************************************
+//
+// DrawTMenuBufPropString ()
+//
+// Draws a string at px, py to bufferofs
+//
+//******************************************************************************
+
+void DrawTMenuBufPropString (int px, int py, const char *string)
+{
+   byte  pix;
+   int   width,height,ht;
+   byte  *source, *dest, *origdest;
+   int   ch;
+
+
+   if (MenuBufStarted==false)
+      Error("Called DrawTMenuBufPropString without menubuf started\n");
+
+   ht = CurrentFont->height;
+   dest = origdest = (byte*)menubuf+(px*TEXTUREHEIGHT)+py;
+
+   shadingtable=colormap+(StringShade<<8);
+   while ((ch = (unsigned char)*string++)!=0)
+   {
+      ch -= 31;
+      width = CurrentFont->width[ch];
+      source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
+      while (width--)
+      {
+         height = ht;
+         while (height--)
+         {
+            pix = *source;
+            if (pix)
+               {
+               pix = *dest;
+               pix = *(shadingtable+pix);
+               *dest = pix;
+               }
+            source++;
+            dest ++;
+         }
+
+         PrintX++;
+         origdest+=TEXTUREHEIGHT;
+         dest = origdest;
+      }
+   }
+}
+
+
+//******************************************************************************
+//
+// MenuBufCPrintLine() - Prints a string centered on the current line and
+//    advances to the next line. Newlines are not supported.
+//
+//******************************************************************************
+
+void MenuBufCPrintLine (const char *s)
+{
+   int w, h;
+
+   USL_MeasureString (s, &w, &h, CurrentFont);
+
+   if (w > WindowW)
+      Error("MenuBufCPrintLine() - String exceeds width");
+
+   PrintX = WindowX + ((WindowW - w) / 2);
+   DrawMenuBufPropString (PrintX, PrintY, s);
+   PrintY += h;
+}
+
+//******************************************************************************
+//
+// MenuBufCPrint() - Prints a string in the current window. Newlines are
+//    supported.
+//
+//******************************************************************************
+
+void MenuBufCPrint (const char *string)
+{
+   char  c,
+         *se,
+         *s;
+
+    /* !!! FIXME: this is lame. */
+    if (strlen(string) >= sizeof (strbuf))
+    {
+        fprintf(stderr, "buffer overflow!\n");
+        return;
+    }
+
+    /* prevent writing to literal strings... ( MenubufCPrint("feh"); ) */
+    strcpy(strbuf, string);
+    s = strbuf;
+
+   while (*s)
+   {
+      se = s;
+      while ((c = *se) && (c != '\n'))
+         se++;
+      *se = '\0';
+
+      MenuBufCPrintLine(s);
+
+      s = se;
+      if (c)
+      {
+         *se = c;
+         s++;
+      }
+   }
+}
+
+//******************************************************************************
+//
+// MenuBufPrintLine() - Prints a string on the current line and
+//    advances to the next line. Newlines are not supported.
+//
+//******************************************************************************
+
+void MenuBufPrintLine (const char *s)
+{
+   int w, h;
+
+   USL_MeasureString (s, &w, &h, CurrentFont);
+
+   if (w > WindowW)
+      Error("MenuBufCPrintLine() - String exceeds width");
+
+   PrintX = WindowX;
+   DrawMenuBufPropString (PrintX, PrintY, s);
+   PrintY += h;
+}
+
+//******************************************************************************
+//
+// MenuBufPrint() - Prints a string in the current window. Newlines are
+//    supported.
+//
+//******************************************************************************
+
+void MenuBufPrint (const char *string)
+{
+   char  c,
+         *se,
+         *s;
+
+   strcpy(strbuf, string);
+   s = strbuf;
+   
+   while (*s)
+   {
+      se = s;
+      while ((c = *se) && (c != '\n'))
+         se++;
+      *se = '\0';
+
+      MenuBufPrintLine(s);
+
+      s = se;
+      if (c)
+      {
+         *se = c;
+         s++;
+      }
+   }
+}
+
+//******************************************************************************
+//
+// MenuTBufPrintLine() - Prints a string on the current line and
+//    advances to the next line. Newlines are not supported.
+//
+//******************************************************************************
+
+void MenuTBufPrintLine (const char *s, int shade)
+{
+   int w, h;
+
+   USL_MeasureString (s, &w, &h, CurrentFont);
+
+   if (w > WindowW)
+      Error("MenuBufCPrintLine() - String exceeds width");
+
+   PrintX = WindowX;
+   StringShade=shade;
+   DrawTMenuBufPropString (PrintX, PrintY, s);
+   PrintY += h;
+}
+
+//******************************************************************************
+//
+// FlipMenuBuf
+//
+//******************************************************************************
+
+void FlipMenuBuf ( void )
+{
+   int i;
+   int dh;
+   int h;
+   int y;
+   int dy;
+   int time;
+   int flip;
+
+   if (MenuBufStarted==false)
+      Error("Called FlipMenuBuf without menubuf started\n");
+
+   if (!readytoflip)
+      Error("FlipMenuBuf called without SetAlternateMenuBuf beforehand");
+   readytoflip=0;
+   if (Menuflipspeed<=5)
+      {
+      menubuf=menubuffers[alternatemenubuf];
+      strcpy(titlestring,menutitles[alternatemenubuf]);
+      RefreshMenuBuf(0);
+      }
+   else
+      {
+      menubuf=menubuffers[alternatemenubuf^1];
+      strcpy(titlestring,menutitles[alternatemenubuf^1]);
+      time=Menuflipspeed-5;
+      dh=(1024<<8)/time;
+      h=0;
+      dy=((MENUTITLEY*6)<<8)/time;
+      y=0;
+      flip=0;
+      titleyoffset=0;
+      for (i=0;i<time;i+=tics)
+         {
+         PositionMenuBuf(h>>8,NORMALVIEW,true);
+         h+=dh*tics;
+         y+=dy*tics;
+         titleyoffset=y>>8;
+         if ((h>=512<<8) && (flip==0))
+            {
+            MN_PlayMenuSnd (SD_MENUFLIP);
+            h=1536<<8;
+            dy=-dy;
+            menubuf=menubuffers[alternatemenubuf];
+            strcpy(titlestring,menutitles[alternatemenubuf]);
+            flip=1;
+            }
+         }
+      }
+   titleyoffset=0;
+   BackgroundDrawn=false;
+}
+
+
+
+//******************************************************************************
+//
+// RotatePlane
+//
+//******************************************************************************
+
+void RotatePlane ( void )
+{
+   SetupMenuBuf();
+
+   while (!(Keyboard[0x01]))
+      {
+      RefreshMenuBuf(100);
+      SetAlternateMenuBuf();
+      ClearMenuBuf();
+      DrawMenuBufPic  (0,0,W_GetNumForName("newg11"));
+      DrawMenuBufItem (0,0,W_GetNumForName("apogee"));
+      FlipMenuBuf();
+      EraseMenuBufRegion(30,30,30,30);
+      RefreshMenuBuf(100);
+      SetAlternateMenuBuf();
+      ClearMenuBuf();
+      FlipMenuBuf();
+      }
+   ShutdownMenuBuf();
+}

Added: tags/rott-1.1/rott/rt_build.h
===================================================================
--- tags/rott-1.1/rott/rt_build.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_build.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,65 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_build_public
+#define _rt_build_public
+
+//***************************************************************************
+//
+// RT_BUILD.C
+//
+//***************************************************************************
+
+extern int Menuflipspeed;
+extern byte * intensitytable;
+
+void SetupMenuBuf ( void );
+void ShutdownMenuBuf ( void );
+
+void ClearMenuBuf ( void );
+void SetAlternateMenuBuf ( void );
+void SetMenuTitle ( const char * menutitle );
+
+void PositionMenuBuf( int angle, int distance, boolean drawbackground );
+void RefreshMenuBuf( int time );
+void FlipMenuBuf ( void );
+
+void DrawMenuBufItem (int x, int y, int shapenum);
+void DrawMenuBufIString (int px, int py, const char *string, int color);
+void DrawTMenuBufItem (int x, int y, int shapenum);
+void DrawIMenuBufItem (int x, int y, int shapenum, int color);
+void DrawColoredMenuBufItem (int x, int y, int shapenum, int color);
+void DrawMenuBufPic (int x, int y, int shapenum);
+void DrawTMenuBufPic (int x, int y, int shapenum);
+void EraseMenuBufRegion (int x, int y, int width, int height);
+
+void DrawMenuBufPropString (int px, int py, const char *string);
+void DrawTMenuBufPropString (int px, int py, const char *string);
+
+void DrawTMenuBufBox (int x, int y, int width, int height);
+void DrawTMenuBufHLine (int x, int y, int width, boolean up);
+void DrawTMenuBufVLine (int x, int y, int height, boolean up);
+void MenuBufCPrintLine (const char *s);
+void MenuBufCPrint (const char *s);
+void MenuBufPrint (const char *s);
+void MenuTBufPrintLine (const char *s, int shade);
+
+void DrawMenuBufPicture (int x, int y, const byte * pic, int w, int h);
+
+#endif

Added: tags/rott-1.1/rott/rt_cfg.c
===================================================================
--- tags/rott-1.1/rott/rt_cfg.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_cfg.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,2187 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//****************************************************************************
+//
+// RT_CFG.C
+//
+//****************************************************************************
+
+#define _ROTT_
+
+#ifdef DOS
+#include <io.h>
+#include <bios.h>
+#include <conio.h>
+#include <process.h>
+#else
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#endif
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef _ROTT_
+#include "rt_def.h"
+#else
+#include "st_def.h"
+#endif
+
+#include "rt_cfg.h"
+#include "version.h"
+
+#ifdef _ROTT_
+
+#include "scriplib.h"
+#include "rt_playr.h"
+#include "rt_menu.h"
+#include "rt_game.h"
+#include "rt_in.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "rt_crc.h"
+#include "rt_sound.h"
+#include "rt_util.h"
+#include "rt_main.h"
+#include "rt_view.h"
+#include "rt_msg.h"
+#include "rt_battl.h"
+#include "rt_net.h"
+#include "isr.h"
+#include "fx_man.h"
+#include "develop.h"
+
+#else
+
+#include "st_def.h"
+#include "rt_cfg.h"
+#include "scriplib.h"
+#include "rt_sound.h"
+#include "st_util.h"
+
+#endif
+//MED
+#include "memcheck.h"
+
+
+//******************************************************************************
+//
+// GLOBALS
+//
+//******************************************************************************
+
+extern int G_weaponscale;
+extern boolean iG_aimCross;
+
+boolean WriteSoundFile   = true;
+
+int     FXMode           = 0;
+int     MusicMode        = 0;
+
+int     MUvolume         = 196;
+int     FXvolume         = 196;
+
+#ifdef DOS
+fx_blaster_config SBSettings =
+   {
+   0x220, fx_SB, 7, 1, 5, 0x330, 0x620
+   };
+#endif
+
+boolean mouseenabled     = 1;
+boolean usemouselook     = 0;
+int     inverse_mouse    = 1; //set  to -1 to invert mouse
+boolean usejump          = 0;
+boolean sdl_fullscreen   = 1;
+
+boolean joystickenabled  = 0;
+boolean joypadenabled    = 0;
+int     joystickport     = 0;
+int     mouseadjustment  = 5;
+int     threshold        = 1;
+int     NumVoices        = 4;
+int     NumChannels      = 1;
+int     NumBits          = 8;
+#ifdef DOS
+int     MidiAddress      = 0x330;
+#endif
+boolean cybermanenabled  = false;
+boolean assassinenabled  = false;
+boolean spaceballenabled = false;
+boolean AutoDetailOn     = true;
+int     DoubleClickSpeed = 20;
+boolean BobbinOn         = true;
+int     Menuflipspeed    = 15;
+int     DetailLevel      = 2;         //HI DETAIL
+int     fandc            = 1;
+int     blanktime        = (2*60*VBLCOUNTER);
+boolean ConfigLoaded     = false;
+boolean stereoreversed   = false;
+
+int     DefaultDifficulty      = 2;
+int     DefaultPlayerCharacter = 0;
+int     DefaultPlayerColor     = 0;
+byte    passwordstring[20];
+
+#ifndef _ROTT_
+
+int     fulllight        = 0;
+int     viewsize         = 7;
+
+#endif
+MacroList CommbatMacros[MAXMACROS];
+
+#ifdef DOS
+char *ApogeePath = "APOGEECD";
+#else
+char ApogeePath[256];
+#endif
+
+//******************************************************************************
+//
+// LOCALS
+//
+//******************************************************************************
+
+static char SoundName[13]  = "sound.rot";
+
+#ifdef _ROTT_
+
+static char *ConfigName = "config.rot";
+static char *ScoresName = "scores.rot";
+static char *ROTT       = "rott.rot";
+static char *CONFIG     = "setup.rot";
+static char *BattleName = "battle.rot";
+
+AlternateInformation RemoteSounds;
+//AlternateInformation PlayerGraphics;
+AlternateInformation GameLevels;
+AlternateInformation BattleLevels;
+char CodeName[MAXCODENAMELENGTH];
+
+#endif
+
+
+#ifdef _ROTT_
+
+//******************************************************************************
+//
+// ReadScores ()
+//
+//******************************************************************************
+
+void ReadScores (void)
+{
+   int file;
+   char filename[ 128 ];
+
+   GetPathFromEnvironment( filename, ApogeePath, ScoresName );
+   if (access (filename, F_OK) == 0)
+      {
+      file = SafeOpenRead (filename);
+      SafeRead (file, &Scores, sizeof (Scores));
+      close(file);
+      }
+   else
+      gamestate.violence = 0;
+}
+
+#endif
+
+//******************************************************************************
+//
+// ReadInt
+//
+//******************************************************************************
+
+void ReadInt (const char * s1, int * val)
+{
+   GetToken (true);
+   if (!strcmpi (token,s1))
+      {
+      if (TokenAvailable()==true)
+         {
+         GetToken(false);
+         *val=ParseNum(token);
+         }
+      }
+}
+
+//******************************************************************************
+//
+// ReadBoolean
+//
+//******************************************************************************
+
+void ReadBoolean (const char * s1, boolean * val)
+{
+   int temp;
+
+   temp = (int)(*val);
+   ReadInt (s1,&temp);
+   *val = (boolean) temp;
+}
+
+//******************************************************************************
+//
+// ReadUnsigned
+//
+//******************************************************************************
+
+void ReadUnsigned (const char * s1, unsigned long * val)
+{
+   int temp;
+
+   temp = (int)(*val);
+   ReadInt (s1,&temp);
+   *val = (unsigned) temp;
+}
+
+//******************************************************************************
+//
+// ParseSoundFile ()
+//
+//******************************************************************************
+
+boolean ParseSoundFile (void)
+{
+   boolean retval = true;
+   int version    = 0;
+
+   ReadInt("Version",&version);
+
+   if (version == ROTTVERSION)
+   {
+      // Read in Music Mode
+
+      ReadInt ("MusicMode",&MusicMode);
+
+      // Read in FX Mode
+
+      ReadInt ("FXMode",&FXMode);
+
+      // Read in Music Volume
+
+      ReadInt ("MusicVolume", &MUvolume);
+
+      // Read in FX Volume
+
+      ReadInt ("FXVolume", &FXvolume);
+
+      // Read in numvoices
+
+      ReadInt ("NumVoices",&NumVoices);
+
+      // Read in numchannels
+
+      ReadInt ("NumChannels",&NumChannels);
+
+      // Read in numbits
+
+      ReadInt ("NumBits",&NumBits);
+
+#ifdef DOS
+      // Read in Midi Address
+
+      ReadInt ("MidiAddress",&MidiAddress);
+#endif
+
+      // Read in stereo reversal
+
+      ReadBoolean ("StereoReverse",&stereoreversed);
+
+#ifdef DOS
+      // Read in Sound Blaster info
+      ReadUnsigned ("SBType",  &SBSettings.Type );
+      ReadUnsigned ("SBPort",  &SBSettings.Address );
+      ReadUnsigned ("SBIrq",   &SBSettings.Interrupt );
+      ReadUnsigned ("SBDma8",  &SBSettings.Dma8 );
+      ReadUnsigned ("SBDma16", &SBSettings.Dma16 );
+      ReadUnsigned ("SBMidi",  &SBSettings.Midi );
+      ReadUnsigned ("SBEmu",   &SBSettings.Emu );
+#endif
+   }
+   else
+      retval = false;
+
+   return (retval);
+}
+
+
+
+//******************************************************************************
+//
+// SetSoundDefaultValues ()
+//
+//******************************************************************************
+void SetSoundDefaultValues
+   (
+   void
+   )
+
+   {
+#ifdef DOS
+   fx_blaster_config blaster;
+#endif
+   int status;
+
+   //
+   //  no config file, so select default values
+   //
+   #if !defined(PLATFORM_DOS)
+   // icculus' SDL_mixer driver looks like a soundscape to us
+   MusicMode   = 6;
+   FXMode      = 6;
+   NumVoices   = 8;
+   NumChannels = 2;
+   NumBits     = 16;
+   stereoreversed = false;
+   #else
+   MusicMode   = 0;
+   FXMode      = 0;
+   NumVoices   = 4;
+   NumChannels = 1;
+   NumBits     = 8;
+   MidiAddress = 0x330;
+   stereoreversed = false;
+
+   status = FX_GetBlasterSettings( &blaster );
+   if ( status == FX_Ok )
+      {
+      SBSettings.Type      = blaster.Type;
+      SBSettings.Address   = blaster.Address;
+      SBSettings.Interrupt = blaster.Interrupt;
+      SBSettings.Dma8      = blaster.Dma8;
+      SBSettings.Dma16     = blaster.Dma16;
+      SBSettings.Midi      = blaster.Midi;
+      SBSettings.Emu       = blaster.Emu;
+      }
+   #endif
+   }
+
+
+#ifdef _ROTT_
+
+extern char    pword[ 13 ];
+//******************************************************************************
+//
+// ConvertStringToPasswordString ()
+//
+//******************************************************************************
+
+#define PASSWORDENCRYPTER "7d7e4a2d3b6a0319554654231f6d2a"
+
+void ConvertStringToPasswordString ( char * string )
+{
+   int i;
+   unsigned int j;
+   char temp[3];
+
+   memset(temp,0,sizeof(temp));
+
+   for (i=0;i<13;i++)
+      {
+      memcpy(&temp[0],&string[i<<1],2);
+      sscanf(&temp[0],"%x",&j);
+      passwordstring[i+0] = j & 0xff; j >>= 8;
+      passwordstring[i+1] = j & 0xff; j >>= 8;
+      passwordstring[i+2] = j & 0xff; j >>= 8;
+      passwordstring[i+3] = j & 0xff;
+      }
+}
+
+//******************************************************************************
+//
+// ConvertPasswordStringToPassword ()
+//
+//******************************************************************************
+
+void ConvertPasswordStringToPassword ( void )
+{
+   int i;
+   int x;
+   char temp[3];
+   char key[40];
+
+   memset(temp,0,sizeof(temp));
+   strcpy(&key[0],PASSWORDENCRYPTER);
+
+   for (i=0;i<12;i++)
+      {
+      memcpy(&temp[0],&key[i<<1],2);
+      sscanf(&temp[0],"%x",&x);
+      pword[i]=passwordstring[i]^x;
+      }
+   memcpy(&temp[0],&key[i<<1],2);
+   sscanf(&temp[0],"%x",&x);
+   gamestate.violence=passwordstring[i]^x;
+   if (
+       (gamestate.violence<0) ||
+       (gamestate.violence>3)
+      )
+      gamestate.violence=0;
+}
+
+//******************************************************************************
+//
+// ConvertPasswordStringToString ()
+//
+//******************************************************************************
+
+void ConvertPasswordStringToString ( char * string )
+{
+   int i;
+   char temp[8];
+
+   memset(temp,0,sizeof(temp));
+
+   for (i=0;i<13;i++)
+      {
+      itoa((passwordstring[i]>>4),&temp[0],16);
+      string[(i<<1)+0]=temp[0];
+      itoa((passwordstring[i]&0xf),&temp[0],16);
+      string[(i<<1)+1]=temp[0];
+      }
+}
+
+//******************************************************************************
+//
+// ConvertPasswordToPasswordString ()
+//
+//******************************************************************************
+
+void ConvertPasswordToPasswordString ( void )
+{
+   int i;
+   int x;
+   char temp[3];
+   char key[40];
+
+   memset(temp,0,sizeof(temp));
+   strcpy(&key[0],PASSWORDENCRYPTER);
+
+   for (i=0;i<12;i++)
+      {
+      memcpy(&temp[0],&key[i<<1],2);
+      sscanf(&temp[0],"%x",&x);
+      passwordstring[i]=pword[i]^x;
+      }
+   memcpy(&temp[0],&key[i<<1],2);
+   sscanf(&temp[0],"%x",&x);
+   passwordstring[i]=gamestate.violence^x;
+}
+
+//******************************************************************************
+//
+// ParseConfigFile ()
+//
+//******************************************************************************
+
+boolean ParseConfigFile (void)
+{
+//   int temp;
+   boolean retval = true;
+   int version    = 0;
+
+   ReadInt("Version",&version);
+
+   if (version == ROTTVERSION)
+   {
+      // Read in MouseEnabled
+      ReadBoolean("MouseEnabled",&mouseenabled);
+
+      // Read in UseMouseLook
+      ReadBoolean("UseMouseLook",&usemouselook);
+
+      ReadInt("InverseMouse",&inverse_mouse);
+
+	  // Read in UseJump
+      ReadBoolean("UseJump",&usejump);
+
+      // Read in CrossHair
+      ReadBoolean("CrossHair",&iG_aimCross);
+
+      // Read in JoystickEnabled
+      ReadBoolean("JoystickEnabled",&joystickenabled);
+
+      // Read in JoypadEnabled
+      ReadBoolean("JoypadEnabled",&joypadenabled);
+
+      // Read in JoystickPort
+
+      ReadInt("JoystickPort",&joystickport);
+      
+      // Read in fullscreen
+      ReadBoolean("FullScreen", &sdl_fullscreen);
+      
+      // Read in resolution
+      ReadInt("ScreenWidth", &iGLOBAL_SCREENWIDTH);
+      ReadInt("ScreenHeight", &iGLOBAL_SCREENHEIGHT);
+
+      // Read in ViewSize
+
+      ReadInt("ViewSize",&viewsize);
+
+      // Read in Weaponscale
+
+      ReadInt("Weaponscale",&G_weaponscale);//bna added
+	   if ((G_weaponscale <150)||(G_weaponscale>600)){
+		   if (iGLOBAL_SCREENWIDTH == 320){
+				G_weaponscale=168;
+		   }else if (iGLOBAL_SCREENWIDTH == 640){
+				G_weaponscale=299;		
+		   }else if (iGLOBAL_SCREENWIDTH == 800) {
+				G_weaponscale=376;
+		   }	   
+	   }
+
+      // Read in MouseAdjustment
+
+      ReadInt("MouseAdjustment",&mouseadjustment);
+
+      // Read in threshold
+
+      ReadInt("Threshold",&threshold);
+
+      // Read in Auto Detail
+
+      ReadBoolean ("AutoDetail", &AutoDetailOn);
+
+      // Read in Light Dim
+
+      ReadInt ("LightDim", &fulllight);
+
+      // Read in Bobbin' On
+
+      ReadBoolean ("BobbingOn", &BobbinOn);
+
+      // Read in Double Click Speed
+
+      ReadInt ("DoubleClickSpeed", &DoubleClickSpeed);
+
+      // Read in Menu Flip Speed
+
+      ReadInt ("MenuFlipSpeed", &Menuflipspeed);
+
+      // Read in Detail Level
+
+      ReadInt ("DetailLevel", &DetailLevel);
+
+      // Read in Floor and Ceiling
+
+      ReadInt ("FloorCeiling", &fandc);
+
+      // Read in MessagesEnabled
+
+      ReadBoolean ("Messages", &MessagesEnabled );
+
+      // Read in Autorun
+
+      ReadInt ("AutoRun", &gamestate.autorun );
+
+      // Read in GammaIndex
+
+      ReadInt ("GammaIndex", &gammaindex);
+
+      // Read screen blanking time
+
+      ReadInt ("BlankTime", &blanktime);
+
+      blanktime=blanktime*60*VBLCOUNTER;
+
+      // Read keys
+
+      ReadInt ("Fire",        &buttonscan[0]);
+      ReadInt ("Strafe",      &buttonscan[1]);
+      ReadInt ("Run",         &buttonscan[2]);
+      ReadInt ("Use",         &buttonscan[3]);
+      ReadInt ("LookUp",      &buttonscan[4]);
+      ReadInt ("LookDn",      &buttonscan[5]);
+      ReadInt ("Swap",        &buttonscan[6]);
+      ReadInt ("Drop",        &buttonscan[7]);
+      ReadInt ("TargetUp",    &buttonscan[8]);
+      ReadInt ("TargetDn",    &buttonscan[9]);
+      ReadInt ("SelPistol",   &buttonscan[10]);
+      ReadInt ("SelDualPistol",&buttonscan[11]);
+      ReadInt ("SelMP40",     &buttonscan[12]);
+      ReadInt ("SelMissile",  &buttonscan[13]);
+      ReadInt ("AutoRun",     &buttonscan[14]);
+      ReadInt ("LiveRemRid",  &buttonscan[15]);
+      ReadInt ("StrafeLeft",  &buttonscan[16]);
+      ReadInt ("StrafeRight", &buttonscan[17]);
+      ReadInt ("VolteFace",   &buttonscan[18]);
+      ReadInt ("Aim",         &buttonscan[19]);
+      ReadInt ("Forward",     &buttonscan[20]);
+      ReadInt ("Right",       &buttonscan[21]);
+      ReadInt ("Backward",    &buttonscan[22]);
+      ReadInt ("Left",        &buttonscan[23]);
+      ReadInt ("Map",         &buttonscan[24]);
+      ReadInt ("SendMessage", &buttonscan[25]);
+      ReadInt ("DirectMessage",&buttonscan[26]);
+
+      ReadInt ("MouseButton0",&buttonmouse[0]);
+      ReadInt ("MouseButton1",&buttonmouse[1]);
+      ReadInt ("MouseButton2",&buttonmouse[2]);
+      ReadInt ("DblClickB0",  &buttonmouse[3]);
+      ReadInt ("DblClickB1",  &buttonmouse[4]);
+      ReadInt ("DblClickB2",  &buttonmouse[5]);
+
+      ReadInt ("JoyButton0",  &buttonjoy[0]);
+      ReadInt ("JoyButton1",  &buttonjoy[1]);
+      ReadInt ("JoyButton2",  &buttonjoy[2]);
+      ReadInt ("JoyButton3",  &buttonjoy[3]);
+      ReadInt ("DblClickJB0", &buttonjoy[4]);
+      ReadInt ("DblClickJB1", &buttonjoy[5]);
+      ReadInt ("DblClickJB2", &buttonjoy[6]);
+      ReadInt ("DblClickJB3", &buttonjoy[7]);
+
+      ReadInt ("JoyMaxX",     &joyxmax);
+      ReadInt ("JoyMaxY",     &joyymax);
+      ReadInt ("JoyMinX",     &joyxmin);
+      ReadInt ("JoyMinY",     &joyymin);
+
+      ReadInt( "DefaultDifficulty", &DefaultDifficulty );
+      ReadInt( "DefaultPlayerCharacter", &DefaultPlayerCharacter );
+      ReadInt( "DefaultPlayerColor", &DefaultPlayerColor );
+
+      // Get Password string
+      GetToken (true);
+      if (!stricmp (token, "SecretPassword"))
+         {
+         GetTokenEOL (false);
+         ConvertStringToPasswordString ( &name[0] );
+         }
+
+      if (!CybermanPresent)
+         cybermanenabled = false;
+
+      if (!AssassinPresent)
+         assassinenabled = false;
+
+      if (!SpaceBallPresent)
+         spaceballenabled = false;
+
+      if (!MousePresent)
+         mouseenabled = false;
+
+      if (!JoysPresent[joystickport])
+         joystickenabled = false;
+
+      // precaution
+
+      if (!joyxmin || !joyxmax || !joyymin || !joyymax)
+         joystickenabled = false;
+
+      if (joystickenabled)
+         IN_SetupJoy (joystickport, joyxmin, joyxmax, joyymin, joyymax);
+   }
+   else
+      retval = false;
+
+   return (retval);
+}
+
+
+//******************************************************************************
+//
+// ParseBattleFile ()
+//
+//******************************************************************************
+boolean ParseBattleFile (void)
+{
+   boolean retval = true;
+   int version    = 0;
+   int index;
+   int temp;
+   extern specials BattleSpecialsTimes;
+
+   ReadInt("Version",&version);
+   if (version != ROTTVERSION)
+      retval = false;
+   else
+      {
+      ReadBoolean( "ShowKillCount", &BATTLE_ShowKillCount );
+
+      ReadInt( "GodModeTime",                &BattleSpecialsTimes.GodModeTime );
+      ReadInt( "DogModeTime",                &BattleSpecialsTimes.DogModeTime );
+      ReadInt( "ShroomsModeTime",            &BattleSpecialsTimes.ShroomsModeTime );
+      ReadInt( "ElastoModeTime",             &BattleSpecialsTimes.ElastoModeTime );
+      ReadInt( "AsbestosVestTime",           &BattleSpecialsTimes.AsbestosVestTime );
+      ReadInt( "BulletProofVestTime",        &BattleSpecialsTimes.BulletProofVestTime );
+      ReadInt( "GasMaskTime",                &BattleSpecialsTimes.GasMaskTime );
+      ReadInt( "MercuryModeTime",            &BattleSpecialsTimes.MercuryModeTime );
+      ReadInt( "GodModeRespawnTime",         &BattleSpecialsTimes.GodModeRespawnTime );
+      ReadInt( "DogModeRespawnTime",         &BattleSpecialsTimes.DogModeRespawnTime );
+      ReadInt( "ShroomsModeRespawnTime",     &BattleSpecialsTimes.ShroomsModeRespawnTime );
+      ReadInt( "ElastoModeRespawnTime",      &BattleSpecialsTimes.ElastoModeRespawnTime );
+      ReadInt( "AsbestosVestRespawnTime",    &BattleSpecialsTimes.AsbestosVestRespawnTime );
+      ReadInt( "BulletProofVestRespawnTime", &BattleSpecialsTimes.BulletProofVestRespawnTime );
+      ReadInt( "GasMaskRespawnTime",         &BattleSpecialsTimes.GasMaskRespawnTime );
+      ReadInt( "MercuryModeRespawnTime",     &BattleSpecialsTimes.MercuryModeRespawnTime );
+
+      ReadBoolean( "EKG", &battlegibs );
+
+      for( index = battle_Normal; index < battle_NumBattleModes; index++ )
+         {
+         // Read Gravity
+         temp = BATTLE_Options[ index ].Gravity;
+         ReadInt( "Gravity", &temp );
+			BATTLE_Options[ index ].Gravity = temp;
+
+         // Read Speed
+         temp = bo_normal_speed;
+         ReadInt( "Speed", &temp );
+         if ( ( temp >= bo_normal_speed ) &&
+            ( temp <= bo_fast_speed ) )
+            {
+            BATTLE_Options[ index ].Speed = temp;
+            }
+
+         if ( ( index != battle_Collector ) && ( index != battle_Tag ) &&
+            ( index != battle_Eluder ) )
+            {
+            // Read Ammo
+            temp = bo_normal_shots;
+            BATTLE_Options[ index ].Ammo = bo_normal_shots;
+            ReadInt( "Ammo", &temp );
+            if ( ( temp >= bo_one_shot ) &&
+               ( temp <= bo_infinite_shots ) )
+               {
+               BATTLE_Options[ index ].Ammo = temp;
+               }
+            }
+
+         if ( index != battle_Eluder )
+            {
+            // Read Hitpoints
+            temp = BATTLE_Options[ index ].HitPoints;
+            ReadInt( "Hitpoints", &temp );
+            BATTLE_Options[ index ].HitPoints = temp;
+            }
+
+         // Read Spawn Dangers
+         temp = 1;
+         ReadInt( "SpawnDangers", &temp );
+         BATTLE_Options[ index ].SpawnDangers = temp;
+
+         if ( index != battle_Eluder )
+            {
+            // Read Spawn Health
+            temp = 1;
+            ReadInt( "SpawnHealth", &temp );
+            BATTLE_Options[ index ].SpawnHealth = temp;
+
+            // Read Spawn Mines
+            temp = 0;
+            ReadInt( "SpawnMines", &temp );
+            BATTLE_Options[ index ].SpawnMines = temp;
+            }
+
+         if ( ( index != battle_Collector ) && ( index != battle_Tag ) &&
+            ( index != battle_Eluder ) )
+            {
+            // Read Spawn Weapons
+            temp = 1;
+            ReadInt( "SpawnWeapons", &temp );
+            BATTLE_Options[ index ].SpawnWeapons = temp;
+
+            // Read Random Weapons
+            temp = 0;
+            ReadInt( "RandomWeapons", &temp );
+            BATTLE_Options[ index ].RandomWeapons = temp;
+
+            // Read Weapon Persistence
+            temp = 0;
+            ReadInt( "WeaponPersistence", &temp );
+            BATTLE_Options[ index ].WeaponPersistence = temp;
+            }
+
+         if ( ( index == battle_Normal ) || ( index == battle_ScoreMore ) ||
+            ( index == battle_Hunter ) || ( index == battle_Tag ) )
+            {
+            // Read Friendly Fire
+            temp = 1;
+            ReadInt( "FriendlyFire", &temp );
+            BATTLE_Options[ index ].FriendlyFire = temp;
+            }
+
+         if ( index != battle_Eluder )
+            {
+            // Read Respawn Items
+            temp = 1;
+            ReadInt( "RespawnItems", &temp );
+            BATTLE_Options[ index ].RespawnItems = temp;
+            }
+
+         // Read Light Level
+         temp = bo_light_normal;
+         ReadInt( "LightLevel", &temp );
+         if ( ( temp >= bo_light_dark ) &&
+            ( temp <= bo_light_lightning ) )
+            {
+            BATTLE_Options[ index ].LightLevel = temp;
+            }
+
+         if ( ( index != battle_Collector ) && ( index != battle_Scavenger ) )
+            {
+            // Read Point Goal
+            temp = bo_kills_default;
+            ReadInt( "PointGoal", &temp );
+            BATTLE_Options[ index ].Kills = temp;
+            if ( temp < bo_kills_random )
+               {
+               BATTLE_Options[ index ].Kills = bo_kills_default;
+               }
+            }
+
+         if ( index != battle_Eluder )
+            {
+            // Read Danger Damage
+            temp = bo_danger_normal;
+            ReadInt( "DangerDamage", &temp );
+            BATTLE_Options[ index ].DangerDamage = temp;
+            }
+
+         // Read Time Limit
+         temp = bo_time_infinite;
+         ReadInt( "TimeLimit", &temp );
+         if ( ( index == battle_Hunter ) && ( temp == bo_time_infinite ) )
+            {
+            temp = 99;
+            }
+         BATTLE_Options[ index ].TimeLimit = temp;
+
+         // Read Respawn time
+         temp = bo_normal_respawn_time;
+         ReadInt( "RespawnTime", &temp );
+         BATTLE_Options[ index ].RespawnTime = temp;
+         }
+      }
+
+   return (retval);
+   }
+
+//******************************************************************************
+//
+// SetBattleDefaultValues ()
+//
+//******************************************************************************
+
+void SetBattleDefaultValues (void)
+{
+   int index;
+
+   //
+   //  no config file, so select default values
+   //
+   for( index = battle_StandAloneGame; index < battle_NumBattleModes;
+      index++ )
+      {
+      BATTLE_Options[ index ].Gravity      = NORMAL_GRAVITY;
+      BATTLE_Options[ index ].Speed        = bo_normal_speed;
+      BATTLE_Options[ index ].Ammo         = bo_normal_shots;
+      BATTLE_Options[ index ].HitPoints    = bo_default_hitpoints;
+      BATTLE_Options[ index ].SpawnDangers = 1;
+      BATTLE_Options[ index ].SpawnHealth  = 1;
+      BATTLE_Options[ index ].SpawnMines   = 0;
+      BATTLE_Options[ index ].SpawnWeapons = 1;
+      BATTLE_Options[ index ].RespawnItems = 1;
+      BATTLE_Options[ index ].RandomWeapons = 0;
+      BATTLE_Options[ index ].WeaponPersistence = 0;
+      BATTLE_Options[ index ].FriendlyFire = 1;
+      BATTLE_Options[ index ].LightLevel   = bo_light_normal;
+      BATTLE_Options[ index ].Kills        = bo_kills_default;
+      BATTLE_Options[ index ].DangerDamage = bo_danger_normal;
+      BATTLE_Options[ index ].TimeLimit    = bo_time_infinite;
+      BATTLE_Options[ index ].RespawnTime  = bo_normal_respawn_time;
+      }
+
+   BATTLE_Options[ battle_CaptureTheTriad ].Kills  = 1;
+   BATTLE_Options[ battle_Hunter ].TimeLimit       = 1;
+   BATTLE_Options[ battle_Eluder ].SpawnHealth     = 0;
+   BATTLE_Options[ battle_Eluder ].RespawnItems    = 0;
+   BATTLE_Options[ battle_Eluder ].SpawnWeapons    = 0;
+   BATTLE_Options[ battle_Eluder ].FriendlyFire    = 0;
+   BATTLE_Options[ battle_Collector ].SpawnWeapons = 0;
+   BATTLE_Options[ battle_Collector ].FriendlyFire = 0;
+   BATTLE_Options[ battle_Tag ].SpawnWeapons       = 0;
+   battlegibs=false;
+   BATTLE_ShowKillCount = true;
+   }
+
+//******************************************************************************
+//
+// SetConfigDefaultValues ()
+//
+//******************************************************************************
+
+void SetConfigDefaultValues (void)
+{
+   //
+   //  no config file, so select default values
+   //
+   if (MousePresent)
+      mouseenabled = true;
+
+   joystickenabled = false;
+   joypadenabled   = false;
+   joystickport    = 0;
+   viewsize        = 7;
+   mouseadjustment = 5;
+   gammaindex      = 0;
+   gamestate.violence = 3;
+   passwordstring[0]=0x7d;
+   passwordstring[1]=0x7e;
+   passwordstring[2]=0x4a;
+   passwordstring[3]=0x2d;
+   passwordstring[4]=0x3b;
+   passwordstring[5]=0x6a;
+   passwordstring[6]=0x03;
+   passwordstring[7]=0x19;
+   passwordstring[8]=0x55;
+   passwordstring[9]=0x46;
+   passwordstring[10]=0x54;
+   passwordstring[11]=0x23;
+   passwordstring[12]=0x1c;
+}
+#endif
+
+//******************************************************************************
+//
+// DeleteSoundFile ()
+//
+//******************************************************************************
+void DeleteSoundFile ( void )
+{
+   char filename[ 128 ];
+
+   GetPathFromEnvironment( filename, ApogeePath, SoundName );
+   unlink (filename);          // Delete SOUND.ROT
+}
+
+//******************************************************************************
+//
+// ReadConfig ()
+//
+//******************************************************************************
+
+
+void ReadConfig (void)
+{
+   char filename[ 128 ];
+
+   GetPathFromEnvironment( filename, ApogeePath, SoundName );
+   SetSoundDefaultValues ();
+
+   if (access (filename, F_OK) == 0)
+      {
+      LoadScriptFile (filename);
+
+      if (ParseSoundFile () == false)
+         {
+         DeleteSoundFile();
+         }
+
+      Z_Free (scriptbuffer);
+      }
+#ifdef DOS
+   else if ( !SOUNDSETUP )
+      {
+      Error( "Could not find SOUND.ROT.  Please run SNDSETUP to configure "
+         "your sound hardware." );
+      }
+#endif
+
+
+#ifdef _ROTT_
+   ReadScores();
+
+   GetPathFromEnvironment( filename, ApogeePath, ConfigName );
+   SetConfigDefaultValues ();
+   if (access(filename,F_OK)==0)
+      {
+      LoadScriptFile(filename);
+
+      if (ParseConfigFile () == false)
+         {
+         unlink (filename);          // Delete CONFIG.ROT
+         }
+
+      Z_Free(scriptbuffer);
+      }
+
+   GetPathFromEnvironment( filename, ApogeePath, BattleName );
+   SetBattleDefaultValues ();
+   if (access(filename,F_OK)==0)
+      {
+      LoadScriptFile(filename);
+
+      if (ParseBattleFile() == false)
+         {
+         unlink (filename);          // Delete BATTLE.ROT
+         }
+
+      Z_Free(scriptbuffer);
+      }
+#endif
+   ConfigLoaded = true;
+}
+
+//******************************************************************************
+//
+// CheckVendor ()
+//
+//******************************************************************************
+
+#if (SHAREWARE==1)
+#define VENDORDOC ("VENDOR.DOC")
+#define VENDORLUMP ("VENDOR")
+#else
+#define VENDORDOC ("LICENSE.DOC")
+#define VENDORLUMP ("LICENSE")
+#endif
+
+void CheckVendor (void)
+{
+   boolean saveout=false;
+   int wadcrc;
+   int filecrc;
+   int size;
+   int lump;
+   byte * vendor;
+   char filename[ 128 ];
+
+   GetPathFromEnvironment( filename, ApogeePath, VENDORDOC );
+   if (access (filename, F_OK) == 0)
+      {
+      size = LoadFile(filename,(void **)&vendor);
+      filecrc = CalculateCRC (vendor, size);
+      SafeFree(vendor);
+      lump=W_GetNumForName(VENDORLUMP);
+      vendor = W_CacheLumpNum(lump,PU_CACHE, CvtNull, 1);
+      size=W_LumpLength(lump);
+      wadcrc = CalculateCRC (vendor, size);
+      if (wadcrc != filecrc)
+         saveout=true;
+      }
+   else
+      saveout=true;
+
+   if (saveout==true)
+      {
+      lump=W_GetNumForName(VENDORLUMP);
+      vendor = W_CacheLumpNum(lump,PU_CACHE, CvtNull, 1);
+      size = W_LumpLength(lump);
+      SaveFile (filename,vendor,size);
+      }
+}
+
+//******************************************************************************
+//
+// WriteParameter
+//
+//******************************************************************************
+
+void WriteParameter (int file, const char * s1, int val)
+{
+   char s[50];
+
+   // Write out Header
+   SafeWriteString (file, (char *)s1);
+
+   // Write out space character
+   strcpy (&s[0],(const char *)"  ");
+   SafeWriteString (file, &s[0]);
+
+   // Write out value
+   itoa(val,&s[0],10);
+   SafeWriteString (file, &s[0]);
+
+   // Write out EOL character
+   strcpy (&s[0],(const char *)"\n");
+   SafeWriteString (file, &s[0]);
+}
+
+
+//******************************************************************************
+//
+// WriteParameterHex
+//
+//******************************************************************************
+
+void WriteParameterHex (int file, const char * s1, int val)
+{
+   char s[50];
+
+   // Write out Header
+   SafeWriteString (file, (char *)s1);
+
+   // Write out space character
+   strcpy (&s[0],(const char *)"  $");
+   SafeWriteString (file, &s[0]);
+
+   // Write out value
+   itoa(val,&s[0],16);
+   SafeWriteString (file, &s[0]);
+
+   // Write out EOL character
+   strcpy (&s[0],(const char *)"\n");
+   SafeWriteString (file, &s[0]);
+}
+
+
+
+#ifdef _ROTT_
+
+//******************************************************************************
+//
+// WriteScores ()
+//
+//******************************************************************************
+
+void WriteScores (void)
+{
+   int file;
+   char filename[ 128 ];
+
+   GetPathFromEnvironment( filename, ApogeePath, ScoresName );
+   file=SafeOpenWrite( filename );
+   SafeWrite (file, &Scores, sizeof (Scores));
+   close(file);
+}
+
+
+//******************************************************************************
+//
+// WriteBattleConfig ()
+//
+//******************************************************************************
+
+void WriteBattleConfig
+   (
+   void
+   )
+
+   {
+   int  file;
+   int  index;
+   char filename[ 128 ];
+   extern specials BattleSpecialsTimes;
+
+   // Write Battle File
+   GetPathFromEnvironment( filename, ApogeePath, BattleName );
+   file = open( filename, O_RDWR | O_TEXT | O_CREAT | O_TRUNC,
+      S_IREAD | S_IWRITE );
+
+   if ( file == -1 )
+      {
+      Error( "Error opening %s: %s", filename, strerror( errno ) );
+      }
+
+   // Write out BATTLECONFIG header
+   SafeWriteString( file,
+      ";Rise of the Triad Battle Configuration File\n"
+      ";                  (c) 1995\n"
+      ";\n"
+      ";You may change these options at you own risk.  Using any values\n"
+      ";other than the ones documented may make the game unplayable.\n"
+      ";If this happens, you may delete this file (BATTLE.ROT) and ROTT\n"
+      ";will recreate it with the default values selected.\n"
+      ";\n"
+      ";With that in mind, have fun!\n"
+      ";\n"
+      "\n" );
+
+   // Write out Version
+   WriteParameter( file, "Version                        ", ROTTVERSION );
+
+   // Write out BATTLE_ShowKillPics
+   SafeWriteString(file, "\n;\n");
+	WriteParameter( file, "; Yes                        - ", 1 );
+   WriteParameter( file, "; No                         - ", 0 );
+   WriteParameter( file, "ShowKillCount                  ", BATTLE_ShowKillCount );
+
+   // Write out specials' times
+   SafeWriteString(file, "\n;\n"
+      "; These are the time in seconds of the various powerups.\n"
+      "; You could modify these to give you infinite Mercury mode,\n"
+      "; stronger vests, or to make them persistant.\n;\n" );
+
+   WriteParameter( file, "GodModeTime                ", BattleSpecialsTimes.GodModeTime );
+   WriteParameter( file, "DogModeTime                ", BattleSpecialsTimes.DogModeTime );
+   WriteParameter( file, "ShroomsModeTime            ", BattleSpecialsTimes.ShroomsModeTime );
+   WriteParameter( file, "ElastoModeTime             ", BattleSpecialsTimes.ElastoModeTime );
+   WriteParameter( file, "AsbestosVestTime           ", BattleSpecialsTimes.AsbestosVestTime );
+   WriteParameter( file, "BulletProofVestTime        ", BattleSpecialsTimes.BulletProofVestTime );
+   WriteParameter( file, "GasMaskTime                ", BattleSpecialsTimes.GasMaskTime );
+   WriteParameter( file, "MercuryModeTime            ", BattleSpecialsTimes.MercuryModeTime );
+   WriteParameter( file, "GodModeRespawnTime         ", BattleSpecialsTimes.GodModeRespawnTime );
+   WriteParameter( file, "DogModeRespawnTime         ", BattleSpecialsTimes.DogModeRespawnTime );
+   WriteParameter( file, "ShroomsModeRespawnTime     ", BattleSpecialsTimes.ShroomsModeRespawnTime );
+   WriteParameter( file, "ElastoModeRespawnTime      ", BattleSpecialsTimes.ElastoModeRespawnTime );
+   WriteParameter( file, "AsbestosVestRespawnTime    ", BattleSpecialsTimes.AsbestosVestRespawnTime );
+   WriteParameter( file, "BulletProofVestRespawnTime ", BattleSpecialsTimes.BulletProofVestRespawnTime );
+   WriteParameter( file, "GasMaskRespawnTime         ", BattleSpecialsTimes.GasMaskRespawnTime );
+   WriteParameter( file, "MercuryModeRespawnTime     ", BattleSpecialsTimes.MercuryModeRespawnTime );
+
+   // Write out battlegibs
+   SafeWriteString(file, "\n;\n");
+	WriteParameter( file, "; Yes                        - ", 1 );
+   WriteParameter( file, "; No                         - ", 0 );
+   WriteParameter( file, "EKG                            ", battlegibs );
+
+   // Describe options
+
+   // Write out Gravity
+   SafeWriteString(file, "\n"
+                         ";\n"
+                         "; Here is a description of the possible values for"
+                         " each option:\n"
+                         ";\n"
+                         "; Gravity options:\n" );
+   WriteParameter( file, ";    Low Gravity             - ", LOW_GRAVITY );
+   WriteParameter( file, ";    Normal Gravity          - ", NORMAL_GRAVITY );
+   WriteParameter( file, ";    High Gravity            - ", HIGH_GRAVITY );
+
+   // Write out Speed
+   SafeWriteString(file, ";\n"
+                         "; Speed options:\n" );
+   WriteParameter( file, ";    Normal Speed            - ", bo_normal_speed );
+   WriteParameter( file, ";    Fast Speed              - ", bo_fast_speed );
+
+   // Write out Ammo
+   SafeWriteString(file, ";\n"
+                         "; Ammo options:\n" );
+   WriteParameter( file, ";    One Shot                - ", bo_one_shot );
+   WriteParameter( file, ";    Normal Shots            - ", bo_normal_shots );
+   WriteParameter( file, ";    Infinite Shots          - ", bo_infinite_shots );
+
+   // Write out Hit Points
+   SafeWriteString(file, ";\n"
+                         "; Hitpoint options:\n" );
+   WriteParameter( file, ";    Character Hitpoints     - ", bo_character_hitpoints );
+   WriteParameter( file, ";       1 Hitpoint           - ", 1 );
+   WriteParameter( file, ";      25 Hitpoints          - ", 25 );
+   WriteParameter( file, ";     100 Hitpoints          - ", 100 );
+   WriteParameter( file, ";     500 Hitpoints          - ", 500 );
+   WriteParameter( file, ";     250 Hitpoints          - ", 250 );
+   WriteParameter( file, ";    4000 Hitpoints          - ", 4000 );
+
+   // Write out Danger Spawning
+   SafeWriteString(file, ";\n"
+                         "; SpawnDangers options:\n"
+                         ";    Spawn Dangers           -   1\n"
+                         ";    Don't Spawn Dangers     -   0\n" );
+
+   // Write out Health Spawning
+   SafeWriteString(file, ";\n"
+                         "; SpawnHealth options:\n"
+                         ";    Spawn Health            -   1\n"
+                         ";    Don't Spawn Health      -   0\n" );
+
+   // Write out Mine Spawning
+   SafeWriteString(file, ";\n"
+                         "; SpawnMines options:\n"
+                         ";    Spawn Mines             -   1\n"
+                         ";    Don't Spawn Mines       -   0\n" );
+
+   // Write out Weapon Spawning
+   SafeWriteString(file, ";\n"
+                         "; SpawnWeapons options:\n"
+                         ";    Spawn Weapons           -   1\n"
+                         ";    Don't Spawn Weapons     -   0\n" );
+
+   // Write out Random Weapons
+   SafeWriteString(file, ";\n"
+                         "; RandomWeapons options:\n"
+                         ";    Randomize Weapons       -   1\n"
+                         ";    Don't Randomize Weapons -   0\n" );
+
+   // Write out Weapon Persistence
+   SafeWriteString(file, ";\n"
+                         "; WeaponPersistence options:\n"
+                         ";    Weapons Persist         -   1\n"
+                         ";    Weapons don't Persist   -   0\n" );
+
+   // Write out Friendly Fire
+   SafeWriteString(file, ";\n"
+                         "; FriendlyFire options:\n"
+                         ";    Penalize Friendly Fire  -   1\n"
+                         ";    No penalty              -   0\n" );
+
+   // Write out Respawn Items
+   SafeWriteString(file, ";\n"
+                         "; RespawnItems options:\n"
+                         ";    Respawn Items           -   1\n"
+                         ";    Don't Respawn Items     -   0\n" );
+
+   // Write out Light Level
+   SafeWriteString(file, ";\n"
+                         "; LightLevel options:\n" );
+   WriteParameter( file, ";    Dark                    - ", bo_light_dark );
+   WriteParameter( file, ";    Normal Light Levels     - ", bo_light_normal );
+   WriteParameter( file, ";    Bright                  - ", bo_light_bright );
+   WriteParameter( file, ";    Fog                     - ", bo_light_fog );
+   WriteParameter( file, ";    Periodic light          - ", bo_light_periodic );
+   WriteParameter( file, ";    Lightning               - ", bo_light_lightning );
+
+   // Write out Point Goal
+   SafeWriteString(file, ";\n"
+                         "; PointGoal options:\n" );
+   WriteParameter( file, ";           1 Point          - ", 1 );
+   WriteParameter( file, ";           5 Points         - ", 5 );
+   WriteParameter( file, ";          11 Points         - ", 11 );
+   WriteParameter( file, ";          21 Points         - ", 21 );
+   WriteParameter( file, ";          50 Points         - ", 50 );
+   WriteParameter( file, ";         100 Points         - ", 100 );
+   WriteParameter( file, ";      Random Points         - ", bo_kills_random );
+   WriteParameter( file, ";       Blind Points         - ", bo_kills_blind );
+   WriteParameter( file, ";    Infinite Points         - ", bo_kills_infinite );
+
+   // Write out Danger Damage
+   SafeWriteString(file, ";\n"
+                         "; DangerDamage options:\n" );
+   WriteParameter( file, ";    Normal Damage           - ", bo_danger_normal );
+   WriteParameter( file, ";    Low Damage              - ", bo_danger_low );
+   WriteParameter( file, ";    Kill                    - ", bo_danger_kill );
+
+   // Write out TimeLimit
+   SafeWriteString(file, ";\n"
+                         "; TimeLimit options:\n" );
+   WriteParameter( file, ";     1 minute               - ", 1 );
+   WriteParameter( file, ";     2 minute               - ", 2 );
+   WriteParameter( file, ";     5 minutes              - ", 5 );
+   WriteParameter( file, ";    10 minutes              - ", 10 );
+   WriteParameter( file, ";    21 minutes              - ", 21 );
+   WriteParameter( file, ";    30 minutes              - ", 30 );
+   WriteParameter( file, ";    99 minutes              - ", 99 );
+   WriteParameter( file, ";    No limit                - ", bo_time_infinite );
+
+   // Write out RespawnTime
+   SafeWriteString(file, ";\n"
+                         "; RespawnTime options:\n" );
+   WriteParameter( file, ";     1 second               - ", 1 );
+   WriteParameter( file, ";     1 minute               - ", 60 );
+   WriteParameter( file, ";     2 minutes              - ", 120 );
+   WriteParameter( file, ";       normal               - ", bo_normal_respawn_time );
+
+   for( index = battle_Normal; index < battle_NumBattleModes; index++ )
+      {
+      SafeWriteString(file, "\n;\n");
+      switch( index )
+         {
+         case battle_Normal :
+            SafeWriteString( file, "; Standard battle options\n;\n" );
+            break;
+
+         case battle_ScoreMore :
+            SafeWriteString( file, "; Score More battle options\n;\n" );
+            break;
+
+         case battle_Collector :
+            SafeWriteString( file, "; Collector battle options\n;\n" );
+            break;
+
+         case battle_Scavenger :
+            SafeWriteString( file, "; Scavenger battle options\n;\n" );
+            break;
+
+         case battle_Hunter :
+            SafeWriteString( file, "; Hunter battle options\n;\n" );
+            break;
+
+         case battle_Tag :
+            SafeWriteString( file, "; Tag battle options\n;\n" );
+            break;
+
+         case battle_Eluder :
+            SafeWriteString( file, "; Eluder battle options\n;\n" );
+            break;
+
+         case battle_Deluder :
+            SafeWriteString( file, "; Deluder battle options\n;\n" );
+            break;
+
+			case battle_CaptureTheTriad :
+				SafeWriteString( file, "; Capture the Triad battle options\n;\n" );
+				break;
+			}
+
+		// Write out Gravity
+      WriteParameter( file, "Gravity          ",
+         BATTLE_Options[ index ].Gravity );
+
+      // Write out Speed
+      WriteParameter( file, "Speed            ",
+         BATTLE_Options[ index ].Speed );
+
+      if ( ( index != battle_Collector ) && ( index != battle_Tag ) &&
+         ( index != battle_Eluder ) )
+         {
+         // Write out Ammo
+         WriteParameter( file, "Ammo             ",
+            BATTLE_Options[ index ].Ammo );
+         }
+
+      if ( index != battle_Eluder )
+         {
+         // Write out Hit Points
+         WriteParameter( file, "Hitpoints        ",
+            BATTLE_Options[ index ].HitPoints );
+         }
+
+      // Write out Danger Spawning
+      WriteParameter( file, "SpawnDangers     ",
+         BATTLE_Options[ index ].SpawnDangers );
+
+      if ( index != battle_Eluder )
+         {
+         // Write out Health Spawning
+         WriteParameter( file, "SpawnHealth      ",
+            BATTLE_Options[ index ].SpawnHealth );
+
+         // Write out Mine Spawning
+         WriteParameter( file, "SpawnMines       ",
+            BATTLE_Options[ index ].SpawnMines );
+         }
+
+      if ( ( index != battle_Collector ) && ( index != battle_Tag ) &&
+         ( index != battle_Eluder ) )
+         {
+         // Write out Weapon Spawning
+         WriteParameter( file, "SpawnWeapons     ",
+            BATTLE_Options[ index ].SpawnWeapons );
+
+         // Write out Random Weapons
+         WriteParameter( file, "RandomWeapons    ",
+            BATTLE_Options[ index ].RandomWeapons );
+
+         // Write out Weapon Persistence
+         WriteParameter( file, "WeaponPersistence",
+            BATTLE_Options[ index ].WeaponPersistence );
+         }
+
+      if ( ( index == battle_Normal ) || ( index == battle_ScoreMore ) ||
+         ( index == battle_Hunter ) || ( index == battle_Tag ) )
+         {
+         // Write out Friendly Fire
+         WriteParameter( file, "FriendlyFire     ",
+            BATTLE_Options[ index ].FriendlyFire );
+         }
+
+      if ( index != battle_Eluder )
+         {
+         // Write out Respawn Items
+         WriteParameter( file, "RespawnItems     ",
+            BATTLE_Options[ index ].RespawnItems );
+         }
+
+      // Write out Light Level
+      WriteParameter( file, "LightLevel       ",
+         BATTLE_Options[ index ].LightLevel );
+
+      if ( ( index != battle_Collector ) && ( index != battle_Scavenger ) )
+         {
+         // Write out Point Goal
+         WriteParameter( file, "PointGoal        ",
+            BATTLE_Options[ index ].Kills );
+         }
+
+      if ( index != battle_Eluder )
+         {
+         // Write out Danger Damage
+         WriteParameter( file, "DangerDamage     ",
+            BATTLE_Options[ index ].DangerDamage );
+         }
+
+      // Write out TimeLimit
+      WriteParameter( file, "TimeLimit        ",
+         BATTLE_Options[ index ].TimeLimit );
+
+      // Write out RespawnTime
+      WriteParameter( file, "RespawnTime      ",
+         BATTLE_Options[ index ].RespawnTime );
+      }
+
+   close( file );
+   }
+
+#endif
+
+//******************************************************************************
+//
+// WriteSoundConfig ()
+//
+//******************************************************************************
+
+void WriteSoundConfig
+   (
+   void
+   )
+
+   {
+   int file;
+   char filename[ 128 ];
+
+   if ( !WriteSoundFile )
+      {
+      return;
+      }
+
+   GetPathFromEnvironment( filename, ApogeePath, SoundName );
+   file = open ( filename, O_RDWR | O_TEXT | O_CREAT | O_TRUNC,
+      S_IREAD | S_IWRITE);
+
+   if (file == -1)
+      Error ("Error opening %s: %s", filename, strerror(errno));
+
+   // Write out ROTTSOUND header
+
+   SafeWriteString (file, ";Rise of the Triad Sound File\n");
+   SafeWriteString (file, ";                  (c) 1995\n\n");
+
+   // Write out Version
+
+   WriteParameter(file,"Version          ",ROTTVERSION);
+
+   // Write out Music Mode
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Music Modes\n");
+   SafeWriteString(file,"; 0  -  Off\n");
+#ifdef DOS
+   SafeWriteString(file,"; 1  -  UltraSound\n");
+   SafeWriteString(file,"; 2  -  Sound Blaster\n");
+   SafeWriteString(file,"; 3  -  Sound Man 16\n");
+   SafeWriteString(file,"; 4  -  Pro Audio Spectrum\n");
+   SafeWriteString(file,"; 5  -  Awe32\n");
+   SafeWriteString(file,"; 6  -  SoundScape\n");
+   SafeWriteString(file,"; 7  -  Wave Blaster\n");
+   SafeWriteString(file,"; 8  -  General Midi\n");
+   SafeWriteString(file,"; 9  -  Sound Canvas\n");
+   SafeWriteString(file,"; 10 -  Adlib\n");
+#else
+   SafeWriteString(file,"; 6  -  On\n");
+#endif
+   WriteParameter(file,"MusicMode        ",MusicMode);
+
+   // Write out FX Mode
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; FX Modes\n");
+   SafeWriteString(file,"; 0  -  Off\n");
+#ifdef DOS
+   SafeWriteString(file,"; 1  -  UltraSound\n");
+   SafeWriteString(file,"; 2  -  Sound Blaster\n");
+   SafeWriteString(file,"; 3  -  Sound Man 16\n");
+   SafeWriteString(file,"; 4  -  Pro Audio Spectrum\n");
+   SafeWriteString(file,"; 5  -  Awe32\n");
+   SafeWriteString(file,"; 6  -  SoundScape\n");
+   SafeWriteString(file,"; 7  -  Adlib\n");
+   SafeWriteString(file,"; 8  -  Disney Sound Source\n");
+   SafeWriteString(file,"; 9  -  Tandy Sound Source\n");
+   SafeWriteString(file,"; 10 -  PC Speaker\n");
+#else
+   SafeWriteString(file,"; 6  -  On\n");
+#endif
+   WriteParameter(file,"FXMode           ",FXMode);
+
+   // Write in Music Volume
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Music Volume\n");
+   SafeWriteString(file,"; (low) 0 - 255 (high)\n");
+   WriteParameter (file, "MusicVolume    ", MUvolume);
+
+   // Write in FX Volume
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; FX Volume\n");
+   SafeWriteString(file,"; (low) 0 - 255 (high)\n");
+   WriteParameter (file, "FXVolume       ", FXvolume);
+
+   // Write out numvoices
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Number of Voices\n");
+   SafeWriteString(file,"; 1 - 8\n");
+   WriteParameter(file,"NumVoices        ",NumVoices);
+
+   // Write out numchannels
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Stereo or Mono\n");
+   SafeWriteString(file,"; 1 - Mono\n");
+   SafeWriteString(file,"; 2 - Stereo\n");
+   WriteParameter(file,"NumChannels      ",NumChannels);
+
+   // Write out numbits
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Resolution\n");
+   SafeWriteString(file,"; 8 bit\n");
+   SafeWriteString(file,"; 16 bit\n");
+   WriteParameter(file,"NumBits          ",NumBits);
+
+#ifdef DOS
+   // Write out Midi Address
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Midi Addresses\n");
+   SafeWriteString(file,"; $300\n");
+   SafeWriteString(file,"; $310\n");
+   SafeWriteString(file,"; $320\n");
+   SafeWriteString(file,"; $330\n");
+   SafeWriteString(file,"; $340\n");
+   SafeWriteString(file,"; $350\n");
+   SafeWriteString(file,"; $360\n");
+   SafeWriteString(file,"; $370\n");
+   SafeWriteString(file,"; $380\n");
+   WriteParameterHex(file,"MidiAddress      ",MidiAddress);
+#endif
+
+   // Write out stereo reversal
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; ReverseStereo\n");
+   SafeWriteString(file,"; 0 no reversal\n");
+   SafeWriteString(file,"; 1 reverse stereo\n");
+   WriteParameter (file,"StereoReverse      ",stereoreversed);
+
+#ifdef DOS
+   // Write out Sound Blaster info
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Sound Blaster Settings\n");
+   WriteParameter(file, "SBType           ", SBSettings.Type );
+   WriteParameterHex(file, "SBPort           ", SBSettings.Address );
+   WriteParameter(file, "SBIrq            ", SBSettings.Interrupt );
+   WriteParameter(file, "SBDma8           ", SBSettings.Dma8 );
+   WriteParameter(file, "SBDma16          ", SBSettings.Dma16 );
+   WriteParameterHex(file, "SBMidi           ", SBSettings.Midi );
+   WriteParameterHex(file, "SBEmu            ", SBSettings.Emu );
+#endif
+
+   close (file);
+   }
+
+
+//******************************************************************************
+//
+// WriteConfig ()
+//
+//******************************************************************************
+
+void WriteConfig (void)
+{
+   int file;
+   char filename[ 128 ];
+   char passwordtemp[50];
+   static int inconfig = 0;
+
+   if (inconfig > 0)
+      return;
+
+   inconfig++ ;
+
+   if ( !ConfigLoaded )
+      {
+      return;
+      }
+
+   // Write Sound File
+   WriteSoundConfig();
+
+  // Write Config, Battle and Score files
+#ifdef _ROTT_
+   WriteScores();
+   WriteBattleConfig();
+
+   GetPathFromEnvironment( filename, ApogeePath, ConfigName );
+   file = open( filename,O_RDWR | O_TEXT | O_CREAT | O_TRUNC
+   , S_IREAD | S_IWRITE);
+
+   if (file == -1)
+      Error ("Error opening %s: %s",filename,strerror(errno));
+
+   // Write out ROTTCONFIG header
+
+   SafeWriteString (file, ";Rise of the Triad Configuration File\n");
+   SafeWriteString (file, ";                  (c) 1995\n\n");
+
+   // Write out Version
+
+   WriteParameter(file,"Version          ",ROTTVERSION);
+
+   // Write out MouseEnabled
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - Mouse Enabled\n");
+   SafeWriteString(file,"; 0 - Mouse Disabled\n");
+   WriteParameter(file,"MouseEnabled     ",mouseenabled);
+
+   // Write out UseMouseLook
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - UseMouseLook Enabled\n");
+   SafeWriteString(file,"; 0 - UseMouseLook Disabled\n");
+   WriteParameter(file,"UseMouseLook     ",usemouselook);
+
+   // Write out InverseMouse
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - Normal Mouse Enabled\n");
+   SafeWriteString(file,"; -1 - Inverse Mouse Enabled\n");
+   WriteParameter(file,"InverseMouse     ",inverse_mouse);
+
+   // Write out UseJump
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - usejump Enabled\n");
+   SafeWriteString(file,"; 0 - usejump Disabled\n");
+   WriteParameter(file,"UseJump          ",usejump);
+
+   // Write out CrossHair
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - CrossHair Enabled\n");
+   SafeWriteString(file,"; 0 - CrossHair Disabled\n");
+   WriteParameter(file,"CrossHair        ", iG_aimCross);
+
+   // Write out JoystickEnabled
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - Joystick Enabled\n");
+   SafeWriteString(file,"; 0 - Joystick Disabled\n");
+   WriteParameter(file,"JoystickEnabled  ",joystickenabled);
+
+   // Write out JoypadEnabled
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - Joypad Enabled\n");
+   SafeWriteString(file,"; 0 - Joypad Disabled\n");
+   WriteParameter(file,"JoypadEnabled    ",joypadenabled);
+
+   // Write out JoystickPort
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 0 - Use Joystick Port 1\n");
+   SafeWriteString(file,"; 1 - Use Joystick Port 2\n");
+   WriteParameter(file,"JoystickPort     ",joystickport);
+
+   // Write out fullscreen
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 0 - Start in windowed mode\n");
+   SafeWriteString(file,"; 1 - Start in fullscreen mode\n");
+   WriteParameter(file,"FullScreen       ",sdl_fullscreen);
+      
+   // Write out resolution
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Screen Resolution, supported resolutions: \n");
+   SafeWriteString(file,"; 320x200, 640x480 and 800x600\n");
+   WriteParameter(file,"ScreenWidth      ",iGLOBAL_SCREENWIDTH);
+   WriteParameter(file,"ScreenHeight     ",iGLOBAL_SCREENHEIGHT);
+
+   // Write out ViewSize
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Size of View port.\n");
+   SafeWriteString(file,"; (smallest) 0 - 10 (largest)\n");
+   WriteParameter(file,"ViewSize         ",viewsize);
+
+   // Write out WEAPONSCALE  bna added
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Size of Weaponscale.\n");
+   SafeWriteString(file,"; (smallest) 150 - 600 (largest)\n");
+   G_weaponscale = (weaponscale * 168 )/65536;
+
+   if ((G_weaponscale <150)||(G_weaponscale>600)){
+	   if (iGLOBAL_SCREENWIDTH == 320){
+			G_weaponscale=168;
+	   }else if (iGLOBAL_SCREENWIDTH == 640){
+			G_weaponscale=299;		
+	   }else if (iGLOBAL_SCREENWIDTH == 800) {
+			G_weaponscale=376;
+	   }	   
+   }
+   WriteParameter(file,"Weaponscale         ",G_weaponscale);
+
+
+   // Write out MouseAdjustment
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Sensitivity of Mouse\n");
+   SafeWriteString(file,"; (lowest) 0 - 11 (highest)\n");
+   WriteParameter(file,"MouseAdjustment  ",mouseadjustment);
+
+   // Write out threshold
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Threshold of Mouse and Joystick\n");
+   SafeWriteString(file,"; (smallest) 1 - 15 (largest)\n");
+   WriteParameter(file,"Threshold        ",threshold);
+
+   // Write in Cyberman Enabled
+
+//   SafeWriteString(file,"\n;\n");
+//   SafeWriteString(file,"; 1 - Cyberman Enabled\n");
+//   SafeWriteString(file,"; 0 - Cyberman Disabled\n");
+//   WriteParameter(file,"CybermanEnabled  ",cybermanenabled);
+
+   // Write in Spaceball Enabled
+
+//   SafeWriteString(file,"\n;\n");
+//   SafeWriteString(file,"; 1 - Spaceball Enabled\n");
+//   SafeWriteString(file,"; 0 - Spaceball Disabled\n");
+//   WriteParameter(file,"SpaceballEnabled ",spaceballenabled);
+
+   // Write in Auto Detail
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - Auto Detail on\n");
+   SafeWriteString(file,"; 0 - Auto Detail off\n");
+   WriteParameter (file,"AutoDetail       ", AutoDetailOn);
+
+   // Write in Light Dim
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - Light Diminishing on\n");
+   SafeWriteString(file,"; 0 - Light Diminishing off\n");
+   WriteParameter (file,"LightDim         ", fulllight);
+
+   // Write in Bobbin' On
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - Bobbing on\n");
+   SafeWriteString(file,"; 0 - Bobbing off\n");
+   WriteParameter (file,"BobbingOn        ", BobbinOn);
+
+   // Write in Double Click Speed
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; (slowest) 50 - 5 (fastest)\n");
+   WriteParameter (file,"DoubleClickSpeed ", DoubleClickSpeed);
+
+   // Write in Menu Flip Speed
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Menu Flip Speed\n");
+   SafeWriteString(file,"; (slowest) 100 - 5 (fastest)\n");
+   WriteParameter (file,"MenuFlipSpeed    ", Menuflipspeed);
+
+   // Write in Detail Level
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 0 - Detail Level Low\n");
+   SafeWriteString(file,"; 1 - Detail Level Medium\n");
+   SafeWriteString(file,"; 2 - Detail Level High\n");
+   WriteParameter (file,"DetailLevel      ", DetailLevel);
+
+   // Write in Floor and Ceiling
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - Floor and Ceiling on\n");
+   SafeWriteString(file,"; 0 - Floor and Ceiling off\n");
+   WriteParameter (file,"FloorCeiling     ", fandc);
+
+   // Write in DisableMessages
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - Messages on\n");
+   SafeWriteString(file,"; 0 - Messages off\n");
+   WriteParameter (file,"Messages         ", MessagesEnabled );
+
+   // Write in AutoRun
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 1 - AutoRun on\n");
+   SafeWriteString(file,"; 0 - AutoRun off\n");
+   WriteParameter (file,"AutoRun          ", gamestate.autorun );
+
+   // Write in GammaIndex
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; 0 - Gamma Correction level 1\n");
+   SafeWriteString(file,"; 1 - Gamma Correction level 2\n");
+   SafeWriteString(file,"; 2 - Gamma Correction level 3\n");
+   SafeWriteString(file,"; 3 - Gamma Correction level 4\n");
+   SafeWriteString(file,"; 4 - Gamma Correction level 5\n");
+   WriteParameter (file,"GammaIndex       ", gammaindex);
+
+   // Write out screen saver time
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Minutes before screen blanking\n");
+   WriteParameter (file,"BlankTime        ", blanktime/(VBLCOUNTER*60));
+
+
+   // Write out keys
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Scan codes for keyboard buttons\n");
+   WriteParameter (file,"Fire             ", buttonscan[0]);
+   WriteParameter (file,"Strafe           ", buttonscan[1]);
+   WriteParameter (file,"Run              ", buttonscan[2]);
+   WriteParameter (file,"Use              ", buttonscan[3]);
+   WriteParameter (file,"LookUp           ", buttonscan[4]);
+   WriteParameter (file,"LookDn           ", buttonscan[5]);
+   WriteParameter (file,"Swap             ", buttonscan[6]);
+   WriteParameter (file,"Drop             ", buttonscan[7]);
+   WriteParameter (file,"TargetUp         ", buttonscan[8]);
+   WriteParameter (file,"TargetDn         ", buttonscan[9]);
+   WriteParameter (file,"SelPistol        ", buttonscan[10]);
+   WriteParameter (file,"SelDualPistol    ", buttonscan[11]);
+   WriteParameter (file,"SelMP40          ", buttonscan[12]);
+   WriteParameter (file,"SelMissile       ", buttonscan[13]);
+   WriteParameter (file,"AutoRun          ", buttonscan[14]);
+   WriteParameter (file,"LiveRemRid       ", buttonscan[15]);
+   WriteParameter (file,"StrafeLeft       ", buttonscan[16]);
+   WriteParameter (file,"StrafeRight      ", buttonscan[17]);
+   WriteParameter (file,"VolteFace        ", buttonscan[18]);
+   WriteParameter (file,"Aim              ", buttonscan[19]);
+   WriteParameter (file,"Forward          ", buttonscan[20]);
+   WriteParameter (file,"Right            ", buttonscan[21]);
+   WriteParameter (file,"Backward         ", buttonscan[22]);
+   WriteParameter (file,"Left             ", buttonscan[23]);
+   WriteParameter (file,"Map              ", buttonscan[24]);
+   WriteParameter (file,"SendMessage      ", buttonscan[25]);
+   WriteParameter (file,"DirectMessage    ", buttonscan[26]);
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Mouse buttons\n");
+
+   WriteParameter (file,"MouseButton0     ", buttonmouse[0]);
+   WriteParameter (file,"MouseButton1     ", buttonmouse[1]);
+   WriteParameter (file,"MouseButton2     ", buttonmouse[2]);
+   WriteParameter (file,"DblClickB0       ", buttonmouse[3]);
+   WriteParameter (file,"DblClickB1       ", buttonmouse[4]);
+   WriteParameter (file,"DblClickB2       ", buttonmouse[5]);
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Joystick buttons\n");
+
+   WriteParameter (file,"JoyButton0       ", buttonjoy[0]);
+   WriteParameter (file,"JoyButton1       ", buttonjoy[1]);
+   WriteParameter (file,"JoyButton2       ", buttonjoy[2]);
+   WriteParameter (file,"JoyButton3       ", buttonjoy[3]);
+   WriteParameter (file,"DblClickJB0      ", buttonjoy[4]);
+   WriteParameter (file,"DblClickJB1      ", buttonjoy[5]);
+   WriteParameter (file,"DblClickJB2      ", buttonjoy[6]);
+   WriteParameter (file,"DblClickJB3      ", buttonjoy[7]);
+
+   SafeWriteString(file,"\n;\n");
+   SafeWriteString(file,"; Joystick calibration coordinates\n");
+
+   WriteParameter (file,"JoyMaxX          ", joyxmax);
+   WriteParameter (file,"JoyMaxY          ", joyymax);
+   WriteParameter (file,"JoyMinX          ", joyxmin);
+   WriteParameter (file,"JoyMinY          ", joyymin);
+
+   // Write out DefaultDifficulty
+   SafeWriteString(file,"\n;\n");
+	WriteParameter(file,"; Easy             - ", gd_baby );
+	WriteParameter(file,"; Medium           - ", gd_easy );
+	WriteParameter(file,"; Hard             - ", gd_medium );
+	WriteParameter(file,"; Crezzy           - ", gd_hard );
+   WriteParameter(file,"DefaultDifficulty    ", DefaultDifficulty );
+
+   // Write out DefaultPlayerCharacter
+   SafeWriteString(file,"\n;\n");
+	WriteParameter(file,"; Taradino Cassatt   - ", 0 );
+	WriteParameter(file,"; Thi Barrett        - ", 1 );
+	WriteParameter(file,"; Doug Wendt         - ", 2 );
+	WriteParameter(file,"; Lorelei Ni         - ", 3 );
+	WriteParameter(file,"; Ian Paul Freeley   - ", 4 );
+   WriteParameter(file,"DefaultPlayerCharacter ", DefaultPlayerCharacter );
+
+   // Write out DefaultPlayerColor
+   SafeWriteString(file,"\n;\n");
+	WriteParameter(file,"; Gray             - ", 0 );
+	WriteParameter(file,"; Brown            - ", 1 );
+	WriteParameter(file,"; Black            - ", 2 );
+	WriteParameter(file,"; Tan              - ", 3 );
+	WriteParameter(file,"; Red              - ", 4 );
+	WriteParameter(file,"; Olive            - ", 5 );
+	WriteParameter(file,"; Blue             - ", 6 );
+	WriteParameter(file,"; White            - ", 7 );
+	WriteParameter(file,"; Green            - ", 8 );
+	WriteParameter(file,"; Purple           - ", 9 );
+	WriteParameter(file,"; Orange           - ", 10 );
+   WriteParameter(file,"DefaultPlayerColor   ", DefaultPlayerColor );
+
+   // Writeout password Password string
+   SafeWriteString(file,"\n;\nSecretPassword         ");
+   memset(passwordtemp,0,sizeof(passwordtemp));
+   ConvertPasswordStringToString ( &passwordtemp[0] );
+   SafeWriteString(file,&passwordtemp[0]);
+
+   close (file);
+#endif
+   inconfig--;
+}
+
+#ifdef _ROTT_
+
+
+//****************************************************************************
+//
+// GetAlternatePath ()
+//
+//****************************************************************************
+
+void GetAlternatePath (char * tokenstr, AlternateInformation *info)
+{
+   strcpy (&info->path[0], ".\0");
+   GetToken (true);
+   if (!stricmp (token, tokenstr))
+      {
+      GetTokenEOL (false);
+      memset (&info->path[0], 0, sizeof (info->path));
+      strcpy (&info->path[0], &name[0]);
+      }
+}
+
+
+//****************************************************************************
+//
+// GetAlternateFile ()
+//
+//****************************************************************************
+
+void GetAlternateFile (char * tokenstr, AlternateInformation *info)
+{
+   // Read in remote sound file
+   //
+   strcpy (&info->file[0], "foo.foo\0");
+   GetToken (true);
+   if (!stricmp (token, tokenstr))
+      {
+      if (TokenAvailable()==true)
+         {
+         GetToken (false);
+         if (stricmp (token, "~"))
+            {
+            #if (SHAREWARE == 0)
+            info->avail = true;
+            memset (&info->file[0], 0, sizeof (info->file));
+            strcpy (&info->file[0], &token[0]);
+            #else
+            printf("Alternate file %s ignored.\n",token);
+            memset (&info->file[0], 0, sizeof (info->file));
+            #endif
+            }
+         }
+      }
+}
+
+
+//****************************************************************************
+//
+// ReadSETUPFiles ()
+//
+//****************************************************************************
+
+void ReadSETUPFiles (void)
+{
+   char filename[ 128 ];
+   int i;
+
+   RemoteSounds.avail   = false;
+//   PlayerGraphics.avail = false;
+   GameLevels.avail     = false;
+   BattleLevels.avail   = false;
+
+   GetPathFromEnvironment( filename, ApogeePath, CONFIG );
+   if (access (filename, F_OK) == 0)
+   {
+      LoadScriptFile (filename);
+
+      GetTokenEOL (true);     //MODEMNAME
+      GetTokenEOL (true);     //MODEMINITSTR
+      GetTokenEOL (true);     //MODEMHANGUP
+      GetTokenEOL (true);     //RATE
+      GetTokenEOL (true);     //COMPORT
+      GetTokenEOL (true);     //IRQ
+      GetTokenEOL (true);     //UART
+      GetTokenEOL (true);     //PULSE
+      GetTokenEOL (true);     //AUTOMATICDIALOUT
+
+      GetAlternatePath ("REMOTESOUNDPATH", &RemoteSounds);
+//      GetAlternatePath ("PLAYERGRAPHICSPATH", &PlayerGraphics);
+      GetAlternatePath ("GAMELEVELPATH", &GameLevels);
+      GetAlternatePath ("BATTLELEVELPATH", &BattleLevels);
+
+      // Get CodeName
+      GetToken (true);
+      if (stricmp (token, "CODENAME"))
+         Error ("Can't find %s token.\n", "CODENAME");
+
+      GetTokenEOL (false);
+      memset (&CodeName[0], 0, sizeof (CodeName));
+      if (stricmp (name, "~"))
+         {
+
+         // Get First (MAXCODENAMELENGTH-1) characters
+         for (i=0;i<MAXCODENAMELENGTH-1;i++)
+            CodeName[i]=name[i];
+         }
+      GetTokenEOL (true);     //NUMPLAYERS
+      GetTokenEOL (true);     //NETWORKSOCKET
+      GetTokenEOL (true);     //DEFAULT
+      for (i=0;i<14;i++)
+         GetTokenEOL (true);  //NUMBERLIST
+
+      memset (CommbatMacros, 0, sizeof(CommbatMacros) );
+
+      for (i=0;i<MAXMACROS;i++)
+         {
+         GetToken (true);
+
+         GetTokenEOL (true);
+
+         if (name[0] != '~')
+            {
+            memcpy (&CommbatMacros[i].macro[0], &name[0], strlen (name));
+            CommbatMacros[i].avail = 1;
+            }
+         }
+
+      Z_Free (scriptbuffer);
+   }
+
+   GetPathFromEnvironment( filename, ApogeePath, ROTT );
+   if (access (filename, F_OK) == 0)
+   {
+      LoadScriptFile (filename);
+
+      GetTokenEOL (true);     //PHONENUMBER
+
+      GetAlternateFile ("REMOTESOUNDFILE", &RemoteSounds);
+//      GetAlternateFile ("PLAYERGRAPHICSFILE", &PlayerGraphics);
+      GetAlternateFile ("GAMELEVELFILE", &GameLevels);
+      GetAlternateFile ("COMMBATLEVELFILE", &BattleLevels);
+
+      Z_Free (scriptbuffer);
+
+      unlink (filename);          // Delete ROTT.ROT
+   }
+}
+
+#endif
+

Added: tags/rott-1.1/rott/rt_cfg.h
===================================================================
--- tags/rott-1.1/rott/rt_cfg.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_cfg.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,120 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_cfg_public
+#define _rt_cfg_public
+
+//****************************************************************************
+//
+// Public header for RT_CFG.C
+//
+//****************************************************************************
+
+
+//****************************************************************************
+//
+// GLOBALS
+//
+//****************************************************************************
+
+extern int     FXMode;
+extern int     MusicMode;
+extern int     MUvolume;
+extern int     FXvolume;
+extern boolean mouseenabled;
+extern boolean joystickenabled;
+extern boolean joypadenabled;
+extern int     joystickport;
+extern int     mouseadjustment;
+extern int     threshold;
+extern int     NumVoices;
+extern int     NumChannels;
+extern int     NumBits;
+#ifdef DOS
+extern int     MidiAddress;
+#endif
+extern boolean stereoreversed;
+extern boolean cybermanenabled;
+extern boolean assassinenabled;
+extern boolean spaceballenabled;
+extern boolean AutoDetailOn;
+extern int     DoubleClickSpeed;
+extern int     fulllight;
+extern boolean BobbinOn;
+extern int     Menuflipspeed;
+extern int     DetailLevel;
+extern int     fandc;
+extern int     blanktime;
+extern char    CodeName[9];
+#ifdef DOS
+extern char   *ApogeePath;
+#else
+extern char   ApogeePath[256];
+#endif
+
+extern int     DefaultDifficulty;
+extern int     DefaultPlayerCharacter;
+extern int     DefaultPlayerColor;
+extern byte    passwordstring[20];
+
+typedef struct
+{
+   char path[41];
+   boolean avail;
+   char file[14];
+} AlternateInformation;
+
+extern AlternateInformation RemoteSounds;
+extern AlternateInformation PlayerGraphics;
+extern AlternateInformation GameLevels;
+extern AlternateInformation BattleLevels;
+
+#define MAXMACROLENGTH 32
+#define MAXMACROS      10
+
+typedef struct {
+   byte avail;
+   char macro[MAXMACROLENGTH+1];
+} MacroList;
+
+extern MacroList CommbatMacros[MAXMACROS];
+
+//****************************************************************************
+//
+// PROTOTYPES
+//
+//****************************************************************************
+
+void WriteBattleConfig(void);
+void ReadScores (void);
+void ReadInt (const char * s1, int * val);
+void ReadBoolean (const char * s1, boolean * val);
+void ReadConfig (void);
+void WriteParameter (int file, const char * s1, int val);
+void WriteScores (void);
+void WriteConfig (void);
+void ReadSETUPFiles (void);
+void DeleteSoundFile ( void );
+void CheckVendor (void);
+void ConvertStringToPasswordString ( char * string );
+void ConvertPasswordStringToPassword ( void );
+void ConvertPasswordStringToString ( char * string );
+void ConvertPasswordToPasswordString ( void );
+
+#endif

Added: tags/rott-1.1/rott/rt_com.c
===================================================================
--- tags/rott-1.1/rott/rt_com.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_com.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,799 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+#ifdef DOS
+#include <conio.h>
+#include <dos.h>
+#include <process.h>
+#include <bios.h>
+#endif
+
+#include "rt_def.h"
+#include "_rt_com.h"
+#include "rt_com.h"
+#include "rt_util.h"
+#include "rt_in.h"
+#include "rt_crc.h"
+#include "rt_playr.h"
+#include "isr.h"
+#include "rt_msg.h"
+#include "rottnet.h"
+#include "rt_main.h"
+#include "rt_net.h"
+#include "rt_draw.h"
+//#include "rt_ser.h"
+//MED
+#include "memcheck.h"
+
+// GLOBAL VARIABLES
+
+// Same as in real mode
+rottcom_t   *	rottcom;
+int badpacket;
+int consoleplayer;
+byte ROTTpacket[MAXCOMBUFFERSIZE];
+int controlsynctime;
+
+// LOCAL VARIABLES
+#ifdef DOS
+static union  REGS   comregs;
+#endif
+
+static int    ComStarted=false;
+static int    transittimes[MAXPLAYERS];
+
+void SyncTime( int client );
+void SetTransitTime( int client, int time );
+
+#ifdef PLATFORM_UNIX
+
+static int sock = -1;
+
+static void ReadUDPPacket()
+{
+	rottcom->remotenode = -1;
+}
+
+static void WriteUDPPacket()
+{
+}
+
+#endif
+
+/*
+===============
+=
+= InitROTTNET
+=
+===============
+*/
+
+void InitROTTNET (void)
+{
+	int netarg;
+	long netaddress;
+
+	if (ComStarted==true)
+		return;
+	ComStarted=true;
+
+#ifdef DOS
+        netarg=CheckParm ("net");
+	netarg++;
+
+	netaddress=atol(_argv[netarg]);
+	rottcom=(rottcom_t *)netaddress;
+#elif defined(PLATFORM_UNIX)
+	/*
+	server-specific options:
+	-net: enables netplay
+	-server: run as rott server (default port 34858)
+	-port: select a non-default port for server
+	-host: select a non-default ip address to bind to
+	-standalone: run as standalone server
+	-remoteridicule: enable remote ridicule
+	-players: number of players to expect
+
+	client-specific options:
+	-master: request to have control
+	-net: specifies the host to connect to
+	-port: select a non-default port to connect to
+	*/
+	
+        rottcom = (rottcom_t *) malloc (sizeof(rottcom_t));
+        memset(rottcom, 0, sizeof(rottcom_t));
+        
+        rottcom->ticstep = 1;
+        rottcom->gametype = 1;
+        rottcom->remotenode = -1;
+        
+        if (CheckParm("server")) {
+        	if (CheckParm("standalone")) {
+        		rottcom->consoleplayer = 0;
+        	} else {
+        		rottcom->consoleplayer = 1;
+        	}
+        	
+        	if (CheckParm("remoteridicule")) {
+        		rottcom->remoteridicule = 1;
+        	} else {
+        		rottcom->remoteridicule = 0;
+        	}
+        	
+        	netarg = CheckParm("players");
+        	if (netarg && netarg < _argc-1) {
+        		rottcom->numplayers = atoi(_argv[netarg+1]);
+        	} else {
+        		rottcom->numplayers = 2;
+        	}
+        	
+        	rottcom->client = 0;
+        } else {
+        	rottcom->client = 1;
+        	
+        	/* consoleplayer will be initialized after connecting */
+        	/* numplayers will be initialized after connecting */
+        	/* remoteridicule will be initialized after connecting */
+        }
+        
+        /* client-server negotiation protocol, as inspired by ipxsetup.c */
+        /*
+          Best case:
+          client sends a HereIAm packet.
+          server replies with a YouAre packet, and broadcasts an Info packet
+            to the rest, indicating that the new player has joined.
+          client replies with an IAm packet
+          until all players have joined, the server broadcasts an Info packet
+            to the rest, indicating that another player is needed.
+          once server has enough players, it broadcasts an AllDone packet.
+          
+          In detail:
+          Client state: HereIAm (initial connection)
+          Client sends HereIAm packet, waits for YouAre from server.
+          At timeout, Client resends HereIam
+          When client receives YouAre, client switches to IAm state
+          
+          Client state: IAm
+          Client sends IAm packet, waits for IAmAck from server.
+          At timeout, Client resends IAm
+          When client receives IAmAck, client switches to WaitForDone state.
+          
+          Client state: WaitForDone
+          Client waits for AllDone packet.
+          When client receives AllDone, it sends an AllDoneAck.
+         */
+        
+#endif
+
+   remoteridicule = false;
+   remoteridicule = rottcom->remoteridicule;
+   if (rottcom->ticstep != 1)
+      remoteridicule = false;
+   if (remoteridicule == true)
+      {
+      if (!quiet)
+         printf("ROTTNET: LIVE Remote Ridicule Enabled\n");
+      }
+
+   if (!quiet)
+      {
+#ifdef DOS
+      printf("ROTTNET: Communicating on vector %ld\n",(long int)rottcom->intnum);
+#endif
+      printf("ROTTNET: consoleplayer=%ld\n",(long int)rottcom->consoleplayer);
+      }
+}
+
+/*
+================
+=
+= ReadPacket
+=
+================
+*/
+
+boolean ReadPacket (void)
+{
+   word   crc;
+   word   sentcrc;
+
+   // Set command (Get Packet)
+	rottcom->command=CMD_GET;
+
+   badpacket = 0;
+
+   // Check to see if a packet is ready
+
+#ifdef DOS
+	int386(rottcom->intnum,&comregs,&comregs);
+#elif PLATFORM_UNIX
+	ReadUDPPacket();
+#endif
+
+   // Is it ready?
+
+   if (rottcom->remotenode!=-1)
+      {
+      // calculate crc on packet
+      crc=CalculateCRC (&rottcom->data[0], rottcom->datalength-sizeof(word));
+
+      // get crc inside packet
+      sentcrc=*((word *)(&rottcom->data[rottcom->datalength-sizeof(word)]));
+
+      // are the crcs the same?
+      if (crc!=sentcrc)
+         {
+         badpacket=1;
+         SoftError("BADPKT at %d\n",GetTicCount());
+         }
+      if (networkgame==false)
+         {
+         rottcom->remotenode=server;
+         }
+      else
+         {
+         if ((IsServer==true) && (rottcom->remotenode>0))
+            rottcom->remotenode--;
+         }
+      memcpy(&ROTTpacket[0], &rottcom->data[0], rottcom->datalength);
+
+//      SoftError( "ReadPacket: time=%ld size=%ld src=%ld type=%d\n",GetTicCount(), rottcom->datalength,rottcom->remotenode,rottcom->data[0]);
+
+#if 0
+      rottcom->command=CMD_OUTQUEBUFFERSIZE;
+      int386(rottcom->intnum,&comregs,&comregs);
+      SoftError( "outque size=%ld\n",*((short *)&(rottcom->data[0])));
+      rottcom->command=CMD_INQUEBUFFERSIZE;
+      int386(rottcom->intnum,&comregs,&comregs);
+      SoftError( "inque size=%ld\n",*((short *)&(rottcom->data[0])));
+#endif
+      return true;
+      }
+   else // Not ready yet....
+      return false;
+}
+
+
+/*
+=============
+=
+= WritePacket
+=
+=============
+*/
+
+void WritePacket (void * buffer, int len, int destination)
+{
+   word      crc;
+
+   // set send command
+	rottcom->command=CMD_SEND;
+
+   // set destination
+   rottcom->remotenode=destination;
+
+   if (len>(int)(MAXCOMBUFFERSIZE-sizeof(word)))
+      {
+      Error("WritePacket: Overflowed buffer\n");
+      }
+
+   // copy local buffer into realmode buffer
+   memcpy((byte *)&(rottcom->data[0]),(byte *)buffer,len);
+
+   // calculate CRC
+   crc=CalculateCRC (buffer, len);
+
+   // put CRC into realmode buffer packet
+   *((word *)&rottcom->data[len])=crc;
+
+   // set size of realmode packet including crc
+   rottcom->datalength=len+sizeof(word);
+
+   if (*((byte *)buffer)==0)
+       Error("Packet type = 0\n");
+
+   if (networkgame==true)
+      {
+      if (IsServer==true)
+         rottcom->remotenode++; // server fix-up
+      }
+
+//   SoftError( "WritePacket: time=%ld size=%ld src=%ld type=%d\n",GetTicCount(),rottcom->datalength,rottcom->remotenode,rottcom->data[0]);
+   // Send It !
+#ifdef DOS
+	int386(rottcom->intnum,&comregs,&comregs);
+#elif PLATFORM_UNIX
+	WriteUDPPacket();
+#endif
+
+#if 0
+   rottcom->command=CMD_OUTQUEBUFFERSIZE;
+   int386(rottcom->intnum,&comregs,&comregs);
+   SoftError( "outque size=%ld\n",*((short *)&(rottcom->data[0])));
+   rottcom->command=CMD_INQUEBUFFERSIZE;
+   int386(rottcom->intnum,&comregs,&comregs);
+   SoftError( "inque size=%ld\n",*((short *)&(rottcom->data[0])));
+#endif
+}
+
+
+
+
+/*
+=============
+=
+= ValidSyncPacket
+=
+=============
+*/
+boolean ValidSyncPacket ( synctype * sync )
+{
+   if (ReadPacket() && (badpacket==0))
+      {
+      if (((syncpackettype *)&(ROTTpacket[0]))->type==COM_SYNC)
+         {
+         memcpy(&(sync->pkt),&(ROTTpacket[0]),sizeof(sync->pkt));
+         return true;
+         }
+      }
+   return false;
+}
+
+/*
+=============
+=
+= SendSyncPacket
+=
+=============
+*/
+void SendSyncPacket ( synctype * sync, int dest)
+{
+   sync->pkt.type=COM_SYNC;
+   sync->sendtime=GetTicCount();
+   WritePacket( &(sync->pkt.type) , sizeof(syncpackettype) , dest );
+}
+
+
+/*
+=============
+=
+= SlavePhaseHandler
+=
+=============
+*/
+
+boolean SlavePhaseHandler( synctype * sync )
+{
+   boolean done;
+
+   done=false;
+
+   switch (sync->pkt.phase)
+      {
+      case SYNC_PHASE1:
+         break;
+      case SYNC_PHASE2:
+         ISR_SetTime(sync->pkt.clocktime);
+         break;
+      case SYNC_PHASE3:
+         sync->pkt.clocktime=GetTicCount();
+         break;
+      case SYNC_PHASE4:
+         ISR_SetTime(GetTicCount()-sync->pkt.delta);
+         sync->pkt.clocktime=GetTicCount();
+         break;
+      case SYNC_PHASE5:
+         ISR_SetTime(GetTicCount()-sync->pkt.delta);
+         sync->sendtime=sync->pkt.clocktime;
+         done=true;
+         break;
+      }
+   return done;
+}
+
+
+
+/*
+=============
+=
+= MasterPhaseHandler
+=
+=============
+*/
+
+boolean MasterPhaseHandler( synctype * sync )
+{
+   boolean done;
+
+   done=false;
+
+   switch (sync->pkt.phase)
+      {
+      case SYNC_PHASE1:
+         sync->pkt.phase=SYNC_PHASE2;
+         sync->pkt.clocktime=GetTicCount()+(sync->deltatime>>1);
+         break;
+      case SYNC_PHASE2:
+         sync->pkt.phase=SYNC_PHASE3;
+         break;
+      case SYNC_PHASE3:
+         sync->pkt.delta=sync->pkt.clocktime-GetTicCount()+(sync->deltatime>>1);
+         sync->pkt.phase=SYNC_PHASE4;
+         break;
+      case SYNC_PHASE4:
+         sync->pkt.phase=SYNC_PHASE5;
+         sync->pkt.delta=sync->pkt.clocktime-GetTicCount()+(sync->deltatime>>1);
+         sync->sendtime=GetTicCount()+SYNCTIME;
+         sync->pkt.clocktime=sync->sendtime;
+         done=true;
+         break;
+      }
+   return done;
+}
+
+
+/*
+=============
+=
+= ComSetTime
+=
+=============
+*/
+
+void ComSetTime ( void )
+{
+   int i;
+   syncpackettype * syncpacket;
+   boolean done=false;
+
+   syncpacket=(syncpackettype *)SafeMalloc(sizeof(syncpackettype));
+
+
+   // Sync clocks
+
+   if (networkgame==true)
+      {
+      if (IsServer==true)
+         {
+         for (i=0;i<numplayers;i++)
+            {
+            if (PlayerInGame(i)==false)
+               continue;
+            if (standalone==true)
+               SyncTime(i);
+            else if (i!=consoleplayer)
+               SyncTime(i);
+            if (standalone==true)
+               printf("ComSetTime: player#%ld\n",(long int)i);
+            }
+         }
+      else
+         {
+         SyncTime(0);
+         }
+      }
+   else // Modem 2-player game
+      {
+      if (consoleplayer==0)
+         SyncTime(server);
+      else
+         SyncTime(server);
+      }
+
+   if ( ( (networkgame==true) && (IsServer==true) ) ||
+        ( (networkgame==false) && (consoleplayer==0) )
+      ) // Master/Server
+      {
+      int nump;
+      int time;
+
+      syncpacket->type=COM_START;
+      syncpacket->clocktime=GetTicCount();
+      controlsynctime=syncpacket->clocktime;
+      if (networkgame==true)
+         nump=numplayers;
+      else
+         nump=1;
+
+      time = GetTicCount();
+
+      for (i=0;i<nump;i++)
+         {
+         WritePacket( &(syncpacket->type) , sizeof(syncpackettype) , i );
+         }
+
+      while (GetTicCount()<time+(VBLCOUNTER/4)) ;
+
+      for (i=0;i<nump;i++)
+         {
+         WritePacket( &(syncpacket->type) , sizeof(syncpackettype) , i );
+         }
+
+      if (standalone==true)
+         printf("ComSetTime: Start packets sent\n");
+      }
+   else // Slave/Client
+      {
+      while (done==false)
+         {
+         AbortCheck("ComSetTime aborted as client");
+
+         if (ReadPacket() && (badpacket==0))
+            {
+            memcpy(syncpacket,&(ROTTpacket[0]),sizeof(syncpackettype));
+            if (syncpacket->type==COM_START)
+               {
+               controlsynctime=syncpacket->clocktime;
+               done=true;
+               }
+            }
+         }
+      }
+   if (standalone==false)
+      {
+      AddMessage("All players synched.",MSG_SYSTEM);
+      ThreeDRefresh();
+      }
+   SafeFree(syncpacket);
+
+//
+// flush out any extras
+//
+   while (GetTicCount()<controlsynctime+VBLCOUNTER)
+      {
+      ReadPacket ();
+      }
+}
+
+/*
+=============
+=
+= InitialMasterSync
+=
+=============
+*/
+void InitialMasterSync ( synctype * sync, int client )
+{
+   boolean done=false;
+   int i;
+
+   if (networkgame==true)
+      {
+      for (i=0;i<numplayers;i++)
+         {
+         if (i<=client)
+            continue;
+         sync->pkt.type=COM_SYNC;
+         sync->pkt.phase=SYNC_MEMO;
+         sync->pkt.clocktime=client;
+         SendSyncPacket(sync,i);
+         }
+      }
+
+   // Initialize send time so as soon as we enter the loop, we send
+
+   sync->sendtime=GetTicCount()-SYNCTIME;
+
+   while (done==false)
+      {
+      sync->pkt.phase=SYNC_PHASE0;
+
+      AbortCheck("Initial sync aborted as master");
+	   if ((sync->sendtime+SYNCTIME) <= GetTicCount())
+         SendSyncPacket(sync,client);
+      if (ValidSyncPacket(sync)==true)
+         {
+         if (sync->pkt.phase==SYNC_PHASE0)
+            {
+            int time=GetTicCount();
+
+            while (time+SYNCTIME>GetTicCount())
+               {
+               ReadPacket();
+               }
+            time=GetTicCount();
+            while (time+SYNCTIME>GetTicCount()) {}
+            done=true;
+            }
+         }
+      }
+}
+
+/*
+=============
+=
+= InitialSlaveSync
+=
+=============
+*/
+void InitialSlaveSync ( synctype * sync )
+{
+   boolean done=false;
+
+   while (done==false)
+      {
+      AbortCheck("Initial sync aborted as slave");
+      if (ValidSyncPacket(sync)==true)
+         {
+         if (sync->pkt.phase==SYNC_MEMO)
+            {
+            char str[50]="Server is synchronizing player ";
+            char str2[10];
+
+            strcat(str,itoa(sync->pkt.clocktime+1,str2,10));
+            AddMessage(str,MSG_SYSTEM);
+            ThreeDRefresh();
+            }
+         if (sync->pkt.phase==SYNC_PHASE0)
+            {
+            int time=GetTicCount();
+
+            SendSyncPacket(sync,server);
+            while (time+SYNCTIME>GetTicCount())
+               {
+               ReadPacket();
+               }
+            done=true;
+            }
+         }
+      }
+   AddMessage("Server is synchronizing your system",MSG_SYSTEM);
+   ThreeDRefresh();
+}
+
+
+/*
+=============
+=
+= SyncTime
+=
+=============
+*/
+
+void SyncTime( int client )
+{
+   int dtime[NUMSYNCPHASES];
+   boolean done;
+   int i;
+   synctype * sync;
+
+   sync=(synctype *)SafeMalloc(sizeof(synctype));
+
+   if ( ((networkgame==true) && (IsServer==true)) ||
+         ((networkgame==false) && (consoleplayer==0)) )
+      {
+      // Master
+
+      InitialMasterSync ( sync, client );
+
+      done=false;
+
+      // Initial setup for Master
+      // Initialize send time so as soon as we enter the loop, we send
+
+      sync->pkt.phase=SYNC_PHASE1;
+      sync->sendtime=GetTicCount()-SYNCTIME;
+
+      while (done==false)
+         {
+         // Master
+
+         AbortCheck("SyncTime aborted as master");
+
+		   if ((sync->sendtime+SYNCTIME) <= GetTicCount())
+            SendSyncPacket(sync,client);
+
+         while (ValidSyncPacket(sync)==true)
+            {
+
+            // find average delta
+
+            sync->deltatime=0;
+
+            // calculate last delta
+
+            dtime[sync->pkt.phase]=GetTicCount()-sync->sendtime;
+
+            for (i=0;i<=sync->pkt.phase;i++)
+               sync->deltatime+=dtime[i];
+            if (i!=0)
+               sync->deltatime/=i;
+            else
+               Error("SyncTime: this should not happen\n");
+
+            done = MasterPhaseHandler( sync );
+
+            SendSyncPacket(sync,client);
+
+            }
+         }
+      }
+   else
+      {
+      // Slave
+
+      InitialSlaveSync ( sync );
+
+      done=false;
+
+      while (done==false)
+         {
+         // Slave
+
+         AbortCheck("SyncTime aborted as slave");
+
+         while (ValidSyncPacket(sync)==true)
+            {
+            done = SlavePhaseHandler( sync );
+
+            if (done==false)
+               SendSyncPacket(sync,server);
+
+            }
+         }
+      }
+
+   while (sync->sendtime > GetTicCount())
+      {
+      while (ReadPacket()) {}
+      }
+   while ((sync->sendtime+SYNCTIME) > GetTicCount())
+      {
+      }
+
+   if ( ((networkgame==true) && (IsServer==true)) ||
+         ((networkgame==false) && (consoleplayer==0)) )
+      SetTransitTime( client, (sync->deltatime>>1));
+
+   SafeFree(sync);
+}
+
+/*
+=============
+=
+= SetTransitTime
+=
+=============
+*/
+
+void SetTransitTime( int client, int time )
+{
+   transittimes[client]=time;
+}
+
+/*
+=============
+=
+= GetTransitTime
+=
+=============
+*/
+
+int GetTransitTime( int client )
+{
+   return transittimes[client];
+}
+

Added: tags/rott-1.1/rott/rt_com.h
===================================================================
--- tags/rott-1.1/rott/rt_com.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_com.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,48 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_com_public
+#define _rt_com_public
+
+//***************************************************************************
+//
+// RT_COM.C
+//
+//***************************************************************************
+
+#define MAXPACKET	512
+
+#include "rottnet.h"
+
+extern int badpacket;
+extern int consoleplayer;
+extern byte ROTTpacket[MAXCOMBUFFERSIZE];
+
+extern int controlsynctime;
+
+
+//#define consoleplayer (rottcom->consoleplayer)
+
+void InitROTTNET (void);
+boolean ReadPacket (void);
+void WritePacket (void * buffer, int len, int destination);
+void ComSetTime (void);
+int GetTransitTime( int client );
+
+#endif

Added: tags/rott-1.1/rott/rt_crc.c
===================================================================
--- tags/rott-1.1/rott/rt_crc.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_crc.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,131 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// CRC lib
+
+#include	<stdio.h>
+#include	<stdlib.h>
+#include	<string.h>
+#include "rt_crc.h"
+//MED
+#include "memcheck.h"
+
+/* variables */
+static const unsigned short int crc16tab[256] =
+{
+	0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+	0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+	0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+	0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+	0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+	0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+	0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+	0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+	0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+	0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+	0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+	0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+	0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+	0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+	0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+	0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+	0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+	0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+	0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+	0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+	0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+	0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+	0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+	0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+	0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+	0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+	0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+	0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+	0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+	0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+	0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+	0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+
+/* driver */
+#if 0
+main(argc,argv)
+int argc; char **argv;
+{
+	if(argc>2) perr("Usage:  crcfast [filename]");
+	if(argc==2) strcpy(filename,argv[1]);
+	else
+	{
+		printf("\nEnter filename:  "); gets(filename);
+	}
+	if((fp=fopen(filename,"rb"))==NULL) perr("Can't open file");
+	num=0L; crc16=crctt=0;
+	while((ch=fgetc(fp))!=EOF)
+	{
+		num++;
+		crc16=updatecrc(crc16,ch);
+//		crctt=updcrc(crctt,ch);
+	}
+	fclose(fp);
+	printf("\nNumber of bytes = %lu\nCRC16 = %04X\nCRCTT = %04X",
+		num,crc16,crctt);
+}
+
+#endif
+
+/* update crc reverse */
+int updatecrc(int crc, int c)
+{
+	int tmp;
+	tmp=crc^c;
+	crc=(crc>>8)^crc16tab[tmp & 0xff];
+	return crc;
+}
+
+//******************************************************************************
+//
+// CalculateCRC ()
+//
+//******************************************************************************
+
+word CalculateCRC (byte *source, unsigned size)
+{
+   unsigned i;
+   int checksum;
+	int tmp;
+
+   checksum=0;
+
+   for (i = 0; i < size; i++)
+      {
+   	tmp=checksum^(*(source++));
+	   checksum=(checksum>>8)^crc16tab[tmp & 0xff];
+      }
+
+   return ((word)checksum);
+
+}
+
+
+
+
+
+
+
+

Added: tags/rott-1.1/rott/rt_crc.h
===================================================================
--- tags/rott-1.1/rott/rt_crc.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_crc.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,24 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+
+int updatecrc(int,int);
+word CalculateCRC (byte *source, unsigned size);
+

Added: tags/rott-1.1/rott/rt_debug.c
===================================================================
--- tags/rott-1.1/rott/rt_debug.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_debug.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1684 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "rt_debug.h"
+#include "isr.h"
+#include "rt_game.h"
+#include "rt_menu.h"
+#include "rt_build.h"
+#include "rt_str.h"
+#include "rt_vid.h"
+#include "rt_playr.h"
+#include "rt_main.h"
+#include "rt_util.h"
+#include "rt_draw.h"
+#include "rt_in.h"
+#include "z_zone.h"
+#include "rt_ted.h"
+#include "rt_view.h"
+#include "develop.h"
+#include "rt_msg.h"
+#include "rt_net.h"
+#include "rt_sound.h"
+#include "rt_stat.h"
+#include "rt_map.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+//MED
+#include "memcheck.h"
+#include "w_wad.h"
+
+extern int		iDemoNames;
+extern boolean iG_aimCross;
+
+
+extern void DisplayMessage   (int num,int position);
+
+
+typedef struct {
+   char code[15];
+   byte length;
+} CodeStruct;
+
+enum
+{
+   ENABLECHEAT,               // enable cheats
+   ENABLECHEATALT,            // enable cheats
+   SOMEITEMS,                 // three keys, more health
+   SOMEITEMSALT,              // three keys, more health
+   INVULNERABLE,              // normal god mode
+   INVULNERABLEALT,           // normal god mode
+   WARP,                      // warp
+   WARPALT,                   // warp
+   ITEMS,                     // all keys, armor, 100% health
+   ITEMSALT,                  // all keys, armor, 100% health
+   GODMODEPWUP,               // god mode powerup
+	GODMODEPWUPALT,            // god mode powerup
+#if (SHAREWARE == 0)
+   DOGMODEPWUP,               // dog mode powerup
+   DOGMODEPWUPALT,            // dog mode powerup
+#endif
+	MERCURYPWUP,               // mercury mode powerup
+   MERCURYPWUPALT,            // mercury mode powerup
+   SHROOMSPWUP,               // shrooms mode powerup
+   SHROOMSPWUPALT,            // shrooms mode powerup
+   ELASTOPWUP,                // elasto mode powerup
+   ELASTOPWUPALT,             // elasto mode powerup
+   RESTARTGAME,               // warp to level 1, start with pistol
+   RESTARTGAMEALT,            // warp to level 1, start with pistol
+   HURTPLAYER,                // hurt player 10%
+   HURTPLAYERALT,             // hurt player 10%
+   TOMHALLMODE,               // run fast all the time
+	TOMHALLMODEALT,            // run fast all the time
+   NORMAL,                    // back to normal
+   NORMALALT,                 // back to normal
+   LIGHTDIMON,                // light diminishing on
+   LIGHTDIMONALT,             // light diminishing on
+   LIGHTDIMOFF,               // light diminishing off
+   LIGHTDIMOFFALT,            // light diminishing off
+   FOGON,                     // fog on (0x00 - 0x80 minmax)
+   FOGONALT,                  // fog on (0x00 - 0x80 minmax)
+   FOGOFF,                    // fog off (0x80 - 0xFF minmax)
+   FOGOFFALT,                 // fog off (0x80 - 0xFF minmax)
+   QUITGAME,                  // blow out of game
+   QUITGAMEALT,               // blow out of game
+   ENDLEVEL,                  // end the current level
+   ENDLEVELALT,               // end the current level
+   FANDCOFF,                  // floor and ceiling off
+   FANDCOFFALT,               // floor and ceiling off
+   FANDCON,                   // floor and ceiling on
+   FANDCONALT,                // floor and ceiling on
+   BULLETARMOR,               // bullet proof armor
+   BULLETARMORALT,            // bullet proof armor
+   FIREARMOR,                 // fire proof armor
+   FIREARMORALT,              // fire proof armor
+   GASMASK,                   // gas mask
+   GASMASKALT,                // gas mask
+   OUTFIT,                    // all keys, armor, 100% health, MP40, heatseek
+   OUTFITALT,                 // all keys, armor, 100% health, MP40, heatseek
+   KILLPLAYER,                // kill player
+	KILLPLAYERALT,             // kill player
+	RESTARTLEVEL,              // re-enter level
+	RESTARTLEVELALT,           // re-enter level
+   WEAPONTWOPISTOL,           // give double pistol
+   WEAPONTWOPISTOLALT,        // give double pistol
+   WEAPONMP40,                // give mp40
+   WEAPONMP40ALT,             // give mp40
+   WEAPONBAZOOKA,             // give bazooka
+   WEAPONBAZOOKAALT,          // give bazooka
+   WEAPONHEAT,                // give heatseeker
+   WEAPONHEATALT,             // give heatseeker
+   WEAPONDRUNK,               // give drunk missile
+   WEAPONDRUNKALT,            // give drunk missile
+   WEAPONFIREBOMB,            // give firebomb
+   WEAPONFIREBOMBALT,         // give firebomb
+   WEAPONFIREWALL,            // give firewall
+   WEAPONFIREWALLALT,         // give firewall
+	WEAPONGOD,                 // give godhand
+	WEAPONGODALT,              // give godhand
+	AIMCROSS,                 // bna++
+	AIMCROSSALT,              // give bna++
+
+#if (SHAREWARE == 0)
+
+   WEAPONSPLIT,               // give split missile
+   WEAPONSPLITALT,            // give split missile
+   WEAPONKES,                 // give kes
+   WEAPONKESALT,              // give kes
+   WEAPONBAT,                 // give bat
+   WEAPONBATALT,              // give bat
+   WEAPONDOG,                 // give dogmode
+   WEAPONDOGALT,              // give dogmode
+#endif
+
+   MISSILECAMTOGGLE,          // Turn missile cam on/off
+   MISSILECAMTOGGLEALT,       // Turn missile cam on/off
+   HUDTOGGLE,                 // Turn HUD on/off
+   HUDTOGGLEALT,              // Turn HUD on/off
+   ROTATIONFUN,               // Rotation fun
+   DEMORECORD,                // Start recording demo
+   DEMOEND,                   // End recording demo
+   DEMOPLAYBACK,              // Playback demo
+   CRAZYGIBS,                 // Engine Killing Gibs
+   JUKEBOX,                   // JukeBox
+   JUKEBOXALT,                // JukeBox
+   MAPCHEAT,                  // Map Cheat
+   MAPCHEATALT,               // Map Cheat Alt
+   MAXCODES
+};
+
+CodeStruct Codes[MAXCODES + 6] =
+{
+	{"KCITSPID",    8},        // enable cheats
+	{"CCE\\",       4},        // enable cheats
+   {"REKCALS",     7},        // three keys, more health
+   {"MUB\\",       4},        // three keys, more health
+   {"NIJOHC",      6},        // normal god mode
+	{"WWW\\",       4},        // normal god mode
+	{"OTOG",        4},        // warp
+	{"LTG\\",       4},        // warp
+	{"SYOTXIS",     7},        // all keys, armor, 100% health
+	{"IAG\\",       4},        // all keys, armor, 100% health
+   {"DASOOT",      6},        // god mode powerup
+   {"DOG\\",       4},        // god mode powerup
+#if (SHAREWARE == 0)
+   {"FOOW",        4},        // dog mode powerup
+	{"GOD\\",       4},        // dog mode powerup
+#endif
+	{"YOBYLF",      6},        // mercury mode powerup
+	{"REM\\",       4},        // mercury mode powerup
+	{"PIRTDAB",     7},        // shrooms mode powerup
+	{"RHS\\",       4},        // shrooms mode powerup
+	{"GNIOB",       5},        // elasto mode powerup
+	{"ALE\\",       4},        // elasto mode powerup
+	{"SREBOOG",     7},        // warp to level 1, start with pistol
+	{"OOG\\",       4},        // warp to level 1, start with pistol
+	{"KCAHW",       5},        // hurt player 10%
+	{"FOO\\",       4},        // hurt player 10%
+	{"DEEPS",       5},        // run fast all the time
+	{"AFR\\",       4},        // run fast all the time
+	{"CINAP",       5},        // back to normal
+	{"NAP\\",       4},        // back to normal
+	{"NOMID",       5},        // light diminishing on
+	{"NOD\\",       4},        // light diminishing on
+	{"FFOMID",      6},        // light diminishing off
+	{"FOD\\",       4},        // light diminishing off
+	{"NODNOL",      6},        // fog on (0x00 - 0x80 minmax)
+	{"NOF\\",       4},        // fog on (0x00 - 0x80 minmax)
+	{"LONDON",      6},        // fog off (0x80 - 0xFF minmax)
+	{"FOF\\",       4},        // fog off (0x80 - 0xFF minmax)
+	{"SETAGOG",     7},        // blow out of game
+	{"R8L\\",       4},        // blow out of game
+	{"HCRAOG",      6},        // end the current level
+	{"LCE\\",       4},        // end the current level
+	{"683ATOG",     7},        // floor and ceiling off
+	{"NOC\\",       4},        // floor and ceiling off
+	{"684ATOG",     7},        // floor and ceiling on
+	{"FOC\\",       4},        // floor and ceiling on
+	{"EMTOOHS",     7},        // bullet proof armor
+	{"RAB\\",       4},        // bullet proof armor
+	{"EMNRUB",      6},        // fire proof armor
+	{"RAF\\",       4},        // fire proof armor
+	{"GNUDGNUL",    8},        // gas mask
+	{"RAG\\",       4},        // gas mask
+	{"KCAPTNUH",    8},        // all keys, armor, 100% health, MP40, heatseek
+	{"PFO\\",       4},        // all keys, armor, 100% health, MP40, heatseek
+	{"EM68",        4},        // kill player
+	{"EID\\",       4},        // kill player
+	{"REEN",        4},        // re-enter level
+	{"LER\\",       4},        // re-enter level
+   {"OOWNHOJ",     7},        // give double pistol
+	{"2WG\\",       4},        // give double pistol
+	{"EMGULP",      6},        // give mp40
+	{"3WG\\",       4},        // give mp40
+	{"ALLINAV",     7},        // give bazooka
+	{"4WG\\",       4},        // give bazooka
+	{"SEMITTOH",    8},        // give heatseeker
+   {"5WG\\",       4},        // give heatseeker
+   {"EZOOB",       5},        // give drunk missile
+   {"6WG\\",       4},        // give drunk missile
+   {"BMOBERIF",    8},        // give firebomb
+   {"7WG\\",       4},        // give firebomb
+	{"SENOB",       5},        // give firewall
+	{"8WG\\",       4},        // give firewall
+	{"AYEES",       5},        // give god hand
+   {"9WG\\",       4},        // give god hand
+	{"MIA",       3},        // give aim bna++
+   {"MIA\\",       4},        // give aim bna++
+
+
+
+#if (SHAREWARE == 0)
+
+   {"TILPS",       5},        // give split missile
+   {"AWG\\",       4},        // give split missile
+	{"HTAEDFOSEK", 10},        // give kes
+   {"BWG\\",       4},        // give kes
+	{"NUREMOH",     8},        // give bat
+   {"CWG\\",       4},        // give bat
+   {"OJUC",        4},        // give dog weapon
+   {"DWG\\",       4},        // give dog weapon
+#endif
+   {"EDIR",        4},        // give MISSILE CAM
+   {"MAC\\",       4},        // give Missile Cam
+   {"EREHW",       5},        // turn where am i on/off
+   {"DUH\\",       4},        // give hud
+   {"NUF\\",       4},        // Rotation fun
+   {"DROCER",      6},        // Demo RECORD
+   {"POTS",        4},        // Demo stop recording
+   {"YALP",        4},        // Demo Playback
+   {"GKE\\",       4},        // Engine Killing Gibs
+   {"ORTSEAM",     7},        // JukeBox
+   {"EEL\\",       4},        // JukeBox
+   {"REITRAC",     7},        // Map Cheat
+   {"PAM\\",       4},        // Map Cheat
+   {"UOY\\",       4},        // Secret Message
+   {"EVAH",        4},        // Secret Message
+   {"ON\\",        3},        // Secret Message
+   {"EFIL",        4},        // Secret Message
+
+};
+
+
+
+
+/*
+================
+=
+= CheatSpawnItem
+=
+================
+*/
+
+void CheatSpawnItem (int item)
+   {
+   SpawnStatic(player->tilex, player->tiley, item,-1);
+   LASTSTAT->z = player->z;
+	MakeStatActive(LASTSTAT);
+	LASTSTAT->flags|=FL_ABP;
+   }
+
+
+/*
+================
+=
+= FixupPowerupsY
+=
+================
+*/
+
+void FixupPowerupsY (void)
+{
+	player->z   = nominalheight;
+}
+
+
+/*
+================
+=
+= EnableCheatCodes
+=
+================
+*/
+
+void EnableCheatCodes (void)
+{
+	DebugOk ^= 1;
+
+	if (DebugOk)
+      AddMessage ("Cheat Codes \\cENABLED!", MSG_CHEAT);
+	else
+      AddMessage ("Cheat Codes \\cDISABLED!", MSG_CHEAT);
+}
+
+
+/*
+================
+=
+= ResetCheatCodes
+=
+================
+*/
+
+void ResetCheatCodes (void)
+{
+//	godmode = false;
+}
+
+/*
+================
+=
+= DoMapCheat
+=
+================
+*/
+
+void DoMapCheat (void)
+{
+   AddMessage ("Entire Map Revealed!", MSG_CHEAT);
+   CheatMap ();
+}
+
+/*
+================
+=
+= DoGodMode
+=
+================
+*/
+
+void DoGodMode (void)
+{
+	if (godmode)
+      AddMessage ("Woundless With Weapons \\cOFF", MSG_CHEAT);
+	else
+      AddMessage ("Woundless With Weapons \\cON", MSG_CHEAT);
+
+	godmode ^= 1;
+}
+
+
+/*
+================
+=
+= DoWarp
+=
+================
+*/
+#include "byteordr.h"//bna++
+void DoWarp (void)
+{
+/*
+	char str[10];
+	boolean esc;
+	int level;
+
+   CurrentFont = smallfont;
+
+   US_CenterWindow(26,3);
+	PrintY+=6;
+
+   US_Print(" Warp to level(1-99):");
+
+   VW_UpdateScreen();
+
+   ShutdownClientControls();
+
+   esc = !US_LineInput (px, py, str, NULL, true, 2, 25, 13);
+
+   if (!esc)
+   {
+      level = ParseNum (str);
+      if (level>0 && level<=99)
+      {
+         gamestate.mapon = level-1;
+         playstate = ex_warped;
+         gamestate.episode = GetEpisode (gamestate.mapon);
+      }
+   }
+
+   while (Keyboard[sc_Escape])
+		IN_UpdateKeyboard ();
+   IN_ClearKeyboardQueue ();
+
+*/
+
+   int level;
+
+
+	EnableScreenStretch();//bna++ shut on streech mode
+
+
+   MU_StoreSongPosition();
+   MU_StartSong( song_secretmenu);
+   StopWind();
+   ShutdownClientControls();
+
+   SetupMenuBuf();
+   SetUpControlPanel ();
+
+   level = CP_LevelSelectionMenu();
+
+   CleanUpControlPanel();
+   ShutdownMenuBuf();
+
+   	//bna++ section
+  if (( playstate == ex_stillplaying )&&(iGLOBAL_SCREENWIDTH > 320)){
+		pic_t *shape;
+		shape =  ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );
+		DrawTiledRegion( 0, 16, iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT - 32, 0, 16, shape );
+		DisableScreenStretch();//dont strech when we go BACK TO GAME
+		DrawPlayScreen(true);//repaint ammo and life stat
+		VW_UpdateScreen ();//update screen
+  }
+   //bna section end
+
+	EnableScreenStretch();//bna++ shut on streech mode
+   while( Keyboard[ sc_Escape ] )
+      {
+		IN_UpdateKeyboard();
+      }
+   IN_ClearKeyboardQueue();
+
+   if ((level == -1) || (level == gamestate.mapon))
+      {
+      MU_StartSong(song_level);
+      MU_RestoreSongPosition();
+      }
+
+   if ( level >= 0 )
+      {
+      playstate = ex_warped;
+      gamestate.mapon   = level;
+      
+      GetEpisode( gamestate.mapon );
+
+      VL_FadeOut (0, 255, 0, 0, 0, 20);
+      }
+   else
+      {
+	   DisableScreenStretch();//dont strech when we go BACK TO GAME
+      SetupScreen(true);
+      }
+
+   StartupClientControls();
+   }
+
+/*
+================
+=
+= DoJukeBox
+=
+================
+*/
+
+void DoJukeBox  (void)
+
+   {
+	if (iGLOBAL_SCREENWIDTH > 320) {
+		EnableScreenStretch();//bna++ shut on streech mode
+	}
+   StopWind();
+   ShutdownClientControls();
+
+   SetupMenuBuf();
+   SetUpControlPanel ();
+
+   MU_JukeBoxMenu();
+
+   CleanUpControlPanel();
+   ShutdownMenuBuf();
+
+   	//bna++ section
+  if (( playstate == ex_stillplaying )&&(iGLOBAL_SCREENWIDTH > 320)){
+		pic_t *shape;
+		shape =  ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );
+		DrawTiledRegion( 0, 16, iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT - 32, 0, 16, shape );
+		DisableScreenStretch();//dont strech when we go BACK TO GAME
+		DrawPlayScreen(true);//repaint ammo and life stat
+		VW_UpdateScreen ();//update screen
+  }
+   //bna section end
+
+   SetupScreen(true);
+
+   while( Keyboard[ sc_Escape ] )
+      {
+		IN_UpdateKeyboard();
+      }
+   IN_ClearKeyboardQueue();
+
+   StartupClientControls();
+   }
+
+
+
+/*
+================
+=
+= DoNormalThing
+=
+================
+*/
+
+void DoNormalThing (void)
+{
+   AddMessage ("BACK TO NORMAL.  AH.", MSG_CHEAT);
+
+	player->flags &= ~(FL_BPV|FL_AV|FL_GASMASK);
+	locplayerstate->protectiontime = 0;
+
+   if (player->flags & FL_ELASTO)
+      player->flags &= ~FL_NOFRICTION;
+   player->flags &= ~(FL_SHROOMS|FL_ELASTO|FL_FLEET);
+	locplayerstate->poweruptime = 0;
+
+	InitializeWeapons(locplayerstate);
+	locplayerstate->keys = 0;
+
+   DrawPlayScreen (false);
+}
+
+
+
+/*
+================
+=
+= DoItemCheat
+=
+================
+*/
+
+void DoItemCheat (void)
+{
+   AddMessage ("Items Aplenty!", MSG_CHEAT);
+
+	GivePoints (100000);
+	HealPlayer (99, player);
+
+	locplayerstate->keys = 0xF;
+	DrawKeys (false);
+
+   player->flags &= ~(FL_GASMASK|FL_BPV|FL_AV);
+   CheatSpawnItem(stat_bulletproof);
+
+   /*
+   player->flags |= FL_BPV;
+	player->flags &= ~(FL_GASMASK|FL_AV);
+	locplayerstate->protectiontime = POWERUPTICS;
+   GM_DrawBonus (stat_bulletproof);
+   */
+}
+
+/*
+================
+=
+= DoSomeItemCheat
+=
+================
+*/
+
+void DoSomeItemCheat (void)
+{
+   AddMessage ("Slacker pack!", MSG_CHEAT);
+
+   HealPlayer (40, player);
+
+   locplayerstate->keys = 0x7;
+	DrawKeys (false);
+}
+
+
+/*
+================
+=
+= DoGodModePowerup
+=
+================
+*/
+
+void DoGodModePowerup (void)
+   {
+
+   if (PLAYER[0]->flags & FL_GODMODE)
+	  return;
+
+   CheatSpawnItem(stat_godmode);
+   }
+
+
+/*
+================
+=
+= DoDogModePowerup
+=
+================
+*/
+
+void DoDogModePowerup (void)
+   {
+
+   if (PLAYER[0]->flags & FL_DOGMODE)
+	  return;
+
+   CheatSpawnItem(stat_dogmode);
+   }
+
+
+/*
+================
+=
+= DoMercuryModePowerup
+=
+================
+*/
+
+void DoMercuryModePowerup (void)
+   {
+
+   if (PLAYER[0]->flags & FL_FLEET)
+	  return;
+
+   CheatSpawnItem(stat_fleetfeet);
+   }
+
+
+/*
+================
+=
+= DoElastoModePowerup
+=
+================
+*/
+
+void DoElastoModePowerup (void)
+   {
+   if (PLAYER[0]->flags & FL_ELASTO)
+	  return;
+
+   CheatSpawnItem(stat_elastic);
+   }
+
+
+/*
+================
+=
+= DoShroomsModePowerup
+=
+================
+*/
+
+void DoShroomsModePowerup (void)
+   {
+   if (PLAYER[0]->flags & FL_SHROOMS)
+	  return;
+
+   AddMessage ("SHROOMS MODE POWERDOWN!", MSG_CHEAT);
+
+   CheatSpawnItem(stat_mushroom);
+   }
+
+
+/*
+================
+=
+= RestartNormal
+=
+================
+*/
+
+void RestartNormal (void)
+{
+	EnableScreenStretch();//bna
+	DoNormalThing ();
+
+   AddMessage ("Restart to level 1", MSG_CHEAT);
+	gamestate.mapon   = 0;
+	playstate         = ex_warped;
+	
+	GetEpisode (gamestate.mapon);
+}
+
+
+/*
+================
+=
+= HurtPlayer
+=
+================
+*/
+
+void HurtPlayer (void)
+{
+   int oldhitpoints;
+
+   oldhitpoints = player->hitpoints;
+	DamageThing (player, MaxHitpointsForCharacter(locplayerstate) / 10);
+   if (player->hitpoints < oldhitpoints)
+      AddMessage ("OUCH!!!!", MSG_CHEAT);
+
+   Collision(player,player,0,0);
+}
+
+
+/*
+================
+=
+= SetLightDiminish
+=
+================
+*/
+
+void SetLightDiminish (boolean off)
+{
+	if (off)
+	{
+      AddMessage ("Light Diminishing \\cOff", MSG_CHEAT);
+		fulllight = 1;
+	}
+	else
+	{
+      AddMessage ("Light Diminishing \\cOn", MSG_CHEAT);
+		fulllight = 0;
+	}
+}
+
+
+/*
+================
+=
+= SetFog
+=
+================
+*/
+
+void SetFog (boolean on)
+{
+	if (on)
+	{
+      AddMessage ("Fog \\cOn", MSG_CHEAT);
+		MAPSPOT(2,0,1)=105;
+		MAPSPOT(3,0,1)=0;
+		SetupLightLevels ();
+
+	}
+	else
+	{
+      AddMessage ("Fog \\cOff", MSG_CHEAT);
+		MAPSPOT(2,0,1)=104;
+		SetupLightLevels ();
+	}
+}
+
+
+
+/*
+================
+=
+= ToggleMissileCam
+=
+================
+*/
+
+void ToggleMissileCam (void)
+{
+   if (missilecam==false)
+      {
+      missilecam=true;
+      AddMessage ("Missile Cam \\cOn", MSG_CHEAT);
+      }
+   else
+      {
+      missilecam=false;
+      AddMessage ("Missile Cam \\cOff", MSG_CHEAT);
+      }
+}
+
+/*
+================
+=
+= ToggleHUD
+=
+================
+*/
+
+void ToggleHUD (void)
+{
+   if (HUD==false)
+      {
+      HUD=true;
+      AddMessage ("HUD \\cOn", MSG_CHEAT);
+      }
+   else
+      {
+      HUD=false;
+      AddMessage ("HUD \\cOff", MSG_CHEAT);
+      }
+}
+
+
+
+/*
+================
+=
+= EndLevel
+=
+================
+*/
+
+void EndLevel (void)
+{
+   AddMessage ("End Level", MSG_CHEAT);
+   playstate = ex_skiplevel;
+}
+
+
+/*
+================
+=
+= FloorandCeiling
+=
+================
+*/
+
+void FloorandCeiling (boolean off)
+{
+	if (off)
+	{
+      AddMessage ("Floor and Ceiling \\cON", MSG_CHEAT);
+		fandc = 1;
+	}
+	else
+	{
+      AddMessage ("Floor and Ceiling \\cOFF", MSG_CHEAT);
+		fandc = 0;
+	}
+}
+
+
+/*
+================
+=
+= GiveGasMask
+=
+================
+*/
+
+void GiveGasMask ()
+   {
+
+	if (PLAYER[0]->flags & FL_GASMASK)
+     return;
+
+   CheatSpawnItem(stat_gasmask);
+   }
+
+/*
+================
+=
+= GiveBulletProofArmor
+=
+================
+*/
+
+void GiveBulletProofArmor ()
+   {
+	if (PLAYER[0]->flags & FL_BPV)
+     return;
+
+
+   CheatSpawnItem(stat_bulletproof);
+   }
+
+/*
+================
+=
+= GiveAsbestoArmor
+=
+================
+*/
+
+void GiveAsbestoArmor ()
+   {
+	if (PLAYER[0]->flags & FL_AV)
+     return;
+
+   CheatSpawnItem(stat_asbesto);
+   }
+
+
+/*
+================
+=
+= OutfitPlayer
+=
+================
+*/
+void OutfitPlayer ()
+{
+   AddMessage ("Outfit Player!", MSG_CHEAT);
+
+	locplayerstate->keys = 0xF;
+	DrawKeys (false);
+	HealPlayer (99, player);
+
+   /*
+   player->flags |= FL_BPV;
+	player->flags &= ~(FL_GASMASK|FL_AV);
+	locplayerstate->protectiontime = POWERUPTICS;
+   GM_DrawBonus (stat_bulletproof);
+
+	GiveWeapon (player,wp_mp40);
+   */
+
+#if (SHAREWARE == 0)
+   CheatSpawnItem(stat_splitmissile);
+#else
+   CheatSpawnItem(stat_heatseeker);
+#endif
+
+
+}
+
+/*
+================
+=
+= KillPlayer
+=
+================
+*/
+
+void KillPlayer ()
+{
+   AddMessage ("Say Goodnight.", MSG_CHEAT);
+	playstate = ex_died;
+}
+
+
+
+/*
+================
+=
+= RestartCurrentLevel
+=
+================
+*/
+
+void RestartCurrentLevel (void)
+{
+	playstate         = ex_warped;
+	
+	GetEpisode (gamestate.mapon);
+}
+
+/*
+================
+=
+= EndDemo
+=
+================
+*/
+void EndDemo ( void )
+{
+	char str[10];
+	boolean esc;
+	int demonumber;
+
+   if (demorecord==false)
+      return;
+
+   ShutdownClientControls();
+
+   CurrentFont = smallfont;
+
+   demorecord = false;
+   US_CenterWindow (26, 4);
+   US_CPrint ("Save demo as:");
+   US_Print  ("\n");
+	US_CPrint ("Demo Number (1-4):");
+
+   VW_UpdateScreen();
+
+   esc = !US_LineInput (px, py, str, NULL, true, 1, 25, 13);
+
+   if (!esc)
+   {
+      demonumber = ParseNum (str);
+      if ((demonumber > 0) && (demonumber < 5))
+      {
+         SaveDemo (demonumber);
+      }
+   }
+
+   IN_ClearKeysDown ();
+
+   while (Keyboard[sc_Enter])
+      IN_UpdateKeyboard ();
+   while (Keyboard[sc_Escape])
+      IN_UpdateKeyboard ();
+	IN_ClearKeyboardQueue ();
+
+   StartupClientControls();
+   DisableScreenStretch();
+}
+
+
+/*
+================
+=
+= RecordDemoQuery
+=
+================
+*/
+void RecordDemoQuery ( void )
+{
+   char str[10];
+	boolean esc;
+	int level;
+
+   ShutdownClientControls();
+
+   CurrentFont = smallfont;
+
+   US_CenterWindow (26, 5);
+   PrintY += 6;
+
+   US_CPrint ("Record Demo");
+   US_Print  ("\n");
+#if (SHAREWARE==0)
+   US_CPrint ("Which level (1-36):");
+#else
+   US_CPrint ("Which level (1-8):");
+#endif
+
+   VW_UpdateScreen();
+
+   esc = !US_LineInput (px, py, str, NULL, true, 2, 25, 13);
+
+   if (!esc)
+      {
+      level = ParseNum (str);
+#if (SHAREWARE==0)
+      if ((level > 0) && (level < 37))
+#else
+      if ((level > 0) && (level < 9))
+#endif
+         {
+			EnableScreenStretch();//bna
+			 gamestate.mapon = level-1;
+			 playstate = ex_demorecord;
+         }
+      }
+
+   while (Keyboard[sc_Enter])
+      IN_UpdateKeyboard ();
+   while (Keyboard[sc_Escape])
+      IN_UpdateKeyboard ();
+   IN_ClearKeyboardQueue ();
+
+   StartupClientControls();
+}
+
+/*
+================
+=
+= PlaybackDemoQuery
+=
+================
+*/
+void PlaybackDemoQuery ( void )
+{
+   char str[10];
+	boolean esc;
+	int level;
+
+   ShutdownClientControls();
+
+   CurrentFont = smallfont;
+   US_CenterWindow (33, 4);
+   US_CPrint ("Playback demo");
+   US_Print ("\n");
+   US_CPrint ("Enter demo number (1-4):");
+
+   VW_UpdateScreen ();
+
+   esc = !US_LineInput (px, py, str, NULL, true, 1, 25, 13);
+
+   if (!esc)
+   {
+      level = ParseNum (str);
+      if ((level > 0) && (level < 5))
+         {
+         if (DemoExists (level) == true)
+            LoadDemo (level);
+         }
+   }
+
+   while (Keyboard[sc_Enter])
+      IN_UpdateKeyboard ();
+   while (Keyboard[sc_Escape])
+      IN_UpdateKeyboard ();
+   IN_ClearKeyboardQueue ();
+
+   StartupClientControls();
+
+   EnableScreenStretch();
+}
+
+/*
+================
+=
+= DebugKeys
+=
+================
+*/
+
+int DebugKeys (void)
+{
+#if (DEVELOPMENT == 1)
+	char str[10];
+	boolean esc;
+	int level;
+	int i,f,temp;
+	static int whichpowerup    = 0;
+	static int whichprotection = 0;
+
+	if (Keyboard[sc_G])     // G = god mode
+	{
+      DoGodMode ();
+      while (Keyboard[sc_G])
+         IN_UpdateKeyboard ();
+      return 1;
+	}
+   else if (Keyboard[sc_Q])         // Q = fast quit
+      QuitGame ();
+   else if (Keyboard[sc_W])         // W = warp to level
+   {
+      DoWarp ();
+      return 1;
+   }
+	else if (Keyboard[sc_F])     // F = FPS
+	{
+		f=0;
+		for (i=0;i<VBLCOUNTER*10;i+=tics)
+			{
+			ThreeDRefresh();
+			DoSprites();
+			CalcTics ();
+			f++;
+			}
+
+		CurrentFont = smallfont;
+
+		US_CenterWindow (12,2);
+		temp=f*10;
+		SoftError("fps  = %2ld.%2ld\n",temp/100,temp%100);
+
+		US_Print ("FPS=");
+		US_PrintUnsigned (temp/100);
+		US_Print (".");
+		US_PrintUnsigned (temp%100);
+
+		VW_UpdateScreen();
+		IN_Ack();
+
+		return 1;
+	}
+	else if (Keyboard[sc_H])     // H = hurt self
+	{
+		IN_ClearKeysDown ();
+		HurtPlayer ();
+	}
+	else if (Keyboard[sc_Z])     // Z = end level
+	{
+      EndLevel ();
+	}
+	else if (Keyboard[sc_P])     // P = step through powerups
+	{
+		whichpowerup++;
+		if (whichpowerup == 6)
+			whichpowerup = 0;
+
+		switch (whichpowerup)
+		{
+			case 0:  // nothing
+				if (player->flags & FL_ELASTO)
+					player->flags &= ~FL_NOFRICTION;
+				player->flags &= ~(FL_SHROOMS|FL_ELASTO|FL_FLEET|FL_GODMODE|FL_DOGMODE);
+				locplayerstate->poweruptime = 0;
+				GM_UpdateBonus (0, true);
+			break;
+
+			case 1:  // god mode
+            DoGodModePowerup ();
+			break;
+
+			case 2:  // dog mode
+            DoDogModePowerup ();
+			break;
+
+			case 3:  // fleet feet
+            DoMercuryModePowerup ();
+			break;
+
+			case 4:  // elasto
+            DoElastoModePowerup ();
+			break;
+
+			case 5:  // shrooms
+            DoShroomsModePowerup ();
+			break;
+		}
+
+		while (Keyboard[sc_P])
+			IN_UpdateKeyboard ();
+	}
+	else if (Keyboard[sc_A])     // step through armor
+	{
+		whichprotection++;
+		if (whichprotection == 4)
+			whichprotection = 0;
+
+		switch (whichprotection)
+      {
+         case 0:  // nothing
+            player->flags &= ~(FL_BPV|FL_AV|FL_GASMASK);
+				locplayerstate->protectiontime = 0;
+            GM_UpdateBonus (0, false);
+         break;
+
+         case 1:  // gas mask
+            GiveGasMask ();
+         break;
+
+         case 2:  // armor
+            GiveBulletProofArmor ();
+         break;
+
+         case 3:  // fire vest
+            GiveAsbestoArmor ();
+         break;
+      }
+
+      while (Keyboard[sc_A])
+         IN_UpdateKeyboard ();
+   }
+   else if (Keyboard[sc_O])     // O = outfit player
+   {
+      OutfitPlayer ();
+
+		IN_ClearKeysDown ();
+		IN_Ack ();
+		return 1;
+	}
+	else if (Keyboard[sc_K])     // K = kill self
+	{
+		IN_ClearKeysDown ();
+      locplayerstate->lives = -1;
+      KillPlayer ();
+	}
+	else if (Keyboard[sc_I])        // I = item cheat
+	{
+      DoItemCheat ();
+		return 1;
+	}
+	else if (Keyboard[53])        // \ = back to normal
+	{
+      DoNormalThing ();
+      return 1;
+   }
+   else if (Keyboard[sc_R])
+   {
+      RecordDemoQuery();
+   }
+   else if (Keyboard[sc_E])
+   {
+      EndDemo();
+   }
+   else if (Keyboard[sc_D])
+   {
+      PlaybackDemoQuery();
+   }
+#endif
+   return (0);
+}
+
+
+/*
+================
+=
+= WeaponCheat
+=
+================
+*/
+
+void WeaponCheat (int weapon)
+   {
+   if ((player->flags & FL_GODMODE) || (player->flags & FL_DOGMODE))
+      return;
+
+   if ((weapon <= wp_mp40) && (PLAYERSTATE[0].HASBULLETWEAPON[weapon]))
+      return;
+
+   CheatSpawnItem(GetItemForWeapon(weapon));
+
+   }
+
+
+
+/*
+================
+=
+= CheckCode ()
+=
+================
+*/
+
+
+
+void CheckCode (int which)
+{
+   int pos = (LastLetter-1)&(MAXLETTERS-1);
+   int num = 0;
+   int start;
+
+   start = pos;
+
+   while ((toupper(LetterQueue[pos]) == Codes[which].code[num]) &&
+          (num < Codes[which].length))
+   {
+      pos = (pos-1)&(MAXLETTERS-1);
+      num++;
+   }
+
+	if (num == Codes[which].length)
+   {
+      // Kill last letter so the debug rtn will not keep triggering
+      LetterQueue[start] = 0;
+
+      switch (which)
+      {
+         case ENABLECHEAT:
+         case ENABLECHEATALT:
+            EnableCheatCodes ();
+         break;
+
+         case INVULNERABLE:
+         case INVULNERABLEALT:
+            DoGodMode ();
+         break;
+
+         case WARP:
+         case WARPALT:
+            DoWarp ();
+         break;
+
+         case ITEMS:
+         case ITEMSALT:
+            DoItemCheat ();
+         break;
+
+         case SOMEITEMS:
+         case SOMEITEMSALT:
+            DoSomeItemCheat ();
+         break;
+
+			case GODMODEPWUP:
+			case GODMODEPWUPALT:
+            DoGodModePowerup ();
+         break;
+
+#if (SHAREWARE == 0)
+         case DOGMODEPWUP:
+         case DOGMODEPWUPALT:
+            DoDogModePowerup ();
+         break;
+#endif
+
+         case MERCURYPWUP:
+         case MERCURYPWUPALT:
+            DoMercuryModePowerup ();
+         break;
+
+         case SHROOMSPWUP:
+			case SHROOMSPWUPALT:
+            DoShroomsModePowerup ();
+         break;
+
+         case ELASTOPWUP:
+         case ELASTOPWUPALT:
+            DoElastoModePowerup ();
+         break;
+
+         case RESTARTGAME:
+         case RESTARTGAMEALT:
+            RestartNormal ();
+         break;
+
+         case HURTPLAYER:
+         case HURTPLAYERALT:
+               HurtPlayer ();
+         break;
+
+         case TOMHALLMODE:
+         case TOMHALLMODEALT:
+            gamestate.autorun = true;
+            AddMessage("Autorun enabled!",MSG_CHEAT);
+         break;
+
+         case NORMAL:
+         case NORMALALT:
+            DoNormalThing ();
+         break;
+
+         case LIGHTDIMON:
+         case LIGHTDIMONALT:
+            SetLightDiminish (false);
+         break;
+
+         case LIGHTDIMOFF:
+         case LIGHTDIMOFFALT:
+            SetLightDiminish (true);
+         break;
+
+         case FOGON:
+         case FOGONALT:
+            SetFog (true);
+         break;
+
+			case FOGOFF:
+         case FOGOFFALT:
+            SetFog (false);
+         break;
+
+         case QUITGAME:
+         case QUITGAMEALT:
+            QuitGame ();
+         break;
+
+         case ENDLEVEL:
+         case ENDLEVELALT:
+				EndLevel ();
+         break;
+
+         case FANDCOFF:
+         case FANDCOFFALT:
+            FloorandCeiling (false);
+         break;
+
+         case FANDCON:
+         case FANDCONALT:
+            FloorandCeiling (true);
+         break;
+
+
+         case AIMCROSS:
+         case AIMCROSSALT:
+            if (iG_aimCross == 0) {
+			    iG_aimCross = 1;
+				AddMessage("Crosshair on",MSG_GAME);
+			}else{
+				iG_aimCross = 0;
+				AddMessage("Crosshair off",MSG_GAME);
+			}
+         break;
+
+
+         case BULLETARMOR:
+         case BULLETARMORALT:
+            GiveBulletProofArmor ();
+         break;
+
+         case FIREARMOR:
+         case FIREARMORALT:
+            GiveAsbestoArmor ();
+			break;
+
+         case GASMASK:
+         case GASMASKALT:
+            GiveGasMask ();
+         break;
+
+         case OUTFIT:
+         case OUTFITALT:
+            OutfitPlayer ();
+         break;
+
+         case KILLPLAYER:
+         case KILLPLAYERALT:
+            KillPlayer ();
+         break;
+
+         case RESTARTLEVEL:
+         case RESTARTLEVELALT:
+				RestartCurrentLevel ();
+			break;
+
+
+         case WEAPONTWOPISTOL:
+         case WEAPONTWOPISTOLALT:
+             WeaponCheat(wp_twopistol);
+             break;
+
+         case WEAPONMP40:
+         case WEAPONMP40ALT:
+             WeaponCheat(wp_mp40);
+             break;
+
+         case WEAPONBAZOOKA:
+         case WEAPONBAZOOKAALT:
+             WeaponCheat(wp_bazooka);
+             break;
+         case WEAPONFIREBOMB:
+         case WEAPONFIREBOMBALT:
+             WeaponCheat(wp_firebomb);
+             break;
+
+         case WEAPONHEAT:
+         case WEAPONHEATALT:
+             WeaponCheat(wp_heatseeker);
+             break;
+
+         case WEAPONDRUNK:
+         case WEAPONDRUNKALT:
+             WeaponCheat(wp_drunk);
+             break;
+
+         case WEAPONFIREWALL:
+         case WEAPONFIREWALLALT:
+             WeaponCheat(wp_firewall);
+             break;
+
+         case WEAPONGOD:
+         case WEAPONGODALT:
+             WeaponCheat(wp_godhand);
+             break;
+
+
+#if (SHAREWARE == 0)
+
+         case WEAPONSPLIT:
+         case WEAPONSPLITALT:
+             WeaponCheat(wp_split);
+             break;
+
+         case WEAPONKES:
+         case WEAPONKESALT:
+             WeaponCheat(wp_kes);
+             break;
+
+         case WEAPONBAT:
+         case WEAPONBATALT:
+             WeaponCheat(wp_bat);
+             break;
+
+         case WEAPONDOG:
+         case WEAPONDOGALT:
+             WeaponCheat(wp_dog);
+             break;
+#endif
+
+         case MISSILECAMTOGGLE:
+         case MISSILECAMTOGGLEALT:
+             ToggleMissileCam();
+             break;
+
+         case HUDTOGGLE:
+         case HUDTOGGLEALT:
+             ToggleHUD();
+             break;
+
+         case ROTATIONFUN:
+            ShutdownClientControls();
+            RotationFun();
+            StartupClientControls();
+            SetupScreen( true );
+            break;
+         case DEMORECORD:
+            RecordDemoQuery();
+            break;
+         case DEMOEND:
+            EndDemo();
+            break;
+         case DEMOPLAYBACK:
+            PlaybackDemoQuery();
+            break;
+         case CRAZYGIBS:
+            if (gamestate.violence == vl_excessive)
+               {
+
+               ludicrousgibs ^= 1;
+               if (ludicrousgibs == true)
+                  AddMessage("EKG mode on!",MSG_GAME);
+               else
+                  AddMessage("EKG mode off!",MSG_GAME);
+               }
+            break;
+
+         case JUKEBOX:
+         case JUKEBOXALT:
+            DoJukeBox();
+         break;
+         case MAPCHEAT:
+         case MAPCHEATALT:
+            DoMapCheat();
+         break;
+      }
+   }
+}
+
+
+/*
+================
+=
+= CheckDebug ()
+=
+================
+*/
+
+void CheckDebug (void)
+{
+	int which;
+	if (DebugOk == false)
+		{
+      CheckCode (0);      // Check for Debug switch only
+      CheckCode (1);      // Check for Debug switch only
+      CheckCode (2);      // Check for Slacker pack
+      CheckCode (3);      // Check for Slacker pack
+      }
+	else
+      {
+      if (demoplayback==true)
+         {
+         return;
+         }
+      else if (demorecord==true)
+         {
+         CheckCode (DEMORECORD);
+         CheckCode (DEMOEND);
+         }
+      else
+         {
+         for (which = 0; which < MAXCODES; which++) // Check all debug codes
+            CheckCode (which);
+         }
+      }
+}

Added: tags/rott-1.1/rott/rt_debug.h
===================================================================
--- tags/rott-1.1/rott/rt_debug.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_debug.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,34 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_debug_public
+#define _rt_debug_public
+
+//***************************************************************************
+//
+// RT_DEBUG.C
+//
+//***************************************************************************
+
+void ResetCheatCodes (void);
+int  DebugKeys (void);
+void CheckDebug (void);
+void EndDemo ( void );
+
+#endif

Added: tags/rott-1.1/rott/rt_def.h
===================================================================
--- tags/rott-1.1/rott/rt_def.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_def.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,544 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_def_public
+#define _rt_def_public
+
+
+// RT_DEF.H Zee big one
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "develop.h"
+#define SAVE_SCREEN  1
+
+#if PLATFORM_UNIX
+#include <unistd.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <dirent.h>
+#include <ctype.h>
+#endif
+
+#if (defined _MSC_VER)
+/* __int64 is built in. */
+#include <malloc.h>
+#include <fcntl.h>
+#include <io.h>
+//#define alloca(x) _alloca(x)
+#define access(x, y) _access(x, y)
+#define F_OK  0
+#elif (defined __GNUC__)
+#define __int64 long long
+#else
+#error please define your platform.
+#endif
+
+#if PLATFORM_DOS || PLATFORM_WIN32
+#define PATH_SEP_CHAR '\\'
+#define PATH_SEP_STR  "\\"
+#elif PLATFORM_UNIX
+#define PATH_SEP_CHAR '/'
+#define PATH_SEP_STR  "/"
+#define ROOTDIR       "/"
+#define CURDIR        "./"
+#elif PLATFORM_MACCLASSIC
+#define PATH_SEP_CHAR ':'
+#define PATH_SEP_STR  ":"
+#else
+#error please define your platform.
+#endif
+
+#if (!defined MAX_PATH)
+  #if (defined MAXPATHLEN)
+    #define MAX_PATH MAXPATHLEN
+  #elif (defined PATH_MAX)
+    #define MAX_PATH PATH_MAX
+  #else
+    #define MAX_PATH 256
+  #endif
+#endif
+
+//
+//
+//
+//***************************************************************************
+//
+//    Global Constants
+//
+//***************************************************************************
+
+#ifndef DATADIR
+#define DATADIR	""
+#endif
+
+#undef PI
+#undef M_PI
+
+#ifndef NULL
+#define NULL       0
+#endif
+
+#define PI      3.141592657
+#define LONG(a) ((int)a)
+#define M_PI            3.14159
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#ifndef O_TEXT
+#define O_TEXT 0
+#endif
+
+#ifndef min
+#define min(a, b)  (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef max
+#define max(a, b)  (((a) > (b)) ? (a) : (b))
+#endif
+
+#if !PLATFORM_DOS
+  #if PLATFORM_WIN32
+    #define strcmpi(x, y) stricmp(x, y)
+    #define _fstricmp(x, y) stricmp(x, y)
+  #elif PLATFORM_UNIX
+    #ifndef strcmpi
+      #define strcmpi(x, y) strcasecmp(x, y)
+    #endif
+
+    #ifndef stricmp
+      #define stricmp(x, y) strcasecmp(x, y)
+    #endif
+
+    #ifndef _fstricmp
+      #define _fstricmp(x, y) strcasecmp(x, y)
+    #endif
+
+    char *strupr(char *);
+    char *itoa(int, char *, int);
+    char *ltoa(long, char *, int);
+    char *ultoa(unsigned long, char *, int);
+    char getch(void);
+    long filelength(int handle);
+  #else
+    #error please define for your platform.
+  #endif
+
+#if !defined(ANSIESC)
+#define STUB_FUNCTION fprintf(stderr,"STUB: %s at " __FILE__ ", line %d, thread %d\n",__FUNCTION__,__LINE__,getpid())
+#else
+#define STUB_FUNCTION
+#endif
+
+#define far
+#define cdecl
+#endif
+
+//***************************************************************************
+//
+//    Screen Constants
+//
+//***************************************************************************
+#define VIEWGLOBAL              0x10000         // globals visable flush to wall
+/*
+#define VIEWWIDTH               MAXSCREENWIDTH//320*2             // size of view window
+#define VIEWHEIGHT              MAXSCREENHEIGHT//200*2
+#define MAXSCANLINES            MAXSCREENHEIGHT//200*2             // size of ylookup table
+*/
+#define CHARWIDTH               2
+#define TILEWIDTH               4
+#define STATUSLINES             16
+
+
+
+//***************************************************************************
+//
+//    Engine Constants
+//
+//***************************************************************************
+
+#define ANGLES                            2048 // must be divisible by 4
+#define ANGLEQUAD                         (ANGLES/4)
+#define FINEANGLES                        2048
+#define FINEANGLEQUAD                     (FINEANGLES/4)
+#define ANG90                             (FINEANGLES/4)
+#define ANG180                            (ANG90*2)
+#define ANG270                            (ANG90*3)
+#define ANG360                            (ANG90*4)
+#define VANG90                            (ANGLES/4)
+#define VANG180                           (VANG90*2)
+#define VANG270                           (VANG90*3)
+#define VANG360                           (VANG90*4)
+#define ANGLESDIV8                        (ANGLES/8)
+#define MINDIST                           (0x5800l)
+#define PIXRADIUS                         512
+#define FOCALLENGTH                       (0x5700l)             // in global coordinates
+#define MAXTICS                           10
+
+//***************************************************************************
+//
+//    Map Constants/ macros
+//
+//***************************************************************************
+
+
+#define GLOBAL1                           (1l<<16)
+#define TILEGLOBAL                        GLOBAL1
+#define PIXGLOBAL                         (GLOBAL1/64)
+#define TILESHIFT                         16l
+#define UNSIGNEDSHIFT                     8
+#define PLAYERSIZE                        0x5700l                       // player radius
+#define MAPSIZE                           128                         // maps are 64*64 max
+#define NUMAREAS                          47
+#define MAPSPOT(x,y,plane)                (mapplanes[plane][MAPSIZE*(y)+(x)])
+#define AREATILE                          107
+#define ICONARROWS                        72
+#define PUSHABLETILE                      80
+#define ELEVATORTILE                      72
+#define ALTELEVATORTILE                   106
+#define LASTLEVELVALUE                    459
+
+#define AREANUMBER(x,y)                   (MAPSPOT((x),(y),0)-AREATILE)
+
+//***************************************************************************
+//
+//    Scale Constants
+//
+//***************************************************************************
+
+#define SFRACBITS 16
+#define SFRACUNIT (0x10000)
+#define FRACUNIT (0x100)
+
+//***************************************************************************
+//
+//    Actor Constants
+//
+//***************************************************************************
+
+#define RUNSPEED                6000
+#define MINACTORDIST            0x9000l
+#define MAXSTATS                400                           // max number of lamps, bonus, etc
+
+#define MAXWALLTILES            105          // max number of wall tiles
+#define MAXACTORS               600
+#define NORTH                   0
+#define EAST                    1
+#define SOUTH                   2
+#define WEST                    3
+
+//***************************************************************************
+//
+//    Input Defines - joystick, keyboard and mouse
+//
+//***************************************************************************
+
+#define MaxJoys            2
+#define MaxKbds            2
+#define MaxJoys            2
+#define NumCodes           128
+
+// Key definitions
+
+#define  key_None    0
+#define  key_Return     0x0d
+#define  key_Enter      key_Return
+#define  key_Escape     0x1b
+#define  key_Space      0x20
+#define  key_BackSpace  0x08
+#define  key_Tab        0x09
+#define  key_Delete     0x7f
+
+#define  ANGLEBITS      16
+#define  ANGLEFRACMAX   (FINEANGLES<<ANGLEBITS)
+
+
+//***************************************************************************
+//
+//    SWIFT Constants
+//
+//***************************************************************************
+
+//
+// device type codes, returned in deviceType field (SWIFT_StaticData)
+//
+#define SWIFT_DEV_NONE		0
+#define SWIFT_DEV_CYBERMAN	1
+
+//
+// Dynamic device data
+//
+#define SDD_EXTERNAL_POWER_CONNECTED	1
+#define SDD_EXTERNAL_POWER_TOO_HIGH	   2
+
+#define AX(r) ((r).x.eax)
+#define BX(r) ((r).x.ebx)
+#define CX(r) ((r).x.ecx)
+#define DX(r) ((r).x.edx)
+#define SI(r) ((r).x.esi)
+#define DI(r) ((r).x.edi)
+
+//***************************************************************************
+//
+//    Global Types
+//
+//***************************************************************************
+
+///////////////////      GLOBAL DATA TYPES ///////////////////////////////
+
+
+typedef unsigned char           byte;
+typedef unsigned short int      word;
+typedef unsigned int            longword;
+typedef int fixed;
+
+
+//////////////////////////////////////////////////////////////////////////
+
+
+//////////////////      GLOBAL ENUMERATED TYPES    ///////////////////////
+
+#ifdef __WATCOMC__
+typedef enum
+ {false,
+  true
+ }
+ boolean;
+#else
+/* boolean is serialized at the moment, and watcomc made it a byte. */
+
+typedef unsigned char boolean;
+enum {
+  false, true
+};
+#endif
+
+
+
+
+typedef enum {
+		  east,
+		  northeast,
+		  north,
+		  northwest,
+		  west,
+		  southwest,
+		  south,
+		  southeast,
+		  nodir
+} dirtype;
+
+typedef enum
+ {SPRITE,
+  WALL,
+  ACTOR,
+  DOOR,
+  PWALL,
+  MWALL
+ }
+ thingtype;
+
+#define NUMTXBUTTONS    16
+enum    {
+		  bt_nobutton=-1,
+		  bt_attack=0,
+		  bt_strafe=1,
+		  bt_run=2,
+		  bt_use=3,
+		  bt_lookup=4,
+		  bt_lookdown=5,
+		  bt_swapweapon=6,
+		  bt_dropweapon=7,
+		  bt_horizonup=8,
+        bt_horizondown=9,
+        bt_pistol=10,
+        bt_dualpistol=11,
+        bt_mp40=12,
+        bt_missileweapon=13,
+        bt_autorun=14,
+		  bt_recordsound=15,
+		  bt_strafeleft=16,
+		  bt_straferight=17,
+        bt_turnaround=18,
+        bt_aimbutton=19,
+        di_north=20,
+        di_east=21,
+        di_south=22,
+        di_west=23,
+        bt_map=24,
+        bt_message=25,
+        bt_directmsg=26,
+        NUMBUTTONS
+};
+
+
+#if (SHAREWARE == 0)
+ #define MAXWEAPONS  13
+#else
+ #define MAXWEAPONS  9
+#endif
+
+
+typedef enum    { wp_pistol,
+						wp_twopistol,
+						wp_mp40,
+						wp_bazooka,
+						wp_heatseeker,
+                  wp_drunk,
+                  wp_firebomb,
+                  wp_firewall,
+						wp_godhand,
+
+#if (SHAREWARE == 0)
+                  wp_split,
+						wp_kes,
+						wp_bat,
+                  wp_dog
+#endif
+
+                } weapontype;
+
+
+
+enum    {
+						gd_baby,
+						gd_easy,
+						gd_medium,
+						gd_hard
+};
+
+
+typedef enum    {
+		  ex_stillplaying,
+		  ex_completed,
+		  ex_died,
+		  ex_warped,
+		  ex_resetgame,
+		  ex_loadedgame,
+		  ex_victorious,
+		  ex_abort,
+		  ex_demodone,
+		  ex_skiplevel,
+		  ex_secretlevel,
+        ex_secretdone,
+        ex_titles,
+		  ex_demorecord,
+		  ex_demoplayback,
+
+		  ex_bossdied,
+		  ex_gameover,
+		  ex_battledone
+} exit_t;
+
+// Types for cache lumps (for endian converters)
+enum    {
+	cache_other,
+	cache_pic_t,
+	cache_lpic_t,
+	cache_font_t,
+	cache_lbm_t,
+	cache_patch_t,
+	cache_transpatch_t,
+	cache_cfont_t
+};
+
+////////////////////////////////////////////////////////////////////////////
+
+/////////////////      GLOBAL STRUCTURE TYPES     //////////////////////////
+
+
+//=================== SHARED FLAGS =====================================//
+
+#define FL_SHOOTABLE            0x01
+#define FL_ACTIVE               0x02
+#define FL_VISIBLE              0x08
+#define FL_NOFRICTION           0x100 //
+#define FL_DYING                0x1000
+#define FL_ALTERNATE            0x20000
+#define FL_GODSTRUCK            0x80000
+#define FL_ABP                  0x400000
+#define FL_BLOCK                0x800000
+#define FL_HBM                  0x1000000
+#define FL_RIDING               0x2000000
+#define FL_SOLIDCOLOR           0x4000000
+#define FL_SEEN                 0x8000000
+#define FL_COLORED              0x10000000
+#define FL_FULLLIGHT       0x80000000
+
+//=================== ACTOR FLAGS =====================================//
+
+#define FL_NEVERMARK            4
+#define FL_ATTACKMODE           0x10
+#define FL_FIRSTATTACK          0x20
+#define FL_ISFIRE               0x20
+#define FL_AMBUSH               0x40
+#define FL_NONMARK              0x80
+#define FL_DONE                 0x200 // used by push column
+#define FL_DODGE                0x400 // "
+#define FL_STUCK                0x800 //
+#define FL_HASAUTO              0x2000
+#define FL_FALLINGOBJECT        0x4000
+#define FL_KEYACTOR             0x8000
+#define FL_HEAD                 0x40000
+#define FL_TARGET               0x200000
+#define FL_FLIPPED              0x40000000
+#define FL_CRAZY                0x40000000
+
+
+//================== PLAYER FLAGS ======================================//
+
+#define FL_BPV                  0x10
+#define FL_SHROOMS              0x20
+#define FL_AV                   0x40
+#define FL_ELASTO               0x200
+#define FL_FLEET                0x400
+#define FL_PUSHED               0x2000
+#define FL_PAIN                 0x4000
+#define FL_GODMODE              0x8000
+#define FL_DOGMODE              0x10000
+#define FL_GASMASK              0x100000
+#define FL_DESIGNATED           0x20000000
+#define FL_DIDTAG               0x40000000
+
+//================== SPRITE FLAGS ======================================//
+
+#define NOTHING                 -1
+#define FL_BONUS                0x04
+#define FL_LIGHT                0x20
+#define FL_CHANGES              0x40
+#define FL_BACKWARDS            0x100
+#define FL_BANDF                0x200
+#define FL_HEAT                 0x400
+#define FL_LIGHTOFF             0x800
+#define FL_ACTOR                0x1000
+#define FL_ROTATING             0x2000
+#define FL_RESPAWN              0x4000
+#define FL_WOODEN               0x8000
+#define FL_METALLIC             0x10000
+#define FL_EARTHEN              0x20000
+#define FL_LIGHTON              0x40000
+#define FL_FADING               0x80000
+#define FL_DEADBODY             0x100000
+#define FL_WEAPON               0x200000
+#define FL_TRANSLUCENT          0x2000000
+#define FL_HEIGHTFLIPPABLE      0x40000000
+
+#endif

Added: tags/rott-1.1/rott/rt_dmand.c
===================================================================
--- tags/rott-1.1/rott/rt_dmand.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_dmand.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,400 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#ifdef DOS
+#include <mem.h>
+#endif
+
+#include "rt_def.h"
+#include "rt_util.h"
+#include "rt_sound.h"
+#include "rt_net.h"
+#include "rt_dmand.h"
+#include "_rt_dman.h"
+#include "fx_man.h"
+#include "develop.h"
+//MED
+#include "memcheck.h"
+
+static boolean Recording=false;
+static boolean Feeder=false;
+static byte * RecordingBuffer;
+static int Playingvoice;
+static int RecordingPointer;
+static int FeederPointer;
+static boolean Playback=false;
+static boolean Playing=false;
+static byte * PlaybackBuffer;
+static int PlaybackPointer;
+static int PlayingPointer;
+static boolean RecordingSemaphore=false;
+
+//#define FX_StartDemandFeedPlayback MV_StartDemandFeedPlayback
+//#define FX_StartRecording          MV_StartRecording
+//#define FX_StopRecord              MV_StopRecord
+//#include "multivoc.h"
+
+//***************************************************************************
+//
+// SD_UpdatePlaybackSound - Update playback of a sound in chunks
+//
+//***************************************************************************
+void SD_UpdatePlaybackSound ( char ** ptr, unsigned long * length )
+   {
+   if ( Playing==false )
+      {
+      *ptr = NULL;
+      *length = 0;
+      return;
+      }
+   if (PlayingPointer==PlaybackPointer)
+      {
+      *ptr = NULL;
+      *length = 0;
+      if (Playback==false)
+         {
+         FX_StopSound( Playingvoice );
+         SafeFree ( PlaybackBuffer );
+         Playing=false;
+         }
+      return;
+      }
+
+   *length=PLAYBACKDELTASIZE;
+
+   if (PlayingPointer==-1)
+      {
+      *ptr = NULL;
+      *length = 0;
+      return;
+      }
+
+   *ptr=&PlaybackBuffer[PlayingPointer];
+
+   PlayingPointer = (PlayingPointer + *length) &
+                      (PLAYBACKBUFFERSIZE - 1);
+   }
+
+//***************************************************************************
+//
+// SD_StartIncomingSound - Setup to receive an incoming sound in chunks
+//
+//***************************************************************************
+
+void SD_StartIncomingSound ( void )
+{
+   if (SD_Started==false)
+      return;
+   if ( ( Recording==true ) || ( Playback==true ) )
+      {
+      return;
+      }
+
+   Playback=true;
+   PlaybackBuffer = SafeMalloc (PLAYBACKBUFFERSIZE);
+   Playing = false;
+   PlayingPointer = -1;
+   PlaybackPointer = 0;
+
+   Playingvoice = FX_StartDemandFeedPlayback ( SD_UpdatePlaybackSound,
+                  RECORDINGSAMPLERATE,
+                  0, 255, 255, 255, 255, -1);
+   if (Playingvoice==0)
+      {
+      SafeFree(PlaybackBuffer);
+      Playback=false;
+      }
+}
+
+//***************************************************************************
+//
+// SD_StopIncomingSound - Stop receiving an incoming sound and playback
+//
+//***************************************************************************
+
+void SD_StopIncomingSound ( void )
+{
+   if (SD_Started==false)
+      return;
+   Playback=false;
+}
+
+
+//***************************************************************************
+//
+// SD_UpdateIncomingSound - Update an incoming sound
+//
+//***************************************************************************
+
+void SD_UpdateIncomingSound ( byte * ptr, word length )
+{
+   int amount;
+
+   if (SD_Started==false)
+      return;
+
+   if ( Playback==false )
+      {
+      return;
+      }
+   amount=length;
+   if (PlaybackPointer+length > PLAYBACKBUFFERSIZE)
+      amount=PLAYBACKBUFFERSIZE-PlaybackPointer;
+   memcpy ( &PlaybackBuffer[PlaybackPointer],
+            ptr, amount);
+   PlaybackPointer = (PlaybackPointer + amount) &
+                      (PLAYBACKBUFFERSIZE - 1);
+
+   ptr+=amount;
+
+   if (length!=amount)
+      {
+      amount=length-amount;
+      memcpy ( &PlaybackBuffer[PlaybackPointer],
+               ptr, amount);
+      PlaybackPointer = (PlaybackPointer + amount) &
+                         (PLAYBACKBUFFERSIZE - 1);
+      }
+
+   if (PlayingPointer==-1)
+      {
+      Playing=true;
+      PlayingPointer=0;
+      }
+   if (PlaybackPointer==PlayingPointer)
+      {
+      Playback=false;
+      }
+}
+
+//***************************************************************************
+//
+// SD_UpdateRecordingSound - Update recording a sound in chunks
+//
+//***************************************************************************
+extern int whereami;
+void SD_UpdateRecordingSound ( char * ptr, int length )
+   {
+   int amount;
+
+   whereami = 69;
+   if ( Recording==false )
+      {
+      return;
+      }
+   whereami = 70;
+   amount=length;
+   if (RecordingPointer+length > RECORDINGBUFFERSIZE)
+      amount=RECORDINGBUFFERSIZE-RecordingPointer;
+   memcpy ( &RecordingBuffer[RecordingPointer],
+            ptr, amount);
+   whereami = 71;
+   RecordingPointer = (RecordingPointer + amount) &
+                      (RECORDINGBUFFERSIZE - 1);
+
+   if (length!=amount)
+      {
+      ptr += amount;
+      amount=length-amount;
+      memcpy ( &RecordingBuffer[RecordingPointer],
+               ptr, amount);
+      RecordingPointer = (RecordingPointer + amount) &
+                         (RECORDINGBUFFERSIZE - 1);
+      }
+   whereami = 72;
+   if (Feeder == false)
+      {
+      Feeder = true;
+      }
+
+   whereami = 73;
+   if (RecordingPointer==FeederPointer)
+      {
+      Recording=false;
+      }
+   whereami = 74;
+   }
+
+//***************************************************************************
+//
+// SD_StartRecordingSound - Start recording a sound in chunks
+//
+//***************************************************************************
+
+boolean SD_StartRecordingSound ( void )
+{
+   int status;
+
+   if (SD_Started==false)
+      return false;
+   if (remoteridicule == false)
+      return false;
+   if ( ( Recording==true ) || ( Playback==true ) || (Feeder==true))
+      {
+      return false;
+      }
+   Recording=true;
+   RecordingBuffer = SafeMalloc (RECORDINGBUFFERSIZE);
+   Feeder = false;
+   FeederPointer = -1;
+   RecordingPointer = 0;
+
+   status=FX_StartRecording( RECORDINGSAMPLERATE, SD_UpdateRecordingSound);
+
+   if (status!=FX_Ok)
+      {
+      Recording=false;
+      SafeFree(RecordingBuffer);
+      return false;
+      }
+
+   return true;
+}
+
+//***************************************************************************
+//
+// SD_StopRecordingSound - Stop recording a sound
+//
+//***************************************************************************
+
+void SD_StopRecordingSound ( void )
+{
+   if (SD_Started==false)
+      return;
+   if (Recording == true)
+      {
+      FX_StopRecord();
+      Recording=false;
+      }
+}
+
+//***************************************************************************
+//
+// SD_SetRecordingActive - Set the recording active flag
+//
+//***************************************************************************
+
+void SD_SetRecordingActive ( void )
+{
+   RecordingSemaphore=true;
+}
+
+//***************************************************************************
+//
+// SD_ClearRecordingActive - Clear the recording active flag
+//
+//***************************************************************************
+
+void SD_ClearRecordingActive ( void )
+{
+   RecordingSemaphore=false;
+}
+
+//***************************************************************************
+//
+// SD_RecordingActive - Check if recording is active on some system
+//
+//***************************************************************************
+
+boolean SD_RecordingActive ( void )
+{
+   return RecordingSemaphore;
+}
+
+//***************************************************************************
+//
+// SD_GetSoundData - Returns next piece of sound data, returns:
+//
+//                   nodata if no sound data is ready
+//                   newsound if it is the start of a new sound
+//                            data is also returned;
+//                   endsound if the sound is finished
+//                   data if data is ready
+//
+//***************************************************************************
+
+recordstate SD_GetSoundData ( byte * data, word length )
+{
+   recordstate status=rs_data;
+   int amount;
+
+   if (SD_Started==false)
+      return rs_nodata;
+
+   if (Feeder==false)
+      return rs_nodata;
+
+   if (FeederPointer==RecordingPointer)
+      {
+      if (Recording==false)
+         {
+         SafeFree(RecordingBuffer);
+         Feeder=false;
+         return rs_endsound;
+         }
+      else
+         {
+         return rs_nodata;
+         }
+      }
+
+   if (FeederPointer==-1)
+      {
+      status=rs_newsound;
+      FeederPointer=0;
+      }
+
+   amount=length;
+
+   if (FeederPointer+length > RECORDINGBUFFERSIZE)
+      amount=RECORDINGBUFFERSIZE-FeederPointer;
+   memcpy ( data, &RecordingBuffer[FeederPointer], amount);
+
+   FeederPointer = (FeederPointer + amount) &
+                      (RECORDINGBUFFERSIZE - 1);
+
+   data += amount;
+
+   if (length!=amount)
+      {
+      amount=length-amount;
+      memcpy ( data, &RecordingBuffer[FeederPointer], amount);
+      FeederPointer = (FeederPointer + amount) &
+                        (RECORDINGBUFFERSIZE - 1);
+      }
+
+   return status;
+}
+
+//***************************************************************************
+//
+// SD_SoundDataReady - Returns true if data is ready
+//
+//***************************************************************************
+
+boolean SD_SoundDataReady ( void )
+{
+   if (SD_Started==false)
+      return false;
+   return Feeder;
+}
+
+
+

Added: tags/rott-1.1/rott/rt_dmand.h
===================================================================
--- tags/rott-1.1/rott/rt_dmand.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_dmand.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,114 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_dmand_public
+#define _rt_dmand_public
+
+typedef enum {
+   rs_nodata,
+   rs_newsound,
+   rs_endsound,
+   rs_data
+} recordstate;
+
+//***************************************************************************
+//
+// SD_StartIncomingSound - Setup to receive an incoming sound in chunks
+//
+//***************************************************************************
+
+void SD_StartIncomingSound ( void );
+
+//***************************************************************************
+//
+// SD_StopIncomingSound - Stop receiving an incoming sound and playback
+//
+//***************************************************************************
+
+void SD_StopIncomingSound ( void );
+
+//***************************************************************************
+//
+// SD_UpdateIncomingSound - Update an incoming sound
+//
+//***************************************************************************
+
+void SD_UpdateIncomingSound ( byte * data, word length );
+
+//***************************************************************************
+//
+// SD_GetSoundData - Returns next piece of sound data, returns:
+//
+//                   nodata if no sound data is ready
+//                   newsound if it is the start of a new sound
+//                            data is also returned;
+//                   data if data is ready
+//
+//***************************************************************************
+
+recordstate SD_GetSoundData ( byte * data, word length );
+
+//***************************************************************************
+//
+// SD_SoundDataReady - Returns true if data is ready
+//
+//***************************************************************************
+
+boolean SD_SoundDataReady ( void );
+
+//***************************************************************************
+//
+// SD_SetRecordingActive - Set the recording active flag
+//
+//***************************************************************************
+
+void SD_SetRecordingActive ( void );
+
+//***************************************************************************
+//
+// SD_ClearRecordingActive - Clear the recording active flag
+//
+//***************************************************************************
+
+void SD_ClearRecordingActive ( void );
+
+//***************************************************************************
+//
+// SD_RecordingActive - Check if recording is active on some system
+//
+//***************************************************************************
+
+boolean SD_RecordingActive ( void );
+
+//***************************************************************************
+//
+// SD_StartRecordingSound - Start recording a sound in chunks
+//
+//***************************************************************************
+
+boolean SD_StartRecordingSound ( void );
+
+//***************************************************************************
+//
+// SD_StopRecordingSound - Stop recording a sound
+//
+//***************************************************************************
+void SD_StopRecordingSound ( void );
+
+#endif

Added: tags/rott-1.1/rott/rt_door.c
===================================================================
--- tags/rott-1.1/rott/rt_door.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_door.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,4414 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "rt_sound.h"
+#include "rt_door.h"
+#include "rt_actor.h"
+#include "rt_stat.h"
+#include "_rt_door.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "rt_ted.h"
+#include "rt_draw.h"
+#include "rt_main.h"
+#include "rt_playr.h"
+#include "rt_util.h"
+#include "rt_menu.h"
+#include "rt_ted.h"
+#include "rt_msg.h"
+#include "rt_game.h"
+#include "rt_vid.h"
+#include "rt_net.h"
+#include "isr.h"
+#include "develop.h"
+#include "rt_rand.h"
+#include "engine.h"
+#include <stdlib.h>
+#include <string.h>
+//MED
+#include "memcheck.h"
+
+/*=============================================================================
+
+							DOORS
+
+doorobjlist[] holds most of the information for the doors
+
+Open doors conect two areas, so sounds will travel between them and sight
+	will be checked when the player is in a connected area.
+
+Areaconnect is incremented/decremented by each door. If >0 they connect
+
+Every time a door opens or closes the areabyplayer matrix gets recalculated.
+	An area is true if it connects with the player's current spor.
+
+=============================================================================
+*/
+
+
+// Global Variables
+
+
+#define ELEVATORMUSICTIME   560
+
+elevator_t     ELEVATOR[MAXELEVATORS];
+int            _numelevators;
+animmaskedwallobj_t* FIRSTANIMMASKEDWALL,*LASTANIMMASKEDWALL;
+maskedwallobj_t* FIRSTMASKEDWALL,*LASTMASKEDWALL;
+byte             touchindices[MAPSIZE][MAPSIZE],lasttouch;
+touchplatetype   *touchplate[MAXTOUCHPLATES],*lastaction[MAXTOUCHPLATES];
+
+byte             numactions[MAXTOUCHPLATES];
+int              totalactions;
+
+byte             TRIGGER[MAXTOUCHPLATES];
+doorobj_t	   *doorobjlist[MAXDOORS];
+int			   doornum;
+maskedwallobj_t *maskobjlist[MAXMASKED];
+int            maskednum;
+
+pwallobj_t     *pwallobjlist[MAXPWALLS];
+int            pwallnum;
+
+byte	         areaconnect[NUMAREAS][NUMAREAS];
+
+boolean	      areabyplayer[NUMAREAS];
+
+
+// Local Variables
+
+static void (*touchactions[NUMTOUCHPLATEACTIONS])(long) =
+						 {ActivatePushWall,
+						  ActivateMoveWall,
+						  LinkedOpenDoor,
+						  LinkedCloseDoor,
+						  EnableObject,
+						  DisableObject,
+						  ActivateLight,
+						  DeactivateLight};
+
+#if ((DEVELOPMENT == 1))
+#if ((LOADSAVETEST == 1))
+static char*touchstrings[NUMTOUCHPLATEACTIONS] =
+						 {"ActivatePushWall",
+						  "ActivateMoveWall",
+						  "LinkedOpenDoor",
+						  "LinkedCloseDoor",
+						  "EnableObject",
+						  "DisableObject",
+						  "ActivateLight",
+						  "DeactivateLight"
+						 };
+#endif
+#endif
+#if ((DEVELOPMENT == 1))
+#if ((ELEVATORTEST == 1))
+
+static char*elevstring[NUMELEVATORACTIONS] =
+						{"ready at source",
+						 "ready at destination",
+						 "moving to source",
+						 "moving to destination",
+						 "doorclosing"
+						};
+#endif
+#endif
+
+void UtilizeDoor (int door,void (*action)(int));
+void UseDoor (int door);
+void Teleport(elevator_t*eptr,int destination);
+void ConnectPushWall (int pwall);
+void SetupPushWall (int pwall);
+void WallMoving (int pwall);
+int SetNextAction(elevator_t*eptr,int action);
+
+/*
+===============
+=
+= MakeMaskedWallActive
+=
+===============
+*/
+
+void MakeMaskedWallActive(maskedwallobj_t* tmwall)
+ {if (!FIRSTMASKEDWALL)
+	 FIRSTMASKEDWALL	= tmwall;
+  else
+	  {tmwall->prev = LASTMASKEDWALL;
+		LASTMASKEDWALL->next = tmwall;
+	  }
+  LASTMASKEDWALL = tmwall;
+ }
+
+/*
+===============
+=
+= MakeMaskedWallInactive
+=
+===============
+*/
+
+
+void MakeMaskedWallInactive(maskedwallobj_t* tmwall)
+{
+ if (tmwall == LASTMASKEDWALL)
+	LASTMASKEDWALL = tmwall->prev;
+ else
+	tmwall->next->prev = tmwall->prev;
+
+ if (tmwall == FIRSTMASKEDWALL)
+	FIRSTMASKEDWALL = tmwall->next;
+ else
+	tmwall->prev->next = tmwall->next;
+
+ tmwall->prev = NULL;
+ tmwall->next = NULL;
+
+}
+
+
+/*
+===============
+=
+= ActivateAnimMaskedWall
+=
+===============
+*/
+
+void ActivateAnimMaskedWall(animmaskedwallobj_t* amwall)
+{
+   if (!FIRSTANIMMASKEDWALL)
+	   FIRSTANIMMASKEDWALL	= amwall;
+   else
+	   {
+      amwall->prev = LASTANIMMASKEDWALL;
+		LASTANIMMASKEDWALL->next = amwall;
+	   }
+   LASTANIMMASKEDWALL = amwall;
+}
+
+/*
+===============
+=
+= DeactivateAnimMaskedWall
+=
+===============
+*/
+
+
+void DeactivateAnimMaskedWall(animmaskedwallobj_t* amwall)
+{
+ if (amwall == LASTANIMMASKEDWALL)
+	LASTANIMMASKEDWALL = amwall->prev;
+ else
+	amwall->next->prev = amwall->prev;
+
+ if (amwall == FIRSTANIMMASKEDWALL)
+	FIRSTANIMMASKEDWALL = amwall->next;
+ else
+	amwall->prev->next = amwall->next;
+
+ amwall->prev = NULL;
+ amwall->next = NULL;
+
+}
+
+
+int PlatformHeight(int tilex,int tiley)
+   {
+   int platform;
+
+   if (!IsPlatform(tilex,tiley))
+      return nominalheight;
+
+   platform = MAPSPOT(tilex,tiley,2);
+
+   switch(platform)
+      {
+      case 1:
+         return -10;
+      case 4:
+         return nominalheight;
+      case 5:
+      case 6:
+         return nominalheight - 64;
+      case 7:
+         return nominalheight;
+      case 8:
+      case 9:
+         return -10;
+      }
+
+   return -1000;
+   }
+
+void SpawnAnimatedMaskedWall ( int num )
+{
+   animmaskedwallobj_t * temp;
+
+	temp = (animmaskedwallobj_t *)Z_LevelMalloc(sizeof(animmaskedwallobj_t),PU_LEVELSTRUCT,NULL);
+   if (!temp)
+      Error("SpawnAnimatedMaskedWall: Failed on allocation of animated masked wall");
+   temp->num=num;
+   temp->count=AMW_NUMFRAMES;
+   temp->ticcount=AMW_TICCOUNT;
+   temp->next=NULL;
+   temp->prev=NULL;
+   ActivateAnimMaskedWall(temp);
+}
+
+void KillAnimatedMaskedWall ( animmaskedwallobj_t * temp )
+{
+   DeactivateAnimMaskedWall(temp);
+   Z_Free(temp);
+}
+
+
+void DoAnimatedMaskedWalls ( void )
+{
+   boolean done;
+   animmaskedwallobj_t * temp;
+
+   for(temp=FIRSTANIMMASKEDWALL;temp;)
+      {
+      done=false;
+      temp->ticcount-=tics;
+      while (temp->ticcount<0)
+         {
+         temp->ticcount+=AMW_TICCOUNT;
+         temp->count--;
+         maskobjlist[temp->num]->bottomtexture++;
+         if (temp->count==0)
+            {
+            done=true;
+            break;
+            }
+         }
+      if (done==true)
+         {
+         animmaskedwallobj_t * temp2;
+
+         temp2=temp->next;
+         KillAnimatedMaskedWall(temp);
+         temp=temp2;
+         }
+      else
+         temp=temp->next;
+      }
+}
+
+
+int GetIndexForAction(void (*action)(long))
+{int i;
+
+ for(i=0;i<NUMTOUCHPLATEACTIONS;i++)
+  if (action == touchactions[i])
+	 return i;
+
+ Error("Touchplate Action Not Matched");
+ return -1;
+}
+
+
+void SaveTouchPlates(byte ** buffer,int *size)
+{int i,k;
+ byte * tptr;
+ touchplatetype *temp;
+ saved_touch_type dummy;
+
+ *size = sizeof(TRIGGER);
+ *size += sizeof(numactions);
+ *size += sizeof(saved_touch_type)*totalactions;
+
+ *buffer = (byte *)SafeMalloc(*size);
+ tptr = *buffer;
+ memcpy(tptr,&TRIGGER[0],sizeof(TRIGGER));
+ tptr+=sizeof(TRIGGER);
+
+ memcpy(tptr,&numactions[0],sizeof(numactions));
+ tptr+=sizeof(numactions);
+
+ #if ((DEVELOPMENT == 1))
+ #if (LOADSAVETEST == 1)
+	Debug("\n\nSAVE INFO\n");
+	Debug("---------");
+
+	Debug("\n\nTOUCHINDICES\n");
+	Debug("------------\n\n");
+	for(i=0;i<MAPSIZE;i++)
+	 for(j=0;j< MAPSIZE;j++)
+		if (touchindices[i][j])
+		  Debug("\ntouchindices[%3d][%3d]: %d",i,j,touchindices[i][j]);
+
+	Debug("\n\nTRIGGER: ");
+	for(i=0;i<(sizeof(TRIGGER)/sizeof(TRIGGER[0]));i++)
+	  if (TRIGGER[i])
+		 Debug("%1d",TRIGGER[i]);
+	Debug("\n\nNUMACTIONS PER TOUCHPLATE\n");
+	Debug("-------------------------\n\n");
+	for(i=0;i<(sizeof(numactions)/sizeof(numactions[0]));i++)
+	  if (numactions[i])
+	  Debug("\n %2d: %2d",i,numactions[i]);
+ #endif
+ #endif
+
+ for(i=0;i<lasttouch;i++)
+	 {
+    #if ((DEVELOPMENT == 1))
+    #if (LOADSAVETEST == 1)
+	  Debug("\n\nTOUCHPLATE[%2d]\n",i);
+	  Debug("--------------\n\n");
+	 #endif
+	 #endif
+
+	 for(k=0,temp=touchplate[i];temp;k++,temp = temp->nextaction)
+		 {
+		 dummy.tictime = temp->tictime;
+		 dummy.ticcount = temp->ticcount;
+		 dummy.triggered = temp->triggered;
+		 dummy.done = temp->done;
+		 dummy.complete = temp->complete;
+
+		 if (temp->action)
+			dummy.actionindex = GetIndexForAction(temp->action);
+		 else
+			dummy.actionindex = -1;
+
+		 if (temp->swapaction)
+			dummy.swapactionindex = GetIndexForAction(temp->swapaction);
+		 else
+			dummy.swapactionindex = -1;
+		 if ((dummy.actionindex > 5) || (dummy.swapactionindex > 5)) // means whichobj holds pointer to actor
+			{
+			statobj_t *tstat;
+
+			tstat = (statobj_t*)(temp->whichobj);
+			dummy.whichobj = (tstat->whichstat|FL_TSTAT);
+			}
+
+		 else if ((dummy.actionindex > 3) || (dummy.swapactionindex > 3))
+
+			{
+			objtype *tactor;
+
+			tactor = (objtype*)(temp->whichobj);
+			dummy.whichobj = (tactor->whichactor|FL_TACT);
+			}
+
+		 else
+			dummy.whichobj = temp->whichobj;
+
+       #if ((DEVELOPMENT == 1))
+       #if (LOADSAVETEST == 1)
+		  Debug("action node %d: tictime: %d, ticcount: %d ",k,dummy.tictime,dummy.ticcount);
+		  if (dummy.actionindex == -1)
+			 Debug("action: -1,");
+		  else
+			 Debug("action: %13s,",touchstrings[dummy.actionindex]);
+
+		  if (dummy.swapactionindex == -1)
+			 Debug("swapaction: -1,");
+		  else
+			 Debug("swapaction: %13s,",touchstrings[dummy.swapactionindex]);
+
+		  if (dummy.whichobj & FL_TACT)
+			 Debug("whichobj (actor): %4x\n",(dummy.whichobj & ~FL_TACT));
+		  else
+			 Debug("whichobj (nonactor): %4x\n",dummy.whichobj);
+		 #endif
+		 #endif
+
+
+		 memcpy(tptr,&dummy,sizeof(saved_touch_type));
+		 tptr+=sizeof(saved_touch_type);
+		}
+	 }
+}
+
+statobj_t* GetStatForIndex(int index)
+{statobj_t *temp;
+
+ for(temp = FIRSTSTAT;temp;temp=temp->statnext)
+	if (temp->whichstat == index)
+	  return temp;
+
+ SoftError("\nstat not found in GetStatForIndex");
+ return NULL;
+
+}
+
+
+void LoadTouchPlates(byte * buffer, int size)
+{touchplatetype *temp;
+ int i,savedactions,loadedactions,index=0;
+ saved_touch_type dummy;
+
+ savedactions = (size-sizeof(TRIGGER)-sizeof(numactions))/sizeof(saved_touch_type);
+ memset(touchplate,0,sizeof(touchplate));
+ memset(lastaction,0,sizeof(lastaction));
+ memset(numactions,0,sizeof(numactions));
+ totalactions = 0;
+
+ memcpy(&TRIGGER[0],buffer,sizeof(TRIGGER));
+ buffer += sizeof(TRIGGER);
+
+ memcpy(&numactions[0],buffer,sizeof(numactions));
+ buffer += sizeof(numactions);
+
+ for(loadedactions=0,index=0,i=0;i<savedactions;i++)
+  {memcpy(&dummy,buffer,sizeof(saved_touch_type));
+	temp = (touchplatetype*)Z_LevelMalloc(sizeof(touchplatetype),PU_LEVELSTRUCT,NULL);
+	if (!temp)
+		Error("LoadTouchplates: Failed on allocation of touchplates %d of %d",i,savedactions);
+	memset(temp,0,sizeof(*temp));
+
+	temp->tictime = dummy.tictime;
+	temp->ticcount = dummy.ticcount;
+	temp->triggered = dummy.triggered;
+	temp->done = dummy.done;
+	temp->complete = dummy.complete;
+
+	if (dummy.whichobj & FL_TACT)
+	  temp->whichobj = (long)(objlist[dummy.whichobj & ~FL_TACT]);
+
+	else if (dummy.whichobj & FL_TSTAT)
+	  temp->whichobj = (long)(GetStatForIndex(dummy.whichobj & ~FL_TSTAT));
+	else
+	  temp->whichobj = dummy.whichobj;
+	if (dummy.actionindex != -1)
+	 temp->action = touchactions[dummy.actionindex];
+	else
+	 temp->action = NULL;
+
+	if (dummy.swapactionindex != -1)
+	 temp->swapaction = touchactions[dummy.swapactionindex];
+	else
+	 temp->swapaction = NULL;
+
+	buffer+=sizeof(saved_touch_type);
+
+	while (!numactions[index])
+	  index ++;
+
+	AddTouchplateAction(temp,index);
+
+	/*if (touchplate[index])
+	  lastaction[index]->nextaction = temp;
+	else
+	  touchplate[index] = temp;
+	lastaction[index] = temp;*/
+
+	totalactions ++;
+
+	loadedactions++;
+	if (loadedactions == numactions[index]) // found end of a touchplate's actions, goto next touch.
+	 {loadedactions = 0;
+	  index++;
+	 }
+  }
+
+
+ #if ((DEVELOPMENT == 1))
+ #if (LOADSAVETEST == 1)
+	Debug("\n\nLOAD INFO\n");
+	Debug("---------");
+
+	Debug("\n\nTOUCHINDICES\n");
+	Debug("------------\n\n");
+	for(i=0;i<MAPSIZE;i++)
+	 for(j=0;j< MAPSIZE;j++)
+		if (touchindices[i][j])
+		  Debug("\ntouchindices[%3d][%3d]: %d",i,j,touchindices[i][j]);
+
+	Debug("\n\nTRIGGER: ");
+	for(i=0;i<(sizeof(TRIGGER)/sizeof(TRIGGER[0]));i++)
+	  if (TRIGGER[i])
+		  Debug("%1d",TRIGGER[i]);
+	Debug("\n\nNUMACTIONS PER TOUCHPLATE\n");
+	Debug("-------------------------\n\n");
+	for(i=0;i<(sizeof(numactions)/sizeof(numactions[0]));i++)
+	  if (numactions[i])
+	  Debug("\n %2d: %2d",i,numactions[i]);
+
+	for(i=0;i<lasttouch;i++)
+	  {
+	  Debug("\n\nTOUCHPLATE[%2d]\n",i);
+	  Debug("--------------\n\n");
+
+	  for(k=0,temp=touchplate[i];temp;k++,temp = temp->nextaction)
+		  {
+		  Debug("action node %d: tictime: %d, ticcount: %d ",k,temp->tictime,temp->ticcount);
+		  if (!temp->action)
+			 Debug("action: NULL,");
+		  else
+			 Debug("action: %13s,",touchstrings[GetIndexForAction(temp->action)]);
+
+		  if (!temp->swapaction)
+			 Debug("swapaction: NULL,");
+		  else
+			 Debug("swapaction: %13s,",touchstrings[GetIndexForAction(temp->swapaction)]);
+
+		  Debug("whichobj: %4x\n",(int)temp->whichobj);
+		  }
+	  }
+ #endif
+ #endif
+
+   SafeFree(objlist);
+
+}
+
+
+
+
+void AddTouchplateAction(touchplatetype *tplate,int index)
+{
+ if (touchplate[index])
+	 {tplate->prevaction = lastaction[index];
+	  lastaction[index]->nextaction = tplate;
+	 }
+  else
+	 touchplate[index] = tplate;
+  lastaction[index] = tplate;
+
+}
+
+
+
+
+void  RemoveTouchplateAction(touchplatetype *tplate,int index)
+{
+  if (tplate == lastaction[index])     // remove from master list
+	 lastaction[index] = tplate->prevaction;
+  else
+	 tplate->nextaction->prevaction = tplate->prevaction;
+
+  if (tplate == touchplate[index])
+	 touchplate[index] = tplate->nextaction;
+  else
+	 tplate->prevaction->nextaction = tplate->nextaction;
+
+  Z_Free(tplate);
+  numactions[index]--;
+  totalactions--;
+
+}
+
+
+
+void  Link_To_Touchplate(word touchlocx, word touchlocy, void (*maction)(long), void (*swapaction)(long), long wobj, int delaytime)
+{touchplatetype *temp;
+ int index;
+
+ index = touchindices[touchlocx][touchlocy]-1;
+
+ temp = (touchplatetype*)Z_LevelMalloc(sizeof(touchplatetype),PU_LEVELSTRUCT,NULL);
+ if (!temp)
+	 Error("Link_To_Touchplate: Failed on allocation of touchplate\n");
+ memset(temp,0,sizeof(*temp));
+ temp->action = maction;
+ temp->swapaction = swapaction;
+ temp->whichobj = wobj;
+ temp->tictime = temp->ticcount = delaytime;
+
+ AddTouchplateAction(temp,index);
+ /*if(touchplate[index])
+	lastaction[index]->nextaction=temp;
+ else
+	touchplate[index] = temp;
+ lastaction[index] = temp;*/
+ numactions[index]++;
+ totalactions++;
+}
+
+
+
+void ClockLink (void (*saction)(long), void (*eaction)(long), long wobj,int whichclock)
+{touchplatetype*temp;
+
+
+ // adding two actions per clock
+ temp = (touchplatetype*)Z_LevelMalloc(sizeof(touchplatetype),PU_LEVELSTRUCT,NULL);
+ if (!temp)
+	 Error("ClockLink: Failed on allocation of clock");
+ memset(temp,0,sizeof(*temp));
+ temp->action = saction;
+ temp->swapaction = eaction;
+ temp->whichobj = wobj;
+ temp->clocktype = 1;
+
+ AddTouchplateAction(temp,whichclock);
+/*  if(touchplate[whichclock])
+	lastaction[whichclock]->nextaction = temp;
+  else
+	touchplate[whichclock] = temp;
+  lastaction[whichclock]=temp;*/
+
+ numactions[whichclock]++;
+ totalactions ++;
+}
+
+
+void DisplayMessageForAction(touchplatetype *temp, boolean *wallmessage,
+                             boolean *doormessage, boolean*columnmessage)
+   {
+
+   if ((temp->action == ActivatePushWall) ||
+      (temp->action == ActivateMoveWall)
+      )
+      {
+      if (*wallmessage == false)
+         {
+         if (temp->clocktype)
+            AddMessage("Time-delay wall moves.",MSG_GAME);
+         else
+            AddMessage("A wall moves.",MSG_GAME);
+         *wallmessage = true;
+         }
+      }
+
+   else if (temp->action == LinkedCloseDoor)
+      {
+      if (*doormessage == false)
+         {
+         if (temp->clocktype)
+            AddMessage("Time-delay door closes.",MSG_GAME);
+         else
+            AddMessage("A door closes.",MSG_GAME);
+         *doormessage = true;
+         }
+      }
+
+   else if (temp->action == LinkedOpenDoor)
+      {
+      if (*doormessage == false)
+         {
+         if (temp->clocktype)
+            AddMessage("Time-delay door opens.",MSG_GAME);
+         else
+            AddMessage("A door opens.",MSG_GAME);
+         *doormessage = true;
+         }
+      }
+
+   else if (temp->action == EnableObject)
+      {
+      objtype *tempactor = (objtype*)(temp->whichobj);
+
+      if (M_ISACTOR(tempactor) && (tempactor->obclass == pillarobj))
+         {
+         if (*columnmessage == false)
+            {
+            if (temp->clocktype)
+               AddMessage("Time-delay column moves.",MSG_GAME);
+            else
+               AddMessage("A column moves.",MSG_GAME);
+            *columnmessage = true;
+            }
+         }
+      }
+   }
+
+void TriggerStuff(void)
+   {
+   touchplatetype *temp;
+   int i,touchcomplete,j;
+   int playeron;
+   void (*tempact)(long);
+   boolean wallmessage,doormessage,columnmessage;
+
+   for(i=0;i<lasttouch;i++)
+      {
+      playeron = false;
+      for( j = 0; j < numplayers; j++ )
+         {
+         if ( i == touchindices[ PLAYER[ j ]->tilex ][ PLAYER[ j ]->tiley ] - 1 )
+            {
+            playeron = true;
+            break;
+            }
+         }
+#if (BNACRASHPREVENT == 1)
+	  //SetTextMode (  ); qwert
+	  //	CRASH IN SHAREWARE 'ride em cowboy' BNA FIX
+      // DONT ALLOW BAD touchplate ( == 0 ) see rt_playr.c
+	  if (touchplate[i] == 0) {continue;}
+#endif
+
+      if (!TRIGGER[i])
+         continue;
+
+      else if (touchplate[i]->complete)
+         {
+         if (!playeron)
+            TRIGGER[i] = 0;
+         continue;
+         }
+
+      if (touchplate[i]->done)
+         {
+         if (!playeron)
+            {
+            for(temp = touchplate[i];temp;temp = temp->nextaction)
+               temp->triggered=false;
+            TRIGGER[i] = 0;
+            touchplate[i]->done = false;
+            }
+         }
+
+      else
+         {
+         wallmessage = false;
+         doormessage = false;
+         columnmessage = false;
+
+         for(temp = touchplate[i];temp;temp = temp->nextaction)
+            {
+            if (temp->action && (!temp->triggered))
+               {
+               if (!temp->ticcount)
+                  {
+                  temp->action(temp->whichobj);
+                  if (temp->action == ActivateMoveWall)
+                     {
+                     int tilex,tiley;
+
+                     tilex = pwallobjlist[temp->whichobj]->tilex;
+                     tiley = pwallobjlist[temp->whichobj]->tiley;
+                     tilemap[tilex][tiley] = 0;
+
+                     }
+                  if (gamestate.difficulty == gd_baby)
+                     {
+                     DisplayMessageForAction(temp,&wallmessage,&doormessage,&columnmessage);
+                     }
+
+                  tempact = temp->action;
+                  temp->action = temp->swapaction;
+                  temp->swapaction = tempact;
+                  temp->ticcount = temp->tictime;
+                  temp->triggered = true;
+                  }
+
+               else
+                  temp->ticcount --;
+               }
+            }
+   //done:
+
+         // check to see if any actions will ever be triggered by this
+         // touchplate again; if not, null touchplate out; else,
+         // check status of other actions
+
+         touchcomplete = 1;
+         for(temp = touchplate[i];temp;temp = temp->nextaction)
+            {
+            if (temp->action)
+               {
+               touchcomplete = 0;
+               break;
+               }
+            }
+
+         if (touchcomplete)
+            touchplate[i]->complete = 1; // this touchplate is out of commission
+         else
+            {
+            touchplate[i]->done = true;
+            for(temp = touchplate[i];temp;temp = temp->nextaction)
+               {
+               if (temp->action && (!temp->triggered))
+                  {
+                  touchplate[i]->done = false;
+                  break;
+                  }
+               }
+            }
+         }
+      }
+   }
+
+
+//==================== Tile stuff ====================================
+
+boolean CheckTile(int x, int y)
+{
+
+	if ((x < 2) || (x > (MAPSIZE-1)) || (y < 2) || (y > (MAPSIZE - 1)))
+	  return false;
+
+	if (actorat[x][y])
+	  {objtype *check = (objtype*)(actorat[x][y]);
+		if (insetupgame)
+		  return false;
+		if (!(M_ISACTOR(check) && (check->obclass == playerobj)))
+		  return false;
+     }
+   if (DiskAt(x,y))
+      return false;
+   if (sprites[x][y])
+		return false;
+	if ((tilemap[x][y]) && (IsPlatform(x,y)==false))
+		return false;
+	if ((AREANUMBER(x,y)<=0) || (AREANUMBER(x,y)>NUMAREAS))
+		return false;
+   if (IsWindow(x,y))
+      return false;
+   return true;
+}
+
+
+#define CountTile(x,y) \
+{                       \
+ if (oldarea == AREANUMBER(x,y))\
+    {if (CheckTile(x,y))         \
+        numemptytiles ++;                   \
+                                             \
+     areanumbercount++;                       \
+     if (areanumbercount == numareatiles[oldarea])\
+        return numemptytiles;                     \
+    }                                              \
+                                                    \
+}                                                   \
+
+
+int Number_of_Empty_Tiles_In_Area_Around(int x, int y)
+{int roverx,rovery,areanumbercount=0,
+     numemptytiles=0,oldarea,i,limit,j;
+
+ oldarea = AREANUMBER(x,y);
+
+   for (i=1;;i++)
+      {roverx = x-i;
+       rovery = y-i;
+
+       CountTile(roverx,rovery);
+       limit = i<<1;
+
+       for(j=0;j<limit;j++)
+         {roverx++;
+          CountTile(roverx,rovery);
+         }
+
+       for(j=0;j<limit;j++)
+         {rovery++;
+          CountTile(roverx,rovery);
+         }
+
+       for(j=0;j<limit;j++)
+         {roverx--;
+          CountTile(roverx,rovery);
+         }
+
+       for(j=0;j<limit-1;j++)
+         {rovery--;
+          CountTile(roverx,rovery);
+         }
+      }
+}
+
+
+
+#define CheckSet(x,y)      \
+{if (CheckTile(x,y) && (oldarea == AREANUMBER(x,y))) \
+   {*stilex = x;    \
+    *stiley = y;    \
+    return;              \
+   } \
+}                     \
+
+
+
+void FindEmptyTile(int *stilex, int *stiley)
+{
+   int i,j,x,y,oldarea,roverx,rovery,limit;
+
+	oldarea = AREANUMBER(*stilex,*stiley);
+
+   x = *stilex;
+   y = *stiley;
+
+   if (CheckTile(x,y) && (oldarea == AREANUMBER(x,y)))
+     return;
+
+   for (i=1;;i++)
+      {roverx = x-i;
+       rovery = y-i;
+
+       CheckSet(roverx,rovery);
+       limit = i<<1;
+
+       for(j=0;j<limit;j++)
+         {roverx++;
+          CheckSet(roverx,rovery);
+         }
+
+       for(j=0;j<limit;j++)
+         {rovery++;
+          CheckSet(roverx,rovery);
+         }
+
+       for(j=0;j<limit;j++)
+         {roverx--;
+          CheckSet(roverx,rovery);
+         }
+
+       for(j=0;j<limit-1;j++)
+         {rovery--;
+          CheckSet(roverx,rovery);
+         }
+      }
+}
+
+//================================================================
+
+
+
+
+void RecursiveConnect (int areanumber)
+{
+	int	i;
+
+	for (i=0;i<NUMAREAS;i++)
+	{
+		if (areaconnect[areanumber][i] && !areabyplayer[i])
+		{
+			areabyplayer[i] = true;
+			RecursiveConnect (i);
+		}
+	}
+}
+
+
+/*
+==============
+=
+= ConnectAreas
+=
+= Scans outward from playerarea, marking all connected areas
+=
+==============
+*/
+
+void ConnectAreas (void)
+{objtype*temp;
+ statobj_t*tstat;
+ int i;
+#define MASTER_DISK(ob) ((ob->obclass == diskobj) && (ob->flags & FL_MASTER))
+
+   memset (areabyplayer,0,sizeof(areabyplayer));
+   for (i=0;i<numplayers;i++)
+      {
+      areabyplayer[PLAYER[i]->areanumber] = true;
+      RecursiveConnect (PLAYER[i]->areanumber);
+      }
+	for(temp=FIRSTACTOR;temp;temp=temp->next)
+		{
+      if (MASTER_DISK(temp))
+        continue;
+		if (!areabyplayer[temp->areanumber])
+			continue;
+		if (!(temp->flags & FL_ABP))
+			{temp->flags |= FL_ABP;
+			 MakeActive(temp);
+			}
+		}
+
+	for(tstat=FIRSTSTAT;tstat;tstat=tstat->statnext)
+	  {if (areabyplayer[tstat->areanumber])
+		  {if (!(tstat->flags & FL_ABP))
+			  {tstat->flags |= FL_ABP;
+				MakeStatActive(tstat);
+			  }
+		  }
+		else if (tstat->flags & FL_ABP)
+		 {MakeStatInactive(tstat);
+		  tstat->flags &= ~FL_ABP;
+		 }
+	  }
+
+	for(i=0;i<maskednum;i++)
+	  {if (areabyplayer[maskobjlist[i]->areanumber])
+		  {if (!(maskobjlist[i]->flags & MW_ABP))
+			  {maskobjlist[i]->flags |= MW_ABP;
+				MakeMaskedWallActive(maskobjlist[i]);
+			  }
+		  }
+		else if (maskobjlist[i]->flags & MW_ABP)
+		 {MakeMaskedWallInactive(maskobjlist[i]);
+		  maskobjlist[i]->flags &= ~MW_ABP;
+		 }
+	  }
+}
+
+
+void InitAreas (void)
+{
+	memset (areabyplayer,0,sizeof(areabyplayer));
+	memset (areaconnect,0,sizeof(areaconnect));
+}
+
+
+/*
+===============
+=
+= InitDoorList
+=
+===============
+*/
+
+void InitDoorList (void)
+{
+   doornum=0;
+   pwallnum=0;
+	maskednum=0;
+	lasttouch = 0;
+   numclocks=0;
+
+	memset(touchindices,0,sizeof(touchindices));
+	memset(touchplate,0,sizeof(touchplate));
+	memset(lastaction,0,sizeof(lastaction));
+	memset(numactions,0,sizeof(numactions));
+	totalactions = 0;
+	memset(TRIGGER,0,sizeof(TRIGGER));
+	memset(Clocks,0,sizeof(Clocks));
+   FIRSTMASKEDWALL=NULL;
+   LASTMASKEDWALL=NULL;
+   FIRSTANIMMASKEDWALL=NULL;
+   LASTANIMMASKEDWALL=NULL;
+}
+
+/*
+===============
+=
+= IsWall
+=
+===============
+*/
+
+int IsWall (int tilex, int tiley)
+{
+	int map;
+
+	map=MAPSPOT(tilex,tiley,0);
+
+	if ((map>=1) && (map<=89))
+		return 1;
+
+	else if ((map>=106) && (map<=107))
+		return 1;
+
+	else if ((map>=224) && (map<=233))
+		return 1;
+
+	else if ((map>=242) && (map<=244))
+		return 1;
+
+	return 0;
+}
+
+
+
+/*
+===============
+=
+= InitElevators
+=
+===============
+*/
+
+void InitElevators(void)
+{_numelevators = 0;
+ memset(ELEVATOR,0,sizeof(ELEVATOR));
+
+}
+
+
+
+/*
+===============
+=
+= IsDoor
+=
+===============
+*/
+
+int IsDoor (int tilex, int tiley)
+{
+	int map;
+
+	map=MAPSPOT(tilex,tiley,0);
+
+	if ((map>=33) && (map<=35))
+		return 1;
+
+	if ((map>=90) && (map<=104))
+		return 1;
+
+	if ((map>=154) && (map<=156))
+		return 1;
+
+	if (M_ISDOOR(tilex,tiley))
+      return 1;
+
+	return 0;
+}
+
+
+/*
+===============
+=
+= SpawnDoor
+=
+===============
+*/
+
+void SpawnDoor (int tilex, int tiley, int lock, int texture)
+{
+   int i;
+   doorobj_t * lastdoorobj;
+   int up,dn,lt,rt;
+   int abovewallstart;
+   int swallstart;
+   int basetexture;
+
+   abovewallstart=W_GetNumForName("ABVWSTRT")+1;
+   swallstart=W_GetNumForName("SIDESTRT")+1;
+
+   doorobjlist[doornum]=(doorobj_t*)Z_LevelMalloc(sizeof(doorobj_t),PU_LEVELSTRUCT,NULL);
+   if (!doorobjlist[doornum])
+      Error("SpawnDoor: Failed on allocation of door %d ",doornum);
+   memset(doorobjlist[doornum],0,sizeof(doorobj_t));
+   lastdoorobj=doorobjlist[doornum];
+
+   if (
+        ( MAPSPOT(tilex,tiley,1) >= 29 ) &&
+        ( MAPSPOT(tilex,tiley,1) <= 32 )
+      )
+      {
+      lock = MAPSPOT(tilex,tiley,1) - 28;
+      }
+
+   lastdoorobj->position = 0;
+	lastdoorobj->tilex = tilex;
+	lastdoorobj->tiley = tiley;
+	lastdoorobj->lock = lock;
+	lastdoorobj->action = dr_closed;
+	lastdoorobj->which = DOOR;
+   lastdoorobj->flags = 0;
+	lastdoorobj->eindex = -1;
+
+   //
+   // make the door space solid
+   //
+
+   if (loadedgame==false)
+      actorat[tilex][tiley] = lastdoorobj;
+
+   if (IsDoor(tilex,tiley-1)) up=2;
+   else if (IsWall(tilex,tiley-1)) up=1;
+   else up=0;
+
+   if (IsDoor(tilex,tiley+1)) dn=2;
+   else if (IsWall(tilex,tiley+1)) dn=1;
+   else dn=0;
+
+   if (IsDoor(tilex-1,tiley)) lt=2;
+   else if (IsWall(tilex-1,tiley)) lt=1;
+   else lt=0;
+
+   if (IsDoor(tilex+1,tiley)) rt=2;
+   else if (IsWall(tilex+1,tiley)) rt=1;
+   else rt=0;
+
+	if ((up==1) && (dn==1))
+		lastdoorobj->vertical = true;
+	else if ((lt==1) && (rt==1))
+		lastdoorobj->vertical = false;
+	else if ((up>0) && (dn>0))
+		lastdoorobj->vertical = true;
+	else if ((lt>0) && (rt>0))
+		lastdoorobj->vertical = false;
+	else if (up>0)
+		lastdoorobj->vertical = true;
+	else if (dn>0)
+		lastdoorobj->vertical = true;
+	else if (lt>0)
+		lastdoorobj->vertical = false;
+	else if (rt>0)
+		lastdoorobj->vertical = false;
+
+   switch (texture)
+      {
+
+      case 0:
+      case 8:
+         basetexture = W_GetNumForName("RAMDOOR1\0");
+         break;
+
+      case 1:
+      case 9:
+         basetexture = W_GetNumForName("DOOR2\0");
+         break;
+
+
+      case 2:
+      case 3:
+      case 13:
+         basetexture = W_GetNumForName("TRIDOOR1\0");
+         break;
+
+      case 10:
+      case 11:
+      case 14:
+         basetexture = W_GetNumForName("SDOOR4\0");
+         break;
+
+
+
+      case 12:
+         basetexture = W_GetNumForName("EDOOR\0");
+         break;
+      case 15:
+         basetexture = W_GetNumForName("SNDOOR\0");
+         break;
+      case 16:
+         basetexture = W_GetNumForName("SNADOOR\0");
+         break;
+      case 17:
+         basetexture = W_GetNumForName("SNKDOOR\0");
+         break;
+
+      case 18:
+         basetexture = W_GetNumForName("TNDOOR\0");
+         break;
+      case 19:
+         basetexture = W_GetNumForName("TNADOOR\0");
+         break;
+      case 20:
+         basetexture = W_GetNumForName("TNKDOOR\0");
+         break;
+      default:
+         Error("Illegal door value encountered\n");
+         break;
+      }
+   lastdoorobj->basetexture = basetexture;
+	lastdoorobj->texture = lastdoorobj->basetexture;
+
+   SD_PreCacheSoundGroup(SD_OPENDOORSND,SD_CLOSEDOORSND);
+
+//
+// make the door tile a special tile, and mark the adjacent tiles
+// for door sides
+//
+   tilemap[tilex][tiley] = doornum | 0x8000;
+
+   switch (texture)
+      {
+      case 0:
+      case 1:
+      case 2:
+      case 3:
+      case 8:
+      case 9:
+      case 10:
+      case 11:
+      case 12:
+      case 13:
+      case 14:
+         lastdoorobj->sidepic    = W_GetNumForName("SIDE8");
+         lastdoorobj->alttexture = W_GetNumForName("ABOVEW3");
+         break;
+
+      case 15:
+      case 16:
+      case 17:
+      #if (SHAREWARE == 1)
+         lastdoorobj->sidepic = W_GetNumForName("SIDE8");
+
+      #else
+         lastdoorobj->sidepic    = W_GetNumForName("SIDE16");
+      #endif
+
+         lastdoorobj->alttexture = W_GetNumForName("ABOVEW16");
+         break;
+
+      case 18:
+      case 19:
+      case 20:
+      #if (SHAREWARE == 1)
+         lastdoorobj->sidepic = W_GetNumForName("SIDE8");
+         lastdoorobj->alttexture = W_GetNumForName("ABOVEW3");
+
+      #else
+         lastdoorobj->sidepic    = W_GetNumForName("SIDE17");
+         lastdoorobj->alttexture = W_GetNumForName("ABOVEW17");
+
+      #endif
+
+         break;
+      default:
+         Error("Illegal door value encountered\n");
+         break;
+      }
+
+
+
+   if ((lock>0) && (lock<5))
+      lastdoorobj->sidepic    = W_GetNumForName("lock1")+lock-1;
+
+   PreCacheLump(lastdoorobj->sidepic,PU_CACHEWALLS,cache_pic_t);
+   PreCacheLump(lastdoorobj->alttexture,PU_CACHEWALLS,cache_pic_t);
+
+	if (lastdoorobj->vertical==true)
+	{
+      if (up==1)
+		   tilemap[tilex][tiley-1] |= 0x4000;
+      else if (up==2)
+         lastdoorobj->flags|=DF_MULTI;
+      if (dn==1)
+		   tilemap[tilex][tiley+1] |= 0x4000;
+      else if (dn==2)
+         lastdoorobj->flags|=DF_MULTI;
+	}
+	else
+	{
+      if (lt==1)
+		   tilemap[tilex-1][tiley] |= 0x4000;
+      else if (lt==2)
+         lastdoorobj->flags|=DF_MULTI;
+      if (rt==1)
+		   tilemap[tilex+1][tiley] |= 0x4000;
+      else if (rt==2)
+         lastdoorobj->flags|=DF_MULTI;
+	}
+
+   PreCacheLump(lastdoorobj->texture,PU_CACHEWALLS,cache_pic_t);
+   for (i=1;i<9;i++) // only first texture is pic_t!
+      PreCacheLump(lastdoorobj->texture+i,PU_CACHEWALLS,cache_patch_t);
+	doornum++;
+	lastdoorobj++;
+	if (doornum==MAXDOORS)
+		Error ("Too many doors on level!");
+
+}
+
+/*
+===============
+=
+= MakeWideDoorVisible
+=
+===============
+*/
+void MakeWideDoorVisible ( int doornum )
+{
+   int dx,dy;
+   doorobj_t * dr2;
+   doorobj_t * dr;
+   int tx,ty;
+
+   dr=doorobjlist[doornum];
+
+   dx=0;dy=0;
+   if (dr->vertical==true)
+      dy=1;
+   else
+      dx=1;
+   spotvis[dr->tilex][dr->tiley]=1;
+   tx=dr->tilex+dx;
+   ty=dr->tiley+dy;
+	while (M_ISDOOR(tx,ty))
+      {
+      int num;
+
+      num=tilemap[tx][ty]&0x3ff;
+      dr2=doorobjlist[num];
+      if (!(dr2->flags&DF_MULTI))
+         break;
+      spotvis[tx][ty]=1;
+
+      tx+=dx;
+      ty+=dy;
+      }
+   tx=dr->tilex-dx;
+   ty=dr->tiley-dy;
+	while (M_ISDOOR(tx,ty))
+      {
+      int num;
+
+      num=tilemap[tx][ty]&0x3ff;
+      dr2=doorobjlist[num];
+      if (!(dr2->flags&DF_MULTI))
+         break;
+      spotvis[tx][ty]=1;
+
+      tx-=dx;
+      ty-=dy;
+      }
+}
+
+/*
+=====================
+=
+= LockLinkedDoor
+=
+=====================
+*/
+
+void LockLinkedDoor (int door)
+{
+	doorobj_t*dptr;
+
+	dptr = doorobjlist[door];
+   if (!dptr->lock)
+      dptr->lock=5;
+}
+
+/*
+=====================
+=
+= IsDoorLinked
+=
+=====================
+*/
+
+boolean IsDoorLinked (int door)
+{
+	doorobj_t*dptr;
+
+	dptr = doorobjlist[door];
+   if (dptr->lock==5)
+      return true;
+   return false;
+}
+
+
+/*
+===============
+=
+= FixDoorAreaNumbers
+=
+===============
+*/
+void FixDoorAreaNumbers ( void )
+{
+   int i;
+   int up,dn,lt,rt;
+   int tilex,tiley;
+
+   for (i=0;i<doornum;i++)
+      {
+      tilex=doorobjlist[i]->tilex;
+      tiley=doorobjlist[i]->tiley;
+      up=MAPSPOT(tilex,tiley-1,0)-AREATILE;
+		dn=MAPSPOT(tilex,tiley+1,0)-AREATILE;
+		lt=MAPSPOT(tilex-1,tiley,0)-AREATILE;
+		rt=MAPSPOT(tilex+1,tiley,0)-AREATILE;
+
+      up = ((up>0) && (up<=NUMAREAS));
+		dn = ((dn>0) && (dn<=NUMAREAS));
+		lt = ((lt>0) && (lt<=NUMAREAS));
+		rt = ((rt>0) && (rt<=NUMAREAS));
+
+
+		if (doorobjlist[i]->vertical==true)
+			{
+         if (rt)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex+1,tiley,0);
+         else if (lt)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex-1,tiley,0);
+			else
+				Error("FixDoors: Couldn't fix up area at x=%d y=%d\n",tilex,tiley);
+			}
+		else
+			{
+         if (dn)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley+1,0);
+         else if (up)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley-1,0);
+			else
+				Error("FixDoors: Couldn't fix up area at x=%d y=%d\n",tilex,tiley);
+			}
+      if (IsDoorLinked(i))
+         UtilizeDoor(i,LockLinkedDoor);
+		}
+}
+
+
+//===========================================================================
+
+/*
+=====================
+=
+= OpenDoor
+=
+=====================
+*/
+
+void OpenDoor (int door)
+{
+	if (doorobjlist[door]->action == dr_open)
+		doorobjlist[door]->ticcount = 0;			// reset open time
+	else
+      {
+		doorobjlist[door]->action = dr_opening;	// start it opening
+      }
+}
+
+/*
+=====================
+=
+= DoorUnBlocked
+=
+=====================
+*/
+
+boolean DoorUnBlocked (int door)
+{
+	int	tilex,tiley;
+	objtype *check;
+	doorobj_t*dptr;
+
+	dptr = doorobjlist[door];
+
+//
+// don't close on anything solid
+//
+
+	tilex = dptr->tilex;
+	tiley = dptr->tiley;
+	check = (objtype*)actorat[tilex][tiley];
+
+	if (check && (check->which == ACTOR))
+		return false;
+
+	if (dptr->vertical==true)
+	{
+		check = (objtype*)actorat[tilex-1][tiley];
+		if (check && (check->which==ACTOR) && ((check->x+MINDIST) >> TILESHIFT) == tilex )
+			return false;
+		check = (objtype*)actorat[tilex+1][tiley];
+		if (check && (check->which==ACTOR) && ((check->x-MINDIST) >> TILESHIFT) == tilex )
+			return false;
+	}
+	else if (dptr->vertical==false)
+	{
+		check = (objtype*)actorat[tilex][tiley-1];
+		if (check && (check->which==ACTOR) && ((check->y+MINDIST) >> TILESHIFT) == tiley )
+			return false;
+		check = (objtype*)actorat[tilex][tiley+1];
+		if (check && (check->which==ACTOR) && ((check->y-MINDIST) >> TILESHIFT) == tiley )
+			return false;
+	}
+   return true;
+}
+
+
+/*
+=====================
+=
+= DoorReadyToClose
+=
+= Alter the door's state
+=
+=====================
+*/
+
+boolean DoorReadyToClose(int door)
+{
+	doorobj_t*dptr;
+	int dx,dy;
+	doorobj_t * dr2;
+	int tx,ty;
+
+
+	dptr = doorobjlist[door];
+
+	if (dptr->action==dr_closed)
+		return true;
+
+	if (DoorUnBlocked(door)==false)
+		return false;
+
+	dx=0;dy=0;
+	if (dptr->vertical==true)
+		dy=1;
+	else
+		dx=1;
+	tx=dptr->tilex+dx;
+	ty=dptr->tiley+dy;
+	while (M_ISDOOR(tx,ty))
+		{
+		int num;
+
+		num=tilemap[tx][ty]&0x3ff;
+		dr2=doorobjlist[num];
+		if (!(dr2->flags&DF_MULTI))
+			break;
+		if (DoorUnBlocked(num)==false)
+			return false;
+		tx+=dx;
+		ty+=dy;
+		}
+	tx=dptr->tilex-dx;
+	ty=dptr->tiley-dy;
+	while (M_ISDOOR(tx,ty))
+		{
+		int num;
+
+		num=tilemap[tx][ty]&0x3ff;
+		dr2=doorobjlist[num];
+		if (!(dr2->flags&DF_MULTI))
+			break;
+		if (DoorUnBlocked(num)==false)
+			return false;
+		tx-=dx;
+		ty-=dy;
+		}
+	return true;
+}
+
+
+/*
+=====================
+=
+= CloseDoor
+=
+=====================
+*/
+
+void CloseDoor (int door)
+{
+	int	tilex,tiley,area;
+	doorobj_t*dptr;
+
+	dptr = doorobjlist[door];
+   if (dptr->action == dr_closed)
+      return;
+	tilex = dptr->tilex;
+	tiley = dptr->tiley;
+
+//
+// play door sound
+//
+   area = MAPSPOT(tilex,tiley,0)-AREATILE;
+   if (areabyplayer[area])
+      {
+      dptr->soundhandle=SD_PlaySoundRTP ( SD_CLOSEDOORSND, dptr->tilex<<16, dptr->tiley<<16 );
+      }
+
+	dptr->action = dr_closing;
+//
+// make the door space solid
+//
+	actorat[tilex][tiley] = dptr;
+}
+
+
+
+/*
+=====================
+=
+= OperateDoor
+=
+= The player wants to change the door's direction
+=
+=====================
+*/
+
+void OperateDoor (int keys, int door, boolean localplayer )
+{
+	int	lock;
+	doorobj_t*dptr;
+
+	dptr = doorobjlist[door];
+	if ( ( dptr->flags & DF_ELEVLOCKED ) ||
+      ( MISCVARS->GASON && ( MAPSPOT( dptr->tilex,
+      dptr->tiley, 1 ) == GASVALUE ) ) )
+      {
+      if ( localplayer )
+         {
+         // locked
+         SD_Play ( SD_NOITEMSND );
+         }
+      return;
+      }
+
+   lock = dptr->lock;
+	if ( lock && !( keys & ( 1 << ( lock - 1 ) ) ) )
+      {
+      if ( localplayer )
+         {
+         // locked
+         switch (lock)
+            {
+            case 1:
+               AddMessage("You need the \\EGOLD key",MSG_DOOR);
+               break;
+
+            case 2:
+               AddMessage("You need the \\FSILVER key",MSG_DOOR);
+               break;
+
+            case 3:
+               AddMessage("You need the \\8IRON key",MSG_DOOR);
+               break;
+
+            case 4:
+               AddMessage("You need the \\AOSCURO key",MSG_DOOR);
+               break;
+
+            default:
+               AddMessage("This door appears to be locked",MSG_DOOR);
+               break;
+            }
+
+         SD_Play( SD_NOITEMSND );
+         }
+      return;
+      }
+   UseDoor(door);
+   }
+
+/*
+=====================
+=
+= LinkedOpenDoor
+=
+=====================
+*/
+
+void LinkedOpenDoor (long door)
+{
+   UtilizeDoor(door,OpenDoor);
+}
+
+/*
+=====================
+=
+= LinkedCloseDoor
+=
+=====================
+*/
+
+void LinkedCloseDoor (long door)
+{
+   if (DoorReadyToClose(door)==true)
+      UtilizeDoor(door,CloseDoor);
+}
+
+/*
+=====================
+=
+= UtilizeDoor
+=
+= Alter the door's state
+=
+=====================
+*/
+
+void UtilizeDoor (int door,void (*action)(int))
+{
+	doorobj_t*dptr;
+   int dx,dy;
+   doorobj_t * dr2;
+   int tx,ty;
+
+	dptr = doorobjlist[door];
+
+   action(door);
+
+   dx=0;dy=0;
+   if (dptr->vertical==true)
+      dy=1;
+   else
+      dx=1;
+   tx=dptr->tilex+dx;
+   ty=dptr->tiley+dy;
+	while (M_ISDOOR(tx,ty))
+      {
+      int num;
+
+      num=tilemap[tx][ty]&0x3ff;
+      dr2=doorobjlist[num];
+      if (!(dr2->flags&DF_MULTI))
+         break;
+      action(num);
+      tx+=dx;
+      ty+=dy;
+      }
+   tx=dptr->tilex-dx;
+   ty=dptr->tiley-dy;
+	while (M_ISDOOR(tx,ty))
+      {
+      int num;
+
+      num=tilemap[tx][ty]&0x3ff;
+      dr2=doorobjlist[num];
+      if (!(dr2->flags&DF_MULTI))
+         break;
+      action(num);
+      tx-=dx;
+      ty-=dy;
+      }
+}
+
+/*
+=====================
+=
+= UseDoor
+=
+= Alter the door's state
+=
+=====================
+*/
+
+void UseDoor (int door)
+{
+	switch (doorobjlist[door]->action)
+	{
+	case dr_closing:
+		SD_StopSound(doorobjlist[door]->soundhandle);
+	case dr_closed:
+      UtilizeDoor(door,OpenDoor);
+		break;
+	case dr_opening:
+		SD_StopSound(doorobjlist[door]->soundhandle);
+	case dr_open:
+      if (DoorReadyToClose(door)==true)
+         UtilizeDoor(door,CloseDoor);
+		break;
+	}
+}
+
+//===========================================================================
+
+/*
+===============
+=
+= DoorOpen
+=
+= Close the door after three seconds
+=
+===============
+*/
+
+void DoorOpen (int door)
+{doorobj_t* dptr;
+
+ dptr = doorobjlist[door];
+ dptr->ticcount += 1;
+ if ((dptr->ticcount >= OPENTICS) &&
+     (!(dptr->flags & DF_TIMED)) &&
+     (DoorReadyToClose(door)==true))
+    UtilizeDoor(door,CloseDoor);
+}
+
+
+
+/*
+===============
+=
+= DoorOpening
+=
+===============
+*/
+
+void DoorOpening (int door)
+{
+	int		area1,area2;
+	word  	*map;
+	long	   position;
+	int      tilex,tiley;
+
+	position = doorobjlist[door]->position;
+	tilex = doorobjlist[door]->tilex;
+	tiley = doorobjlist[door]->tiley;
+	if (!position)
+	{
+	//
+	// door is just starting to open, so connect the areas
+	//
+		map = &MAPSPOT(tilex,tiley,0);
+
+		if (doorobjlist[door]->vertical==true)
+		{
+			area1 =	*(map+1);
+			area2 =	*(map-1);
+		}
+		else
+		{
+		 area1 =	*(map-mapwidth);
+		 area2 =	*(map+mapwidth);
+		}
+		area1 -= AREATILE;
+		area2 -= AREATILE;
+		areaconnect[area1][area2]++;
+		areaconnect[area2][area1]++;
+		if ((insetupgame==false) && (loadedgame==false))
+			ConnectAreas ();
+	   if (areabyplayer[area1])
+    	   {
+         doorobjlist[door]->soundhandle=SD_PlaySoundRTP ( SD_OPENDOORSND, doorobjlist[door]->tilex<<16, doorobjlist[door]->tiley<<16 );
+         }
+	}
+
+//
+// slide the door by an adaptive amount
+//
+	position += 1<<12;
+	if (position >= 0xffff)
+	{
+	//
+	// door is all the way open
+	//
+		position = 0xffff;
+		doorobjlist[door]->ticcount = 0;
+		doorobjlist[door]->action = dr_open;
+		if (doorobjlist[door] == actorat[tilex][tiley])
+			actorat[tilex][tiley] = 0;
+	}
+
+	doorobjlist[door]->position = position;
+	doorobjlist[door]->texture=doorobjlist[door]->basetexture+((position+1)>>13);
+}
+
+
+/*
+===============
+=
+= DoorClosing
+=
+===============
+*/
+
+void DoorClosing (int door)
+{
+	int		area1,area2;
+	word	   *map;
+	long	   position;
+	int		tilex,tiley;
+	doorobj_t *dptr;
+
+	dptr = doorobjlist[door];
+
+	tilex = dptr->tilex;
+	tiley = dptr->tiley;
+
+	position = dptr->position;
+
+//
+// slide the door by an adaptive amount
+//
+	position -= 1<<12;
+	if (position < (0xffff >> 1))
+	   ResolveDoorSpace(tilex,tiley);
+
+
+	if (position <= 0)
+	{
+	//
+	// door is closed all the way, so disconnect the areas
+	//
+		position = 0;
+
+		dptr->action = dr_closed;
+
+
+
+		map = &MAPSPOT(tilex,tiley,0);
+
+      if (areabyplayer[(*map-AREATILE)])
+         {
+         dptr->soundhandle=SD_PlaySoundRTP ( SD_DOORHITSND, dptr->tilex<<16, dptr->tiley<<16 );
+         }
+
+      if (dptr->vertical==true)
+		{
+			area1 =	*(map+1);
+			area2 =	*(map-1);
+		}
+		else
+		{
+			area1 =	*(map-mapwidth);
+			area2 =	*(map+mapwidth);
+		}
+		area1 -= AREATILE;
+		area2 -= AREATILE;
+		areaconnect[area1][area2]--;
+		areaconnect[area2][area1]--;
+
+		ConnectAreas ();
+   }
+
+	dptr->position = position;
+	dptr->texture=dptr->basetexture+((position+1)>>13);
+}
+
+/*
+===============
+=
+= IsMaskedWall
+=
+===============
+*/
+
+int IsMaskedWall (int tilex, int tiley)
+{
+	int map;
+
+	if (IsPlatform(tilex,tiley))
+		return 1;
+
+	map=MAPSPOT(tilex,tiley,0);
+
+	if ((map>=157) && (map<=160))
+		return 1;
+
+	if ((map>=162) && (map<=179))
+		return 1;
+
+	if (M_ISMWALL(tilex,tiley))
+      return 1;
+
+	return 0;
+}
+
+/*
+===============
+=
+= SpawnMaskedWall
+=
+===============
+*/
+
+
+void SpawnMaskedWall (int tilex, int tiley, int which, int flags)
+{word *map;
+ int area1, area2;
+ int up,dn,lt,rt;
+ int himask;
+ boolean sidepic;
+ int side, middle, above, bottom;
+ maskedwallobj_t * lastmaskobj;
+ boolean metal;
+ int maskedstart;
+ int abovemaskedwallstart;
+ int swallstart;
+
+	himask=W_GetNumForName("HMSKSTRT")+1;
+   maskedstart=W_GetNumForName("MASKSTRT");
+   abovemaskedwallstart=W_GetNumForName("ABVMSTRT");
+   swallstart=W_GetNumForName("SIDESTRT");
+
+	maskobjlist[maskednum]=(maskedwallobj_t*)Z_LevelMalloc(sizeof(maskedwallobj_t),PU_LEVELSTRUCT,NULL);
+	memset(maskobjlist[maskednum],0,sizeof(maskedwallobj_t));
+	lastmaskobj=maskobjlist[maskednum];
+
+   sidepic=true;
+
+	lastmaskobj->tilex = tilex;
+	lastmaskobj->tiley = tiley;
+	lastmaskobj->which = MWALL;
+	up=MAPSPOT(tilex,tiley-1,0)-AREATILE;
+	dn=MAPSPOT(tilex,tiley+1,0)-AREATILE;
+	lt=MAPSPOT(tilex-1,tiley,0)-AREATILE;
+	rt=MAPSPOT(tilex+1,tiley,0)-AREATILE;
+
+   if (IsMaskedWall(tilex,tiley-1)) up=2;
+   else if (IsWall(tilex,tiley-1)) up=1;
+   else up=0;
+
+   if (IsMaskedWall(tilex,tiley+1)) dn=2;
+   else if (IsWall(tilex,tiley+1)) dn=1;
+   else dn=0;
+
+   if (IsMaskedWall(tilex-1,tiley)) lt=2;
+   else if (IsWall(tilex-1,tiley)) lt=1;
+   else lt=0;
+
+   if (IsMaskedWall(tilex+1,tiley)) rt=2;
+   else if (IsWall(tilex+1,tiley)) rt=1;
+   else rt=0;
+
+	if ((up==1) && (dn==1))
+		lastmaskobj->vertical = true;
+	else if ((lt==1) && (rt==1))
+		lastmaskobj->vertical = false;
+	else if ((up>0) && (dn>0))
+		lastmaskobj->vertical = true;
+	else if ((lt>0) && (rt>0))
+		lastmaskobj->vertical = false;
+	else if (up>0)
+		lastmaskobj->vertical = true;
+	else if (dn>0)
+		lastmaskobj->vertical = true;
+	else if (lt>0)
+		lastmaskobj->vertical = false;
+	else if (rt>0)
+		lastmaskobj->vertical = false;
+
+	tilemap[tilex][tiley] = maskednum | 0xc000;
+	map = &MAPSPOT(tilex,tiley,0);
+
+	if (lastmaskobj->vertical==true)
+		{
+		area1 =	*(map+1);
+		area2 =	*(map-1);
+      area1 -= AREATILE;
+		area2 -= AREATILE;
+		if (lt==0 && rt==0)
+			{
+			areaconnect[area1][area2]++;
+			areaconnect[area2][area1]++;
+			}
+		}
+	else
+		{
+		area1 =	*(map-mapwidth);
+		area2 =	*(map+mapwidth);
+      area1 -= AREATILE;
+		area2 -= AREATILE;
+		if (up==0 && dn==0)
+			{
+			areaconnect[area1][area2]++;
+			areaconnect[area2][area1]++;
+			}
+		}
+	lastmaskobj->flags=flags;
+
+   if (IsPlatform(tilex,tiley))
+      {
+      if (MAPSPOT(tilex,tiley,0)==21)
+         {
+         metal=true;
+			actorat[tilex][tiley]=0;
+         }
+      else
+         metal=false;
+      }
+
+
+
+   switch (which)
+      {
+      case mw_peephole:
+
+      //#if (SHAREWARE == 1)
+         side = W_GetNumForName("SIDE21");
+         middle = W_GetNumForName("ABOVEM4A") ;
+         above  = W_GetNumForName("ABOVEM4") ;
+      /*
+      #else
+         side   = W_GetNumForName("SIDE16");
+         middle = W_GetNumForName("ABOVEM3A") ;
+         above  = W_GetNumForName("ABOVEM2A") ;
+
+      #endif
+      */
+         bottom = W_GetNumForName("PEEPMASK");
+         break;
+
+
+      case mw_dogwall:
+
+         side = W_GetNumForName("SIDE21");
+         above  = W_GetNumForName("ABOVEM4") ;
+
+   #if (SHAREWARE == 1)
+         middle = W_GetNumForName("ABOVEM4A") ;
+   #else
+         middle = W_GetNumForName("ABOVEM9") ;
+
+   #endif
+         bottom = W_GetNumForName("DOGMASK");
+         break;
+
+      case mw_multi1:
+
+  /*
+      #if (SHAREWARE == 1)
+         side = W_GetNumForName("SIDE21");
+         middle = W_GetNumForName("ABOVEM4A") ;
+         above  = W_GetNumForName("ABOVEM4") ;
+
+      #else
+  */
+         //side   = W_GetNumForName("SIDE23") ;
+         side   = W_GetNumForName("SIDE21") ;
+         middle = W_GetNumForName("ABOVEM5A") ;
+         above  = W_GetNumForName("ABOVEM5") ;
+
+     // #endif
+
+         bottom = W_GetNumForName("MULTI1");
+         break;
+
+      case mw_multi2:
+      /*
+      #if (SHAREWARE == 1)
+         side = W_GetNumForName("SIDE21");
+         middle = W_GetNumForName("ABOVEM4A");
+         above  = W_GetNumForName("ABOVEM4") ;
+
+      #else
+      */
+         //side   = W_GetNumForName("SIDE23") ;
+         side   = W_GetNumForName("SIDE21") ;
+         middle = W_GetNumForName("ABOVEM5B");
+         above  = W_GetNumForName("ABOVEM5") ;
+
+
+      //#endif
+
+         bottom = W_GetNumForName("MULTI2");
+         break;
+
+      case mw_multi3:
+
+      /*
+      #if (SHAREWARE == 1)
+         side = W_GetNumForName("SIDE21");
+         middle = W_GetNumForName("ABOVEM4A") ;
+         above  = W_GetNumForName("ABOVEM4")  ;
+
+      #else
+      */
+         //side   = W_GetNumForName("SIDE23") ;
+         side   = W_GetNumForName("SIDE21") ;
+         middle = W_GetNumForName("ABOVEM5C") ;
+         above  = W_GetNumForName("ABOVEM5")  ;
+
+
+      //#endif
+
+         bottom = W_GetNumForName("MULTI3");
+         break;
+
+      case mw_singlepane:
+
+   //   #if (SHAREWARE == 1)
+         side = W_GetNumForName("SIDE21");
+
+   //   #else
+   //      side   = W_GetNumForName("SIDE22") ;
+   //   #endif
+
+         middle = W_GetNumForName("ABOVEM4A") ;
+         above  = W_GetNumForName("ABOVEM4")  ;
+         bottom = W_GetNumForName("MASKED4");
+         break;
+
+      case mw_normal1:
+         side = W_GetNumForName("SIDE21");
+
+
+     // #if (SHAREWARE == 1)
+         middle = W_GetNumForName("ABOVEM4A") ;
+         above  = W_GetNumForName("ABOVEM4")  ;
+
+      //#else
+       //  middle = W_GetNumForName("ABOVEM1A") ;
+       //  above  = W_GetNumForName("ABOVEM1")  ;
+
+
+      //#endif
+
+         bottom = W_GetNumForName("MASKED1");
+         break;
+
+      case mw_normal2:
+         side = W_GetNumForName("SIDE21");
+
+      //#if (SHAREWARE == 1)
+         middle = W_GetNumForName("ABOVEM4A") ;
+         above  = W_GetNumForName("ABOVEM4")  ;
+
+      //#else
+      //   middle = W_GetNumForName("ABOVEM2A") ;
+      //   above  = W_GetNumForName("ABOVEM2")  ;
+
+      //#endif
+
+         bottom = W_GetNumForName("MASKED2");
+         break;
+
+      case mw_normal3:
+         side = W_GetNumForName("SIDE21");
+
+      //#if (SHAREWARE == 1)
+         middle = W_GetNumForName("ABOVEM4A") ;
+         above  = W_GetNumForName("ABOVEM4")  ;
+
+      //#else
+      //   middle = W_GetNumForName("ABOVEM3A") ;
+      //   above  = W_GetNumForName("ABOVEM3")  ;
+
+      //#endif
+
+         bottom = W_GetNumForName("MASKED3");
+         break;
+
+      case mw_exitarch:
+
+         side = W_GetNumForName("SIDE21");
+
+      //#if (SHAREWARE == 1)
+         middle = W_GetNumForName("ABOVEM4A") ;
+         above  = W_GetNumForName("ABOVEM4")  ;
+
+      //#else
+      //   middle = W_GetNumForName("ABOVEM6A") ;
+      //   above  = W_GetNumForName("ABOVEM6")  ;
+
+      //#endif
+
+         bottom = W_GetNumForName("EXITARCH");
+         break;
+
+      case mw_secretexitarch:
+
+         side = W_GetNumForName("SIDE21");
+
+      //#if (SHAREWARE == 1)
+         middle = W_GetNumForName("ABOVEM4A") ;
+         above  = W_GetNumForName("ABOVEM4")  ;
+
+      //#else
+      //   middle = W_GetNumForName("ABOVEM8A") ;
+      //   above  = W_GetNumForName("ABOVEM8")  ;
+
+      //#endif
+
+         bottom = W_GetNumForName("EXITARCA");
+         break;
+
+      case mw_railing:
+         sidepic = false;
+         middle = -1;
+         above  = -1;
+         bottom = W_GetNumForName("RAILING");
+         break;
+
+      case mw_hiswitchon:
+         sidepic = false;
+         middle = himask+1;
+         above = himask+3;
+         bottom = himask;
+         break;
+
+      case mw_hiswitchoff:
+         sidepic = false;
+         middle = himask+1;
+         above = himask+2;
+         bottom = himask;
+         break;
+
+      case mw_entrygate:
+         side = W_GetNumForName("SIDE21");
+
+      //#if (SHAREWARE == 1)
+         //side = W_GetNumForName("SIDE21");
+         middle = W_GetNumForName("ABOVEM4A") ;
+         above  = W_GetNumForName("ABOVEM4")  ;
+
+      //#else
+         //side   = W_GetNumForName("SIDE20") ;
+      //   middle = W_GetNumForName("ABOVEM7A") ;
+      //   above  = W_GetNumForName("ABOVEM7")  ;
+
+
+      //#endif
+
+         bottom = W_GetNumForName("ENTRARCH");
+         break;
+
+      case mw_platform1:
+         sidepic = false;
+         bottom = -1;
+         middle = -1;
+         above  = himask+10;
+         if (metal==true)
+            {
+            bottom = -1;
+            middle = -1;
+            above  = himask+15;
+            }
+         break;
+      case mw_platform2:
+         sidepic = false;
+         bottom = himask+8;
+         middle = -1;
+         above = -1;
+         if (metal==true)
+            {
+            bottom = himask+14;
+            middle = -1;
+            above = -1;
+            }
+         else
+            lastmaskobj->flags|=MW_BOTTOMFLIPPING;
+         break;
+      case mw_platform3:
+         sidepic = false;
+         bottom = himask+8;
+         middle = -1;
+         above = himask+10;
+         if (metal==true)
+            {
+            bottom = himask+14;
+            middle = -1;
+            above = himask+15;
+            }
+         else
+            lastmaskobj->flags|=MW_BOTTOMFLIPPING;
+         break;
+      case mw_platform4:
+         sidepic = false;
+         bottom = himask+12;
+         middle = himask+7;
+         above = himask+7;
+         if (metal==true)
+            {
+            bottom = -1;
+            middle = himask+15;
+            above = himask+15;
+            }
+         break;
+      case mw_platform5:
+         sidepic = false;
+         bottom = himask+12;
+         middle = himask+7;
+         above = himask+5;
+         if (metal==true)
+            {
+            bottom = -1;
+            middle = himask+15;
+            above = -1;
+            }
+         else
+            lastmaskobj->flags|=MW_TOPFLIPPING;
+         break;
+      case mw_platform6:
+         sidepic = false;
+         bottom = himask+4;
+         middle = himask+7;
+         above = himask+5;
+         if (metal==true)
+            {
+            bottom = himask+14;
+            middle = himask+15;
+            above = -1;
+            }
+         else
+            lastmaskobj->flags|=MW_TOPFLIPPING;
+         break;
+      case mw_platform7:
+         sidepic = false;
+         bottom = himask+4;
+         middle = himask+7;
+         above = himask+5;
+         if ((up==1) || (dn==1))
+            lastmaskobj->vertical=true;
+         else if ((lt==1) || (rt==1))
+            lastmaskobj->vertical=false;
+         else
+            Error("Perpendicular platform used with no wall near it\n");
+         if (metal==true)
+            {
+            bottom = himask+14;
+            middle = himask+15;
+            above = -1;
+            }
+         else
+            lastmaskobj->flags|=MW_TOPFLIPPING;
+         break;
+      }
+
+   switch (which)
+      {
+      case mw_multi1:
+      case mw_multi2:
+      case mw_multi3:
+      case mw_singlepane:
+      case mw_normal1:
+      case mw_normal2:
+      case mw_normal3:
+         if (!(flags & MW_SHOOTABLE))
+            bottom+=9;
+         break;
+      }
+   lastmaskobj->midtexture=middle;
+   lastmaskobj->toptexture=above;
+   lastmaskobj->bottomtexture=bottom;
+
+   if (sidepic == true)
+      {
+      lastmaskobj->sidepic=side;
+      if (lastmaskobj->vertical==true)
+         {
+         if (up==1)
+            tilemap[tilex][tiley-1] |= 0x4000;
+         if (dn==1)
+            tilemap[tilex][tiley+1] |= 0x4000;
+         }
+      else
+         {
+         if (lt==1)
+            tilemap[tilex-1][tiley] |= 0x4000;
+         if (rt==1)
+            tilemap[tilex+1][tiley] |= 0x4000;
+         }
+      }
+
+	// Cache in the broken version
+
+	if (lastmaskobj->flags & MW_SHOOTABLE)
+      {
+      int i;
+
+      for (i=1;i<AMW_NUMFRAMES;i++)
+         {
+         PreCacheLump(lastmaskobj->bottomtexture+i,PU_CACHEWALLS,cache_transpatch_t);
+         }
+      SD_PreCacheSound(SD_GLASSBREAKSND);
+		}
+   if (sidepic==true)
+      {
+      PreCacheLump(lastmaskobj->sidepic,PU_CACHEWALLS,cache_pic_t);
+      }
+   if (lastmaskobj->bottomtexture>=0)
+      PreCacheLump(lastmaskobj->bottomtexture,PU_CACHEWALLS,cache_transpatch_t);
+   if (lastmaskobj->toptexture>=0)
+      PreCacheLump(lastmaskobj->toptexture,PU_CACHEWALLS,cache_patch_t);
+   if (lastmaskobj->midtexture>=0)
+      PreCacheLump(lastmaskobj->midtexture,PU_CACHEWALLS,cache_patch_t);
+	maskednum++;
+	lastmaskobj++;
+	if (maskednum==MAXMASKED)
+		Error ("Too many masked walls\n");
+}
+
+/*
+===============
+=
+= FixMaskedWallAreaNumbers
+=
+===============
+*/
+void FixMaskedWallAreaNumbers ( void )
+{
+	int i;
+	int up,dn,lt,rt;
+	int tilex,tiley;
+
+	for (i=0;i<maskednum;i++)
+		{
+		int tile;
+		tilex=maskobjlist[i]->tilex;
+		tiley=maskobjlist[i]->tiley;
+      tile=MAPSPOT(tilex,tiley,0)-AREATILE;
+		if ((tile<=NUMAREAS) && (tile>0))
+		   {
+         maskobjlist[i]->areanumber = tile;
+			continue;
+		   }
+		up=MAPSPOT(tilex,tiley-1,0)-AREATILE;
+		dn=MAPSPOT(tilex,tiley+1,0)-AREATILE;
+		lt=MAPSPOT(tilex-1,tiley,0)-AREATILE;
+		rt=MAPSPOT(tilex+1,tiley,0)-AREATILE;
+
+
+
+		up = ((up>0) && (up<=NUMAREAS));
+		dn = ((dn>0) && (dn<=NUMAREAS));
+		lt = ((lt>0) && (lt<=NUMAREAS));
+		rt = ((rt>0) && (rt<=NUMAREAS));
+
+		if (maskobjlist[i]->vertical==true)
+			{
+			if (rt)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex+1,tiley,0);
+			else if (lt)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex-1,tiley,0);
+			else if (up)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley-1,0);
+			else if (dn)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley+1,0);
+			else
+				Error("FixMaskedWalls: Couldn't fix up area at x=%d y=%d\n",tilex,tiley);
+			}
+		else
+			{
+			if (dn)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley+1,0);
+			else if (up)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex,tiley-1,0);
+			else if (rt)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex+1,tiley,0);
+			else if (lt)
+				MAPSPOT(tilex,tiley,0) = MAPSPOT(tilex-1,tiley,0);
+			else
+				Error("FixMaskedWalls: Couldn't fix up area at x=%d y=%d\n",tilex,tiley);
+			}
+		maskobjlist[i]->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE;
+		if ((maskobjlist[i]->areanumber <0) || (maskobjlist[i]->areanumber > NUMAREAS))
+		  Error("Bad masked wall areanumber of %d",maskobjlist[i]->areanumber);
+		}
+}
+
+
+/*
+===============
+=
+= CheckMaskedWall
+=
+===============
+*/
+
+int CheckMaskedWall( maskedwallobj_t * mw )
+{
+	int result;
+
+	result=0;
+	if (mw->flags & MW_SHOOTABLE)
+		{
+		if (mw->flags & MW_BLOCKINGCHANGES)
+         {
+         mw->flags&=~MW_BLOCKINGCHANGES;
+         mw->flags&=~MW_BLOCKING;
+         mw->flags|=MW_BOTTOMPASSABLE;
+         }
+      mw->flags&=~MW_SHOOTABLE;
+//      mw->bottomtexture++;
+      result=1;
+      }
+   return result;
+}
+
+
+/*
+===============
+=
+= UpdateMaskedWall
+=
+===============
+*/
+
+int UpdateMaskedWall (int num)
+{
+   maskedwallobj_t * mw;
+   int result;
+
+
+   mw=maskobjlist[num];
+   result=CheckMaskedWall(mw);
+   if (result==1)
+      {
+      SpawnAnimatedMaskedWall(num);
+      if (loadedgame==false)
+	      SD_PlaySoundRTP(SD_GLASSBREAKSND,mw->tilex<<16,mw->tiley<<16);
+      if (mw->flags&MW_MULTI)
+         {
+         int i;
+         int dx,dy;
+         int r;
+         maskedwallobj_t * mw2;
+
+         dx=0;dy=0;
+         if (mw->vertical==true)
+            dy=1;
+         else
+            dx=1;
+         i=1;
+			while (M_ISMWALL(mw->tilex+(dx*i),mw->tiley+(dy*i)))
+            {
+            int num;
+
+            num=tilemap[mw->tilex+(dx*i)][mw->tiley+(dy*i)]&0x3ff;
+            mw2=maskobjlist[num];
+            if (!(mw2->flags&MW_MULTI))
+               break;
+            r=CheckMaskedWall(mw2);
+            if (r==1)
+               {
+               SpawnAnimatedMaskedWall(num);
+               if (loadedgame==false)
+	               SD_PlaySoundRTP(SD_GLASSBREAKSND,mw2->tilex<<16,mw2->tiley<<16);
+               }
+            i++;
+            }
+         i=1;
+			while (M_ISMWALL(mw->tilex-(dx*i),mw->tiley-(dy*i)))
+            {
+            int num;
+
+            num=tilemap[mw->tilex-(dx*i)][mw->tiley-(dy*i)]&0x3ff;
+            mw2=maskobjlist[num];
+            if (!(mw2->flags&MW_MULTI))
+               break;
+            r=CheckMaskedWall(mw2);
+            if (r==1)
+               {
+               SpawnAnimatedMaskedWall(num);
+               if (loadedgame==false)
+	               SD_PlaySoundRTP(SD_GLASSBREAKSND,mw2->tilex<<16,mw2->tiley<<16);
+               }
+            i++;
+            }
+         }
+      }
+   return result;
+}
+
+
+
+/*
+============================
+=
+= ExecuteElevatorStopActions
+=
+============================
+*/
+
+
+void ExecuteElevatorStopActions(elevator_t *eptr, int teleport_location,
+                                int desttilex,int desttiley)
+   {
+   eptr->state = ev_doorclosing;
+   eptr->doorclosing = eptr->doortoopen;
+   doorobjlist[eptr->doortoopen]->flags &= ~DF_ELEVLOCKED;
+   OpenDoor(eptr->doortoopen);
+   SD_PlaySoundRTP(SD_ELEVATORENDSND,desttilex,desttiley);
+   Teleport(eptr,teleport_location);
+   eptr->ticcount = OPENTICS;
+   eptr->doortoopen = -1;
+   if (MISCVARS->elevatormusicon == true)
+      {
+      MU_StartSong(song_level);
+      MU_RestoreSongPosition();
+      MISCVARS->elevatormusicon = false;
+
+      }
+   }
+
+
+boolean PlayerInElevator(elevator_t *eptr)
+   {
+   if (eptr->state == ev_mts)
+      {
+      if ((eptr->dx == player->tilex) && (eptr->dy == player->tiley))
+         return true;
+      }
+   else if (eptr->state == ev_mtd)
+      {
+      if ((eptr->sx == player->tilex) && (eptr->sy == player->tiley))
+         return true;
+      }
+
+   return false;
+
+   }
+
+#define SHOULD_START_ELEVATOR_MUSIC(eptr)                              \
+        ((demoplayback == false) && (demorecord == false) &&           \
+         (MusicStarted() == true) &&                                   \
+         (!BATTLEMODE) && \
+         (!(player->flags & FL_GODMODE)) &&\
+         (GameRandomNumber("elevator music",0) < 25) && \
+         (PlayerInElevator(eptr))                                      \
+        )                                                              \
+
+
+/*
+==========================
+=
+= SetElevatorOperationTime
+=
+==========================
+*/
+
+
+void SetElevatorOperationTime(elevator_t*eptr)
+   {
+   if (SHOULD_START_ELEVATOR_MUSIC(eptr))
+      {
+      MU_StoreSongPosition();
+      MU_StartSong(song_elevator);
+      MISCVARS->elevatormusicon = true;
+      eptr->ticcount = ELEVATORMUSICTIME;
+      }
+
+   else if (AREANUMBER(eptr->sx,eptr->sy) == AREANUMBER(eptr->dx,eptr->dy))
+      eptr->ticcount = 70;
+   else
+      eptr->ticcount = 170;
+
+   }
+
+
+/*
+=====================
+=
+= CheckElevatorStart
+=
+=====================
+*/
+
+void CheckElevatorStart (elevator_t*eptr)
+   {
+   doorobj_t *dptr = doorobjlist[eptr->doorclosing];
+
+   if (dptr->action == dr_closed)
+      {
+
+      if (eptr->nextaction!=-1)
+         {
+         eptr->state = eptr->nextaction;
+         eptr->nextaction = -1;
+         switch (eptr->state)
+            {
+            case ev_mtd:
+               eptr->doortoopen = eptr->door2;
+               SD_PlaySoundRTP(SD_ELEVATORONSND,eptr->sx<<16,eptr->sy<<16);
+               //eptr->doorclosing = eptr->door1;
+
+               SetElevatorOperationTime(eptr);
+               break;
+
+            case ev_mts:
+               eptr->doortoopen = eptr->door1;
+
+               SD_PlaySoundRTP(SD_ELEVATORONSND,eptr->dx<<16,eptr->dy<<16);
+
+               SetElevatorOperationTime(eptr);
+               break;
+            }
+         }
+
+      else if (eptr->doorclosing == eptr->door1)
+         eptr->state = ev_ras;
+
+
+      else if (eptr->doorclosing == eptr->door2)
+         eptr->state = ev_rad;
+
+
+      eptr->doorclosing = -1;
+      }
+   }
+
+
+/*
+=====================
+=
+= ProcessElevators
+=
+= Called from PlayLoop
+=
+=====================
+*/
+
+void ProcessElevators (void)
+   {
+	int		  ectr;
+	elevator_t *eptr;
+
+	for (ectr = 0 ; ectr < _numelevators ; ectr++)
+      {
+      eptr = &ELEVATOR[ectr];
+		if (eptr->ticcount)
+			eptr->ticcount --;
+		else
+         {
+         switch (eptr->state)
+            {
+            /*
+            case ev_ras:
+               break;
+
+            case ev_rad:
+               break;
+            */
+            case ev_mts:
+               ExecuteElevatorStopActions(eptr,0,(eptr->sx << 16),(eptr->sy << 16));
+               break;
+
+            case ev_mtd:
+               ExecuteElevatorStopActions(eptr,1,(eptr->dx << 16),(eptr->dy << 16));
+               break;
+
+            case ev_doorclosing:
+               CheckElevatorStart(eptr);
+               break;
+            }
+         }
+      }
+   }
+
+
+
+void Teleport(elevator_t*eptr,int destination)
+{statobj_t*tstat;
+ objtype*temp;
+ int startx,starty,destx,desty;
+
+ if (destination) // move to dest
+	{startx = eptr->sx;
+	 starty = eptr->sy;
+	 destx = eptr->dx;
+	 desty = eptr->dy;
+    tilemap[eptr->esx][eptr->esy] = (elevatorstart + 5) | 0x2000;
+
+	}
+ else
+	{startx = eptr->dx;
+	 starty = eptr->dy;
+	 destx = eptr->sx;
+	 desty = eptr->sy;
+	 tilemap[eptr->edx][eptr->edy] = (elevatorstart + 5) | 0x2000;
+	}
+
+ for(tstat=firstactivestat;tstat;tstat=tstat->nextactive)
+	{if ((tstat->tilex == startx) && (tstat->tiley == starty))
+		{
+		 tstat->x += ((destx - tstat->tilex) << TILESHIFT);
+		 tstat->y += ((desty - tstat->tiley) << TILESHIFT);
+		 tstat->tilex = tstat->x >> TILESHIFT;
+		 tstat->tiley = tstat->y >> TILESHIFT;
+		 tstat->visspot = &spotvis[tstat->tilex][tstat->tiley];
+		 if (sprites[startx][starty] == tstat)
+			{sprites[startx][starty] = NULL;
+			 sprites[destx][desty] = tstat;
+
+			}
+
+		}
+	}
+
+ for(temp=firstactive;temp;temp=temp->nextactive)
+	{if ((temp->tilex == startx) && (temp->tiley == starty))
+		{temp->x += ((destx - temp->tilex) << TILESHIFT);
+		 temp->y += ((desty - temp->tiley) << TILESHIFT);
+		 temp->tilex = temp->x >> TILESHIFT;
+		 temp->tiley = temp->y >> TILESHIFT;
+		 if (temp->obclass!=inertobj)
+			 {
+			 RemoveFromArea (temp);
+			 temp->areanumber = AREANUMBER(temp->tilex,temp->tiley);
+			 MakeLastInArea (temp);
+			 }
+		 if (temp == player)
+			SHAKETICS = 10;
+		}
+	}
+
+
+
+}
+
+
+
+void OperateElevatorDoor(int dnum)
+{
+ elevator_t*eptr;
+ doorobj_t *dptr,*door1,*door2;
+
+ dptr = doorobjlist[dnum];
+ eptr = &ELEVATOR[dptr->eindex];
+ door1 = doorobjlist[eptr->door1];
+ door2 = doorobjlist[eptr->door2];
+
+ switch(eptr->state)
+	{/*
+	 case ev_mtd:               // if already on the way to request,
+										 // ignore; else, put request in
+		if (dnum == eptr->door1)
+		  {eptr->nextaction = ev_mts;
+			//eptr->doortoopen = eptr->door1;
+         #if (DEVELOPMENT == 1)
+         #if (ELEVATORTEST == 1)
+			Debug("\nplayer at source requesting elev %d mtd",dptr->eindex);
+			#endif
+			#endif
+		  }
+		break;
+
+	 case ev_mts:
+		if (dnum == eptr->door2)
+		  {eptr->nextaction = ev_mtd;
+			//eptr->doortoopen = eptr->door2;
+         #if (DEVELOPMENT == 1)
+         #if (ELEVATORTEST == 1)
+			Debug("\nplayer at dest requesting elev %d mts",dptr->eindex);
+			#endif
+			#endif
+		  }
+		break;
+	 */
+	 case ev_rad:                          // if ready at other place,
+		if ((dnum == eptr->door1) && (eptr->nextaction != ev_mts))  // process request, lock doors,
+
+			{
+         #if (DEVELOPMENT == 1)
+         #if (ELEVATORTEST == 1)
+			Debug("\nplayer at source requesting elev %d rad",dptr->eindex);
+			#endif
+			#endif
+												// start moving to current loc;
+			 SetNextAction(eptr,0);		// if already there, do nothing
+
+			}
+		break;
+
+	 case ev_ras:
+		if ((dnum == eptr->door2) && (eptr->nextaction != ev_mtd))
+			{
+         #if (DEVELOPMENT == 1)
+         #if (ELEVATORTEST == 1)
+			 Debug("\nplayer at dest requesting elev %d ras",dptr->eindex);
+			#endif
+			#endif
+			 SetNextAction(eptr,1);
+
+			}
+		break;
+
+	 case ev_doorclosing:
+		if (eptr->doorclosing == dnum)      // if opening door at current loc,
+														// reset elev state to ready
+		  {//if (eptr->door1 == dnum)
+			// eptr->nextaction = ev_ras;
+			//else
+			 //eptr->nextaction = ev_rad;
+		  }
+		else                                //else prepare for movement
+		  {if ((eptr->door1 == dnum) && (eptr->nextaction != ev_mts))
+			  {
+            #if ((DEVELOPMENT == 1))
+            #if ((ELEVATORTEST == 1))
+				Debug("\nplayer at source requesting elev %d dc",dptr->eindex);
+				#endif
+				#endif
+				SetNextAction(eptr,0);
+
+			  }
+			else if ((eptr->door2 == dnum) && (eptr->nextaction != ev_mtd))
+			  {
+            #if ((DEVELOPMENT == 1))
+            #if ((ELEVATORTEST == 1))
+				Debug("\nplayer at dest requesting elev %d dc",dptr->eindex);
+				#endif
+				#endif
+				SetNextAction(eptr,1);
+
+			  }
+		  }
+	  break;
+
+
+	 }
+
+}
+
+
+int SetNextAction(elevator_t*eptr,int action)
+{int dn;
+
+ if (action)
+	{if (!DoorReadyToClose(eptr->door1))
+	  return false;
+
+	 eptr->nextaction = ev_mtd;
+	 dn = eptr->door1;
+	}
+ else
+	{if (!DoorReadyToClose(eptr->door2))
+	  return false;
+
+	 eptr->nextaction = ev_mts;
+	 dn = eptr->door2;
+	}
+ eptr->state = ev_doorclosing;
+
+ eptr->doorclosing = dn;
+ #if (DEVELOPMENT == 1)
+ #if (ELEVATORTEST == 1)
+	Debug("\nCloseDoor %d",dn);
+ #endif
+ #endif
+ if (doorobjlist[dn]->action != dr_closed)
+  CloseDoor(dn);
+ doorobjlist[dn]->flags |= DF_ELEVLOCKED;
+
+ return true;
+}
+
+
+void OperateElevatorSwitch(objtype*ob,int elevnum,int checkx,int checky)
+{elevator_t*eptr;
+ doorobj_t *door1,*door2;
+
+ eptr = &ELEVATOR[elevnum];
+
+ if ((eptr->state == ev_mts) ||
+	  (eptr->state == ev_mtd))
+	{
+    #if (DEVELOPMENT == 1)
+    #if (ELEVATORTEST == 1)
+	 Debug("\nobj %d tried to use elevator %d switch while in use",ob->obclass,elevnum);
+	 #endif
+	 #endif
+	 return;
+	}
+
+ door1 = doorobjlist[eptr->door1];
+ door2 = doorobjlist[eptr->door2];
+
+ if ((abs(ob->tilex-door1->tilex)<=1) && //switch at source
+	  (abs(ob->tiley-door1->tiley)<=1))
+	{if (!SetNextAction(eptr,1)) // set next to dest
+		return;
+    #if (DEVELOPMENT == 1)
+    #if (ELEVATORTEST == 1)
+	 Debug("\nswitch at src %d flipped",elevnum);
+	 #endif
+	 #endif
+	 eptr->ticcount = 0;
+	}
+ else //switch at dest
+	{if (!SetNextAction(eptr,0)) // set next to src
+		return;
+    #if (DEVELOPMENT == 1)
+    #if (ELEVATORTEST == 1)
+	 Debug("\nswitch at dest %d flipped",elevnum);
+	 #endif
+	 #endif
+	 eptr->ticcount = 0;
+	}
+
+ tilemap[checkx][checky] = (elevatorstart + 6) | 0x2000;
+ SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
+
+}
+
+
+
+
+/*
+=====================
+=
+= MoveDoors
+=
+= Called from PlayLoop
+=
+=====================
+*/
+
+void MoveDoors (void)
+{
+	int		door;
+
+	for (door = 0 ; door < doornum ; door++)
+		switch (doorobjlist[door]->action)
+		{
+		case dr_open:
+			DoorOpen (door);
+			break;
+
+		case dr_opening:
+			DoorOpening(door);
+         SD_PanRTP ( doorobjlist[door]->soundhandle, doorobjlist[door]->tilex<<16, doorobjlist[door]->tiley<<16 );
+			break;
+
+		case dr_closing:
+			DoorClosing(door);
+         SD_PanRTP ( doorobjlist[door]->soundhandle, doorobjlist[door]->tilex<<16, doorobjlist[door]->tiley<<16 );
+			break;
+		default:
+		    ;
+		}
+}
+
+
+//===========================================================
+//
+//                   PUSHWALLS
+//
+//===========================================================
+
+
+/*
+===============
+=
+= GetAreaNumber
+=
+===============
+*/
+int GetAreaNumber ( int tilex, int tiley, int dir )
+{
+   int up,dn,lt,rt;
+
+   up=MAPSPOT(tilex,tiley-1,0)-AREATILE;
+   dn=MAPSPOT(tilex,tiley+1,0)-AREATILE;
+   lt=MAPSPOT(tilex-1,tiley,0)-AREATILE;
+   rt=MAPSPOT(tilex+1,tiley,0)-AREATILE;
+   if ((up<=0) || (up>NUMAREAS)) up=0;
+   if ((dn<=0) || (dn>NUMAREAS)) dn=0;
+   if ((lt<=0) || (lt>NUMAREAS)) lt=0;
+   if ((rt<=0) || (rt>NUMAREAS)) rt=0;
+	switch (dir)
+		{
+		case north:
+			if (up)
+				return up;
+			else if (dn)
+				return dn;
+			break;
+		case south:
+			if (dn)
+				return dn;
+			else if (up)
+				return up;
+			break;
+		case east:
+			if (rt)
+				return rt;
+			else if (lt)
+				return lt;
+			break;
+		case west:
+			if (lt)
+				return lt;
+			else if (rt)
+				return rt;
+			break;
+		}
+	if (up)
+		return up;
+	else if (dn)
+		return dn;
+	else if (lt)
+		return lt;
+	else if (rt)
+		return rt;
+	else
+		Error("Cannot find an area number for tile at x=%d y=%d\n",tilex,tiley);
+	return -1;
+}
+
+/*
+===============
+=
+= SpawnPushWall
+=
+===============
+*/
+
+void SpawnPushWall (int tilex, int tiley, int lock, int texture, int dir, int type)
+{
+   pwallobj_t * lastpwallobj;
+
+	if (pwallnum==MAXPWALLS)
+		Error ("MAXPWALLS on level!");
+
+   pwallobjlist[pwallnum]=(pwallobj_t*)Z_LevelMalloc(sizeof(pwallobj_t),PU_LEVELSTRUCT,NULL);
+   memset(pwallobjlist[pwallnum],0,sizeof(pwallobj_t));
+   lastpwallobj=pwallobjlist[pwallnum];
+
+	lastpwallobj->x = (tilex<<16)+0x8000;
+	lastpwallobj->y = (tiley<<16)+0x8000;
+   lastpwallobj->momentumx=0;
+   lastpwallobj->momentumy=0;
+   lastpwallobj->tilex = tilex;
+   lastpwallobj->tiley = tiley;
+	lastpwallobj->lock = lock;
+	lastpwallobj->action = pw_npushed;
+	lastpwallobj->which = PWALL;
+	lastpwallobj->dir = dir;
+   lastpwallobj->num = pwallnum;
+	actorat[tilex][tiley] = (pwallobj_t*)(lastpwallobj);	// consider it a solid wall
+
+   if ( (MAPSPOT(tilex,tiley,0)==44) ||
+        (MAPSPOT(tilex,tiley,0)==233)
+      )
+      lastpwallobj->flags=PW_DAMAGE;
+
+	lastpwallobj->texture = texture;
+   if (!texture&0x1000)
+	   PreCacheLump(texture,PU_CACHEWALLS,cache_pic_t);
+   lastpwallobj->areanumber = GetAreaNumber(tilex,tiley,lastpwallobj->dir);
+
+   MAPSPOT (tilex, tiley, 0)=(word)(lastpwallobj->areanumber+AREATILE);
+
+   switch(type)
+      {
+      case 0:
+      case 1:
+		case 3:
+	      lastpwallobj->speed = 2;
+         break;
+      case 2:
+      case 4:
+	      lastpwallobj->speed = 4;
+         break;
+      default:
+         Error("Illegal PushWall type passed into SpawnPushWall\n");
+         break;
+      }
+   if (type>2)
+      {
+      tilemap[tilex][tiley] = 0;
+	   ActivateMoveWall(pwallnum);
+      }
+   else
+      {
+      tilemap[tilex][tiley] = texture|0x800;
+      if ((loadedgame==false) && (type==0))
+         gamestate.secrettotal++;
+      }
+
+	pwallnum++;
+	lastpwallobj++;
+
+	SD_PreCacheSoundGroup(SD_PUSHWALLSND,SD_TURBOWALLSND);
+}
+
+
+
+/*
+=====================
+=
+= OperatePushWall
+=
+= The player wants to change the pushwall's direction
+=
+=====================
+*/
+void OperatePushWall (int pwall, int dir, boolean localplayer )
+{
+   pwallobj_t * pw;
+
+   pw=pwallobjlist[pwall];
+
+   if (pw->lock)
+		{
+      if ( localplayer )
+         {
+         // Can't push
+         AddMessage("This push wall appears to be locked...",MSG_DOOR);
+         PlayNoWaySound();
+         }
+		return;
+		}
+	switch (pw->action)
+	   {
+	   case pw_npushed:
+         if ((dir!=pw->dir) && (pw->dir!=nodir))
+            {
+            // Can't push
+            if ( localplayer )
+               {
+               PlayNoWaySound();
+               }
+            return;
+            }
+         else if (localplayer && (gamestate.difficulty == gd_baby))
+            AddMessage("Push Wall Activated.",MSG_GAME);
+
+         pw->action=pw_pushing;
+         pw->dir=dir;
+         SD_PlaySoundRTP ( SD_TOUCHPLATESND, pw->x, pw->y );
+         ConnectPushWall(pwall);
+         SetupPushWall(pwall);
+   	   gamestate.secretcount++;
+		   break;
+	   default:
+         // Can't push
+         if ( localplayer )
+            {
+            PlayNoWaySound();
+            }
+		   break;
+	   }
+}
+
+/*
+=====================
+=
+= ActivateAllPushWalls
+=
+= A Push wall has beeen activated by a touch plate
+=
+=====================
+*/
+
+void ActivateAllPushWalls(void)
+   {
+   int i;
+
+   for(i=0;i<pwallnum;i++)
+      {
+      if (pwallobjlist[i]->dir != nodir)
+         {
+         ActivatePushWall(i);
+         }
+      }
+   }
+
+/*
+=====================
+=
+= ActivatePushWall
+=
+= A Push wall has beeen activated by a touch plate
+=
+=====================
+*/
+
+void ActivatePushWall (long pwall)
+{
+   pwallobj_t * pw;
+
+   pw=pwallobjlist[pwall];
+
+	switch (pw->action)
+	{
+	case pw_npushed:
+      pw->action=pw_pushing;
+      ConnectPushWall(pwall);
+      SetupPushWall(pwall);
+   	gamestate.secretcount++;
+		break;
+	default:
+      // Can't push
+      SD_Play( SD_BADTOUCHSND );
+		break;
+	}
+}
+
+/*
+=====================
+=
+= ActivateMoveWall
+=
+= A Push wall has beeen activated by a touch plate
+=
+=====================
+*/
+
+void ActivateMoveWall (long pwall)
+{
+   pwallobj_t * pw;
+
+   pw=pwallobjlist[pwall];
+
+	switch (pw->action)
+	{
+	case pw_npushed:
+      pw->action=pw_moving;
+      SetupPushWall(pwall);
+      break;
+	default:
+      SD_Play( SD_BADTOUCHSND );
+		break;
+	}
+}
+
+
+
+/*
+===============
+=
+= ConnectPushWall
+=
+===============
+*/
+
+void ConnectPushWall (int pwall)
+{
+	int      checkx;
+	int      checky;
+	int		area1,area2;
+	int		area3,area4;
+	word  	*map;
+	pwallobj_t * pw;
+
+	pw=pwallobjlist[pwall];
+
+	checkx=pw->tilex;
+	checky=pw->tiley;
+	tilemap[checkx][checky] = 0;
+	map = &MAPSPOT (checkx, checky, 0);
+
+	area1 =	*(map-mapwidth);
+	area2 =	*(map+mapwidth);
+	area3 =  *(map+1);
+	area4 =  *(map-1);
+
+	area1 -= AREATILE;
+	area2 -= AREATILE;
+	area3 -= AREATILE;
+	area4 -= AREATILE;
+	if (((area1>0) && (area1<NUMAREAS)) &&
+		 ((area2>0) && (area2<NUMAREAS)))
+		{
+		areaconnect[area1][area2]++;
+		areaconnect[area2][area1]++;
+
+		if ((insetupgame==false) && (loadedgame==false))
+			ConnectAreas ();
+		}
+	if (((area3>0) && (area3<NUMAREAS)) &&
+		 ((area4>0) && (area4<NUMAREAS)))
+		{
+		areaconnect[area3][area4]++;
+		areaconnect[area4][area3]++;
+
+		if ((insetupgame==false) && (loadedgame==false))
+			ConnectAreas ();
+		}
+}
+
+/*
+===============
+=
+= SetupPushWall
+=
+===============
+*/
+
+void SetupPushWall (int pwall)
+{
+	pwallobj_t * pw;
+	int speed;
+
+	pw=pwallobjlist[pwall];
+	speed=pw->speed<<PUSHWALLSPEED;
+	switch (pw->dir)
+	{
+	case north:
+		pw->momentumx=0;
+		pw->momentumy=-speed;
+		break;
+
+	case east:
+		pw->momentumx=speed;
+		pw->momentumy=0;
+		break;
+
+	case northeast:
+		pw->momentumx=speed;
+		pw->momentumy=-speed;
+		break;
+
+	case southeast:
+		pw->momentumx=speed;
+		pw->momentumy=speed;
+		break;
+
+	case south:
+		pw->momentumx=0;
+		pw->momentumy=speed;
+		break;
+
+	case west:
+		pw->momentumx=-speed;
+		pw->momentumy=0;
+		break;
+
+	case northwest:
+		pw->momentumx=-speed;
+		pw->momentumy=-speed;
+		break;
+
+	case southwest:
+		pw->momentumx=-speed;
+		pw->momentumy=speed;
+		break;
+	}
+	if (pw->action==pw_pushing)
+		{
+      if (loadedgame==false)
+         pw->soundhandle=SD_PlaySoundRTP ( SD_PUSHWALLSND, pw->x, pw->y );
+      pw->state=(0x20000L/speed);
+		}
+	if (pw->action==pw_moving)
+      pw->state=(0x10000L/speed);
+}
+
+
+/*
+=====================
+=
+= MovePWalls
+=
+= Called from PlayLoop
+=
+=====================
+*/
+
+void MovePWalls (void)
+{
+	int		pwall;
+
+	for (pwall = 0 ; pwall < pwallnum ; pwall++)
+		{
+		if (pwallobjlist[pwall]->action==pw_pushing)
+			{
+			WallPushing (pwall);
+			SD_PanRTP (pwallobjlist[pwall]->soundhandle, pwallobjlist[pwall]->x, pwallobjlist[pwall]->y );
+			}
+		if (pwallobjlist[pwall]->action==pw_moving)
+			{
+			WallMoving (pwall);
+			SD_PanRTP (pwallobjlist[pwall]->soundhandle, pwallobjlist[pwall]->x, pwallobjlist[pwall]->y );
+			}
+		}
+}
+
+
+void ClearActorat(pwallobj_t*pw)
+{int txhigh,txlow,tyhigh,tylow;
+ int tryx,tryy,x,y;
+ int pwrad = 0x6fff;
+
+
+ tryx = pw->x;
+ tryy = pw->y;
+ txlow = (tryx - pwrad) >> 16;
+ txhigh = (tryx + pwrad) >> 16;
+ tylow = (tryy - pwrad) >> 16;
+ tyhigh = (tryy + pwrad) >> 16;
+ for(y=tylow;y<=tyhigh;y++)
+	 for(x=txlow;x<=txhigh;x++)
+		{if (actorat[x][y] == pw)
+			actorat[x][y] = NULL;
+		}
+}
+
+void SetActorat(pwallobj_t*pw)
+{int txhigh,txlow,tyhigh,tylow;
+ int tryx,tryy,x,y;
+ int pwrad = 0x6fff;
+
+ tryx = pw->x;
+ tryy = pw->y;
+ txlow = (tryx - pwrad) >> 16;
+ txhigh = (tryx + pwrad) >> 16;
+ tylow = (tryy - pwrad) >> 16;
+ tyhigh = (tryy + pwrad) >> 16;
+
+ for(y=tylow;y<=tyhigh;y++)
+	 for(x=txlow;x<=txhigh;x++)
+		actorat[x][y] = pw;
+}
+
+/*
+=================
+=
+= FinishPushWall
+=
+=================
+*/
+void FinishPushWall (pwallobj_t * pw)
+{
+   pw->action = pw_pushed;
+   actorat[pw->tilex][pw->tiley] = (wall_t*)&walls[GetWallIndex(pw->texture)];
+   tilemap[pw->tilex][pw->tiley] = pw->texture;
+}
+
+/*
+=================
+=
+= ResetPushWall
+=
+=================
+*/
+void ResetPushWall (pwallobj_t * pw)
+{
+   SetActorat(pw);
+   tilemap[pw->tilex][pw->tiley] = pw->texture|0x800;
+}
+
+/*
+=================
+=
+= WallPushing
+=
+=================
+*/
+void WallPushing (int pwall)
+{
+	int      checkx,checky;
+	int      spot;
+	pwallobj_t * pw;
+
+	pw=pwallobjlist[pwall];
+
+   ClearActorat(pw);
+
+	PushWallMove(pwall);
+	pw->x+=pw->momentumx;
+	pw->y+=pw->momentumy;
+
+	pw->state--;
+
+	checkx=pw->tilex;
+	checky=pw->tiley;
+
+	pw->tilex=pw->x>>16;
+	pw->tiley=pw->y>>16;
+
+	if ((pw->tilex!=checkx) || (pw->tiley!=checky))
+		{
+		int x,y;
+		int area = MAPSPOT(pw->tilex,pw->tiley,0)-AREATILE;
+
+		if ((area<=0) || (area>NUMAREAS))
+			{
+			area=pw->areanumber;
+			MAPSPOT (pw->tilex, pw->tiley, 0)=(word)(pw->areanumber+AREATILE);
+			}
+		// block crossed into a new block
+		//
+		// the tile can now be walked into
+		//
+		mapseen[checkx][checky] = 0;
+		pw->areanumber = area;
+		if (pw->momentumx>0)
+			x=1;
+		else if (pw->momentumx<0)
+			x=-1;
+		else
+			x=0;
+		if (pw->momentumy>0)
+			y=1;
+		else if (pw->momentumy<0)
+			y=-1;
+		else
+			y=0;
+		if (tilemap[pw->tilex+x][pw->tiley+y])
+			{
+			pw->state=(0x8000L/(pw->speed<<PUSHWALLSPEED));
+			}
+		if (actorat[pw->tilex+x][pw->tiley+y])
+		  ResolveDoorSpace(pw->tilex+x,pw->tiley+y);
+		}
+
+
+	if (pw->state==0)
+		{
+		pw->x=(pw->tilex<<16)+0x8000;
+		pw->y=(pw->tiley<<16)+0x8000;
+		spot = MAPSPOT(pw->tilex,pw->tiley,1)-ICONARROWS;
+		if ((spot >= 0) && (spot <= 7))
+			{
+         pw->action = pw_npushed;
+			pw->dir = spot;
+         ResetPushWall (pw);
+         if (pw->lock)
+				{
+            pw->action=pw_pushing;
+				ConnectPushWall(pwall);
+				SetupPushWall(pwall);
+				}
+         else
+            {
+            gamestate.secrettotal++;
+            }
+         }
+		else
+			{
+         FinishPushWall (pw);
+			}
+		}
+   else
+      SetActorat(pw);
+}
+
+
+/*
+=================
+=
+= WallMoving
+=
+=================
+*/
+void WallMoving (int pwall)
+{
+	int      checkx,checky;
+	int      spot;
+	pwallobj_t * pw;
+
+	pw=pwallobjlist[pwall];
+
+   ClearActorat(pw);
+
+	PushWallMove(pwall);
+	pw->x+=pw->momentumx;
+	pw->y+=pw->momentumy;
+
+	pw->state--;
+
+	checkx=pw->tilex;
+	checky=pw->tiley;
+
+	pw->tilex=pw->x>>16;
+	pw->tiley=pw->y>>16;
+
+	if ((pw->tilex!=checkx) || (pw->tiley!=checky))
+		{
+		int area = MAPSPOT(pw->tilex,pw->tiley,0)-AREATILE;
+
+		if ((area<=0) || (area>NUMAREAS))
+			{
+			area=pw->areanumber;
+			MAPSPOT (pw->tilex, pw->tiley, 0)=(word)(pw->areanumber+AREATILE);
+			}
+		// block crossed into a new block
+		//
+		// the tile can now be walked into
+		//
+		if (areabyplayer[area])
+			{
+			if (pw->speed==2)
+				pw->soundhandle=SD_PlaySoundRTP ( SD_GOWALLSND, pw->x, pw->y );
+			else
+				pw->soundhandle=SD_PlaySoundRTP ( SD_TURBOWALLSND, pw->x, pw->y );
+			}
+
+		if (actorat[pw->tilex][pw->tilex])
+		  ResolveDoorSpace(pw->tilex,pw->tiley);
+		mapseen[checkx][checky] = 0;
+		pw->areanumber = MAPSPOT (pw->tilex, pw->tiley, 0)-AREATILE;
+		//actorat[pw->tilex][pw->tiley]=pw;
+		if ( (pw->tilex==0) || (pw->tilex==127) ||
+			  (pw->tiley==0) || (pw->tiley==127) )
+			{
+         if (W_CheckNumForName("imfree")>=0)
+            {
+            lbm_t *LBM;
+
+            LBM = (lbm_t *) W_CacheLumpNum (W_GetNumForName ("imfree"), PU_CACHE, Cvt_lbm_t, 1);
+            VL_DecompressLBM (LBM,true);
+            VW_UpdateScreen ();
+            I_Delay (2000);
+            }
+			Error ("PushWall Attempting to escape off the edge of the map\nIt is located at x=%d y=%d\nI'm Free!!!!\n",
+					  pw->tilex, pw->tiley);
+			}
+		}
+	if (pw->state==0)
+		{
+		pw->x=(pw->tilex<<16)+0x8000;
+		pw->y=(pw->tiley<<16)+0x8000;
+		spot = MAPSPOT(pw->tilex,pw->tiley,1)-ICONARROWS;
+		if ((spot >= 0) && (spot <= 7))
+			{
+			int area = MAPSPOT(pw->tilex,pw->tiley,0)-AREATILE;
+
+			if ((area<=0) || (area>NUMAREAS))
+				{
+				area=pw->areanumber;
+				MAPSPOT (pw->tilex, pw->tiley, 0)=(word)(pw->areanumber+AREATILE);
+				}
+
+			if (areabyplayer[area] && (abs(spot-pw->dir)==4))
+				SD_PlaySoundRTP ( SD_PUSHWALLHITSND, pw->x, pw->y );
+			pw->dir = spot;
+			}
+		SetupPushWall(pwall);
+		}
+   else
+      SetActorat(pw);
+}
+
+
+
+/*
+=================
+=
+= SavePushWalls
+=
+=================
+*/
+void SavePushWalls(byte ** buf, int * sz)
+{
+  int unitsize;
+  pwallobj_t * pw;
+  byte * bufptr;
+  int i;
+  int size;
+
+  if (pwallnum==0)
+	  {
+	  *sz=0;
+	  *buf=SafeMalloc(16);
+	  return;
+	  }
+  pw=pwallobjlist[0];
+  unitsize=0;
+  unitsize+=sizeof(pw->state);
+  unitsize+=sizeof(pw->x);
+  unitsize+=sizeof(pw->y);
+  unitsize+=sizeof(pw->dir);
+  unitsize+=sizeof(pw->speed);
+  unitsize+=sizeof(pw->action);
+
+  *sz=pwallnum*unitsize;
+
+  *buf=SafeMalloc(*sz);
+  bufptr=*buf;
+
+  for (i=0;i<pwallnum;i++)
+     {
+     pw=pwallobjlist[i];
+     size=sizeof(pw->state);
+     memcpy(bufptr,&(pw->state),size);
+     bufptr+=size;
+
+     size=sizeof(pw->x);
+     memcpy(bufptr,&(pw->x),size);
+     bufptr+=size;
+
+     size=sizeof(pw->y);
+     memcpy(bufptr,&(pw->y),size);
+     bufptr+=size;
+
+     size=sizeof(pw->dir);
+     memcpy(bufptr,&(pw->dir),size);
+     bufptr+=size;
+
+     size=sizeof(pw->speed);
+     memcpy(bufptr,&(pw->speed),size);
+     bufptr+=size;
+
+     size=sizeof(pw->action);
+     memcpy(bufptr,&(pw->action),size);
+     bufptr+=size;
+     }
+}
+
+/*
+=================
+=
+= LoadPushWalls
+=
+=================
+*/
+void LoadPushWalls(byte * bufptr, int sz)
+{
+  int unitsize;
+  pwallobj_t * pw;
+  pwallobj_t new;
+  int i;
+  int num;
+  int size;
+  int area;
+
+  if (sz==0)
+     return;
+  SetupPushWalls();
+  pw=pwallobjlist[0];
+  unitsize=0;
+  unitsize+=sizeof(pw->state);
+  unitsize+=sizeof(pw->x);
+  unitsize+=sizeof(pw->y);
+  unitsize+=sizeof(pw->dir);
+  unitsize+=sizeof(pw->speed);
+  unitsize+=sizeof(pw->action);
+
+  num=sz/unitsize;
+  if (pwallnum!=num)
+     Error("Different number of Push Walls when trying to load a game\npwallnum=%d num=%d",pwallnum,num);
+
+  for (i=0;i<pwallnum;i++)
+     {
+     pw=pwallobjlist[i];
+
+     size=sizeof(new.state);
+     memcpy(&(new.state),bufptr,size);
+     bufptr+=size;
+
+     size=sizeof(new.x);
+     memcpy(&(new.x),bufptr,size);
+     bufptr+=size;
+
+     size=sizeof(new.y);
+     memcpy(&(new.y),bufptr,size);
+     bufptr+=size;
+
+     size=sizeof(new.dir);
+     memcpy(&(new.dir),bufptr,size);
+     bufptr+=size;
+
+     size=sizeof(new.speed);
+     memcpy(&(new.speed),bufptr,size);
+     bufptr+=size;
+
+     size=sizeof(new.action);
+     memcpy(&(new.action),bufptr,size);
+     bufptr+=size;
+
+	  actorat[pw->tilex][pw->tiley] = 0;
+     mapseen[pw->tilex][pw->tiley] = 0;
+
+     new.tilex=new.x>>16;
+     new.tiley=new.y>>16;
+
+     if ((new.tilex!=pw->tilex) || (new.tiley!=pw->tiley))
+        {
+        ClearActorat(pw);
+        tilemap[pw->tilex][pw->tiley] = 0;
+        if (pw->state!=pw_moving)
+           {
+#if 0
+           if (pw->dir==nodir)
+              {
+              if (tilemap[pw->tilex+1][pw->tiley]==0)
+                 pw->dir=east;
+              else if (tilemap[pw->tilex-1][pw->tiley]==0)
+                 pw->dir=west;
+              else if (tilemap[pw->tilex][pw->tiley+1]==0)
+                 pw->dir=south;
+              else
+                 pw->dir=north;
+              }
+#endif
+           ConnectPushWall(i);
+           }
+        }
+
+//   fixup area if needed
+
+     area = MAPSPOT(new.tilex,new.tiley,0)-AREATILE;
+     if ((area<=0) || (area>NUMAREAS))
+        {
+        MAPSPOT (new.tilex, new.tiley, 0)=(word)(pw->areanumber+AREATILE);
+        }
+
+     pw->tilex=new.tilex;
+     pw->tiley=new.tiley;
+     pw->x=new.x;
+     pw->y=new.y;
+     pw->action=new.action;
+     pw->dir=new.dir;
+     pw->speed=new.speed;
+     SetupPushWall(i);
+     pw->state=new.state;
+
+     pw->areanumber = MAPSPOT (pw->tilex, pw->tiley, 0)-AREATILE;
+
+     if (pw->action==pw_pushed)
+        {
+        FinishPushWall (pw);
+        }
+     else if (pw->action==pw_npushed)
+        {
+        ResetPushWall (pw);
+        }
+     else
+        {
+        SetActorat(pw);
+        }
+     }
+}
+
+
+
+
+
+/*
+=================
+=
+= SaveMaskedWalls
+=
+=================
+*/
+void SaveMaskedWalls(byte ** buf, int * size)
+{
+  int unitsize;
+  maskedwallobj_t * mw;
+  byte * bufptr;
+  int i;
+  int sz;
+
+  if (maskednum==0)
+     {
+     *size=0;
+     *buf=SafeMalloc(16);
+     return;
+     }
+  mw=maskobjlist[0];
+  unitsize=0;
+  unitsize+=sizeof(mw->flags);
+
+  *size=maskednum*unitsize;
+
+  *buf=SafeMalloc(*size);
+  bufptr=*buf;
+
+  for (i=0;i<maskednum;i++)
+     {
+     mw=maskobjlist[i];
+     sz=sizeof(mw->flags);
+     memcpy(bufptr,&(mw->flags),sz);
+     bufptr+=sz;
+     }
+}
+
+/*
+=================
+=
+= LoadMaskedWalls
+=
+=================
+*/
+void LoadMaskedWalls(byte * bufptr, int sz)
+{
+  int unitsize;
+  maskedwallobj_t * mw;
+  int i;
+  int size;
+  int num;
+
+  if (sz==0)
+     return;
+
+  SetupMaskedWalls();
+  FixMaskedWallAreaNumbers();
+
+  mw=maskobjlist[0];
+  unitsize=0;
+  unitsize+=sizeof(mw->flags);
+
+  num=sz/unitsize;
+  if (maskednum!=num)
+     Error("Different number of Masked Walls when trying to load a game\nmaskednum=%d num=%d",maskednum,num);
+
+  for (i=0;i<maskednum;i++)
+     {
+     word flags;	// Endianness fix thanks to DrLex - DDOI
+
+     mw=maskobjlist[i];
+     size=sizeof(mw->flags);
+     memcpy(&flags,bufptr,size);
+     bufptr+=size;
+     if ((flags&0xff)!=mw->flags)	// Preserves original behavior
+        UpdateMaskedWall(i);
+     if (mw->flags&MW_SWITCHON)
+        mw->toptexture--;
+     }
+}
+
+
+/*
+=================
+=
+= SaveDoors
+=
+=================
+*/
+
+void SaveDoors (byte ** buf, int * size)
+{
+   int door;
+   int doorsave;
+   byte doorflag;
+   byte doorlocked;
+   signed char dooreindex;
+   short int doortime;
+   int unitsize;
+   byte *ptr;
+
+   if (doornum==0)
+      {
+      *size=0;
+      *buf=SafeMalloc(16);
+      return;
+      }
+
+   //
+   // Size = (int + byte + byte) * numdoors
+   //
+
+   unitsize=0;
+   unitsize+=sizeof(doorsave);
+   unitsize+=sizeof(doorflag);
+   unitsize+=sizeof(doorlocked);
+   unitsize+=sizeof(doortime);
+   unitsize+=sizeof(dooreindex);
+
+   *size = unitsize*doornum;
+   *buf = (byte *) SafeMalloc (*size);
+
+   ptr = *buf;
+
+	for (door = 0; door < doornum ; door++)
+   {
+      doorsave   = doorobjlist[door]->position & ~3;
+      doorsave  |= doorobjlist[door]->action;
+      doorflag   = doorobjlist[door]->flags;
+      doorlocked = doorobjlist[door]->lock;
+      doortime   = doorobjlist[door]->ticcount;
+      dooreindex = doorobjlist[door]->eindex;
+
+      memcpy (ptr, &doorsave, sizeof (doorsave));
+      ptr += sizeof (doorsave);
+      memcpy (ptr, &doorflag, sizeof (doorflag));
+      ptr += sizeof (doorflag);
+      memcpy (ptr, &doorlocked, sizeof (doorlocked));
+      ptr += sizeof (doorlocked);
+      memcpy (ptr, &doortime, sizeof (doortime));
+      ptr += sizeof (doortime);
+      memcpy (ptr, &dooreindex, sizeof (dooreindex));
+      ptr += sizeof (dooreindex);
+   }
+}
+
+
+/*
+=================
+=
+= LoadDoors
+=
+=================
+*/
+
+void LoadDoors (byte * buf, int size)
+{
+   int door;
+   int doorsave;
+   byte doorflag;
+   byte doorlocked;
+   signed char dooreindex;
+   short int doortime;
+   byte *ptr;
+   int unitsize;
+   int num;
+
+   SetupDoors ();
+   FixDoorAreaNumbers();
+   ptr  = buf;
+
+   unitsize=0;
+   unitsize+=sizeof(doorsave);
+   unitsize+=sizeof(doorflag);
+   unitsize+=sizeof(doorlocked);
+   unitsize+=sizeof(doortime);
+   unitsize+=sizeof(dooreindex);
+
+   num=size/unitsize;
+   if (doornum!=num)
+      Error("Different number of Doors when trying to load a game\ndoornum=%d num=%d",doornum,num);
+
+   for (door = 0; door < doornum; door++)
+   {
+      memcpy (&doorsave, ptr, sizeof (doorsave));
+      ptr += sizeof (doorsave);
+      memcpy (&doorflag, ptr, sizeof (doorflag));
+      ptr += sizeof (doorflag);
+      memcpy (&doorlocked, ptr, sizeof (doorlocked));
+      ptr += sizeof (doorlocked);
+      memcpy (&doortime, ptr, sizeof (doortime));
+      ptr += sizeof (doortime);
+      memcpy (&dooreindex, ptr, sizeof (dooreindex));
+      ptr += sizeof (dooreindex);
+
+      doorobjlist[door]->action    = doorsave & 3;
+
+      // Update Areas
+
+      if (doorobjlist[door]->action != dr_closed)
+         DoorOpening(door);
+
+      doorobjlist[door]->action    = doorsave & 3;
+      doorobjlist[door]->position = doorsave;
+      doorobjlist[door]->flags     = doorflag;
+      doorobjlist[door]->lock      = doorlocked;
+      doorobjlist[door]->ticcount  = doortime;
+      doorobjlist[door]->eindex    = dooreindex;
+
+      if (doorobjlist[door]->action == dr_open)
+         doorobjlist[door]->position = 0xFFFF;
+
+      else if (doorobjlist[door]->action == dr_closed)
+         doorobjlist[door]->position = 0;
+
+      if (
+           (doorobjlist[door]->action == dr_closing) ||
+           (doorobjlist[door]->action == dr_closed)
+         )
+         {
+         actorat[doorobjlist[door]->tilex][doorobjlist[door]->tiley] = doorobjlist[door];
+         }
+      doorobjlist[door]->texture = doorobjlist[door]->basetexture +
+                                  ((doorobjlist[door]->position+1)>>13);
+   }
+}
+
+
+/*
+=====================
+=
+= SaveElevators
+=
+=
+=====================
+*/
+
+void SaveElevators(byte ** buffer,int *size)
+{int i;
+ byte * tptr;
+
+ *size = _numelevators*sizeof(elevator_t);
+
+ *buffer = (byte *)SafeMalloc(*size);
+ tptr = *buffer;
+
+ for(i=0;i<_numelevators;i++)
+  {memcpy(tptr,&ELEVATOR[i],sizeof(elevator_t));
+	tptr += sizeof(elevator_t);
+  }
+}
+
+
+/*
+=====================
+=
+= LoadElevators
+=
+=
+=====================
+*/
+
+void LoadElevators(byte * buffer,int size)
+{int i;
+
+ _numelevators = size/sizeof(elevator_t);
+
+
+ for(i=0;i<_numelevators;i++)
+  {memcpy(&ELEVATOR[i],buffer,sizeof(elevator_t));
+	buffer += sizeof(elevator_t);
+  }
+}
+

Added: tags/rott-1.1/rott/rt_door.h
===================================================================
--- tags/rott-1.1/rott/rt_door.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_door.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,270 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_door_public
+#define _rt_door_public
+
+//***************************************************************************
+//
+//   RT_DOOR.C - doors
+//
+//***************************************************************************
+
+#define MAXTOUCHPLATES 64
+#define MAXMASKED      300  // max masked walls
+#define MAXDOORS       150  // max number of sliding doors
+#define MAXPWALLS      150  // max number of pushwalls
+#define DF_TIMED       0x01
+#define DF_ELEVLOCKED  0x02
+#define DF_MULTI       0x04
+#define MAXELEVATORS   16
+
+#define PW_DAMAGE      0x01
+
+#define NUMELEVATORACTIONS 5
+
+typedef enum
+{ev_ras, //ready at source
+ ev_rad, //ready at destination
+ ev_mts, //moving to source
+ ev_mtd,  //moving to destination
+			 //door at elevator location open
+ ev_doorclosing //door at elevator location closed
+}estate;
+
+typedef enum
+{
+ mw_peephole,
+ mw_dogwall,
+ mw_multi1,
+ mw_multi2,
+ mw_multi3,
+ mw_singlepane,
+ mw_normal1,
+ mw_normal2,
+ mw_normal3,
+ mw_exitarch,
+ mw_secretexitarch,
+ mw_railing,
+ mw_hiswitchon,
+ mw_hiswitchoff,
+ mw_platform1,
+ mw_platform2,
+ mw_platform3,
+ mw_platform4,
+ mw_platform5,
+ mw_platform6,
+ mw_platform7,
+ mw_entrygate
+}masked_walls;
+
+typedef struct elevator
+{ short sx,sy;
+  short dx,dy;
+  short esx,esy,edx,edy;
+  short door1,door2;
+  signed char state;
+  short doortoopen;
+  short doorclosing;
+  short ticcount;
+  short nextaction;
+}elevator_t;
+
+
+typedef struct doorstruct
+{
+		  thingtype   which;
+		  byte        tilex,tiley;
+		  word        texture;
+		  word        alttexture;
+		  word        sidepic;
+		  word        basetexture;
+		  byte        lock;
+		  byte        flags;
+		  short int   ticcount;
+		  signed char eindex;
+		  boolean     vertical;
+		  int         soundhandle;
+		  int         position;
+		  enum    {dr_open,dr_closed,dr_opening,dr_closing}       action;
+} doorobj_t;
+
+typedef struct pwallstruct
+{
+		  thingtype      which;
+		  int       x,y;
+		  int       momentumx,momentumy;
+		  byte      areanumber;
+		  byte      lock;
+		  byte      dir;
+		  byte      tilex,tiley;
+		  byte      num;
+		  byte      speed;
+		  word      texture;
+		  int       soundhandle;
+		  enum      {pw_npushed,pw_pushing,pw_pushed,pw_moving}       action;
+		  int       state;
+        byte      flags;
+} pwallobj_t;
+
+typedef struct tplate
+{ void (*action)(long);
+  void (*swapaction)(long);
+  struct tplate * nextaction;
+  struct tplate * prevaction;
+  long whichobj;
+  byte tictime;
+  byte ticcount;
+  byte triggered;
+  byte done;
+  byte complete;
+  byte clocktype;
+} touchplatetype;
+
+#define MW_SHOOTABLE       0x01
+#define MW_BLOCKING        0x02
+#define MW_MULTI           0x04
+#define MW_BLOCKINGCHANGES 0x08
+#define MW_ABOVEPASSABLE   0x10
+#define MW_NONDOGBLOCKING  0x20
+#define MW_WEAPONBLOCKING  0x40
+#define MW_BOTTOMPASSABLE  0x80
+#define MW_MIDDLEPASSABLE  0x100
+#define MW_ABP             0x200
+#define MW_SWITCHON        0x400
+#define MW_BOTTOMFLIPPING  0x800
+#define MW_TOPFLIPPING     0x1000
+#define M_ISDOOR(x,y) ((tilemap[x][y] & 0x8000) && (!(tilemap[x][y] & 0x4000)))
+#define M_ISMWALL(x,y) ((tilemap[x][y] & 0x8000) && (tilemap[x][y] & 0x4000))
+
+
+typedef struct mwall
+{
+  thingtype      which;
+  byte      tilex,tiley;
+  signed char areanumber;
+  signed short toptexture;
+  signed short midtexture;
+  signed short bottomtexture;
+  word      flags;
+  boolean   vertical;
+  int       sidepic;
+
+  struct mwall *next;
+  struct mwall *prev;
+
+} maskedwallobj_t;
+
+typedef struct animmwall
+{
+  word     num;
+  byte     count;
+  signed char ticcount;
+  struct animmwall *next;
+  struct animmwall *prev;
+
+} animmaskedwallobj_t;
+
+extern elevator_t          ELEVATOR[MAXELEVATORS];
+extern int                 _numelevators;
+extern animmaskedwallobj_t *FIRSTANIMMASKEDWALL,*LASTANIMMASKEDWALL;
+extern maskedwallobj_t     *FIRSTMASKEDWALL,*LASTMASKEDWALL;
+extern byte                touchindices[MAPSIZE][MAPSIZE],lasttouch;
+extern touchplatetype      *touchplate[MAXTOUCHPLATES],*lastaction[MAXTOUCHPLATES];
+extern byte                TRIGGER[MAXTOUCHPLATES];
+
+extern doorobj_t           *doorobjlist[MAXDOORS];
+extern int                 doornum;
+extern maskedwallobj_t     *maskobjlist[MAXMASKED];
+extern int                 maskednum;
+extern pwallobj_t          *pwallobjlist[MAXPWALLS];
+extern int                 pwallnum;
+																																			 // 0xffff = fully open
+extern byte                areaconnect[NUMAREAS][NUMAREAS];
+extern boolean             areabyplayer[NUMAREAS];
+
+
+void ActivateAllPushWalls(void);
+boolean CheckTile(int,int);
+void FindEmptyTile(int*,int*);
+int  Number_of_Empty_Tiles_In_Area_Around(int,int);
+void AddTouchplateAction(touchplatetype*,int);
+void RemoveTouchplateAction(touchplatetype*,int);
+
+void InitElevators(void);
+void ProcessElevators(void);
+void OperateElevatorDoor(int);
+
+
+int  PlatformHeight(int,int);
+void Link_To_Touchplate(word, word, void (*)(long), void (*)(long), long, int);
+void TriggerStuff(void);
+void ClockLink(void (*)(long),void(*)(long),long,int);
+void RecursiveConnect(int);
+void ConnectAreas(void);
+void InitAreas(void);
+void InitDoorList(void);
+void SpawnDoor(int,int,int,int);
+void SpawnMaskedWall (int tilex, int tiley, int which, int flags);
+void OpenDoor(int);
+void CloseDoor(int);
+void OperateDoor (int keys, int door, boolean localplayer );
+void DoorOpen(int);
+void DoorOpening(int);
+void DoorClosing(int door);
+void MoveDoors(void);
+void SpawnPushWall (int tilex, int tiley, int lock, int texture, int dir, int type);
+void MovePWalls(void);
+void WallPushing (int pwall);
+void PushWall (int pwall, int dir);
+void OperatePushWall (int pwall, int dir, boolean localplayer );
+void ActivatePushWall (long pwall);
+void ActivateMoveWall (long pwall);
+int  UpdateMaskedWall (int num);
+
+void FixDoorAreaNumbers ( void );
+void FixMaskedWallAreaNumbers ( void );
+void SaveMaskedWalls(byte ** buf, int * size);
+void LoadMaskedWalls(byte * buf, int size);
+void SaveDoors(byte ** buf, int * size);
+void SaveTouchPlates(byte ** buf, int * size);
+void LoadDoors(byte * buf, int size);
+void LoadTouchPlates(byte * buf, int size);
+void SavePushWalls(byte ** buf, int * sz);
+void LoadPushWalls(byte * bufptr, int sz);
+
+void DeactivateAnimMaskedWall(animmaskedwallobj_t* amwall);
+void ActivateAnimMaskedWall(animmaskedwallobj_t* amwall);
+
+void SpawnAnimatedMaskedWall ( int num );
+void KillAnimatedMaskedWall ( animmaskedwallobj_t * temp );
+
+void DoAnimatedMaskedWalls ( void );
+
+void SaveElevators(byte ** buffer,int *size);
+
+void LoadElevators(byte * buffer,int size);
+
+void MakeWideDoorVisible ( int doornum );
+void LinkedCloseDoor (long door);
+void LinkedOpenDoor (long door);
+int IsWall (int tilex, int tiley);
+int IsDoor (int tilex, int tiley);
+int IsMaskedWall (int tilex, int tiley);
+#endif

Added: tags/rott-1.1/rott/rt_dr_a.asm
===================================================================
--- tags/rott-1.1/rott/rt_dr_a.asm	                        (rev 0)
+++ tags/rott-1.1/rott/rt_dr_a.asm	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,483 @@
+.386p
+.model flat
+
+ SC_INDEX   =           03C4h
+ SC_DATA    =           03C5h
+ SC_RESET   =           0
+ SC_CLOCK   =           1
+ SC_MAPMASK =           2
+ CRTC_INDEX =           03D4h
+ SCREENBWIDE=           96
+ MISC_OUTPUT=           03c2h
+ CEILINGCOLOR=          24
+ FLOORCOLOR=            32
+
+.DATA
+
+loopcount       dd      0
+pixelcount      dd      0
+EXTRN    _spotvis:BYTE
+EXTRN    _viewwidth:DWORD
+EXTRN    _viewheight:DWORD
+EXTRN    _bufferofs:DWORD
+EXTRN    _fandc:DWORD
+EXTRN    _ylookup:DWORD
+EXTRN    _centery:DWORD
+EXTRN    _shadingtable:DWORD
+EXTRN    _hp_startfrac:DWORD
+EXTRN    _hp_srcstep:DWORD
+
+
+.CODE
+SEGMENT text USE32
+        ALIGN   16
+
+
+PROC   RefreshClear_
+PUBLIC RefreshClear_
+
+   pushad
+   mov     edi,OFFSET _spotvis
+   xor     eax,eax
+   mov     ecx,01000h
+; 128*128
+   rep     stosd
+
+   mov     eax,[_fandc]
+   or      eax,eax
+   jz     cont
+   popad
+   ret
+; clear the screen
+cont:
+   mov     edx,SC_DATA
+   mov     eax,15
+; write through all planes
+   out     dx,al
+   mov     edx,SCREENBWIDE
+   mov     eax,[_viewwidth]
+   shr     eax,2
+   sub     edx,eax
+
+   mov     ebx,eax
+   shr     ebx,1
+   mov     ah,CEILINGCOLOR
+   mov     al,CEILINGCOLOR
+   mov     edi,[_bufferofs]
+   mov     esi,[_centery]
+   cmp     esi,0
+   jle     skiptop
+   cmp     esi,[_viewheight]
+   jle     toploop
+   mov     esi,[_viewheight]
+toploop:
+   mov     ecx,ebx
+   rep     stosw
+   add     edi,edx
+   dec     esi
+   jnz     toploop
+skiptop:
+   mov     al,FLOORCOLOR
+   mov     ah,FLOORCOLOR
+   mov     esi,[_viewheight]
+   sub     esi,[_centery]
+   cmp     esi,0
+   jle     skipbottom
+   cmp     esi,[_viewheight]
+   jle     bottomloop
+   mov     esi,[_viewheight]
+bottomloop:
+   mov     ecx,ebx
+   rep     stosw
+   add     edi,edx
+   dec     esi
+   jnz     bottomloop
+skipbottom:
+   popad
+   ret
+
+ENDP   RefreshClear_
+
+
+
+PROC   SetMode240_
+PUBLIC SetMode240_
+
+   pushad
+   mov   dx,SC_INDEX
+   mov   ax,0604h
+        out   dx,ax                 ; disable chain4 mode
+        mov   ax,0100h
+        out   dx,ax                 ; synchronous reset while setting Misc
+                                    ;  Output for safety, even though clock
+                                    ;  unchanged
+        mov   dx,MISC_OUTPUT
+        mov   al,0e3h
+        out   dx,al                 ; select the dot clock and Horiz
+        mov   dx,SC_INDEX
+        mov   ax,0300h
+        out   dx,ax                ; undo reset (restart sequencer)
+
+
+        mov   dx,CRTC_INDEX       ; reprogram the CRT Controller
+        mov   al,11h              ; VSync End reg contains register write
+        out   dx,al               ; protect bit
+        inc   dx                  ; CRT Controller Data register
+        in    al,dx               ; get current VSync End register setting
+        and   al,07fh             ; remove write protect on various
+        out   dx,al               ; CRTC registers
+        dec   dx                  ; CRT Controller Index
+        cld
+        mov   ax,00d06h
+        out   dx,ax
+        mov   ax,03e07h
+        out   dx,ax
+        mov   ax,04109h
+        out   dx,ax
+        mov   ax,0ea10h
+        out   dx,ax
+        mov   ax,0ac11h
+        out   dx,ax
+        mov   ax,0df12h
+        out   dx,ax
+        mov   ax,00014h
+        out   dx,ax
+        mov   ax,0e715h
+        out   dx,ax
+        mov   ax,00616h
+        out   dx,ax
+        mov   ax,0e317h
+        out   dx,ax
+        mov   ax,0f02h
+        mov   dx,SC_INDEX
+        out   dx,ax
+        mov   edi,0a0000h
+        mov   eax,0
+        mov   ecx,08000h
+        cld
+        rep   stosw
+
+   popad
+   ret
+
+ENDP   SetMode240_
+
+;----------------------------------------------------------------------------
+;
+; DrawPost - Draws an unmasked post centered in the viewport
+;
+;            ecx - height to scale post to
+;            esi - source pointer to proper column (x offsetted)
+;            edi - destination pointer to proper screen column (xoffsetted)
+;
+;----------------------------------------------------------------------------
+
+
+PROC    DrawPost_
+PUBLIC  DrawPost_
+
+; ECX - loop variable (height and counter)
+; EDI - top offset + bufferofs
+; EDX - destination offset
+; EBX - high word contains bottom offset, low word contains source data
+; EBP - fraction
+
+  push ebp
+  SETFLAG ecx,ecx
+  jz    donedraw
+  mov   edx,0
+  mov   eax,32*65536
+  div   ecx
+  mov   edx,eax
+; edx holds fractional step
+  mov   [DWORD PTR patch1],edx
+  mov   ebp,edx
+  shr   ebp,1
+  mov   eax,[_centery]
+  add   edi,[_ylookup+4*eax]
+  mov   edx,edi
+  sub   edi,SCREENBWIDE
+  mov   ebx,[_shadingtable]
+  cmp   ecx,eax
+  jle   heightok
+  mov   ecx,eax
+heightok:        ; height is ok.. < viewheigth
+
+ALIGN 16
+
+drawloop:
+  mov   eax,ebp
+  shr   eax,16
+  mov   ax,[WORD PTR esi+eax*2]
+patch1 equ $+2
+  add   ebp,12345678h
+  mov   bl,al
+  mov   al,[ebx]
+  mov   [edi],al
+  mov   bl,ah
+  sub   edi,SCREENBWIDE
+  mov   ah,[ebx]
+  mov   [edx],ah
+  add   edx,SCREENBWIDE
+  dec   ecx
+  jnz   drawloop
+
+donedraw:
+  pop   ebp
+  ret
+
+ENDP DrawPost_
+
+
+
+;============================
+;
+; DrawHeightPost
+;
+;============================
+
+IDEAL
+        ALIGN 16
+PROC	DrawHeightPost_
+PUBLIC	DrawHeightPost_
+
+;EDI - Destination for post
+;ESI - Source data
+;ECX - Length of post
+;EBX - shadingtable
+;EBX - shadingtable
+
+        push    ebp
+        SETFLAG ecx,ecx
+        jz      donehp
+        mov     [pixelcount],ecx                ; save for final pixel
+        shr     ecx,1                           ; double pixel count
+        mov     [loopcount],ecx
+
+        mov     ebp,[_hp_startfrac]
+        mov     ebx,[_hp_srcstep]
+        mov     eax,OFFSET hp1+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET hp2+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+
+; eax           shadingtable
+; ebx           shadingtable
+; ecx,edx       scratch
+; esi           source
+; edi           destination
+; ebp           fraction
+
+        mov     ecx,ebp                      ; begin calculating first pixel
+        add     ebp,ebx                      ; advance frac pointer
+        shr     ecx,16                       ; finish calculation for first pixel
+        mov     edx,ebp                      ; begin calculating second pixel
+        and     ecx,63
+        add     ebp,ebx                      ; advance frac pointer
+        shr     edx,16                       ; finish calculation for second pixel
+        mov     eax,[_shadingtable]
+        and     edx,63
+        mov     ebx,eax
+        mov     al,[esi+ecx]                 ; get first pixel
+        mov     bl,[esi+edx]                 ; get second pixel
+        mov     al,[eax]                     ; color translate first pixel
+        mov     bl,[ebx]                     ; color translate second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     dsloop                       ; at least two pixels to map
+        jmp     last
+
+ALIGN 16
+dsloop:
+        mov     ecx,ebp                      ; begin calculating third pixel
+hp1:
+        add     ebp,12345678h                ; advance frac pointer
+        mov     [edi],al                     ; write first pixel
+        shr     ecx,16                       ; finish calculation for third pixel
+        mov     edx,ebp                      ; begin calculating fourth pixel
+hp2:
+        add     ebp,12345678h                ; advance frac pointer
+        and     ecx,63
+        mov     [edi+SCREENBWIDE],bl         ; write second pixel
+        shr     edx,16                       ; finish calculation for fourth pixel
+        mov     al,[esi+ecx]                 ; get third pixel
+        and     edx,63
+        add     edi,SCREENBWIDE*2            ; advance to third pixel destination
+        mov     bl,[esi+edx]                 ; get fourth pixel
+        dec     [loopcount]                  ; done with loop?
+        mov     al,[eax]                     ; color translate third pixel
+        mov     bl,[ebx]                     ; color translate fourth pixel
+        jnz     dsloop
+
+last:                                        ; one more?
+        test    [pixelcount],1
+        jz      donehp
+        mov     [edi],al                     ; write final pixel
+donehp:
+        pop   ebp
+	ret
+
+ENDP
+
+
+;============================
+;
+; DrawMenuPost
+;
+;============================
+
+IDEAL
+        ALIGN 16
+PROC	DrawMenuPost_
+PUBLIC	DrawMenuPost_
+
+;EDI - Destination for post
+;ESI - Source data
+;ECX - Length of post
+;EBX - shadingtable
+;EBX - shadingtable
+
+        push    ebp
+        SETFLAG ecx,ecx
+        jz      mdonehp
+        mov     [pixelcount],ecx                ; save for final pixel
+        shr     ecx,1                           ; double pixel count
+        mov     [loopcount],ecx
+
+        mov     ebp,[_hp_startfrac]
+        mov     ebx,[_hp_srcstep]
+        mov     eax,OFFSET mhp1+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET mhp2+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+
+; eax           shadingtable
+; ebx           shadingtable
+; ecx,edx       scratch
+; esi           source
+; edi           destination
+; ebp           fraction
+
+        mov     ecx,ebp                      ; begin calculating first pixel
+        add     ebp,ebx                      ; advance frac pointer
+        shr     ecx,16                       ; finish calculation for first pixel
+        mov     edx,ebp                      ; begin calculating second pixel
+        add     ebp,ebx                      ; advance frac pointer
+        shr     edx,16                       ; finish calculation for second pixel
+        mov     al,[esi+ecx]                 ; get first pixel
+        mov     bl,[esi+edx]                 ; get second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     mdsloop                       ; at least two pixels to map
+        jmp     mlast
+
+ALIGN 16
+mdsloop:
+        mov     ecx,ebp                      ; begin calculating third pixel
+mhp1:
+        add     ebp,12345678h                ; advance frac pointer
+        mov     [edi],al                     ; write first pixel
+        shr     ecx,16                       ; finish calculation for third pixel
+        mov     edx,ebp                      ; begin calculating fourth pixel
+mhp2:
+        add     ebp,12345678h                ; advance frac pointer
+        mov     [edi+SCREENBWIDE],bl         ; write second pixel
+        shr     edx,16                       ; finish calculation for fourth pixel
+        mov     al,[esi+ecx]                 ; get third pixel
+        add     edi,SCREENBWIDE*2            ; advance to third pixel destination
+        mov     bl,[esi+edx]                 ; get fourth pixel
+        dec     [loopcount]                  ; done with loop?
+        jnz     mdsloop
+
+mlast:                                        ; one more?
+        test    [pixelcount],1
+        jz      mdonehp
+        mov     [edi],al                     ; write final pixel
+mdonehp:
+        pop   ebp
+	ret
+
+ENDP
+
+
+;============================
+;
+; DrawMapPost
+;
+;============================
+
+IDEAL
+        ALIGN 16
+PROC	DrawMapPost_
+PUBLIC	DrawMapPost_
+
+;EDI - Destination for post
+;ESI - Source data
+;ECX - Length of post
+
+        push    ebp
+        SETFLAG ecx,ecx
+        jz      mpdonehp
+        mov     [pixelcount],ecx                ; save for final pixel
+        shr     ecx,1                           ; double pixel count
+        mov     [loopcount],ecx
+
+        mov     ebp,0
+        mov     ebx,[_hp_srcstep]
+
+; ecx,edx       scratch
+; esi           source
+; edi           destination
+; ebp           fraction
+
+        mov     ecx,ebp                      ; begin calculating first pixel
+        add     ebp,ebx                      ; advance frac pointer
+        shr     ecx,16                       ; finish calculation for first pixel
+        mov     edx,ebp                      ; begin calculating second pixel
+        add     ebp,ebx                      ; advance frac pointer
+        shr     edx,16                       ; finish calculation for second pixel
+        mov     al,[esi+ecx]                 ; get first pixel
+        mov     ah,[esi+edx]                 ; get second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     mpdsloop                       ; at least two pixels to map
+        jmp     mplast
+
+ALIGN 16
+mpdsloop:
+        mov     ecx,ebp                      ; begin calculating third pixel
+        add     ebp,ebx                      ; advance frac pointer
+        mov     [edi],al                     ; write first pixel
+        shr     ecx,16                       ; finish calculation for third pixel
+        mov     edx,ebp                      ; begin calculating fourth pixel
+        add     ebp,ebx                      ; advance frac pointer
+        mov     [edi+SCREENBWIDE],ah         ; write second pixel
+        shr     edx,16                       ; finish calculation for fourth pixel
+        mov     al,[esi+ecx]                 ; get third pixel
+        add     edi,SCREENBWIDE*2            ; advance to third pixel destination
+        mov     ah,[esi+edx]                 ; get fourth pixel
+        dec     [loopcount]                  ; done with loop?
+        jnz     mpdsloop
+
+mplast:                                        ; one more?
+        test    [pixelcount],1
+        jz      mpdonehp
+        mov     [edi],al                     ; write final pixel
+mpdonehp:
+        pop   ebp
+	ret
+
+ENDP
+
+
+ENDS
+
+END
+
+
+
+
+
+
+
+

Added: tags/rott-1.1/rott/rt_dr_a.h
===================================================================
--- tags/rott-1.1/rott/rt_dr_a.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_dr_a.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,45 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_dr_a_public
+#define _rt_dr_a_public
+
+//***************************************************************************
+//
+//    RT_DR_A.ASM - Low level draw stuff, DrawPost
+//
+//***************************************************************************
+
+void SetMode240(void);
+void RefreshClear(void);
+void DrawPost (int height, char * column, char * buf);
+void  DrawHeightPost (int height, byte * src, byte * buf); // IN rt_dr_a.asm
+void R_DrawWallColumn (byte * buf);
+void  DrawMenuPost (int height, byte * src, byte * buf); // IN rt_dr_a.asm
+void  DrawMapPost (int height, byte * src, byte * buf); // IN rt_dr_a.asm
+
+#if defined(__WATCOMC__)
+#pragma aux DrawPost parm [ECX] [ESI] [EDI] modify exact [eax ebx ecx edx esi edi]
+#pragma aux DrawHeightPost parm [ECX] [ESI] [EDI] modify exact [eax ebx ecx edx edi]
+#pragma aux R_DrawWallColumn parm [EDI] modify exact [eax ebx ecx edx esi edi]
+#pragma aux DrawMenuPost parm [ECX] [ESI] [EDI] modify exact [eax ebx ecx edx edi]
+#pragma aux DrawMapPost parm [ECX] [ESI] [EDI] modify exact [eax ebx ecx edx edi]
+#endif
+
+#endif

Added: tags/rott-1.1/rott/rt_draw.c
===================================================================
--- tags/rott-1.1/rott/rt_draw.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_draw.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,6509 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// RT_DRAW.C
+
+#include "profile.h"
+#include "rt_def.h"
+#include <string.h>
+
+#ifdef DOS
+#include <dos.h>
+#include <conio.h>
+#endif
+
+#include "watcom.h"
+#include "sprites.h"
+#include "rt_actor.h"
+#include "rt_stat.h"
+#include "rt_draw.h"
+#include "_rt_draw.h"
+#include "rt_dr_a.h"
+#include "rt_fc_a.h"
+#include "rt_scale.h"
+#include "rt_floor.h"
+#include "rt_main.h"
+#include "rt_playr.h"
+#include "rt_door.h"
+#include "rt_ted.h"
+#include "isr.h"
+#include "rt_util.h"
+#include "engine.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "lumpy.h"
+#include "rt_menu.h"
+#include "rt_game.h"
+#include "rt_vid.h"
+#include "rt_view.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "rt_cfg.h"
+#include "rt_str.h"
+#include "develop.h"
+#include "rt_sound.h"
+#include "rt_msg.h"
+#include "modexlib.h"
+#include "rt_rand.h"
+#include "rt_net.h"
+#include "rt_sc_a.h"
+//MED
+#include "memcheck.h"
+
+
+extern void VH_UpdateScreen (void);
+
+
+
+//int testval;
+/*
+=============================================================================
+
+Global Variables                                                                                                                                 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+int iG_masked;
+
+int whereami=-1;
+
+byte * shadingtable;
+
+word   tilemap[MAPSIZE][MAPSIZE]; // wall values only
+byte   spotvis[MAPSIZE][MAPSIZE];
+byte   mapseen[MAPSIZE][MAPSIZE];
+unsigned long * lights;
+
+int         wstart;
+
+
+const int dirangle8[9] = {0,FINEANGLES/8,2*FINEANGLES/8,3*FINEANGLES/8,4*FINEANGLES/8,
+                     5*FINEANGLES/8,6*FINEANGLES/8,7*FINEANGLES/8,8*FINEANGLES/8};
+
+const int dirangle16[16] = {0,FINEANGLES/16,2*FINEANGLES/16,3*FINEANGLES/16,
+							  4*FINEANGLES/16,5*FINEANGLES/16,6*FINEANGLES/16,
+							  7*FINEANGLES/16,8*FINEANGLES/16,9*FINEANGLES/16,
+							  10*FINEANGLES/16,11*FINEANGLES/16,12*FINEANGLES/16,
+							  13*FINEANGLES/16,14*FINEANGLES/16,15*FINEANGLES/16};
+
+//
+// math tables
+//
+
+short   tantable[FINEANGLES];
+int     sintable[FINEANGLES+FINEANGLEQUAD+1],
+		  *costable = sintable+(FINEANGLES/4);
+
+//
+// refresh variables
+//
+
+fixed   viewx,viewy;                                                     // the focal point
+int     viewangle;
+int     c_startx, c_starty;
+fixed   viewsin,viewcos;
+int     tics;
+
+//
+// ray tracing variables
+//
+
+long    xintercept,yintercept;
+
+int doublestep=0;
+int hp_startfrac;
+int hp_srcstep;
+
+int levelheight;
+
+int actortime=0;
+int drawtime=0;
+
+visobj_t vislist[MAXVISIBLE],*visptr,*visstep,*farthest;
+
+int firstcoloffset=0;
+
+/*
+==================
+=
+= Local Variables
+=
+==================
+*/
+static int nonbobpheight;
+
+static visobj_t * sortedvislist[MAXVISIBLE];
+
+static const fixed mindist = 0x1000;
+
+static int walltime=0;
+
+static int weaponbobx, weaponboby;
+
+static int      pretics[3];
+static int      preindex;
+static int      netlump;
+static int      gmasklump;
+
+int      G_gmasklump;
+
+static const int weaponshape[NUMWEAPGRAPHICS] =
+     {
+#if (SHAREWARE == 0)
+
+      W_KNIFE,
+#endif
+
+      W_MALEPISTOL1,
+		W_MRIGHTPISTOL1,
+		W_MP40,
+		W_BAZOOKA,
+		W_HEATSEEKER,
+      W_DRUNK,
+      W_FIREBOMB,
+      W_FIREWALL,
+		W_GODHAND,
+
+
+#if (SHAREWARE == 0)
+		W_SPLIT,
+		W_KES,
+		W_BAT,
+      W_DOG,
+		W_FEMALEPISTOL1,
+		W_BMALEPISTOL1
+#endif
+		};
+
+void SetColorLightLevel (int x, int y, visobj_t * sprite, int dir, int color, int fullbright);
+void DrawRotatedScreen(int cx, int cy, byte *destscreen, int angle, int scale, int masked);
+void InterpolateMaskedWall (visobj_t * plane);
+void InterpolateDoor (visobj_t * plane);
+void InterpolateWall (visobj_t * plane);
+
+/*
+==================
+=
+= BuildTables
+=
+==================
+*/
+
+void BuildTables (void)
+{
+  byte * table;
+  byte * ptr;
+  int   length;
+  int   i;
+
+//
+// load in tables file
+//
+
+   table=W_CacheLumpName("tables",PU_STATIC, CvtNull, 1);
+   ptr=table;
+
+//
+// get size of first table
+//
+
+   memcpy(&length,ptr,sizeof(int));
+   SwapIntelLong(&length);
+   
+//
+// skip first table
+//
+
+   ptr+=(length+1)*sizeof(int);
+
+//
+// get size of sin/cos table
+//
+
+   memcpy(&length,ptr,sizeof(int));
+   SwapIntelLong(&length);
+   ptr+=sizeof(int);
+   
+//
+// get sin/cos table
+//
+   memcpy(&sintable[0],ptr,length*sizeof(int));
+   SwapIntelLongArray(&sintable[0], length);
+   ptr+=(length)*sizeof(int);
+
+//
+// get size of tangent table
+//
+
+   memcpy(&length,ptr,sizeof(int));
+   SwapIntelLong(&length);
+   ptr+=sizeof(int);
+
+//
+// get tangent table
+//
+   memcpy(tantable,ptr,length*sizeof(short));
+   SwapIntelShortArray(tantable, length);
+   ptr+=(length)*sizeof(short);
+
+//
+// get size of gamma table
+//
+
+   memcpy(&length,ptr,sizeof(int));
+   SwapIntelLong(&length);
+   ptr+=sizeof(int);
+
+//
+// get gamma table
+//
+   memcpy(&gammatable[0],ptr,length*sizeof(byte));
+   table=W_CacheLumpName("tables",PU_CACHE, CvtNull, 1);
+
+   costable = (fixed *)&(sintable[FINEANGLES/4]);
+
+   wstart=W_GetNumForName("WALLSTRT");
+#if (SHAREWARE==0)
+   netlump=W_GetNumForName("net1");
+#endif
+   gmasklump=W_GetNumForName("p_gmask");
+   G_gmasklump = gmasklump;
+
+   preindex=0;
+   pretics[0]=0x10000;
+   pretics[2]=0x10000;
+   pretics[1]=0x10000;
+
+   for(i=0;i<ANGLES;i++)
+    {angletodir[i] = (i + (ANGLES/16))/(ANGLES/8);
+     if (angletodir[i] == 8)
+		angletodir[i] = 0;
+	 }
+
+   // Check out VENDOR.DOC file
+   CheckVendor();
+
+   if (!quiet)
+      printf("RT_DRAW: Tables Initialized\n");
+}
+
+
+/*
+========================
+=
+= TransformObject
+=
+========================
+*/
+
+boolean TransformObject (int x, int y, int *dispx, int *dispheight)
+{
+
+  fixed gx,gy,gxt,gyt,nx,ny;
+
+
+//
+// translate point to view centered coordinates
+//
+  gx = x-viewx;
+  gy = y-viewy;
+
+//
+// calculate newx
+//
+  gxt = FixedMul(gx,viewcos);
+  gyt = FixedMul(gy,viewsin);
+  nx = gxt-gyt;
+
+  if (nx<MINZ)
+     return false;
+
+  // the midpoint could put parts of the shape
+  // into an adjacent wall
+  //
+  // calculate newy
+  //
+  gxt = FixedMul(gx,viewsin);
+  gyt = FixedMul(gy,viewcos);
+  ny = gyt+gxt;
+
+
+//
+// calculate perspective ratio
+//
+
+  *dispx = centerx + ny*scale/nx;            // DEBUG: use assembly divide
+
+  *dispheight = heightnumerator/nx;
+
+  return true;
+}
+
+
+/*
+========================
+=
+= TransformPoint
+=
+========================
+*/
+
+void TransformPoint (int x, int y, int * screenx, int * height, int * texture, int vertical)
+{
+
+  fixed gxt,gyt,nx,ny;
+  fixed gxtt,gytt;
+  int gx,gy;
+  int vx,vy;
+  int svs,svc;
+
+
+//
+// translate point to view centered coordinates
+//
+  gx = x-viewx;
+  gy = y-viewy;
+
+//
+// calculate newx
+//
+  gxt = FixedMul(gx,viewcos);
+  gyt = FixedMul(gy,viewsin);
+  nx =gxt-gyt;
+
+  if (nx<10)
+     nx=10;
+
+
+//
+// calculate newy
+//
+  gxtt = FixedMul(gx,viewsin);
+  gytt = FixedMul(gy,viewcos);
+  ny = gytt+gxtt;
+
+// too close, don't overflow the divid'
+
+
+  *screenx = centerx + ((ny*scale)/nx);            // DEBUG: use assembly divide
+
+  *height = heightnumerator/nx;
+
+
+  if (*screenx<0)
+     {
+     svc=(-centerx)*viewcos;
+     svs=(-centerx)*viewsin;
+     vx=(scale*viewcos)+svs;
+     vy=(-scale*viewsin)+svc;
+     if (vertical)
+        {
+        if ((viewcos-viewsin)==0)
+           {
+           *height=20000<<HEIGHTFRACTION;
+           return;
+           }
+        gy=FixedScale(gx,vy,vx);
+        y=gy+viewy;
+        gyt = FixedMul(gy,viewsin);
+		  nx =gxt-gyt;
+        if (nx<10)
+           nx=10;
+        *screenx = 0;
+        *height = heightnumerator/nx;
+		  }
+     else
+        {
+        if ((-viewsin-viewcos)==0)
+           {
+           *height=20000<<HEIGHTFRACTION;
+           return;
+           }
+        gx=FixedScale(gy,vx,vy);
+        x=gx+viewx;
+        gxt = FixedMul(gx,viewcos);
+        nx =gxt-gyt;
+        if (nx<10)
+           nx=10;
+        *screenx = 0;
+        *height = heightnumerator/nx;
+        }
+	  }
+  else if (*screenx>=viewwidth)
+     {
+     svc=(centerx)*viewcos;
+     svs=(centerx)*viewsin;
+     vx=(scale*viewcos)+svs;
+     vy=(-scale*viewsin)+svc;
+     if (vertical)
+        {
+        if ((viewcos+viewsin)==0)
+           {
+           *height=20000<<HEIGHTFRACTION;
+           return;
+           }
+        gy=FixedScale(gx,vy,vx);
+        y=gy+viewy;
+        gyt = FixedMul(gy,viewsin);
+        nx =gxt-gyt;
+        if (nx<10)
+			  nx=10;
+        *screenx = viewwidth-1;
+        *height = heightnumerator/nx;
+        }
+     else
+        {
+        if ((-viewsin+viewcos)==0)
+           {
+           *height=20000<<HEIGHTFRACTION;
+           return;
+           }
+        gx=FixedScale(gy,vx,vy);
+        x=gx+viewx;
+		  gxt = FixedMul(gx,viewcos);
+        nx =gxt-gyt;
+        if (nx<10)
+           nx=10;
+        *screenx = viewwidth-1;
+        *height = heightnumerator/nx;
+        }
+     }
+  if (vertical)
+     *texture=(y-*texture)&0xffff;
+  else
+     *texture=(x-*texture)&0xffff;
+}
+
+/*
+========================
+=
+= TransformSimplePoint
+=
+========================
+*/
+
+boolean TransformSimplePoint (int x, int y, int * screenx, int * height, int * texture, int vertical)
+{
+
+  fixed gxt,gyt,nx,ny;
+  fixed gxtt,gytt;
+  int gx,gy;
+
+
+//
+// translate point to view centered coordinates
+//
+  gx = x-viewx;
+  gy = y-viewy;
+
+//
+// calculate newx
+//
+  gxt = FixedMul(gx,viewcos);
+  gyt = FixedMul(gy,viewsin);
+  nx =gxt-gyt;
+
+  if (nx<MINZ)
+     return false;
+
+
+//
+// calculate newy
+//
+  gxtt = FixedMul(gx,viewsin);
+  gytt = FixedMul(gy,viewcos);
+  ny = gytt+gxtt;
+
+// too close, don't overflow the divid'
+
+
+  *screenx = centerx + ((ny*scale)/nx);            // DEBUG: use assembly divide
+
+  *height = heightnumerator/nx;
+
+  if (vertical)
+     *texture=(y-*texture)&0xffff;
+  else
+     *texture=(x-*texture)&0xffff;
+
+  return true;
+}
+
+
+/*
+========================
+=
+= TransformPlane
+=
+========================
+*/
+
+boolean TransformPlane (int x1, int y1, int x2, int y2, visobj_t * plane)
+{
+  boolean result2;
+  boolean result1;
+  boolean vertical;
+  int txstart,txend;
+
+  vertical=((x2-x1)==0);
+  plane->viewx=vertical;
+  txstart=plane->texturestart;
+  txend=plane->textureend;
+  result1=TransformSimplePoint(x1,y1,&(plane->x1),&(plane->h1),&(plane->texturestart),vertical);
+  result2=TransformSimplePoint(x2,y2,&(plane->x2),&(plane->h2),&(plane->textureend),vertical);
+  if (result1==true)
+     {
+     if (plane->x1>=viewwidth)
+        return false;
+     if (result2==false)
+        {
+        plane->textureend=txend;
+        TransformPoint(x2,y2,&(plane->x2),&(plane->h2),&(plane->textureend),vertical);
+        }
+	  }
+  else
+     {
+     if (result2==false)
+        return false;
+     else
+        {
+        if (plane->x2<0)
+           return false;
+        plane->texturestart=txstart;
+		  TransformPoint(x1,y1,&(plane->x1),&(plane->h1),&(plane->texturestart),vertical);
+        }
+     }
+  if (plane->x1<0)
+     {
+     plane->texturestart=txstart;
+     TransformPoint(x1,y1,&(plane->x1),&(plane->h1),&(plane->texturestart),vertical);
+     }
+  if (plane->x2>=viewwidth)
+     {
+     plane->textureend=txend;
+     TransformPoint(x2,y2,&(plane->x2),&(plane->h2),&(plane->textureend),vertical);
+     }
+
+  plane->viewheight=(plane->h1+plane->h2)>>1;
+
+  if ((plane->viewheight>=(2000<<HEIGHTFRACTION)) || (plane->x1>=viewwidth-1) || (plane->x2<=0))
+     return false;
+
+  return true;
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= CalcHeight
+=
+= Calculates the height of xintercept,yintercept from viewx,viewy
+=
+====================
+*/
+
+int       CalcHeight (void)
+{
+        fixed  gxt,gyt,nx;
+   long            gx,gy;
+
+   whereami=0;
+
+   gx = xintercept-viewx;
+   gxt = FixedMul(gx,viewcos);
+
+   gy = yintercept-viewy;
+   gyt = FixedMul(gy,viewsin);
+
+   nx = gxt-gyt;
+
+	if (nx<mindist)
+		nx=mindist; // don't let divide overflo'
+
+	return (heightnumerator/nx);
+}
+
+
+
+#if 0
+//==========================================================================
+
+//******************************************************************************
+//
+// NextPlaneptr
+//
+//******************************************************************************
+
+void NextPlaneptr ( void )
+{
+   if (planeptr < &planelist[MAXPLANES-1]) // don't let it overflo'
+  		planeptr++;
+}
+
+//******************************************************************************
+//
+// RestPlaneptr
+//
+//******************************************************************************
+
+void ResetPlaneptr ( void )
+{
+   planeptr = &planelist[0];
+}
+
+//******************************************************************************
+//
+// NextVisptr
+//
+//******************************************************************************
+
+void NextVisptr ( void )
+{
+   if (visptr < &vislist[MAXVISIBLE-1]) // don't let it overflo'
+  		visptr++;
+}
+
+//******************************************************************************
+//
+// ResetVisptr
+//
+//******************************************************************************
+
+void ResetVisptr ( void )
+{
+   visptr = &vislist[0];
+}
+
+#endif
+
+//==========================================================================
+
+
+
+/*
+=====================
+=
+= StatRotate
+=
+=====================
+*/
+
+int  StatRotate (statobj_t *temp)
+{
+	int    angle;
+	int    dx,dy;
+
+   whereami=2;
+
+	dx = temp->x - player->x;
+	dy = player->y - temp->y;
+	angle = atan2_appx(dx,dy);
+
+	angle = angle-VANG180-dirangle8[temp->count];
+	angle+=ANGLES/16;
+	while (angle>=ANGLES)
+		angle-=ANGLES;
+	while (angle<0)
+		angle+=ANGLES;
+
+	return angle/(ANGLES/8);
+
+}
+
+
+
+
+/*
+=====================
+=
+= CalcRotate
+=
+=====================
+*/
+
+int   CalcRotate (objtype *ob)
+{
+	int    angle,viewangle;
+	int    dx,dy;
+	int    rotation;
+
+   whereami=1;
+
+	// this isn't exactly correct, as it should vary by a trig value'
+	// but it is close enough with only eight rotations
+	/*
+	if (ob->obclass == b_robobossobj)
+		viewangle = player->angle;
+	else
+		viewangle = player->angle + (centerx - ob->viewx)/8;*/
+	dx = ob->x - player->x;
+	dy = player->y - ob->y;
+	viewangle = atan2_appx(dx,dy);
+
+	if ((ob->obclass >= p_bazookaobj) || (ob->obclass == missileobj))
+	  {angle = viewangle - ob->angle;
+		#if (0)
+		 Debug("\nviewangle: %d, angle: %d",viewangle,angle);
+		#endif
+	  }
+	else if ((ob->obclass > wallopobj) && (ob->obclass != b_darksnakeobj))
+		angle =  (viewangle-ANG180)- ob->angle;
+	else if (ob->state->rotate == 16)
+		angle =  (viewangle-ANG180)- dirangle16[ob->dir];
+	else
+		angle =  (viewangle-ANG180)- dirangle8[ob->dir];
+
+	if (ob->state->rotate == true)
+	  angle += ANGLES/16;
+	else if (ob->state->rotate == 16)
+	  angle += ANGLES/32;
+
+	while (angle>=ANGLES)
+		angle-=ANGLES;
+	while (angle<0)
+		angle+=ANGLES;
+
+	if (ob->state->rotate == 2)        // 2 rotation pain frame
+		{rotation = 4*(angle/(ANG180));
+		 return rotation;
+		}
+
+	if (ob->state->rotate == 16)
+	  {rotation = angle/(ANGLES/16);
+		#if (0)
+		 Debug("\nrotation: %d", rotation);
+		#endif
+		return rotation;
+	  }
+	rotation = angle/(ANGLES/8);
+	return rotation;
+
+}
+
+
+
+#if 0
+/*
+=====================
+=
+= DrawMaskedWalls
+=
+=====================
+*/
+
+void DrawMaskedWalls (void)
+{
+
+
+  int   i,numvisible;
+  int   gx,gy;
+  unsigned short int  *tilespot;
+  byte   *visspot;
+  boolean result;
+  statobj_t *statptr;
+  objtype   *obj;
+  maskedwallobj_t* tmwall;
+
+	whereami=6;
+
+//
+// place maskwall objects
+//
+  for(tmwall=FIRSTMASKEDWALL;tmwall;tmwall=tmwall->next)
+	  {
+	  if (spotvis[tmwall->tilex][tmwall->tiley])
+		  {
+		  mapseen[tmwall->tilex][tmwall->tiley]=1;
+		  if (tmwall->vertical)
+			  {
+			  gx=(tmwall->tilex<<16)+0x8000;
+			  gy=(tmwall->tiley<<16);
+			  visptr->texturestart=0;
+			  visptr->textureend=0;
+			  if (viewx<gx)
+				  result=TransformPlane(gx,gy,gx,gy+0xffff,visptr);
+			  else
+				  result=TransformPlane(gx,gy+0xffff,gx,gy,visptr);
+			  visptr->shapenum=tmwall->bottomtexture;
+			  visptr->altshapenum=tmwall->midtexture;
+			  visptr->viewx=tmwall->toptexture;
+			  visptr->shapesize=2;
+			  }
+		  else
+			  {
+			  gx=(tmwall->tilex<<16);
+			  gy=(tmwall->tiley<<16)+0x8000;
+			  visptr->texturestart=0;
+			  visptr->textureend=0;
+			  if (viewy<gy)
+				  result=TransformPlane(gx+0xffff,gy,gx,gy,visptr);
+			  else
+				  result=TransformPlane(gx,gy,gx+0xffff,gy,visptr);
+			  visptr->shapenum=tmwall->bottomtexture;
+			  visptr->altshapenum=tmwall->midtexture;
+			  visptr->viewx=tmwall->toptexture;
+			  visptr->shapesize=2;
+			  }
+		  if ((tmwall->flags&MW_TOPFLIPPING) &&
+            (nonbobpheight>64)
+			  )
+			  {
+			  visptr->viewx++;
+			  }
+		  else if ((tmwall->flags&MW_BOTTOMFLIPPING) &&
+                 (nonbobpheight>maxheight-32)
+					 )
+			  {
+			  visptr->shapenum++;
+			  }
+		  if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
+			  visptr++;
+		  }
+	  }
+}
+#endif
+
+/*
+======================
+=
+= SortScaleds
+= Sort the scaleds using a HEAPSORT
+=
+======================
+*/
+
+#define SGN(x)          ((x>0) ? (1) : ((x==0) ? (0) : (-1)))
+
+/*--------------------------------------------------------------------------*/
+int CompareHeights(s1p,s2p) visobj_t **s1p,**s2p;
+{
+   whereami=3;
+   return SGN((*s1p)->viewheight-(*s2p)->viewheight);
+}
+
+void SwitchPointers(s1p,s2p) visobj_t **s1p,**s2p;
+{
+   visobj_t * temp;
+
+   whereami=4;
+   temp=*s1p;
+   *s1p=*s2p;
+   *s2p=temp;
+}
+
+
+void SortVisibleList( int numvisible, visobj_t * vlist )
+{
+   int i;
+
+   whereami=5;
+   for (i=0;i<numvisible;i++)
+      sortedvislist[i]=&(vlist[i]);
+   hsort((char *)&(sortedvislist[0]),numvisible,sizeof(visobj_t *),&CompareHeights,&SwitchPointers);
+}
+
+/*
+=====================
+=
+= DrawScaleds
+=
+= Draws all objects that are visible
+=
+=====================
+*/
+
+#define HF_1 (24)
+#define HF_2 (72)
+
+void DrawScaleds (void)
+{
+
+
+  int   i,numvisible;
+  int   gx,gy;
+  unsigned short int  *tilespot;
+  byte   *visspot;
+  boolean result;
+  statobj_t *statptr;
+  objtype   *obj;
+  maskedwallobj_t* tmwall;
+
+	whereami=6;
+
+//
+// place maskwall objects
+//
+  for(tmwall=FIRSTMASKEDWALL;tmwall;tmwall=tmwall->next)
+	  {
+	  if (spotvis[tmwall->tilex][tmwall->tiley])
+		  {
+		  mapseen[tmwall->tilex][tmwall->tiley]=1;
+		  if (tmwall->vertical)
+			  {
+			  gx=(tmwall->tilex<<16)+0x8000;
+			  gy=(tmwall->tiley<<16);
+			  visptr->texturestart=0;
+			  visptr->textureend=0;
+			  if (viewx<gx)
+				  result=TransformPlane(gx,gy,gx,gy+0xffff,visptr);
+			  else
+				  result=TransformPlane(gx,gy+0xffff,gx,gy,visptr);
+			  visptr->shapenum=tmwall->bottomtexture;
+			  visptr->altshapenum=tmwall->midtexture;
+			  visptr->viewx=tmwall->toptexture;
+			  visptr->shapesize=2;
+			  }
+		  else
+			  {
+			  gx=(tmwall->tilex<<16);
+			  gy=(tmwall->tiley<<16)+0x8000;
+			  visptr->texturestart=0;
+			  visptr->textureend=0;
+			  if (viewy<gy)
+				  result=TransformPlane(gx+0xffff,gy,gx,gy,visptr);
+			  else
+				  result=TransformPlane(gx,gy,gx+0xffff,gy,visptr);
+			  visptr->shapenum=tmwall->bottomtexture;
+			  visptr->altshapenum=tmwall->midtexture;
+			  visptr->viewx=tmwall->toptexture;
+			  visptr->shapesize=2;
+			  }
+		  if ((tmwall->flags&MW_TOPFLIPPING) &&
+            (nonbobpheight>64)
+			  )
+			  {
+			  visptr->viewx++;
+			  }
+		  else if ((tmwall->flags&MW_BOTTOMFLIPPING) &&
+                 (nonbobpheight>maxheight-32)
+					 )
+			  {
+			  visptr->shapenum++;
+			  }
+		  if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
+			  visptr++;
+		  }
+	  }
+//
+// place static objects
+//
+  UpdateClientControls();
+  for (statptr = firstactivestat ; statptr; statptr=statptr->nextactive)
+  {  //redraw:
+			 if((visptr->shapenum = statptr->shapenum) == NOTHING)
+				  continue;
+
+          visptr->shapenum += shapestart;
+			 if ((visptr->shapenum <= shapestart) ||
+				  (visptr->shapenum >= shapestop))
+			  Error("actor shapenum %d out of range (%d-%d)",visptr->shapenum,shapestart,shapestop);
+
+          visspot = statptr->visspot;
+			 if (!((*(visspot-0)) ||
+					 (*(visspot-1)) ||
+					 (*(visspot+1)) ||
+					 (*(visspot-129)) ||
+					 (*(visspot-128)) ||
+					 (*(visspot-127)) ||
+					 (*(visspot+129)) ||
+					 (*(visspot+128)) ||
+					 (*(visspot+127))))
+					 {statptr->flags &= ~FL_VISIBLE;
+					  continue;     // not visible
+					 }
+
+			 result = TransformObject (statptr->x,statptr->y,&(visptr->viewx),&(visptr->viewheight));
+
+			 if ((result==false) || (visptr->viewheight< (1<<(HEIGHTFRACTION+2))))
+				 continue;                         // to close to the object
+			 statptr->flags |= FL_SEEN;
+
+			 statptr->flags |= FL_VISIBLE;
+
+			 if (statptr->flags & FL_ROTATING)
+				 visptr->shapenum += StatRotate(statptr);
+
+			 if (statptr->flags&FL_TRANSLUCENT)
+				 {
+				 visptr->shapesize=1;
+				 if (statptr->flags&FL_FADING)
+					 visptr->h2=transparentlevel;
+				 else
+					 visptr->h2=FIXEDTRANSLEVEL;
+             SetSpriteLightLevel(statptr->x,statptr->y,visptr,0,(statptr->flags&FL_FULLLIGHT));
+				 }
+			 else if (statptr->flags&FL_SOLIDCOLOR)
+				 {
+				 visptr->shapesize=4;
+				 visptr->h2=statptr->hitpoints;
+				 }
+			 else if (statptr->flags&FL_COLORED)
+				 {
+				 visptr->shapesize=0;
+#if (DEVELOPMENT == 1)
+				 if ((statptr->hitpoints>=0) &&
+					 (statptr->hitpoints<MAXPLAYERCOLORS))
+					 {
+#endif
+					 SetColorLightLevel(statptr->x,statptr->y,visptr,
+                                   0,statptr->hitpoints,
+                                   (statptr->flags&FL_FULLLIGHT));
+#if (DEVELOPMENT == 1)
+					 }
+				 else
+                {
+                Error("Illegal color map for sprite type %d\n",statptr->itemnumber);
+					 }
+#endif
+				 }
+          else
+				 {
+				 visptr->shapesize=0;
+             SetSpriteLightLevel(statptr->x,statptr->y,visptr,0,(statptr->flags&FL_FULLLIGHT));
+				 }
+
+			 visptr->h1=pheight-statptr->z;
+
+			 if ((statptr->itemnumber != (unsigned int)-1) &&
+				  (statptr->flags&FL_HEIGHTFLIPPABLE)
+				 )
+				 {
+				 if (statptr->itemnumber==stat_disk)
+					 {
+					 int value;
+                value=nonbobpheight-statptr->z-32;
+					 if ((value<=HF_2) && (value>HF_1))
+						 {
+						 visptr->shapenum++;
+						 }
+					 else if ((value<=HF_1) && (value>=-HF_1))
+						 {
+						 visptr->shapenum+=2;
+						 }
+					 else if ((value<-HF_1) && (value>=-HF_2))
+						 {
+						 visptr->shapenum+=3;
+						 }
+					 else if (value<-HF_2)
+						 {
+						 visptr->shapenum+=4;
+						 }
+					 }
+             else if ((nonbobpheight-statptr->z)<-16)
+					 {
+					 visptr->shapenum++;
+					 }
+				 }
+
+			 if (visptr < &vislist[MAXVISIBLE-1]) // don't let it overflo'
+				visptr++;
+
+
+  }
+//
+// place active objects
+//
+  UpdateClientControls();
+  for (obj = firstactive;obj;obj=obj->nextactive)
+	  {
+	  if (obj==player)
+		  continue;
+
+	  if ((visptr->shapenum = obj->shapenum) == NOTHING)
+		  continue;                         // no shape
+
+	  visptr->shapenum += shapestart;
+     if ((visptr->shapenum <= shapestart) ||
+				  (visptr->shapenum >= shapestop))
+		  Error("actor shapenum %d out of range (%d-%d)",visptr->shapenum,shapestart,shapestop);
+	  visspot = &spotvis[obj->tilex][obj->tiley];
+	  tilespot = &tilemap[obj->tilex][obj->tiley];
+
+	  //
+	  // could be in any of the nine surrounding tiles
+	  //
+	  if (*visspot
+		  || ( *(visspot-1))
+		  || ( *(visspot+1))
+		  || ( *(visspot-129))
+		  || ( *(visspot-128))
+		  || ( *(visspot-127))
+		  || ( *(visspot+129))
+		  || ( *(visspot+128))
+		  || ( *(visspot+127)) )
+		  {
+
+//        result = TransformObject (obj->drawx, obj->drawy,&(visptr->viewx),&(visptr->viewheight));
+        result = TransformObject (obj->x, obj->y,&(visptr->viewx),&(visptr->viewheight));
+        if ((result==false) || (visptr->viewheight< (1<<(HEIGHTFRACTION+2))))
+			  continue;                         // to close to the object
+		  if (obj->state->rotate)
+			  visptr->shapenum += CalcRotate (obj);
+
+        visptr->shapesize=0;
+
+		  if (player->flags&FL_SHROOMS)
+			  {
+			  visptr->shapesize=4;
+			  visptr->h2=(GetTicCount()&0xff);
+			  }
+		  if (obj->obclass==playerobj)
+			  {
+			  if (obj->flags&FL_GODMODE)
+				  {
+				  visptr->shapesize=4;
+				  visptr->h2=240+(GetTicCount()&0x7);
+				  }
+			  else if (obj->flags & FL_COLORED)
+				  {
+				  playertype *pstate;
+
+				  M_LINKSTATE(obj,pstate);
+#if (DEVELOPMENT == 1)
+				  if ((pstate->uniformcolor>=0) &&
+					  (pstate->uniformcolor<MAXPLAYERCOLORS))
+					  {
+#endif
+					  SetColorLightLevel(obj->x,obj->y,visptr,
+                                    obj->dir,pstate->uniformcolor,
+                                    (obj->flags&FL_FULLLIGHT) );
+#if (DEVELOPMENT == 1)
+					  }
+				  else
+					  {
+					  Error("Illegal color map for players\n");
+					  }
+#endif
+				  }
+			  else
+              SetSpriteLightLevel(obj->x,obj->y,visptr,obj->dir,(obj->flags&FL_FULLLIGHT));
+
+			  }
+		  else
+			  {
+			  if ((obj->obclass >= b_darianobj) && (obj->obclass <= b_robobossobj) &&
+				  MISCVARS->redindex)
+              {
+				  visptr->colormap=redmap+((MISCVARS->redindex-1)<<8);
+              }
+           else
+              {
+              SetSpriteLightLevel(obj->x,obj->y,visptr,obj->dir,(obj->flags&FL_FULLLIGHT));
+              }
+           }
+
+		  visptr->h1= pheight - obj->z;
+
+        if (obj->obclass==diskobj)
+           {
+           int value;
+           value=nonbobpheight-obj->z-32;
+           if ((value<=HF_2) && (value>HF_1))
+              {
+              visptr->shapenum++;
+              }
+           else if ((value<=HF_1) && (value>=-HF_1))
+              {
+              visptr->shapenum+=2;
+              }
+           else if ((value<-HF_1) && (value>=-HF_2))
+              {
+              visptr->shapenum+=3;
+              }
+           else if (value<-HF_2)
+              {
+              visptr->shapenum+=4;
+              }
+           }
+        else if ( (obj->obclass==pillarobj) &&
+                  ((nonbobpheight-obj->z)<-16)
+                )
+           {
+           visptr->shapenum++;
+           }
+
+		  if (visptr < &vislist[MAXVISIBLE-1]) // don't let it overflo'
+			  visptr++;
+		  obj->flags |= FL_SEEN;
+		  obj->flags |= FL_VISIBLE;
+		  }
+	  else
+		  obj->flags &= ~FL_VISIBLE;
+	  }
+//
+// draw from back to front
+//
+	numvisible = visptr-&vislist[0];
+	if (!numvisible)
+		return;                                     // no visible objects
+	SortVisibleList( numvisible, &vislist[0] );
+   UpdateClientControls();
+   for (i = 0; i<numvisible; i++)
+		{
+      //
+      // draw farthest
+      //
+
+      if (sortedvislist[i]->shapesize==4) {
+      
+        ScaleSolidShape(sortedvislist[i]);
+        
+      } else if (sortedvislist[i]->shapesize==3) {
+
+         InterpolateDoor (sortedvislist[i]);
+
+      } else if (sortedvislist[i]->shapesize==2) {
+
+         InterpolateMaskedWall (sortedvislist[i]);
+
+      } else if (sortedvislist[i]->shapesize==1) {
+
+         ScaleTransparentShape(sortedvislist[i]);
+
+      } else {
+
+         ScaleShape(sortedvislist[i]);
+
+      }
+
+      }
+}
+
+//==========================================================================
+
+
+
+
+
+/*
+==============
+=
+= DrawPlayerWeapon
+=
+= Draw the player's hand'
+=
+==============
+*/
+
+void DrawPlayerWeapon (void)
+{
+ int shapenum,index;
+ int xdisp=0;
+ int ydisp=0;
+ int female,black;
+ int altshape=0;
+
+   whereami=7;
+
+ SoftError("\n attackframe: %d, weaponframe: %d, weapondowntics: %d"
+           " weaponuptics: %d",locplayerstate->attackframe,
+           locplayerstate->weaponframe,locplayerstate->weapondowntics,
+           locplayerstate->weaponuptics);
+
+ if ((locplayerstate->NETCAPTURED == 1) && (!locplayerstate->HASKNIFE))
+  return;
+
+ if (locplayerstate->weapon != -1)
+  {female = ((locplayerstate->player == 1) || (locplayerstate->player == 3));
+   black = (locplayerstate->player == 2);
+
+	if (((locplayerstate->NETCAPTURED >= 1) || (locplayerstate->NETCAPTURED == -2)) && (locplayerstate->HASKNIFE == 1)) // if raising or lowering
+		 {index = 0;
+		  shapenum = gunsstart + weaponshape[index] + locplayerstate->weaponframe;
+		 }
+	else if  (locplayerstate->weapon != wp_twopistol)
+		 {if (locplayerstate->weapon==wp_pistol)
+			{if (female)
+			  index = NUMWEAPGRAPHICS-2;
+			 else if (black)
+			  index = NUMWEAPGRAPHICS-1;
+			 else
+#if (SHAREWARE == 0)
+			  index = 1;
+#else
+           index = 0;
+#endif
+			}
+		  else
+#if (SHAREWARE == 0)
+
+          index = locplayerstate->weapon + 1;
+#else
+          index = locplayerstate->weapon;
+#endif
+
+        if ((index<0) || (index>=NUMWEAPGRAPHICS))
+           Error ("Weapon shapenum out of range\n");
+		  shapenum = gunsstart + weaponshape[index] + locplayerstate->weaponframe;
+
+#if (SHAREWARE == 0)
+        if ((shapenum < W_GetNumForName("KNIFE1")) ||
+            (shapenum > W_GetNumForName("DOGPAW4"))
+           )
+#else
+        if ((shapenum < W_GetNumForName("MPIST11")) ||
+            (shapenum > W_GetNumForName("GODHAND8"))
+           )
+#endif
+           Error("\n illegal weapon shapenum %d, index %d, weaponframe %d",
+                  shapenum,index,locplayerstate->weaponframe);
+		 }
+
+	else
+    {
+#if (SHAREWARE == 0)
+     if (female)
+		 {altshape = W_FLEFTPISTOL1;
+		  shapenum = W_FRIGHTPISTOL1;
+		 }
+	  else if (black)
+		 {altshape = W_BMLEFTPISTOL1;
+		  shapenum = W_BMRIGHTPISTOL1;
+		 }
+	  else
+#endif
+		{altshape = W_MLEFTPISTOL1;
+		 shapenum = W_MRIGHTPISTOL1;
+		}
+
+	  altshape += gunsstart;
+	  shapenum += gunsstart;
+	  if (locplayerstate->weaponframe > 2)
+			altshape += (locplayerstate->weaponframe - 3);
+	  else
+			shapenum += locplayerstate->weaponframe;
+	 }
+
+	if (!(locplayerstate->NETCAPTURED) ||
+		  (locplayerstate->NETCAPTURED == -1) ||
+		  (locplayerstate->HASKNIFE == 0))
+	 {switch (locplayerstate->weapon)
+		{
+
+		 case wp_godhand:
+			break;
+
+		 case wp_mp40:
+			 break;
+
+		 case wp_firewall:
+			ydisp = 10;
+         break;
+
+		 case wp_bazooka:
+         break;
+
+		 case wp_heatseeker:
+			ydisp = 20;
+			break;
+
+		 case wp_pistol:
+			break;
+
+		 case wp_twopistol:
+			xdisp = 80;
+			break;
+
+       case wp_drunk:
+			ydisp = 10;
+         break;
+
+       case wp_firebomb:
+			break;
+
+
+
+#if (SHAREWARE == 0)
+
+       case wp_kes:
+			break;
+
+       case wp_bat:
+         xdisp = 20;
+			break;
+
+       case wp_split:
+			ydisp = 20;
+			break;
+
+
+		 case wp_dog:
+			break;
+
+
+#endif
+
+		 default:
+         Error("Illegal weapon value = %d\n",locplayerstate->weapon);
+         break;
+		}
+	 }
+  else
+	  xdisp = 60;
+
+
+
+
+  if (altshape)
+     {
+     int temp;
+     int delta;
+
+     temp = weaponscale;
+     delta = FixedMul((weaponbobx<<9),weaponscale);
+     weaponscale += delta;
+     ScaleWeapon(xdisp - weaponbobx,ydisp + weaponboby + locplayerstate->weaponheight,shapenum);
+     weaponscale -= delta;
+	  ScaleWeapon(weaponbobx - 80,ydisp + weaponboby + locplayerstate->weaponheight,altshape);
+     weaponscale = temp;
+     }
+  else
+     {
+     int temp;
+     int delta;
+
+     temp = weaponscale;
+     delta = FixedMul((weaponbobx<<9),weaponscale);
+     weaponscale -= delta;
+     ScaleWeapon(xdisp + weaponbobx,ydisp + weaponboby + locplayerstate->weaponheight,shapenum);
+     weaponscale = temp;
+     }
+  }
+}
+
+void AdaptDetail ( void )
+{
+#if PROFILE
+   return;
+#else
+
+   whereami=8;
+   if ((preindex<0) || (preindex>2))
+      Error("preindex out of range\n");
+   pretics[preindex]=(pretics[0]+pretics[1]+pretics[2]+(tics<<16)+0x8000)>>2;
+   if (pretics[preindex]>GOLOWER)
+      {
+      pretics[0]=GOHIGHER;
+      pretics[1]=GOHIGHER;
+      pretics[2]=GOHIGHER;
+      doublestep++;
+      if (doublestep>2) doublestep=2;
+      }
+   else if (pretics[preindex]<GOHIGHER)
+		{
+      if (doublestep>0)
+         doublestep--;
+      }
+   preindex++;
+   if (preindex>2)
+      preindex=0;
+#endif
+}
+
+
+
+/*
+=====================
+=
+= CalcTics
+=
+=====================
+*/
+
+void CalcTics (void)
+{
+
+#if PROFILE
+   tics=PROFILETICS;
+   GetTicCount()+=PROFILETICS;
+   oldtime=GetTicCount();
+   return;
+#else
+#if (DEVELOPMENT == 1)
+   int i;
+#endif
+   volatile int tc;
+
+   whereami=9;
+//   SoftError("InCalcTics\n");
+//   SoftError("CT GetTicCount()=%ld\n",GetTicCount());
+//   SoftError("CT oldtime=%ld\n",oldtime);
+
+//
+// calculate tics since last refresh for adaptive timing
+//
+
+   tc=GetTicCount();
+	while (tc==oldtime) { tc=GetTicCount(); } /* endwhile */
+   tics=tc-oldtime;
+
+//   SoftError("CT GetTicCount()=%ld\n",GetTicCount());
+//   if (tics>MAXTICS)
+//      {
+//      tc-=(tics-MAXTICS);
+//      GetTicCount() = tc;
+//     tics = MAXTICS;
+//      }
+
+   if (demoplayback || demorecord)
+      {
+      if (tics>MAXTICS)
+         {
+         tc=oldtime+MAXTICS;
+         tics=MAXTICS;
+         ISR_SetTime(tc);
+         }
+      }
+   oldtime=tc;
+#if (DEVELOPMENT == 1)
+   if (graphicsmode==true)
+      {
+      int drawntics;
+
+      VGAWRITEMAP(1);
+      drawntics=tics;
+      if (drawntics>MAXDRAWNTICS)
+         drawntics=MAXDRAWNTICS;
+      for (i=0;i<drawntics;i++)
+         *((byte *)displayofs+screenofs+(SCREENBWIDE*3)+i)=egacolor[15];
+      }
+/*
+      if (drawtime>MAXDRAWNTICS)
+         drawtime=MAXDRAWNTICS;
+      for (i=0;i<drawtime;i++)
+         *((byte *)displayofs+screenofs+(SCREENBWIDE*5)+i)=egacolor[2];
+      if (walltime>MAXDRAWNTICS)
+         walltime=MAXDRAWNTICS;
+      for (i=0;i<walltime;i++)
+         *((byte *)displayofs+screenofs+(SCREENBWIDE*7)+i)=egacolor[14];
+      if (actortime>MAXDRAWNTICS)
+         actortime=MAXDRAWNTICS;
+      for (i=0;i<actortime;i++)
+         *((byte *)displayofs+screenofs+(SCREENBWIDE*9)+i)=egacolor[4];
+      }
+*/
+#endif
+#endif
+
+}
+
+/*
+==========================
+=
+= SetSpriteLightLevel
+=
+==========================
+*/
+
+void SetSpriteLightLevel (int x, int y, visobj_t * sprite, int dir, int fullbright)
+{
+   int i;
+   int lv;
+   int intercept;
+
+   whereami=10;
+
+	if (MISCVARS->GASON==1)
+		{
+		sprite->colormap=greenmap+(MISCVARS->gasindex<<8);
+		return;
+      }
+
+   if (fulllight || fullbright)
+      {
+      sprite->colormap=colormap+(1<<12);
+      return;
+      }
+
+   if (fog)
+      {
+      i=(sprite->viewheight>>normalshade)+minshade;
+      if (i>maxshade) i=maxshade;
+      sprite->colormap=colormap+(i<<8);
+      }
+   else
+      {
+      if (lightsource)
+         {
+    	   if (dir==east || dir==west)
+            intercept=(x>>11)&0x1c;
+         else
+            intercept=(y>>11)&0x1c;
+
+         lv=(((LightSourceAt(x>>16,y>>16)>>intercept)&0xf)>>1);
+         i=maxshade-(sprite->viewheight>>normalshade)-lv;
+         if (i<minshade) i=minshade;
+         sprite->colormap=colormap+(i<<8);
+         }
+      else
+         {
+         i=maxshade-(sprite->viewheight>>normalshade);
+         if (i<minshade) i=minshade;
+         sprite->colormap=colormap+(i<<8);
+         }
+      }
+}
+
+/*
+==========================
+=
+= SetColorLightLevel
+=
+==========================
+*/
+
+void SetColorLightLevel (int x, int y, visobj_t * sprite, int dir, int color, int fullbright)
+{
+   int i;
+   int lv;
+   int intercept;
+   int height;
+   byte * map;
+
+
+   whereami=11;
+   height=sprite->viewheight<<1;
+   map=playermaps[color];
+	if (MISCVARS->GASON==1)
+		{
+		sprite->colormap=greenmap+(MISCVARS->gasindex<<8);
+		return;
+      }
+
+   if ((fulllight) || (fullbright))
+      {
+      sprite->colormap=map+(1<<12);
+      return;
+      }
+
+   if (fog)
+      {
+      i=(height>>normalshade)+minshade;
+      if (i>maxshade) i=maxshade;
+      sprite->colormap=map+(i<<8);
+      }
+   else
+      {
+      if (lightsource)
+         {
+    	   if (dir==east || dir==west)
+            intercept=(x>>11)&0x1c;
+         else
+            intercept=(y>>11)&0x1c;
+
+         lv=(((LightSourceAt(x>>16,y>>16)>>intercept)&0xf)>>1);
+         i=maxshade-(height>>normalshade)-lv;
+         if (i<minshade) i=minshade;
+         sprite->colormap=map+(i<<8);
+         }
+      else
+         {
+         i=maxshade-(height>>normalshade);
+         if (i<minshade) i=minshade;
+         sprite->colormap=map+(i<<8);
+         }
+      }
+}
+
+/*
+==========================
+=
+= SetWallLightLevel
+=
+==========================
+*/
+
+void SetWallLightLevel (wallcast_t * post)
+{
+   int la;
+   int lv;
+   int i;
+
+   whereami=12;
+	if (MISCVARS->GASON==1)
+		{
+		shadingtable=greenmap+(MISCVARS->gasindex<<8);
+		return;
+		}
+
+   switch (post->posttype)
+      {
+      case 0:
+         la=0;
+         break;
+      case 1:
+         la=4;
+         break;
+      case 2:
+         la=(4-gamestate.difficulty);
+         break;
+      case 3:
+         la=3+(4-gamestate.difficulty);
+         break;
+      }
+
+   if (lightsource)
+      {
+      int x,y;
+      int intercept;
+
+      x=post->offset>>7;
+      y=post->offset&0x7f;
+      intercept=(post->texture>>11)&0x1c;
+      lv=(((LightSourceAt(x,y)>>intercept)&0xf)>>1);
+      }
+   else
+      lv=0;
+   if (fulllight)
+      {
+      if (fog)
+         {
+         i =16+minshade-lv+la;
+         if (i>maxshade+la) i=maxshade+la;
+         shadingtable=colormap+(i<<8);
+         }
+      else
+         {
+         i =maxshade-16-lv+la;
+         if (i>=maxshade) i=maxshade;
+         if (i<minshade+la) i=minshade+la;
+         shadingtable=colormap+(i<<8);
+         }
+      return;
+      }
+   if (fog)
+      {
+      i =(post->wallheight>>normalshade)+minshade-lv+la;
+      if (i>maxshade+la) i=maxshade+la;
+      shadingtable=colormap+(i<<8);
+      }
+   else
+      {
+      i =maxshade-(post->wallheight>>normalshade)-lv+la;
+      if (i>=maxshade) i=maxshade;
+      if (i<minshade+la) i=minshade+la;
+      shadingtable=colormap+(i<<8);
+      }
+}
+
+
+
+/*
+====================
+=
+= DrawWallPost
+=
+====================
+*/
+
+void DrawWallPost ( wallcast_t * post, byte * buf)
+{
+   int ht;
+   int topscreen;
+   int bottomscreen;
+   byte * src;
+   byte * src2;
+
+   whereami=42;
+   if (post->lump)
+      src=W_CacheLumpNum(post->lump,PU_CACHE, CvtNull, 1);
+	if (post->alttile!=0)
+      {
+      if (post->alttile==-1)
+         {
+         ht=maxheight+32;
+         dc_invscale   = post->wallheight<<(10-HEIGHTFRACTION);
+         dc_texturemid = (pheight<<SFRACBITS)+(SFRACUNIT>>1);
+         topscreen     = centeryfrac - FixedMul(dc_texturemid,dc_invscale);
+         bottomscreen  = topscreen + (dc_invscale*ht);
+         dc_yh = ((bottomscreen-1)>>SFRACBITS)+1;
+         if (dc_yh < 0)
+            {
+            post->floorclip=-1;
+            post->ceilingclip=0;
+            }
+         else if (dc_yh >= viewheight)
+            {
+            post->floorclip=viewheight-1;
+            post->ceilingclip=viewheight;
+            }
+         else
+            {
+            post->floorclip=dc_yh-1;
+            post->ceilingclip=dc_yh;
+            }
+         return;
+         }
+      else
+         {
+         ht=nominalheight;
+         src2=W_CacheLumpNum(post->alttile,PU_CACHE, CvtNull, 1);
+         }
+      }
+   else
+      {
+      ht=maxheight+32;
+      src2=src;
+      }
+
+   dc_invscale   = post->wallheight<<(10-HEIGHTFRACTION);
+   dc_texturemid = (pheight<<SFRACBITS)+(SFRACUNIT>>1);
+	topscreen     = centeryfrac - FixedMul(dc_texturemid,dc_invscale);
+   bottomscreen  = topscreen + (dc_invscale*ht);
+   dc_yl = (topscreen+SFRACUNIT-1)>>SFRACBITS;
+   dc_yh = ((bottomscreen-1)>>SFRACBITS)+1;
+
+   if (dc_yl >= viewheight)
+      {
+      post->ceilingclip=viewheight;
+      post->floorclip=viewheight-1;
+      return;
+      }
+   else if (dc_yl < 0)
+      dc_yl = 0;
+
+   dc_iscale     = (64<<(16+HEIGHTFRACTION))/post->wallheight;
+
+   if (dc_yh < 0)
+      {
+      post->floorclip=-1;
+      post->ceilingclip=0;
+      goto bottomcheck;
+      }
+   else if (dc_yh > viewheight)
+      dc_yh = viewheight;
+
+   post->ceilingclip=dc_yl;
+   post->floorclip=dc_yh-1;
+   dc_source=src2+((post->texture>>4)&0xfc0);
+   R_DrawWallColumn (buf);
+
+bottomcheck:
+
+   if (ht!=nominalheight)
+      return;
+
+   dc_texturemid-=(nominalheight<<SFRACBITS);
+   topscreen     = centeryfrac - FixedMul(dc_texturemid,dc_invscale);
+   bottomscreen  = topscreen + (dc_invscale<<6);
+   dc_yl = (topscreen+SFRACUNIT-1)>>SFRACBITS;
+   dc_yh = ((bottomscreen-1)>>SFRACBITS);
+
+	if (dc_yl >= viewheight)
+      return;
+   else if (dc_yl < 0)
+      dc_yl = 0;
+   if (dc_yh < 0)
+      return;
+   else if (dc_yh > viewheight)
+      dc_yh = viewheight;
+   post->floorclip=dc_yh-1;
+   dc_source=src+((post->texture>>4)&0xfc0);
+   R_DrawWallColumn (buf);
+}
+
+/*
+====================
+=
+= DrawWalls
+=
+====================
+*/
+
+void   DrawWalls (void)
+{
+   char * buf;
+   int plane;
+   wallcast_t * post;
+
+   whereami=13;
+   
+   plane = 0;
+   
+   if (doublestep>1)
+      {
+#ifdef DOS
+      for (plane=0;plane<4;plane+=2)
+#endif
+         {
+         VGAMAPMASK((1<<plane)+(1<<(plane+1)));
+         buf=(byte *)(bufferofs);
+#ifdef DOS
+         for (post=&posts[plane];post<&posts[viewwidth];post+=4,buf++)
+#else
+         for (post=&posts[plane];post<&posts[viewwidth];post+=2,buf+=2)
+#endif
+            {
+            SetWallLightLevel(post);
+            DrawWallPost(post,buf);
+#ifndef DOS            
+            DrawWallPost(post,buf+1); 
+#endif
+            (post+1)->ceilingclip=post->ceilingclip;
+            (post+1)->floorclip=post->floorclip;
+            }
+         }
+		}
+   else
+      {
+#ifdef DOS
+      for (plane=0;plane<4;plane++)
+#endif
+         {
+         VGAWRITEMAP(plane);
+         buf=(byte *)(bufferofs);
+#ifdef DOS
+         for (post=&posts[plane];post<&posts[viewwidth];post+=4,buf++)
+#else
+         for (post=&posts[plane];post<&posts[viewwidth];post++,buf++)
+#endif
+            {
+            SetWallLightLevel(post);
+            DrawWallPost(post,buf);
+            }
+         }
+      }
+}
+
+
+/*
+====================
+=
+= TransformDoors
+=
+====================
+*/
+
+void TransformDoors( void )
+{
+   int i;
+   int numvisible;
+   boolean result;
+   int gx,gy;
+   visobj_t visdoorlist[MAXVISIBLEDOORS],*doorptr;
+
+   whereami=14;
+   doorptr=&visdoorlist[0];
+//
+// place door objects
+//
+
+  for (i = 0;i<doornum;i++)
+	  {
+	  if (spotvis[doorobjlist[i]->tilex][doorobjlist[i]->tiley])
+		  {
+        mapseen[doorobjlist[i]->tilex][doorobjlist[i]->tiley]=1;
+        doorptr->texturestart=0;
+        doorptr->textureend=0;
+        if (doorobjlist[i]->vertical)
+           {
+           gx=(doorobjlist[i]->tilex<<16)+0x8000;
+           gy=(doorobjlist[i]->tiley<<16);
+           if (viewx<gx)
+              result=TransformPlane(gx,gy,gx,gy+0xffff,doorptr);
+           else
+              result=TransformPlane(gx,gy+0xffff,gx,gy,doorptr);
+           }
+        else
+           {
+           gx=(doorobjlist[i]->tilex<<16);
+           gy=(doorobjlist[i]->tiley<<16)+0x8000;
+           if (viewy<gy)
+              result=TransformPlane(gx+0xffff,gy,gx,gy,doorptr);
+           else
+              result=TransformPlane(gx,gy,gx+0xffff,gy,doorptr);
+           }
+        if (result==true)
+           {
+           doorptr->viewx=0;
+           doorptr->shapenum=doorobjlist[i]->texture;
+           doorptr->altshapenum=doorobjlist[i]->alttexture;
+           if (doorobjlist[i]->texture==doorobjlist[i]->basetexture)
+              {
+              doorptr->shapesize=(doorobjlist[i]->tilex<<7)+doorobjlist[i]->tiley;
+              if (doorptr < &visdoorlist[MAXVISIBLEDOORS-1]) // don't let it overflo'
+                 doorptr++;
+              }
+           else
+              {
+              doorptr->shapesize=3;
+              memcpy(visptr,doorptr,sizeof(visobj_t));
+              if (visptr < &vislist[MAXVISIBLE-1])
+                 visptr++;
+              }
+           }
+		  }
+     }
+//
+// draw from back to front
+//
+   numvisible = doorptr-&visdoorlist[0];
+   if (!numvisible)
+      return;
+   SortVisibleList( numvisible, &visdoorlist[0] );
+   for (i = 0; i<numvisible; i++)
+      {
+      //
+      // draw farthest
+      //
+      InterpolateWall (sortedvislist[i]);
+      }
+}
+
+
+/*
+====================
+=
+= TransformPushWalls
+=
+====================
+*/
+
+void TransformPushWalls( void )
+{
+  int   i;
+  int   gx,gy;
+  byte   *visspot;
+  visobj_t *savedptr;
+  int numvisible;
+  boolean result;
+
+   whereami=15;
+  savedptr=visptr;
+  //
+  // place pwall objects
+  //
+  for (i = 0;i<pwallnum;i++)
+	  {
+     if ((pwallobjlist[i]->action==pw_pushed) || (pwallobjlist[i]->action==pw_npushed))
+        continue;
+	  visspot = &spotvis[pwallobjlist[i]->x>>16][pwallobjlist[i]->y>>16];
+	  if (*visspot
+		  || ( *(visspot-1))
+		  || ( *(visspot+1))
+		  || ( *(visspot-128))
+		  || ( *(visspot+128)))
+        {
+        gx=pwallobjlist[i]->x;
+        gy=pwallobjlist[i]->y;
+        mapseen[gx>>16][gy>>16]=1;
+        if (viewx<gx)
+           {
+           if (viewy<gy)
+              {
+              visptr->texturestart=(gx-0x8000)&0xffff;
+              visptr->textureend=visptr->texturestart;
+              result=TransformPlane(gx+0x7fff,gy-0x8000,gx-0x8000,gy-0x8000,visptr);
+              visptr->texturestart^=0xffff;
+              visptr->textureend^=0xffff;
+              visptr->shapenum=pwallobjlist[i]->texture;
+              visptr->shapesize=((pwallobjlist[i]->x>>16)<<7)+(pwallobjlist[i]->y>>16);
+              visptr->viewx+=2;
+              if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
+                 visptr++;
+              visptr->texturestart=(gy-0x8000)&0xffff;
+              visptr->textureend=visptr->texturestart;//-0xffff;
+              result=TransformPlane(gx-0x8000,gy-0x8000,gx-0x8000,gy+0x7fff,visptr);
+              }
+           else
+              {
+              visptr->texturestart=(gy-0x8000)&0xffff;
+              visptr->textureend=visptr->texturestart;//-0xffff;
+              result=TransformPlane(gx-0x8000,gy-0x8000,gx-0x8000,gy+0x7fff,visptr);
+              visptr->shapenum=pwallobjlist[i]->texture;
+              visptr->shapesize=((pwallobjlist[i]->x>>16)<<7)+(pwallobjlist[i]->y>>16);
+              visptr->viewx+=2;
+              if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
+                 visptr++;
+				  visptr->texturestart=(gx-0x8000)&0xffff;
+              visptr->textureend=visptr->texturestart;//-0xffff;
+              result=TransformPlane(gx-0x8000,gy+0x7fff,gx+0x7fff,gy+0x7fff,visptr);
+              }
+           }
+        else
+           {
+           if (viewy<gy)
+              {
+              visptr->texturestart=(gy-0x8000)&0xffff;
+              visptr->textureend=visptr->texturestart;
+              result=TransformPlane(gx+0x7fff,gy+0x7fff,gx+0x7fff,gy-0x8000,visptr);
+              visptr->texturestart^=0xffff;
+              visptr->textureend^=0xffff;
+              visptr->shapenum=pwallobjlist[i]->texture;
+              visptr->shapesize=((pwallobjlist[i]->x>>16)<<7)+(pwallobjlist[i]->y>>16);
+              visptr->viewx+=2;
+              if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
+                 visptr++;
+              visptr->texturestart=(gx-0x8000)&0xffff;
+              visptr->textureend=visptr->texturestart;
+              result=TransformPlane(gx+0x7fff,gy-0x8000,gx-0x8000,gy-0x8000,visptr);
+              visptr->texturestart^=0xffff;
+              visptr->textureend^=0xffff;
+              }
+           else
+              {
+              visptr->texturestart=(gx-0x8000)&0xffff;
+              visptr->textureend=visptr->texturestart;//-0xffff;
+              result=TransformPlane(gx-0x8000,gy+0x7fff,gx+0x7fff,gy+0x7fff,visptr);
+              visptr->shapenum=pwallobjlist[i]->texture;
+              visptr->shapesize=((pwallobjlist[i]->x>>16)<<7)+(pwallobjlist[i]->y>>16);
+              visptr->viewx+=2;
+              if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
+                 visptr++;
+              visptr->texturestart=(gy-0x8000)&0xffff;
+              visptr->textureend=visptr->texturestart;
+              result=TransformPlane(gx+0x7fff,gy+0x7fff,gx+0x7fff,gy-0x8000,visptr);
+              visptr->texturestart^=0xffff;
+              visptr->textureend^=0xffff;
+              }
+			  }
+        visptr->viewx+=2;
+        visptr->shapenum=pwallobjlist[i]->texture;
+        visptr->shapesize=((pwallobjlist[i]->x>>16)<<7)+(pwallobjlist[i]->y>>16);
+        if ((visptr < &vislist[MAXVISIBLE-1]) && (result==true)) // don't let it overflo'
+           visptr++;
+        }
+     }
+
+
+//
+// draw from back to front
+//
+   numvisible = visptr-savedptr;
+   if (!numvisible)
+      return;
+   SortVisibleList( numvisible, savedptr );
+   for (i = 0; i<numvisible; i++)
+      {
+      //
+      // draw farthest
+      //
+      if (sortedvislist[i]->shapenum & 0x1000)
+         sortedvislist[i]->shapenum=animwalls[sortedvislist[i]->shapenum&0x3ff].texture;
+      sortedvislist[i]->altshapenum=0;
+      InterpolateWall (sortedvislist[i]);
+      }
+   visptr=savedptr;
+}
+
+/*
+====================
+=
+= WallRefresh
+=
+====================
+*/
+
+void WallRefresh (void)
+{
+   volatile int dtime;
+	int mag;
+   int yzangle;
+
+   whereami=16;
+   firstcoloffset=(firstcoloffset+(tics<<8))&65535;
+
+   dtime=GetFastTics();
+   if (missobj)
+      {
+      viewangle=missobj->angle;
+		viewx=missobj->x-costable[viewangle];
+		viewy=missobj->y+sintable[viewangle];
+      pheight = missobj->z + 32;
+      nonbobpheight=pheight;
+      spotvis[missobj->tilex][missobj->tiley]=1;
+		yzangle=missobj->yzangle;
+      }
+   else
+      {
+      if (player->flags&FL_SHROOMS)
+         {
+         viewangle = (player->angle + FixedMulShift(FINEANGLES,sintable[(GetTicCount()<<5)&(FINEANGLES-1)],(16+4)))&(FINEANGLES-1);
+         ChangeFocalWidth(FixedMulShift(40,sintable[(GetTicCount()<<5)&(FINEANGLES-1)],16));
+         }
+      else
+         viewangle = player->angle;
+      if ((viewangle<0) && (viewangle>=FINEANGLES))
+         Error ("View angle out of range = %d\n",viewangle);
+      viewx = player->x;
+      viewy = player->y;
+      pheight = player->z + locplayerstate->playerheight + locplayerstate->heightoffset;
+      nonbobpheight=pheight;
+      if (
+           (
+             (player->z == nominalheight) ||
+             (IsPlatform(player->tilex,player->tiley)) ||
+             (DiskAt(player->tilex,player->tiley))
+           ) &&
+           (!(player->flags & FL_DOGMODE)) &&
+           (BobbinOn==true) &&
+           (GamePaused==false)
+         )
+			{
+         int mag;
+
+         mag=(player->speed>MAXBOB ? MAXBOB : player->speed);
+
+         pheight+=FixedMulShift(mag,sintable[(GetTicCount()<<7)&2047],28);
+
+         weaponbobx=FixedMulShift(mag,costable[((GetTicCount()<<5))&(FINEANGLES-1)],27);
+         weaponboby=FixedMulShift(mag,sintable[((GetTicCount()<<5))&((FINEANGLES/2)-1)],26);
+			}
+      else
+         {
+         weaponbobx=0;
+         weaponboby=0;
+         }
+      yzangle=player->yzangle;
+      spotvis[player->tilex][player->tiley]=1;
+      }
+
+	if (yzangle > ANG180)
+      pheight -= (sintable[yzangle&2047] >> 14);
+	else
+      pheight += (sintable[yzangle&2047] >> 14);
+
+   viewx -= (FixedMul(sintable[yzangle&2047],costable[viewangle&2047])>>1);
+   viewy += (FixedMul(sintable[yzangle&2047],sintable[viewangle&2047])>>1);
+
+// Set YZ angle
+
+   centery=viewheight>>1;
+
+	if (yzangle>ANG180)
+		centery-=FixedMul(FINEANGLES-yzangle,yzangleconverter);
+	else
+		centery+=FixedMul(yzangle,yzangleconverter);
+
+   centeryfrac=(centery<<16);
+
+	if (pheight < 1)
+	   pheight = 1;
+	else if (pheight > maxheight+30)
+		pheight = maxheight+30;
+
+   if (nonbobpheight < 1)
+      nonbobpheight = 1;
+   else if (nonbobpheight > maxheight+30)
+      nonbobpheight = maxheight+30;
+
+   // Set light level of touchplates etc.
+
+   mag=7+((3-gamestate.difficulty)<<2);
+
+   transparentlevel=FixedMul(mag,sintable[(GetTicCount()<<5)&(FINEANGLES-1)])+mag;
+
+   viewsin = sintable[viewangle];
+   viewcos = costable[viewangle];
+   c_startx=(scale*viewcos)-(centerx*viewsin);
+   c_starty=(-scale*viewsin)-(centerx*viewcos);
+   Refresh ();
+   UpdateClientControls();
+   TransformPushWalls();
+   TransformDoors();
+   UpdateClientControls();
+   DrawWalls();
+   UpdateClientControls();
+   walltime=GetFastTics()-dtime;
+
+}
+
+
+/*
+====================
+=
+= GetRainBoundingBox
+=
+====================
+*/
+
+void GetRainBoundingBox (int * xmin, int * xmax, int * ymin, int * ymax)
+{
+   wallcast_t * post;
+   int x,y;
+
+   // zero out all boundaries by default
+
+   *xmax=0;
+   *ymax=0;
+   *xmin=127<<16;
+   *ymin=127<<16;
+
+   // check player's x and y
+
+   if (viewx<(*xmin))
+      (*xmin)=viewx;
+   else if (viewx>(*xmax))
+      (*xmax)=viewx;
+
+   if (viewy<(*ymin))
+      (*ymin)=viewy;
+   else if (viewy>(*ymax))
+      (*ymax)=viewy;
+
+   for (post=&posts[0];post<&posts[viewwidth];post+=(viewwidth>>2))
+      {
+      x=(post->offset>>7)<<16;
+      y=(post->offset&0x7f)<<16;
+
+      if (x<(*xmin))
+         (*xmin)=x;
+      else if (x>(*xmax))
+         (*xmax)=x;
+
+      if (y<(*ymin))
+         (*ymin)=y;
+      else if (y>(*ymax))
+         (*ymax)=y;
+      }
+}
+
+/*
+========================
+=
+= InterpolateWall
+=
+========================
+*/
+
+void InterpolateWall (visobj_t * plane)
+{
+   int d1,d2;
+   int top;
+   int topinc;
+   int bot;
+   int botinc;
+   int i;
+   int texture;
+   int dh;
+   int dx;
+   int height;
+   byte * buf;
+
+   whereami=17;
+   dx=(plane->x2-plane->x1+1);
+   if (plane->h1<=0 || plane->h2<=0 || dx==0)
+      return;
+   d1=(1<<(16+HEIGHTFRACTION)) / plane->h1;
+   d2=(1<<(16+HEIGHTFRACTION)) / plane->h2;
+   dh=(((plane->h2-plane->h1)<<DHEIGHTFRACTION)+(1<<(DHEIGHTFRACTION-1)))/dx;
+   top=0;
+   topinc=FixedMulShift(d1,plane->textureend-plane->texturestart,4);
+   bot=d2*dx;
+   botinc=d1-d2;
+   height=plane->h1<<DHEIGHTFRACTION;
+   buf=(byte *)bufferofs;
+   if (plane->x1>=viewwidth)
+      return;
+   for (i=plane->x1;i<=plane->x2;i++)
+      {
+      if ((i>=0 && i<viewwidth)&&(posts[i].wallheight<=(height>>DHEIGHTFRACTION)))
+         {
+         if (bot)
+            {
+            texture=((top/bot)+(plane->texturestart>>4))&0xfc0;
+            posts[i].texture=texture<<4;
+            posts[i].lump=plane->shapenum;
+				posts[i].alttile=plane->altshapenum;
+            posts[i].posttype=plane->viewx;
+            posts[i].offset=plane->shapesize;
+            posts[i].wallheight=height>>DHEIGHTFRACTION;
+            }
+         }
+      top+=topinc;
+      bot+=botinc;
+      height+=dh;
+      }
+}
+
+
+/*
+========================
+=
+= InterpolateDoor
+=
+========================
+*/
+
+void InterpolateDoor (visobj_t * plane)
+{
+   int d1,d2;
+   int top;
+   int topinc;
+   int bot;
+   int botinc;
+   int i;
+   int texture;
+   int dh;
+   int dx;
+   int height;
+   int bottomscreen;
+   byte * shape;
+   byte * shape2;
+   byte * buf;
+   patch_t *p;
+   int pl;
+
+   whereami=18;
+   dx=(plane->x2-plane->x1+1);
+   if (plane->h1<=0 || plane->h2<=0 || dx==0)
+      return;
+   shape=W_CacheLumpNum(plane->shapenum,PU_CACHE, Cvt_patch_t, 1);
+	shape2=W_CacheLumpNum(plane->altshapenum,PU_CACHE, Cvt_patch_t, 1);
+   p=(patch_t *)shape;
+   d1=(1<<(16+HEIGHTFRACTION)) / plane->h1;
+   d2=(1<<(16+HEIGHTFRACTION)) / plane->h2;
+   dh=(((plane->h2-plane->h1)<<DHEIGHTFRACTION)+(1<<(DHEIGHTFRACTION-1)))/dx;
+   topinc=FixedMulShift(d1,plane->textureend-plane->texturestart,4);
+   botinc=d1-d2;
+   if (plane->x1>=viewwidth)
+      return;
+#ifdef DOS
+   for (pl=0;pl<4;pl++)
+#endif
+      {
+#ifdef DOS
+      top=topinc*pl;
+      bot=(d2*dx)+(pl*botinc);
+      height=(plane->h1<<DHEIGHTFRACTION)+(dh*pl);
+      buf=(byte *)bufferofs+((pl+plane->x1)>>2);
+      VGAWRITEMAP((plane->x1+pl)&3);
+
+      for (i=plane->x1+pl;i<=plane->x2;i+=4,buf++)
+#else
+      top=0;
+      bot=(d2*dx);
+      height=(plane->h1<<DHEIGHTFRACTION);
+      buf=(byte *)bufferofs+(plane->x1);
+
+      for (i=plane->x1;i<=plane->x2;i++,buf++)
+#endif
+         {
+         if ((i>=0 && i<viewwidth) && (bot!=0) && (posts[i].wallheight<=(height>>DHEIGHTFRACTION)) )
+            {
+            dc_invscale=height>>(HEIGHTFRACTION+DHEIGHTFRACTION-10);
+            dc_iscale = 0xffffffffu/(unsigned)dc_invscale;
+            dc_texturemid=((pheight-nominalheight+p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
+            sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
+
+            texture=((top/bot)+(plane->texturestart>>4))>>6;
+            SetLightLevel(height>>DHEIGHTFRACTION);
+            ScaleMaskedPost (p->collumnofs[texture]+shape,buf);
+
+            if (levelheight>1)
+               {
+               sprtopoffset-=(dc_invscale<<6)*(levelheight-1);
+               bottomscreen =sprtopoffset + (dc_invscale*nominalheight);
+               dc_yl = (sprtopoffset+SFRACUNIT-1)>>SFRACBITS;
+               dc_yh = ((bottomscreen-1)>>SFRACBITS)+1;
+               if (dc_yl >= viewheight)
+                  continue;
+               else if (dc_yl < 0)
+						dc_yl = 0;
+               if (dc_yh > viewheight)
+                  dc_yh = viewheight;
+
+               dc_source=shape2+((texture<<6)&0xfc0);
+               R_DrawWallColumn (buf);
+               }
+            }
+            
+#ifdef DOS
+         top+=topinc<<2;
+         bot+=botinc<<2;
+         height+=dh<<2;
+#else
+         top+=topinc;
+         bot+=botinc;
+         height+=dh;
+#endif
+         }
+      }
+}
+
+
+/*
+========================
+=
+= InterpolateMaskedWall
+=
+========================
+*/
+
+void InterpolateMaskedWall (visobj_t * plane)
+{
+   int d1,d2;
+   int top;
+   int topinc;
+   int bot;
+   int botinc;
+   int i;
+   int j;
+   int texture;
+   int dh;
+   int dx;
+   int height;
+   byte * shape;
+   byte * shape2;
+   byte * shape3;
+   byte * buf;
+	transpatch_t *p;
+   patch_t *p2;
+   patch_t *p3;
+   int pl;
+   boolean drawbottom,drawmiddle,drawtop;
+   int topoffset;
+
+   whereami=19;
+   dx=(plane->x2-plane->x1+1);
+   if (plane->h1<=0 || plane->h2<=0 || dx==0)
+      return;
+   if (plane->altshapenum>=0)
+      {
+      drawmiddle=true;
+      shape2=W_CacheLumpNum(plane->altshapenum,PU_CACHE, Cvt_patch_t, 1);
+      p2=(patch_t *)shape2;
+      topoffset=p2->topoffset;
+      }
+   else
+      {
+      drawmiddle=false;
+      }
+   if (plane->viewx>=0)
+      {
+      drawtop=true;
+      shape3=W_CacheLumpNum(plane->viewx,PU_CACHE, Cvt_patch_t, 1);
+      p3=(patch_t *)shape3;
+      topoffset=p3->topoffset;
+      }
+   else
+      {
+      drawtop=false;
+      }
+   if (plane->shapenum>=0)
+      {
+      drawbottom=true;
+      shape=W_CacheLumpNum(plane->shapenum,PU_CACHE, Cvt_transpatch_t, 1);
+      p = (transpatch_t *)shape;
+      topoffset=p->topoffset;
+      }
+   else
+      {
+      drawbottom=false;
+      }
+
+   d1=(1<<(16+HEIGHTFRACTION)) / plane->h1;
+   d2=(1<<(16+HEIGHTFRACTION)) / plane->h2;
+   dh=(((plane->h2-plane->h1)<<DHEIGHTFRACTION)+(1<<(DHEIGHTFRACTION-1)))/dx;
+   topinc=FixedMulShift(d1,plane->textureend-plane->texturestart,4);
+   botinc=d1-d2;
+   if (plane->x1>=viewwidth)
+      return;
+#ifdef DOS
+   for (pl=0;pl<4;pl++)
+#endif
+      {
+#ifdef DOS
+      int planenum;
+
+      top=topinc*pl;
+      bot=(d2*dx)+(pl*botinc);
+      height=(plane->h1<<DHEIGHTFRACTION)+(dh*pl);
+      buf=(byte *)bufferofs+((pl+plane->x1)>>2);
+      planenum=((plane->x1+pl)&3);
+      VGAWRITEMAP(planenum);
+      VGAREADMAP(planenum);
+      for (i=plane->x1+pl;i<=plane->x2;i+=4,buf++)
+#else
+      top=0;
+      bot=(d2*dx);
+      height=(plane->h1<<DHEIGHTFRACTION);
+      buf=(byte *)bufferofs+(plane->x1);
+      for (i=plane->x1;i<=plane->x2;i++,buf++)
+#endif
+         {
+         if ((i>=0 && i<viewwidth) && (bot!=0) && (posts[i].wallheight<=(height>>DHEIGHTFRACTION)) )
+            {
+            dc_invscale=height>>(HEIGHTFRACTION+DHEIGHTFRACTION-10);
+            dc_iscale = 0xffffffffu/(unsigned)dc_invscale;
+            dc_texturemid=((pheight-nominalheight+topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
+            sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
+
+            texture=((top/bot)+(plane->texturestart>>4))>>6;
+            SetLightLevel(height>>DHEIGHTFRACTION);
+            if (drawbottom==true)
+               ScaleTransparentPost (p->collumnofs[texture]+shape,buf,(p->translevel+8));
+				for (j=0;j<levelheight-2;j++)
+               {
+               sprtopoffset-=(dc_invscale<<6);
+               dc_texturemid+=(1<<22);
+               if (drawmiddle==true)
+                  ScaleMaskedPost (p2->collumnofs[texture]+shape2,buf);
+               }
+            if (levelheight>1)
+               {
+               sprtopoffset-=(dc_invscale<<6);
+               dc_texturemid+=(1<<22);
+               if (drawtop==true)
+                  ScaleMaskedPost (p3->collumnofs[texture]+shape3,buf);
+               }
+            }
+#ifdef DOS
+         top+=topinc<<2;
+         bot+=botinc<<2;
+         height+=dh<<2;
+#else
+         top+=topinc;
+         bot+=botinc;
+         height+=dh;
+#endif
+         }
+      }
+}
+
+/*
+========================
+=
+= DrawPlayerLocation
+=
+========================
+*/
+#define PLX  (320-24)
+#define PLY  16
+void DrawPlayerLocation ( void )
+{
+   int i;
+   char buf[30];
+
+   CurrentFont=tinyfont;
+
+   whereami=20;
+   VGAMAPMASK(15);
+   for (i=0;i<18;i++)
+#ifdef DOS
+      memset((byte *)bufferofs+(ylookup[i+PLY])+(PLX>>2),0,6);
+#else
+      memset((byte *)bufferofs+(ylookup[i+PLY])+PLX,0,6);
+#endif
+   px=PLX;
+	py=PLY;
+	VW_DrawPropString(strupr(itoa(player->x,&buf[0],16)));
+	px=PLX;
+	py=PLY+6;
+	VW_DrawPropString(strupr(itoa(player->y,&buf[0],16)));
+	px=PLX;
+	py=PLY+12;
+	VW_DrawPropString(strupr(itoa(player->angle,&buf[0],16)));
+}
+
+
+
+/*
+========================
+=
+= ThreeDRefresh
+=
+========================
+*/
+
+
+int playerview=0;
+void      ThreeDRefresh (void)
+{
+   objtype * tempptr;
+
+   whereami=21;
+   tempptr=player;
+#if (DEVELOPMENT == 1)
+   if (Keyboard[sc_9])
+      {
+      while (Keyboard[sc_9])
+         {
+         IN_UpdateKeyboard();
+         }
+      playerview++;
+      if (playerview>numplayers)
+         playerview=1;
+      }
+   if (playerview!=0)
+      {
+      player=PLAYER[playerview-1];
+      }
+#endif
+
+//
+// Erase old messages
+//
+
+  RestoreMessageBackground();
+
+  bufferofs += screenofs;
+
+  RefreshClear();
+
+  UpdateClientControls ();
+
+//
+// follow the walls from there to the right, drawwing as we go
+//
+
+	visptr = &vislist[0];
+	WallRefresh ();
+
+   UpdateClientControls ();
+
+	if (fandc)
+		DrawPlanes();
+
+   UpdateClientControls ();
+
+//
+// draw all the scaled images
+//
+    DrawScaleds();                                         // draw scaled stuff
+
+   UpdateClientControls ();
+
+	if (!missobj)
+		{
+		if (locplayerstate->NETCAPTURED && (locplayerstate->NETCAPTURED != -2))
+			{
+			int value;
+
+			if (locplayerstate->NETCAPTURED < 0)
+			  value = -locplayerstate->NETCAPTURED;
+			else
+			  value = locplayerstate->NETCAPTURED;
+			DrawScreenSizedSprite(netlump+value-1);
+			}
+		DrawPlayerWeapon ();    // draw player's hand'
+
+		if (SCREENEYE)
+		  DrawScreenSprite(SCREENEYE->targettilex,SCREENEYE->targettiley,SCREENEYE->state->condition + GIBEYE1 + shapestart);
+      UpdateClientControls ();
+
+	   if (player->flags&FL_GASMASK)
+		   DrawScreenSizedSprite(gmasklump);
+
+
+      if ( SHOW_PLAYER_STATS() )
+         {
+         DrawStats ();
+         }
+
+      DoBorderShifts ();
+
+      UpdateClientControls ();
+      }
+
+   bufferofs -= screenofs;
+   DrawMessages();
+   bufferofs += screenofs;
+
+   if ( ((GamePaused==true) && (!Keyboard[sc_LShift])) ||
+        (controlupdatestarted==0)
+      )
+      DrawPause ();
+
+//
+// show screen and time last cycle
+//
+   if ((fizzlein==true) && (modemgame==false))
+   {
+      if (newlevel==true)
+         ShutdownClientControls();
+      bufferofs-=screenofs;
+      DrawPlayScreen (true);
+      RotateBuffer(0,FINEANGLES,FINEANGLES*8,FINEANGLES,(VBLCOUNTER*3)/4);
+      bufferofs+=screenofs;
+      fizzlein = false;
+      StartupClientControls();
+   }
+
+   bufferofs -= screenofs;
+
+   UpdateClientControls ();
+
+   if (HUD == true)
+      DrawPlayerLocation();
+
+   FlipPage();
+   gamestate.frame++;
+
+   player=tempptr;
+}
+
+
+//******************************************************************************
+//
+// FlipPage
+//
+//******************************************************************************
+
+void FlipPage ( void )
+{
+#ifdef DOS
+   unsigned displaytemp;
+
+   whereami=22;
+   displayofs = bufferofs;
+
+   displaytemp = displayofs;
+   if ( ( SHAKETICS != 0xFFFF ) && ( !inmenu ) && ( !GamePaused ) &&
+      ( !fizzlein ) )
+      {
+      ScreenShake ();
+      }
+
+
+//   _disable();
+   OUTP(CRTC_INDEX,CRTC_STARTHIGH);
+   OUTP(CRTC_DATA,((displayofs&0x0000ffff)>>8));
+
+
+   if (SHAKETICS != 0xFFFF)
+   {
+      if (SHAKETICS > 0)
+      {
+         OUTP (CRTC_INDEX, CRTC_STARTLOW);
+         OUTP (CRTC_DATA, (displayofs&0x000000FF));
+         displayofs = displaytemp;
+      }
+      else
+      {
+         displayofs = displaytemp;
+         OUTP(CRTC_INDEX,CRTC_STARTHIGH);
+         OUTP(CRTC_DATA,((displayofs&0x0000ffff)>>8));
+         OUTP (CRTC_INDEX, CRTC_STARTLOW);
+         OUTP (CRTC_DATA, (displayofs&0x000000FF));
+         SHAKETICS = 0xFFFF;
+      }
+   }
+//   _enable();
+
+   bufferofs += screensize;
+   if (bufferofs > page3start)
+      bufferofs = page1start;
+#else
+
+   whereami=22;
+
+   if ( ( SHAKETICS != 0xFFFF ) && ( !inmenu ) && ( !GamePaused ) &&
+      ( !fizzlein ) )
+      {
+      ScreenShake ();
+      }
+      
+      /* TODO some shake thing */
+      
+      /* just call the one in modexlib.c */
+      XFlipPage();
+      
+#endif
+}
+
+
+//******************************************************************************
+//
+// TurnShakeOff
+//
+//******************************************************************************
+void TurnShakeOff
+   (
+   void
+   )
+
+   {
+//   _disable();
+   OUTP (CRTC_INDEX, CRTC_STARTHIGH );
+   OUTP (CRTC_DATA, ( ( displayofs & 0x0000ffff ) >> 8 ) );
+   OUTP (CRTC_INDEX, CRTC_STARTLOW);
+   OUTP (CRTC_DATA, (displayofs&0x000000FF));
+//   _enable();
+   SHAKETICS = 0xFFFF;
+   }
+
+//******************************************************************************
+//
+// DrawScaledScreen
+// draw sreen after reentering fro restore game
+//******************************************************************************
+
+void DrawScaledScreen(int x, int y, int step, byte * src)
+{
+    int     xfrac;
+    int     yfrac;
+//    int     plane;
+    int     i,j;
+    byte    * p;
+    byte    * buf;
+    int     xsize;
+    int     ysize;
+
+    xsize=(iGLOBAL_SCREENWIDTH<<16)/step;
+    if (xsize>iGLOBAL_SCREENWIDTH) xsize=iGLOBAL_SCREENWIDTH;
+    ysize=(iGLOBAL_SCREENHEIGHT<<16)/step;
+    if (ysize>iGLOBAL_SCREENHEIGHT) ysize=iGLOBAL_SCREENHEIGHT;
+
+#ifdef DOS
+    for (plane=x;plane<x+4;plane++)
+#endif
+       {
+       yfrac=0;
+#ifdef DOS
+       VGAWRITEMAP(plane&3);
+#endif
+       for (j=y;j<y+ysize;j++)
+          {
+          p=src+(iGLOBAL_SCREENWIDTH*(yfrac>>16));
+#ifdef DOS
+          buf=(byte *)bufferofs+ylookup[j]+(plane>>2);
+#else
+          buf=(byte *)bufferofs+ylookup[j]+x;
+#endif
+#ifdef DOS
+          xfrac=(plane-x)*step;
+#else
+          xfrac=0;
+#endif
+          yfrac+=step;
+#ifdef DOS
+          for (i=plane;i<x+xsize;i+=4)
+#else
+          for (i=x;i<x+xsize;i++)
+#endif
+             {
+             *buf=*(p+(xfrac>>16));
+             buf++;
+#ifdef DOS
+             xfrac+=(step<<2);
+#else
+             xfrac+=step;
+#endif
+             }
+          }
+       }
+}
+
+
+//******************************************************************************
+//
+// DoLoadGameSequence
+//
+//******************************************************************************
+
+void DoLoadGameSequence ( void )
+{
+   int x;
+   int y;
+   int dx;
+   int dy;
+   int s;
+   int ds;
+   int time;
+   int i;
+   byte * destscreen;
+   pic_t *shape;//bna++
+   
+   
+
+   
+   
+   fizzlein=false;
+   x=(18+SaveGamePicX)<<16;
+   y=(30+SaveGamePicY)<<16;
+   time=VBLCOUNTER;
+   s=0x2000000;
+   dx=(-x)/time;
+   dy=(-y)/time;
+   ds=-((s-0x1000000)/time);
+
+   destscreen=SafeMalloc(64000*8);//bna fixme
+
+   SetupScreen(false);
+   ThreeDRefresh();
+
+   FlipPage();
+   FlipPage();
+
+   VL_CopyPlanarPageToMemory ( (byte *)bufferofs,  destscreen );
+   VL_CopyDisplayToHidden ();
+
+   CalcTics();
+   for (i=0;i<time;i+=tics)
+      {
+      CalcTics();
+      DrawScaledScreen((x>>16),(y>>16),(s>>8),destscreen);
+      FlipPage();
+      x+=(dx*tics);
+      if (x<0) x=0;
+      y+=(dy*tics);
+      if (y<0) y=0;
+      s+=(ds*tics);
+      }
+
+   DrawScaledScreen(0,0,0x10000,destscreen);
+   FlipPage();
+   VL_CopyDisplayToHidden ();
+   SafeFree(destscreen);
+   CalcTics();
+   CalcTics();
+   	//bna++ section
+   shape =  ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );
+   DrawTiledRegion( 0, 16, iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT - 32, 0, 16, shape );//bna++
+   DrawPlayScreen(false);
+   DisableScreenStretch();
+   SHAKETICS = 0xFFFF;
+   //bna section end
+}
+
+//******************************************************************************
+//
+// StartupRotateBuffer
+//
+//******************************************************************************
+byte * RotatedImage;
+boolean RotateBufferStarted = false;
+void StartupRotateBuffer ( int masked)
+{
+	int k;////zxcv
+   int a,b;
+
+//   int Xres = 320;//org
+//   int Yres = 200;//org
+   int   Xres =   iGLOBAL_SCREENWIDTH;//bna val 800
+   int   Yres = iGLOBAL_SCREENHEIGHT;//bna val 600
+
+
+   iG_masked = masked;
+
+   if (RotateBufferStarted == true)
+      return;
+
+   RotateBufferStarted = true;
+
+   //   RotatedImage=SafeMalloc(131072);org
+   //RotatedImage=SafeMalloc(131072*8);
+   if (iGLOBAL_SCREENWIDTH == 320) {
+		RotatedImage=SafeMalloc(131072);
+   }else if (iGLOBAL_SCREENWIDTH == 640) { 
+		RotatedImage=SafeMalloc(131072*4);
+   }else if (iGLOBAL_SCREENWIDTH == 800) { 
+		RotatedImage=SafeMalloc(131072*8);
+   }
+//SetupScreen(false);//used these 2 to test screen size
+//VW_UpdateScreen ();
+   if (masked==0) {
+	   if (iGLOBAL_SCREENWIDTH == 320) {
+		  memset(RotatedImage,0,131072);
+	   }else if (iGLOBAL_SCREENWIDTH == 640) { 
+		  memset(RotatedImage,0,131072*4);
+	   }else if (iGLOBAL_SCREENWIDTH == 800) { 
+		  //memset(RotatedImage,0,131072);//org
+		  memset(RotatedImage,0,131072*8);
+	   }
+   } else {
+	   if (iGLOBAL_SCREENWIDTH == 320) {
+		  memset(RotatedImage,0xff,131072);
+	   }else if (iGLOBAL_SCREENWIDTH == 640) { 
+		  memset(RotatedImage,0xff,131072*4);
+	   }else if (iGLOBAL_SCREENWIDTH == 800) { 
+		  memset(RotatedImage,0xff,131072*8);
+	   }
+   }
+      //memset(RotatedImage,0xff,131072);//org
+      //memset(RotatedImage,0xff,131072*8);
+
+      if ((masked == false)&&(iGLOBAL_SCREENWIDTH == 800)) {
+		DisableScreenStretch();
+		// SetTextMode (  );
+
+		k=(28*512);//14336;
+		//k=((0+28)<<10);//28672
+		   for (a=0;a<iGLOBAL_SCREENHEIGHT;a++){
+			   for (b=0;b<iGLOBAL_SCREENWIDTH;b++){
+					//*(RotatedImage+99+((a+28)<<9)+b)   =   *((byte *)bufferofs+(a*linewidth)+b);
+					// 99 is some offset value
+					k = ((a+28)<<10);
+					*(RotatedImage+(k)+b)   =   *((byte *)bufferofs+(a*linewidth)+b);
+					//*(RotatedImage+b)   =   *((byte *)bufferofs+(a*linewidth)+b);
+			   }
+			   //k+=512*2;
+		   }
+	  }else if ((masked == false)&&(iGLOBAL_SCREENWIDTH == 640)) {
+		DisableScreenStretch();
+		k=(28*512);//14336;
+		   for (a=0;a<iGLOBAL_SCREENHEIGHT;a++){
+			   for (b=0;b<iGLOBAL_SCREENWIDTH;b++){
+					k = ((a+28)<<10);
+					*(RotatedImage+(k)+b)   =   *((byte *)bufferofs+(a*linewidth)+b);
+			   }
+		   }
+
+	  }else if ((masked == true)||(iGLOBAL_SCREENWIDTH == 320)) {
+		  for (a=0;a<200;a++){
+			 for (b=0;b<320;b++)
+				*(RotatedImage+99+((a+28)<<9)+b)=*((byte *)bufferofs+(a*linewidth)+b);
+		  }
+	  }
+
+}
+/* copier liner af 1024 bredde
+a=0=14436 a=1=14848 a=2=15360 a=3=15872  -> 512 i difference
+*(RotatedImage+(512)+0) = bufferofs+(0*800)+0);
+*(RotatedImage+(512)+100) = bufferofs+(100*800)+0);
+*/
+
+//******************************************************************************
+//
+// ShutdownRotateBuffer
+//
+//******************************************************************************
+
+void ShutdownRotateBuffer ( void )
+{
+   if (RotateBufferStarted == false)
+      return;
+
+   RotateBufferStarted = false;
+   SafeFree(RotatedImage);
+}
+
+//******************************************************************************
+//
+// ScaleAndRotateBuffer
+//
+//******************************************************************************
+
+void ScaleAndRotateBuffer (int startangle, int endangle, int startscale, int endscale, int time)
+{
+   int anglestep;
+   int scalestep;
+   int angle;
+   int scale;
+   int i;
+
+
+//bna section
+//   int Xh = 160;//org
+//   int Yh = 100;//org
+
+   int Xh = iGLOBAL_SCREENWIDTH/2;
+   int Yh = iGLOBAL_SCREENHEIGHT/2;
+ //  Xh = 259;
+ //  Yh = 109;
+
+   time = time;
+////zxcv
+	DisableScreenStretch();//bna++
+
+
+   anglestep=((endangle-startangle)<<16)/time;
+   scalestep=((endscale-startscale)<<6)/time;
+
+   angle=(startangle<<16);
+     
+   scale=(startscale<<6);
+
+   CalcTics();
+   CalcTics();
+   for (i=0;i<time;i+=tics)
+      {//zxcv
+      DrawRotatedScreen(Xh,Yh, (byte *)bufferofs,(angle>>16)&(FINEANGLES-1),scale>>6,0);
+      FlipPage();
+      scale+=(scalestep*tics);
+      angle+=(anglestep*tics);
+      CalcTics();
+      }
+
+   DrawRotatedScreen(Xh,Yh, (byte *)bufferofs,endangle&(FINEANGLES-1),endscale,0);
+   FlipPage();
+   DrawRotatedScreen(Xh,Yh, (byte *)bufferofs,endangle&(FINEANGLES-1),endscale,0);
+   FlipPage();
+   DrawRotatedScreen(Xh,Yh, (byte *)bufferofs,endangle&(FINEANGLES-1),endscale,0);
+   CalcTics();
+   CalcTics();
+   //I_Delay (240);//bna++
+   	//bna++ section
+  if ( playstate == ex_stillplaying )	  {//bna++
+	   pic_t *shape;
+	   shape =  ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );
+	   DrawTiledRegion( 0, 16, iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT - 32, 0, 16, shape );//bna++
+	   DisableScreenStretch();//dont strech when we go BACK TO GAME
+	   DrawPlayScreen(true);//repaint ammo and life stat
+  }
+}
+   //bna section end
+
+
+
+//******************************************************************************
+//
+// RotateBuffer
+//
+//******************************************************************************
+
+void RotateBuffer (int startangle, int endangle, int startscale, int endscale, int time)
+{
+   int savetics;
+
+   //save off fastcounter
+
+   savetics=GetFastTics();
+
+   StartupRotateBuffer (0);
+
+   ScaleAndRotateBuffer (startangle, endangle, startscale, endscale, time);
+
+   ShutdownRotateBuffer ();
+
+   // restore fast counter
+   SetFastTics(savetics);
+}
+
+
+//******************************************************************************
+//
+// DrawRotatedScreen
+//
+//******************************************************************************
+
+void DrawRotatedScreen(int cx, int cy, byte *destscreen, int angle, int scale, int masked)
+{//ZXCV
+   int     c, s;
+   int     xst, xct;
+   int     y;
+
+   byte    * screen;
+   //int Xres = 320;//old value
+   //int Yres = 200;//old val
+
+   int Xr = iGLOBAL_SCREENWIDTH;//640;
+   int Yr = (iGLOBAL_SCREENHEIGHT);//400; //bna aaaa fix
+
+//	   SetTextMode (  );
+   c = FixedMulShift(scale,costable[angle],11);
+   s = FixedMulShift(scale,sintable[angle],11);
+
+//   c = c/2; //these values are to rotate degres or?
+//   s = s/2;
+//   xst & xct= start center values ;
+   if ((iGLOBAL_SCREENWIDTH == 320 )||(masked == true)) {
+	   xst = (((-cx)*s)+(128<<16))-(cy*c);
+	   xct = (((-cx)*c)+(256<<16)+(1<<18)-(1<<16))+(cy*s);
+   }
+   else if ((iGLOBAL_SCREENWIDTH == 640 )&&(masked == false)) {
+	   xst = (((-cx)*s)+((268)<<16))-(cy*c);
+	   xct = (((-cx)*c)+((317)<<16)+(1<<18)-(1<<16))+(cy*s);
+   }//y=268;x=317
+   else if ((iGLOBAL_SCREENWIDTH == 800 )&&(masked == false)) {
+	   xst = (((-cx)*s)+((328)<<16))-(cy*c);
+	   xct = (((-cx)*c)+((397)<<16)+(1<<18)-(1<<16))+(cy*s);
+   }//328 397
+
+   mr_xstep=s;
+   mr_ystep=c;
+
+  
+   if ((iGLOBAL_SCREENWIDTH == 800)&&(masked==0)) {
+        screen=destscreen+iGLOBAL_SCREENWIDTH;//bna aaaa fix
+   }else{
+		screen=destscreen;
+   }
+
+   if (masked==0)
+      {
+		 // paint hole 800x600 screen
+		 { 
+         mr_yfrac=xct;
+         mr_xfrac=xst;
+         VGAWRITEMAP(plane);
+         for (y=0; y<Yr; y++,mr_xfrac+=c,mr_yfrac-=s)
+            DrawRotRow(Xr,screen+ylookup[y],RotatedImage);
+         }
+      }
+   else
+      {
+         {
+         mr_yfrac=xct;
+         mr_xfrac=xst;
+         VGAWRITEMAP(plane);
+         for (y=0; y<Yr; y++,mr_xfrac+=c,mr_yfrac-=s)
+            DrawMaskedRotRow(Xr,screen+ylookup[y],RotatedImage);
+         }
+      }
+
+}
+
+
+//******************************************************************************
+//
+// DrawScaledPost
+//
+//******************************************************************************
+
+void DrawScaledPost ( int height, byte * src, int offset, int x)
+{
+   patch_t *p;
+
+   p=(patch_t *)src;
+   dc_invscale=(height<<16)/p->origsize;
+   dc_iscale=(p->origsize<<16)/height;
+   dc_texturemid=(((p->origsize>>1)+p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
+   sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
+   shadingtable=colormap+(1<<12);
+   VGAWRITEMAP(x&3);
+#ifdef DOS
+   ScaleMaskedPost(((p->collumnofs[offset])+src), (byte *)bufferofs+(x>>2));
+#else
+   ScaleMaskedPost(((p->collumnofs[offset])+src), (byte *)bufferofs+x);
+#endif
+}
+
+
+
+void ApogeeTitle (void)
+{
+   byte pal[768];
+   int   angle;
+   int   scale;
+   int   x,y;
+   int   danglex;
+   int   anglex;
+   int   dy,dangle,dscale;
+   int   time;
+
+   CalcTics();
+   CalcTics();
+   IN_ClearKeysDown();
+   viewwidth=320;
+   viewheight=200;
+   memcpy(&pal[0],W_CacheLumpName("ap_pal",PU_CACHE, CvtNull, 1),768);
+   shadingtable=colormap+(1<<12);
+   VL_NormalizePalette(&pal[0]);
+   SwitchPalette(&pal[0],35);
+//   DrawWorld();
+//   RotateBuffer(0,FINEANGLES*6,FINEANGLES*48,FINEANGLES,(VBLCOUNTER*2));
+//   DoLaserShoot("apogee");
+//   DoZIntro();
+
+   VL_ClearBuffer (bufferofs, 255);
+   DrawNormalSprite (0, 0, W_GetNumForName("ap_titl"));
+
+   StartupRotateBuffer (1);
+
+   //save off fastcounter
+
+#define APOGEEXANGLE 913
+#define APOGEEXMAG   180
+#define APOGEESTARTY 0
+#define APOGEEENDY   100
+
+#define APOGEESCALESTART (FINEANGLES<<4)
+#define APOGEESCALEEND (FINEANGLES)
+#define APOGEESONGTIME (124-1)
+
+   time = APOGEESONGTIME;
+
+   anglex=0;
+   danglex=(APOGEEXANGLE<<16)/time;
+
+   y=APOGEESTARTY<<16;
+   dy=((APOGEEENDY-APOGEESTARTY)<<16)/time;
+
+   dscale=((APOGEESCALEEND-APOGEESCALESTART)<<16)/time;
+   scale=APOGEESCALESTART<<16;
+
+   angle=0;
+   dangle=(FINEANGLES<<17)/time;
+
+   MU_StartSong(song_apogee);
+
+   CalcTics();
+
+   while (time>=0)
+      {
+      VL_DrawPostPic (W_GetNumForName("ap_wrld"));
+      IN_PumpEvents();
+
+      x=100+FixedMul(APOGEEXMAG,sintable[anglex>>16]);
+
+      DrawRotatedScreen(x,y>>16,(byte *)bufferofs,(angle>>16)&(FINEANGLES-1),scale>>16,1);
+      FlipPage();
+      CalcTics();
+      angle+=dangle*tics;
+      scale+=dscale*tics;
+      y+=dy*tics;
+      anglex+=danglex*tics;
+      time-=tics;
+      if ((LastScan) || IN_GetMouseButtons())
+         goto apogeeexit;
+      }
+   CalcTics();
+   CalcTics();
+   VL_DrawPostPic (W_GetNumForName("ap_wrld"));
+   DrawRotatedScreen(x,y>>16,(byte *)bufferofs,0,APOGEESCALEEND,1);
+   FlipPage();
+
+   while (MU_SongPlaying())
+      {
+      IN_PumpEvents();
+      if ((LastScan) || IN_GetMouseButtons())
+         goto apogeeexit;
+      }
+
+ //  I_Delay(65); //bna added
+apogeeexit:
+
+   VL_ClearBuffer (bufferofs, 0); //bna added
+   MenuFadeOut(); //bna added
+   VH_UpdateScreen (); //bna added
+   ShutdownRotateBuffer ();
+
+}
+
+#if (SHAREWARE==0)
+
+void DopefishTitle (void)
+{
+   int shapenum;
+   int height;
+
+   shapenum=W_GetNumForName("scthead1");
+   CalcTics();
+   CalcTics();
+   IN_ClearKeysDown();
+   MU_StartSong( song_secretmenu);
+   viewwidth=320;
+   viewheight=200;
+   SwitchPalette(origpal,35);
+   oldtime=GetTicCount();
+   FlipPage();
+   for (height=1;height<200;height+=(tics<<2))
+      {
+      DrawPositionedScaledSprite (160, 100, shapenum, height, 0);
+      FlipPage();
+      CalcTics();
+      if ((LastScan) || IN_GetMouseButtons())
+         break;
+      }
+   SD_Play ( SD_DOPEFISHSND );
+   oldtime=GetTicCount();
+   for (height=0;height<FINEANGLES<<1;height+=(tics<<5))
+      {
+      DrawPositionedScaledSprite (160+FixedMul(60,costable[height&(FINEANGLES-1)]), 100+FixedMul(60,sintable[height&(FINEANGLES-1)]), shapenum, 200, 0);
+      FlipPage();
+      VL_CopyPlanarPage ( (byte *) displayofs, (byte *) bufferofs );
+      CalcTics();
+      if ((LastScan) || IN_GetMouseButtons())
+         break;
+      }
+   SD_Play ( SD_DOPEFISHSND );
+   FlipPage();
+}
+
+#endif
+
+//******************************************************************************
+//
+// RotationFun
+//
+//******************************************************************************
+
+void RotationFun ( void )
+{
+   int   angle;
+   int   scale;
+   int   x,y;
+   word  buttons;
+
+   //save off fastcounter
+
+
+   angle=0;
+   scale=FINEANGLES;
+
+   StartupRotateBuffer (0);
+
+   CalcTics();
+   CalcTics();
+   while (!Keyboard[sc_Escape])
+      {
+      IN_UpdateKeyboard ();
+      DrawRotatedScreen(160,100,(byte *)bufferofs,angle,scale,0);
+      FlipPage();
+      CalcTics();
+      INL_GetMouseDelta(&x, &y);
+      buttons=IN_GetMouseButtons ();
+      angle=(angle-x)&(FINEANGLES-1);
+      if (buttons & (1 << 0))
+         {
+         if (scale>0)
+            scale-=30;
+         }
+      else if (buttons & (1 << 1))
+         {
+         scale+=30;
+         }
+      }
+   CalcTics();
+   CalcTics();
+   Keyboard[sc_Escape]=0;
+
+   ShutdownRotateBuffer ();
+}
+
+boolean ScreenSaverStarted=false;
+screensaver_t * ScreenSaver;
+#define PAUSETIME  (70)
+
+//******************************************************************************
+//
+// SetupScreenSaverPhase
+//
+//******************************************************************************
+void SetupScreenSaverPhase ( void )
+{
+   if (ScreenSaverStarted==false)
+      return;
+
+   if (ScreenSaver->phase==0)
+      {
+      ScreenSaver->x=160;
+      ScreenSaver->y=100;
+      ScreenSaver->angle=0;
+      ScreenSaver->scale=FINEANGLES;
+      ScreenSaver->dangle=FINEANGLES/VBLCOUNTER;
+      ScreenSaver->dx=0;
+      ScreenSaver->dy=0;
+      ScreenSaver->dscale=((FINEANGLES<<2)-(FINEANGLES))/VBLCOUNTER;
+      ScreenSaver->time=VBLCOUNTER;
+      }
+   else if (ScreenSaver->phase==1)
+      {
+      ScreenSaver->x=160;
+      ScreenSaver->y=100;
+      ScreenSaver->angle=0;
+      ScreenSaver->scale=FINEANGLES<<2;
+      ScreenSaver->dangle=FINEANGLES/VBLCOUNTER;
+      ScreenSaver->dx=RandomNumber("StartupScreen",0)>>5;
+      ScreenSaver->dy=RandomNumber("StartupScreen",0)>>5;
+      ScreenSaver->dscale=0;
+      ScreenSaver->time=-1;
+      }
+}
+
+//******************************************************************************
+//
+// StartupScreenSaver
+//
+//******************************************************************************
+void StartupScreenSaver ( void )
+{
+   if (ScreenSaverStarted==true)
+      return;
+
+   ScreenSaverStarted=true;
+
+   StartupRotateBuffer (0);
+
+   ScreenSaver=(screensaver_t *)SafeMalloc(sizeof(screensaver_t));
+   ScreenSaver->phase=0;
+   ScreenSaver->pausetime=PAUSETIME;
+   if (iGLOBAL_SCREENWIDTH == 320){
+		ScreenSaver->pausex=120;
+		ScreenSaver->pausey=84;
+   }else if (iGLOBAL_SCREENWIDTH == 640){
+		ScreenSaver->pausex=240;
+		ScreenSaver->pausey=201;
+   }else if (iGLOBAL_SCREENWIDTH == 800){
+		ScreenSaver->pausex=300;
+		ScreenSaver->pausey=252;
+   }
+   ScreenSaver->pausex=120;
+   ScreenSaver->pausey=84;
+   SetupScreenSaverPhase();
+}
+
+//******************************************************************************
+//
+// ShutdownScreenSaver
+//
+//******************************************************************************
+void ShutdownScreenSaver ( void )
+{
+   if (ScreenSaverStarted==false)
+      return;
+
+   ScreenSaverStarted=false;
+
+   ShutdownRotateBuffer ();
+   SafeFree(ScreenSaver);
+   	//bna section 
+   StartupClientControls();
+		   
+}
+
+//******************************************************************************
+//
+// UpdateScreenSaver
+//
+//******************************************************************************
+
+#define SPINSIZE  40
+#define MAXSPEED  8
+void UpdateScreenSaver ( void )
+{
+	//EnableScreenStretch();
+   if (ScreenSaver->time!=-1)
+      {
+      ScreenSaver->time-=tics;
+      if (ScreenSaver->time<0)
+         {
+         ScreenSaver->phase++;
+         SetupScreenSaverPhase();
+         }
+      }
+   ScreenSaver->x+=ScreenSaver->dx*tics;
+   ScreenSaver->y+=ScreenSaver->dy*tics;
+   ScreenSaver->angle=(ScreenSaver->angle+(ScreenSaver->dangle*tics))&(FINEANGLES-1);
+   ScreenSaver->scale+=ScreenSaver->dscale*tics;
+   if (ScreenSaver->x<SPINSIZE)
+      {
+      ScreenSaver->x=SPINSIZE;
+      ScreenSaver->dx=abs(ScreenSaver->dx);
+      ScreenSaver->dy+=(RandomNumber("Rotate",0)>>6)-2;
+      }
+   else if (ScreenSaver->x>iGLOBAL_SCREENWIDTH-SPINSIZE)
+      {
+      ScreenSaver->x=iGLOBAL_SCREENWIDTH-SPINSIZE;
+      ScreenSaver->dx=-(abs(ScreenSaver->dx));
+      ScreenSaver->dy+=(RandomNumber("Rotate",0)>>6)-2;
+      }
+   if (ScreenSaver->y<SPINSIZE)
+      {
+      ScreenSaver->y=SPINSIZE;
+      ScreenSaver->dy=abs(ScreenSaver->dy);
+      ScreenSaver->dx+=(RandomNumber("Rotate",0)>>6)-2;
+      }
+   else if (ScreenSaver->y>iGLOBAL_SCREENHEIGHT-SPINSIZE)
+      {
+      ScreenSaver->y=iGLOBAL_SCREENHEIGHT-SPINSIZE;
+      ScreenSaver->dy=-(abs(ScreenSaver->dy));
+      ScreenSaver->dx+=(RandomNumber("Rotate",0)>>6)-2;
+      }
+
+   if (abs(ScreenSaver->dx)>MAXSPEED)
+      ScreenSaver->dx=SGN(ScreenSaver->dx)*MAXSPEED;
+
+   if (abs(ScreenSaver->dy)>MAXSPEED)
+      ScreenSaver->dy=SGN(ScreenSaver->dy)*MAXSPEED;
+
+   DrawRotatedScreen(ScreenSaver->x,ScreenSaver->y, (byte *)bufferofs,ScreenSaver->angle,ScreenSaver->scale,0);
+
+   ScreenSaver->pausetime-=tics;
+   if (ScreenSaver->pausetime<=0)
+   {
+      ScreenSaver->pausetime=PAUSETIME;
+	  if (iGLOBAL_SCREENWIDTH == 320){
+		  ScreenSaver->pausex=RandomNumber ("pausex",0)%240;
+		  ScreenSaver->pausey=RandomNumber ("pausey",0)%168;
+      }else if (iGLOBAL_SCREENWIDTH == 640){
+		  ScreenSaver->pausex=RandomNumber ("pausex",0)%480;
+		  ScreenSaver->pausey=RandomNumber ("pausey",0)%403;
+	  }else if (iGLOBAL_SCREENWIDTH == 800){
+		  ScreenSaver->pausex=RandomNumber ("pausex",0)%600;
+		  ScreenSaver->pausey=RandomNumber ("pausey",0)%504;
+	  }
+   }
+   DrawPauseXY (ScreenSaver->pausex, ScreenSaver->pausey);
+
+   FlipPage();
+}
+#if 0
+
+//******************************************************************************
+//
+// DoLaserShoot
+//
+//******************************************************************************
+void DoLaserShoot (char * name)
+{
+
+   int sourcex;
+   int lastx;
+   int sourceheight;
+   int destheight;
+   int sourcestep;
+   int xstep;
+   int hstep;
+   int midx;
+   int startx;
+   int dx;
+   int f;
+   int s;
+   int height;
+   int x;
+   int sx;
+   int size;
+   patch_t *p;
+   byte * shape;
+
+   DrawWorld();
+   midx=160;
+   shape=W_CacheLumpName(name,PU_CACHE);
+   p=(patch_t *)shape;
+   size=p->origsize;
+
+   startx=midx-(size>>1)-(p->leftoffset);
+
+   sourcex=0;
+   lastx=startx+p->width;
+   sourcestep=(320*65536)/p->width;
+   sourceheight=p->origsize<<3;
+   destheight=p->origsize;
+   CalcTics();
+   CalcTics();
+
+
+   for (x=startx;x<lastx;x+=tics,sourcex+=(sourcestep*tics))
+      {
+      for (f=startx;f<=x;f++)
+         DrawScaledPost(destheight,shape,f-startx,f);
+      height=sourceheight<<16;
+      if (x<=midx)
+         {
+         dx=x-(sourcex>>16);
+         xstep=1;
+         }
+      else
+         {
+         dx=(sourcex>>16)-x;
+         xstep=-1;
+         }
+      sx=sourcex>>16;
+      if (dx)
+         hstep=((-destheight+sourceheight)<<16)/dx;
+      else
+         hstep=0;
+      for (s=0;s<dx;s++,height-=hstep,sx+=xstep)
+         DrawScaledPost(height>>16,shape,x-startx,sx);
+      FlipPage();
+      CalcTics();
+      DrawWorld();
+         break;
+      }
+
+   // Write out one more time so that the rest of the screen is clear
+
+   for (f=startx;f<lastx;f++)
+      DrawScaledPost(destheight,shape,f-startx,f);
+   FlipPage();
+}
+
+//******************************************************************************
+//
+// DoIntro
+//
+//******************************************************************************
+
+#define MAXMAG (80)
+#define OSCTIME (5*VBLCOUNTER)
+#define OSCXSHIFT (4)
+#define OSCTSHIFT (4)
+
+void DoIntro (void)
+{
+   byte * shape;
+   byte * origshape;
+   int mag;
+   int currentmag;
+   int magstep;
+   int time;
+   int x;
+   int t;
+
+   shadingtable=colormap+(1<<12);
+
+   origshape=W_CacheLumpName("ap_wrld",PU_CACHE);
+
+   mag=MAXMAG<<16;
+   magstep = (MAXMAG<<16)/OSCTIME;
+   time = OSCTIME;
+   t=0;
+
+   CalcTics();
+
+   while (time>0)
+      {
+      int yoffset;
+      int ylow;
+      int yhigh;
+      int offset;
+      int postheight;
+      byte * src;
+
+      shape=origshape;
+      VL_ClearBuffer (bufferofs, 0);
+      currentmag=mag>>16;
+      for (x=0;x<320;x++,shape+=200)
+         {
+         VGAWRITEMAP(x&3);
+         src=shape;
+         offset=(t+(x<<OSCXSHIFT))&(FINEANGLES-1);
+         yoffset=FixedMul(currentmag,sintable[offset]);
+         ylow=yoffset;
+         if (ylow<0)
+            {
+            src-=ylow;
+            ylow=0;
+            }
+         if (ylow>199)
+            ylow=199;
+         yhigh=yoffset+200;
+         if (yhigh>199)
+            {
+            yhigh=199;
+            }
+         if (yhigh<0)
+            yhigh=0;
+         postheight=yhigh-ylow+1;
+         if (postheight>0)
+#ifdef DOS
+            DrawSkyPost((byte *)bufferofs + (x>>2) + ylookup[ylow],src,postheight);
+#else
+            DrawSkyPost((byte *)bufferofs + x + ylookup[ylow],src,postheight);
+#endif
+         }
+      FlipPage();
+      CalcTics();
+      mag  -= (magstep * tics);
+      time -= tics;
+      t    += (tics<<OSCTSHIFT);
+      if (mag<0) mag = 0;
+      }
+}
+
+
+//******************************************************************************
+//
+// DoZIntro
+//
+//******************************************************************************
+
+#define ZMAXMAG (199)
+#define ZOSCTIME (3*VBLCOUNTER)
+#define ZOSCXSHIFT (2)
+#define ZOSCXSTEP ( (FINEANGLES<<(ZOSCXSHIFT+16))/320 )
+#define ZOSCTSHIFT (2)
+
+void DoZIntro (void)
+{
+   byte * shape;
+   int mag;
+   int currentmag;
+   int magstep;
+   int time;
+   int x;
+   int t;
+
+   SetViewSize (MAXVIEWSIZES-1);
+
+   shadingtable=colormap+(1<<12);
+
+   shape=W_CacheLumpName("ap_wrld",PU_CACHE);
+
+   mag=ZMAXMAG<<16;
+   magstep = (ZMAXMAG<<16)/ZOSCTIME;
+   time = ZOSCTIME;
+   t=0;
+
+   CalcTics();
+
+
+   while (time>0)
+      {
+      int zoffset;
+      int hoffset;
+      int offset;
+      int srcoffset;
+      int bottomscreen;
+      int src;
+//      int i;
+
+
+      VL_ClearBuffer (bufferofs, 0);
+      currentmag=mag>>16;
+
+      srcoffset=0;
+      for (x=0;x<320;)
+         {
+         VGAWRITEMAP(x&3);
+
+         offset=(t+(FixedMul(x,ZOSCXSTEP)))&(FINEANGLES-1);
+         zoffset=FixedMul(currentmag,sintable[offset]);
+//         hoffset=FixedMulShift(currentmag,sintable[offset],17);
+         hoffset=0;
+         dc_texturemid=((100+hoffset)<<SFRACBITS)+(SFRACUNIT>>1);
+
+         dc_invscale=((200+zoffset)<<16)/200;
+         dc_iscale=0xffffffffu/(unsigned)dc_invscale;
+
+         srcoffset+=dc_invscale;
+         sprtopoffset=centeryfrac -  FixedMul(dc_texturemid,dc_invscale);
+         bottomscreen = sprtopoffset + (dc_invscale*200);
+         dc_yl = (sprtopoffset+SFRACUNIT-1)>>SFRACBITS;
+         dc_yh = ((bottomscreen-1)>>SFRACBITS);
+         if (dc_yh >= viewheight)
+            dc_yh = viewheight-1;
+         if (dc_yl < 0)
+            dc_yl = 0;
+         if (dc_yl <= dc_yh)
+            {
+            src=srcoffset>>16;
+            if (src>319)
+               src=319;
+            if (src<0)
+               src=0;
+            dc_source=shape+(src * 200);
+//            if (RandomNumber("hello",0)<128)
+#ifdef DOS
+            R_DrawColumn ((byte *)bufferofs+(x>>2));
+#else
+            R_DrawColumn ((byte *)bufferofs+x);
+#endif
+            }
+//         srcoffset+=0x10000;
+         x++;
+         if ((LastScan) || IN_GetMouseButtons())
+            return;
+         }
+      FlipPage();
+      CalcTics();
+      mag  -= (magstep * tics);
+//      mag  += FixedMulShift((magstep * tics),sintable[time&(FINEANGLES-1)],19);
+      time -= tics;
+      t    += (tics<<ZOSCTSHIFT);
+      if (mag<0) mag = 0;
+      }
+}
+#endif
+
+
+
+// Old Stuff
+
+/*
+   int y1;
+   int y2;
+
+   if (post->alttile!=0)
+      {
+      ht=nominalheight;
+      src2=W_CacheLumpNum(1+post->alttile,PU_CACHE);
+//      src2+=8;
+      }
+   else
+      {
+      ht=maxheight;
+      src2=src;
+      }
+   hp_srcstep=(64<<(16+HEIGHTFRACTION))/post->wallheight;
+   y1 = (((centery<<HFRACTION)-(post->wallheight*pheight)+(1<<(HFRACTION-1))));
+   y2 = (((post->wallheight*ht)+y1)>>HFRACTION);
+
+   if ((y1>>HFRACTION)>=viewheight)
+      {
+      post->ceilingclip=viewheight-1;
+      post->floorclip=viewheight-1;
+      return;
+      }
+   else if (y1<0)
+      {
+      hp_startfrac=FixedMulShift(-y1,hp_srcstep,HFRACTION);
+      y1=0;
+      post->ceilingclip=0;
+      }
+   else
+      {
+      hp_startfrac=FixedMulShift(255-(y1&0xff),hp_srcstep,HFRACTION);
+      y1>>=HFRACTION;
+      post->ceilingclip=y1;
+      }
+   if (y2<0)
+      {
+      post->floorclip=0;
+      post->ceilingclip=0;
+      }
+   else if (y2>viewheight)
+      {
+      DrawHeightPost(viewheight-y1, src2+((post->texture>>4)&0xfc0), buf+ylookup[y1]);
+      post->floorclip=viewheight-1;
+      }
+   else
+      {
+      DrawHeightPost(y2-y1, src2+((post->texture>>4)&0xfc0), buf+ylookup[y1]);
+      post->floorclip=y2-1;
+      }
+
+   if (ht==maxheight)
+      return;
+
+   y1 = (((centery<<HFRACTION)-(post->wallheight*(pheight-ht))+(1<<(HFRACTION-1))));
+   y2 = (((post->wallheight<<6)+y1)>>HFRACTION);
+
+   if ((y1>>HFRACTION)>=viewheight)
+      return;
+   else if (y1<0)
+      {
+      hp_startfrac=FixedMulShift(-y1,hp_srcstep,HFRACTION);
+      y1=0;
+      }
+   else
+      {
+      hp_startfrac=FixedMulShift(255-(y1&0xff),hp_srcstep,HFRACTION);
+      y1>>=HFRACTION;
+      }
+   if (y2<0)
+      return;
+   else if (y2>viewheight)
+      {
+      DrawHeightPost(viewheight-y1, src+((post->texture>>4)&0xfc0), buf+ylookup[y1]);
+      post->floorclip=viewheight-1;
+      }
+   else
+      {
+      DrawHeightPost(y2-y1, src+((post->texture>>4)&0xfc0), buf+ylookup[y1]);
+      post->floorclip=y2-1;
+      }
+}
+*/
+
+
+
+
+
+
+//******************************************************************************
+//
+// DrawBackground
+//
+//******************************************************************************
+
+void DrawBackground ( byte * bkgnd )
+{
+//   int plane;
+   int size;
+
+   size=linewidth*400;
+
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+      VGAWRITEMAP(plane);
+      memcpy((byte *)bufferofs,bkgnd,size);
+      bkgnd+=size;
+      }
+}
+
+
+//******************************************************************************
+//
+// PrepareBackground
+//
+//******************************************************************************
+
+void PrepareBackground ( byte * bkgnd )
+{
+//   int plane;
+   int size;
+
+   size=linewidth*400;
+
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+      VGAREADMAP(plane);
+      memcpy(bkgnd,(byte *)bufferofs,size);
+      bkgnd+=size;
+      }
+}
+
+//******************************************************************************
+//
+// WarpString
+//
+//******************************************************************************
+
+void WarpString (
+                  int x, int y, int endx, int endy,
+                  int time, byte * back, char * str
+                )
+{
+   int dx;
+   int dy;
+   int cx;
+   int cy;
+   int starttime;
+
+
+   LastScan = 0;
+
+
+   dx=((endx-x)<<16)/time;
+   dy=((endy-y)<<16)/time;
+   cx=x<<16;
+   cy=y<<16;
+   starttime=time;
+
+   CalcTics();
+
+   while (time>0)
+      {
+
+      DrawBackground ( back );
+      US_ClippedPrint (cx>>16, cy>>16, str);
+      FlipPage();
+
+      CalcTics();
+      cx+=dx*tics;
+      cy+=dy*tics;
+      time-=tics;
+      if (LastScan != 0)
+         break;
+      }
+
+  // DrawBackground ( back );
+  // US_ClippedPrint (endx, endy, str);
+  // FlipPage();
+
+}
+
+
+#if (SHAREWARE==1)
+//******************************************************************************
+//
+// DoEndCinematic
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// WarpSprite
+//
+//******************************************************************************
+
+void WarpSprite (
+                  int x, int y, int endx, int endy,
+                  int time, byte * back, int shape
+                )
+{
+   int dx;
+   int dy;
+   int cx;
+   int cy;
+   int starttime;
+
+   LastScan = 0;
+
+   dx=((endx-x)<<16)/time;
+   dy=((endy-y)<<16)/time;
+   cx=x<<16;
+   cy=y<<16;
+   starttime=time;
+
+   CalcTics();
+
+   while (time>0)
+      {
+      DrawBackground ( back );
+      DrawUnScaledSprite (cx>>16, cy>>16, shape, 16);
+      FlipPage();
+      CalcTics();
+      cx+=dx*tics;
+      cy+=dy*tics;
+      time-=tics;
+      if (LastScan != 0)
+         break;
+      }
+}
+
+
+char *EndCinematicPicNames[5] =
+         {
+         "lwgshoo2",
+         "hg2shoo2",
+         "ankshoo1",
+         "ligrise4",
+         "tritoss5",
+
+         };
+
+#define NUMENDMESSAGES 24
+
+
+char *EndCinematicText[NUMENDMESSAGES] =
+  {
+  "You've won the battle, Cassatt.\n"
+  "But when the Oscuridos return,\n"
+  "will you be ready as they wage\n"
+  "their Dark War?",
+
+  "Armed with only a pistol and 30\n"
+  "bucks, you must stop the minions of\n"
+  "El Oscuro before they kill millions\n"
+  "of innocent people.",
+
+  "But for now, hey, enjoy the medal\n"
+  "you received and take a vacation.\n"
+  "You've earned it. Maybe on \n"
+  "San Nicolas Island . . ." ,
+
+  "Thanks for playing. If you liked\n"
+  "\"The HUNT Begins\", check Ordering\n"
+  "Info for information about \n"
+  "continuing your adventure.",
+
+  "Okay, you can stop reading now.",
+
+  "Press a key. That's all there is.\n"
+  "Thanks.",
+
+  "Are you lazy, or illiterate?\n"
+  "PRESS A KEY.",
+
+  "Look, this is pointless. You\n"
+  "are done. Push off.",
+
+  "Okay, show's over.  Nothing\n"
+  "more to see here.",
+
+  "Wow, you must like this fine\n"
+  "background screen.",
+
+  "For waiting this long, you get . . .\n"
+  "nothing!  Go away!",
+
+  "I mean, I like you as a friend,\n"
+  "but . . .",
+
+  "\"Bob\"",
+
+  "All right, um . . . you found the\n"
+  "secret message! Congratulations!",
+
+  "Didn't work, huh?  Okay, how about\n"
+  "this . . .",
+
+  "THE END",
+
+  "Dang. Thought I had you there.",
+
+  "Stop watching.",
+
+  "You know that if you registered,\n"
+  "there would be a lot more cool\n"
+  "stuff happening right now.",
+
+  "Episode IV: A New Hope\n",
+
+  "Just think of all the new secret\n"
+  "messages you could find hidden\n"
+  "in the registered version!",
+
+  "Someone right now is probably\n"
+  "enjoying the really exciting\n"
+  "ending of the registered version.",
+
+  "ROTT was filmed before\n"
+  "a live audience.",
+
+  "No animals were harmed during the\n"
+  "creation of this video game, although\n"
+  "one dog did get its butt spanked\n"
+  "when it peed on the carpet.\n",
+
+
+  };
+char NextGameString1[] = "The Developers of Incredible Power";
+char NextGameString2[] = "shall return";
+
+void DoEndCinematic ( void )
+{
+   int trilogo;
+   int group;
+   int world;
+   int width;
+   int height;
+   int x,y;
+   int shape;
+   int time1,time2;
+   byte * tmp;
+   byte * sky;
+   byte * bkgnd;
+   int i;
+
+   byte pal[768];
+	EnableScreenStretch();
+
+   viewwidth = 320;//MAXSCREENWIDTH;
+   viewheight = 200;//MAXSCREENHEIGHT;
+
+   MU_StartSong(song_youwin);
+
+   bkgnd=SafeMalloc(800*linewidth);
+
+   trilogo=W_GetNumForName("trilogo");
+   world=W_GetNumForName("ap_wrld");
+   group=W_GetNumForName("mmbk");
+   VL_DrawPostPic (trilogo);
+   PrepareBackground ( bkgnd );
+
+   WarpSprite (160, -100, 160, 100, (VBLCOUNTER*3), bkgnd, W_GetNumForName("youwin"));
+   if (LastScan !=0)
+      goto fadelogo;
+
+   I_Delay(30);
+fadelogo:
+   MenuFadeOut();
+   ClearGraphicsScreen();
+   memcpy(&pal[0],W_CacheLumpName("ap_pal",PU_CACHE,CvtNull,1),768);
+   VL_NormalizePalette(&pal[0]);
+   SwitchPalette(&pal[0],35);
+
+   VL_DrawPostPic (world);
+   PrepareBackground ( bkgnd );
+
+   WarpSprite (160, 250, 160, 100, (VBLCOUNTER*3), bkgnd, W_GetNumForName("wrldsafe"));
+   if (LastScan !=0)
+      goto fadeworld;
+
+   I_Delay(10);
+   if (LastScan !=0)
+      goto fadeworld;
+
+   WarpSprite (160, 100, 160, -50, (VBLCOUNTER*3), bkgnd, W_GetNumForName("wrldsafe"));
+   if (LastScan !=0)
+      goto fadeworld;
+
+   I_Delay(20);
+
+fadeworld:
+   MenuFadeOut();
+   ClearGraphicsScreen();
+   MenuFadeIn();
+
+
+   sky=W_CacheLumpNum(W_GetNumForName("SKYSTART")+2,PU_CACHE,CvtNull,1);
+   tmp=sky;
+   for (x=0;x<256;x++)
+      {
+      VGAWRITEMAP(x&3);
+      for (y=0;y<200;y++)
+         {
+#ifdef DOS
+         *((byte *)bufferofs+ylookup[y]+(x>>2))=*tmp++;
+#else
+         *((byte *)bufferofs+ylookup[y]+x)=*tmp++;
+#endif
+         }
+      }
+   tmp=sky;
+   for (x=256;x<320;x++)
+      {
+      VGAWRITEMAP(x&3);
+      for (y=0;y<200;y++)
+         {
+#ifdef DOS
+         *((byte *)bufferofs+ylookup[y]+(x>>2))=*tmp++;
+#else
+         *((byte *)bufferofs+ylookup[y]+x)=*tmp++;
+#endif
+         }
+      }
+
+   for(i=0;i<5;i++)
+      {
+      int tx,ty;
+
+      tx = 32 + (i << 6);
+      ty = 100;
+      shape = W_GetNumForName(EndCinematicPicNames[i]);
+      DrawUnScaledSprite (tx, ty, shape,16);
+      }
+
+   PrepareBackground ( bkgnd );
+
+   //CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_CACHE);
+   CurrentFont = smallfont;
+   LastScan = 0;
+
+   for(i=0;i<NUMENDMESSAGES;i++)
+      {
+      if (i>3)
+         I_Delay(50);
+
+      US_MeasureStr (&width, &height, &(EndCinematicText[i][0]));
+      if (LastScan !=0)
+         break;
+
+      x=(320-width)>>1;
+      y=(200-height)>>1;
+      time1 = (300 - y)*(VBLCOUNTER*4)/300;
+      time2 = VBLCOUNTER*4-time1;
+
+      WarpString (x, 250, x, y-50,time1, bkgnd, EndCinematicText[i]);
+      if (LastScan !=0)
+         break;
+      I_Delay(40);
+      if (LastScan !=0)
+         break;
+
+      if (i<=3)
+         I_Delay(40);
+      if (LastScan !=0)
+         break;
+
+      WarpString (x, y-50, x, -50, time2, bkgnd, EndCinematicText[i]);
+      if (LastScan !=0)
+         break;
+
+
+      }
+
+   if (LastScan!=0)
+     goto finalfade;
+
+   sky=W_CacheLumpNum(W_GetNumForName("SKYSTART")+2,PU_CACHE,CvtNull,1);
+   tmp=sky;
+   for (x=0;x<256;x++)
+      {
+      VGAWRITEMAP(x&3);
+      for (y=0;y<200;y++)
+         {
+#ifdef DOS
+         *((byte *)bufferofs+ylookup[y]+(x>>2))=*tmp++;
+#else
+         *((byte *)bufferofs+ylookup[y]+x)=*tmp++;
+#endif
+         }
+      }
+   tmp=sky;
+   for (x=256;x<320;x++)
+      {
+      VGAWRITEMAP(x&3);
+      for (y=0;y<200;y++)
+         {
+#ifdef DOS
+         *((byte *)bufferofs+ylookup[y]+(x>>2))=*tmp++;
+#else
+         *((byte *)bufferofs+ylookup[y]+x)=*tmp++;
+#endif
+         }
+      }
+
+   for(i=0;i<5;i++)
+      {
+      int tx,ty;
+
+      tx = 32 + (i << 6);
+      ty = 100;
+      shape = W_GetNumForName(EndCinematicPicNames[i]);
+      DrawUnScaledSprite (tx, ty, shape,16);
+      }
+
+
+   shape = W_GetNumForName("robogrd3");
+   PrepareBackground ( bkgnd );
+   WarpSprite (420,100,300,100,VBLCOUNTER*3,bkgnd,shape);
+   if (LastScan !=0)
+      goto finalfade;
+
+   PrepareBackground ( bkgnd );
+   WarpString (200,80,200,80,VBLCOUNTER*3,bkgnd, "Am I late?");
+   if (LastScan !=0)
+      goto finalfade;
+
+
+   I_Delay(20);
+finalfade:
+
+   MenuFadeOut();
+   VL_ClearVideo (0);
+   I_Delay(10);
+
+   if (LastScan == 0)
+      {
+      US_MeasureStr (&width, &height, NextGameString1);
+      x=(320-width)>>1;
+      y=(200-height)>>1;
+      US_ClippedPrint (x,y-6, NextGameString1);
+      US_MeasureStr (&width, &height, NextGameString2);
+      x=(320-width)>>1;
+      y=(200-height)>>1;
+      US_ClippedPrint (x,y+6, NextGameString2);
+      FlipPage();
+      VL_FadeIn(0,255,origpal,150);
+      I_Delay(50);
+      VL_FadeOut(0,255,0,0,0,150);
+      VL_ClearVideo (0);
+      I_Delay(10);
+      }
+
+   SafeFree(bkgnd);
+}
+#else
+
+// REGISTERED VERSION ======================================================
+
+static char    burnCastle1Msg []=
+        "The monastery burns.\n"
+        "\n"
+        "El Oscuro is dead.\n"
+        "\n"
+        "The world is safe.\n";
+
+// If all Snake Eggs not destroyed on final level:
+
+
+static char    notDoneMsg[] =
+          "Unfortunately not all\n"
+          "of El Oscuro's larvae\n"
+          "were destroyed.\n"
+          "\n"
+          "Thirty years later,\n"
+          "a descendant of\n"
+          "El Oscuro wiped out\n"
+          "the entire world,\n"
+          "but nice job anyway.\n";
+
+static char    tryAgainMsg[] =
+          "Try Again.\n"
+          "\n"
+          "The world will not be\n"
+          "safe until all of El\n"
+          "Oscuro's larvae are\n"
+          "destroyed. Find them.\n";
+
+// If all snake eggs destroyed:
+static char    doneMsg[] =
+          "You have destroyed\n"
+          "El Oscuro and all his\n"
+          "descendants.  Well done!\n";
+
+// On Triad background, in bigger font.
+static char    youWin1Msg[] =
+        "So, HUNT Members, how\n"
+        "do you think the\n"
+        "mission went?\n";
+
+// Place menu pix of characters here (maybe modem frame too?)
+static char    youWin2Msg[] =
+        "Barrett: Well, I think\n"
+        "I got shin splints from\n"
+        "all those jump pads.\n"
+        "But hey, action-wise,\n"
+        "I've been in tougher\n"
+        "bar fights, for crying\n"
+        "out loud.\n";
+
+static char    youWin3Msg[] =
+        "Cassatt: Apart from\n"
+        "the other HUNT members\n"
+        "saying I look like\n"
+        "Richard Mulligan, it\n"
+        "was quite a success.\n"
+        "And some of the\n"
+        "monastery's ironwork\n"
+        "was very nice.\n";
+
+static char    youWin4Msg[] =
+        "Ni: it was quite easy,\n"
+        "actually.  I just\n"
+        "pictured the enemy\n"
+        "having the face of\n"
+        "my ex-husband, and\n"
+        "man, I was a force\n"
+        "of Nature.\n";
+
+static char    youWin5Msg[] =
+        "Wendt: I was kind of\n"
+        "disappointed. I think\n"
+        "I used the missile\n"
+        "weapons way too much.\n"
+        "Next time, bullets\n"
+        "only.  Nothing sweeter\n"
+        "than a head shot from\n"
+        "a hundred feet.\n";
+
+static char    youWin6Msg[] =
+        "Freeley: I'm still\n"
+        "trying to adjust in\n"
+        "the aftermath.  It's\n"
+        "kinda tough.  I mean,\n"
+        "I save the damn world,\n"
+        "and all people ask\n"
+        "about is my name.\n"
+        "Sheesh.\n";
+
+// On caching screen
+
+static char     youWin7Msg[] =
+           "The HUNT is victorious!\n"
+           "\n"
+           "         THE END\n";
+
+
+static char     youWin8Msg[] =
+           "Now go and celebrate!\n"
+           "\n"
+           "      THE REAL END";
+
+#define NUMEXPLOSIONTYPES 4
+
+typedef struct {
+  char  name[11];
+  byte  numframes;
+} ExplosionInfoType;
+
+ExplosionInfoType ExplosionInfo[NUMEXPLOSIONTYPES]=
+{
+  {"EXPLOS1\0",20},
+  {"EXP1\0",20},
+  {"GREXP1\0",25},
+  {"PART1\0",12},
+#if 0
+  {"GUTS1\0",12},
+  {"ORGAN1\0",12},
+  {"RIB1\0",12},
+  {"GPINK1\0",12},
+  {"GHEAD1\0",12},
+  {"GARM1\0",12},
+  {"GLEG1\0",12},
+  {"GHUM1\0",12},
+  {"GHIP1\0",12},
+  {"GLIMB1\0",12},
+#endif
+};
+
+
+typedef struct {
+  byte  which;
+  byte  frame;
+  byte  x;
+  byte  y;
+} ExplosionType;
+
+#define MAXTRANSMITTEREXPLOSIONS 30
+
+static ExplosionType Explosions[MAXTRANSMITTEREXPLOSIONS];
+
+void ResetTransmitterExplosion ( ExplosionType * Explosion )
+{
+   Explosion->which=RandomNumber("Explosion",0)%NUMEXPLOSIONTYPES;
+   Explosion->frame=0;
+   Explosion->x=(RandomNumber("Explosion",2)>>1)+(160-64);
+   Explosion->y=(RandomNumber("Explosion",3)>>1);
+}
+
+void CacheTransmitterExplosions ( void )
+{
+   int i,j,num;
+
+   for (i=0;i<NUMEXPLOSIONTYPES;i++)
+      {
+      num=W_GetNumForName(ExplosionInfo[i].name);
+      for (j=0;j<ExplosionInfo[i].numframes;j++)
+         {
+         W_CacheLumpNum(num+j, PU_CACHE, Cvt_patch_t, 1);
+         }
+      }
+}
+
+void SetupTransmitterExplosions ( void )
+{
+   int i;
+
+   for (i=0;i<MAXTRANSMITTEREXPLOSIONS;i++)
+      {
+      ResetTransmitterExplosion(&Explosions[i]);
+      }
+}
+void UpdateTransmitterExplosions ( void )
+{
+   int i;
+   for (i=0;i<MAXTRANSMITTEREXPLOSIONS;i++)
+      {
+      Explosions[i].frame+=tics;
+      if (Explosions[i].frame>=(ExplosionInfo[Explosions[i].which].numframes<<1))
+         {
+         ResetTransmitterExplosion(&Explosions[i]);
+         SD_Play(SD_EXPLODEFLOORSND+(RandomNumber("Explosion",4)>>7));
+         }
+      }
+}
+
+void DrawTransmitterExplosions ( void )
+{
+   int i;
+   for (i=0;i<MAXTRANSMITTEREXPLOSIONS;i++)
+      {
+      DrawUnScaledSprite (
+                      Explosions[i].x,
+                      Explosions[i].y,
+                      (W_GetNumForName(ExplosionInfo[Explosions[i].which].name) +
+                      (Explosions[i].frame>>1)),
+                      16
+                      );
+      }
+}
+
+void DoTransmitterExplosion ( void )
+{
+   byte * back;
+   int i;
+
+   VL_ClearVideo(0);
+   back=SafeMalloc(800*linewidth);
+
+   CalcTics();
+   CalcTics();
+   DrawNormalSprite(0,0,W_GetNumForName("transmit"));
+   PrepareBackground ( back );
+   SetupTransmitterExplosions ();
+   CacheTransmitterExplosions ();
+   DrawBackground ( back );
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   SHAKETICS=VBLCOUNTER*15;
+   for (i=0;i<(VBLCOUNTER*15);i+=tics)
+      {
+      DrawBackground ( back );
+      DrawTransmitterExplosions ();
+      FlipPage();
+      CalcTics();
+      UpdateTransmitterExplosions ();
+      }
+   VL_FadeOut (0, 255, 63, 63, 63, 150);
+   screenfaded=false;
+   SD_Play(SD_PLAYERTCSND);
+   SD_Play(SD_PLAYERTBSND);
+   SD_Play(SD_PLAYERDWSND);
+   SD_Play(SD_PLAYERLNSND);
+   SD_Play(SD_PLAYERIPFSND);
+   VL_FadeOut (0, 255, 0, 0, 0, 30);
+   TurnShakeOff();
+
+   SafeFree(back);
+}
+
+void ShowTransmitter ( void )
+{
+   MenuFadeOut();
+   DrawNormalSprite(0,0,W_GetNumForName("transmit"));
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   I_Delay(30);
+   VL_FadeOut (0, 255, 0, 0, 0, 30);
+}
+
+void ShowFinalDoor ( void )
+{
+   byte pal[768];
+
+   MenuFadeOut();
+
+   VL_ClearBuffer (bufferofs, 0);
+   DrawNormalSprite (0, (200-120)>>1, W_GetNumForName("finldoor"));
+   FlipPage();
+   memcpy(&pal[0],W_CacheLumpName("findrpal",PU_CACHE,CvtNull, 1),768);
+   VL_NormalizePalette(&pal[0]);
+   SD_Play(SD_OPENDOORSND);
+   VL_FadeIn (0, 255, pal, 30);
+   I_Delay(30);
+   VL_FadeOut (0, 255, 0, 0, 0, 30);
+}
+
+void ShowFinalFire ( void )
+{
+   byte pal[768];
+
+   MenuFadeOut();
+
+   VL_ClearBuffer (bufferofs, 0);
+   DrawNormalSprite (0, (200-120)>>1, W_GetNumForName("finlfire"));
+   FlipPage();
+   memcpy(&pal[0],W_CacheLumpName("finfrpal",PU_CACHE,CvtNull, 1),768);
+   VL_NormalizePalette(&pal[0]);
+   SD_Play(SD_BAZOOKAFIRESND);
+   VL_FadeIn (0, 255, pal, 30);
+   SD_Play(SD_FIREBOMBFIRESND);
+   I_Delay(2);
+   SD_Play(SD_HEATSEEKFIRESND);
+   I_Delay(2);
+   SD_Play(SD_DRUNKFIRESND);
+   SD_Play(SD_HEATSEEKFIRESND);
+   I_Delay(2);
+   SD_Play(SD_ATKMP40SND);
+   SD_Play(SD_ATKMP40SND);
+   I_Delay(2);
+   SD_Play(SD_HEATSEEKFIRESND);
+   SD_Play(SD_FIREBOMBFIRESND);
+   I_Delay(2);
+   SD_Play(SD_ATKMP40SND);
+   SD_Play(SD_HEATSEEKFIRESND);
+   I_Delay(2);
+   SD_Play(SD_DRUNKFIRESND);
+   I_Delay(2);
+   SD_Play(SD_FIREBOMBFIRESND);
+   I_Delay(2);
+   SD_Play(SD_HEATSEEKFIRESND);
+   SD_Play(SD_ATKMP40SND);
+   I_Delay(2);
+   SD_Play(SD_DRUNKFIRESND);
+   SD_Play(SD_HEATSEEKFIRESND);
+   I_Delay(2);
+   SD_Play(SD_FIREBOMBFIRESND);
+   SD_Play(SD_ATKMP40SND);
+   I_Delay(2);
+   SD_Play(SD_DRUNKFIRESND);
+   I_Delay(2);
+   SD_Play(SD_HEATSEEKFIRESND);
+   SD_Play(SD_FIREBOMBFIRESND);
+   I_Delay(2);
+   SD_Play(SD_ATKMP40SND);
+   SD_Play(SD_HEATSEEKFIRESND);
+   I_Delay(2);
+   SD_Play(SD_DRUNKFIRESND);
+   SD_Play(SD_FIREBOMBFIRESND);
+   I_Delay(2);
+   SD_Play(SD_HEATSEEKFIRESND);
+   SD_Play(SD_DRUNKFIRESND);
+   SD_Play(SD_BAZOOKAFIRESND);
+   I_Delay(4);
+   VL_FadeOut (0, 255, 0, 0, 0, 30);
+}
+
+void ScrollString ( int cy, char * string, byte * bkgnd, int scrolltime, int pausetime )
+{
+   int x,y;
+   int width,height;
+   int time1,time2;
+
+   LastScan=0;
+   US_MeasureStr (&width, &height, string);
+
+   x=(320-width)>>1;
+   y=cy-(height>>1);
+   time1 = ((220 - y)*scrolltime)/(220+height);
+   time2 = scrolltime-time1;
+
+   WarpString (x, 210, x, y, time1, bkgnd, string);
+
+   if (LastScan !=0)
+      return;
+
+   I_Delay(pausetime);
+
+   if (LastScan !=0)
+      return;
+
+   WarpString (x, y, x, -10-height, time2, bkgnd, string);
+}
+
+void DoBurningCastle ( void )
+{
+   byte * back;
+
+   LastScan=0;
+   VL_ClearVideo(0);
+   back=SafeMalloc(800*linewidth);
+
+   DrawNormalSprite(0,0,W_GetNumForName("finale"));
+   PrepareBackground ( back );
+   CurrentFont = smallfont;
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1 );
+   ScrollString ( 150, &burnCastle1Msg[0], back, 4*VBLCOUNTER, 80);
+   W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
+   VL_FadeOut (0, 255, 0, 0, 0, 80);
+   SafeFree(back);
+}
+
+void DoFailedScreen ( void )
+{
+   byte * back;
+
+   back=SafeMalloc(800*linewidth);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   PrepareBackground ( back );
+   CurrentFont = smallfont;
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   ScrollString ( 100, &notDoneMsg[0], back, 4*VBLCOUNTER, 100);
+   VL_FadeOut (0, 255, 0, 0, 0, 80);
+   SafeFree(back);
+}
+
+void DoTryAgainScreen ( void )
+{
+   byte * back;
+
+   back=SafeMalloc(800*linewidth);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   PrepareBackground ( back );
+   CurrentFont = smallfont;
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   ScrollString ( 100, tryAgainMsg, back, 4*VBLCOUNTER, 80);
+   VL_FadeOut (0, 255, 0, 0, 0, 80);
+   SafeFree(back);
+}
+
+void ResetWorldExplosion ( ExplosionType * Explosion )
+{
+   Explosion->which=RandomNumber("Explosion",0)%NUMEXPLOSIONTYPES;
+   Explosion->frame=0;
+//   RandomNumber("Explosion",1)%ExplosionInfo[Explosions[i].which].numframes;
+   Explosion->x=(RandomNumber("Explosion",2))+64;
+   Explosion->y=(RandomNumber("Explosion",3)%180);
+}
+
+void SetupWorldExplosions ( void )
+{
+   int i;
+
+   for (i=0;i<MAXTRANSMITTEREXPLOSIONS;i++)
+      {
+      ResetWorldExplosion(&Explosions[i]);
+      }
+}
+void UpdateWorldExplosions ( void )
+{
+   int i;
+   for (i=0;i<MAXTRANSMITTEREXPLOSIONS;i++)
+      {
+      Explosions[i].frame+=tics;
+      if (Explosions[i].frame>=(ExplosionInfo[Explosions[i].which].numframes<<1))
+         {
+         ResetWorldExplosion(&Explosions[i]);
+         SD_Play(SD_EXPLODEFLOORSND+(RandomNumber("Explosion",4)>>7));
+         }
+      }
+}
+
+void DestroyEarth ( void )
+{
+   byte * back;
+   int i;
+
+   VL_ClearVideo(0);
+   back=SafeMalloc(800*linewidth);
+
+   CalcTics();
+   CalcTics();
+   DrawNormalSprite(0,0,W_GetNumForName("ourearth"));
+   PrepareBackground ( back );
+   SetupWorldExplosions ();
+   CacheTransmitterExplosions ();
+   DrawBackground ( back );
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   SHAKETICS=VBLCOUNTER*10;
+   for (i=0;i<(VBLCOUNTER*10);i+=tics)
+      {
+      DrawBackground ( back );
+      DrawTransmitterExplosions ();
+      FlipPage();
+      CalcTics();
+      UpdateWorldExplosions ();
+      }
+   VL_FadeOut (0, 255, 63, 63, 63, 150);
+   screenfaded=false;
+   if (gamestate.violence==vl_excessive)
+      SD_Play(SD_YOUSUCKSND);
+   VL_FadeOut (0, 255, 0, 0, 0, 50);
+   TurnShakeOff();
+
+   SafeFree(back);
+}
+
+boolean DestroyedAllEggs ( void )
+{
+   statobj_t * temp;
+
+   for(temp=FIRSTSTAT;temp;temp=temp->statnext)
+      {
+      if (temp->itemnumber==stat_tomlarva)
+         return false;
+      }
+   return true;
+}
+
+void DoSanNicolas ( void )
+{
+   byte pal[768];
+
+   LastScan=0;
+   VL_ClearVideo(0);
+   DrawNormalSprite(0,16,W_GetNumForName("nicolas"));
+   DrawNormalSprite(10,200-58,W_GetNumForName("budgcut"));
+   FlipPage();
+   memcpy(&pal[0],W_CacheLumpName("nicpal",PU_CACHE, CvtNull, 1),768);
+   VL_NormalizePalette(&pal[0]);
+   VL_FadeIn (0, 255, pal, 30);
+   I_Delay(60);
+   VL_FadeOut (0, 255, 0, 0, 0, 80);
+}
+
+void PlayerQuestionScreen ( void )
+{
+   byte * back;
+
+   back=SafeMalloc(800*linewidth);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   PrepareBackground ( back );
+   CurrentFont = smallfont;
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
+   ScrollString ( 100, &doneMsg[0], back, 4*VBLCOUNTER, 40);
+   ScrollString ( 100, &youWin1Msg[0], back, 4*VBLCOUNTER, 50);
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawXYPic ( 8, 100-24, W_GetNumForName("player2"));
+   PrepareBackground ( back );
+   CurrentFont = smallfont;
+   SD_Play(SD_PLAYERTBSND);
+   ScrollString ( 100, &youWin2Msg[0], back, 4*VBLCOUNTER, 100);
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawXYPic ( 8, 100-24, W_GetNumForName("player1"));
+   PrepareBackground ( back );
+   SD_Play(SD_PLAYERTCSND);
+   ScrollString ( 100, &youWin3Msg[0], back, 4*VBLCOUNTER, 100);
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawXYPic ( 8, 100-24, W_GetNumForName("player4"));
+   PrepareBackground ( back );
+   SD_Play(SD_PLAYERLNSND);
+   ScrollString ( 100, &youWin4Msg[0], back, 4*VBLCOUNTER, 100);
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawXYPic ( 8, 100-24, W_GetNumForName("player3"));
+   PrepareBackground ( back );
+   SD_Play(SD_PLAYERDWSND);
+   ScrollString ( 100, &youWin5Msg[0], back, 4*VBLCOUNTER, 100);
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawXYPic ( 8, 100-24, W_GetNumForName("player5"));
+   PrepareBackground ( back );
+   SD_Play(SD_PLAYERIPFSND);
+   ScrollString ( 100, &youWin6Msg[0], back, 4*VBLCOUNTER, 100);
+   W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
+   VL_FadeOut (0, 255, 0, 0, 0, 80);
+   SafeFree(back);
+}
+
+void DoYouWin ( void )
+{
+   pic_t * pic;
+   byte * back;
+
+   back=SafeMalloc(800*linewidth);
+   LastScan=0;
+   VL_ClearVideo(0);
+   pic = (pic_t *) W_CacheLumpNum (W_GetNumForName ("mmbk"), PU_CACHE, Cvt_pic_t, 1);
+   VWB_DrawPic (0, 0, pic);
+   PrepareBackground ( back );
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
+   ScrollString ( 100, &youWin7Msg[0], back, 4*VBLCOUNTER, 300);
+   W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
+   VL_FadeOut (0, 255, 0, 0, 0, 80);
+   SafeFree(back);
+}
+
+void DoFinalEnd ( void )
+{
+   pic_t * pic;
+   byte * back;
+
+   back=SafeMalloc(800*linewidth);
+   LastScan=0;
+   VL_ClearVideo(0);
+   pic = (pic_t *) W_CacheLumpNum (W_GetNumForName ("mmbk"), PU_CACHE, Cvt_pic_t, 1);
+   VWB_DrawPic (0, 0, pic);
+   DrawNormalSprite(0,0,W_GetNumForName("sombrero"));
+   DrawNormalSprite(0,0,W_GetNumForName("amflag"));
+   DrawNormalSprite(0,0,W_GetNumForName("witchhat"));
+   DrawNormalSprite(0,0,W_GetNumForName("esterhat"));
+   DrawNormalSprite(0,0,W_GetNumForName("santahat"));
+   PrepareBackground ( back );
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
+   ScrollString ( 100, &youWin8Msg[0], back, 4*VBLCOUNTER, 100);
+   W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
+   VL_FadeOut (0, 255, 0, 0, 0, 80);
+   SafeFree(back);
+   VL_ClearVideo(0);
+}
+
+static char     dipMsg[] =
+           "The Developers of Incredible Power!\n"
+           "\n"
+           "Susan  Tom  Jim  Stephen\n"
+           "Mark  William  Chuck\n";
+
+static char     creditsMsg[] =
+           "Rise of the Triad Credits\n";
+
+static char     credits1Msg[] =
+           "Programmers\n"
+           "\n"
+           "Mark Dochtermann\n"
+           "William Scarboro\n"
+           "Jim Dose'\n"
+           "Nolan Martin\n";
+
+static char     credits2Msg[] =
+           "Creative Director\n"
+           "\n"
+           "Tom Hall\n";
+
+static char     credits3Msg[] =
+           "Artists\n"
+           "\n"
+           "Stephen Hornback\n"
+           "Tim Neveu\n"
+           "Chuck Jones\n"
+           "Susan Singer\n"
+           "James Storey\n"
+           "Cygnus Multimedia\n";
+
+static char     credits4Msg[] =
+           "Level Designers\n"
+           "\n"
+           "Tom Hall\n"
+           "Joseph Selinske\n"
+           "Marianna Vayntrub\n"
+           "Joe Siegler\n";
+static char     credits5Msg[] =
+           "Music\n"
+           "\n"
+           "Lee Jackson\n"
+           "Bobby Prince\n";
+
+static char     credits6Msg[] =
+           "Robot Models\n"
+           "\n"
+           "Gregor Punchatz\n";
+
+static char     credits7Msg[] =
+           "Special Thanks\n"
+           "\n"
+           "George Broussard\n"
+           "Scott Miller\n"
+           "Steven Blackburn\n"
+           "Apogee Technical Support\n"
+           "Apogee Support Staff\n"
+           "John Carmack\n"
+           "Ken Silverman\n";
+
+static char     credits8Msg[] =
+           "The Hand of God\n"
+           "\n"
+           "Tim Neveu's Hand\n";
+
+static char     credits9Msg[] =
+           "Dog Snout and Paw\n"
+           "\n"
+           "Loki\n"
+           "The Carpet Wetting Maestro\n";
+
+static char     credits10Msg[] =
+           "Krist's chair\n"
+           "\n"
+           "Stephen Blackburn's Comfy Chair\n"
+           "Marianna's Paper and Glue\n";
+
+static char     credits11Msg[] =
+           "Character Voices\n"
+           "\n"
+           "Darian - Mark Dochtermann\n"
+           "Krist - Joe Siegler\n"
+           "NME - Sound CD#4005\n"
+           "Oscuro - Tom Hall\n"
+           "Low Guard - Steve Quarrella\n"
+           "High Guard - Steven Blackburn\n"
+           "Over Patrol - Chuck Jones\n";
+
+static char     credits12Msg[] =
+           "Character Voices Continued\n"
+           "\n"
+           "Strike Team - Scott Miller\n"
+           "Lightning Guard - William Scarboro\n"
+           "Triad Enforcer - George Broussard\n"
+           "All Monks - Tom Hall\n"
+           "Taradino - Joe Selinske\n"
+           "Lorelei - Pau Suet Ying\n"
+           "Ian Paul - Jim Dose'\n"
+           "Doug - Lee Jackson\n"
+           "Thi - Susan Singer\n";
+
+static char     actorsMsg[] =
+           "The Actors\n";
+
+static char     actors1Msg[] =
+           "Low Guard\n"
+           "\n"
+           "Steve Quarrella\n";
+
+static char     actors2Msg[] =
+           "High Guard\n"
+           "\n"
+           "Steven Blackburn\n";
+
+static char     actors3Msg[] =
+           "Over Patrol\n"
+           "\n"
+           "Nolan Martin\n";
+
+static char     actors4Msg[] =
+           "Strike Team\n"
+           "\n"
+           "Scott Miller\n";
+
+static char     actors5Msg[] =
+           "Lightning Guard\n"
+           "\n"
+           "Kevin Green\n";
+
+static char     actors6Msg[] =
+           "Triad Enforcer\n"
+           "\n"
+           "George Broussard\n";
+
+static char     actors7Msg[] =
+           "Death Monk\n"
+           "\n"
+           "Lee Jackson\n";
+
+static char     actors8Msg[] =
+           "Deathfire Monk\n"
+           "\n"
+           "Allen Blum III\n";
+
+static char     actors9Msg[] =
+           "Robot Guard\n"
+           "\n"
+           "Himself\n";
+
+static char     actors10Msg[] =
+           "General Darian\n"
+           "\n"
+           "Steve Maines\n";
+
+static char     actors11Msg[] =
+           "Sebastian Krist\n"
+           "\n"
+           "Joe Siegler\n";
+
+static char     actors12Msg[] =
+           "The NME\n"
+           "\n"
+           "Himself\n";
+
+static char     actors13Msg[] =
+           "El Oscuro\n"
+           "\n"
+           "Tom Hall\n";
+
+
+static char     cut1Msg[] =
+           "Deathfire Monk\n"
+           "\n"
+           "Mark Dochtermann\n";
+
+
+static char     cut2Msg[] =
+           "Over Patrol\n"
+           "\n"
+           "Pat Miller\n";
+
+
+static char     cut3Msg[] =
+           "Low Guard\n"
+           "\n"
+           "Marianna Vayntrub\n";
+
+
+static char     cut4Msg[] =
+           "Strike Team\n"
+           "\n"
+           "Ann Grauerholz\n";
+
+static char     cut5Msg[] =
+           "Lightning Guard\n"
+           "\n"
+           "William Scarboro\n";
+
+
+static char     cut6Msg[] =
+           "High Guard\n"
+           "\n"
+           "Stephen Hornback\n";
+
+
+
+static char     playersCutMsg[] =
+           "Actors who were\n"
+           "cut from the game\n";
+
+void DIPCredits ( void )
+{
+   byte * back;
+
+   back=SafeMalloc(800*linewidth);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   PrepareBackground ( back );
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
+   ScrollString ( 100, &creditsMsg[0], back, 4*VBLCOUNTER, 30);
+   CurrentFont = smallfont;
+   ScrollString ( 100, &credits1Msg[0], back, 4*VBLCOUNTER, 50);
+   ScrollString ( 100, &credits2Msg[0], back, 4*VBLCOUNTER, 50);
+   ScrollString ( 100, &credits3Msg[0], back, 4*VBLCOUNTER, 50);
+   ScrollString ( 100, &credits4Msg[0], back, 4*VBLCOUNTER, 50);
+   ScrollString ( 100, &credits5Msg[0], back, 4*VBLCOUNTER, 50);
+   ScrollString ( 100, &credits6Msg[0], back, 4*VBLCOUNTER, 50);
+   ScrollString ( 100, &credits7Msg[0], back, 4*VBLCOUNTER, 50);
+   ScrollString ( 100, &credits8Msg[0], back, 4*VBLCOUNTER, 50);
+   ScrollString ( 100, &credits9Msg[0], back, 4*VBLCOUNTER, 50);
+   ScrollString ( 100, &credits10Msg[0], back, 4*VBLCOUNTER, 50);
+   ScrollString ( 100, &credits11Msg[0], back, 4*VBLCOUNTER, 80);
+   ScrollString ( 100, &credits12Msg[0], back, 4*VBLCOUNTER, 80);
+
+   CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
+   ScrollString ( 100, &actorsMsg[0], back, 4*VBLCOUNTER, 50);
+
+   CurrentFont = smallfont;
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("lwgshoo2"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors1Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("hg2shoo2"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors2Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("obpshoo1"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors3Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("ankshoo1"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors4Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("ligrise4"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors5Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("tritoss5"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors6Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("monkdr4"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors7Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("allksh4"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors8Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("robogrd1"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors9Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("darshoo1"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors10Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("hdope8"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors11Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("rbody101"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("rhead101"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("rsw01"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors12Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("tomfly21"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &actors13Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   PrepareBackground ( back );
+   CurrentFont = (font_t *)W_CacheLumpName ("newfnt1", PU_STATIC, Cvt_font_t, 1);
+   ScrollString ( 100, &playersCutMsg[0], back, 4*VBLCOUNTER, 40);
+
+   CurrentFont = smallfont;
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutmark"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &cut1Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutpat"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &cut2Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutmari"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &cut3Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutann"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &cut4Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutwill"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &cut5Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+   DrawNormalSprite(0,(200-128)>>1,W_GetNumForName("cutstev"));
+   PrepareBackground ( back );
+   ScrollString ( 100, &cut6Msg[0], back, 4*VBLCOUNTER, 50);
+
+   VL_FadeOut (0, 255, 0, 0, 0, 80);
+
+   DrawNormalSprite(0,0,W_GetNumForName("grouppic"));
+   PrepareBackground ( back );
+   FlipPage();
+   VL_FadeIn (0, 255, origpal, 30);
+   ScrollString ( 175, &dipMsg[0], back, 4*VBLCOUNTER, 140);
+   VL_FadeOut (0, 255, 0, 0, 0, 80);
+
+   W_CacheLumpName ("newfnt1", PU_CACHE, Cvt_font_t, 1);
+   SafeFree(back);
+}
+
+void DoEndCinematic ( void )
+{
+	EnableScreenStretch();
+
+   viewwidth = 320;//MAXSCREENWIDTH;
+   viewheight = 200;//MAXSCREENHEIGHT;
+   MU_FadeOut ( 1000 );
+   MU_StopSong ();
+
+   ShowFinalDoor();
+   ShowTransmitter ();
+   ShowFinalFire();
+   DoTransmitterExplosion();
+   MU_StartSong(song_youwin);
+   DoBurningCastle ();
+   DoSanNicolas();
+   if (DestroyedAllEggs () == true)
+      {
+      PlayerQuestionScreen();
+      DIPCredits();
+      DoYouWin();
+      if (LastScan !=0)
+         {
+         IN_UpdateKeyboard();
+         return;
+         }
+      DoFinalEnd();
+      }
+   else
+      {
+      MU_StartSong(song_gameover);
+      DoFailedScreen();
+      DestroyEarth();
+      DoTryAgainScreen ();
+      playstate=ex_warped;
+      gamestate.mapon=33;
+      }
+   IN_UpdateKeyboard();
+}
+
+void DoInBetweenCinematic (int yoffset, int lump, int delay, char * string )
+{
+   int width,height;
+   int x,y;
+
+   VL_FadeOut (0, 255, 0, 0, 0, 20);
+   VL_ClearBuffer (bufferofs, 0);
+   DrawNormalSprite(0,yoffset,lump);
+
+   CurrentFont=smallfont;
+   US_MeasureStr (&width, &height, string);
+   x=(320-width)>>1;
+   y=190-height;
+   US_ClippedPrint (x, y, string);
+   FlipPage();
+   VL_FadeIn(0,255,origpal,20);
+   I_Delay (delay);
+   VL_FadeOut (0, 255, 0, 0, 0, 20);
+}
+#endif
+
+
+//******************************************************************************
+//
+// DoCreditScreen
+//
+//******************************************************************************
+
+#define NUMFIRSTCREDITMESSAGES 22
+#define NUMSECONDCREDITMESSAGES 28
+
+typedef struct CreditType {
+  char  text[80];
+  byte  font;
+  byte  endy;
+} CreditType;
+
+CreditType FirstCredits[NUMFIRSTCREDITMESSAGES] =
+  {
+    {"Rise of the Triad Credits",0,0},
+    {"COPYRIGHT (c) 1995 Apogee Software Ltd.",1,10},
+    {"Apogee's Developers of Incredible Power",1,20},
+    {"Creative Director",0,30},
+    {"Tom Hall",1,40},
+    {"Programmers",0,50},
+    {"Mark Dochtermann  William Scarboro",1,60},
+    {"Jim Dose'  Nolan Martin",1,66},
+    {"Artists",0,76},
+    {"Stephen Hornback  Chuck Jones",1,86},
+    {"Susan Singer  Tim Neveu",1,92},
+    {"James Storey  Cygnus Multimedia",1,98},
+    {"Level Designers",0,108},
+    {"Joseph Selinske  Tom Hall",1,118},
+    {"Marianna Vayntrub  Joe Siegler",1,124},
+    {"Musicians",0,134},
+    {"Lee Jackson  Robert Prince",1,144},
+    {"Uniforms",0,154},
+    {"D.J. Goodwin  Matt McKinney",1,164},
+    {"Special Thanks",0,174},
+    {"John Carmack  Ken Silverman  Gregor Punchatz",1,184},
+  };
+
+CreditType SecondCredits[NUMSECONDCREDITMESSAGES] =
+  {
+    {"Rise of the Triad Credits",0,0},
+    {"COPYRIGHT (c) 1995 Apogee Software Ltd.",1,10},
+    {"Executive Producers",0,20},
+    {"George Broussard  Scott Miller",1,30},
+    {"Manual Design",0,40},
+    {"Robert Atkins",1,50},
+    {"Beta Testers",0,60},
+    {"Steven Blackburn",1,70},
+    {"Todd Aubin  Mike Bartelt",1,76},
+    {"Wayne Benner  Neil Bonner",1,82},
+    {"Glenn Brensinger  Douglas Brewer",1,88},
+    {"David Butler  Daniel Creeron",1,94},
+    {"Scott Darling  Jason Ewasiuk",1,100},
+    {"Craig Hamilton  Ken Heckbert",1,106},
+    {"Terry Herrin  Greg Hively",1,112},
+    {"John Howard  Douglas Howell",1,118},
+    {"Dennis Kurek  Hank Leukart",1,124},
+    {"Jim Lietzan  Ken Mayer",1,130},
+    {"Wayne Millard  Penny Plant",1,136},
+    {"Brian Prinner  Jeff Rausch",1,142},
+    {"Kelly Rogers  Neil Rubenking",1,148},
+    {"Steven Salter  Chris White",1,154},
+    {"Special Thanks",0,162},
+    {"Apogee Technical Support  Pau Suet Ying",1,172},
+    {"Anthony, Zach, Rajan, Miki, Loki",1,178},
+    {"Nathan, Petro, Tim, Jake, MacKay",1,184},
+    {"Loyal, Ric, Teller, Amano",1,190},
+  };
+
+void DrawPreviousCredits ( int num, CreditType * Credits )
+{
+   int width;
+   int height;
+   int x,y;
+   int i;
+
+   for(i=0;i<num;i++)
+      {
+      if (Credits[i].font==0)
+         CurrentFont=smallfont;
+      else
+         CurrentFont=tinyfont;
+      US_MeasureStr (&width, &height, &(Credits[i].text[0]));
+      x=(320-width)>>1;
+      y=Credits[i].endy;
+      US_ClippedPrint (x, y+4, &Credits[i].text[0]);
+      }
+}
+
+#define CREDITSTARTY 220
+//******************************************************************************
+//
+// WarpCreditString
+//
+//******************************************************************************
+
+extern boolean dopefish;
+void WarpCreditString ( int time, byte * back, int num, CreditType * Credits)
+{
+   int dy;
+   int cy;
+   int x;
+   int y;
+   int width;
+   int height;
+   boolean soundplayed;
+
+
+   LastScan = 0;
+
+   if (Credits[num].font==0)
+      CurrentFont=smallfont;
+   else
+      CurrentFont=tinyfont;
+   US_MeasureStr (&width, &height, &(Credits[num].text[0]));
+
+   x=(320-width)>>1;
+   y=Credits[num].endy;
+   dy=((y-CREDITSTARTY)<<16)/time;
+   cy=CREDITSTARTY<<16;
+
+   CalcTics();
+
+   soundplayed=false;
+
+   while (time>0)
+      {
+      DrawBackground ( back );
+      DrawPreviousCredits ( num, Credits );
+      if (Credits[num].font==0)
+         CurrentFont=smallfont;
+      else
+         CurrentFont=tinyfont;
+      US_ClippedPrint (x, (cy>>16)+4, &Credits[num].text[0]);
+      if ( ((cy>>16)<196) && (soundplayed==false))
+         {
+         if ((dopefish==true) && (SD_Started==true))
+            {
+            int snd;
+
+            do
+               {
+               snd=(RandomNumber("DoCredits",0)+RandomNumber("DoCredits",0))%MAXSOUNDS;
+               }
+            while (SD_SoundOkay ( snd ) == false);
+            SD_Play ( snd );
+            }
+         else
+            {
+//            SD_Play ( SD_BAZOOKAFIRESND );
+#if (SHAREWARE == 0)
+            SD_Play ( SD_BAZOOKAFIRESND + (RandomNumber("DoCredits",1)%13) );
+#else
+            SD_Play ( SD_BAZOOKAFIRESND + (RandomNumber("DoCredits",1)%6) );
+#endif
+            soundplayed=true;
+            }
+         }
+      FlipPage();
+      CalcTics();
+      cy+=dy*tics;
+      time-=tics;
+      if (LastScan != 0)
+         break;
+      }
+}
+
+void DoCreditScreen ( void )
+{
+   int trilogo;
+   int time;
+   byte * bkgnd;
+   font_t * oldfont;
+   int i;
+	EnableScreenStretch();
+   viewwidth = 320;//MAXSCREENWIDTH;
+   viewheight = 200;//MAXSCREENHEIGHT;
+
+   bkgnd=SafeMalloc(800*linewidth);
+
+   trilogo=W_GetNumForName("trilogo");
+   VL_DrawPostPic (trilogo);
+//  SetTextMode (  );
+
+   PrepareBackground ( bkgnd );
+
+   oldfont=CurrentFont;
+
+   for(i=0;i<NUMFIRSTCREDITMESSAGES;i++)
+      {
+      time = (CREDITSTARTY - FirstCredits[i].endy)*(VBLCOUNTER*1)/CREDITSTARTY;
+//      time = VBLCOUNTER;
+      WarpCreditString ( time, bkgnd, i, FirstCredits );
+      IN_PumpEvents();
+//      SD_Play ( SD_EXPLODESND );
+      if (LastScan !=0)
+         break;
+      }
+   i=NUMFIRSTCREDITMESSAGES;
+   DrawBackground ( bkgnd );
+   DrawPreviousCredits ( i, FirstCredits );
+   FlipPage();
+   IN_PumpEvents();
+
+   I_Delay(40);
+
+   for(i=0;i<NUMSECONDCREDITMESSAGES;i++)
+      {
+      time = (CREDITSTARTY - SecondCredits[i].endy)*(VBLCOUNTER/2)/CREDITSTARTY;
+//      time = VBLCOUNTER;
+      WarpCreditString ( time, bkgnd, i, SecondCredits );
+      IN_PumpEvents();
+//      SD_Play ( SD_EXPLODESND );
+      if (LastScan !=0)
+         break;
+      }
+   i=NUMSECONDCREDITMESSAGES;
+   DrawBackground ( bkgnd );
+   DrawPreviousCredits ( i, SecondCredits );
+   FlipPage();
+   IN_PumpEvents();
+
+   I_Delay(40);
+   MenuFadeOut();
+   VL_ClearVideo (0);
+
+   SafeFree(bkgnd);
+   CurrentFont=oldfont;
+}
+
+
+#define NUMSTORYLINES 16
+
+char * MicroStory[NUMSTORYLINES] =
+   {
+   "You are a member of HUNT, the",
+   "High-Risk United Nations Taskforce.",
+   "Stranded on an island in the",
+   "Pacific, you must battle a master",
+   "of pyrotechnics, hundreds of",
+   "members of a death cult, and their",
+   "leader, El Oscuro.",
+   "\0",
+   "You must reach the transmitter",
+   "that is signalling the systematic",
+   "destruction of Los Angeles.",
+   "\0",
+   "If you fail, millions will die",
+   "and you will be tortured.",
+   "\0",
+   "So, you know, don't fail."
+   };
+
+void DoMicroStoryScreen ( void )
+{
+   pic_t * pic;
+   int x,y;
+   int i;
+
+   VL_FadeOut (0, 255, 0, 0, 0, 20);
+
+   pic=(pic_t *)W_CacheLumpName("mmbk",PU_CACHE,Cvt_pic_t,1);
+   VWB_DrawPic (0, 0, pic);
+   CheckHolidays();
+
+   x=15;
+   y=30;
+
+   IFont = ( cfont_t * )W_CacheLumpName( "sifont", PU_CACHE, Cvt_cfont_t, 1);
+   for(i=0;i<NUMSTORYLINES;i++)
+      {
+      DrawIntensityString (x, y, MicroStory[i], 241);
+      y += 9;
+      }
+
+   FlipPage();
+   MenuFadeIn();
+   I_Delay (100);//240
+
+   VL_FadeOut (0, 255, 0, 0, 0, 20);
+}
+
+#ifndef DOS
+
+void  DrawMenuPost (int height, byte * src, byte * buf)
+{
+	int frac = hp_startfrac;
+	while (height--) {
+		*buf = src[frac >> 16];
+		
+		buf += linewidth;
+		frac += hp_srcstep;
+	}
+}
+
+void  DrawMapPost (int height, byte * src, byte * buf)
+{
+	int frac = 0;
+	while (height--) {
+		*buf = src[frac >> 16];
+		
+		buf += linewidth;
+		frac += hp_srcstep;
+	}
+}
+
+void DrawRotRow(int count, byte * dest, byte * src)
+{
+	unsigned eax, ecx, edx;
+//	unsigned a, b, c,d;
+	 byte * srctmp;
+	 byte * desttmp;
+
+	ecx = mr_yfrac;
+	edx = mr_xfrac;
+
+	if ((iGLOBAL_SCREENWIDTH == 320)||(iG_masked==true))  
+	{
+		while (count--) {
+			eax = edx >> 16;
+			if (eax < 256 && (ecx >> 16) < 512) {
+				eax = (eax << 9) | ((ecx << 7) >> (32-9));
+			} else {
+				eax = 0;
+			}
+			
+			*dest++ = src[eax];
+			
+			edx += mr_xstep;
+			ecx += mr_ystep;
+		}
+	}else if (iGLOBAL_SCREENWIDTH == 640) {
+		while (count--) {
+			eax = edx >> 16;
+			if (eax < (256*2.0) && (ecx >> 16) < (512*1.8)) {
+				eax = (eax << 10) | ((ecx << 6) >> (32-10));
+			} else {
+				eax = 0;
+			}
+			
+			*dest++ = src[eax];
+			
+			edx += mr_xstep;
+			ecx += mr_ystep;
+		}
+	}else if (iGLOBAL_SCREENWIDTH == 800) {
+
+
+
+	srctmp = src;
+	desttmp = dest;
+
+	desttmp -= (iGLOBAL_SCREENWIDTH*1);
+
+	ecx = mr_yfrac;
+	edx = mr_xfrac;
+	//count = 800
+//zxcv
+	while (count--) { 
+		eax = edx >> 16;//edx=4146069504 eax=63264  edx/eax = 65536->0x10000
+		 
+		//a=(eax << 9); //=eax*512
+		//a=(eax << 7); //=eax*128
+		//a=512|128; = 640;
+		//SetTextMode (  );
+		//a=(ecx >> 16);//ecx=4102225920 a=62595   ecx/65536 = 62595
+
+		//         Y-dir                    x-dir
+		if (eax < (256*2.5) && (ecx >> 16) < (512*2)) {
+			//eax = (eax << 9) | ((ecx << 7) >> (32-9));
+			eax = (eax << 10) | ((ecx << 6) >> (32-10));
+	/*		eax = (eax * 512*2) ;
+								//(23)
+			eax += 	 ((ecx ) >> (32-9));//ecx=196608
+			*/
+		} else {
+			eax = 0;
+
+			
+		}
+ 		//desttmp -= centeroffset;	
+		*desttmp++ = srctmp[eax];
+		//*desttmp++ = srctmp[eax];
+		
+		edx += mr_xstep;
+		ecx += mr_ystep;
+	}
+
+	}
+}
+
+void DrawMaskedRotRow(int count, byte * dest, byte * src)
+{
+	unsigned eax;
+	unsigned xfrac, yfrac;
+	
+	xfrac = mr_xfrac;
+	yfrac = mr_yfrac;
+	
+	while (count--) {
+		eax = xfrac >> 16;
+		if (eax < 256 && (yfrac >> 16) < 512) {
+			eax = (eax << 9) | ((yfrac << 7) >> (32-9));
+		} else {
+			eax = 0;
+		}
+		
+		if (src[eax] != 0xff) *dest = src[eax];
+		dest++;
+		
+		xfrac += mr_xstep;
+		yfrac += mr_ystep;
+	}
+}
+
+void DrawSkyPost (byte * buf, byte * src, int height)
+{
+// bna fix for missing sky by high res eg 800x600
+// when sky is >400 (max skyheight) then reverse mouintain to missing spot
+// there should be 200 line of mouintain (400+200) = 600 height lines
+// not the best solution but what it works
+
+	if (iGLOBAL_SCREENWIDTH > 320){
+	// bna section start
+		//int n = 0;
+		int orgh = 0;//height;
+		if (height > 400){orgh=height;}
+
+		while (height--) {
+			if ((orgh > 0)&&( height<(orgh-400))){
+				src-=2;
+				*buf = shadingtable[*src];
+			}else{
+
+				*buf = shadingtable[*src];
+			}
+			buf += linewidth;
+			src++;
+		}
+	// bna section end
+	}
+	else {
+	// org code
+		while (height--) {
+			*buf = shadingtable[*src];
+			
+			buf += linewidth;
+			src++;
+		}
+	//	
+	}
+  
+	/*
+	int lw = linewidth * 2;
+	int h  = height;
+
+	while (h--) {
+		*(buf) = shadingtable[*src];
+		buf += lw;
+		*(buf) = shadingtable[*src];
+		buf += lw;
+		
+		//buf += lw;
+		src++;
+		
+	}*/
+}
+
+#define CEILINGCOLOR 24 //default color when no sky or floor
+#define FLOORCOLOR 32
+
+void RefreshClear (void)
+{
+	int start, base;
+	
+	memset(spotvis, 0, sizeof(spotvis));
+	
+	if (fandc) {
+		return;
+	}
+	
+	start = min(centery, viewheight);
+	
+	if (start > 0) {
+		VL_Bar(0, 0, iGLOBAL_SCREENHEIGHT, start, CEILINGCOLOR);
+	} else {
+		start = 0;
+	}
+	
+	base = start;
+	
+	start = min(viewheight-start, viewheight);
+	if (start > 0) {
+		VL_Bar(0, base, iGLOBAL_SCREENHEIGHT, start, FLOORCOLOR);
+	}
+}
+
+#endif
+
+#if 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef struct {
+  int   x;
+  int   y;
+  int   angle;
+  int   speed;
+  int   color;
+  int   endx;
+  int   endy;
+  int   plane;
+  int   time;
+} ParticleType;
+
+#define NUMPARTICLES 300
+#define PARTICLETHINKTIME 5
+#define Fix(a)        (a &= (FINEANGLES-1))
+ParticleType * Particle;
+int numparticles;
+
+//******************************************************************************
+//
+// InitializeParticles
+//
+//******************************************************************************
+
+void InitializeParticles (void)
+{
+   int i;
+   ParticleType * part;
+
+   Particle=(ParticleType *)SafeMalloc ( sizeof(ParticleType) * numparticles );
+   memset ( Particle, 0, sizeof(ParticleType) * numparticles );
+
+   for (i=0;i<numparticles;i++)
+      {
+      part=&Particle[i];
+      part->x=((RandomNumber("hello",0)*RandomNumber("hello",0))%viewwidth)<<16;
+      part->y=((RandomNumber("hello",0)*RandomNumber("hello",0))%viewheight)<<16;
+//      part->x=(((RandomNumber("hello",0)*RandomNumber("hello",0))%(viewwidth-40)+20)<<16);
+//      part->y=(((RandomNumber("hello",0)*RandomNumber("hello",0))%(viewheight-40)+20)<<16);
+      part->angle=(RandomNumber("hello",0)*RandomNumber("hello",0))%FINEANGLES;
+//      part->speed=(RandomNumber("hello",0)%2)<<16;
+      part->speed=(1<<16)-1;
+      part->color=RandomNumber("hello",0);
+      part->endx=-1;
+      part->endy=-1;
+      part->plane=(part->x>>16)&3;
+      part->time=(RandomNumber("",0)%PARTICLETHINKTIME)+1;
+//      part->color=255;
+      }
+}
+
+//******************************************************************************
+//
+// ShutdownParticles
+//
+//******************************************************************************
+
+void ShutdownParticles (void)
+{
+   SafeFree(Particle);
+}
+
+
+void AdjustParticleAngle(int maxadjust, int *currangle,int targetangle)
+   {
+   int dangle,i,magangle;
+
+   for(i=0;i<maxadjust;i++)
+      {
+      dangle = *currangle - targetangle;
+
+      if (dangle)
+         {
+         magangle = abs(dangle);
+         if (magangle > (ANGLES/2))
+            {
+            if (dangle > 0)
+               (*currangle) ++;
+            else
+               (*currangle) --;
+            }
+         else
+            {
+            if (dangle > 0)
+               (*currangle) --;
+            else
+               (*currangle) ++;
+            }
+         Fix(*currangle);
+         }
+      }
+   }
+
+//******************************************************************************
+//
+// UpdateParticles
+//
+//******************************************************************************
+
+//#define MAXADJUST (FINEANGLES/40)
+#define MAXADJUST (FINEANGLES/20)
+void UpdateParticles (int type)
+{
+   int i;
+   int dx,dy;
+   ParticleType * target;
+   ParticleType * part;
+
+   if (type==0)
+      {
+      for (i=0;i<numparticles-1;i++)
+         {
+         int angle;
+
+         part=&Particle[i];
+//         target=&Particle[numparticles-1];
+//         target=&Particle[i+1];
+         target=&Particle[(RandomNumber("",0)*RandomNumber("",0))%numparticles];
+         part->x+=-FixedMul (part->speed, costable[part->angle]);
+         part->y+= FixedMul (part->speed, sintable[part->angle]);
+         part->plane=(part->x>>16)&3;
+
+         dx = part->x - target->x;
+         dy = target->y - part->y;
+         if (dx && dy)
+            {
+            angle = atan2_appx(dx,dy);
+            AdjustParticleAngle(MAXADJUST,&(part->angle),angle);
+            }
+         }
+      part=&Particle[numparticles-1];
+      part->x+=-FixedMul (part->speed, costable[part->angle]);
+      part->y+= FixedMul (part->speed, sintable[part->angle]);
+      part->plane=(part->x>>16)&3;
+
+      dx=part->x>>16;
+      dy=part->y>>16;
+
+      if ( (dx<20) || (dx>(viewwidth-20)) )
+         {
+         if ( part->angle < (FINEANGLES/2) )
+            {
+            part->angle=FINEANGLES/2-part->angle;
+            Fix(part->angle);
+            }
+         else
+            {
+            part->angle=FINEANGLES-part->angle;
+            Fix(part->angle);
+            }
+         }
+      if ( (dy<20) || (dy>(viewheight-20)) )
+         {
+         part->angle=FINEANGLES-part->angle;
+         Fix(part->angle);
+         }
+      }
+   else
+      {
+      for (i=0;i<numparticles;i++)
+         {
+         int angle;
+
+         part=&Particle[i];
+         if ((part->x>>16)!=part->endx)
+            part->x+=-FixedMul (part->speed, costable[part->angle]);
+         else
+            part->x=part->endx<<16;
+         if ((part->y>>16)!=part->endy)
+            part->y+= FixedMul (part->speed, sintable[part->angle]);
+         else
+            part->y=part->endy<<16;
+         part->plane=(part->x>>16)&3;
+
+         part->time--;
+         if (part->time==0)
+            {
+            part->time=PARTICLETHINKTIME;
+            dx = part->x - (part->endx<<16);
+            dy = (part->endy<<16) - part->y;
+            if (dx && dy)
+               {
+               angle = atan2_appx(dx,dy);
+               AdjustParticleAngle(MAXADJUST,&(part->angle),angle);
+               }
+            }
+         }
+      }
+}
+
+//******************************************************************************
+//
+// DrawParticles
+//
+//******************************************************************************
+
+void DrawParticles (void)
+{
+   int i;
+   int dx,dy;
+   int plane;
+   ParticleType * part;
+
+   VL_ClearBuffer (bufferofs, 0);
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+      VGAWRITEMAP(plane);
+      for (i=0;i<numparticles;i++)
+         {
+         part=&Particle[i];
+         if (part->plane!=plane)
+            continue;
+         dx=part->x>>16;
+         dy=part->y>>16;
+         if (dx<0) dx=0;
+         if (dx>=viewwidth) dx=viewwidth-1;
+         if (dy<0) dy=0;
+         if (dy>=viewheight) dy=viewheight-1;
+#ifdef DOS
+         *( (byte *) bufferofs + (dx>>2) + ylookup[dy] ) = part->color;
+#else
+         *( (byte *) bufferofs + dx + ylookup[dy] ) = part->color;
+#endif
+         }
+      }
+}
+
+void DrawParticleTemplate (void)
+{
+   byte pal[768];
+
+   viewwidth=320;
+   viewheight=200;
+   memcpy(&pal[0],W_CacheLumpName("ap_pal",PU_CACHE),768);
+   VL_NormalizePalette(&pal[0]);
+   SwitchPalette(&pal[0],35);
+   VL_ClearBuffer (bufferofs, 255);
+   DrawNormalSprite (0, 0, W_GetNumForName("ap_titl"));
+}
+
+void DrawAlternateParticleTemplate (void)
+{
+   viewwidth=320;
+   viewheight=200;
+   VL_ClearBuffer (bufferofs, 255);
+   DrawNormalSprite (0, 0, W_GetNumForName("LIFE_C1"));
+}
+
+int CountParticles (void)
+{
+   int plane,a,b;
+   int count;
+
+   count=0;
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+      VGAREADMAP(plane);
+      for (a=0;a<200;a++)
+         {
+#ifdef DOS
+         for (b=0;b<80;b++)
+#else
+         for (b=0;b<320;b++)
+#endif
+            {
+            if (*((byte *)bufferofs+(a*linewidth)+b)!=255)
+               count++;
+            }
+         }
+      }
+   return count;
+}
+
+void AssignParticles (void)
+{
+   int plane,a,b;
+   byte pixel;
+   ParticleType * part;
+
+   part=&Particle[0];
+
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+      VGAREADMAP(plane);
+      for (a=0;a<200;a++)
+         {
+#ifdef DOS
+         for (b=0;b<80;b++)
+#else
+         for (b=0;b<320;b++)
+#endif
+            {
+            pixel = *((byte *)bufferofs+(a*linewidth)+b);
+            if (pixel!=255)
+               {
+#ifdef DOS
+               part->endx=plane+(b<<2);
+#else
+               part->endx=b;
+#endif
+               part->endy=a;
+               part->color=pixel;
+               part++;
+               }
+            }
+         }
+      }
+}
+
+//******************************************************************************
+//
+// ParticleIntro
+//
+//******************************************************************************
+
+void ParticleIntro (void)
+{
+   int i,j;
+
+
+   SetViewSize (MAXVIEWSIZES-1);
+   numparticles=NUMPARTICLES;
+   DrawAlternateParticleTemplate ();
+//   DrawParticleTemplate ();
+   numparticles=CountParticles ();
+   InitializeParticles ();
+   AssignParticles();
+//   numparticles>>=1;
+
+   CalcTics();
+   CalcTics();
+   LastScan=0;
+   for (i=0;i<VBLCOUNTER*15;i+=tics)
+      {
+      DrawParticles();
+      FlipPage();
+      for (j=0;j<tics;j++)
+         {
+         UpdateParticles(0);
+         }
+      CalcTics();
+      if ((LastScan) || IN_GetMouseButtons())
+         break;;
+      }
+   LastScan=0;
+   for (i=0;i<VBLCOUNTER*15;i+=tics)
+      {
+      DrawParticles();
+      FlipPage();
+      for (j=0;j<tics;j++)
+         {
+         UpdateParticles(1);
+         }
+      CalcTics();
+      if ((LastScan) || IN_GetMouseButtons())
+         break;;
+      }
+   ShutdownParticles ();
+}
+
+#endif
+

Added: tags/rott-1.1/rott/rt_draw.h
===================================================================
--- tags/rott-1.1/rott/rt_draw.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_draw.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,127 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_draw_public
+#define _rt_draw_public
+
+//***************************************************************************
+//
+//    RT_DRAW.C - Draw-o-rama
+//
+//***************************************************************************
+
+
+#define MAXVISIBLE              256
+
+extern int whereami;
+
+extern byte * shadingtable;            // Shading table for DrawPost
+
+typedef struct
+{
+int viewheight;
+int viewx;
+int shapenum;
+int altshapenum;
+int shapesize;
+int x1,x2,h1,h2;
+int texturestart;
+int textureend;
+byte * colormap;
+
+} visobj_t;
+
+
+extern  word             tilemap[MAPSIZE][MAPSIZE];    // wall values only
+extern  byte             spotvis[MAPSIZE][MAPSIZE];
+
+extern int tics;
+extern int wstart;
+extern int fandc;
+
+//
+// math tables
+//
+extern short    tantable[FINEANGLES];
+extern fixed    sintable[FINEANGLES+FINEANGLEQUAD+1];
+extern fixed    *costable;
+
+//
+// refresh variables
+//
+
+extern fixed   viewx,viewy;             // the focal point
+extern int     viewangle;
+extern fixed   viewsin,viewcos;
+
+//
+// ray tracing variables
+//
+
+extern visobj_t vislist[MAXVISIBLE];
+extern visobj_t *visptr,*visstep,*farthest;
+
+extern long     xintercept,yintercept;
+extern byte     mapseen[MAPSIZE][MAPSIZE];
+extern unsigned long * lights;
+
+extern int hp_startfrac;
+extern int hp_srcstep;
+extern int levelheight;
+extern int maxheight;
+extern int nominalheight;
+
+extern int actortime;
+extern int drawtime;
+extern int c_startx;
+extern int c_starty;
+
+extern const int dirangle8[9];
+extern const int dirangle16[16];
+extern  int firstcoloffset;
+
+//=========================== macros =============================
+
+#define LightSourceAt(x,y)    (*(lights+((x)<<7)+(y)))
+#define SetLight(x,y,level)   (LightSourceAt((x),(y))|=(unsigned long)(level))
+
+//=========================== functions =============================
+
+void  BuildTables (void);
+void  CalcTics (void);
+void  ThreeDRefresh (void);
+void  FlipPage ( void );
+void  TurnShakeOff( void );
+void  AdaptDetail ( void );
+int   CalcHeight (void);
+void  DoLoadGameSequence( void );
+void RotateBuffer (int startangle, int endangle, int startscale, int endscale, int time);
+void ApogeeTitle (void);
+void DopefishTitle (void);
+void RotationFun (void);
+void GetRainBoundingBox (int * xmin, int * xmax, int * ymin, int * ymax);
+void StartupScreenSaver ( void );
+void ShutdownScreenSaver ( void );
+void UpdateScreenSaver ( void );
+void DoEndCinematic ( void );
+void DoCreditScreen ( void );
+void DoMicroStoryScreen ( void );
+void DoInBetweenCinematic (int yoffset, int lump, int delay, char * string );
+
+#endif

Added: tags/rott-1.1/rott/rt_err.c
===================================================================
--- tags/rott-1.1/rott/rt_err.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_err.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,336 @@
+const unsigned char ROTT_ERR[4000] = {
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC9, 0x1B, 0xCD, 0x1B, 0xB5, 0x1B,
+  0x1E, 0x9C, 0x52, 0x1E, 0x69, 0x1E, 0x73, 0x1E, 0x65, 0x1E, 0x20, 0x1E,
+  0x6F, 0x1E, 0x66, 0x1E, 0x20, 0x1E, 0x74, 0x1E, 0x68, 0x1E, 0x65, 0x1E,
+  0x20, 0x1E, 0x54, 0x1E, 0x72, 0x1E, 0x69, 0x1E, 0x61, 0x1E, 0x64, 0x1E,
+  0x20, 0x1E, 0x45, 0x1E, 0x72, 0x1E, 0x72, 0x1E, 0x6F, 0x1E, 0x72, 0x1E,
+  0x21, 0x1E, 0x1E, 0x9C, 0xC6, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xB5, 0x1B, 0x76, 0x19, 0x53, 0x19, 0x31, 0x19, 0x2E, 0x19, 0x30, 0x19,
+  0xC6, 0x1B, 0xCD, 0x1B, 0xBB, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xBA, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0xBA, 0x1B, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x50, 0x1B,
+  0x6C, 0x1B, 0x65, 0x1B, 0x61, 0x1B, 0x73, 0x1B, 0x65, 0x1B, 0x20, 0x1B,
+  0x72, 0x1B, 0x75, 0x1B, 0x6E, 0x1B, 0x20, 0x1B, 0x52, 0x1B, 0x4F, 0x1B,
+  0x54, 0x1B, 0x54, 0x1B, 0x48, 0x1B, 0x45, 0x1B, 0x4C, 0x1B, 0x50, 0x1B,
+  0x2E, 0x1B, 0x45, 0x1B, 0x58, 0x1B, 0x45, 0x1B, 0x20, 0x1B, 0x66, 0x1B,
+  0x6F, 0x1B, 0x72, 0x1B, 0x20, 0x1B, 0x6D, 0x1B, 0x6F, 0x1B, 0x72, 0x1B,
+  0x65, 0x1B, 0x2C, 0x1B, 0x20, 0x1B, 0x77, 0x1B, 0x65, 0x1B, 0x6C, 0x1B,
+  0x6C, 0x1B, 0x2C, 0x1B, 0x20, 0x1B, 0x68, 0x1F, 0x65, 0x1F, 0x6C, 0x1F,
+  0x70, 0x1F, 0x66, 0x1F, 0x75, 0x1F, 0x6C, 0x1F, 0x20, 0x1B, 0x69, 0x1B,
+  0x6E, 0x1B, 0x66, 0x1B, 0x6F, 0x1B, 0x72, 0x1B, 0x6D, 0x1B, 0x61, 0x1B,
+  0x74, 0x1B, 0x69, 0x1B, 0x6F, 0x1B, 0x6E, 0x1B, 0x2E, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC8, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xBC, 0x1B, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC9, 0x1B,
+  0xCD, 0x1B, 0xB5, 0x1B, 0x1E, 0x9C, 0x55, 0x1E, 0x68, 0x1E, 0x2C, 0x1E,
+  0x20, 0x1E, 0x6F, 0x1E, 0x68, 0x1E, 0x2E, 0x1E, 0x20, 0x1E, 0x4D, 0x1E,
+  0x65, 0x1E, 0x6D, 0x1E, 0x6F, 0x1E, 0x72, 0x1E, 0x79, 0x1E, 0x20, 0x1E,
+  0x70, 0x1E, 0x72, 0x1E, 0x6F, 0x1E, 0x62, 0x1E, 0x6C, 0x1E, 0x65, 0x1E,
+  0x6D, 0x1E, 0x73, 0x1E, 0x2E, 0x1E, 0x1E, 0x9C, 0xC6, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xB5, 0x1B, 0x76, 0x19, 0x53, 0x19, 0x31, 0x19,
+  0x2E, 0x19, 0x30, 0x19, 0xC6, 0x1B, 0xCD, 0x1B, 0xBB, 0x1B, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x59, 0x1B, 0x6F, 0x1B, 0x75, 0x1B, 0x20, 0x1B, 0x64, 0x1B,
+  0x6F, 0x1B, 0x20, 0x1B, 0x6E, 0x1B, 0x6F, 0x1B, 0x74, 0x1B, 0x20, 0x1B,
+  0x68, 0x1B, 0x61, 0x1B, 0x76, 0x1B, 0x65, 0x1B, 0x20, 0x1B, 0x65, 0x1B,
+  0x6E, 0x1B, 0x6F, 0x1B, 0x75, 0x1B, 0x67, 0x1B, 0x68, 0x1B, 0x20, 0x1B,
+  0x6D, 0x1B, 0x65, 0x1B, 0x6D, 0x1B, 0x6F, 0x1B, 0x72, 0x1B, 0x79, 0x1B,
+  0x20, 0x1B, 0x74, 0x1B, 0x6F, 0x1B, 0x20, 0x1B, 0x72, 0x1B, 0x75, 0x1B,
+  0x6E, 0x1B, 0x20, 0x1B, 0x52, 0x1F, 0x69, 0x1F, 0x73, 0x1F, 0x65, 0x1F,
+  0x20, 0x1F, 0x6F, 0x1F, 0x66, 0x1F, 0x20, 0x1F, 0x74, 0x1F, 0x68, 0x1F,
+  0x65, 0x1F, 0x20, 0x1F, 0x54, 0x1F, 0x72, 0x1F, 0x69, 0x1F, 0x61, 0x1F,
+  0x64, 0x1F, 0x2E, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xBA, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x53, 0x1B, 0x6F, 0x1B, 0x6D, 0x1B,
+  0x65, 0x1B, 0x20, 0x1B, 0x74, 0x1B, 0x68, 0x1B, 0x69, 0x1B, 0x6E, 0x1B,
+  0x67, 0x1B, 0x73, 0x1B, 0x20, 0x1B, 0x79, 0x1B, 0x6F, 0x1B, 0x75, 0x1B,
+  0x20, 0x1B, 0x6D, 0x1B, 0x69, 0x1B, 0x67, 0x1B, 0x68, 0x1B, 0x74, 0x1B,
+  0x20, 0x1B, 0x74, 0x1B, 0x72, 0x1B, 0x79, 0x1B, 0x20, 0x1B, 0x74, 0x1B,
+  0x6F, 0x1B, 0x20, 0x1B, 0x63, 0x1B, 0x6F, 0x1B, 0x72, 0x1B, 0x72, 0x1B,
+  0x65, 0x1B, 0x63, 0x1B, 0x74, 0x1B, 0x20, 0x1B, 0x74, 0x1B, 0x68, 0x1B,
+  0x69, 0x1B, 0x73, 0x1B, 0x20, 0x1B, 0x73, 0x1B, 0x69, 0x1B, 0x74, 0x1B,
+  0x75, 0x1B, 0x61, 0x1B, 0x74, 0x1B, 0x69, 0x1B, 0x6F, 0x1B, 0x6E, 0x1B,
+  0x3A, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0xBA, 0x1B, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x07, 0x1B, 0x20, 0x1B,
+  0x75, 0x1B, 0x6E, 0x1B, 0x6C, 0x1B, 0x6F, 0x1B, 0x61, 0x1B, 0x64, 0x1B,
+  0x20, 0x1B, 0x61, 0x1B, 0x6E, 0x1B, 0x79, 0x1B, 0x20, 0x1B, 0x54, 0x1B,
+  0x53, 0x1B, 0x52, 0x1B, 0x73, 0x1B, 0x20, 0x1B, 0x79, 0x1B, 0x6F, 0x1B,
+  0x75, 0x1B, 0x20, 0x1B, 0x68, 0x1B, 0x61, 0x1B, 0x76, 0x1B, 0x65, 0x1B,
+  0x20, 0x1B, 0x69, 0x1B, 0x6E, 0x1B, 0x20, 0x1B, 0x6D, 0x1B, 0x65, 0x1B,
+  0x6D, 0x1B, 0x6F, 0x1B, 0x72, 0x1B, 0x79, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xBA, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x07, 0x1B, 0x20, 0x1B, 0x64, 0x1B, 0x6F, 0x1B, 0x20, 0x1B, 0x6E, 0x1B,
+  0x6F, 0x1B, 0x74, 0x1B, 0x20, 0x1B, 0x6C, 0x1B, 0x6F, 0x1B, 0x61, 0x1B,
+  0x64, 0x1B, 0x20, 0x1B, 0x53, 0x1B, 0x4D, 0x1B, 0x41, 0x1B, 0x52, 0x1B,
+  0x54, 0x1B, 0x44, 0x1B, 0x52, 0x1B, 0x56, 0x1B, 0x2E, 0x1B, 0x45, 0x1B,
+  0x58, 0x1B, 0x45, 0x1B, 0x20, 0x1B, 0x69, 0x1B, 0x6E, 0x1B, 0x20, 0x1B,
+  0x79, 0x1B, 0x6F, 0x1B, 0x75, 0x1B, 0x72, 0x1B, 0x20, 0x1B, 0x41, 0x1B,
+  0x55, 0x1B, 0x54, 0x1B, 0x4F, 0x1B, 0x45, 0x1B, 0x58, 0x1B, 0x45, 0x1B,
+  0x43, 0x1B, 0x2E, 0x1B, 0x42, 0x1B, 0x41, 0x1B, 0x54, 0x1B, 0x20, 0x1B,
+  0x66, 0x1B, 0x69, 0x1B, 0x6C, 0x1B, 0x65, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0xBA, 0x1B, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x07, 0x1B, 0x20, 0x1B, 0x64, 0x1B, 0x6F, 0x1B,
+  0x20, 0x1B, 0x6E, 0x1B, 0x6F, 0x1B, 0x74, 0x1B, 0x20, 0x1B, 0x62, 0x1B,
+  0x6F, 0x1B, 0x6F, 0x1B, 0x74, 0x1B, 0x20, 0x1B, 0x77, 0x1B, 0x69, 0x1B,
+  0x74, 0x1B, 0x68, 0x1B, 0x20, 0x1B, 0x61, 0x1B, 0x20, 0x1B, 0x6D, 0x1B,
+  0x65, 0x1B, 0x6D, 0x1B, 0x6F, 0x1B, 0x72, 0x1B, 0x79, 0x1B, 0x20, 0x1B,
+  0x6D, 0x1B, 0x61, 0x1B, 0x6E, 0x1B, 0x61, 0x1B, 0x67, 0x1B, 0x65, 0x1B,
+  0x72, 0x1B, 0x20, 0x1B, 0x28, 0x1B, 0x6C, 0x1B, 0x69, 0x1B, 0x6B, 0x1B,
+  0x65, 0x1B, 0x20, 0x1B, 0x45, 0x1B, 0x4D, 0x1B, 0x4D, 0x1B, 0x33, 0x1B,
+  0x38, 0x1B, 0x36, 0x1B, 0x29, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x07, 0x1B, 0x20, 0x1B,
+  0x64, 0x1B, 0x6F, 0x1B, 0x20, 0x1B, 0x6E, 0x1B, 0x6F, 0x1B, 0x74, 0x1B,
+  0x20, 0x1B, 0x6C, 0x1B, 0x6F, 0x1B, 0x61, 0x1B, 0x64, 0x1B, 0x20, 0x1B,
+  0x61, 0x1B, 0x6E, 0x1B, 0x79, 0x1B, 0x20, 0x1B, 0x64, 0x1B, 0x69, 0x1B,
+  0x73, 0x1B, 0x6B, 0x1B, 0x20, 0x1B, 0x63, 0x1B, 0x6F, 0x1B, 0x6D, 0x1B,
+  0x70, 0x1B, 0x72, 0x1B, 0x65, 0x1B, 0x73, 0x1B, 0x73, 0x1B, 0x69, 0x1B,
+  0x6F, 0x1B, 0x6E, 0x1B, 0x20, 0x1B, 0x64, 0x1B, 0x72, 0x1B, 0x69, 0x1B,
+  0x76, 0x1B, 0x65, 0x1B, 0x72, 0x1B, 0x73, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xBA, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x07, 0x1B, 0x20, 0x1B, 0x72, 0x1B, 0x75, 0x1B, 0x6E, 0x1B, 0x20, 0x1B,
+  0x52, 0x1B, 0x4F, 0x1B, 0x54, 0x1B, 0x54, 0x1B, 0x48, 0x1B, 0x45, 0x1B,
+  0x4C, 0x1B, 0x50, 0x1B, 0x2E, 0x1B, 0x45, 0x1B, 0x58, 0x1B, 0x45, 0x1B,
+  0x20, 0x1B, 0x66, 0x1B, 0x6F, 0x1B, 0x72, 0x1B, 0x20, 0x1B, 0x69, 0x1B,
+  0x6E, 0x1B, 0x66, 0x1B, 0x6F, 0x1B, 0x72, 0x1B, 0x6D, 0x1B, 0x61, 0x1B,
+  0x74, 0x1B, 0x69, 0x1B, 0x6F, 0x1B, 0x6E, 0x1B, 0x20, 0x1B, 0x6F, 0x1B,
+  0x6E, 0x1B, 0x20, 0x1B, 0x68, 0x1B, 0x6F, 0x1B, 0x77, 0x1B, 0x20, 0x1B,
+  0x74, 0x1B, 0x6F, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0xBA, 0x1B, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x61, 0x1B, 0x6C, 0x1B,
+  0x6C, 0x1B, 0x65, 0x1B, 0x76, 0x1B, 0x69, 0x1B, 0x61, 0x1B, 0x74, 0x1B,
+  0x65, 0x1B, 0x20, 0x1B, 0x74, 0x1B, 0x68, 0x1B, 0x69, 0x1B, 0x73, 0x1B,
+  0x20, 0x1B, 0x70, 0x1B, 0x72, 0x1B, 0x6F, 0x1B, 0x62, 0x1B, 0x6C, 0x1B,
+  0x65, 0x1B, 0x6D, 0x1B, 0x20, 0x1B, 0x28, 0x1B, 0x73, 0x1B, 0x65, 0x1B,
+  0x61, 0x1B, 0x72, 0x1B, 0x63, 0x1B, 0x68, 0x1B, 0x20, 0x1B, 0x66, 0x1B,
+  0x6F, 0x1B, 0x72, 0x1B, 0x20, 0x1B, 0x22, 0x1B, 0x4D, 0x1B, 0x65, 0x1B,
+  0x6D, 0x1B, 0x6F, 0x1B, 0x72, 0x1B, 0x79, 0x1B, 0x20, 0x1B, 0x50, 0x1B,
+  0x72, 0x1B, 0x6F, 0x1B, 0x62, 0x1B, 0x6C, 0x1B, 0x65, 0x1B, 0x6D, 0x1B,
+  0x73, 0x1B, 0x22, 0x1B, 0x29, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xBA, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x54, 0x1B, 0x68, 0x1B, 0x61, 0x1B,
+  0x74, 0x1B, 0x27, 0x1B, 0x73, 0x1B, 0x20, 0x1B, 0x61, 0x1B, 0x62, 0x1B,
+  0x6F, 0x1B, 0x75, 0x1B, 0x74, 0x1B, 0x20, 0x1B, 0x61, 0x1B, 0x6C, 0x1B,
+  0x6C, 0x1B, 0x20, 0x1B, 0x77, 0x1B, 0x65, 0x1B, 0x20, 0x1B, 0x63, 0x1B,
+  0x61, 0x1B, 0x6E, 0x1B, 0x20, 0x1B, 0x66, 0x1B, 0x69, 0x1B, 0x74, 0x1B,
+  0x20, 0x1B, 0x69, 0x1B, 0x6E, 0x1B, 0x20, 0x1B, 0x74, 0x1B, 0x68, 0x1B,
+  0x69, 0x1B, 0x73, 0x1B, 0x20, 0x1B, 0x73, 0x1B, 0x71, 0x1B, 0x75, 0x1B,
+  0x61, 0x1B, 0x72, 0x1B, 0x65, 0x1B, 0x2E, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x54, 0x1B, 0x72, 0x1B, 0x79, 0x1B, 0x20, 0x1B, 0x52, 0x1B, 0x4F, 0x1B,
+  0x54, 0x1B, 0x54, 0x1B, 0x48, 0x1B, 0x45, 0x1B, 0x4C, 0x1B, 0x50, 0x1B,
+  0x21, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0xBA, 0x1B, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xBA, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B, 0x20, 0x1B,
+  0xBA, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC8, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B, 0xCD, 0x1B,
+  0xCD, 0x1B, 0xCD, 0x1B, 0xBC, 0x1B, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04, 0xC4, 0x04,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07, 0x20, 0x07,
+  0x20, 0x07, 0x20, 0x07
+};

Added: tags/rott-1.1/rott/rt_error.c
===================================================================
--- tags/rott-1.1/rott/rt_error.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_error.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,414 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include <dos.h>
+#include <errno.h>
+#include <io.h>
+#include <stdio.h>
+#include <conio.h>
+#include <stdarg.h>
+#include <mem.h>
+#include <ctype.h>
+#include "rt_def.h"
+#include "rt_str.h"
+#include "rt_error.h"
+#include "rt_menu.h"
+#include "isr.h"
+#include "w_wad.h"
+#include "z_zone.h"
+#include "rt_vid.h"
+#include "rt_util.h"
+#include "modexlib.h"
+//MED
+#include "memcheck.h"
+
+
+//*****************************************************************************
+//
+//                          HARD ERROR ROUTINES
+//
+//****************************************************************************
+
+#define WINDOWUX           7
+#define WINDOWUY           76
+#define WINDOWLX           138
+#define WINDOWLY           158
+
+#define MESSAGEBOXCOLOR    166
+
+
+#define DISKERROR          0x4000         // bit 15 (of deverr)
+#define IGNOREAVAILABLE    0x1000         // bit 13   (bit 14 isn't used)
+#define RETRYAVAILABLE     0x800          // bit 12
+#define FAILAVAILABLE      0x400          // bit 11
+#define LOCATION           0x300          // bit 10 and 9
+#define READWRITEERROR     0x80           // bit 8
+#define DRIVEOFERROR       0x0F           // low-order byte
+
+#define DIVISIONINT                0x00
+
+// Globals
+
+boolean DivisionError = false;
+
+// Statics
+
+
+static char ErrorCodes[13][25] =
+{
+   "Write-protected disk\0",
+   "Unknown unit\0",
+   "Drive not ready\0",
+   "Unknown command\0",
+   "CRC error in data\0",
+   "Bad drive struct length\0",
+   "Seek error\0",
+   "Unknown media type\0",
+   "Sector not found\0",
+   "Printer out of paper\0",
+   "Write fault\0",
+   "Read fault\0",
+   "General failure\0"
+};
+
+static char Drives[7][3] =
+{
+   "A\0",
+   "B\0",
+   "C\0",
+   "D\0",
+   "E\0",
+   "F\0",
+   "G\0"
+};
+
+static char Locations[4][11] =
+{
+   "MS-DOS\0",
+   "FAT\0",
+   "Directory\0",
+   "Data area\0"
+};
+
+static char ReadWrite[2][6] =
+{
+   "Read\0",
+   "Write\0"
+};
+
+static boolean ErrorHandlerStarted=false;
+void (__interrupt __far *olddivisr) () = NULL;
+
+//******************************************************************************
+//
+// UL_UserMessage ()
+//
+//******************************************************************************
+
+void UL_UserMessage (int x, int y, char *str, ...) __attribute__((format(printf,3,4)))
+{
+   va_list strptr;
+   char buf[128];
+   int width, height;
+
+   memset (&buf[0], 0, sizeof (buf));
+   va_start (strptr, str);
+   vsprintf (&buf[0], str, strptr);
+   va_end (strptr);
+
+	if ( *(byte *)0x449 == 0x13)
+      {
+      CurrentFont = tinyfont;
+
+      WindowW=160;
+      WindowH=100;
+      WindowX=80;
+      WindowY=50;
+
+      US_MeasureStr (&width, &height, &buf[0]);
+
+      width  += (CurrentFont->width[1] << 1);
+      height += (CurrentFont->height << 1);
+
+      VL_Bar (x, y, WindowW-2, WindowH, MESSAGEBOXCOLOR);
+
+      PrintX = x+CurrentFont->width[1];
+      PrintY = y+CurrentFont->height;
+
+      US_CPrint (&buf[0]);
+
+      displayofs=bufferofs;
+
+      OUTP(CRTC_INDEX, CRTC_STARTHIGH);
+      OUTP(CRTC_DATA,((displayofs&0x0000ffff)>>8));
+
+
+      bufferofs += screensize;
+      if (bufferofs > page3start)
+         bufferofs = page1start;
+      }
+   else
+      printf("%s\n",&buf[0]);
+}
+
+//****************************************************************************
+//
+// UL_GeneralError ()
+//
+//****************************************************************************
+
+int UL_GeneralError (int code)
+{
+   boolean done = false;
+   int retval = 0;
+
+   UL_UserMessage (80, 50, "Device Error!\n%s.\n \n(A)bort  (R)etry\n",
+                   ErrorCodes[code]);
+
+   if (KeyboardStarted==true)
+      {
+      while (!done)
+      {
+         if (Keyboard[sc_A])
+         {
+            retval = 1;
+            done = true;
+
+            while (Keyboard[sc_A])
+               ;
+         }
+         else
+            if (Keyboard[sc_R])
+            {
+               retval = 0;
+               done = true;
+
+               while (Keyboard[sc_R])
+                  ;
+            }
+      }
+      }
+   else
+      {
+      while (!done)
+      {
+         if (kbhit())
+         {
+            char ch;
+
+            ch=toupper(getch());
+            if (ch=='A')
+               {
+               retval = 1;
+               done = true;
+               }
+            else if (ch=='R')
+               {
+               retval = 0;
+               done = true;
+               }
+         }
+      }
+      }
+
+
+   return (retval);
+}
+
+
+//****************************************************************************
+//
+// UL_DriveError ()
+//
+//****************************************************************************
+
+int UL_DriveError (int code, int location, int rwerror, int whichdrive)
+{
+   boolean done = false;
+   int retval   = 0;
+
+   UL_UserMessage (80, 50,
+                  "Drive Error!\n%s.\nOn drive %s.\nLocation: %s.\n%s error.\n(A)bort  (R)etry\n",
+                    ErrorCodes[code], Drives[whichdrive],
+                    Locations[location], ReadWrite[rwerror]);
+
+   if (KeyboardStarted==true)
+      {
+      while (!done)
+      {
+         if (Keyboard[sc_A])
+         {
+            retval = 1;
+            done = true;
+
+            while (Keyboard[sc_A])
+               ;
+         }
+         else
+            if (Keyboard[sc_R])
+            {
+               retval = 0;
+               done = true;
+
+               while (Keyboard[sc_R])
+                  ;
+            }
+      }
+      }
+   else
+      {
+      while (!done)
+      {
+         if (kbhit())
+         {
+            char ch;
+
+            ch=toupper(getch());
+            if (ch=='A')
+               {
+               retval = 1;
+               done = true;
+               }
+            else if (ch=='R')
+               {
+               retval = 0;
+               done = true;
+               }
+         }
+      }
+      }
+
+   return (retval);
+}
+
+
+//****************************************************************************
+//
+//	UL_harderr ()
+//
+//****************************************************************************
+
+int __far UL_harderr (unsigned deverr, unsigned errcode, unsigned far *devhdr)
+{
+   int DiskError      = 0;    // Indicates if it was a disk error
+   int IgnoreAvail    = 0;    // if "ignore" response is available
+   int RetryAvail     = 0;    // if "retry" response is available
+   int FailAvail      = 0;    // if "fail" response is available
+   byte ErrorLocation = 0;    // Location of error
+   byte RWerror       = 0;    // Read/Write error (0 == read, 1 == write)
+   byte whichDrive    = 0;    // Drive the error is on (0 == A, 1 == B, ...)
+   int action;
+
+   unsigned temp;
+   temp = *devhdr;
+
+  // Check errors
+   DiskError     = (deverr & DISKERROR);
+   IgnoreAvail   = (deverr & IGNOREAVAILABLE);
+   RetryAvail    = (deverr & RETRYAVAILABLE);
+   FailAvail     = (deverr & FAILAVAILABLE);
+   ErrorLocation = ((deverr & LOCATION) >> 8);
+   RWerror       = (deverr & READWRITEERROR);
+
+   if (DiskError == 0)
+      action = UL_GeneralError (errcode);
+   else
+      action = UL_DriveError (errcode, ErrorLocation, RWerror, whichDrive);
+
+   if (action)
+      Error ("USER BREAK : ROTT aborted.\n");
+   return (_HARDERR_RETRY);
+}
+
+
+//****************************************************************************
+//
+//	UL_DivisionISR ()
+//
+//****************************************************************************
+
+extern byte * colormap;
+
+void __interrupt __far UL_DivisionISR ( void )
+{
+// acknowledge the interrupt
+
+   SetBorderColor (*(colormap+(((100-10)>>2)<<8)+160));
+   DivisionError = true;
+   OUTP (0x20, 0x20);
+}
+
+
+//****************************************************************************
+//
+//	UL_ErrorStartup ()
+//
+//****************************************************************************
+
+void UL_ErrorStartup ( void )
+{
+   if (ErrorHandlerStarted==true)
+      return;
+   ErrorHandlerStarted=true;
+   _harderr (UL_harderr);     // Install hard error handler
+   UL_StartupDivisionByZero();
+}
+
+//****************************************************************************
+//
+//	UL_ErrorShutdown ()
+//
+//****************************************************************************
+
+void UL_ErrorShutdown ( void )
+{
+   if (ErrorHandlerStarted==false)
+      return;
+   ErrorHandlerStarted=false;
+   UL_ShutdownDivisionByZero();
+}
+
+
+/*
+===============
+=
+= UL_StartupDivisionByZero
+=
+===============
+*/
+
+void UL_StartupDivisionByZero ( void )
+{
+	olddivisr = _dos_getvect(DIVISIONINT);
+	_dos_setvect (DIVISIONINT, UL_DivisionISR);
+}
+
+/*
+===============
+=
+= UL_ShutdownDivisionByZero
+=
+===============
+*/
+
+void UL_ShutdownDivisionByZero ( void )
+{
+	_dos_setvect (DIVISIONINT, olddivisr);
+}
+

Added: tags/rott-1.1/rott/rt_error.h
===================================================================
--- tags/rott-1.1/rott/rt_error.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_error.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,28 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_error_public
+#define _rt_error_public
+
+extern boolean DivisionError;
+
+void UL_ErrorStartup ( void );
+void UL_ErrorShutdown ( void );
+
+#endif

Added: tags/rott-1.1/rott/rt_fc_a.asm
===================================================================
--- tags/rott-1.1/rott/rt_fc_a.asm	                        (rev 0)
+++ tags/rott-1.1/rott/rt_fc_a.asm	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,462 @@
+; rt_fc_a.ASM
+
+.386P
+.MODEL	flat
+
+SCREENROW = 96
+
+;============================================================================
+
+.DATA
+loopcount       dd      0
+pixelcount      dd      0
+
+EXTRN	_mr_rowofs:DWORD
+EXTRN	_mr_count:DWORD
+EXTRN	_mr_xstep:DWORD
+EXTRN	_mr_ystep:DWORD
+EXTRN	_mr_xfrac:DWORD
+EXTRN	_mr_yfrac:DWORD
+EXTRN	_mr_dest:DWORD
+EXTRN   _shadingtable:DWORD
+
+
+;============================================================================
+
+.CODE
+SEGMENT text USE32
+        ALIGN   16
+
+;============================
+;
+; DrawRow
+;
+;============================
+
+IDEAL
+        ALIGN   16
+PROC	DrawRow_
+PUBLIC	DrawRow_
+
+        push    ebp
+        mov     [pixelcount],ecx                                ; save for final pixel
+        shr     ecx,1                                           ; double pixel count
+        mov     [loopcount],ecx
+;        mov     esi,[_mr_src]
+	mov	ebx,[_mr_ystep]
+        shl     ebx,16
+	mov	eax,[_mr_xstep]
+        mov     bx,ax
+        mov     eax,OFFSET hpatch1+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET hpatch2+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+	mov	ebp,[_mr_yfrac]
+	shl	ebp,16
+	mov	eax,[_mr_xfrac]
+	mov	bp,ax
+;        mov     eax,[_shadingtable]
+
+; eax           aligned colormap
+; ebx           aligned colormap
+; ecx,edx       scratch
+; esi           virtual source
+; edi           moving destination pointer
+; ebp           frac
+
+        shld    ecx,ebp,23                         ; begin calculating third pixel (y units)
+        shld    ecx,ebp,7                          ; begin calculating third pixel (x units)
+        add     ebp,ebx                                 ; advance frac pointer
+        and     ecx,16383                            ; finish calculation for third pixel
+        shld    edx,ebp,23                         ; begin calculating fourth pixel (y units)
+        shld    edx,ebp,7                          ; begin calculating fourth pixel (x units)
+        add     ebp,ebx                                 ; advance frac pointer
+        and     edx,16383                            ; finish calculation for fourth pixel
+        mov     eax,[_shadingtable]
+        mov     ebx,eax
+        mov     al,[esi+ecx]                    ; get first pixel
+        mov     bl,[esi+edx]                    ; get second pixel
+        mov     al,[eax]                                ; color translate first pixel
+        mov     bl,[ebx]                                ; color translate second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     hdoubleloop                             ; at least two pixels to map
+        jmp     hchecklast
+
+
+        ALIGN   16
+hdoubleloop:
+        shld    ecx,ebp,23                         ; begin calculating third pixel (y units)
+        shld    ecx,ebp,7                          ; begin calculating third pixel (x units)
+hpatch1:
+        add     ebp,12345678h                      ; advance frac pointer
+        mov     [edi],al                           ; write first pixel
+        and     ecx,16383                          ; finish calculation for third pixel
+        shld    edx,ebp,23                         ; begin calculating fourth pixel (y units)
+        shld    edx,ebp,7                          ; begin calculating fourth pixel (x units)
+hpatch2:
+        add     ebp,12345678h                      ; advance frac pointer
+        mov     [edi+1],bl                         ; write second pixel
+        and     edx,16383                          ; finish calculation for fourth pixel
+        mov     al,[esi+ecx]                       ; get third pixel
+        add     edi,2                              ; advance to third pixel destination
+        mov     bl,[esi+edx]                       ; get fourth pixel
+        dec     [loopcount]                        ; done with loop?
+        mov     al,[eax]                           ; color translate third pixel
+        mov     bl,[ebx]                           ; color translate fourth pixel
+        jnz     hdoubleloop
+
+; check for final pixel
+hchecklast:
+        test    [pixelcount],1
+        jz      hdone
+        mov     [edi],al                                ; write final pixel
+
+hdone:
+        pop     ebp
+        ret
+
+ENDP
+
+
+
+
+
+
+
+
+;============================
+;
+; DrawRotRow
+;
+;============================
+
+IDEAL
+        ALIGN   16
+PROC	DrawRotRow_
+PUBLIC	DrawRotRow_
+
+        push    ebp
+        mov     [pixelcount],ecx                                ; save for final pixel
+        shr     ecx,1                                           ; double pixel count
+        mov     [loopcount],ecx
+	mov	ebx,[_mr_xstep]
+        mov     edx,OFFSET hrpatch1+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET hrpatch1a+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET hrpatch1b+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET hrpatch1c+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+	mov	ebx,[_mr_ystep]
+        mov     edx,OFFSET hrpatch2+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET hrpatch2a+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET hrpatch2b+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET hrpatch2c+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+	mov	ecx,[_mr_yfrac]
+	mov	edx,[_mr_xfrac]
+
+        mov     eax,edx                 ; Move yfrac into y
+        mov     ebp,ecx                 ; Move xfrac into x
+        shr     eax,16                  ; shift yfrac off
+hrpatch1:
+        add     edx,012345678h          ; increment y fraction
+hrpatch2:
+        add     ecx,012345678h          ; increment x fraction
+        cmp     eax,255                 ; test bounds of y fraction
+        ja      nok3
+        shr     ebp,16                  ; shift xfrac off
+        cmp     ebp,511                 ; test bounds of x fraction
+        ja      nok3
+        shl     ebp,23                  ;
+        shld    eax,ebp,9               ; form composite offset
+ok3:
+        mov     bl,[esi+eax]            ; get first pixel
+        mov     eax,edx                 ; Move yfrac into y
+        mov     ebp,ecx                 ; Move xfrac into x
+        shr     eax,16                  ; shift yfrac off
+hrpatch1a:
+        add     edx,012345678h          ; increment y fraction
+hrpatch2a:
+        add     ecx,012345678h          ; increment x fraction
+        cmp     eax,255                 ; test bounds of y fraction
+        ja      nok4
+        shr     ebp,16                  ; shift xfrac off
+        cmp     ebp,511                 ; test bounds of x fraction
+        ja      nok4
+        shl     ebp,23                  ;
+        shld    eax,ebp,9               ; form composite offset
+ok4:
+        mov     bh,[esi+eax]            ; get second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     hrdoubleloop                       ; at least two pixels to map
+        jmp     hrchecklast
+nok3:
+        xor  eax,eax
+        jmp  ok3
+nok4:
+        xor  eax,eax
+        jmp  ok4
+
+        ALIGN   16
+hrdoubleloop:
+        mov     eax,edx                 ; Move yfrac into y
+        mov     ebp,ecx                 ; Move xfrac into x
+        shr     eax,16                  ; shift yfrac off
+hrpatch1b:
+        add     edx,012345678h          ; increment y fraction
+hrpatch2b:
+        add     ecx,012345678h          ; increment x fraction
+        cmp     eax,255                 ; test bounds of y fraction
+        ja      nok1
+        shr     ebp,16                  ; shift xfrac off
+        cmp     ebp,511                 ; test bounds of x fraction
+        ja      nok1
+        shl     ebp,23                  ;
+        shld    eax,ebp,9               ; form composite offset
+ok1:
+        mov     [edi],bl                ; write first pixel
+        mov     ebp,ecx                 ; Move xfrac into x
+        mov     bl,[esi+eax]            ; get third pixel
+
+        mov     eax,edx                 ; Move yfrac into y
+        shr     eax,16                  ; shift yfrac off
+hrpatch1c:
+        add     edx,012345678h          ; increment y fraction
+hrpatch2c:
+        add     ecx,012345678h          ; increment x fraction
+        cmp     eax,255                 ; test bounds of y fraction
+        ja      nok2
+        shr     ebp,16                  ; shift xfrac off
+        cmp     ebp,511                 ; test bounds of x fraction
+        ja      nok2
+        shl     ebp,23                  ;
+        shld    eax,ebp,9               ; form composite offset
+ok2:
+        mov     [edi+1],bh                ; write second pixel
+        add     edi,2
+        dec     [loopcount]                     ; done with loop?
+        mov     bh,[esi+eax]            ; get second pixel
+        jnz     hrdoubleloop
+; check for final pixel
+hrchecklast:
+        test    [pixelcount],1
+        jz      hrdone
+        mov     [edi],bl                                ; write final pixel
+
+hrdone:
+        pop     ebp
+        ret
+
+nok1:
+        xor  eax,eax
+        jmp  ok1
+nok2:
+        xor  eax,eax
+        jmp  ok2
+
+
+ENDP
+
+
+
+;============================
+;
+; DrawMaskedRotRow
+;
+;============================
+
+IDEAL
+        ALIGN   16
+PROC  DrawMaskedRotRow_
+PUBLIC   DrawMaskedRotRow_
+
+        push    ebp
+        mov     [pixelcount],ecx                                ; save for final pixel
+        shr     ecx,1                                           ; double pixel count
+        mov     [loopcount],ecx
+	mov	ebx,[_mr_xstep]
+        mov     edx,OFFSET mhrpatch1+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET mhrpatch1a+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET mhrpatch1b+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET mhrpatch1c+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+	mov	ebx,[_mr_ystep]
+        mov     edx,OFFSET mhrpatch2+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET mhrpatch2a+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET mhrpatch2b+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+        mov     edx,OFFSET mhrpatch2c+2            ; convice tasm to modify code...
+        mov     [edx],ebx
+	mov	ecx,[_mr_yfrac]
+	mov	edx,[_mr_xfrac]
+
+        mov     eax,edx                 ; Move yfrac into y
+        mov     ebp,ecx                 ; Move xfrac into x
+        shr     eax,16                  ; shift yfrac off
+mhrpatch1:
+        add     edx,012345678h          ; increment y fraction
+mhrpatch2:
+        add     ecx,012345678h          ; increment x fraction
+        cmp     eax,255                 ; test bounds of y fraction
+        ja      mnok3
+        shr     ebp,16                  ; shift xfrac off
+        cmp     ebp,511                 ; test bounds of x fraction
+        ja      mnok3
+        shl     ebp,23                  ;
+        shld    eax,ebp,9               ; form composite offset
+mok3:
+        mov     bl,[esi+eax]            ; get first pixel
+        mov     eax,edx                 ; Move yfrac into y
+        mov     ebp,ecx                 ; Move xfrac into x
+        shr     eax,16                  ; shift yfrac off
+mhrpatch1a:
+        add     edx,012345678h          ; increment y fraction
+mhrpatch2a:
+        add     ecx,012345678h          ; increment x fraction
+        cmp     eax,255                 ; test bounds of y fraction
+        ja      mnok4
+        shr     ebp,16                  ; shift xfrac off
+        cmp     ebp,511                 ; test bounds of x fraction
+        ja      mnok4
+        shl     ebp,23                  ;
+        shld    eax,ebp,9               ; form composite offset
+mok4:
+        mov     bh,[esi+eax]            ; get second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     mhrdoubleloop                       ; at least two pixels to map
+        jmp     mhrchecklast
+mnok3:
+        xor  eax,eax
+        jmp  mok3
+mnok4:
+        xor  eax,eax
+        jmp  mok4
+
+        ALIGN   16
+mhrdoubleloop:
+        mov     eax,edx                 ; Move yfrac into y
+        mov     ebp,ecx                 ; Move xfrac into x
+        shr     eax,16                  ; shift yfrac off
+mhrpatch1b:
+        add     edx,012345678h          ; increment y fraction
+mhrpatch2b:
+        add     ecx,012345678h          ; increment x fraction
+        cmp     eax,255                 ; test bounds of y fraction
+        ja      mnok1
+        shr     ebp,16                  ; shift xfrac off
+        cmp     ebp,511                 ; test bounds of x fraction
+        ja      mnok1
+        shl     ebp,23                  ;
+        shld    eax,ebp,9               ; form composite offset
+mok1:
+        cmp     bl,0ffh
+        je      skip1
+        mov     [edi],bl                ; write first pixel
+skip1:
+        mov     ebp,ecx                 ; Move xfrac into x
+        mov     bl,[esi+eax]            ; get third pixel
+
+        mov     eax,edx                 ; Move yfrac into y
+        shr     eax,16                  ; shift yfrac off
+mhrpatch1c:
+        add     edx,012345678h          ; increment y fraction
+mhrpatch2c:
+        add     ecx,012345678h          ; increment x fraction
+        cmp     eax,255                 ; test bounds of y fraction
+        ja      mnok2
+        shr     ebp,16                  ; shift xfrac off
+        cmp     ebp,511                 ; test bounds of x fraction
+        ja      mnok2
+        shl     ebp,23                  ;
+        shld    eax,ebp,9               ; form composite offset
+mok2:
+        cmp     bh,0ffh
+        je      skip2
+        mov     [edi+1],bh                ; write second pixel
+skip2:
+        add     edi,2
+        dec     [loopcount]                     ; done with loop?
+        mov     bh,[esi+eax]            ; get second pixel
+        jnz     mhrdoubleloop
+; check for final pixel
+mhrchecklast:
+        test    [pixelcount],1
+        jz      mhrdone
+        mov     [edi],bl                                ; write final pixel
+
+mhrdone:
+        pop     ebp
+        ret
+
+mnok1:
+        xor  eax,eax
+        jmp  mok1
+mnok2:
+        xor  eax,eax
+        jmp  mok2
+
+
+ENDP
+
+
+;============================
+;
+; DrawSkyPost
+;
+;
+;============================
+
+IDEAL
+PROC	DrawSkyPost_
+PUBLIC	DrawSkyPost_
+
+;EDI - Destination for post
+;ESI - Source data
+;ECX - Length of post
+
+        mov     ebx,ecx
+        mov     edx,[_shadingtable]
+        shr     ebx,1
+        jz      dsextra
+dsloop:
+        mov     ax,[esi]
+        mov     dl,al
+        mov     al,[edx]                                ; color translate third pixel
+        mov     [edi],al
+        add     esi,2
+        mov     dl,ah
+        add     edi,SCREENROW*2
+        mov     al,[edx]                                ; color translate third pixel
+        mov     [edi-SCREENROW],al
+        dec     ebx
+        jnz     dsloop
+        MASKFLAG ecx,1
+        jz      done
+dsextra:
+        mov     al,[esi]
+        mov     dl,al
+        mov     al,[edx]                                ; color translate third pixel
+        mov     [edi],al
+done:
+	ret
+
+ENDP
+
+
+ENDS
+
+END
+

Added: tags/rott-1.1/rott/rt_fc_a.h
===================================================================
--- tags/rott-1.1/rott/rt_fc_a.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_fc_a.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,42 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_fc_a_public
+#define _rt_fc_a_public
+
+//***************************************************************************
+//
+//    RT_FC_A.ASM - Maprow stuff for floor and ceiling
+//
+//***************************************************************************
+
+void DrawSkyPost (byte * buf, byte * src, int height);
+void DrawRow(int count, byte * dest, byte * src);
+void DrawRotRow(int count, byte * dest, byte * src);
+void DrawMaskedRotRow(int count, byte * dest, byte * src);
+
+#if (defined __WATCOMC__)
+#pragma aux DrawSkyPost parm [EDI] [ESI] [ECX] modify exact [eax ecx edx edi esi ebx]
+#pragma aux DrawRow parm [ECX] [EDI] [ESI] modify exact [eax ebx ecx edx esi edi]
+#pragma aux DrawRotRow parm [ECX] [EDI] [ESI] modify exact [eax ebx ecx edx esi edi]
+#pragma aux DrawMaskedRotRow parm [ECX] [EDI] [ESI] modify exact [eax ebx ecx edx esi edi]
+#endif
+
+#endif
+

Added: tags/rott-1.1/rott/rt_floor.c
===================================================================
--- tags/rott-1.1/rott/rt_floor.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_floor.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,748 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// RT_FLOOR.C
+
+#ifdef DOS
+#include <conio.h>
+#endif
+
+#include "rt_def.h"
+#include "watcom.h"
+#include "rt_floor.h"
+#include "rt_fc_a.h"
+#include "_rt_floo.h"
+#include "rt_draw.h"
+#include "rt_util.h"
+#include "engine.h"
+#include "rt_main.h"
+#include "w_wad.h"
+#include "z_zone.h"
+#include "rt_view.h"
+#include "rt_ted.h"
+#include "rt_cfg.h"
+#include "rt_actor.h"
+#include <string.h>
+#include "isr.h"
+#include "modexlib.h"
+#include "rt_playr.h"
+#include "rt_sound.h"
+#include "rt_rand.h"
+//MED
+#include "memcheck.h"
+
+/*
+=============================================================================
+
+Global Variables                                                                                                                                 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+int      sky;
+int		mr_rowofs;
+int		mr_count;
+int		mr_xstep;
+int		mr_ystep;
+int		mr_xfrac;
+int		mr_yfrac;
+byte *   mr_dest;
+byte *   mr_src;
+
+/*
+==================
+=
+= Local Variables
+=
+==================
+*/
+
+static byte     *floor;
+static byte     *ceiling;
+//static int xstarts[MAXVIEWHEIGHT];
+static int xstarts[600];//set to max hight res
+static byte * skysegs[MAXSKYSEGS];
+static byte * skydata[MAXSKYDATA];
+static int      horizonheight;
+static int      centerskypost;
+static int      oldsky=-1;
+
+
+//bna fixit skyerror by 800x600 clouds not big enough
+
+void DrawSky( void )
+{
+
+   byte * src;
+   int dest;
+//   int plane;
+   int height;
+//   int height2;
+   int ang;
+   int angle;
+   int ofs;
+
+   angle=viewangle;
+
+   if ((fog==0) && (lightning==true))
+      shadingtable=colormap+((basemaxshade-6-lightninglevel)<<8);
+   else
+      shadingtable=colormap+(1<<12);
+
+   ofs=(((maxheight)-(player->z))>>3)+(centery-(viewheight>>1));
+   if (ofs>centerskypost)
+      {
+      ofs=centerskypost;
+      }
+   else if (((centerskypost-ofs)+viewheight)>1799)
+      {
+      ofs=-(1799-(centerskypost+viewheight));
+      }
+//ofs=centerskypost;
+#ifdef DOS
+   if (doublestep>0)
+      {
+#ifdef DOS
+      for (plane=0;plane<4;plane+=2)
+#endif
+         {
+#ifdef DOS
+         VGAMAPMASK((1<<plane)+(1<<(plane+1)));
+         for (dest=plane;dest<viewwidth;dest+=4)
+#else
+         for (dest=0;dest<viewwidth;dest+=2)
+#endif
+            {
+            height=posts[dest].ceilingclip;
+            height2=posts[dest+1].ceilingclip;
+            if (height<height2)
+               height=height2;
+            if (height<=0)
+               continue;
+            ang=(angle+pixelangle[dest])&(FINEANGLES-1);
+            src=skysegs[ang]-ofs;
+#ifdef DOS
+            DrawSkyPost((byte *)bufferofs + (dest>>2),src,height);
+#else
+	/* TODO: this isn't right since it's not really optimized */
+            DrawSkyPost((byte *)bufferofs + dest,src,height);
+            DrawSkyPost((byte *)bufferofs + dest + 1,src,height);
+#endif
+            }
+         }
+      }
+   else
+#endif
+      {
+#ifdef DOS
+      for (plane=0;plane<4;plane++)
+#endif
+         {
+#ifdef DOS
+         VGAWRITEMAP(plane);
+         for (dest=plane;dest<viewwidth;dest+=4)
+#else
+         for (dest=0;dest<viewwidth;dest++)
+#endif
+            {
+            if ((height=posts[dest].ceilingclip)<=0)
+               continue;
+            ang=(angle+pixelangle[dest])&(FINEANGLES-1);
+            src=skysegs[ang]-ofs;
+#ifdef DOS
+            DrawSkyPost((byte *)bufferofs + (dest>>2),src,height);
+#else
+            DrawSkyPost((byte *)bufferofs + dest,src,height);
+#endif
+            }
+         }
+      }
+}
+
+/*
+===================
+=
+= DrawFullSky
+=
+===================
+*/
+void DrawFullSky( void )
+{
+
+   byte * src;
+   int dest;
+   int plane;
+   int ang;
+   int angle;
+   int ofs;
+
+   angle=viewangle;
+
+   if ((fog==0) && (lightning==true))
+      shadingtable=colormap+((basemaxshade-5-lightninglevel)<<8);
+   else
+      shadingtable=colormap+(1<<12);
+
+   ofs=(((maxheight)-(player->z))>>3)+(centery-(viewheight>>1));
+   if (ofs>centerskypost)
+      {
+      ofs=centerskypost;
+      }
+   else if (((centerskypost-ofs)+viewheight)>599)
+      {
+      ofs=-(599-(centerskypost+viewheight));
+      }
+
+   bufferofs+=screenofs;
+
+#ifdef DOS
+   for (plane=0;plane<4;plane++)
+#endif
+      {
+#ifdef DOS
+      VGAWRITEMAP(plane);
+      for (dest=plane;dest<viewwidth;dest+=4)
+#else
+      for (dest=0;dest<viewwidth;dest++)
+#endif
+         {
+         ang=(angle+pixelangle[dest])&(FINEANGLES-1);
+         src=skysegs[ang]-ofs;
+#ifdef DOS
+         DrawSkyPost((byte *)bufferofs + (dest>>2),src,viewheight);
+#else
+         DrawSkyPost((byte *)bufferofs + dest,src,viewheight);
+#endif
+         }
+      }
+
+   bufferofs-=screenofs;
+}
+
+/*
+===================
+=
+= MakeSkyTile
+=
+===================
+*/
+void MakeSkyTile (byte * tile)
+{
+   int i,j;
+   int srcstep;
+   int src;
+
+   srcstep=200<<10;
+   for (i=0;i<64;i++)
+      {
+      src=0;
+      for (j=0;j<64;j++)
+         {
+         *(tile + (i<<6) + j)=*(skysegs[(i<<2)]+(src>>16));
+         src+=srcstep;
+         }
+      }
+}
+
+/*
+===================
+=
+= MakeSkyData
+=
+===================
+*/
+void MakeSkyData ( void )
+{
+   byte * temp;
+   byte * ptr;
+   int c;
+
+   temp=SafeMalloc(256*800);
+
+   ptr=temp;
+
+   for (c=0;c<256;c++)
+      {
+
+      memcpy(ptr,skydata[1]+(c*200),200);
+      ptr+=200;
+ 
+      memcpy(ptr,skydata[0]+(c*200),200);
+      ptr+=200;
+
+      //memcpy(ptr,skydata[1]+(c*200),200);
+      //ptr+=200;
+      //memcpy(ptr,skydata[0]+(c*200),200);
+      //ptr+=200;
+      }
+   skydata[0]=temp;
+}
+
+/*
+===================
+=
+= GetFloorCeilingLump
+=
+===================
+*/
+
+int GetFloorCeilingLump ( int num )
+{
+   int lump;
+
+   switch (num)
+      {
+      case 1:
+         lump=W_GetNumForName("FLRCL1\0");
+         break;
+      case 2:
+         lump=W_GetNumForName("FLRCL2\0");
+         break;
+      case 3:
+         lump=W_GetNumForName("FLRCL3\0");
+         break;
+      case 4:
+         lump=W_GetNumForName("FLRCL4\0");
+         break;
+      case 5:
+         lump=W_GetNumForName("FLRCL5\0");
+         break;
+      case 6:
+         lump=W_GetNumForName("FLRCL6\0");
+         break;
+      case 7:
+         lump=W_GetNumForName("FLRCL7\0");
+         break;
+      case 8:
+         lump=W_GetNumForName("FLRCL8\0");
+         break;
+      case 9:
+         lump=W_GetNumForName("FLRCL9\0");
+         break;
+      case 10:
+         lump=W_GetNumForName("FLRCL10\0");
+         break;
+      case 11:
+         lump=W_GetNumForName("FLRCL11\0");
+         break;
+      case 12:
+         lump=W_GetNumForName("FLRCL12\0");
+         break;
+      case 13:
+         lump=W_GetNumForName("FLRCL13\0");
+         break;
+      case 14:
+         lump=W_GetNumForName("FLRCL14\0");
+         break;
+      case 15:
+         lump=W_GetNumForName("FLRCL15\0");
+         break;
+      case 16:
+         lump=W_GetNumForName("FLRCL16\0");
+         break;
+      default:
+         Error("Illegal Floor/Ceiling Tile = %d\n",num);
+         break;
+      }
+   return lump;
+}
+
+/*
+===================
+=
+= SkyExists
+=
+===================
+*/
+
+boolean SkyExists (void)
+{
+   if (MAPSPOT(1,0,0) >= 234)
+      {
+      return true;
+      }
+   else
+      {
+      return false;
+      }
+
+}
+
+/*
+===================
+=
+= SetPlaneViewSize
+=
+===================
+*/
+
+void SetPlaneViewSize (void)
+{
+   int      x;
+   int      i;
+   int      s;
+   int      floornum;
+   int      ceilingnum;
+   int      skytop;
+   int      skybottom;
+
+   sky=0;
+
+   if (oldsky>0)
+      {
+      SafeFree(skydata[0]);
+      oldsky=-1;
+      }
+
+   lightning=false;
+
+	if (MAPSPOT(1,0,0) >= 234)
+    {
+    word crud;
+	 sky = (MAPSPOT(1,0,0) - 233);
+    if ((sky<1) || (sky>6))
+       Error("Illegal Sky Tile = %d\n",sky);
+    ceilingnum=1;
+	 crud=(word)MAPSPOT(1,0,1);
+	 if ((crud>=90) && (crud<=97))
+	    horizonheight=crud-89;
+    else if ((crud>=450) && (crud<=457))
+		 horizonheight=crud-450+9;
+	 else
+       Error("You must specify a valid horizon height sprite icon over the sky at (2,0) on map %d\n",gamestate.mapon);
+
+    // Check for lightnign icon
+
+	 crud=(word)MAPSPOT(4,0,1);
+	 if (crud==377)
+       lightning=true;
+    }
+	else
+	 ceilingnum = MAPSPOT(1,0,0)-197;
+
+	floornum = MAPSPOT(0,0,0)-(179);
+
+   floornum = GetFloorCeilingLump ( floornum );
+   //ceilingnum = GetFloorCeilingLump ( ceilingnum );
+
+   floor = W_CacheLumpNum(floornum,PU_LEVELSTRUCT, Cvt_patch_t, 1);
+   floor +=8;
+
+   if (sky==0)  // Don't cache in if not used
+      {
+      ceilingnum = GetFloorCeilingLump ( ceilingnum );
+      ceiling = W_CacheLumpNum(ceilingnum,PU_LEVELSTRUCT, Cvt_patch_t, 1);
+      ceiling +=8;
+      } else {
+      	ceiling = NULL;
+      }
+
+	s = W_GetNumForName("SKYSTART");
+
+   switch (sky)
+      {
+      case 1:
+         skytop=s+1;
+         skybottom=s+2;
+         break;
+      case 2:
+         skytop=s+3;
+         skybottom=s+4;
+         break;
+      case 3:
+         skytop=s+5;
+         skybottom=s+6;
+         break;
+      case 4:
+         skytop=s+7;
+         skybottom=s+8;
+         break;
+      case 5:
+         skytop=s+9;
+         skybottom=s+10;
+         break;
+      case 6:
+         skytop=s+11;
+         skybottom=s+12;
+         break;
+      }
+      if (sky!=0)
+         {
+         skydata[0]=W_CacheLumpNum(skytop,PU_STATIC, CvtNull, 1);
+         skydata[1]=W_CacheLumpNum(skybottom,PU_STATIC, CvtNull, 1);
+         centerskypost=MINSKYHEIGHT-(horizonheight*6);
+         oldsky=sky;
+         MakeSkyData();
+         W_CacheLumpNum(skytop,PU_CACHE, CvtNull, 1);
+         W_CacheLumpNum(skybottom,PU_CACHE, CvtNull, 1);
+         x=511;
+         for (i=0;i<MAXSKYSEGS;i++)
+            {
+            skysegs[i]=skydata[0]+((x>>1)*400)+centerskypost;
+            x--;
+            if (x==-1)
+               {
+               x=511;
+               }
+            } /* endfor */
+         }
+}
+
+/*
+==========================
+=
+= SetFCLightLevel
+=
+==========================
+*/
+void SetFCLightLevel (int height)
+{
+   int i;
+
+	if (MISCVARS->GASON==1)
+      {
+		shadingtable=greenmap+(MISCVARS->gasindex<<8);
+      return;
+      }
+   if (fulllight)
+      {
+      shadingtable=colormap+(1<<12);
+      return;
+      }
+   if (fog)
+      {
+      i=(height>>normalshade)+minshade;
+      if (i>maxshade) i=maxshade;
+      shadingtable=colormap+(i<<8);
+      }
+   else
+      {
+      i=maxshade-(height>>normalshade);
+      if (i<minshade) i=minshade;
+      shadingtable=colormap+(i<<8);
+      }
+}
+
+
+
+void DrawHLine (int xleft, int xright, int yp)
+{
+   int plane;
+   byte * buf;
+   byte * dest;
+   int startxfrac;
+   int startyfrac;
+   int height;
+//   int length;
+   int ofs;
+
+   if (yp==centery)
+      return;
+   if (yp>centery)
+      {
+      int hd;
+
+      buf=floor;
+      hd=yp-centery;
+      height=(hd<<13)/(maxheight-pheight+32);
+      }
+   else
+      {
+      int hd;
+
+      /* ROTT bug? It'd draw when there was no ceiling. - SBF */
+      if (ceiling == NULL) return;
+      
+      buf=ceiling;
+      
+      hd=centery-yp;
+      height=(hd<<13)/pheight;
+      }
+   SetFCLightLevel(height>>(8-HEIGHTFRACTION-1));
+	mr_xstep = ((viewsin<<8)/(height));
+	mr_ystep = ((viewcos<<8)/(height));
+
+	startxfrac = ((viewx>>1) + FixedMulShift(mr_ystep,scale,2))-
+                FixedMulShift(mr_xstep,(centerx-xleft),2);
+
+	startyfrac = ((viewy>>1) - FixedMulShift(mr_xstep,scale,2))-
+                FixedMulShift(mr_ystep,(centerx-xleft),2);
+
+   dest=(byte *)bufferofs+ylookup[yp];
+
+/* TODO: horizontal isn't as easy as vertical in packed */
+#ifdef DOS
+   if (doublestep>0)
+      {
+      if (xleft&1)
+         xleft--;
+
+#ifdef DOS
+      for (plane=xleft;plane<xleft+4;plane+=2)
+#endif
+         {
+
+#ifdef DOS
+         mr_dest=dest+(plane>>2);
+#else
+         mr_dest=dest+xleft;
+#endif
+
+         mr_xfrac = startxfrac;
+		   mr_yfrac = startyfrac;
+
+#ifdef DOS
+         startxfrac+=mr_xstep>>1;
+         startyfrac+=mr_ystep>>1;
+
+         mr_count=((xright-plane)>>2)+1;
+#else
+         mr_count = xright - xleft;
+#endif
+
+         if (mr_count)
+            {
+#ifdef DOS
+            int p;
+            ofs=((plane&3)<<3)+(plane&3)+1;
+//          VGAMAPMASK(*((byte *)mapmasks1+ofs));
+            p=plane&3;
+            VGAMAPMASK((1<<p) + (1<<(p+1)));
+#endif
+            DrawRow(mr_count,mr_dest,buf);
+
+#if 0
+            ofs=(byte)*((byte *)mapmasks2+ofs);
+            if (ofs!=0)
+               {
+               VGAMAPMASK(ofs);
+               DrawRow(mr_count,mr_dest+1,buf);
+               }
+#endif
+            }
+         }
+      }
+   else
+#endif
+      {
+#ifdef DOS
+      for (plane=xleft;plane<xleft+4;plane++)
+#endif
+         {
+#ifdef DOS
+         mr_dest=dest+(plane>>2);
+         VGAWRITEMAP(plane&3);
+#else
+         mr_dest=dest+xleft;
+#endif
+
+         mr_xfrac = startxfrac;
+         mr_yfrac = startyfrac;
+
+#ifdef DOS
+         startxfrac+=mr_xstep>>2;
+         startyfrac+=mr_ystep>>2;
+
+         mr_count=((xright-plane)>>2)+1;
+#else
+        // back off the pixel increment (orig. is 4x)
+        mr_xstep >>= 2;
+        mr_ystep >>= 2;
+        
+        mr_count = xright-xleft+1;
+#endif
+
+         if (mr_count)
+            DrawRow(mr_count,mr_dest,buf);
+         }
+      }
+
+}
+
+void DrawPlanes( void )
+{
+   int x,y;
+   int twall;
+   int bwall;
+
+   if (sky)
+      DrawSky();
+   else
+      {
+      y=0;
+      for (x=0;x<viewwidth;x++)
+         {
+         twall=posts[x].ceilingclip;
+         while (y<twall)
+            {
+            xstarts[y]=x;
+            y++;
+            }
+         while (y>twall)
+            {
+            y--;
+            DrawHLine(xstarts[y],x-1,y);
+            }
+         }
+      while (y>0)
+         {
+         y--;
+         DrawHLine(xstarts[y],viewwidth-1,y);
+         }
+      }
+   y=viewheight-1;
+   for (x=0;x<viewwidth;x++)
+      {
+      bwall=posts[x].floorclip;
+      while (y>bwall)
+         {
+         xstarts[y]=x;
+         y--;
+         }
+      while (y<bwall)
+         {
+         y++;
+         DrawHLine(xstarts[y],x-1,y);
+         }
+      }
+   while (y<viewheight-1)
+      {
+      y++;
+      DrawHLine(xstarts[y],viewwidth-1,y);
+      }
+}
+
+#ifndef DOS
+void DrawRow(int count, byte * dest, byte * src)
+{
+	unsigned frac, fracstep;
+	int coord;
+
+	frac = (mr_yfrac<<16) + (mr_xfrac&0xffff);
+	fracstep = (mr_ystep<<16) + (mr_xstep&0xffff);
+
+	while (count--) {
+		/* extract the x/y coordinates */
+		coord = ((frac >> (32-7)) | ((frac >> (32-23)) << 7)) & 16383;
+		
+		*dest++ = shadingtable[src[coord]];
+		frac += fracstep;
+	}
+}
+#endif

Added: tags/rott-1.1/rott/rt_floor.h
===================================================================
--- tags/rott-1.1/rott/rt_floor.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_floor.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_floor_public
+#define _rt_floor_public
+
+//***************************************************************************
+//
+//    RT_FLOOR.C - Floor and Ceiling stuff
+//
+//***************************************************************************
+
+extern int		mr_xstep;
+extern int		mr_ystep;
+extern int		mr_xfrac;
+extern int		mr_yfrac;
+
+extern int     sky;      //Whether Parallax is on or off
+void DrawPlanes (void);
+void SetPlaneViewSize( void );
+void MakeSkyTile (byte * tile);
+void DrawFullSky( void );
+boolean SkyExists (void);
+
+#endif
+
+
+

Added: tags/rott-1.1/rott/rt_game.c
===================================================================
--- tags/rott-1.1/rott/rt_game.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_game.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,5604 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#ifdef DOS
+#include <dos.h>
+#include <io.h>
+#include <conio.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "rt_def.h"
+#include "rt_main.h"
+#include "rt_game.h"
+#include "_rt_game.h"
+#include "rt_menu.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "lumpy.h"
+#include "rt_playr.h"
+#include "rt_util.h"
+#include "rt_ted.h"
+#include "rt_draw.h"
+#include "rt_view.h"
+#include "rt_vid.h"
+#include "rt_door.h"
+#include "rt_in.h"
+#include "rt_str.h"
+#include "isr.h"
+#include "rt_build.h"
+#include "rt_rand.h"
+#include "rt_cfg.h"
+#include "rt_sound.h"
+#include "version.h"
+#include "rt_crc.h"
+#include "modexlib.h"
+#include "engine.h"
+#include "gmove.h"
+#include "rt_com.h"
+#include "rt_net.h"
+#include "watcom.h"
+#include "rt_floor.h"
+#include "rt_msg.h"
+#include "rt_scale.h"
+#include "develop.h"
+//MED
+#include "memcheck.h"
+
+#if (SHAREWARE == 1)
+#define NUMAMMOGRAPHICS 10
+#else
+#define NUMAMMOGRAPHICS 20
+#endif
+
+//******************************************************************************
+//
+// GLOBALS
+//
+//******************************************************************************
+
+int PlayerSnds[5] = {SD_PLAYERTCSND, SD_PLAYERTBSND, SD_PLAYERDWSND,
+                     SD_PLAYERLNSND, SD_PLAYERIPFSND};
+
+
+unsigned short SHAKETICS = 0xFFFF;//bna++
+//int SHAKETICS   = 0xFFFF;
+int damagecount = 0;
+HighScore   Scores[MaxScores] =
+				{
+               {"Tom",70000,7,1},
+               {"Chuck",60000,6,1},
+               {"Mark",50000,5,1},
+               {"The Joes",40000,4,1},
+               {"William",30000,3,1},
+               {"Jim",20000,2,1},
+               {"Steve",10000,1,1},
+            };
+
+//******************************************************************************
+//
+// LOCALS
+//
+//******************************************************************************
+
+static int KeyX[4]  = {KEY1_X, KEY2_X, KEY3_X, KEY4_X};
+
+static const char *Names[ 5 ] =
+   {
+   "Taradino", "Thi",     "Doug",  "Lorelei", "Ian Paul"
+   };
+
+static const char *LastNames[ 5 ] =
+   {
+   "Cassatt",  "Barrett", "Wendt", "Ni",      "Freeley"
+   };
+
+static STR ScoreStr;
+static STR LivesStr;
+static STR TriadStr;
+static STR KillStr;
+
+static pic_t *lifeptnums[10];
+static pic_t *lifenums[10];
+static pic_t *timenums[10];
+static pic_t *scorenums[10];
+static pic_t *keys[4];
+static pic_t *men[5];
+
+static pic_t *health[6];
+static pic_t *ammo[26];
+static pic_t *erase;
+static pic_t *eraseb;
+static pic_t *fragpic[ 5 ];
+static pic_t *frag100pic[ 5 ];
+static pic_t *negfragpic[ 5 ];
+static pic_t *menneg[ 5 ];
+static pic_t *blankfragpic;
+
+static int powerpics;
+static int poweradjust;
+
+static int poweruptime;
+static int powerupheight;
+static int protectiontime;
+static int protectionheight;
+
+
+static boolean EndLevelStuff = false;
+static boolean borderset     = false;
+static int oldsec            = -1;
+
+static pic_t *BkPic;
+int SaveTime = 0;
+int oldhealth;
+
+static int oldplayerhealth;
+static int oldpercenthealth;
+
+static int playeruniformcolor;
+
+#define NUMBONUSES   11
+#define BONUSBONUS   100000
+
+
+extern void VL_MemToScreenClipped (byte *source, int width, int height, int x, int y);
+void DrawPPic (int xpos, int ypos, int width, int height, byte *src, int num, boolean up, boolean bufferofsonly);
+extern void    MoveScreenUpLeft();
+extern void    MoveScreenUpRight();
+extern void    MoveScreenDownLeft();
+extern void    MoveScreenDownRight();
+//******************************************************************************
+//
+// V_ReDrawBkgnd ()
+//
+//******************************************************************************
+
+void V_ReDrawBkgnd (int x, int y, int width, int height, boolean shade)
+{
+   byte *src;
+   byte *dest;
+   byte *origdest;
+   int j,
+       k,
+       planes,
+       mask,
+       m;
+
+   m = (x&3);
+   mask = (1 << m);
+
+#ifdef DOS
+   origdest = (byte *)(bufferofs+ylookup[y]+(x>>2));
+#else
+   origdest = (byte *)(bufferofs+ylookup[y]+x);
+#endif
+
+   if (VW_MarkUpdateBlock (x, y, x+width-1, y+height-1))
+   {
+      for (planes = 0; planes < 4; planes++)
+      {
+         src = (&(BkPic->data)+((80*200)*m)+(80*y)+(x>>2));
+         dest = origdest;
+
+#ifdef DOS
+         VGAMAPMASK (mask);
+#else
+         dest += planes;
+#endif
+
+         for (j = 0; j < height; j++)
+         {
+            for (k = 0; k < (width/4); k++) {
+               if (shade) {
+                  *dest = *(colormap + ((MENUSHADELEVEL>>2)<<8) + *src++);
+               } else {
+                  *dest = *src++;
+               }
+#ifdef DOS
+               dest++;
+#else
+               dest += 4;
+#endif
+            }
+
+#ifndef DOS            
+            // draw the remainder.  did the DOS version even bother? - SBF
+            if ((width & 3) > planes) {
+               if (shade) {
+                  *dest = *(colormap + ((MENUSHADELEVEL>>2)<<8) + *src);
+               } else {
+                  *dest = *src;
+               }
+            }  
+#endif
+
+	    src += (80-(width/4));
+#ifdef DOS            
+            dest += (linewidth-(width/4));
+#else
+            dest += (linewidth-(width&~3));
+#endif
+         }
+
+         m++;
+         
+         mask <<= 1;
+
+         if (mask == 16)
+         {
+            x+=4;
+            mask = 1;
+            m = 0;
+#ifdef DOS
+            origdest++;
+#endif
+         }
+      }
+   }
+}
+
+
+//******************************************************************************
+//
+// CacheLumpGroup ()
+//
+//******************************************************************************
+void CacheLumpGroup
+   (
+   char   *startlump,
+   pic_t **lumparray,
+   int     numberoflumps
+   )
+
+   {
+   int lumpnum;
+   int i;
+
+   lumpnum = W_GetNumForName( startlump );
+
+   for( i = 0; i < numberoflumps; i++ )
+      {
+      lumparray[ i ] = ( pic_t * )W_CacheLumpNum( lumpnum + i, PU_LEVEL, Cvt_pic_t, 1 );
+      }
+   }
+
+//******************************************************************************
+//
+// SetupPlayScreen ()
+//
+//******************************************************************************
+void SetupPlayScreen
+   (
+   void
+   )
+
+   {
+	int i;
+	int j;
+   int num;
+
+   erase  = ( pic_t * )W_CacheLumpName( "erase", PU_LEVEL, Cvt_pic_t, 1 );
+   eraseb = ( pic_t * )W_CacheLumpName( "eraseb", PU_LEVEL, Cvt_pic_t, 1 );
+
+   CacheLumpGroup( "tmnum0", timenums, 10 );
+   CacheLumpGroup( "lfnum0", lifeptnums, 10 );
+   CacheLumpGroup( "lvnum0", lifenums, 10 );
+   CacheLumpGroup( "health1b", health, 6 );
+   CacheLumpGroup( "key1", keys, 4 );
+
+   if ( !BATTLEMODE )
+      {
+      CacheLumpGroup( "scnum0", scorenums, 10 );
+
+      num = locplayerstate->player;
+      men[ num ] = ( pic_t * )W_CacheLumpNum( W_GetNumForName( "MAN1" ) +
+         num, PU_LEVEL, Cvt_pic_t, 1 );
+      }
+   else
+      {
+      int  man;
+      int  num100;
+      int  negnum;
+      int  negman;
+
+      CacheLumpGroup( "kilnum0", scorenums, 10 );
+
+      negnum  = W_GetNumForName( "botnpic1" );
+      num     = W_GetNumForName( "botpic0" );
+      num100  = W_GetNumForName( "botopic1" );
+      negman  = W_GetNumForName( "negman1" );
+      man     = W_GetNumForName( "man1" );
+
+      blankfragpic = ( pic_t * )W_CacheLumpNum( num, PU_LEVEL, Cvt_pic_t, 1 );
+      num++;
+
+      for( i = 0; i < numplayers; i++ )
+         {
+         j = PLAYERSTATE[ i ].player;
+         if ( !gamestate.teamplay )
+            {
+            fragpic[ j ]    = ( pic_t * )W_CacheLumpNum( num + j, PU_LEVEL, Cvt_pic_t, 1 );
+            frag100pic[ j ] = ( pic_t * )W_CacheLumpNum( num100 + j, PU_LEVEL, Cvt_pic_t, 1 );
+            negfragpic[ j ] = ( pic_t * )W_CacheLumpNum( negnum + j, PU_LEVEL, Cvt_pic_t, 1 );
+            }
+         else
+            {
+            negfragpic[ j ] = ( pic_t * )W_CacheLumpName( "teamnpic", PU_LEVEL, Cvt_pic_t, 1 );
+            fragpic[ j ]    = ( pic_t * )W_CacheLumpName( "teampic", PU_LEVEL, Cvt_pic_t, 1 );
+            frag100pic[ j ] = fragpic[ j ];
+            }
+
+         menneg[ j ]     = ( pic_t * )W_CacheLumpNum( negman + j, PU_LEVEL, Cvt_pic_t, 1 );
+         men[ j ]        = ( pic_t * )W_CacheLumpNum( man + j, PU_LEVEL, Cvt_pic_t, 1 );
+         }
+      }
+
+   powerpics   = W_GetNumForName( "GDMODEP" );
+   poweradjust = POWERUPTICS / 16;
+
+   num   = W_GetNumForName( "INF_B" );
+
+   // bullet weapons
+   ammo[0] = ( pic_t * )W_CacheLumpNum( num, PU_LEVEL, Cvt_pic_t, 1 );
+   ammo[1] = ( pic_t * )W_CacheLumpNum( num, PU_LEVEL, Cvt_pic_t, 1 );
+   ammo[2] = ( pic_t * )W_CacheLumpNum( num++, PU_LEVEL, Cvt_pic_t, 1 );
+
+
+   for(i=3;i < 13; i++ )
+      {
+      ammo[ i ] = ( pic_t * )W_CacheLumpNum( num++, PU_LEVEL, Cvt_pic_t, 1 );
+      }
+
+   ammo[13] = ( pic_t * )W_CacheLumpNum( num, PU_LEVEL, Cvt_pic_t, 1 );
+   ammo[14] = ( pic_t * )W_CacheLumpNum( num, PU_LEVEL, Cvt_pic_t, 1 );
+   ammo[15] = ( pic_t * )W_CacheLumpNum( num++, PU_LEVEL, Cvt_pic_t, 1 );
+
+
+   for(i=16;i < 26; i++ )
+      {
+      ammo[ i ] = ( pic_t * )W_CacheLumpNum( num++, PU_LEVEL, Cvt_pic_t, 1 );
+      }
+
+
+   oldplayerhealth  = -1;
+   oldpercenthealth = -1;
+   }
+
+
+
+//******************************************************************************
+//
+// GameMemToScreen()
+//
+//******************************************************************************
+
+void GameMemToScreen
+   (
+   pic_t *source,
+   int   x,
+   int   y,
+   int   bufferofsonly
+   )
+
+   {
+   if ( bufferofsonly )
+      {
+      VL_MemToScreen( ( byte * )&source->data, source->width,
+         source->height, x, y );
+      }
+   else
+      {
+      GM_MemToScreen( ( byte * )&source->data, source->width,
+         source->height, x, y );
+      }
+   }
+
+
+//******************************************************************************
+//
+// DrawPlayScreen ()
+//
+//******************************************************************************
+void DrawPlayScreen (boolean bufferofsonly)
+
+   {
+   pic_t *shape;
+   int    shapenum;
+   int ShowKillsYoffset = 0;//bna++
+
+//return; 
+
+   if ( SHOW_TOP_STATUS_BAR() )
+      {
+	   if (iGLOBAL_SCREENWIDTH == 640) {
+		   //use this as dummy pic to fill out missing bar
+		  shape = ( pic_t * ) W_CacheLumpName( "bottbar", PU_CACHE, Cvt_pic_t, 1 );
+		  //GameMemToScreen( shape, 0, 0, bufferofsonly );
+		  GameMemToScreen( shape, 320, 0, bufferofsonly );
+		  // delete hart in middle of topbar
+		  DrawPPic( 323,1, 8 >> 2, 16,
+				 ( byte * )&erase->data, 2, true, bufferofsonly );
+		  // delete bullet in end of topbar
+		  DrawPPic( 620,1, 8 >> 2, 16,
+				 ( byte * )&erase->data, 2, true, bufferofsonly );
+		  shape = ( pic_t * )W_CacheLumpName( "stat_bar", PU_CACHE, Cvt_pic_t, 1 );
+		  GameMemToScreen( shape, 0, 0, bufferofsonly );
+	   }else if (iGLOBAL_SCREENWIDTH == 800) {
+		   //use this as dummy pic to fill out missing bar
+		  shape = ( pic_t * ) W_CacheLumpName( "bottbar", PU_CACHE, Cvt_pic_t, 1 );
+		  GameMemToScreen( shape, 0, 0, bufferofsonly );
+		  GameMemToScreen( shape, 260, 0, bufferofsonly );
+		  GameMemToScreen( shape, 800-320, 0, bufferofsonly );
+		  // delete hart in middle of topbar
+		  DrawPPic( 480+3,1, 8 >> 2, 16,
+				 ( byte * )&erase->data, 2, true, bufferofsonly );
+		  // delete bullet in end of topbar
+		  DrawPPic( 780,1, 8 >> 2, 16,
+				 ( byte * )&erase->data, 2, true, bufferofsonly );
+		  shape = ( pic_t * )W_CacheLumpName( "stat_bar", PU_CACHE, Cvt_pic_t, 1 );
+		  GameMemToScreen( shape, 0, 0, bufferofsonly );
+	   }else if (iGLOBAL_SCREENWIDTH == 320) {
+		  
+		  //SetTextMode (  );
+		  shape = ( pic_t * )W_CacheLumpName( "stat_bar", PU_CACHE, Cvt_pic_t, 1 );
+		  GameMemToScreen( shape, 0, 0, bufferofsonly );
+	   }
+      }
+
+   if ( BATTLEMODE )
+      {
+      DrawKills( bufferofsonly );
+      }
+
+   if ( SHOW_BOTTOM_STATUS_BAR() )
+      {
+      shape = ( pic_t * ) W_CacheLumpName( "bottbar", PU_CACHE, Cvt_pic_t, 1 );
+
+      if ( SHOW_KILLS() )
+         {
+		  ShowKillsYoffset = KILLS_HEIGHT;
+		  //shape =  ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );
+		  //DrawTiledRegion( 0, 584, iGLOBAL_SCREENWIDTH, 32-16, 0, 16, shape );//bna++
+	   
+
+	//	     health_y = iGLOBAL_HEALTH_Y;
+ //  if ( SHOW_KILLS() )
+   //   {
+     // health_y -= KILLS_HEIGHT;
+          //GameMemToScreen( shape, 0, (iGLOBAL_SCREENHEIGHT-40)+16, bufferofsonly );
+
+         //GameMemToScreen( shape, 0, 160, bufferofsonly );bna++
+         }
+      //else 
+         {
+
+			if (iGLOBAL_SCREENWIDTH == 640) {
+				  //bna fix - not to good? but no one has 286 any more
+				  //statusbar dosent cover hole screen, because its a lump picture width max 320
+				  //first write dummy shape and next over it
+				 GameMemToScreen( shape, 320, (224*2)+16-ShowKillsYoffset, bufferofsonly );
+				 //copy next shape to mem
+				 GameMemToScreen( shape, 0, (224*2)+16-ShowKillsYoffset, bufferofsonly );
+				 // delete bullet in middle of shape picture
+				 DrawPPic( 310, (224*2)+17-ShowKillsYoffset, 8 >> 2, 16,
+					 ( byte * )&erase->data, 2, true, bufferofsonly );
+				 // delete hart in middle of shape picture
+				 DrawPPic( 324, (224*2)+17-ShowKillsYoffset, 8 >> 2, 16,
+					 ( byte * )&erase->data, 2, true, bufferofsonly );
+
+			}else if (iGLOBAL_SCREENWIDTH == 800) {
+				 GameMemToScreen( shape, 800-320, 584-ShowKillsYoffset, bufferofsonly );
+				 //copy next shape to mem
+				 GameMemToScreen( shape, 300, 584-ShowKillsYoffset, bufferofsonly );
+				 //copy next shape to mem
+				 GameMemToScreen( shape, 0, 584-ShowKillsYoffset, bufferofsonly );
+				 // delete 2 bullets in middle of shape picture
+				 DrawPPic( 305, 584+1-ShowKillsYoffset, 8 >> 2, 16,
+					 ( byte * )&erase->data, 2, true, bufferofsonly );
+				 // delete hart in middle of shape picture
+				 DrawPPic( 610, 584+1-ShowKillsYoffset, 8 >> 2, 16,
+					 ( byte * )&erase->data, 2, true, bufferofsonly );
+
+			}else{
+				 GameMemToScreen( shape, 0, 184, bufferofsonly );
+			}
+         }
+
+      DrawBarAmmo( bufferofsonly );
+      DrawBarHealth( bufferofsonly );
+
+      if ( demoplayback )
+      {
+			 shape = ( pic_t * )W_CacheLumpName( "demo", PU_CACHE, Cvt_pic_t, 1 );
+			 if (iGLOBAL_SCREENWIDTH == 640) {
+				 //DrawPPic( 148, 185, shape->width, shape->height,
+				 //   ( byte * )&shape->data, 1, true, bufferofsonly );bna
+				 DrawPPic( 148*2, 465, shape->width, shape->height,
+					( byte * )&shape->data, 1, true, bufferofsonly );
+			 }else if (iGLOBAL_SCREENWIDTH == 800) {
+				 DrawPPic( 380, 585, shape->width, shape->height,
+					( byte * )&shape->data, 1, true, bufferofsonly );
+			 }else{
+					DrawPPic( 148, 185, shape->width, shape->height,
+					( byte * )&shape->data, 1, true, bufferofsonly );		
+			 }
+	  }
+    }
+
+   if ( !SHOW_TOP_STATUS_BAR() )
+      {
+      return;
+      }
+
+//draws small player picture and name in topbar
+   oldsec = -1;
+
+   DrawTime( bufferofsonly );
+
+   if ( !BATTLEMODE )
+   {
+      int character;
+      int width;
+      int height;
+
+      character = locplayerstate->player;
+      GameMemToScreen( men[ character ], MEN_X, MEN_Y,bufferofsonly );
+
+      CurrentFont = tinyfont;
+
+      // Draw player's name
+      DrawGameString ( MEN_X + 3, MEN_Y + 2, Names[ character ], bufferofsonly );
+
+      VW_MeasurePropString( LastNames[ character ], &width, &height );
+
+      DrawGameString ( MEN_X + 44 - width, MEN_Y + 8,
+         LastNames[ character ], bufferofsonly );
+
+      UpdateLives( locplayerstate->lives );
+      UpdateScore( gamestate.score );
+      DrawTriads( bufferofsonly );
+      DrawLives( bufferofsonly );
+      DrawScore( bufferofsonly );
+      }
+
+   DrawKeys( bufferofsonly );
+
+   if ( locplayerstate->poweruptime )
+      {
+      if ( player->flags & FL_GODMODE )
+         {
+         shapenum = powerpics;
+         }
+      else if ( player->flags & FL_DOGMODE )
+         {
+         shapenum = powerpics + 1;
+         }
+      else if ( player->flags & FL_FLEET )
+         {
+         shapenum = powerpics + 2;
+         }
+      else if ( player->flags & FL_ELASTO )
+         {
+         shapenum = powerpics + 3;
+         }
+      else if ( player->flags & FL_SHROOMS )
+         {
+         shapenum = powerpics + 4;
+         }
+
+      shape = ( pic_t * )W_CacheLumpNum ( shapenum, PU_CACHE, Cvt_pic_t, 1 );
+
+      GameMemToScreen( eraseb, POWERUP1X, POWERUPY, bufferofsonly );
+
+      DrawMPPic( POWERUP1X, POWERUPY + powerupheight, shape->width,
+         shape->height - powerupheight, powerupheight,
+         ( byte * )&shape->data, bufferofsonly );
+      }
+
+
+   if ( locplayerstate->protectiontime )
+      {
+      if ( player->flags & FL_BPV )
+         {
+         shapenum = powerpics + 6;
+         }
+      else if ( player->flags & FL_GASMASK )
+         {
+         shapenum = powerpics + 5;
+         }
+      else if ( player->flags & FL_AV )
+         {
+         shapenum = powerpics + 7;
+         }
+
+      shape = ( pic_t * )W_CacheLumpNum( shapenum, PU_CACHE, Cvt_pic_t, 1 );
+
+      GameMemToScreen( eraseb, POWERUP2X, POWERUPY, bufferofsonly );
+
+      DrawMPPic( POWERUP2X, POWERUPY + protectionheight, shape->width,
+         shape->height - protectionheight, protectionheight,
+         ( byte * )&shape->data, bufferofsonly );
+      }
+   }
+
+
+//******************************************************************************
+//
+// ShortenCodeName()
+//
+//******************************************************************************
+void GetShortCodeName
+   (
+   char *dest,
+   char *source,
+   int  maxwidth
+   )
+
+   {
+   int width;
+   int height;
+   int length;
+
+   strcpy( dest, source );
+
+   // Shorten name to fit
+   length = strlen( dest );
+   VW_MeasurePropString( dest, &width, &height );
+   while( width > maxwidth )
+      {
+      dest[ length ] = 0;
+      length--;
+      VW_MeasurePropString( dest, &width, &height );
+      }
+   }
+
+
+//******************************************************************************
+//
+// DrawKills ()
+//
+//******************************************************************************
+void DrawKills
+   (
+   boolean bufferofsonly
+   )
+   {
+   int  rank;
+	int  xpos;
+   char codename[ MAXCODENAMELENGTH ];
+   int  width;
+   int  playernum;
+   int  playerimage;
+   int  temp;
+   int  iKILLS_Y;
+   pic_t *pic;
+
+   CurrentFont = tinyfont;
+
+   if ( SHOW_TOP_STATUS_BAR() )
+      {
+      playernum   = BATTLE_Team[ consoleplayer ];
+      playerimage = BATTLE_TeamLeader[ playernum ];
+
+      // Set uniformcolor
+      playeruniformcolor = PLAYERSTATE[ playerimage ].uniformcolor;
+
+      // Draw player's point box
+      pic = men[ PLAYERSTATE[ playerimage ].player ];
+      if ( ( gamestate.ShowScores ) && ( BATTLE_Points[ playernum ] < 0 ) )
+         {
+         pic = menneg[ PLAYERSTATE[ playerimage ].player ];
+         }
+
+      DrawPPic( MEN_X, MEN_Y, pic->width, pic->height,
+         ( byte * )&pic->data, 1, true, bufferofsonly );
+
+      // Draw player's name
+      if ( gamestate.teamplay )
+         {
+         GetShortCodeName( codename, colorname[ playeruniformcolor ],
+            42 );
+         }
+      else
+         {
+         GetShortCodeName( codename, PLAYERSTATE[ playerimage ].codename,
+            42 );
+         }
+
+      DrawGameString ( MEN_X + 2, MEN_Y + 2, codename, bufferofsonly );
+      // Draw "It" if player is 'it'
+      if ( ( ( gamestate.battlemode == battle_Tag ) ||
+         ( gamestate.battlemode == battle_Hunter ) ) &&
+         ( BATTLE_It == BATTLE_Team[ consoleplayer ] ) )
+         {
+         DrawGameString ( MEN_X + 22, MEN_Y + 8,
+            "It", bufferofsonly);
+         }
+
+      // Draw triad if player is 'it' or has caught a triad
+      if ( PLAYER[ consoleplayer ]->flags & FL_DESIGNATED )
+         {
+         pic = W_CacheLumpName( "smalltri", PU_CACHE, Cvt_pic_t, 1 );
+         DrawPPic( TRIAD_X - 1, TRIAD_Y - 2, pic->width, pic->height,
+            ( byte * )&pic->data, 1, true, bufferofsonly );
+         }
+      else if ( ( gamestate.ShowScores ) &&
+         ( DisplayPoints != bo_kills_infinite ) )
+         {
+         // Draw Kill goal
+         if ( ( gamestate.battlemode == battle_Collector ) ||
+            ( gamestate.battlemode == battle_StandAloneGame ) )
+            {
+            temp = BATTLE_NumCollectorItems;
+            }
+         else
+            {
+            temp = DisplayPoints;
+            }
+
+         ltoa ( temp % 1000, KillStr.str, 10);
+         KillStr.length = strlen (KillStr.str);
+         DrawNumber (TRIAD_X - 6, TRIAD_Y, 3, 5, bufferofsonly);
+         }
+
+      // Set uniformcolor
+      playeruniformcolor = PLAYERSTATE[ consoleplayer ].uniformcolor;
+
+      if ( gamestate.ShowScores )
+         {
+         // Draw local player's points
+         temp = BATTLE_Points[ playernum ] % 1000;
+         if ( temp < 0 )
+            {
+            temp = -temp;
+            }
+         ltoa ( temp, KillStr.str, 10);
+         KillStr.length = strlen (KillStr.str);
+
+         DrawNumber( LIVES_X - 12, LIVES_Y, 3, 4, bufferofsonly);
+         }
+      else
+         {
+         pic = W_CacheLumpName( "minus", PU_CACHE, Cvt_pic_t, 1 );
+         StatusDrawColoredPic( LIVES_X - 12, LIVES_Y, pic, bufferofsonly, playeruniformcolor );
+         StatusDrawColoredPic( LIVES_X - 4, LIVES_Y, pic, bufferofsonly, playeruniformcolor );
+         }
+
+      // Draw whoever is 'It'
+      playernum   = BATTLE_It;
+      playerimage = BATTLE_TeamLeader[ playernum ];
+
+      // Set uniformcolor
+      playeruniformcolor = PLAYERSTATE[ playerimage ].uniformcolor;
+
+      // Draw player's point box
+      pic = men[ PLAYERSTATE[ playerimage ].player ];
+      if ( ( gamestate.ShowScores ) && ( BATTLE_Points[ playernum ] < 0 ) )
+         {
+         pic = menneg[ PLAYERSTATE[ playerimage ].player ];
+         }
+
+      DrawPPic( LEADER_X, LEADER_Y, pic->width, pic->height,
+         (byte *)&pic->data, 1, true, bufferofsonly );
+
+      if ( ( gamestate.battlemode == battle_Tag ) ||
+         ( gamestate.battlemode == battle_Hunter ) )
+         {
+         DrawGameString ( LEADER_X + 22, LEADER_Y + 8,
+            "It", bufferofsonly);
+         }
+
+      if ( gamestate.ShowScores )
+         {
+         // Draw number of points
+         temp = BATTLE_Points[ playernum ] % 1000;
+         if ( temp < 0 )
+            {
+            temp = -temp;
+            }
+         ltoa ( temp, KillStr.str, 10);
+         KillStr.length = strlen (KillStr.str);
+         DrawNumber ( LEADER_NUM_X, LEADER_NUM_Y, 3, 4, bufferofsonly);
+         }
+      else
+         {
+         pic = W_CacheLumpName( "minus", PU_CACHE, Cvt_pic_t, 1 );
+         StatusDrawColoredPic( LEADER_NUM_X, LEADER_NUM_Y, pic, bufferofsonly, playeruniformcolor );
+         StatusDrawColoredPic( LEADER_NUM_X + 8, LEADER_NUM_Y, pic, bufferofsonly, playeruniformcolor );
+         }
+
+      // Draw name
+      if ( gamestate.teamplay )
+         {
+         DrawGameString ( LEADER_NAME_X, LEADER_NAME_Y - 1,
+            colorname[ playeruniformcolor ], bufferofsonly);
+         }
+      else
+         {
+         GetShortCodeName( codename, PLAYERSTATE[ playerimage ].codename,
+            42 );
+         DrawGameString ( LEADER_NAME_X - 1, LEADER_NAME_Y,
+            codename, bufferofsonly);
+         }
+      }
+
+   // Only draw the rest of the rifraff when the kill count is selected
+   
+   if ( !SHOW_KILLS() )
+      {
+      return;
+      }
+//	 SetTextMode (  );
+   // Draw all the other losers
+	//#define KILLS_Y      176
+    iKILLS_Y = iGLOBAL_SCREENHEIGHT - 24;
+	//draw blank status  pic->width = 8;pic->height = 24
+    pic = blankfragpic;
+    for (temp = iGLOBAL_SCREENWIDTH-pic->width-24;temp > pic->width; temp -= pic->width){	
+		  DrawPPic( temp, iKILLS_Y, pic->width, pic->height,
+			 (byte *)&pic->data, 1, true, bufferofsonly );
+
+	}
+
+	xpos = KILLS_X;
+   for( rank = 0; rank < BATTLE_NumberOfTeams; rank++ )
+      {
+      playernum   = BATTLE_PlayerOrder[ rank ];
+      playerimage = BATTLE_TeamLeader[ playernum ];
+
+      if ( ( playernum == BATTLE_It ) && SHOW_TOP_STATUS_BAR() )
+         {
+         continue;
+         }
+
+      // Set uniformcolor
+      playeruniformcolor = PLAYERSTATE[ playerimage ].uniformcolor;
+
+      // Draw player's point box
+      pic = fragpic[ PLAYERSTATE[ playerimage ].player ];
+      if ( gamestate.ShowScores )
+         {
+         if ( BATTLE_Points[ playernum ] < 0 )
+            {
+            pic = negfragpic[ PLAYERSTATE[ playerimage ].player ];
+            }
+         else if ( BATTLE_Points[ playernum ] >= 100 )
+            {
+            pic = frag100pic[ PLAYERSTATE[ playerimage ].player ];
+            }
+         }
+      DrawPPic( xpos, iKILLS_Y, pic->width, pic->height,
+         (byte *)&pic->data, 1, true, bufferofsonly );
+
+      // Draw number of points
+      if ( gamestate.ShowScores )
+         {
+         temp = BATTLE_Points[ playernum ] % 1000;
+         if ( temp < 0 )
+            {
+            temp = -temp;
+            }
+         ltoa ( temp, KillStr.str, 10);
+         KillStr.length = strlen (KillStr.str);
+         width = 2;
+         if ( temp > 99 )
+            {
+            width = 3;
+            }
+         DrawNumber( xpos + KILLS_OFFSET + 16 - ( 8 * width ), iKILLS_Y, width, 4, bufferofsonly);
+         }
+      else
+         {
+         pic =  ( pic_t * )W_CacheLumpName( "minus", PU_CACHE, Cvt_pic_t, 1 );
+         StatusDrawColoredPic( ( xpos + KILLS_OFFSET ), iKILLS_Y, pic, bufferofsonly, playeruniformcolor );
+         StatusDrawColoredPic( ( xpos + KILLS_OFFSET + 8 ), iKILLS_Y, pic, bufferofsonly, playeruniformcolor );
+         }
+
+      // Get codename
+      if ( gamestate.teamplay )
+         {
+         GetShortCodeName( codename, colorname[ playeruniformcolor ],
+            KILLS_WIDTH - 2 );
+         }
+      else
+         {
+         GetShortCodeName( codename, PLAYERSTATE[ playerimage ].codename,
+            KILLS_WIDTH - 2 );
+         }
+
+      // Draw name
+      DrawGameString (xpos + 1, KILLS_NAME_Y, codename, bufferofsonly);
+
+      // Advance to next position
+		xpos += KILLS_WIDTH;
+
+      if ( xpos >= iGLOBAL_SCREENWIDTH )
+         {
+         break;
+         }
+      }
+
+   for( rank = BATTLE_NumberOfTeams; rank <= MAXKILLBOXES; rank++ )
+      {
+      if ( xpos >= iGLOBAL_SCREENWIDTH )
+         {
+         break;
+         }
+
+      pic = blankfragpic;
+      DrawPPic( xpos, iKILLS_Y, pic->width, pic->height,
+         (byte *)&pic->data, 1, true, bufferofsonly );
+
+      // Advance to next position
+		xpos += KILLS_WIDTH;
+      }
+   }
+
+
+//******************************************************************************
+//
+// DrawPlayers ()
+//
+//******************************************************************************
+void DrawPlayers
+   (
+   void
+   )
+
+   {
+	int    num;
+	int    xpos;
+   char   codename[ MAXCODENAMELENGTH ];
+   int    length;
+   int    width;
+   int    height;
+   int    team;
+   int    player;
+   int    character;
+   pic_t *pic;
+   pic_t *enemy;
+   pic_t *friend;
+
+   num = W_GetNumForName( "botpic1" );
+
+   scorenums[ 0 ]= ( pic_t * )W_CacheLumpName( "kilnum0", PU_CACHE, Cvt_pic_t, 1 );
+   friend = ( pic_t * )W_CacheLumpName( "t_friend", PU_CACHE, Cvt_pic_t, 1 );
+   enemy  = ( pic_t * )W_CacheLumpName( "t_enemy", PU_CACHE, Cvt_pic_t, 1 );
+
+   // Draw all the losers 
+   CurrentFont = tinyfont;
+
+	xpos = (iGLOBAL_SCREENWIDTH  - min( numplayers, MAXKILLBOXES ) * KILLS_WIDTH ) / 2;
+//SetTextMode (  );//PLAYERSTATE
+   for( team = 0; team < BATTLE_NumberOfTeams; team++ )
+      {
+      for( player = 0; player < numplayers; player++ )
+         {
+         if ( BATTLE_Team[ player ] == team )
+            {
+            character = PLAYERSTATE[ player ].player;
+
+            fragpic[ character ] = ( pic_t * )W_CacheLumpNum( num +
+               character, PU_CACHE, Cvt_pic_t, 1 );
+
+            if ( ( numplayers <= MAXKILLBOXES ) ||
+               ( player != consoleplayer ) )
+               {
+               // Set uniformcolor
+               playeruniformcolor = PLAYERSTATE[ player ].uniformcolor;
+
+               // Draw player's point box
+               pic = fragpic[ PLAYERSTATE[ player ].player ];
+
+               VWB_DrawPic ( xpos, PLAYERS_Y, pic );
+               if ( gamestate.teamplay )
+                  {
+                  if ( BATTLE_Team[ player ] == BATTLE_Team[ consoleplayer ] )
+                     {
+                     VWB_DrawPic ( xpos, PLAYERS_TEAM_Y, friend );
+                     }
+                  else
+                     {
+                     VWB_DrawPic ( xpos, PLAYERS_TEAM_Y, enemy );
+                     }
+                  }
+
+               strcpy( KillStr.str, "00" );
+               KillStr.length = strlen ( KillStr.str );
+               DrawNumber( xpos + KILLS_OFFSET, PLAYERS_Y, 2, 4, true );
+
+               // Get codename
+               strcpy( codename, PLAYERSTATE[ player ].codename );
+
+               // Shorten name to fit into point count
+               length = strlen( codename );
+               US_MeasureStr( &width, &height, codename );
+               while( width > KILLS_WIDTH )
+                  {
+                  codename[ length ] = 0;
+                  length--;
+                  US_MeasureStr( &width, &height, codename );
+                  }
+
+               // Draw name
+               PrintX = xpos;
+               PrintY = PLAYERS_NAME_Y;
+               US_Print( codename );
+
+               // Advance to next position
+               xpos += KILLS_WIDTH;
+               }
+            }
+         if ( xpos >= iGLOBAL_SCREENWIDTH )
+            {
+            break;
+            }
+         }
+      if ( xpos >= iGLOBAL_SCREENWIDTH )
+         {
+         break;
+         }
+      }
+   }
+
+//******************************************************************************
+//
+// StatusDrawPic ()
+//
+//******************************************************************************
+
+void StatusDrawPic (unsigned x, unsigned y, pic_t *nums, boolean bufferofsonly)
+{
+   DrawMPPic (x, y, nums->width, nums->height, 0,
+             (byte *)&nums->data, bufferofsonly);
+}
+
+//******************************************************************************
+//
+// StatusDrawColoredPic ()
+//
+//******************************************************************************
+
+void StatusDrawColoredPic (unsigned x, unsigned y, pic_t *nums, boolean bufferofsonly, int color)
+{
+   DrawColoredMPPic (x, y, nums->width, nums->height, 0,
+             (byte *)&nums->data, bufferofsonly, color);
+}
+
+//******************************************************************************
+//
+// DrawGameString ()
+//
+// draw string to game screen at x,y
+//
+//******************************************************************************
+
+void DrawGameString (int x, int y, const char * str, boolean bufferofsonly)
+{
+   byte *tempbuf;
+
+   px=x;
+   py=y;
+
+   if (bufferofsonly==true)
+      VW_DrawPropString (str);
+   else
+      {
+      tempbuf=bufferofs;
+      bufferofs=page1start;
+      VW_DrawPropString (str);
+#ifdef DOS
+      px=x;
+      py=y;
+      bufferofs=page2start;
+      VW_DrawPropString (str);
+      px=x;
+      py=y;
+      bufferofs=page3start;
+      VW_DrawPropString (str);
+#endif
+      bufferofs=tempbuf;
+      }
+}
+
+
+//******************************************************************************
+//
+// DrawNumber ()
+//
+// right justifies and pads with zeros
+//
+//******************************************************************************
+
+void DrawNumber (int x, int y, int width, int which, boolean bufferofsonly)
+{
+   unsigned length,c;
+   char  *str;
+   byte z;
+
+   switch (which)
+   {
+      case 1:
+         str = ScoreStr.str;
+         length = ScoreStr.length;
+      break;
+
+      case 2:
+         str = LivesStr.str;
+         length = LivesStr.length;
+      break;
+
+      case 3:
+         str = TriadStr.str;
+         length = TriadStr.length;
+      break;
+
+      case 4:
+      case 5:
+      case 6:
+         str = KillStr.str;
+         length = KillStr.length;
+      break;
+   }
+
+   z = width - length;     // Num zeros
+
+   while (z)
+   {
+      switch (which)
+      {
+         case 1: StatusDrawPic (x, y, scorenums[0], bufferofsonly);  x+=8; break;
+         case 2: StatusDrawPic (x, y, lifenums[0], bufferofsonly);   x+=8; break;
+         case 3: StatusDrawPic (x, y, lifeptnums[0], bufferofsonly); x+=6; break;
+         case 4: StatusDrawColoredPic (x, y, scorenums[0], bufferofsonly, playeruniformcolor);   x+=8; break;
+         case 5: StatusDrawPic (x, y, lifeptnums[0], bufferofsonly); x+=6; break;
+         case 6: StatusDrawPic (x, y, lifenums[0], bufferofsonly);   x+=8; break;
+      }
+      z--;
+   }
+
+   c = length <= (unsigned)width ? 0 : length-width;
+   while (c < length)
+   {
+      switch (which)
+      {
+         case 1: StatusDrawPic (x, y, scorenums[str[c]-'0'], bufferofsonly);  x+=8; break;
+         case 2: StatusDrawPic (x, y, lifenums[str[c]-'0'], bufferofsonly);   x+=8; break;
+         case 3: StatusDrawPic (x, y, lifeptnums[str[c]-'0'], bufferofsonly); x+=6; break;
+         case 4: StatusDrawColoredPic (x, y, scorenums[str[c]-'0'], bufferofsonly, playeruniformcolor);   x+=8; break;
+         case 5: StatusDrawPic (x, y, lifeptnums[str[c]-'0'], bufferofsonly); x+=6; break;
+         case 6: StatusDrawPic (x, y, lifenums[str[c]-'0'], bufferofsonly);   x+=8; break;
+      }
+      c++;
+   }
+}
+
+
+
+//******************************************************************************
+//
+// HealPlayer ()
+//
+//******************************************************************************
+
+void HealPlayer
+   (
+   int      points,
+   objtype *ob
+   )
+
+   {
+   playertype *pstate;
+   int maxhitpoints;
+
+	M_LINKSTATE( ob, pstate );
+
+	pstate->health += points;
+	maxhitpoints = MaxHitpointsForCharacter( pstate );
+	if ( pstate->health > maxhitpoints )
+      {
+      pstate->health = maxhitpoints;
+      }
+
+   if ( ( SHOW_BOTTOM_STATUS_BAR() ) && ( ob == player ) )
+      {
+      DrawBarHealth( false );
+      }
+   }
+
+//******************************************************************************
+//
+// DrawLives ()
+//
+//******************************************************************************
+
+void DrawLives
+   (
+   boolean bufferofsonly
+   )
+
+   {
+   if ( !SHOW_TOP_STATUS_BAR() )
+      {
+      return;
+      }
+
+	if ( !EndLevelStuff )
+      {
+      DrawNumber( LIVES_X, LIVES_Y, 2, 2, bufferofsonly );
+      }
+   }
+
+
+//******************************************************************************
+//
+// GiveExtraMan ()
+//
+//******************************************************************************
+
+void  GiveExtraMan (void)
+{
+   if (locplayerstate->lives < 99)
+      locplayerstate->lives++;
+   UpdateLives (locplayerstate->lives);
+   DrawLives (false);
+//   SD_PlaySound (BONUS1UPSND);
+}
+
+
+
+//******************************************************************************
+//
+// DrawScore ()
+//
+//******************************************************************************
+
+void DrawScore
+   (
+   boolean bufferofsonly
+   )
+
+   {
+   if ( !SHOW_TOP_STATUS_BAR() )
+      {
+      return;
+      }
+
+   if ( !BATTLEMODE )
+      {
+      DrawNumber( SCORE_X, SCORE_Y, 10, 1, bufferofsonly );
+      }
+   }
+
+
+//******************************************************************************
+//
+// GivePoints ()
+//
+//******************************************************************************
+
+void  GivePoints (long points)
+{
+   gamestate.score += points;
+
+   UpdateScore (gamestate.score);
+
+   if (!EndLevelStuff)
+      DrawScore (false);
+}
+
+
+//******************************************************************************
+//
+// GiveKey ()
+//
+//******************************************************************************
+
+void GiveKey (int key)
+{
+   locplayerstate->keys |= (1<<key);
+   DrawKeys (false);
+}
+
+
+//******************************************************************************
+//
+// GiveLives ()
+//
+//******************************************************************************
+
+void GiveLives (int newlives)
+{
+   if ((locplayerstate->lives + newlives) <= 99)
+      locplayerstate->lives += newlives;
+   else
+      locplayerstate->lives = 99;
+   UpdateLives (locplayerstate->lives);
+   DrawLives (false);
+}
+
+
+#define EnableOldWeapon(pstate)    \
+   {                               \
+   LASTSTAT->flags |= FL_ABP;      \
+   LASTSTAT->flags &= ~FL_RESPAWN; \
+   MakeStatActive(LASTSTAT);       \
+   pstate->weaponx = ob->tilex;    \
+   pstate->weapony = ob->tiley;    \
+   }
+
+
+//******************************************************************************
+//
+// GiveWeapon ()
+//
+//******************************************************************************
+
+void GiveWeapon
+   (
+   objtype *ob,
+   int weapon
+   )
+
+   {
+   playertype *pstate;
+
+   M_LINKSTATE( ob, pstate );
+
+   if ( pstate->weapon == weapon )
+      {
+      return;
+      }
+
+   pstate->HASBULLETWEAPON[ weapon ] = 1;
+   if ( ( pstate->weapon == pstate->bulletweapon ) &&
+      ( pstate->weapon < weapon ) )
+      {
+      pstate->new_weapon = weapon;
+      pstate->weapondowntics = WEAPONS[ pstate->weapon ].screenheight / GMOVE;
+      if ( ( ob == player ) && ( SHOW_BOTTOM_STATUS_BAR() ) )
+         {
+         DrawBarAmmo( false );
+         }
+      }
+
+   if ( gamestate.BattleOptions.WeaponPersistence )
+      {
+      SpawnStatic(ob->tilex,ob->tiley,GetItemForWeapon(weapon),9);
+      EnableOldWeapon(pstate);
+      }
+
+   if ( weapon > pstate->bulletweapon )
+      {
+      pstate->bulletweapon = weapon;
+      }
+   }
+
+
+//******************************************************************************
+//
+// GiveMissileWeapon ()
+//
+//******************************************************************************
+
+void GiveMissileWeapon(objtype * ob, int which)
+{
+	playertype * pstate;
+
+
+	//pstate = (ob==player)?(&playerstate):(&remoteplayerstate);
+	M_LINKSTATE(ob,pstate);
+
+   if (!gamestate.BattleOptions.WeaponPersistence)
+      {
+      if (pstate->ammo &&
+          (pstate->missileweapon != -1) &&
+          (!(WEAPON_IS_MAGICAL(which))) &&
+          (!(WEAPON_IS_MAGICAL(pstate->missileweapon)))
+         )
+         {
+         int nx,ny;
+
+
+         nx = ob->tilex;
+         ny = ob->tiley;
+         //FindEmptyTile(&nx,&ny);
+
+         if (IsPlatform(nx,ny))
+            SpawnStatic(nx,ny,GetItemForWeapon(pstate->missileweapon),9);
+         else
+            {
+            int newz = sprites[ob->tilex][ob->tiley]->z;
+            SpawnStatic(nx,ny,GetItemForWeapon(pstate->missileweapon),-1);
+            LASTSTAT->z = newz;
+            }
+         LASTSTAT->ammo = pstate->ammo;
+         EnableOldWeapon(pstate);
+
+         }
+      }
+
+   else if (!WEAPON_IS_MAGICAL(which))
+      {
+      int newz = sprites[ob->tilex][ob->tiley]->z;
+      SpawnStatic(ob->tilex,ob->tiley,GetItemForWeapon(which),9);
+      LASTSTAT->z = newz;
+      EnableOldWeapon(pstate);
+
+      }
+   pstate->new_weapon = pstate->missileweapon = which;
+   pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
+
+
+}
+
+
+//******************************************************************************
+//
+// DrawKeys ()
+//
+//******************************************************************************
+
+void DrawKeys
+   (
+   boolean bufferofsonly
+   )
+
+   {
+   if ( !SHOW_TOP_STATUS_BAR() )
+      {
+      return;
+      }
+
+   if ( locplayerstate->keys & 1 )
+      {
+      GameMemToScreen( keys[ 0 ], KeyX[ 0 ], KEY_Y, bufferofsonly );
+      }
+
+   if ( locplayerstate->keys & 2 )
+      {
+      GameMemToScreen( keys[ 1 ], KeyX[ 1 ], KEY_Y, bufferofsonly );
+      }
+
+   if ( locplayerstate->keys & 4 )
+      {
+      GameMemToScreen( keys[ 2 ], KeyX[ 2 ], KEY_Y, bufferofsonly );
+      }
+
+   if ( locplayerstate->keys & 8 )
+      {
+      GameMemToScreen( keys[ 3 ], KeyX[ 3 ], KEY_Y, bufferofsonly );
+      }
+   }
+
+
+//******************************************************************************
+//
+// StatusDrawTime ()
+//
+//******************************************************************************
+
+void StatusDrawTime
+   (
+   unsigned x,
+   unsigned y,
+   unsigned num,
+   boolean  bufferofsonly
+   )
+
+   {
+	DrawMPPic( x, y, timenums[ num ]->width, timenums[ num ]->height, 0,
+      ( byte * )&timenums[ num ]->data, bufferofsonly );
+   }
+
+
+//******************************************************************************
+//
+// DrawTimeNumber ()
+//
+// right justifies and pads with blanks
+//
+//******************************************************************************
+
+void DrawTimeNumber (int x, int y, int number, boolean seconds, boolean bufferofsonly)
+{
+   char  str[20];
+
+   ltoa (number,str,10);
+
+   if (seconds)
+	{
+      if (number < 10)
+      {
+         StatusDrawTime (x,   y, 0, bufferofsonly);
+         StatusDrawTime (x+8, y, str[0]-'0', bufferofsonly);
+      }
+      else
+      {
+         StatusDrawTime (x,   y, str[0]-'0', bufferofsonly);
+         StatusDrawTime (x+8, y, str[1]-'0', bufferofsonly);
+      }
+   }
+   else
+   {
+      if (number < 10)
+         StatusDrawTime (x+8, y, str[0]-'0', bufferofsonly);
+      else
+      {
+         StatusDrawTime (x,   y, str[0]-'0', bufferofsonly);
+         StatusDrawTime (x+8, y, str[1]-'0', bufferofsonly);
+      }
+   }
+}
+
+
+//******************************************************************************
+//
+// DrawTimeXY ()
+//
+//******************************************************************************
+
+void DrawTimeXY
+   (
+   int x,
+   int y,
+   int sec,
+   boolean bufferofsonly
+   )
+
+   {
+   int min;
+   int hour;
+
+   while (sec > ( ( 9 * 3600 ) + 3599 ) )
+      {
+      sec -= ( ( 9 * 3600 ) + 3599 );
+      }
+
+   hour  = sec / 3600;
+   min   = ( sec / 60 ) - ( hour * 60 );
+   sec  %= 60;
+
+   DrawTimeNumber ( x + HOUR_X, y, hour, false, bufferofsonly );
+   DrawTimeNumber ( x + MIN_X, y, min, true, bufferofsonly );
+   DrawTimeNumber ( x + SEC_X, y, sec, true, bufferofsonly );
+   }
+
+
+//******************************************************************************
+//
+// DrawTime ()
+//
+//******************************************************************************
+
+void DrawTime
+   (
+   boolean bufferofsonly
+   )
+
+   {
+   int sec;
+
+   if ( !SHOW_TOP_STATUS_BAR() )
+      {
+      return;
+      }
+
+   if (timelimitenabled == true)
+      {
+      sec = (timelimit-gamestate.TimeCount) / VBLCOUNTER;
+      }
+   else
+      {
+      sec = gamestate.TimeCount / VBLCOUNTER;
+      }
+
+   if ( oldsec != sec )
+      {
+      oldsec = sec;
+      DrawTimeXY( GAMETIME_X, GAMETIME_Y, sec, bufferofsonly) ;
+      }
+   }
+
+
+//******************************************************************************
+//
+// DrawMPPic ()
+//
+// Purpose
+//    Draws a masked, planer pic at xpos, ypos.
+//
+// Parms
+//    xpos   - x position.
+//    ypos   - y position.
+//    width  - width of pic : should be << 2.
+//    height - height of pic.
+//    src    - data to draw.
+//
+// Returns
+//    Nothing.
+//
+//******************************************************************************
+
+void DrawMPPic (int xpos, int ypos, int width, int height, int heightmod, byte *src, boolean bufferofsonly)
+{
+   int olddest;
+   int dest;
+   int x;
+   int y;
+   int planes;
+   byte mask;
+   byte pixel;
+
+   mask = 1 << (xpos&3);
+
+#ifdef DOS
+   olddest = ylookup[ypos] + (xpos>>2);
+#else
+   olddest = ylookup[ypos] + xpos;
+#endif
+
+   for (planes = 0; planes < 4; planes++)
+   {
+      VGAMAPMASK (mask);
+
+      dest = olddest;
+
+#ifndef DOS
+      dest += planes;
+#endif
+
+      for (y = 0; y < height; y++)
+      {
+         for (x = 0; x < width; x++)
+         {
+            pixel = *src++;
+
+            if (pixel != 255)
+            {
+               if (bufferofsonly)
+                  *(dest+bufferofs) = pixel;
+               else
+               {
+                  *(dest+page1start) = pixel;
+                  *(dest+page2start) = pixel;
+                  *(dest+page3start) = pixel;
+               }
+            }
+
+#ifdef DOS
+            dest++;
+#else
+            dest += 4;
+#endif
+         }
+
+#ifdef DOS
+         dest += (linewidth-width);
+#else
+         dest += (linewidth-width*4);
+#endif
+      }
+
+      if (heightmod)
+         src += (heightmod*width);
+
+#ifdef DOS
+      mask <<= 1;
+      if (mask == 16)
+      {
+         mask = 1;
+         olddest++;
+      }
+#endif
+   }
+}
+
+
+//******************************************************************************
+//
+// DrawColoredMPPic ()
+//
+// Purpose
+//    Draws a masked, planer pic at xpos, ypos.
+//
+// Parms
+//    xpos   - x position.
+//    ypos   - y position.
+//    width  - width of pic : should be << 2.
+//    height - height of pic.
+//    src    - data to draw.
+//
+// Returns
+//    Nothing.
+//
+//******************************************************************************
+
+void DrawColoredMPPic (int xpos, int ypos, int width, int height, int heightmod, byte *src, boolean bufferofsonly, int color)
+{
+   int olddest;
+   int dest;
+   int x;
+   int y;
+   int planes;
+   byte mask;
+   byte pixel;
+   byte * cmap;
+
+   cmap=playermaps[color]+(1<<12);
+
+   mask = 1 << (xpos&3);
+
+#ifdef DOS
+   olddest = ylookup[ypos] + (xpos>>2);
+#else
+   olddest = ylookup[ypos] + xpos;
+#endif
+
+   for (planes = 0; planes < 4; planes++)
+   {
+      VGAMAPMASK (mask);
+
+      dest = olddest;
+
+#ifndef DOS
+      dest += planes;
+#endif
+
+      for (y = 0; y < height; y++)
+      {
+         for (x = 0; x < width; x++)
+         {
+            pixel = *src++;
+
+            pixel = *(cmap+pixel);
+
+            if (pixel != 255)
+            {
+               if (bufferofsonly)
+                  *(dest+bufferofs) = pixel;
+               else
+               {
+                  *(dest+page1start) = pixel;
+                  *(dest+page2start) = pixel;
+                  *(dest+page3start) = pixel;
+               }
+            }
+
+#ifdef DOS
+            dest++;
+#else
+            dest += 4;
+#endif
+         }
+
+#ifdef DOS
+         dest += (linewidth-width);
+#else
+         dest += (linewidth-width*4);
+#endif
+      }
+
+      if (heightmod)
+         src += (heightmod*width);
+
+#ifdef DOS
+      mask <<= 1;
+      if (mask == 16)
+      {
+         mask = 1;
+         olddest++;
+      }
+#endif
+   }
+}
+
+
+//******************************************************************************
+//
+// UpdateScore ()
+//
+//******************************************************************************
+
+void UpdateScore (unsigned int num)
+{
+   if (num > 999999999)
+   {
+      num = 999999999;
+      gamestate.score = 999999999;
+   }
+
+   ltoa (num, ScoreStr.str, 10);
+   ScoreStr.length = strlen (ScoreStr.str);
+}
+
+
+//******************************************************************************
+//
+// UpdateLives ()
+//
+//******************************************************************************
+
+void UpdateLives (int num)
+{
+   ltoa (num, LivesStr.str, 10);
+   LivesStr.length = strlen (LivesStr.str);
+}
+
+//****************************************************************************
+//
+// ClearTriads ()
+//
+//****************************************************************************
+void ClearTriads (playertype * pstate)
+{
+   pstate->triads = 0;
+   ltoa (pstate->triads, TriadStr.str, 10);
+   TriadStr.length = strlen (TriadStr.str);
+}
+
+//****************************************************************************
+//
+// UpdateTriads ()
+//
+//****************************************************************************
+
+void UpdateTriads (objtype * ob, int num)
+{
+   playertype * pstate;
+
+	M_LINKSTATE(ob,pstate);
+
+   pstate->triads += num;
+
+   if (pstate->triads >= 100)
+   {
+      GiveLives(1);
+      if (ob==player)
+         {
+         AddMessage("100 Life Item Points!  Extra Life!",MSG_BONUS);
+         SD_PlaySoundRTP (SD_GET1UPSND, player->x, player->y);
+         }
+      pstate->triads -= 100;
+   }
+
+   if (ob==player)
+      {
+      ltoa (pstate->triads, TriadStr.str, 10);
+      TriadStr.length = strlen (TriadStr.str);
+      }
+}
+
+//****************************************************************************
+//
+// DrawTriads ()
+//
+//****************************************************************************
+
+void DrawTriads
+   (
+   boolean bufferofsonly
+   )
+
+   {
+   if ( !SHOW_TOP_STATUS_BAR() )
+      {
+      return;
+      }
+
+   if ( !EndLevelStuff )
+      {
+      DrawNumber( TRIAD_X, TRIAD_Y, 2, 3, bufferofsonly );
+      }
+   }
+
+
+//******************************************************************************
+//
+// DrawPPic ()
+//
+//******************************************************************************
+
+void DrawPPic (int xpos, int ypos, int width, int height, byte *src, int num, boolean up, boolean bufferofsonly)
+{
+   int olddest;
+   int dest;
+   int x;
+   int y;
+   int planes;
+   byte mask;
+   byte pixel;
+   int k;
+   int amt;
+
+#ifdef DOS
+   if (up)
+      amt = 2;
+   else
+      amt = -2;
+#else
+   if (up)
+      amt = 8;
+   else
+      amt = -8;
+#endif
+
+   mask = 1;
+
+#ifdef DOS
+   olddest = ylookup[ypos] + (xpos>>2);
+#else
+   olddest = ylookup[ypos] + xpos;
+#endif
+
+   for (planes = 0; planes < 4; planes++)
+   {
+      VGAMAPMASK (mask);
+
+      dest = olddest;
+
+#ifndef DOS
+      dest += planes;
+#endif
+
+      for (y = 0; y < height; y++)
+      {
+         for (x = 0; x < width; x++)
+         {
+            pixel = *src++;
+
+            if (pixel != 255)
+            {
+               for (k = 0; k < num; k++)
+               {
+                  if (bufferofsonly)
+                     *(dest+bufferofs+(amt*k)) = pixel;
+                  else
+                  {
+                     *(dest+page1start+(amt*k)) = pixel;
+                     *(dest+page2start+(amt*k)) = pixel;
+                     *(dest+page3start+(amt*k)) = pixel;
+                  }
+               }
+            }
+
+#ifdef DOS
+            dest++;
+#else
+            dest += 4;
+#endif
+         }
+
+#ifdef DOS
+         dest += (linewidth-width);
+#else
+         dest += (linewidth-width*4);
+#endif
+      }
+
+      mask <<= 1;
+   }
+}
+
+
+//****************************************************************************
+//
+// DrawBarHealth ()
+//
+//****************************************************************************
+
+void DrawBarHealth
+   (
+   boolean bufferofsonly
+   )
+
+   {
+   int percenthealth;
+   int health_y;
+
+   if ( !SHOW_BOTTOM_STATUS_BAR() )
+      {
+      return;
+      }
+
+   health_y = iGLOBAL_HEALTH_Y;
+   if ( SHOW_KILLS() )
+      {
+      health_y -= KILLS_HEIGHT;
+      }
+
+   percenthealth = ( locplayerstate->health * 10 ) /
+      MaxHitpointsForCharacter( locplayerstate );
+
+   oldpercenthealth = percenthealth + 1;
+
+   if ( playstate == ex_died )
+      {
+      DrawPPic( iGLOBAL_HEALTH_X, health_y, 8 >> 2, 16, ( byte * )&erase->data,
+         10, true, bufferofsonly );
+
+      return;
+      }
+
+   if ( locplayerstate->health <= 0 )
+      {
+      oldpercenthealth = 0;
+      }
+
+   if ( oldpercenthealth >= 11 )
+      {
+      oldpercenthealth = 10;
+      }
+
+   if ( oldpercenthealth < 4 )
+      {
+      DrawPPic( iGLOBAL_HEALTH_X, health_y, 8 >> 2, 16,
+         ( byte * )&health[ 0 ]->data, oldpercenthealth,
+         true, bufferofsonly );
+      }
+   else if ( oldpercenthealth < 5 )
+      {
+      DrawPPic( iGLOBAL_HEALTH_X, health_y, 8 >> 2, 16,
+         (byte *)&health[ 1 ]->data, oldpercenthealth,
+         true, bufferofsonly );
+      }
+   else
+      {
+      DrawPPic( iGLOBAL_HEALTH_X, health_y, 8 >> 2, 16,
+         ( byte * )&health[ 2 ]->data, oldpercenthealth,
+         true, bufferofsonly );
+      }
+
+   if ( oldpercenthealth < 10 )
+      {
+      DrawPPic( iGLOBAL_HEALTH_X + ( 8 * oldpercenthealth ), health_y,
+         8 >> 2, 16, ( byte * )&erase->data, 10 - oldpercenthealth,
+         true, bufferofsonly );
+      }
+   }
+
+
+//****************************************************************************
+//
+// DrawBarAmmo ()
+//
+//****************************************************************************
+
+void DrawBarAmmo
+   (
+   boolean bufferofsonly
+   )
+
+   {
+   int ammo_y;
+
+   if ( ( !SHOW_BOTTOM_STATUS_BAR() ) || ( playstate == ex_died ) )
+      {
+      return;
+      }
+
+   ammo_y = iGLOBAL_AMMO_Y;
+   if ( SHOW_KILLS() )
+      {
+      ammo_y -= KILLS_HEIGHT;
+      }
+
+   DrawPPic ( iGLOBAL_AMMO_X, ammo_y + 1, 8 >> 2, 16, ( byte * )&erase->data,
+      10, false, bufferofsonly );
+
+   if ( !ARMED( player->dirchoosetime ) )
+      {
+      return;
+      }
+   if ((locplayerstate->new_weapon < wp_bazooka) ||
+       (locplayerstate->new_weapon == wp_godhand) ||
+       ( gamestate.BattleOptions.Ammo == bo_infinite_shots )
+      )
+      {
+      DrawPPic( iGLOBAL_AMMO_X - 16, ammo_y, 24 >> 2, 16,
+         ( byte * )&ammo[ 0 ]->data, 1, true, bufferofsonly);
+
+      DrawPPic( iGLOBAL_AMMO_X - 32, ammo_y + 1, 8 >> 2, 16,
+         ( byte * )&erase->data, 2, true, bufferofsonly );
+      }
+#if (SHAREWARE == 0)
+   else if ( locplayerstate->new_weapon == wp_dog )
+      {
+      DrawPPic( iGLOBAL_AMMO_X - 16, ammo_y, 24 >> 2, 16,
+         ( byte * )&ammo[12]->data, 1, true, bufferofsonly );
+
+      DrawPPic( iGLOBAL_AMMO_X - 32, ammo_y + 1, 8 >> 2, 16,
+         ( byte * )&erase->data, 2, true, bufferofsonly );
+      }
+#endif
+   else
+      {
+      DrawPPic( iGLOBAL_AMMO_X, ammo_y + 1, 8 >> 2, 16,
+         ( byte * )&ammo[ locplayerstate->new_weapon]->data,
+         locplayerstate->ammo, false, bufferofsonly );
+      }
+   }
+
+
+//******************************************************************************
+//
+// SingleDrawPPic ()
+//
+//******************************************************************************
+
+void SingleDrawPPic (int xpos, int ypos, int width, int height, byte *src, int num, boolean up)
+{
+   byte *olddest;
+   byte *dest;
+   int x;
+	int y;
+   int planes;
+   byte mask;
+   byte pixel;
+   int k;
+   int amt;
+
+#ifdef DOS
+   if (up)
+      amt = 2;
+   else
+      amt = -2;
+#else
+   if (up)
+      amt = 8;
+   else
+      amt = -8;
+#endif
+
+   mask = 1;
+
+#ifdef DOS
+   olddest = (byte *)(bufferofs - screenofs + ylookup[ypos] + (xpos>>2));
+#else
+   olddest = (byte *)(bufferofs - screenofs + ylookup[ypos] + xpos);
+#endif
+
+   for (planes = 0; planes < 4; planes++)
+   {
+      VGAMAPMASK (mask);
+
+      dest = olddest;
+
+#ifndef DOS
+      dest += planes;
+#endif
+
+      for (y = 0; y < height; y++)
+      {
+         for (x = 0; x < width; x++)
+         {
+            pixel = *src++;
+
+            if (pixel != 255)
+            {
+               for (k = 0; k < num; k++)
+               {
+                  *(dest+(amt*k)) = pixel;
+               }
+            }
+
+#ifdef DOS
+            dest++;
+#else
+            dest += 4;
+#endif
+         }
+
+#ifdef DOS
+         dest += (linewidth-width);
+#else
+         dest += (linewidth-width*4);
+#endif
+      }
+
+      mask <<= 1;
+   }
+}
+
+
+
+//****************************************************************************
+//
+// DrawStats ()
+//
+//****************************************************************************
+
+void DrawStats
+   (
+   void
+   )
+
+   {
+   int percenthealth;
+   int health_y;
+   int ammo_y;
+
+   if ( ( !SHOW_PLAYER_STATS() ) || ( playstate == ex_died ) ||
+      ( locplayerstate->health <= 0 ) )
+      {
+      return;
+      }
+
+// Uncomment this if we want transparent health only on sizes < 16
+//   if ( viewsize < 16 )
+//      {
+//      pic_t *shape;
+//
+//      shape = W_CacheLumpName( "backtile", PU_CACHE );
+//      DrawTiledRegion( 0, 160, 320, 24, shape );
+//      }
+
+   health_y = iGLOBAL_HEALTH_Y;
+   ammo_y   = iGLOBAL_AMMO_Y;
+
+   if ( SHOW_KILLS() )
+      {
+      health_y -= KILLS_HEIGHT;
+      ammo_y   -= KILLS_HEIGHT;
+      }
+
+   if ( oldplayerhealth != locplayerstate->health )
+      {
+      oldplayerhealth = locplayerstate->health;
+
+      percenthealth = ( locplayerstate->health * 10 ) /
+         MaxHitpointsForCharacter( locplayerstate );
+
+      oldpercenthealth = percenthealth + 1;
+      }
+
+   if ( oldpercenthealth > 10 )
+      {
+      oldpercenthealth = 10;
+      }
+
+   if ( oldpercenthealth < 4 )
+      {
+      SingleDrawPPic( iGLOBAL_HEALTH_X - 16, health_y, 8 >> 2, 16,
+         ( byte * )&health[ 3 ]->data, oldpercenthealth, true);
+      }
+   else if ( oldpercenthealth < 5 )
+      {
+      SingleDrawPPic( iGLOBAL_HEALTH_X - 16, health_y, 8 >> 2, 16,
+         ( byte * )&health[ 4 ]->data, oldpercenthealth, true );
+      }
+   else
+      {
+      SingleDrawPPic( iGLOBAL_HEALTH_X - 16, health_y, 8 >> 2, 16,
+         ( byte * )&health[ 5 ]->data, oldpercenthealth, true );
+      }
+
+   if ( ARMED( consoleplayer ) )
+      {
+      if ((locplayerstate->new_weapon < wp_bazooka) ||
+          (locplayerstate->new_weapon == wp_godhand) ||
+          (gamestate.BattleOptions.Ammo == bo_infinite_shots )
+         )
+
+        {
+         SingleDrawPPic( iGLOBAL_AMMO_X - 16, ammo_y, 24 >> 2, 16,
+            ( byte * )&ammo[13]->data, 1, true );
+         }
+#if (SHAREWARE == 0)
+      else if ( locplayerstate->new_weapon == wp_dog )
+         {
+         SingleDrawPPic( iGLOBAL_AMMO_X - 16, ammo_y + 1, 24 >> 2, 16,
+            ( byte * )&ammo[25]->data, 1, true );
+         }
+#endif
+      else
+         {
+         SingleDrawPPic( iGLOBAL_AMMO_X, ammo_y + 1, 8 >> 2, 16,
+            ( byte * )&ammo[13 + locplayerstate->new_weapon]->data,
+            locplayerstate->ammo, false );
+         }
+      }
+   }
+
+
+//****************************************************************************
+//
+// DrawPauseXY ()
+//
+//****************************************************************************
+
+void DrawPauseXY (int x, int y)
+{
+   pic_t *p;
+   byte *buftmp;
+
+   buftmp = bufferofs;
+
+   if (GamePaused == true)
+   {
+      p = (pic_t *) W_CacheLumpNum (W_GetNumForName ("paused"), PU_CACHE, Cvt_pic_t, 1);
+	  VL_MemToScreen ((byte *)&p->data, p->width, p->height,x, y);
+	  //VWB_DrawPic (x, y, p);
+	  bufferofs = buftmp;
+      DrawEpisodeLevel (x,y);
+	  //VL_MemToScreen ((byte *)&p->data, p->width, p->height,x, y);
+
+   }
+   else
+   {
+      p = (pic_t *) W_CacheLumpNum (W_GetNumForName ("wait"), PU_CACHE, Cvt_pic_t, 1);
+	  VL_MemToScreen ((byte *)&p->data, p->width, p->height,x, y);
+      //VWB_DrawPic (x, y, p);
+   }
+   bufferofs = buftmp;
+}
+
+//****************************************************************************
+//
+// DrawPause ()
+//
+//****************************************************************************
+
+void DrawPause (void)
+{
+   pic_t *p;
+   byte *bufftemp = bufferofs;
+
+   bufferofs -= screenofs;
+
+   if (GamePaused == true)
+   {
+	  bufferofs = bufftemp;
+      p = (pic_t *) W_CacheLumpNum (W_GetNumForName ("paused"), PU_CACHE, Cvt_pic_t, 1);
+      DrawPauseXY( (iGLOBAL_SCREENWIDTH-(p->width<<2) ) >>1, (iGLOBAL_SCREENHEIGHT-p->height)>>1);//bna++
+      //DrawPauseXY( (320-(p->width<<2) ) >>1, (200-p->height)>>1);
+/*
+	  //buf = (byte *) SafeMalloc (64000);
+	  w = p->width;
+	  h = p->height;
+	  x = (iGLOBAL_SCREENWIDTH-((p->width)<<2) ) >>1;
+	  y = (iGLOBAL_SCREENHEIGHT-(p->height))>>1;
+
+	  x1 = (iGLOBAL_SCREENWIDTH-((p->width*2)<<2) ) >>1;
+	  y1 = (iGLOBAL_SCREENHEIGHT-(p->height*2))>>1;
+
+	  source = bufferofs + (iGLOBAL_SCREENWIDTH*y)+x;
+	  target = bufferofs + (iGLOBAL_SCREENWIDTH*y1)+x1;
+	  
+	 // memcpy(tmpPICbuf,bufftemp,iGLOBAL_SCREENWIDTH*iGLOBAL_SCREENHEIGHT);
+
+	  bufferofs = bufftemp;//(byte *)tmpPICbuf;//buf;//write picture in tmpbuf
+	  VL_MemToScreen ((byte *)&p->data, p->width, p->height,x, y);
+	  bufferofs = bufftemp;
+	  DrawEpisodeLevel (x,y);
+
+	  
+	  //VL_MemStrechedToScreen ((byte *)&p->data, p->width, p->height,(iGLOBAL_SCREENWIDTH-((p->width*2)<<2) ) >>1, (iGLOBAL_SCREENHEIGHT-(p->height*2))>>1);
+      //DrawEpisodeLevel (x,y);
+	  
+	  //VL_MemToScreen ((byte *)&p->data, p->width, p->height,0, 0);
+	  //bufferofs = bufftemp;//move ptr back
+	  //write it back to bufferofs while streching
+
+	  //buf = bufftemp;
+	  //b = tmpPICbuf ;
+
+	  source = bufferofs + (iGLOBAL_SCREENWIDTH*y)+x+(w*4);
+	  target = bufferofs + (iGLOBAL_SCREENWIDTH*y1)+x+(2*w*4);
+
+	  //first strech lines in x direction
+	  for (y=0;y<h;y++){
+        c=target;t2=source;
+		for (x=0;x<w*4;x++){
+			*target-- = *source;
+			*target-- = *source--;
+		}
+		target=c;source=t2;
+		target += iGLOBAL_SCREENWIDTH;
+		source += iGLOBAL_SCREENWIDTH;
+	  }
+	  //strech then lines in y direction
+	  source -= ((iGLOBAL_SCREENWIDTH*(y/2))+(w*4));//bufferofs + (iGLOBAL_SCREENWIDTH*y)+x+(iGLOBAL_SCREENWIDTH*(y));
+	  target = (source+(iGLOBAL_SCREENWIDTH*(y))+1);//bufferofs + (iGLOBAL_SCREENWIDTH*y)+x+(iGLOBAL_SCREENWIDTH*(y1));
+
+	  for (y=0;y<h;y++){
+		memcpy(target,source,(w*4*2));
+		memcpy(target+iGLOBAL_SCREENWIDTH,source,(w*4*2));
+
+		target -= iGLOBAL_SCREENWIDTH*2;
+		source -= iGLOBAL_SCREENWIDTH;
+	  }
+
+/ *
+	  for (y=0;y<h;y++){
+        c=target;t2=source;
+		for (x=0;x<w*4;x++){
+			*target = *source;
+			*(target+++iGLOBAL_SCREENWIDTH) = *source;
+			*target = *source;
+			*(target+++iGLOBAL_SCREENWIDTH) = *source;
+			source++;
+		}
+		target=c;source=t2;
+		target += iGLOBAL_SCREENWIDTH*2;
+		source += iGLOBAL_SCREENWIDTH;
+	  }
+*/
+
+//	  memcpy( bufftemp,tmpPICbuf,iGLOBAL_SCREENWIDTH*iGLOBAL_SCREENHEIGHT);
+
+   }
+   else
+   {
+      p = (pic_t *) W_CacheLumpNum (W_GetNumForName ("wait"), PU_CACHE, Cvt_pic_t, 1);
+      DrawPauseXY( (iGLOBAL_SCREENWIDTH-(p->width<<2) ) >>1, (iGLOBAL_SCREENHEIGHT-p->height)>>1);//bna++
+      //DrawPauseXY( (320-(p->width<<2) ) >>1, (200-p->height)>>1);
+   }
+//   VH_UpdateScreen () ;
+
+   bufferofs = bufftemp;
+}
+
+//****************************************************************************
+//
+// GM_DrawBonus ()
+//
+//****************************************************************************
+
+void GM_DrawBonus
+   (
+   int which
+   )
+
+   {
+   int    x;
+
+   if ( which < stat_gasmask )
+      {
+      x = POWERUP1X;
+      poweruptime = GetBonusTimeForItem(which);
+      poweradjust = (poweruptime >> 4);
+      powerupheight  = 0;
+      GM_UpdateBonus(poweruptime-poweradjust - 1,true);
+
+      }
+   else
+      {
+      x = POWERUP2X;
+      protectiontime = GetBonusTimeForItem(which);
+      poweradjust = (protectiontime >> 4);
+      protectionheight = 0;
+      GM_UpdateBonus(protectiontime-poweradjust-1,false);
+
+      }
+
+   }
+
+
+//******************************************************************************
+//
+// GM_UpdateBonus ()
+//
+//******************************************************************************
+
+void GM_UpdateBonus
+   (
+   int time,
+   int powerup
+   )
+
+   {
+   pic_t *shape;
+   int    shapenum;
+
+   if ( powerup )
+      {
+      if ( time < ( poweruptime - poweradjust ) )
+         {
+         powerupheight++;
+         if ( !SHOW_TOP_STATUS_BAR() )
+            {
+            poweruptime = time;
+            }
+         }
+      }
+   else
+      {
+      if ( time < ( protectiontime - poweradjust ) )
+         {
+         protectionheight++;
+         if ( !SHOW_TOP_STATUS_BAR() )
+            {
+            protectiontime = time;
+            }
+         }
+      }
+
+
+   if ( !SHOW_TOP_STATUS_BAR() )
+      {
+      return;
+      }
+
+   if ( !time )
+      {
+      if ( powerup == 1 )
+         {
+         shapenum = POWERUP1X;
+         }
+      else
+         {
+         shapenum = POWERUP2X;
+         }
+
+      GM_MemToScreen( ( byte * )&eraseb->data, eraseb->width,
+         eraseb->height, shapenum, POWERUPY );
+
+      return;
+      }
+
+   if ( powerup )
+      {
+      if ( time < ( poweruptime - poweradjust ) )
+         {
+   	   if ( player->flags & FL_GODMODE )
+            {
+            shapenum = powerpics;
+            }
+         else if ( player->flags & FL_DOGMODE )
+            {
+            shapenum = powerpics + 1;
+            }
+         else if ( player->flags & FL_FLEET )
+            {
+            shapenum = powerpics + 2;
+            }
+         else if ( player->flags & FL_ELASTO )
+            {
+            shapenum = powerpics + 3;
+            }
+         else if ( player->flags & FL_SHROOMS )
+            {
+            shapenum = powerpics + 4;
+            }
+         else
+            {
+            GM_MemToScreen( ( byte * )&eraseb->data,
+               eraseb->width, eraseb->height, POWERUP1X, POWERUPY );
+
+            return;
+            }
+
+         poweruptime = time;
+
+         shape = ( pic_t * )W_CacheLumpNum( shapenum, PU_CACHE, Cvt_pic_t, 1 );
+
+         GM_MemToScreen( ( byte * )&eraseb->data, eraseb->width,
+            eraseb->height, POWERUP1X, POWERUPY );
+
+         DrawMPPic( POWERUP1X, POWERUPY + powerupheight, shape->width,
+            shape->height - powerupheight, powerupheight,
+            ( byte * )&shape->data, false );
+         }
+      }
+   else
+      {
+      if ( time < ( protectiontime - poweradjust ) )
+         {
+         if ( player->flags & FL_BPV )
+            {
+            shapenum = powerpics + 6;
+            }
+         else if ( player->flags & FL_GASMASK )
+            {
+            shapenum = powerpics + 5;
+            }
+         else if ( player->flags & FL_AV )
+            {
+            shapenum = powerpics + 7;
+            }
+
+         protectiontime = time;
+
+         shape = ( pic_t * )W_CacheLumpNum( shapenum, PU_CACHE, Cvt_pic_t, 1 );
+
+         GM_MemToScreen( ( byte * )&eraseb->data, eraseb->width,
+            eraseb->height, POWERUP2X, POWERUPY );
+
+         DrawMPPic( POWERUP2X, POWERUPY + protectionheight,
+            shape->width, shape->height - protectionheight,
+            protectionheight, ( byte * )&shape->data, false );
+         }
+      }
+   }
+
+
+//******************************************************************************
+//
+// Drawpic ()
+//
+// Purpose
+//    Draws a masked, planer pic at xpos, ypos.
+//
+// Parms
+//    xpos   - x position.
+//    ypos   - y position.
+//    width  - width of pic : should be << 2.
+//    height - height of pic.
+//    src    - data to draw.
+//
+// Returns
+//    Nothing.
+//
+//******************************************************************************
+
+void Drawpic (int xpos, int ypos, int width, int height, byte *src)
+{
+   byte *olddest;
+   byte *dest;
+   int x;
+   int y;
+   int planes;
+   byte mask;
+   byte pixel;
+
+
+   mask = 1 << (xpos&3);
+
+#ifdef DOS
+   olddest = (byte *)(bufferofs + ylookup[ypos] + (xpos>>2));
+#else
+   olddest = (byte *)(bufferofs + ylookup[ypos] + xpos);
+#endif
+   for (planes = 0; planes < 4; planes++)
+   {
+      VGAMAPMASK (mask);
+
+      dest = olddest;
+
+#ifdef DOS
+      dest += planes;
+#endif
+
+      for (y = 0; y < height; y++)
+      {
+         for (x = 0; x < width; x++)
+         {
+            pixel = *src++;
+
+            if (pixel != 255)
+               *(dest) = pixel;
+
+#ifdef DOS
+            dest++;
+#else
+            dest += 4;
+#endif
+         }
+
+#ifdef DOS
+         dest += (linewidth-width);
+#else
+         dest += (linewidth-width*4);
+#endif
+      }
+      
+#ifdef DOS
+      mask <<= 1;
+      if (mask == 16)
+		{
+         mask = 1;
+         olddest++;
+      }
+#endif
+   }
+}
+
+
+//******************************************************************************
+//
+// DrawEpisodeLevel ()
+//
+// right justifies and pads with blanks
+//
+//******************************************************************************
+
+void  DrawEpisodeLevel (int x, int y)
+{
+   int level;
+   char  str[20];
+   pic_t *p;
+
+   if (!BATTLEMODE)
+   {
+      ltoa (gamestate.episode, str, 10);
+
+      //bna-- Drawpic (x+29, y+16, 8>>2, 16, (byte *)&timenums[str[0]-'0']->data);
+	  VL_MemToScreenClipped ((byte *)&timenums[str[0]-'0']->data,  8>>2, 16, x+29, y+16);
+
+      if ((gamestate.mapon == 6) || (gamestate.mapon == 14) ||
+          (gamestate.mapon == 22) || (gamestate.mapon == 32) ||
+          (gamestate.mapon == 33))
+      {
+         p = (pic_t *) W_CacheLumpName ("tnumb", PU_CACHE, Cvt_pic_t, 1);
+         //Drawpic (x+40, y+16, 8>>2, 16, (byte *)&p->data);
+		 VL_MemToScreenClipped ((byte *)&p->data, 8>>2, 16, x+40, y+16);
+
+         if (gamestate.mapon == 6)
+            level = 1;
+         else
+            if (gamestate.mapon == 14)
+               level = 2;
+            else
+               if (gamestate.mapon == 22)
+                  level = 3;
+               else
+                  if (gamestate.mapon == 32)
+							level = 4;
+                  else
+                     level = 5;
+      }
+      else
+         level = GetLevel (gamestate.episode, gamestate.mapon);
+
+      level = abs(level);
+      ltoa (level, str, 10);
+
+      if (level < 10){
+         //Drawpic (x+49, y+16, 8>>2, 16, (byte *)&timenums[str[0]-'0']->data);
+	     VL_MemToScreenClipped ((byte *)&timenums[str[0]-'0']->data, 8>>2, 16, x+49, y+16);
+      }else{
+         //Drawpic (x+49, y+16, 8>>2, 16, (byte *)&timenums[str[0]-'0']->data);
+		 VL_MemToScreenClipped ((byte *)&timenums[str[0]-'0']->data, 8>>2, 16, x+49, y+16);
+         //Drawpic (x+57, y+16, 8>>2, 16, (byte *)&timenums[str[1]-'0']->data);
+		 VL_MemToScreenClipped ((byte *)&timenums[str[1]-'0']->data, 8>>2, 16, x+57, y+16);
+
+      }
+   }
+   else
+   {
+      p = (pic_t *) W_CacheLumpName ("battp", PU_CACHE, Cvt_pic_t, 1);
+      //Drawpic (x+16, y+15, 32>>2, 16, (byte *)&p->data);
+	  VL_MemToScreenClipped ((byte *)&p->data, 32>>2, 16, x+16, y+15);
+
+      level = abs(gamestate.mapon + 1);
+      ltoa (level, str, 10);
+
+      if (level < 10){
+         //Drawpic (x+49, y+16, 8>>2, 16, (byte *)&timenums[str[0]-'0']->data);
+	     VL_MemToScreenClipped ((byte *)&timenums[str[0]-'0']->data, 8>>2, 16, x+49, y+16);
+      }else {
+         //Drawpic (x+49, y+16, 8>>2, 16, (byte *)&timenums[str[0]-'0']->data);
+		 VL_MemToScreenClipped ((byte *)&timenums[str[0]-'0']->data, 8>>2, 16, x+49, y+16);
+         //Drawpic (x+57, y+16, 8>>2, 16, (byte *)&timenums[str[1]-'0']->data);
+		 VL_MemToScreenClipped ((byte *)&timenums[str[1]-'0']->data, 8>>2, 16, x+57, y+16);
+      }
+   }
+}
+
+
+//******************************************************************************
+//
+// GM_MemToScreen ()
+//
+//******************************************************************************
+
+void GM_MemToScreen (byte *source, int width, int height, int x, int y)
+{
+   int dest;
+   byte *dest1, *dest2, *dest3, mask;
+   byte *screen1, *screen2, *screen3;
+   int  plane;
+   int w;
+   
+#ifdef DOS
+   dest = ylookup[y]+(x>>2);
+#else
+   dest = ylookup[y]+x;
+#endif
+   mask = 1 << (x&3);
+
+   dest1 = (byte *)(dest+page1start);
+   dest2 = (byte *)(dest+page2start);
+   dest3 = (byte *)(dest+page3start);
+
+   for (plane = 0; plane<4; plane++)
+   {
+      VGAMAPMASK (mask);
+
+      screen1 = dest1;
+      screen2 = dest2;
+      screen3 = dest3;
+      for (y = 0; y < height; y++, screen1 += linewidth,
+                                   screen2 += linewidth,
+                                   screen3 += linewidth, source+=width)
+      {
+#ifdef DOS
+         memcpy (screen1, source, width);
+         memcpy (screen2, source, width);
+         memcpy (screen3, source, width);
+#else
+	for (x = 0; x < width; x++) {
+		screen1[x*4+plane] = source[x];
+		screen2[x*4+plane] = source[x];
+		screen3[x*4+plane] = source[x];
+	}
+#endif
+      }
+
+#ifdef DOS
+      mask <<= 1;
+
+      if (mask == 16)
+      {
+         mask = 1;
+         dest1++;
+         dest2++;
+         dest3++;
+      }
+#endif
+   }
+}
+
+
+//==========================================================================
+
+/*
+==================
+=
+= ScreenShake
+=
+==================
+*/
+
+void ScreenShake (void)
+{
+   static int which = 0;
+//	   SetTextMode (  );
+   if (SHAKETICS != 0xFFFF)
+   {
+      SHAKETICS -= tics;
+	  if (SHAKETICS >= 0xFF00){SHAKETICS = 0xFFFF;}//bna safety val check
+
+      which = (RandomNumber ("ScreenShake",0) & 3);
+
+      switch (which)
+      {
+         case 0:
+            displayofs += 1;
+			MoveScreenUpLeft();//SetTextMode (  );
+			DrawPlayScreen(true);//repaint ammo and life stat
+         break;
+
+         case 1:
+            displayofs -= 1;
+			MoveScreenUpRight();
+			DrawPlayScreen(true);//repaint ammo and life stat
+         break;
+
+         case 2:
+            displayofs += 3*iGLOBAL_SCREENBWIDE;
+			MoveScreenDownLeft();
+			DrawPlayScreen(true);//repaint ammo and life stat
+         break;
+
+         case 3:
+            displayofs -= 3*iGLOBAL_SCREENBWIDE;
+			MoveScreenDownRight();
+			DrawPlayScreen(true);//repaint ammo and life stat
+         break;
+      }
+
+   }
+}
+
+//******************************************************************************
+//
+// DoBorderShifts ()
+//
+//******************************************************************************
+
+void DoBorderShifts (void)
+{
+	if (damagecount)
+   {
+      if (damagecount > 100)
+         damagecount = 100;
+
+      damagecount -= 6;
+
+      if (damagecount < 0)
+         damagecount = 0;
+
+      SetBorderColor (*(colormap+(((100-damagecount)>>2)<<8)+48));
+
+      borderset = true;
+   }
+   else
+      if (borderset)
+      {
+         SetBorderColor (0);
+         borderset = false;
+      }
+}
+
+
+//******************************************************************************
+//
+// DrawHighScores ()
+//
+//******************************************************************************
+
+void DrawHighScores (void)
+{
+   char buffer[16];
+#if (SHAREWARE == 0)
+   char buffer1[5];
+#endif
+   int  i,
+        w,
+        h;
+   HighScore *s;
+
+   for (i = 0, s = Scores; i < MaxScores; i++, s++)
+   {
+      PrintY = 25 + (16 * i);
+
+      //
+      // name
+      //
+		PrintX = 3*8;
+      DrawMenuBufPropString (PrintX, PrintY, s->name);
+
+      //
+      // level
+      //
+      ultoa (s->completed, buffer, 10);
+
+      PrintX = (17 * 8)-10;
+#if (SHAREWARE == 0)
+      itoa (s->episode, buffer1, 10);
+
+      DrawMenuBufPropString (PrintX, PrintY, buffer1);
+#else
+      DrawMenuBufPropString (PrintX, PrintY, "S");
+#endif
+
+      DrawMenuBufPropString (PrintX, PrintY, "-");
+
+#if (SHAREWARE == 0)
+      if (s->completed == 7)
+         DrawMenuBufPropString (PrintX, PrintY, "B");
+      else if (s->completed == 8)
+         DrawMenuBufPropString (PrintX, PrintY, "S");
+      else if (s->completed == 9)
+         DrawMenuBufPropString (PrintX, PrintY, "C");
+      else if (s->completed == 10)
+         DrawMenuBufPropString (PrintX, PrintY, "D");
+      else
+         DrawMenuBufPropString (PrintX, PrintY, buffer);
+#else
+      DrawMenuBufPropString (PrintX, PrintY, buffer);
+#endif
+
+      //
+      // score
+      //
+      ultoa(s->score,buffer,10);
+
+      VW_MeasurePropString (buffer, &w, &h);
+      PrintX = (33 * 8) - w;
+      DrawMenuBufPropString (PrintX, PrintY, buffer);
+   }
+}
+
+
+
+//******************************************************************************
+//
+// CheckHighScore ()
+//
+//******************************************************************************
+
+void CheckHighScore (long score, word other, boolean INMENU)
+{
+   word        i,j;
+   int         n;
+   HighScore   myscore;
+   int         level;
+
+   MenuFadeIn();
+   if (!INMENU)
+      SetupMenuBuf ();
+
+   strcpy (myscore.name,"");
+   myscore.score     = score;
+
+   level = GetLevel (gamestate.episode, other-1);
+
+   myscore.episode   = gamestate.episode;
+   myscore.completed = level;
+
+   CurrentFont = smallfont;
+
+   for (i = 0, n = -1; i < MaxScores; i++)
+   {
+      if ((myscore.score > Scores[i].score)  ||
+         ((myscore.score == Scores[i].score) &&
+          (myscore.completed > Scores[i].completed)))
+      {
+         for (j = MaxScores; --j > i;)
+            Scores[j] = Scores[j - 1];
+         Scores[i] = myscore;
+         n = i;
+         break;
+      }
+   }
+
+   if (INMENU)
+   {
+      SetAlternateMenuBuf();
+      SetMenuTitle ("High Scores");
+      ClearMenuBuf();
+      DrawHighScores ();
+		if (n != -1)
+         DisplayInfo (6);
+      else
+         DisplayInfo (5);
+      FlipMenuBuf ();
+   }
+   else
+   {
+      ClearMenuBuf ();
+      SetMenuTitle ("High Scores");
+      DrawHighScores ();
+      if (n != -1)
+         DisplayInfo (6);
+      else
+         DisplayInfo (5);
+      RefreshMenuBuf (0);
+   }
+
+   if (n != -1)
+   {
+      PrintY = 25 + (16 * n);
+      PrintX = 3*8;
+      US_LineInput (PrintX, PrintY, Scores[n].name, NULL,
+                    true, 10, 98, 0);
+   }
+   else
+   {
+      IN_ClearKeysDown ();
+      if ( INMENU )
+         {
+         while( !IN_CheckAck () )
+            {
+            RefreshMenuBuf (0);
+            }
+         }
+      else
+         {
+         for( i = 0; i <= 150; i += tics )
+            {
+            RefreshMenuBuf (0);
+            if (IN_CheckAck ())
+               {
+               break;
+               }
+            }
+         }
+      }
+
+   if (INMENU)
+      {
+      SD_Play (SD_ESCPRESSEDSND);
+      }
+   else
+      {
+      ShutdownMenuBuf ();
+      }
+   }
+
+
+//===========================================================================
+
+//#define HEADERX      140
+//#define BONERNAMEX   170
+#define HEADERX      152
+#define BONERNAMEX   166
+
+
+/*
+==================
+=
+= DrawEOLHeader ()
+=
+==================
+*/
+void DrawEOLHeader
+   (
+   int playstate
+   )
+
+   {
+   int  health;
+   char tempstr[ 15 ];
+   char *string;
+   int  level;
+   int  w;
+   int  h;
+
+   VWB_TBar( 30, 5, 250, 75 );
+
+   switch( playstate )
+      {
+      case ex_skiplevel :
+         if ( ( gamestate.violence >= vl_high ) &&
+            ( gamestate.difficulty >= gd_hard ) )
+            {
+            string = "LEVEL WUSSED OUT ON!";
+            }
+         else
+            {
+            string = "LEVEL SKIPPED.";
+            }
+         break;
+
+      case ex_secretdone :
+         string = "SECRET LEVEL COMPLETED!";
+         break;
+
+      case ex_secretlevel :
+         string = "SECRET EXIT TAKEN!";
+         break;
+
+      case ex_gameover :
+         string = "GAME COMPLETED!";
+         break;
+
+      case ex_bossdied :
+         string = "BOSS DEFEATED!";
+         break;
+
+      default :
+         string = "LEVEL COMPLETED!";
+         break;
+      }
+
+   VW_MeasurePropString( string, &w, &h );
+
+   px = ( 320 - w ) / 2;
+   py = 10;
+   VWB_DrawPropString( string );
+
+   // draw episode number
+   string = "EPISODE";
+   VW_MeasurePropString( string, &w, &h );
+   px = HEADERX - w;
+   py = 25;
+   VWB_DrawPropString( string );
+
+   itoa( gamestate.episode, tempstr, 10 );
+   px = BONERNAMEX;
+   VWB_DrawPropString( tempstr );
+
+   // draw area number
+   level = GetLevel( gamestate.episode, gamestate.mapon );
+   itoa( level, tempstr, 10 );
+
+   py = 35;
+
+   if ( playstate == ex_secretdone )
+      {
+      string = "SECRET AREA";
+      }
+   else if ( playstate == ex_bossdied )
+      {
+      string = "BOSS AREA";
+      }
+   else if ( gamestate.mapon == 32 )
+      {
+      string = "CHASE AREA";
+      }
+   else
+      {
+      string = "AREA";
+      }
+
+   VW_MeasurePropString( string, &w, &h);
+   px = HEADERX - w;
+   VWB_DrawPropString( string );
+
+   if ( gamestate.mapon != 33 )
+      {
+      px = BONERNAMEX;
+      VWB_DrawPropString( tempstr );
+      }
+
+   string = "SCORE";
+   VW_MeasurePropString( string, &w, &h);
+   px = HEADERX - w;
+   py = 45;
+   VWB_DrawPropString( string );
+
+   px = BONERNAMEX;
+   itoa( gamestate.score, tempstr, 10 );
+	VWB_DrawPropString( tempstr );
+
+   string = "HEALTH";
+   VW_MeasurePropString( string, &w, &h );
+   px = HEADERX - w;
+   py = 55;
+   VWB_DrawPropString( string );
+
+   px = BONERNAMEX;
+   health = ( ( locplayerstate->health * 100 ) /
+      MaxHitpointsForCharacter( locplayerstate ) );
+
+   itoa( health, tempstr, 10 );
+   VWB_DrawPropString( tempstr );
+   VWB_DrawPropString( "%" );
+
+   //
+   // Secret count
+   //
+
+   {
+   char str1[10];
+   char str2[10];
+
+   itoa(gamestate.secretcount,&(str1[0]),10);
+   strcat(str1," / ");
+   itoa(gamestate.secrettotal,&(str2[0]),10);
+   strcat(str1,str2);
+   string = "SECRET WALLS";
+   VW_MeasurePropString( string, &w, &h );
+   px = HEADERX - w;
+   py = 65;
+   VWB_DrawPropString( string );
+
+   px = BONERNAMEX;
+   VWB_DrawPropString( str1 );
+   }
+
+   VW_UpdateScreen ();
+   }
+
+boolean EndBonusFirst;
+boolean EndBonusSkip;
+int     EndBonusNumBonuses;
+int     EndBonusVoice;
+int     EndBonusStartY;
+
+void DrawEndBonus
+   (
+   char *string,
+   char *bonusstring,
+   int   type
+   )
+
+   {
+   int w;
+   int h;
+   int  health;
+   char tempstr[ 15 ];
+
+   if ( EndBonusFirst )
+      {
+      VWB_TBar( 5, EndBonusStartY - 2, 310, 4 );
+      EndBonusFirst = false;
+      }
+
+   VWB_TBar( 5, EndBonusStartY + 2, 310, 10 );
+   VW_MeasurePropString( string, &w, &h );
+
+   py = EndBonusStartY;
+   if ( bonusstring == NULL )
+      {
+      px = ( 320 - w ) / 2;
+      VWB_DrawPropString( string );
+      }
+   else
+      {
+      px = BONERNAMEX - w;
+      VWB_DrawPropString( string );
+
+      EndBonusNumBonuses++;
+      VW_MeasurePropString( bonusstring, &w, &h );
+      px = 310 - w;
+      py = EndBonusStartY;
+      VWB_DrawPropString( bonusstring );
+      }
+
+   // Update Score
+   py = 45;
+   px = BONERNAMEX;
+   V_ReDrawBkgnd( px, py, 107, 11, false );
+   VWB_TBar( px, py, 107, 11 );
+   itoa( gamestate.score, tempstr, 10 );
+   VWB_DrawPropString( tempstr );
+
+   // Update Health
+   py = 55;
+   px = BONERNAMEX;
+   V_ReDrawBkgnd( px, py, 107, 11, false );
+   VWB_TBar( px, py, 107, 11 );
+   health = ( ( locplayerstate->health * 100 ) /
+      MaxHitpointsForCharacter( locplayerstate ) );
+   itoa( health, tempstr, 10 );
+   VWB_DrawPropString( tempstr );
+   VWB_DrawPropString( "%" );
+
+   switch( type )
+      {
+      case 0 :
+         EndBonusVoice = SD_Play( SD_ENDBONUS1SND );
+         break;
+
+      case 1 :
+         EndBonusVoice = SD_Play( SD_NOBONUSSND );
+         break;
+
+      case 2 :
+         VL_FillPalette(255,255,255);
+         //bna--VW_UpdateScreen();
+         VL_FadeIn(0,255,origpal,10);
+         EndBonusVoice = SD_Play( SD_LIGHTNINGSND );
+         break;
+      }
+
+   EndBonusStartY += 10;
+
+   //bna--VW_UpdateScreen();
+   while( SD_SoundActive( EndBonusVoice ) && !EndBonusSkip )
+      {
+      if ( IN_CheckAck() )
+         {
+         EndBonusSkip = true;
+         }
+      }
+   }
+
+
+
+/*
+==================
+=
+= LevelCompleted
+=
+= Exit with the screen faded out
+=
+==================
+*/
+
+extern int OLDLMWEAPON;
+extern int OLDLWEAPON;
+
+void LevelCompleted
+   (
+   exit_t playstate
+   )
+
+   {
+   objtype *obj;
+   boolean dobonus;
+   int i;
+   int kr;
+   int sr;
+   int tr;
+   int missileratio;
+   int superratio;
+   int healthratio;
+   int democraticratio;
+   int plantratio;
+   int cnt;
+
+   pic_t *tmpPic;
+//   byte *picbuf;
+
+   EndBonusNumBonuses = 0;
+   EndBonusFirst      = true;
+   EndBonusSkip       = false;
+   EndBonusStartY     = 90;
+
+   EnableScreenStretch();
+   tmpPic = ( pic_t * )W_CacheLumpName( "mmbk", PU_CACHE, Cvt_pic_t, 1 );
+   VWB_DrawPic( 0, 0, tmpPic );
+   VW_UpdateScreen();
+   DisableScreenStretch();
+
+   IN_StartAck();
+   EndBonusVoice = 0;
+
+
+   if ( playstate != ex_bossdied )
+      {
+      EndBonusVoice = SD_Play( SD_LEVELDONESND );
+      VL_FillPalette( 255, 255, 255 );
+      VL_FadeIn( 0, 255, origpal, 10 );
+      if ( player->flags & FL_DOGMODE )
+         {
+         MU_StartSong( song_dogend );
+         }
+      else
+         {
+         MU_StartSong( song_endlevel );
+         }
+      }
+
+   BkPic = ( pic_t * )W_CacheLumpName( "mmbk", PU_CACHE, Cvt_pic_t, 1 );
+   VWB_DrawPic( 0, 0, BkPic );
+
+   CheckHolidays();
+   CurrentFont = smallfont;
+
+   // Kill powerups
+   if ( player->flags & FL_ELASTO )
+      {
+      player->flags &= ~FL_NOFRICTION;
+      }
+
+   player->flags &= ~( FL_FLEET | FL_SHROOMS | FL_ELASTO | FL_GODMODE |
+      FL_DOGMODE | FL_BPV | FL_AV | FL_GASMASK );
+
+   // Turn off quickload for next level
+   pickquick = false;
+
+   //
+   // FIGURE RATIOS OUT BEFOREHAND
+   //
+   kr = 0;
+   tr = 0;
+   tr = 0;
+   superratio      = 0;
+   missileratio    = 0;
+   healthratio     = 0;
+   democraticratio = 0;
+   plantratio      = 0;
+
+   if ( gamestate.killtotal )
+      {
+      kr = ( int )( ( ( int )gamestate.killcount ) * 100 ) /
+         ( ( int )gamestate.killtotal );
+      }
+
+   if ( gamestate.secrettotal )
+      {
+      sr = ( int )( ( ( int )gamestate.secretcount ) * 100 ) /
+         ( ( int )gamestate.secrettotal );
+      }
+
+   if ( gamestate.treasuretotal )
+      {
+      tr = ( int )( ( ( int )gamestate.treasurecount ) * 100 ) /
+         ( ( int )gamestate.treasuretotal );
+      }
+
+   if ( gamestate.supertotal )
+      {
+      superratio = ( int )( ( ( int )gamestate.supercount ) * 100 ) /
+         ( ( int )gamestate.supertotal );
+      }
+
+   if ( gamestate.missiletotal )
+      {
+      missileratio = ( int )( ( ( int )gamestate.missilecount ) * 100 ) /
+         ( ( int )gamestate.missiletotal );
+      }
+
+   if ( gamestate.healthtotal )
+      {
+      healthratio = ( int )( ( ( int )gamestate.healthcount ) * 100 ) /
+         ( ( int )gamestate.healthtotal );
+      }
+
+   if ( gamestate.democratictotal )
+      {
+      democraticratio = ( int )( ( ( int )gamestate.democraticcount ) *
+         100 ) / ( ( int )gamestate.democratictotal );
+      }
+
+   if ( gamestate.planttotal )
+      {
+      plantratio = ( int )( ( ( int )gamestate.plantcount ) * 100 ) /
+         ( ( int )gamestate.planttotal );
+      }
+
+   DrawEOLHeader( playstate );
+/*
+	//bna section  store picture  because its written on again
+   // store screen first
+   picbuf = (byte *)SafeMalloc (64000);
+   memcpy(picbuf ,bufferofs ,64000);
+
+   EnableScreenStretch();
+   VW_UpdateScreen();//tmpPICbuf is destroyed here
+   DisableScreenStretch();
+   //copy it back
+
+   memcpy(bufferofs ,picbuf , 64000);
+	//bna section end
+*/
+   
+EndBonusSkip = true;
+
+   while( SD_SoundActive( EndBonusVoice ) && !EndBonusSkip )
+      {
+
+      //bna--VW_UpdateScreen();
+
+      if ( IN_CheckAck() )
+         {
+         EndBonusSkip = true;
+         }
+      }
+ //  tmpPic = ( pic_t * )W_CacheLumpName( "mmbk", PU_CACHE, Cvt_pic_t, 1 );
+ //  VWB_DrawPic( 0, 0, tmpPic );
+    
+   if ( GetNextMap(player->tilex,player->tiley) == -1)
+      {
+   	if ( gamestate.dipballs == 3 )
+         {
+         gamestate.score += 100000;
+         DrawEndBonus( "DIP BONUS", "100000 POINTS", 0 );
+         EndBonusStartY += 10;
+         }
+
+      if ( locplayerstate->lives > 0 )
+         {
+         char str[20];
+         char str2[60];
+
+         DrawEndBonus( "EXTRA LIVES BONUS", "\0", 0 );
+         itoa(locplayerstate->lives,str,10);
+         strcpy(str2,str);
+         strcat(str2," EXTRA LIVES =");
+         DrawEndBonus( "\0", str2, 0 );
+         itoa(locplayerstate->lives,str,10);
+         strcpy(str2,str);
+         strcat(str2," X 10000 = ");
+         itoa(locplayerstate->lives*10000,str,10);
+         strcat(str2,str);
+         strcat(str2," POINTS");
+         gamestate.score += 10000*locplayerstate->lives;
+         DrawEndBonus( "\0", str2, 0 );
+         }
+      }
+   else
+      {
+      //
+      // Check for SKIN OF YO TEETH
+      //
+      if ( locplayerstate->health <= 10 )
+         {
+         locplayerstate->health = MaxHitpointsForCharacter( locplayerstate );
+         DrawEndBonus( "SKIN OF YOUR TEETH", "100% HEALTH", 0 );
+         }
+
+      // BULL IN CHINA SHOP BONUS
+      if ( tr == 100 )
+         {
+         gamestate.score += 10000;
+         DrawEndBonus( "BULL IN CHINA SHOP", "10000 POINTS", 0 );
+         }
+
+      // SUPERCHARE BONUS
+      if ( superratio == 100 )
+         {
+         gamestate.score += 10000;
+         DrawEndBonus( "SUPERCHARGE BONUS", "10000 POINTS", 0 );
+         }
+
+      // BLEEDER BONUS
+      if ( healthratio == 100 )
+         {
+         gamestate.score += 10000;
+         DrawEndBonus( "BLEEDER BONUS", "10000 POINTS", 0 );
+         }
+
+      // ADRENALINE BONUS
+      if ( kr == 100 )
+         {
+         gamestate.score += 10000;
+         DrawEndBonus( "ADRENALINE BONUS", "10000 POINTS", 0 );
+         }
+
+      // CURIOSITY BONUS
+      dobonus = true;
+
+      //
+      // Check switches
+      cnt = lastswitch - &switches[ 0 ];
+      if ( cnt != 0 )
+         {
+         for ( i = 0; i < cnt; i++ )
+            {
+            if ( ( switches[ i ].flags & FL_S_FLIPPED ) == 0 )
+               {
+               dobonus = false;
+               break;
+               }
+            }
+         }
+
+      //
+      // Check pillars
+      for ( obj = FIRSTACTOR; obj != NULL; obj = obj->next )
+         {
+         if ( ( obj->obclass == pillarobj ) &&
+            ( ( obj->flags & FL_FLIPPED ) == 0 ) )
+            {
+            dobonus = false;
+            }
+         }
+
+      if ( ( gamestate.secrettotal ) && ( sr != 100 ) )
+         {
+         dobonus = false;
+         }
+
+      if ( dobonus )
+         {
+         gamestate.score += 10000;
+         DrawEndBonus( "CURIOSITY BONUS", "10000 POINTS", 0 );
+         }
+
+      // GROUND ZERO BONUS
+      if ( gamestate.DOGROUNDZEROBONUS )
+         {
+         gamestate.score += 10000;
+         DrawEndBonus( "GROUND ZERO BONUS", "10000 POINTS", 0 );
+         }
+
+      // REPUBLICAN BONUS 1
+      if ( missileratio == 100 )
+         {
+         gamestate.score += 5000;
+         DrawEndBonus( "REPUBLICAN BONUS 1", " 5000 POINTS", 0 );
+         }
+
+      // REPUBLICAN BONUS 2
+      if (plantratio == 100)
+         {
+         gamestate.score += 5000;
+         DrawEndBonus( "REPUBLICAN BONUS 2", " 5000 POINTS", 0 );
+         }
+
+      // DEMOCRATIC BONUS 1
+      if ( gamestate.DODEMOCRATICBONUS1 )
+         {
+         gamestate.score += 5000;
+         DrawEndBonus( "DEMOCRATIC BONUS 1", " 5000 POINTS", 0 );
+         }
+
+      // DEMOCRATIC BONUS 2
+      if (democraticratio == 100)
+         {
+         gamestate.score += 5000;
+         DrawEndBonus( "DEMOCRATIC BONUS 2", " 5000 POINTS", 0 );
+         }
+      }
+
+   if ( EndBonusNumBonuses == 0 )
+      {
+      DrawEndBonus( "NO BONUS!", NULL, 1 );
+      }
+
+   if ( ( EndBonusNumBonuses != 0 ) || ( playstate == ex_gameover ) )
+      {
+      SD_Play( PlayerSnds[ locplayerstate->player ] );
+
+      // DO BONUS BONUS
+      if ( EndBonusNumBonuses == NUMBONUSES )
+         {
+         IN_StartAck();
+         while( !IN_CheckAck() )
+            {
+            ;
+            }
+
+         BkPic = ( pic_t * )W_CacheLumpName( "mmbk", PU_CACHE, Cvt_pic_t, 1 );
+         VWB_DrawPic( 0, 0, BkPic );
+
+         gamestate.score += BONUSBONUS;
+         DrawEOLHeader( playstate );
+         EndBonusFirst = true;
+         EndBonusStartY = 110;
+         EndBonusSkip = true;
+         DrawEndBonus( "BONUS BONUS!  1,000,000 POINTS!", NULL, 2 );
+         }
+      else if ( ( kr == 100 ) && ( dobonus ) )
+         {
+         IN_StartAck();
+         while( !IN_CheckAck() )
+            {
+            ;
+            }
+
+         BkPic = ( pic_t * )W_CacheLumpName( "mmbk", PU_CACHE, Cvt_pic_t, 1 );
+         VWB_DrawPic( 0, 0, BkPic );
+
+         DrawEOLHeader( playstate );
+         EndBonusFirst = true;
+         EndBonusStartY = 110;
+         DrawEndBonus( "You have done well.", NULL, 3 );
+		 
+#if (SHAREWARE==1)
+         EndBonusVoice = SD_Play( SD_RICOCHET3SND );
+#else
+         EndBonusVoice = SD_Play( SD_PERCENT100SND );
+#endif
+		 
+         EndBonusSkip = false;
+         DrawEndBonus( "This level is toast.", NULL, 3 );
+
+         }
+      }
+    	  
+    
+
+	//bna section 
+    EnableScreenStretch();//bna++
+    VW_UpdateScreen();//bna++
+//    DisableScreenStretch();//bna++
+	//bna section end
+
+
+   IN_StartAck();
+   while( !IN_CheckAck() )
+      {
+      ;
+      }
+
+   EndLevelStuff = false;
+   CurrentFont = smallfont;
+   }
+
+
+void DrawTallyHeader
+   (
+   int which
+   )
+
+   {
+   pic_t *Name;
+   pic_t *KillCount;
+   pic_t *TimesYouKilledPerson;
+   pic_t *TimesPersonKilledYou;
+   pic_t *Suicides;
+   pic_t *Score;
+   pic_t *Blank;
+   pic_t *TopBar;
+
+   Name                 = ( pic_t * )W_CacheLumpName( "t_name",    PU_CACHE, Cvt_pic_t, 1 );
+   Blank                = ( pic_t * )W_CacheLumpName( "t_blnk",    PU_CACHE, Cvt_pic_t, 1 );
+   KillCount            = ( pic_t * )W_CacheLumpName( "t_kcount",  PU_CACHE, Cvt_pic_t, 1 );
+   TimesYouKilledPerson = ( pic_t * )W_CacheLumpName( "t_kilper",  PU_CACHE, Cvt_pic_t, 1 );
+   TimesPersonKilledYou = ( pic_t * )W_CacheLumpName( "t_perkil" , PU_CACHE, Cvt_pic_t, 1 );
+   Suicides             = ( pic_t * )W_CacheLumpName( "t_suicid",  PU_CACHE, Cvt_pic_t, 1 );
+   Score                = ( pic_t * )W_CacheLumpName( "t_score",   PU_CACHE, Cvt_pic_t, 1 );
+   TopBar               = ( pic_t * )W_CacheLumpName( "t_bar",     PU_CACHE, Cvt_pic_t, 1 );
+
+   IFont = ( cfont_t * )W_CacheLumpName( "sifont", PU_CACHE, Cvt_cfont_t, 1 );
+
+   switch( which )
+      {
+      case 0 :
+         VWB_DrawPic (   8,  8, TopBar );
+         DrawIntensityString( 12, 11, "FINAL SCORE", 20 );
+         VWB_DrawPic (   8, 24, Name );
+         VWB_DrawPic ( 136, 24, KillCount );
+         VWB_DrawPic ( 184, 24, Suicides );
+         VWB_DrawPic ( 272, 24, Score );
+         break;
+
+      case 1 :
+         VWB_DrawPic (   8,  8, TopBar );
+         DrawIntensityString( 12, 11, "FINAL SCORE", 20 );
+         VWB_DrawPic (   8, 24, Name );
+         VWB_DrawPic ( 136, 24, Blank );
+         VWB_DrawPic ( 272, 24, Score );
+         break;
+
+      case 2 :
+         VWB_DrawPic (   8,  8, TopBar );
+         DrawIntensityString( 12, 11, "YOUR KILLS", 20 );
+         VWB_DrawPic (   8, 24, Name );
+         VWB_DrawPic ( 136, 24, KillCount );
+         VWB_DrawPic ( 184, 24, TimesYouKilledPerson );
+         break;
+
+      case 3 :
+         VWB_DrawPic (   8,  8, TopBar );
+         DrawIntensityString( 12, 11, "YOUR DEATHS", 20 );
+         VWB_DrawPic (   8, 24, Name );
+         VWB_DrawPic ( 136, 24, TimesPersonKilledYou );
+         break;
+//bna added
+      case 4 :
+		 VWB_DrawPic ( 198+48, 8, Blank );
+         VWB_DrawPic (   8,  8, TopBar );
+         DrawIntensityString( 12, 11, "FINAL SCORE", 20 );
+         VWB_DrawPic (   8, 24, TopBar );//used to blank
+         VWB_DrawPic (   8, 24, Name );
+         VWB_DrawPic ( 136, 24, KillCount);
+         VWB_DrawPic ( 198, 24, TimesPersonKilledYou);
+		 VWB_DrawPic ( 198+48, 24, Blank );
+         VWB_DrawPic ( 272, 24, Score );
+         break;
+//bna added end
+   }            
+                 
+   DrawTimeXY( TALLYTIME_X, TALLYTIME_Y, gamestate.TimeCount / VBLCOUNTER,
+      true );
+   }
+
+
+#define BT_RANK_X    23
+#define BT_PLAYER_X  30
+#define BT_KILLS_X   ( 139 + ( ( 40 + 20 ) / 2 ) )
+#define BT_DEATHS_X  ( 193 + ( ( 56 + 20 ) / 2 ) )
+//#define BT_SCORE_X   ( 263 + ( ( 46 + 20 ) / 2 ) )
+#define BT_SCORE_X   ( 273 + ( ( 46 + 20 ) / 2 ) )
+
+
+void ShowKills( int localplayer )
+{
+   int  w;
+   int  h;
+   int  i;
+   int  j;
+   int  temp;
+   int  rank;
+   int  player;
+   int  killer;
+   int  victim;
+   int  color;
+   char tempstr[15];
+   int  KillCount[ MAXPLAYERS ];
+   int  Order[ MAXPLAYERS ];
+   int  NumPlayers;
+
+   // show at the most 11 players
+   NumPlayers = min( numplayers, 11 );
+
+   // Count kills
+   for( killer = 0; killer < NumPlayers; killer++ )
+      {
+      Order[ killer ] = killer;
+      KillCount[ killer ] = 0;
+      for( victim = 0; victim < NumPlayers; victim++ )
+         {
+         if ( BATTLE_Team[ victim ] != BATTLE_Team[ killer ] )
+            {
+            KillCount[ killer ] += WhoKilledWho[ killer ][ victim ];
+            }
+         }
+      }
+
+   for( i = 0; i < NumPlayers - 1; i++ )
+      {
+      for( j = i + 1; j < NumPlayers; j++ )
+         {
+         if ( KillCount[ Order[ i ] ] < KillCount[ Order[ j ] ] )
+            {
+            temp = Order[ i ];
+            Order[ i ] = Order[ j ];
+            Order[ j ] = temp;
+            }
+         }
+      }
+
+   DrawTallyHeader( 2 );
+
+   IFont = (cfont_t * )W_CacheLumpNum (W_GetNumForName ("sifont"), PU_CACHE, Cvt_cfont_t, 1);
+   CurrentFont = smallfont;
+   py = 43;
+
+   for( rank = 0; rank < NumPlayers; rank++ )
+      {
+      player = Order[ rank ];
+
+      color = 21;
+
+      // Highlight the your score
+      if ( player == localplayer )
+         {
+         // Change to Intensity
+         color = 241;
+         }
+
+      // Draw rank if not tied with previous rank
+      if ( ( rank == 0 ) || ( KillCount[ player ] !=
+         KillCount[ Order[ rank - 1 ] ] ) )
+         {
+         itoa( rank + 1, tempstr, 10 );
+         }
+      else
+         {
+         strcpy( tempstr, "Tie" );
+         }
+
+      VW_MeasureIntensityPropString ( tempstr, &w, &h);
+      DrawIntensityString( BT_RANK_X - w, py, tempstr, color );
+
+      // Draw name
+      DrawIntensityString( BT_PLAYER_X, py, PLAYERSTATE[ player ].codename, color );
+
+      // Draw kills
+      itoa( KillCount[ player ], tempstr, 10 );
+      VW_MeasureIntensityPropString ( tempstr, &w, &h);
+      DrawIntensityString( BT_KILLS_X - w, py, tempstr, color );
+
+      // Draw times you killed that person
+      if ( player != localplayer )
+         {
+         itoa( WhoKilledWho[ localplayer ][ player ], tempstr, 10 );
+         }
+      else
+         {
+         strcpy( tempstr, "-" );
+         }
+
+      VW_MeasureIntensityPropString ( tempstr, &w, &h);
+      DrawIntensityString( BT_DEATHS_X - w, py, tempstr, color );
+
+      if ( gamestate.teamplay )
+         {
+         DrawIntensityString( BT_DEATHS_X + 16, py,
+            colorname[ PLAYERSTATE[ player ].uniformcolor ], color );
+         }
+
+      py += h;
+      }
+   }
+
+
+void ShowDeaths( int localplayer )
+   {
+   int  w;
+   int  h;
+   int  i;
+   int  j;
+   int  temp;
+   int  rank;
+   int  player;
+   int  killer;
+   int  victim;
+   int  color;
+   char tempstr[15];
+   int  DeathCount[ MAXPLAYERS ];
+   int  Order[ MAXPLAYERS ];
+   int  NumPlayers;
+
+   // show at the most 11 players
+   NumPlayers = min( numplayers, 11 );
+
+   // Count Deaths
+   for( victim = 0; victim < NumPlayers; victim++ )
+      {
+      Order[ victim ] = victim;
+      DeathCount[ victim ] = 0;
+      for( killer = 0; killer < NumPlayers; killer++ )
+         {
+         DeathCount[ victim ] += WhoKilledWho[ killer ][ victim ];
+         }
+      }
+
+   for( i = 0; i < NumPlayers - 1; i++ )
+      {
+      for( j = i + 1; j < NumPlayers; j++ )
+         {
+         if ( DeathCount[ Order[ i ] ] < DeathCount[ Order[ j ] ] )
+            {
+            temp = Order[ i ];
+            Order[ i ] = Order[ j ];
+            Order[ j ] = temp;
+            }
+         }
+      }
+
+   DrawTallyHeader( 3 );
+
+   IFont = (cfont_t * )W_CacheLumpNum (W_GetNumForName ("sifont"), PU_CACHE, Cvt_cfont_t, 1);
+   CurrentFont = smallfont;
+   py = 43;
+
+   for( rank = 0; rank < NumPlayers; rank++ )
+      {
+      player = Order[ rank ];
+      color = 21;
+
+      // Highlight the your score
+      if ( player == localplayer )
+         {
+         // Change to Intensity
+         color = 241;
+         }
+
+      // Draw rank if not tied with previous rank
+      if ( ( rank == 0 ) || ( DeathCount[ player ] !=
+         DeathCount[ Order[ rank - 1 ] ] ) )
+         {
+         itoa( rank + 1, tempstr, 10 );
+         }
+      else
+         {
+         strcpy( tempstr, "Tie" );
+         }
+
+      VW_MeasureIntensityPropString ( tempstr, &w, &h);
+      DrawIntensityString( BT_RANK_X - w, py, tempstr, color );
+
+      // Draw name
+      DrawIntensityString( BT_PLAYER_X, py, PLAYERSTATE[ player ].codename, color );
+
+      // Draw deaths
+      itoa( DeathCount[ player ], tempstr, 10 );
+      VW_MeasureIntensityPropString ( tempstr, &w, &h);
+      DrawIntensityString( BT_KILLS_X - w, py, tempstr, color );
+
+      // Draw times you were killed by that person
+      itoa( WhoKilledWho[ player ][ localplayer ], tempstr, 10 );
+      VW_MeasureIntensityPropString ( tempstr, &w, &h);
+      DrawIntensityString( BT_DEATHS_X - w, py, tempstr, color );
+
+      if ( gamestate.teamplay )
+         {
+         DrawIntensityString( BT_DEATHS_X + 16, py,
+            colorname[ PLAYERSTATE[ player ].uniformcolor ], color );
+         }
+
+      py += h;
+      }
+   }
+
+
+void ShowEndScore( int localplayer )
+   {
+   int  w;
+   int  h;
+   int  rank;
+   int  leader;
+   int  team;
+   int  color;
+   int  killer;
+   int  victim;
+   int  killcount;
+   int  suicidecount;
+   char tempstr[15];
+   boolean dofullstats;
+   int  NumPlayers;
+
+   // show at the most 11 players
+   NumPlayers = min( numplayers, 11 );
+
+   dofullstats = false;
+   switch( gamestate.battlemode )
+      {
+		case battle_Normal :
+		case battle_ScoreMore :
+		case battle_Hunter :
+         dofullstats = true;
+         DrawTallyHeader( 0 );
+         break;
+
+		case battle_Collector :
+		case battle_Scavenger :
+		case battle_Tag :
+		case battle_Eluder :
+		case battle_Deluder :
+		case battle_CaptureTheTriad :
+         dofullstats = false;
+         DrawTallyHeader( 1 );
+         break;
+      }
+
+   IFont = (cfont_t * )W_CacheLumpNum (W_GetNumForName ("sifont"), PU_CACHE, Cvt_cfont_t, 1);
+   CurrentFont = smallfont;
+   py = 43;
+
+   for( rank = 0; rank < BATTLE_NumberOfTeams; rank++ )
+      {
+      team = BATTLE_PlayerOrder[ rank ];
+
+      color = 21;
+      if ( team == BATTLE_Team[ localplayer ] )
+         {
+         // Change to Intensity
+         color = 241;
+         }
+
+      // Draw rank if not tied with previous rank
+      if ( ( rank == 0 ) || ( BATTLE_Points[ team ] !=
+         BATTLE_Points[ BATTLE_PlayerOrder[ rank - 1 ] ] ) )
+         {
+         itoa( rank + 1, tempstr, 10 );
+         }
+      else
+         {
+         strcpy( tempstr, "Tie" );
+         }
+
+      VW_MeasureIntensityPropString ( tempstr, &w, &h);
+      DrawIntensityString( BT_RANK_X - w, py, tempstr, color );
+
+      // Draw name of team leader
+      leader = BATTLE_TeamLeader[ team ];
+      if ( gamestate.teamplay )
+         {
+         DrawIntensityString( BT_PLAYER_X, py,
+            colorname[ PLAYERSTATE[ leader ].uniformcolor ], color );
+         }
+      else
+         {
+         DrawIntensityString( BT_PLAYER_X, py,
+            PLAYERSTATE[ leader ].codename, color );
+         }
+
+      if ( dofullstats )
+         {
+         // Count how many kills each person on the team got
+         killcount = 0;
+         suicidecount = 0;
+         for( killer = 0; killer < NumPlayers; killer++ )
+            {
+            if ( BATTLE_Team[ killer ] == team )
+               {
+               for( victim = 0; victim < NumPlayers; victim++ )
+                  {
+                  if ( BATTLE_Team[ victim ] != team )
+                     {
+                     killcount += WhoKilledWho[ killer ][ victim ];
+                     }
+                  else
+                     {
+                     suicidecount += WhoKilledWho[ killer ][ victim ];
+                     }
+                  }
+               }
+            }
+
+         // Draw kills
+         itoa( killcount, tempstr, 10 );
+         VW_MeasureIntensityPropString ( tempstr, &w, &h);
+         DrawIntensityString( BT_KILLS_X - w, py, tempstr, color );
+
+         // Draw suicides
+         itoa( suicidecount, tempstr, 10 );
+         VW_MeasureIntensityPropString ( tempstr, &w, &h);
+         DrawIntensityString( BT_DEATHS_X - w, py, tempstr, color );
+         }
+
+      // Draw Score
+      itoa( BATTLE_Points[ team ], tempstr, 10 );
+      VW_MeasureIntensityPropString ( tempstr, &w, &h);
+      DrawIntensityString( BT_SCORE_X - w, py, tempstr, color );
+
+      py += h;
+      }
+   }
+
+
+void BattleLevelCompleted ( int localplayer )
+   {
+   ControlInfo ci;
+   int w;
+   int h;
+   int key;
+   int Screen;
+   int LastScreen;
+   int Player;
+   char text[80];
+
+   EnableScreenStretch();
+
+   IN_ClearKeysDown ();
+
+   Player = localplayer;
+   Screen = 1;
+   LastScreen = 0;
+   key = -1;
+   while( 1 )
+      {
+      if ( Screen != LastScreen )
+         {
+         VL_DrawPostPic (W_GetNumForName("trilogo"));
+
+         switch( Screen )
+            {
+            case 1 :
+               ShowEndScore( Player );
+               break;
+
+            case 2 :
+               ShowKills( Player );
+               break;
+
+            case 3 :
+               ShowDeaths( Player );
+               break;
+            }
+
+         CurrentFont = tinyfont;
+
+         sprintf ( text, "Page %d of 3.  Use arrows to switch stats.  "
+            "Press Esc to quit.", Screen );
+         VW_MeasurePropString ( text, &w, &h);
+         py = 192;
+         px = ( 320 - w ) / 2;
+         VWB_DrawPropString ( text );
+         VW_UpdateScreen ();
+
+         do
+            {
+            ReadAnyControl (&ci);
+            }
+         while( ci.dir == (dirtype)key );
+         }
+
+      LastScreen = Screen;
+      ReadAnyControl ( &ci );
+      key = ci.dir;
+      if ( ( Screen > 1 ) && ( key == dir_West ) )
+         {
+         Screen--;
+         MN_PlayMenuSnd (SD_MOVECURSORSND);
+         }
+      else if ( ( Screen < 3 ) && ( key == dir_East ) )
+         {
+         Screen++;
+         MN_PlayMenuSnd (SD_MOVECURSORSND);
+         }
+      // Allow us to select which player to view
+      if ( Keyboard[ sc_RShift ] && ( key == dir_South ) )
+         {
+         Player++;
+         if ( Player >= numplayers )
+            {
+            Player = 0;
+            }
+         LastScreen = 0;
+         MN_PlayMenuSnd (SD_SELECTSND);
+         }
+
+      if ( Keyboard[ sc_RShift ] && ( key == dir_North ) )
+         {
+         Player--;
+         if ( Player < 0 )
+            {
+            Player = numplayers - 1;
+            }
+         LastScreen = 0;
+         MN_PlayMenuSnd (SD_SELECTSND);
+         }
+
+      if ( Keyboard[sc_Escape] )
+         {
+         break;
+         }
+      }
+
+   while ( Keyboard[sc_Escape] )
+      {
+      IN_UpdateKeyboard ();
+      }
+
+   MN_PlayMenuSnd (SD_ESCPRESSEDSND);
+
+   CurrentFont = smallfont;
+   }
+
+//==========================================================================
+
+/*
+==================
+=
+= FindAngleToWindow
+=
+==================
+*/
+int FindAngleToWindow ( int tx, int ty )
+{
+   if (!IsWindow(tx+1,ty))
+      return ANG180;
+   else if (!IsWindow(tx-1,ty))
+      return 0;
+   else if (!IsWindow(tx,ty+1))
+      return ANG90;
+   else
+      return ANG270;
+}
+
+#define STARTRADIUS (0xa000)
+#define STOPRADIUS (0x14000)
+#define DEATHRADIUS (STOPRADIUS-STARTRADIUS)
+#define ROTRATE      (5)
+#define TOTALDEATHROT (FINEANGLES<<1)
+#define RADIUSINC   ((DEATHRADIUS)/(TOTALDEATHROT))
+
+/*
+==================
+=
+= ZoomDeathOkay
+=
+==================
+*/
+boolean ZoomDeathOkay ( void )
+{
+   int x,y;
+   int radius;
+
+   if (
+        !(
+        (player->state==&s_ashwait) ||
+        ((player->flags & FL_HBM) && (gamestate.violence >= vl_high))
+        )
+      )
+      return false;
+
+   radius=STOPRADIUS;
+   x=player->x;
+   y=player->y;
+   while (radius>0)
+      {
+      if (tilemap[x>>16][(y+radius)>>16])
+         return false;
+      if (tilemap[x>>16][(y-radius)>>16])
+         return false;
+      if (tilemap[(x-radius)>>16][y>>16])
+         return false;
+      if (tilemap[(x+radius)>>16][y>>16])
+         return false;
+      if (tilemap[(x+radius)>>16][(y+radius)>>16])
+         return false;
+      if (tilemap[(x+radius)>>16][(y-radius)>>16])
+         return false;
+      if (tilemap[(x-radius)>>16][(y+radius)>>16])
+         return false;
+      if (tilemap[(x-radius)>>16][(y-radius)>>16])
+         return false;
+      radius-=0x10000;
+      }
+   return true;
+}
+
+/*
+==================
+=
+= Died
+=
+==================
+*/
+
+#define DEATHROTATE 6
+
+extern boolean dopefish;
+void Died (void)
+{
+   long  dx,dy;
+   int      iangle,curangle,clockwise,change;
+   int   da;
+   int   rate;
+   lbm_t *LBM;
+   int   slowrate;
+   playertype *pstate;
+   objtype * killerobj=(objtype *)player->target;
+player->yzangle=0;
+
+   if (killerobj == NULL)
+      killerobj = player;
+
+   if (CheckParm("slowdeath"))
+      slowrate=3;
+   else
+      slowrate=0;
+
+   M_LINKSTATE (player, pstate);
+
+   if ( (ZoomDeathOkay()==true) && (pstate->falling==false))
+      {
+      int x,y,z,radius,heightoffset;
+      int endangle,startangle,killangle;
+      boolean deadflagset;
+      objtype * dummy;
+
+      x=player->x;
+      y=player->y;
+      z=player->z;
+      dummy=player;
+      SpawnPlayerobj (x>>16, y>>16, 0, 0);
+      player=dummy;
+      dummy=new;
+      dummy->x=x;
+      dummy->drawx=x;
+      dummy->y=y;
+      dummy->z=z;
+      dummy->drawy=y;
+      dummy->flags=player->flags;
+      player->momentumx=0;
+      player->momentumy=0;
+      player->speed=0;
+      radius=STARTRADIUS;
+      heightoffset=pstate->heightoffset;
+      deadflagset=false;
+      startangle=(player->angle+ANG180)&(FINEANGLES-1);
+      endangle=startangle+TOTALDEATHROT;
+      killangle=startangle+(TOTALDEATHROT>>1);
+      if (dopefish==true)
+         {
+         AddMessage("Dopefish Death Cam",MSG_SYSTEM);
+         }
+      for (iangle=startangle;;)
+         {
+         if ( iangle > killangle )
+            {
+            if ( deadflagset==false )
+               {
+               dummy->hitpoints=0;
+               pstate->health=0;
+               dummy->flags &= ~FL_DYING;
+               dummy->flags |= FL_SHOOTABLE;
+               if (player->state==&s_ashwait)
+                  dummy->flags |= FL_SKELETON;
+               Collision(dummy,(objtype*)NULL,0,0);
+               deadflagset=true;
+               if ( ( killerobj==player ) && ( gamestate.violence >=
+                  vl_high ) && ( gamestate.difficulty >= gd_hard ) )
+                  {
+                  SD_Play( SD_YOUSUCKSND );
+                  }
+               else
+                  {
+                  SD_Play (SD_PLAYERTCDEATHSND+(pstate->player));
+                  }
+               }
+            }
+         else
+            {
+            dummy->flags &= ~FL_DYING;
+            }
+         if (dopefish==true)
+            {
+            dummy->momentumx+=(RandomNumber("Died",0)<<6)-(256<<5);
+            dummy->momentumy+=(RandomNumber("Died",0)<<6)-(256<<5);
+            }
+         player->x=x+FixedMul(radius,costable[iangle&(FINEANGLES-1)]);
+         player->y=y-FixedMul(radius,sintable[iangle&(FINEANGLES-1)]);
+         player->z=dummy->z;
+         player->angle=(iangle+ANG180)&(FINEANGLES-1);
+         if (dopefish==true)
+            {
+            int dx,dy;
+
+            dx = dummy->x - player->x;
+            dy = player->y - dummy->y;
+
+            if (dx && dy)
+               player->angle = atan2_appx (dx,dy);
+            }
+         pstate->heightoffset=heightoffset;
+         player->yzangle=0;
+         UpdateGameObjects();
+         player->momentumx=0;
+         player->momentumy=0;
+         player->speed=0;
+         ThreeDRefresh ();
+         AnimateWalls();
+         DoSprites();
+         DoAnimatedMaskedWalls();
+         UpdatePlayers();
+         UpdateLightLevel(player->areanumber);
+
+         if (iangle<endangle)
+            {
+            iangle+=(tics<<ROTRATE);
+            radius+=tics*(RADIUSINC<<ROTRATE);
+            }
+         if ( (dummy->state==dummy->state->next) && (iangle>=endangle) )
+            break;
+         }
+      }
+   else if (pstate->falling==false)
+      {
+
+      //
+      // swing around to face attacker
+      //
+
+      rate=DEATHROTATE-slowrate;
+         {
+         if (killerobj==player)
+            {
+            iangle=player->angle;
+            if ( ( gamestate.violence >= vl_high ) &&
+               ( gamestate.difficulty >= gd_hard ) )
+               {
+               SD_Play( SD_YOUSUCKSND );
+               }
+            }
+         else
+            {
+            SD_Play (SD_PLAYERTCDEATHSND+(pstate->player));
+            if (killerobj->which==PWALL)
+            {
+               dx = ((pwallobj_t *)killerobj)->x - player->x;
+               dy = player->y - ((pwallobj_t *)killerobj)->y;
+            }
+            else
+            {
+               dx = killerobj->x - player->x;
+               dy = player->y - killerobj->y;
+            }
+
+            iangle = atan2_appx (dx,dy);       // returns -pi to pi
+            }
+         }
+
+      da = iangle-player->angle;
+
+      if (da>0)
+         clockwise=1;
+      else
+         clockwise=0;
+      da=abs(da);
+      if (da>ANG180)
+         {
+         clockwise^=1;
+         da=ANGLES-da;
+         }
+
+      curangle = player->angle;
+
+      do
+         {
+         DoBorderShifts ();
+         change = tics<<rate;
+         if (clockwise==1)
+            curangle+=change;
+         else
+            curangle-=change;
+         da-=change;
+         if (curangle >= ANGLES)
+            curangle -= ANGLES;
+         if (curangle < 0)
+            curangle += ANGLES;
+         player->angle = (curangle & (FINEANGLES-1));
+         ThreeDRefresh ();
+         CalcTics ();
+         } while (da>0);
+      }
+   else
+      {
+      DrawFullSky();
+      FlipPage();
+      }
+
+   while (damagecount)
+      DoBorderShifts ();
+   DoBorderShifts ();
+
+   locplayerstate->weapon = -1;        // take away weapon
+
+   if (
+        (tedlevel == false) && // SO'S YA DON'T GET KILLED WHILE LAUNCHING!
+        (timelimitenabled == false)
+      )
+      locplayerstate->lives--;
+
+   if (pstate->falling==false)
+      {
+      ThreeDRefresh ();
+      }
+
+   FlipPage();
+   FlipPage();
+
+   if (locplayerstate->lives > -1)
+   {
+      int rng;
+
+      rng = RandomNumber ("Died",0);
+
+      if (pstate->falling==true)
+         {
+         RotateBuffer (0, 0, (FINEANGLES), (FINEANGLES>>6), (VBLCOUNTER*(1+slowrate)));
+         SD_Play (SD_PLAYERTCDEATHSND+(pstate->player));
+         pstate->falling=false;
+         }
+
+      else if (rng < 64)
+         RotateBuffer (0, 0, (FINEANGLES), (FINEANGLES*64), (VBLCOUNTER*(2+slowrate)));
+      else if (rng < 128)
+         {
+         RotateBuffer (0, 0, (FINEANGLES), (FINEANGLES>>6), (VBLCOUNTER*(1+slowrate)));
+         }
+      else if (rng < 192)
+         RotateBuffer(0, (FINEANGLES*4), (FINEANGLES), (FINEANGLES*64), (VBLCOUNTER*(3+slowrate)));
+      else
+         VL_FadeToColor (VBLCOUNTER*2, 100, 0, 0);
+
+      screenfaded=false;
+
+      VL_FadeOut (0, 255, 0,0,0,VBLCOUNTER>>1);
+      gamestate.episode = 1;
+      player->flags &= ~FL_DONE;
+
+      InitializeWeapons (locplayerstate);
+      ResetPlayerstate(locplayerstate);
+
+      UpdateLives (locplayerstate->lives);
+      UpdateScore (gamestate.score);
+
+      DrawTriads(true);
+      DrawLives (true);
+      DrawKeys (true);
+      DrawScore (true);
+   }
+   else
+   {
+      int rng;
+
+      SD_Play (SD_GAMEOVERSND);
+      rng=RandomNumber("Died",0);
+      if (rng<64)
+         RotateBuffer(0,(FINEANGLES>>1),(FINEANGLES),(FINEANGLES*64),(VBLCOUNTER*(3+slowrate)));
+      else if (rng<128)
+         VL_FadeToColor (VBLCOUNTER*3, 255, 255, 255);
+      else if (rng<192)
+         RotateBuffer(0,(FINEANGLES*2),(FINEANGLES),(FINEANGLES*64),(VBLCOUNTER*(3+slowrate)));
+      else
+         RotateBuffer(0,(FINEANGLES*2),(FINEANGLES),(FINEANGLES*64),(VBLCOUNTER*(3+slowrate)));
+
+      screenfaded=false;
+
+      VL_FadeOut (0, 255, 0,0,0,VBLCOUNTER>>1);
+
+      MU_StartSong(song_gameover);
+
+#if (SHAREWARE==0)
+      if (gamestate.violence==vl_excessive)
+         LBM = (lbm_t *) W_CacheLumpNum (W_GetNumForName ("bootblod"), PU_CACHE, Cvt_lbm_t, 1);
+      else
+         LBM = (lbm_t *) W_CacheLumpNum (W_GetNumForName ("bootnorm"), PU_CACHE, Cvt_lbm_t, 1);
+#else
+      LBM = (lbm_t *) W_CacheLumpNum (W_GetNumForName ("bootblod"), PU_CACHE, Cvt_lbm_t, 1);
+#endif
+      VL_DecompressLBM (LBM,true);
+
+      StopWind();
+
+      IN_UserInput (VBLCOUNTER*60);
+
+      MainMenu[savegame].active = 0;
+      MainMenu[viewscores].routine = (void *)CP_ViewScores;
+      MainMenu[viewscores].texture[6] = '7';
+      MainMenu[viewscores].texture[7] = '\0';
+      MainMenu[viewscores].letter     = 'V';
+   }
+   ClearGraphicsScreen();
+
+   VL_FadeIn (0, 255, origpal, 15);
+}
+
+
+//******************************************************************************
+//
+// DoLoadGameAction ()
+//
+//******************************************************************************
+
+static byte whichstr = 0;
+
+void DoLoadGameAction (void)
+{
+   if ((SaveTime+1) < GetTicCount())
+   {
+      byte *temp = bufferofs;
+
+      bufferofs = displayofs;
+      SaveTime = GetTicCount();
+
+      CurrentFont=tinyfont;
+
+      px = 92;
+      py = 152;
+      if (whichstr)
+      {
+//         VW_DrawPropString ("ƒ");
+         VW_DrawPropString (".");
+         whichstr = 0;
+		}
+      else
+      {
+//         VW_DrawPropString ("„");
+         VW_DrawPropString (".");
+         whichstr = 1;
+      }
+      bufferofs = temp;
+   }
+}
+
+//******************************************************************************
+//
+// DoCheckSum ()
+//
+//******************************************************************************
+
+long DoCheckSum (byte *source, int size, long csum)
+{
+   int i;
+   long checksum;
+
+   checksum = csum;
+
+   for (i = 0; i < size; i++)
+      checksum=updatecrc(checksum,*(source+i));
+
+   return checksum;
+}
+
+//******************************************************************************
+//
+// CaculateSaveGameCheckSum ()
+//
+//******************************************************************************
+
+#define SAVECHECKSUMSIZE (10000)
+long CalculateSaveGameCheckSum (char * filename)
+{
+   int handle;
+   int lengthleft;
+   int length;
+   byte * altbuffer;
+   long checksum;
+
+   altbuffer=SafeMalloc(SAVECHECKSUMSIZE);
+
+   checksum = 0;
+
+   // Open the savegame file
+
+   handle = SafeOpenRead (filename);
+   lengthleft = filelength (handle);
+
+   while (lengthleft>0)
+      {
+      length=SAVECHECKSUMSIZE;
+      if (length>lengthleft)
+         length=lengthleft;
+
+      SafeRead(handle,altbuffer,length);
+      checksum = DoCheckSum (altbuffer, length, checksum);
+
+      lengthleft-=length;
+      }
+
+   SafeFree(altbuffer);
+
+   close (handle);
+
+   return checksum;
+}
+
+//******************************************************************************
+//
+// StoreBuffer
+//
+//******************************************************************************
+void StoreBuffer (int handle, byte * src, int size)
+{
+   SafeWrite(handle,&size,sizeof(size));
+   SafeWrite(handle,src,size);
+}
+
+//******************************************************************************
+//
+// SaveTag
+//
+//******************************************************************************
+void SaveTag (int handle, char * tag, int size)
+{
+   SafeWrite(handle,tag,size);
+}
+
+
+//******************************************************************************
+//
+// SaveTheGame ()
+//
+// Expects game to be premalloced
+//
+//******************************************************************************
+
+boolean SaveTheGame (int num, gamestorage_t * game)
+{
+   char   loadname[MAX_PATH]="rottgam0.rot";
+   char   filename[MAX_PATH];
+   byte   * altbuffer;
+	int    size;
+	int    avail;
+   int    savehandle;
+   int    crc;
+	int    i;
+   char   letter;
+   int myticcount;
+   
+	if (num > 15 || num < 0)
+		Error("Illegal Saved game value=%d\n",num);
+
+   //
+   // Save Alternate Game Level information for reloading game
+   //
+   memset (&game->info, 0, sizeof (game->info));
+   if (GameLevels.avail == true)
+   {
+      memcpy (&game->info.path[0], &GameLevels.path[0], sizeof (GameLevels.path));
+      memcpy (&game->info.file[0], &GameLevels.file[0], sizeof (GameLevels.file));
+      game->info.avail = true;
+   }
+
+   game->mapcrc=GetMapCRC (gamestate.mapon);
+
+	// Create the proper file name
+
+   itoa(num,&loadname[7],16);
+   loadname[8]='.';
+
+
+   GetPathFromEnvironment( filename, ApogeePath, loadname );
+
+#if PLATFORM_DOS
+{
+   struct diskfree_t dfree;
+   // Determine available disk space
+   letter = toupper(filename[0]);
+   if (
+       (letter >= 'A') &&
+       (letter <= 'Q')
+      )
+      {
+      if (_dos_getdiskfree ((letter-'A'+1), &dfree))
+         Error ("Error in _dos_getdiskfree call\n");
+      }
+   else
+      {
+      if (_dos_getdiskfree (0, &dfree))
+         Error ("Error in _dos_getdiskfree call\n");
+      }
+
+	avail = (int) dfree.avail_clusters *
+					  dfree.bytes_per_sector *
+					  dfree.sectors_per_cluster;
+   avail -= 8192;
+
+	// Check to see if we have enough
+
+   if (avail < MAXSAVEDGAMESIZE)
+		{
+      CP_DisplayMsg ("There is not enough\nspace on your disk\nto Save Game!\nPress any key to continue", 13);
+		return (false);
+		}
+}
+#endif
+
+   // Open the savegame file
+
+   savehandle = SafeOpenWrite (filename);
+
+	// Save out file tag
+
+	size=4;
+   SaveTag(savehandle,"ROTT",size);
+
+	// Save out header
+
+	size=sizeof(*game);
+
+   SafeWrite(savehandle,game,size);
+
+/////////////////////////////////////////////////////////////////////////////
+// Save out rest of save game file beyond this point
+/////////////////////////////////////////////////////////////////////////////
+
+	// Door Tag
+
+	size=4;
+   SaveTag(savehandle,"DOOR",size);
+
+	// Doors
+
+	SaveDoors(&altbuffer,&size);
+   StoreBuffer(savehandle,altbuffer,size);
+	SafeFree(altbuffer);
+
+	// Elevator Tag
+
+	size = 9;
+   SaveTag(savehandle,"ELEVATORS",size);
+
+	// Elevators
+
+	SaveElevators(&altbuffer,&size);
+   StoreBuffer(savehandle,altbuffer,size);
+	SafeFree(altbuffer);
+
+	// Pushwall Tag
+
+	size=5;
+   SaveTag(savehandle,"PWALL",size);
+
+	// PushWalls
+
+	SavePushWalls(&altbuffer,&size);
+   StoreBuffer(savehandle,altbuffer,size);
+	SafeFree(altbuffer);
+
+	// MaskedWalls Tag
+
+	size=5;
+   SaveTag(savehandle,"MWALL",size);
+
+	// Masked Walls
+
+	SaveMaskedWalls(&altbuffer,&size);
+   StoreBuffer(savehandle,altbuffer,size);
+	SafeFree(altbuffer);
+
+	// Switches Tag
+
+	size=6;
+   SaveTag(savehandle,"SWITCH",size);
+
+	// Switches
+
+	SaveSwitches(&altbuffer,&size);
+   StoreBuffer(savehandle,altbuffer,size);
+	SafeFree(altbuffer);
+
+	// Statics Tag
+
+	size=6;
+   SaveTag(savehandle,"STATIC",size);
+
+	// Statics
+
+	SaveStatics(&altbuffer,&size);
+   StoreBuffer(savehandle,altbuffer,size);
+	SafeFree(altbuffer);
+
+	// Actors Tag
+
+	size=5;
+   SaveTag(savehandle,"ACTOR",size);
+
+	// Actors
+
+	SaveActors(&altbuffer,&size);
+   StoreBuffer(savehandle,altbuffer,size);
+	SafeFree(altbuffer);
+
+	// TouchPlates Tag
+
+	size=5;
+   SaveTag(savehandle,"TOUCH",size);
+
+	// TouchPlates
+
+	SaveTouchPlates(&altbuffer,&size);
+   StoreBuffer(savehandle,altbuffer,size);
+	SafeFree(altbuffer);
+
+	// GameState Tag
+
+	size=9;
+   SaveTag(savehandle,"GAMESTATE",size);
+
+	// GameState
+
+	size=sizeof(gamestate);
+   SafeWrite(savehandle,&gamestate,size);
+
+	// PlayerState Tag
+
+	size=12;
+   SaveTag(savehandle,"PLAYERSTATES",size);
+
+	// PlayerStates
+	size=sizeof(playertype);
+	for(i=0;i<numplayers;i++)
+     {
+      SafeWrite(savehandle,&PLAYERSTATE[i],size);
+	  }
+
+	// Mapseen Tag
+
+	size=7;
+   SaveTag(savehandle,"MAPSEEN",size);
+
+	// MapSeen
+
+	size=sizeof(mapseen);
+   SafeWrite(savehandle,&mapseen,size);
+
+	// Song Tag
+
+	size=4;
+   SaveTag(savehandle,"SONG",size);
+
+	// Song info
+
+	MU_SaveMusic(&altbuffer,&size);
+   StoreBuffer(savehandle,altbuffer,size);
+	SafeFree(altbuffer);
+
+	// Misc Tag
+
+	size=4;
+   SaveTag(savehandle,"MISC",size);
+
+	// Misc
+
+	// ticcount
+	myticcount = GetTicCount();
+	size=sizeof(myticcount);
+   SafeWrite(savehandle,&myticcount,size);
+
+	// shaketics
+	size=sizeof(SHAKETICS);
+   SafeWrite(savehandle,&SHAKETICS,size);
+
+	// damagecount
+	size=sizeof(damagecount);
+   SafeWrite(savehandle,&damagecount,size);
+
+	// viewsize
+	size=sizeof(viewsize);
+   SafeWrite(savehandle,&viewsize,size);
+
+	// poweruptimes
+	size = sizeof (poweruptime);
+   SafeWrite(savehandle,&poweruptime,size);
+
+	size = sizeof (protectiontime);
+   SafeWrite(savehandle,&protectiontime,size);
+
+	size = sizeof (powerupheight);
+   SafeWrite(savehandle,&powerupheight,size);
+
+	size = sizeof (protectionheight);
+   SafeWrite(savehandle,&protectionheight,size);
+
+	size = sizeof (poweradjust);
+   SafeWrite(savehandle,&poweradjust,size);
+
+   close (savehandle);
+
+   // Calculate CRC
+
+   crc = CalculateSaveGameCheckSum (filename);
+
+   // Append the crc
+
+   savehandle = SafeOpenAppend (filename);
+
+   size=sizeof(crc);
+   SafeWrite(savehandle,&crc,size);
+
+   close (savehandle);
+
+   pickquick = true;
+	return (true);
+}
+
+
+//******************************************************************************
+//
+// LoadTag
+//
+//******************************************************************************
+
+void LoadTag (byte ** src, char * tag, int size)
+{
+	if (StringsNotEqual((char *)*src,(char *)tag,size)==true)
+		Error("Could not locate %s header in saved game file\n",tag);
+	*src+=size;
+}
+
+//******************************************************************************
+//
+// LoadBuffer
+//
+//******************************************************************************
+int LoadBuffer (byte ** dest, byte ** src)
+{
+	int size;
+
+	memcpy(&size,*src,sizeof(size));
+	*src+=sizeof(size);
+	*dest=SafeMalloc(size);
+	memcpy(*dest,*src,size);
+	*src+=size;
+	return size;
+}
+
+
+//******************************************************************************
+//
+// LoadTheGame ()
+//
+// Expects game to be premalloced
+//
+//******************************************************************************
+
+boolean LoadTheGame (int num, gamestorage_t * game)
+{
+   char   loadname[45]="rottgam0.rot";
+   char   filename[128];
+   byte   * loadbuffer;
+	byte   * bufptr;
+	byte   * altbuffer;
+	int    size;
+	int    totalsize;
+	int    checksum;
+	int    savedchecksum;
+	int    i;
+   word   mapcrc;
+        int myticcount;
+
+	if (num>15 || num<0)
+		Error("Illegal Load game value=%d\n",num);
+
+	// Create the proper file name
+
+   itoa(num,&loadname[7],16);
+   loadname[8]='.';
+
+   GetPathFromEnvironment( filename, ApogeePath, loadname );
+
+   // Load the file
+
+	totalsize=LoadFile(filename,(void **)&loadbuffer);
+	bufptr=loadbuffer;
+
+	// Calculate checksum
+
+	checksum = DoCheckSum (loadbuffer, totalsize-sizeof(checksum), 0);
+
+	// Retrieve saved checksum
+
+	memcpy (&savedchecksum,loadbuffer+(totalsize-sizeof(savedchecksum)),sizeof(savedchecksum));
+
+	// Compare the two checksums;
+
+	if (checksum!=savedchecksum)
+      {
+      if (CP_DisplayMsg ("Your Saved Game file is\n"
+                         "shall we say, \"corrupted\".\n"
+                         "Would you like to\n"
+                         "continue anyway (Y/N)?\n", 12)==false)
+         {
+         return false;
+         }
+      }
+
+	// Load in file tag
+
+	size=4;
+	LoadTag(&bufptr,"ROTT",size);
+
+	// Load in header
+
+	size=sizeof(*game);
+	memcpy(game,bufptr,size);
+	bufptr+=size;
+
+	if (game->version!=ROTTVERSION)
+		return false;
+
+   memcpy (&GameLevels, &game->info, sizeof (GameLevels));
+
+	gamestate.episode=game->episode;
+	gamestate.mapon=game->area;
+
+   mapcrc=GetMapCRC (gamestate.mapon);
+
+   if (mapcrc!=game->mapcrc)
+      return false;
+
+/////////////////////////////////////////////////////////////////////////////
+// Load in rest of saved game file beyond this point
+/////////////////////////////////////////////////////////////////////////////
+
+	// Free up the current level
+	Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND);       // Free current level
+
+   gamestate.battlemode = battle_StandAloneGame;
+   BATTLE_SetOptions( &BATTLE_Options[ battle_StandAloneGame ] );
+   BATTLE_Init( gamestate.battlemode, 1 );
+
+	DoLoadGameAction ();
+	SetupGameLevel();
+
+	// This prevents a nasty glitch when loading some saved games
+	PreCacheGroup(W_GetNumForName("BULLETHO"),W_GetNumForName("ALTBHO"),cache_transpatch_t);	
+	
+	// Door Tag
+
+	size=4;
+	LoadTag(&bufptr,"DOOR",size);
+
+	// Doors
+
+	DoLoadGameAction ();
+	size=LoadBuffer(&altbuffer,&bufptr);
+	LoadDoors(altbuffer,size);
+	SafeFree(altbuffer);
+
+	// Elevator Tag
+
+	size = 9;
+	LoadTag(&bufptr,"ELEVATORS",size);
+
+
+	// Elevators
+
+	DoLoadGameAction ();
+	size=LoadBuffer(&altbuffer,&bufptr);
+	LoadElevators(altbuffer,size);
+	SafeFree(altbuffer);
+
+	// Pushwall Tag
+
+	size=5;
+	LoadTag(&bufptr,"PWALL",size);
+
+	// PushWalls
+
+	DoLoadGameAction ();
+	size=LoadBuffer(&altbuffer,&bufptr);
+	LoadPushWalls(altbuffer,size);
+	SafeFree(altbuffer);
+#if 0
+	// Animated Walls Tag
+
+	size=5;
+	LoadTag(&bufptr,"AWALL",size);
+
+	// Animated Walls
+	size=LoadBuffer(&altbuffer,&bufptr);
+	LoadAnimWalls(altbuffer,size);
+	SafeFree(altbuffer);
+#endif
+
+	// MaskedWalls Tag
+
+	size=5;
+	LoadTag(&bufptr,"MWALL",size);
+
+	// Masked Walls
+
+	DoLoadGameAction ();
+	size=LoadBuffer(&altbuffer,&bufptr);
+	LoadMaskedWalls(altbuffer,size);
+	SafeFree(altbuffer);
+
+	// Switches Tag
+
+	size=6;
+	LoadTag(&bufptr,"SWITCH",size);
+
+	// Switches
+
+	DoLoadGameAction ();
+	size=LoadBuffer(&altbuffer,&bufptr);
+	LoadSwitches(altbuffer,size);
+	SafeFree(altbuffer);
+
+
+	// Statics Tag
+
+	size=6;
+	LoadTag(&bufptr,"STATIC",size);
+
+   // Statics
+
+   DoLoadGameAction ();
+   size=LoadBuffer(&altbuffer,&bufptr);
+   LoadStatics(altbuffer,size);
+   SafeFree(altbuffer);
+
+   // Actors Tag
+
+   size=5;
+   LoadTag(&bufptr,"ACTOR",size);
+
+   // Actors
+
+   DoLoadGameAction ();
+   size=LoadBuffer(&altbuffer,&bufptr);
+   LoadActors(altbuffer,size);
+	SafeFree(altbuffer);
+
+	// TouchPlates Tag
+
+	size=5;
+	LoadTag(&bufptr,"TOUCH",size);
+
+	// TouchPlates
+
+	DoLoadGameAction ();
+	size=LoadBuffer(&altbuffer,&bufptr);
+	LoadTouchPlates(altbuffer,size);
+	SafeFree(altbuffer);
+
+   // SetupWindows
+
+   SetupWindows();
+
+	// GameState Tag
+
+	size=9;
+	LoadTag(&bufptr,"GAMESTATE",size);
+
+   // GameState
+
+   DoLoadGameAction ();
+   size=sizeof(gamestate);
+   memcpy(&gamestate,bufptr,size);
+   bufptr+=size;
+
+   // PlayerState Tag
+
+	size=12;
+	LoadTag(&bufptr,"PLAYERSTATES",size);
+
+	// PlayerState
+
+	DoLoadGameAction ();
+	size=sizeof(playertype);
+	for(i=0;i<numplayers;i++)
+	 {memcpy(&PLAYERSTATE[i],bufptr,size);
+	  bufptr+=size;
+	 }
+
+   // Zero out player targets
+
+   locplayerstate->guntarget=0;
+   locplayerstate->targettime=0;
+
+   // Mapseen Tag
+
+   size=7;
+   LoadTag(&bufptr,"MAPSEEN",size);
+
+   // MapSeen
+
+   DoLoadGameAction ();
+   size=sizeof(mapseen);
+   memcpy(&mapseen,bufptr,size);
+   bufptr+=size;
+
+	// Song Tag
+
+	size=4;
+   LoadTag(&bufptr,"SONG",size);
+
+	// Song info
+
+   DoLoadGameAction ();
+	size=LoadBuffer(&altbuffer,&bufptr);
+	MU_LoadMusic(altbuffer,size);
+	SafeFree(altbuffer);
+
+   // Misc Tag
+
+   size=4;
+   LoadTag(&bufptr,"MISC",size);
+
+   // Misc
+
+   // ticcount
+   DoLoadGameAction ();
+   size=sizeof(myticcount);
+	memcpy((void *)&myticcount,bufptr,size);
+   bufptr+=size;
+   SaveTime = myticcount;
+   ISR_SetTime(myticcount);
+   
+   // shaketics
+   DoLoadGameAction ();
+   size=sizeof(SHAKETICS);
+   memcpy(&SHAKETICS,bufptr,size);
+   bufptr+=size;
+
+   // damagecount
+   DoLoadGameAction ();
+   size=sizeof(damagecount);
+   memcpy(&damagecount,bufptr,size);
+   bufptr+=size;
+
+	// viewsize
+   DoLoadGameAction ();
+   size=sizeof(viewsize);
+   memcpy(&viewsize,bufptr,size);
+   bufptr+=size;
+
+   // powerup times
+   DoLoadGameAction ();
+   size = sizeof (poweruptime);
+   memcpy (&poweruptime, bufptr, size);
+   bufptr += size;
+   size = sizeof (protectiontime);
+   memcpy (&protectiontime, bufptr, size);
+   bufptr += size;
+   size = sizeof (powerupheight);
+   memcpy (&powerupheight, bufptr, size);
+   bufptr += size;
+   size = sizeof (protectionheight);
+   memcpy (&protectionheight, bufptr, size);
+   bufptr += size;
+   size = sizeof (poweradjust);
+   memcpy (&poweradjust, bufptr, size);
+   bufptr += size;
+
+  // Set the viewsize
+
+   SetViewSize(viewsize);
+   DoLoadGameAction ();
+
+   // Connect areas
+
+   ConnectAreas ();
+   DoLoadGameAction ();
+
+   // Free up the loadbuffer
+
+   SafeFree (loadbuffer);
+   DoLoadGameAction ();
+
+   Illuminate();
+
+	IN_UpdateKeyboard ();
+   LoadPlayer ();
+   DoLoadGameAction ();
+   SetupPlayScreen();
+   UpdateScore (gamestate.score);
+   UpdateLives (locplayerstate->lives);
+   UpdateTriads (player, 0);
+	PreCache ();
+   InitializeMessages();
+
+	for (i=0;i<100;i++)
+		UpdateLightLevel(player->areanumber);
+
+   CalcTics();
+   CalcTics();
+
+   pickquick = true;
+
+   return (true);
+}
+
+
+//******************************************************************************
+//
+// GetSavedMessage ()
+//
+// Expects message to be premalloced
+//
+//******************************************************************************
+
+void GetSavedMessage (int num, char * message)
+{
+   gamestorage_t game;
+   char   loadname[45]="rottgam0.rot";
+   char   filename[128];
+   byte   * loadbuffer;
+   byte   * bufptr;
+   int    size;
+
+   if (num>15 || num<0)
+      Error("Illegal Load game value=%d\n",num);
+
+   // Create the proper file name
+
+   itoa(num,&loadname[7],16);
+   loadname[8]='.';
+
+   GetPathFromEnvironment( filename, ApogeePath, loadname );
+
+   // Load the file
+
+   size=LoadFile(filename,(void **)&loadbuffer);
+   bufptr=loadbuffer;
+
+   size=4;
+   LoadTag(&bufptr,"ROTT",size);
+
+   // Load in header
+
+   size=sizeof(game);
+   memcpy(&game,bufptr,size);
+   strcpy(message,game.message);
+   SafeFree(loadbuffer);
+}
+
+//******************************************************************************
+//
+// GetSavedHeader ()
+//
+// Expects game to be premalloced
+//
+//******************************************************************************
+
+void GetSavedHeader (int num, gamestorage_t * game)
+{
+   char   loadname[45]="rottgam0.rot";
+   char   filename[128];
+   byte   * loadbuffer;
+   byte   * bufptr;
+   int    size;
+
+   if (num>15 || num<0)
+      Error("Illegal Load game value=%d\n",num);
+
+   // Create the proper file name
+
+   itoa(num,&loadname[7],16);
+   loadname[8]='.';
+
+   GetPathFromEnvironment( filename, ApogeePath, loadname );
+
+   // Load the file
+
+   size=LoadFile(filename, (void **)&loadbuffer);
+   bufptr=loadbuffer;
+
+   size=4;
+   LoadTag(&bufptr,"ROTT",size);
+
+   // Load in header
+
+   size=sizeof(*game);
+   memcpy(game,bufptr,size);
+   SafeFree(loadbuffer);
+}
+
+
+
+//******************************************************************************
+//
+// GetLevel ()
+//
+//******************************************************************************
+
+int GetLevel (int episode, int mapon)
+{
+   int level;
+
+   level = (mapon+1) - ((episode-1) << 3);
+
+   return (level);
+}

Added: tags/rott-1.1/rott/rt_game.h
===================================================================
--- tags/rott-1.1/rott/rt_game.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_game.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,147 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_game_public
+#define _rt_game_public
+
+//***************************************************************************
+//
+// Public header for RT_GAME.C
+//
+//***************************************************************************
+
+#include "rt_actor.h"
+#include "lumpy.h"
+#include "rt_cfg.h"
+#include "rt_playr.h"
+
+//***************************************************************************
+//
+// DEFINES
+//
+//***************************************************************************
+
+#define  MaxHighName 57
+#define  MaxScores   7
+
+
+//***************************************************************************
+//
+// TYPEDEFS
+//
+//***************************************************************************
+
+typedef struct
+{
+   char  message[30];
+   byte  episode;
+   byte  area;
+   byte  version;
+   byte  picture[16000];
+   word  mapcrc;
+   AlternateInformation info;
+} gamestorage_t;
+
+typedef  struct
+{
+	char  name[MaxHighName + 1];
+	long  score;
+	word  completed,episode;
+} HighScore;
+
+
+//***************************************************************************
+//
+// GLOBALS
+//
+//***************************************************************************
+
+extern int PlayerSnds[5];
+
+//extern int SHAKETICS;
+extern unsigned short SHAKETICS;//bna++
+extern int damagecount;
+
+extern HighScore   Scores[MaxScores];
+extern int SaveTime;
+
+//***************************************************************************
+//
+// PROTOTYPES
+//
+//***************************************************************************
+
+void SetupPlayScreen (void);
+void SD_PreCache (void);
+void GameMemToScreen( pic_t *source, int x, int y, int bufferofsonly );
+void DrawPlayScreen (boolean bufferofsonly);
+
+void DrawKills (boolean bufferofsonly);
+void DrawPlayers ( void );
+void DrawGameString (int x, int y, const char * str, boolean bufferofsonly);
+void DrawNumber (int x, int y, int width, int which, boolean bufferofsonly);
+void TakeDamage (int points, objtype *attacker);
+void HealPlayer (int points, objtype * ob);
+void DrawLives (boolean bufferofsonly);
+void GiveExtraMan (void);
+void DrawScore (boolean bufferofsonly);
+void GivePoints (long points);
+void DrawKeys (boolean bufferofsonly);
+void GiveKey (int key);
+void GiveWeapon (objtype * ob, int weapon);
+void GiveMissileWeapon(objtype * ob, int which);
+void GiveLives (int newlives);
+
+void UpdateScore (unsigned int num);
+void UpdateLives (int num);
+
+void DrawTimeXY( int x, int y, int sec, boolean bufferofsonly );
+void DrawTime (boolean bufferofsonly);
+
+boolean SaveTheGame (int num, gamestorage_t * game);
+boolean LoadTheGame (int num, gamestorage_t * game);
+void GetSavedMessage (int num, char * message);
+void GetSavedHeader (int num, gamestorage_t * game);
+
+void DrawHighScores (void);
+void CheckHighScore (long score, word other, boolean INMENU);
+void LevelCompleted ( exit_t playstate );
+void BattleLevelCompleted ( int localplayer );
+void Died (void);
+void ScreenShake (void);
+void UpdateTriads (objtype * ob, int num);
+void DrawTriads (boolean bufferofsonly);
+void DrawStats (void);
+void DrawBarHealth (boolean bufferonly);
+void DrawBarAmmo (boolean bufferonly);
+void GM_DrawBonus (int which);
+
+void DrawEpisodeLevel ( int x, int y );
+void DoBorderShifts (void);
+void GM_UpdateBonus (int time, int powerup);
+void DoLoadGameAction (void);
+int GetLevel (int episode, int mapon);
+void DrawPause (void);
+void DrawPauseXY (int x, int y);
+
+void DrawColoredMPPic (int xpos, int ypos, int width, int height, int heightmod, byte *src, boolean bufferofsonly, int color);
+void StatusDrawColoredPic (unsigned x, unsigned y, pic_t *nums, boolean bufferofsonly, int color);
+
+void ClearTriads (playertype * pstate);
+#endif

Added: tags/rott-1.1/rott/rt_in.c
===================================================================
--- tags/rott-1.1/rott/rt_in.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_in.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1955 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if PLATFORM_DOS
+#include <conio.h>
+#include <dos.h>
+#include <i86.h>
+#endif
+
+#if USE_SDL
+#include "SDL.h"
+#endif
+
+#include "rt_main.h"
+#include "rt_spbal.h"
+#include "rt_def.h"
+#include "rt_in.h"
+#include "_rt_in.h"
+#include "isr.h"
+#include "rt_util.h"
+#include "rt_swift.h"
+#include "rt_vh_a.h"
+#include "rt_cfg.h"
+#include "rt_msg.h"
+#include "rt_playr.h"
+#include "rt_net.h"
+#include "rt_com.h"
+#include "rt_cfg.h"
+//MED
+#include "memcheck.h"
+#include "keyb.h"
+
+#define MAXMESSAGELENGTH      (COM_MAXTEXTSTRINGLENGTH-1)
+
+//****************************************************************************
+//
+// GLOBALS
+//
+//****************************************************************************]
+
+//
+// Used by menu routines that need to wait for a button release.
+// Sometimes the mouse driver misses an interrupt, so you can't wait for
+// a button to be released.  Instead, you must ignore any buttons that
+// are pressed.
+//
+int IgnoreMouse = 0;
+
+// configuration variables
+//
+boolean  SpaceBallPresent;
+boolean  CybermanPresent;
+boolean  AssassinPresent;
+boolean  MousePresent;
+boolean  JoysPresent[MaxJoys];
+boolean  JoyPadPresent     = 0;
+
+//    Global variables
+//
+boolean  Paused;
+char LastASCII;
+volatile int LastScan;
+
+byte Joy_xb,
+     Joy_yb,
+     Joy_xs,
+     Joy_ys;
+word Joy_x,
+     Joy_y;
+
+
+int LastLetter = 0;
+char LetterQueue[MAXLETTERS];
+ModemMessage MSG;
+
+
+#if USE_SDL
+static SDL_Joystick* sdl_joysticks[MaxJoys];
+static int sdl_mouse_delta_x = 0;
+static int sdl_mouse_delta_y = 0;
+static word sdl_mouse_button_mask = 0;
+static int sdl_total_sticks = 0;
+static word *sdl_stick_button_state = NULL;
+static word sdl_sticks_joybits = 0;
+static int sdl_mouse_grabbed = 0;
+static unsigned int scancodes[SDLK_LAST];
+extern boolean sdl_fullscreen;
+#endif
+
+
+//   'q','w','e','r','t','y','u','i','o','p','[',']','\\', 0 ,'a','s',
+
+const char ScanChars[128] =    // Scan code names with single chars
+{
+    0 , 0 ,'1','2','3','4','5','6','7','8','9','0','-','=', 0 , 0 ,
+   'q','w','e','r','t','y','u','i','o','p','[',']', 0 , 0 ,'a','s',
+   'd','f','g','h','j','k','l',';','\'','`', 0 ,'\\','z','x','c','v',
+   'b','n','m',',','.','/', 0 , 0 , 0 ,' ', 0 , 0 , 0 , 0 , 0 , 0 ,
+    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,'-', 0 ,'5', 0 ,'+', 0 ,
+    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+};
+
+const char ShiftedScanChars[128] =    // Shifted Scan code names with single chars
+{
+    0 , 0 ,'!','@','#','$','%','^','&','*','(',')','_','+', 0 , 0 ,
+   'Q','W','E','R','T','Y','U','I','O','P','{','}', 0 , 0 ,'A','S',
+   'D','F','G','H','J','K','L',':','"','~', 0 ,'|','Z','X','C','V',
+   'B','N','M','<','>','?', 0 , 0 , 0 ,' ', 0 , 0 , 0 , 0 , 0 , 0 ,
+    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,'-', 0 ,'5', 0 ,'+', 0 ,
+    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
+    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
+};
+
+#if 0
+const char ScanChars[128] =    // Scan code names with single chars
+{
+   '?','?','1','2','3','4','5','6','7','8','9','0','-','+','?','?',
+   'Q','W','E','R','T','Y','U','I','O','P','[',']','|','?','A','S',
+   'D','F','G','H','J','K','L',';','\'','?','?','?','Z','X','C','V',
+   'B','N','M',',','.','/','?','?','?',' ','?','?','?','?','?','?',
+   '?','?','?','?','?','?','?','?','?','?','-','?','5','?','+','?',
+   '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?',
+   '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?',
+   '?','?','?','?','?','?','?','?','?','?','?','?','?','?','?','?'
+};
+#endif
+
+
+
+//****************************************************************************
+//
+// LOCALS
+//
+//****************************************************************************]
+
+static KeyboardDef KbdDefs = {0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51};
+static JoystickDef JoyDefs[MaxJoys];
+static ControlType Controls[MAXPLAYERS];
+
+
+static boolean  IN_Started;
+
+static   Direction   DirTable[] =      // Quick lookup for total direction
+{
+   dir_NorthWest, dir_North,  dir_NorthEast,
+   dir_West,      dir_None,   dir_East,
+   dir_SouthWest, dir_South,  dir_SouthEast
+};
+
+int (far *function_ptr)();
+
+static char *ParmStrings[] = {"nojoys","nomouse","spaceball","cyberman","assassin",NULL};
+
+
+#if USE_SDL
+#define sdldebug printf
+
+static int sdl_mouse_button_filter(SDL_Event const *event)
+{
+        /*
+         * What DOS games expect:
+         *  0	left button pressed if 1
+         *  1	right button pressed if 1
+         *  2	middle button pressed if 1
+         *
+         *   (That is, this is what Int 33h (AX=0x05) returns...)
+         */
+
+    Uint8 bmask = SDL_GetMouseState(NULL, NULL);
+    sdl_mouse_button_mask = 0;  /* this is a static var. */
+    if (bmask & SDL_BUTTON_LMASK) sdl_mouse_button_mask |= 1;
+    if (bmask & SDL_BUTTON_RMASK) sdl_mouse_button_mask |= 2;
+    if (bmask & SDL_BUTTON_MMASK) sdl_mouse_button_mask |= 4;
+    return(0);
+} /* sdl_mouse_up_filter */
+
+
+static int sdl_mouse_motion_filter(SDL_Event const *event)
+{
+    static int mouse_x = 0;
+    static int mouse_y = 0;
+    int mouse_relative_x = 0;
+    int mouse_relative_y = 0;
+
+    if (event->type == SDL_JOYBALLMOTION)
+    {
+        mouse_relative_x = event->jball.xrel/100;
+        mouse_relative_y = event->jball.yrel/100;
+       	mouse_x += mouse_relative_x;
+       	mouse_y += mouse_relative_y;
+    } /* if */
+    else
+    {
+        if (sdl_mouse_grabbed || sdl_fullscreen)
+        {
+          	mouse_relative_x = event->motion.xrel;
+       	    mouse_relative_y = event->motion.yrel;
+           	mouse_x += mouse_relative_x;
+           	mouse_y += mouse_relative_y;
+        } /* if */
+        else
+        {
+          	mouse_relative_x = event->motion.x - mouse_x;
+           	mouse_relative_y = event->motion.y - mouse_y;
+           	mouse_x = event->motion.x;
+           	mouse_y = event->motion.y;
+        } /* else */
+    } /* else */
+
+#if 0
+   	if (mouse_x < 0) mouse_x = 0;
+   	if (mouse_x > surface->w) mouse_x = surface->w;
+   	if (mouse_y < 0) mouse_y = 0;
+   	if (mouse_y > surface->h) mouse_y = surface->h;
+#endif
+
+    /* set static vars... */
+    sdl_mouse_delta_x += mouse_relative_x;
+    sdl_mouse_delta_y += mouse_relative_y;
+
+    return(0);
+} /* sdl_mouse_motion_filter */
+
+
+/**
+ * Attempt to flip the video surface to fullscreen or windowed mode.
+ *  Attempts to maintain the surface's state, but makes no guarantee
+ *  that pointers (i.e., the surface's pixels field) will be the same
+ *  after this call.
+ *
+ * Caveats: Your surface pointers will be changing; if you have any other
+ *           copies laying about, they are invalidated.
+ *
+ *          Do NOT call this from an SDL event filter on Windows. You can
+ *           call it based on the return values from SDL_PollEvent, etc, just
+ *           not during the function you passed to SDL_SetEventFilter().
+ *
+ *          Thread safe? Likely not.
+ *
+ *   @param surface pointer to surface ptr to toggle. May be different
+ *                  pointer on return. MAY BE NULL ON RETURN IF FAILURE!
+ *   @param flags   pointer to flags to set on surface. The value pointed
+ *                  to will be XOR'd with SDL_FULLSCREEN before use. Actual
+ *                  flags set will be filled into pointer. Contents are
+ *                  undefined on failure. Can be NULL, in which case the
+ *                  surface's current flags are used.
+ *  @return non-zero on success, zero on failure.
+ */
+static int attempt_fullscreen_toggle(SDL_Surface **surface, Uint32 *flags)
+{
+    long framesize = 0;
+    void *pixels = NULL;
+    SDL_Rect clip;
+    Uint32 tmpflags = 0;
+    int w = 0;
+    int h = 0;
+    int bpp = 0;
+    int grabmouse = (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
+    int showmouse = SDL_ShowCursor(-1);
+    SDL_Color *palette = NULL;
+    int ncolors = 0;
+
+    /*
+    sdldebug("attempting to toggle fullscreen flag...");
+    */
+
+    if ( (!surface) || (!(*surface)) )  /* don't try if there's no surface. */
+    {
+	    /*
+        sdldebug("Null surface (?!). Not toggling fullscreen flag.");
+	*/
+        return(0);
+    } /* if */
+
+    if (SDL_WM_ToggleFullScreen(*surface))
+    {
+	    /*
+        sdldebug("SDL_WM_ToggleFullScreen() seems to work on this system.");
+	*/
+        if (flags)
+            *flags ^= SDL_FULLSCREEN;
+        return(1);
+    } /* if */
+
+    if ( !(SDL_GetVideoInfo()->wm_available) )
+    {
+	    /*
+        sdldebug("No window manager. Not toggling fullscreen flag.");
+	*/
+        return(0);
+    } /* if */
+
+    /*
+    sdldebug("toggling fullscreen flag The Hard Way...");
+    */
+    tmpflags = (*surface)->flags;
+    w = (*surface)->w;
+    h = (*surface)->h;
+    bpp = (*surface)->format->BitsPerPixel;
+
+    if (flags == NULL)  /* use the surface's flags. */
+        flags = &tmpflags;
+
+    SDL_GetClipRect(*surface, &clip);
+
+        /* save the contents of the screen. */
+    if ( (!(tmpflags & SDL_OPENGL)) && (!(tmpflags & SDL_OPENGLBLIT)) )
+    {
+        framesize = (w * h) * ((*surface)->format->BytesPerPixel);
+        pixels = malloc(framesize);
+        if (pixels == NULL)
+            return(0);
+        memcpy(pixels, (*surface)->pixels, framesize);
+    } /* if */
+
+#if 1
+    STUB_FUNCTION;   /* palette is broken. FIXME !!! --ryan. */
+#else
+    if ((*surface)->format->palette != NULL)
+    {
+        ncolors = (*surface)->format->palette->ncolors;
+        palette = malloc(ncolors * sizeof (SDL_Color));
+        if (palette == NULL)
+        {
+            free(pixels);
+            return(0);
+        } /* if */
+        memcpy(palette, (*surface)->format->palette->colors,
+               ncolors * sizeof (SDL_Color));
+    } /* if */
+#endif
+
+    if (grabmouse)
+        SDL_WM_GrabInput(SDL_GRAB_OFF);
+
+    SDL_ShowCursor(1);
+
+    *surface = SDL_SetVideoMode(w, h, bpp, (*flags) ^ SDL_FULLSCREEN);
+
+    if (*surface != NULL)
+        *flags ^= SDL_FULLSCREEN;
+
+    else  /* yikes! Try to put it back as it was... */
+    {
+        *surface = SDL_SetVideoMode(w, h, bpp, tmpflags);
+        if (*surface == NULL)  /* completely screwed. */
+        {
+            if (pixels != NULL)
+                free(pixels);
+            if (palette != NULL)
+                free(palette);
+            return(0);
+        } /* if */
+    } /* if */
+
+    /* Unfortunately, you lose your OpenGL image until the next frame... */
+
+    if (pixels != NULL)
+    {
+        memcpy((*surface)->pixels, pixels, framesize);
+        free(pixels);
+    } /* if */
+
+#if 1
+    STUB_FUNCTION;   /* palette is broken. FIXME !!! --ryan. */
+#else
+    if (palette != NULL)
+    {
+            /* !!! FIXME : No idea if that flags param is right. */
+        SDL_SetPalette(*surface, SDL_LOGPAL, palette, 0, ncolors);
+        free(palette);
+    } /* if */
+#endif
+
+    SDL_SetClipRect(*surface, &clip);
+
+    if (grabmouse)
+        SDL_WM_GrabInput(SDL_GRAB_ON);
+
+    SDL_ShowCursor(showmouse);
+
+#if 0
+    STUB_FUNCTION;  /* pull this out of buildengine/sdl_driver.c ... */
+    output_surface_info(*surface);
+#endif
+
+    return(1);
+} /* attempt_fullscreen_toggle */
+
+
+    /*
+     * The windib driver can't alert us to the keypad enter key, which
+     *  Ken's code depends on heavily. It sends it as the same key as the
+     *  regular return key. These users will have to hit SHIFT-ENTER,
+     *  which we check for explicitly, and give the engine a keypad enter
+     *  enter event.
+     */
+static int handle_keypad_enter_hack(const SDL_Event *event)
+{
+    static int kp_enter_hack = 0;
+    int retval = 0;
+
+    if (event->key.keysym.sym == SDLK_RETURN)
+    {
+        if (event->key.state == SDL_PRESSED)
+        {
+            if (event->key.keysym.mod & KMOD_SHIFT)
+            {
+                kp_enter_hack = 1;
+                retval = scancodes[SDLK_KP_ENTER];
+            } /* if */
+        } /* if */
+
+        else  /* key released */
+        {
+            if (kp_enter_hack)
+            {
+                kp_enter_hack = 0;
+                retval = scancodes[SDLK_KP_ENTER];
+            } /* if */
+        } /* if */
+    } /* if */
+
+    return(retval);
+} /* handle_keypad_enter_hack */
+
+
+static int sdl_key_filter(const SDL_Event *event)
+{
+	int k;
+    int keyon;
+    int strippedkey;
+    SDL_GrabMode grab_mode = SDL_GRAB_OFF;
+    int extended;
+
+    if ( (event->key.keysym.sym == SDLK_g) &&
+         (event->key.state == SDL_PRESSED) &&
+         (event->key.keysym.mod & KMOD_CTRL) )
+    {
+      if (!sdl_fullscreen)
+      {
+        sdl_mouse_grabbed = ((sdl_mouse_grabbed) ? 0 : 1);
+        if (sdl_mouse_grabbed)
+            grab_mode = SDL_GRAB_ON;
+        SDL_WM_GrabInput(grab_mode);
+      }
+      return(0);
+    } /* if */
+
+    else if ( ( (event->key.keysym.sym == SDLK_RETURN) ||
+                (event->key.keysym.sym == SDLK_KP_ENTER) ) &&
+              (event->key.state == SDL_PRESSED) &&
+              (event->key.keysym.mod & KMOD_ALT) )
+    {
+        if (SDL_WM_ToggleFullScreen(SDL_GetVideoSurface()))
+            sdl_fullscreen ^= 1;
+        return(0);
+    } /* if */
+
+    /* HDG: put this above the scancode lookup otherwise it is never reached */
+    if ( (event->key.keysym.sym == SDLK_PAUSE) &&
+         (event->key.state == SDL_PRESSED))
+    {
+        PausePressed = true;
+        return(0);
+    }
+
+    k = handle_keypad_enter_hack(event);
+    if (!k)
+    {
+        k = scancodes[event->key.keysym.sym];
+        if (!k)   /* No DOS equivalent defined. */
+            return(0);
+    } /* if */
+    
+    /* Fix elweirdo SDL capslock/numlock handling, always treat as press */
+    if ( (event->key.keysym.sym != SDLK_CAPSLOCK) &&
+         (event->key.keysym.sym != SDLK_NUMLOCK)  &&
+         (event->key.state == SDL_RELEASED) )
+        k += 128;  /* +128 signifies that the key is released in DOS. */
+
+    if (event->key.keysym.sym == SDLK_SCROLLOCK)
+        PanicPressed = true;
+
+    else
+    {
+        extended = ((k & 0xFF00) >> 8);
+
+        keyon = k & 0x80;
+        strippedkey = k & 0x7f;
+
+        if (extended != 0)
+        {
+            KeyboardQueue[ Keytail ] = extended;
+            Keytail = ( Keytail + 1 )&( KEYQMAX - 1 );
+            k = scancodes[event->key.keysym.sym] & 0xFF;
+            if (event->key.state == SDL_RELEASED)
+                k += 128;  /* +128 signifies that the key is released in DOS. */
+        }
+
+        if (keyon)        // Up event
+            Keystate[strippedkey]=0;
+        else                 // Down event
+        {
+            Keystate[strippedkey]=1;
+            LastScan = k;
+        }
+
+        KeyboardQueue[ Keytail ] = k;
+        Keytail = ( Keytail + 1 )&( KEYQMAX - 1 );
+    }
+
+    return(0);
+} /* sdl_key_filter */
+
+
+static int root_sdl_event_filter(const SDL_Event *event)
+{
+    switch (event->type)
+    {
+        case SDL_KEYUP:
+        case SDL_KEYDOWN:
+            return(sdl_key_filter(event));
+        case SDL_JOYBALLMOTION:
+        case SDL_MOUSEMOTION:
+            return(sdl_mouse_motion_filter(event));
+        case SDL_MOUSEBUTTONUP:
+        case SDL_MOUSEBUTTONDOWN:
+            return(sdl_mouse_button_filter(event));
+        case SDL_QUIT:
+            /* !!! rcg TEMP */
+            fprintf(stderr, "\n\n\nSDL_QUIT!\n\n\n");
+            SDL_Quit();
+            exit(42);
+    } /* switch */
+
+    return(1);
+} /* root_sdl_event_filter */
+
+
+static void sdl_handle_events(void)
+{
+    SDL_Event event;
+    while (SDL_PollEvent(&event))
+        root_sdl_event_filter(&event);
+} /* sdl_handle_events */
+#endif
+
+
+//******************************************************************************
+//
+// IN_PumpEvents () - Let platform process an event queue.
+//
+//******************************************************************************
+void IN_PumpEvents(void)
+{
+#if USE_SDL
+   sdl_handle_events();
+
+#elif PLATFORM_DOS
+   /* no-op. */
+
+#else
+#error please define for your platform.
+#endif
+}
+
+
+
+//******************************************************************************
+//
+// INL_GetMouseDelta () - Gets the amount that the mouse has moved from the
+//                        mouse driver
+//
+//******************************************************************************
+
+void INL_GetMouseDelta(int *x,int *y)
+{
+   IN_PumpEvents();
+
+#ifdef PLATFORM_DOS
+   union REGS inregs;
+   union REGS outregs;
+
+   if (!MousePresent)
+      *x = *y = 0;
+   else
+   {
+     inregs.w.ax = MDelta;
+     int386 (MouseInt, &inregs, &outregs);
+     *x = outregs.w.cx;
+     *y = outregs.w.dx;
+   }
+
+#elif USE_SDL
+   *x = sdl_mouse_delta_x;
+   *y = sdl_mouse_delta_y;
+
+   sdl_mouse_delta_x = sdl_mouse_delta_y = 0;
+
+#else
+   #error please define for your platform.
+#endif
+}
+
+
+
+//******************************************************************************
+//
+// IN_GetMouseButtons () - Gets the status of the mouse buttons from the
+//                         mouse driver
+//
+//******************************************************************************
+
+word IN_GetMouseButtons
+   (
+   void
+   )
+
+   {
+   word buttons = 0;
+
+   IN_PumpEvents();
+
+#if USE_SDL
+   buttons = sdl_mouse_button_mask;
+
+#elif PLATFORM_DOS
+   union REGS inregs;
+   union REGS outregs;
+
+   if (!MousePresent || !mouseenabled)
+      return (0);
+
+   inregs.w.ax = MButtons;
+   int386 (MouseInt, &inregs, &outregs);
+
+   buttons = outregs.w.bx;
+
+#else
+#  error please define for your platform.
+#endif
+
+// Used by menu routines that need to wait for a button release.
+// Sometimes the mouse driver misses an interrupt, so you can't wait for
+// a button to be released.  Instead, you must ignore any buttons that
+// are pressed.
+
+   IgnoreMouse &= buttons;
+   buttons &= ~IgnoreMouse;
+
+   return (buttons);
+}
+
+
+//******************************************************************************
+//
+// IN_IgnoreMouseButtons () -
+//    Tells the mouse to ignore the currently pressed buttons.
+//
+//******************************************************************************
+
+void IN_IgnoreMouseButtons
+   (
+   void
+   )
+
+   {
+   IgnoreMouse |= IN_GetMouseButtons();
+   }
+
+
+//******************************************************************************
+//
+// IN_GetJoyAbs () - Reads the absolute position of the specified joystick
+//
+//******************************************************************************
+
+void IN_GetJoyAbs (word joy, word *xp, word *yp)
+{
+   Joy_x  = Joy_y = 0;
+   Joy_xs = joy? 2 : 0;       // Find shift value for x axis
+   Joy_xb = 1 << Joy_xs;      // Use shift value to get x bit mask
+   Joy_ys = joy? 3 : 1;       // Do the same for y axis
+   Joy_yb = 1 << Joy_ys;
+
+#ifdef DOS
+   JoyStick_Vals ();
+#else
+   if (joy < sdl_total_sticks)
+   {
+	   Joy_x = SDL_JoystickGetAxis (sdl_joysticks[joy], 0);
+	   Joy_y = SDL_JoystickGetAxis (sdl_joysticks[joy], 1);
+   } else {
+	   Joy_x = 0;
+	   Joy_y = 0;
+   }
+#endif
+
+   *xp = Joy_x;
+   *yp = Joy_y;
+}
+
+void JoyStick_Vals (void)
+{
+
+}
+
+
+//******************************************************************************
+//
+// INL_GetJoyDelta () - Returns the relative movement of the specified
+//                     joystick (from +/-127)
+//
+//******************************************************************************
+
+void INL_GetJoyDelta (word joy, int *dx, int *dy)
+{
+   word        x, y;
+   JoystickDef *def;
+   static longword lasttime;
+
+   IN_GetJoyAbs (joy, &x, &y);
+   def = JoyDefs + joy;
+
+   if (x < def->threshMinX)
+   {
+      if (x < def->joyMinX)
+         x = def->joyMinX;
+
+      x = -(x - def->threshMinX);
+      x *= def->joyMultXL;
+      x >>= JoyScaleShift;
+      *dx = (x > 127)? -127 : -x;
+   }
+   else if (x > def->threshMaxX)
+   {
+      if (x > def->joyMaxX)
+         x = def->joyMaxX;
+
+      x = x - def->threshMaxX;
+      x *= def->joyMultXH;
+      x >>= JoyScaleShift;
+      *dx = (x > 127)? 127 : x;
+   }
+   else
+      *dx = 0;
+
+   if (y < def->threshMinY)
+   {
+      if (y < def->joyMinY)
+         y = def->joyMinY;
+
+      y = -(y - def->threshMinY);
+      y *= def->joyMultYL;
+      y >>= JoyScaleShift;
+      *dy = (y > 127)? -127 : -y;
+   }
+   else if (y > def->threshMaxY)
+   {
+      if (y > def->joyMaxY)
+         y = def->joyMaxY;
+
+      y = y - def->threshMaxY;
+      y *= def->joyMultYH;
+      y >>= JoyScaleShift;
+      *dy = (y > 127)? 127 : y;
+   }
+   else
+      *dy = 0;
+
+   lasttime = GetTicCount();
+}
+
+
+
+//******************************************************************************
+//
+// INL_GetJoyButtons () - Returns the button status of the specified
+//                        joystick
+//
+//******************************************************************************
+
+word INL_GetJoyButtons (word joy)
+{
+   word  result = 0;
+
+#if USE_SDL
+   if (joy < sdl_total_sticks)
+       result = sdl_stick_button_state[joy];
+
+#elif PLATFORM_DOS
+   result = inp (0x201);   // Get all the joystick buttons
+   result >>= joy? 6 : 4;  // Shift into bits 0-1
+   result &= 3;            // Mask off the useless bits
+   result ^= 3;
+
+#else
+#error please define for your platform.
+#endif
+
+   return result;
+}
+
+#if 0
+//******************************************************************************
+//
+// IN_GetJoyButtonsDB () - Returns the de-bounced button status of the
+//                         specified joystick
+//
+//******************************************************************************
+
+word IN_GetJoyButtonsDB (word joy)
+{
+   longword lasttime;
+   word result1,result2;
+
+   do
+   {
+      result1 = INL_GetJoyButtons (joy);
+      lasttime = GetTicCount();
+      while (GetTicCount() == lasttime)
+         ;
+      result2 = INL_GetJoyButtons (joy);
+   } while (result1 != result2);
+
+   return(result1);
+}
+#endif
+
+//******************************************************************************
+//
+// INL_StartMouse () - Detects and sets up the mouse
+//
+//******************************************************************************
+
+boolean INL_StartMouse (void)
+{
+
+   boolean retval = false;
+
+#if USE_SDL
+   /* no-op. */
+   retval = true;
+
+#elif PLATFORM_DOS
+   union REGS inregs;
+   union REGS outregs;
+
+   inregs.w.ax = 0;
+   int386 (MouseInt, &inregs, &outregs);
+
+   retval = ((outregs.w.ax == 0xffff) ? true : false);
+
+#else
+#error please define your platform.
+#endif
+
+   return (retval);
+}
+
+
+
+//******************************************************************************
+//
+// INL_SetJoyScale () - Sets up scaling values for the specified joystick
+//
+//******************************************************************************
+
+void INL_SetJoyScale (word joy)
+{
+   JoystickDef *def;
+
+   def = &JoyDefs[joy];
+   def->joyMultXL = JoyScaleMax / (def->threshMinX - def->joyMinX);
+   def->joyMultXH = JoyScaleMax / (def->joyMaxX - def->threshMaxX);
+   def->joyMultYL = JoyScaleMax / (def->threshMinY - def->joyMinY);
+   def->joyMultYH = JoyScaleMax / (def->joyMaxY - def->threshMaxY);
+}
+
+
+
+//******************************************************************************
+//
+// IN_SetupJoy () - Sets up thresholding values and calls INL_SetJoyScale()
+//                  to set up scaling values
+//
+//******************************************************************************
+
+void IN_SetupJoy (word joy, word minx, word maxx, word miny, word maxy)
+{
+   word     d,r;
+   JoystickDef *def;
+
+   def = &JoyDefs[joy];
+
+   def->joyMinX = minx;
+   def->joyMaxX = maxx;
+   r = maxx - minx;
+   d = r / 3;
+   def->threshMinX = ((r / 2) - d) + minx;
+   def->threshMaxX = ((r / 2) + d) + minx;
+
+   def->joyMinY = miny;
+   def->joyMaxY = maxy;
+   r = maxy - miny;
+   d = r / 3;
+   def->threshMinY = ((r / 2) - d) + miny;
+   def->threshMaxY = ((r / 2) + d) + miny;
+
+   INL_SetJoyScale (joy);
+}
+
+
+//******************************************************************************
+//
+// INL_StartJoy () - Detects & auto-configures the specified joystick
+//                   The auto-config assumes the joystick is centered
+//
+//******************************************************************************
+
+
+boolean INL_StartJoy (word joy)
+{
+   word x,y;
+
+#if USE_SDL
+   if (!SDL_WasInit(SDL_INIT_JOYSTICK))
+   {
+       SDL_Init(SDL_INIT_JOYSTICK);
+       sdl_total_sticks = SDL_NumJoysticks();
+       if (sdl_total_sticks > MaxJoys) sdl_total_sticks = MaxJoys;
+
+       if ((sdl_stick_button_state == NULL) && (sdl_total_sticks > 0))
+       {
+           sdl_stick_button_state = (word *) malloc(sizeof (word) * sdl_total_sticks);
+           if (sdl_stick_button_state == NULL)
+               SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+           else
+               memset(sdl_stick_button_state, '\0', sizeof (word) * sdl_total_sticks);
+       }
+       SDL_JoystickEventState(SDL_ENABLE);
+   }
+
+   if (joy >= sdl_total_sticks) return (false);
+   sdl_joysticks[joy] = SDL_JoystickOpen (joy);
+#endif
+
+   IN_GetJoyAbs (joy, &x, &y);
+
+   if
+   (
+      ((x == 0) || (x > MaxJoyValue - 10))
+   || ((y == 0) || (y > MaxJoyValue - 10))
+   )
+      return(false);
+   else
+   {
+      IN_SetupJoy (joy, 0, x * 2, 0, y * 2);
+      return (true);
+   }
+}
+
+
+
+//******************************************************************************
+//
+// INL_ShutJoy() - Cleans up the joystick stuff
+//
+//******************************************************************************
+
+void INL_ShutJoy (word joy)
+{
+   JoysPresent[joy] = false;
+#ifndef DOS
+   if (joy < sdl_total_sticks) SDL_JoystickClose (sdl_joysticks[joy]);
+#endif
+}
+
+
+
+//******************************************************************************
+//
+// IN_Startup() - Starts up the Input Mgr
+//
+//******************************************************************************
+
+
+void IN_Startup (void)
+{
+   boolean checkjoys,
+           checkmouse,
+           checkcyberman,
+           checkspaceball,
+           swiftstatus,
+           checkassassin;
+
+   word    i;
+
+   if (IN_Started==true)
+      return;
+
+#if USE_SDL
+
+#if PLATFORM_WIN32
+// fixme: remove this.
+sdl_mouse_grabbed = 1;
+#endif
+
+/*
+  all keys are now mapped to the wolf3d-style names,
+  except where no such name is available.
+ */
+    memset(scancodes, '\0', sizeof (scancodes));
+    scancodes[SDLK_ESCAPE]          = sc_Escape;
+    scancodes[SDLK_1]               = sc_1;
+    scancodes[SDLK_2]               = sc_2;
+    scancodes[SDLK_3]               = sc_3;
+    scancodes[SDLK_4]               = sc_4;
+    scancodes[SDLK_5]               = sc_5;
+    scancodes[SDLK_6]               = sc_6;
+    scancodes[SDLK_7]               = sc_7;
+    scancodes[SDLK_8]               = sc_8;
+    scancodes[SDLK_9]               = sc_9;
+    scancodes[SDLK_0]               = sc_0;
+    
+    //scancodes[SDLK_EQUALS]          = 0x4E;
+    scancodes[SDLK_EQUALS]          = sc_Equals;
+    
+    scancodes[SDLK_BACKSPACE]       = sc_BackSpace;
+    scancodes[SDLK_TAB]             = sc_Tab;
+    scancodes[SDLK_q]               = sc_Q;
+    scancodes[SDLK_w]               = sc_W;
+    scancodes[SDLK_e]               = sc_E;
+    scancodes[SDLK_r]               = sc_R;
+    scancodes[SDLK_t]               = sc_T;
+    scancodes[SDLK_y]               = sc_Y;
+    scancodes[SDLK_u]               = sc_U;
+    scancodes[SDLK_i]               = sc_I;
+    scancodes[SDLK_o]               = sc_O;
+    scancodes[SDLK_p]               = sc_P;
+    scancodes[SDLK_LEFTBRACKET]     = sc_OpenBracket;
+    scancodes[SDLK_RIGHTBRACKET]    = sc_CloseBracket;
+    scancodes[SDLK_RETURN]          = sc_Return;
+    scancodes[SDLK_LCTRL]           = sc_Control;
+    scancodes[SDLK_a]               = sc_A;
+    scancodes[SDLK_s]               = sc_S;
+    scancodes[SDLK_d]               = sc_D;
+    scancodes[SDLK_f]               = sc_F;
+    scancodes[SDLK_g]               = sc_G;
+    scancodes[SDLK_h]               = sc_H;
+    scancodes[SDLK_j]               = sc_J;
+    scancodes[SDLK_k]               = sc_K;
+    scancodes[SDLK_l]               = sc_L;
+    scancodes[SDLK_SEMICOLON]       = 0x27;
+    scancodes[SDLK_QUOTE]           = 0x28;
+    scancodes[SDLK_BACKQUOTE]       = 0x29;
+    
+    /* left shift, but ROTT maps it to right shift in isr.c */
+    scancodes[SDLK_LSHIFT]          = sc_RShift; /* sc_LShift */
+    
+    scancodes[SDLK_BACKSLASH]       = 0x2B;
+    scancodes[SDLK_z]               = sc_Z;
+    scancodes[SDLK_x]               = sc_X;
+    scancodes[SDLK_c]               = sc_C;
+    scancodes[SDLK_v]               = sc_V;
+    scancodes[SDLK_b]               = sc_B;
+    scancodes[SDLK_n]               = sc_N;
+    scancodes[SDLK_m]               = sc_M;
+    scancodes[SDLK_COMMA]           = sc_Comma;
+    scancodes[SDLK_PERIOD]          = sc_Period;
+    scancodes[SDLK_SLASH]           = 0x35;
+    scancodes[SDLK_RSHIFT]          = sc_RShift;
+    scancodes[SDLK_KP_DIVIDE]       = 0x35;
+    
+    /* 0x37 is printscreen */
+    //scancodes[SDLK_KP_MULTIPLY]     = 0x37;
+    
+    scancodes[SDLK_LALT]            = sc_Alt;
+    scancodes[SDLK_RALT]            = sc_Alt;
+    scancodes[SDLK_MODE]            = sc_Alt;
+    scancodes[SDLK_RCTRL]           = sc_Control;
+    scancodes[SDLK_SPACE]           = sc_Space;
+    scancodes[SDLK_CAPSLOCK]        = sc_CapsLock;
+    scancodes[SDLK_F1]              = sc_F1;
+    scancodes[SDLK_F2]              = sc_F2;
+    scancodes[SDLK_F3]              = sc_F3;
+    scancodes[SDLK_F4]              = sc_F4;
+    scancodes[SDLK_F5]              = sc_F5;
+    scancodes[SDLK_F6]              = sc_F6;
+    scancodes[SDLK_F7]              = sc_F7;
+    scancodes[SDLK_F8]              = sc_F8;
+    scancodes[SDLK_F9]              = sc_F9;
+    scancodes[SDLK_F10]             = sc_F10;
+    scancodes[SDLK_F11]             = sc_F11;
+    scancodes[SDLK_F12]             = sc_F12;
+    scancodes[SDLK_NUMLOCK]         = 0x45;
+    scancodes[SDLK_SCROLLOCK]       = 0x46;
+    
+    //scancodes[SDLK_MINUS]           = 0x4A;
+    scancodes[SDLK_MINUS]           = sc_Minus;
+    
+    scancodes[SDLK_KP7]             = sc_Home;
+    scancodes[SDLK_KP8]             = sc_UpArrow;
+    scancodes[SDLK_KP9]             = sc_PgUp;
+    scancodes[SDLK_HOME]            = sc_Home;
+    scancodes[SDLK_UP]              = sc_UpArrow;
+    scancodes[SDLK_PAGEUP]          = sc_PgUp;
+    // Make this a normal minus, for viewport changing
+    //scancodes[SDLK_KP_MINUS]        = 0xE04A;
+    scancodes[SDLK_KP_MINUS]        = sc_Minus;
+    scancodes[SDLK_KP4]             = sc_LeftArrow;
+    scancodes[SDLK_KP5]             = 0x4C;
+    scancodes[SDLK_KP6]             = sc_RightArrow;
+    scancodes[SDLK_LEFT]            = sc_LeftArrow;
+    scancodes[SDLK_RIGHT]           = sc_RightArrow;
+    
+    //scancodes[SDLK_KP_PLUS]         = 0x4E;
+    scancodes[SDLK_KP_PLUS]         = sc_Plus;
+    
+    scancodes[SDLK_KP1]             = sc_End;
+    scancodes[SDLK_KP2]             = sc_DownArrow;
+    scancodes[SDLK_KP3]             = sc_PgDn;
+    scancodes[SDLK_END]             = sc_End;
+    scancodes[SDLK_DOWN]            = sc_DownArrow;
+    scancodes[SDLK_PAGEDOWN]        = sc_PgDn;
+    scancodes[SDLK_DELETE]          = sc_Delete;
+    scancodes[SDLK_KP0]             = sc_Insert;
+    scancodes[SDLK_INSERT]          = sc_Insert;
+    scancodes[SDLK_KP_ENTER]        = sc_Return;
+#endif
+
+   checkjoys        = true;
+   checkmouse       = true;
+   checkcyberman    = false;
+   checkassassin    = false;
+   checkspaceball   = false;
+   SpaceBallPresent = false;
+   CybermanPresent  = false;
+   AssassinPresent  = false;
+
+   for (i = 1; i < _argc; i++)
+   {
+      switch (US_CheckParm (_argv[i], ParmStrings))
+      {
+      case 0:
+         checkjoys = false;
+      break;
+
+      case 1:
+         checkmouse = false;
+      break;
+
+      case 2:
+         checkspaceball = true;
+      break;
+
+      case 3:
+         checkcyberman = true;
+         checkmouse = false;
+      break;
+
+      case 4:
+         checkassassin = true;
+         checkmouse = false;
+      break;
+      }
+   }
+
+   MousePresent = checkmouse ? INL_StartMouse() : false;
+
+   if (!MousePresent)
+      mouseenabled = false;
+   else
+      {
+      if (!quiet)
+         printf("IN_Startup: Mouse Present\n");
+      }
+
+   for (i = 0;i < MaxJoys;i++)
+      {
+      JoysPresent[i] = checkjoys ? INL_StartJoy(i) : false;
+      if (INL_StartJoy(i))
+         {
+         if (!quiet)
+            printf("IN_Startup: Joystick Present\n");
+         }
+      }
+
+   if (checkspaceball)
+      {
+      OpenSpaceBall ();
+      spaceballenabled=true;
+      }
+
+   if ((checkcyberman || checkassassin) && (swiftstatus = SWIFT_Initialize ()))
+   {
+      int dynamic;
+
+      if (checkcyberman)
+         {
+         CybermanPresent = swiftstatus;
+         cybermanenabled = true;
+         }
+      else if (checkassassin)
+         {
+         AssassinPresent = checkassassin & swiftstatus;
+         assassinenabled = true;
+         }
+
+      dynamic = SWIFT_GetDynamicDeviceData ();
+
+      SWIFT_TactileFeedback (40, 20, 20);
+
+      if (SWIFT_GetDynamicDeviceData () == 2)
+         Error ("SWIFT ERROR : External Power too high!\n");
+
+      SWIFT_TactileFeedback (100, 10, 10);
+      if (!quiet)
+         printf("IN_Startup: Swift Device Present\n");
+   }
+
+   IN_Started = true;
+}
+
+
+#if 0
+//******************************************************************************
+//
+// IN_Default() - Sets up default conditions for the Input Mgr
+//
+//******************************************************************************
+
+void IN_Default (boolean gotit, ControlType in)
+{
+   if
+   (
+      (!gotit)
+   ||    ((in == ctrl_Joystick1) && !JoysPresent[0])
+   ||    ((in == ctrl_Joystick2) && !JoysPresent[1])
+   ||    ((in == ctrl_Mouse) && !MousePresent)
+   )
+      in = ctrl_Keyboard1;
+   IN_SetControlType (0, in);
+}
+#endif
+
+//******************************************************************************
+//
+// IN_Shutdown() - Shuts down the Input Mgr
+//
+//******************************************************************************
+
+void IN_Shutdown (void)
+{
+   word  i;
+
+   if (IN_Started==false)
+      return;
+
+//   INL_ShutMouse();
+
+   for (i = 0;i < MaxJoys;i++)
+      INL_ShutJoy(i);
+
+   if (CybermanPresent || AssassinPresent)
+      SWIFT_Terminate ();
+
+   CloseSpaceBall ();
+
+   IN_Started = false;
+}
+
+
+//******************************************************************************
+//
+// IN_ClearKeysDown() - Clears the keyboard array
+//
+//******************************************************************************
+
+void IN_ClearKeysDown (void)
+{
+   LastScan = sc_None;
+   memset ((void *)Keyboard, 0, sizeof (Keyboard));
+}
+
+
+//******************************************************************************
+//
+// IN_ReadControl() - Reads the device associated with the specified
+//    player and fills in the control info struct
+//
+//******************************************************************************
+
+void IN_ReadControl (int player, ControlInfo *info)
+{
+   boolean     realdelta;
+   word        buttons;
+   int         dx,dy;
+   Motion      mx,my;
+   ControlType type;
+
+   KeyboardDef *def;
+
+   dx = dy = 0;
+   mx = my = motion_None;
+   buttons = 0;
+
+
+   switch (type = Controls[player])
+   {
+      case ctrl_Keyboard:
+         def = &KbdDefs;
+
+#if 0
+         if (Keyboard[def->upleft])
+            mx = motion_Left,my = motion_Up;
+         else if (Keyboard[def->upright])
+            mx = motion_Right,my = motion_Up;
+         else if (Keyboard[def->downleft])
+            mx = motion_Left,my = motion_Down;
+         else if (Keyboard[def->downright])
+            mx = motion_Right,my = motion_Down;
+#endif
+         if (Keyboard[sc_UpArrow])
+            my = motion_Up;
+         else if (Keyboard[sc_DownArrow])
+            my = motion_Down;
+
+         if (Keyboard[sc_LeftArrow])
+            mx = motion_Left;
+         else if (Keyboard[sc_RightArrow])
+            mx = motion_Right;
+
+         if (Keyboard[def->button0])
+            buttons += 1 << 0;
+         if (Keyboard[def->button1])
+            buttons += 1 << 1;
+         realdelta = false;
+      break;
+
+#if 0
+      case ctrl_Joystick1:
+      case ctrl_Joystick2:
+         INL_GetJoyDelta (type - ctrl_Joystick, &dx, &dy);
+         buttons = INL_GetJoyButtons (type - ctrl_Joystick);
+         realdelta = true;
+      break;
+
+      case ctrl_Mouse:
+         INL_GetMouseDelta (&dx,&dy);
+         buttons = IN_GetMouseButtons ();
+         realdelta = true;
+      break;
+           
+#endif
+   default:
+       ;
+   }
+
+   if (realdelta)
+   {
+      mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None);
+      my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None);
+   }
+   else
+   {
+      dx = mx * 127;
+      dy = my * 127;
+   }
+
+   info->x = dx;
+   info->xaxis = mx;
+   info->y = dy;
+   info->yaxis = my;
+   info->button0 = buttons & (1 << 0);
+   info->button1 = buttons & (1 << 1);
+   info->button2 = buttons & (1 << 2);
+   info->button3 = buttons & (1 << 3);
+   info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
+}
+
+
+//******************************************************************************
+//
+// IN_WaitForKey() - Waits for a scan code, then clears LastScan and
+//    returns the scan code
+//
+//******************************************************************************
+
+ScanCode IN_WaitForKey (void)
+{
+   ScanCode result;
+
+   while (!(result = LastScan))
+      IN_PumpEvents();
+   LastScan = 0;
+   return (result);
+}
+
+
+//******************************************************************************
+//
+// IN_Ack() - waits for a button or key press.  If a button is down, upon
+// calling, it must be released for it to be recognized
+//
+//******************************************************************************
+
+boolean  btnstate[8];
+
+void IN_StartAck (void)
+{
+   unsigned i,
+            buttons = 0;
+
+//
+// get initial state of everything
+//
+   LastScan = 0;
+
+   IN_ClearKeysDown ();
+   memset (btnstate, 0, sizeof(btnstate));
+
+   IN_PumpEvents();
+
+   buttons = IN_JoyButtons () << 4;
+
+   buttons |= IN_GetMouseButtons();
+
+	if (SpaceBallPresent && spaceballenabled)
+		{
+      buttons |= GetSpaceBallButtons ();
+      }
+
+   for (i=0;i<8;i++,buttons>>=1)
+      if (buttons&1)
+         btnstate[i] = true;
+}
+
+
+
+//******************************************************************************
+//
+// IN_CheckAck ()
+//
+//******************************************************************************
+
+boolean IN_CheckAck (void)
+{
+   unsigned i,
+            buttons = 0;
+
+//
+// see if something has been pressed
+//
+   if (LastScan)
+      return true;
+
+   IN_PumpEvents();
+
+   buttons = IN_JoyButtons () << 4;
+
+   buttons |= IN_GetMouseButtons();
+
+   for (i=0;i<8;i++,buttons>>=1)
+      if ( buttons&1 )
+      {
+         if (!btnstate[i])
+            return true;
+      }
+      else
+         btnstate[i]=false;
+
+   return false;
+}
+
+
+
+//******************************************************************************
+//
+// IN_Ack ()
+//
+//******************************************************************************
+
+void IN_Ack (void)
+{
+   IN_StartAck ();
+
+   while (!IN_CheckAck ())
+   ;
+}
+
+
+
+//******************************************************************************
+//
+// IN_UserInput() - Waits for the specified delay time (in ticks) or the
+//    user pressing a key or a mouse button. If the clear flag is set, it
+//    then either clears the key or waits for the user to let the mouse
+//    button up.
+//
+//******************************************************************************
+
+boolean IN_UserInput (long delay)
+{
+   long lasttime;
+
+   lasttime = GetTicCount();
+
+   IN_StartAck ();
+   do
+   {
+      if (IN_CheckAck())
+         return true;
+   } while ((GetTicCount() - lasttime) < delay);
+
+   return (false);
+}
+
+//===========================================================================
+
+
+/*
+===================
+=
+= IN_JoyButtons
+=
+===================
+*/
+
+byte IN_JoyButtons (void)
+{
+   unsigned joybits = 0;
+
+#if USE_SDL
+   joybits = sdl_sticks_joybits;
+
+#elif PLATFORM_DOS
+   joybits = inp (0x201);  // Get all the joystick buttons
+   joybits >>= 4;          // only the high bits are useful
+   joybits ^= 15;          // return with 1=pressed
+
+#else
+#error define your platform.
+#endif
+
+   return (byte) joybits;
+}
+
+
+//******************************************************************************
+//
+// IN_UpdateKeyboard ()
+//
+//******************************************************************************
+
+/* HACK HACK HACK */
+static int queuegotit=0;
+
+void IN_UpdateKeyboard (void)
+{
+   int tail;
+   int key;
+
+   if (!queuegotit)
+       IN_PumpEvents();
+   
+   queuegotit=0;
+   
+   if (Keytail != Keyhead)
+   {
+      tail = Keytail;
+
+      while (Keyhead != tail)
+      {
+         if (KeyboardQueue[Keyhead] & 0x80)        // Up event
+         {
+            key = KeyboardQueue[Keyhead] & 0x7F;   // AND off high bit
+
+//            if (keysdown[key])
+//            {
+//               KeyboardQueue[Keytail] = KeyboardQueue[Keyhead];
+//               Keytail = (Keytail+1)&(KEYQMAX-1);
+//            }
+//            else
+    				Keyboard[key] = 0;
+         }
+         else                                      // Down event
+         {
+            Keyboard[KeyboardQueue[Keyhead]] = 1;
+//            keysdown[KeyboardQueue[Keyhead]] = 1;
+         }
+
+         Keyhead = (Keyhead+1)&(KEYQMAX-1);
+
+      }        // while
+    }           // if
+
+   // Carry over movement keys from the last refresh
+//   keysdown[sc_RightArrow] = Keyboard[sc_RightArrow];
+//   keysdown[sc_LeftArrow]  = Keyboard[sc_LeftArrow];
+//   keysdown[sc_UpArrow]    = Keyboard[sc_UpArrow];
+//   keysdown[sc_DownArrow]  = Keyboard[sc_DownArrow];
+   }
+
+
+
+//******************************************************************************
+//
+// IN_InputUpdateKeyboard ()
+//
+//******************************************************************************
+
+int IN_InputUpdateKeyboard (void)
+{
+   int key;
+   int returnval = 0;
+   boolean done = false;
+
+//   _disable ();
+
+   if (Keytail != Keyhead)
+   {
+      int tail = Keytail;
+
+      while (!done && (Keyhead != tail))
+      {
+         if (KeyboardQueue[Keyhead] & 0x80)        // Up event
+         {
+            key = KeyboardQueue[Keyhead] & 0x7F;   // AND off high bit
+
+            Keyboard[key] = 0;
+         }
+         else                                      // Down event
+         {
+            Keyboard[KeyboardQueue[Keyhead]] = 1;
+            returnval = KeyboardQueue[Keyhead];
+            done = true;
+         }
+
+         Keyhead = (Keyhead+1)&(KEYQMAX-1);
+      }
+    }           // if
+
+//   _enable ();
+
+   return (returnval);
+}
+
+
+//******************************************************************************
+//
+// IN_ClearKeyboardQueue ()
+//
+//******************************************************************************
+
+void IN_ClearKeyboardQueue (void)
+{
+   return;
+
+//   IN_ClearKeysDown ();
+
+//   Keytail = Keyhead = 0;
+//   memset (KeyboardQueue, 0, sizeof (KeyboardQueue));
+//   I_SendKeyboardData(0xf6);
+//   I_SendKeyboardData(0xf4);
+}
+
+
+#if 0
+//******************************************************************************
+//
+// IN_DumpKeyboardQueue ()
+//
+//******************************************************************************
+
+void IN_DumpKeyboardQueue (void)
+{
+   int head = Keyhead;
+   int tail = Keytail;
+   int key;
+
+   if (tail != head)
+   {
+      SoftError( "START DUMP\n");
+
+      while (head != tail)
+      {
+         if (KeyboardQueue[head] & 0x80)        // Up event
+         {
+            key = KeyboardQueue[head] & 0x7F;   // AND off high bit
+
+//            if (keysdown[key])
+//            {
+//               SoftError( "%s - was put in next refresh\n",
+//                                 IN_GetScanName (key));
+//            }
+//            else
+//            {
+               if (Keyboard[key] == 0)
+                  SoftError( "%s %ld - was lost\n", IN_GetScanName (key), key);
+               else
+                  SoftError( "%s %ld - up\n", IN_GetScanName (key), key);
+//            }
+         }
+         else                                      // Down event
+            SoftError( "%s %ld - down\n", IN_GetScanName (KeyboardQueue[head]), KeyboardQueue[head]);
+
+         head = (head+1)&(KEYQMAX-1);
+      }        // while
+
+      SoftError( "END DUMP\n");
+
+    }           // if
+}
+#endif
+
+
+//******************************************************************************
+//
+// QueueLetterInput ()
+//
+//******************************************************************************
+
+void QueueLetterInput (void)
+{
+   int head = Keyhead;
+   int tail = Keytail;
+   char c;
+   int scancode;
+   boolean send = false;
+
+#ifndef PLATFORM_DOS
+   /* HACK HACK HACK */
+   /* 
+     OK, we want the new keys NOW, and not when the update gets them.
+     Since this called before IN_UpdateKeyboard in PollKeyboardButtons,
+     we shall update here.  The hack is there to prevent IN_UpdateKeyboard 
+     from stealing any keys... - SBF
+    */
+   IN_PumpEvents();
+   head = Keyhead;
+   tail = Keytail;
+   queuegotit=1;
+   /* HACK HACK HACK */
+#endif
+
+   while (head != tail)
+      {
+      if (!(KeyboardQueue[head] & 0x80))        // Down event
+         {
+         scancode = KeyboardQueue[head];
+
+         if (Keyboard[sc_RShift] || Keyboard[sc_LShift])
+            {
+            c = ShiftedScanChars[scancode];
+            }
+         else
+            {
+            c = ScanChars[scancode];
+            }
+
+         // If "is printable char", queue the character
+         if (c)
+            {
+            LetterQueue[LastLetter] = c;
+            LastLetter = (LastLetter+1)&(MAXLETTERS-1);
+
+            // If typing a message, update the text with 'c'
+
+            if ( MSG.messageon )
+               {
+               Keystate[scancode]=0;
+               KeyboardQueue[head] = 0;
+               if ( MSG.inmenu )
+                  {
+                  if ( ( c == 'A' ) || ( c == 'a' ) )
+                     {
+                     MSG.towho = MSG_DIRECTED_TO_ALL;
+                     send      = true;
+                     }
+
+                  if ( ( gamestate.teamplay ) &&
+                     ( ( c == 'T' ) || ( c == 't' ) ) )
+                     {
+                     MSG.towho = MSG_DIRECTED_TO_TEAM;
+                     send      = true;
+                     }
+
+                  if ( ( c >= '0' ) && ( c <= '9' ) )
+                     {
+                     int who;
+
+                     if ( c == '0' )
+                        {
+                        who = 10;
+                        }
+                     else
+                        {
+                        who = c - '1';
+                        }
+
+                     // Skip over local player
+                     if ( who >= consoleplayer )
+                        {
+                        who++;
+                        }
+
+                     if ( who < numplayers )
+                        {
+                        MSG.towho = who;
+                        send      = true;
+                        }
+                     }
+
+                  if ( send )
+                     {
+                     MSG.messageon = false;
+                     KeyboardQueue[ head ] = 0;
+                     Keyboard[ scancode ]  = 0;
+                     LastScan              = 0;
+                     FinishModemMessage( MSG.textnum, true );
+                     }
+                  }
+               else if ( ( scancode >= sc_1 ) && ( scancode <= sc_0 ) &&
+                  ( Keyboard[ sc_Alt ] ) )
+                  {
+                  int msg;
+
+                  msg = scancode - sc_1;
+
+                  if ( CommbatMacros[ msg ].avail )
+                     {
+                     MSG.length = strlen( CommbatMacros[ msg ].macro ) + 1;
+                     strcpy( Messages[ MSG.textnum ].text,
+                        CommbatMacros[ msg ].macro );
+
+                     MSG.messageon = false;
+                     FinishModemMessage( MSG.textnum, true );
+                     KeyboardQueue[ head ] = 0;
+                     Keyboard[ sc_Enter ]  = 0;
+                     Keyboard[ sc_Escape ] = 0;
+                     LastScan              = 0;
+                     }
+                  else
+                     {
+                     MSG.messageon = false;
+                     MSG.directed  = false;
+
+                     FinishModemMessage( MSG.textnum, false );
+                     AddMessage( "No macro.", MSG_MACRO );
+                     KeyboardQueue[ head ] = 0;
+                     Keyboard[ sc_Enter ]  = 0;
+                     Keyboard[ sc_Escape ] = 0;
+                     LastScan              = 0;
+                     }
+                  }
+               else if ( MSG.length < MAXMESSAGELENGTH )
+                  {
+                  UpdateModemMessage (MSG.textnum, c);
+                  }
+               }
+            }
+         else
+            {
+            // If typing a message, check for special characters
+
+            if ( MSG.messageon && MSG.inmenu )
+               {
+               if ( scancode == sc_Escape )
+                  {
+                  MSG.messageon = false;
+                  MSG.directed  = false;
+                  FinishModemMessage( MSG.textnum, false );
+                  KeyboardQueue[head] = 0;
+                  Keyboard[sc_Enter]  = 0;
+                  Keyboard[sc_Escape] = 0;
+                  LastScan            = 0;
+                  }
+               }
+            else if ( MSG.messageon && !MSG.inmenu )
+               {
+               if ( ( scancode >= sc_F1 ) &&
+                  ( scancode <= sc_F10 ) )
+                  {
+                  MSG.remoteridicule = scancode - sc_F1;
+                  MSG.messageon = false;
+                  FinishModemMessage(MSG.textnum, true);
+                  KeyboardQueue[head] = 0;
+                  Keyboard[sc_Enter]  = 0;
+                  Keyboard[sc_Escape] = 0;
+                  LastScan            = 0;
+                  }
+
+               switch (scancode)
+                  {
+                  case sc_BackSpace:
+                     KeyboardQueue[head] = 0;
+                     if (MSG.length > 1)
+                        {
+                        ModemMessageDeleteChar (MSG.textnum);
+                        }
+                     Keystate[scancode]=0;
+                     break;
+
+                  case sc_Enter:
+                     MSG.messageon = false;
+                     FinishModemMessage(MSG.textnum, true);
+                     KeyboardQueue[head] = 0;
+                     Keyboard[sc_Enter]  = 0;
+                     Keyboard[sc_Escape] = 0;
+                     LastScan            = 0;
+                     Keystate[scancode]=0;
+                     break;
+
+                  case sc_Escape:
+                     MSG.messageon = false;
+                     MSG.directed  = false;
+                     FinishModemMessage(MSG.textnum, false);
+                     KeyboardQueue[head] = 0;
+                     Keyboard[sc_Enter]  = 0;
+                     Keyboard[sc_Escape] = 0;
+                     LastScan            = 0;
+                     break;
+                  }
+               }
+            }
+         }
+
+      head = (head+1)&(KEYQMAX-1);
+      }        // while
+   }

Added: tags/rott-1.1/rott/rt_in.h
===================================================================
--- tags/rott-1.1/rott/rt_in.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_in.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,212 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+// Public header for RT_IN.C.
+//
+//***************************************************************************
+
+#ifndef _rt_in_public
+#define _rt_in_public
+
+#include "develop.h"
+#include "rottnet.h"
+
+//***************************************************************************
+//
+// DEFINES
+//
+//***************************************************************************
+
+#define MAXLETTERS   32
+
+
+//***************************************************************************
+//
+// TYPEDEFS
+//
+//***************************************************************************
+
+typedef  enum
+{
+	motion_Left  = -1,
+	motion_Up    = -1,
+   motion_None  = 0,
+   motion_Right = 1,
+   motion_Down  = 1
+} Motion;
+
+
+typedef  enum
+{
+   dir_North,
+   dir_NorthEast,
+   dir_East,
+   dir_SouthEast,
+   dir_South,
+   dir_SouthWest,
+   dir_West,
+   dir_NorthWest,
+   dir_None
+} Direction;
+
+typedef byte ScanCode;
+
+typedef  enum
+{
+	ctrl_Keyboard,
+	ctrl_Keyboard1 = ctrl_Keyboard, ctrl_Keyboard2,
+	ctrl_Joystick,
+	ctrl_Joystick1 = ctrl_Joystick, ctrl_Joystick2,
+	ctrl_Mouse
+} ControlType;
+
+typedef  struct
+{
+	boolean     button0,
+					button1,
+					button2,
+					button3;
+	int         x,
+					y;
+	Motion      xaxis,
+					yaxis;
+	Direction   dir;
+} CursorInfo;
+
+
+typedef  CursorInfo  ControlInfo;
+
+
+typedef  struct
+{
+   ScanCode button0,
+            button1,
+            upleft,
+            up,
+            upright,
+            left,
+            right,
+            downleft,
+            down,
+            downright;
+} KeyboardDef;
+
+
+typedef struct
+{
+   word  joyMinX,joyMinY,
+         threshMinX,threshMinY,
+         threshMaxX,threshMaxY,
+         joyMaxX,joyMaxY,
+         joyMultXL,joyMultYL,
+         joyMultXH,joyMultYH;
+} JoystickDef;
+
+
+typedef struct
+{
+   boolean messageon;
+   boolean directed;
+   boolean inmenu;
+   int     remoteridicule;
+   int     towho;
+   int     textnum;
+   int     length;
+} ModemMessage;
+
+
+//***************************************************************************
+//
+// GLOBALS
+//
+//***************************************************************************
+
+extern boolean MousePresent;
+extern boolean JoysPresent[MaxJoys];
+extern boolean JoyPadPresent;
+extern int     mouseadjustment;
+extern int     threshold;
+
+extern boolean  Paused;
+extern volatile int LastScan;
+/* extern KeyboardDef KbdDefs;
+extern JoystickDef JoyDefs[];
+extern ControlType Controls[MAXPLAYERS]; */
+
+extern boolean  SpaceBallPresent;
+extern boolean  CybermanPresent;
+extern boolean  AssassinPresent;
+extern char LastASCII;
+extern volatile int LastScan;
+
+extern byte Joy_xb,
+            Joy_yb,
+            Joy_xs,
+            Joy_ys;
+extern word Joy_x,
+            Joy_y;
+
+extern int LastLetter;
+extern char LetterQueue[MAXLETTERS];
+extern ModemMessage MSG;
+
+extern const char ScanChars[128];
+
+//***************************************************************************
+//
+// PROTOTYPES
+//
+//***************************************************************************
+
+void INL_GetMouseDelta(int *x,int *y);
+word IN_GetMouseButtons (void);
+void IN_IgnoreMouseButtons( void );
+boolean INL_StartMouse (void);
+void INL_ShutMouse (void);
+void IN_Startup(void);
+void IN_Default (boolean gotit, ControlType in);
+void IN_Shutdown (void);
+void IN_SetKeyHook(void (*hook)());
+void IN_ClearKeysDown (void);
+void IN_ReadControl (int player, ControlInfo *info);
+void IN_SetControlType (int player, ControlType type);
+ScanCode IN_WaitForKey (void);
+char IN_WaitForASCII (void);
+void IN_StartAck (void);
+boolean IN_CheckAck (void);
+void IN_Ack (void);
+boolean IN_UserInput (long delay);
+void IN_GetJoyAbs (word joy, word *xp, word *yp);
+void INL_GetJoyDelta (word joy, int *dx, int *dy);
+word INL_GetJoyButtons (word joy);
+//word IN_GetJoyButtonsDB (word joy);
+void INL_SetJoyScale (word joy);
+void IN_SetupJoy (word joy, word minx, word maxx, word miny, word maxy);
+boolean INL_StartJoy (word joy);
+void INL_ShutJoy (word joy);
+byte IN_JoyButtons (void);
+void IN_UpdateKeyboard (void);
+void IN_ClearKeyboardQueue (void);
+int IN_InputUpdateKeyboard (void);
+void IN_PumpEvents (void);
+void QueueLetterInput (void);
+
+#endif

Added: tags/rott-1.1/rott/rt_main.c
===================================================================
--- tags/rott-1.1/rott/rt_main.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_main.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,3502 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "lumpy.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <fcntl.h>
+#include <string.h>
+
+#ifdef DOS
+#include <malloc.h>
+#include <dos.h>
+#include <io.h>
+#include <conio.h>
+#include <graph.h>
+#include <process.h>
+#include <direct.h>
+#include <bios.h>
+#else
+#include <signal.h>
+#endif
+
+#if USE_SDL
+/* Need to redefine main to SDL_main on some platforms... */
+#include "SDL.h"
+#endif
+
+#include "rt_actor.h"
+#include "rt_stat.h"
+#include "rt_vid.h"
+#include "rt_menu.h"
+#include "rt_sound.h"
+#include "watcom.h"
+#include "scriplib.h"
+#include "rt_main.h"
+#include "_rt_main.h"
+#include "rt_com.h"
+#include "rt_util.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "rt_game.h"
+#include "rt_floor.h"
+#include "rt_playr.h"
+#include "rt_draw.h"
+#include "rt_str.h"
+#include "rt_view.h"
+#include "rt_door.h"
+#include "rt_ted.h"
+#include "rt_in.h"
+#include "rt_map.h"
+#include "rt_rand.h"
+#include "rt_debug.h"
+#include "isr.h"
+#include "rt_cfg.h"
+#include "develop.h"
+#include "version.h"
+#include "rt_menu.h"
+#include "rt_dr_a.h"
+#include "rt_msg.h"
+#include "rt_build.h"
+#include "rt_error.h"
+#include "modexlib.h"
+#include "rt_net.h"
+#include "cin_main.h"
+#include "rottnet.h"
+#include "rt_scale.h"
+
+#include "music.h"
+#include "fx_man.h"
+//MED
+#include "memcheck.h"
+
+volatile int    oldtime;
+volatile int    gametime;
+
+boolean         tedlevel;
+int             tedlevelnum;
+int             tedx=0;
+int             tedy=0;
+boolean         warp;
+int             warpx=0;
+int             warpy=0;
+int             warpa=0;
+int             NoSound;
+int             polltime;
+int             oldpolltime;
+boolean         fizzlein = false;
+int             pheight;
+
+boolean SCREENSHOTS             = false;
+boolean MONOPRESENT             = false;
+boolean MAPSTATS                = false;
+boolean TILESTATS               = false;
+boolean HUD                     = false;
+boolean IS8250                  = false;
+
+boolean dopefish;
+
+boolean newlevel = false;
+boolean infopause;
+#ifdef DOS
+boolean SOUNDSETUP=false;
+#endif
+boolean quiet = false;
+
+#if (DEVELOPMENT == 1)
+boolean DebugOk = true;
+#else
+boolean DebugOk = false;
+#endif
+
+#if (WHEREAMI==1)
+int programlocation=-1;
+#endif
+
+#if SAVE_SCREEN
+static char savename[13] = "ROTT0000.LBM";
+static int totalbytes;
+static byte *bptr;
+#endif
+static boolean turbo;
+
+static int NoWait;
+static int startlevel=0;
+static int demonumber=-1;
+
+char CWD[40];                          // curent working directory
+static boolean quitactive = false;
+
+int timelimit;
+int maxtimelimit;
+boolean timelimitenabled;
+boolean demoexit;
+boolean noecho;
+
+void CheckCommandLineParameters( void );
+void PlayTurboGame( void );
+void Init_Tables (void);
+void CheckRemoteRidicule ( int scancode );
+void SetRottScreenRes (int Width, int Height);
+
+#ifndef DOS
+extern void crash_print (int);
+extern int setup_homedir (void);
+#endif
+
+//extern int G_argc;
+//extern char G_argv[30][80];
+int G_weaponscale;
+extern int iDropDemo;
+extern boolean iG_aimCross;
+extern boolean sdl_fullscreen;
+
+extern void ComSetTime ( void );
+extern void VH_UpdateScreen (void);
+extern void RottConsole ( void );
+extern void	ReadDelay(long delay);
+extern void RecordDemoQuery ( void );
+
+
+int main (int argc, char *argv[])
+{
+    char *macwd;
+#ifndef DOS
+	_argc = argc;
+	_argv = argv;
+#endif
+
+#if defined(PLATFORM_MACOSX)
+    {
+        /* OS X will give us a path in the form '/Applications/Rise of the Triad.app/Contents/MacOS/Rise of the Triad'.
+           Our data is in Contents/Resources. */
+        char *path;
+        const char suffix[] = "/Resources/";
+        int end;
+        path = (char *)malloc(strlen(argv[0]) + strlen(suffix) + 1);
+        if (path == NULL) return 1;
+        strcpy(path, argv[0]);
+        /* Back up two '/'s. */
+        for (end = strlen(path)-1; end >= 0 && path[end] != '/'; end--);
+        if (end >= 0) for (--end; end >= 0 && path[end] != '/'; end--);
+        strcpy(&path[end], suffix);
+        printf("Changing to working directory: %s\n", path);
+        chdir(path);
+        free(path);
+    }
+#endif
+
+#ifndef DOS
+   signal (11, crash_print);
+
+   if (setup_homedir() == -1) return 1;
+#endif
+
+   // Set which release version we're on
+   gamestate.Version = ROTTVERSION;
+
+#if ( SHAREWARE == 1 )
+   gamestate.Product = ROTT_SHAREWARE;
+#elif ( SUPERROTT == 1 )
+   gamestate.Product = ROTT_SUPERCD;
+#elif ( SITELICENSE == 1 )
+   gamestate.Product = ROTT_SITELICENSE;
+#else
+   gamestate.Product = ROTT_REGISTERED;
+#endif
+
+   DrawRottTitle ();
+   gamestate.randomseed=-1;
+
+   gamestate.autorun = 0;
+   StartupSoftError();
+//   UL_ErrorStartup ();
+
+   CheckCommandLineParameters();
+
+   // Start up Memory manager with a certain amount of reserved memory
+
+   Z_Init(50000,1000000);
+
+   IN_Startup ();
+
+   InitializeGameCommands();
+   if (standalone==false)
+      {
+      ReadConfig ();
+      ReadSETUPFiles ();
+      doublestep=0;
+      SetupWads();
+      BuildTables ();
+      GetMenuInfo ();
+      }
+
+   SetRottScreenRes (iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT);
+   
+//   if (modemgame==true)
+//      {
+//      SCREENSHOTS=true;
+//      if (standalone==false)
+//         {
+//         MenuFixup ();
+//         }
+//      MAPSTATS=true;
+//      }
+   if (standalone==false)
+      {
+      int status1 = 0;
+      int status2 = 0;
+      int status3 = 0;
+
+      if ( !NoSound && !IS8250 )
+         {
+         if (!quiet)
+            printf( "MU_Startup: " );
+         status1 = MU_Startup(false);
+         if (!quiet)
+            printf( "%s\n", MUSIC_ErrorString( MUSIC_Error ) );
+         }
+      else if ( IS8250 )
+         {
+         printf( "==============================================================================\n");
+         printf( "WARNING: 8250 detected.\n" );
+         printf( "Music has been disabled.  This is necessary to maintain high interrupt\n" );
+         printf( "rates with the 8250 UART which will improve overall game performance.\n");
+         printf( "                      < Press any key to continue >\n");
+         printf( "==============================================================================\n");
+         getch();
+         }
+
+      if (!NoSound)
+         {
+         int nv, nb, nc;
+
+         if (!quiet)
+            printf( "SD_SetupFXCard: " );
+         status2 = SD_SetupFXCard (&nv, &nb, &nc);
+         if (!quiet)
+            printf( "%s\n", FX_ErrorString( FX_Error ) );
+
+         if ( !status2 )
+            {
+            if (!quiet)
+               printf( "SD_Startup: " );
+            status3 = SD_Startup(false);
+            if (!quiet)
+               printf( "%s\n", FX_ErrorString( FX_Error ) );
+            }
+         }
+      else
+         {
+         if (!quiet)
+            printf( "Sound FX disabled.\n" );
+         }
+
+#ifdef DOS
+      if ( status1 || status2 || status3 )
+         {
+         printf( "\n\nROTT was unable to initialize your " );
+         if ( status1 )
+            {
+            printf( "music " );
+            MusicMode = 0;
+            }
+         if ( status2 || status3 )
+            {
+            if ( status1 )
+               {
+               printf( "or " );
+               }
+            printf( "sound fx " );
+
+            FXMode = 0;
+            }
+
+         printf( "hardware.\n"
+                 "Now entering sound setup.\n" );
+         SOUNDSETUP = true;
+         }
+#endif
+
+      Init_Tables ();
+      InitializeRNG ();
+      InitializeMessages();
+      LoadColorMap();
+      }
+   if (infopause==true)
+      {
+      printf("\n< Press any key to continue >\n");
+      getch();
+      }
+   I_StartupTimer();
+   I_StartupKeyboard();
+#if 0
+#if (SHAREWARE == 1)
+   if ((!SOUNDSETUP) && (standalone==false))
+      {
+      byte * txtscn;
+      int i;
+
+      for (i=0;i<20;i++)
+         printf("\n");
+      txtscn = (byte *) W_CacheLumpNum (W_GetNumForName ("rotts10"), PU_CACHE);
+      memcpy ((byte *)0xB8000, txtscn, 4000);
+      I_Delay (600);
+      }
+#endif
+#endif
+   locplayerstate = &PLAYERSTATE[consoleplayer];
+
+   if (standalone==true)
+      ServerLoop();
+
+   VL_SetVGAPlaneMode();
+   VL_SetPalette(origpal);
+
+//   SetTextMode();
+//   GraphicsMode();
+//   SetTextMode();
+//   VL_SetVGAPlaneMode();
+//   VL_SetPalette(origpal);
+//   SetBorderColor(155);
+   SetViewSize(8);
+
+#ifdef DOS
+   if ( SOUNDSETUP )
+      {
+      SwitchPalette( origpal, 35 );
+      CP_SoundSetup();
+      }
+#endif
+
+   playstate = ex_titles;
+
+//   I_SetKeyboardLEDs( caps_lock, 0 );
+
+   gamestate.battlemode = battle_StandAloneGame;
+
+   BATTLE_SetOptions( &BATTLE_Options[ battle_StandAloneGame ] );
+
+   if (turbo || tedlevel)
+		{
+      if (modemgame == true)
+         {
+         turbo = false;
+         NoWait = true;
+         }
+      else
+         {
+         PlayTurboGame();
+         }
+      }
+   else
+      {
+#if (SHAREWARE == 0)
+      if ( dopefish == true )
+         {
+         DopefishTitle();
+         }
+      else if ( NoWait == false )
+         {
+         ApogeeTitle();
+         }
+#else
+      if ( NoWait == false )
+         {
+         if (W_CheckNumForName("svendor") != -1)
+            {
+            lbm_t * LBM;
+
+            LBM = (lbm_t *) W_CacheLumpName( "svendor", PU_CACHE, Cvt_lbm_t, 1);
+            VL_DecompressLBM (LBM,true);
+            I_Delay(40);
+            MenuFadeOut();
+            }
+//         ParticleIntro ();
+         ApogeeTitle();
+         }
+#endif
+      }
+
+   GameLoop();
+
+
+   QuitGame();
+   
+   return 0;
+}
+
+void DrawRottTitle ( void )
+{
+   char title[80];
+   char buf[5];
+
+   SetTextMode();
+   TurnOffTextCursor ();
+
+   if (CheckParm("QUIET") == 0)
+      {
+      SetTextMode();
+      TurnOffTextCursor ();
+#ifdef DOS
+      if (CheckParm ("SOUNDSETUP") == 0)
+         {
+#endif
+#ifdef ANSIESC
+         printf("\n\n\n");
+#endif
+         strcpy (title,"Rise of the Triad Startup  Version ");
+         strcat (title,itoa(ROTTMAJORVERSION,&buf[0],10));
+         strcat (title,".");
+//MED
+#if (SHAREWARE==1)||(DOPEFISH==0)
+         strcat (title,itoa(ROTTMINORVERSION,&buf[0],10));
+#else
+         strcat (title,"DFISH");
+#endif
+#ifndef ANSIESC
+         strcat (title,"\n");
+#endif
+
+         px=(80-strlen(title))>>1;
+         py=0;
+
+         UL_printf(title);
+
+         memset (title,0,sizeof(title));
+
+         if (gamestate.Product == ROTT_SHAREWARE)
+            {
+#if (DELUXE==1)
+            strcpy(title,"Lasersoft Deluxe Version");
+#elif (LOWCOST==1)
+            strcpy(title,"Episode One");
+#else
+            strcpy(title,"Shareware Version");
+#endif
+            }
+         else if (gamestate.Product == ROTT_SUPERCD)
+             strcpy(title,"CD Version");
+         else if (gamestate.Product == ROTT_SITELICENSE)
+             strcpy(title,"Site License CD Version");
+         else
+             strcpy(title,"Commercial Version");
+
+         px=(80-strlen(title))>>1;
+         py=1;
+
+         UL_printf(title);
+#ifndef ANSIESC
+	 printf ("\n");
+#endif
+
+         UL_ColorBox (0, 0, 80, 2, 0x1e);
+#ifdef DOS
+         }
+      else
+         {
+         printf("\n\n");
+         strcpy (title,"Rise of the Triad Sound Setup  Version ");
+         strcat (title,itoa(ROTTMAJORVERSION,&buf[0],10));
+         strcat (title,".");
+         strcat (title,itoa(ROTTMINORVERSION,&buf[0],10));
+
+         px=(80-strlen(title))>>1;
+         py=0;
+
+         UL_printf(title);
+
+         UL_ColorBox (0, 0, 80, 1, 0x1e);
+         }
+#endif
+      }
+   else
+      {
+      TurnOffTextCursor ();
+      }
+
+}
+
+void CheckCommandLineParameters( void )
+{
+   char *PStrings[] = {"TEDLEVEL","NOWAIT","NOSOUND","NOW",
+                       "TRANSPORT","DOPEFISH","SCREENSHOTS",
+                       "MONO","MAPSTATS","TILESTATS","VER","net",
+                       "PAUSE","SOUNDSETUP","WARP","IS8250","ENABLEVR",
+                       "TIMELIMIT","MAXTIMELIMIT","NOECHO","DEMOEXIT","QUIET",NULL};
+   int i,n;
+
+   infopause=false;
+#ifdef DOS
+   SOUNDSETUP = false;
+#endif
+   tedlevel=false;
+   NoWait=false;
+   NoSound=false;
+   turbo=false;
+   warp=false;
+   dopefish=false;
+   modemgame=false;
+   SCREENSHOTS=false;
+   MONOPRESENT=false;
+   MAPSTATS=false;
+   TILESTATS=false;
+   IS8250 = false;
+   vrenabled = false;
+   demoexit = false;
+
+   modemgame=false;
+   networkgame=false;
+	consoleplayer=0;
+	numplayers = 1;
+   timelimit=-1;
+   timelimitenabled=false;
+   noecho = false;
+   quiet = false;
+
+   if (
+        (CheckParm("?\0")) ||
+        (CheckParm("HELP")) ||
+        (
+         (_argc>1) &&
+         (_argv[1][0]=='?')
+        )
+      )
+      {
+      SetTextMode ();
+      printf ("Rise of the Triad  (c) 1995 Apogee Software\n\n");
+      printf ("COMMAND LINE PARAMETERS\n");
+      printf ("   AIM        - Give Aim Crosshair.\n");
+      printf ("   FULLSCREEN - Start in fullscreen mode\n");
+      printf ("   WINDOW     - Start in windowed mode\n");
+      printf ("   RESOLUTION - Specify the screen resolution to use\n");
+      printf ("              - next param is <widthxheight>, valid resolutions are:\n");
+      printf ("              - 320x200, 640x480 and 800x600\n");
+#if (SHAREWARE==0)
+      printf ("   FILERTL    - used to load Userlevels (RTL files)\n");
+      printf ("              - next parameter is RTL filename\n");
+      printf ("   FILERTC    - used to load Battlelevels (RTC files)\n");
+      printf ("              - next parameter is RTC filename\n");
+      printf ("   FILE       - used to load Extern WAD files\n");
+      printf ("              - next parameter is WAD filename\n");
+#endif
+      printf ("   SPACEBALL  - Enable check for Spaceball.\n");
+      printf ("   NOJOYS     - Disable check for joystick.\n");
+      printf ("   NOMOUSE    - Disable check for mouse.\n");
+      printf ("   CYBERMAN   - Enable check for Cyberman.\n");
+      printf ("   ASSASSIN   - Enable check for Wingman Assassin.\n");
+      printf ("   VER        - Version number.\n");
+      printf ("   MAPSTATS   - Dump Map statistics to ERROR.\n");
+      printf ("   TILESTATS  - Dump Tile statistics to ERROR.\n");
+      printf ("   MONO       - Enable mono-monitor support.\n");
+      printf ("   SCREENSHOTS- Clean screen capture for shots.\n");
+      printf ("   PAUSE      - Pauses startup screen information.\n");
+#ifdef DOS
+      printf ("   SOUNDSETUP - Setup sound for ROTT\n");
+#endif
+      printf ("   ENABLEVR   - Enable VR helmet input devices\n");
+      printf ("   NOECHO     - Turn off sound reverb\n");
+      printf ("   DEMOEXIT   - Exit program when demo is terminated\n");
+      printf ("   WARP       - Warp to specific ROTT level\n");
+      printf ("                next paramater is level to start on\n");
+      printf ("   TIMELIMIT  - Play ROTT in time limit mode\n");
+      printf ("                next paramater is time in seconds\n");
+      printf ("   MAXTIMELIMIT - Maximimum time to count down from\n");
+      printf ("                next paramater is time in seconds\n");
+      printf ("   DOPEFISH   - ?\n");
+      printf (" \n");
+      printf ("CONTROLS\n");
+      printf ("         Arrows           - Move\n");
+      printf ("         Ctrl             - Fire\n");
+      printf ("         Comma/Alt+left   - Sidestep Left\n");
+      printf ("         Period/Alt+right - Sidestep Right\n");
+      printf ("         Shift            - Run/Turn faster\n");
+      printf ("         Space            - Use/Open\n");
+      printf ("         1-4              - Choose Weapon\n");
+      printf ("         5-6              - Scale Weapon Up/Down\n");
+      printf ("         Enter            - Swap Weapon\n");
+      printf ("         Backspace        - Turn 180\n");
+      printf ("         Delete           - Drop Weapon\n");
+      printf ("         +/-              - Change Viewsize\n");
+      printf ("         PgUp/PgDn        - Look Up/Down\n");
+      printf ("         Home/End         - Aim Up/Down\n");
+      printf ("         [ ]              - Sound Volumen\n");
+      printf ("         ( )              - Music Volumen\n");
+      printf ("         Tab              - Enter Automapper\n");
+      printf (" \n");
+      printf ("AUTO-MAPPER\n");
+      printf ("         Arrows           - Scroll around\n");
+      printf ("         PgUp             - Zoom Out\n");
+      printf ("         PgDn             - Zoom In\n");
+      printf ("         Tab              - Exit Auto-Mapper\n");
+      printf (" \n");
+      printf ("HOTKEYS\n");
+      printf ("         F1               - Help\n");
+      printf ("         F2               - Save Game\n");
+      printf ("         F3               - Restore Game\n");
+      printf ("         F4               - Controls/Sound/Music\n");
+      printf ("         F5               - Change Detail Level\n");
+      printf ("         F6               - Quick Save\n");
+      printf ("         F7               - Messages On/Off\n");
+      printf ("         F8               - End Game\n");
+      printf ("         F9               - Quick Load\n");
+      printf ("         F10              - Quit\n");
+      printf ("         F11              - Gamma Correction\n");
+      printf (" \n");
+      printf ("COMM-BAT\n");
+      printf ("         F1 - F10         - RemoteRidicule(tm) sounds\n");
+      printf ("         F12              - Live RemoteRidicule\n");
+      printf ("         T                - Type message to all\n");
+      printf ("         Z                - Type directed message\n");
+      printf ("         Tab              - Toggle KillCount display\n");
+      printf (" \n");
+      printf ("SCREENSHOOT\n");
+#ifdef DOS /* makes no sense under Linux as there are no lbm viewers there */
+      printf ("         Alt+V            - Screenshoot in LBM format\n");
+#endif
+      printf ("         Alt+C            - Screenshoot in PCX format\n");
+      exit (0);
+      }
+
+   // Check For command line parameters
+
+   for (i = 1;i < _argc;i++)
+   {
+      n = US_CheckParm(_argv[i],PStrings);
+      switch(n)
+      {
+#if (TEDLAUNCH==1)
+       case 0:
+         tedlevelnum = ParseNum(_argv[i + 1]);
+         tedlevel=true;
+         if (i+3>=_argc)
+            {
+            tedx=0;
+            tedy=0;
+            }
+         else
+            {
+            tedx=ParseNum(_argv[i + 2]);
+            tedy=ParseNum(_argv[i + 3]);
+            }
+         MenuFixup ();
+         break;
+#endif
+       case 1:
+         NoWait = true;
+         break;
+		 case 2:
+         NoSound = true;
+         break;
+       case 3:
+         turbo = true;
+         break;
+       case 4:
+         warp = true;
+         warpx=ParseNum(_argv[i + 1]);
+         warpy=ParseNum(_argv[i + 2]);
+         warpa=ParseNum(_argv[i + 3]);
+         break;
+       case 5:
+         dopefish=true;
+         break;
+       case 6:
+         SCREENSHOTS = true;
+         break;
+       case 7:
+         MONOPRESENT = true;
+         break;
+       case 8:
+         MAPSTATS = true;
+         break;
+       case 9:
+         TILESTATS = true;
+         break;
+       case 10:
+         SetTextMode ();
+         printf ("Rise of the Triad  (c) 1995 Apogee Software\n");
+//MED
+         if (gamestate.Product == ROTT_SHAREWARE)
+            {
+#if (DELUXE==1)
+            printf("Lasersoft Deluxe ");
+#elif (LOWCOST==1)
+            printf("Episode One ");
+#else
+            printf("Shareware ");
+#endif
+            }
+         else if (gamestate.Product == ROTT_SUPERCD)
+            printf("CD ");
+         else if (gamestate.Product == ROTT_SITELICENSE)
+            printf("Site License ");
+         else
+            printf("Commercial ");
+         printf ("Version %d.%d\n", ROTTMAJORVERSION,ROTTMINORVERSION);
+         exit (0);
+         break;
+       case 11:
+         InitROTTNET();
+		   numplayers = rottcom->numplayers;
+         if (numplayers>MAXPLAYERS)
+            Error("Too many players.\n");
+         if (!quiet)
+	     printf("Playing %ld player ROTT\n",(long int)numplayers);
+         modemgame=true;
+         if (rottcom->gametype==NETWORK_GAME)
+            {
+            if (!quiet)
+               printf("NETWORK GAME\n");
+            networkgame=true;
+            }
+         else
+            {
+            if (!quiet)
+               printf("MODEM GAME\n");
+            }
+         break;
+       case 12:
+         infopause=true;
+         break;
+       case 13:
+#ifdef DOS
+          SOUNDSETUP = true;
+#endif
+          break;
+       case 14:
+          startlevel = (ParseNum(_argv[i + 1])-1);
+          break;
+       case 15:
+          IS8250 = true;
+          break;
+       case 16:
+          vrenabled = true;
+          if (!quiet)
+             printf("Virtual Reality Mode enabled\n");
+          break;
+       case 17:
+          timelimitenabled = true;
+          timelimit = ParseNum(_argv[i + 1]);
+          if (!quiet)
+             printf("Time Limit = %ld Seconds\n",(long int)timelimit);
+          timelimit *= VBLCOUNTER;
+          break;
+
+       case 18:
+          maxtimelimit = ParseNum(_argv[i + 1]);
+          maxtimelimit *= VBLCOUNTER;
+          break;
+       case 19:
+          noecho = true;
+          break;
+       case 20:
+          demoexit = true;
+          break;
+       case 21:
+          quiet = true;
+          break;
+      }
+   }
+}
+
+void SetupWads( void )
+{
+   char  *newargs[99];
+   int i, arg, argnum = 0;
+   char tempstr[129];
+   char *PStrings[] = {"AIM", "FULLSCREEN", "WINDOW", "RESOLUTION", NULL };
+
+   // These must be checked here so that they can override the cfg file
+   for (i = 1;i < _argc;i++)
+   {
+      arg = US_CheckParm(_argv[i],PStrings);
+      switch(arg)
+      {
+         case 0:
+            iG_aimCross = 1;
+            break;
+         case 1:
+            sdl_fullscreen = 1;
+            break;
+         case 2:
+            sdl_fullscreen = 0;
+            break;
+         case 3:
+            i++;
+            if (i < _argc)
+            {
+               int width, height;
+               if ( (sscanf(_argv[i], "%dx%d", &width, &height) == 2) &&
+                    ( ( (width == 320) && (height == 200) ) ||
+                      ( (width == 640) && (height == 480) ) ||
+                      ( (width == 800) && (height == 600) ) ) )
+               {
+                 iGLOBAL_SCREENWIDTH  = width;
+                 iGLOBAL_SCREENHEIGHT = height;
+               }
+               else
+                  printf("Invalid resolution parameter: %s\n", _argv[i]);
+            }
+            else
+               printf("Missing resolution parameter\n");
+            break;
+      }
+   }
+
+
+#if (SHAREWARE==0)
+   // Check for rtl files 	
+   arg = CheckParm ("filertl");
+   if (arg!=0)
+   {
+	   FILE *f;char buf[32];
+	   if (_argv[arg+1] != 0) { //are there a filename included
+		   strcpy (tempstr,_argv[arg+1]);//copy it to tempstr
+		   if (strlen (tempstr) < MAX_PATH) {
+			   if (access (tempstr, 0) != 0) { //try open
+				  	strcat (tempstr,".rtc");//non exists, try add .rtc
+					if (access (tempstr, 0) != 0) { //try open again
+						//stil no useful filename
+						strcat (tempstr," not found, skipping RTL file ");
+						printf(tempstr);
+						goto NoRTL;
+					}
+			   }
+			   if((f = fopen( tempstr, "r" )) == NULL ){ //try opnong file
+					strcat (tempstr," not could not be opened, skipping RTL file ");
+					printf(tempstr);
+					goto NoRTL;
+			   }else{
+					fread(buf,3,3,f);//is the 3 first letters RTL (RTC)
+				    if (((strstr(buf,"RTL") != 0)||strstr(buf,"RTC") != 0)) {
+						strcpy (GameLevels.file,tempstr);
+						GameLevels.avail++;
+						strcpy (buf,"Adding ");
+						strcat (buf,tempstr);
+						printf(buf);
+					}
+					fclose(f);
+			   }
+		   }
+	   }else{printf("Missing RTL filename");}
+   }
+NoRTL:;
+   // Check for rtc files
+   arg = CheckParm ("filertc");
+   if (arg!=0)
+   {
+	   FILE *f;char buf[32];
+	   if (_argv[arg+1] != 0) { //are there a filename included
+		   strcpy (tempstr,_argv[arg+1]);//copy it to tempstr
+		   if (strlen (tempstr) < MAX_PATH) {
+			   if (access (tempstr, 0) != 0) { //try open
+				  	strcat (tempstr,".rtc");//non exists, try add .rtc
+					if (access (tempstr, 0) != 0) { //try open again
+						//stil no useful filename
+						strcat (tempstr," not found, skipping RTC file ");
+						printf(tempstr);
+						goto NoRTL;
+					}
+			   }
+			   if((f = fopen( tempstr, "r" )) == NULL ){ //try opening file
+					strcat (tempstr," not could not be opened, skipping RTC file ");
+					printf(tempstr);
+					goto NoRTL;
+			   }else{
+					fread(buf,3,3,f);//is the 3 first letters RTL (RTC)
+				    if (((strstr(buf,"RTL") != 0)||strstr(buf,"RTC") != 0)) {
+						strcpy (BattleLevels.file,tempstr);
+						BattleLevels.avail++;
+						strcpy (buf,"Adding ");
+						strcat (buf,tempstr);
+						printf(buf);
+					}
+					fclose(f);
+			   }
+		   }
+	   }else{printf("Missing RTC filename");}
+   }
+NoRTC:;
+
+   // Check for User wads
+   arg = CheckParm ("file");
+   if (arg!=0)
+      {
+      newargs [argnum++] = _argv[arg+1];
+      }
+
+   arg = CheckParm ("file1");
+   if (arg!=0)
+      {
+      newargs [argnum++] = _argv[arg+1];
+      }
+
+   arg = CheckParm ("file2");
+   if (arg!=0)
+      {
+      newargs [argnum++] = _argv[arg+1];
+      }
+
+#else
+   if (
+       (CheckParm ("file") > 0) ||
+       (CheckParm ("file1") > 0) ||
+       (CheckParm ("file2") > 0)
+      )
+      printf("External wads ignored.\n");
+
+#endif
+
+   // Normal ROTT wads
+
+#if (SHAREWARE)
+   newargs [argnum++] = DATADIR "HUNTBGIN.WAD";
+#else
+   newargs [argnum++] = DATADIR "DARKWAR.WAD";
+#endif
+
+//   newargs [argnum++] = "credits.wad";
+
+   // Check for Remote Ridicule WAD
+
+   if (RemoteSounds.avail == true)
+      {
+      char  *src;
+
+      strcpy (tempstr,RemoteSounds.path);
+      src = RemoteSounds.path + strlen(RemoteSounds.path) - 1;
+      if (*src != '\\')
+         strcat (tempstr,"\\\0");
+      strcat (tempstr,RemoteSounds.file);
+      newargs [argnum++] = tempstr;
+      }
+   else
+      {
+      newargs [argnum++] = DATADIR "REMOTE1.RTS";
+      }
+
+   newargs [argnum++] = NULL;
+
+   W_InitMultipleFiles(newargs);
+}
+
+void PlayTurboGame
+   (
+   void
+   )
+
+   {
+   NewGame = true;
+   locplayerstate->player = DefaultPlayerCharacter;
+   playstate = ex_resetgame;
+   GameLoop();
+   }
+
+
+//***************************************************************************
+//
+// Init_Tables () - Init tables needed for double buffering
+//
+//***************************************************************************
+
+void Init_Tables (void)
+{
+	int i;
+	int x,
+		 y;
+	unsigned *blockstart;
+	byte * shape;
+
+   memset (&CWD[0], 0, 40);
+   getcwd (CWD, 40);                      // get the current directory
+
+   origpal=SafeMalloc(768);
+   memcpy (origpal, W_CacheLumpName("pal",PU_CACHE, CvtNull, 1), 768);
+
+   FindEGAColors();
+
+	for (i=0;i<PORTTILESHIGH;i++)
+		uwidthtable[i] = UPDATEWIDE*i;
+
+	updateptr = &update[0];
+
+	blockstart = &blockstarts[0];
+	for (y=0;y<UPDATEHIGH;y++)
+		for (x=0;x<UPDATEWIDE;x++)
+			*blockstart++ = iG_SCREENWIDTH*16*y+x*TILEWIDTH;
+
+	for (i = 0; i < 0x300; i++)
+		*(origpal+(unsigned int)i) = (*(origpal+(unsigned int)i))>>2;
+
+	// Cache in fonts
+	shape = W_CacheLumpNum (W_GetNumForName ("smallfont"), PU_STATIC, Cvt_font_t, 1);
+	smallfont = (font_t *)shape;
+	CurrentFont = smallfont;
+
+	// Cache in tiny font
+	shape = W_CacheLumpNum (W_GetNumForName ("tinyfont"), PU_STATIC, Cvt_font_t, 1);
+	tinyfont = (font_t *)shape;
+
+   intensitytable=W_CacheLumpNum(W_GetNumForName("menucmap"),PU_STATIC, CvtNull, 1);
+   fontcolor = egacolor[4];
+
+   if (!quiet)
+      printf("RT_MAIN: Fonts Initialized\n");
+}
+
+
+
+
+int NumberOfTeams
+   (
+   void
+   )
+
+   {
+   int index;
+   int team[ MAXPLAYERCOLORS ];
+   int count;
+   int color;
+
+   memset( team, 0, sizeof( team ) );
+
+   count = 0;
+   for( index = 0; index < numplayers; index++ )
+      {
+      color = PLAYERSTATE[ index ].uniformcolor;
+      if ( !team[ color ] )
+         {
+         team[ color ] = true;
+         count++;
+         }
+      }
+
+   return( count );
+   }
+
+void GameLoop (void)
+{
+   boolean done   = false;
+   boolean loadit = false;
+   int NextLevel;
+
+   wami(1);
+
+	while (1)
+	   {
+      if ( playstate == ex_battledone )
+         {
+         while( damagecount > 0 )
+            {
+            DoBorderShifts();
+            }
+         damagecount = 0;
+         SetBorderColor (0);
+
+         StopWind();
+
+         ShutdownClientControls();
+
+         SD_Play (SD_LEVELDONESND);
+
+         if ( ( player->flags & FL_DOGMODE ) ||
+            ( gamestate.battlemode == battle_Eluder ) )
+            MU_StartSong(song_dogend);
+         else
+            MU_StartSong(song_endlevel);
+
+
+         VL_FillPalette(255,255,255);
+         VL_FadeIn(0,255,origpal,10);
+
+         BattleLevelCompleted( consoleplayer );
+
+         BATTLE_Shutdown();
+
+         Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND);       // Free current level
+
+         ingame = false;
+
+         if ( networkgame == true )
+            {
+            AddGameEndCommand ();
+            }
+
+         AdjustMenuStruct ();
+
+         CalcTics();
+         CalcTics();
+
+
+         playstate = ex_titles;
+         }
+
+		switch (playstate)
+		   {
+         case ex_titles:
+		 
+            BATTLE_Shutdown();
+            MU_StartSong(song_title);
+			EnableScreenStretch();
+            if ((NoWait==false)&&(!modemgame))
+               {
+               byte dimpal[768];
+               int i;
+
+               for (i = 0; i < 0x300; i++)
+                  dimpal[i] = origpal[i]>>2;
+               CalcTics();
+               CalcTics();
+               IN_ClearKeysDown ();
+               while (IN_GetMouseButtons()) {}
+               while ((!LastScan) && (!IN_GetMouseButtons()))
+                  {
+                  int i;
+                  byte *tempbuf;
+                  MenuFadeOut();
+                  ClearGraphicsScreen();
+                  SetPalette(&dimpal[0]);
+                  PlayMovie ("shartitl", true);
+                  if ( ( LastScan ) || ( IN_GetMouseButtons() ) )
+                     {
+                     break;
+                     }
+
+                  PlayMovie ("shartit2", true);
+
+                  if ( ( LastScan ) || ( IN_GetMouseButtons() ) )
+                     {
+                     break;
+                     }
+                  SD_Play (SD_LIGHTNINGSND);
+                  MenuFadeIn();
+                  I_Delay(30);
+                  SD_Play (SD_ACTORSQUISHSND);
+                  tempbuf=bufferofs;
+                  bufferofs=page1start; // fixed, was displayofs
+                  DrawNormalSprite(320-94,200-41,W_GetNumForName("rsac"));
+						VW_UpdateScreen(); // fixed, was missing
+                  bufferofs=tempbuf;
+                  I_Delay(30);
+
+                  if ( ( LastScan ) || ( IN_GetMouseButtons() ) )
+                     {
+                     break;
+                     }
+
+					DoCreditScreen ();
+                  if ((!LastScan) && (!IN_GetMouseButtons()))
+                     CheckHighScore (0, 0, false);
+#if (SHAREWARE==0)
+                  if ((!LastScan) && (!IN_GetMouseButtons()))
+                     {
+                     DoMicroStoryScreen ();
+                     }
+#endif
+                  if (
+                      (!LastScan) &&
+                      (!IN_GetMouseButtons()) &&
+                      (lowmemory==0) &&
+                      (GameLevels.avail==false)
+                     )
+                     {
+                     if (demonumber==-1)
+                        demonumber=RandomNumber("GameLoop",0);
+                     for (i=0;i<4;i++)
+                        {
+                        demonumber=(demonumber+1)%4;
+                        if (DemoExists (demonumber+1) == true)
+                           break;
+                        }
+                     if (DemoExists (demonumber+1) == true)
+                        {
+                        ingame=true;
+                        LoadDemo (demonumber+1);
+                        break;
+                        }
+                     }
+                  }
+               }
+
+            if (playstate != ex_demoplayback)
+               {
+               if (demoexit == true)
+                  {
+                  QuitGame();
+                  }
+               NoWait = false;
+               SwitchPalette(origpal,35);
+               CP_MainMenu();
+
+               }
+         break;
+
+         case ex_resetgame:
+
+  // SetTextMode (  ); //12345678
+	    EnableScreenStretch();//bna++ shut on streech mode 
+            InitCharacter();
+
+            InitializeMessages();
+
+            fizzlein = true;
+            BATTLE_GetSpecials();
+            BATTLE_SetOptions( &BATTLE_Options[ gamestate.battlemode ] );
+
+            if ( modemgame == true )
+               {
+               fizzlein = false;
+
+               if ( consoleplayer == 0 )
+                  {
+                  // Setup Master
+                  SetupGameMaster();
+                  }
+               else
+                  {
+                  // Setup slave
+                  SetupGamePlayer();
+                  }
+
+               if ( gamestate.Version < ROTTVERSION )
+                  {
+                  Error( "This version of Rise of the Triad (%d.%d) is incompatible with\n"
+                     "version %d.%d.", ROTTMAJORVERSION, ROTTMINORVERSION,
+                     gamestate.Version / 10, gamestate.Version % 10 );
+                  }
+               if ( gamestate.teamplay )
+                  {
+                  int teams;
+
+                  teams = NumberOfTeams();
+                  if ( gamestate.battlemode == battle_CaptureTheTriad )
+                     {
+                     if ( teams != 2 )
+                        {
+                        CP_CaptureTheTriadError();
+                        playstate = ex_titles;
+                        continue;
+                        }
+                     }
+                  else if ( teams < 2 )
+                     {
+                     CP_TeamPlayErrorMessage();
+                     playstate = ex_titles;
+                     continue;
+                     }
+                  }
+               }
+
+            InitCharacter();
+
+            BATTLE_Init( gamestate.battlemode, numplayers );
+
+            NewGame = true;
+
+            if ( ( BATTLEMODE ) && ( BATTLE_ShowKillCount ) )
+               {
+               StatusBar |= STATUS_KILLS;
+               }
+            else
+               {
+               StatusBar &= ~STATUS_KILLS;
+               }
+
+            if (loadedgame == false)
+               {
+               if ( !BATTLEMODE )
+                  {
+                  PlayCinematic();
+                  }
+
+               SetupGameLevel();
+               }
+
+            IN_ClearKeyboardQueue();
+
+				SetupScreen (true);
+
+            MenuFixup ();
+            playstate=ex_stillplaying;
+
+	    DisableScreenStretch();//bna++ shut off streech mode
+
+         break;
+
+         case ex_stillplaying:
+            InitializeMessages();
+
+            SHAKETICS = 0xFFFF;
+            if (modemgame==true)
+               {
+               ComSetTime();
+               turbo = false;
+               }
+            else if (turbo==true)
+               turbo=false;
+            else
+               newlevel=true;
+            PlayLoop ();
+         break;
+
+         case ex_died:
+            loadit = done = false;
+//		   SetTextMode (  ); //12345678
+            Died ();
+            StopWind();
+			 DisableScreenStretch();//bna++ shut off streech mode
+            while (damagecount>0)
+               DoBorderShifts();
+
+            damagecount = 0;
+            SetBorderColor (0);
+            if (demorecord)
+               {
+               FreeDemo ();
+               }
+            if (demoplayback)
+               {
+               FreeDemo ();
+               playstate=ex_demodone;
+               }
+            else
+               {
+               ShutdownClientControls();
+
+               Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND);       // Free current level
+
+               if (CheckForQuickLoad()==false)
+                  {
+                  if (locplayerstate->lives < 0)
+                     {
+                     if (timelimitenabled == false)
+                        {
+                        CheckHighScore (gamestate.score, gamestate.mapon+1, false);
+                        playstate = ex_titles;
+                        AdjustMenuStruct ();
+                        ingame = false;
+                        locplayerstate->health     = MaxHitpointsForCharacter(locplayerstate);
+                        gamestate.score            = 0;
+                        locplayerstate->lives      = 3;
+                        locplayerstate->weapon     = wp_pistol;
+                        locplayerstate->triads     = 0;
+                        UpdateLives (locplayerstate->lives);
+                        UpdateScore (gamestate.score);
+                        }
+                     else
+                        {
+                        QuitGame();
+                        }
+                     }
+                  else
+                     {
+                     fizzlein = true;
+                     SetupGameLevel ();
+                     UpdateTriads(player,0);
+                     playstate = ex_stillplaying;
+                     }
+                  }
+               }
+            break;
+
+         case ex_warped:
+            StopWind();
+            TurnShakeOff();
+            SHAKETICS = 0xffff;
+            gamestate.TimeCount = 0;
+	         gamestate.frame=0;
+
+            Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND);       // Free current level
+
+            fizzlein = true;
+            SetupGameLevel ();
+
+            playstate = ex_stillplaying;
+         break;
+
+         case ex_skiplevel:
+         case ex_secretdone:
+         case ex_secretlevel:
+         case ex_completed:
+         case ex_bossdied:
+
+            ShutdownClientControls();
+            TurnShakeOff();
+            SHAKETICS = 0xffff;
+            if (timelimitenabled == false)
+               {
+               gamestate.TimeCount = 0;
+               gamestate.frame=0;
+               }
+            StopWind();
+#if (SHAREWARE==0)
+            if ((playstate==ex_bossdied) && (gamestate.mapon!=30))
+               {
+               int shape;
+               lbm_t * LBM;
+               byte *s;
+               patch_t *p;
+               char str[50];
+               int width, height;
+
+               LBM = (lbm_t *) W_CacheLumpName( "deadboss", PU_CACHE, Cvt_lbm_t, 1);
+               VL_DecompressLBM (LBM,false);
+               MenuFadeOut();
+               switch (gamestate.mapon)
+                  {
+                  case 6:
+                     shape = W_GetNumForName("deadstev");
+                     break;
+                  case 14:
+                     shape = W_GetNumForName("deadjoe");
+                     break;
+                  case 22:
+                     shape = W_GetNumForName("deadrobo");
+                     break;
+                  case 33:
+                     shape = W_GetNumForName("deadtom");
+                     break;
+//                  default:
+//                     Error("Boss died on an illegal level\n");
+//                     break;
+                  }
+               s = W_CacheLumpNum (shape, PU_CACHE, Cvt_patch_t, 1);
+               p = (patch_t *)s;
+               DrawNormalSprite ((320-p->origsize)>>1, (230-(p->height-p->topoffset))>>1, shape);
+               switch (gamestate.mapon)
+                  {
+                  case 6:
+                     strcpy(&str[0],"\"General\" John Darian");
+                     break;
+                  case 14:
+                     strcpy(&str[0],"Sebastian \"Doyle\" Krist");
+                     break;
+                  case 22:
+                     strcpy(&str[0],"the NME");
+                     break;
+                  case 33:
+                     strcpy(&str[0],"El Oscuro");
+                     break;
+//                  default:
+//                     Error("Boss died on an illegal level\n");
+//                     break;
+                  }
+               CurrentFont=smallfont;
+               US_MeasureStr (&width, &height, str);
+               US_ClippedPrint ((320-width)>>1, 180, str);
+               VW_UpdateScreen();
+               MenuFadeIn();
+
+               WaitKeyUp();
+               LastScan = 0;
+               while (!LastScan) IN_UpdateKeyboard();	// Thanks again DrLex
+               LastScan=0;
+               }
+#endif
+            LevelCompleted ( playstate );
+
+            NextLevel = GetNextMap(player->tilex,player->tiley);
+
+            demoplayback = false;
+
+            Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND);       // Free current level
+            if (NextLevel != -1 )
+               {
+               gamestate.mapon = NextLevel;
+               PlayCinematic();
+               fizzlein = true;
+               SetupGameLevel ();
+               playstate = ex_stillplaying;
+               }
+            else
+               {
+               playstate = ex_gameover;
+               }
+         break;
+
+         case ex_demodone:
+            ingame=false;
+            ShutdownClientControls();
+            TurnShakeOff();
+            SHAKETICS = 0xffff;
+            gamestate.TimeCount = 0;
+	         gamestate.frame=0;
+
+            demoplayback = false;
+
+            Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND);       // Free current level
+            if (predemo_violence != -1)
+            {
+               gamestate.violence = predemo_violence;
+               predemo_violence = -1;
+            }
+            playstate=ex_titles;
+         break;
+
+         case ex_gameover:
+            StopWind();
+            DoEndCinematic();
+            if (playstate==ex_gameover)
+               {
+               CheckHighScore (gamestate.score, gamestate.mapon+1, false);
+
+               ingame = false;
+               AdjustMenuStruct ();
+               playstate = ex_titles;
+               }
+         break;
+
+         case ex_demorecord:
+            ShutdownClientControls();
+            Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND);       // Free current level
+
+            RecordDemo();
+            SetupGameLevel ();
+
+            fizzlein = true;
+            playstate = ex_stillplaying;
+         break;
+
+         case ex_demoplayback:
+            ShutdownClientControls();
+            Z_FreeTags (PU_LEVELSTRUCT, PU_LEVELEND);       // Free current level
+
+            SetupDemo();
+            SetupGameLevel ();
+
+            fizzlein = true;
+            playstate = ex_stillplaying;
+         break;
+	 default:
+	     ;
+         }
+      }
+   waminot();
+   }
+
+boolean CheckForQuickLoad  (void )
+
+   {
+
+   EnableScreenStretch();//bna++
+
+   if ( pickquick )
+      {
+      SetupMenuBuf();
+
+      pickquick = CP_DisplayMsg( "\nQuick load saved game?\n", 12 );
+      if ( pickquick )
+         {
+         AllocateSavedScreenPtr();
+         CP_LoadGame( 1, 1 );
+         FreeSavedScreenPtr();
+         }
+      else
+         {
+         // Erase the quick load message
+         VL_FadeOut( 0, 255, 0, 0, 0, 20 );
+         }
+
+      ShutdownMenuBuf();
+      }
+
+   return( pickquick );
+   }
+
+//===========================================================================
+
+void ShutDown ( void )
+{
+   if ( ( standalone == false )
+#ifdef DOS
+        || ( SOUNDSETUP ) 
+#endif
+   )
+      {
+      WriteConfig ();
+      }
+
+//   if (
+//       (networkgame==false) &&
+//       (modemgame==true)
+//      )
+//      {
+//      ShutdownModemGame ();
+//      }
+
+   ShutdownClientControls();
+   I_ShutdownKeyboard();
+#ifdef DOS /* the UL_ErrorStartup() call is commented out... */
+   UL_ErrorShutdown ();
+#endif
+   ShutdownGameCommands();
+   MU_Shutdown();
+   I_ShutdownTimer();
+   SD_Shutdown();
+   IN_Shutdown ();
+   ShutdownSoftError ();
+   Z_ShutDown();
+//   _settextcursor (0x0607);
+}
+
+//===========================================================================
+
+#if (DEVELOPMENT == 1)
+   extern int totallevelsize;
+#endif
+
+void QuitGame ( void )
+{
+#if (DEBUG == 1)
+   char buf[5];
+#endif
+
+#if (DEVELOPMENT == 1)
+   int temp;
+#else
+   byte *txtscn;
+#endif
+   int k;
+
+   MU_FadeOut(200);
+   while (MU_FadeActive())
+      {
+      int time=GetTicCount();
+      while (GetTicCount()==time) {}
+      }
+
+   PrintMapStats();
+   PrintTileStats();
+   SetTextMode();
+
+#if (DEVELOPMENT == 1)
+   printf("Clean Exit\n");
+   if (gamestate.TimeCount)
+      {
+      temp=(gamestate.frame*VBLCOUNTER*100)/gamestate.TimeCount;
+      printf("fps  = %2ld.%2ld\n",temp/100,temp%100);
+      }
+   printf("argc=%ld\n",_argc);
+   for (k=0;k<_argc;k++) printf("%s\n",_argv[k]);
+   switch( _heapchk() )
+   {
+   case _HEAPOK:
+     printf( "OK - heap is good\n" );
+     break;
+   case _HEAPEMPTY:
+     printf( "OK - heap is empty\n" );
+     break;
+   case _HEAPBADBEGIN:
+     printf( "ERROR - heap is damaged\n" );
+     break;
+   case _HEAPBADNODE:
+     printf( "ERROR - bad node in heap\n" );
+     break;
+   }
+   printf("\nLight Characteristics\n");
+   printf("---------------------\n");
+   if (fog)
+      printf("FOG is ON\n");
+   else
+      printf("FOG is OFF\n");
+   printf("LIGHTLEVEL=%ld\n",GetLightLevelTile());
+   printf("LIGHTRATE =%ld\n",GetLightRateTile());
+   printf("\nCENTERY=%ld\n",centery);
+#else
+#ifdef DOS
+   if ( !SOUNDSETUP )
+      {
+#endif
+#if (SHAREWARE==0)
+      txtscn = (byte *) W_CacheLumpNum (W_GetNumForName ("regend"), PU_CACHE, CvtNull, 1);
+#else
+      txtscn = (byte *) W_CacheLumpNum (W_GetNumForName ("shareend"), PU_CACHE, CvtNull, 1);
+#endif
+#if DOS
+      for (k = 0; k < 23; k++)
+         printf ("\n");
+      memcpy ((byte *)0xB8000, txtscn, 4000);
+#elif defined (ANSIESC)
+      DisplayTextSplash (txtscn, 25);
+#endif
+
+#if (DEBUG == 1)
+      px = ERRORVERSIONCOL;
+      py = ERRORVERSIONROW;
+#if (BETA == 1)
+      UL_printf ("á");
+#else
+      UL_printf (itoa(ROTTMAJORVERSION,&buf[0],10));
+#endif
+      // Skip the dot
+      px++;
+
+      UL_printf (itoa(ROTTMINORVERSION,&buf[0],10));
+#endif
+#ifdef DOS
+      }
+#endif
+#endif
+
+#ifdef DOS
+   if ( SOUNDSETUP )
+      {
+      printf( "\nSound setup complete.\n"
+              "Type ROTT to run the game.\n" );
+      }
+   ShutDown();
+#endif
+
+   exit(0);
+}
+
+void InitCharacter
+   (
+   void
+   )
+
+   {
+   locplayerstate->health = MaxHitpointsForCharacter( locplayerstate );
+   if (timelimitenabled == true)
+      {
+      locplayerstate->lives  = 1;
+      }
+   else
+      {
+      locplayerstate->lives  = 3;
+      }
+
+   ClearTriads (locplayerstate);
+   locplayerstate->playerheight = characters[ locplayerstate->player ].height;
+//   locplayerstate->stepwhich = 0;
+//   locplayerstate->steptime = 0;
+
+   gamestate.score = 0;
+
+   if ( gamestate.battlemode == battle_StandAloneGame )
+      {
+      gamestate.mapon = startlevel;
+      gamestate.difficulty = DefaultDifficulty;
+      }
+   else
+      {
+      gamestate.difficulty = gd_hard;
+      }
+
+   gamestate.dipballs = 0;
+   gamestate.TimeCount = 0;
+
+	godmode = 0;
+   damagecount = 0;
+
+   UpdateScore( gamestate.score );
+   }
+
+
+
+
+void UpdateGameObjects ( void )
+{
+	int j;
+	volatile int atime;
+	objtype * ob,*temp;
+   battle_status BattleStatus;
+
+   wami(2);
+
+   if (controlupdatestarted==0)
+      {
+      return;
+      waminot();
+      }
+
+	atime=GetFastTics();
+
+   UpdateClientControls ();
+
+   if (demoplayback == false)
+       PollControls ();
+
+   CalcTics ();
+
+   UpdateClientControls ();
+
+
+   while (oldpolltime<oldtime)
+	   {
+      UpdateClientControls ();
+	   MoveDoors();
+      ProcessElevators();
+	   MovePWalls();
+      UpdateLightning ();
+	   TriggerStuff();
+		CheckCriticalStatics();
+		for(j=0;j<numclocks;j++)
+		   if (Clocks[j].time1 &&
+			   ((gamestate.TimeCount == Clocks[j].time1) ||
+			   (gamestate.TimeCount == Clocks[j].time2)))
+				TRIGGER[Clocks[j].linkindex]=1;
+		for (ob = firstactive; ob;)
+			{
+			 temp = ob->nextactive;
+			 DoActor (ob);
+#if (DEVELOPMENT == 1)
+			 if ((ob->x<=0) || (ob->y<=0))
+				Error("object xy below zero obj->x=%ld obj->y=%ld obj->obclass=%ld\n",ob->x,ob->y,ob->obclass);
+			 if ((ob->angle<0) || (ob->angle>=FINEANGLES))
+				Error("object angle below zero obj->angle=%ld obj->obclass=%ld\n",ob->angle,ob->obclass);
+#endif
+			 ob = temp;
+			}
+
+      BattleStatus = BATTLE_CheckGameStatus( battle_refresh, 0 );
+      if ( BattleStatus != battle_no_event )
+         {
+         switch( BattleStatus )
+            {
+            case battle_end_game :
+            case battle_out_of_time :
+               playstate = ex_battledone;
+               break;
+
+            case battle_end_round :
+               SetWhoHaveWeapons();
+               break;
+	    default:
+		;
+            }
+         if ( playstate == ex_battledone )
+            {
+            break;
+            }
+         }
+#if (SYNCCHECK == 1)
+      CheckForSyncCheck();
+#endif
+      if (timelimitenabled == true)
+         {
+         if (timelimit-gamestate.TimeCount>maxtimelimit)
+            timelimit = maxtimelimit+gamestate.TimeCount;
+         if (gamestate.TimeCount == timelimit)
+            {
+            locplayerstate->lives=-1;
+            playstate=ex_died;
+            }
+         }
+
+      gamestate.TimeCount ++;
+
+      ResetCurrentCommand();
+
+      oldpolltime++;
+      if (GamePaused==true)
+         break;
+		}
+   actortime=GetFastTics()-atime;
+
+   UpdateClientControls ();
+
+   if (noecho == false)
+      {
+      if ( player->flags & FL_SHROOMS )
+         {
+         FX_SetReverb( 230 );
+         }
+      else if (sky == 0)
+         {
+         FX_SetReverb( min( numareatiles[ player->areanumber ] >> 1, 90 ) );
+         }
+      }
+
+   waminot();
+
+}
+
+
+void PauseLoop ( void )
+{
+   StopWind();
+
+   UpdateClientControls ();
+
+   while (oldpolltime<oldtime)
+	   {
+      CheckUnPause();
+#if (SYNCCHECK == 1)
+      CheckForSyncCheck();
+#endif
+      oldpolltime++;
+      if (GamePaused==false)
+         {
+   			//bna++ section
+		  if (( playstate == ex_stillplaying )&&(iGLOBAL_SCREENWIDTH > 320)){
+				pic_t *shape;
+				shape =  ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );
+				DrawTiledRegion( 0, 16, iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT - 32, 0, 16, shape );
+				DisableScreenStretch();//dont strech when we go BACK TO GAME
+				DrawPlayScreen(true);//repaint ammo and life stat
+				VW_UpdateScreen ();//update screen
+		  }
+		  StartupClientControls();
+		   //bna section end
+         break;
+         }
+		}
+
+   CalcTics ();
+   if (demoplayback==false)
+      PollControls ();
+
+   if ((RefreshPause == true) &&
+       (GamePaused == true) &&
+       ((GetTicCount() - pausedstartedticcount) >= blanktime))
+      {
+      RefreshPause = false;
+      StartupScreenSaver();
+      }
+}
+
+
+
+void PlayLoop
+   (
+   void
+   )
+
+   {
+   volatile int atime;
+
+   boolean canquit = true;
+   int     quittime = 0;
+
+   wami(3);
+
+
+   if ( (loadedgame == false) && (timelimitenabled == false) )
+      {
+      gamestate.TimeCount = 0;
+      gamestate.frame = 0;
+      }
+
+fromloadedgame:
+
+   GamePaused = false;
+
+	if ( loadedgame == false )
+      {
+    	DrawPlayScreen( true );
+		missobj = NULL;
+		}
+	else
+		{
+		loadedgame = false;
+      DoLoadGameSequence();
+		}
+
+   drawtime  = 0;
+   actortime = 0;
+	tics      = 0;
+	SetFastTics(0);
+
+   if ( fizzlein == false )
+      {
+      StartupClientControls();
+      }
+   else
+      {
+      ShutdownClientControls();
+      }
+
+   // set detail level
+   doublestep = 2 - DetailLevel;
+
+   ResetMessageTime();
+   DeletePriorityMessage( MSG_SYSTEM );
+
+   if ( ( gamestate.battlemode == battle_Normal ) &&
+      ( numplayers == 1 ) )
+      {
+      AddMessage( "Comm-bat is for Modem and Network games.", MSG_GAME );
+      AddMessage( "You will not be facing any", MSG_GAME );
+      AddMessage( "opponents.  Have fun and explore.", MSG_GAME );
+      }
+
+
+	while( playstate == ex_stillplaying )
+      {
+      UpdateClientControls();
+
+      if ( GamePaused )
+         {
+         PauseLoop();
+
+         atime = GetFastTics();
+
+         if ( RefreshPause )
+            {
+            ThreeDRefresh();
+            }
+         else
+            {
+            UpdateScreenSaver();
+            }
+         }
+      else
+         {
+         if (controlupdatestarted == 1)
+            UpdateGameObjects();
+
+         atime = GetFastTics();
+
+         ThreeDRefresh();
+         }
+
+      SyncToServer();
+
+		drawtime = GetFastTics() - atime;
+
+      // Don't allow player to quit if entering message
+      canquit = !MSG.messageon;
+
+      PollKeyboard();
+
+      MISCVARS->madenoise = false;
+
+      AnimateWalls();
+
+      UpdateClientControls();
+
+      #if (DEVELOPMENT == 1)
+         Z_CheckHeap();
+      #endif
+
+      if ( AutoDetailOn == true )
+         {
+   		AdaptDetail();
+         }
+
+      UpdateClientControls();
+
+      DoSprites();
+      DoAnimatedMaskedWalls();
+
+      UpdatePlayers();
+
+      DrawTime( false );
+
+      UpdateClientControls();
+
+      if ( ( !BATTLEMODE ) && ( CP_CheckQuick( LastScan ) ) )
+			{
+         boolean escaped=false;
+
+         if (LastScan == sc_Escape)
+            {
+            MU_StoreSongPosition();
+            MU_StartSong(song_menu);
+            escaped = true;
+            }
+         TurnShakeOff();
+         StopWind();
+         SetBorderColor( 0 );
+         ShutdownClientControls();
+         if (demoplayback==true)
+            {
+            FreeDemo();
+            playstate = ex_demodone;
+            if (demoexit==true)
+               {
+               QuitGame();
+               }
+            return;
+            }
+
+         ControlPanel( LastScan );
+
+         // set detail level
+         doublestep = 2 - DetailLevel;
+
+         inmenu = false;
+
+         if ( playstate == ex_titles )
+            {
+            return;
+            }
+
+         if ( playstate == ex_stillplaying )
+            {
+            SetupScreen( false );
+            }
+
+         if ( loadedgame == true )
+            {
+            goto fromloadedgame;
+            }
+
+         if (
+              ( playstate == ex_stillplaying ) &&
+              ( ( fizzlein == false ) ||
+                ( GamePaused )
+              )
+            )
+            {
+            StartupClientControls();
+            }
+
+         if (
+              (playstate == ex_stillplaying) &&
+              (GamePaused == false) &&
+              (escaped == true)
+            )
+            {
+            MU_StartSong(song_level);
+            MU_RestoreSongPosition();
+            }
+         }
+
+      if ( BATTLEMODE )
+         {
+         if ( MSG.messageon == false )
+            {
+            CheckRemoteRidicule( LastScan );
+            }
+         if ( quitactive == false )
+            {
+            if ( ( LastScan == sc_Escape ) && ( canquit ) )
+               {
+               quitactive = true;
+               quittime   = GetTicCount() + QUITTIMEINTERVAL;
+
+               if ( (consoleplayer == 0) || (networkgame == false) )
+                  {
+                  AddMessage( "Do you want to end this game? "
+                     "(\\FY\\O/\\FN\\O)", MSG_QUIT );
+                  }
+               else
+                  {
+                  AddMessage( "Do you want to exit to DOS? "
+                     "(\\FY\\O/\\EN\\O)", MSG_QUIT );
+                  }
+               }
+            }
+         else
+            {
+            if ( GetTicCount() > quittime )
+               {
+               quitactive = false;
+               }
+            else if ( LastScan == sc_N )
+               {
+               DeletePriorityMessage( MSG_QUIT );
+               quitactive = false;
+               }
+            else if ( LastScan == sc_Y )
+               {
+               DeletePriorityMessage( MSG_QUIT );
+               if ( (consoleplayer == 0) || (networkgame==false) )
+                  {
+                  AddEndGameCommand();
+                  }
+               else
+                  {
+                  AddQuitCommand();
+                  }
+               }
+            }
+         }
+      }
+   waminot();
+   }
+
+//******************************************************************************
+//
+// CheckRemoteRidicule ()
+//
+//******************************************************************************
+
+void CheckRemoteRidicule ( int scancode )
+{
+   int num=-1;
+
+   wami(4);
+   switch (scancode)
+   {
+      case sc_F1:
+         num=0;
+         break;
+      case sc_F2:
+         num=1;
+         break;
+      case sc_F3:
+         num=2;
+         break;
+      case sc_F4:
+         num=3;
+         break;
+      case sc_F5:
+         if ( !Keyboard[ sc_RShift ] )
+            {
+            num=4;
+            }
+         break;
+      case sc_F6:
+         num=5;
+         break;
+      case sc_F7:
+         if ( !Keyboard[ sc_RShift ] )
+            {
+            num=6;
+            }
+         break;
+      case sc_F8:
+         num=7;
+         break;
+      case sc_F9:
+         num=8;
+         break;
+      case sc_F10:
+         num=9;
+         break;
+   }
+   if (num>=0)
+      {
+      AddRemoteRidiculeCommand ( consoleplayer, MSG_DIRECTED_TO_ALL, num );
+      LastScan=0;
+      }
+   waminot();
+}
+
+//******************************************************************************
+//
+// DoBossKey ()
+//
+//******************************************************************************
+
+void DoBossKey ( void )
+{
+#ifdef DOS
+   union REGS regs;
+   ShutdownClientControls();
+
+   SetTextMode();
+
+   // move cursor to the row 0 column 4
+   regs.w.ax = 0x0200;
+   regs.w.bx = 0;
+   regs.w.dx = 0x0004;
+   int386(0x10,&regs,&regs);
+   px=0;
+   py=0;
+   UL_printf("C:\\>\n");
+
+   LastScan = 0;
+   IN_WaitForKey ();
+   VL_SetVGAPlaneMode();
+   VL_SetPalette(origpal);
+   SetBorderColor(0);
+   TurnShakeOff();
+   SetupScreen(true);
+   ThreeDRefresh();
+
+   StartupClientControls();
+#else
+	STUB_FUNCTION;
+#endif
+}
+
+
+//******************************************************************************
+//
+// PollKeyboard ()
+//
+//******************************************************************************
+
+void PollKeyboard
+   (
+   void
+   )
+
+   {
+   static char autopressed = false;
+
+   wami(5);
+
+   if (demoplayback==true)
+      {
+      IN_UpdateKeyboard();
+      }
+
+   if ( !BATTLEMODE )
+      {
+      CheckDebug ();
+      if (
+         ( Keyboard[ sc_CapsLock ] ) &&
+         ( DebugOk )
+         )
+         {
+         DebugKeys ();
+         }
+      }
+
+   if ( locplayerstate->buttonstate[ bt_autorun ] )
+      {
+      if ( !autopressed )
+         {
+         autopressed = true;
+         gamestate.autorun ^= 1;
+         if ( gamestate.autorun == 0 )
+            {
+            AddMessage( "AutoRun is \\cOFF", MSG_SYSTEM );
+            }
+         else
+            {
+            AddMessage( "AutoRun is \\cON", MSG_SYSTEM );
+            }
+         }
+      }
+   else
+      {
+      autopressed = false;
+      }
+
+#if 0
+   if ( modemgame == false )
+      {
+      CheckDevelopmentKeys();
+      }
+#endif
+
+   if ( ( MSG.messageon == false ) && ( !quitactive ) )
+      {
+      if ( ( Keyboard[ buttonscan[ bt_message ] ] ) && ( BATTLEMODE ) )
+         {
+         // Send message to all
+         MSG.messageon = true;
+         MSG.directed  = false;
+         MSG.inmenu    = false;
+         MSG.remoteridicule = -1;
+         MSG.towho     = MSG_DIRECTED_TO_ALL;
+         MSG.textnum   = AddMessage( "_", MSG_MODEM );
+         MSG.length    = 1;
+         DeletePriorityMessage( MSG_MACRO );
+         }
+      else if ( ( Keyboard[ buttonscan[ bt_directmsg ] ] ) && ( BATTLEMODE ) )
+         {
+         // Send directed message
+         MSG.messageon = true;
+         MSG.directed  = true;
+         MSG.inmenu    = false;
+         MSG.remoteridicule = -1;
+         MSG.towho     = 0;
+         MSG.textnum   = AddMessage( "_", MSG_MODEM );
+         MSG.length    = 1;
+         DeletePriorityMessage( MSG_MACRO );
+         }
+      if ( buttonpoll[ bt_map ] )
+         {
+         if ( !BATTLEMODE )
+            {
+            // Automap
+            StopWind();
+            DoMap( player->tilex, player->tiley );
+            }
+         else
+            {
+            // Show kill counts
+            if ( SHOW_KILLS() )
+               {
+               BATTLE_ShowKillCount = false;
+               StatusBar &= ~STATUS_KILLS;
+               }
+            else
+               {
+               StatusBar |= STATUS_KILLS;
+               BATTLE_ShowKillCount = true;
+               }
+
+            SetupScreen( true );
+            }
+         }
+
+      // Shrink screen
+      if ( Keyboard[ sc_Minus ] )
+         {
+         Keyboard[ sc_Minus ] = false; // HDG debounce
+         if ( viewsize > 0 )
+            {
+            viewsize--;
+            SetupScreen( true );
+            }
+         }
+
+      // Expand screen
+      if ( Keyboard[ sc_Plus ] )
+         {
+         Keyboard[ sc_Plus ] = false; // HDG debounce
+         if ( viewsize < MAXVIEWSIZES - 1 )
+            {
+            viewsize++;
+            SetupScreen( true );
+            }
+         }
+
+      // Set detail
+      if ( ( Keyboard[ sc_F5 ] ) && ( ( !BATTLEMODE ) ||
+         ( Keyboard[ sc_RShift ] ) ) )
+         {
+         Keyboard[ sc_F5 ] = false;
+         LastScan = 0;
+         DetailLevel++;
+         if ( DetailLevel > 2 )
+            {
+            DetailLevel = 0;
+            }
+
+         switch( DetailLevel )
+            {
+            case 0 :
+               AddMessage( "Low detail", MSG_SYSTEM );
+               break;
+
+            case 1 :
+               AddMessage( "Medium detail", MSG_SYSTEM );
+               break;
+
+            case 2 :
+               AddMessage( "High detail", MSG_SYSTEM );
+               break;
+            }
+         doublestep = 2 - DetailLevel;
+         }
+
+      // Turn messages on/off
+
+      if ( ( Keyboard[ sc_F7 ] ) && ( ( !BATTLEMODE ) ||
+         ( Keyboard[ sc_RShift ] ) ) )
+         {
+         Keyboard[ sc_F7 ] = false;
+         LastScan = 0;
+         MessagesEnabled = !MessagesEnabled;
+         if ( !MessagesEnabled )
+            {
+            AddMessage( "Messages disabled.", MSG_MSGSYSTEM );
+            }
+         else
+            {
+            AddMessage( "Messages enabled.", MSG_MSGSYSTEM );
+            }
+         }
+
+      if ( ( Keyboard[ sc_F6 ] ) && ( !BATTLEMODE ) )
+         {
+         Keyboard[ sc_F6 ] = false;
+         if (Keyboard[sc_RShift])
+            {
+            ShutdownClientControls();
+            UndoQuickSaveGame();
+            StartupClientControls();
+            }
+         else if (quicksaveslot==-1)
+            {
+            ShutdownClientControls();
+            LastScan=sc_F2;
+            inmenu = true;
+            ControlPanel( LastScan );
+            StartupClientControls();
+            }
+         else
+            {
+            LastScan = 0;
+            ShutdownClientControls();
+            ThreeDRefresh();
+            QuickSaveGame();
+            StartupClientControls();
+            }
+         }
+
+//#if 0
+      if ( ( Keyboard[ sc_F12 ] ) && ( !BATTLEMODE ) )
+         {
+         Keyboard[ sc_F12 ] = false;
+         LastScan = 0;
+         DoBossKey();
+         }
+//#endif
+
+      // Gamma correction
+      if ( Keyboard[ sc_F11 ] )
+         {
+         char str[ 50 ] = "Gamma Correction Level ";
+         char str2[ 10 ];
+
+         gammaindex++;
+         if ( gammaindex == NUMGAMMALEVELS )
+            {
+            gammaindex = 0;
+            }
+         VL_SetPalette( origpal );
+         itoa( gammaindex, str2, 10 );
+         strcat( str, str2 );
+         AddMessage( str, MSG_SYSTEM );
+
+         while( Keyboard[ sc_F11 ] )
+            {
+            IN_UpdateKeyboard();
+            }
+         }
+    #if 0
+      if ( Keyboard[ sc_M ] )
+         {
+         char str[ 50 ] = "Mouse Y-Rotation Input Scale ";
+         char str2[ 10 ];
+
+         if ( Keyboard[ sc_RShift ] )
+            mouse_ry_input_scale += 50;
+         else
+            mouse_ry_input_scale -= 50;
+
+         itoa(mouse_ry_input_scale,str2,10);
+         strcat( str, str2 );
+         AddMessage( str, MSG_SYSTEM );
+
+         }
+    #endif
+      // Increase volume
+      if ( Keyboard[ sc_CloseBracket ] )
+         {
+         if ( Keyboard[ sc_RShift ] )
+            {
+            char str[ 50 ] = "Music Volume Level ";
+            char str2[ 10 ];
+
+            if ( MUvolume < 255 )
+               {
+               MUvolume++;
+               }
+            MU_SetVolume( MUvolume );
+
+            itoa( MUvolume, str2, 10 );
+            strcat( str, str2 );
+            AddMessage( str, MSG_SYSTEM );
+            }
+         else
+            {
+            char str[ 50 ] = "Sound FX Volume Level ";
+            char str2[ 10 ];
+
+            if ( FXvolume < 255 )
+               {
+               FXvolume++;
+               }
+            FX_SetVolume( FXvolume );
+
+            itoa( FXvolume, str2, 10 );
+            strcat( str, str2 );
+            AddMessage( str, MSG_SYSTEM );
+            }
+         }
+
+      // Decrease volume
+      if ( Keyboard[ sc_OpenBracket ] )
+         {
+         if ( Keyboard[ sc_RShift ] )
+            {
+            char str[ 50 ] = "Music Volume Level ";
+            char str2[ 10 ];
+
+            if ( MUvolume > 0 )
+               {
+               MUvolume--;
+               }
+            MU_SetVolume( MUvolume );
+
+            itoa( MUvolume, str2, 10 );
+            strcat( str, str2 );
+            AddMessage( str, MSG_SYSTEM );
+            }
+         else
+            {
+            char str[ 50 ] = "Sound FX Volume Level ";
+            char str2[ 10 ];
+
+            if ( FXvolume > 0 )
+               {
+               FXvolume--;
+               }
+            FX_SetVolume( FXvolume );
+
+            itoa( FXvolume, str2, 10 );
+            strcat( str, str2 );
+            AddMessage( str, MSG_SYSTEM );
+            }
+         }
+
+      #if SAVE_SCREEN
+#if (DEVELOPMENT == 1)
+         if ( Keyboard[ sc_CapsLock ] && Keyboard[ sc_C ] )
+            {
+            SaveScreen( true );
+            }
+         else if ( Keyboard[ sc_CapsLock ] && Keyboard[ sc_X ] )
+            {
+            SaveScreen( false );
+            }
+#endif
+         else if ( Keyboard[ sc_Alt] && Keyboard[ sc_C ] )
+            {
+            SaveScreen( false );
+            }
+#ifdef DOS /* makes no sense under Linux as there are no lbm viewers there */
+         else if ( Keyboard[ sc_Alt] && Keyboard[ sc_V ] )
+            {
+            SaveScreen( true );
+            }
+#endif
+      #endif
+      }
+#ifdef USE_SDL
+      /* SDL doesn't send proper release events for these */
+      if (Keystate[sc_CapsLock])
+      {
+         Keystate[sc_CapsLock]++;
+         if (Keystate[sc_CapsLock] == 3)
+            Keystate[sc_CapsLock] = 0;
+      }
+      if (Keystate[0x45]) /* numlock */ 
+      {
+         Keystate[0x45]++;
+         if (Keystate[0x45] == 3)
+            Keystate[0x45] = 0;
+      }
+#endif
+   waminot();
+   }
+
+
+//******************************************************************************
+//
+// CheckDevelopmentKeys ()
+//
+//******************************************************************************
+#if 0
+void CheckDevelopmentKeys
+   (
+   void
+   )
+
+   {
+   #if (DEBUG == 1)
+   if ( Keyboard[ sc_CapsLock ] && Keyboard[ sc_T ] )
+      {
+      if ( warp == true )
+         {
+         player->x     = warpx;
+         player->y     = warpy;
+         player->angle = warpa;
+         locplayerstate->anglefrac = warpa << ANGLEBITS;
+         player->momentumx = 0;
+         player->momentumy = 0;
+         player->momentumz = 0;
+         }
+      return;
+      }
+   #endif
+
+   // Lower wall height
+   if ( Keyboard[ sc_5 ] )
+      {
+      if ( levelheight > 1 )
+         {
+         levelheight--;
+         }
+
+      while( Keyboard[ sc_5 ] )
+         {
+         IN_UpdateKeyboard ();
+         }
+
+      maxheight = ( levelheight << 6 ) - 32;
+      nominalheight = maxheight - 32;
+      }
+
+   // Raise wall height
+   if ( Keyboard[ sc_6 ] )
+      {
+      levelheight++;
+
+      while( Keyboard[ sc_6 ] )
+         {
+         IN_UpdateKeyboard();
+         }
+
+      maxheight = ( levelheight << 6 ) - 32;
+      nominalheight = maxheight - 32;
+      }
+
+   if ( Keyboard[ sc_8 ] )
+      {
+      char str[ 50 ] = "You are now player ";
+      char str2[ 10 ];
+
+      locplayerstate->player++;
+      if ( locplayerstate->player == 5 )
+         {
+         locplayerstate->player = 0;
+         }
+
+      while( Keyboard[ sc_8 ] )
+         {
+         IN_UpdateKeyboard ();
+         }
+
+      itoa( locplayerstate->player, str2, 10 );
+      strcat( str, str2 );
+      AddMessage( str, MSG_SYSTEM );
+      }
+
+#if 0
+   // Cycle forward through wall textures
+      if (Keyboard[sc_W] && (modemgame==false))
+         {int i,j;
+
+          for(i=0;i<128;i++)
+            for(j=0;j<128;j++)
+              {if (IsWall(i,j))
+                 {if (tilemap[i][j] ==
+                      (W_GetNumForName("WALLSTOP")-W_GetNumForName("WALLSTRT")-1))
+                    tilemap[i][j] = 1;
+                  else
+                    tilemap[i][j] ++;
+                 }
+              }
+          while(Keyboard[sc_W])
+            IN_UpdateKeyboard ();
+
+         }
+
+
+
+      if (Keyboard[sc_Q] && (modemgame==false))
+         {int i,j;
+
+          for(i=0;i<128;i++)
+            for(j=0;j<128;j++)
+              {if (IsWall(i,j))
+                 {if (tilemap[i][j] == 1)
+                    tilemap[i][j] = 74;
+                  else
+                    tilemap[i][j] --;
+                 }
+              }
+          while(Keyboard[sc_Q])
+            IN_UpdateKeyboard ();
+
+         }
+
+#endif
+   // Step through cieling/skies
+   if ( Keyboard[ sc_K ] )
+       {
+       if ( sky > 0 )
+          {
+          MAPSPOT( 1, 0, 0 )++;
+          if ( MAPSPOT( 1, 0, 0 ) > 239 )
+             {
+             MAPSPOT( 1, 0, 0 ) = 234;
+             }
+          }
+       else
+          {
+          MAPSPOT( 1, 0, 0 )++;
+          if ( MAPSPOT( 1, 0, 0 ) > 198 + 15 )
+             {
+             MAPSPOT( 1, 0, 0 ) = 198;
+             }
+          }
+
+       SetPlaneViewSize();
+
+       while( Keyboard[ sc_K ] )
+          {
+          IN_UpdateKeyboard();
+          }
+       }
+
+   // Step through floors
+   if ( Keyboard[ sc_L ] )
+      {
+      MAPSPOT( 0, 0, 0 )++;
+      if ( MAPSPOT( 0, 0, 0 ) > 180 + 15 )
+         {
+         MAPSPOT( 0, 0, 0 ) = 180;
+         SetPlaneViewSize();
+
+         while( Keyboard[ sc_L ] )
+            {
+            IN_UpdateKeyboard();
+            }
+         }
+      }
+
+   // Increase darkness level
+   if ( Keyboard[ sc_M ] )
+      {
+      if ( darknesslevel < 7 )
+         {
+         darknesslevel++;
+         }
+
+      SetLightLevels( darknesslevel );
+
+      while( Keyboard[ sc_M ] )
+         {
+         IN_UpdateKeyboard();
+         }
+      }
+
+   // Decrease darkness level
+   if ( Keyboard[ sc_N ] )
+      {
+      if ( darknesslevel > 0 )
+         {
+         darknesslevel--;
+         }
+
+      SetLightLevels( darknesslevel );
+
+      while( Keyboard[ sc_N ] )
+         {
+         IN_UpdateKeyboard();
+         }
+      }
+
+   // Increase light rate
+   if ( Keyboard[ sc_B ] )
+      {
+      SetLightRate( GetLightRate() + 1 );
+      myprintf( "normalshade = %ld\n", normalshade );
+
+      while( Keyboard[ sc_B ] )
+         {
+         IN_UpdateKeyboard();
+         }
+      }
+
+   // Decrease light rate
+   if ( Keyboard[ sc_V ] )
+      {
+      SetLightRate( GetLightRate() - 1 );
+      myprintf( "normalshade = %ld\n", normalshade );
+
+      while( Keyboard[ sc_V ] )
+         {
+         IN_UpdateKeyboard();
+         }
+      }
+
+   // Toggle light diminishing on/off
+   if ( Keyboard[ sc_T ] )
+      {
+      fulllight ^= 1;
+
+      while( Keyboard[ sc_T ] )
+         {
+         IN_UpdateKeyboard();
+         }
+      }
+   }
+#endif
+
+
+#if SAVE_SCREEN
+
+
+short   BigShort (short l)
+{
+   byte    b1,b2;
+
+   b1 = l&255;
+   b2 = (l>>8)&255;
+
+   return (b1<<8) + b2;
+}
+
+long    BigLong (long l)
+{
+   byte    b1,b2,b3,b4;
+
+   b1 = l&255;
+   b2 = (l>>8)&255;
+   b3 = (l>>16)&255;
+   b4 = (l>>24)&255;
+
+   return ((long)b1<<24) + ((long)b2<<16) + ((long)b3<<8) + b4;
+}
+
+/*
+==============
+=
+= WriteLBMfile
+=
+==============
+*/
+
+void WriteLBMfile (char *filename, byte *data, int width, int height)
+{
+   byte    *lbm, *lbmptr;
+   long    *formlength, *bmhdlength, *cmaplength, *bodylength;
+   long    length;
+   bmhd_t  basebmhd;
+   int     handle;
+   int     i;
+
+   lbm = lbmptr = (byte *) SafeMalloc ((iGLOBAL_SCREENWIDTH*iGLOBAL_SCREENHEIGHT)+4000);
+
+//
+// start FORM
+//
+   *lbmptr++ = 'F';
+   *lbmptr++ = 'O';
+   *lbmptr++ = 'R';
+   *lbmptr++ = 'M';
+
+   formlength = (long*)lbmptr;
+   lbmptr+=4;                      // leave space for length
+
+   *lbmptr++ = 'P';
+   *lbmptr++ = 'B';
+   *lbmptr++ = 'M';
+   *lbmptr++ = ' ';
+
+//
+// write BMHD
+//
+   *lbmptr++ = 'B';
+   *lbmptr++ = 'M';
+   *lbmptr++ = 'H';
+   *lbmptr++ = 'D';
+
+   bmhdlength = (long *)lbmptr;
+   lbmptr+=4;                      // leave space for length
+
+   memset (&basebmhd,0,sizeof(basebmhd));
+   basebmhd.w = BigShort(width);
+   basebmhd.h = BigShort(height);
+   basebmhd.nPlanes = BigShort(8);
+   basebmhd.xAspect = BigShort(5);
+   basebmhd.yAspect = BigShort(6);
+   basebmhd.pageWidth = BigShort(width);
+   basebmhd.pageHeight = BigShort(height);
+
+   memcpy (lbmptr,&basebmhd,sizeof(basebmhd));
+   lbmptr += sizeof(basebmhd);
+
+   length = lbmptr-(byte *)bmhdlength-4;
+   *bmhdlength = BigLong(length);
+   if (length&1)
+      *lbmptr++ = 0;          // pad chunk to even offset
+
+//
+// write CMAP
+//
+   *lbmptr++ = 'C';
+   *lbmptr++ = 'M';
+   *lbmptr++ = 'A';
+   *lbmptr++ = 'P';
+
+   cmaplength = (long *)lbmptr;
+   lbmptr+=4;                      // leave space for length
+
+   for (i = 0; i < 0x300; i++)
+      *lbmptr++ = (*(origpal+i))<<2;
+
+// memcpy (lbmptr,&origpal[0],768);
+// lbmptr += 768;
+
+   length = lbmptr-(byte *)cmaplength-4;
+   *cmaplength = BigLong(length);
+   if (length&1)
+      *lbmptr++ = 0;          // pad chunk to even offset
+
+//
+// write BODY
+//
+   *lbmptr++ = 'B';
+   *lbmptr++ = 'O';
+   *lbmptr++ = 'D';
+   *lbmptr++ = 'Y';
+
+   bodylength = (long *)lbmptr;
+   lbmptr+=4;                      // leave space for length
+
+   memcpy (lbmptr,data,width*height);
+   lbmptr += width*height;
+
+   length = lbmptr-(byte *)bodylength-4;
+   *bodylength = BigLong(length);
+   if (length&1)
+      *lbmptr++ = 0;          // pad chunk to even offset
+
+//
+// done
+//
+   length = lbmptr-(byte *)formlength-4;
+   *formlength = BigLong(length);
+   if (length&1)
+      *lbmptr++ = 0;          // pad chunk to even offset
+
+//
+// write output file
+//
+   handle = SafeOpenWrite (filename);
+
+   SafeWrite (handle, lbm, lbmptr-lbm);
+
+   close (handle);
+   SafeFree(lbm);
+}
+
+
+//****************************************************************************
+//
+// GetFileName ()
+//
+//****************************************************************************
+
+void GetFileName (boolean saveLBM)
+{
+#ifdef DOS
+   char num[4];
+   int cnt = 0;
+   struct find_t fblock;
+
+   if (saveLBM)
+      memcpy (savename, "ROTT0000.LBM\0", 13);
+   else
+      memcpy (savename, "ROTT0000.PCX\0", 13);
+
+   if (_dos_findfirst (savename, 0, &fblock) != 0)
+      return;
+
+   do
+   {
+      cnt++;
+      memset (&num[0], 0, 4);
+      itoa (cnt, num, 10);
+
+      if (cnt > 99)
+      {
+         savename[5] = num[0];
+         savename[6] = num[1];
+         savename[7] = num[2];
+      }
+      else
+      if (cnt > 9)
+      {
+         savename[6] = num[0];
+         savename[7] = num[1];
+      }
+      else
+         savename[7] = num[0];
+   }
+   while (_dos_findfirst (savename, 0, &fblock) == 0);
+#else
+	int i;
+	
+	for (i = 0; i < 9999; i++) {
+		char filename[128];
+		
+		if (saveLBM) {
+	   		sprintf(savename, "rott%04d.lbm", i);
+	   	} else {
+	   		sprintf(savename, "rott%04d.pcx", i);
+	   	}
+
+		GetPathFromEnvironment( filename, ApogeePath, savename );
+		
+		if (access(filename, F_OK) != 0) {
+			return;
+		}
+	}
+#endif
+}
+
+//****************************************************************************
+//
+// SaveScreen ()
+//
+//****************************************************************************
+
+boolean inhmenu;
+
+#if (BETA == 1)
+#define SSX (160-(46*2))
+#define SSY (17)
+#endif
+void SaveScreen (boolean saveLBM)
+{
+   byte *buffer;
+   byte * screen;
+   boolean oldHUD;
+   char filename[ 128 ];
+
+#if (BETA == 1)
+   unsigned tmp;
+   char buf[30];
+   int i;
+#endif
+
+
+   oldHUD=HUD;
+   HUD=false;
+   doublestep=0;
+   if (inhmenu==false)
+      screen = (byte *) bufferofs;
+   else
+      screen = (byte *) displayofs;
+
+   if (inhmenu==false)
+      ThreeDRefresh ();
+   doublestep = 2 - DetailLevel;
+
+   //buffer = (byte *) SafeMalloc (65000);
+   buffer = (byte *) SafeMalloc ((iGLOBAL_SCREENHEIGHT*iGLOBAL_SCREENWIDTH)+4000);
+
+#if (BETA == 1)
+   if (SCREENSHOTS == false)
+   {
+      if (screen!=(byte *)bufferofs)
+         {
+         tmp=bufferofs;
+         bufferofs=displayofs;
+         }
+      CurrentFont=tinyfont;
+
+      VGAMAPMASK(15);
+      for (i=-1;i<6;i++)
+         memset((byte *)bufferofs+(ylookup[i+SSY])+(SSX>>2),0,46);
+      px=SSX;
+      py=SSY;
+      VW_DrawPropString(" Rise of the Triad (c) 1995 Apogee  Version ");
+      VW_DrawPropString(itoa(ROTTMAJORVERSION,&buf[0],10));
+      VW_DrawPropString(".");
+      VW_DrawPropString(itoa(ROTTMINORVERSION,&buf[0],10));
+      px=SSX+13;
+      py=SSY+8;
+      VW_DrawPropString(" Episode ");
+      VW_DrawPropString(itoa(gamestate.episode,&buf[0],10));
+      VW_DrawPropString(" Area ");
+      VW_DrawPropString(itoa(GetLevel(gamestate.episode, gamestate.mapon),&buf[0],10));
+
+      if (screen!=(byte *)bufferofs)
+         bufferofs=tmp;
+   }
+#endif
+
+
+
+   GetFileName (saveLBM);
+   GetPathFromEnvironment( filename, ApogeePath, savename );
+   //   
+	memcpy(buffer,screen , iGLOBAL_SCREENWIDTH*iGLOBAL_SCREENHEIGHT);//bna	
+   //bna--VL_CopyPlanarPageToMemory(screen,buffer);
+
+   if (saveLBM)
+   {
+      WriteLBMfile (filename, buffer, iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT);
+#if (DEVELOPMENT == 1)
+      while (Keyboard[sc_CapsLock] && Keyboard[sc_C])
+#else
+      while (Keyboard[sc_Alt] && Keyboard[sc_V])
+#endif
+           IN_UpdateKeyboard ();
+   }
+   else
+   {
+      WritePCX (filename, buffer);
+#if (DEVELOPMENT == 1)
+      while (Keyboard[sc_CapsLock] && Keyboard[sc_X])
+#else
+      while (Keyboard[sc_Alt] && Keyboard[sc_C])
+#endif
+           IN_UpdateKeyboard ();
+   }
+
+   SafeFree(buffer);
+   HUD=oldHUD;
+}
+
+//****************************************************************************
+//
+// WritePCX ()
+//
+//****************************************************************************
+
+void WritePCX (char * file, byte * source)
+{
+   PCX_HEADER pcxHDR;
+   byte *tempbuffer;
+   byte pal[0x300];
+   int pcxhandle;
+   int i, j, y;
+   unsigned char c;
+   unsigned char buffer1[GAP_SIZE];
+
+   pcxhandle = SafeOpenWrite (file);
+
+      /* --- init the header that we'll write.
+       *    Note: since DPaint never reads & writes at the same time,
+       *    it is okay to share the same read & write structure,
+       *    unlike in CONVERT.EXE.
+       */
+
+   memset (&pcxHDR, 0, sizeof(PCX_HEADER));
+
+   pcxHDR.manufacturer  = 10;
+   pcxHDR.version       = 5;
+   pcxHDR.encoding      = 1;
+
+   pcxHDR.bitsperpixel  = 8;           //bpp;
+   pcxHDR.xmin          = pcxHDR.ymin = 0;
+   pcxHDR.xmax          = iGLOBAL_SCREENWIDTH - 1;
+   pcxHDR.ymax          = iGLOBAL_SCREENHEIGHT - 1;
+   pcxHDR.hres          = iGLOBAL_SCREENWIDTH;         //N_COLUMNS;
+   pcxHDR.vres          = iGLOBAL_SCREENHEIGHT;         //N_LINES;
+
+  // bytesperline doesn't take into account multiple planes.
+  // Output in same format as bitmap (planar vs packed).
+  //
+   pcxHDR.bytesperline  = iGLOBAL_SCREENWIDTH;         //bitmap->width;
+
+   pcxHDR.nplanes       = 1;           //bitmap->planes;
+   pcxHDR.reserved      = 0;
+
+  // First 16 colors of our palette info.
+   for (i = 0, j = 0; i < 16; ++i, j += 3) {
+      pcxHDR.colormap[i][0] = (unsigned char)(origpal[j]);
+      pcxHDR.colormap[i][1] = (unsigned char)(origpal[j]+2);
+      pcxHDR.colormap[i][2] = (unsigned char)(origpal[j]+3);
+   }
+
+  //
+  // Write the 128-byte header
+  //
+   SafeWrite(pcxhandle,&pcxHDR, sizeof (PCX_HEADER));
+
+   memset (buffer1, 0, GAP_SIZE);
+
+   SafeWrite (pcxhandle, &buffer1, GAP_SIZE);
+
+   tempbuffer = (byte *) SafeMalloc ((iGLOBAL_SCREENHEIGHT*iGLOBAL_SCREENWIDTH)+4000);
+   bptr = tempbuffer;
+   totalbytes = 0;
+
+  //
+  // Write to a bit-packed file.
+  //
+	for (y = 0;  y < iGLOBAL_SCREENHEIGHT;  ++y) 		// for each line in band
+		if (PutBytes (((unsigned char *) (source+(y*iGLOBAL_SCREENWIDTH))),
+						  pcxHDR.bytesperline))
+         Error ("Error writing PCX bit-packed line!\n");
+
+   SafeWrite (pcxhandle, tempbuffer, totalbytes);
+
+  //
+  // Write out PCX palette
+  //
+   c = 0x0C;
+
+   for (i = 0; i < 0x300; i++)
+      pal[i] = (*(origpal+i))<<2;
+
+   SafeWrite (pcxhandle, &c, 1);
+   SafeWrite (pcxhandle, &pal[0], 768);
+
+   close (pcxhandle);
+   SafeFree (tempbuffer);
+}
+
+
+//****************************************************************************
+//
+// PutBytes ()
+//
+// Write bytes to a file, handling packing as it goes.
+// Returns :  0 == SUCCESS
+//            1 == FAIL.
+//
+//****************************************************************************
+
+int PutBytes (unsigned char *ptr, unsigned int bytes)
+{
+	unsigned int startbyte, count;
+	char b;
+
+	while (bytes > 0) {
+	  // check for a repeating byte value
+		startbyte = *ptr;
+		*ptr++ = 0;
+		--bytes;
+		count = 1;
+		while (*ptr == startbyte && bytes > 0 && count < 63)
+		{
+			*ptr = 0;
+			++ptr;
+			--bytes;
+			++count;
+		}
+	  // If we can pack the sequence, or if we have to add a
+	  //	byte before it because the top 2 bits of the value
+	  //	are 1's, write a packed sequence of 2 bytes.
+	  //	Otherwise, just write the byte value.
+	  //
+		if (count > 1  ||  (startbyte & 0xc0) == 0xc0)
+		{
+			b = 0xc0 | count;
+
+			*bptr++ = b;
+			totalbytes++;
+		}
+		b = startbyte;
+
+		*bptr++ = b;
+		totalbytes++;
+	}
+	return (0);
+}
+
+
+#endif
+
+
+//****************************************************************************
+//
+// PlayCinematic () - Play intro cinematics
+//
+//****************************************************************************
+
+void PlayCinematic (void)
+{
+
+   if ((tedlevel == true) || (turbo == true))
+      return;
+
+   switch (gamestate.mapon)
+   {
+#if (SHAREWARE == 0)
+      byte pal[768];
+      case 0:        // Start of EPISODE 1
+
+         MU_StartSong ( song_cinematic1 );
+         VL_FadeOut (0, 255, 0, 0, 0, 20);
+         VL_ClearBuffer (bufferofs, 0);
+         DrawNormalSprite(0,30,W_GetNumForName("nicolas"));
+         DrawNormalSprite(0,168,W_GetNumForName("oneyear"));
+         FlipPage();
+         memcpy(&pal[0],W_CacheLumpName("nicpal",PU_CACHE, CvtNull, 1),768);
+         VL_NormalizePalette(&pal[0]);
+         VL_FadeIn(0,255,pal,20);
+         I_Delay (60);
+         VL_FadeOut (0, 255, 0, 0, 0, 20);
+         IN_UpdateKeyboard();
+         if (LastScan!=0)
+            {
+            LastScan=0;
+            return;
+            }
+         SD_PlayPitchedSound(SD_LIGHTNINGSND,255,-1500);
+         DoInBetweenCinematic (20, W_GetNumForName("binoculr"), 80,
+                               "The HUNT cases an\n"
+                               "ancient monastery."
+                              );
+         IN_UpdateKeyboard();
+         if (LastScan!=0)
+            {
+            LastScan=0;
+            return;
+            }
+         SD_Play(SD_NMESEESND);
+         DoInBetweenCinematic (20, W_GetNumForName("binosee"), 80,
+                               "\"There they are,\" says\n"
+                               "Cassatt. \"Let's get back\n"
+                               "to the boat and inform HQ.\""
+                              );
+         IN_UpdateKeyboard();
+         if (LastScan!=0)
+            {
+            LastScan=0;
+            return;
+            }
+         SD_Play(SD_HIGHGUARD1SEESND);
+         DoInBetweenCinematic (20, W_GetNumForName("boatgard"), 80,
+                               "\"The intruders, on that hill!\""
+                              );
+         IN_UpdateKeyboard();
+         if (LastScan!=0)
+            {
+            LastScan=0;
+            return;
+            }
+         SD_Play(SD_EXPLODESND);
+         DoInBetweenCinematic (20, W_GetNumForName("boatblow"), 80,
+                               "\"There goes our ride home,\"\n"
+                               "says Barrett.  \"Looks like\n"
+                               "the only way out is in....\""
+                              );
+         IN_UpdateKeyboard();
+         LastScan=0;
+      break;
+
+      case 8:        // Start of EPISODE 2
+         MU_StartSong ( song_cinematic2 );
+         DoInBetweenCinematic (0, W_GetNumForName("epi12"), 1200,
+                               "The HUNT makes their way\n"
+                               "into the main keep."
+                              );
+         IN_UpdateKeyboard();
+         LastScan=0;
+      break;
+
+      case 16:       // Start of EPISODE 3
+         MU_StartSong ( song_cinematic1 );
+         DoInBetweenCinematic (20, W_GetNumForName("epi23"), 1200,
+                               "The HUNT stands before a pair\n"
+                               "of ominous wooden doors.\n"
+                               "The sounds of machinery and\n"
+                               "servomotors fill the air.\n"
+                              );
+         IN_UpdateKeyboard();
+         LastScan=0;
+      break;
+
+      case 24:       // Start of EPISODE 4
+         MU_StartSong ( song_cinematic2 );
+         DoInBetweenCinematic (0, W_GetNumForName("epi34"), 1200,
+                               "Stairs lead down beneath the\n"
+                               "keep.  From behind the doors\n"
+                               "come the moans of the undead."
+                              );
+         IN_UpdateKeyboard();
+         LastScan=0;
+      break;
+#endif
+   }
+}

Added: tags/rott-1.1/rott/rt_main.h
===================================================================
--- tags/rott-1.1/rott/rt_main.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_main.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,167 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//                  RT_MAIN.H
+//
+//***************************************************************************
+
+#ifndef _rt_main_public
+#define _rt_main_public
+
+#include "develop.h"
+#include "rt_def.h"
+#include "rottnet.h"
+#include "rt_battl.h"
+
+enum
+{vl_low,
+ vl_medium,
+ vl_high,
+ vl_excessive
+};
+
+// Enum for each version of the game
+typedef enum
+   {
+   ROTT_SHAREWARE,
+   ROTT_REGISTERED,
+   ROTT_SUPERCD,
+   ROTT_SITELICENSE
+   } version_type;
+
+typedef struct
+   {
+   int GodModeTime;
+   int DogModeTime;
+   int ShroomsModeTime;
+   int ElastoModeTime;
+   int AsbestosVestTime;
+   int BulletProofVestTime;
+   int GasMaskTime;
+   int MercuryModeTime;
+
+   int GodModeRespawnTime;
+   int DogModeRespawnTime;
+   int ShroomsModeRespawnTime;
+   int ElastoModeRespawnTime;
+   int AsbestosVestRespawnTime;
+   int BulletProofVestRespawnTime;
+   int GasMaskRespawnTime;
+   int MercuryModeRespawnTime;
+
+   }specials;
+
+
+typedef struct
+   {
+   unsigned Version;
+   // Variable for which version of the game can be played
+   version_type Product;
+
+   int     TimeCount;
+   int     frame;
+   int     secrettotal,treasuretotal,killtotal;
+   int     secretcount,treasurecount,killcount;
+   int     supertotal,healthtotal,missiletotal;
+   int     supercount,healthcount,missilecount;
+   int     democratictotal,planttotal;
+   int     democraticcount,plantcount;
+   int     dipballs;
+   int     difficulty;
+   int     violence;
+	int     mapon;
+	int     score;
+	int     episode;
+	int     battlemode;
+	int     battleoption;
+	int     randomseed;
+   boolean teamplay;
+	boolean DODEMOCRATICBONUS1;
+	boolean DOGROUNDZEROBONUS;
+	int     autorun;
+
+	// Battle Options
+   battle_type BattleOptions;
+
+   boolean SpawnCollectItems;
+	boolean SpawnEluder;
+	boolean SpawnDeluder;
+   boolean ShowScores;
+	boolean PlayerHasGun[ MAXPLAYERS ];
+   specials SpecialsTimes;
+   } gametype;
+
+
+extern  int      doublestep;
+extern  boolean  tedlevel;
+extern  int      tedlevelnum;
+extern  int      tedx;
+extern  int      tedy;
+extern  boolean  fizzlein;
+extern  int      pheight;
+extern  int      NoSound;
+extern  int      timelimit;
+extern  boolean  timelimitenabled;
+extern  boolean  noecho;
+extern  boolean  demoexit;
+extern  boolean  quiet;
+
+extern gametype  gamestate;
+extern boolean DebugOk;
+extern  boolean newlevel;
+
+void QuitGame( void );
+void PlayCinematic (void);
+void InitCharacter(void);
+void ShutDown ( void );
+void UpdateGameObjects ( void );
+
+#if (WHEREAMI==1)
+extern int programlocation;
+#endif
+
+extern  int polltime;
+extern  int oldpolltime;
+extern  volatile int oldtime;
+void PauseLoop ( void );
+#if SAVE_SCREEN
+extern boolean inhmenu;
+void SaveScreen (boolean saveLBM);
+#endif
+void SetupWads( void );
+
+extern boolean SCREENSHOTS;
+extern boolean MEMORYTEST;
+extern boolean MODEMTEST;
+extern boolean STATICMEMORYTEST;
+extern boolean STATICMEMORYPREVIEWTEST;
+extern boolean COMPUTELEVELSIZE;
+extern boolean MONOPRESENT;
+extern boolean MAPSTATS;
+extern boolean TILESTATS;
+extern boolean HUD;
+#ifdef DOS
+extern boolean SOUNDSETUP;
+#endif
+
+extern char CWD[40];
+
+#endif

Added: tags/rott-1.1/rott/rt_map.c
===================================================================
--- tags/rott-1.1/rott/rt_map.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_map.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1074 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include <string.h>
+
+#ifdef DOS
+#include <conio.h>
+#include <dos.h>
+#endif
+
+#include "sprites.h"
+#include "rt_map.h"
+#include "rt_dr_a.h"
+#include "_rt_map.h"
+#include "isr.h"
+#include "rt_util.h"
+#include "modexlib.h"
+#include "rt_draw.h"
+#include "rt_stat.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "rt_main.h"
+#include "rt_playr.h"
+#include "lumpy.h"
+#include "rt_door.h"
+#include "rt_scale.h"
+#include "rt_vid.h"
+#include "rt_in.h"
+#include "rt_ted.h"
+#include "rt_game.h"
+#include "rt_rand.h"
+#include "rt_view.h"
+#include "rt_floor.h"
+#include "engine.h"
+#include "develop.h"
+#include "rt_spbal.h"
+#include "rt_menu.h"
+#include "rt_net.h"
+#include "rt_str.h"
+#include "watcom.h"
+//MED
+#include "memcheck.h"
+
+//===========================================================================
+
+
+static int tilesize;
+static fixed xscale;
+static fixed yscale;
+static int mapscale=2;
+static int oldw,oldh;
+static byte * skytile;
+static int mapcolor=8;
+
+typedef struct PType {
+  int   x;
+  int   y;
+} Ptype;
+
+static Ptype arrows[8][7]=
+       {
+         { {4,2}, {2,4}, {2,3}, {0,3}, {0,1}, {2,1}, {2,0} },
+         { {4,0}, {4,3}, {3,2}, {1,4}, {0,3}, {2,1}, {1,0} },
+         { {2,0}, {4,2}, {3,2}, {3,4}, {1,4}, {1,2}, {0,2} },
+         { {0,0}, {3,0}, {2,1}, {4,3}, {3,4}, {1,2}, {0,3} },
+         { {0,2}, {2,0}, {2,1}, {4,1}, {4,3}, {2,3}, {2,4} },
+         { {0,4}, {0,1}, {1,2}, {3,0}, {4,1}, {2,3}, {3,4} },
+         { {2,4}, {0,2}, {1,2}, {1,0}, {3,0}, {3,2}, {4,2} },
+         { {4,4}, {1,4}, {2,3}, {0,1}, {1,0}, {3,2}, {4,1} },
+     };
+
+void DrawMap_MaskedShape (int x, int y, int lump, int type);
+
+void CheatMap( void )
+{
+   int i;
+   int j;
+   statobj_t * temp;
+   objtype * a;
+
+   for(temp=FIRSTSTAT;temp;temp=temp->statnext)
+      temp->flags|=FL_SEEN;
+
+	for(a=FIRSTACTOR;a;a=a->next)
+      a->flags|=FL_SEEN;
+
+
+   for (j=0;j<MAPSIZE;j++)
+      for (i=0;i<MAPSIZE;i++)
+         mapseen[i][j]=1;
+}
+
+
+void FixMapSeen( void )
+{
+   int i;
+   int j;
+
+   for (j=0;j<MAPSIZE;j++)
+      for (i=0;i<MAPSIZE;i++)
+         if (!mapseen[i][j])
+            {
+            if (i==0 && ((mapseen[i][j+1] && j<MAPSIZE-1) || (mapseen[i][j-1] && j>0)) && mapseen[i+1][j])
+               mapseen[i][j]=1;
+            else if (i==MAPSIZE-1 && mapseen[i-1][j] && ((mapseen[i][j+1] && j<MAPSIZE-1) || (mapseen[i][j-1] && j>0)))
+               mapseen[i][j]=1;
+            else if (j==0 && ((mapseen[i+1][j] && i<MAPSIZE-1) || (mapseen[i-1][j] && i>0)) && mapseen[i][j+1])
+               mapseen[i][j]=1;
+            else if (j==MAPSIZE-1 && mapseen[i][j-1] && ((mapseen[i+1][j] && i<MAPSIZE-1) || (mapseen[i-1][j] && i>0)))
+               mapseen[i][j]=1;
+            else if (
+               (  ((mapseen[i-1][j]) && (mapseen[i][j+1]) && (!(tilemap[i-1][j+1])))
+                   ||
+                  ((mapseen[i-1][j]) && (mapseen[i][j-1]) && (!(tilemap[i-1][j-1])))
+                   ||
+                  ((mapseen[i+1][j]) && (mapseen[i][j+1]) && (!(tilemap[i+1][j+1])))
+                   ||
+                  ((mapseen[i+1][j]) && (mapseen[i][j-1]) && (!(tilemap[i+1][j-1])))
+               ) &&
+               tilemap[i][j])
+                  mapseen[i][j]=1;
+            }
+}
+
+
+/*
+=======================
+=
+= DrawMap_Wall
+=
+=======================
+*/
+
+void DrawMap_Wall (int x, int y, int tile)
+{
+   byte * buf;
+   int p;
+   byte * b;
+   byte * source;
+   byte * s;
+   int i;
+
+   x*=tilesize;
+   y*=tilesize;
+   
+#ifdef DOS
+   buf=(byte *)bufferofs+ylookup[y]+(x>>2);
+#else
+   buf=(byte *)bufferofs+ylookup[y]+x;
+#endif
+
+   source=W_CacheLumpNum(tile,PU_CACHE, CvtNull, 1);
+
+#ifdef DOS
+   for (p=0;p<4;p++)
+#endif
+      {
+#ifdef DOS
+      VGAWRITEMAP(p);
+      s=source+((p*hp_srcstep)>>10);
+#else
+      s=source;
+#endif
+      b=buf;
+
+#ifdef DOS
+      for (i=p;i<tilesize;i+=4,b++)
+#else
+      for (i=0;i<tilesize;i++,b++)
+#endif
+         {
+         DrawMapPost(tilesize,s,b);
+#ifdef DOS
+         s+=(hp_srcstep>>8);
+#else
+         s+=(hp_srcstep>>10);
+#endif
+         }
+      }
+}
+
+/*
+=======================
+=
+= DrawMap_AnimatedWall
+=
+=======================
+*/
+
+void DrawMap_AnimatedWall (int x, int y, int tile)
+{
+   DrawMap_Wall(x,y,animwalls[tile].texture);
+}
+
+/*
+=======================
+=
+= DrawMap_SkyTile
+=
+=======================
+*/
+
+void DrawMap_SkyTile (int x, int y)
+{
+   byte * buf;
+   int p;
+   byte * b;
+   byte * s;
+   int i;
+
+   x*=tilesize;
+   y*=tilesize;
+
+#ifdef DOS
+   buf=(byte *)bufferofs+ylookup[y]+(x>>2);
+#else
+   buf=(byte *)bufferofs+ylookup[y]+x;
+#endif
+
+#ifdef DOS
+   for (p=0;p<4;p++)
+#endif
+      {
+#ifdef DOS
+      VGAWRITEMAP(p);
+      s=skytile+((p*hp_srcstep)>>10);
+#else
+      s=skytile;
+#endif
+
+      b=buf;
+#ifdef DOS
+      for (i=p;i<tilesize;i+=4,b++)
+#else
+      for (i=0;i<tilesize;i++,b++)
+#endif
+         {
+         DrawMapPost(tilesize,s,b);
+#ifdef DOS
+         s+=(hp_srcstep>>8);
+#else
+         s+=(hp_srcstep>>10);
+#endif
+         }
+      }
+}
+
+/*
+=======================
+=
+= DrawMap_MaskedWall
+=
+=======================
+*/
+
+void DrawMap_MaskedWall (int x, int y, int tile)
+{
+   if (IsPlatform(maskobjlist[tile]->tilex,maskobjlist[tile]->tiley))
+      {
+      if (!(maskobjlist[tile]->flags&MW_ABOVEPASSABLE))
+         DrawMap_MaskedShape(x,y,maskobjlist[tile]->toptexture,0);
+      else if (!(maskobjlist[tile]->flags&MW_BOTTOMPASSABLE))
+         DrawMap_MaskedShape(x,y,maskobjlist[tile]->bottomtexture,1);
+      else
+         DrawMap_MaskedShape(x,y,maskobjlist[tile]->midtexture,0);
+      }
+   else
+      {
+      DrawMap_MaskedShape(x,y,maskobjlist[tile]->bottomtexture,1);
+      }
+}
+
+/*
+=======================
+=
+= DrawMap_Door
+=
+=======================
+*/
+
+void DrawMap_Door (int x, int y, int tile)
+{
+   if (
+       (doorobjlist[tile]->lock > 0) &&
+       (doorobjlist[tile]->lock <= 4)
+      )
+      DrawMap_Wall(x,y,W_GetNumForName("lock1")+doorobjlist[tile]->lock-1);
+   else if (doorobjlist[tile]->texture==doorobjlist[tile]->basetexture)
+      DrawMap_Wall(x,y,doorobjlist[tile]->texture);
+   else
+      DrawMap_MaskedShape(x,y,doorobjlist[tile]->texture,0);
+}
+
+/*
+=======================
+=
+= DrawMap_PushWall
+=
+=======================
+*/
+
+void DrawMap_PushWall (int x, int y, pwallobj_t * pw)
+{
+   if (pw->texture&0x1000)
+      DrawMap_AnimatedWall(x,y,pw->texture&0x3ff);
+   else
+      DrawMap_Wall(x,y,pw->texture&0x3ff);
+}
+
+/*
+=======================
+=
+= DrawMap_Actor
+=
+=======================
+*/
+
+void DrawMap_Actor (int x, int y, objtype * a)
+{
+   int translucent;
+
+	if (!(a->flags&FL_SEEN))
+      return;
+
+   translucent=0;
+	if (a->flags&FL_TRANSLUCENT)
+      translucent=1;
+   DrawMap_MaskedShape(x,y,a->shapenum+shapestart,translucent);
+}
+
+/*
+=======================
+=
+= DrawMap_Sprite
+=
+=======================
+*/
+
+void DrawMap_Sprite (int x, int y, statobj_t * s)
+{
+   int translucent;
+
+	if (!(s->flags&FL_SEEN))
+      return;
+
+   translucent=0;
+	if (s->flags&FL_TRANSLUCENT)
+      translucent=1;
+   DrawMap_MaskedShape(x,y,s->shapenum+shapestart,translucent);
+}
+
+/*
+=======================
+=
+= DrawMap_MaskedShape
+=
+=======================
+*/
+
+void DrawMap_MaskedShape (int x, int y, int lump, int type)
+{
+
+   // Calculate center coordinates for sprites
+
+   x*=tilesize;
+   y*=tilesize;
+   x+=tilesize>>1;
+   y+=tilesize>>1;
+   DrawPositionedScaledSprite(x,y,lump,tilesize,type);
+}
+
+/*
+=======================
+=
+= DrawMap_PlayerArrow
+=
+=======================
+*/
+
+/* Indices: mapscale, reduced coordinate */
+static const int arrowscale[4][5] =
+{{ 1,17,32,47,63},  /* Mapscale 0: 64 pixels/sprite */
+ { 1, 9,16,23,31},  /* Mapscale 1: 32 pixels/sprite */
+ { 1, 5, 8,11,15},  /* Mapscale 2: 16 pixels/sprite */
+ { 1, 3, 4, 5, 7}}; /* Mapscale 3:  8 pixels/sprite */
+
+void DrawMap_PlayerArrow (int x, int y, int dir)
+{
+   int i;
+   
+   x*=tilesize;
+   y*=tilesize;
+
+   /* You can't draw a 4x4 arrow */
+   if(mapscale == 4)
+   {
+     VL_Bar(x+1,y+1,2,2,244);
+     return;
+   }
+
+   for (i=0;i<6;i++)
+      {
+      VL_DrawLine (arrowscale[mapscale][arrows[dir][i].x]+x,
+                   arrowscale[mapscale][arrows[dir][i].y]+y,
+                   arrowscale[mapscale][arrows[dir][i+1].x]+x,
+                   arrowscale[mapscale][arrows[dir][i+1].y]+y,
+                   244
+                  );
+      }
+   VL_DrawLine (  arrowscale[mapscale][arrows[dir][6].x]+x,
+                  arrowscale[mapscale][arrows[dir][6].y]+y,
+                  arrowscale[mapscale][arrows[dir][0].x]+x,
+                  arrowscale[mapscale][arrows[dir][0].y]+y,
+                  244
+               );
+}
+
+/*
+=======================
+=
+= DrawMap_Player
+=
+=======================
+*/
+
+void DrawMap_Player (int x, int y)
+{
+   if (player->flags&FL_SHROOMS)
+      DrawMap_PlayerArrow(x,y,( RandomNumber("DrawMap_PLAYER",0)>>5) );
+   else
+      DrawMap_PlayerArrow(x,y,( ( (player->angle+(FINEANGLES/16)) & (FINEANGLES-1) ) >>8) );
+   DrawMap_MaskedShape(x,y,player->shapenum+shapestart,0);
+}
+
+/*
+=======================
+=
+= DrawMap
+=
+=======================
+*/
+
+void DrawMap( int cx, int cy )
+{
+   fixed x,y;
+   statobj_t * s;
+   objtype * a;
+   int i,j;
+   int mapx,mapy;
+   int wall;
+
+   // Clear buffer
+
+   VL_ClearBuffer (bufferofs, egacolor[mapcolor]);
+
+   x=cx>>16;
+   y=cy>>16;
+
+   // Draw Walls,Doors,maskedwalls,animatingwalls
+
+   for (j=0;j<yscale;j++)
+      {
+
+      // Don't go off the bottom of the map
+
+      mapy=j+y;
+
+      if (mapy<0)
+         continue;
+
+      if (mapy>127)
+         break;
+
+      for (i=0;i<xscale;i++)
+         {
+
+         // Don't go off the right side of the map
+
+         mapx=i+x;
+
+         if (mapx<0)
+            continue;
+
+         if (mapx>127)
+            break;
+
+         if ((mapx==player->tilex ) && (mapy==player->tiley))
+            {
+            DrawMap_Player(i,j);
+            continue;
+            }
+
+         wall=tilemap[mapx][mapy];
+
+         // Check for absence of wall
+
+         if (wall)
+            {
+
+            if (!mapseen[mapx][mapy])
+               continue;
+
+            // Check to see if it is a door or masked wall
+
+            if (wall&0x8000)
+               {
+               if (wall&0x4000)
+                  {
+                  // Must be a masked wall
+                  DrawMap_MaskedWall(i,j,wall&0x3ff);
+                  }
+               else
+                  {
+                  // Must be a door
+                  DrawMap_Door(i,j,wall&0x3ff);
+                  }
+               }
+
+            // Check to see if it is an animating wall
+
+            else if (wall&0x1000)
+               {
+               DrawMap_AnimatedWall(i,j,wall&0x3ff);
+               }
+            else if (IsWindow(mapx,mapy))
+               {
+               if (sky!=0)
+                  DrawMap_SkyTile(i,j);
+               else
+                  Error("Trying to draw a sky on a level without sky\n");
+               }
+            else
+               {
+               // Must be a normal wall or a wall with something above
+               DrawMap_Wall(i,j,wall&0x3ff);
+               }
+            }
+         else
+            {
+            a=actorat[mapx][mapy];
+
+            // Check for absence of actor
+
+            if (a)
+               {
+               switch(a->which)
+                  {
+                  case PWALL:
+                     if (!mapseen[mapx][mapy])
+                        continue;
+                     DrawMap_PushWall(i,j,(pwallobj_t *)a);
+                     break;
+                  case ACTOR:
+                     DrawMap_Actor(i,j,a);
+                     break;
+                  case SPRITE:
+                     DrawMap_Actor(i,j,a);
+                     break;
+                  default:
+                     SoftError("Unable to resolve actorat at x=%d y=%d which=%d\n",mapx,mapy,a->which);
+                     break;
+                  }
+               }
+            else
+               {
+               s=sprites[mapx][mapy];
+
+               // Check for absence of sprite
+
+               if (s)
+                  {
+                  DrawMap_Sprite(i,j,s);
+                  }
+               }
+            }
+         }
+      }
+}
+
+
+
+
+/*
+=======================
+=
+= SetupFullMap
+=
+=======================
+*/
+
+void SetupFullMap( void )
+{
+   int ty;
+   pic_t *pic;
+
+   // Fill in backgrounds
+
+   pic = (pic_t *) W_CacheLumpNum (W_GetNumForName ("mmbk"), PU_CACHE, Cvt_pic_t, 1);
+   VWB_DrawPic (0, 0, pic);
+   CheckHolidays();
+
+   // Clear area for map
+
+#ifdef DOS
+   VGAMAPMASK(15);
+   for (ty=37;ty<37+127;ty++)
+      memset((byte *)bufferofs+ylookup[ty]+24,0,32);
+#else
+   for (ty=37;ty<37+127;ty++)
+      memset((byte *)bufferofs+ylookup[ty]+96,0,128);
+#endif
+}
+
+/*
+=======================
+=
+= DrawFullMap
+=
+=======================
+*/
+
+void DrawFullMap( void )
+{
+   statobj_t * s;
+   objtype * a;
+   int mapx,mapy;
+   int wall;
+   byte * buf;
+
+   SetupFullMap();
+
+   // Draw Walls,Doors,maskedwalls,animatingwalls
+
+   for (mapx=0;mapx<mapwidth;mapx++)
+      {
+#ifdef DOS
+      VGAWRITEMAP(mapx&3);
+      buf=(byte *)bufferofs+ylookup[37]+((96+mapx)>>2);
+#else      
+      buf=(byte *)bufferofs+ylookup[37]+((96+mapx));
+#endif
+
+#ifdef DOS
+      for (mapy=0;mapy<mapheight;mapy++,buf+=iGLOBAL_SCREENBWIDE)
+#else
+      for (mapy=0;mapy<mapheight;mapy++,buf+=iGLOBAL_SCREENWIDTH)
+#endif
+         {
+         if ((mapx==player->tilex ) && (mapy==player->tiley))
+            {
+            *buf=egacolor[MAP_PLAYERCOLOR];
+            continue;
+            }
+
+         wall=tilemap[mapx][mapy];
+
+         // Check for absence of wall
+
+         if (wall)
+            {
+
+            if (!mapseen[mapx][mapy])
+               continue;
+
+            // Check to see if it is a door or masked wall
+
+            if (wall&0x8000)
+               {
+               if (wall&0x4000)
+                  {
+                  // Must be a maskedwall
+                  *(buf)=egacolor[MAP_MWALLCOLOR];
+                  }
+               else
+                  {
+                  // Must be a door
+                  *(buf)=egacolor[MAP_DOORCOLOR];
+                  }
+               }
+
+            // Check to see if it is an animating wall
+
+            else if (wall&0x1000)
+               {
+               *(buf)=egacolor[MAP_AWALLCOLOR];
+               }
+            else if (IsWindow(mapx,mapy))
+               {
+               if (sky!=0)
+                  *(buf)=egacolor[MAP_SKYCOLOR];
+               else
+                  Error("Trying to draw a sky on a level without sky\n");
+               }
+            else
+               {
+               // Must be a normal wall or a wall with something above
+               *(buf)=egacolor[MAP_WALLCOLOR];
+               }
+            }
+         else
+            {
+            a=actorat[mapx][mapy];
+
+            // Check for absence of actor
+
+            if (a)
+               {
+               switch(a->which)
+                  {
+                  case PWALL:
+                     if (!mapseen[mapx][mapy])
+                        continue;
+                     *(buf)=egacolor[MAP_PWALLCOLOR];
+                     break;
+                  case ACTOR:
+                     if (a->flags&FL_SEEN)
+                        {
+                        if (a->obclass==inertobj)
+                           *(buf)=egacolor[MAP_SPRITECOLOR];
+                        else
+                           *(buf)=egacolor[MAP_ACTORCOLOR];
+                        }
+                     break;
+                  case SPRITE:
+                     if (a->flags&FL_SEEN)
+                        *(buf)=egacolor[MAP_SPRITECOLOR];
+                     break;
+                  default:
+                     SoftError("Unable to resolve actorat at x=%d y=%d which=%d\n",mapx,mapy,a->which);
+                     break;
+                  }
+               }
+            else
+               {
+               s=sprites[mapx][mapy];
+
+               // Check for absence of sprite
+
+               if (s && (s->flags&FL_SEEN))
+                  {
+                  *(buf)=egacolor[MAP_SPRITECOLOR];
+                  }
+               }
+            }
+         }
+      }
+   FlipPage();
+}
+
+/*
+=======================
+=
+= DrawMapInfo
+=
+=======================
+*/
+
+void DrawMapInfo ( void )
+{
+   char temp[80];
+   int width,height;
+
+   CurrentFont=tinyfont;
+
+   PrintX = 2;
+   PrintY = 2;
+   strcpy (&temp[0], &(LevelName[0]));
+   US_MeasureStr (&width, &height, &temp[0]);
+
+   VWB_TBar (0, 0, 320, height+4);
+
+   US_BufPrint (&temp[0]);
+
+   strcpy (&temp[0], "TAB=EXIT");
+   US_MeasureStr (&width, &height, &temp[0]);
+
+   PrintX = 316-width;
+   PrintY = 2;
+
+   US_BufPrint (&temp[0]);
+
+   strcpy (&temp[0], "< > CHANGE BACKGROUND COLOR");
+   US_MeasureStr (&width, &height, &temp[0]);
+
+   PrintX = (320-width)>>1;
+   PrintY = 2;
+
+   US_BufPrint (&temp[0]);
+}
+
+/*
+=======================
+=
+= SetupMapScale
+=
+=======================
+*/
+
+void SetupMapScale( int s )
+{
+   mapscale=s;
+   tilesize=64>>mapscale;
+   xscale=320/tilesize;
+   yscale=200/tilesize;
+   hp_srcstep=0x10000<<mapscale;
+}
+
+
+/*
+=======================
+=
+= ChangeMapScale
+=
+=======================
+*/
+
+void ChangeMapScale( int * newx, int * newy, int newmapscale )
+{
+   if (newmapscale<0)
+      return;
+   if (newmapscale>FULLMAP_SCALE)
+      return;
+
+   if (newmapscale==FULLMAP_SCALE)
+      DrawFullMap();
+
+   *newx=*newx+(xscale<<15);
+   *newy=*newy+(yscale<<15);
+
+   SetupMapScale(newmapscale);
+
+   *newx=*newx-(xscale<<15);
+   *newy=*newy-(yscale<<15);
+}
+
+
+/*
+=======================
+=
+= SetupMapper
+=
+=======================
+*/
+void SetupMapper ( void )
+{
+   FixMapSeen();
+
+   tics=0;
+   oldw=viewwidth;
+   oldh=viewheight;
+   viewwidth=320;
+   viewheight=200;
+
+   if (sky!=0)
+      {
+      skytile=SafeMalloc(64*64);
+      MakeSkyTile(skytile);
+      }
+}
+
+/*
+=======================
+=
+= ShutdownMapper
+=
+=======================
+*/
+void ShutdownMapper ( void )
+{
+   VL_ClearVideo (0);
+   viewwidth=oldw;
+   viewheight=oldh;
+   SetupScreen (true);
+
+   if (sky!=0)
+      SafeFree(skytile);
+   if (mouseenabled && MousePresent)
+      PollMouseMove();
+}
+
+/*
+=======================
+=
+= DoMap
+=
+=======================
+*/
+
+void DoMap (int cx, int cy)
+{
+   int x,y;
+   int dx;
+   int dy;
+   boolean done;
+   int quitkey;
+   ControlInfo control;
+
+EnableScreenStretch();//bna++
+
+   ShutdownClientControls();
+
+   done=false;
+
+   while (Keyboard[sc_Tab])
+      IN_UpdateKeyboard ();
+   if (SpaceBallPresent && spaceballenabled)
+      {
+      while (GetSpaceBallButtons()) ;
+      }
+
+   x=(cx-(xscale>>1))<<16;
+   y=(cy-(yscale>>1))<<16;
+
+   SetupMapper();
+
+   transparentlevel=25;
+
+   ChangeMapScale(&x, &y, mapscale);
+
+   while (done==false)
+     {
+     IN_UpdateKeyboard ();
+     if ((Keyboard[sc_Tab]) || (Keyboard[sc_Escape]))
+        {
+        if (Keyboard[sc_Tab])
+           quitkey=sc_Tab;
+        else
+           quitkey=sc_Escape;
+        done=true;
+        }
+     if (SpaceBallPresent && spaceballenabled)
+        {
+        if (GetSpaceBallButtons()!=0)
+           done=true;
+        }
+     if ( Keyboard[ sc_Home ] )
+        {
+        x=(cx-(xscale>>1))<<16;
+        y=(cy-(yscale>>1))<<16;
+        }
+     dx=0;
+     dy=0;
+     if (mapscale==FULLMAP_SCALE)
+        CalcTics();
+     else
+        {
+        DrawMap(x,y);
+        DrawMapInfo ();
+        FlipPage();
+        CalcTics();
+        DoSprites();
+	     AnimateWalls();
+        }
+     ReadAnyControl (&control);
+     if ((Keyboard[sc_PgUp]) ||
+         (Keyboard[sc_Plus])  ||
+         (control.button1))
+        {
+        ChangeMapScale(&x, &y, mapscale+1);
+        while(Keyboard[sc_PgUp])
+           IN_UpdateKeyboard ();
+        while(Keyboard[sc_Plus])
+           IN_UpdateKeyboard ();
+        while(control.button1)
+           ReadAnyControl (&control);
+        }
+     if ((Keyboard[sc_PgDn]) ||
+         (Keyboard[sc_Minus])  ||
+         (control.button0))
+        {
+        ChangeMapScale(&x, &y, mapscale-1);
+        while(Keyboard[sc_PgDn])
+           IN_UpdateKeyboard ();
+        while(Keyboard[sc_Minus])
+           IN_UpdateKeyboard ();
+        while(control.button0)
+           ReadAnyControl (&control);
+        }
+     if (Keyboard[sc_CapsLock] && Keyboard[sc_C])
+        {
+        inhmenu=true;
+        SaveScreen (true);
+        inhmenu=false;
+        }
+     if (Keyboard[sc_CapsLock] && Keyboard[sc_X])
+        {
+        inhmenu=true;
+        SaveScreen (false);
+        inhmenu=false;
+        }
+     if (Keyboard[sc_Comma])
+        {
+        if (mapcolor>0)
+           mapcolor--;
+        while(Keyboard[sc_Comma])
+           IN_UpdateKeyboard ();
+        }
+     if (Keyboard[sc_Period])
+        {
+        if (mapcolor<15)
+           mapcolor++;
+        while(Keyboard[sc_Period])
+           IN_UpdateKeyboard ();
+        }
+     if (mapscale!=FULLMAP_SCALE)
+        {
+        if (control.dir==dir_East)
+           dx=(tics<<17)/(5-mapscale);
+        if (control.dir==dir_West)
+           dx=-(tics<<17)/(5-mapscale);
+        if (control.dir==dir_South)
+           dy=(tics<<17)/(5-mapscale);
+        if (control.dir==dir_North)
+           dy=-(tics<<17)/(5-mapscale);
+        }
+#if (DEVELOPMENT == 1)
+     if (Keyboard[sc_M])
+        {
+        CheatMap();
+        ChangeMapScale( &x, &y, mapscale );
+        }
+#endif
+
+     x+=dx;
+     y+=dy;
+
+     if (x>0x7effff)
+        x=0x7effff;
+     else if (x<-(xscale<<15))
+        x=-(xscale<<15);
+     if (y>0x7effff)
+        y=0x7effff;
+     else if (y<-(yscale<<15))
+        y=-(yscale<<15);
+     }
+
+  if ( playstate == ex_stillplaying )	  {//bna++
+	   pic_t *shape;
+	   shape =  ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );
+	   DrawTiledRegion( 0, 16, iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT - 32, 0, 16, shape );//bna++
+	   DisableScreenStretch();//dont strech when we go BACK TO GAME
+	   VW_UpdateScreen ();
+	   DrawPlayScreen(true);//repaint ammo and life stat
+
+  }
+   while (Keyboard[quitkey])
+      IN_UpdateKeyboard ();
+
+   LastScan=0;
+   Keyboard[sc_Escape]=0;
+   Keyboard[sc_Tab]=0;
+
+   ShutdownMapper();
+
+   StartupClientControls();
+}
+

Added: tags/rott-1.1/rott/rt_map.h
===================================================================
--- tags/rott-1.1/rott/rt_map.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_map.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,32 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+// RT_MAP.C
+//
+//***************************************************************************
+
+#ifndef _rt_map_public
+#define _rt_map_public
+
+void DoMap(int x, int y);
+void CheatMap( void );
+
+#endif

Added: tags/rott-1.1/rott/rt_menu.c
===================================================================
--- tags/rott-1.1/rott/rt_menu.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_menu.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,10332 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//******************************************************************************
+//
+// RT_MENU.C
+//    Contains the menu stuff!
+//
+//******************************************************************************
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <string.h>
+#include <ctype.h>
+
+#if PLATFORM_DOS
+#include <conio.h>
+#include <dos.h>
+#include <io.h>
+#elif PLATFORM_UNIX
+#include <unistd.h>
+#include <SDL/SDL.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "rt_def.h"
+#include "_rt_menu.h"
+#include "rt_menu.h"
+#include "rt_sound.h"
+#include "fx_man.h"
+#include "rt_build.h"
+#include "rt_in.h"
+#include "isr.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "rt_util.h"
+#include "rt_main.h"
+#include "rt_playr.h"
+#include "rt_rand.h"
+#include "rt_game.h"
+#include "rt_floor.h"
+#include "rt_draw.h"
+#include "rt_view.h"
+#include "rt_str.h"
+#include "rt_vid.h"
+#include "rt_ted.h"
+#include "rt_com.h"
+#include "lumpy.h"
+#include "rt_cfg.h"
+#include "version.h"
+#include "modexlib.h"
+#include "rt_msg.h"
+#include "rt_net.h"
+#include "rt_spbal.h"
+#include "rt_scale.h"
+
+#include "rt_battl.h"
+#include "develop.h"
+//MED
+#include "memcheck.h"
+
+
+//******************************************************************************
+//
+// GLOBALS
+//
+//******************************************************************************
+
+#define DELAYAMT  2
+
+#define SNDCARDS  12
+
+#define CP_NO     0
+#define CP_ESC    -1
+#define CP_YES    1
+
+int CP_Acknowledge;
+
+boolean POK = false;
+char    pword[ 13 ];
+
+boolean ingame    = false;
+boolean inmenu    = false;
+boolean pickquick = false;
+boolean NewGame   = false;
+
+//
+// Global window coords
+//
+int PrintX;
+int PrintY;
+int WindowX;
+int WindowY;
+int WindowH = 160;
+int WindowW;
+
+int px;
+int py;
+int bufferheight;
+int bufferwidth;
+
+cfont_t *IFont;
+font_t  *CurrentFont;
+font_t  *newfont1;
+font_t  *smallfont;
+font_t  *bigfont;
+font_t  *tinyfont;
+
+boolean loadedgame = false;
+
+battle_type BATTLE_Options[ battle_NumBattleModes ];
+
+int quicksaveslot=-1;
+
+//******************************************************************************
+//
+// LOCALS
+//
+//******************************************************************************
+
+char order[ 21 ] = {
+   di_west, di_east, di_north, di_south, bt_run, bt_use, bt_attack,
+   bt_strafe, bt_strafeleft, bt_straferight, bt_lookup, bt_lookdown,
+   bt_aimbutton, bt_horizonup, bt_horizondown, bt_swapweapon, bt_dropweapon,
+   bt_turnaround, bt_autorun, bt_message, bt_directmsg
+   };
+
+// bt_pistol, bt_dualpistol, bt_mp40, bt_missileweapon, bt_recordsound,
+
+#define RETURNVAL    100
+
+static boolean loadsavesound = false;
+static int numdone;
+
+static char *endStrings[ 7 ] =
+   {
+   "Press Y to reformat \nand install Windows.\0\0",
+   "Press Y to activate \nguillotine.\0\0",
+   "Press Y to release \nthe cyanide gas.\0\0",
+   "Press Y to open \ntrap door.\0\0",
+   "Press Y to drive your \ncar off the cliff.\0\0",
+   "Press Y to pull \nyour plug.\0\0",
+   "Press Y to activate \nelectric chair.\0\0"
+   };
+
+static char *BattleModeDescriptions[ battle_NumBattleModes - 1 ] =
+   {
+   "Kill your enemies!  Don't get killed!  Kill some more!",
+   "Score more points for more difficult kills.",
+   "Collect the most triads to win the game.  Whoopee!",
+   "Collect triads to win the game--this time with weapons!",
+   "Armed hunters vs. unarmed prey--then the tables are turned!",
+   "Tag your enemies.  Run away.  Lowest points wins.",
+   "Chase roving 'Eluders'--tag them for points.",
+   "Use weapons to destroy roving Eluder triads for points.",
+   "Capture the opposing team's triad while guarding your own."
+   };
+
+static char *BattleOptionDescriptions[ 9 ] =
+   {
+   "Adjust the Gravitational Constant of the game universe!",
+   "Adjust the top speed for all players in the game",
+   "Adjust the amount of ammo in all missile weapons",
+   "Adjust the hit points of all players in the game",
+   "Radically change the way the game plays",
+   "Adjust the light characteristics of the game",
+   "Adjust the point goal of the game",
+   "Adjust the damage done by environment dangers",
+   "Adjust the time limit for the game"
+   };
+
+static char *GravityOptionDescriptions[ 3 ] =
+   {
+   "Similar to gravity on the moon",
+   "Normal Gravity (9.81 m/s^2 !)",
+   "Similar to gravity on Jupiter"
+   };
+
+static char *SpeedOptionDescriptions[ 2 ] =
+   {
+   "Player speeds are determined by character",
+   "All players can move at the fastest possible speed"
+   };
+
+static char *AmmoOptionDescriptions[ 3 ] =
+   {
+   "One piece of ammo per missile weapon",
+   "Normal ammo for all missile weapons",
+   "Infinite ammo for all missile weapons"
+   };
+
+static char *HitPointsOptionDescriptions[ 7 ] =
+   {
+   "One hit point for each player",
+   "25 hit points for each player",
+   "Hit points determined by character",
+   "100 hit points for each player",
+   "250 hit points for each player (default)",
+   "500 hit points for each player",
+   "4000 hit points for each player",
+   };
+
+static char *RadicalOptionDescriptions[ 8 ] =
+   {
+   "Control spawning of environment dangers",
+   "Control spawning of health items",
+   "Control spawning of missile weapons",
+   "Spawn mines instead of health items",
+   "Objects reappear a short time after being picked up",
+   "Missile weapons remain when picked up",
+   "Weapons are chosen randomly at the start of the game",
+   "Killing yourself or a team member counts as a suicide"
+   };
+
+static char *LightLevelOptionDescriptions[ 6 ] =
+   {
+   "Very dark, cave-like",
+   "Lighting determined by level design",
+   "Full brightness",
+   "Bright with fog",
+   "Periodic lighting (voobing)",
+   "Dark with lightning"
+   };
+
+static char *PointGoalOptionDescriptions[ 9 ] =
+   {
+   "One Point/Kill",
+   "5 Points/Kills",
+   "11 Points/Kills",
+   "21 Points/Kills",
+   "50 Points/Kills",
+   "100 Points/Kills",
+   "Random Points/Kills",
+   "Random Points/Kills but goal is not revealed",
+   "Infinite Points/Kills"
+   };
+
+static char *DangerDamageOptionDescriptions[ 3 ] =
+   {
+   "Environmental dangers' damage is relatively low",
+   "Environmental dangers' damage normal",
+   "One touch and you are dead!"
+   };
+
+static char *TimeLimitOptionDescriptions[ 8 ] =
+   {
+   "One Minute",
+   "2 Minutes",
+   "5 Minutes",
+   "10 Minutes",
+   "21 Minutes",
+   "30 Minutes",
+   "99 Minutes",
+   "No Time Limit"
+   };
+
+
+static char *BattleModeNames[ battle_NumBattleModes - 1 ] =
+   {
+   "NORMAL COMM-BAT", "SCORE MORE", "COLLECTOR", "SCAVENGER",
+   "HUNTER", "TAG", "ELUDER", "DELUDER", "CAPTURE THE TRIAD"
+   };
+
+static int OptionNums[ 12 ] =
+   {
+   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+   };
+
+static int HitPointNums[ 7 ] =
+   {
+   1, 25, bo_character_hitpoints, 100, 250, 500, 4000
+   };
+
+static int KillNums[ 9 ] =
+   {
+   1, 5, 11, 21, 50, 100, bo_kills_random,
+   bo_kills_blind, bo_kills_infinite
+   };
+
+static int GravityNums[ 3 ] =
+   {
+   LOW_GRAVITY, NORMAL_GRAVITY, HIGH_GRAVITY
+   };
+
+static int TimeLimitNums[ 8 ] =
+   {
+   1, 2, 5, 10, 21, 30, 99, bo_time_infinite
+   };
+
+static int DangerNums[ 3 ] =
+   {
+   bo_danger_low, bo_danger_normal, bo_danger_kill
+   };
+
+static int MenuNum = 0;
+static int handlewhich;
+static int CSTactive = 0;
+static boolean INFXSETUP = false;
+static int MaxVoices;
+static int MaxBits;
+static int MaxChannels;
+
+//
+// MENU CURSOR SHAPES
+//
+
+#define MAXCURSORNUM 24
+
+static int cursorwidth;
+static int cursorheight;
+static int yinc;
+
+static char *FontNames[] = { "itnyfont", "ifnt", "sifont", "lifont" };
+static int   FontSize[]  = { 6, 7, 9, 14 };
+static char *SmallCursor = "smallc01";
+static char *LargeCursor = "cursor01";
+static char *CursorLump  = "cursor01";
+static int CursorNum = 0;
+static int CursorFrame[ MAXCURSORNUM ] =
+   {
+   0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3,
+   4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1
+   };
+
+typedef enum
+   {
+   MOUSEENABLE,
+	JOYENABLE,
+	USEPORT2,
+	PADENABLE,
+	SPACEBALLENABLE,
+	CYBERMANENABLE,
+	THRESSENS,
+	MOUSESENS,
+	CUSTOMIZE
+   } controltypes;
+
+
+static char *playerwadname[] =
+   {
+   "cass1", "bars1", "wens1", "lnis1", "ipfs1"
+   };
+
+char *colorname[] =
+   {
+   "Gray", "Brown", "Black", "Tan", "Red", "Olive",
+   "Blue", "White", "Green", "Purple", "Orange"
+   };
+
+//
+// MENU ITEMS
+//
+CP_MenuNames MainMenuNames[] =
+   {
+   "NEW GAME",
+   "COMM-BAT GAME",
+   "RESTORE GAME",
+   "SAVE GAME",
+   "OPTIONS",
+   "ORDERING INFO",
+   "VIEW SCORES", //"END GAME"
+   "BACK TO DEMO", //"BACK TO GAME"
+   "QUIT"
+   };
+
+CP_iteminfo MainItems  = { MENU_X, MENU_Y + 1, 9, STARTITEM, 32, MainMenuNames, mn_largefont };
+CP_itemtype MainMenu[] =
+   {
+      { CP_CursorLocation, "mm_opt1\0",  'N', (menuptr)CP_NewGame },
+      { CP_Active,         "battle\0",   'C', (menuptr)CP_BattleModes },
+      { CP_Active,         "mm_opt2\0",  'R', (menuptr)CP_LoadGame },
+      { CP_Inactive,       "mm_opt3\0",  'S', (menuptr)CP_SaveGame },
+      { CP_Active,         "mm_opt5\0",  'O', (menuptr)CP_ControlMenu },
+      { CP_Active,         "ordrinfo\0", 'O', (menuptr)CP_OrderInfo },
+      { CP_Active,         "mm_opt7\0",  'V', (menuptr)CP_ViewScores },
+      { CP_Active,         "mm_opt8\0",  'B', (menuptr)NULL },
+      { CP_Active,         "mm_opt9\0",  'Q', (menuptr)CP_Quit }
+   };
+
+
+CP_iteminfo LSItems  = { LSM_X, LSM_Y, NUMSAVEGAMES, 0, 10, NULL, mn_largefont };
+CP_itemtype LSMenu[] =
+   {
+	   { CP_Active, "", 'a', NULL },
+	   { CP_Active, "", 'b', NULL },
+	   { CP_Active, "", 'c', NULL },
+	   { CP_Active, "", 'd', NULL },
+	   { CP_Active, "", 'e', NULL },
+	   { CP_Active, "", 'f', NULL },
+	   { CP_Active, "", 'g', NULL },
+	   { CP_Active, "", 'h', NULL },
+      { CP_Active, "", 'i', NULL },
+      { CP_Active, "", 'j', NULL },
+      { CP_Active, "", 'k', NULL },
+      { CP_Active, "", 'l', NULL },
+      { CP_Active, "", 'm', NULL },
+      { CP_Active, "", 'n', NULL },
+	   { CP_Active, "", 'o', NULL }
+   };
+
+CP_MenuNames CtlMenuNames[] =
+   {
+   "MOUSE ENABLED",
+   "JOYSTICK ENABLED",
+   "USE JOYSTICK PORT 2",
+   "GAMEPAD ENABLED",
+   "SPACEBALL ENABLED",
+   "CYBERMAN ENABLED",
+   "ADJUST THRESHOLD",
+   "MOUSE SENSITIVITY",
+   "CUSTOMIZE CONTROLS"
+   };
+
+CP_iteminfo CtlItems  = { CTL_X, MENU_Y, 9, -1, 36, CtlMenuNames, mn_largefont };
+CP_itemtype CtlMenu[] =
+   {
+      { CP_Inactive, "ctl_mic\0", 'M', NULL },
+      { CP_Inactive, "ctl_jen\0", 'J', NULL },
+      { CP_Inactive, "ctl_jp2\0", 'U', NULL },
+      { CP_Inactive, "ctl_gpd\0", 'G', NULL },
+      { CP_Inactive, "spball\0",  'S', NULL },
+      { CP_Inactive, "cyberman\0",'C', NULL },
+      { CP_Inactive, "ctl_thr\0", 'A', (menuptr)DoThreshold },
+      { CP_Inactive, "ctl_mse\0", 'M', (menuptr)MouseSensitivity },
+      { CP_Active,   "ctl_cus\0", 'C', (menuptr)CP_Custom }
+   };
+
+CP_iteminfo CusItems  = { 32, CST_Y + 13 * 2, 9, -1, 0, NULL, mn_largefont };
+CP_itemtype CusMenu[] =
+   {
+      { CP_Active,   "ctl_mic\0", 'a', NULL },
+      { CP_Inactive, "ctl_mic\0", 'a', NULL },
+      { CP_Inactive, "ctl_mic\0", 'a', NULL },
+      { CP_Active,   "ctl_mic\0", 'a', NULL },
+      { CP_Inactive, "ctl_mic\0", 'a', NULL },
+      { CP_Inactive, "ctl_mic\0", 'a', NULL },
+      { CP_Active,   "ctl_mic\0", 'a', NULL },
+      { CP_Inactive, "ctl_mic\0", 'a', NULL },
+      { CP_Active,   "ctl_mic\0", 'a', NULL }
+   };
+
+
+CP_iteminfo TufItems = { TUF_X, TUF_Y, 7, 0, 80, NULL, mn_largefont };
+CP_itemtype TufMenu[ 4 ][ 7 ] =
+   {
+      {
+         { 2, "new11\0", 'a', NULL },
+         { 3, "new11\0", 'a', NULL },
+         { 1, "new12\0", 'a', NULL },
+         { 3, "new12\0", 'a', NULL },
+         { 1, "new13\0", 'a', NULL },
+         { 3, "new13\0", 'a', NULL },
+         { 1, "new14\0", 'a', NULL },
+      },
+
+      {
+         { 2, "new21\0", 'a', NULL },
+         { 3, "new21\0", 'a', NULL },
+         { 1, "new22\0", 'a', NULL },
+         { 3, "new22\0", 'a', NULL },
+         { 1, "new23\0", 'a', NULL },
+         { 3, "new23\0", 'a', NULL },
+         { 1, "new24\0", 'a', NULL },
+      },
+
+      {
+         { 2, "new31\0", 'a', NULL },
+         { 3, "new31\0", 'a', NULL },
+         { 1, "new32\0", 'a', NULL },
+         { 3, "new32\0", 'a', NULL },
+         { 1, "new33\0", 'a', NULL },
+         { 3, "new33\0", 'a', NULL },
+         { 1, "new34\0", 'a', NULL },
+      },
+
+      {
+         { 2, "stk_1\0", 'a', NULL },
+         { 3, "stk_1\0", 'a', NULL },
+         { 1, "stk_2\0", 'a', NULL },
+         { 3, "stk_2\0", 'a', NULL },
+         { 1, "stk_3\0", 'a', NULL },
+         { 3, "stk_3\0", 'a', NULL },
+         { 1, "stk_4\0", 'a', NULL },
+      }
+   };
+
+CP_MenuNames CustomMenuNames[] =
+   {
+   "CUSTOMIZE KEYBOARD",
+   "CUSTOMIZE MOUSE",
+   "CUSTOMIZE JOYSTICK"
+   };
+
+CP_iteminfo CustomItems = {32, 64, 3, 0, 24, CustomMenuNames, mn_largefont };
+
+CP_itemtype CustomMenu[] =
+{
+  {2, "custom1\0", 'C', (menuptr)CP_Keyboard},
+  {1, "custom2\0", 'C', (menuptr)CP_Mouse},
+  {1, "custom3\0", 'C', (menuptr)CP_Joystick}
+};
+
+#define KEYNAMEINDEX 21
+
+CP_MenuNames NormalKeyNames[] =
+   {
+   "LEFT               \x9      ",
+   "RIGHT              \x9      ",
+   "FORWARD            \x9      ",
+   "BACKWARD           \x9      ",
+   "RUN                \x9      ",
+   "OPEN               \x9      ",
+   "FIRE               \x9      ",
+   "STRAFE             \x9      ",
+   "STRAFE LEFT        \x9      ",
+   "STRAFE RIGHT       \x9      ",
+   "LOOK/FLY UP        \x9      ",
+   "LOOK/FLY DOWN      \x9      ",
+   "AIM                \x9      ",
+   "AIM UP             \x9      ",
+   "AIM DOWN           \x9      ",
+   "TOGGLE WEAPON      \x9      ",
+   "DROP WEAPON        \x9      ",
+   "VOLTE-FACE         \x9      ",
+   "AUTORUN            \x9      ",
+   "SEND MESSAGE       \x9      ",
+   "DIRECT MESSAGE     \x9      "
+   };
+
+#define NORMALKEY_X  74
+#define NORMALKEY_Y  16
+CP_iteminfo NormalKeyItems = { NORMALKEY_X, 17, 21, 0, 16, NormalKeyNames, mn_tinyfont };
+
+CP_itemtype NormalKeyMenu[] =
+   {
+      { 2, "\0", 'L', (menuptr)DefineKey },
+      { 1, "\0", 'R', (menuptr)DefineKey },
+      { 1, "\0", 'F', (menuptr)DefineKey },
+      { 1, "\0", 'B', (menuptr)DefineKey },
+      { 1, "\0", 'R', (menuptr)DefineKey },
+      { 1, "\0", 'O', (menuptr)DefineKey },
+      { 1, "\0", 'F', (menuptr)DefineKey },
+      { 1, "\0", 'S', (menuptr)DefineKey },
+      { 1, "\0", 'S', (menuptr)DefineKey },
+      { 1, "\0", 'S', (menuptr)DefineKey },
+      { 1, "\0", 'L', (menuptr)DefineKey },
+      { 1, "\0", 'L', (menuptr)DefineKey },
+      { 1, "\0", 'A', (menuptr)DefineKey },
+      { 1, "\0", 'A', (menuptr)DefineKey },
+      { 1, "\0", 'T', (menuptr)DefineKey },
+      { 1, "\0", 'D', (menuptr)DefineKey },
+      { 1, "\0", 'V', (menuptr)DefineKey },
+      { 1, "\0", 'A', (menuptr)DefineKey },
+      { 1, "\0", 'A', (menuptr)DefineKey },
+      { 1, "\0", 'S', (menuptr)DefineKey },
+      { 1, "\0", 'D', (menuptr)DefineKey }
+   };
+
+#define NUMCONTROLNAMES 21
+
+CP_MenuNames ControlNames[] =
+   {
+   "NONE",
+   "LEFT",
+   "RIGHT",
+   "FORWARD",
+   "BACKWARD",
+   "RUN",
+   "OPEN",
+   "FIRE",
+   "STRAFE",
+   "STRAFE LEFT",
+   "STRAFE RIGHT",
+   "LOOK/FLY UP",
+   "LOOK/FLY DOWN",
+   "AIM",
+   "AIM UP",
+   "AIM DOWN",
+   "TOGGLE WEAPON",
+   "DROP WEAPON",
+   "VOLTE-FACE",
+   "AUTORUN",
+   "MAP"
+   };
+
+int controlorder[ NUMCONTROLNAMES ] = {
+   bt_nobutton, di_west, di_east, di_north, di_south, bt_run, bt_use,
+   bt_attack, bt_strafe, bt_strafeleft, bt_straferight, bt_lookup,
+   bt_lookdown, bt_aimbutton, bt_horizonup, bt_horizondown,
+   bt_swapweapon, bt_dropweapon, bt_turnaround, bt_autorun, bt_map
+   };
+
+#define CONTROLSELECT_X  106
+CP_iteminfo ControlSelectItems = { CONTROLSELECT_X, 17, NUMCONTROLNAMES, 0, 16, ControlNames, mn_tinyfont };
+
+CP_itemtype ControlSelectMenu[] =
+   {
+      { 2, "\0", 'N', NULL },
+      { 1, "\0", 'L', NULL },
+      { 1, "\0", 'R', NULL },
+      { 1, "\0", 'F', NULL },
+      { 1, "\0", 'B', NULL },
+      { 1, "\0", 'R', NULL },
+      { 1, "\0", 'O', NULL },
+      { 1, "\0", 'F', NULL },
+      { 1, "\0", 'S', NULL },
+      { 1, "\0", 'S', NULL },
+      { 1, "\0", 'S', NULL },
+      { 1, "\0", 'L', NULL },
+      { 1, "\0", 'L', NULL },
+      { 1, "\0", 'A', NULL },
+      { 1, "\0", 'A', NULL },
+      { 1, "\0", 'A', NULL },
+      { 1, "\0", 'T', NULL },
+      { 1, "\0", 'D', NULL },
+      { 1, "\0", 'V', NULL },
+      { 1, "\0", 'A', NULL },
+      { 1, "\0", 'M', NULL }
+   };
+
+#define MOUSEBTNINDEX 17
+
+CP_MenuNames MouseBtnNames[] =
+   {
+   "             B0  \x9             ",
+   "             B1  \x9             ",
+   "             B2  \x9             ",
+   "DOUBLE-CLICK B0  \x9             ",
+   "DOUBLE-CLICK B1  \x9             ",
+   "DOUBLE-CLICK B2  \x9             "
+   };
+
+CP_iteminfo MouseBtnItems = { 19, 52, 6, 0, 11, MouseBtnNames, mn_8x8font };
+
+CP_itemtype MouseBtnMenu[] =
+   {
+      { 2, "\0", 'B', (menuptr)DefineMouseBtn },
+      { 1, "\0", 'B', (menuptr)DefineMouseBtn },
+      { 1, "\0", 'B', (menuptr)DefineMouseBtn },
+      { 1, "\0", 'D', (menuptr)DefineMouseBtn },
+      { 1, "\0", 'D', (menuptr)DefineMouseBtn },
+      { 1, "\0", 'D', (menuptr)DefineMouseBtn }
+   };
+
+
+#define JOYBTNINDEX 17
+
+CP_MenuNames JoyBtnNames[] =
+   {
+   "             B0  \x9             ",
+   "             B1  \x9             ",
+   "             B2  \x9             ",
+   "             B3  \x9             ",
+   "DOUBLE-CLICK B0  \x9             ",
+   "DOUBLE-CLICK B1  \x9             ",
+   "DOUBLE-CLICK B2  \x9             ",
+   "DOUBLE-CLICK B3  \x9             "
+   };
+
+CP_iteminfo JoyBtnItems = { 19, 48, 8, 0, 11, JoyBtnNames, mn_8x8font };
+
+CP_itemtype JoyBtnMenu[] =
+   {
+      { 2, "\0", 'B', (menuptr)DefineJoyBtn },
+      { 1, "\0", 'B', (menuptr)DefineJoyBtn },
+      { 1, "\0", 'B', (menuptr)DefineJoyBtn },
+      { 1, "\0", 'B', (menuptr)DefineJoyBtn },
+      { 1, "\0", 'D', (menuptr)DefineJoyBtn },
+      { 1, "\0", 'D', (menuptr)DefineJoyBtn },
+      { 1, "\0", 'D', (menuptr)DefineJoyBtn },
+      { 1, "\0", 'D', (menuptr)DefineJoyBtn }
+   };
+
+CP_MenuNames PlayerMenuNames[] =
+   {
+   "TARADINO CASSATT",
+   "THI BARRETT",
+   "DOUG WENDT",
+   "LORELEI NI",
+   "IAN PAUL FREELEY"
+   };
+
+CP_iteminfo PlayerItems = {TUF_X, 48, 5, 0, 80, PlayerMenuNames, mn_largefont };
+
+CP_itemtype PlayerMenu[] =
+{
+	{2, "name1\0", 'T', NULL},
+   {1, "name2\0", 'T', NULL},
+   {1, "name3\0", 'D', NULL},
+   {1, "name4\0", 'L', NULL},
+   {1, "name5\0", 'I', NULL},
+};
+
+CP_MenuNames ControlMMenuNames[] =
+   {
+   "CONTROLS",
+   "USER OPTIONS",
+   "EXT USER OPTIONS",//bna added
+   "MUSIC VOLUME",
+   "SOUND FX VOLUME"
+
+   };
+CP_iteminfo ControlMItems = {32, 48-8, 5, 0, 32, ControlMMenuNames, mn_largefont };//bna added
+//CP_iteminfo ControlMItems = {32, 48, 4, 0, 32, ControlMMenuNames, mn_largefont };
+
+CP_itemtype ControlMMenu[] =
+{
+   {2, "cntl\0",     'C', (menuptr)CP_Control},
+   {1, "uopt\0",     'U', (menuptr)CP_OptionsMenu},
+   {1, "euopt\0", 'E', (menuptr)CP_ExtOptionsMenu},//bna added
+   {1, "muvolumn\0", 'M', (menuptr)MusicVolume},
+   {1, "fxvolumn\0", 'S', (menuptr)FXVolume}
+
+};
+
+CP_MenuNames OptionsNames[] =
+   {
+   "AUTO DETAIL ADJUST",
+   "LIGHT DIMINISHING",
+   "BOBBIN'",
+   "FLOOR AND CEILING",
+   "DOUBLE-CLICK SPEED",
+   "MENU FLIP SPEED",
+   "DETAIL LEVELS",
+   "VIOLENCE LEVEL",
+   "SCREEN SIZE"
+   };
+//bna added
+CP_MenuNames ExtOptionsNames[] =
+   {
+   "MOUSELOOK",
+   "INVERSE MOUSE",
+   "CROSS HAIR",
+   "JUMPING",
+   "FULLSCREEN"
+   };
+CP_iteminfo ExtOptionsItems = { 20, MENU_Y, 5, 0, 43, ExtOptionsNames, mn_largefont };
+
+CP_itemtype ExtOptionsMenu[] =
+{
+   {1, "", 'M', NULL},
+   {1, "", 'I', NULL},
+   {1, "", 'C', NULL},
+   {1, "", 'J', NULL},
+   {1, "", 'F', NULL}
+};
+   
+//bna added end
+
+CP_iteminfo OptionsItems = { 20, MENU_Y, 9, 0, 43, OptionsNames, mn_largefont };
+
+CP_itemtype OptionsMenu[] =
+{
+   {2, "autoadj\0", 'A', NULL},
+   {1, "lightdim\0",'L', NULL},
+   {1, "bobbin\0",  'B', NULL},
+   {1, "fandc\0",   'F', NULL},
+   {1, "double\0",  'D', (menuptr)CP_DoubleClickSpeed},
+   {1, "menuspd\0", 'M', (menuptr)MenuFlipSpeed},
+   {1, "detail\0",  'D', (menuptr)CP_DetailMenu},
+   {1, "vlevel\0",  'V', (menuptr)CP_ViolenceMenu},
+   {1, "\0",        'S', (menuptr)CP_ScreenSize}
+};
+
+CP_MenuNames DetailMenuNames[] =
+   {
+   "LOW DETAIL",
+   "MEDIUM DETAIL",
+   "HIGH DETAIL"
+   };
+
+CP_iteminfo DetailItems = { 32, 64, 3, 0, 43, DetailMenuNames, mn_largefont };
+
+CP_itemtype DetailMenu[] =
+{
+   {2, "lowdtl\0", 'L', NULL},
+   {1, "meddtl\0", 'M', NULL},
+   {1, "hidtl\0",  'H', NULL}
+};
+
+CP_MenuNames BattleMenuNames[] =
+   {
+   "PLAY GAME",
+   "PLAY TEAM GAME",
+   "COMM-BAT OPTIONS"
+   };
+
+CP_iteminfo BattleItems = { 32, 19, 3, 0, 24, BattleMenuNames, mn_largefont };
+
+CP_itemtype BattleMenu[] =
+{
+   {2, "bplay\0",    'P', (menuptr)BattleNoTeams},
+   {1, "playteam\0", 'P', (menuptr)BattleTeams},
+   {1, "comopt\0",   'C', (menuptr)CP_BattleOptions}
+};
+
+CP_MenuNames ViolenceMenuNames[] =
+   {
+   "NONE",
+   "SOME",
+   "A LOT",
+   "EXCESSIVE"
+   };
+
+CP_iteminfo ViolenceItems = { 32, 64, 4, 0, 45, ViolenceMenuNames, mn_largefont };
+
+CP_itemtype ViolenceMenu[] =
+{
+   {2, "vnone\0",   'N', NULL},
+   {1, "vsome\0",   'S', NULL},
+   {1, "valot\0",   'A', NULL},
+   {1, "vexcess\0", 'E', NULL}
+};
+
+CP_MenuNames VMenuNames[] =
+   {
+   "SET VIOLENCE LEVEL",
+   "" // "ENTER PASSWORD" // "CHANGE PASSWORD"
+   };
+
+CP_iteminfo VItems = { 32, MP_Y, 2, 0, 24, VMenuNames, mn_largefont };
+
+CP_itemtype VMenu[] =
+{
+   {2, "msetv\0",  'S',  (menuptr)CP_ViolenceLevel},
+   {1, "mepass\0", 'E', (menuptr)CP_PWMenu}
+};
+
+CP_MenuNames ModeMenuNames[] =
+   {
+   "NORMAL",
+   "SCORE MORE",
+   "COLLECTOR",
+   "SCAVENGER",
+   "HUNTER",
+   "TAG",
+   "ELUDER",
+   "DELUDER",
+   "CAPTURE THE TRIAD"
+   };
+
+CP_iteminfo ModeItems = { MENU_X, MENU_Y + 1, 9, 0, 24, ModeMenuNames, mn_largefont };
+
+CP_itemtype ModeMenu[] =
+{
+   {CP_CursorLocation, "normal\0",   'N', (menuptr)CP_BattleMenu},
+   {CP_Active,         "scorem\0",   'S', (menuptr)CP_BattleMenu},
+   {CP_Active,         "collect\0",  'C', (menuptr)CP_BattleMenu},
+   {CP_Active,         "scaven\0",   'S', (menuptr)CP_BattleMenu},
+   {CP_Active,         "hunter\0",   'H', (menuptr)CP_BattleMenu},
+   {CP_Active,         "tag\0",      'T', (menuptr)CP_BattleMenu},
+   {CP_Active,         "eluder\0",   'E', (menuptr)CP_BattleMenu},
+   {CP_Active,         "deluder\0",  'D', (menuptr)CP_BattleMenu},
+   {CP_Active,         "captriad\0", 'C', (menuptr)CP_BattleMenu}
+};
+
+CP_MenuNames BOptNames[] =
+   {
+   "GRAVITY",
+   "SPEED",
+   "AMMO PER WEAPON",
+   "HIT POINTS",
+   "RADICAL OPTIONS",
+   "LIGHT LEVELS",
+   "POINT GOAL",
+   "DANGER DAMAGE",
+   "TIME LIMIT"
+   };
+
+CP_iteminfo BOptItems = { MENU_X, MENU_Y + 1, 9, 0, 24, BOptNames, mn_largefont };
+
+CP_itemtype BOptMenu[] =
+{
+   {2, "gravity\0",  'G', (menuptr)CP_GravityOptions},
+   {1, "speed\0",    'S', (menuptr)CP_SpeedOptions},
+   {1, "ammoper\0",  'A', (menuptr)CP_AmmoPerWeaponOptions},
+   {1, "hitp\0",     'H', (menuptr)CP_HitPointsOptions},
+   {1, "radical\0",  'R', (menuptr)CP_SpawnControlOptions},
+   {1, "lightl\0",   'L', (menuptr)CP_LightLevelOptions},
+   {1, "pntgoal\0",  'P', (menuptr)CP_PointGoalOptions},
+   {1, "danger\0",   'D', (menuptr)CP_DangerOptions},
+   {1, "timel\0",    'T', (menuptr)CP_TimeLimitOptions}
+};
+
+CP_MenuNames GravityMenuNames[] =
+   {
+   "LOW",
+   "NORMAL",
+   "HIGH"
+   };
+
+CP_iteminfo GravityItems = { 32, 26, 3, 0, 45, GravityMenuNames, mn_largefont };
+
+CP_itemtype GravityMenu[] =
+{
+	{2, "b_low\0",    'L', NULL},
+	{1, "b_normal\0", 'N', NULL},
+	{1, "b_high\0",   'H', NULL}
+};
+
+CP_MenuNames SpeedMenuNames[] =
+   {
+   "NORMAL",
+   "FAST"
+   };
+
+CP_iteminfo SpeedItems = { 32, MP_Y, 2, 0, 45, SpeedMenuNames, mn_largefont };
+
+CP_itemtype SpeedMenu[] =
+{
+   {2, "b_normal\0", 'N', NULL},
+   {1, "b_fast\0",   'F', NULL}
+};
+
+CP_MenuNames AmmoPerWeaponMenuNames[] =
+   {
+   "ONE",
+   "NORMAL",
+   "GUNFINITY"
+   };
+
+CP_iteminfo AmmoPerWeaponItems = { 32, 26, 3, 0, 45, AmmoPerWeaponMenuNames, mn_largefont };
+
+CP_itemtype AmmoPerWeaponMenu[] =
+{
+   {2, "b_one\0",    'O', NULL},
+   {1, "b_normal\0", 'N', NULL},
+   {1, "b_gunf\0",   'G', NULL}
+};
+
+CP_MenuNames HitPointMenuNames[] =
+   {
+   "ONE",
+   "25",
+   "BY CHARACTER",
+   "100",
+   "250",
+   "500",
+   "4000"
+   };
+
+CP_iteminfo HitPointItems = { 32, 32, 7, 0, 45, HitPointMenuNames, mn_largefont };
+
+CP_itemtype HitPointMenu[] =
+{
+   {2, "b_one\0",  'O', NULL},
+   {1, "b_25\0",   'a', NULL},
+   {1, "b_char\0", 'C', NULL},
+   {1, "b_100\0",  'a', NULL},
+   {1, "b_250\0",  'a', NULL},
+	{1, "b_500\0",  'a', NULL},
+   {1, "b_4000\0", 'a', NULL}
+};
+
+CP_MenuNames SpawnMenuNames[] =
+   {
+   "SPAWN DANGERS",
+   "SPAWN HEALTH",
+   "SPAWN WEAPONS",
+   "SPAWN MINES",
+   "RESPAWN ITEMS",
+   "WEAPON PERSISTENCE",
+   "RANDOM WEAPONS",
+   "FRIENDLY FIRE"
+   };
+
+CP_iteminfo SpawnItems = { 20, 24, 8, 0, 35, SpawnMenuNames, mn_largefont };
+
+CP_itemtype SpawnMenu[] =
+{
+   {2, "b_danger\0", 'S', NULL},
+   {1, "b_health\0", 'S', NULL},
+   {1, "b_weap\0",   'S', NULL},
+   {1, "b_mines\0",  'S', NULL},
+   {1, "b_rpawn\0",  'R', NULL},
+   {1, "b_persis\0", 'W', NULL},
+   {1, "b_rndwpn\0", 'R', NULL},
+   {1, "b_friend\0", 'F', NULL}
+};
+
+CP_MenuNames LightLevelMenuNames[] =
+   {
+   "DARK",
+   "NORMAL",
+   "BRIGHT",
+   "FOG",
+   "PERIODIC",
+   "LIGHTNING"
+   };
+
+CP_iteminfo LightLevelItems = { 32, 40, 6, 0, 45, LightLevelMenuNames, mn_largefont };
+
+CP_itemtype LightLevelMenu[] =
+{
+   {2, "b_dark\0",   'D', NULL},
+   {1, "b_normal\0", 'N', NULL},
+   {1, "b_bright\0", 'B', NULL},
+   {1, "b_fog\0",    'F', NULL},
+   {1, "b_period\0", 'P', NULL},
+   {1, "b_light\0",  'L', NULL}
+};
+
+CP_MenuNames PointGoalMenuNames[] =
+   {
+   "1",
+   "5",
+   "11",
+   "21",
+   "50",
+   "100",
+   "RANDOM",
+   "RANDOM BLIND",
+   "INFINITE"
+   };
+
+CP_iteminfo PointGoalItems = { 32, 16, 9, 0, 45, PointGoalMenuNames, mn_largefont };
+
+CP_itemtype PointGoalMenu[] =
+{
+	{2, "b_1\0",      'a', NULL},
+   {1, "b_5\0",      'a', NULL},
+   {1, "b_11\0",     'a', NULL},
+   {1, "b_21\0",     'a', NULL},
+   {1, "b_50\0",     'a', NULL},
+   {1, "b_100\0",    'a', NULL},
+   {1, "b_random\0", 'R', NULL},
+	{1, "b_randb\0",  'R', NULL},
+	{1, "b_inf\0",    'I', NULL}
+};
+
+CP_MenuNames DangerMenuNames[] =
+   {
+   "LOW",
+   "NORMAL",
+   "KILL"
+   };
+
+CP_iteminfo DangerItems = { 32, 56, 3, 0, 45, DangerMenuNames, mn_largefont };
+
+CP_itemtype DangerMenu[] =
+{
+   {2, "b_low\0",    'L', NULL},
+   {1, "b_normal\0", 'N', NULL},
+	{1, "b_kill\0",   'K', NULL}
+};
+
+CP_MenuNames TimeLimitMenuNames[] =
+   {
+   "1",
+   "2",
+   "5",
+   "10",
+   "21",
+   "30",
+   "99",
+   "NONE"
+   };
+
+CP_iteminfo TimeLimitItems = { 32, 24, 8, 0, 45, TimeLimitMenuNames, mn_largefont };
+
+CP_itemtype TimeLimitMenu[] =
+{
+	{2, "b_1\0",    'a', NULL},
+	{1, "b_2\0",    'a', NULL},
+	{1, "b_5\0",    'a', NULL},
+	{1, "b_10\0",   'a', NULL},
+   {1, "b_21\0",   'a', NULL},
+	{1, "b_30\0",   'a', NULL},
+	{1, "b_99\0",   'a', NULL},
+   {1, "vnone\0",  'N', NULL}
+};
+
+CP_MenuNames MultiPageCustomNames[ MAXCUSTOM + 2 ] =
+   {
+   "NEXT PAGE",
+   "PREVIOUS PAGE"
+   };
+
+CP_iteminfo MultiPageCustomItems = { 18, 17, 0, 0, 12, MultiPageCustomNames, mn_smallfont };
+CP_itemtype MultiPageCustomMenu[] =
+{
+	{1, "", 'N', NULL},
+   {1, "", 'P', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+   {1, "", 'a', NULL},
+};
+
+#define COLORX 113
+#define COLORY 43
+#define COLORW 60
+#define COLORH 96
+
+// Custom menu stuff
+static int CUSTOM_y[ 7 ] = { 31, 0, 63, 0, 94, 0, 126 };
+
+//
+// Save globals
+//
+static boolean StartGame = false;
+
+static int  SaveGamesAvail[ NUMSAVEGAMES ];
+static char SaveGameNames[ NUMSAVEGAMES ][ 32 ];
+static char SaveName[ 13 ] = "rottgam?.rot\0";
+
+static byte *savedscreen;
+static mapfileinfo_t * mapinfo;
+
+static void HideCursor
+   (
+   CP_iteminfo *item_i,
+   CP_itemtype *items,
+   int x,
+   int y,
+   int which
+   );
+static void ShowCursor
+   (
+   CP_iteminfo *item_i,
+   CP_itemtype *items,
+   int x,
+   int *y,
+   int which,
+   int basey
+   );
+void CP_DrawSelectedGame (int w);
+int HandleMenu (CP_iteminfo *item_i, CP_itemtype *items, void (*routine)(int w));
+void DrawStoredGame ( byte * pic, int episode, int area );
+void DrawCustomKeyboard (void);
+void DrawBattleModeName( int which );
+void DrawBattleModeDescription( int w );
+void DrawSoundSetupMainMenu( void );
+int ColorMenu(void);
+
+//******************************************************************************
+//
+// MN_DrawButtons
+//
+//******************************************************************************
+
+void MN_DrawButtons
+   (
+   CP_iteminfo *item_i,
+   CP_itemtype *items,
+   int check,
+   int *nums
+   )
+
+   {
+   int i;
+   int button_on;
+   int button_off;
+
+   button_on  = W_GetNumForName( "snd_on" );
+   button_off = W_GetNumForName( "snd_off" );
+
+   for( i = 0; i < item_i->amount; i++ )
+      {
+      if ( items[ i ].active != CP_Active3 )
+         {
+         if ( nums[ i ] == check )
+            {
+            DrawMenuBufItem( item_i->x + 27, item_i->y + i *
+               FontSize[ item_i->fontsize ] - 1, button_on);
+            }
+         else
+            {
+            DrawMenuBufItem( item_i->x + 27, item_i->y + i *
+               FontSize[ item_i->fontsize ] - 1, button_off);
+            }
+         }
+      }
+   }
+
+
+//****************************************************************************
+//
+// MN_GetCursorLocation()
+//
+//****************************************************************************
+
+void MN_GetCursorLocation
+   (
+   CP_iteminfo *item_i,
+   CP_itemtype *items
+   )
+
+   {
+   int i;
+   int position;
+
+   position = -1;
+   for( i = 0; i < item_i->amount; i++ )
+      {
+      if ( items[ i ].active == CP_CursorLocation )
+         {
+         position = i;
+         break;
+         }
+
+      if ( ( items[ i ].active == CP_Active ) && ( position == -1 ) )
+         {
+         position = i;
+         }
+      }
+
+   if ( position != -1 )
+      {
+      item_i->curpos = position;
+      items[ position ].active = CP_CursorLocation;
+      }
+   }
+
+
+//****************************************************************************
+//
+// MN_GetActive ()
+//
+//****************************************************************************
+
+int MN_GetActive
+   (
+   CP_iteminfo *item_i,
+   CP_itemtype *items,
+   int check,
+   int *nums
+   )
+
+   {
+   int i;
+   int returnval;
+
+   returnval = 0;
+   for( i = 0; i < item_i->amount; i++ )
+      {
+      items[ i ].active = CP_Active;
+      if ( nums[ i ] == check )
+         {
+         item_i->curpos    = i;
+         items[ i ].active = CP_CursorLocation;
+         returnval = i;
+         }
+      }
+
+   return( returnval );
+   }
+
+
+//****************************************************************************
+//
+// MN_MakeActive ()
+//
+//****************************************************************************
+
+void MN_MakeActive
+   (
+   CP_iteminfo *item_i,
+   CP_itemtype *items,
+   int which
+   )
+
+   {
+   int i;
+
+   for( i = 0; i < item_i->amount; i++ )
+      if (i == which)
+      {
+         items[i].active = CP_CursorLocation;
+         item_i->curpos    = i;
+      }
+      else
+         items[i].active = CP_Active;
+}
+
+
+//******************************************************************************
+//
+// DrawMenu ()
+//
+// Purpose - Draws a menu
+//
+//******************************************************************************
+void DrawMenu
+   (
+   CP_iteminfo *item_i,
+   CP_itemtype *items
+   )
+
+   {
+   int i;
+   int active;
+   int color;
+   int posx;
+   int posy;
+
+   posx = item_i->x + item_i->indent;
+   posy = item_i->y;
+   WindowX = posx;
+   WindowY = posy;
+   WindowW = 320;
+   WindowH = 200;
+
+   for ( i = 0; i < item_i->amount; i++ )
+      {
+      posy   = item_i->y + i * FontSize[ item_i->fontsize ];
+      active = items[ i ].active;
+
+      color = -1;
+      switch( active )
+         {
+         case CP_CursorLocation :
+            color = ACTIVECOLOR;
+            break;
+
+         case CP_Inactive :
+            color = NOTAVAILABLECOLOR;
+            break;
+
+         case CP_Active :
+            color = NORMALCOLOR;
+            break;
+
+         case CP_SemiActive :
+            color = DIMMEDCOLOR;
+            break;
+
+         case CP_Highlight :
+            color = HIGHLIGHTCOLOR;
+            break;
+         }
+
+      if ( color != -1 )
+         {
+         if ( item_i->names == NULL )
+            {
+            DrawIMenuBufItem( posx, posy, W_GetNumForName( items[ i ].texture ),
+               color );
+            }
+         else
+            {
+            IFont = ( cfont_t * )W_CacheLumpName( FontNames[ item_i->fontsize ],
+               PU_CACHE, Cvt_cfont_t, 1 );
+            if ( item_i->fontsize == mn_tinyfont )
+               {
+               DrawMenuBufIString( posx + 1, posy, item_i->names[ i ], 0 );
+               }
+            DrawMenuBufIString( posx, posy - 1, item_i->names[ i ], color );
+            }
+         }
+      }
+   }
+
+
+//******************************************************************************
+//
+// getASCII () - Gets info from Keyboard.
+//
+//******************************************************************************
+
+int getASCII ( void )
+{
+   int i;
+   int LS;
+   int RS;
+   int returnvalue = 0;
+   int scancode = 0;
+
+#ifdef DOS
+   _disable ();      // must disable for SHIFT purposes
+#endif
+
+   IN_UpdateKeyboard ();
+
+   LS = Keyboard[sc_LShift];
+   RS = Keyboard[sc_RShift];
+
+   Keyboard[sc_LShift] = Keyboard[sc_RShift] = 0;
+
+   scancode = 0;
+
+   for (i = 0; i < 127; i++)
+      if (Keyboard[i])
+      {
+         scancode = i;
+         break;
+      }
+
+	if (scancode)
+   {
+      if (LS || RS)
+         returnvalue = ShiftNames[scancode];
+      else
+         returnvalue = ASCIINames[scancode];
+   }
+
+   Keyboard[sc_LShift] = LS;
+   Keyboard[sc_RShift] = RS;
+
+#ifdef DOS
+   _enable ();
+#endif
+
+   return (returnvalue);
+}
+
+
+//******************************************************************************
+//
+// ScanForSavedGames ()
+//
+//******************************************************************************
+
+void ScanForSavedGames ()
+{
+   struct find_t f;
+   char filename[256];
+   char str[45];
+   int which;
+   boolean found = false;
+#ifndef DOS
+   char *pathsave;
+#endif
+
+   //
+   // SEE WHICH SAVE GAME FILES ARE AVAILABLE & READ STRING IN
+   //
+   memset (&SaveGamesAvail[0], 0, sizeof (SaveGamesAvail));
+#if PLATFORM_DOS || PLATFORM_WIN32
+   GetPathFromEnvironment( filename, ApogeePath, SaveName );
+#else
+   strncpy (filename, SaveName, 256);
+   pathsave = getcwd (NULL, 0);
+   chdir (ApogeePath);
+#endif
+
+   if (!_dos_findfirst (filename, 0, &f))
+      do
+      {
+         strcpy(str,&f.name[7]);
+         sscanf((const char *)&str[0],"%x",&which);
+
+         if (which < NUMSAVEGAMES)
+         {
+            found = true;
+            SaveGamesAvail[which] = 1;
+            GetSavedMessage (which, &SaveGameNames[which][0]);
+         }
+
+      } while (!_dos_findnext (&f));
+
+      if (found)
+      {
+         if (MainMenu[loadgame].active == CP_Inactive)
+            MainMenu[loadgame].active = CP_Active;
+      }
+      else
+         MainMenu[loadgame].active = CP_Inactive;
+#if ((!PLATFORM_DOS) && (!PLATFORM_WIN32))
+      chdir (pathsave);
+      free (pathsave);
+#endif
+}
+
+
+//******************************************************************************
+//
+// SetUpControlPanel ()
+//
+//******************************************************************************
+
+void SetUpControlPanel (void)
+{
+   int i;
+   int j;
+   byte * b;
+   byte * s;
+
+//   int Xres = 320;//org
+//   int Yres = 200;//org
+   int Xres = 640;
+   int Yres = 400;
+
+   //dont work in 800x600 until we get a better screen schrinker
+  //  int Xres = iGLOBAL_SCREENWIDTH;//640;
+ //  int Yres = iGLOBAL_SCREENHEIGHT;//400;
+
+  Xres = 640;
+   Yres = 400;
+
+
+
+   // Save the current game screen
+
+   //bna--savedscreen = SafeMalloc (16000);
+   savedscreen = SafeMalloc (16000*8);
+
+   // Copy the current save game screen (½ size) to this buffer
+
+   if (RefreshPause==false)
+      {
+      GamePaused=false;
+      ThreeDRefresh();
+      FlipPage();
+      FlipPage();
+      GamePaused=true;
+      }
+
+
+   s=savedscreen;
+
+
+    
+	  if (iGLOBAL_SCREENWIDTH == 320) { 
+		  for (i=0;i<Xres;i+=2)	{	  
+			  b=(byte *)bufferofs+i;
+			  for (j=0;j<100;j++,s++,b+=(iGLOBAL_SCREENWIDTH<<1))
+				 *s=*b;
+		  }
+	  }	  
+	  if (iGLOBAL_SCREENWIDTH >= 640) { 
+		  for (i=0;i<Xres;i+=4)	{		  
+			  b=(byte *)bufferofs+i;//schrink screen to 1/2 size
+			  for (j=0;j<(Yres/4);j++,s++,b+=(iGLOBAL_SCREENWIDTH<<1)*2)
+				 *s=*b;
+			  }
+	  }/*
+      if (iGLOBAL_SCREENWIDTH == 800) { 	 
+		  for (i=0;i<Xres;i+=8)		{	  
+			  b=(byte *)bufferofs+i;//schrink screen to 1/3 size
+			  for (j=0;j<(Yres/8);j++,s++,b+=(iGLOBAL_SCREENWIDTH<<1)*3)
+				 *s=*b;
+		  }
+
+      }*/
+
+   ScanForSavedGames ();
+
+
+
+   if (modemgame == true)
+      {
+      // Make battle mode active
+      //
+      MainMenu[battlemode].active = CP_Active;
+
+      // No save or load game in modem game
+      //
+      MainMenu[newgame].active    = CP_Inactive;
+      MainMenu[backtodemo].active = CP_Inactive;
+      MainMenu[loadgame].active   = CP_Inactive;
+      MainMenu[savegame].active   = CP_Inactive;
+
+      if ( MainMenu[ MainItems.curpos ].active == CP_Inactive )
+         {
+         MainItems.curpos = battlemode;
+         }
+
+      MainMenu[MainItems.curpos].active = CP_CursorLocation;
+
+      if ( consoleplayer != 0 )
+         {
+         MainMenu[battlemode].routine = ( void (*)(int) )BattleGamePlayerSetup;
+         }
+      }
+   }
+
+//******************************************************************************
+//
+// GetMenuInfo ()
+//
+// Gets the user's password
+//
+//******************************************************************************
+
+void GetMenuInfo (void)
+{
+   ConvertPasswordStringToPassword ();
+
+   POK=true;
+   if (pword[0]==0)
+      POK=false;
+}
+
+
+//******************************************************************************
+//
+// WriteMenuInfo ()
+//
+// Writes out password
+//
+//******************************************************************************
+
+void WriteMenuInfo (void)
+{
+   ConvertPasswordToPasswordString ();
+}
+
+//******************************************************************************
+//
+// AllocateSavedScreenPtr ()
+//
+//******************************************************************************
+
+void AllocateSavedScreenPtr (void)
+{
+   // Save the current game screen
+
+   savedscreen = SafeMalloc(16000);
+   inmenu  = true;
+   numdone = 0;
+}
+
+
+//******************************************************************************
+//
+// FreeSavedScreenPtr ()
+//
+//******************************************************************************
+
+void FreeSavedScreenPtr (void)
+{
+   SafeFree (savedscreen);
+   inmenu  = false;
+}
+
+
+//******************************************************************************
+//
+// CleanUpControlPanel ()
+//
+//******************************************************************************
+
+void CleanUpControlPanel (void)
+{
+	int   joyx, joyy;
+
+   if ((playstate==ex_resetgame) || (loadedgame==true))
+      ShutdownClientControls();
+
+   // Free up saved screen image
+
+   FreeSavedScreenPtr ();
+
+   WriteConfig ();
+
+   INL_GetJoyDelta (joystickport, &joyx, &joyy);
+
+   if (mouseenabled)
+      PollMouseMove ();    // Trying to kill movement
+
+   if (cybermanenabled)
+      PollCyberman ();
+
+   RefreshPause = true;
+}
+
+
+//******************************************************************************
+//
+// CP_CheckQuick ()
+//
+//******************************************************************************
+boolean CP_CheckQuick
+   (
+   byte scancode
+   )
+
+   {
+   if (demoplayback==true)
+      {
+      switch ( scancode )
+         {
+         case sc_Escape:
+            inmenu = true;
+            return( true );
+            break;
+         }
+      }
+   else
+      {
+      switch ( scancode )
+         {
+         case sc_Escape:
+         case sc_F1:
+         case sc_F2:
+         case sc_F3:
+         case sc_F4:
+         case sc_F8:
+         case sc_F9:
+         case sc_F10:
+            inmenu = true;
+            return( true );
+            break;
+         }
+      }
+
+   return( false );
+   }
+
+
+//******************************************************************************
+//
+// ControlPanel
+//
+//    ROTT Control Panel!
+//
+//******************************************************************************
+void ControlPanel
+   (
+   byte scancode
+   )
+
+   {
+   if ( scancode == sc_Escape )
+      {
+      CP_MainMenu();
+      if ( ( playstate == ex_stillplaying ) && ( loadedgame == false ) )
+         {
+         fizzlein = true;
+         }
+      return;
+      }
+
+   SetupMenuBuf();
+
+   numdone = 0;
+   StartGame = false;
+ 
+   SetUpControlPanel();
+   EnableScreenStretch();
+   //
+   // F-KEYS FROM WITHIN GAME
+   //
+	switch( scancode )
+      {
+      case sc_F1:
+         CP_F1Help();
+         break;
+
+      case sc_F2:
+         CP_SaveGame();
+         break;
+
+      case sc_F3:
+         CP_LoadGame( 0, 0 );
+         break;
+
+      case sc_F4:
+         CP_ControlMenu();
+         break;
+
+      case sc_F8:
+         LastScan          = 0;
+         Keyboard[ sc_F8 ] = 0;
+         CP_EndGame();
+         break;
+
+      case sc_F9:
+         LastScan          = 0;
+         Keyboard[ sc_F9 ] = 0;
+
+         loadsavesound = true;
+         CP_LoadGame( 1, 0 );
+         break;
+
+      case sc_F10:
+         SetMenuTitle ("Quit");
+
+         LastScan           = 0;
+         Keyboard[ sc_F10 ] = 0;
+         CP_Quit( -1 );
+         break;
+
+      }
+
+   CleanUpControlPanel();
+   ShutdownMenuBuf();
+
+   if ( loadedgame == false )
+      {
+      SetupScreen( false );
+      fizzlein = true;
+      inmenu = false;
+      }
+
+   loadsavesound = false;
+   }
+
+
+//******************************************************************************
+//
+// CP_MainMenu
+//
+//******************************************************************************
+menuitems CP_MainMenu
+   (
+   void
+   )
+
+   {
+   int which;
+
+   SetupMenuBuf();
+
+   numdone = 0;
+
+   SetUpControlPanel();
+
+   DrawMainMenu();
+
+   //
+   // Main menu loop.  "Exit options" or "New game" exits
+   //
+   StartGame = false;
+   EnableScreenStretch();
+
+   while( !StartGame )
+      {
+      StartGame = false;
+
+      IN_ClearKeysDown();
+
+      which = HandleMenu( &MainItems, &MainMenu[ 0 ], NULL );
+
+      switch( which )
+         {
+         case backtodemo:
+            if ( !ingame )
+               {
+               playstate = ex_titles;
+               }
+
+            StartGame = true;
+			DisableScreenStretch();//bna++ shut off streech mode
+            break;
+
+         case -1:
+            CP_Quit( 0 );
+            break;
+
+         default:
+            if ( !StartGame )
+               {
+               DoMainMenu();
+               }
+         }
+      }
+
+   // Deallocate everything
+   CleanUpControlPanel();
+   ShutdownMenuBuf();
+
+   return( which );
+   }
+
+
+//******************************************************************************
+//
+// DrawMainMenu ()
+//
+//******************************************************************************
+
+void DrawMainMenu(void)
+{    
+
+   MenuNum = 1;
+		EnableScreenStretch();//bna++ shut off streech mode
+   //
+   // CHANGE "GAME" AND "DEMO"
+   //
+   if ( ingame )
+      {
+      MainMenu[ backtodemo ].texture[ 6 ] = '1';
+      MainMenu[ backtodemo ].texture[ 7 ] = '1';
+      MainMenu[ backtodemo ].texture[ 8 ] = '\0';
+      strcpy (MainMenuNames[ backtodemo ] , "BACK TO GAME");
+      }
+   else
+      {
+      MainMenu[ backtodemo ].texture[ 6 ] = '8';
+      MainMenu[ backtodemo ].texture[ 7 ] = '\0';
+      strcpy (MainMenuNames[ backtodemo ] , "BACK TO DEMO");
+      }
+
+   MN_GetCursorLocation( &MainItems, &MainMenu[ 0 ] );
+   SetMenuTitle ("Main Menu");
+   DrawMenu (&MainItems, &MainMenu[0]);
+
+	numdone ++;
+   DisplayInfo (0);
+}
+
+
+//******************************************************************************
+//
+// Handle moving triad around a menu
+//
+//******************************************************************************
+
+int HandleMenu (CP_iteminfo *item_i, CP_itemtype *items, void (*routine)(int w))
+{
+
+   char        key;
+   int         i,
+               x,
+               y,
+               basey,
+               exit,
+               numactive,
+               count;
+   int         newpos;
+   volatile int timer;
+   ControlInfo ci;
+   boolean     playsnd = false;
+
+   handlewhich = item_i->curpos;
+   x     = item_i->x;
+   if ((MenuNum == 4) || (MenuNum == 6) ||
+      ( item_i->fontsize == mn_smallfont ) )
+      {
+      basey = item_i->y;
+
+      CursorLump = SmallCursor;
+      yinc = 9;
+      cursorwidth = cursorheight = 8;
+      }
+   else if ( item_i->fontsize == mn_8x8font )
+      {
+      basey = item_i->y - 1;
+
+      CursorLump = SmallCursor;
+		yinc = 7;
+      cursorwidth = cursorheight = 8;
+      }
+   else if ( item_i->fontsize == mn_tinyfont )
+      {
+      basey = item_i->y - 2;
+
+      CursorLump = SmallCursor;
+		yinc = 6;
+      cursorwidth = cursorheight = 8;
+      }
+   else
+      {
+      basey = item_i->y-2;
+
+      CursorLump = LargeCursor;
+		yinc = 14;
+      cursorwidth = cursorheight = 16;
+      }
+
+
+   if (MenuNum)
+      y = basey + handlewhich*yinc;
+   else
+      y = CUSTOM_y[handlewhich];
+
+
+   if (MenuNum != 5)
+      DrawMenuBufItem (x, y, W_GetNumForName( CursorLump ) +
+         CursorFrame[ CursorNum ] );
+
+   if (routine)
+      routine (handlewhich);
+
+   count    = 2;
+   exit     = 0;
+   timer    = GetTicCount();
+   IN_ClearKeysDown ();
+
+   numactive = GetNumActive (item_i, items);
+
+   do
+   {
+      ReadAnyControl (&ci);
+      RefreshMenuBuf (0);
+     // Change Cursor Shape
+      if ((GetTicCount() > (timer+count)) && (MenuNum != 5))
+      {
+         timer = GetTicCount();
+
+         CursorNum++;
+         if (CursorNum > (MAXCURSORNUM-1))
+            CursorNum = 0;
+
+         EraseMenuBufRegion(x, y, cursorwidth, cursorheight);
+         DrawMenuBufItem (x, y, W_GetNumForName( CursorLump ) +
+            CursorFrame[ CursorNum ] );
+
+      }
+
+     // Initial char - pass 1
+      key = getASCII ();
+      if (key)
+      {
+         int ok = 0;
+
+         key = toupper (key);
+
+         for (i = (handlewhich + 1); i < item_i->amount; i++)
+            if ((items+i)->active && (items+i)->letter == key)
+            {
+               HideCursor (item_i, items, x, y, handlewhich);
+               MN_PlayMenuSnd (SD_MOVECURSORSND);
+               handlewhich = i;
+
+
+               if (routine)
+                  routine (handlewhich);
+
+               ShowCursor (item_i, items, x, &y, handlewhich, basey);
+               ok = 1;
+               IN_ClearKeysDown();
+               break;
+            }
+
+        // Initial char - pass 2
+         if (!ok)
+         {
+            for (i = 0; i < handlewhich; i++)
+               if ((items+i)->active && (items+i)->letter == key)
+               {
+                  HideCursor (item_i, items, x, y, handlewhich);
+                  MN_PlayMenuSnd (SD_MOVECURSORSND);
+                  handlewhich = i;
+
+
+                  if (routine)
+                     routine (handlewhich);
+
+                  ShowCursor (item_i, items, x,& y, handlewhich, basey);
+                  IN_ClearKeysDown ();
+                  break;
+               }
+         }
+      }
+
+      ReadAnyControl (&ci);
+
+      if (numactive > 1)
+		{
+         switch (ci.dir)
+         {
+            case dir_North:
+               HideCursor (item_i, items, x, y, handlewhich);
+
+
+               CursorNum++;
+               if (CursorNum > (MAXCURSORNUM-1))
+                  CursorNum = 0;
+
+
+              // Do a half step if possible
+               if ((handlewhich) &&
+                  (((items+handlewhich-1)->active == CP_CursorLocation) ||
+                  ((items+handlewhich-1)->active == CP_Active)))
+               {
+                  y -= 6;
+                  DrawHalfStep (x, y);
+                  playsnd = false;
+
+                  RefreshMenuBuf (0);
+
+                  CursorNum++;
+                  if (CursorNum > (MAXCURSORNUM-1))
+                     CursorNum = 0;
+               }
+               else
+               {
+                  playsnd = true;
+                  RefreshMenuBuf (0);
+               }
+
+               do
+               {
+                  if (!handlewhich)
+                     handlewhich = item_i->amount-1;
+                  else
+                     handlewhich--;
+               } while (((items+handlewhich)->active == CP_Inactive) || ((items+handlewhich)->active == CP_Active3));
+
+               if (playsnd)
+                  MN_PlayMenuSnd (SD_MOVECURSORSND);
+					ShowCursor (item_i, items, x, &y, handlewhich, basey);
+
+               if (routine)
+                  routine (handlewhich);
+
+               RefreshMenuBuf(0);
+            break;
+
+            case dir_South:
+               HideCursor (item_i, items, x, y, handlewhich);
+
+               CursorNum++;
+               if (CursorNum > (MAXCURSORNUM-1))
+                  CursorNum = 0;
+
+               // Do a half step if possible
+               if ((handlewhich != item_i->amount-1) &&
+                  (((items+handlewhich+1)->active == CP_CursorLocation) ||
+                  ((items+handlewhich+1)->active == CP_Active)))
+               {
+                  y += 6;
+                  DrawHalfStep(x,y);
+                  playsnd = false;
+
+                  RefreshMenuBuf (0);
+
+                  CursorNum++;
+                  if (CursorNum > (MAXCURSORNUM-1))
+                     CursorNum = 0;
+               }
+               else
+               {
+                  playsnd = true;
+                  RefreshMenuBuf (0);
+               }
+
+               do
+               {
+                  if (handlewhich==item_i->amount-1)
+                     handlewhich=0;
+                  else
+                     handlewhich++;
+               } while (((items+handlewhich)->active == CP_Inactive) || ((items+handlewhich)->active == CP_Active3));
+
+               if (playsnd)
+                  MN_PlayMenuSnd (SD_MOVECURSORSND);
+               ShowCursor(item_i,items,x,&y,handlewhich,basey);
+
+               if (routine)
+                  routine (handlewhich);
+
+               RefreshMenuBuf (0);
+            break;
+	 default:
+	     ;
+         }
+      }
+
+      ReadAnyControl (&ci);
+      if (ci.button0 || Keyboard[sc_Space] || Keyboard[sc_Enter])
+      {
+         exit = 1;
+         WaitKeyUp ();
+         MN_PlayMenuSnd (SD_SELECTSND);
+      }
+
+      if (ci.button1 || Keyboard[sc_Escape])
+      {
+         WaitKeyUp ();
+         exit = 2;
+      }
+
+      if ( ( Keyboard[ sc_Home ] ) && ( numactive > 1 ) )
+         {
+         newpos = 0;
+         while( ( items[ newpos ].active == CP_Inactive ) ||
+            ( items[ newpos ].active == CP_Active3 ) )
+            {
+            newpos++;
+            }
+
+         if ( newpos != handlewhich )
+            {
+            HideCursor( item_i, items, x, y, handlewhich );
+
+            CursorNum++;
+            if ( CursorNum > ( MAXCURSORNUM - 1 ) )
+               {
+               CursorNum = 0;
+               }
+
+            RefreshMenuBuf( 0 );
+
+            handlewhich = newpos;
+
+            MN_PlayMenuSnd( SD_MOVECURSORSND );
+
+            ShowCursor( item_i, items, x, &y, handlewhich, basey );
+
+            if ( routine )
+               {
+               routine( handlewhich );
+               }
+
+            RefreshMenuBuf( 0 );
+            }
+         }
+      else if ( ( Keyboard[ sc_End ] ) && ( numactive > 1 ) )
+         {
+         newpos = item_i->amount - 1;
+         while( ( items[ newpos ].active == CP_Inactive ) ||
+            ( items[ newpos ].active == CP_Active3 ) )
+            {
+            newpos--;
+            }
+
+         if ( newpos != handlewhich )
+            {
+            HideCursor( item_i, items, x, y, handlewhich );
+
+            CursorNum++;
+            if ( CursorNum > ( MAXCURSORNUM - 1 ) )
+               {
+               CursorNum = 0;
+               }
+
+            RefreshMenuBuf( 0 );
+
+            handlewhich = newpos;
+
+            MN_PlayMenuSnd( SD_MOVECURSORSND );
+
+            ShowCursor( item_i, items, x, &y, handlewhich, basey );
+
+            if ( routine )
+               {
+               routine( handlewhich );
+               }
+
+            RefreshMenuBuf( 0 );
+            }
+         }
+
+      // Page Up/Down
+      if ( MenuNum == 11 )
+         {
+         if ( ( Keyboard[ sc_PgUp ] ) &&
+            ( ( items + 1 )->active != CP_Inactive ) )
+            {
+            item_i->curpos = handlewhich;
+            handlewhich = PAGEUP;
+            exit = 3;
+            MN_PlayMenuSnd( SD_SELECTSND );
+            }
+         else if ( ( Keyboard[ sc_PgDn ] ) &&
+            ( ( items + 0 )->active != CP_Inactive ) )
+            {
+            item_i->curpos = handlewhich;
+            handlewhich = PAGEDOWN;
+            exit = 3;
+            MN_PlayMenuSnd( SD_SELECTSND );
+            }
+         }
+
+      // Delete save games
+      if ((MenuNum == 4) || (MenuNum == 6))
+      {
+         if (Keyboard[sc_Delete] && SaveGamesAvail[handlewhich])
+         {
+            if (CP_DisplayMsg ("Delete saved game?\nAre you sure?", 12) == true)
+            {
+               char loadname[45] = "rottgam0.rot";
+               char filename[128];
+
+               // Create the proper file name
+               itoa (handlewhich, &loadname[7], 16);
+               loadname[8]='.';
+
+               GetPathFromEnvironment( filename, ApogeePath, loadname );
+
+               // Delete the file
+
+					unlink (filename);
+
+               memset (&SaveGameNames[handlewhich][0], 0, 32);
+               SaveGamesAvail[handlewhich] = 0;
+               if (handlewhich==quicksaveslot)
+                  quicksaveslot=-1;
+
+               PrintX = LSM_X+LSItems.indent+2;
+               PrintY = LSM_Y+handlewhich*9+2;
+            }
+            ScanForSavedGames ();
+
+            LSItems.curpos = handlewhich;
+            if (MenuNum == 4)
+               DrawLoadSaveScreenAlt (1);
+            else
+               DrawLoadSaveScreenAlt (0);
+            CP_DrawSelectedGame (handlewhich);
+         }
+      }
+
+
+#if SAVE_SCREEN
+      if (Keyboard[sc_CapsLock] && Keyboard[sc_C])
+      {
+         inhmenu=true;
+         SaveScreen (true);
+         inhmenu=false;
+      }
+      else
+         if (Keyboard[sc_CapsLock] && Keyboard[sc_X])
+         {
+            inhmenu=true;
+            SaveScreen (false);
+            inhmenu=false;
+         }
+         else
+            if (Keyboard[sc_CapsLock] && Keyboard[sc_Q])
+               Error ("Insta-Menu Quit!\n");
+#endif
+
+   } while (!exit);
+
+
+   IN_ClearKeysDown();
+
+   if (routine)
+      routine (handlewhich);
+
+   if ( exit != 3 )
+      {
+      item_i->curpos = handlewhich;
+      }
+
+   if (MenuNum == 3)
+   {
+      if (exit != 2)
+         CSTactive = handlewhich;
+      else
+         CSTactive = -1;
+   }
+
+   switch (exit)
+   {
+      case 1:
+         if ((items+handlewhich)->routine!=NULL)
+            (items+handlewhich)->routine(0);
+         return (handlewhich);
+
+      case 2:
+         MN_PlayMenuSnd (SD_ESCPRESSEDSND);
+         return (-1);
+
+      case 3:
+         return( handlewhich );
+   }
+
+
+   return (0);
+}
+
+//******************************************************************************
+//
+// HideCursor
+//
+//******************************************************************************
+void HideCursor
+   (
+   CP_iteminfo *item_i,
+   CP_itemtype *items,
+   int x,
+   int y,
+   int which
+   )
+
+   {
+   int time = GetTicCount();
+   int color;
+   int delay;
+   int posx;
+   int posy;
+
+   if ( MenuNum != 5 )
+      {
+		EraseMenuBufRegion( x, y, cursorwidth, cursorheight );
+      }
+
+   if ( MenuNum && ( MenuNum != 4 ) && ( MenuNum != 6 ) )
+      {
+      posx = item_i->x + item_i->indent;
+      posy = item_i->y + ( which * yinc );
+
+      color = -1;
+      switch( items[ which ].active )
+         {
+         case CP_Inactive :
+            color = NOTAVAILABLECOLOR;
+            break;
+
+         case CP_CursorLocation :
+         case CP_Active :
+            color = NORMALCOLOR;
+            break;
+
+         case CP_SemiActive :
+            color = DIMMEDCOLOR;
+            break;
+
+         case CP_Highlight :
+            color = HIGHLIGHTCOLOR;
+            break;
+         }
+
+      if ( color != -1 )
+         {
+         if ( item_i->names == NULL )
+            {
+            DrawIMenuBufItem( posx, posy,
+               W_GetNumForName( items[ which ].texture ), color );
+            }
+         else
+            {
+            IFont = ( cfont_t * )W_CacheLumpName( FontNames[ item_i->fontsize ],
+               PU_CACHE, Cvt_cfont_t, 1 );
+            if ( item_i->fontsize == mn_tinyfont )
+               {
+               DrawMenuBufIString( posx + 1, posy, item_i->names[ which ], 0 );
+               }
+            DrawMenuBufIString( posx, posy - 1, item_i->names[ which ],
+               color );
+            }
+         }
+      }
+
+   if ( ( items[ which ].active != CP_Inactive ) &&
+      ( items[ which ].active != CP_SemiActive ) )
+      {
+      items[ which ].active = CP_Active;
+      }
+
+   delay = DELAYAMT - tics;
+   while( ( time + delay ) > GetTicCount() )
+      {
+      RefreshMenuBuf (0);
+      }
+   }
+
+
+//******************************************************************************
+//
+// DrawHalfStep
+//
+//******************************************************************************
+
+void DrawHalfStep (int x, int y)
+{
+   MN_PlayMenuSnd (SD_MOVECURSORSND);
+   if (MenuNum == 5)
+      return;
+
+   DrawMenuBufItem (x, y, W_GetNumForName( CursorLump ) +
+      CursorFrame[ CursorNum ] );
+}
+
+
+//******************************************************************************
+//
+// GetNumActive ()
+//
+//******************************************************************************
+
+int GetNumActive (CP_iteminfo *item_i, CP_itemtype *items)
+{
+   int cnt;
+   int num = 0;
+
+   for (cnt = 0; cnt < item_i->amount; cnt ++)
+   {
+      if ((items+cnt)->active != CP_Inactive)
+         num++;
+   }
+
+   return (num);
+}
+
+
+//******************************************************************************
+//
+// ShowCursor
+//    Draw triad at new position.
+//
+//******************************************************************************
+void ShowCursor
+   (
+   CP_iteminfo *item_i,
+   CP_itemtype *items,
+   int x,
+   int *y,
+   int which,
+   int basey
+   )
+
+   {
+   int time = GetTicCount();
+   int delay;
+   int posx;
+   int posy;
+
+   if ( MenuNum )
+      {
+      EraseMenuBufRegion( x, *y, cursorwidth, cursorheight );
+      *y = basey + which * yinc;
+      }
+   else
+      {
+      *y = CUSTOM_y[ which ];
+      }
+
+   if ( MenuNum != 5 )
+      {
+      DrawMenuBufItem( x, *y, W_GetNumForName( CursorLump ) +
+         CursorFrame[ CursorNum ] );
+      }
+
+   if ( items[ which ].active != CP_SemiActive )
+      {
+      if ( MenuNum && ( MenuNum != 4 ) && ( MenuNum != 6 ) )
+         {
+         posx = item_i->x + item_i->indent;
+         posy = item_i->y + which * yinc;
+
+         if ( item_i->names == NULL )
+            {
+            DrawIMenuBufItem( posx, posy,
+               W_GetNumForName( items[ which ].texture ), ACTIVECOLOR);
+            }
+         else
+            {
+            IFont = ( cfont_t * )W_CacheLumpName( FontNames[ item_i->fontsize ],
+               PU_CACHE, Cvt_cfont_t, 1 );
+            if ( item_i->fontsize == mn_tinyfont )
+               {
+               DrawMenuBufIString( posx + 1, posy, item_i->names[ which ], 0 );
+               }
+            DrawMenuBufIString( posx, posy - 1, item_i->names[ which ],
+               ACTIVECOLOR );
+            }
+         }
+
+      items[ which ].active = CP_CursorLocation;
+      }
+
+   delay = DELAYAMT - tics;
+   while( ( time + delay ) > GetTicCount() )
+      {
+      RefreshMenuBuf( 0 );
+      }
+   }
+
+//******************************************************************************
+//
+// DrawOrderInfo()
+//
+//******************************************************************************
+
+void DrawOrderInfo
+   (
+   int which
+   )
+
+   {
+   int start;
+   char *lumpname;
+
+   start = W_GetNumForName( "ORDRSTRT" ) + 1;
+
+   lumpname = W_GetNameForNum( start + which );
+
+   // Screen shots are grabbed as pics
+   if ( lumpname[ 0 ] == 'S' )
+      {
+      VWB_DrawPic( 0, 0, ( pic_t * )W_CacheLumpNum( start + which, PU_CACHE, Cvt_pic_t, 1 ) );
+      }
+   else
+      {
+      VL_DrawPostPic( W_GetNumForName( "trilogo" ) );
+      DrawNormalSprite( 0, 0, start );
+      DrawNormalSprite( 0, 0, start + which );
+      }
+
+   VW_UpdateScreen();
+   }
+
+
+//******************************************************************************
+//
+// CP_OrderInfo()
+//
+//******************************************************************************
+
+void CP_OrderInfo
+   (
+   void
+   )
+
+   {
+   int maxpage;
+   int page;
+   int key;
+   boolean newpage;
+
+
+
+   maxpage = W_GetNumForName( "ORDRSTOP" ) - W_GetNumForName( "ORDRSTRT" ) - 2;
+   newpage = false;
+   page = 1;
+
+   do
+      {
+	  EnableScreenStretch();//bna++
+      DrawOrderInfo( page );
+	  DisableScreenStretch();//bna++ turn off or screen will be strected every time it passes VW_UpdateScreen
+      if ( newpage )
+         {
+         while( Keyboard[ key ] )
+            {
+            VW_UpdateScreen();
+            IN_UpdateKeyboard ();
+            }
+         }
+
+      LastScan=0;
+      while( LastScan == 0 )
+         {
+         VW_UpdateScreen();
+         IN_UpdateKeyboard ();
+         }
+
+      key = LastScan;
+      switch( key )
+         {
+         case sc_Home :
+            if ( page != 1 )
+               {
+               page = 1;
+               newpage = true;
+               MN_PlayMenuSnd( SD_MOVECURSORSND );
+               }
+            break;
+
+         case sc_End :
+            if ( page != maxpage )
+               {
+               page = maxpage;
+               newpage = true;
+               MN_PlayMenuSnd( SD_MOVECURSORSND );
+               }
+            break;
+
+         case sc_PgUp :
+         case sc_UpArrow :
+         case sc_LeftArrow :
+            if ( page > 1 )
+               {
+               page--;
+               newpage = true;
+               MN_PlayMenuSnd( SD_MOVECURSORSND );
+               }
+            break;
+
+         case sc_PgDn :
+         case sc_DownArrow :
+         case sc_RightArrow :
+            if ( page < maxpage )
+               {
+               page++;
+               newpage = true;
+               MN_PlayMenuSnd( SD_MOVECURSORSND );
+               }
+            break;
+         }
+      }
+   while( key != sc_Escape );
+
+   Keyboard[ key ] = 0;
+   LastScan = 0;
+ EnableScreenStretch();//bna++
+   MN_PlayMenuSnd( SD_ESCPRESSEDSND );
+   }
+
+
+//******************************************************************************
+//
+// CP_ViewScores ()
+//
+//******************************************************************************
+
+void CP_ViewScores (void)
+{
+   CheckHighScore (0, 0, true);
+}
+
+
+//******************************************************************************
+//
+// CP_Quit () - QUIT THIS INFERNAL GAME!
+//
+//******************************************************************************
+void CP_Quit ( int which )
+{
+   int num = 100;
+   static int oldnum;
+
+   while ((num >= 7) || (oldnum == num))
+      num = (RandomNumber ("CP_QUIT", 0) & 7);
+
+   oldnum = num;
+
+   if (CP_DisplayMsg (endStrings[num], num))
+   {
+      int handle;
+
+      MU_FadeOut(310);
+      handle=SD_Play(SD_QUIT1SND+num);
+      VL_FadeOut (0, 255, 0, 0, 0, 10);
+      CleanUpControlPanel();
+      SD_WaitSound (handle);
+      QuitGame ();
+   }
+
+   if ( which != -1 )
+      {
+      ClearMenuBuf();
+      DrawMainMenu();
+      DrawMenuBufItem (MainItems.x,  ((MainItems.curpos*14)+(MainItems.y-2)),
+         W_GetNumForName ( LargeCursor ) + CursorFrame[ CursorNum ] );
+      RefreshMenuBuf (0);
+      }
+}
+
+//******************************************************************************
+//
+// CP_DisplayMsg ()
+//
+//******************************************************************************
+
+boolean CP_DisplayMsg
+   (
+   char *s,
+   int number
+   )
+
+   {
+#define Q_W    184
+#define Q_H    72
+#define Q_X    ((320-Q_W)/2)-18
+#define Q_Y    ((200-Q_H)/2)-33
+
+#define Q_b1X  (Q_X+85)
+#define Q_b2X  (Q_X+135)
+#define Q_bY   (Q_Y+45)
+#define Q_bW   33
+#define Q_bH   10
+
+#define W_X    72
+#define W_Y    11
+#define W_W    102
+
+#define YES    "q_yes\0"
+#define NO     "q_no\0"
+
+   ControlInfo ci;
+   boolean retval;
+   boolean done;
+   boolean YESON;
+   boolean redraw;
+   boolean blowout;
+   char   *temp;
+   char   *active;
+   char   *inactive;
+   int     activex;
+   int     inactivex;
+   int     W_H = 0;
+   int     L_Y = 0;
+   int     tri;
+   int     QUITPIC;
+   int     t;
+
+   W_H = 1;
+   retval  = false;
+   done    = false;
+   YESON   = true;
+   redraw  = false;
+   blowout = false;
+
+   IN_ClearKeysDown();
+   IN_IgnoreMouseButtons();
+
+
+   QUITPIC = W_GetNumForName( "quitpic" );
+
+   if ( number < 11 )
+      {
+      tri = W_GetNumForName( "QUIT01" ) + number;
+      MN_PlayMenuSnd( SD_WARNINGBOXSND );
+      }
+   else
+      {
+      if ( number == 11 )
+         {
+         tri = W_GetNumForName( "tri1pic" );
+         MN_PlayMenuSnd( SD_INFOBOXSND );
+         }
+      else
+         {
+         if ( number == 12 )
+            {
+            tri = W_GetNumForName( "tri2pic" );
+            MN_PlayMenuSnd( SD_QUESTIONBOXSND );
+            }
+         if ( number == 13 )
+            {
+            tri = W_GetNumForName( "tri1pic" );
+            MN_PlayMenuSnd( SD_WARNINGBOXSND );
+            }
+         }
+      }
+
+   DrawMenuBufPic( Q_X, Q_Y, QUITPIC );
+   DrawMenuBufPic( Q_X + 12, Q_Y + 11, tri );
+
+   temp = s;
+   while( *temp )
+      {
+      if ( *temp == '\n' )
+         {
+         W_H++;
+         }
+      temp++;
+      }
+
+   CurrentFont = tinyfont;
+   W_H = ( W_H * CurrentFont->height ) + 3;
+
+   WindowX = Q_X + W_X;
+   WindowY = L_Y + 2;
+   L_Y     = Q_Y + W_Y;
+   PrintX  = WindowX;
+   PrintY  = WindowY;
+
+   WindowW = W_W;
+   WindowH = W_H;
+
+   redraw = true;
+
+   IFont = ( cfont_t * )W_CacheLumpName( FontNames[ mn_smallfont ],
+      PU_CACHE, Cvt_cfont_t, 1 );
+/*
+   DrawSTMenuBuf( WindowX, L_Y, W_W, W_H, false );
+   MenuBufCPrint( s );
+
+   DrawSTMenuBuf( Q_b1X, Q_bY, Q_bW, Q_bH, false );
+   DrawMenuBufIString( Q_b1X + 3, Q_Y + 46, "YES", NORMALCOLOR );
+//   DrawIMenuBufItem (PrintX, PrintY, W_GetNumForName (YES), NORMALCOLOR);
+
+   DrawSTMenuBuf( Q_b2X, Q_bY, Q_bW, Q_bH, true );
+   DrawMenuBufIString( Q_b2X + 2, Q_Y + 45, "NO", ACTIVECOLOR );
+//   DrawIMenuBufItem (PrintX, PrintY, W_GetNumForName (NO), ACTIVECOLOR);
+*/
+   if (number != 13)
+   {
+   while ( !done )
+      {
+      RefreshMenuBuf( 0 );
+
+      ReadAnyControl( &ci );
+
+      if ( ( ci.dir == dir_West ) && ( !YESON ) )
+         {
+         MN_PlayMenuSnd( SD_MOVECURSORSND );
+         YESON = 1;
+         redraw = true;
+         }
+      else if ( ( ci.dir == dir_East ) && ( YESON ) )
+         {
+         MN_PlayMenuSnd( SD_MOVECURSORSND );
+         YESON = 0;
+         redraw = true;
+         }
+
+      if ( Keyboard[ sc_Y ] )
+         {
+         YESON  = 1;
+         redraw = true;
+         Keyboard[ sc_Enter ] = true;
+         blowout = true;
+         }
+      else if ( Keyboard[ sc_N ] )
+         {
+         YESON  = 0;
+         redraw = true;
+         Keyboard[ sc_Enter ] = true;
+         blowout = true;
+         }
+
+      if ( redraw )
+         {
+         redraw = false;
+
+         DrawMenuBufPic( Q_X, Q_Y, QUITPIC );
+         DrawMenuBufPic( Q_X + 12, Q_Y + 11, tri );
+
+         PrintX = Q_X + W_X;
+         PrintY = Q_Y + W_Y + 2;
+         DrawSTMenuBuf( WindowX, L_Y, W_W, W_H, false );
+         CurrentFont = tinyfont;
+         MenuBufCPrint( s );
+
+         if ( YESON )
+            {
+            active    = "YES";
+            inactive  = "NO";
+            activex   = Q_b1X;
+            inactivex = Q_b2X;
+            }
+         else
+            {
+            active    = "NO";
+            inactive  = "YES";
+            activex   = Q_b2X;
+            inactivex = Q_b1X;
+            }
+
+         DrawSTMenuBuf( activex, Q_bY, Q_bW, Q_bH, false );
+         DrawMenuBufIString( activex + 3, Q_Y + 46, active, ACTIVECOLOR );
+//         DrawIMenuBufItem (PrintX, PrintY, W_GetNumForName (YES), NORMALCOLOR);
+
+         DrawSTMenuBuf( inactivex, Q_bY, Q_bW, Q_bH, true );
+         DrawMenuBufIString( inactivex + 2, Q_Y + 45, inactive, NORMALCOLOR );
+//         DrawIMenuBufItem (PrintX, PrintY, W_GetNumForName (NO), ACTIVECOLOR);
+
+         for( t = 0; t < 5; t++ )
+            {
+            RefreshMenuBuf( 0 );
+            }
+         }
+
+      if ( ( Keyboard[ sc_Space ] || Keyboard[ sc_Enter ] ||
+         ci.button0 ) && YESON )
+         {
+         done   = true;
+         retval = true;
+         MN_PlayMenuSnd( SD_SELECTSND );
+         CP_Acknowledge = CP_YES;
+         }
+      else if ( Keyboard[ sc_Escape ] || ci.button1 )
+         {
+         done   = true;
+         retval = false;
+         CP_Acknowledge = CP_ESC;
+         MN_PlayMenuSnd( SD_ESCPRESSEDSND );
+         }
+      else if ( ( Keyboard[ sc_Space ] || Keyboard[ sc_Enter ] ||
+         ci.button0 ) && !YESON )
+         {
+         done   = true;
+         retval = false;
+         CP_Acknowledge = CP_NO;
+
+         if ( Keyboard[ sc_N ] )
+            {
+            MN_PlayMenuSnd( SD_SELECTSND );
+            }
+         else
+            {
+            MN_PlayMenuSnd( SD_ESCPRESSEDSND );
+            }
+         }
+      }
+
+   while( ( Keyboard[ sc_Enter ] || Keyboard[ sc_Space ] ||
+      Keyboard[ sc_Escape ] ) && !blowout )
+      {
+      IN_UpdateKeyboard();
+      RefreshMenuBuf( 0 );
+      }
+   }
+   else
+   {
+      PrintX = Q_X + W_X;
+      PrintY = Q_Y + W_Y + 2;
+      DrawSTMenuBuf( WindowX, L_Y, W_W, W_H, false );
+      CurrentFont = tinyfont;
+      MenuBufCPrint( s );
+      LastScan=0;
+      while (LastScan == 0)
+         {
+         IN_UpdateKeyboard();
+         RefreshMenuBuf( 0 );
+         }
+      LastScan = 0;
+   }
+   IN_ClearKeysDown();
+   return( retval );
+   }
+
+
+//******************************************************************************
+//
+// EndGameStuff ()
+//
+//******************************************************************************
+
+void EndGameStuff (void)
+{
+   Z_FreeTags( PU_LEVELSTRUCT, PU_LEVELEND );
+
+	pickquick = false;
+   CheckHighScore (gamestate.score, gamestate.mapon+1, true);
+   locplayerstate->lives = 0;
+   playstate = ex_died;
+   damagecount = 0;
+   SetBorderColor (0);
+
+   AdjustMenuStruct ();
+   ingame = false;
+
+   GamePaused  = false;
+}
+
+
+//******************************************************************************
+//
+// START A NEW GAME
+//
+//******************************************************************************
+
+#define CURGAME   "You are currently in\n"\
+      "a game. Continuing will\n"\
+      "erase old game. Ok?\0"
+
+int ToughMenuNum;
+
+void CP_NewGame
+   (
+   void
+   )
+
+   {
+   int which;
+
+#if ( SHAREWARE == 1 )
+   ToughMenuNum = 0;
+#else
+   int temp;
+
+   temp = ToughMenuNum;
+
+   while( ToughMenuNum == temp )
+      {
+		temp = ( ( RandomNumber( "TOUGH MENU", 0 ) ) & 3 );
+      if ( temp == 3 )
+         {
+         temp = 1;
+         }
+      }
+
+   ToughMenuNum = temp;
+#endif
+
+   //
+   // ALREADY IN A GAME?
+   //
+   if ( ingame )
+      {
+      if ( !CP_DisplayMsg( CURGAME, 12 ) )
+         {
+         return;
+         }
+      else
+         {
+         EndGameStuff();
+         }
+      }
+   else
+      {
+      handlewhich = 100;
+      }
+
+	if ( CP_PlayerSelection() == 0 )
+      {
+		return;
+      }
+
+   TufMenu[ ToughMenuNum ][ 0 ].active = CP_Active;
+   TufMenu[ ToughMenuNum ][ 2 ].active = CP_Active;
+   TufMenu[ ToughMenuNum ][ 4 ].active = CP_Active;
+   TufMenu[ ToughMenuNum ][ 6 ].active = CP_Active;
+
+   switch( DefaultDifficulty )
+      {
+      case gd_baby :
+         TufItems.curpos = 0;
+         break;
+
+      case gd_easy :
+         TufItems.curpos = 2;
+         break;
+
+      case gd_medium :
+         TufItems.curpos = 4;
+         break;
+
+      case gd_hard :
+         TufItems.curpos = 6;
+         break;
+
+      default :
+         TufItems.curpos = 0;
+         break;
+      }
+
+   TufMenu[ ToughMenuNum ][ TufItems.curpos ].active = CP_CursorLocation;
+
+   DrawNewGame();
+
+   which = HandleMenu( &TufItems, &TufMenu[ ToughMenuNum ][ 0 ],
+      DrawNewGameDiff );
+
+   if ( which < 0 )
+      {
+      handlewhich = 1;
+      return;
+      }
+
+   handlewhich = 0;
+
+   switch( which )
+      {
+      case 0 :
+         DefaultDifficulty = gd_baby;
+         break;
+
+      case 2 :
+         DefaultDifficulty = gd_easy;
+         break;
+
+      case 4 :
+         DefaultDifficulty = gd_medium;
+         break;
+
+      case 6 :
+         DefaultDifficulty = gd_hard;
+         break;
+      }
+
+   MainMenu[ savegame ].active = CP_Active;
+
+   gamestate.battlemode = battle_StandAloneGame;
+   StartGame = true;
+   DisableScreenStretch();
+   playstate = ex_resetgame;
+
+
+   }
+
+//******************************************************************************
+//
+// CP_EndGame ()
+//
+//******************************************************************************
+
+#define ENDGAMESTR   "Are you sure you want\n"\
+               "to end the game you\n"\
+               "are playing? (Y or N):"
+
+void CP_EndGame
+   (
+   void
+   )
+
+   {
+   boolean action;
+
+   SetMenuTitle( "End Game" );
+   action = CP_DisplayMsg( ENDGAMESTR, 12 );
+
+   StartGame = false;
+   EnableScreenStretch();
+   if ( action )
+      {
+      EndGameStuff ();
+      pickquick = false;
+      }
+   }
+
+//******************************************************************************
+//
+// AdjustMenuStruct ()
+//
+//******************************************************************************
+void AdjustMenuStruct
+   (
+   void
+   )
+
+   {
+   MainMenu[ savegame ].active         = CP_Inactive;
+   MainMenu[ viewscores ].routine      = ( void * )CP_ViewScores;
+   MainMenu[ viewscores ].texture[ 6 ] = '7';
+   MainMenu[ viewscores ].texture[ 7 ] = '\0';
+   MainMenu[ viewscores ].letter       = 'V';
+   strcpy (MainMenuNames[ viewscores ] , "VIEW SCORES");
+   }
+
+//******************************************************************************
+//
+// CP_DrawSelectedGame
+//
+//******************************************************************************
+
+void CP_DrawSelectedGame (int w)
+{
+   gamestorage_t game;
+
+   if (SaveGamesAvail[w])
+      {
+      GetSavedHeader(w,&game);
+
+      DrawStoredGame(&game.picture[0],game.episode,game.area);
+      }
+   else
+      EraseMenuBufRegion(SaveGamePicX,SaveGamePicY,160,124);
+}
+
+//******************************************************************************
+//
+// DrawStoredGame
+//
+//******************************************************************************
+
+void DrawStoredGame ( byte * pic, int episode, int area )
+{
+   char str[3];
+   int level;
+   byte *shape;
+
+	shape = W_CacheLumpNum (W_GetNumForName ("newfnt1"), PU_CACHE, Cvt_font_t, 1);
+	newfont1 = (font_t *)shape;
+   CurrentFont = newfont1;
+   EraseMenuBufRegion (74, 128, 85, 14);
+
+	DrawMenuBufPropString (74, 128, "E");
+
+   itoa (episode, str, 10);
+   DrawMenuBufPropString (87, 128, str);
+
+   DrawMenuBufPropString (103, 128, "A");
+
+   if (episode > 1)
+      level = (area+1) - ((episode-1) << 3);
+   else
+      level = area+1;
+
+   ltoa (level, str, 10);
+   DrawMenuBufPropString (117, 128, str);
+   CurrentFont = tinyfont;
+
+   DrawMenuBufPicture(SaveGamePicX,SaveGamePicY,pic,160,100);
+}
+
+
+
+//******************************************************************************
+//
+// DoLoad ()
+//
+//******************************************************************************
+
+int DoLoad (int which)
+{
+   gamestorage_t game;
+   int exit = 0;
+
+   if ((which >= 0) && SaveGamesAvail[which])
+   {
+      loadedgame = true;
+
+      if (loadsavesound)
+         MN_PlayMenuSnd (SD_SELECTSND);
+
+      if (LoadTheGame (which, &game) == true)
+      {
+         MenuFixup ();
+		 DisableScreenStretch();
+         StartGame = true;
+			exit      = 1;
+      }
+      else
+      {
+         if (CP_DisplayMsg ("Saved Game is\n old or incompatible\nDelete it?", 12)==true)
+         {
+            char loadname[45] = "rottgam0.rot";
+            char filename[128];
+
+            // Create the proper file name
+            itoa (which, &loadname[7], 16);
+            loadname[8]='.';
+
+            GetPathFromEnvironment( filename, ApogeePath, loadname );
+
+            // Delete the file
+
+            unlink (filename);
+
+            memset (&SaveGameNames[which][0], 0, 32);
+            SaveGamesAvail[which] = 0;
+         }
+
+         loadedgame = false;
+         DrawLoadSaveScreenAlt (0);
+      }
+   }
+
+   return (exit);
+}
+
+
+//******************************************************************************
+//
+// LOAD SAVED GAMES
+//
+//******************************************************************************
+
+int CP_LoadGame (int quick, int dieload)
+{
+   int which,
+       exit = 0;
+
+
+	MenuNum = 6;
+
+   SaveTime = GetTicCount();
+
+   //
+   // QUICKLOAD?
+   //
+   if (quick)
+   {
+      which = LSItems.curpos;
+
+      if (SaveGamesAvail[which])
+      {
+         if (dieload)
+         {
+            DrawLoadSaveScreenAlt (0);
+            CP_DrawSelectedGame (which);
+            RefreshMenuBuf (0);
+            DoLoad (which);
+
+            return (1);
+         }
+         else
+         {
+            DrawLoadSaveScreen (0);
+            if (CP_DisplayMsg ("Quick load saved game?\nAre you sure?", 12) == true)
+            {
+               DrawLoadSaveScreen (0);
+               CP_DrawSelectedGame (which);
+               RefreshMenuBuf (0);
+               DoLoad (which);
+
+               return (1);
+            }
+            else
+            {
+					return (0);
+            }
+         }
+      }
+   }
+
+   DrawLoadSaveScreen (0);
+   do
+   {
+      which = HandleMenu (&LSItems, &LSMenu[0], CP_DrawSelectedGame);
+
+      if ((exit = DoLoad (which)))
+         break;
+
+   } while (which >= 0);
+
+   handlewhich = OUTOFRANGE;
+
+   if (MainMenu[loadgame].active == CP_Inactive)    // If all the saved games have been
+   {
+      MainItems.curpos = 0;               //  deleted dehighlight LOADGAME
+      MainMenu[newgame].active = CP_CursorLocation;
+   }
+
+   return exit;
+}
+
+//******************************************************************************
+//
+// QuickSaveGame ()
+//
+//******************************************************************************
+
+void QuickSaveGame (void)
+{
+   int i;
+   int j;
+   byte * b;
+   byte * s;
+   int which;
+   gamestorage_t game;
+   byte * buf;
+   int length;
+
+   char   loadname[45]="rottgam0.rot";
+   char   filename[128];
+
+   // Create the proper file name
+
+   itoa(quicksaveslot,&loadname[7],16);
+   loadname[8]='.';
+
+   GetPathFromEnvironment( filename, ApogeePath, loadname );
+   length=LoadFile(filename,(void **)&buf);
+   GetPathFromEnvironment( filename, ApogeePath, QUICKSAVEBACKUP );
+   SaveFile(filename,buf,length);
+   SafeFree(buf);
+
+   s=&game.picture[0];
+   for (i=0;i<320;i+=2)
+      {
+#ifdef DOS
+      VGAREADMAP(i&3);
+      b=(byte *)bufferofs+(i>>2);
+      for (j=0;j<100;j++,s++,b+=iGLOBAL_SCREENBWIDE<<1)
+         *s=*b;
+#else
+      b=(byte *)bufferofs+i;
+      for (j=0;j<100;j++,s++,b+=(iGLOBAL_SCREENWIDTH<<1))
+         *s=*b;
+#endif
+      }
+
+   ScanForSavedGames ();
+   which = quicksaveslot;
+
+   if (SaveGamesAvail[which])
+      {
+      game.episode = gamestate.episode;
+      game.area    = gamestate.mapon;
+      game.version = ROTTVERSION;
+      strcpy (game.message, &SaveGameNames[which][0]);
+
+      if (SaveTheGame (which, &game) == true)
+         {
+         char str[50];
+
+         strcpy (str, "Game Saved: ");
+         strcat (str, &SaveGameNames[which][0]);
+         AddMessage(str,MSG_SYSTEM);
+         }
+      else
+         {
+         AddMessage("Game Not Saved.",MSG_SYSTEM);
+         }
+      }
+   else
+      {
+      AddMessage("No Quick Save Slot.",MSG_SYSTEM);
+      }
+
+   }
+
+//******************************************************************************
+//
+// UndoQuickSaveGame ()
+//
+//******************************************************************************
+
+void UndoQuickSaveGame (void)
+{
+   byte * buf;
+   char   loadname[45]="rottgam0.rot";
+   char   filename[128];
+   int length;
+
+   if (quicksaveslot!=-1)
+      {
+      // Create the proper file name
+
+      itoa(quicksaveslot,&loadname[7],16);
+      loadname[8]='.';
+      GetPathFromEnvironment( filename, ApogeePath, QUICKSAVEBACKUP );
+      length=LoadFile(filename,(void **)&buf);
+      GetPathFromEnvironment( filename, ApogeePath, loadname );
+      SaveFile(filename,buf,length);
+      SafeFree(buf);
+      AddMessage("Previous Quicksave Game Restored.",MSG_SYSTEM);
+      }
+   else
+      {
+      AddMessage("No Quick Save Slot Selected.",MSG_SYSTEM);
+      }
+}
+
+
+//******************************************************************************
+//
+// SAVE CURRENT GAME
+//
+//******************************************************************************
+int CP_SaveGame ( void )
+{
+   int  which,
+        exit=0;
+
+   char input[32];
+   gamestorage_t game;
+
+
+	MenuNum = 4;
+
+
+   DrawLoadSaveScreen (1);
+
+   do
+   {
+      which = HandleMenu (&LSItems, &LSMenu[0], CP_DrawSelectedGame);
+      if (which >= 0)
+      {
+         //
+         // OVERWRITE EXISTING SAVEGAME?
+         //
+	  if (SaveGamesAvail[which]) {
+            if (!CP_DisplayMsg (GAMESVD, 12))
+            {
+               DrawLoadSaveScreenAlt (1);
+               continue;
+            }
+            else
+            {
+               DrawLoadSaveScreenAlt (1);
+               EraseMenuBufRegion (LSM_X+LSItems.indent, LSM_Y+1+which*9, 80, 8);
+               PrintLSEntry (which);
+            }
+	  }
+         quicksaveslot=which;
+
+         DrawStoredGame (savedscreen, gamestate.episode, gamestate.mapon);
+
+         strcpy (input, &SaveGameNames[which][0]);
+
+         if (!SaveGamesAvail[which])
+            EraseMenuBufRegion (LSM_X+LSItems.indent+1, LSM_Y+which*9+2,
+                                77, 6);
+
+         if (US_LineInput (LSM_X+LSItems.indent+2, LSM_Y+which*9+2,
+                           input, input, true, 22, 75, 0))
+         {
+            SaveGamesAvail[which] = 1;
+            memcpy(&game.picture[0],savedscreen,16000);
+            game.episode=gamestate.episode;
+            game.area=gamestate.mapon;
+            game.version=ROTTVERSION;
+            strcpy (game.message, input);
+            strcpy (&SaveGameNames[which][0], input);
+
+            if (SaveTheGame(which,&game)==true)
+               {
+					MainMenu[loadgame].active=CP_Active;
+
+//               MN_PlayMenuSnd (SD_SELECTSND);
+               exit = 1;
+               }
+            WaitKeyUp ();
+         }
+         else
+         {
+            EraseMenuBufRegion (LSM_X+LSItems.indent+1, LSM_Y+which*9+2,
+                                77, 6);
+
+            PrintX = LSM_X+LSItems.indent+2;
+            PrintY = LSM_Y+which*9+2;
+
+            if (SaveGamesAvail[which])
+               DrawMenuBufPropString (PrintX, PrintY, SaveGameNames[which]);
+            else
+               DrawMenuBufPropString (PrintX, PrintY, "     -  -");
+
+//            MN_PlayMenuSnd (SD_ESCPRESSEDSND);
+            continue;
+         }
+         break;
+      }
+
+   } while (which >= 0);
+
+   handlewhich = OUTOFRANGE;
+
+   return (exit);
+}
+
+
+
+//******************************************************************************
+//
+// DEFINE CONTROLS
+//
+//******************************************************************************
+
+void CP_Control (void)
+{
+   #define CTL_SPC   70
+
+   int which;
+
+   DrawCtlScreen ();
+   WaitKeyUp ();
+
+   do
+   {
+      which = HandleMenu (&CtlItems, &CtlMenu[0], NULL);
+
+      switch (CSTactive)
+      {
+         case MOUSEENABLE:
+            if (MousePresent)
+            {
+               mouseenabled^=1;
+               DrawCtlButtons ();
+               CusItems.curpos=-1;
+            }
+            else
+               mouseenabled = 0;
+         break;
+
+			case JOYENABLE:
+            joystickenabled^=1;
+            if ( joystickenabled )
+               {
+               if ( !CalibrateJoystick() )
+                  {
+                  joystickenabled = 0;
+                  joypadenabled = 0;
+                  }
+               }
+            else
+               {
+               joypadenabled = 0;
+               }
+            DrawCtlScreen();
+            break;
+
+         case USEPORT2:
+            joystickport^=1;
+            if ( joystickport )
+               {
+               joypadenabled = 0;
+               }
+
+            joystickenabled = 1;
+            if ( !CalibrateJoystick() )
+               {
+               joystickenabled = 0;
+               joystickport = 0;
+               }
+
+            if ( joystickport )
+               {
+               CtlMenu[ 3 ].active = CP_Inactive;
+               joypadenabled = 0;
+               }
+            else
+               {
+               CtlMenu[ 3 ].active = CP_Active;
+               }
+
+            DrawCtlScreen();
+         break;
+
+         case PADENABLE:
+            joypadenabled^=1;
+            if ( ( joypadenabled ) && ( !joystickenabled ) )
+               {
+               joystickenabled=1;
+               if ( !CalibrateJoystick() )
+                  {
+                  joystickenabled = 0;
+                  joypadenabled = 0;
+                  }
+
+               DrawCtlScreen();
+               }
+            else
+               {
+               DrawCtlButtons ();
+               }
+         break;
+
+         case SPACEBALLENABLE:
+            spaceballenabled ^= 1;
+            DrawCtlButtons ();
+         break;
+
+         case CYBERMANENABLE:
+            cybermanenabled ^= 1;
+            DrawCtlButtons ();
+         break;
+
+			case THRESSENS:
+         case MOUSESENS:
+         case CUSTOMIZE:
+            DrawCtlScreen ();
+         break;
+      }
+
+   } while (which >= 0);
+
+   DrawControlMenu ();
+
+   if (which < 0)
+   {
+      handlewhich = 1;
+      return;
+   }
+}
+
+
+//****************************************************************************
+//
+// CP_Custom ()
+//
+//****************************************************************************
+
+void CP_Custom (void)
+{
+   int which;
+
+   DrawCustomMenu();
+
+   do
+   {
+      which = HandleMenu (&CustomItems, &CustomMenu[0], NULL);
+   } while (which >= 0);
+
+   DrawCtlScreen ();
+}
+
+
+//******************************************************************************
+//
+// CUSTOMIZE CONTROLS
+//
+//******************************************************************************
+
+//****************************************************************************
+//
+// CP_Keyboard ()
+//
+//****************************************************************************
+void CP_Keyboard
+   (
+   void
+   )
+
+   {
+   int which;
+
+   MenuNum = 1;
+
+   DrawCustomKeyboard ();
+
+   do
+      {
+      which = HandleMenu( &NormalKeyItems, &NormalKeyMenu[ 0 ], NULL );
+      }
+   while( which >= 0 );
+
+   DrawCustomMenu();
+   }
+
+
+//******************************************************************************
+//
+// DEFINE THE KEYBOARD BUTTONS
+//
+//******************************************************************************
+
+void DefineKey
+   (
+   void
+   )
+
+   {
+   boolean tick;
+   boolean picked;
+   int     timer;
+   int     x;
+   int     y;
+
+   tick   = false;
+   picked = false;
+   timer  = GetTicCount();
+
+   x = NORMALKEY_X + 97;
+   y = NORMALKEY_Y + ( handlewhich * FontSize[ NormalKeyItems.fontsize ] );
+
+   strcpy( &NormalKeyNames[ handlewhich ][ KEYNAMEINDEX ],
+      "     " );
+
+//   SetMenuTitle ( "Select which key to use" );
+   ClearMenuBuf();
+   DrawMenu( &NormalKeyItems, &NormalKeyMenu[ 0 ] );
+   DisplayInfo( 0 );
+
+   DrawMenuBufIString( x + 3, y, "?", 0 );
+   DrawMenuBufIString( x + 2, y - 1, "?", HIGHLIGHTCOLOR );
+
+   RefreshMenuBuf( 0 );
+
+   do
+      {
+
+      IN_PumpEvents();
+
+      //
+      // FLASH CURSOR
+      //
+      if ( ( GetTicCount() - timer ) > 10 )
+         {
+         int color;
+
+         if ( tick )
+            {
+            color = HIGHLIGHTCOLOR;
+            }
+         else
+            {
+            color = DIMMEDCOLOR;
+            }
+
+         DrawMenuBufIString( x + 3, y, "?", 0 );
+         DrawMenuBufIString( x + 2, y - 1, "?", color );
+
+         tick  = !tick;
+         timer = GetTicCount();
+         }
+
+      RefreshMenuBuf( 0 );
+
+
+      if ( LastScan )
+         {
+         int key;
+
+         key = LastScan;
+         LastScan = 0;
+
+         buttonscan[ (unsigned int)order[ handlewhich ] ] = key;
+
+         strcpy( &NormalKeyNames[ handlewhich ][ KEYNAMEINDEX ],
+            IN_GetScanName( key ) );
+
+         picked = true;
+
+         WaitKeyUp();
+         Keyboard[ key ] = 0;
+
+         IN_ClearKeysDown();
+         }
+      }
+   while( !picked );
+
+   ClearMenuBuf();
+   SetMenuTitle( "Customize Keyboard" );
+
+   DrawMenu( &NormalKeyItems, &NormalKeyMenu[ 0 ] );
+   DisplayInfo( 0 );
+   RefreshMenuBuf (0);
+   }
+
+//****************************************************************************
+//
+// DrawControlSelect ()
+//
+//****************************************************************************
+
+void DrawControlSelect
+   (
+   void
+   )
+
+   {
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Select Button Function");
+
+   MN_GetCursorLocation( &ControlSelectItems, &ControlSelectMenu[ 0 ] );
+   DrawMenu( &ControlSelectItems, &ControlSelectMenu[ 0 ] );
+
+   DisplayInfo( 0 );
+   FlipMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// DefineMouseBtn()
+//
+//****************************************************************************
+
+void DefineMouseBtn
+   (
+   void
+   )
+
+   {
+   int button;
+   int which;
+
+   button = handlewhich;
+
+   MN_GetActive( &ControlSelectItems, &ControlSelectMenu[ 0 ],
+      buttonmouse[ button ], controlorder );
+
+   DrawControlSelect();
+
+   which = HandleMenu( &ControlSelectItems, &ControlSelectMenu[ 0 ], NULL );
+   if ( which != -1 )
+      {
+      buttonmouse[ button ] = controlorder[ which ];
+      }
+
+   handlewhich = OUTOFRANGE;
+   }
+
+//****************************************************************************
+//
+// CP_Mouse ()
+//
+//****************************************************************************
+void CP_Mouse
+   (
+   void
+   )
+
+   {
+   int which;
+
+   MenuNum = 1;
+
+   do
+      {
+      DrawCustomMouse();
+      which = HandleMenu( &MouseBtnItems, &MouseBtnMenu[ 0 ], NULL );
+      }
+   while( which >= 0 );
+
+   handlewhich = OUTOFRANGE;
+
+   DrawCustomMenu();
+   }
+
+
+//****************************************************************************
+//
+// DrawCustomMouse ()
+//
+//****************************************************************************
+
+void DrawCustomMouse
+   (
+   void
+   )
+
+   {
+   int i;
+   int j;
+   int num;
+   int button;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Customize Mouse");
+
+   for( i = 0; i < 6; i++ )
+      {
+      num = 0;
+      button = buttonmouse[ i ];
+      buttonmouse[ i ] = bt_nobutton;
+      MouseBtnNames[ i ][ MOUSEBTNINDEX ] = 0;
+
+      for( j = 0; j < NUMCONTROLNAMES; j++ )
+         {
+         if ( button == controlorder[ j ] )
+            {
+            buttonmouse[ i ] = button;
+            num = j;
+            break;
+            }
+         }
+
+      strcpy( &MouseBtnNames[ i ][ MOUSEBTNINDEX ],
+         ControlNames[ num ] );
+      }
+
+   MN_GetCursorLocation( &MouseBtnItems, &MouseBtnMenu[ 0 ] );
+   DrawMenu( &MouseBtnItems, &MouseBtnMenu[ 0 ] );
+
+   DisplayInfo( 0 );
+   FlipMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// DefineJoyBtn()
+//
+//****************************************************************************
+
+void DefineJoyBtn
+   (
+   void
+   )
+
+   {
+   int button;
+   int which;
+
+   button = handlewhich;
+
+   MN_GetActive( &ControlSelectItems, &ControlSelectMenu[ 0 ],
+      buttonjoy[ button ], controlorder );
+
+   DrawControlSelect();
+
+   which = HandleMenu( &ControlSelectItems, &ControlSelectMenu[ 0 ], NULL );
+   if ( which != -1 )
+      {
+      buttonjoy[ button ] = controlorder[ which ];
+      }
+
+   handlewhich = OUTOFRANGE;
+   }
+
+
+//****************************************************************************
+//
+// DrawCustomJoystick ()
+//
+//****************************************************************************
+
+void DrawCustomJoystick
+   (
+   void
+   )
+
+   {
+   int i;
+   int j;
+   int num;
+   int button;
+   int active;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Customize Joystick");
+
+   for( i = 0; i < 8; i++ )
+      {
+      num = 0;
+      button = buttonjoy[ i ];
+      buttonjoy[ i ] = bt_nobutton;
+      JoyBtnNames[ i ][ JOYBTNINDEX ] = 0;
+
+      for( j = 0; j < NUMCONTROLNAMES; j++ )
+         {
+         if ( button == controlorder[ j ] )
+            {
+            buttonjoy[ i ] = button;
+            num = j;
+            break;
+            }
+         }
+
+      strcpy( &JoyBtnNames[ i ][ JOYBTNINDEX ], ControlNames[ num ] );
+      }
+
+   JoyBtnMenu[ 0 ].active = CP_Active;
+   JoyBtnMenu[ 1 ].active = CP_Active;
+   JoyBtnMenu[ 4 ].active = CP_Active;
+   JoyBtnMenu[ 5 ].active = CP_Active;
+
+   if ( joypadenabled )
+      {
+      active = CP_Active;
+      }
+   else
+      {
+      active = CP_Inactive;
+      }
+
+   JoyBtnMenu[ 2 ].active = active;
+   JoyBtnMenu[ 3 ].active = active;
+   JoyBtnMenu[ 6 ].active = active;
+   JoyBtnMenu[ 7 ].active = active;
+
+   if ( JoyBtnMenu[ JoyBtnItems.curpos ].active == CP_Inactive )
+      {
+      MN_GetCursorLocation( &JoyBtnItems, &JoyBtnMenu[ 0 ] );
+      }
+   else
+      {
+      JoyBtnMenu[ JoyBtnItems.curpos ].active = CP_CursorLocation;
+      }
+
+   DrawMenu( &JoyBtnItems, &JoyBtnMenu[ 0 ] );
+
+   DisplayInfo( 0 );
+   FlipMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// CP_Joystick ()
+//
+//****************************************************************************
+
+void CP_Joystick
+   (
+   void
+   )
+
+   {
+   int which;
+
+   MenuNum = 1;
+
+   do
+      {
+      DrawCustomJoystick();
+      which = HandleMenu( &JoyBtnItems, &JoyBtnMenu[ 0 ], NULL );
+      }
+   while( which >= 0 );
+
+   handlewhich = OUTOFRANGE;
+
+   DrawCustomMenu();
+   }
+
+
+//******************************************************************************
+//
+// PRINT A MESSAGE IN A WINDOW
+//
+//******************************************************************************
+
+void Message (char *string)
+{
+   int   h = 0,
+         w = 0,
+         mw = 0,
+         i;
+   byte *shape;
+
+	shape = W_CacheLumpNum (W_GetNumForName ("newfnt1"), PU_CACHE, Cvt_font_t, 1);
+	newfont1 = (font_t *)shape;
+   CurrentFont = newfont1;
+   h = CurrentFont->height;
+
+   for (i = 0; i < (int)strlen (string); i++)
+      if (string[i] == '\n')
+      {
+         if (w > mw)
+            mw = w;
+         w = 0;
+         h += CurrentFont->height;
+      }
+      else
+         w += CurrentFont->width[string[i]-31];
+
+   if ((w + 10) > mw)
+      mw = w+10;
+
+   PrintY = 78 - (h / 2);
+   PrintX = WindowX = 143 - (mw / 2);
+   WindowW = mw;
+
+   EraseMenuBufRegion (WindowX-5, PrintY-5, (mw+14)&0xFFFC, h+10);
+	DrawSTMenuBuf (WindowX-5, PrintY-5, (mw+14)&0xFFFC, h+10, true);
+
+   MenuBufCPrint (string);
+   RefreshMenuBuf (0);
+}
+
+
+
+//******************************************************************************
+//
+// DRAW NEW GAME MENU
+//
+//******************************************************************************
+
+void DrawNewGame (void)
+{
+   MenuNum = 5;
+
+   SetAlternateMenuBuf ();
+   ClearMenuBuf ();
+   SetMenuTitle ("Choose Difficulty");
+   DrawMenu (&TufItems, &TufMenu[ToughMenuNum][0]);
+   DrawNewGameDiff (TufItems.curpos);
+   DisplayInfo (0);
+   FlipMenuBuf();
+
+}
+
+//******************************************************************************
+//
+// DRAW NEW GAME GRAPHIC
+//
+//******************************************************************************
+
+int newgameY[7] = {19, 0, 42, 0, 74, 0, 93};
+char *DifficultyStrings[ 4 ] =
+   {
+   "Easy", "Medium", "Hard", "Crezzy Man"
+   };
+
+void DrawNewGameDiff
+   (
+   int w
+   )
+
+   {
+   int x;
+
+   switch ( w )
+      {
+      case 0:
+         x = 0;
+         break;
+
+      case 2:
+         x = 1;
+         break;
+
+      case 4:
+         x = 2;
+         break;
+
+      case 6:
+         x = 3;
+         break;
+      }
+
+   EraseMenuBufRegion( 25, 18, 52, 125 );
+   DrawMenuBufPic( 25, newgameY[ w ], W_GetNumForName( "NEWG1" ) +
+      ( ToughMenuNum * 4 ) + x );
+   EraseMenuBufRegion( 25, 149, 64, 8 );
+//   DrawMenuBufPic (25, 149, W_GetNumForName( "O_EASY" ) + x );
+
+   CurrentFont = tinyfont;
+   DrawMenuBufPropString( 25, 149, DifficultyStrings[ x ] );
+   }
+
+
+//******************************************************************************
+//
+// DRAW THE LOAD/SAVE SCREEN
+//
+//******************************************************************************
+
+void DrawLoadSaveScreen (int loadsave)
+{
+   int i;
+   byte *shape;
+
+	shape = W_CacheLumpNum (W_GetNumForName ("newfnt1"), PU_CACHE, Cvt_font_t, 1);
+	newfont1 = (font_t *)shape;
+   CurrentFont = newfont1;
+
+   if (numdone || (!ingame) || (!inmenu))
+      SetAlternateMenuBuf();
+
+   ClearMenuBuf();
+   if (loadsave)
+      {
+      SetMenuTitle ("Save Game");
+      }
+   else
+      {
+      SetMenuTitle ("Load Game");
+      }
+
+   for (i = 0; i < NUMSAVEGAMES; i++)
+      PrintLSEntry (i);
+   DrawMenuBufItem (LSItems.x, ((LSItems.curpos*9)+(LSItems.y)),
+      W_GetNumForName( SmallCursor ) + CursorFrame[ CursorNum ] );
+   DisplayInfo (7);
+   if ((!numdone) && ingame && inmenu)
+      RefreshMenuBuf (0);
+   else
+		FlipMenuBuf();
+
+   WaitKeyUp ();
+
+   numdone++;
+}
+
+//******************************************************************************
+//
+// DRAW THE LOAD/SAVE SCREEN - no flip
+//
+//******************************************************************************
+
+void DrawLoadSaveScreenAlt (int loadsave)
+{
+   int i;
+   byte *shape;
+
+	shape = W_CacheLumpNum (W_GetNumForName ("newfnt1"), PU_CACHE, Cvt_font_t, 1);
+	newfont1 = (font_t *)shape;
+   CurrentFont = newfont1;
+
+   ClearMenuBuf();
+   if (loadsave)
+      {
+      SetMenuTitle ("Save Game");
+      }
+   else
+      {
+      SetMenuTitle ("Load Game");
+      }
+
+   for (i = 0; i < NUMSAVEGAMES; i++)
+      PrintLSEntry (i);
+   DrawMenuBufItem (LSItems.x, ((LSItems.curpos*9)+(LSItems.y)),
+      W_GetNumForName( SmallCursor ) + CursorFrame[ CursorNum ] );
+   DisplayInfo (7);
+   RefreshMenuBuf (0);
+
+   WaitKeyUp ();
+
+   numdone++;
+}
+
+
+//******************************************************************************
+//
+// PRINT LOAD/SAVE GAME ENTRY W/BOX OUTLINE
+//
+//******************************************************************************
+
+void PrintLSEntry (int w)
+{
+
+   DrawSTMenuBuf (LSM_X+LSItems.indent, LSM_Y+1+w*9, 80, 7, false);
+
+   PrintX = LSM_X+LSItems.indent+2;
+   PrintY = LSM_Y+(w*9)+2;
+
+   CurrentFont = tinyfont;
+
+   if (SaveGamesAvail[w])
+      DrawMenuBufPropString (PrintX, PrintY, SaveGameNames[w]);
+   else
+      DrawMenuBufPropString (PrintX, PrintY, "     -  -");
+}
+
+
+
+//******************************************************************************
+//
+// CALIBRATE JOYSTICK
+//
+//******************************************************************************
+int CalibrateJoystick
+   (
+   void
+   )
+
+   {
+   #define CALX   45
+   #define CALY   22
+
+   word xmax, ymax, xmin, ymin, jb;
+   int  checkbits;
+   int  status;
+   boolean done;
+
+   if ( joypadenabled )
+      {
+      // Gravis GamePad : Check all buttons
+      checkbits = ( 1 << 0 ) + ( 1 << 1 ) + ( 1 << 2 ) + ( 1 << 3 );
+      }
+   else if ( joystickport )
+      {
+      // Joystick port 2 : check only buttons 2 and 3
+      checkbits = ( 1 << 2 ) + ( 1 << 3 );
+      }
+   else
+      {
+      // Joystick port 1 : check only buttons 0 and 1
+      checkbits = ( 1 << 0 ) + ( 1 << 1 );
+      }
+
+   status = 0;
+   done = false;
+   while( !done )
+      {
+      SetAlternateMenuBuf();
+      ClearMenuBuf();
+      SetMenuTitle ("Calibrate Joystick");
+      //DrawMenuBufItem( CALX, CALY, W_GetNumForName( "joystk2" ) );
+      WindowW = 288;
+      WindowH = 158;
+      PrintX = WindowX = 0;
+      PrintY = WindowY = 50;
+
+      newfont1 = (font_t *)W_CacheLumpName( "newfnt1", PU_CACHE, Cvt_font_t, 1 );
+      CurrentFont = newfont1;
+      MenuBufCPrint( "MOVE JOYSTICK TO\nUPPER LEFT AND\nPRESS A BUTTON." );
+
+      DisplayInfo( 2 );
+      FlipMenuBuf();
+
+      do
+         {
+         RefreshMenuBuf( 0 );
+         jb = IN_JoyButtons();
+         IN_UpdateKeyboard();
+
+         if ( Keyboard[ sc_Escape ] )
+            {
+            return( 0 );
+            }
+         }
+      while( !( jb & checkbits ) );
+
+      IN_GetJoyAbs( joystickport, &xmin, &ymin );
+      MN_PlayMenuSnd( SD_SELECTSND );
+
+      while( IN_JoyButtons() & checkbits )
+         {
+         IN_UpdateKeyboard();
+
+         if ( Keyboard[ sc_Escape ] )
+            {
+            return( 0 );
+            }
+         }
+
+      ClearMenuBuf();
+//      DrawMenuBufItem( CALX, CALY, W_GetNumForName( "joystk1" ) );
+      WindowW = 288;
+      WindowH = 158;
+      PrintX = WindowX = 0;
+      PrintY = WindowY = 50;
+
+      newfont1 = (font_t *)W_CacheLumpName( "newfnt1", PU_CACHE, Cvt_font_t, 1 );
+      CurrentFont = newfont1;
+      MenuBufCPrint( "MOVE JOYSTICK TO\nLOWER RIGHT AND\nPRESS A BUTTON." );
+
+      DisplayInfo( 2 );
+
+      do
+         {
+         RefreshMenuBuf( 0 );
+         jb = IN_JoyButtons();
+         IN_UpdateKeyboard();
+
+         if ( Keyboard[ sc_Escape ] )
+            {
+            return( 0 );
+            }
+         }
+      while( !( jb & checkbits ) );
+
+      IN_GetJoyAbs( joystickport, &xmax, &ymax );
+      MN_PlayMenuSnd( SD_SELECTSND );
+
+      while( IN_JoyButtons() & checkbits )
+         {
+         IN_UpdateKeyboard();
+
+         if ( Keyboard[ sc_Escape ] )
+            {
+            return( 0 );
+            }
+         }
+
+      //
+      // ASSIGN ACTUAL VALUES HERE
+      //
+      if ( ( xmin < xmax ) && ( ymin < ymax ) )
+         {
+         IN_SetupJoy( joystickport, xmin, xmax, ymin, ymax );
+         joyxmin = xmin;
+         joyxmax = xmax;
+         joyymin = ymin;
+         joyymax = ymax;
+
+         status = 1;
+         done = true;
+         }
+      else
+         {
+         CP_ErrorMsg( "Joystick Error",
+            "Calibration failed.  The joystick must be moved "
+            "to the upper-left first and then the lower-right.",
+            mn_smallfont );
+         }
+      }
+
+   return( status );
+   }
+
+
+//******************************************************************************
+//
+// ADJUST MOUSE SENSITIVITY
+//
+//******************************************************************************
+
+void MouseSensitivity
+   (
+   void
+   )
+
+   {
+   SliderMenu( &mouseadjustment, 11, 0, 21, 81, 240, 1, "block1", NULL,
+      "Mouse Sensitivity", "Slow", "Fast" );
+   }
+
+//******************************************************************************
+//
+// ADJUST MOUSE AND JOYSTICK THRESHOLD
+//
+//******************************************************************************
+
+void DoThreshold
+   (
+   void
+   )
+
+   {
+   SliderMenu (&threshold, 15, 1, 44, 81, 194, 1, "block2", NULL,
+      "Adjust Threshold", "Small", "Large" );
+   }
+
+//******************************************************************************
+//
+// DRAW CONTROL MENU SCREEN
+//
+//******************************************************************************
+
+void DrawCtlScreen (void)
+{
+   MenuNum = 3;
+
+   if (numdone || (!ingame) || (!inmenu))
+      SetAlternateMenuBuf();
+
+   ClearMenuBuf();
+   SetMenuTitle ("Options");
+
+
+   DrawCtlButtons ();
+
+   DisplayInfo (0);
+   DrawMenu (&CtlItems, &CtlMenu[0]);
+   DrawMenuBufItem (CtlItems.x, ((CtlItems.curpos*14)+(CtlItems.y-2)),
+                  W_GetNumForName( LargeCursor ) + CursorFrame[ CursorNum ] );
+
+   if (ingame && inmenu && (!numdone))
+      RefreshMenuBuf (0);
+   else
+      FlipMenuBuf();
+
+	numdone++;
+}
+
+
+//******************************************************************************
+//
+// DrawCtlButtons ()
+//
+//******************************************************************************
+
+void DrawCtlButtons (void)
+{
+   int i,
+       x,
+       y;
+   static boolean first = true;
+   int button_on;
+   int button_off;
+
+   button_on  = W_GetNumForName ("snd_on");
+   button_off = W_GetNumForName ("snd_off");
+
+   WindowX = 0;
+   WindowW = 320;
+
+   if (first)
+   {
+      if (JoysPresent[0] || JoysPresent[1])
+         {
+         CtlMenu[JOYENABLE].active = CP_Active;
+         CtlMenu[USEPORT2].active  = CP_Active;
+         CtlMenu[PADENABLE].active = CP_Active;
+         CtlMenu[THRESSENS].active = CP_Active;
+         }
+      else
+      {
+         joystickenabled = 0;
+         joypadenabled   = 0;
+         joystickport    = 0;
+      }
+
+      if (MousePresent)
+      {
+			CtlMenu[THRESSENS].active = CP_Active;
+         CtlMenu[MOUSESENS].active = CP_Active;
+         CtlMenu[MOUSEENABLE].active = CP_Active;
+      }
+      else
+      {
+         CtlMenu[0].active = CP_Inactive;
+         mouseenabled = 0;
+      }
+
+      if (SpaceBallPresent)
+         CtlMenu[SPACEBALLENABLE].active = CP_Active;
+
+      if (CybermanPresent)
+         CtlMenu[CYBERMANENABLE].active = CP_Active;
+
+      for (x = 0; x < CtlItems.amount; x++)
+      {
+         if (CtlMenu[x].active)
+         {
+            CtlMenu[x].active = CP_CursorLocation;
+            break;
+         }
+      }
+      first = false;
+   }
+
+   x = CTL_X+CtlItems.indent-18;
+   y = MENU_Y-1;
+
+   if (mouseenabled)
+      DrawMenuBufItem (x, y, button_on);
+   else
+   {
+      EraseMenuBufRegion (x, y, 16, 16);
+      DrawMenuBufItem  (x, y, button_off);
+   }
+
+   y += 14;
+   if (joystickenabled)
+      DrawMenuBufItem (x, y, button_on);
+   else
+   {
+		EraseMenuBufRegion (x, y, 16, 16);
+      DrawMenuBufItem (x, y, button_off);
+   }
+
+   y += 14;
+   if (joystickport)
+      DrawMenuBufItem (x, y, button_on);
+   else
+   {
+      EraseMenuBufRegion (x, y, 16, 16);
+      DrawMenuBufItem (x, y, button_off);
+   }
+
+   y += 14;
+   if (joypadenabled)
+      DrawMenuBufItem (x, y, button_on);
+   else
+   {
+      EraseMenuBufRegion (x, y, 16, 16);
+      DrawMenuBufItem (x, y, button_off);
+   }
+
+   y += 14;
+   if (spaceballenabled)
+      DrawMenuBufItem (x, y, button_on);
+   else
+   {
+      EraseMenuBufRegion (x, y, 16, 16);
+      DrawMenuBufItem (x, y, button_off);
+   }
+
+   y += 14;
+   if (cybermanenabled)
+      DrawMenuBufItem (x, y, button_on);
+   else
+   {
+      EraseMenuBufRegion (x, y, 16, 16);
+      DrawMenuBufItem (x, y, button_off);
+   }
+
+
+   if ((CtlItems.curpos < 0) || (!CtlMenu[CtlItems.curpos].active))
+      for (i = 0; i < CtlItems.amount; i++)
+			if (CtlMenu[i].active)
+         {
+            CtlItems.curpos = i;
+            break;
+         }
+
+}
+
+//******************************************************************************
+//
+// WAIT FOR CTRLKEY-UP OR BUTTON-UP
+//
+//******************************************************************************
+
+void WaitKeyUp (void)
+{
+   ControlInfo ci;
+
+   IN_IgnoreMouseButtons();
+   ReadAnyControl (&ci);
+
+   while (ci.button0 || ci.button1 || ci.button2 || ci.button3 ||
+          Keyboard[sc_Space] || Keyboard[sc_Enter] || Keyboard[sc_Escape])
+   {
+      ReadAnyControl (&ci);
+      RefreshMenuBuf (0);
+      if (Keystate[sc_CapsLock] && Keystate[sc_Q])
+         Error("Stuck in WaitKeyUp\n");
+   }
+}
+
+#define PMOUSE    3
+#define SMOUSE    4
+
+//******************************************************************************
+//
+// READ KEYBOARD, JOYSTICK AND MOUSE FOR INPUT
+//
+//******************************************************************************
+
+void ReadAnyControl (ControlInfo *ci)
+{
+
+#if PLATFORM_DOS
+   union REGS inregs;
+   union REGS outregs;
+#endif
+
+   int mouseactive = 0;
+   word buttons = 0;
+//   struct Spw_IntPacket packet;
+
+
+   IN_UpdateKeyboard ();  /* implies IN_PumpEvents() ... */
+   IN_ReadControl (0, ci);
+
+   if (MousePresent && mouseenabled)
+   {
+      int mousey,
+          mousex;
+
+#if USE_SDL
+      INL_GetMouseDelta(&mousex, &mousey);
+      if (mousex >= SENSITIVE)
+      {
+         ci->dir = dir_East;
+         mouseactive = 1;
+      }
+      else if (mousex <= -SENSITIVE)
+      {
+         ci->dir = dir_West;
+         mouseactive = 1;
+      }
+
+      if (mousey >= SENSITIVE)
+      {
+         ci->dir = dir_South;
+         mouseactive = 1;
+      }
+      else if (mousey <= -SENSITIVE)
+      {
+         ci->dir = dir_North;
+         mouseactive = 1;
+      }
+
+#elif PLATFORM_DOS
+		// READ MOUSE MOTION COUNTERS
+      // RETURN DIRECTION
+      // HOME MOUSE
+      // CHECK MOUSE BUTTONS
+
+      inregs.w.ax = PMOUSE;
+      int386 (MouseInt, &inregs, &outregs);
+
+      mousex = outregs.w.cx;
+      mousey = outregs.w.dx;
+
+
+      if (mousey < (CENTER-SENSITIVE))
+      {
+         ci->dir = dir_North;
+
+         inregs.w.cx = CENTER;
+         inregs.w.dx = CENTER;
+
+         inregs.w.ax = SMOUSE;
+         int386 (MouseInt, &inregs, &outregs);
+
+         mouseactive = 1;
+
+      }
+      else
+      if (mousey > (CENTER+SENSITIVE))
+      {
+         ci->dir = dir_South;
+
+         inregs.w.cx = CENTER;
+         inregs.w.dx = CENTER;
+
+         inregs.w.ax = SMOUSE;
+         int386 (MouseInt, &inregs, &outregs);
+
+         mouseactive = 1;
+      }
+
+      if (mousex < (CENTER-SENSITIVE))
+      {
+         ci->dir = dir_West;
+
+			inregs.w.cx = CENTER;
+         inregs.w.dx = CENTER;
+
+         inregs.w.ax = SMOUSE;
+         int386 (MouseInt, &inregs, &outregs);
+
+
+         mouseactive = 1;
+      }
+      else
+      if (mousex > (CENTER+SENSITIVE))
+      {
+         ci->dir = dir_East;
+
+         inregs.w.cx = CENTER;
+         inregs.w.dx = CENTER;
+
+         inregs.w.ax = SMOUSE;
+         int386 (MouseInt, &inregs, &outregs);
+
+         mouseactive = 1;
+      }
+#else
+#error please define your platform.  /* or maybe just nuke the DOS section? */
+#endif
+
+      buttons = IN_GetMouseButtons();
+      if ( buttons )
+         {
+         ci->button0 = buttons & 1;
+         ci->button1 = buttons & 2;
+         ci->button2 = buttons & 4;
+         ci->button3 = false;
+         mouseactive = 1;
+         }
+      }
+
+   if (joystickenabled && !mouseactive)
+   {
+      int jx,jy,jb;
+
+
+      INL_GetJoyDelta (joystickport, &jx, &jy);
+
+      if (jy<-SENSITIVE)
+         ci->dir=dir_North;
+      else
+		if (jy>SENSITIVE)
+         ci->dir=dir_South;
+
+      if (jx<-SENSITIVE)
+         ci->dir=dir_West;
+      else
+      if (jx>SENSITIVE)
+         ci->dir=dir_East;
+
+      jb = IN_JoyButtons();
+      if (jb)
+      {
+         ci->button0=jb&1;
+         ci->button1=jb&2;
+         if (joypadenabled)
+         {
+            ci->button2=jb&4;
+            ci->button3=jb&8;
+         }
+         else
+            ci->button2=ci->button3=false;
+      }
+   }
+
+
+#if 0
+   if (SpaceBallPresent && spaceballenabled)
+   {
+		SP_Get(&packet);
+
+      if (packet.button)
+      {
+         if (packet.button & SP_BTN_1)
+            ci->button0 = true;
+
+         if (packet.button & SP_BTN_2)
+            ci->button1 = true;
+      }
+
+		if (packet.ty >  MENU_AMT)
+         ci->dir = dir_North;
+      else
+         if (packet.ty < -MENU_AMT)
+            ci->dir = dir_South;
+
+		if (packet.tx < (-MENU_AMT* 6))
+         ci->dir = dir_West;
+      else
+         if (packet.tx > (MENU_AMT * 6))
+            ci->dir = dir_East;
+   }
+#endif
+}
+
+
+//******************************************************************************
+//
+// IN_GetScanName () - Returns a string containing the name of the
+//                     specified scan code
+//
+//******************************************************************************
+
+byte * IN_GetScanName (ScanCode scan)
+{
+   byte     **p;
+   ScanCode *s;
+
+   for (s = ExtScanCodes, p = ExtScanNames; *s; p++, s++)
+      if (*s == scan)
+         return (*p);
+
+   return(ScanNames[scan]);
+}
+
+
+//******************************************************************************
+//
+// DisplayInfo ()
+//
+//******************************************************************************
+
+void DisplayInfo (int which)
+{
+   patch_t *p;
+   int x;
+   int num;
+
+   num = W_GetNumForName ( "info1" ) + which;
+   p = (patch_t *) W_CacheLumpNum (num, PU_CACHE, Cvt_patch_t, 1);
+
+   x = (288 - p->width) >> 1;
+
+   DrawMenuBufItem (x, 149, num);
+}
+
+
+//******************************************************************************
+//
+// DrawSTMenuBuf()
+//
+//******************************************************************************
+
+void DrawSTMenuBuf (int x, int y, int w, int h, boolean up)
+{
+   if (!up)
+   {
+      DrawTMenuBufHLine (x,   y,   w+1, false);
+      DrawTMenuBufVLine (x,   y+1, h-1, false);
+      DrawTMenuBufHLine (x,   y+h, w+1, true);
+      DrawTMenuBufVLine (x+w, y+1, h-1, true);
+   }
+   else
+   {
+      DrawTMenuBufHLine (x,   y,   w+1, true);
+      DrawTMenuBufVLine (x,   y+1, h-1, true);
+      DrawTMenuBufHLine (x,   y+h, w+1, false);
+      DrawTMenuBufVLine (x+w, y+1, h-1, false);
+   }
+}
+
+
+//****************************************************************************
+//
+// DoMainMenu ()
+//
+//****************************************************************************
+
+void DoMainMenu (void)
+{
+		EnableScreenStretch();//bna++ shut on streech mode
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   DrawMainMenu();
+	DrawMenuBufItem (MainItems.x,  ((MainItems.curpos*14)+(MainItems.y-2)),
+                  W_GetNumForName( LargeCursor ) + CursorFrame[ CursorNum ] );
+   FlipMenuBuf();
+}
+
+
+//****************************************************************************
+//
+// DrawCustomMenu ()
+//
+//****************************************************************************
+
+void DrawCustomMenu (void)
+{
+   MenuNum = 3;
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Customize Menu");
+   MN_GetCursorLocation( &CustomItems, &CustomMenu[ 0 ] );
+   DrawMenu (&CustomItems, &CustomMenu[0]);
+   DrawMenuBufItem (CustomItems.x, ((CustomItems.curpos*14)+(CustomItems.y-2)),
+                  W_GetNumForName( LargeCursor ) + CursorFrame[ CursorNum ] );
+   DisplayInfo (0);
+   FlipMenuBuf();
+}
+
+
+
+//****************************************************************************
+//
+// DrawCustomKeyboard ()
+//
+//****************************************************************************
+void DrawCustomKeyboard (void)
+{
+   int i;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Customize Keyboard");
+
+   for( i = 0; i < NormalKeyItems.amount; i++ )
+      {
+      strcpy( &NormalKeyNames[ i ][ KEYNAMEINDEX ],
+         IN_GetScanName( buttonscan[ (unsigned int)order[ i ] ] ) );
+      }
+
+   MN_GetCursorLocation( &NormalKeyItems, &NormalKeyMenu[ 0 ] );
+   DrawMenu( &NormalKeyItems, &NormalKeyMenu[ 0 ] );
+
+   DisplayInfo( 0 );
+   FlipMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// MusicVolume ()
+//
+//****************************************************************************
+
+void MusicVolume
+   (
+   void
+   )
+
+   {
+#ifdef DOS
+   extern boolean SOUNDSETUP;
+#endif
+
+   SliderMenu( &MUvolume, 254, 0, 33, 81, 225, 8, "block3", MUSIC_SetVolume,
+      "Music Volume", "Low", "High" );
+
+#ifdef DOS
+   if ( SOUNDSETUP )
+      {
+      DrawSoundSetupMainMenu();
+      }
+   else
+      {
+#endif
+      DrawControlMenu();
+#ifdef DOS
+      }
+#endif
+   }
+
+
+//****************************************************************************
+//
+// FXVolume ()
+//
+//****************************************************************************
+
+void FXVolume
+   (
+   void
+   )
+
+   {
+#ifdef DOS
+   extern boolean SOUNDSETUP;
+#endif
+   int oldvolume;
+
+   oldvolume = FXvolume;
+
+   SliderMenu( &FXvolume, 254, 0, 33, 81, 225, 8, "block3", FX_SetVolume,
+      "Sound Volume", "Low", "High" );
+
+#ifdef DOS
+   if ( SOUNDSETUP )
+      {
+      DrawSoundSetupMainMenu();
+      }
+   else
+      {
+#endif
+      DrawControlMenu();
+#ifdef DOS
+      }
+#endif
+   }
+
+
+
+//****************************************************************************
+//
+// DrawPlayerMenu ()
+//
+//****************************************************************************
+
+void DrawPlayerMenu (void)
+{
+   MenuNum = 5;
+
+
+   MN_MakeActive( &PlayerItems, &PlayerMenu[0], DefaultPlayerCharacter );
+
+#if ( SHAREWARE == 1 )
+   PlayerMenu[ 1 ].active = CP_SemiActive; // Thi Barrett
+   PlayerMenu[ 2 ].active = CP_SemiActive; // Doug Wendt
+   PlayerMenu[ 3 ].active = CP_SemiActive; // Lorelei Ni
+   PlayerMenu[ 4 ].active = CP_SemiActive; // Ian Paul Freeley
+#endif
+
+   if (numdone || (!ingame) || (!inmenu))
+      SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Choose Player");
+
+   DrawMenu (&PlayerItems, &PlayerMenu[0]);
+   DrawNewPlayerDiff (PlayerItems.curpos);
+
+   DisplayInfo (0);
+
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+
+   if (ingame && inmenu && (!numdone))
+      RefreshMenuBuf (0);
+   else
+      FlipMenuBuf();
+}
+
+//******************************************************************************
+//
+// DRAW NEW PLAYER GRAPHIC
+//
+//******************************************************************************
+
+int newplayerY[5] = {28, 42, 56, 70, 84};
+
+void DrawNewPlayerDiff (int w)
+{
+   EraseMenuBufRegion (25, 18, 52, 125);
+   DrawMenuBufPic (25, newplayerY[w], W_GetNumForName( "PLAYER1" ) + w );
+}
+
+
+//******************************************************************************
+//
+// MenuFixup ()
+//
+//******************************************************************************
+void MenuFixup
+   (
+   void
+   )
+
+   {
+   MainMenu[ viewscores ].texture[ 6 ] = '1';
+   MainMenu[ viewscores ].texture[ 7 ] = '0';
+   MainMenu[ viewscores ].texture[ 8 ] = '\0';
+   MainMenu[ viewscores ].routine      = ( void * )CP_EndGame;
+   MainMenu[ viewscores ].letter       = 'E';
+   strcpy (MainMenuNames[ viewscores ] , "END GAME");
+   MainMenu[ savegame ].active         = CP_Active;
+   ingame = true;
+   }
+
+//******************************************************************************
+//
+// GetEpisode ()
+//
+//******************************************************************************
+
+void GetEpisode (int level)
+{
+   if (level < 8)
+      gamestate.episode = 1;
+   else
+      if (level < 16)
+         gamestate.episode = 2;
+      else
+         if (level < 24)
+            gamestate.episode = 3;
+         else
+            gamestate.episode = 4;
+}
+
+
+//****************************************************************************
+//
+// DrawControlMenu ()
+//
+//****************************************************************************
+
+void DrawControlMenu (void)
+{
+   MenuNum = 1;
+
+   if (numdone || (!ingame) || (!inmenu))
+      SetAlternateMenuBuf();
+
+   ClearMenuBuf();
+   SetMenuTitle ("Options");
+
+   MN_GetCursorLocation( &ControlMItems, &ControlMMenu[ 0 ] );
+   DrawMenu (&ControlMItems, &ControlMMenu[0]);
+   DisplayInfo (0);
+
+   if (ingame && inmenu && (!numdone))
+      RefreshMenuBuf (0);
+   else
+      FlipMenuBuf();
+
+   numdone ++;
+}
+
+//****************************************************************************
+//
+//  CP_ControlMenu ()
+//
+//****************************************************************************
+
+void CP_ControlMenu (void)
+{
+   int which;
+
+   DrawControlMenu();
+
+   do
+   {
+      which = HandleMenu (&ControlMItems, &ControlMMenu[0], NULL);
+
+   } while (which >= 0);
+
+   handlewhich = OUTOFRANGE;
+}
+
+
+
+//****************************************************************************
+//
+// DrawOptionsMenu ()
+//
+//****************************************************************************
+
+void DrawOptionsMenu (void)
+{
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("User Options");
+
+   MN_GetCursorLocation( &OptionsItems, &OptionsMenu[ 0 ] );
+   DrawMenu (&OptionsItems, &OptionsMenu[0]);
+   DrawOptionsButtons ();
+   DisplayInfo (0);
+   FlipMenuBuf();
+}
+//****************************************************************************
+//
+// DrawExtOptionsMenu ()  () bna added
+//
+//****************************************************************************
+
+void DrawExtOptionsMenu (void)
+{
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Extended User Options");
+
+   MN_GetCursorLocation( &ExtOptionsItems, &ExtOptionsMenu[ 0 ] );
+   DrawMenu (&ExtOptionsItems, &ExtOptionsMenu[0]);
+   DrawExtOptionsButtons ();
+   DisplayInfo (0);
+
+   FlipMenuBuf();
+}
+extern long inverse_mouse;
+extern boolean usemouselook;
+extern int iG_aimCross;
+extern boolean usejump;
+extern boolean sdl_fullscreen;
+
+void CP_ExtOptionsMenu (void)
+{
+   int which;
+
+   DrawExtOptionsMenu();
+
+   do
+   {
+      which = HandleMenu (&ExtOptionsItems, &ExtOptionsMenu[0], NULL);
+
+      switch (which)
+      {
+         case 0: usemouselook  ^= 1; DrawExtOptionsButtons (); break;
+         case 1: if (inverse_mouse == 1){
+					inverse_mouse = -1;
+				 }else{
+					inverse_mouse = 1;
+				 }
+				 DrawExtOptionsButtons (); 
+				 break;
+         case 2: iG_aimCross   ^= 1; DrawExtOptionsButtons (); break;
+         case 3: usejump       ^= 1; DrawExtOptionsButtons (); break;
+         case 4:
+            if (SDL_WM_ToggleFullScreen(SDL_GetVideoSurface()))
+            {
+               sdl_fullscreen ^= 1;
+               DrawExtOptionsButtons ();
+            }
+            break;
+      }
+
+	} while (which >= 0);
+
+   DrawControlMenu();
+}
+void DrawExtOptionsButtons (void)
+{
+   int i,
+       on;
+   int button_on;
+   int button_off;
+
+   button_on  = W_GetNumForName ("snd_on");
+   button_off = W_GetNumForName ("snd_off");
+
+   for (i = 0; i < ExtOptionsItems.amount; i++)
+      if (ExtOptionsMenu[i].active != CP_Active3)
+      {
+         //
+         // DRAW SELECTED/NOT SELECTED GRAPHIC BUTTONS
+         //
+
+         on = 0;
+
+         switch (i)
+         {
+            case 0: if (usemouselook  == 1) on = 1; break;
+            case 1: if (inverse_mouse == -1)on = 1; break;
+            case 2: if (iG_aimCross   == 1) on = 1; break;
+            case 3: if (usejump       == 1) on = 1; break;
+            case 4: if (sdl_fullscreen== 1) on = 1; break;
+         }
+
+         if (on)
+            DrawMenuBufItem (20+22, ExtOptionsItems.y+i*14-1, button_on);
+         else
+            DrawMenuBufItem (20+22, ExtOptionsItems.y+i*14-1, button_off);
+		}
+}
+
+//****************************************************************************
+//
+// CP_OptionsMenu ()
+//
+//****************************************************************************
+
+void CP_OptionsMenu (void)
+{
+   int which;
+
+   DrawOptionsMenu();
+
+   do
+   {
+      which = HandleMenu (&OptionsItems, &OptionsMenu[0], NULL);
+
+      switch (which)
+      {
+         case 0: AutoDetailOn  ^= 1; DrawOptionsButtons (); break;
+         case 1: fulllight     ^= 1; DrawOptionsButtons (); break;
+         case 2: BobbinOn      ^= 1; DrawOptionsButtons (); break;
+         case 3: fandc         ^= 1; DrawOptionsButtons (); break;
+      }
+
+	} while (which >= 0);
+
+   DrawControlMenu();
+}
+
+//****************************************************************************
+//
+// DrawOptionsButtons
+//
+//****************************************************************************
+
+void DrawOptionsButtons (void)
+{
+   int i,
+       on;
+   int button_on;
+   int button_off;
+
+   button_on  = W_GetNumForName ("snd_on");
+   button_off = W_GetNumForName ("snd_off");
+
+   for (i = 0; i < OptionsItems.amount-5; i++)
+      if (OptionsMenu[i].active != CP_Active3)
+      {
+         //
+         // DRAW SELECTED/NOT SELECTED GRAPHIC BUTTONS
+         //
+
+         on = 0;
+
+         switch (i)
+         {
+            case 0: if (AutoDetailOn  == 1) on = 1; break;
+            case 1: if (fulllight     == 0) on = 1; break;
+            case 2: if (BobbinOn      == 1) on = 1; break;
+            case 3: if (fandc         == 1) on = 1; break;
+         }
+
+         if (on)
+            DrawMenuBufItem (20+22, OptionsItems.y+i*14-1, button_on);
+         else
+            DrawMenuBufItem (20+22, OptionsItems.y+i*14-1, button_off);
+		}
+}
+
+
+//****************************************************************************
+//
+// CP_DoubleClickSpeed()
+//
+//****************************************************************************
+
+void CP_DoubleClickSpeed
+   (
+   void
+   )
+
+   {
+   int temp;
+
+   temp = 50 - ( DoubleClickSpeed - 5 );
+   SliderMenu( &temp, 50, 5, 31, 81, 225, 3, "block1", NULL,
+      "Double-Click Speed", "Slow", "Fast" );
+   DoubleClickSpeed = 50 - ( temp - 5 );
+
+   handlewhich = 100;
+   DrawOptionsMenu();
+   }
+
+//****************************************************************************
+//
+// MenuFlipSpeed ()
+//
+//****************************************************************************
+
+void MenuFlipSpeed
+   (
+   void
+   )
+
+   {
+   int temp;
+
+   temp = 50 - ( Menuflipspeed - 5 );
+
+   SliderMenu( &temp, 50, 5, 31, 81, 225, 3, "block1", NULL,
+      "Menu Flip Speed", "Slow", "Fast" );
+
+   Menuflipspeed = 50 - ( temp - 5 );
+
+   DrawOptionsMenu ();
+   handlewhich = 10;
+   }
+
+
+//****************************************************************************
+//
+// DrawDetailMenu ()
+//
+//****************************************************************************
+
+void DrawDetailMenu (void)
+{
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Detail Menu");
+
+   MN_DrawButtons (&DetailItems, &DetailMenu[0], DetailLevel, OptionNums);
+   MN_GetCursorLocation( &DetailItems, &DetailMenu[ 0 ] );
+   DrawMenu (&DetailItems, &DetailMenu[0]);
+   DisplayInfo (0);
+   FlipMenuBuf();
+}
+
+//****************************************************************************
+//
+// CP_DetailMenu ()
+//
+//****************************************************************************
+
+void CP_DetailMenu (void)
+{
+   int which;
+
+   DrawDetailMenu();
+
+   do
+   {
+      which = HandleMenu (&DetailItems, &DetailMenu[0], NULL);
+
+      switch (which)
+      {
+         case 0:
+            DetailLevel = 0;
+            MN_DrawButtons (&DetailItems, &DetailMenu[0], DetailLevel, OptionNums);
+         break;
+
+         case 1:
+            DetailLevel = 1;
+            MN_DrawButtons (&DetailItems, &DetailMenu[0], DetailLevel, OptionNums);
+         break;
+
+         case 2:
+            DetailLevel = 2;
+            MN_DrawButtons (&DetailItems, &DetailMenu[0], DetailLevel, OptionNums);
+         break;
+      }
+
+   } while (which >= 0);
+
+   handlewhich = 10;
+   DrawOptionsMenu();
+}
+
+
+//****************************************************************************
+//
+// DrawBattleMenu ()
+//
+//****************************************************************************
+
+void DrawBattleMenu (void)
+{
+   MenuNum = 1;
+
+   if (numdone || (!ingame) || (!inmenu))
+      SetAlternateMenuBuf();
+
+   ClearMenuBuf();
+   SetMenuTitle ("Battle Menu");
+
+   DrawBattleModeName( gamestate.battlemode );
+
+   MN_GetCursorLocation( &BattleItems, &BattleMenu[ 0 ] );
+   DrawMenu (&BattleItems, &BattleMenu[0]);
+   DisplayInfo (0);
+
+   BATTLE_SetOptions( &BATTLE_Options[ gamestate.battlemode ] );
+   ShowBattleOptions( true, MENU_X, MENU_Y + 49 );
+
+   if (ingame && inmenu && (!numdone))
+      RefreshMenuBuf (0);
+   else
+      FlipMenuBuf();
+}
+
+
+//****************************************************************************
+//
+// BattleGamePlayerSetup()
+//
+//****************************************************************************
+
+void BattleGamePlayerSetup( void )
+   {
+   int status;
+   int pos;
+
+   pos = 1;
+   if ( consoleplayer == 0 )
+      {
+      pos = 0;
+      }
+
+   while( 1 )
+      {
+      switch( pos )
+         {
+         case 0 :
+            // Select level to play on
+            status = CP_LevelSelectionMenu ();
+            if ( status >= 0  )
+               {
+               gamestate.mapon=status;
+               pos = 1;
+               }
+            else
+               {
+               DrawBattleMenu();
+               return;
+               }
+            break;
+
+         case 1 :
+            // Select CodeName
+            status = CP_EnterCodeNameMenu();
+            pos = 2;
+            if ( !status )
+               {
+               if ( consoleplayer == 0 )
+                  {
+                  pos = 0;
+                  }
+               else
+                  {
+                  return;
+                  }
+               }
+            break;
+
+         case 2 :
+            // Select character
+            status = CP_PlayerSelection ();
+            pos = 1;
+            if ( status )
+               {
+               pos = 3;
+               }
+            break;
+
+         case 3 :
+            // Select color/team
+            status = CP_ColorSelection();
+            pos = 2;
+            if ( status )
+               {
+               StartGame   = true;
+			      DisableScreenStretch();
+               handlewhich = -2;
+               playstate   = ex_resetgame;
+               BATTLEMODE  = true;
+               // Show please wait
+               CP_ModemGameMessage( consoleplayer );
+               return;
+               }
+            break;
+         }
+      }
+   }
+
+
+//****************************************************************************
+//
+// BattleNoTeams()
+//
+//****************************************************************************
+
+void BattleNoTeams( void )
+   {
+   BattleGamePlayerSetup();
+   if ( StartGame )
+      {
+      gamestate.teamplay = false;
+      }
+   }
+
+
+//****************************************************************************
+//
+// BattleTeams()
+//
+//****************************************************************************
+
+void BattleTeams( void )
+   {
+   BattleGamePlayerSetup();
+   if ( StartGame )
+      {
+      gamestate.teamplay = true;
+      }
+   }
+
+
+//****************************************************************************
+//
+// CP_BattleMenu ()
+//
+//****************************************************************************
+
+void CP_BattleMenu (void)
+{
+   int which;
+
+   gamestate.battlemode = handlewhich + battle_Normal;
+
+   BattleMenu[0].active = CP_Active;
+   BattleMenu[1].active = CP_Active;
+
+
+   // Tag can't be played in team mode
+   // Also, can't play teams if only 1 person is playing
+   if ( ( gamestate.battlemode == battle_Tag ) ||
+      ( numplayers < 2 ) )
+      {
+      BattleMenu[1].active = CP_Inactive;
+      if ( BattleItems.curpos == 1 )
+         {
+         BattleItems.curpos = 0;
+         }
+      }
+
+   // Capture the Triad can only be played in team mode
+   if ( gamestate.battlemode == battle_CaptureTheTriad )
+      {
+      BattleMenu[0].active = CP_Inactive;
+      if ( BattleItems.curpos == 0 )
+         {
+         BattleItems.curpos = 1;
+         }
+      }
+
+   BattleMenu[ BattleItems.curpos ].active = CP_CursorLocation;
+   DrawBattleMenu();
+
+   do
+      {
+		which = HandleMenu (&BattleItems, &BattleMenu[0], NULL);
+      }
+   while (which >= 0);
+
+   if ( which == -1 )
+      {
+      DrawBattleModes ();
+      handlewhich = OUTOFRANGE;
+      }
+   }
+
+
+//****************************************************************************
+//
+// MN_PlayMenuSnd ()
+//
+//****************************************************************************
+
+extern boolean dopefish;
+void MN_PlayMenuSnd (int which)
+{
+   if (INFXSETUP || (SD_Started == false))
+      return;
+#if (SHAREWARE==0)
+   if (dopefish==true)
+      {
+      switch (which)
+         {
+         case SD_ESCPRESSEDSND:
+            which = SD_SOUNDESCSND;
+         break;
+         case SD_MOVECURSORSND:
+            which = SD_SILLYMOVESND;
+         break;
+         case SD_SELECTSND:
+            which = SD_SOUNDSELECTSND;
+         break;
+         }
+      }
+#endif
+   SD_Play (which);
+}
+
+
+//******************************************************************************
+//
+// SliderMenu ()
+//
+//******************************************************************************
+
+boolean SliderMenu
+   (
+   int *number,
+   int upperbound,
+   int lowerbound,
+   int erasex,
+   int erasey,
+   int erasew,
+   int numadjust,
+   char *blockname,
+   void ( *routine )( int w ),
+   char *title,
+   char *left,
+   char *right
+   )
+
+   {
+   ControlInfo ci;
+   Direction   lastdir;
+   patch_t    *shape;
+   boolean     returnval;
+   boolean     moved;
+   unsigned long scale;
+   int         exit;
+   int         range;
+   int         timer;
+   int         width;
+   int         height;
+   int         blkx;
+   int         eraseh;
+   int         block;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( title );
+
+   newfont1 = (font_t *)W_CacheLumpName( "newfnt1", PU_CACHE, Cvt_font_t, 1);
+   CurrentFont = newfont1;
+   PrintX = 25;
+   PrintY = 62;
+   DrawMenuBufPropString( PrintX, PrintY, left );
+
+   VW_MeasurePropString( right, &width, &height );
+   DrawMenuBufPropString( 263 - width, PrintY, right );
+
+   block = W_GetNumForName( blockname );
+   shape = ( patch_t * )W_CacheLumpNum( block, PU_CACHE, Cvt_patch_t, 1 );
+   blkx  = erasex - shape->leftoffset;
+   eraseh =  shape->height;
+   scale = ( erasew + shape->leftoffset - shape->width ) << 16;
+   range = upperbound - lowerbound;
+
+   DrawSTMenuBuf( erasex - 1, erasey - 1, erasew + 1, eraseh + 1, false );
+
+   DrawMenuBufItem( blkx + ( ( ( ( *number - lowerbound ) *
+      scale ) / range ) >> 16 ), erasey, block );
+
+   DisplayInfo( 1 );
+   FlipMenuBuf();
+
+   exit  = 0;
+   moved = false;
+   timer = GetTicCount();
+   lastdir = dir_None;
+
+   do
+      {
+      RefreshMenuBuf( 0 );
+
+      ReadAnyControl( &ci );
+      if ( ( ( GetTicCount() - timer ) > 5 ) || ( ci.dir != lastdir ) )
+         {
+         timer = GetTicCount();
+
+         switch( ci.dir )
+            {
+            case dir_North:
+            case dir_West:
+               if ( *number > lowerbound )
+                  {
+                  *number = *number - numadjust;
+
+                  if ( *number < lowerbound )
+                     {
+                     *number = lowerbound;
+                     }
+
+                  moved = true;
+                  }
+               break;
+
+            case dir_South:
+            case dir_East:
+               if ( *number < upperbound )
+                  {
+                  *number = *number + numadjust;
+
+                  if ( *number > upperbound )
+                     {
+                     *number = upperbound;
+                     }
+
+                  moved = true;
+                  }
+               break;
+	    default:
+		;
+            }
+
+         lastdir = ci.dir;
+         }
+
+      if ( moved )
+         {
+         moved = false;
+
+         EraseMenuBufRegion( erasex, erasey, erasew, eraseh );
+
+         DrawMenuBufItem( blkx + ( ( ( ( *number - lowerbound ) *
+            scale ) / range ) >> 16 ), erasey, block );
+
+         if ( routine )
+            {
+            routine( *number );
+            }
+
+         MN_PlayMenuSnd( SD_MOVECURSORSND );
+         }
+
+      if ( ci.button0 || Keyboard[ sc_Space ] || Keyboard[ sc_Enter ] )
+         {
+         exit = 1;
+         }
+      else if ( ci.button1 || Keyboard[ sc_Escape ] )
+         {
+         exit = 2;
+         }
+      }
+   while( !exit );
+
+   if ( exit == 2 )
+      {
+      MN_PlayMenuSnd( SD_ESCPRESSEDSND );
+      returnval = false;
+      }
+   else
+      {
+      MN_PlayMenuSnd( SD_SELECTSND );
+      returnval = true;
+      }
+
+   WaitKeyUp ();
+   return( returnval );
+   }
+
+
+//******************************************************************************
+//
+// DrawF1Help ()
+//
+//******************************************************************************
+
+void DrawF1Help (void)
+{
+
+   VL_DrawPostPic (W_GetNumForName("trilogo"));
+
+   DrawNormalSprite (0, 0, W_GetNumForName("help"));
+
+   VW_UpdateScreen ();
+}
+
+//******************************************************************************
+//
+// CP_F1Help ()
+//
+//******************************************************************************
+
+void CP_F1Help (void)
+{
+   LastScan=0;
+
+   DrawF1Help ();
+
+   while (LastScan == 0)
+   {
+      IN_UpdateKeyboard ();
+   }
+
+   LastScan=0;
+#if (SHAREWARE==1)
+   {
+   DrawOrderInfo( 2 );
+   while (LastScan == 0)
+   {
+      IN_UpdateKeyboard ();
+   }
+
+   LastScan=0;
+   }
+#endif
+}
+
+
+//****************************************************************************
+//
+// CP_ScreenSize()
+//
+//****************************************************************************
+
+void CP_ScreenSize
+   (
+   void
+   )
+
+   {
+   SliderMenu( &viewsize, MAXVIEWSIZES - 1, 0, 33, 81, 225, 1, "block1",
+      NULL, "Screen Size", "Small", "Large" );
+
+   handlewhich = 100;
+   DrawOptionsMenu();
+   }
+
+
+//****************************************************************************
+//
+// DrawViolenceMenu ()
+//
+//****************************************************************************
+
+void DrawViolenceMenu (void)
+{
+   MenuNum = 1;
+   if ( POK )
+      {
+      memcpy( &VMenu[ 1 ].texture, "mcpass\0", 7 );
+      VMenu[ 1 ].letter = 'C';
+      strcpy (VMenuNames[ 1 ] , "CHANGE PASSWORD");
+      }
+   else
+      {
+      memcpy( &VMenu[ 1 ].texture, "mepass\0", 7 );
+      VMenu[ 1 ].letter = 'E';
+      strcpy (VMenuNames[ 1 ] , "ENTER PASSWORD");
+      }
+
+   if (VMenu[0].active != CP_CursorLocation)
+      VMenu[0].active = CP_Active;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Violence Level");
+
+   MN_GetCursorLocation( &VItems, &VMenu[ 0 ] );
+   DrawMenu (&VItems, &VMenu[0]);
+   DisplayInfo (0);
+   FlipMenuBuf();
+}
+
+
+//****************************************************************************
+//
+// CP_ViolenceMenu ()
+//
+//****************************************************************************
+
+void CP_ViolenceMenu (void)
+{
+   int which;
+
+   CurrentFont = smallfont;
+   DrawViolenceMenu ();
+
+   do
+   {
+      which = HandleMenu (&VItems, &VMenu[0], NULL);
+
+   } while (which >= 0);
+
+   handlewhich = 100;
+   DrawOptionsMenu();
+}
+
+
+//****************************************************************************
+//
+// DrawViolenceLevel ()
+//
+//****************************************************************************
+
+void DrawViolenceLevel (void)
+{
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Change Violence Level");
+
+   MN_DrawButtons (&ViolenceItems, &ViolenceMenu[0], gamestate.violence, OptionNums);
+   MN_GetActive (&ViolenceItems, &ViolenceMenu[0], gamestate.violence, OptionNums);
+
+//   DrawMenuBufItem (58, 24, W_GetNumForName ("blood"));
+   IFont = ( cfont_t * )W_CacheLumpName( FontNames[ mn_largefont ],
+      PU_CACHE, Cvt_cfont_t, 1 );
+   DrawMenuBufIString( 58, 24, "HOW MUCH ", NORMALCOLOR );
+   DrawMenuBufIString( PrintX, PrintY, "BLOOD", 51 );
+   DrawMenuBufIString( 71, 37, "DO YOU WANT?", NORMALCOLOR );
+
+   DrawMenu (&ViolenceItems, &ViolenceMenu[0]);
+   DisplayInfo (0);
+   FlipMenuBuf();
+}
+
+
+//****************************************************************************
+//
+// CP_ViolenceLevel ()
+//
+//****************************************************************************
+
+void CP_ViolenceLevel (void)
+{
+   int which;
+   char p1[13];
+   boolean passok=false;
+
+   if (ingame)
+   	{
+      CP_ErrorMsg( "Change Violence Level",
+         "The current game must be ended to change the Violence Level.",
+         mn_largefont );
+      }
+   else if ( POK )
+      {
+      memset (p1, 0, 13);
+
+      CurrentFont = smallfont;
+      DrawViolenceLevelPWord ();
+
+      if (US_lineinput (PBOXX+2, PBOXY+1, p1, NULL, true, 12, 110, 0))
+         {
+         //compare user entered to password
+         if (StringsNotEqual (p1, pword, StringLength (p1)) == false)
+            passok=true;
+         else
+            {
+            CP_ErrorMsg( "Violence Password", "Incorrect Password.",
+               mn_largefont );
+            }
+         }
+      }
+   else
+      passok=true;
+   if (passok==true)
+      {
+      DrawViolenceLevel ();
+      do
+         {
+         which = HandleMenu (&ViolenceItems, &ViolenceMenu[0], NULL);
+
+         if (which >= 0)
+            gamestate.violence = which;
+
+         MN_DrawButtons (&ViolenceItems, &ViolenceMenu[0], gamestate.violence, OptionNums);
+
+         } while (which >= 0);
+
+      WriteMenuInfo ();
+      }
+
+   handlewhich = 100;
+   DrawViolenceMenu();
+}
+
+
+
+//****************************************************************************
+//
+// DrawViolenceLevelPWord ();
+//
+//****************************************************************************
+
+void DrawViolenceLevelPWord
+   (
+   void
+   )
+
+   {
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Violence Password" );
+
+//   CurrentFont = newfont1;
+//   DrawMenuBufPropString( PWORDX, PWORDY, "ENTER PASSWORD" );
+
+   IFont = ( cfont_t * )W_CacheLumpName( FontNames[ mn_largefont ],
+      PU_CACHE, Cvt_cfont_t, 1 );
+   DrawMenuBufIString( PWORDX, PWORDY, "ENTER PASSWORD", NORMALCOLOR );
+
+   DrawSTMenuBuf( PBOXX, PBOXY, PBOXW, PBOXH, false );
+   FlipMenuBuf();
+   }
+
+
+
+//****************************************************************************
+//
+// DrawPWMenu ()
+//
+//****************************************************************************
+
+void DrawPWMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Violence Password" );
+
+//   CurrentFont = newfont1;
+   IFont = ( cfont_t * )W_CacheLumpName( FontNames[ mn_largefont ],
+      PU_CACHE, Cvt_cfont_t, 1 );
+
+   if ( POK )
+      {
+//      DrawMenuBufPropString( PWORDX - 24, PWORDY, "ENTER OLD PASSWORD" );
+      DrawMenuBufIString( PWORDX - 24, PWORDY, "ENTER OLD PASSWORD", NORMALCOLOR );
+      }
+   else
+      {
+//      DrawMenuBufPropString( PWORDX - 24, PWORDY, "ENTER PASSWORD" );
+      DrawMenuBufIString( PWORDX - 24, PWORDY, "ENTER PASSWORD", NORMALCOLOR );
+      }
+
+   DrawSTMenuBuf( PBOXX, PBOXY, PBOXW, PBOXH, false );
+   FlipMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// CP_PWMenu ()
+//
+//****************************************************************************
+
+void CP_PWMenu (void)
+   {
+   char p1[13];
+   char p2[13];
+   boolean EnterNewPassword;
+   boolean AskForNew;
+   boolean RetypePassword;
+
+   memset (p1, 0, 13);
+   memset (p2, 0, 13);
+
+   CurrentFont = smallfont;
+
+   EnterNewPassword = true;
+   if ( POK )
+      {
+      DrawPWMenu ();
+
+      // get old password
+      //
+      EnterNewPassword = false;
+      if (US_lineinput (PBOXX+2, PBOXY+1, p1, NULL, true, 12, PSTRW, 0))
+         {
+         //compare user entered to old
+         //
+         if (StringsNotEqual (p1, pword, StringLength (p1))==false)
+            {
+
+            // Password was correct so they may change it.
+            EnterNewPassword = true;
+            }
+         else
+            {
+            CP_ErrorMsg( "Violence Password", "Incorrect Password.",
+               mn_largefont );
+            }
+         }
+      }
+
+   if ( EnterNewPassword )
+      {
+      MenuNum = 1;
+
+      // get new password
+      //
+		AskForNew = true;
+      RetypePassword = false;
+      while( AskForNew )
+         {
+         CurrentFont = smallfont;
+
+         SetAlternateMenuBuf ();
+         ClearMenuBuf();
+         SetMenuTitle ("Violence Password");
+
+         IFont = ( cfont_t * )W_CacheLumpName( FontNames[ mn_largefont ],
+            PU_CACHE, Cvt_cfont_t, 1 );
+         DrawMenuBufIString( PWORDX - 24, PWORDY, "ENTER NEW PASSWORD", NORMALCOLOR );
+
+//         CurrentFont = newfont1;
+//         DrawMenuBufPropString( PWORDX - 24, PWORDY, "ENTER NEW PASSWORD" );
+//         DrawMenuBufItem (PWORDX-24, PWORDY, W_GetNumForName ("mnewpass"));
+
+         DrawSTMenuBuf (PBOXX, PBOXY, PBOXW, PBOXH, false);
+         FlipMenuBuf();
+
+         memset (p1, 0, 13);
+
+         AskForNew = false;
+         if (US_lineinput (PBOXX+2, PBOXY+1, p1, NULL, true, 12, PSTRW, 0))
+            {
+            // Check for blank password
+            if ( p1[ 0 ] == 0 )
+               {
+               if ( CP_DisplayMsg ( "Clear Password?\nAre you sure?", 12 ) )
+                  {
+                  AskForNew = false;
+                  memset (pword, 0, 13);
+                  WriteMenuInfo ();
+                  POK = false;
+                  }
+               else
+                  {
+                  AskForNew = true;
+                  }
+               }
+            else
+               {
+               RetypePassword = true;
+               }
+            }
+         }
+
+      if ( RetypePassword )
+         {
+			SetAlternateMenuBuf();
+         ClearMenuBuf();
+         SetMenuTitle ("Violence Password");
+
+//         CurrentFont = newfont1;
+//         DrawMenuBufPropString( PWORDX, PWORDY, "RETYPE PASSWORD" );
+
+         IFont = ( cfont_t * )W_CacheLumpName( FontNames[ mn_largefont ],
+            PU_CACHE, Cvt_cfont_t, 1 );
+         DrawMenuBufIString( PWORDX, PWORDY, "RETYPE PASSWORD", NORMALCOLOR );
+
+         DrawSTMenuBuf (PBOXX, PBOXY, PBOXW, PBOXH, false);
+
+         FlipMenuBuf();
+
+         // reenter password
+         //
+         if ( US_lineinput (PBOXX+2, PBOXY+1, p2, NULL, true, 12, PSTRW, 0) )
+            {
+            // compare password and retyped password
+            //
+            if (stricmp (p1, p2) == 0)
+               {
+               memset (pword, 0, 13);
+               strcpy (pword, p1);
+               WriteMenuInfo ();
+
+               // If we have a null password, then we don't need to
+               // ask for one.
+               POK = true;
+               if ( pword[ 0 ] == 0 )
+                  {
+                  POK = false;
+                  }
+               }
+            else
+               {
+               CP_ErrorMsg( "Violence Password", "Passwords did not match.",
+                  mn_largefont );
+               }
+            }
+         }
+      }
+
+   DrawViolenceMenu ();
+   }
+
+//****************************************************************************
+//
+// DrawOptionDescription()
+//
+//****************************************************************************
+
+void DrawOptionDescription( char ** options, int w )
+   {
+   int     width;
+   int     height;
+   char   *string;
+   font_t *temp;
+
+   EraseMenuBufRegion (25, 4, 287 - 25, 10 );
+
+   temp = CurrentFont;
+   CurrentFont = tinyfont;
+
+   string = options[ w ];
+
+	VW_MeasurePropString ( string, &width, &height );
+   DrawMenuBufPropString ( ( 288 - width) / 2, 4, string );
+
+   CurrentFont = temp;
+   }
+
+//****************************************************************************
+//
+// DrawBattleOptionDescription()
+//
+//****************************************************************************
+
+void DrawBattleOptionDescription( int w )
+   {
+   DrawOptionDescription( BattleOptionDescriptions, w );
+   }
+//****************************************************************************
+//
+// DrawGravityOptionDescription()
+//
+//****************************************************************************
+
+void DrawGravityOptionDescription( int w )
+   {
+   DrawOptionDescription( GravityOptionDescriptions, w );
+   }
+//****************************************************************************
+//
+// DrawSpeedOptionDescription()
+//
+//****************************************************************************
+
+void DrawSpeedOptionDescription( int w )
+   {
+   DrawOptionDescription( SpeedOptionDescriptions, w );
+   }
+//****************************************************************************
+//
+// DrawAmmoOptionDescription()
+//
+//****************************************************************************
+
+void DrawAmmoOptionDescription( int w )
+   {
+   DrawOptionDescription( AmmoOptionDescriptions, w );
+   }
+//****************************************************************************
+//
+// DrawHitPointsOptionDescription()
+//
+//****************************************************************************
+
+void DrawHitPointsOptionDescription( int w )
+   {
+   DrawOptionDescription( HitPointsOptionDescriptions, w );
+   }
+//****************************************************************************
+//
+// DrawRadicalOptionDescription()
+//
+//****************************************************************************
+
+void DrawRadicalOptionDescription( int w )
+   {
+   DrawOptionDescription( RadicalOptionDescriptions, w );
+   }
+//****************************************************************************
+//
+// DrawLightLevelOptionDescription()
+//
+//****************************************************************************
+
+void DrawLightLevelOptionDescription( int w )
+   {
+   DrawOptionDescription( LightLevelOptionDescriptions, w );
+   }
+//****************************************************************************
+//
+// DrawPointGoalOptionDescription()
+//
+//****************************************************************************
+
+void DrawPointGoalOptionDescription( int w )
+   {
+   DrawOptionDescription( PointGoalOptionDescriptions, w );
+   }
+//****************************************************************************
+//
+// DrawDangerDamageOptionDescription()
+//
+//****************************************************************************
+
+void DrawDangerDamageOptionDescription( int w )
+   {
+   DrawOptionDescription( DangerDamageOptionDescriptions, w );
+   }
+
+//****************************************************************************
+//
+// DrawTimeLimitOptionDescription()
+//
+//****************************************************************************
+
+void DrawTimeLimitOptionDescription( int w )
+   {
+   DrawOptionDescription( TimeLimitOptionDescriptions, w );
+   }
+
+
+
+#define TURN_OFF_BATTLE_MODE( x ) \
+   ModeMenu[ ( x ) - 1 ].active  = CP_SemiActive; \
+   ModeMenu[ ( x ) - 1 ].routine = NULL;
+
+
+//****************************************************************************
+//
+// DrawBattleModes ()
+//
+//****************************************************************************
+void DrawBattleModes
+   (
+   void
+   )
+
+   {
+   int i;
+
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Battle Modes");
+
+
+   MN_GetActive( &ModeItems, &ModeMenu[ 0 ], gamestate.battlemode -
+      battle_Normal, OptionNums );
+
+   #if ( SHAREWARE == 1 )
+      TURN_OFF_BATTLE_MODE( battle_ScoreMore );
+      TURN_OFF_BATTLE_MODE( battle_Scavenger );
+      TURN_OFF_BATTLE_MODE( battle_Tag );
+      TURN_OFF_BATTLE_MODE( battle_Eluder );
+      TURN_OFF_BATTLE_MODE( battle_Deluder );
+      TURN_OFF_BATTLE_MODE( battle_CaptureTheTriad );
+   #endif
+
+   // Capture the Triad, Tag, ScoreMore, and Hunter can only be
+   // played with 2 or more players
+   if ( numplayers < 2 )
+      {
+      TURN_OFF_BATTLE_MODE( battle_ScoreMore );
+      TURN_OFF_BATTLE_MODE( battle_Tag );
+      TURN_OFF_BATTLE_MODE( battle_Hunter );
+      TURN_OFF_BATTLE_MODE( battle_CaptureTheTriad );
+      }
+
+   if ( ModeMenu[ ModeItems.curpos ].active != CP_CursorLocation )
+      {
+      for( i = 0; i < ModeItems.amount; i++ )
+         {
+         if ( ModeMenu[ i ].active == CP_Active )
+            {
+            ModeItems.curpos = i;
+            ModeMenu[ i ].active = CP_CursorLocation;
+            break;
+            }
+         }
+      }
+
+   DrawMenu( &ModeItems, &ModeMenu[ 0 ] );
+   DisplayInfo( 0 );
+   DrawBattleModeDescription( ModeItems.curpos );
+
+   FlipMenuBuf();
+   }
+
+
+
+//****************************************************************************
+//
+// DrawBattleModeName()
+//
+//****************************************************************************
+
+void DrawBattleModeName( int which )
+   {
+   int     width;
+   int     height;
+   char   *string;
+   font_t *temp;
+
+
+   if ( ( which < battle_Normal ) || ( which > battle_CaptureTheTriad ) )
+      {
+      return;
+      }
+
+   string = BattleModeNames[ which - battle_Normal ];
+
+   temp = CurrentFont;
+   CurrentFont = tinyfont;
+
+	VW_MeasurePropString ( string, &width, &height );
+   DrawMenuBufPropString ( ( 288 - width ) / 2, 4, string );
+//   DrawMenuBufPropString ( 270-width, 4, string );
+
+   CurrentFont = temp;
+   }
+
+
+//****************************************************************************
+//
+// DrawBattleModeDescription()
+//
+//****************************************************************************
+
+void DrawBattleModeDescription( int w )
+   {
+   int     width;
+   int     height;
+   char   *string;
+   font_t *temp;
+
+   EraseMenuBufRegion (25, 4, 287 - 25, 10 );
+
+   temp = CurrentFont;
+   CurrentFont = tinyfont;
+
+   string = BattleModeDescriptions[ w ];
+
+   // Capture the Triad, Tag, ScoreMore, and Hunter can only be
+   // played with 2 or more players
+   if ( numplayers < 2 )
+      {
+      switch( w + 1 )
+         {
+         case battle_ScoreMore :
+         case battle_Tag :
+         case battle_Hunter :
+         case battle_CaptureTheTriad :
+            string = "This mode can only be played with 2 or more players.";
+            break;
+         }
+      }
+
+   #if ( SHAREWARE == 1 )
+      switch( w + 1 )
+         {
+         case battle_ScoreMore :
+         case battle_Scavenger :
+         case battle_Tag :
+         case battle_Eluder :
+         case battle_Deluder :
+         case battle_CaptureTheTriad :
+            string = "See Ordering Info to find out how to get this game.";
+            break;
+         }
+   #endif
+
+	VW_MeasurePropString ( string, &width, &height );
+   DrawMenuBufPropString ( ( 288 - width ) / 2, 4, string );
+
+   CurrentFont = temp;
+   }
+
+
+//****************************************************************************
+//
+// CP_BattleModes ()
+//
+//****************************************************************************
+
+void CP_BattleModes ( void )
+   {
+   int which;
+   static char Warning = 0;
+
+   //
+   // ALREADY IN A GAME?
+   //
+   if ( ingame )
+      {
+      if ( !CP_DisplayMsg( CURGAME, 12 ) )
+         {
+         return;
+         }
+      else
+         {
+         EndGameStuff();
+         }
+      }
+
+   if ( ( numplayers==1 ) && ( Warning == 0 ) )
+      {
+      Warning = 1;
+      CP_OnePlayerWarningMessage();
+      }
+
+   DrawBattleModes ();
+
+   damagecount = 0;
+   BATTLEMODE  = true;
+
+   do
+      {
+      which = HandleMenu( &ModeItems, &ModeMenu[ 0 ],
+         DrawBattleModeDescription );
+      }
+   while ( which >= 0 );
+
+   handlewhich = 100;
+
+   if ( !StartGame )
+      {
+      BATTLEMODE = false;
+      gamestate.battlemode = battle_StandAloneGame;
+      }
+   }
+
+//****************************************************************************
+//
+// DrawBattleOptions ()
+//
+//****************************************************************************
+
+void DrawBattleOptions (void)
+{
+   int i;
+
+	MenuNum = 1;
+
+	SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Battle Mode Options");
+
+   MN_MakeActive ( &BOptItems, &BOptMenu[0], BOptItems.curpos );
+
+   switch( gamestate.battlemode )
+      {
+      case battle_Collector :
+         BOptMenu[2].active = CP_Inactive; // Ammo
+         BOptMenu[6].active = CP_Inactive; // Point Goal
+         break;
+
+      case battle_Scavenger :
+         BOptMenu[6].active = CP_Inactive; // Point Goal
+         break;
+
+      case battle_Tag :
+         BOptMenu[2].active = CP_Inactive; // Ammo
+         break;
+
+      case battle_Eluder :
+         BOptMenu[2].active = CP_Inactive; // Ammo
+         BOptMenu[3].active = CP_Inactive; // Hit points
+         BOptMenu[7].active = CP_Inactive; // Danger damage
+         break;
+      }
+
+   if ( BOptMenu[ BOptItems.curpos ].active == CP_Inactive )
+      {
+      // Find an available cursor position
+      for( i = 0; i < BOptItems.amount; i++ )
+         {
+         if ( BOptMenu[ i ].active == CP_Active )
+            {
+            BOptMenu[ i ].active = CP_CursorLocation;
+            BOptItems.curpos = i;
+            break;
+            }
+         }
+      }
+
+   DrawBattleModeName( gamestate.battlemode );
+   DrawBattleOptionDescription( BOptItems.curpos );
+   DrawMenu (&BOptItems, &BOptMenu[0]);
+	DisplayInfo (0);
+	FlipMenuBuf();
+}
+
+
+//****************************************************************************
+//
+// CP_BattleOptions ()
+//
+//****************************************************************************
+
+void CP_BattleOptions (void)
+{
+	int which;
+
+	DrawBattleOptions ();
+
+	do
+	{
+      which = HandleMenu (&BOptItems, &BOptMenu[0], DrawBattleOptionDescription);
+
+	} while (which >= 0);
+
+	handlewhich = 100;
+//   WriteBattleConfig();
+	CalcTics();
+
+	DrawBattleMenu ();
+}
+
+
+
+//****************************************************************************
+//
+// DrawColorMenu ()
+//
+//****************************************************************************
+
+
+void DrawColorMenu( void )
+   {
+   int   width;
+   int   height;
+   char *text;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Uniform Color");
+
+   CurrentFont = smallfont;
+
+   text = colorname[ locplayerstate->uniformcolor ];
+   VW_MeasurePropString ( text, &width, &height );
+   DrawMenuBufPropString ( ( 320 - width ) / 2 - 16, MENU_Y + 5, text );
+   DisplayInfo( 8 );
+   EraseMenuBufRegion( COLORX, COLORY, COLORW, COLORH );
+   DrawTMenuBufBox( COLORX, COLORY, COLORW, COLORH );
+   DrawColoredMenuBufItem( COLORX - 36, COLORY - 33,
+      W_GetNumForName( playerwadname[ locplayerstate->player ] ),
+      locplayerstate->uniformcolor);
+
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+
+   FlipMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// CP_ColorSelection ()
+//
+//****************************************************************************
+
+int CP_ColorSelection (void)
+{
+   int status;
+
+   locplayerstate->uniformcolor = DefaultPlayerColor;
+
+	DrawColorMenu ();
+	status = ColorMenu();
+   return( status );
+}
+
+int ColorMenu
+   (
+   void
+   )
+
+   {
+   ControlInfo ci;
+   int colorindex;
+   char *text;
+   int width;
+   int height;
+   int timer;
+   int baseshape;
+   int status;
+   boolean update;
+   boolean done;
+
+   colorindex = DefaultPlayerColor;
+   timer      = GetTicCount();
+   baseshape  = W_GetNumForName( playerwadname[ locplayerstate->player ] );
+
+   update = false;
+   done   = false;
+   while( !done )
+      {
+      ReadAnyControl( &ci );
+      if ( ( ci.dir == dir_East ) && ( ( GetTicCount() - timer ) > 5 ) )
+         {
+         update = true;
+         timer = GetTicCount();
+
+         colorindex++;
+         if ( colorindex >= MAXPLAYERCOLORS )
+            {
+            colorindex = 0;
+            }
+
+         MN_PlayMenuSnd( SD_MOVECURSORSND );
+         }
+
+      if ( ( ci.dir == dir_West ) && ( ( GetTicCount() - timer ) > 5 ) )
+         {
+         update = true;
+         timer = GetTicCount();
+
+         colorindex--;
+         if ( colorindex < 0 )
+            {
+            colorindex = MAXPLAYERCOLORS - 1;
+            }
+         MN_PlayMenuSnd( SD_MOVECURSORSND );
+         }
+
+      if ( update )
+         {
+         update = false;
+         DefaultPlayerColor = colorindex;
+         locplayerstate->uniformcolor = colorindex;
+         text = colorname[ locplayerstate->uniformcolor ];
+
+         EraseMenuBufRegion( 0, MENU_Y + 5, 200, 10 );
+         EraseMenuBufRegion( COLORX, COLORY, COLORW, COLORH );
+         VW_MeasurePropString( text, &width, &height );
+         DrawMenuBufPropString( ( 320 - width ) / 2 - 16, MENU_Y + 5, text );
+         DrawTMenuBufBox( COLORX, COLORY, COLORW, COLORH );
+         DrawColoredMenuBufItem( COLORX - 36, COLORY - 33,
+            baseshape, locplayerstate->uniformcolor );
+         }
+
+      if ( ci.button0 || Keyboard[ sc_Space ] || Keyboard[sc_Enter ] )
+         {
+         Keyboard[ sc_Space ] = 0;
+         Keyboard[ sc_Enter ] = 0;
+         MN_PlayMenuSnd( SD_SELECTSND );
+         status = 1;
+         done = true;
+         }
+      else if ( ci.button1 || Keyboard[ sc_Escape ] )
+         {
+         MN_PlayMenuSnd( SD_ESCPRESSEDSND );
+         status = 0;
+         done = true;
+         }
+
+      RefreshMenuBuf( 0 );
+      }
+
+   IN_ClearKeysDown();
+   return( status );
+   }
+
+
+//****************************************************************************
+//
+// CP_PlayerSelection ()
+//
+//****************************************************************************
+int CP_PlayerSelection
+   (
+   void
+   )
+
+   {
+	int which;
+
+   // Do Pick-A-Player menu
+	DrawPlayerMenu();
+
+   do
+      {
+      which = HandleMenu( &PlayerItems, &PlayerMenu[ 0 ], DrawNewPlayerDiff );
+      if ( which < 0 )
+         {
+         handlewhich = 1;
+         return( 0 );
+         }
+
+      #if ( SHAREWARE == 1 )
+         if ( PlayerMenu[ which ].active == CP_SemiActive )
+            {
+            CP_ErrorMsg( "Choose Player",
+               "Read the Ordering Info section from the Main Menu to "
+               "find out how to get the other characters.",
+               mn_smallfont );
+
+            DrawPlayerMenu();
+            }
+      #endif
+      }
+   while( PlayerMenu[ which ].active == CP_SemiActive );
+
+
+#if ( SHAREWARE == 1 )
+   DefaultPlayerCharacter = 0;
+   locplayerstate->player = 0;
+#else
+   DefaultPlayerCharacter = which;
+   locplayerstate->player = which;
+#endif
+
+	return (1);
+}
+
+//****************************************************************************
+//
+// CP_OnePlayerWarningMessage ()
+//
+//****************************************************************************
+
+void CP_OnePlayerWarningMessage
+   (
+   void
+   )
+
+   {
+   CP_ErrorMsg( "Comm-bat Warning",
+      "Comm-bat is designed for modem and network play.  "
+      "One player mode is provided for exploration.  The "
+      "Collector battle mode is still fun on your own.",
+      mn_smallfont );
+   }
+
+
+//****************************************************************************
+//
+// CP_CaptureTheTriadError()
+//
+//****************************************************************************
+
+void CP_CaptureTheTriadError
+   (
+   void
+   )
+
+   {
+   SetupMenuBuf();
+   SetUpControlPanel();
+
+   CP_ErrorMsg( "Comm-bat Warning",
+      "Capture the Traid can only be played with 2 teams."
+      "  All players must return to the menu to choose their "
+      "team colors.", mn_largefont );
+
+   CleanUpControlPanel();
+   ShutdownMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// CP_TeamPlayErrorMessage()
+//
+//****************************************************************************
+
+void CP_TeamPlayErrorMessage
+   (
+   void
+   )
+
+   {
+   SetupMenuBuf();
+   SetUpControlPanel();
+
+   CP_ErrorMsg( "Comm-bat Warning",
+      "Team play can only be played with 2 or more teams."
+      "  All players must return to the menu to choose their "
+      "team colors.", mn_largefont );
+
+   CleanUpControlPanel();
+   ShutdownMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// CP_ModemGameMessage ()
+//
+//****************************************************************************
+
+#if (SITELICENSE == 0)
+
+#define SITELINES 8
+
+char *sitemessage[] =
+   {
+   "HEY! ARE YOU PLAYING ON AN ILLEGAL COPY?",
+   "Network players: it's easy to play legally!",
+   "Just get a site license.  For a little over",
+   "the price of two games, you get 10 more battle",
+   "levels, 11 command cards, and a signed Site",
+   "License.  We don't charge you for 11 copies--",
+   "just for two!  Call 1-800-APOGEE1 to order.",
+   "For more on site licenses, see ORDERING INFO."
+   };
+
+#endif
+
+void CP_ModemGameMessage (int player  )
+
+   {
+   int i;
+    EnableScreenStretch();
+       // SetTextMode (  );
+
+	SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Game Message");
+
+   newfont1 = (font_t *)W_CacheLumpName( "newfnt1", PU_CACHE, Cvt_font_t, 1);
+   CurrentFont = newfont1;
+   if ( modemgame == false )
+      {
+      WindowW = 288;
+      WindowH = 158;
+      PrintX = WindowX = 0;
+      PrintY = WindowY = 60;
+      MenuBufCPrint ("Please wait.\nLoading game.");
+      }
+   else
+      {
+      WindowW = 288;
+      WindowH = 158;
+      PrintX = WindowX = 0;
+      PrintY = WindowY = 50;
+
+      if (networkgame==true)
+         {
+         PrintY = WindowY = 28;
+         }
+
+      if ( player == 0 )
+         {
+         MenuBufCPrint ("Please wait for\nplayers to choose\ntheir characters.");
+         }
+      else
+         {
+         MenuBufCPrint ("Please wait while\nMaster selects\nCOMM-BAT options.");
+         }
+
+#if (SITELICENSE == 0)
+      if (networkgame==true)
+         {
+         for( i = 0; i < SITELINES; i++ )
+            {
+            PrintBattleOption( true, 68, 77 + i * 8,
+               sitemessage[ i ] );
+            }
+         }
+#endif
+      }
+
+   FlipMenuBuf();
+	RefreshMenuBuf (0);
+
+	 DisableScreenStretch();
+   }
+
+
+//****************************************************************************
+//
+// DrawGravityMenu ()
+//
+//****************************************************************************
+
+void DrawGravityMenu (void)
+{
+   MenuNum = 1;
+
+   SetAlternateMenuBuf ();
+   ClearMenuBuf();
+   SetMenuTitle ("Gravity");
+
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+
+   MN_DrawButtons (&GravityItems, &GravityMenu[0],
+		BATTLE_Options[gamestate.battlemode].Gravity, GravityNums);
+   MN_GetActive (&GravityItems, &GravityMenu[0],
+		BATTLE_Options[gamestate.battlemode].Gravity, GravityNums);
+
+	DrawMenu (&GravityItems, &GravityMenu[0]);
+   DrawGravityOptionDescription( GravityItems.curpos );
+   PrintBattleOption( true, 32, 79,
+      "WARNING: High gravity has an unfortunate side effect in" );
+   PrintBattleOption( true, 32, 87,
+      "some levels.  It is possible to jump into an area that is" );
+   PrintBattleOption( true, 32, 95,
+      "impossible, or at least extremely difficult to get out" );
+   PrintBattleOption( true, 32, 103,
+      "of.  In these situations, the only thing you can do is" );
+   PrintBattleOption( true, 32, 111,
+      "kill your character, or find some kindly soul to do it" );
+   PrintBattleOption( true, 32, 119,
+      "for you.  If this fails, you'll just have to end your game." );
+
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+}
+
+
+//****************************************************************************
+//
+// CP_GravityOptions ()
+//
+//****************************************************************************
+
+void CP_GravityOptions (void)
+{
+   int which;
+
+   DrawGravityMenu ();
+
+   do
+   {
+      which = HandleMenu (&GravityItems, &GravityMenu[0], DrawGravityOptionDescription);
+
+      if (which >= 0)
+		  BATTLE_Options[gamestate.battlemode].Gravity = GravityNums[ which ];
+
+      MN_DrawButtons (&GravityItems, &GravityMenu[0],
+			BATTLE_Options[gamestate.battlemode].Gravity, GravityNums);
+
+   } while (which >= 0);
+
+   handlewhich = 100;
+   DrawBattleOptions ();
+}
+
+
+//****************************************************************************
+//
+// DrawSpeedMenu ()
+//
+//****************************************************************************
+
+void DrawSpeedMenu (void)
+{
+	MenuNum = 1;
+
+   SetAlternateMenuBuf ();
+   ClearMenuBuf();
+   SetMenuTitle ("Speed");
+
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+
+   MN_DrawButtons (&SpeedItems, &SpeedMenu[0],
+						 BATTLE_Options[gamestate.battlemode].Speed, OptionNums );
+   MN_GetActive (&SpeedItems, &SpeedMenu[0],
+					  BATTLE_Options[gamestate.battlemode].Speed, OptionNums );
+
+   DrawMenu (&SpeedItems, &SpeedMenu[0]);
+   DrawSpeedOptionDescription( SpeedItems.curpos );
+   DisplayInfo (0);
+   FlipMenuBuf();
+}
+
+
+//****************************************************************************
+//
+// CP_SpeedOptions ()
+//
+//****************************************************************************
+
+void CP_SpeedOptions (void)
+{
+   int which;
+
+   DrawSpeedMenu ();
+
+   do
+   {
+      which = HandleMenu (&SpeedItems, &SpeedMenu[0], DrawSpeedOptionDescription);
+
+      if (which >= 0)
+		  BATTLE_Options[gamestate.battlemode].Speed = which;
+
+      MN_DrawButtons (&SpeedItems, &SpeedMenu[0],
+         BATTLE_Options[gamestate.battlemode].Speed, OptionNums );
+   } while (which >= 0);
+
+   handlewhich = 100;
+   DrawBattleOptions ();
+}
+
+
+//****************************************************************************
+//
+// DrawAmmoPerWeaponMenu ()
+//
+//****************************************************************************
+void DrawAmmoPerWeaponMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Ammo Per Weapon");
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+
+   MN_DrawButtons( &AmmoPerWeaponItems, &AmmoPerWeaponMenu[ 0 ],
+      BATTLE_Options[ gamestate.battlemode ].Ammo, OptionNums );
+
+   MN_GetActive( &AmmoPerWeaponItems, &AmmoPerWeaponMenu[ 0 ],
+      BATTLE_Options[ gamestate.battlemode ].Ammo, OptionNums );
+
+   DrawMenu( &AmmoPerWeaponItems, &AmmoPerWeaponMenu[ 0 ] );
+
+   PrintBattleOption( true, 32, 79,
+      "WARNING: Infinite ammo can seriously alter the balance of" );
+   PrintBattleOption( true, 32, 87,
+      "the game.  We recommend that you only use it occasionally." );
+   PrintBattleOption( true, 32, 95,
+      "It tends to only work well on small levels with lots of" );
+   PrintBattleOption( true, 32, 103,
+      "weapons, where the action is far more intense.  On large" );
+   PrintBattleOption( true, 32, 111,
+      "levels, you may find it causes people to wait in easily" );
+   PrintBattleOption( true, 32, 119,
+      "guardable areas and pick off anyone that comes in the room" );
+   PrintBattleOption( true, 32, 127,
+      "(creating an unfair advantage)." );
+
+   if ( AmmoPerWeaponItems.curpos == 2 )
+      {
+      PrintBattleOption( true, 102, 136, "You have been warned." );
+      }
+
+   DrawAmmoOptionDescription( AmmoPerWeaponItems.curpos );
+   DisplayInfo( 0 );
+   FlipMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// CP_AmmoPerWeaponOptions ()
+//
+//****************************************************************************
+void CP_AmmoPerWeaponOptions
+   (
+   void
+   )
+
+   {
+   int which;
+
+   DrawAmmoPerWeaponMenu();
+
+   do
+      {
+      which = HandleMenu( &AmmoPerWeaponItems, &AmmoPerWeaponMenu[ 0 ], DrawAmmoOptionDescription);
+
+      if (which >= 0)
+         {
+         if ( AmmoPerWeaponItems.curpos == 2 )
+            {
+            MN_PlayMenuSnd( SD_LIGHTNINGSND );
+            PrintBattleOption( true, 102, 136, "You have been warned." );
+            VL_FillPalette(255,255,255);
+            VL_FadeIn(0,255,origpal,10);
+            }
+         else if ( BATTLE_Options[ gamestate.battlemode ].Ammo == 2 )
+            {
+            EraseMenuBufRegion( 102, 136, 84, 8 );
+            MN_PlayMenuSnd( SD_PLAYERTCSND );
+            }
+
+         BATTLE_Options[ gamestate.battlemode ].Ammo = which;
+         }
+
+      MN_DrawButtons( &AmmoPerWeaponItems, &AmmoPerWeaponMenu[ 0 ],
+         BATTLE_Options[ gamestate.battlemode ].Ammo, OptionNums );
+      }
+   while( which >= 0 );
+
+   handlewhich = 100;
+   DrawBattleOptions();
+   }
+
+
+//****************************************************************************
+//
+// DrawHitPointsMenu ()
+//
+//****************************************************************************
+void DrawHitPointsMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = 1;
+
+   SetAlternateMenuBuf ();
+   ClearMenuBuf();
+   SetMenuTitle ("Player Hitpoints");
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+
+   MN_DrawButtons( &HitPointItems, &HitPointMenu[ 0 ],
+      BATTLE_Options[ gamestate.battlemode ].HitPoints, HitPointNums );
+
+   MN_GetActive( &HitPointItems, &HitPointMenu[ 0 ],
+      BATTLE_Options[ gamestate.battlemode ].HitPoints, HitPointNums );
+
+   DrawMenu( &HitPointItems, &HitPointMenu[ 0 ] );
+   DrawHitPointsOptionDescription( HitPointItems.curpos );
+   DisplayInfo( 0 );
+   FlipMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// CP_HitPointsOptions ()
+//
+//****************************************************************************
+
+void CP_HitPointsOptions (void)
+{
+   int which;
+
+   DrawHitPointsMenu ();
+
+   do
+   {
+      which = HandleMenu (&HitPointItems, &HitPointMenu[0], DrawHitPointsOptionDescription);
+
+      if (which >= 0)
+         BATTLE_Options[gamestate.battlemode].HitPoints = HitPointNums[ which ];
+
+      MN_DrawButtons (&HitPointItems, &HitPointMenu[0],
+							 BATTLE_Options[gamestate.battlemode].HitPoints, HitPointNums);
+
+   } while (which >= 0);
+
+   handlewhich = 100;
+   DrawBattleOptions ();
+}
+
+
+
+//****************************************************************************
+//
+// DrawSpawnControlMenu ()
+//
+//****************************************************************************
+void DrawSpawnControlMenu
+   (
+   void
+   )
+
+   {
+   int i;
+
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Radical Options");
+
+   MN_MakeActive( &SpawnItems, &SpawnMenu[ 0 ], SpawnItems.curpos );
+
+#if ( SHAREWARE == 1 )
+   BATTLE_Options[ gamestate.battlemode ].SpawnMines = false;
+   SpawnMenu[ 3 ].active = CP_Inactive; // Mines
+#endif
+
+   switch( gamestate.battlemode )
+      {
+      case battle_Normal :
+         break;
+
+      case battle_ScoreMore :
+         break;
+
+      case battle_Collector :
+         SpawnMenu[ 2 ].active = CP_Inactive; // Weapons
+         SpawnMenu[ 5 ].active = CP_Inactive; // Persistence
+         SpawnMenu[ 6 ].active = CP_Inactive; // Random Weapons
+         SpawnMenu[ 7 ].active = CP_Inactive; // Friendly Fire
+         break;
+
+      case battle_Scavenger :
+         SpawnMenu[ 7 ].active = CP_Inactive; // Friendly Fire
+         break;
+
+      case battle_Hunter :
+         break;
+
+      case battle_Tag :
+         SpawnMenu[ 2 ].active = CP_Inactive; // Weapons
+         SpawnMenu[ 5 ].active = CP_Inactive; // Persistence
+         SpawnMenu[ 6 ].active = CP_Inactive; // Random Weapons
+         break;
+
+      case battle_Eluder :
+         SpawnMenu[ 1 ].active = CP_Inactive; // Health
+         SpawnMenu[ 2 ].active = CP_Inactive; // Weapons
+         SpawnMenu[ 4 ].active = CP_Inactive; // Respawn
+         SpawnMenu[ 5 ].active = CP_Inactive; // Persistence
+         SpawnMenu[ 6 ].active = CP_Inactive; // Random Weapons
+         SpawnMenu[ 7 ].active = CP_Inactive; // Friendly Fire
+         break;
+
+      case battle_Deluder :
+         SpawnMenu[ 7 ].active = CP_Inactive; // Friendly Fire
+         break;
+
+      case battle_CaptureTheTriad :
+         SpawnMenu[ 7 ].active = CP_Inactive; // Friendly Fire
+         break;
+      }
+
+   if ( SpawnMenu[ SpawnItems.curpos ].active == CP_Inactive )
+      {
+      // Find an available cursor position
+      for( i = 0; i < SpawnItems.amount; i++ )
+         {
+         if ( SpawnMenu[ i ].active == CP_Active )
+            {
+            SpawnMenu[ i ].active = CP_CursorLocation;
+            SpawnItems.curpos = i;
+            break;
+            }
+         }
+      }
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+
+   DrawSpawnControlButtons();
+
+   MN_GetCursorLocation( &SpawnItems, &SpawnMenu[ 0 ] );
+
+   DrawMenu( &SpawnItems, &SpawnMenu[ 0 ] );
+   DrawRadicalOptionDescription( SpawnItems.curpos );
+   DisplayInfo( 0 );
+   FlipMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// DrawSpawnControlButtons ()
+//
+//****************************************************************************
+void DrawSpawnControlButtons
+   (
+   void
+   )
+
+   {
+   int x;
+   int y;
+   int button_on;
+   int button_off;
+
+   button_on  = W_GetNumForName( "snd_on" );
+   button_off = W_GetNumForName( "snd_off" );
+
+   x = SpawnItems.x + 18;
+   y = SpawnItems.y - 1;
+
+	if ( BATTLE_Options[ gamestate.battlemode ].SpawnDangers )
+		{
+		DrawMenuBufItem( x, y, button_on );
+		}
+	else
+		{
+		EraseMenuBufRegion( x, y, 16, 16 );
+		DrawMenuBufItem( x, y, button_off );
+		}
+
+	y += 14;
+	if ( BATTLE_Options[ gamestate.battlemode ].SpawnHealth )
+		{
+		DrawMenuBufItem( x, y, button_on );
+		}
+	else
+		{
+		EraseMenuBufRegion( x, y, 16, 16 );
+		DrawMenuBufItem( x, y, button_off );
+		}
+
+	y += 14;
+	if ( BATTLE_Options[ gamestate.battlemode ].SpawnWeapons )
+		{
+		DrawMenuBufItem( x, y, button_on );
+		}
+	else
+		{
+		EraseMenuBufRegion( x, y, 16, 16 );
+		DrawMenuBufItem( x, y, button_off );
+		}
+
+	y += 14;
+	if ( BATTLE_Options[ gamestate.battlemode ].SpawnMines )
+		{
+		DrawMenuBufItem( x, y, button_on );
+		}
+	else
+		{
+		EraseMenuBufRegion( x, y, 16, 16 );
+		DrawMenuBufItem( x, y, button_off );
+		}
+
+	y += 14;
+	if ( BATTLE_Options[ gamestate.battlemode ].RespawnItems )
+		{
+		DrawMenuBufItem( x, y, button_on );
+		}
+	else
+		{
+		EraseMenuBufRegion( x, y, 16, 16 );
+		DrawMenuBufItem( x, y, button_off );
+		}
+
+	y += 14;
+	if ( BATTLE_Options[ gamestate.battlemode ].WeaponPersistence )
+		{
+		DrawMenuBufItem( x, y, button_on );
+		}
+	else
+		{
+		EraseMenuBufRegion( x, y, 16, 16 );
+		DrawMenuBufItem( x, y, button_off );
+		}
+
+	y += 14;
+	if ( BATTLE_Options[ gamestate.battlemode ].RandomWeapons )
+		{
+		DrawMenuBufItem( x, y, button_on );
+		}
+	else
+		{
+		EraseMenuBufRegion( x, y, 16, 16 );
+		DrawMenuBufItem( x, y, button_off );
+		}
+
+	y += 14;
+	if ( BATTLE_Options[ gamestate.battlemode ].FriendlyFire )
+		{
+		DrawMenuBufItem( x, y, button_on );
+		}
+	else
+		{
+		EraseMenuBufRegion( x, y, 16, 16 );
+		DrawMenuBufItem( x, y, button_off );
+		}
+	}
+
+
+//****************************************************************************
+//
+// CP_SpawnControlOptions ()
+//
+//****************************************************************************
+void CP_SpawnControlOptions
+   (
+   void
+   )
+
+   {
+	int which;
+
+	DrawSpawnControlMenu();
+
+   do
+      {
+      which = HandleMenu( &SpawnItems, &SpawnMenu[ 0 ], DrawRadicalOptionDescription );
+      switch( which )
+         {
+			case 0 :
+				BATTLE_Options[ gamestate.battlemode ].SpawnDangers =
+               !BATTLE_Options[ gamestate.battlemode ].SpawnDangers;
+            break;
+
+         case 1 :
+				BATTLE_Options[ gamestate.battlemode ].SpawnHealth =
+               !BATTLE_Options[ gamestate.battlemode ].SpawnHealth;
+            break;
+
+         case 2 :
+				BATTLE_Options[ gamestate.battlemode ].SpawnWeapons =
+               !BATTLE_Options[ gamestate.battlemode ].SpawnWeapons;
+            break;
+
+         case 3 :
+				BATTLE_Options[ gamestate.battlemode ].SpawnMines =
+               !BATTLE_Options[ gamestate.battlemode ].SpawnMines;
+            break;
+
+         case 4 :
+				BATTLE_Options[ gamestate.battlemode ].RespawnItems =
+               !BATTLE_Options[ gamestate.battlemode ].RespawnItems;
+            break;
+
+         case 5 :
+				BATTLE_Options[ gamestate.battlemode ].WeaponPersistence =
+               !BATTLE_Options[ gamestate.battlemode ].WeaponPersistence;
+            break;
+
+         case 6 :
+				BATTLE_Options[ gamestate.battlemode ].RandomWeapons =
+               !BATTLE_Options[ gamestate.battlemode ].RandomWeapons;
+            break;
+
+         case 7 :
+				BATTLE_Options[ gamestate.battlemode ].FriendlyFire =
+               !BATTLE_Options[ gamestate.battlemode ].FriendlyFire;
+            break;
+         }
+
+      DrawSpawnControlButtons();
+      }
+   while( which >= 0 );
+
+   handlewhich = 100;
+   DrawBattleOptions();
+   }
+
+
+
+//****************************************************************************
+//
+// DrawLightLevelMenu ()
+//
+//****************************************************************************
+
+void DrawLightLevelMenu (void)
+{
+   MenuNum = 1;
+
+	SetAlternateMenuBuf ();
+   ClearMenuBuf();
+   SetMenuTitle ("Light Levels");
+
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+
+   MN_DrawButtons (&LightLevelItems, &LightLevelMenu[0],
+      BATTLE_Options[gamestate.battlemode].LightLevel, OptionNums );
+   MN_GetActive (&LightLevelItems, &LightLevelMenu[0],
+      BATTLE_Options[gamestate.battlemode].LightLevel, OptionNums );
+
+   DrawMenu (&LightLevelItems, &LightLevelMenu[0]);
+   DrawLightLevelOptionDescription( LightLevelItems.curpos );
+   DisplayInfo (0);
+   FlipMenuBuf();
+}
+
+
+//****************************************************************************
+//
+// CP_LightLevelOptions ()
+//
+//****************************************************************************
+
+void CP_LightLevelOptions (void)
+{
+   int which;
+
+   DrawLightLevelMenu ();
+
+   do
+   {
+      which = HandleMenu (&LightLevelItems, &LightLevelMenu[0], DrawLightLevelOptionDescription);
+
+      if (which >= 0)
+		  BATTLE_Options[gamestate.battlemode].LightLevel = which;
+
+      MN_DrawButtons (&LightLevelItems, &LightLevelMenu[0],
+         BATTLE_Options[gamestate.battlemode].LightLevel, OptionNums );
+
+   } while (which >= 0);
+
+   handlewhich = 100;
+   DrawBattleOptions ();
+}
+
+
+
+//****************************************************************************
+//
+// DrawPointGoalMenu()
+//
+//****************************************************************************
+
+void DrawPointGoalMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Point Goal");
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+
+   MN_DrawButtons( &PointGoalItems, &PointGoalMenu[ 0 ],
+      BATTLE_Options[ gamestate.battlemode ].Kills, KillNums );
+
+   MN_GetActive( &PointGoalItems, &PointGoalMenu[ 0 ],
+	   BATTLE_Options[ gamestate.battlemode ].Kills, KillNums );
+
+   DrawMenu( &PointGoalItems, &PointGoalMenu[ 0 ] );
+   DrawPointGoalOptionDescription( PointGoalItems.curpos );
+   DisplayInfo( 0 );
+   FlipMenuBuf();
+   }
+
+
+//****************************************************************************
+//
+// CP_PointGoalOptions()
+//
+//****************************************************************************
+
+void CP_PointGoalOptions
+   (
+   void
+   )
+
+   {
+   int which;
+
+   DrawPointGoalMenu();
+
+   do
+      {
+      which = HandleMenu( &PointGoalItems, &PointGoalMenu[ 0 ], DrawPointGoalOptionDescription );
+
+      if ( which >= 0 )
+         {
+         BATTLE_Options[ gamestate.battlemode ].Kills = KillNums[ which ];
+
+         MN_DrawButtons( &PointGoalItems, &PointGoalMenu[ 0 ],
+            BATTLE_Options[ gamestate.battlemode ].Kills, KillNums );
+         }
+      }
+   while( which >= 0 );
+
+   handlewhich = 100;
+   DrawBattleOptions();
+   }
+
+
+//****************************************************************************
+//
+// DrawDangerMenu ()
+//
+//****************************************************************************
+
+void DrawDangerMenu (void)
+{
+   MenuNum = 1;
+
+   SetAlternateMenuBuf ();
+   ClearMenuBuf();
+   SetMenuTitle ("Danger Damage");
+
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+   MN_DrawButtons (&DangerItems, &DangerMenu[0],
+						 BATTLE_Options[gamestate.battlemode].DangerDamage, DangerNums);
+   MN_GetActive (&DangerItems, &DangerMenu[0],
+						 BATTLE_Options[gamestate.battlemode].DangerDamage, DangerNums);
+
+   DrawMenu (&DangerItems, &DangerMenu[0]);
+   DrawDangerDamageOptionDescription( DangerItems.curpos );
+   DisplayInfo (0);
+   FlipMenuBuf();
+}
+
+
+//****************************************************************************
+//
+// CP_DangerOptions ()
+//
+//****************************************************************************
+
+void CP_DangerOptions (void)
+{
+   int which;
+
+   DrawDangerMenu ();
+
+   do
+   {
+      which = HandleMenu (&DangerItems, &DangerMenu[0], DrawDangerDamageOptionDescription);
+
+      if (which >= 0)
+		  BATTLE_Options[gamestate.battlemode].DangerDamage = DangerNums[which];
+
+      MN_DrawButtons (&DangerItems, &DangerMenu[0],
+			BATTLE_Options[gamestate.battlemode].DangerDamage, DangerNums);
+
+   } while (which >= 0);
+
+   handlewhich = 100;
+   DrawBattleOptions ();
+}
+
+
+//****************************************************************************
+//
+// DrawTimeLimitMenu ()
+//
+//****************************************************************************
+
+void DrawTimeLimitMenu (void)
+{
+   MenuNum = 1;
+
+   SetAlternateMenuBuf ();
+   ClearMenuBuf();
+   SetMenuTitle ("Time Limit");
+
+
+   if ( ( gamestate.battlemode != battle_StandAloneGame ) &&
+      ( consoleplayer == 0 ) )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+   MN_DrawButtons (&TimeLimitItems, &TimeLimitMenu[0],
+	   BATTLE_Options[gamestate.battlemode].TimeLimit, TimeLimitNums);
+   MN_GetActive (&TimeLimitItems, &TimeLimitMenu[0],
+      BATTLE_Options[gamestate.battlemode].TimeLimit, TimeLimitNums);
+
+   if ( gamestate.battlemode == battle_Hunter )
+      {
+      TimeLimitMenu[7].active = CP_Inactive; // No time limit
+      if ( TimeLimitItems.curpos == 7 )
+         {
+         TimeLimitMenu[0].active = CP_CursorLocation;
+         TimeLimitItems.curpos = 0;
+         }
+      }
+
+	DrawMenu (&TimeLimitItems, &TimeLimitMenu[0]);
+   DrawTimeLimitOptionDescription( TimeLimitItems.curpos );
+   DisplayInfo (0);
+   FlipMenuBuf();
+}
+
+
+//****************************************************************************
+//
+// CP_TimeLimitOptions ()
+//
+//****************************************************************************
+
+void CP_TimeLimitOptions (void)
+{
+   int which;
+
+   DrawTimeLimitMenu ();
+
+   do
+   {
+      which = HandleMenu (&TimeLimitItems, &TimeLimitMenu[0], DrawTimeLimitOptionDescription);
+
+      if (which >= 0)
+		  BATTLE_Options[gamestate.battlemode].TimeLimit = TimeLimitNums[which];
+
+      MN_DrawButtons (&TimeLimitItems, &TimeLimitMenu[0],
+			BATTLE_Options[gamestate.battlemode].TimeLimit, TimeLimitNums);
+
+   } while (which >= 0);
+
+	handlewhich = 100;
+	DrawBattleOptions ();
+}
+
+void PrintBattleOption
+   (
+   boolean inmenu,
+   int x,
+   int y,
+   char *text
+   )
+
+   {
+   if ( inmenu )
+      {
+      IFont = ( cfont_t * )W_CacheLumpName( "itnyfont", PU_CACHE, Cvt_cfont_t, 1 );
+      DrawMenuBufIString( x + 1, y + 1, text, 0 );
+      DrawMenuBufIString( x, y, text, ACTIVECOLOR );
+      }
+   else
+      {
+      PrintX = x;
+      PrintY = y;
+      US_BufPrint( text );
+      }
+   }
+
+void ShowBattleOption
+   (
+   boolean inmenu,
+   int PosX,
+   int PosY,
+   int column,
+   int Line,
+   char *text1,
+   char *text2
+   )
+
+   {
+   char text[ 80 ];
+   int x;
+   int y;
+
+   y = PosY + ( Line * 7 );
+   x = PosX + column * 120;
+
+   PrintBattleOption( inmenu, x, y, text1 );
+
+   strcpy( text, ": " );
+   strcat( text, text2 );
+
+   PrintBattleOption( inmenu, x + 60, y, text );
+   }
+
+void ShowBattleOptions
+	(
+   boolean inmenu,
+   int PosX,
+   int PosY
+	)
+
+	{
+   battle_type *options;
+	battle_type BatOps;
+   char *string;
+   char text[ 80 ];
+   int  width;
+   int  height;
+   int  temp;
+
+	CurrentFont = tinyfont;
+
+   strcpy( text, "CURRENT OPTIONS FOR " );
+   strcat( text, BattleModeNames[ gamestate.battlemode - battle_Normal ] );
+	VW_MeasurePropString ( text, &width, &height );
+   if ( inmenu )
+      {
+      temp = 288;
+      }
+   else
+      {
+      temp = 320;
+      }
+   PrintBattleOption( inmenu, (temp - width)/2, PosY, text );
+
+   PosY++;
+
+   BATTLE_GetOptions( &BatOps );
+	options = &BatOps;
+
+   ShowBattleOption( inmenu, PosX, PosY, 0, 1, "Friendly Fire",
+      ( options->FriendlyFire ) ? "On" : "Off" );
+
+   ShowBattleOption( inmenu, PosX, PosY, 0, 2, "Weapon Persist",
+      ( options->WeaponPersistence ) ? "On" : "Off" );
+
+   ShowBattleOption( inmenu, PosX, PosY, 0, 3, "Random Weapons",
+      ( options->RandomWeapons ) ? "On" : "Off" );
+
+   ShowBattleOption( inmenu, PosX, PosY, 0, 4, "Respawn Items",
+      ( options->RespawnItems ) ? "On" : "Off" );
+
+   ShowBattleOption( inmenu, PosX, PosY, 0, 5, "Spawn Health",
+      ( options->SpawnHealth ) ? "On" : "Off" );
+
+   ShowBattleOption( inmenu, PosX, PosY, 0, 6, "Spawn Weapons",
+      ( options->SpawnWeapons ) ? "On" : "Off" );
+
+   ShowBattleOption( inmenu, PosX, PosY, 0, 7, "Spawn Mines",
+      ( options->SpawnMines ) ? "On" : "Off" );
+
+   ShowBattleOption( inmenu, PosX, PosY, 0, 8, "Spawn Dangers",
+      ( options->SpawnDangers ) ? "On" : "Off" );
+
+   switch( options->DangerDamage )
+      {
+      case bo_danger_low :
+         string = "Low";
+         break;
+
+      case bo_danger_normal :
+         string = "Normal";
+         break;
+
+      case bo_danger_kill :
+         string = "Kill";
+         break;
+
+      default :
+         itoa( options->DangerDamage, text, 10 );
+         string = text;
+      }
+   ShowBattleOption( inmenu, PosX, PosY, 0, 9, "Danger Damage", string );
+
+   GetMapFileName ( text );
+   ShowBattleOption( inmenu, PosX, PosY, 0, 10, "Filename", text );
+
+   itoa( numplayers, text, 10 );
+   ShowBattleOption( inmenu, PosX, PosY, 1, 1, "Players", text );
+
+   if ( options->TimeLimit == bo_time_infinite )
+      {
+      string = "None";
+      }
+   else
+      {
+      itoa( options->TimeLimit, text, 10 );
+      string = text;
+      }
+   ShowBattleOption( inmenu, PosX, PosY, 1, 2, "Time Limit", string );
+
+   if ( ( gamestate.battlemode == battle_Collector ) ||
+      ( gamestate.battlemode == battle_Scavenger ) )
+      {
+      string = "?";
+      }
+   else
+      {
+      switch( options->Kills )
+         {
+         case bo_kills_random :
+            string = "Random";
+            break;
+
+         case bo_kills_blind :
+            string = "Blind";
+            break;
+
+         case bo_kills_infinite :
+            string = "Infinite";
+            break;
+
+         default :
+            itoa( options->Kills, text, 10 );
+            string = text;
+         }
+      }
+   ShowBattleOption( inmenu, PosX, PosY, 1, 3, "Point Goal", string );
+
+   switch( options->Ammo )
+      {
+      case bo_one_shot :
+         string = "One shot";
+         break;
+
+      case bo_normal_shots :
+         string = "Normal";
+         break;
+
+      case bo_infinite_shots :
+         string = "Gunfinity";
+         break;
+		}
+   ShowBattleOption( inmenu, PosX, PosY, 1, 4, "Ammo", string );
+
+   if ( options->HitPoints == bo_character_hitpoints )
+      {
+      string = "Character";
+      }
+   else
+      {
+      itoa( options->HitPoints, text, 10 );
+      string = text;
+      }
+   ShowBattleOption( inmenu, PosX, PosY, 1, 5, "Hit Points", string );
+
+   itoa( options->RespawnTime, text, 10 );
+   ShowBattleOption( inmenu, PosX, PosY, 1, 6, "Respawn Time", text );
+
+   switch( options->Speed )
+      {
+      case bo_normal_speed :
+         string = "Normal";
+         break;
+
+      case bo_fast_speed :
+         string = "Fast";
+         break;
+      }
+   ShowBattleOption( inmenu, PosX, PosY, 1, 7, "Speed", string );
+
+   switch( options->LightLevel )
+      {
+      case bo_light_dark :
+         string = "Dark";
+         break;
+
+      case bo_light_normal :
+         string = "Normal";
+         break;
+
+      case bo_light_bright :
+         string = "Bright";
+         break;
+
+      case bo_light_fog :
+         string = "Fog";
+         break;
+
+      case bo_light_periodic :
+         string = "Periodic";
+			break;
+
+      case bo_light_lightning :
+         string = "Lightning";
+         break;
+      }
+   ShowBattleOption( inmenu, PosX, PosY, 1, 8, "Light", string );
+
+   if ( options->Gravity == NORMAL_GRAVITY )
+		{
+      string = "Normal";
+      temp = NORMAL_GRAVITY;
+      }
+   else if ( options->Gravity < NORMAL_GRAVITY )
+      {
+      string = "Low";
+      temp = LOW_GRAVITY;
+      }
+   else
+      {
+      string = "High";
+      temp = HIGH_GRAVITY;
+      }
+
+   strcpy( text, string );
+   if ( options->Gravity < (unsigned int)temp )
+      {
+      strcat( text, "-" );
+      }
+
+   if ( options->Gravity > (unsigned int)temp )
+      {
+      strcat( text, "+" );
+      }
+   ShowBattleOption( inmenu, PosX, PosY, 1, 9, "Gravity", text );
+   }
+
+
+//****************************************************************************
+//
+// SetMenuHeader()
+//
+//****************************************************************************
+
+void SetMenuHeader
+   (
+   char *header
+   )
+
+   {
+   int width;
+   int height;
+
+   EraseMenuBufRegion( 16, 0, 256, 16 );
+
+   CurrentFont = tinyfont;
+   VW_MeasurePropString ( header, &width, &height );
+   DrawMenuBufPropString ( ( 288 - width ) / 2, 4, header );
+
+   RefreshMenuBuf( 0 );
+   }
+
+
+//****************************************************************************
+//
+// DrawMultiPageCustomMenu()
+//
+//****************************************************************************
+
+void DrawMultiPageCustomMenu
+   (
+   char *title,
+   void ( *redrawfunc )( void )
+   )
+
+   {
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( title );
+
+   DrawMenu( &MultiPageCustomItems, &MultiPageCustomMenu[ 0 ] );
+
+   DisplayInfo( 0 );
+
+   if ( redrawfunc != NULL )
+      {
+      redrawfunc();
+      }
+
+   CalcTics();
+   FlipMenuBuf();
+	RefreshMenuBuf( 0 );
+   }
+
+
+//****************************************************************************
+//
+// HandleMultiPageCustomMenu()
+//
+//****************************************************************************
+
+int HandleMultiPageCustomMenu
+   (
+   char **names,
+   int   amount,
+   int   curpos,
+   char *title,
+   void  ( *routine )( int w ),
+   void ( *redrawfunc )( void ),
+   boolean exitonselect
+   )
+
+   {
+   boolean redraw;
+   int  page;
+   int  cursorpos;
+   int  maxpos;
+   int  numpos;
+   int  which;
+   int  selection;
+   int  i;
+   char letter;
+
+   MenuNum = 11;
+
+   cursorpos = curpos % MAXCUSTOM;
+   page      = curpos - cursorpos;
+   MultiPageCustomItems.curpos = cursorpos + 2;
+
+   redraw = true;
+
+   do
+      {
+      if ( redraw )
+         {
+         redraw = false;
+         MultiPageCustomMenu[ 0 ].active = CP_Active;
+         MultiPageCustomMenu[ 1 ].active = CP_Active;
+         if ( page == 0 )
+            {
+            MultiPageCustomMenu[ 1 ].active = CP_Inactive;
+            }
+
+         maxpos = page + MAXCUSTOM;
+         if ( maxpos >= amount )
+            {
+            MultiPageCustomMenu[ 0 ].active = CP_Inactive;
+            maxpos = amount;
+            }
+
+         numpos = maxpos - page + 2;
+         MultiPageCustomItems.amount = numpos;
+
+         for( i = 2; i < numpos; i++ )
+            {
+            MultiPageCustomMenu[ i ].active = CP_Active;
+
+            // Set the name of the level
+            strcpy (MultiPageCustomNames[ i ] , names[ page + i - 2 ]);
+
+            // Set the quick key
+            letter = *names[ page + i - 2 ];
+
+            // Force it to upper case
+            if ( ( letter >= 'a' ) && ( letter <= 'z' ) )
+               {
+               letter = letter - 'a' + 'A';
+               }
+
+            // Only use letters
+            if ( ( letter < 'A' ) || ( letter > 'Z' ) )
+               {
+               letter = 'a';
+               }
+            MultiPageCustomMenu[ i ].letter = letter;
+            }
+
+         // If the cursor is at an invalid position, find a valid one
+         cursorpos = MultiPageCustomItems.curpos;
+         if ( cursorpos >= numpos )
+            {
+            cursorpos = numpos - 1;
+            }
+         else
+            {
+            while( MultiPageCustomMenu[ cursorpos ].active == CP_Inactive )
+               {
+               cursorpos++;
+               }
+            }
+         MultiPageCustomItems.curpos = cursorpos;
+         MultiPageCustomMenu[ cursorpos ].active = CP_CursorLocation;
+
+         DrawMultiPageCustomMenu( title, redrawfunc );
+         }
+
+      which = HandleMenu( &MultiPageCustomItems, &MultiPageCustomMenu[ 0 ],
+         NULL );
+
+      switch( which )
+         {
+         case ESCPRESSED :
+            selection = -1;
+            break;
+
+         case PAGEDOWN :
+         case 0 :
+            page += MAXCUSTOM;
+            which = 0;
+            redraw = true;
+            break;
+
+         case PAGEUP :
+         case 1 :
+            page -= MAXCUSTOM;
+            which = 0;
+            redraw = true;
+            break;
+
+         default :
+            selection = page + which - 2;
+            if ( routine )
+               {
+               routine( selection );
+               }
+
+            if ( exitonselect )
+               {
+               which = -1;
+               }
+            break;
+         }
+      }
+   while( which >= 0 );
+
+   return( selection );
+   }
+
+
+//****************************************************************************
+//
+// CP_LevelSelectionRedraw()
+//
+//****************************************************************************
+
+void CP_LevelSelectionRedraw
+   (
+   void
+   )
+
+   {
+   if ( gamestate.battlemode >= battle_Normal )
+      {
+      SetMenuHeader( BattleModeNames[ gamestate.battlemode - battle_Normal ] );
+      }
+   }
+
+
+//****************************************************************************
+//
+// CP_LevelSelectionMenu ()
+//
+//****************************************************************************
+int CP_LevelSelectionMenu
+   (
+   void
+   )
+
+   {
+   static char levelcursorpos[ 2 ] = { 0 };
+
+   char *LevelNames[ 100 ];
+   int   whichlevels;
+   int   numlevels;
+   int   level;
+   int   i;
+
+   whichlevels = 0;
+   if ( BATTLEMODE )
+      {
+      whichlevels = 1;
+      }
+
+   mapinfo = ( mapfileinfo_t * )SafeMalloc( sizeof( mapfileinfo_t ) );
+   GetMapInfo( mapinfo );
+
+   numlevels = mapinfo->nummaps;
+   if ( numlevels <= 0 )
+      {
+      Error( "CP_LevelSelectionMenu : No maps found in RTL/RTC file." );
+      }
+
+   for( i = 0; i < numlevels; i++ )
+      {
+      LevelNames[ i ] = mapinfo->maps[ i ].mapname;
+      }
+
+   level = HandleMultiPageCustomMenu( LevelNames, numlevels,
+      levelcursorpos[ whichlevels ], "Level Selection", NULL,
+      CP_LevelSelectionRedraw, true );
+
+   SafeFree( mapinfo );
+
+   if ( level >= 0 )
+      {
+      levelcursorpos[ whichlevels ] = level;
+      }
+
+   return( level );
+   }
+
+
+//****************************************************************************
+//
+// DrawEnterCodeNameMenu ()
+//
+//****************************************************************************
+void DrawEnterCodeNameMenu
+   (
+   void
+   )
+
+   {
+	SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Enter CodeName");
+
+   if ( consoleplayer == 0 )
+      {
+      DrawBattleModeName( gamestate.battlemode );
+      }
+
+   WindowW = 288;
+   WindowH = 158;
+   WindowX = 0;
+   WindowY = 50;
+   PrintX  = 0;
+   PrintY  = 50;
+
+   CurrentFont = smallfont;
+
+   MenuBufCPrint( "Enter CodeName\n" );
+   MenuBufCPrint( "maximum 8 letters\n" );
+
+   DrawSTMenuBuf( ( 288 - 92 ) / 2 - 2, 80 - 2, 92 + 4, 10 + 4, false );
+
+   DrawMenuBufPropString( ( 288 - 92 ) / 2, 80, CodeName );
+
+   WindowX = 144 - ( 9 * 4 );
+   PrintX  = WindowX;
+
+   FlipMenuBuf();
+	RefreshMenuBuf( 0 );
+   }
+
+//****************************************************************************
+//
+// CP_EnterCodeNameMenu ()
+//
+//****************************************************************************
+int CP_EnterCodeNameMenu
+   (
+   void
+   )
+
+   {
+   char input[10];
+
+   DrawEnterCodeNameMenu();
+
+   memset(input,0,sizeof(input));
+   strcpy(input,CodeName);
+
+
+   if (US_LineInput ((288-92)/2, 80, input, input, true, 8, 92, 0))
+      {
+      strcpy (&locplayerstate->codename[0], input);
+      strcpy (CodeName, input);
+      WaitKeyUp();
+      return 1;
+      }
+   else
+      {
+      WaitKeyUp();
+      return 0;
+      }
+   }
+
+#ifdef DOS
+void SS_DrawSBTypeMenu( void );
+void SS_SBTypeMenu( void );
+void SS_DrawPortMenu( void );
+void SS_PortMenu( void );
+void SS_Draw8BitDMAMenu( void );
+void SS_8BitDMAMenu( void );
+void SS_Draw16BitDMAMenu( void );
+void SS_16BitDMAMenu( void );
+void SS_DrawIrqMenu( void );
+void SS_IrqMenu( void );
+void SS_Quit( void );
+void DrawSoundSetupMainMenu( void );
+void CP_SoundSetup( void );
+void SS_MusicMenu( void );
+void SS_DrawMusicMenu( void );
+void SS_SoundMenu( void );
+void SS_DrawSoundMenu( void );
+void SS_SetupMusicCardMenu( void );
+void DrawMusicCardMenu( void );
+void SS_SetupSoundBlaster( int sbmenu );
+void SS_SetupSoundCardMenu( void );
+void SS_VoiceMenu( int sbmenu );
+void SS_DrawVoiceMenu( void );
+void SS_ChannelMenu( void );
+void SS_DrawChannelMenu( void );
+void SS_BitMenu( void );
+void SS_DrawBitMenu( void );
+
+extern int musicnums[ 11 ];
+extern int fxnums[ 11 ];
+
+static int midinums[ 12 ]  = {
+   0x220, 0x230, 0x240, 0x250, 0x300, 0x320,
+   0x330, 0x332, 0x334, 0x336, 0x340, 0x360
+   };
+static int voicenums[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+static int resnums[2]   = {8, 16};
+static int smnums[2]    = {1, 2};
+
+//
+// MENU ITEMS
+//
+CP_MenuNames SoundSetupMenuNames[] =
+   {
+   "SETUP SOUND FX",
+   "SETUP MUSIC",
+   "SOUND FX VOLUME",
+   "MUSIC VOLUME",
+   "QUIT"
+   };
+
+CP_iteminfo SoundSetupMenuItems  = { MENU_X, 48, 5, STARTITEM, 32, SoundSetupMenuNames, mn_largefont };
+CP_itemtype SoundSetupMenu[] =
+   {
+      { CP_CursorLocation, "\0",  'S', (menuptr)SS_SoundMenu },
+      { CP_Active,         "\0",  'S', (menuptr)SS_MusicMenu },
+      { CP_Active,         "\0",  'S', (menuptr)FXVolume },
+      { CP_Active,         "\0",  'M', (menuptr)MusicVolume },
+      { CP_Active,         "\0",  'Q', (menuptr)SS_Quit }
+   };
+
+CP_MenuNames SoundSetupMusicNames[] =
+   {
+   "None",
+   "Ultrasound",
+   "Sound Blaster",
+   "Sound Man 16",
+   "Pro Audio Spectrum",
+   "AWE 32",
+   "Soundscape",
+   "Wave Blaster",
+   "General Midi",
+   "Sound Canvas",
+   "Adlib"
+   };
+
+CP_iteminfo SoundSetupMusicItems  = { 44, MENU_Y + 15, 11, STARTITEM, 16, SoundSetupMusicNames, mn_smallfont };
+CP_itemtype SoundSetupMusic[] =
+   {
+      { CP_CursorLocation, "\0",  'N', (menuptr)SS_SetupMusicCardMenu },
+      { CP_Active,         "\0",  'U', (menuptr)SS_SetupMusicCardMenu },
+      { CP_Active,         "\0",  'S', (menuptr)SS_SetupMusicCardMenu },
+      { CP_Active,         "\0",  'S', (menuptr)SS_SetupMusicCardMenu },
+      { CP_Active,         "\0",  'P', (menuptr)SS_SetupMusicCardMenu },
+      { CP_Active,         "\0",  'A', (menuptr)SS_SetupMusicCardMenu },
+      { CP_Active,         "\0",  'S', (menuptr)SS_SetupMusicCardMenu },
+      { CP_Active,         "\0",  'W', (menuptr)SS_SetupMusicCardMenu },
+      { CP_Active,         "\0",  'G', (menuptr)SS_SetupMusicCardMenu },
+      { CP_Active,         "\0",  'S', (menuptr)SS_SetupMusicCardMenu },
+      { CP_Active,         "\0",  'A', (menuptr)SS_SetupMusicCardMenu }
+   };
+
+
+CP_MenuNames SoundSetupSoundNames[] =
+   {
+   "None",
+   "Ultrasound",
+   "Sound Blaster",
+   "Sound Man 16",
+   "Pro Audio Spectrum",
+   "AWE 32",
+   "Soundscape",
+   "Adlib",
+   "Disney Sound Source",
+   "Tandy Sound Source",
+   "PC Speaker"
+   };
+
+CP_iteminfo SoundSetupSoundItems  = { MENU_X, MENU_Y + 15, 11, STARTITEM, 16, SoundSetupSoundNames, mn_smallfont };
+CP_itemtype SoundSetupSound[] =
+   {
+      { CP_CursorLocation, "\0",  'N', (menuptr)SS_SetupSoundCardMenu },
+      { CP_Active,         "\0",  'U', (menuptr)SS_SetupSoundCardMenu },
+      { CP_Active,         "\0",  'S', (menuptr)SS_SetupSoundCardMenu },
+      { CP_Active,         "\0",  'S', (menuptr)SS_SetupSoundCardMenu },
+      { CP_Active,         "\0",  'P', (menuptr)SS_SetupSoundCardMenu },
+      { CP_Active,         "\0",  'A', (menuptr)SS_SetupSoundCardMenu },
+      { CP_Active,         "\0",  'S', (menuptr)SS_SetupSoundCardMenu },
+      { CP_Active,         "\0",  'A', (menuptr)SS_SetupSoundCardMenu },
+      { CP_Active,         "\0",  'S', (menuptr)SS_SetupSoundCardMenu },
+      { CP_Active,         "\0",  'T', (menuptr)SS_SetupSoundCardMenu },
+      { CP_Active,         "\0",  'P', (menuptr)SS_SetupSoundCardMenu }
+   };
+
+CP_MenuNames SoundSetupMidiPortNames[] =
+   {
+   "220", "230", "240", "250", "300", "320",
+   "330", "332", "334", "336", "340", "360"
+   };
+
+CP_iteminfo SoundSetupMidiPortItems = { 108, MENU_Y + 10, 12, STARTITEM, 16, SoundSetupMidiPortNames, mn_smallfont };
+CP_itemtype SoundSetupMidiPort[] =
+   {
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_CursorLocation, "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL }
+   };
+
+CP_MenuNames SoundSetupVoiceNames[] =
+   {
+   "1 voice",
+   "2 voices",
+   "3 voices",
+   "4 voices",
+   "5 voices",
+   "6 voices",
+   "7 voices",
+   "8 voices"
+   };
+
+CP_iteminfo SoundSetupVoiceItems  = { MENU_X + 36, 24, 8, STARTITEM, 32, SoundSetupVoiceNames, mn_largefont };
+CP_itemtype SoundSetupVoice[] =
+   {
+      { CP_CursorLocation, "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL }
+   };
+
+CP_MenuNames SoundSetupChannelNames[] =
+   {
+   "  Mono Sound FX",
+   "Stereo Sound FX"
+   };
+
+CP_iteminfo SoundSetupChannelItems  = { MENU_X, MP_Y, 2, STARTITEM, 32, SoundSetupChannelNames, mn_largefont };
+CP_itemtype SoundSetupChannel[] =
+   {
+      { CP_CursorLocation, "\0",  'M', NULL },
+      { CP_Active,         "\0",  'S', NULL }
+   };
+
+CP_MenuNames SoundSetupResolutionNames[] =
+   {
+   "8 Bit Mixing",
+   "16 Bit Mixing"
+   };
+
+CP_iteminfo SoundSetupResolutionItems  = { MENU_X, MP_Y, 2, STARTITEM, 32, SoundSetupResolutionNames, mn_largefont };
+CP_itemtype SoundSetupResolution[] =
+   {
+      { CP_CursorLocation, "\0",  'a', NULL },
+      { CP_Active,         "\0",  'b', NULL }
+   };
+
+static int typenums[ 5 ] =
+   {
+   fx_SB, fx_SB20, fx_SBPro, fx_SBPro2, fx_SB16
+   };
+
+static char typetostring[ 6 ] =
+   {
+   5, 0, 2, 1, 3, 4
+   };
+
+#define UNDEFINED -1
+
+CP_MenuNames TypeNames[] =
+   {
+   "Sound Blaster or compatible",
+   "Sound Blaster 2.0",
+   "Sound Blaster Pro (old)",
+   "Sound Blaster Pro 2.0 (new)",
+   "Sound Blaster 16 or AWE32",
+   "Undefined"
+   };
+
+CP_iteminfo TypeItems  = { MENU_X - 13, MENU_Y + 36, 5, STARTITEM, 10, TypeNames, mn_smallfont };
+CP_itemtype TypeMenu[] =
+   {
+      { CP_CursorLocation, "\0",  'S', NULL },
+      { CP_Active,         "\0",  'S', NULL },
+      { CP_Active,         "\0",  'S', NULL },
+      { CP_Active,         "\0",  'S', NULL },
+      { CP_Active,         "\0",  'S', NULL }
+   };
+
+static int portnums[ 7 ] =
+   {
+   0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x280
+   };
+
+CP_MenuNames PortNames[] =
+   {
+   "210", "220", "230", "240", "250", "260", "280"
+   };
+
+CP_iteminfo PortItems = { 92, 32, 7, STARTITEM, 32, PortNames, mn_largefont };
+CP_itemtype PortMenu [] =
+   {
+      { CP_CursorLocation, "\0",  '2', NULL },
+      { CP_Active,         "\0",  '2', NULL },
+      { CP_Active,         "\0",  '2', NULL },
+      { CP_Active,         "\0",  '2', NULL },
+      { CP_Active,         "\0",  '2', NULL },
+      { CP_Active,         "\0",  '2', NULL },
+      { CP_Active,         "\0",  '2', NULL }
+   };
+
+static int _8BitDMAnums[ 3 ] =
+   {
+   0, 1, 3
+   };
+
+CP_MenuNames _8BitDMANames[] =
+   {
+   "DMA channel 0",
+   "DMA channel 1",
+   "DMA channel 3"
+   };
+
+CP_iteminfo _8BitDMAItems = { 32, 60, 3, STARTITEM, 32, _8BitDMANames, mn_largefont };
+CP_itemtype _8BitDMAMenu [] =
+   {
+      { CP_CursorLocation, "\0",  '0', NULL },
+      { CP_Active,         "\0",  '1', NULL },
+      { CP_Active,         "\0",  '3', NULL }
+   };
+
+static int _16BitDMAnums[ 3 ] =
+   {
+   5, 6, 7
+   };
+
+CP_MenuNames _16BitDMANames[] =
+   {
+   "DMA channel 5",
+   "DMA channel 6",
+   "DMA channel 7"
+   };
+
+CP_iteminfo _16BitDMAItems = { 32, 60, 3, STARTITEM, 32, _16BitDMANames, mn_largefont };
+CP_itemtype _16BitDMAMenu [] =
+   {
+      { CP_CursorLocation, "\0",  '5', NULL },
+      { CP_Active,         "\0",  '6', NULL },
+      { CP_Active,         "\0",  '7', NULL }
+   };
+
+static int irqnums[ 8 ] =
+   {
+   2, 3, 5, 7, 10, 11, 12, 15
+   };
+
+CP_MenuNames IrqNames[] =
+   {
+   "IRQ 2",
+   "IRQ 3",
+   "IRQ 5",
+   "IRQ 7",
+   "IRQ 10",
+   "IRQ 11",
+   "IRQ 12",
+   "IRQ 15"
+   };
+
+CP_iteminfo IrqItems = { 82, 24, 8, STARTITEM, 32, IrqNames, mn_largefont };
+CP_itemtype IrqMenu [] =
+   {
+      { CP_CursorLocation, "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL },
+      { CP_Active,         "\0",  'a', NULL }
+   };
+
+CP_MenuNames SBSetupNames[] =
+   {
+   "Use Current Settings",
+   "Custom Setup"
+   };
+
+CP_iteminfo SBSetupItems  = { MENU_X - 11, MENU_Y + 76, 2, STARTITEM, 19, SBSetupNames, mn_largefont };
+CP_itemtype SBSetupMenu[] =
+   {
+      { CP_CursorLocation, "\0",  'U', SS_SetupSoundBlaster },
+      { CP_Active,         "\0",  'C', (menuptr)SS_SBTypeMenu },
+   };
+
+extern fx_blaster_config SBSettings;
+
+//******************************************************************************
+//
+// SS_DrawSBSetupMenu()
+//
+//******************************************************************************
+
+void SS_DrawSBSetupMenu
+   (
+   void
+   )
+
+   {
+   char text[ 80 ];
+   char num[ 10 ];
+   char *undefined;
+
+   MenuNum = SNDCARDS;
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Sound Blaster Setup" );
+
+   WindowW = 288;
+   WindowH = 158;
+   WindowX = 96;
+   WindowY = 32;
+   PrintX  = 0;
+   PrintY  = 32;
+
+   CurrentFont = tinyfont;
+
+   undefined = "Undefined";
+
+   SBSetupMenu[ 0 ].active = CP_Active;
+
+   PrintBattleOption( true, WindowX + 16, PrintY, "Current Settings:" );
+   PrintY += 9;
+
+   strcpy( text, "Card Type : " );
+
+   if ( ( SBSettings.Type < fx_SB ) || ( SBSettings.Type > fx_SB16 ) )
+      {
+      SBSettings.Type = UNDEFINED;
+      strcat( text, undefined );
+      SBSetupMenu[ 0 ].active = CP_Inactive;
+      }
+   else
+      {
+	  strcat( text, TypeNames[ (unsigned int)typetostring[ SBSettings.Type ] ] );
+      }
+
+   PrintBattleOption( true, WindowX, PrintY, text );
+   PrintY += 6;
+
+   strcpy( text, "Port : " );
+   if ( SBSettings.Address != (unsigned long)UNDEFINED )
+      {
+      itoa( SBSettings.Address, num, 16 );
+      strcat( text, num );
+      }
+   else
+      {
+      strcat( text, undefined );
+      SBSetupMenu[ 0 ].active = CP_Inactive;
+      }
+
+   PrintBattleOption( true, WindowX + 19, PrintY, text );
+   PrintY += 6;
+
+   strcpy( text, "IRQ : " );
+   if ( SBSettings.Interrupt != (unsigned long)UNDEFINED )
+      {
+      itoa( SBSettings.Interrupt, num, 10 );
+      strcat( text, num );
+      }
+   else
+      {
+      strcat( text, undefined );
+      SBSetupMenu[ 0 ].active = CP_Inactive;
+      }
+   PrintBattleOption( true, WindowX + 23, PrintY, text );
+   PrintY += 6;
+
+   strcpy( text, "DMA : " );
+   if ( SBSettings.Dma8 != (unsigned long)UNDEFINED )
+      {
+      itoa( SBSettings.Dma8, num, 10 );
+      strcat( text, num );
+      }
+   else
+      {
+      strcat( text, undefined );
+      SBSetupMenu[ 0 ].active = CP_Inactive;
+      }
+   PrintBattleOption( true, WindowX + 21, PrintY, text );
+   PrintY += 6;
+
+   strcpy( text, "16-Bit DMA : " );
+   if ( SBSettings.Dma16 != (unsigned long)UNDEFINED )
+      {
+      itoa( SBSettings.Dma16, num, 10 );
+      strcat( text, num );
+      }
+   else
+      {
+      strcat( text, undefined );
+      }
+   PrintBattleOption( true, WindowX - 4, PrintY, text );
+   PrintY += 6;
+
+   MN_GetCursorLocation( &SBSetupItems, &SBSetupMenu[ 0 ] );
+   DrawMenu( &SBSetupItems, &SBSetupMenu[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   RefreshMenuBuf( 0 );
+   }
+
+
+//******************************************************************************
+//
+// SS_DrawSBTypeMenu()
+//
+//******************************************************************************
+
+void SS_DrawSBTypeMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Select Sound Blaster Type" );
+   MN_GetActive( &TypeItems, &TypeMenu[ 0 ], SBSettings.Type, typenums );
+   DrawMenu( &TypeItems, &TypeMenu[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+//******************************************************************************
+//
+// SS_SBTypeMenu()
+//
+//******************************************************************************
+
+void SS_SBTypeMenu
+   (
+   void
+   )
+
+   {
+   int which;
+
+   do
+      {
+      SS_DrawSBTypeMenu();
+      which = HandleMenu( &TypeItems, &TypeMenu[0], NULL );
+      if ( which >= 0 )
+         {
+         SBSettings.Type = typenums[ which ];
+         SS_PortMenu();
+         if ( handlewhich == -1 )
+            {
+            continue;
+            }
+         return;
+         }
+      }
+   while( which >= 0 );
+
+   handlewhich = -2;
+   }
+
+//******************************************************************************
+//
+// SS_DrawPortMenu()
+//
+//******************************************************************************
+
+void SS_DrawPortMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Select Sound Blaster Port" );
+   MN_GetActive( &PortItems, &PortMenu[ 0 ], SBSettings.Address, portnums );
+   DrawMenu( &PortItems, &PortMenu[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+//******************************************************************************
+//
+// SS_PortMenu()
+//
+//******************************************************************************
+
+void SS_PortMenu
+   (
+   void
+   )
+
+   {
+   int which;
+
+   do
+      {
+      SS_DrawPortMenu();
+      which = HandleMenu( &PortItems, &PortMenu[0], NULL );
+      if ( which >= 0 )
+         {
+         SBSettings.Address = portnums[ which ];
+         SBSettings.Emu = SBSettings.Address;
+         SS_8BitDMAMenu();
+         if ( handlewhich == -1 )
+            {
+            continue;
+            }
+         return;
+         }
+      }
+   while( which >= 0 );
+
+   handlewhich = -1;
+   }
+
+//******************************************************************************
+//
+// SS_Draw8BitDMAMenu()
+//
+//******************************************************************************
+
+void SS_Draw8BitDMAMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Select 8-bit DMA Channel" );
+   MN_GetActive( &_8BitDMAItems, &_8BitDMAMenu[ 0 ], SBSettings.Dma8, _8BitDMAnums );
+   DrawMenu( &_8BitDMAItems, &_8BitDMAMenu[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+//******************************************************************************
+//
+// SS_8BitDMAMenu()
+//
+//******************************************************************************
+
+void SS_8BitDMAMenu
+   (
+   void
+   )
+
+   {
+   int which;
+
+   do
+      {
+      SS_Draw8BitDMAMenu();
+      which = HandleMenu( &_8BitDMAItems, &_8BitDMAMenu[0], NULL );
+      if ( which >= 0 )
+         {
+         SBSettings.Dma8 = _8BitDMAnums[ which ];
+         SS_16BitDMAMenu();
+         if ( handlewhich == -1 )
+            {
+            continue;
+            }
+         return;
+         }
+      }
+   while( which >= 0 );
+
+   handlewhich = -1;
+   }
+
+//******************************************************************************
+//
+// SS_Draw16BitDMAMenu()
+//
+//******************************************************************************
+
+void SS_Draw16BitDMAMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Select 16-bit DMA Channel" );
+   MN_GetActive( &_16BitDMAItems, &_16BitDMAMenu[ 0 ], SBSettings.Dma16, _16BitDMAnums );
+   DrawMenu( &_16BitDMAItems, &_16BitDMAMenu[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+//******************************************************************************
+//
+// SS_16BitDMAMenu()
+//
+//******************************************************************************
+
+void SS_16BitDMAMenu
+   (
+   void
+   )
+
+   {
+   int which;
+
+   if ( SBSettings.Type != fx_SB16 )
+      {
+      SS_IrqMenu();
+      return;
+      }
+
+   do
+      {
+      SS_Draw16BitDMAMenu();
+      which = HandleMenu( &_16BitDMAItems, &_16BitDMAMenu[0], NULL );
+      if ( which >= 0 )
+         {
+         SBSettings.Dma16 = _16BitDMAnums[ which ];
+         SS_IrqMenu();
+         if ( handlewhich == -1 )
+            {
+            continue;
+            }
+         return;
+         }
+      }
+   while( which >= 0 );
+
+   handlewhich = -1;
+   }
+
+//******************************************************************************
+//
+// SS_DrawIrqMenu()
+//
+//******************************************************************************
+
+void SS_DrawIrqMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Select Sound Blaster IRQ" );
+   MN_GetActive( &IrqItems, &IrqMenu[ 0 ], SBSettings.Interrupt, irqnums );
+   DrawMenu( &IrqItems, &IrqMenu[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+//******************************************************************************
+//
+// SS_IrqMenu()
+//
+//******************************************************************************
+
+void SS_IrqMenu
+   (
+   void
+   )
+
+   {
+   int which;
+
+   do
+      {
+      SS_DrawIrqMenu();
+      which = HandleMenu( &IrqItems, &IrqMenu[0], NULL );
+
+      if ( which >= 0 )
+         {
+         SBSettings.Interrupt = irqnums[ which ];
+         SS_SetupSoundBlaster( true );
+
+         if ( handlewhich == -1 )
+            {
+            continue;
+            }
+
+         return;
+         }
+      }
+   while( which >= 0 );
+
+   handlewhich = -1;
+   }
+#endif
+
+
+//******************************************************************************
+//
+// GetNextWord()
+//
+//******************************************************************************
+char *GetNextWord
+   (
+   char *dest,
+   char *source,
+   int  length
+   )
+
+   {
+   while( ( *source != 0 ) && ( isspace( *source ) ) && ( length > 0 ) )
+      {
+      *dest = *source;
+      length--;
+      dest++;
+      source++;
+      }
+
+   while( ( *source != 0 ) && ( !isspace( *source ) ) && ( length > 0 ) )
+      {
+      *dest = *source;
+      length--;
+      dest++;
+      source++;
+      }
+
+   *dest = 0;
+   return( source );
+   }
+
+//******************************************************************************
+//
+// CP_ErrorMsg()
+//
+//******************************************************************************
+
+void CP_ErrorMsg
+   (
+   char *title,
+   char *error,
+   int font
+   )
+
+   {
+   char wordtext[ 80 ];
+   char text[ 10 ][ 80 ];
+   int  pos;
+   int  length;
+   int  line;
+   int  w;
+   int  h;
+   int  y;
+   extern void VWL_MeasureIntensityString (char *s, int *width, int *height, cfont_t *font);
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( title );
+
+   WindowW = 288;
+   WindowH = 158;
+   WindowX = 0;
+   WindowY = 40;
+
+   IFont = ( cfont_t * )W_CacheLumpName( FontNames[ font ], PU_CACHE, Cvt_cfont_t, 1 );
+
+   pos = 0;
+   line = 0;
+
+   text[ 0 ][ 0 ] = 0;
+
+   while( *error != 0 )
+      {
+      error = GetNextWord( wordtext, error, 79 );
+
+      pos = 0;
+      while( ( wordtext[ pos ] != 0 ) && ( isspace( wordtext[ pos ] ) ) )
+         {
+         pos++;
+         }
+
+      length = strlen( text[ line ] );
+      if ( length == 0 )
+         {
+         strcat( text[ line ], &wordtext[ pos ] );
+         }
+      else
+         {
+         strcat( text[ line ], wordtext );
+         }
+
+      VWL_MeasureIntensityString( text[ line ], &w, &h, IFont );
+
+      if ( w > WindowW - 32 )
+         {
+         text[ line ][ length ] = 0;
+         if ( line >= 10 )
+            {
+            break;
+            }
+         line++;
+         strcpy( text[ line ], &wordtext[ pos ] );
+         }
+      }
+
+   if ( strlen( text[ line ] ) == 0 )
+      {
+      line--;
+      }
+
+   VWL_MeasureIntensityString( text[ 0 ], &w, &h, IFont );
+
+   y = ( WindowH - ( line + 1 ) * h ) / 2;
+
+   for( pos = 0; pos <= line; pos++ )
+      {
+      VWL_MeasureIntensityString( text[ pos ], &w, &h, IFont );
+      DrawMenuBufIString( ( 288 - w ) / 2, y, text[ pos ], ACTIVECOLOR );
+      y += h;
+      }
+
+   DisplayInfo( 5 );
+   FlipMenuBuf();
+   RefreshMenuBuf( 0 );
+
+   IN_Ack();
+   WaitKeyUp();
+
+   MN_PlayMenuSnd( SD_ESCPRESSEDSND );
+   }
+
+#ifdef DOS
+
+//****************************************************************************
+//
+// DrawSoundSetupMainMenu ()
+//
+//****************************************************************************
+void DrawSoundSetupMainMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = 1;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Sound Setup" );
+   if ( FXMode == 0 )
+      {
+      SoundSetupMenu[ 2 ].active = CP_Inactive;
+      }
+   else if ( SoundSetupMenu[ 2 ].active == CP_Inactive )
+      {
+      SoundSetupMenu[ 2 ].active = CP_Active;
+      }
+
+   if ( MusicMode == 0 )
+      {
+      SoundSetupMenu[ 3 ].active = CP_Inactive;
+      }
+   else if ( SoundSetupMenu[ 3 ].active == CP_Inactive )
+      {
+      SoundSetupMenu[ 3 ].active = CP_Active;
+      }
+
+   MN_GetCursorLocation( &SoundSetupMenuItems, &SoundSetupMenu[ 0 ] );
+   DrawMenu( &SoundSetupMenuItems, &SoundSetupMenu[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+
+//******************************************************************************
+//
+// Sound Setup Quit
+//
+//******************************************************************************
+
+void SS_Quit
+   (
+   void
+   )
+
+   {
+   extern boolean WriteSoundFile;
+
+   CP_DisplayMsg( "Do you wish to\nsave your changes?\n"
+      "Press ESC to return\nto sound setup.", 12 );
+
+   if ( CP_Acknowledge != CP_ESC )
+      {
+      WriteSoundFile = true;
+      if ( CP_Acknowledge == CP_NO )
+         {
+         WriteSoundFile = false;
+         }
+
+      MU_FadeOut(310);
+      VL_FadeOut (0, 255, 0, 0, 0, 10);
+      ShutdownMenuBuf();
+      QuitGame ();
+      }
+
+   DrawSoundSetupMainMenu();
+   }
+
+//******************************************************************************
+//
+// Sound Setup
+//
+//******************************************************************************
+
+void CP_SoundSetup ( void )
+   {
+   int which;
+   extern boolean WriteSoundFile;
+
+   WriteSoundFile = false;
+
+   SetupMenuBuf();
+   DrawSoundSetupMainMenu();
+   IN_ClearKeysDown();
+
+   if ( MusicMode != 0 )
+      {
+      MU_StartSong( song_title );
+      }
+
+   while( 1 )
+      {
+      which = HandleMenu( &SoundSetupMenuItems, SoundSetupMenu, NULL );
+      if ( which == -1 )
+         {
+         SS_Quit();
+         }
+      }
+   }
+
+//******************************************************************************
+//
+// SS_MusicMenu ()
+//
+//******************************************************************************
+
+void SS_MusicMenu
+   (
+   void
+   )
+
+   {
+   int which;
+
+   MN_MakeActive( &SoundSetupMusicItems, &SoundSetupMusic[ 0 ], MusicMode );
+
+   SS_DrawMusicMenu ();
+   IN_ClearKeysDown();
+
+   do
+      {
+      which = HandleMenu( &SoundSetupMusicItems, &SoundSetupMusic[ 0 ], NULL );
+      }
+   while( which > 0 );
+
+   DrawSoundSetupMainMenu();
+   handlewhich = RETURNVAL;
+   }
+
+
+//******************************************************************************
+//
+// SS_DrawMusicMenu ()
+//
+//******************************************************************************
+
+void SS_DrawMusicMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Select Music Card" );
+
+   MN_GetCursorLocation( &SoundSetupMusicItems, &SoundSetupMusic[ 0 ] );
+   DrawMenu( &SoundSetupMusicItems, &SoundSetupMusic[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+
+//******************************************************************************
+//
+// SS_SetupMusicCardMenu()
+//
+//******************************************************************************
+
+void SS_SetupMusicCardMenu
+   (
+   void
+   )
+
+   {
+   int status;
+   int select;
+   if ( ( ( musicnums[ handlewhich ] == SoundBlaster ) ||
+      ( musicnums[ handlewhich ] == WaveBlaster ) ||
+      ( musicnums[ handlewhich ] == Awe32 ) ) &&
+      ( fxnums[ FXMode ] != SoundBlaster ) &&
+      ( fxnums[ FXMode ] != Awe32 ) )
+      {
+      CP_ErrorMsg( "Music Error",
+         "Please set your Sound FX card to Sound Blaster before "
+         "selecting this card for music.", mn_smallfont );
+
+      handlewhich = -1;
+      return;
+      }
+
+   MusicMode = handlewhich;
+
+   MU_Shutdown();
+
+   if ( ( musicnums[ MusicMode ] == GenMidi ) ||
+      ( musicnums[ MusicMode ] == SoundCanvas ) ||
+      ( musicnums[ MusicMode ] == WaveBlaster ) ||
+      ( musicnums[ MusicMode ] == Awe32 ) )
+      {
+      DrawMusicCardMenu();
+
+      IN_ClearKeysDown ();
+
+      select = HandleMenu( &SoundSetupMidiPortItems,
+         &SoundSetupMidiPort[0], NULL );
+
+      if ( select > -1 )
+         {
+         MidiAddress = midinums[ select ];
+         }
+      else
+         {
+         SS_DrawMusicMenu ();
+         handlewhich = RETURNVAL;
+         MusicMode = 0;
+         return;
+         }
+      }
+
+   if ( MusicMode != 0 )
+      {
+      if ( ( musicnums[ handlewhich ] == WaveBlaster ) ||
+         ( musicnums[ handlewhich ] == Awe32 ) )
+         {
+         SD_Shutdown();
+         }
+
+      SetAlternateMenuBuf();
+      ClearMenuBuf();
+      SetMenuTitle( "Music Card Initialization" );
+      WindowW = 288;
+      WindowH = 158;
+      PrintX = WindowX = 0;
+      PrintY = WindowY = 65;
+      newfont1 = (font_t *)W_CacheLumpName( "newfnt1", PU_CACHE, Cvt_font_t, 1 );
+      CurrentFont = newfont1;
+      MenuBufCPrint( "Initializing card.\nPlease wait." );
+      FlipMenuBuf();
+      RefreshMenuBuf( 0 );
+
+      status = MU_Startup( false );
+      if ( status )
+         {
+         MusicMode = 0;
+
+         CP_ErrorMsg( "Music Error", MUSIC_ErrorString( MUSIC_Error ),
+            mn_smallfont );
+         SS_DrawMusicMenu ();
+         handlewhich = RETURNVAL;
+         }
+      else
+         {
+         handlewhich = -1;
+         MU_StartSong( song_title );
+         }
+
+      if ( ( musicnums[ MusicMode ] == WaveBlaster ) ||
+         ( musicnums[ MusicMode ] == Awe32 ) )
+         {
+         status = SD_Startup( false );
+            if ( status != FX_Ok )
+            {
+            CP_ErrorMsg( "Sound FX Error", FX_ErrorString( FX_Error ),
+               mn_smallfont );
+
+            handlewhich = -2;
+            }
+         }
+      }
+   else
+      {
+      handlewhich = -1;
+      MU_Shutdown();
+      }
+   }
+
+
+//******************************************************************************
+//
+// DrawMusicCardMenu()
+//
+//******************************************************************************
+
+void DrawMusicCardMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle( "Select MIDI Port Address" );
+   MN_GetActive( &SoundSetupMidiPortItems, &SoundSetupMidiPort[ 0 ],
+      MidiAddress, midinums );
+   DrawMenu( &SoundSetupMidiPortItems, &SoundSetupMidiPort[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+//******************************************************************************
+//
+// SS_SoundMenu ()
+//
+//******************************************************************************
+
+void SS_SoundMenu
+   (
+   void
+   )
+
+   {
+   int which;
+
+   MN_MakeActive( &SoundSetupSoundItems, &SoundSetupSound[0], FXMode );
+
+   SS_DrawSoundMenu ();
+   IN_ClearKeysDown();
+
+   do {
+      which = HandleMenu( &SoundSetupSoundItems, &SoundSetupSound[ 0 ], NULL );
+      }
+   while( which >= 0 );
+
+   DrawSoundSetupMainMenu();
+   handlewhich = RETURNVAL;
+   }
+
+
+//******************************************************************************
+//
+// SS_DrawSoundMenu ()
+//
+//******************************************************************************
+
+void SS_DrawSoundMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Select Sound FX Card");
+
+   MN_GetCursorLocation( &SoundSetupSoundItems, &SoundSetupSound[0] );
+
+   DrawMenu( &SoundSetupSoundItems, &SoundSetupSound[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+
+//******************************************************************************
+//
+// SS_SetupSoundBlaster()
+//
+//******************************************************************************
+
+void SS_SetupSoundBlaster
+   (
+   int sbmenu
+   )
+
+   {
+   int status;
+
+   status = FX_SetupSoundBlaster( SBSettings, &MaxVoices,
+      &MaxBits, &MaxChannels );
+
+   if ( status == FX_Ok )
+      {
+      SS_VoiceMenu( sbmenu );
+
+      if ( handlewhich < 0 )
+         {
+         return;
+         }
+      SetAlternateMenuBuf();
+      ClearMenuBuf();
+      SetMenuTitle( "Sound Card Initialization" );
+      WindowW = 288;
+      WindowH = 158;
+      PrintX = WindowX = 0;
+      PrintY = WindowY = 65;
+      newfont1 = (font_t *)W_CacheLumpName( "newfnt1", PU_CACHE, Cvt_font_t, 1 );
+      CurrentFont = newfont1;
+      MenuBufCPrint( "Initializing card.\nPlease wait." );
+      FlipMenuBuf();
+      RefreshMenuBuf( 0 );
+
+      status = SD_Startup( false );
+
+      RefreshMenuBuf( 0 );
+      }
+
+   if ( status != FX_Ok )
+      {
+      CP_ErrorMsg( "Sound FX Error", FX_ErrorString( FX_Error ),
+         mn_smallfont );
+
+      handlewhich = -2;
+      }
+   }
+
+
+//******************************************************************************
+//
+// SS_SetupSoundCardMenu()
+//
+//******************************************************************************
+
+void SS_SetupSoundCardMenu
+   (
+   void
+   )
+
+   {
+   int which;
+   int FXstatus;
+   extern int fxnums[];
+
+   INFXSETUP = true;
+
+   FXMode = handlewhich;
+
+   SD_Shutdown();
+
+   if ( FXMode == 0 )
+      {
+      handlewhich = -1;
+      }
+   else
+      {
+      if ( ( fxnums[ FXMode ] == SoundBlaster ) ||
+         ( fxnums[ FXMode ] == Awe32 ) )
+         {
+         do
+            {
+            SS_DrawSBSetupMenu();
+            which = HandleMenu( &SBSetupItems, &SBSetupMenu[ 0 ], NULL );
+            }
+         while( which == -2 );
+
+         if ( which == -1 )
+            {
+            FXMode = 0;
+            handlewhich = 0;
+            SS_DrawSoundMenu();
+            }
+         else
+            {
+            handlewhich = -1;
+            }
+
+         INFXSETUP = false;
+         return;
+         }
+
+      FXstatus = SD_SetupFXCard( &MaxVoices, &MaxBits, &MaxChannels );
+      if ( FXstatus == FX_Ok )
+         {
+         SS_VoiceMenu( true );
+
+         if ( handlewhich == -1 )
+            {
+            SS_DrawSoundMenu ();
+            handlewhich = RETURNVAL;
+            FXMode = 0;
+            SD_Shutdown ();
+            INFXSETUP = false;
+            return;
+            }
+
+         SetAlternateMenuBuf();
+         ClearMenuBuf();
+         SetMenuTitle( "Sound Card Initialization" );
+         WindowW = 288;
+         WindowH = 158;
+         PrintX = WindowX = 0;
+         PrintY = WindowY = 65;
+         newfont1 = (font_t *)W_CacheLumpName( "newfnt1", PU_CACHE, Cvt_font_t, 1 );
+         CurrentFont = newfont1;
+         MenuBufCPrint( "Initializing card.\nPlease wait." );
+         FlipMenuBuf();
+         RefreshMenuBuf( 0 );
+
+         FXstatus = SD_Startup( false );
+
+         RefreshMenuBuf( 0 );
+         }
+
+      if ( FXstatus != FX_Ok )
+         {
+         FXMode = 0;
+         handlewhich = RETURNVAL;
+
+         CP_ErrorMsg( "Sound FX Error", FX_ErrorString( FX_Error ),
+            mn_smallfont );
+         SS_DrawSoundMenu();
+         }
+      else
+         {
+         handlewhich = -1;
+         }
+      }
+
+   INFXSETUP = false;
+   }
+
+
+//******************************************************************************
+//
+// SS_VoiceMenu ()
+//
+//******************************************************************************
+
+void SS_VoiceMenu
+   (
+   int sbmenu
+   )
+
+   {
+   int which;
+
+   if ( MaxVoices < 2 )
+      {
+      NumVoices = 1;
+      SS_ChannelMenu();
+      return;
+      }
+
+   do
+      {
+      SS_DrawVoiceMenu ();
+
+      which = HandleMenu( &SoundSetupVoiceItems, &SoundSetupVoice[0],
+         NULL );
+      if ( which >= 0 )
+         {
+         NumVoices = voicenums[ which ];
+         SS_ChannelMenu();
+         if ( handlewhich == -1 )
+            {
+            continue;
+            }
+         return;
+         }
+      }
+   while( which >= 0 );
+
+   if ( sbmenu )
+      {
+      handlewhich = -1;
+      }
+   else
+      {
+      handlewhich = -2;
+      }
+   }
+
+//******************************************************************************
+//
+// SS_DrawVoiceMenu()
+//
+//******************************************************************************
+
+void SS_DrawVoiceMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Number of Voices");
+
+   MN_GetActive( &SoundSetupVoiceItems, &SoundSetupVoice[0],
+      NumVoices, voicenums );
+
+   DrawMenu( &SoundSetupVoiceItems, &SoundSetupVoice[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+//******************************************************************************
+//
+// SS_ChannelMenu ()
+//
+//******************************************************************************
+
+void SS_ChannelMenu
+   (
+   void
+   )
+
+   {
+   int which;
+
+   if ( MaxChannels < 2 )
+      {
+      NumChannels = 1;
+      SS_BitMenu();
+      return;
+      }
+
+   do
+      {
+      SS_DrawChannelMenu ();
+      which = HandleMenu( &SoundSetupChannelItems, &SoundSetupChannel[0],
+         NULL );
+      if ( which >= 0 )
+         {
+         NumChannels = smnums[ which ];
+         SS_BitMenu();
+         if ( handlewhich == -1 )
+            {
+            continue;
+            }
+         return;
+         }
+      }
+   while( which >= 0 );
+
+   handlewhich = -1;
+   }
+
+//******************************************************************************
+//
+// SS_DrawChannelMenu()
+//
+//******************************************************************************
+
+void SS_DrawChannelMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Number of Channels");
+
+   MN_GetActive( &SoundSetupChannelItems, &SoundSetupChannel[0],
+      NumChannels, smnums );
+
+   DrawMenu( &SoundSetupChannelItems, &SoundSetupChannel[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+
+//******************************************************************************
+//
+// SS_BitMenu ()
+//
+//******************************************************************************
+
+void SS_BitMenu
+   (
+   void
+   )
+
+   {
+   int which;
+
+   if ( MaxBits < 16 )
+      {
+      NumBits = 8;
+      return;
+      }
+
+   SS_DrawBitMenu ();
+
+   which = HandleMenu( &SoundSetupResolutionItems,
+      &SoundSetupResolution[0], NULL );
+
+   if ( which >= 0 )
+      {
+      NumBits = resnums[ which ];
+      return;
+      }
+
+   handlewhich = -1;
+   }
+
+
+//******************************************************************************
+//
+// SS_DrawBitMenu()
+//
+//******************************************************************************
+
+void SS_DrawBitMenu
+   (
+   void
+   )
+
+   {
+   MenuNum = SNDCARDS;
+
+   SetAlternateMenuBuf();
+   ClearMenuBuf();
+   SetMenuTitle ("Playback Resolution");
+
+   MN_GetActive( &SoundSetupResolutionItems, &SoundSetupResolution[0],
+      NumBits, resnums );
+
+   DrawMenu( &SoundSetupResolutionItems, &SoundSetupResolution[ 0 ] );
+   DisplayInfo( 0 );
+
+   FlipMenuBuf();
+   }
+#endif

Added: tags/rott-1.1/rott/rt_menu.h
===================================================================
--- tags/rott-1.1/rott/rt_menu.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_menu.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,216 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_menu_public
+#define _rt_menu_public
+
+//******************************************************************************
+//
+// Public header for RT_MENU.C.
+//
+//******************************************************************************
+
+#include "lumpy.h"
+#include "rt_in.h"
+
+#define MaxX            320
+#define MaxY            200
+#define MaxString       128
+
+#define SaveGamePicX    18
+#define SaveGamePicY    18
+
+//******************************************************************************
+//
+// TYPEDEFS
+//
+//******************************************************************************
+
+typedef enum
+   {
+   mn_tinyfont,
+   mn_8x8font,
+   mn_smallfont,
+   mn_largefont
+   } mn_fontsize;
+
+typedef char CP_MenuNames[64];
+
+typedef struct
+   {
+   int x;
+   int y;
+   int amount;
+   int curpos;
+   int indent;
+   CP_MenuNames *names;
+   mn_fontsize  fontsize;
+   } CP_iteminfo;
+
+
+//MED
+typedef void (*menuptr)(int);
+
+typedef struct
+{
+   int active;
+   char texture[9];
+   char letter;
+   void (* routine)(int temp1);
+} CP_itemtype;
+
+enum
+   {
+   CP_Inactive,
+   CP_Active,
+   CP_CursorLocation,
+   CP_Active3
+   };
+
+//******************************************************************************
+//
+// GLOBALS
+//
+//******************************************************************************
+
+extern char*colorname[];
+extern boolean NewGame;
+
+extern CP_itemtype MainMenu[];
+extern boolean pickquick;
+
+extern cfont_t *IFont;
+extern font_t *CurrentFont;
+extern font_t *tinyfont;
+
+//
+// Global window coords
+//
+extern int PrintX;
+extern int PrintY;
+extern int WindowX;
+extern int WindowY;
+extern int WindowH;
+extern int WindowW;
+
+extern int px;
+extern int py;
+extern int bufferheight;
+extern int bufferwidth;
+extern boolean loadedgame;
+extern int FXMode;
+extern int MusicMode;
+
+extern font_t *newfont1;
+extern font_t *smallfont;
+extern font_t *bigfont;
+
+
+extern boolean AutoDetailOn;
+extern boolean DoubleClickOn;
+extern boolean BobbinOn;
+extern int     Menuflipspeed;
+extern int     DetailLevel;
+
+extern boolean          ingame;
+extern boolean          inmenu;
+extern int              scancode;
+
+extern int quicksaveslot;
+
+//****************************************************************************
+//
+// TYPEDEFS
+//
+//****************************************************************************
+typedef enum
+{
+   newgame,
+   battlemode,
+   loadgame,
+   savegame,
+   control,
+   orderinfo,
+   viewscores,
+   backtodemo,
+   quit
+} menuitems;
+
+
+
+//****************************************************************************
+//
+// PROTOTYPES
+//
+//****************************************************************************
+
+int  CP_ColorSelection(void);
+void CP_BattleMode(void);
+void DisplayInfo (int which);
+boolean CP_DisplayMsg (char *s, int number);
+void Message (char *string);
+void DrawMenu (CP_iteminfo *item_i, CP_itemtype *items);
+void DrawMainMenu(void);
+void AllocateSavedScreenPtr (void);
+void FreeSavedScreenPtr (void);
+void CleanUpControlPanel (void);
+void SetUpControlPanel (void);
+void ControlPanel (byte scancode);
+menuitems CP_MainMenu( void );
+int getASCII ( void );
+void DoMainMenu (void);
+boolean CP_CheckQuick (byte scancode);
+void AdjustMenuStruct (void);
+void MenuFixup (void);
+void GetEpisode (int level);
+void MN_PlayMenuSnd (int which);
+void CP_ViewScores (void);
+void ReadAnyControl (ControlInfo *ci);
+void WaitKeyUp (void);
+
+void GetMenuInfo (void);
+void WriteMenuInfo (void);
+int GetNumActive (CP_iteminfo *item_i, CP_itemtype *items);
+int MN_GetActive (CP_iteminfo *item_i, CP_itemtype *items, int check, int *nums);
+void MN_MakeActive (CP_iteminfo *item_i, CP_itemtype *items, int which);
+void MN_PlayMenuSnd (int which);
+
+int CP_LoadGame (int quick, int dieload);
+
+int CP_PlayerSelection (void);
+void BattleGamePlayerSetup( void );
+void BattleNoTeams( void );
+void BattleTeams( void );
+void CP_BattleMenu (void);
+void CP_BattleModes (void);
+void CP_ModemGameMessage ( int player );
+void ShowBattleOptions( boolean inmenu, int PosX, int PosY );
+void SetMenuHeader( char *header );
+int  HandleMultiPageCustomMenu( char **names, int amount, int curpos, char *title, void ( *routine )( int w ), void ( *redrawfunc )( void ), boolean exitonselect );
+int CP_LevelSelectionMenu ( void );
+int CP_EnterCodeNameMenu ( void );
+#ifdef DOS
+void CP_SoundSetup( void );
+#endif
+void QuickSaveGame (void);
+void UndoQuickSaveGame (void);
+void CP_CaptureTheTriadError( void );
+void CP_TeamPlayErrorMessage( void );
+
+#endif

Added: tags/rott-1.1/rott/rt_msg.c
===================================================================
--- tags/rott-1.1/rott/rt_msg.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_msg.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,812 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "rt_view.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "lumpy.h"
+#include "rt_util.h"
+#include "rt_vid.h"
+#include "rt_str.h"
+#include "rt_menu.h"
+#include "_rt_msg.h"
+#include "rt_msg.h"
+#include "rt_playr.h"
+#include "isr.h"
+#include "rt_main.h"
+#include "rt_net.h"
+#include "rt_com.h"
+
+#ifdef DOS
+#include <mem.h>
+#endif
+
+#include <stdlib.h>
+//MED
+#include "memcheck.h"
+
+
+/*
+=============================================================================
+
+                               GLOBALS
+
+=============================================================================
+*/
+messagetype Messages[MAXMSGS];
+
+/*
+=============================================================================
+
+                               LOCAL
+
+=============================================================================
+*/
+
+static int  UpdateMessageBackground;
+static int  MessageSystemStarted=0;
+static int  LastMessageTime;
+static boolean EraseMessage[ MAXMSGS ];
+static int     MessageOrder[ MAXMSGS ];
+static int     TotalMessages = 0;
+static int     MsgPos = 0;
+
+boolean MessagesEnabled = true;
+
+int StringLength (char *string)
+{
+	int length=0;
+
+   while ((*string)!=0)
+      {
+      length++;
+      string++;
+      }
+
+   length++;
+
+   return length;
+}
+
+/*
+====================
+=
+= ResetMessageTime
+=
+====================
+*/
+
+void ResetMessageTime ( void )
+{
+   LastMessageTime=GetTicCount();
+}
+
+/*
+====================
+=
+= InitializeMessages
+=
+====================
+*/
+void InitializeMessages
+   (
+   void
+   )
+
+   {
+   int i;
+   boolean start;
+
+   start = false;
+
+   if ( MessageSystemStarted == 0 )
+      {
+      start = true;
+      MessageSystemStarted = 1;
+      memset( Messages, 0, sizeof( Messages ) );
+      }
+
+   for ( i = 0; i < MAXMSGS; i++ )
+      {
+      if ( Messages[ i ].active == 1 )
+         {
+         SafeFree( Messages[ i ].text );
+         Messages[ i ].active  = 0;
+         Messages[ i ].tictime = 0;
+         Messages[ i ].flags   = 0;
+         Messages[ i ].text    = NULL;
+         }
+      }
+
+   MSG.messageon = false;
+
+   LastMessageTime = 0;
+   UpdateMessageBackground = 0;
+   TotalMessages = 0;
+   memset( EraseMessage,  0, sizeof( EraseMessage ) );
+   memset( MessageOrder, -1, sizeof( MessageOrder ) );
+
+   // Only print startup message if it's the first time in
+   if ( start && !quiet )
+      {
+      printf( "RT_MSG: Message System Started\n" );
+      }
+   }
+
+
+/*
+====================
+=
+= GetMessageOrder
+=
+====================
+*/
+void GetMessageOrder
+   (
+   void
+   )
+
+   {
+   int  i;
+   int  lowest;
+   int  lowesttime;
+   byte done[ MAXMSGS ];
+   boolean found;
+
+   memset( &done[ 0 ],    0, sizeof( done ) );
+   memset( MessageOrder, -1, sizeof( MessageOrder ) );
+
+   for( TotalMessages = 0; TotalMessages < MAXMSGS; TotalMessages++ )
+      {
+      found = false;
+      lowesttime = 1000;
+      lowest = 0;
+
+      for( i = 0; i < MAXMSGS; i++ )
+         {
+         if ( ( Messages[ i ].active == 1 ) && ( done[ i ] == 0 ) &&
+            ( Messages[ i ].tictime < lowesttime ) )
+            {
+            lowesttime = Messages[ i ].tictime;
+            lowest = i;
+            found = true;
+            }
+         }
+
+      if ( !found )
+         {
+         break;
+         }
+
+      done[ lowest ] = 1;
+      MessageOrder[ TotalMessages ] = lowest;
+      }
+   }
+
+
+/*
+====================
+=
+= DeleteMessage
+=
+====================
+*/
+void DeleteMessage
+   (
+   int num
+   )
+
+   {
+   int i;
+   int msg;
+   boolean found;
+
+   found = false;
+   for( i = 0; i < TotalMessages; i++ )
+      {
+      msg = MessageOrder[ i ];
+
+      if ( msg == num )
+         {
+         found = true;
+         }
+
+      if ( found )
+         {
+         UpdateMessageBackground -= EraseMessage[ i ];
+         UpdateMessageBackground += 3;
+         EraseMessage[ i ] = 3;
+         }
+      }
+
+   SafeFree( Messages[ num ].text );
+   memset( &Messages[ num ], 0, sizeof( messagetype ) );
+
+   GetMessageOrder();
+   }
+
+
+/*
+====================
+=
+= DeletePriorityMessage
+=
+====================
+*/
+void DeletePriorityMessage ( int flags )
+{
+   int i;
+
+   for (i=0;i<MAXMSGS;i++)
+      {
+      if (Messages[i].active==1)
+         {
+         if (Messages[i].flags==flags)
+            DeleteMessage(i);
+         }
+      }
+}
+
+
+/*
+====================
+=
+= GetFreeMessage
+=
+====================
+*/
+int GetFreeMessage
+   (
+   void
+   )
+
+   {
+   int i;
+   int found;
+
+   for( i = 0; i < MAXMSGS; i++ )
+      {
+      if ( Messages[ i ].active == 0 )
+         {
+         return( i );
+         }
+      }
+
+   found = -1;
+
+   for( i = 0; i < MAXMSGS; i++ )
+      {
+      if ( Messages[ i ].tictime >= 0 )
+         {
+         if ( found == -1 )
+            {
+            found = i;
+            }
+         else
+            {
+            if ( Messages[ i ].tictime < Messages[ found ].tictime )
+               {
+               found = i;
+               }
+            }
+         }
+      }
+
+   DeleteMessage( found );
+
+   return( found );
+   }
+
+
+/*
+====================
+=
+= SetMessage
+=
+====================
+*/
+void SetMessage
+   (
+   int   num,
+   char *text,
+   int   flags
+   )
+
+   {
+   int i;
+   int msg;
+   int length;
+   boolean found;
+
+   if (iGLOBAL_SCREENWIDTH >= 640){
+		CurrentFont = newfont1;//smallfont;
+   }else{
+		CurrentFont = smallfont;
+   }
+
+
+   length = StringLength( text );
+
+   Messages[ num ].active = 1;
+   Messages[ num ].flags  = flags;
+
+   if ( PERMANENT_MSG( flags ) )
+      {
+      int l;
+
+      l = COM_MAXTEXTSTRINGLENGTH + 1;
+      Messages[ num ].text = SafeMalloc( l );
+      memset( Messages[ num ].text, 0, l );
+
+      // Hack so that we can place menu in certain order
+      Messages[ num ].tictime = -100 + MsgPos;
+      }
+   else
+      {
+      Messages[ num ].text = SafeMalloc( length );
+
+      memset( Messages[ num ].text, 0, length );
+      Messages[ num ].tictime = MESSAGETIME;
+      }
+
+   memcpy( Messages[ num ].text, text, length );
+
+   GetMessageOrder();
+   found = false;
+   for( i = 0; i < TotalMessages; i++ )
+      {
+      msg = MessageOrder[ i ];
+      if ( msg == num )
+         {
+         found = true;
+         }
+      else if ( found )
+         {
+         UpdateMessageBackground -= EraseMessage[ i - 1 ];
+         UpdateMessageBackground += 3;
+         EraseMessage[ i - 1 ] = 3;
+         }
+      }
+   }
+
+
+/*
+====================
+=
+= AddMessage
+=
+====================
+*/
+int AddMessage
+   (
+   char *text,
+   int flags
+   )
+
+   {
+   int new;
+
+   if ( MessageSystemStarted == 0 )
+      {
+      Error( "Called AddMessage without starting Message system\n" );
+      }
+
+   if ( !( flags & MSG_NODELETE ) )
+      {
+      DeletePriorityMessage( flags );
+      }
+
+   new = GetFreeMessage();
+   SetMessage( new, text, flags );
+
+   return( new );
+   }
+
+/*
+====================
+=
+= UpdateMessages
+=
+====================
+*/
+void UpdateMessages
+   (
+   void
+   )
+
+   {
+   int messagetics;
+   int i;
+
+   messagetics = GetTicCount() - LastMessageTime;
+   LastMessageTime = GetTicCount();
+
+   if ( GamePaused == true )
+      {
+      return;
+      }
+
+   for( i = 0; i < MAXMSGS; i++ )
+      {
+      if ( ( Messages[ i ].active == 1 ) &&
+         ( !PERMANENT_MSG( Messages[ i ].flags ) ) )
+         {
+         Messages[ i ].tictime -= messagetics;
+         if ( Messages[ i ].tictime <= 0 )
+            {
+            DeleteMessage( i );
+            }
+         }
+      }
+   }
+
+
+/*
+====================
+=
+= DisplayMessage
+=
+====================
+*/
+
+void DisplayMessage   (int num,int position)
+   {
+   PrintX = 1;
+   if (iGLOBAL_SCREENWIDTH > 320){
+		PrintY = 2 + ( position * (9*2) );
+   }else{
+		PrintY = 2 + ( position * (9*1) );
+   }
+
+
+   if ( SHOW_TOP_STATUS_BAR() )
+      {
+      PrintY += 16;
+      }
+   if ( !MessagesEnabled )
+      {
+      switch ( Messages[ num ].flags )
+         {
+         case MSG_QUIT:
+         case MSG_MACRO:
+         case MSG_MODEM:
+         case MSG_NAMEMENU:
+         case MSG_MSGSYSTEM:
+            break;
+
+         case MSG_REMOTERIDICULE:
+         case MSG_REMOTE:
+         case MSG_GAME:
+         case MSG_DOOR:
+         case MSG_BONUS:
+         case MSG_BONUS1:
+         case MSG_CHEAT:
+         case MSG_SYSTEM:
+         default :
+            DeleteMessage( num );
+            return;
+         }
+      }
+
+   switch ( Messages[ num ].flags )
+      {
+      case MSG_REMOTERIDICULE:
+      case MSG_REMOTE:
+         fontcolor = egacolor[ WHITE ];
+         break;
+
+      case MSG_MODEM:
+         fontcolor = egacolor[ LIGHTBLUE ];
+         DrawIString( PrintX, PrintY, "Message>", Messages[ num ].flags );
+		 if ( iGLOBAL_SCREENWIDTH == 320) {
+			PrintX += 8 * 8;
+		 }else if ( iGLOBAL_SCREENWIDTH == 640) {
+			PrintX += 8 * 8*2;
+		 }else if ( iGLOBAL_SCREENWIDTH == 800) {
+			PrintX += 8 * 8*2;
+		 }
+
+         fontcolor = egacolor[ LIGHTGRAY ];
+         break;
+
+      case MSG_GAME:
+      case MSG_DOOR:
+      case MSG_BONUS:
+      case MSG_BONUS1:
+      case MSG_NAMEMENU:
+         fontcolor = egacolor[ GREEN ];
+         break;
+
+      case MSG_CHEAT:
+         fontcolor = egacolor[ YELLOW ];
+         break;
+      case MSG_MSGSYSTEM:
+      case MSG_SYSTEM:
+      case MSG_QUIT:
+      case MSG_MACRO:
+         fontcolor = egacolor[ RED ];
+         break;
+
+      default :
+#if ((DEVELOPMENT == 1))
+         Error( "DisplayMessage called with invalid priority number." );
+#else
+         fontcolor = egacolor[ LIGHTGREEN ];
+#endif
+      }
+
+   DrawIString( PrintX, PrintY, Messages[ num ].text, Messages[ num ].flags );
+   }
+
+
+
+/*
+====================
+=
+= RestoreMessageBackground
+=
+====================
+*/
+void RestoreMessageBackground
+   (
+   void
+   )
+
+   {
+   pic_t *shape;
+   int i;
+   int y;
+
+   if ( UpdateMessageBackground > 0 )
+      {
+      y = 18;
+      for( i = 0; i < MAXMSGS; i++ )
+         {
+         if ( EraseMessage[ i ] )
+            {
+            UpdateMessageBackground--;
+            EraseMessage[ i ]--;
+            if ( viewsize < 15 )
+               {
+               shape =  ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );//w=32 h=8
+			   	   //SetTextMode (  );
+               //DrawTiledRegion( 0, y, 320, 9, 0, y, shape );KILLS_HEIGHT bna--
+				DrawTiledRegion( 0, y, iGLOBAL_SCREENWIDTH, 9, 0, y, shape );
+				DrawTiledRegion( 0, y+8, iGLOBAL_SCREENWIDTH, 9, 0, y, shape );
+				DrawTiledRegion( 0, y+16, iGLOBAL_SCREENWIDTH, 9, 0, y, shape );
+
+               //DrawTiledRegion( 0, y, iGLOBAL_SCREENWIDTH, 212, 0, y, shape );
+               }
+            if ( viewsize == 0 )
+               {
+               if ( ( y + 9 > YOURCPUSUCKS_Y ) &&
+                  ( y < ( YOURCPUSUCKS_Y + YOURCPUSUCKS_HEIGHT ) ) )
+                  {
+                  DrawCPUJape();
+                  }
+               }
+            }
+
+         y += 9;
+         }
+      }
+   }
+
+
+/*
+====================
+=
+= DrawMessages
+=
+====================
+*/
+void DrawMessages
+   (
+   void
+   )
+
+   {
+   int i;
+
+   if ( TotalMessages > 0 )
+      {
+      IFont = ( cfont_t * )W_CacheLumpName( "ifnt", PU_CACHE, Cvt_cfont_t, 1 );
+
+      for( i = 0; i < TotalMessages; i++ )
+         {
+         DisplayMessage( MessageOrder[ i ], i );
+         }
+      }
+   UpdateMessages();
+   }
+
+
+/*
+====================
+=
+= UpdateModemMessage
+=
+====================
+*/
+void UpdateModemMessage
+   (
+   int num,
+   char c
+   )
+
+   {
+   int i;
+
+   Messages[ num ].text[ MSG.length - 1 ] = ( byte )c;
+   Messages[ num ].text[ MSG.length ]     = ( byte )'_';
+   MSG.length++;
+
+   for( i = 0; i < TotalMessages; i++ )
+      {
+      if ( MessageOrder[ i ] == num )
+         {
+         UpdateMessageBackground -= EraseMessage[ i ];
+         UpdateMessageBackground += 3;
+         EraseMessage[ i ] = 3;
+         break;
+         }
+      }
+   }
+
+
+/*
+====================
+=
+= ModemMessageDeleteChar
+=
+====================
+*/
+void ModemMessageDeleteChar
+   (
+   int num
+   )
+
+   {
+   int i;
+
+   MSG.length--;
+   Messages[ num ].text[ MSG.length ]     = ( byte )0;
+   Messages[ num ].text[ MSG.length - 1 ] = ( byte )'_';
+
+   for( i = 0; i < TotalMessages; i++ )
+      {
+      if ( MessageOrder[ i ] == num )
+         {
+         UpdateMessageBackground -= EraseMessage[ i ];
+         UpdateMessageBackground += 3;
+         EraseMessage[ i ] = 3;
+         break;
+         }
+      }
+   }
+
+
+/*
+====================
+=
+= DrawPlayerSelectionMenu
+=
+====================
+*/
+
+void DrawPlayerSelectionMenu
+   (
+   void
+   )
+
+   {
+   int i;
+   int p;
+   char str[ 20 ];
+
+   p = 1;
+   MsgPos = 1;
+   AddMessage( "Press a key from 0 to 9 to select", MSG_NAMEMENU );
+   MsgPos++;
+   AddMessage( "who to send your message to:", MSG_NAMEMENU );
+   MsgPos++;
+
+   for( i = 0; i < numplayers; i++ )
+      {
+      if ( i != consoleplayer )
+         {
+         strcpy( str, "0 - " );
+         strcat( str, PLAYERSTATE[ i ].codename );
+         str[ 0 ] = '0' + p;
+         p++;
+         if ( p > 9 )
+            {
+            p = 0;
+            }
+
+         AddMessage( str, MSG_NAMEMENU );
+         MsgPos++;
+         }
+      }
+
+   if ( ( MsgPos < MAXMSGS - 1 ) && ( gamestate.teamplay ) )
+      {
+      AddMessage( "T - All team members", MSG_NAMEMENU );
+      MsgPos++;
+      }
+
+   if ( MsgPos < MAXMSGS - 1 )
+      {
+      AddMessage( "A - All players", MSG_NAMEMENU );
+      }
+
+   MsgPos = 0;
+   }
+
+
+/*
+====================
+=
+= FinishModemMessage
+=
+====================
+*/
+void FinishModemMessage
+   (
+   int num,
+   boolean send
+   )
+   {
+   if ( ( !MSG.inmenu ) && ( MSG.length > 0 ) )
+      {
+      Messages[ num ].text[ MSG.length - 1 ] = ( byte )0;
+      MSG.length--;
+      }
+
+   if ( ( send == true ) && ( ( MSG.length > 0 ) ||
+      ( MSG.remoteridicule != -1 ) ) )
+      {
+      if ( ( MSG.directed ) && ( !MSG.inmenu ) )
+         {
+         DrawPlayerSelectionMenu();
+         MSG.messageon = true;
+         MSG.inmenu = true;
+         return;
+         }
+
+      MSG.messageon = false;
+      if ( MSG.remoteridicule != -1 )
+         {
+         AddRemoteRidiculeCommand( consoleplayer, MSG.towho,
+            MSG.remoteridicule );
+         }
+      if ( MSG.length > 0 )
+         {
+         AddTextMessage( Messages[ num ].text, MSG.length, MSG.towho );
+         }
+      }
+
+   if ( MSG.inmenu )
+      {
+      DeletePriorityMessage( MSG_NAMEMENU );
+      }
+
+   DeleteMessage( num );
+   }

Added: tags/rott-1.1/rott/rt_msg.h
===================================================================
--- tags/rott-1.1/rott/rt_msg.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_msg.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,71 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_msg_public
+#define _rt_msg_public
+
+#define MSG_PERMANENT     0x80
+#define MSG_NODELETE      0x40
+#define MSG_PRIORITY( x ) ( ( x ) & 0x3f )
+
+#define PERMANENT_MSG( x ) ( ( x ) & MSG_PERMANENT )
+#define DELETABLE_MSG( x ) ( ( x ) & MSG_NODELETE )
+
+#define MSG_MODEM          ( 1 | MSG_PERMANENT )
+#define MSG_SYSTEM         ( 2 )
+#define MSG_REMOTERIDICULE ( 3 )
+#define MSG_REMOTE         ( 4 | MSG_NODELETE )
+#define MSG_GAME           ( 5 | MSG_NODELETE )
+#define MSG_DOOR           ( 6 )
+#define MSG_CHEAT          ( 7 )
+#define MSG_NAMEMENU       ( 8 | MSG_PERMANENT | MSG_NODELETE )
+#define MSG_QUIT           ( 9 )
+#define MSG_MACRO          ( 10 )
+#define MSG_BONUS1         ( 11 )
+#define MSG_BONUS          ( 12 )
+#define MSG_MSGSYSTEM      ( 13 )
+
+#define MAXMSGS 15
+
+typedef struct msgt
+{
+  byte active;
+  byte flags;
+  int  tictime;
+  char * text;
+} messagetype;
+
+extern messagetype Messages[MAXMSGS];
+
+extern boolean MessagesEnabled;
+
+
+void RestoreMessageBackground( void );
+void DrawMessages ( void );
+int AddMessage (char * text, int flags);
+void InitializeMessages ( void );
+void ResetMessageTime ( void );
+int StringLength (char *string);
+void UpdateModemMessage (int num, char c);
+void ModemMessageDeleteChar (int num);
+void DeleteMessage ( int num );
+void FinishModemMessage( int num, boolean send );
+void DeletePriorityMessage( int flags );
+
+#endif

Added: tags/rott-1.1/rott/rt_net.c
===================================================================
--- tags/rott-1.1/rott/rt_net.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_net.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,3338 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#ifdef DOS
+#include <dos.h>
+#include <io.h>
+#endif
+
+#include "rt_def.h"
+#include "rt_main.h"
+#include "rt_net.h"
+#include "rt_com.h"
+#include "_rt_net.h"
+#include "rt_actor.h"
+#include "rt_playr.h"
+#include "isr.h"
+#include "z_zone.h"
+#include "develop.h"
+#include "rottnet.h"
+#include "rt_msg.h"
+#include "rt_sound.h"
+#include "rt_menu.h"
+#include "rt_util.h"
+#include "rt_rand.h"
+#include "rt_game.h"
+#include "rt_draw.h"
+#include "myprint.h"
+#include "rt_debug.h"
+#include "rt_view.h"
+#include "rt_battl.h"
+#include "rt_dmand.h"
+//MED
+#include "memcheck.h"
+
+#if (SYNCCHECK == 1)
+int            lastsynccheck;
+COM_CheckSyncType PlayerSync[MAXPLAYERS];
+#endif
+
+
+CommandType * LocalCmds;
+CommandType * ServerCmds;
+
+
+int        controlupdatestartedtime=-1;
+int        controlupdatetime=-1;
+int        serverupdatetime=-1;
+int        controlupdatestarted=0;
+boolean    GamePaused=false;
+
+boolean    modemgame;
+boolean    networkgame;
+int        numplayers;
+int        server;
+boolean    IsServer;
+boolean    standalone;
+boolean    restartgame=false;
+boolean    respawnactive=false;
+boolean    playerdead=false;
+boolean    controlschanged=true;
+boolean    battlegibs=false;
+boolean    remoteridicule = false;
+/*
+=============================================================================
+
+					LOCAL FUNCTION PROTOTYPES and VARIABLES
+
+=============================================================================
+*/
+boolean  demorecord,
+			demoplayback;
+byte     *demoptr,
+			*lastdemoptr,
+         *demobuffer=NULL;
+boolean  demodone = false;
+int      predemo_violence = -1;
+int oldmomx;
+int oldmomy;
+int oldspdang;
+
+static boolean GameCommandsStarted=false;
+
+static int oldcontrolbuf[3];
+static int oldbuttonbits;
+static CommandType * PlayerCmds[MAXPLAYERS];
+static CommandType * ClientCmds[MAXPLAYERS];
+
+static boolean GotPlayersDesc[MAXPLAYERS];
+static boolean PlayersReady[MAXPLAYERS];
+static int     LastCommandTime[MAXPLAYERS];
+
+static CommandStatusType * CommandState[MAXPLAYERS+1];
+
+static boolean InProcessServer=false;
+static int lastcontrolupdatetime;
+static int largesttime;
+static int PlayerStatus[MAXPLAYERS];
+//static int syncservertime;
+//static boolean FixingPackets;
+static int controldivisor=1;
+static int nextupdatetime;
+static boolean UpdateServer=true;
+
+void CheckForPacket ( void );
+void PrepareLocalPacket ( void );
+void SendSyncCheckPacket ( void );
+void AddModemSubPacket(void * incoming);
+void SetPlayerDescription( void * pkt );
+void UpdateDemoPlayback (int time);
+int GetTypeSize (int type);
+int MaxSpeedForCharacter(playertype *pstate);
+
+/*
+=============================================================================
+
+						  Game Command Section
+
+=============================================================================
+*/
+
+//****************************************************************************
+//
+// ComError ()
+//
+//****************************************************************************
+
+#define ComError SoftError
+#if 0
+void ComError (char *error, ...)
+{
+#if 0
+	va_list	argptr;
+#endif
+
+   SoftError(error);
+#if 0
+   if (standalone==true)
+      {
+	   va_start (argptr, error);
+      vprintf (error, argptr);
+	   va_end (argptr);
+      }
+#endif
+}
+#endif
+
+//****************************************************************************
+//
+// ConsoleIsServer()
+//
+//****************************************************************************
+boolean ConsoleIsServer ( void )
+{
+   if (modemgame==true)
+      {
+      if (networkgame==true)
+         {
+         if (rottcom->client==0)
+            {
+            return true;
+            }
+         }
+      }
+   return false;
+}
+
+//****************************************************************************
+//
+// GamePacketSize()
+//
+//****************************************************************************
+int GamePacketSize( void )
+{
+   if ((remoteridicule == true) || (ConsoleIsServer() == true))
+      {
+      return GetTypeSize(COM_SOUNDANDDELTA);
+      }
+   else
+      return GetTypeSize(COM_TEXT);
+}
+
+//****************************************************************************
+//
+// InitializeGameCommands()
+//
+//****************************************************************************
+void InitializeGameCommands( void )
+{
+   int i;
+   int j;
+
+	// default to player 0
+
+   if (GameCommandsStarted==true)
+      return;
+
+   GameCommandsStarted=true;
+
+   if ((modemgame==true))
+      controldivisor=rottcom->ticstep;
+
+   standalone=false;
+   IsServer=false;
+
+   if (modemgame==true)
+      {
+		consoleplayer=rottcom->consoleplayer;
+
+      if (networkgame==true)
+         {
+         if (rottcom->client==0)
+            {
+            IsServer=true;
+            // turn it on absolutely for the server
+            remoteridicule = true;
+				if (consoleplayer==0)
+               standalone=true;
+            }
+			if (consoleplayer>0)
+				consoleplayer--; // playernumber fixup
+         }
+      }
+
+   if (standalone==false)
+      {
+      int size;
+
+      size = GamePacketSize ();
+
+		for (i=0;i<numplayers;i++)
+         {
+         PlayerCmds[i]=(CommandType *)SafeLevelMalloc(sizeof(CommandType));
+         for (j=0;j<MAXCMDS;j++)
+            {
+            PlayerCommand(i,j)=SafeLevelMalloc(size);
+            }
+         }
+      }
+
+
+   // allocate local commands
+
+   LocalCmds=(CommandType *)SafeLevelMalloc(sizeof(CommandType));
+   for (j=0;j<MAXCMDS;j++)
+      {
+      int size;
+
+      size = GamePacketSize();
+
+      LocalCommand(j)=SafeLevelMalloc(size);
+      memset(LocalCommand(j),COM_DELTANULL,size);
+      }
+
+   CommandState[0]=(CommandStatusType *)SafeLevelMalloc(sizeof(CommandStatusType));
+
+   if (modemgame==true)
+      {
+      for (i=0;i<numplayers;i++)
+         {
+         PlayerStatus[i]=player_ingame;
+         }
+      if (networkgame==true)
+         {
+         server=1;
+
+         // initialize the Server
+
+         if (IsServer==true)
+            {
+            server=0;
+            ServerCmds=(CommandType *)SafeMalloc(sizeof(CommandType));
+            for (j=0;j<MAXCMDS;j++)
+               {
+               int size;
+               size=( (numplayers * GetTypeSize(COM_TEXT)) +
+                      GetTypeSize(COM_SOUNDANDDELTA) +
+                      sizeof(COM_ServerHeaderType) -
+                      sizeof(byte)
+                    );
+               ServerCommand(j)=SafeMalloc( size );
+               memset(ServerCommand(j),COM_DELTANULL,size);
+               }
+            for (i=1;i<=numplayers;i++)
+               {
+               CommandState[i]=(CommandStatusType *)
+                               SafeMalloc(sizeof(CommandStatusType));
+               }
+				for (i=0;i<numplayers;i++)
+               {
+               ClientCmds[i]=(CommandType *)SafeMalloc(sizeof(CommandType));
+               for (j=0;j<MAXCMDS;j++)
+                  {
+                  int size;
+
+                  size=GetTypeSize(COM_SOUNDANDDELTA);
+                  ClientCommand(i,j)=SafeMalloc(size);
+                  memset(ClientCommand(i,j),COM_DELTANULL,size);
+                  }
+               }
+            }
+         }
+		else // must be a two player game
+         {
+			server=consoleplayer^1;
+         }
+      }
+#if 0
+#if (DEVELOPMENT == 1)
+      if (IsServer)
+         ComError("I am the server\n");
+      ComError("consoleplayer=%ld\n",consoleplayer);
+      ComError("server=%ld mynumber=%ld\n",server,consoleplayer);
+#endif
+#endif
+}
+
+
+//****************************************************************************
+//
+// ShutdownGameCommands()
+//
+//****************************************************************************
+void ShutdownGameCommands( void )
+{
+   int i;
+   int j;
+
+   if (GameCommandsStarted==false)
+      return;
+
+   GameCommandsStarted=false;
+
+	// free up playercmds;
+   if (standalone==false)
+      {
+	   for (i=0;i<numplayers;i++)
+         {
+         for (j=0;j<MAXCMDS;j++)
+            {
+            if (PlayerCommand(i,j))
+               {
+               SafeFree(PlayerCommand(i,j));
+               PlayerCommand(i,j)=NULL;
+               }
+            }
+         SafeFree( PlayerCmds[i] );
+         PlayerCmds[i]=NULL;
+         }
+      }
+
+   // free up command status
+
+   SafeFree(CommandState[0]);
+   CommandState[0]=NULL;
+
+   if (modemgame==true)
+      {
+
+      // free up local commands
+
+      for (j=0;j<MAXCMDS;j++)
+         {
+         if (LocalCommand(j))
+            {
+            SafeFree(LocalCommand(j));
+            LocalCommand(j)=NULL;
+            }
+         }
+      SafeFree(LocalCmds);
+      LocalCmds=NULL;
+
+
+      // free up Server
+
+      if (networkgame==true)
+         {
+         if (IsServer==true)
+            {
+            for (j=0;j<MAXCMDS;j++)
+               {
+               if (ServerCommand(j))
+                  {
+                  SafeFree(ServerCommand(j));
+                  ServerCommand(j)=NULL;
+                  }
+               }
+            SafeFree(ServerCmds);
+            ServerCmds=NULL;
+            for (i=1;i<=numplayers;i++)
+               {
+               SafeFree(CommandState[i]);
+               CommandState[i]=NULL;
+               }
+				for (i=0;i<numplayers;i++)
+               {
+               for (j=0;j<MAXCMDS;j++)
+                  {
+                  if (ClientCommand(i,j))
+                     {
+                     SafeFree(ClientCommand(i,j));
+                     ClientCommand(i,j)=NULL;
+                     }
+                  }
+               SafeFree( ClientCmds[i] );
+               ClientCmds[i]=NULL;
+               }
+            }
+         }
+      }
+}
+
+
+
+
+/*
+=============================================================================
+
+						  Client Controls Section
+
+=============================================================================
+*/
+
+
+//****************************************************************************
+//
+// ShutdownClientControls ()
+//
+//****************************************************************************
+
+void ShutdownClientControls ( void )
+{
+   int i;
+#if (DEVELOPMENT == 1)
+   SoftError ("LARGEST time difference=%ld\n",largesttime);
+#endif
+   controlupdatestarted=0;
+   for (i=0;i<numplayers;i++)
+       {
+       if (PlayerStatus[i] == player_leftgame)
+          PlayerStatus[i]=player_ingame;
+       }
+}
+
+
+//****************************************************************************
+//
+// StartupClientControls ()
+//
+//****************************************************************************
+
+void StartupClientControls ( void )
+{
+   int i,j;
+
+   if (controlupdatestarted==1)
+      return;
+
+   controlupdatestarted=1;
+
+   memset(oldcontrolbuf,-1,sizeof(oldcontrolbuf));
+   oldbuttonbits=-1;
+   controlschanged=true;
+
+   INL_GetMouseDelta(&i,&i);
+
+
+   locplayerstate->dmomx = 0;
+   locplayerstate->dmomy = 0;
+   locplayerstate->angle = 0;
+   locplayerstate->topspeed=MaxSpeedForCharacter(locplayerstate);
+
+
+   CalcTics();
+   CalcTics();
+
+//   FixingPackets=false;
+
+	memset (controlbuf, 0, sizeof (controlbuf));
+   buttonbits = 0;
+   lastpolltime=-1;
+   IN_ClearKeyboardQueue ();
+
+   if (modemgame==true)
+      {
+      controlupdatetime=controlsynctime+(VBLCOUNTER*2);
+      SoftError("Controls started at %d\n",controlupdatetime);
+      }
+   else if (demoplayback || demorecord)
+      {
+      ISR_SetTime(20);
+      oldtime = 20;
+      controlupdatetime=20;
+      }
+   else
+      controlupdatetime=GetTicCount();
+
+   controlupdatetime-=(controlupdatetime%controldivisor);
+
+   serverupdatetime=controlupdatetime;
+   oldpolltime=controlupdatetime;
+   nextupdatetime=oldpolltime;
+#if (SYNCCHECK == 1)
+   lastsynccheck=oldpolltime+CHECKSYNCTIME;
+#endif
+   controlupdatestartedtime=controlupdatetime;
+
+   for( j = 0; j < numplayers; j++ )
+      {
+      memset( PLAYERSTATE[ j ].buttonheld, 0,
+         sizeof( PLAYERSTATE[ j ].buttonheld ) );
+      memset( PLAYERSTATE[ j ].buttonstate, 0,
+         sizeof( PLAYERSTATE[ j ].buttonstate ) );
+      }
+
+   for (i=0;i<MAXCMDS;i++)
+      {
+      ServerCommandNumberStatus( i ) = cs_notarrived;
+      }
+
+   LastCommandTime[0]=controlupdatetime-controldivisor;
+   if (IsServer==true)
+      {
+      int size;
+
+      UpdateServer=true;
+      size=( (numplayers * GetTypeSize(COM_TEXT)) +
+               GetTypeSize(COM_SOUNDANDDELTA) +
+               sizeof(COM_ServerHeaderType) -
+               sizeof(byte)
+            );
+
+      for (j=0;j<numplayers;j++)
+         {
+	      for (i=0;i<MAXCMDS;i++)
+            {
+            ClientCommandNumberStatus( j , i ) = cs_notarrived;
+            }
+         LastCommandTime[j]=controlupdatetime-controldivisor;
+         }
+      for (i=0;i<MAXCMDS;i++)
+         memset(ServerCommand(i),COM_DELTANULL,size);
+      }
+   else if (modemgame==true)
+      {
+      int nump;
+
+      nump=numplayers;
+      if (nump<2) nump=2;
+
+      for (i=0;i<nump;i++)
+         {
+         LastCommandTime[i]=controlupdatetime-controldivisor;
+         }
+      }
+
+
+#if (DEVELOPMENT == 1)
+//   ComError("StartupClientControls: GetTicCount()=%ld oldtime=%ld controlupdatetime=%ld\n",GetTicCount(),oldtime,controlupdatetime);
+#endif
+
+   if ((demoplayback==false) && (standalone==false))
+      {
+      if (modemgame==true)
+         {
+         while (GetTicCount()<(controlupdatetime-10))
+            {
+            CalcTics();
+            }
+         }
+      lastcontrolupdatetime=GetTicCount();
+      largesttime=0;
+      PollControls();
+      }
+   if (standalone==true)
+      printf("Packet Server started\n");
+}
+
+
+
+//****************************************************************************
+//
+// UpdateClientControls ()
+//
+//****************************************************************************
+
+static boolean InUCC=false;
+void UpdateClientControls ( void )
+{
+   int time;
+//   int delta;
+
+   if (controlupdatestarted==0)
+      return;
+
+   if (InUCC)
+      return;
+   else
+      InUCC = true;
+
+   wami(6);
+
+#if 0
+
+   delta=GetTicCount()-lastcontrolupdatetime;
+   if (delta>largesttime)
+      {
+      if (delta>10)
+         largesttime=delta;
+      largesttime=delta;
+      }
+
+#endif
+   lastcontrolupdatetime=GetTicCount();
+
+   if (standalone==false)
+      {
+      time=GetTicCount();
+
+      // if we are a fixing the current packet stop update of deltas
+      // in non-network games.
+      if (
+           (networkgame == false) &&
+           (ServerCommandStatus(oldpolltime)==cs_fixing)
+         )
+         {
+         time=controlupdatetime-controldivisor;
+         }
+
+      while (time>=controlupdatetime)
+         {
+         MoveType * Delta;
+         boolean soundready;
+
+         soundready = SD_SoundDataReady();
+
+         if (demoplayback==true)
+            {
+            UpdateDemoPlayback(controlupdatetime);
+            }
+//         else
+//            {
+//            PollControls();
+//            }
+
+         if (
+             (memcmp(&controlbuf[0],&oldcontrolbuf[0],sizeof(controlbuf))!=0) ||
+             (buttonbits!=oldbuttonbits)
+            )
+            {
+            controlschanged=true;
+            memcpy(&oldcontrolbuf[0],&controlbuf[0],sizeof(controlbuf));
+            oldbuttonbits=buttonbits;
+            }
+         else
+            {
+            controlschanged=false;
+            }
+
+         if ((controlschanged==false) && (soundready==false))
+            {
+            NullMoveType * NullDelta;
+
+            NullDelta=(NullMoveType *)NextLocalCommand();
+            NullDelta->type=COM_DELTANULL;
+            }
+         else
+            {
+            Delta=(MoveType *)NextLocalCommand();
+            Delta->type=COM_DELTA;
+            Delta->momx=(controlbuf[0]>>1);
+            Delta->momy=(controlbuf[1]>>1);
+            Delta->dangle=controlbuf[2]>>11;
+            Delta->buttons=buttonbits;
+
+            // See if we need to update sound packet
+
+            if (soundready==true)
+               {
+               COM_SoundType * sndpkt;
+               recordstate status;
+
+               if (remoteridicule == false)
+                  Error("Attempt to record Remote Ridicule without adequate storage");
+               sndpkt=(COM_SoundType *)Delta->Sounddata;
+
+               // Turn the packet into a COM_SOUNDANDDELTA packet
+
+               Delta->type=COM_SOUNDANDDELTA;
+               status = SD_GetSoundData ( &(sndpkt->data[0]),
+                                          COM_SOUND_BUFFERSIZE );
+               switch (status)
+                  {
+                  case rs_nodata:
+                     Delta->type=COM_DELTA;
+                     break;
+                  case rs_newsound:
+                     sndpkt->type=COM_SOUND_START_TRANSMISSION;
+                     break;
+                  case rs_endsound:
+                     sndpkt->type=COM_SOUND_END_TRANSMISSION;
+                     break;
+                  case rs_data:
+                     sndpkt->type=COM_SOUND_NORMAL_TRANSMISSION;
+                     break;
+                  default:
+                     Error("Illegal return value for SD_GetSoundData");
+                     break;
+                  }
+               }
+            if (demorecord==true)
+               RecordDemoCmd();
+            }
+         PrepareLocalPacket();
+
+         if (
+              (controlupdatetime != -1) &&
+              (controlupdatetime > (lastpolltime+MAXPOLLTICS)) &&
+              (demoplayback==false)
+            )
+            {
+            controlbuf[0] = controlbuf[1] = controlbuf[2] = 0;
+            }
+         }
+      }
+   if (modemgame==true)
+      {
+      CheckForPacket ();
+      }
+
+   if ((standalone == false) && (IsServer==true) && (UpdateServer==true))
+      ProcessServer();
+
+// take out
+   if (modemgame==true)
+      {
+//#if (DEVELOPMENT == 1)
+      if (PanicPressed==true)
+         {
+         Error("Game Aborted. Scroll Lock pressed\n");
+         }
+//#endif
+		if (Keyboard[sc_Insert] && Keyboard[sc_Q])
+         Error("Game Aborted. Insert->Q pressed\n");
+      }
+
+   InUCC = false;
+
+   waminot();
+}
+
+//****************************************************************************
+//
+// PlayerInGame()
+//
+//****************************************************************************
+boolean PlayerInGame ( int p )
+{
+   if (PlayerStatus[p]!=player_ingame)
+      return false;
+   return true;
+}
+
+/*
+=============================================================================
+
+						  Packet Section
+
+=============================================================================
+*/
+
+//****************************************************************************
+//
+// CheckForPacket()
+//
+//****************************************************************************
+void CheckForPacket ( void )
+{
+   wami(7);
+   while (ReadPacket()==true)
+      {
+      if (badpacket==0)
+         {
+         ProcessPacket(&ROTTpacket[0], rottcom->remotenode);
+         #if (DEVELOPMENT == 1)
+//         ComError("CheckForPacket: from=%ld\n",rottcom->remotenode);
+         #endif
+         }
+      else
+         RequestPacket (LastCommandTime[rottcom->remotenode]+controldivisor, rottcom->remotenode, controldivisor);
+      }
+   waminot();
+}
+
+
+//****************************************************************************
+//
+// AddRemoteRidiculeCommand()
+//
+//****************************************************************************
+void AddRemoteRidiculeCommand ( int player, int towho, int num )
+{
+   ((COM_RemoteRidiculeType *)NextLocalCommand())->type=COM_REMRID;
+   ((COM_RemoteRidiculeType *)NextLocalCommand())->num=num;
+   ((COM_RemoteRidiculeType *)NextLocalCommand())->player=player;
+   ((COM_RemoteRidiculeType *)NextLocalCommand())->towho=towho;
+
+   PrepareLocalPacket();
+}
+
+//****************************************************************************
+//
+// ProcessRemoteRidicule()
+//
+//****************************************************************************
+void ProcessRemoteRidicule ( void * pkt )
+   {
+   COM_RemoteRidiculeType * remrot;
+   char name[ 50 ];
+   int from;
+   int who;
+
+   remrot = (COM_RemoteRidiculeType *)pkt;
+   from   = remrot->player;
+   who    = remrot->towho;
+   if ( ( who == consoleplayer ) || ( who == MSG_DIRECTED_TO_ALL ) ||
+      ( ( who == MSG_DIRECTED_TO_TEAM ) && ( BATTLE_Team[ from ] ==
+      BATTLE_Team[ consoleplayer ] ) ) )
+      {
+      strcpy( name, "( RR from " );
+      strcat( name, PLAYERSTATE[from].codename );
+      strcat( name, ")" );
+      AddMessage( name, MSG_REMOTERIDICULE );
+
+      SD_Play( SD_REMOTEM1SND + remrot->num );
+      }
+   }
+
+//****************************************************************************
+//
+// AddEndGameCommand()
+//
+//****************************************************************************
+void AddEndGameCommand ( void )
+{
+   ((COM_EndGameType *)NextLocalCommand())->type=COM_ENDGAME;
+
+   PrepareLocalPacket();
+}
+
+//****************************************************************************
+//
+// AddGameEndCommand()
+//
+//****************************************************************************
+void AddGameEndCommand ( void )
+{
+   ((COM_GameEndType *)NextLocalCommand())->type=COM_GAMEEND;
+
+   PrepareLocalPacket();
+}
+
+//****************************************************************************
+//
+// AddQuitCommand()
+//
+//****************************************************************************
+void AddQuitCommand ( void )
+{
+   ((COM_QuitType *)NextLocalCommand())->type=COM_QUIT;
+   PrepareLocalPacket();
+}
+
+//****************************************************************************
+//
+// AddExitCommand()
+//
+//****************************************************************************
+void AddExitCommand ( void )
+{
+   ((COM_ExitType *)NextLocalCommand())->type=COM_EXIT;
+   PrepareLocalPacket();
+}
+
+//****************************************************************************
+//
+// AddPauseStateCommand()
+//
+//****************************************************************************
+void AddPauseStateCommand ( int type )
+{
+   ((COM_PauseType *)NextLocalCommand())->type=type;
+
+   PrepareLocalPacket();
+}
+
+
+//****************************************************************************
+//
+// AddRespawnCommand()
+//
+//****************************************************************************
+void AddRespawnCommand ( void )
+{
+   if (respawnactive==true)
+      return;
+
+   respawnactive=true;
+
+   ((COM_RespawnType *)NextLocalCommand())->type=COM_RESPAWN;
+
+   PrepareLocalPacket();
+}
+
+
+//****************************************************************************
+//
+// AddTextMessage()
+//
+//****************************************************************************
+void AddTextMessage
+   (
+   char *message,
+   int   length,
+   int   towho
+   )
+
+   {
+   COM_TextType *Text;
+
+   Text = ( COM_TextType * )NextLocalCommand();
+
+   Text->type = COM_TEXT;
+   memset( &Text->string[ 0 ], 0, COM_MAXTEXTSTRINGLENGTH );
+
+   if ( length >= COM_MAXTEXTSTRINGLENGTH )
+      {
+      length = COM_MAXTEXTSTRINGLENGTH - 1;
+      }
+
+   memcpy( &Text->string[ 0 ], message, length );
+
+   Text->towho = towho;
+
+   PrepareLocalPacket();
+   }
+
+
+//****************************************************************************
+//
+// PrepareLocalPacket
+//
+//****************************************************************************
+
+void PrepareLocalPacket ( void )
+{
+   MoveType * pkt;
+
+   wami(8);
+
+   pkt=(MoveType *)NextLocalCommand();
+
+   pkt->time=controlupdatetime;
+
+   if (networkgame==false) // Whether it is a modem game or not we do this
+      {
+		AddClientPacket (pkt, consoleplayer);
+      if (modemgame==false)
+         {
+         ServerCommandStatus ( controlupdatetime ) = cs_ready;
+         }
+      }
+
+   if (modemgame==true)
+      SendPacket (pkt, server);
+
+#if (DEVELOPMENT == 1)
+//   ComError("packet sent: realtime=%ld time=%ld type=%ld dest=%ld\n",GetTicCount(),pkt->time,pkt->type,server);
+#endif
+
+   controlupdatetime+=controldivisor;
+   waminot();
+}
+
+
+
+//****************************************************************************
+//
+// GetPacketSize ()
+//
+//****************************************************************************
+
+int GetPacketSize (void * pkt)
+{
+   int size;
+
+   switch (((MoveType *)pkt)->type)
+      {
+      case COM_DELTA:
+         size=sizeof(MoveType);
+         break;
+      case COM_DELTANULL:
+         size=sizeof(NullMoveType);
+         break;
+      case COM_REQUEST:
+         size=sizeof(COM_RequestType);
+         break;
+      case COM_FIXUP:
+         size=sizeof(COM_FixupType);
+         break;
+      case COM_TEXT:
+         size=sizeof(COM_TextType);
+         break;
+      case COM_PAUSE:
+         size=sizeof(COM_PauseType);
+         break;
+      case COM_QUIT:
+         size=sizeof(COM_QuitType);
+         break;
+      case COM_EXIT:
+         size=sizeof(COM_ExitType);
+         break;
+      case COM_REMRID:
+         size=sizeof(COM_RemoteRidiculeType);
+         break;
+      case COM_RESPAWN:
+         size=sizeof(COM_RespawnType);
+         break;
+      case COM_UNPAUSE:
+         size=sizeof(COM_UnPauseType);
+         break;
+      case COM_SERVER:
+         size=sizeof(COM_ServerHeaderType);
+         size-=sizeof(byte);
+         break;
+      case COM_GAMEDESC:
+         size=sizeof(COM_GamePlayerType);
+         break;
+      case COM_GAMEEND:
+         size=sizeof(COM_GameEndType);
+         break;
+      case COM_GAMEPLAY:
+         size=DUMMYPACKETSIZE;
+         break;
+      case COM_GAMEACK:
+         size=sizeof(COM_GameAckType);
+         break;
+      case COM_GAMEMASTER:
+         size=sizeof(COM_GameMasterType);
+         break;
+      case COM_ENDGAME:
+         size=sizeof(COM_EndGameType);
+         break;
+      case COM_SYNCTIME:
+         size=sizeof(COM_SyncType);
+         break;
+#if (SYNCCHECK == 1)
+      case COM_SYNCCHECK:
+         size=sizeof(COM_CheckSyncType);
+         break;
+#endif
+      case COM_SOUNDANDDELTA:
+         size=sizeof(MoveType)+sizeof(COM_SoundType);
+         break;
+      default:
+         Error("Unhandled packet type in GetPacketSize type=%d",((MoveType *)pkt)->type);
+         break;
+      }
+
+   return size;
+}
+
+//****************************************************************************
+//
+// GetTypeSize ()
+//
+//****************************************************************************
+
+int GetTypeSize (int type)
+{
+   byte pkt[2];
+
+   pkt[0]=(byte)type;
+   return ( GetPacketSize(&(pkt[0])) );
+}
+
+//****************************************************************************
+//
+// GetServerPacketSize ()
+//
+//****************************************************************************
+
+int GetServerPacketSize (void * pkt)
+{
+   int i;
+   byte * ptr;
+   COM_ServerHeaderType * serverpkt;
+
+   serverpkt=(COM_ServerHeaderType *)pkt;
+   if (serverpkt->type==COM_SERVER)
+      {
+      ptr=&serverpkt->data;
+
+      for (i=0;i<serverpkt->numpackets;i++)
+         {
+         ptr+=GetPacketSize(ptr);
+         }
+      return ((byte *)ptr-(byte *)pkt);
+      }
+   else
+      return GetPacketSize(pkt);
+}
+
+//****************************************************************************
+//
+// SendPacket ()
+//
+//****************************************************************************
+
+void SendPacket (void * pkt, int dest)
+{
+   if ((networkgame==false) && (PlayerStatus[dest]!=player_ingame))
+      return;
+   if ((IsServer==true) && (dest==server) && (standalone==false)) // must be client on top of server
+      ProcessPacket(pkt,dest);
+   else if ((IsServer==false) && (dest!=server) && (standalone==false)) // We shouldn't be sending as client to anyone else
+      ComError("SendPacket:Problems\n");
+   else
+      WritePacket(pkt,GetPacketSize(pkt),dest);
+#if (DEVELOPMENT == 1)
+//   ComError( "SendPacket: time=%ld dest=%ld\n",((MoveType *)pkt)->time,dest);
+#endif
+}
+
+//****************************************************************************
+//
+// ResetCurrentCommand ()
+//
+//****************************************************************************
+
+void ResetCurrentCommand ( void )
+{
+   ServerCommandStatus(oldpolltime)=cs_notarrived;
+}
+
+//****************************************************************************
+//
+// BroadcastServerPacket ()
+//
+//****************************************************************************
+
+void BroadcastServerPacket (void * pkt, int size)
+{
+   int i;
+
+
+	for (i=0;i<numplayers;i++)
+      {
+      if (PlayerStatus[i]!=player_ingame)
+         continue;
+//      if ((standalone==false) && (i==consoleplayer))
+//         ProcessPacket(pkt,i);
+//      else
+         WritePacket((byte *)pkt,size,i);
+      }
+}
+
+
+//****************************************************************************
+//
+// ResendLocalPackets ()
+//
+//****************************************************************************
+
+void ResendLocalPackets (int time, int dest, int numpackets)
+{
+   int cmd;
+   MoveType * pkt;
+
+   cmd = CommandAddress(time);
+
+#if 0
+   if (networkgame==false)
+      {
+      int nump;
+      nump=controlupdatetime-time;
+      if (nump>numpackets)
+         numpackets=nump;
+      }
+#endif
+
+   if (controlupdatetime<=time)
+      return;
+
+   pkt = (MoveType *)LocalCommand(cmd);
+
+   if (pkt->time!=time)
+      {
+      Error( "CLIENT: Could not find packet to resend\ntime=%d packettime=%d controlupdatetime=%d\n",
+             time, pkt->time, controlupdatetime);
+      }
+   else
+      {
+      byte * tempbuf;
+      byte * tempptr;
+      byte * tempstart;
+      COM_FixupType * fixup;
+      int i;
+      int starti;
+      int size;
+      boolean done;
+
+      // allocate some space
+
+      tempbuf=SafeMalloc(MAXCOMBUFFERSIZE);
+
+      fixup=(COM_FixupType *)tempbuf;
+
+      fixup->type=COM_FIXUP;
+      tempstart=&(fixup->data);
+
+      done=false;
+      i=0;
+      while (done==false)
+         {
+         tempptr=tempstart;
+         starti=i;
+         fixup->time=( (MoveType *)LocalCommand(cmd) )->time;
+         for (;i<numpackets;i++)
+            {
+            pkt = (MoveType *)LocalCommand(cmd);
+            size=GetPacketSize(pkt);
+
+            if (((tempptr+size)-tempbuf)>MAXCOMBUFFERSIZE)
+               {
+               break;
+               }
+            memcpy(tempptr,pkt,size);
+            tempptr+=size;
+            cmd = (cmd + controldivisor) & (MAXCMDS-1);
+            }
+         fixup->numpackets=i-starti;
+         WritePacket(tempbuf,tempptr-tempbuf,dest);
+         if (i==numpackets)
+            done=true;
+         }
+
+      SafeFree(tempbuf);
+      }
+}
+
+//****************************************************************************
+//
+// ResendServerPackets ()
+//
+//****************************************************************************
+
+void ResendServerPackets (int time, int dest, int numpackets)
+{
+   int cmd;
+   COM_ServerHeaderType * serverpkt;
+
+
+   cmd = CommandAddress(time);
+
+   if (serverupdatetime<=time)
+      return;
+
+   serverpkt = (COM_ServerHeaderType *)ServerCommand(cmd);
+
+   if (serverpkt->time!=time)
+      {
+      Error( "SERVER: Could not find packet to resend\ntime=%d packettime=%d serverupdatetime=%d\n",
+             time, serverpkt->time,serverupdatetime);
+      }
+   else
+      {
+      byte * tempbuf;
+      byte * tempptr;
+      byte * tempstart;
+      COM_FixupType * fixup;
+      int i;
+      int starti;
+      int size;
+      boolean done;
+
+      // allocate some space
+
+      tempbuf=SafeMalloc(MAXCOMBUFFERSIZE);
+
+      fixup=(COM_FixupType *)tempbuf;
+
+      fixup->type=COM_FIXUP;
+      tempstart=&(fixup->data);
+
+      done=false;
+      i=0;
+      while (done==false)
+         {
+         tempptr=tempstart;
+         starti=i;
+         fixup->time=( (MoveType *)ServerCommand(cmd) )->time;
+         for (;i<numpackets;i++)
+            {
+            serverpkt = (COM_ServerHeaderType *)ServerCommand(cmd);
+            size=GetServerPacketSize(serverpkt);
+
+            if (((tempptr+size)-tempbuf)>MAXCOMBUFFERSIZE)
+               {
+               break;
+               }
+            memcpy(tempptr,serverpkt,size);
+            tempptr+=size;
+            cmd = (cmd + controldivisor) & (MAXCMDS-1);
+            }
+         fixup->numpackets=i-starti;
+         WritePacket(tempbuf,tempptr-tempbuf,dest);
+         if (i==numpackets)
+            done=true;
+         }
+
+      SafeFree(tempbuf);
+      }
+}
+
+
+//****************************************************************************
+//
+// ResendPacket (incoming packet, whoever requested it)
+//
+//****************************************************************************
+
+void ResendPacket (void * pkt, int dest)
+{
+   int time;
+   COM_RequestType * request;
+
+   if ((networkgame==false) && (PlayerStatus[dest]!=player_ingame))
+      return;
+
+   request=(COM_RequestType * )pkt;
+   time=request->time;
+
+   ComError( "RESEND request received at %d\n packet time=%d dest=%d numpackets=%d\n",
+             GetTicCount(), time, dest, request->numpackets);
+
+   if (IsServer==true)
+      {
+      if ((dest==server) && (standalone==false))
+         Error("Trying to resend packets to client on top of server\n");
+      ComError( "RESEND SERVER serverupdatetime=%d\n",serverupdatetime);
+      if (IsServerCommandReady ( time ) == true)
+         ResendServerPackets(time,dest,request->numpackets);
+      else
+         ComError( "RESEND SERVER time=%d is not ready\n",time);
+      }
+   else
+      {
+      ResendLocalPackets(time,dest,request->numpackets);
+      }
+}
+
+//****************************************************************************
+//
+// FixupPacket ()
+//
+//****************************************************************************
+
+void FixupPacket (void * pkt, int src)
+{
+   COM_FixupType * fix;
+   int i;
+   int time;
+   byte * ptr;
+
+   fix=(COM_FixupType *)pkt;
+
+   ComError( "Fixup received at %d, time=%d numpackets=%d\n", GetTicCount(), fix->time, fix->numpackets);
+#if 0
+   if (networkgame==false)
+      FixingPackets=false;
+#endif
+   time=fix->time;
+   ptr=&(fix->data);
+
+   for (i=0;i<fix->numpackets;i++,time+=controldivisor)
+      {
+      if (time == (LastCommandTime[src]+controldivisor))
+         LastCommandTime[src]=time;
+
+      if (IsServer==true)
+         {
+         if (ClientCommandStatus(src, time)!=cs_fixing)
+            {
+            ComError("Server Received fixup with no bad packet time=%d from %d\n",time,src);
+            }
+         else
+            {
+            AddSubPacket(ptr, src);
+            }
+         ptr+=GetPacketSize(ptr);
+         }
+      else
+         {
+         if (ServerCommandStatus(time)!=cs_fixing)
+            {
+            ComError("Client Received fixup with no bad packet time=%d from %d\n",time,src);
+            }
+         else
+            {
+            if (networkgame==true)
+               {
+               AddServerSubPacket( (COM_ServerHeaderType *)ptr );
+               }
+            else
+               {
+               AddModemSubPacket(ptr);
+               }
+            }
+         ptr+=GetServerPacketSize(ptr);
+         }
+      }
+}
+
+#if (SYNCCHECK == 1)
+//****************************************************************************
+//
+// CheckForSyncCheck
+//
+//****************************************************************************
+
+void CheckForSyncCheck ( void )
+{
+   int i;
+
+
+   if (modemgame==true)
+      {
+      if (oldpolltime==lastsynccheck)
+         {
+         for (i=0;i<numplayers;i++)
+            {
+            PlayerSync[i].x=PLAYER[i]->x;
+            PlayerSync[i].y=PLAYER[i]->y;
+            PlayerSync[i].z=PLAYER[i]->z;
+            PlayerSync[i].angle=PLAYER[i]->angle;
+            }
+         PlayerSync[0].randomindex=GetRNGindex();
+         PlayerSync[0].synctime=lastsynccheck;
+         SendSyncCheckPacket();
+         lastsynccheck+=CHECKSYNCTIME;
+         }
+      if (oldpolltime>lastsynccheck)
+         {
+         Error("Missed a player sync check time=%d\n",oldpolltime);
+         }
+      }
+}
+#endif
+
+//****************************************************************************
+//
+// ProcessSyncTimePacket
+//
+//****************************************************************************
+
+void ProcessSyncTimePacket (void * pkt)
+{
+   COM_SyncType * sync;
+
+   sync=(COM_SyncType *)pkt;
+   ISR_SetTime(sync->synctime);
+}
+
+#if (SYNCCHECK == 1)
+//****************************************************************************
+//
+// ProcessSyncCheckPacket
+//
+//****************************************************************************
+
+void ProcessSyncCheckPacket (void * pkt, int src)
+{
+   COM_CheckSyncType * sync;
+
+   sync=(COM_CheckSyncType *)pkt;
+//   SoftError("Sync packet time=%ld\n",sync->synctime);
+   if (sync->synctime!=PlayerSync[0].synctime)
+      {
+      SoftError("Old sync packet received\n");
+      return;
+      }
+   if (sync->randomindex!=PlayerSync[0].randomindex)
+      {
+      Error("Player %d is unsynced localindex=%d remoteindex=%d\n"
+            "Unsynced Player x=%x y=%x a=%d z=%d name=%s\n",
+             src, PlayerSync[0].randomindex, sync->randomindex,
+             PlayerSync[src].x, PlayerSync[src].y, PlayerSync[src].angle,
+             PlayerSync[src].z,PLAYERSTATE[src].codename);
+      }
+   if (sync->x!=PlayerSync[src].x)
+      {
+      Error("Player %d is unsynced local x=%d remote x=%d\n"
+            "Unsynced Player x=%x y=%x a=%d z=%d name=%s\n",
+             src,PlayerSync[src].x,sync->x,
+             PlayerSync[src].x, PlayerSync[src].y, PlayerSync[src].angle,
+             PlayerSync[src].z,PLAYERSTATE[src].codename);
+      }
+   if (sync->y!=PlayerSync[src].y)
+      {
+      Error("Player %d is unsynced local y=%d remote y=%d\n"
+            "Unsynced Player x=%x y=%x a=%d z=%d name=%s\n",
+             src,PlayerSync[src].y,sync->y,
+             PlayerSync[src].x, PlayerSync[src].y, PlayerSync[src].angle,
+             PlayerSync[src].z,PLAYERSTATE[src].codename);
+      }
+   if (sync->z!=PlayerSync[src].z)
+      {
+      Error("Player %d is unsynced local z=%d remote z=%d\n"
+            "Unsynced Player x=%x y=%x a=%d z=%d name=%s\n",
+             src,PlayerSync[src].z,sync->z,
+             PlayerSync[src].x, PlayerSync[src].y, PlayerSync[src].angle,
+             PlayerSync[src].z,PLAYERSTATE[src].codename);
+      }
+   if (sync->angle!=PlayerSync[src].angle)
+      {
+      Error("Player %d is unsynced local angle=%d remote angle=%d\n"
+            "Unsynced Player x=%x y=%x a=%d z=%d name=%s\n",
+             src,PlayerSync[src].angle,sync->angle,
+             PlayerSync[src].x, PlayerSync[src].y, PlayerSync[src].angle,
+             PlayerSync[src].z,PLAYERSTATE[src].codename);
+      }
+}
+
+//****************************************************************************
+//
+// SendSyncCheckPacket
+//
+//****************************************************************************
+
+void SendSyncCheckPacket ( void )
+{
+   ((COM_CheckSyncType *)NextLocalCommand())->type=COM_SYNCCHECK;
+   ((COM_CheckSyncType *)NextLocalCommand())->synctime=PlayerSync[0].synctime;
+   ((COM_CheckSyncType *)NextLocalCommand())->x=PlayerSync[consoleplayer].x;
+	((COM_CheckSyncType *)NextLocalCommand())->y=PlayerSync[consoleplayer].y;
+	((COM_CheckSyncType *)NextLocalCommand())->z=PlayerSync[consoleplayer].z;
+	((COM_CheckSyncType *)NextLocalCommand())->angle=PlayerSync[consoleplayer].angle;
+	((COM_CheckSyncType *)NextLocalCommand())->randomindex=PlayerSync[0].randomindex;
+
+   PrepareLocalPacket();
+}
+#endif
+
+#if 0
+
+//****************************************************************************
+//
+// CheckForSyncTime
+//
+//****************************************************************************
+
+void CheckForSyncTime ( void )
+{
+   if ((modemgame==true) && (networkgame==false) && (consoleplayer==0))
+      {
+      if (controlupdatetime>=syncservertime)
+         {
+         SendSyncTimePacket();
+         syncservertime+=MODEMSYNCSERVERTIME;
+         }
+      }
+}
+#endif
+
+#if 0
+//****************************************************************************
+//
+// SendSyncTimePacket
+//
+//****************************************************************************
+
+void SendSyncTimePacket ( void )
+{
+   int i;
+   COM_SyncType sync;
+
+   return;
+
+   sync.type=COM_SYNCTIME;
+
+   if (networkgame==true)
+      {
+      for (i=0;i<numplayers;i++)
+         {
+         if ((PlayerStatus[i]!=player_ingame) || ( (i==consoleplayer) && (standalone==false) ) )
+            continue;
+         sync.synctime=GetTicCount()+GetTransitTime(i);
+         WritePacket ( &sync.type, GetPacketSize(&sync.type), i);
+         }
+      }
+   else
+      {
+      if (PlayerStatus[server]==player_ingame)
+         {
+         sync.synctime=GetTicCount()+GetTransitTime(server);
+         WritePacket ( &sync.type, GetPacketSize(&sync.type), server);
+         }
+      }
+}
+#endif
+
+//****************************************************************************
+//
+// ProcessSoundAndDeltaPacket
+//
+//****************************************************************************
+
+void ProcessSoundAndDeltaPacket (void * pkt, int src)
+{
+   MoveType * packet;
+   COM_SoundType * sndpkt;
+   byte oldtype;
+
+   packet = (MoveType *)pkt;
+
+   // Trick packet into being a normal delta packet
+
+   oldtype=packet->type;
+   packet->type=COM_DELTA;
+   AddClientPacket (pkt,src);
+   packet->type=oldtype;
+
+   // Don't process sound if it is from us
+   if (src==consoleplayer)
+      return;
+
+   sndpkt = (COM_SoundType *) (packet->Sounddata);
+
+   if (sndpkt->type==COM_SOUND_START_TRANSMISSION)
+      {
+      SD_StartIncomingSound ();
+      }
+   if (sndpkt->type==COM_SOUND_END_TRANSMISSION)
+      {
+      SD_StopIncomingSound();
+      }
+   else
+      {
+      SD_UpdateIncomingSound (&(sndpkt->data[0]), COM_SOUND_BUFFERSIZE);
+      }
+}
+//****************************************************************************
+//
+// SyncToServer
+//
+//****************************************************************************
+#define NETWORKTIMEAHEADOFSERVER (1)
+#define MODEMTIMEAHEADOFSERVER (2)
+void SyncToServer( void )
+{
+   int diff;
+
+   if ((networkgame==false) && (consoleplayer==0))
+      return;
+   if (IsServer==true)
+      return;
+//   if (networkgame==true)
+//      {
+//      diff = (GetTicCount()-controldivisor-LastCommandTime[0])/controldivisor;
+//      SoftError("diff=%ld\n",diff);
+//      if (abs(diff)>1)
+//         ISR_SetTime(GetTicCount()-diff);
+#if 0
+      diff = controlupdatetime-LastCommandTime[0];
+      if (diff>3)
+         {
+         ISR_SetTime(GetTicCount()-1);
+         }
+      else if (diff<-3)
+         {
+         ISR_SetTime(GetTicCount()+1);
+         }
+#endif
+//      }
+//   else
+//      {
+      diff = (GetTicCount()-controldivisor-LastCommandTime[server])/controldivisor;
+      if (abs(diff)>0)
+         ISR_SetTime(GetTicCount()-diff);
+//      }
+}
+
+//****************************************************************************
+//
+// ProcessPacket
+//
+//****************************************************************************
+
+void ProcessPacket (void * pkt, int src)
+{
+   switch (((MoveType *)pkt)->type)
+      {
+      case COM_DELTA:
+      case COM_DELTANULL:
+      case COM_TEXT:
+      case COM_PAUSE:
+      case COM_QUIT:
+      case COM_EXIT:
+      case COM_REMRID:
+      case COM_RESPAWN:
+      case COM_UNPAUSE:
+      case COM_ENDGAME:
+#if (SYNCCHECK == 1)
+      case COM_SYNCCHECK:
+#endif
+//         if (FixingPackets==false)
+         AddPacket(pkt,src);
+         break;
+      case COM_SOUNDANDDELTA:
+         if (remoteridicule == false )
+            {
+            ((MoveType *)pkt)->type = COM_DELTA;
+            }
+         AddPacket(pkt,src);
+         break;
+      case COM_SERVER:
+         AddServerPacket(pkt,src);
+         break;
+
+      case COM_REQUEST:
+         ResendPacket(pkt, src);
+         break;
+
+      case COM_FIXUP:
+         FixupPacket(pkt, src);
+         break;
+
+      case COM_SYNCTIME:
+         ProcessSyncTimePacket(pkt);
+         break;
+
+      case COM_GAMEEND:
+      case COM_GAMEDESC:
+      case COM_GAMEACK:
+      case COM_GAMEMASTER:
+         if (standalone==true)
+            restartgame=true;
+         break;
+
+      case COM_START:
+         break;
+
+      default:
+         Error("ProcessPacket: Unknown packet type=%d\n",((MoveType *)pkt)->type);
+      }
+}
+
+
+//****************************************************************************
+//
+// AddServerSubPacket
+//
+//****************************************************************************
+
+void AddServerSubPacket(COM_ServerHeaderType * serverpkt)
+{
+   byte * pkt;
+   int i;
+
+   ServerCommandStatus(serverpkt->time)=cs_ready;
+
+   pkt=&serverpkt->data;
+   for (i=0;i<serverpkt->numpackets;i++)
+      {
+      AddClientPacket(pkt,i);
+      pkt+=GetPacketSize(pkt);
+      }
+}
+
+//****************************************************************************
+//
+// AddModemSubPacket
+//
+//****************************************************************************
+
+void AddModemSubPacket(void * incoming)
+{
+   MoveType * pkt;
+
+   pkt=(MoveType *)incoming;
+   ServerCommandStatus(pkt->time)=cs_ready;
+
+   AddClientPacket(incoming,server);
+}
+
+//****************************************************************************
+//
+// AddServerPacket
+//
+//****************************************************************************
+
+void AddServerPacket(void * pkt, int src)
+{
+   COM_ServerHeaderType * serverpkt;
+
+   // The server uses the client's lgts for communicating
+
+   // Last good time can be set even for the client/server combo
+
+   if (standalone==true)
+      {
+      Error("standalone should not be here\n");
+      }
+
+   if (src!=server)
+      {
+      Error("Received server packet from non-server src=%d\n",src);
+      }
+
+   serverpkt=(COM_ServerHeaderType *)pkt;
+
+//   if (networkgame==false)
+//      SyncToServer(serverpkt->time);
+
+   LastCommandTime[src]+=controldivisor;
+
+   if (serverpkt->time != LastCommandTime[src])
+      {
+      int numpackets;
+
+      numpackets=serverpkt->time-LastCommandTime[src];
+      if (ServerCommandStatus(LastCommandTime[src])!=cs_fixing)
+         {
+         RequestPacket ( LastCommandTime[src] , src , numpackets );
+
+         ComError("AddServerPacket: Request packet time=%d lct=%d numpackets=%d\n",
+                  serverpkt->time, LastCommandTime[src], numpackets
+                 );
+         }
+
+      LastCommandTime[src]+=numpackets;
+      }
+
+   AddServerSubPacket( serverpkt );
+}
+
+//****************************************************************************
+//
+// AddClientPacket
+//
+//****************************************************************************
+
+void AddClientPacket (void * pkt, int src)
+{
+   int size;
+   MoveType * packet;
+
+   packet=(MoveType *)pkt;
+
+   switch (packet->type)
+      {
+      case COM_DELTA:
+      case COM_DELTANULL:
+      case COM_TEXT:
+      case COM_REMRID:
+      case COM_PAUSE:
+      case COM_QUIT:
+      case COM_EXIT:
+      case COM_RESPAWN:
+      case COM_UNPAUSE:
+#if (SYNCCHECK == 1)
+      case COM_SYNCCHECK:
+#endif
+      case COM_ENDGAME:
+         size=GetPacketSize(packet);
+         memcpy(PlayerCommand(src,CommandAddress(packet->time)),packet,size);
+         break;
+      case COM_SOUNDANDDELTA:
+         ProcessSoundAndDeltaPacket(packet, src);
+         break;
+      default:
+         Error("AddClientPacket: Unknown packet type = %d\n",packet->type);
+      }
+}
+
+//****************************************************************************
+//
+// AddSubPacket
+//
+//****************************************************************************
+
+void AddSubPacket (void * pkt, int src)
+{
+   MoveType * packet;
+
+   if (networkgame==false)
+      Error("Modem game should not be here in AddSubPacket\n");
+
+   packet = (MoveType *) pkt;
+
+   ClientCommandStatus(src, packet->time)=cs_ready;
+
+   memcpy (
+          ClientTimeCommand(src,packet->time),
+          pkt,
+          GetPacketSize(packet)
+          );
+}
+
+//****************************************************************************
+//
+// AddPacket
+//
+//****************************************************************************
+
+void AddPacket (void * pkt, int src)
+{
+   MoveType * packet;
+
+   // should only be called by server in network game
+   // in modem game we fall through the first condition
+   // all packets should be sequential
+
+   if ((IsServer==true) && (PlayerStatus[src]!=player_ingame))
+      return;
+   packet = (MoveType *) pkt;
+
+//   if ((networkgame==false) && (consoleplayer!=0))
+//      SyncToServer();
+
+   if (!((src==server) && (standalone==false) && (IsServer==true)))
+      {
+      LastCommandTime[src]+=controldivisor;
+
+      if (packet->time != LastCommandTime[src])
+         {
+         int numpackets;
+
+         numpackets=packet->time-LastCommandTime[src];
+         if ( ( (networkgame==false) &&
+               (ServerCommandStatus(LastCommandTime[src])!=cs_fixing)
+            )
+            ||
+            ( (networkgame==true) &&
+               (ClientCommandStatus(src,LastCommandTime[src])!=cs_fixing)
+            )
+            )
+            {
+            RequestPacket ( LastCommandTime[src] , src , numpackets );
+
+            ComError("AddPacket: Request packet time=%d lct=%d numpackets=%d\n",
+                     packet->time, LastCommandTime[src], numpackets
+                     );
+            }
+
+         LastCommandTime[src]+=numpackets;
+         }
+      }
+
+   if (networkgame==true)
+      {
+      AddSubPacket ( packet, src );
+      }
+   else
+      {
+      AddModemSubPacket(packet);
+      }
+}
+
+
+//****************************************************************************
+//
+// RequestPacket ( int time, int dest )
+//
+//****************************************************************************
+
+void RequestPacket (int time, int dest, int numpackets)
+{
+   COM_RequestType request;
+   int i;
+
+
+#if (DEVELOPMENT == 1)
+   if (modemgame==false)
+      Error("Called Request Packet outside of modem game\n");
+#endif
+
+   request.type=COM_REQUEST;
+   request.time=time;
+   request.numpackets=numpackets/controldivisor;
+
+   if (IsServer==true)
+      {
+      if ((dest==server) && (standalone==false))
+         {
+         Error("Requesting packet from client on top of server\n");
+         }
+      if (PlayerStatus[dest]!=player_ingame)
+         return;
+      for (i=0;i<numpackets;i+=controldivisor)
+         {
+         ClientCommandStatus( dest , (time+i) ) = cs_fixing;
+         }
+      }
+   else
+      {
+      if ((networkgame==false) && (PlayerStatus[dest]!=player_ingame))
+         return;
+      for (i=0;i<numpackets;i+=controldivisor)
+         {
+         ServerCommandStatus( (time+i) ) = cs_fixing;
+         }
+      }
+//   if (networkgame==false)
+//      FixingPackets=true;
+
+   // send out the packet
+
+   WritePacket (&request, GetPacketSize(&request), dest);
+
+#if (DEVELOPMENT == 1)
+//   ComError( "BADPKT, request sent at %ld lgt=%ld dest=%ld\n",GetTicCount(),time,dest);
+#endif
+}
+
+//****************************************************************************
+//
+// IsServerCommandReady ()
+//
+//****************************************************************************
+boolean IsServerCommandReady ( int time )
+{
+
+   if (
+       (
+        (COM_ServerHeaderType *)
+         ServerCommand(CommandAddress (time) ) )->time==time)
+      return true;
+   else
+      {
+      return false;
+      }
+}
+
+//****************************************************************************
+//
+// AreClientsReady ()
+//
+//****************************************************************************
+boolean AreClientsReady ( void )
+{
+   int i;
+   int timeindex;
+   int status;
+
+   timeindex=CommandAddress(serverupdatetime);
+
+	for (i=0;i<numplayers;i++)
+      {
+      if (PlayerStatus[i]!=player_ingame)
+         continue;
+      status=ClientCommandStatus(i, serverupdatetime);
+      if (status==cs_notarrived)
+         return false;
+      else if (status==cs_fixing)
+         {
+//         RequestPacket ( serverupdatetime , i , controldivisor );
+         return false;
+         }
+      else if (((MoveType *)ClientCommand(i, timeindex))->time != serverupdatetime)
+         return false;
+      }
+   return true;
+}
+
+//****************************************************************************
+//
+// IsPlayerCommandReady ()
+//
+//****************************************************************************
+boolean IsPlayerCommandReady (int num, int time)
+{
+   MoveType * cmd;
+
+   cmd=(MoveType *)PlayerCommand(num,CommandAddress(time));
+
+   if (cmd->time==time)
+      return true;
+   else
+      return false;
+}
+
+//****************************************************************************
+//
+// ResetClientCommands ()
+//
+//****************************************************************************
+void ResetClientCommands ( int player )
+{
+   int j;
+
+   for (j=0;j<MAXCMDS;j++)
+      {
+      memset(ClientCommand(player,j),COM_DELTA,GamePacketSize());
+      }
+}
+
+//****************************************************************************
+//
+// SendFullServerPacket ()
+//
+//****************************************************************************
+void SendFullServerPacket ( void )
+{
+   int i;
+   int size;
+   byte * pkt;
+   COM_ServerHeaderType * spkt;
+   int timeindex;
+   int playerstatus[MAXPLAYERS];
+
+   timeindex=CommandAddress(serverupdatetime);
+
+   spkt=(COM_ServerHeaderType *)ServerCommand(timeindex);
+
+   pkt=&spkt->data;
+   spkt->time=serverupdatetime;
+   spkt->type=COM_SERVER;
+	spkt->numpackets=numplayers;
+
+
+   memset(playerstatus,-1,sizeof(playerstatus));
+	for (i=0;i<numplayers;i++)
+      {
+      size=GetPacketSize(ClientCommand(i,timeindex));
+      if (((MoveType *)ClientCommand(i,timeindex))->type == COM_QUIT)
+         {
+         playerstatus[i]=player_quitgame;
+         }
+      if (((MoveType *)ClientCommand(i,timeindex))->type == COM_ENDGAME)
+         {
+         playerstatus[i]=player_leftgame;
+         }
+      memcpy(pkt,
+            ClientCommand(i,timeindex),
+            size
+            );
+      pkt+=size;
+      ClientCommandNumberStatus(i,timeindex)=cs_notarrived;
+      }
+   BroadcastServerPacket((void *)spkt,(pkt-(byte *)spkt));
+   serverupdatetime+=controldivisor;
+
+   for (i=0;i<numplayers;i++)
+      {
+      if (playerstatus[i]!=-1)
+         {
+         if ((standalone==false) && (consoleplayer==i))
+            {
+            UpdateServer=false;
+            }
+         else
+            {
+            ResetClientCommands(i);
+            PlayerStatus[i]=playerstatus[i];
+            }
+         }
+      }
+}
+
+
+
+//****************************************************************************
+//
+// ProcessServer ()
+//
+//****************************************************************************
+
+void ProcessServer ( void )
+{
+   boolean done;
+   boolean exit;
+   int i;
+   int time;
+   int quittime;
+
+   if (InProcessServer==true)
+      return;
+
+   InProcessServer=true;
+
+   if (GetTicCount()<serverupdatetime)
+      goto exitProcessServer;
+
+   time=GetTicCount();
+   quittime=GetTicCount()+SERVERTIMEOUT;
+   exit=false;
+
+   while (time>=serverupdatetime)
+      {
+      int savetime;
+
+      savetime=GetTicCount()+NETWORKTIMEOUT;
+      done = false;
+		while (done == false)
+         {
+         if (standalone==true)
+            AbortCheck("GameServer aborted\n");
+
+         done = AreClientsReady ();
+
+         if ( (standalone==false) && (serverupdatetime>=(controlupdatetime-controldivisor)) && (done==false) )
+            break;
+
+         CheckForPacket ();
+
+         if (standalone==false)
+            UpdateClientControls();
+
+         if (restartgame==true)
+            break;
+         if (GetTicCount()>savetime)
+            {
+            for (i=0;i<numplayers;i++)
+               {
+               int val;
+
+               val=ClientCommandStatus(i, serverupdatetime);
+               if ((val!=cs_ready) && (PlayerStatus[i]==player_ingame))
+                  {
+                  SoftError("Server timeout\n");
+                  RequestPacket(serverupdatetime, i , controldivisor);
+                  }
+               }
+            savetime=GetTicCount()+NETWORKTIMEOUT;
+            }
+//         if (GetTicCount()>quittime)
+//            {
+//            Error("Server aborting after %ld seconds\n",SERVERTIMEOUT/VBLCOUNTER);
+//            }
+         if ((standalone==false) && (done==false))
+            {
+            exit=true;
+            done=true;
+            }
+         }
+      if (exit==true)
+         break;
+      if ( (serverupdatetime>=(controlupdatetime-controldivisor)) && (standalone==false))
+         break;
+      if (restartgame==true)
+         break;
+      SendFullServerPacket();
+#if 0
+      if (serverupdatetime>=syncservertime)
+         {
+         SendSyncTimePacket();
+         syncservertime+=NETSYNCSERVERTIME;
+         }
+#endif
+      }
+exitProcessServer:
+   InProcessServer=false;
+}
+
+
+//****************************************************************************
+//
+// SetupCheckForPacket()
+//
+//****************************************************************************
+int SetupCheckForPacket ( void )
+{
+   int retval=scfp_nodata;
+
+   if ((ReadPacket()==true) && (badpacket==0))
+      {
+      MoveType * pkt;
+
+      retval=scfp_data;
+      pkt=(MoveType *)&ROTTpacket[0];
+      if ((IsServer==true) && (standalone==true))
+         {
+         switch (pkt->type)
+            {
+            case COM_GAMEEND:
+               break;
+            case COM_GAMEDESC:
+               if (standalone==true)
+                  printf("Received GameDescription from player#%ld\n",(long int)rottcom->remotenode);
+               WritePacket(&ROTTpacket[0],GetPacketSize(pkt),0); // Send to player 0
+               break;
+            case COM_GAMEACK:
+               if (standalone==true)
+                  printf("Received GameAcknowledgement from player#%ld\n",(long int)rottcom->remotenode);
+               WritePacket(&ROTTpacket[0],GetPacketSize(pkt),0); // Send to player 0
+               break;
+            case COM_GAMEMASTER:
+               if (standalone==true)
+                  printf("Received GameMasterPacket from player#%ld\n",(long int)rottcom->remotenode);
+               BroadcastServerPacket(&ROTTpacket[0],GetPacketSize(pkt)); // Send to all
+               break;
+            case COM_GAMEPLAY:
+               if (standalone==true)
+                  printf("Received StartGamePacket from player#%ld\n",(long int)rottcom->remotenode);
+               BroadcastServerPacket(&ROTTpacket[0],GetPacketSize(pkt)); // Send to all
+               retval=scfp_done;
+               break;
+            default:
+               ComError("Server received unknown packet in Game preamble\n");
+               break;
+            }
+         }
+      else
+         {
+         switch (pkt->type)
+            {
+            case COM_GAMEPLAY:
+                retval=scfp_done;
+                break;
+            case COM_GAMEMASTER:
+                SetGameDescription(pkt);
+                retval=scfp_gameready;
+                break;
+            case COM_GAMEACK:
+					 PlayersReady[((COM_GameAckType *)pkt)->player]=true;
+                break;
+            case COM_GAMEDESC:
+					 GotPlayersDesc[((COM_GamePlayerType *)pkt)->player]=true;
+                SetPlayerDescription(pkt);
+                break;
+            }
+         }
+      }
+   return retval;
+}
+
+
+//****************************************************************************
+//
+// ServerLoop ()
+//
+//****************************************************************************
+void ServerLoop( void )
+{
+   boolean done;
+
+   while (1)
+      {
+      ShutdownClientControls();
+      restartgame=false;
+
+      done=false;
+      while (done==false)
+         {
+         AbortCheck("SetupGameServer aborted\n");
+
+         if (SetupCheckForPacket()==scfp_done)
+            done=true;
+         }
+      ComSetTime();
+      StartupClientControls();
+      while(1)
+         {
+         ProcessServer();
+#if (DEVELOPMENT == 1)
+         Z_CheckHeap();
+#endif
+         CalcTics();
+         if (restartgame==true)
+            break;
+         }
+      }
+}
+
+//****************************************************************************
+//
+// ProcessPlayerCommand()
+//
+//****************************************************************************
+void ProcessPlayerCommand( int player )
+{
+   MoveType * cmd;
+
+   cmd=(MoveType *)PlayerCommand(player,CommandAddress(oldpolltime));
+
+	if (cmd->type==COM_DELTA)
+      {
+		UpdatePlayerObj(player);
+      }
+	else if (cmd->type==COM_RESPAWN)
+      {
+		if (player==consoleplayer) // reset spawn state
+         respawnactive=false;
+      RespawnPlayerobj(PLAYER[player]);
+      }
+	else if (cmd->type==COM_ENDGAME)
+      {
+      playstate = ex_battledone;
+      }
+   else if (cmd->type==COM_QUIT)
+      {
+      if (player==consoleplayer)
+         QuitGame();
+      else
+         {
+         char str[50]="Player #";
+         char str2[10];
+
+         strcat(str,itoa(player+1,str2,10));
+         strcat(str,", ");
+         strcat(str,PLAYERSTATE[player].codename);
+         strcat(str," has left the game.");
+         AddMessage(str,MSG_REMOTE);
+         PlayerStatus[player]=player_quitgame;
+         }
+      }
+   else if (cmd->type==COM_EXIT)
+      {
+      QuitGame();
+      }
+   else if (cmd->type==COM_REMRID)
+      {
+      ProcessRemoteRidicule (cmd);
+      }
+   else if (cmd->type==COM_TEXT)
+      {
+      int who;
+
+      who = ( ( COM_TextType * )cmd )->towho;
+      if ( ( who == consoleplayer ) ||
+         ( who == MSG_DIRECTED_TO_ALL ) ||
+         ( ( who == MSG_DIRECTED_TO_TEAM ) &&
+         ( BATTLE_Team[ player ] == BATTLE_Team[ consoleplayer ] ) ) )
+         {
+         char string[ 50 ];
+
+         strcpy( string, "\\N9" );
+         strcat( string, PLAYERSTATE[player].codename );
+         strcat( string, ":\\NF" );
+         strcat( string, ((COM_TextType *)cmd)->string );
+         SD_PlayPitchedSound ( SD_ENDBONUS1SND, 255, 1200 );
+
+         AddMessage( string, MSG_REMOTE );
+         }
+      }
+#if (SYNCCHECK == 1)
+	else if (cmd->type==COM_SYNCCHECK)
+      {
+      ProcessSyncCheckPacket(cmd, player);
+      }
+#endif
+	else if (cmd->type==COM_PAUSE)
+      {
+      MUSIC_Pause();
+      GamePaused=true;
+      pausedstartedticcount = oldpolltime;
+      }
+	else if (cmd->type==COM_UNPAUSE)
+      {
+      GamePaused=false;
+      MUSIC_Continue ();
+      if (RefreshPause == false)       // screen is blanked
+         {
+         ShutdownScreenSaver();
+         SetupScreen (true);
+         RefreshPause = true;
+         }
+      }
+}
+
+//****************************************************************************
+//
+// CheckUnPause ()
+//
+//****************************************************************************
+void CheckUnPause ( void )
+{
+   if (oldpolltime==nextupdatetime)
+      {
+      nextupdatetime=oldpolltime+controldivisor;
+      while (1)
+         {
+         if (ServerCommandStatus(oldpolltime)==cs_ready)
+            {
+            int j;
+
+            for (j=0;j<numplayers;j++)
+               {
+               if (PlayerStatus[j]==player_ingame)
+                  ProcessPlayerCommand( j );
+               }
+            break;
+            }
+         else
+            {
+            UpdateClientControls();
+            }
+         }
+      }
+}
+
+
+//****************************************************************************
+//
+// ControlPlayerObj ()
+//
+//****************************************************************************
+void ControlPlayerObj (objtype * ob)
+{
+	playertype * pstate;
+   int num;
+   int savetime;
+//   boolean asked;
+
+//   if (GamePaused==true)
+//      return;
+
+   M_LINKSTATE(ob,pstate);
+
+	// get player number
+
+   num=ob->dirchoosetime;
+
+   memcpy (pstate->buttonheld, pstate->buttonstate, sizeof(pstate->buttonstate));
+
+   if (oldpolltime==nextupdatetime)
+      {
+      if (num==numplayers-1)
+         nextupdatetime=oldpolltime+controldivisor;
+      if (networkgame==true)
+         savetime=GetTicCount()+NETWORKTIMEOUT;
+      else
+         savetime=GetTicCount()+MODEMTIMEOUT;
+
+      if (PlayerStatus[num]!=player_ingame)
+         return;
+
+      //   asked=false;
+
+      // copy previous state of buttons
+
+
+      while (1)
+         {
+         if (ServerCommandStatus(oldpolltime)==cs_ready)
+            {
+            ProcessPlayerCommand (num);
+            if (demoplayback||demorecord) {
+               SoftError("x=%4x y=%4x a=%4x time=%5d\n",player->x,player->y,player->angle,oldpolltime);
+	    }
+            break;
+            }
+   //      else if ((ServerCommandStatus(oldpolltime)==cs_fixing) &&
+   //               (networkgame==false) &&
+   //               (asked==false)
+   //              )
+   //         {
+   //         asked=true;
+   //         RequestPacket(oldpolltime, server, controldivisor);
+   //         }
+         else
+            {
+            UpdateClientControls();
+            }
+
+         if (GetTicCount()>savetime)
+            {
+            SoftError("Client timeout oldpolltime=%d\n",oldpolltime);
+            if (IsServer==false)
+               RequestPacket(oldpolltime, server, controldivisor);
+            if (networkgame==true)
+               savetime=GetTicCount()+NETWORKTIMEOUT;
+            else
+               savetime=GetTicCount()+MODEMTIMEOUT;
+            }
+         }
+      }
+
+   if (!(ob->flags&FL_DYING))
+      {
+      if (ob->flags&FL_PUSHED)
+         {
+         ob->flags&=~FL_PUSHED;
+#if 0
+         if (abs(ob->momentumx)>0)
+            {
+            if (abs(ob->momentumx+pstate->dmomx)>=abs(ob->momentumx))
+               {
+               ob->momentumx += pstate->dmomx;
+               ob->momentumy += pstate->dmomy;
+               }
+            }
+         else if (abs(ob->momentumy+pstate->dmomy)>=abs(ob->momentumy))
+            {
+            ob->momentumx += pstate->dmomx;
+            ob->momentumy += pstate->dmomy;
+            }
+#endif
+         if (abs(ob->momentumx+pstate->dmomx)>=abs(ob->momentumx))
+            {
+            ob->momentumx += pstate->dmomx;
+            }
+         if (abs(ob->momentumy+pstate->dmomy)>=abs(ob->momentumy))
+            {
+            ob->momentumy += pstate->dmomy;
+            }
+         }
+      else
+         {
+         ob->momentumx += pstate->dmomx;
+         ob->momentumy += pstate->dmomy;
+         }
+      }
+}
+
+//****************************************************************************
+//
+// MaxSpeedForCharacter ()
+//
+//****************************************************************************
+
+int MaxSpeedForCharacter(playertype*pstate)
+{
+   if (BATTLEMODE && (gamestate.BattleOptions.Speed == bo_fast_speed))
+      {
+      return( FASTSPEED );
+      }
+   else
+      {
+      if (pstate->buttonstate[bt_run])
+         return (characters[pstate->player].toprunspeed);
+      else
+         return (characters[pstate->player].topspeed);
+      }
+}
+
+//****************************************************************************
+//
+// UpdatePlayerObj ()
+//
+//****************************************************************************
+
+void UpdatePlayerObj ( int player )
+{
+	int i, buttonbits;
+	playertype * pstate;
+	MoveType * MoveCmd;
+
+   MoveCmd=(MoveType *)PlayerCommand(player,CommandAddress(oldpolltime));
+
+	pstate=&PLAYERSTATE[player];
+
+   buttonbits = MoveCmd->buttons;
+	for (i = 0; i < NUMTXBUTTONS; i++)
+		{
+		pstate->buttonstate[i] = buttonbits & 1;
+		buttonbits   >>= 1;
+		}
+
+   pstate->dmomx = (int)(MoveCmd->momx)<<1;
+   pstate->dmomy = (int)(MoveCmd->momy)<<1;
+	pstate->angle = MoveCmd->dangle;
+	pstate->angle <<= 11;
+   pstate->topspeed=MaxSpeedForCharacter(pstate);
+
+   if (demoplayback||demorecord) {
+      SoftError("  dmx=%4x dmy=%4x da=%4x time=%5d\n",pstate->dmomx,pstate->dmomy,pstate->angle>>11,oldpolltime);
+   }
+#if 0
+#if (DEVELOPMENT == 1)
+         if ((modemgame==true) || (demoplayback==true) || (demorecord==true))
+		   {
+			ComError( "player#%2ld\n",player);
+		   ComError( "momx = %6ld\n", PLAYER[player]->momentumx);
+		   ComError( "momy = %6ld\n", PLAYER[player]->momentumy);
+		   ComError( "   x = %6ld\n", PLAYER[player]->x);
+		   ComError( "   y = %6ld\n", PLAYER[player]->y);
+		   ComError( "   z = %6ld\n", PLAYER[player]->z);
+		   ComError( "   a = %6ld\n", PLAYER[player]->angle);
+		   if (pstate->buttonstate[bt_attack])
+			   ComError( "FIRING\n");
+         }
+#endif
+#endif
+}
+
+
+//****************************************************************************
+//
+// SendPlayerDescription ()
+//
+//****************************************************************************
+
+void SendPlayerDescription( void )
+{
+   byte * temp;
+   COM_GamePlayerType * desc;
+   int length;
+
+   length=sizeof(COM_GamePlayerType);
+   temp=SafeMalloc(length);
+
+   memset(temp,0,length);
+
+   desc=(COM_GamePlayerType *)temp;
+   desc->type=(byte)COM_GAMEDESC;
+	desc->player=consoleplayer;
+   desc->violence=gamestate.violence;
+   desc->Version = gamestate.Version;
+   desc->Product = gamestate.Product;
+   desc->playerdescription.character=locplayerstate->player;
+   desc->playerdescription.uniformcolor=locplayerstate->uniformcolor;
+   strcpy(&(desc->playerdescription.codename[0]),
+      &locplayerstate->codename[0]);
+
+   WritePacket(temp,length,server);
+
+   SafeFree(temp);
+}
+
+//****************************************************************************
+//
+// SendGameDescription ()
+//
+//****************************************************************************
+
+void SendGameDescription( void )
+{
+   byte * temp;
+   COM_GameMasterType * desc;
+   int length;
+   int i;
+
+   length=sizeof(COM_GameMasterType);
+   temp=SafeMalloc(length);
+
+   memset(temp,0,length);
+
+   desc=(COM_GameMasterType *)temp;
+   desc->type=(byte)COM_GAMEMASTER;
+   desc->level=gamestate.mapon;
+   desc->mapcrc=GetMapCRC (gamestate.mapon);
+   desc->mode=gamestate.battlemode;
+   desc->violence=gamestate.violence;
+   desc->Version = gamestate.Version;
+   desc->Product = gamestate.Product;
+   desc->teamplay = gamestate.teamplay;
+   memcpy( &desc->SpecialsTimes, &gamestate.SpecialsTimes, sizeof( specials ) );
+   BATTLE_GetOptions( &( desc->options ) );
+   GetMapFileName( &(desc->battlefilename[0]) );
+   desc->randomseed=GetRNGindex ( );
+   gamestate.randomseed=desc->randomseed;
+   desc->ludicrousgibs=battlegibs;
+   ludicrousgibs=battlegibs;
+//   SetRNGindex ( gamestate.randomseed );
+	for (i=0;i<numplayers;i++)
+      {
+      if (gamestate.Product == ROTT_SHAREWARE)
+         PLAYERSTATE[i].player = 0;
+		desc->players[i].character    =PLAYERSTATE[i].player;
+		desc->players[i].uniformcolor =PLAYERSTATE[i].uniformcolor;
+      strcpy ( &(desc->players[i].codename[0]),&(PLAYERSTATE[i].codename[0]));
+      }
+
+   if (!networkgame)
+      AssignTeams();
+
+   if (IsServer==false)
+      {
+      WritePacket(temp,length,server);
+      }
+   else
+      {
+      BroadcastServerPacket(temp,length); // Send to all
+      }
+
+   SafeFree(temp);
+}
+
+//****************************************************************************
+//
+// SetGameDescription ()
+//
+//****************************************************************************
+
+void SetGameDescription( void * pkt )
+{
+   COM_GameMasterType * desc;
+   word localcrc;
+   int i;
+
+   desc=(COM_GameMasterType *)pkt;
+   gamestate.mapon=desc->level;
+   gamestate.battlemode=desc->mode;
+   gamestate.violence=desc->violence;
+   gamestate.Version = desc->Version;
+   gamestate.Product = desc->Product;
+   gamestate.teamplay = desc->teamplay;
+   memcpy( &gamestate.SpecialsTimes, &desc->SpecialsTimes, sizeof( specials ) );
+   BATTLE_SetOptions( &( desc->options ) );
+   gamestate.randomseed=desc->randomseed;
+   SetRNGindex ( gamestate.randomseed );
+   SetBattleMapFileName( &(desc->battlefilename[0]) );
+   localcrc=GetMapCRC (gamestate.mapon);
+   ludicrousgibs=desc->ludicrousgibs;
+   if (localcrc!=desc->mapcrc)
+      Error("You have different maps on your system\n");
+   for (i=0;i<numplayers;i++)
+      {
+		PLAYERSTATE[i].player=desc->players[i].character;
+		PLAYERSTATE[i].uniformcolor=desc->players[i].uniformcolor;
+      strcpy ( &(PLAYERSTATE[i].codename[0]),
+               &(desc->players[i].codename[0])
+             );
+      }
+   AssignTeams();
+}
+
+//****************************************************************************
+//
+// SetPlayerDescription ()
+//
+//****************************************************************************
+
+void SetPlayerDescription( void * pkt )
+{
+   COM_GamePlayerType * desc;
+
+   desc=(COM_GamePlayerType *)pkt;
+	PLAYERSTATE[desc->player].player=desc->playerdescription.character;
+   PLAYERSTATE[desc->player].uniformcolor=desc->playerdescription.uniformcolor;
+   strcpy ( &(PLAYERSTATE[desc->player].codename[0]),
+            &(desc->playerdescription.codename[0])
+          );
+   if ( gamestate.Version != desc->Version )
+      {
+      Error("Player %s is using a different version of ROTT\n",PLAYERSTATE[desc->player].codename);
+//      gamestate.Version = desc->Version;
+      }
+
+   if ( gamestate.violence > desc->violence )
+      {
+      gamestate.violence = desc->violence;
+      }
+
+   if ( gamestate.Product > desc->Product )
+      {
+      gamestate.Product = desc->Product;
+      }
+}
+
+//****************************************************************************
+//
+// SendGameAck ()
+//
+//****************************************************************************
+
+void SendGameAck( void )
+{
+   byte * temp;
+   int length;
+   COM_GameAckType * desc;
+
+   length=sizeof(COM_GameAckType);
+   temp=SafeMalloc(length);
+   desc=(COM_GameAckType *)temp;
+   desc->type=COM_GAMEACK;
+	desc->player=consoleplayer;
+
+   WritePacket(temp,length,server);
+
+   SafeFree(temp);
+}
+
+//****************************************************************************
+//
+// SendGameStart ()
+//
+//****************************************************************************
+
+void SendGameStart( void )
+{
+   byte * temp;
+   int length;
+
+   length=DUMMYPACKETSIZE;
+   temp=SafeMalloc(length);
+   *(temp)=(byte)COM_GAMEPLAY;
+
+   if (IsServer==false)
+      {
+      WritePacket(temp,length,server);
+      }
+   else
+      {
+      BroadcastServerPacket(temp,length); // Send to all
+      }
+
+   SafeFree(temp);
+}
+
+//****************************************************************************
+//
+// SetupGamePlayer ()
+//
+//****************************************************************************
+void SetupGamePlayer ( void )
+{
+   int savetime;
+   boolean done;
+   boolean gameready;
+
+   savetime=GetTicCount();
+
+   done=false;
+   gameready=false;
+
+   while (done==false)
+      {
+		// Setup individual player
+      AbortCheck("SetupGamePlayer aborted\n");
+
+      // send Player Description
+		if (GetTicCount() >= savetime)
+         {
+         savetime=GetTicCount()+SETUPTIME;
+         if (gameready==false)
+            SendPlayerDescription();
+         else
+            SendGameAck();
+         }
+      switch (SetupCheckForPacket())
+         {
+         case scfp_done:
+            done=true;
+            break;
+         case scfp_gameready:
+            gameready=true;
+            break;
+         }
+      }
+   savetime=GetTicCount()+(VBLCOUNTER/2);
+
+   while (GetTicCount()<savetime)
+      {
+      SetupCheckForPacket ();
+      }
+}
+
+//****************************************************************************
+//
+// AllPlayersReady ()
+//
+//****************************************************************************
+boolean AllPlayersReady ( void )
+{
+   int i;
+
+	for (i=0;i<numplayers;i++)
+      if ((PlayersReady[i]==false) && (PlayerStatus[i]==player_ingame))
+         return false;
+
+   return true;
+}
+
+//****************************************************************************
+//
+// GotAllPlayerDescriptions ()
+//
+//****************************************************************************
+boolean GotAllPlayerDescriptions ( void )
+{
+   int i;
+
+	for (i=0;i<numplayers;i++)
+      if ((GotPlayersDesc[i]==false) && (PlayerStatus[i]==player_ingame))
+         return false;
+
+   return true;
+}
+
+//****************************************************************************
+//
+// SetupGameMaster ()
+//
+//****************************************************************************
+void SetupGameMaster ( void )
+{
+   int savetime;
+   boolean done;
+
+   memset(GotPlayersDesc,false,sizeof(GotPlayersDesc));
+	GotPlayersDesc[consoleplayer]=true;
+
+   memset(PlayersReady,false,sizeof(PlayersReady));
+	PlayersReady[consoleplayer]=true;
+
+   savetime=GetTicCount();
+
+   done=false;
+
+   InitializeRNG ();
+
+   while (done==false)
+      {
+		// Setup individual player
+
+      AbortCheck("SetupGameMaster aborted\n");
+
+      // send Game Description
+		if (GetTicCount() >= savetime)
+         {
+         savetime=GetTicCount()+SETUPTIME;
+			if (GotAllPlayerDescriptions()==true)
+            SendGameDescription();
+         }
+      if (AllPlayersReady ()==true)
+         {
+         SendGameStart();
+         SendGameStart();
+         done=true;
+         }
+      SetupCheckForPacket();
+      }
+   savetime=GetTicCount()+(VBLCOUNTER/2);
+
+   while (GetTicCount()<savetime)
+      {
+      SetupCheckForPacket ();
+      }
+}
+
+
+
+
+
+
+
+
+
+
+/*
+=============================================================================
+
+   DEMO CODE
+
+=============================================================================
+*/
+//****************************************************************************
+//
+// GetDemoFilename ()
+//
+//****************************************************************************
+
+void GetDemoFilename (int demonumber, char * filename)
+{
+   strcpy(filename,"demo0_0.dmo\0");
+
+   filename[4] = (char)('0' + (byte)demonumber);
+   filename[6] = (char)('0' + (byte)gamestate.violence);
+   FixFilePath(filename);
+}
+//****************************************************************************
+//
+// DemoExists ()
+//
+//****************************************************************************
+
+boolean DemoExists (int demonumber)
+{
+   char demo[20];
+
+   GetDemoFilename (demonumber, &demo[0]);
+   if (access (demo, F_OK) == 0)
+      return true;
+   else
+   {
+      /* Saves the users violence level, only do this once, otherwise
+         we might override the saved level with one already modified by us */
+      if (predemo_violence == -1)
+         predemo_violence = gamestate.violence;
+      /* The demos distributed with rott are all for a violence level of 3 */
+      gamestate.violence = 3;
+      GetDemoFilename (demonumber, &demo[0]);
+      if (access (demo, F_OK) == 0)
+         return true;
+      else
+         return false;
+   }
+}
+
+//****************************************************************************
+//
+// SaveDemo ()
+//
+//****************************************************************************
+
+void SaveDemo (int demonumber)
+{
+   char demo[20];
+
+   RecordDemoCmd ();
+   GetDemoFilename (demonumber, &demo[0]);
+   SaveFile (demo, demobuffer, (demoptr-demobuffer));
+   FreeDemo();
+}
+
+//****************************************************************************
+//
+// LoadDemo ()
+//
+//****************************************************************************
+
+void LoadDemo (int demonumber)
+{
+   char demo[20];
+   int size;
+
+   GetDemoFilename (demonumber, demo);
+   if (demobuffer!=NULL)
+      FreeDemo();
+   size = LoadFile (demo, (void **)&demobuffer);
+   playstate = ex_demoplayback;
+   demoptr = demobuffer;
+   lastdemoptr = (demoptr+size);
+   locplayerstate->player=0;
+   InitializeWeapons(locplayerstate);
+   ResetPlayerstate(locplayerstate);
+   InitCharacter();
+}
+
+//****************************************************************************
+//
+// RecordDemo ()
+//
+//****************************************************************************
+
+void RecordDemo ( void )
+{
+   DemoHeaderType * DemoHeader;
+   int level;
+
+   if (demobuffer!=NULL)
+      FreeDemo();
+   godmode=0;
+   demobuffer = SafeMalloc (DEMOBUFFSIZE);
+   demoptr = demobuffer;
+   lastdemoptr = demobuffer+DEMOBUFFSIZE;
+
+   // Save off level number
+
+   DemoHeader=(DemoHeaderType *)demoptr;
+   demoptr+=sizeof(gamestate);
+   memcpy(&(DemoHeader->demostate),&gamestate,sizeof(gamestate));
+   demorecord = true;
+   locplayerstate->player=0;
+   InitializeWeapons(locplayerstate);
+   ResetPlayerstate(locplayerstate);
+   level=gamestate.mapon;
+   InitCharacter();
+   gamestate.mapon=level;
+   SoftError(">>>>>>>>>>>>Start demo record\n");
+}
+
+//****************************************************************************
+//
+// SetupDemo ()
+//
+//****************************************************************************
+
+void SetupDemo ( void )
+{
+   DemoHeaderType * DemoHeader;
+
+   demoplayback = true;
+   godmode=0;
+
+   DemoHeader=(DemoHeaderType *)demoptr;
+   demoptr+=sizeof(gamestate);
+//   if (gamestate.violence!=DemoHeader->demostate.violence)
+//      Error ("This demo has a different difficulty level than your current settings\n");
+   memcpy(&gamestate,&(DemoHeader->demostate),sizeof(gamestate));
+   SoftError(">>>>>>>>>>>>Start demo playback\n");
+}
+
+//****************************************************************************
+//
+// FreeDemo ()
+//
+//****************************************************************************
+
+void FreeDemo ( void )
+{
+   demoplayback = false;
+   demorecord = false;
+   SafeFree (demobuffer);
+   demobuffer=NULL;
+}
+
+//****************************************************************************
+//
+// CheckForDemoDone ()
+//
+//****************************************************************************
+
+void CheckForDemoDone ( void )
+{
+	if ((demoplayback==true) && (demoptr >= lastdemoptr))
+		{
+      FreeDemo();
+      playstate = ex_demodone;
+		}
+}
+
+//****************************************************************************
+//
+// CheckForDemoOverflowed ()
+//
+//****************************************************************************
+
+void CheckForDemoOverflowed ( void )
+{
+	if (demoptr >= (lastdemoptr-sizeof(DemoType)))
+      {
+      playstate = ex_completed;     // demo is done
+      EndDemo();
+      }
+}
+
+//****************************************************************************
+//
+// RecordDemoCmd ()
+//
+//****************************************************************************
+
+void RecordDemoCmd (void)
+{
+   DemoType * dtime;
+
+   SoftError("Demo command recorded at %d\n",controlupdatetime);
+   dtime=(DemoType *)demoptr;
+   dtime->time = controlupdatetime;
+   dtime->momx = (controlbuf[0]>>1);
+   dtime->momy = (controlbuf[1]>>1);
+   dtime->dangle = controlbuf[2]>>11;
+   dtime->buttons = buttonbits;
+
+   demoptr+=sizeof(DemoType);
+
+   CheckForDemoOverflowed();
+}
+
+//****************************************************************************
+//
+// AddDemoCmd ()
+//
+//****************************************************************************
+
+void AddDemoCmd (void)
+{
+   DemoType * dtime;
+
+   //
+   // get info from demo buffer
+   //
+
+   SoftError("Demo command played at %d\n",controlupdatetime);
+   if (demoplayback==true)
+      {
+      dtime=(DemoType *)demoptr;
+      controlbuf[0]=dtime->momx<<1;
+      controlbuf[1]=dtime->momy<<1;
+      controlbuf[2]=dtime->dangle<<11;
+      buttonbits   =dtime->buttons;
+      demoptr+=sizeof(DemoType);
+		}
+}
+
+//****************************************************************************
+//
+// GetNextDemoTime ()
+//
+//****************************************************************************
+
+int GetNextDemoTime (void)
+{
+   DemoType * dtime;
+
+   CheckForDemoDone();
+   dtime=(DemoType *)demoptr;
+   if (demoplayback)
+      return dtime->time;
+   else
+      return -1;
+}
+
+//****************************************************************************
+//
+// UpdateDemoPlayback ()
+//
+//****************************************************************************
+
+void UpdateDemoPlayback (int time)
+{
+   if (demoplayback)
+      {
+      if (GetNextDemoTime()==time)
+         AddDemoCmd();
+      }
+}
+
+
+
+
+

Added: tags/rott-1.1/rott/rt_net.h
===================================================================
--- tags/rott-1.1/rott/rt_net.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_net.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,331 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//   RT_NET.H - Network stuff
+//
+//***************************************************************************
+
+#ifndef _rt_net_public
+#define _rt_net_public
+
+#include "develop.h"
+#include "rottnet.h"
+#include "rt_actor.h"
+#include "rt_battl.h"
+#include "rt_playr.h"
+#include "rt_main.h"
+
+
+#define MAXCMDS  256
+
+#define COM_DELTA   1
+#define COM_REQUEST 2
+#define COM_FIXUP   3
+#define COM_TEXT    4
+#define COM_PAUSE   5
+#define COM_QUIT    6
+#define COM_SYNC    7
+#define COM_REMRID  8
+#define COM_RESPAWN 10
+#define COM_UNPAUSE 11
+#define COM_SERVER  12
+#define COM_START   13
+#define COM_GAMEDESC 15
+#define COM_GAMEPLAY 16
+#define COM_GAMEMASTER 17
+#define COM_GAMEACK 18
+#define COM_ENDGAME  19
+#define COM_SYNCTIME 20
+#if (SYNCCHECK==1)
+#define COM_SYNCCHECK 21
+#endif
+#define COM_SOUNDANDDELTA  22
+#define COM_EXIT    23
+#define COM_GAMEEND 24
+#define COM_DELTANULL 25
+
+#define CHECKSYNCTIME  (VBLCOUNTER<<2)
+
+#define NETSYNCSERVERTIME (VBLCOUNTER)
+#define MODEMSYNCSERVERTIME (VBLCOUNTER/4)
+
+#define DUMMYPACKETSIZE 20
+
+
+#define COM_MAXTEXTSTRINGLENGTH 33
+
+// Sound defines for Remote ridicule
+
+#define COM_SOUND_START_TRANSMISSION  (0xff)
+#define COM_SOUND_END_TRANSMISSION    (0xfe)
+#define COM_SOUND_NORMAL_TRANSMISSION (0xfd)
+#define COM_SOUND_BUFFERSIZE 256
+
+// Demo Delta Structure
+typedef struct DemoType {
+  int   time;
+  short momx;
+  short momy;
+  word  dangle;
+  word  buttons;
+} DemoType;
+
+// Demo Header Structure
+typedef struct DemoHeaderType {
+  gametype demostate;
+} DemoHeaderType;
+
+// Movement Queue Structure
+typedef struct MoveType {
+  byte  type;
+  int   time;
+  short momx;
+  short momy;
+  word  dangle;
+  word  buttons;
+  char  Sounddata[0];
+} MoveType;
+
+typedef struct NullMoveType {
+  byte  type;
+  int   time;
+} NullMoveType;
+
+typedef struct {
+
+  void * Commands[MAXCMDS];
+
+} CommandType;
+
+typedef struct {
+
+  byte CommandStates[MAXCMDS];
+
+} CommandStatusType;
+
+typedef MoveType COM_SoundAndDeltaType;
+
+// uncomment for live remote ridicule
+typedef struct {
+  byte  type;
+  byte  data[COM_SOUND_BUFFERSIZE];
+//  char  data[COM_MAXTEXTSTRINGLENGTH];
+} COM_SoundType;
+
+typedef struct {
+  byte  type;
+  int   synctime;
+} COM_SyncType;
+
+typedef struct {
+  byte  type;
+  int   time;
+  int   synctime;
+  int   x;
+  int   y;
+  int   z;
+  word  angle;
+  word  randomindex;
+} COM_CheckSyncType;
+
+typedef struct {
+  byte  type;
+  int   time;
+  byte  numpackets;
+  byte  data;
+} COM_ServerHeaderType;
+
+typedef struct {
+  byte  type;
+  int   time;
+  byte   numpackets;
+} COM_RequestType;
+
+typedef struct {
+  byte  type;
+  int   time;
+  byte  towho;
+  char  string[COM_MAXTEXTSTRINGLENGTH];
+} COM_TextType;
+
+#define MSG_DIRECTED_TO_ALL  255
+#define MSG_DIRECTED_TO_TEAM 254
+
+typedef struct {
+  byte  type;
+  int   time;
+  byte  player;
+  byte  num;
+  byte  towho;
+} COM_RemoteRidiculeType;
+
+typedef struct {
+  byte  type;
+  int   time;
+  byte  numpackets;
+  byte  data;
+} COM_FixupType;
+
+typedef struct {
+  byte  type;
+  int   time;
+} COM_QuitType;
+
+typedef struct {
+  byte  type;
+  int   time;
+} COM_ExitType;
+
+typedef struct {
+  byte  type;
+  int   time;
+} COM_GameEndType;
+
+typedef struct {
+  byte  character;    // which character
+  byte  uniformcolor; // which color
+  char  codename[MAXCODENAMELENGTH];  // codename
+} COM_PlayerDescriptionType;
+
+typedef struct {
+  byte  type;
+  byte  player;    // which player
+  byte  violence;
+  byte  Product;
+  unsigned Version;
+
+  COM_PlayerDescriptionType playerdescription;
+} COM_GamePlayerType;
+
+typedef struct {
+  byte  type;
+  byte  level;
+  word  mapcrc;
+  byte  violence;
+  byte  Product;
+  byte  mode;
+  unsigned Version;
+  boolean teamplay;
+  specials SpecialsTimes;
+  battle_type options;
+  char  battlefilename[20];
+  int   randomseed;
+  boolean ludicrousgibs;
+  COM_PlayerDescriptionType players[MAXPLAYERS];
+} COM_GameMasterType;
+
+typedef struct {
+  byte  type;
+  byte  player; // which player
+} COM_GameAckType;
+
+typedef struct {
+  byte  type;
+  int   time;
+} COM_EndGameType;
+
+typedef struct {
+  byte  type;
+  int   time;
+} COM_RespawnType;
+
+typedef struct {
+  byte  type;
+  int   time;
+} COM_PauseType;
+
+typedef struct {
+  byte  type;
+  int   time;
+} COM_UnPauseType;
+
+extern boolean  demorecord,
+					 demoplayback;
+extern byte     *demoptr,
+					 *lastdemoptr,
+                *demobuffer;
+extern boolean  demodone;
+extern int      predemo_violence;
+
+void     ControlPlayer (void);
+void     ControlRemote (objtype * ob);
+void     ControlPlayerObj (objtype * ob);
+void InitializeGameCommands( void );
+void ShutdownGameCommands( void );
+void UpdateClientControls ( void );
+void StartupClientControls ( void );
+void ShutdownClientControls ( void );
+void ProcessServer ( void );
+void ServerLoop( void );
+void SendPlayerDescription( void );
+void SetGameDescription( void * pkt );
+void SendGameDescription( void );
+void SendGameAck( void );
+void SendGameStart( void );
+void SetupGamePlayer ( void );
+void SetupGameMaster ( void );
+void SetNormalHorizon (objtype * ob);
+void SaveDemo (int demonumber);
+void LoadDemo (int demonumber);
+void RecordDemo ( void );
+void SetupDemo ( void );
+void FreeDemo ( void );
+boolean DemoExists (int demonumber);
+
+void AddEndGameCommand ( void );
+void AddTextMessage ( char * message, int length, int towho );
+void AddEndGameCommand ( void );
+void AddPauseStateCommand ( int type );
+void AddRespawnCommand ( void );
+void RecordDemoCmd (void);
+void ResetCurrentCommand ( void );
+void AddRemoteRidiculeCommand ( int player, int towho, int num );
+void ProcessRemoteRidicule ( void * pkt );
+void SyncToServer( void );
+void AddQuitCommand ( void );
+void AddExitCommand ( void );
+void AddGameEndCommand ( void );
+boolean PlayerInGame ( int p );
+boolean ConsoleIsServer ( void );
+
+extern boolean IsServer;
+extern boolean standalone;
+extern boolean    playerdead;
+
+extern boolean    modemgame;
+extern boolean    networkgame;
+extern int        numplayers;
+extern int        server;
+
+extern boolean    GamePaused;
+extern boolean    battlegibs;
+
+extern boolean    remoteridicule;
+
+#if (SYNCCHECK==1)
+extern int        lastsynccheck;
+extern COM_CheckSyncType PlayerSync[MAXPLAYERS];
+void CheckForSyncCheck ( void );
+#endif
+
+int GamePacketSize( void );
+
+#endif

Added: tags/rott-1.1/rott/rt_playr.c
===================================================================
--- tags/rott-1.1/rott/rt_playr.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_playr.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,6382 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#ifdef DOS
+#include <dos.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "rt_def.h"
+#include "watcom.h"
+#include "rt_sound.h"
+#include "gmove.h"
+#include "states.h"
+#include "rt_sqrt.h"
+#include "rt_actor.h"
+#include "rt_main.h"
+#include "rt_playr.h"
+#include "isr.h"
+#include "rt_draw.h"
+#include "rt_ted.h"
+#include "rt_door.h"
+#include "rt_menu.h"
+#include "rt_view.h"
+#include "rt_com.h"
+#include "rt_in.h"
+#include "rt_util.h"
+#include "rt_game.h"
+#include "rt_rand.h"
+#include "z_zone.h"
+#include "rt_swift.h"
+#include "engine.h"
+#include "_rt_play.h"
+#include "rt_cfg.h"
+#include "rt_spbal.h"
+#include "rt_floor.h"
+#include "develop.h"
+#include "rt_msg.h"
+#include "rt_debug.h"
+#include "sprites.h"
+#include "rt_net.h"
+#include "rt_dmand.h"
+//MED
+#include "memcheck.h"
+
+
+#define FLYINGZMOM  350000
+
+
+#if (DEVELOPMENT == 1)
+#include "rt_str.h"
+#endif
+
+extern boolean usejump;
+
+
+specials CurrentSpecialsTimes =
+      {
+      60*VBLCOUNTER, // god
+      60*VBLCOUNTER, // dog
+      20*VBLCOUNTER, // shrooms
+      20*VBLCOUNTER, // elasto
+      60*VBLCOUNTER, // asbestos vest
+      60*VBLCOUNTER, // bullet proof vest
+      GASTICS, // gas mask
+      60*VBLCOUNTER, // mercury mode
+
+      300*VBLCOUNTER, // god respawn
+      60*VBLCOUNTER, // dog respawn
+      60*VBLCOUNTER, // shrooms respawn
+      60*VBLCOUNTER, // elasto respawn
+      60*VBLCOUNTER, // asbestos vest respawn
+      60*VBLCOUNTER, // bullet proof vest respawn
+      60*VBLCOUNTER, // gas mask respawn
+      60*VBLCOUNTER  // mercury mode respawn
+      };
+
+int GRAVITY = NORMAL_GRAVITY;
+
+ROTTCHARS characters[5]={
+   {0x2100,0x4800,100,2,25},  // Taradino Cassatt
+   {0x2200,0x5200,85,3,32},   // Thi Barrett
+   {0x1f00,0x4000,150,3,20},  // Doug Wendt
+   {0x2300,0x5500,70,2,33},   // Lorelei Ni
+   {0x2000,0x4400,120,3,25}}; // Ian Paul Freeley
+
+static const int TD = MINACTORDIST+0x1000;
+static const int STRAFEAMOUNT = ((KEYBOARDNORMALTURNAMOUNT >> 10) + (KEYBOARDNORMALTURNAMOUNT >> 12));
+
+
+static const int GODYZANGLE     = -(9*FINEANGLES/360);
+static const int DOGYZANGLE     =  (4*FINEANGLES/360);
+static const int SHROOMYZANGLE  =  (15*FINEANGLES/360);
+static const int FALLINGYZANGLE = -(15*FINEANGLES/360);
+static const int NORMALYZANGLE  = 0;
+
+
+/*
+=============================================================================
+
+			GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+int controlbuf[3];
+int buttonbits;
+extern _2Dpoint LASTSOUND;
+//
+// player state info
+//
+
+statobj_t      *DEADPLAYER[MAXDEAD];
+int            NUMDEAD;
+int            lastpolltime;
+
+statobj_t      *BulletHoles[MAXBULLETS];
+int            BulletHoleNum;
+
+objtype        *PLAYER[MAXPLAYERS],*player;
+playertype     PLAYERSTATE[MAXPLAYERS],*locplayerstate;
+
+gametype       gamestate;
+
+boolean        godmode = false;
+
+boolean       missilecam=false;
+objtype       * missobj=NULL;
+// Player control variables
+
+int KX = 0;
+int KY = 0;
+int MX = 0;
+int MY = 0;
+int JX = 0;
+int JY = 0;
+int CX = 0;
+int CY = 0;
+boolean vrenabled = false;
+int VX = 0;
+int VY = 0;
+
+int oldcyberx = 0;
+int oldcybery = 0;
+int CYBERDEADRANGE = 6000;
+boolean CYBERLOOKUP,CYBERLOOKDOWN;
+
+int leftmom = 0;
+int rightmom = 0;
+int lastmom = 0;
+int first    = 1;
+
+int pausedstartedticcount;
+boolean RefreshPause = true;
+
+boolean  buttonpoll[NUMBUTTONS];
+
+int      buttonscan[NUMBUTTONS] = {sc_Control, sc_Alt, sc_RShift, sc_Space,
+											  sc_PgUp,sc_PgDn,sc_Enter,sc_Delete,
+                                   sc_Home,sc_End,sc_1,sc_2,sc_3,sc_4,
+                                   sc_CapsLock, sc_F12,
+                                   sc_Comma,sc_Period,sc_BackSpace,sc_A,
+                                   sc_UpArrow, sc_RightArrow,
+                                   sc_DownArrow, sc_LeftArrow,
+                                   sc_Tab, sc_T, sc_Z };
+
+int      joyxmax = 0, joyymax = 0, joyxmin = 0, joyymin = 0;
+
+int      buttonmouse[6] = {bt_attack, bt_strafe, di_north,
+                           bt_nobutton, bt_use, bt_nobutton };
+
+int      buttonjoy[8] = {bt_attack, bt_strafe, bt_run, bt_use,
+                         bt_nobutton, bt_nobutton, bt_nobutton, bt_nobutton };
+
+williamdidthis FREE = {84,5,0,0,9,{{done,2,1},{done,2,2},{done,2,3},
+  {done,2,4},{done,2,5},{done,2,6},{done,2,7},{done,2,8},
+  {reset,2,9}}};
+
+williamdidthis DOGSCRATCH = {128,5,0,0,4,{{done,2,8},{at_pulltrigger,2,9},{done,2,10},
+                             {reset,2,11}}};
+
+williamdidthis DOGLICK =    {128,5,0,0,4,{{done,2,4},{done,2,5},{done,2,6},
+                             {reset,2,7}}};
+
+
+williamdidthis WEAPONS[MAXWEAPONS] =
+
+{
+ {100,-1,10,0x2000l,3,{{at_pulltrigger,4,1},{done,4,2},{reset,4,0}}}, //single pistol
+ {100,-1,10,0x2000l,6,{{at_pulltrigger,2,1},{done,2,2},{done,2,3},
+						{at_pulltrigger,2,4},{done,2,5},{reset,2,3}}}, // double pistol
+ {70,-1,10,0x2000l,2,{{at_pulltrigger,2,1},{reset,1,2}}}, //mp 40
+ {80,5,10,0x50000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //bazooka
+ {80,5,10,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //firebomb
+ {80,5,10,0x50000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //heatseeker
+ {80,5,10,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //drunk
+ {80,5,7,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,2},{reset2,6,0}}}, // firewall
+ {125,5,7,0x10000l,7,{{done,3,1},{done,3,2},{done,3,3},{done,3,4},
+						  {at_missileweapon,3,5},{done,3,6},{reset,3,7}}},	//GODHAND
+
+#if (SHAREWARE == 0)
+ {80,5,7,0x10000l,4,{{at_missileweapon,2,1},{done,2,2},{reset,2,3},{reset2,6,0}}}, //split
+ {80,5,7,0x10000l,9,{{done,5,1},{done,5,2},{done,5,3},{done,5,4},
+						{at_missileweapon,10,5},{done,5,4},{done,5,3}, // kes
+						{done,5,2},{reset,5,1}}},
+ {200,5,7,0x10000l,6,{{done,1,1},{done,1,2},{at_pulltrigger,1,3},{at_pulltrigger,1,4},
+						  {at_pulltrigger,1,5},{reset,1,6}}},	//BAT
+ {128,5,7,0x10000l,3,{{done,2,1},{at_pulltrigger,2,2},{reset,2,3}}}
+#endif
+};
+
+
+
+/*
+=============================================================================
+
+					LOCAL FUNCTION PROTOTYPES and VARIABLES
+
+=============================================================================
+*/
+
+void     CheckPlayerSpecials(objtype * ob);
+void     CheckWeaponStates(objtype * ob);
+boolean  CheckSprite (statobj_t* ,int *);
+void     T_Tag (objtype *ob);
+void     T_Player (objtype *ob);
+void     T_BatBlast(objtype*ob);
+void     T_Attack (objtype *ob);
+void     T_Free (objtype *ob);
+void     T_DogUse (objtype *ob);
+void     PlayerMove(objtype * ob);
+void     Thrust (objtype * ob);
+void     CheckWeaponChange (objtype * ob);
+void     PlayerMissileAttack(objtype* );
+void     Cmd_Use(objtype*);
+//void     ComError (char *error, ...);
+int      FinddTopYZANGLELIMITvalue(objtype *ob);
+
+statetype s_free = {false,0,0,T_Free,0,&s_free};
+statetype s_inelevator = {false,0,420,T_Player,0,&s_player};
+
+#if (SHAREWARE == 0)
+statetype s_dogwait = {true,SERIALDOG_W11,50,T_Player,SF_DOGSTATE,&s_serialdog};
+
+statetype s_doguse = {true,SERIALDOG_W11,140,T_DogUse,SF_DOGSTATE,&s_serialdog};
+statetype s_doglick = {true,SERIALDOG_W11,0,T_DogLick,SF_DOGSTATE,&s_doglick};
+#endif
+
+statetype s_tag = {false,CASSATT_S1,20,T_Tag,0,&s_player};
+
+static SWIFT_3DStatus SWIFTStatus;
+
+//
+// curent user input
+//
+
+static int turnheldtime;
+static int turnaround = 0;
+static int turnaroundtime;
+
+//
+// Double Click variables
+//
+
+static int  DoubleClickTimer[ 3 ]   = { 0 };
+static byte DoubleClickCount[ 3 ]   = { 0 };
+static byte DoubleClickPressed[ 3 ] = { false };
+static int  JoyDblClickTimer[ 4 ]   = { 0 };
+static byte JoyDblClickCount[ 4 ]   = { 0 };
+static byte JoyDblClickPressed[ 4 ] = { false };
+
+
+static int PlayerRecording=-1;
+static int nettics;
+
+void Move_Player_From_Exit_To_Start(objtype *ob);
+void CheckTagGame(objtype *actor1,objtype*actor2);
+void CheckFlying(objtype*ob,playertype *pstate);
+
+/*
+===============
+=
+= LoadPlayer
+=
+===============
+*/
+void LoadPlayer ( void )
+{
+	memset (locplayerstate->buttonstate, 0, sizeof(locplayerstate->buttonstate));
+   locplayerstate->anglefrac=player->angle<<ANGLEBITS;
+   areabyplayer[player->areanumber]=true;
+	ConnectAreas();
+}
+
+
+int MaxHitpointsForCharacter(playertype*pstate)
+{
+   if (BATTLEMODE && (gamestate.BattleOptions.HitPoints != bo_character_hitpoints))
+      {
+      return( gamestate.BattleOptions.HitPoints );
+      }
+   return characters[pstate->player].hitpoints;
+}
+
+void InitializeWeapons(playertype*pstate)
+{
+
+
+#if (SHAREWARE == 0)
+ if (gamestate.SpawnEluder)
+	{pstate->new_weapon = pstate->weapon = pstate->missileweapon = wp_dog;
+	 pstate->oldweapon = pstate->oldmissileweapon = wp_dog;
+	 pstate->bulletweapon = -1;
+	 pstate->HASBULLETWEAPON[wp_pistol] = 0;
+	 pstate->HASBULLETWEAPON[wp_twopistol] = 0;
+	 pstate->HASBULLETWEAPON[wp_mp40] = 0;
+	}
+ else
+#endif
+	{if (gamestate.PlayerHasGun[pstate-&PLAYERSTATE[0]])
+		 {pstate->new_weapon = pstate->weapon = pstate->oldweapon =
+		  pstate->bulletweapon = wp_pistol;
+		  pstate->HASBULLETWEAPON[wp_pistol] = 1;
+		  pstate->HASBULLETWEAPON[wp_twopistol] = 0;
+		  pstate->HASBULLETWEAPON[wp_mp40] = 0;
+		  pstate->missileweapon = pstate->oldmissileweapon = -1;
+		 }
+	 else
+		 {pstate->new_weapon = pstate->weapon = pstate->oldweapon =
+		  pstate->bulletweapon = -1;
+		  pstate->HASBULLETWEAPON[wp_pistol] = 0;
+		  pstate->HASBULLETWEAPON[wp_twopistol] = 0;
+		  pstate->HASBULLETWEAPON[wp_mp40] = 0;
+		  pstate->missileweapon = pstate->oldmissileweapon = -1;
+		 }
+	}
+
+
+ pstate->ammo = -1;
+}
+
+void ResetPlayerstate(playertype*pstate)
+{
+
+ pstate->batblast = 0;
+ pstate->poweruptime = pstate->protectiontime = 0;
+ pstate->NETCAPTURED = 0;
+ MISCVARS->NET_IN_FLIGHT = 0;
+ pstate->weaponuptics = 0;
+ pstate->weapondowntics = 0;
+ if ((insetupgame==false) || NewGame)
+	 pstate->health = MaxHitpointsForCharacter(pstate);
+ pstate->keys = 0;
+
+ // Give players all the keys in battle game
+
+ if ( BATTLEMODE )
+    {
+    pstate->keys = 0x0f;
+    }
+ pstate->attackframe = pstate->attackcount =
+ pstate->weaponframe = 0;
+ if (gamestate.battlemode == battle_Tag)
+	pstate->weaponheight = TAGHANDHEIGHT;
+ else
+	pstate->weaponheight = 0;
+ pstate->heightoffset = pstate->oldheightoffset = 0;
+ if (gamestate.SpawnEluder)
+	pstate->playerheight = 40;
+ else
+	pstate->playerheight = characters[pstate->player].height;
+ pstate->falling = false;
+ memset (pstate->buttonstate, 0, sizeof(pstate->buttonstate));
+ SetPlayerHorizon(pstate,NORMALYZANGLE);
+}
+
+
+
+
+/*
+===============
+=
+= SetupPlayerobj
+=
+===============
+*/
+void SetupPlayerobj (int tilex, int tiley, int dir, objtype * ob)
+{
+	playertype *pstate;
+
+	M_LINKSTATE(ob,pstate);
+
+	ob->obclass = playerobj;
+	ob->tilex = tilex;
+	ob->tiley = tiley;
+	actorat[tilex][tiley] = ob;
+	ob->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE;
+	MakeLastInArea(ob);
+	ob->x = ((long)tilex<<TILESHIFT)+TILEGLOBAL/2;
+	ob->y = ((long)tiley<<TILESHIFT)+TILEGLOBAL/2;
+	ob->z = PlatformHeight(tilex,tiley);
+   if ((ob->z == -10) || DiskAt(tilex,tiley))
+     ob->z = 0;
+
+	ob->angle = (1-dir)*ANG90;
+	ob->which = ACTOR;
+	Fix(ob->angle);
+   ob->yzangle = 0;
+
+	ob->dir   = angletodir[ob->angle];
+	ob->flags = (FL_SHOOTABLE|FL_ABP|FL_BLOCK|FL_COLORED);
+	ob->drawx=ob->x;
+	ob->drawy=ob->y;
+	ob->hitpoints = pstate->health;
+	pstate->anglefrac= (ob->angle<<ANGLEBITS);
+	pstate->angle=0;
+	areabyplayer[ob->areanumber]=true;
+
+
+	if (ob == player)
+		{
+		playerdead=false; // local player dead flag
+		}
+	if (!gamestate.SpawnEluder)
+	  ob->shapeoffset = pstate->player*REMOTEOFFSET;
+
+	memset (pstate->buttonstate, 0, sizeof(pstate->buttonstate));
+   if (SCREENEYE != NULL)
+      {
+      NewState(SCREENEYE,&s_megaremove);
+      SCREENEYE = NULL;
+      }
+}
+
+
+
+void SetShapeoffset(objtype*ob)
+{playertype *pstate;
+
+ M_LINKSTATE(ob,pstate);
+ ob->shapeoffset = pstate->player*REMOTEOFFSET;
+ ob->flags |= FL_COLORED;
+ ob->flags &= ~FL_DYING;
+
+}
+
+
+/*
+===============
+=
+= RevivePlayerobj
+=
+===============
+*/
+void RevivePlayerobj (int tilex, int tiley, int dir, objtype*ob)
+{
+	playertype *pstate;
+	statetype *tstate;
+
+	M_LINKSTATE(ob,pstate);
+	tstate = ob->state;
+	RemoveFromArea(ob);
+	TurnActorIntoSprite(ob);
+	if ((LASTSTAT->z < nominalheight) && (!IsPlatform(LASTSTAT->tilex,LASTSTAT->tiley)))
+      {
+      SpawnParticles(ob,GUTS,10 + gamestate.difficulty);
+		RemoveStatic(LASTSTAT);
+      }
+	else
+	  {if (DEADPLAYER[NUMDEAD])
+			RemoveStatic(DEADPLAYER[NUMDEAD]);
+		DEADPLAYER[NUMDEAD] = LASTSTAT;
+		LASTSTAT->linked_to = NUMDEAD;
+		NUMDEAD = (NUMDEAD+1)&(MAXDEAD-1);
+	  }
+
+	ob->state = tstate;
+
+	SetupPlayerobj (tilex, tiley, dir, ob);
+	ConnectAreas();
+
+	ResetPlayerstate(pstate);
+	InitializeWeapons(pstate);
+   SD_PlaySoundRTP(SD_PLAYERSPAWNSND,ob->x,ob->y);
+	if (!gamestate.SpawnEluder)
+      {
+      ob->shapeoffset = 0;
+      ob->flags &= ~FL_COLORED;
+      ob->flags |= FL_DYING;
+      NewState(ob,&s_respawn1);
+      if (gamestate.battlemode == battle_Tag)
+         {
+         if (BATTLE_Team[ob->dirchoosetime] == BATTLE_It)
+
+            {
+            pstate->missileweapon = pstate->oldweapon = pstate->new_weapon =
+            pstate->oldmissileweapon = pstate->weapon = wp_godhand;
+            pstate->bulletweapon = -1;
+            ob->flags |= FL_DESIGNATED;
+            }
+         else
+            {
+            pstate->weaponheight = 0;
+            }
+         }
+		}
+#if (SHAREWARE == 0)
+	else
+      NewState(ob,&s_serialdog);
+#endif
+	if (ob==player)
+		DrawPlayScreen(false);
+   ob->momentumx = ob->momentumy = ob->momentumz = 0;
+}
+
+
+/*
+===============
+=
+= SpawnPlayerobj
+=
+===============
+*/
+void SpawnPlayerobj (int tilex, int tiley, int dir, int playerindex)
+{
+ playertype *pstate;
+
+	pstate = &PLAYERSTATE[playerindex];
+
+	GetNewActor();
+	MakeActive(new);
+
+	// Set player number
+
+	new->dirchoosetime = playerindex;
+
+	// Save off if local player
+
+	if (playerindex==consoleplayer)
+		player=new;
+
+	PLAYER[playerindex] = new;
+
+	SetupPlayerobj (tilex, tiley, dir, new);
+
+	if (!gamestate.SpawnEluder)
+		NewState(new,&s_player);
+#if (SHAREWARE == 0)
+   else
+      NewState(new,&s_serialdog);
+#endif
+
+
+}
+
+/*
+===============
+=
+= SetupBulletHoleLink
+=
+===============
+*/
+void SetupBulletHoleLink (int num, statobj_t * item)
+{
+   BulletHoles[num] = item;
+}
+
+/*
+===============
+=
+= SpawnBulletHole
+=
+===============
+*/
+void SpawnBulletHole (int x, int y, int z)
+{
+   if (M_ISDOOR(x>>16,y>>16))
+      return;
+   if (BulletHoles[MISCVARS->BulletHoleNum])
+      RemoveStatic(BulletHoles[MISCVARS->BulletHoleNum]);
+   SpawnInertStatic(x,y,z,stat_bullethole);
+	BulletHoles[MISCVARS->BulletHoleNum]=LASTSTAT;
+   LASTSTAT->linked_to=MISCVARS->BulletHoleNum;
+	MISCVARS->BulletHoleNum = (MISCVARS->BulletHoleNum+1)&(MAXBULLETS-1);
+}
+
+
+
+
+void SpawnGunSmoke(int x, int y, int z, int angle, int bullethole)
+
+{
+	int chance;
+
+	if ((x<=0) || (y<=0))
+      {
+      SoftError("SpawnGunSmoke: xy below angle=%d\n",angle);
+      return;
+      }
+
+   if ((bullethole!=0) && (z>=-32) && (z<=maxheight))
+      switch (bullethole)
+         {
+         case 1:
+            SpawnBulletHole(x-BULLETHOLEOFFSET,y,z);
+            break;
+         case 2:
+            SpawnBulletHole(x+BULLETHOLEOFFSET,y,z);
+            break;
+         case 3:
+            SpawnBulletHole(x,y-BULLETHOLEOFFSET,z);
+            break;
+         case 4:
+            SpawnBulletHole(x,y+BULLETHOLEOFFSET,z);
+            break;
+         case 5:
+            SpawnBulletHole(x,y,z);
+            break;
+         default:
+            Error("Invalid bullethole value\n");
+            break;
+         }
+
+   SpawnInertActor(x,y,z);
+
+   NewState(new,&s_gunsmoke1);
+
+   if (angle < ANGLES/4)
+	 {if ((angle < (3*ANGLES/16)) && (angle > (ANGLES/16)))
+		chance = 128;
+	  else
+		chance = 20;
+	 }
+	else if (angle < ANGLES/2)
+	 {if ((angle < (7*ANGLES/16)) && (angle > (5*ANGLES/16)))
+		chance = 128;
+	  else
+		chance = 20;
+	 }
+	else if (angle < 3*ANGLES/4)
+	 {if ((angle < (11*ANGLES/16)) && (angle > (9*ANGLES/16)))
+		chance = 128;
+	  else
+		chance = 20;
+	 }
+	else
+	 {if ((angle < (15*ANGLES/16)) && (angle > (13*ANGLES/16)))
+		chance = 128;
+	  else
+		chance = 20;
+	 }
+
+	if (RandomNumber("Wall ricochet check",0)<chance)
+	 {int rand;
+
+	  rand = RandomNumber("Spawn Ricochet Sound in SpawnGunSmoke",0);
+	  if (rand < 80)
+		 SD_PlaySoundRTP(SD_RICOCHET1SND,new->x,new->y);
+	  else if (rand < 160)
+		 SD_PlaySoundRTP(SD_RICOCHET2SND,new->x,new->y);
+	  else
+		 SD_PlaySoundRTP(SD_RICOCHET3SND,new->x,new->y);
+	 }
+}
+
+void  SpawnBlood(objtype * ob, int angle)
+   {
+
+   SpawnInertActor(ob->x-(costable[angle]>>5),
+                   ob->y+(sintable[angle]>>5),ob->z);
+
+   NewState(new,&s_bloodspurt1);
+
+   if ((new->x<=0) || (new->y<=0))
+	   Error("SpawnBlood: bad x,y obj->obclass=%d\n",ob->obclass);
+   }
+
+void  SpawnMetalSparks(objtype * ob, int angle)
+   {
+   int rand,dispx=0,dispy=0;
+
+
+   if (ob->which == ACTOR)
+      {
+      dispx = ob->momentumx;
+      dispy = ob->momentumy;
+      }
+
+   SpawnInertActor(ob->x-(costable[angle]>>3)+dispx,
+                   ob->y+(sintable[angle]>>3)+dispy,ob->z);
+
+   if (GameRandomNumber("Spawn Metal Sparks",0)<128)
+	  NewState(new,&s_hitmetalactor1);
+	else
+	  NewState(new,&s_hitmetalwall1);
+
+	rand = RandomNumber("Spawn Ricochet Sound",0);
+	if (rand < 80)
+	 SD_PlaySoundRTP(SD_RICOCHET1SND,new->x,new->y);
+	else if (rand < 160)
+	 SD_PlaySoundRTP(SD_RICOCHET2SND,new->x,new->y);
+	else
+	 SD_PlaySoundRTP(SD_RICOCHET3SND,new->x,new->y);
+	if ((new->x<=0) || (new->y<=0))
+	   Error("SpawnMetalSparks: bad x,y obj->obclass=%d\n",ob->obclass);
+}
+
+/*
+===============
+=
+= UnTargetActor ( objtype * target )
+=
+===============
+*/
+void UnTargetActor ( objtype * target )
+{
+   int i;
+
+   for (i=0;i<numplayers;i++)
+      {
+      if (PLAYERSTATE[i].guntarget==target)
+         {
+         PLAYERSTATE[i].guntarget=NULL;
+         SetNormalHorizon(PLAYER[i]);
+         }
+      }
+}
+
+
+
+//=============================================================
+
+int GetWeaponForItem(int itemnumber)
+   {
+   switch (itemnumber)
+      {
+
+
+      case  stat_twopistol:
+         return wp_twopistol;
+
+      case  stat_mp40:
+         return wp_mp40;
+
+      case  stat_bazooka:
+         return wp_bazooka;
+
+      case  stat_heatseeker:
+         return wp_heatseeker;
+
+      case  stat_drunkmissile:
+         return wp_drunk;
+
+      case  stat_firebomb:
+         return wp_firebomb;
+
+      case  stat_firewall:
+         return wp_firewall;
+
+      case  stat_godmode:
+         return wp_godhand;
+
+#if (SHAREWARE == 0)
+
+
+      case  stat_splitmissile:
+         return wp_split;
+
+      case  stat_kes:
+         return wp_kes;
+
+      case  stat_bat:
+         return wp_bat;
+
+
+      case  stat_dogmode:
+         return wp_dog;
+#endif
+      }
+    return 0;
+   }
+
+
+int GetItemForWeapon(int weapon)
+   {
+   switch (weapon)
+      {
+
+      case wp_twopistol:
+         return stat_twopistol;
+
+      case  wp_mp40:
+         return stat_mp40;
+
+      case  wp_bazooka:
+         return stat_bazooka;
+
+      case  wp_heatseeker:
+         return stat_heatseeker;
+
+      case  wp_drunk:
+         return stat_drunkmissile;
+
+      case  wp_firebomb:
+         return stat_firebomb;
+
+      case  wp_firewall:
+         return stat_firewall;
+
+      case  wp_godhand:
+         return stat_godmode;
+
+#if (SHAREWARE == 0)
+
+      case  wp_split:
+         return stat_splitmissile;
+
+      case  wp_kes:
+         return stat_kes;
+
+      case  wp_bat:
+         return stat_bat;
+
+
+      case  wp_dog:
+         return stat_dogmode;
+#endif
+      }
+    return -1;
+   }
+
+
+
+#define MF_SINGULAR 0x01
+
+missile_stats PlayerMissileData[13] =
+
+    {
+     {0,0,0,0,0},
+     {0,0,0,0,0},
+     {0,0,0,0,0},
+
+     {&s_p_bazooka1,0x6000,p_bazookaobj,0x7000,MF_SINGULAR},
+     {&s_p_bazooka1,0x8000,p_heatseekobj,0x7000,MF_SINGULAR},
+     {&s_p_bazooka1,0x6000,p_drunkmissileobj,0x7000,0},
+     {&s_p_bazooka1,0x8000,p_firebombobj,0x7000,MF_SINGULAR},
+     {&s_p_grenade,0x4000,p_firewallobj,0x8000,0},
+     {&s_godfire1,0x3800,p_godballobj,0x8000,0},
+     {&s_p_bazooka1,0x8000,p_splitmissileobj,0x7000,MF_SINGULAR},
+#if (SHAREWARE == 0)
+     {&s_kessphere1,0xc000,p_kesobj,0x5000,MF_SINGULAR},
+#else
+     {0,0,0,0,0},
+#endif
+     {0,0,0,0,0},
+     {0,0,0,0,0}
+
+    };
+
+
+void MissileAutoTarget(objtype *ob,missile_stats *mdata)
+   {
+   int dx,dy,angle,mindist,currdist,magangle,saveangle,
+       xydist,dz,yzangle,oldyzangle,saveyzangle;
+   objtype *target,*temp;
+
+   mindist = 0x7fffffff;
+   target = NULL;
+   for(temp = firstactive;temp;temp=temp->nextactive)
+      {
+      if (temp == ob)
+         continue;
+      if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
+         continue;
+      if (!CheckLine(ob,temp,SHOOT))
+         continue;
+
+      dx = temp->x-ob->x;
+      dy = ob->y-temp->y;
+      dz = ob->z-temp->z;
+      xydist = FindDistance(dx,dy);
+      yzangle = atan2_appx(xydist,dz<<10);
+
+      angle = atan2_appx(dx,dy);
+
+      magangle = abs(ob->angle - angle);
+      if (magangle > VANG180)
+         magangle = ANGLES - magangle;
+
+      if (magangle > ANGLESDIV8)
+         continue;
+
+      currdist = FindDistance(ob->x-temp->x,ob->y-temp->y);
+      if (currdist < mindist)
+         {
+         mindist = currdist;
+         target = temp;
+         saveangle = angle;
+         saveyzangle = yzangle;
+         }
+      }
+
+   if (target)
+      {
+      oldyzangle = ob->yzangle;
+      ob->yzangle = saveyzangle;
+      SpawnMissile(ob,mdata->obclass,mdata->speed,saveangle,
+                   mdata->state,mdata->offset);
+      ob->yzangle = oldyzangle;
+      }
+
+   else if (ob->flags&FL_GODMODE)
+      {
+      int saveangle;
+
+      saveangle=ob->yzangle;
+      ob->yzangle -= GODYZANGLE;
+      Fix(ob->yzangle);
+      SpawnMissile(ob,mdata->obclass,mdata->speed,
+                   ob->angle,mdata->state,mdata->offset);
+      ob->yzangle=saveangle;
+      }
+   else
+      SpawnMissile(ob,mdata->obclass,mdata->speed,ob->angle,
+                   mdata->state,mdata->offset);
+
+  }
+
+
+void PlayerMissileAttack(objtype*ob)
+
+   {
+   playertype * pstate;
+   missile_stats *newmissiledata;
+   M_LINKSTATE(ob,pstate);
+
+
+   MISCVARS->madenoise = true;
+   newmissiledata = &PlayerMissileData[pstate->missileweapon];
+
+   // ready to annihilate this poor bastard
+
+   if ((newmissiledata->obclass == p_godballobj) ||
+       (newmissiledata->obclass == p_kesobj))
+      MissileAutoTarget(ob,newmissiledata);
+
+   else
+      {
+      SpawnMissile(ob,newmissiledata->obclass,newmissiledata->speed,ob->angle,
+                  newmissiledata->state,newmissiledata->offset);
+
+      if (newmissiledata->obclass == p_drunkmissileobj)
+         {
+         int i;
+
+         for(i=0;i<4;i++)
+            {
+            if (!MissileTryMove(new,new->x+new->momentumx,new->y+new->momentumy,new->z))
+               {
+               new->x = new->drawx = ob->x + (costable[new->angle]>>3);
+               new->y = new->drawy = ob->y - (sintable[new->angle]>>3);
+
+               ob->momentumx = -FixedMul(0x5000l,costable[ob->angle]);
+               ob->momentumy = FixedMul(0x5000l,sintable[ob->angle]);
+               }
+
+            SpawnMissile(ob,newmissiledata->obclass,newmissiledata->speed,ob->angle,
+                        newmissiledata->state,newmissiledata->offset);
+
+
+            }
+         }
+      }
+
+
+   if (newmissiledata->flags & MF_SINGULAR)
+      PLAYER0MISSILE = new;
+
+   SD_PlaySoundRTP(BAS[new->obclass].fire,ob->x,ob->y);
+
+   // if (new->obclass == p_godballobj)
+   //   new->z += 10;
+
+   new->dirchoosetime = 5;
+   if (missilecam==true)
+      missobj=new;
+   if (!MissileTryMove(new,new->x+new->momentumx,new->y+new->momentumy,new->z))
+      {
+      new->x = new->drawx = ob->x + (costable[new->angle]>>3);
+      new->y = new->drawy = ob->y - (sintable[new->angle]>>3);
+
+      ob->momentumx = -FixedMul(0x5000l,costable[ob->angle]);
+      ob->momentumy = FixedMul(0x5000l,sintable[ob->angle]);
+      }
+
+   }
+
+//====================================================================
+
+
+boolean InRange (objtype *p, objtype *victim, int distance)
+{
+	int dx,dy;
+	int angle;
+	int magangle;
+
+   if (victim->which==SPRITE)
+		{
+	   dx = ((statobj_t *)victim)->x - p->x;
+	   dy = p->y - ((statobj_t *)victim)->y;
+      }
+   else
+      {
+	   dx = victim->x - p->x;
+	   dy = p->y - victim->y;
+      }
+	angle = atan2_appx (dx,dy);
+
+	magangle = abs(p->angle - angle);
+	if (magangle > VANG180)
+		 magangle = ANGLES - magangle;
+	if (magangle<(75-(distance>>16)))
+		return true;
+	else
+		return false;
+}
+
+
+void DogAttack(objtype*ob)
+   {
+   objtype *temp;
+   int dx,dy,dz;
+
+   SD_PlaySoundRTP(SD_DOGMODEBITE1SND+(RandomNumber("DogAttack",0)>>7),ob->x,ob->y);
+   for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
+      {
+
+      if (temp->obclass > b_heinrichobj)
+         continue;
+
+
+      if ((temp == ob) || (temp->obclass == roboguardobj))
+         continue;
+
+      if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
+         continue;
+      if (temp->obclass == collectorobj)
+         continue;
+
+
+      dx = abs(temp->x - ob->x);
+      if (dx > 0xc000)
+         continue;
+
+      dy = abs(temp->y - ob->y);
+      if (dy > 0xc000)
+         continue;
+
+      dz = abs(temp->z - ob->z);
+      if (dz > (0xc000>>10))
+         continue;
+
+      DamageThing(temp,30);
+      if (gamestate.violence == vl_excessive)
+         SpawnParticles(temp,GUTS,15);
+      Collision(temp,ob,-temp->momentumx,-temp->momentumy);
+      if ((temp->obclass == playerobj) && (temp->flags & FL_DYING))
+         BATTLE_PlayerKilledPlayer(battle_kill_with_missile,ob->dirchoosetime,temp->dirchoosetime);
+
+      return;
+      }
+   }
+
+
+void DogBlast(objtype*ob)
+   {
+   int txl,txh,tyl,tyh,radius = 0x70000,x,y,tile;
+   objtype*temp;
+   statobj_t*tstat;
+
+   txl = ((ob->x - radius)>>TILESHIFT);
+   tyl = ((ob->y - radius)>>TILESHIFT);
+
+   txh = ((ob->x + radius)>>TILESHIFT);
+   tyh = ((ob->y + radius)>>TILESHIFT);
+
+   if (txl < 1)
+      txl = 1;
+   if (txh > MAPSIZE-1)
+      txh = MAPSIZE-1;
+   if (tyl < 1)
+      tyl = 1;
+   if (tyh > MAPSIZE-1)
+      tyh = MAPSIZE-1;
+
+   for(x=txl;x<=txh;x++)
+      for(y=tyl;y<=tyh;y++)
+         {
+         temp = (objtype*)actorat[x][y];
+
+         if (temp && (temp->which == ACTOR) && (temp->flags & FL_SHOOTABLE) &&
+             (temp != ob) && (temp->obclass < roboguardobj) &&
+             (temp->flags & FL_ABP)
+            )
+            {
+            DamageThing(temp,100);
+            if ((temp->hitpoints<=0) && (temp->obclass < roboguardobj))
+               {
+               MISCVARS->supergibflag = true;
+               temp->flags |= FL_HBM;
+               }
+            Collision(temp,ob,0,0);
+            MISCVARS->supergibflag = false;
+
+            if ((temp->obclass == playerobj) && (temp->flags & FL_DYING))
+               BATTLE_PlayerKilledPlayer(battle_kill_with_missile,ob->dirchoosetime,temp->dirchoosetime);
+
+            }
+
+         tile = tilemap[x][y];
+         if ((tile & 0x4000) && (tile & 0x8000))
+            {
+            maskedwallobj_t * mw;
+
+            mw=maskobjlist[tile&0x3ff];
+            if ((mw->flags & MW_SHOOTABLE) && (mw->flags & MW_ABP))
+               UpdateMaskedWall(tile&0x3ff);
+            }
+
+         tstat = sprites[x][y];
+         if (tstat && (tstat->flags & FL_SHOOTABLE) && (tstat->flags & FL_ABP))
+               DamageThing(tstat,50);
+         }
+   }
+/*
+void DogBlast(objtype*ob)
+   {
+   int txl,txh,tyl,tyh,radius = 0x70000,x,y,tile;
+   objtype*temp;
+   statobj_t*tstat;
+
+   txl = ((ob->x - radius)>>TILESHIFT);
+   tyl = ((ob->y - radius)>>TILESHIFT);
+
+   txh = ((ob->x + radius)>>TILESHIFT);
+   tyh = ((ob->y + radius)>>TILESHIFT);
+
+   if (txl < 1)
+      txl = 1;
+   if (txh > MAPSIZE-1)
+      txh = MAPSIZE-1;
+   if (tyl < 1)
+      tyl = 1;
+   if (tyh > MAPSIZE-1)
+      tyh = MAPSIZE-1;
+
+   for(x=txl;x<=txh;x++)
+      for(y=tyl;y<=tyh;y++)
+         {
+         temp = (objtype*)actorat[x][y];
+
+         if (temp && (temp->which == ACTOR) && (temp->flags & FL_SHOOTABLE) &&
+            (temp != ob) && (temp->obclass < roboguardobj))
+            {
+            DamageThing(temp,100);
+            if ((temp->hitpoints<=0) && (temp->obclass < roboguardobj))
+               {
+               MISCVARS->supergibflag = true;
+               temp->flags |= FL_HBM;
+               }
+            Collision(temp,ob,0,0);
+            MISCVARS->supergibflag = false;
+
+            if ((temp->obclass == playerobj) && (temp->flags & FL_DYING))
+               BATTLE_PlayerKilledPlayer(battle_kill_with_missile,ob->dirchoosetime,temp->dirchoosetime);
+
+            }
+
+         tile = tilemap[x][y];
+         if ((tile & 0x4000) && (tile & 0x8000))
+            {
+            maskedwallobj_t * mw;
+
+            mw=maskobjlist[tile&0x3ff];
+            if (mw->flags & MW_SHOOTABLE)
+               UpdateMaskedWall(tile&0x3ff);
+            }
+
+         tstat = sprites[x][y];
+         if (tstat && (tstat->flags & FL_SHOOTABLE))
+            DamageThing(tstat,50);
+         }
+   }
+*/
+
+void BatBlast(objtype*ob)
+{int angle;
+ playertype *pstate;
+
+ M_LINKSTATE(ob,pstate);
+
+ angle = ob->angle - ANGLES/8 + ((++pstate->batblast)*ANGLES/48);
+ Fix(angle);
+#if (SHAREWARE == 0)
+ SpawnMissile(ob,p_bazookaobj,0x6000,angle,&s_batblast1,0xa000);
+#endif
+
+}
+
+
+
+void BatAttack(objtype*ob)
+{objtype *temp,*temp2;
+ objtype *grenadetarget;
+ statobj_t*tstat;
+ int dx,dy,dz,angle,momx,momy,op,magangle;
+ int tilexlow,tilexhigh;
+ int tileylow,tileyhigh;
+ int radius =0x10000;
+ int x,y;
+
+ SD_PlaySoundRTP(SD_EXCALISWINGSND,ob->x,ob->y);
+ for(temp=firstareaactor[ob->areanumber];temp;temp=temp->nextinarea)
+  {if (temp == ob)
+	 continue;
+
+   if (temp->flags & FL_DYING)
+     continue;
+
+   if ((temp->obclass != grenadeobj) &&
+       (!((temp->obclass >= grenadeobj) && (temp->obclass <= p_godballobj))) &&
+		 (!(temp->flags & FL_SHOOTABLE) ||
+		  (temp->obclass >= roboguardobj))
+		)
+	 continue;
+
+	dx = abs(temp->x - ob->x);
+	dy = abs(temp->y - ob->y);
+	dz = abs(temp->z - ob->z);
+   if ((dx > 0x10000) || (dy > 0x10000) || (dz > 20))
+	 continue;
+
+	magangle = abs(ob->angle - AngleBetween(ob,temp));
+	if (magangle > VANG180)
+		 magangle = ANGLES - magangle;
+
+	if (magangle > ANGLES/8)
+	  continue;
+
+
+	angle= ob->angle+ANGLES/16;
+	Fix(angle);
+
+   if ((temp->obclass >= grenadeobj) && (temp->obclass <= p_godballobj))
+     {
+      temp->angle += ANGLES/2;
+      Fix(temp->angle);
+      temp->momentumx = temp->momentumy = temp->momentumz = 0;
+      ParseMomentum(temp,temp->angle);
+      temp->whatever = ob;
+      temp->target = NULL;
+      continue;
+     }
+
+
+   else if (temp->obclass != grenadeobj)
+	  {momx = FixedMul(0x3000l,costable[angle]);
+		momy = -FixedMul(0x3000l,sintable[angle]);
+		if (levelheight > 2)
+		 {op = FixedMul(GRAVITY,(maxheight-100)<<16) << 1;
+		  temp->momentumz = -FixedSqrtHP(op);
+		 }
+		temp->flags |= FL_NOFRICTION;
+		SD_PlaySoundRTP(SD_EXCALIHITSND,ob->x,ob->y);
+		if ((gamestate.violence == vl_excessive) && (GameRandomNumber("Bat Gibs",0) < 150))
+		  {temp->flags |= FL_HBM;
+			DamageThing(temp,50);
+		  }
+		else
+			DamageThing(temp,10);
+		if ((temp->flags & FL_HBM) && (temp->hitpoints > 0))
+		  temp->flags &= ~FL_HBM;
+      Collision(temp,ob,momx,momy);
+		if ((temp->obclass == blitzguardobj) && (temp->state == &s_blitzplead7))
+		  {temp->shapeoffset += deathshapeoffset[temp->obclass];
+			temp->flags |= FL_ALTERNATE;
+			NewState(temp,&s_blitzdie3);
+			temp->momentumx = temp->momentumy = 0;
+		  }
+	  }
+	else // find target to hit grenade back at
+	  {int rand;
+
+		rand = GameRandomNumber("bat/grenade target",0);
+		if (rand < 80)
+		  {grenadetarget = (objtype*)(temp->whatever); // hit back at george
+         GetMomenta(grenadetarget,ob,&(temp->momentumx),&(temp->momentumy),&(temp->momentumz),0x3000);
+		  }
+		else if (rand < 160) // hit back at first eligible
+		  {
+
+			for(temp2 = firstareaactor[ob->areanumber];temp2;temp2 = temp2->nextinarea)
+				{magangle = abs(ob->angle-AngleBetween(ob,temp2));
+				 if (magangle > VANG180)
+					 magangle = ANGLES - magangle;
+
+				 if (magangle > ANGLES/8)
+					 continue;
+             GetMomenta(temp2,ob,&(temp->momentumx),&(temp->momentumy),&(temp->momentumz),0x3000);
+				 break;
+				}
+		  }
+		else // hit wherever
+		  {ob->angle += (rand >> 1);
+			Fix(ob->angle);
+			ob->momentumx = ob->momentumy = 0;
+			ParseMomentum(ob,ob->angle);
+		  }
+
+
+		temp->temp1 = 0x70000;
+		NewState(temp,&s_grenade1);
+	  }
+	break;
+  }
+
+ for(tstat=firstactivestat;tstat;tstat=tstat->statnext)
+  {
+	if (!(tstat->flags & FL_SHOOTABLE))
+	  continue;
+
+	dx = abs(tstat->x - ob->x);
+	dy = abs(tstat->y - ob->y);
+	dz = abs(tstat->z - ob->z);
+
+	if ((dx > 0xc000) || (dy > 0xc000) || (dz > 20))
+	 continue;
+
+	magangle = abs(ob->angle - AngleBetween(ob,(objtype*)tstat));
+	if (magangle > VANG180)
+		 magangle = ANGLES - magangle;
+
+	if (magangle > ANGLES/8)
+	  continue;
+
+	DamageThing(tstat,50);
+
+
+  }
+
+ tilexlow = (int)((ob->x-radius) >>TILESHIFT);
+ tileylow = (int)((ob->y-radius) >>TILESHIFT);
+
+ tilexhigh = (int)((ob->x+radius) >>TILESHIFT);
+ tileyhigh = (int)((ob->y+radius) >>TILESHIFT);
+
+ for (y=tileylow;y<=tileyhigh;y++)
+	for (x=tilexlow;x<=tilexhigh;x++)
+		{if ((tilemap[x][y]&0x8000) && (tilemap[x][y]&0x4000))
+			{maskedwallobj_t * mw;
+
+			 mw=maskobjlist[tilemap[x][y]&0x3ff];
+			 if (mw->flags&MW_SHOOTABLE)
+					UpdateMaskedWall(tilemap[x][y]&0x3ff);
+			}
+		}
+
+}
+
+void AutoTargetHorizon(objtype *ob)
+   {
+   int dx,dy,angle,mindist,magangle,
+       xydist,dz;
+   objtype *temp;
+   playertype * pstate;
+
+	M_LINKSTATE(ob,pstate);
+
+   mindist = 0x7fffffff;
+   for(temp = firstactive;temp;temp=temp->nextactive)
+      {
+      if (temp == ob)
+         continue;
+      if ((!(temp->flags & FL_SHOOTABLE)) || (temp->flags & FL_DYING))
+         continue;
+      if (!CheckLine(ob,temp,SHOOT))
+         continue;
+
+      dx = temp->x-ob->x;
+      dy = ob->y-temp->y;
+      dz = ob->z-temp->z;//-pstate->playerheight+32;
+
+      xydist = FindDistance(dx,dy);
+      if (abs(dz<<10)>xydist)
+         continue;
+
+
+      angle = atan2_appx(dx,dy);
+
+      magangle = ob->angle - angle;
+      Fix(magangle);
+
+      if (
+          (magangle>=(ANGLESDIV8/4)) &&
+          (magangle<=(FINEANGLES-(ANGLESDIV8/4)))
+         )
+         {
+         continue;
+         }
+
+      if (xydist < mindist)
+         {
+         mindist = xydist;
+         pstate->guntarget=temp;
+         temp->flags |= FL_TARGET;
+         pstate->targettime=oldpolltime+(VBLCOUNTER);
+         }
+      }
+  }
+
+void  GunAttack (objtype *ob)
+{
+	playertype * pstate;
+	int      damage;
+
+	M_LINKSTATE(ob,pstate);
+
+	MISCVARS->madenoise = true;
+
+ switch (pstate->weapon)
+	{
+	case wp_pistol:
+		SD_PlaySoundRTP(SD_ATKPISTOLSND,ob->x,ob->y);
+		damage=DMG_PISTOL;
+		break;
+
+	case wp_mp40:
+		SD_PlaySoundRTP(SD_ATKMP40SND,ob->x,ob->y);
+		damage=DMG_MP40;
+		break;
+
+	case wp_twopistol:
+		SD_PlaySoundRTP(SD_ATKTWOPISTOLSND,ob->x,ob->y);
+		damage=DMG_PISTOL;
+		break;
+	}
+
+   AutoTargetHorizon(ob);
+   RayShoot (ob, damage, (characters[pstate->player].accuracy+gamestate.difficulty)<<3);
+
+}
+
+
+/*
+===============
+=
+= Cmd_Fire
+=
+===============
+*/
+void Cmd_Fire (objtype*ob)
+   {
+   playertype *pstate;
+
+   M_LINKSTATE(ob,pstate);
+
+//   pstate->buttonheld[bt_attack] = true;
+
+   if (pstate->NETCAPTURED && (!pstate->HASKNIFE))
+      return;
+
+   if (W_CHANGE(pstate))
+      return;
+
+   pstate->attackframe = 0;
+
+   if ((ob==player) && (pstate->weapon < wp_mp40) && (!pstate->NETCAPTURED))
+      gamestate.DODEMOCRATICBONUS1 = false;
+
+   if (!pstate->NETCAPTURED)
+      {
+      if (pstate->weapon <= wp_mp40)
+         NewState(ob,&s_pgunattack1);
+ #if (SHAREWARE == 0)
+      else if ((pstate->weapon == wp_bat) && (pstate->batblast >= BBTIME))
+         {
+         pstate->batblast = 0;
+         NewState(ob,&s_pbatblast);
+         }
+      else if (pstate->weapon == wp_dog)
+         NewState(ob,&s_serialdogattack);
+ #endif
+      else
+         NewState(ob,&s_pmissattack1);
+
+ #if (SHAREWARE == 0)
+
+      if ((pstate->weapon == wp_dog) && (!ob->momentumz))
+         ob->momentumz = -0x50000;
+ #endif
+      pstate->attackcount = WEAPONS[pstate->weapon].attackinfo[0].mtics;
+      pstate->weaponframe = WEAPONS[pstate->weapon].attackinfo[0].frame;
+      }
+
+   else if (pstate->NETCAPTURED == 1)
+      {
+      NewState(player,&s_free);
+      pstate->attackcount = FREE.attackinfo[0].mtics;
+      pstate->weaponframe = FREE.attackinfo[0].frame;
+      }
+
+   }
+
+void PlayNoWaySound ( void )
+   {
+   if (player->flags & FL_DOGMODE)
+      SD_Play(SD_DOGMODEBITE2SND);
+   else if ((locplayerstate->player == 1) || (locplayerstate->player == 3))
+      SD_Play(SD_PLAYERTBHURTSND);
+   else
+      SD_Play(SD_NOWAYSND);
+   }
+
+
+/*
+===============
+=
+= Cmd_Use
+=
+===============
+*/
+
+boolean AreJumping = false;//bna added
+int		oldzval;
+int donttilt=0;
+
+
+
+void Cmd_Use (objtype*ob)
+{
+   int             checkx,checky,doorn,
+                  /*newtilex,newtiley,oldtilex,oldtiley,*/elevnum,
+                  wallx,wally;
+//      statobj_t*      tempsprite=NULL;
+   objtype*        tempactor= NULL;
+   doorobj_t*      tempdoor=NULL;
+   pwallobj_t*      temppwall=NULL;
+   wall_t*         tempwall=NULL;
+   int             index;
+   playertype * pstate;
+
+
+
+   M_LINKSTATE(ob,pstate);
+
+#if (SHAREWARE == 0)
+
+   if ((pstate->weapon == wp_dog) && (ob->state != &s_doguse) &&
+       (ob->state != &s_dogwait) && (!W_CHANGE(pstate))
+      )
+      {
+      pstate->attackframe = 0;
+      NewState(ob,&s_doguse);
+      pstate->attackcount = DOGSCRATCH.attackinfo[0].mtics;
+      pstate->weaponframe = DOGSCRATCH.attackinfo[0].frame;
+      ob->momentumz = -0x40000;
+      return;
+
+      }
+
+   else
+#endif
+     if ((ob->flags & FL_DESIGNATED) && (BATTLEMODE) && (gamestate.battlemode == battle_Tag))
+        {
+        NewState(ob,&s_tag);
+      //return;
+        }
+//
+// find which cardinal direction the player is facing
+//
+   if (ob->angle < FINEANGLES/8 || ob->angle > 7*FINEANGLES/8)
+      {
+            checkx = ob->tilex + 1;
+            checky = ob->tiley;
+            ob->dir = east;
+            wallx = (checkx << TILESHIFT);
+            wally = (checky << TILESHIFT) + TILEGLOBAL/2;
+      }
+   else if (ob->angle < 3*FINEANGLES/8)
+      {
+            checkx = ob->tilex;
+            checky = ob->tiley-1;
+            ob->dir = north;
+            wally = (checky << TILESHIFT) + TILEGLOBAL;
+            wallx = (checkx << TILESHIFT) + TILEGLOBAL/2;
+      }
+   else if (ob->angle < 5*FINEANGLES/8)
+      {
+            checkx = ob->tilex - 1;
+            checky = ob->tiley;
+            ob->dir = west;
+            wallx = (checkx << TILESHIFT) + TILEGLOBAL;
+            wally = (checky << TILESHIFT) + TILEGLOBAL/2;
+      }
+   else
+      {
+            checkx = ob->tilex;
+            checky = ob->tiley + 1;
+            ob->dir = south;
+            wally = (checky << TILESHIFT);
+            wallx = (checkx << TILESHIFT) + TILEGLOBAL/2;
+      }
+
+
+   if (actorat[checkx][checky])
+      {
+      tempdoor=(doorobj_t*)actorat[checkx][checky];
+      tempactor = (objtype*)actorat[checkx][checky];
+      tempwall = (wall_t*)actorat[checkx][checky];
+      }
+   doorn = tilemap[checkx][checky] & ~0x2000;
+//      if (sprites[checkx][checky])
+//       tempsprite = sprites[checkx][checky];
+   if (doorn == (elevatorstart + 6))
+      return;
+
+   //bna ++ jumpmode
+   //SetTextMode (  );
+   if (!BATTLEMODE){//dont use jump in battle, spoils sync
+   if (usejump == true){
+   if (pstate->buttonheld[bt_use]){
+   if ((AreJumping == false)&&(ob->z > 0)&&(doorn==0)){
+	    oldzval = ob->z;
+		ob->z -= 15;
+		ob->momentumz += GRAVITY;
+		AreJumping = true;
+		donttilt=10;
+		return;
+   } 
+		AreJumping = false;
+		return;
+   }
+   }
+   }
+   //bna 
+
+
+   if (pstate->buttonheld[bt_use])
+      return;
+
+   if (doorn == (elevatorstart + 1))
+      {
+      tilemap[checkx][checky]++;              // flip switch
+      if (MAPSPOT(ob->tilex,ob->tiley,1) == ALTELEVATORTILE);
+         // playstate = ex_secretlevel;
+      else if (ob==player)
+         playstate = ex_completed;
+      }
+
+
+   else if (doorn == (elevatorstart + 5))
+
+      {
+      elevnum = MAPSPOT(ob->tilex,ob->tiley,1) - 90;
+      tempwall->flags |= FL_S_FLIPPED;
+      OperateElevatorSwitch(ob,elevnum,checkx,checky);
+      }
+   else if (tempdoor && tempdoor->which==PWALL)
+      {
+      temppwall=(pwallobj_t *)tempdoor;
+      OperatePushWall (temppwall->num,ob->dir, ob == player );
+      }
+   else if ((doorn&0x8000) && (!(doorn&0x4000)))
+      {
+      doorobj_t* dptr = doorobjlist[doorn&0x3ff];
+      int dnum = doorn&0x3ff;
+      int lock;
+
+      OperateDoor (pstate->keys, dnum, (ob == player));
+      if (dptr->eindex != -1)
+         {
+         elevator_t*eptr;
+
+
+         lock = dptr->lock;
+         if ( lock && !( pstate->keys & ( 1 << ( lock - 1 ) ) ) )
+            {
+            if (ob==player)
+               {
+               // locked
+               switch (lock)
+                  {
+                  case 1:
+                     AddMessage("You need the \\EGOLD key",MSG_DOOR);
+                     break;
+
+                  case 2:
+                     AddMessage("You need the \\FSILVER key",MSG_DOOR);
+                     break;
+
+                  case 3:
+                     AddMessage("You need the \\8IRON key",MSG_DOOR);
+                     break;
+
+                  case 4:
+                     AddMessage("You need the \\AOSCURO key",MSG_DOOR);
+                     break;
+
+                  default:
+                     AddMessage("This door appears to be locked",MSG_DOOR);
+                     break;
+                  }
+
+               SD_Play( SD_NOITEMSND );
+               }
+            return;
+            }
+
+         eptr = &ELEVATOR[dptr->eindex];
+         if (((dnum == eptr->door1) && (eptr->state == ev_rad)) ||
+             ((dnum == eptr->door2) && (eptr->state == ev_ras))
+            )
+            if (ob == player)
+               AddMessage("Elevator is on the way.",MSG_GAME);
+
+         OperateElevatorDoor(dnum);
+         }
+
+      }
+
+   else if ((tempactor) && (tempactor->which == ACTOR) &&
+            (tempactor->obclass == pillarobj) &&
+            DISTOK(ob->x,tempactor->x,TD) &&
+            DISTOK(ob->y,tempactor->y,TD) &&
+            (!(tempactor->flags & FL_DONE)) &&
+            (!MAPSPOT(tempactor->tilex,tempactor->tiley,2))
+           )
+
+      {if ((tempactor->dir == nodir) ||
+           (tempactor->dir == ob->dir))
+            {if (tempactor->dir == nodir)
+                {
+                tempactor->dir = ob->dir;
+                ParseMomentum(tempactor,dirangle8[tempactor->dir]);
+                }
+             SD_PlaySoundRTP ( SD_PUSHWALLSND, tempactor->x, tempactor->y );
+             tempactor->flags |= FL_ACTIVE;
+             tempactor->flags |= FL_FLIPPED;
+//               MakeActive(tempactor);
+             tempactor->whatever = ob;
+             gamestate.secretcount++;
+            }
+
+      }
+   else if ((tempwall) && (tempwall->which == WALL) &&
+            (tempwall->flags & FL_SWITCH) )
+      {
+      tempwall->flags |= FL_S_FLIPPED;
+      if ((tempwall->flags & FL_W_INVERTED) &&
+            DISTOK(ob->x,wallx,TD) &&
+            DISTOK(ob->y,wally,TD) &&
+            DISTOK(ob->z,0,32)
+         )
+         {
+         index = touchindices[checkx][checky]-1;
+         if (!(tempwall->flags & FL_ON))
+            {
+            maskobjlist[tilemap[checkx][checky]&0x3ff]->toptexture++;
+            tempwall->flags |= FL_ON;
+            TRIGGER[index] = 1;
+            SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
+            if (ob==player)
+               AddMessage("Switch turned on.",MSG_GAME);
+            }
+         else if (tempwall->flags & FL_REVERSIBLE)
+            {
+            maskobjlist[tilemap[checkx][checky]&0x3ff]->toptexture--;
+            tempwall->flags &= ~FL_ON;
+            TRIGGER[index] = 1;
+            SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
+            if (ob==player)
+               AddMessage("Switch turned off.",MSG_GAME);
+            }
+
+         }
+      else if (DISTOK(ob->x,wallx,TD) &&
+               DISTOK(ob->y,wally,TD) &&
+               !(tempwall->flags & FL_W_INVERTED)
+              )
+         {
+         index = touchindices[checkx][checky]-1;
+         if (!(tempwall->flags & FL_ON))
+            {
+            tilemap[checkx][checky]++;
+            tempwall->flags |= FL_ON;
+            TRIGGER[index] = 1;
+            SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
+            if (ob==player)
+               AddMessage("Switch turned on.",MSG_GAME);
+            }
+         else if (tempwall->flags & FL_REVERSIBLE)
+            {
+            tilemap[checkx][checky]--;
+            tempwall->flags &= ~FL_ON;
+            TRIGGER[index] = 1;
+            SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
+            if (ob==player)
+               AddMessage("Switch turned off.",MSG_GAME);
+            }
+
+         }
+      }
+   else if ((tempwall) && (tempwall->which == WALL) && (ob==player)){
+      PlayNoWaySound();
+   	  //bna ++ jumpmode
+   //SetTextMode (  );
+   if (!BATTLEMODE){//dint use jump in battle, spoils sync
+   if (usejump == true){
+   if (pstate->buttonheld[bt_use]){
+   if ((AreJumping == false)&&(ob->z > 0)&&(doorn==0)){
+	    oldzval = ob->z;
+		ob->z -= 15;
+		ob->momentumz += GRAVITY;
+		AreJumping = true;
+		donttilt=10;
+		return;
+   } 
+		AreJumping = false;
+		return;
+   }
+   }
+   }
+	  //bna 
+	  }
+//      else
+//         SD_PlaySoundRTP (SD_NOWAYSND,ob->x,ob->y);
+//   pstate->buttonheld[bt_use] = true;
+}
+
+
+/*
+=============================================================================
+
+						  USER CONTROL
+
+=============================================================================
+*/
+
+
+//******************************************************************************
+//
+// PollKeyboardButtons
+//
+//******************************************************************************
+
+void PollKeyboardButtons (void)
+{
+   int i;
+
+   QueueLetterInput ();
+   IN_UpdateKeyboard();
+
+   for (i = 0; i < NUMBUTTONS; i++)
+   {
+      if (Keystate[buttonscan[i]])
+      {
+         buttonpoll[i] = true;
+      }
+   }
+}
+
+//******************************************************************************
+//
+// PollMouseButtons
+//
+//******************************************************************************
+extern boolean usemouselook;
+void PollMouseButtons (void)
+   {
+   int i;
+   int buttons;
+   int mask;
+   int press;
+
+   buttons = IN_GetMouseButtons();
+
+   mask = 1;
+   for( i = 0; i < 3; i++, mask <<= 1 )
+      {
+      press = buttons & mask;
+
+      if ( press )
+         {//SetTextMode (  );
+//         if ( ( buttonmouse[ i ] != bt_nobutton ) &&
+//            ( DoubleClickCount[ i ] != 2 ) )
+         if ( buttonmouse[ i ] != bt_nobutton )
+            {
+            buttonpoll[ buttonmouse[ i ] ] = true;
+			//bna added
+			if ((i == 1)&&(usemouselook == true)){
+			//if rightclick set horizon to 512 (normall)
+				playertype * pstate;
+				pstate=&PLAYERSTATE[consoleplayer];
+				pstate->horizon = 512;
+				// SetNormalHorizon(PLAYER[0]);
+			}
+			//bna added
+
+            }
+         }
+
+      // Check double-click
+      if ( buttonmouse[ i + 3 ] != bt_nobutton )
+         {
+         if ( press )
+            {
+            // Was the button pressed last tic?
+            if ( !DoubleClickPressed[ i ] )
+               {
+               // Yes, take note of it
+               DoubleClickPressed[ i ] = true;
+
+               // Is this the first click, or a really late click?
+               if ( ( DoubleClickCount[ i ] == 0 ) ||
+                  ( GetTicCount() >= DoubleClickTimer[ i ] ) )
+                  {
+                  // Yes, now wait for a second click
+                  DoubleClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
+
+                     //( tics << 5 );
+                  DoubleClickCount[ i ] = 1;
+                  }
+               else
+                  {
+                  // Second click
+                  buttonpoll[ buttonmouse[ i + 3 ] ] = true;
+                  DoubleClickTimer[ i ] = 0;
+                  DoubleClickCount[ i ] = 2;
+                  }
+               }
+            else
+               {
+               // After second click, button remains pressed
+               // until user releases it
+               if ( DoubleClickCount[ i ] == 2 )
+                  {
+                  buttonpoll[ buttonmouse[ i + 3 ] ] = true;
+                  }
+               }
+            }
+         else
+            {
+            if ( DoubleClickCount[ i ] == 2 )
+               {
+               DoubleClickCount[ i ] = 0;
+               }
+            DoubleClickPressed[ i ] = false;
+            }
+         }
+      }
+   }
+
+
+//******************************************************************************
+//
+// PollJoystickButtons
+//
+//******************************************************************************
+void PollJoystickButtons
+   (
+   void
+   )
+
+   {
+   int i;
+   int buttons;
+   int mask;
+   int num;
+   int press;
+
+   buttons = IN_JoyButtons ();
+
+   if ( joypadenabled )
+      {
+      num = 4;
+      mask = 1;
+      }
+   else
+      {
+      num = 2;
+      if ( joystickport )
+         {
+         mask = 4;
+         }
+      else
+         {
+         mask = 1;
+         }
+      }
+
+   for( i = 0; i < num; i++, mask <<= 1 )
+      {
+      press = buttons & mask;
+
+      if ( press )
+         {
+//         if ( ( buttonjoy[ i ] != bt_nobutton ) &&
+//            ( JoyDblClickCount[ i ] != 2 ) )
+         if ( buttonjoy[ i ] != bt_nobutton )
+            {
+            buttonpoll[ buttonjoy[ i ] ] = true;
+            }
+         }
+
+      // Check double-click
+      if ( buttonjoy[ i + 4 ] != bt_nobutton )
+         {
+         if ( press )
+            {
+            // Was the button pressed last tic?
+            if ( !JoyDblClickPressed[ i ] )
+               {
+               // Yes, take note of it
+               JoyDblClickPressed[ i ] = true;
+
+               // Is this the first click, or a really late click?
+               if ( ( JoyDblClickCount[ i ] == 0 ) ||
+                  ( GetTicCount() >= JoyDblClickTimer[ i ] ) )
+                  {
+                  // Yes, now wait for a second click
+                  JoyDblClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
+
+                     //( tics << 5 );
+                  JoyDblClickCount[ i ] = 1;
+                  }
+               else
+                  {
+                  // Second click
+                  buttonpoll[ buttonjoy[ i + 4 ] ] = true;
+                  JoyDblClickTimer[ i ] = 0;
+                  JoyDblClickCount[ i ] = 2;
+                  }
+               }
+            else
+               {
+               // After second click, button remains pressed
+               // until user releases it
+               if ( JoyDblClickCount[ i ] == 2 )
+                  {
+                  buttonpoll[ buttonjoy[ i + 4 ] ] = true;
+                  }
+               }
+            }
+         else
+            {
+            if ( JoyDblClickCount[ i ] == 2 )
+               {
+               JoyDblClickCount[ i ] = 0;
+               }
+            JoyDblClickPressed[ i ] = false;
+            }
+         }
+      }
+   }
+
+
+//===========================================================================
+
+//******************************************************************************
+//
+// PollKeyboardMove
+//
+//******************************************************************************
+
+void PollKeyboardMove
+   (
+   void
+   )
+
+   {
+   if ( ( buttonpoll[ bt_turnaround ] ) && ( turnaround == 0 ) )
+      {
+      turnaround = 1;
+      turnaroundtime = 15 + tics;
+      turnheldtime = 0;
+      }
+   if ( turnaround == 0 )
+      {
+      if ( buttonpoll[ di_east ] )
+         {
+         turnheldtime+=tics;
+         if (turnheldtime>=TURBOTURNTIME)
+            {
+            KX = -KEYBOARDNORMALTURNAMOUNT;
+            }
+         else
+            {
+            KX = -KEYBOARDPREAMBLETURNAMOUNT;
+            }
+         }
+      else if ( buttonpoll[ di_west ] )
+         {
+         turnheldtime+=tics;
+         if (turnheldtime>=TURBOTURNTIME)
+            {
+            KX = KEYBOARDNORMALTURNAMOUNT;
+            }
+         else
+            {
+            KX = KEYBOARDPREAMBLETURNAMOUNT;
+            }
+         }
+      else
+         {
+		   KX = 0;
+         turnheldtime=0;
+         }
+      if ( (buttonpoll[bt_run]) &&
+           ( (turnheldtime>=TURBOTURNTIME) || (turnheldtime==0) )
+         )
+         KX = FixedMul(KX,TURBOTURNAMOUNT);
+      }
+   else
+      {
+      KX=TURNAROUNDSPEED;
+      turnaroundtime-=tics;
+      if (turnaroundtime<=0)
+         {
+         turnaround=0;
+         KX=((turnaroundtime*TURNAROUNDSPEED)>>1);
+         }
+      }
+
+   if ( buttonpoll[ di_north ] )
+      {
+      KY = -BASEMOVE;
+      }
+   else if ( buttonpoll[ di_south ] )
+      {
+      KY = BASEMOVE;
+      }
+   else
+      KY = 0;
+
+   if (buttonpoll[bt_run])
+      {
+      KY <<= 1;
+      }
+}
+
+//******************************************************************************
+//
+// PollMouseMove
+//
+//******************************************************************************
+
+//#define MOUSE_RY_SHIFT 12
+//#define MOUSE_TZ_SHIFT 3
+#define MOUSE_TZ_SENSITIVITY_SCALE 65535
+#define MOUSE_RY_SENSITIVITY_SCALE 18725*2
+//#define MOUSE_RY_INPUT_SCALE 6000
+#define MOUSE_TZ_INPUT_SCALE 20
+int mouse_ry_input_scale = 5000;
+
+int sensitivity_scalar[15] =
+    {
+    0,1,2,3,4,5,6,8,11,13,15,18,12,13,14
+    };
+//#define MOUSE_RY_SCALE 65535
+//#define MOUSE_TZ_SCALE 65535
+#define MAXMOUSETURN 7000000
+
+/* use SDL mouse */
+#define USESDLMOUSE 1
+
+
+extern int inverse_mouse;
+ double Y_MouseSpeed=70;
+
+void PollMouseMove (void)
+{
+   int  mousexmove, mouseymove;
+   double Ys;
+//SetTextMode();
+
+   Ys=(Y_MouseSpeed/100);
+//
+
+// const long inverse_mouse  = 1; //set  to -1 to invert mouse
+// inverse_mouse def moved to RT_CFG.C
+
+#ifdef USESDLMOUSE
+   INL_GetMouseDelta(&mousexmove, &mouseymove);
+#else
+   PollMouse();//Uses DirectInput mouse in DInput.cpp
+   mousexmove=MX;
+   mouseymove=MY;
+#endif
+
+   if (abs(mousexmove)>abs(mouseymove))
+      mouseymove/=2;
+   else
+      mousexmove/=2;
+   MX = 0;
+   MY = 0;
+
+
+   if ((abs (mouseymove)) >= threshold)
+      {//
+      MY =  MOUSE_TZ_INPUT_SCALE*mouseymove;
+	  MY *= inverse_mouse;
+	  if (usemouselook == true){
+		  if (MY > 0){
+				playertype * pstate;
+				pstate=&PLAYERSTATE[consoleplayer];
+				//if (pstate->horizon > 512){
+					pstate->horizon -= Ys * (2*sensitivity_scalar[mouseadjustment]);
+				//}
+		  }
+		  else if (MY < 0){
+		  		playertype * pstate;
+				pstate=&PLAYERSTATE[consoleplayer];
+				//SetTextMode (  );
+				pstate->horizon += Ys * (2*sensitivity_scalar[mouseadjustment]);
+				//buttonpoll[ bt_horizonup ] = true;
+		  }
+		  MY = 0;
+	  }else{
+		 // MY += FixedMul(MY,mouseadjustment*MOUSE_TZ_SENSITIVITY_SCALE);
+		  if (abs(mouseymove)>200)
+			 {
+			 buttonpoll[bt_run]=true;
+			 // buttonpoll[ bt_lookup ] = true;
+			 }
+		  }
+	  }
+
+
+
+		 
+
+   if ((abs (mousexmove)) >= threshold)
+   {
+      //MX = -MOUSE_RY_INPUT_SCALE*mousexmove;
+      MX = -mouse_ry_input_scale*mousexmove;
+      MX += FixedMul(MX,sensitivity_scalar[mouseadjustment]*MOUSE_RY_SENSITIVITY_SCALE);
+   //   if (abs(MX) > MAXMOUSETURN)
+     //   MX = MAXMOUSETURN*SGN(MX);
+	  if (usemouselook == true){
+		  if (abs(mouseymove)>10)
+		  {
+			 buttonpoll[bt_run]=true;
+			  //buttonpoll[ bt_lookdown ] = true;
+		  }
+	  }
+   }
+//   if (MY > 0)
+//      MX -= (MX/2);
+
+//   MX=0;
+//   MY=0;
+
+}
+
+
+//******************************************************************************
+//
+// PollJoystickMove
+//
+//******************************************************************************
+
+void PollJoystickMove (void)
+{
+   int   joyx,joyy;
+
+   INL_GetJoyDelta (joystickport, &joyx, &joyy);
+   if ( joypadenabled )
+      {
+      if (joyx >= threshold)
+         {
+         buttonpoll[ di_east ] = true;
+         }
+      if (-joyx >= threshold)
+         {
+         buttonpoll[ di_west ] = true;
+         }
+      if ( joyy >= threshold )
+         {
+         buttonpoll[ di_south ] = true;
+         }
+      if ( -joyy >= threshold )
+         {
+         buttonpoll[ di_north ] = true;
+         }
+      }
+   else
+      {
+      if ((abs (joyx)) >= threshold)
+         {
+         JX = ((-joyx)<<13)+((-joyx)<<11);
+         turnheldtime += tics;
+         }
+      else
+         JX = 0;
+
+      if ((abs (joyy)) >= threshold)
+         {
+         JY = joyy<<4;
+         }
+      else
+         JY = 0;
+      if (buttonpoll[bt_run])
+         {
+         JX <<= 1;
+         JY <<= 1;
+         }
+      }
+   }
+
+//******************************************************************************
+//
+// StartVRFeedback
+//
+//******************************************************************************
+
+void StartVRFeedback (int guntype)
+{
+#ifdef DOS
+   union REGS inregs;
+   union REGS outregs;
+
+   inregs.x.eax = VR_FEEDBACK_SERVICE;
+   inregs.x.ebx = 1;
+   inregs.x.ecx = guntype;
+   int386 (0x33, &inregs, &outregs);
+#else
+	STUB_FUNCTION;
+#endif
+}
+
+//******************************************************************************
+//
+// StopVRFeedback
+//
+//******************************************************************************
+
+void StopVRFeedback (void)
+{
+#ifdef DOS
+   union REGS inregs;
+   union REGS outregs;
+
+   inregs.x.eax = VR_FEEDBACK_SERVICE;
+   inregs.x.ebx = 0;
+   int386 (0x33, &inregs, &outregs);
+#else
+	STUB_FUNCTION;
+#endif
+}
+
+//******************************************************************************
+//
+// PollVirtualReality
+//
+//******************************************************************************
+
+#define VR_BUTTON(x) ((vr_buttons>>x) & 1)
+
+void PollVirtualReality (void)
+{
+#ifdef DOS
+   union REGS inregs;
+   union REGS outregs;
+   short int  mousexmove,
+              mouseymove;
+   word vr_buttons;
+
+   inregs.x.eax = VR_INPUT_SERVICE;
+
+   inregs.x.ebx = player->angle;
+   inregs.x.ecx = player->yzangle;
+
+   int386 (0x33, &inregs, &outregs);
+
+   vr_buttons = outregs.w.bx;
+
+   buttonpoll[bt_run          ] |= VR_BUTTON(VR_RUNBUTTON          );
+   buttonpoll[bt_strafeleft   ] |= VR_BUTTON(VR_STRAFELEFTBUTTON   );
+   buttonpoll[bt_straferight  ] |= VR_BUTTON(VR_STRAFERIGHTBUTTON  );
+   buttonpoll[bt_attack       ] |= VR_BUTTON(VR_ATTACKBUTTON       );
+   buttonpoll[bt_lookup       ] |= VR_BUTTON(VR_LOOKUPBUTTON       );
+   buttonpoll[bt_lookdown     ] |= VR_BUTTON(VR_LOOKDOWNBUTTON     );
+   buttonpoll[bt_swapweapon   ] |= VR_BUTTON(VR_SWAPWEAPONBUTTON   );
+   buttonpoll[bt_use          ] |= VR_BUTTON(VR_USEBUTTON          );
+   buttonpoll[bt_horizonup    ] |= VR_BUTTON(VR_HORIZONUPBUTTON    );
+   buttonpoll[bt_horizondown  ] |= VR_BUTTON(VR_HORIZONDOWNBUTTON  );
+   buttonpoll[bt_map          ] |= VR_BUTTON(VR_MAPBUTTON          );
+   buttonpoll[bt_pistol       ] |= VR_BUTTON(VR_PISTOLBUTTON       );
+   buttonpoll[bt_dualpistol   ] |= VR_BUTTON(VR_DUALPISTOLBUTTON   );
+   buttonpoll[bt_mp40         ] |= VR_BUTTON(VR_MP40BUTTON         );
+   buttonpoll[bt_missileweapon] |= VR_BUTTON(VR_MISSILEWEAPONBUTTON);
+   buttonpoll[bt_recordsound  ] |= VR_BUTTON(VR_RECORDBUTTON       );
+
+   mousexmove = outregs.w.cx;
+	mouseymove = outregs.w.dx;
+
+   VX = 0;
+   VY = 0;
+
+
+   if ((abs (mouseymove)) >= threshold)
+      {
+      VY =  MOUSE_TZ_INPUT_SCALE*mouseymove;
+      if (abs(mouseymove)>200)
+         {
+         buttonpoll[bt_run]=true;
+         }
+      }
+
+   if ((abs (mousexmove)) >= threshold)
+      {
+      VX = -mouse_ry_input_scale*mousexmove;
+      VX += FixedMul(MX,sensitivity_scalar[mouseadjustment]*MOUSE_RY_SENSITIVITY_SCALE);
+      if (abs(mousexmove)>10)
+         {
+         buttonpoll[bt_run]=true;
+         }
+      }
+#else
+	STUB_FUNCTION;
+#endif      
+}
+
+
+//******************************************************************************
+//
+// PollMove ()
+//
+//******************************************************************************
+
+boolean aimbuttonpressed=false;
+void PollMove (void)
+{
+	int angle;
+   int x, y;
+
+
+   x = KX + MX + JX + CX + VX;
+   y = KY + MY + JY + CY + VY;
+
+   if (buttonpoll[bt_aimbutton])
+      {
+      if (y>0)
+         {
+         buttonpoll[bt_horizonup]=1;
+         y=0;
+         aimbuttonpressed=true;
+         }
+      else if (y<0)
+         {
+         buttonpoll[bt_horizondown]=1;
+         y=0;
+         aimbuttonpressed=true;
+         }
+      else if (aimbuttonpressed==false)
+         {
+         buttonpoll[bt_lookup]=1;
+         buttonpoll[bt_lookdown]=1;
+         }
+      }
+   else
+      {
+      aimbuttonpressed=false;
+      }
+
+   if (player->flags & FL_FLEET)
+		y += y>>1;
+
+   if ((locplayerstate->NETCAPTURED == 1) && (!locplayerstate->HASKNIFE))
+   {
+      if (first)
+      {
+         nettics = GetTicCount() + (VBLCOUNTER * 4);
+         first = 0;
+      }
+
+      if (x > 0)
+         {
+         rightmom += NETMOM;
+         if (lastmom!=0)
+            controlbuf[2]=x<<1;
+         lastmom=0;
+         }
+      else
+         if (x < 0)
+            {
+            leftmom += NETMOM;
+            if (lastmom!=1)
+               controlbuf[2]=x<<1;
+            lastmom=1;
+            }
+         else
+         {
+            rightmom -= (NETMOM >> 2);
+            if (rightmom < 0)
+               rightmom = 0;
+            leftmom  -= (NETMOM >> 2);
+            if (leftmom < 0)
+               leftmom = 0;
+         }
+
+      if ((GetTicCount() > nettics) && (rightmom > (NETMOM * 2)) &&
+                                  (leftmom > (NETMOM * 2)))
+      {
+         rightmom = 0;
+         leftmom  = 0;
+         first    = 1;
+         lastmom^=1;
+			locplayerstate->NETCAPTURED = 0;
+			MISCVARS->NET_IN_FLIGHT = false;
+         NewState(player, &s_player);
+			locplayerstate->weaponuptics = WEAPONS[locplayerstate->weapon].screenheight/GMOVE;
+			locplayerstate->weaponheight = locplayerstate->weaponuptics*GMOVE ;
+      }
+   }
+   else if ((buttonpoll[bt_strafe]) && (turnaround==0))
+   {
+      // strafing
+      if (x < 0)
+         {
+			angle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
+
+         x = (x>>10) + (x >> 11);
+
+         controlbuf[0] = -(FixedMul (x, costable[angle]));
+         controlbuf[1] = FixedMul (x, sintable[angle]);
+			}
+      else if (x > 0)
+			{
+         angle = (player->angle + FINEANGLES/4)&(FINEANGLES-1);
+
+         x = (x>>10) + (x >> 11);
+
+			controlbuf[0] = FixedMul (x, costable[angle]);
+         controlbuf[1] = -(FixedMul (x, sintable[angle]));
+         }
+      if (y != 0)
+         {
+         controlbuf[0] += -(FixedMul (y, viewcos));
+         controlbuf[1] += (FixedMul (y, viewsin));
+         }
+   }
+   else
+   {
+      if (y != 0)
+         {
+         controlbuf[0] = -FixedMul (y, viewcos);
+         controlbuf[1] = FixedMul (y, viewsin);
+         }
+
+      if (x != 0)
+         controlbuf[2] = x;
+   }
+
+   if (buttonpoll[bt_strafeleft])
+      {
+      angle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
+      controlbuf[0] += -(FixedMul (STRAFEAMOUNT, costable[angle]));
+      controlbuf[1] +=   FixedMul (STRAFEAMOUNT, sintable[angle]);
+		}
+   else if (buttonpoll[bt_straferight])
+      {
+      angle = (player->angle + FINEANGLES/4)&(FINEANGLES-1);
+      controlbuf[0] += -(FixedMul (STRAFEAMOUNT, costable[angle]));
+      controlbuf[1] +=   FixedMul (STRAFEAMOUNT, sintable[angle]);
+      }
+}
+
+
+//******************************************************************************
+//
+// PollCyberman ()
+//
+//******************************************************************************
+
+void PollCyberman (void)
+{
+   int i;
+   int mask;
+   int press;
+
+   SWIFT_Get3DStatus (&SWIFTStatus);
+
+   mask = 4;
+   for( i = 0; i < 3; i++, mask >>= 1 )
+      {
+      press = SWIFTStatus.buttons & mask;
+
+      if ( press )
+         {
+//         if ( ( buttonmouse[ i ] != bt_nobutton ) &&
+//            ( DoubleClickCount[ i ] != 2 ) )
+         if ( buttonmouse[ i ] != bt_nobutton )
+            {
+            buttonpoll[ buttonmouse[ i ] ] = true;
+            }
+         }
+
+      // Check double-click
+      if ( buttonmouse[ i + 3 ] != bt_nobutton )
+         {
+         if ( press )
+            {
+            // Was the button pressed last tic?
+            if ( !DoubleClickPressed[ i ] )
+               {
+               // Yes, take note of it
+               DoubleClickPressed[ i ] = true;
+
+               // Is this the first click, or a really late click?
+               if ( ( DoubleClickCount[ i ] == 0 ) ||
+                  ( GetTicCount() >= DoubleClickTimer[ i ] ) )
+                  {
+                  // Yes, now wait for a second click
+                  DoubleClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
+
+                     //( tics << 5 );
+                  DoubleClickCount[ i ] = 1;
+                  }
+               else
+                  {
+                  // Second click
+                  buttonpoll[ buttonmouse[ i + 3 ] ] = true;
+                  DoubleClickTimer[ i ] = 0;
+                  DoubleClickCount[ i ] = 2;
+                  }
+               }
+            else
+               {
+               // After second click, button remains pressed
+               // until user releases it
+               if ( DoubleClickCount[ i ] == 2 )
+                  {
+                  buttonpoll[ buttonmouse[ i + 3 ] ] = true;
+                  }
+               }
+            }
+         else
+            {
+            if ( DoubleClickCount[ i ] == 2 )
+               {
+               DoubleClickCount[ i ] = 0;
+               }
+            DoubleClickPressed[ i ] = false;
+            }
+         }
+      }
+
+   if (SWIFTStatus.pitch > 0)
+     CYBERLOOKUP = true;
+   else if (SWIFTStatus.pitch < 0)
+     CYBERLOOKDOWN = true;
+
+   if ((abs (SWIFTStatus.x)) > CYBERDEADRANGE)
+   {
+      CX = -(SGN (SWIFTStatus.x) * (( (abs(SWIFTStatus.x)-CYBERDEADRANGE) ) << 10));
+      turnheldtime += tics;
+   }
+   else
+      if (SWIFTStatus.x != oldcyberx)
+		{
+         turnheldtime += tics;
+         if (SWIFTStatus.x > oldcyberx)
+				CX = -(0xB8000);
+         else
+				CX = 0xB8000;
+
+         oldcyberx = SWIFTStatus.x;
+      }
+      else
+         CX = 0;
+
+   if ((abs (SWIFTStatus.y)) > CYBERDEADRANGE)
+   {
+      CY = SWIFTStatus.y >> 2;
+   }
+	else
+      CY = 0;
+}
+
+//******************************************************************************
+//
+// PollAssassin ()
+//
+//******************************************************************************
+
+#define MAXRAMPS 5
+typedef struct
+   {
+   int  min;
+   int  factor;
+   } RampType;
+void PollAssassin (void)
+{
+   int i;
+   int mask;
+   int press;
+   int yaw;
+   int strafeAngle;
+   int acc;
+   int numramps=4;
+   RampType ramp[MAXRAMPS]={
+                              {0,280000},
+                              {4,380000},
+                              {10,480000},
+                              {25,680000},
+//                              {25,( (1<<26)/80  )}
+                            };
+
+   SWIFT_Get3DStatus (&SWIFTStatus);
+
+   mask = 4;
+   for( i = 0; i < 3; i++, mask >>= 1 )
+      {
+      press = SWIFTStatus.buttons & mask;
+
+      if ( press )
+         {
+//         if ( ( buttonmouse[ i ] != bt_nobutton ) &&
+//            ( DoubleClickCount[ i ] != 2 ) )
+         if ( buttonmouse[ i ] != bt_nobutton )
+            {
+            buttonpoll[ buttonmouse[ i ] ] = true;
+            }
+         }
+
+      // Check double-click
+      if ( buttonmouse[ i + 3 ] != bt_nobutton )
+         {
+         if ( press )
+            {
+            // Was the button pressed last tic?
+            if ( !DoubleClickPressed[ i ] )
+               {
+               // Yes, take note of it
+               DoubleClickPressed[ i ] = true;
+
+               // Is this the first click, or a really late click?
+               if ( ( DoubleClickCount[ i ] == 0 ) ||
+                  ( GetTicCount() >= DoubleClickTimer[ i ] ) )
+                  {
+                  // Yes, now wait for a second click
+                  DoubleClickTimer[ i ] = GetTicCount() + DoubleClickSpeed;
+
+                     //( tics << 5 );
+                  DoubleClickCount[ i ] = 1;
+                  }
+               else
+                  {
+                  // Second click
+                  buttonpoll[ buttonmouse[ i + 3 ] ] = true;
+                  DoubleClickTimer[ i ] = 0;
+                  DoubleClickCount[ i ] = 2;
+                  }
+               }
+            else
+               {
+               // After second click, button remains pressed
+               // until user releases it
+               if ( DoubleClickCount[ i ] == 2 )
+                  {
+                  buttonpoll[ buttonmouse[ i + 3 ] ] = true;
+                  }
+               }
+            }
+         else
+            {
+            if ( DoubleClickCount[ i ] == 2 )
+               {
+               DoubleClickCount[ i ] = 0;
+               }
+            DoubleClickPressed[ i ] = false;
+            }
+         }
+      }
+
+   buttonpoll[bt_horizonup] |=   ((SWIFTStatus.buttons>>7) & 1);
+   buttonpoll[bt_horizondown] |= ((SWIFTStatus.buttons>>8) & 1);
+
+   if ( abs(SWIFTStatus.pitch) < (20<<6) )
+      {
+      SWIFTStatus.pitch = 0;
+      }
+   else
+      {
+      SWIFTStatus.pitch -= SGN(SWIFTStatus.pitch)*(20<<6);
+      }
+
+   if ( abs(SWIFTStatus.pitch) > (60<<6) )
+      {
+      buttonpoll[bt_run] = 1;
+      }
+
+   if ( abs(SWIFTStatus.roll) > (80<<6) )
+      {
+      buttonpoll[bt_run] = 1;
+      }
+
+
+   if ( abs(SWIFTStatus.roll) < (20<<6) )
+      {
+      SWIFTStatus.roll = 0;
+      }
+   else
+      {
+      SWIFTStatus.roll -= SGN(SWIFTStatus.roll)*(20<<6);
+      }
+
+   strafeAngle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
+
+   controlbuf[0] += -(FixedMulShift (SWIFTStatus.pitch, viewcos,16))+
+                   FixedMulShift (-SWIFTStatus.roll, costable[strafeAngle], 16);
+
+   controlbuf[1] +=  FixedMulShift (SWIFTStatus.pitch, viewsin,16) -
+                   FixedMulShift (-SWIFTStatus.roll, sintable[strafeAngle], 16);
+
+   yaw = abs(SWIFTStatus.yaw);
+   acc = 0;
+   for (i=0;i<numramps;i++)
+      {
+      if (yaw > ramp[i].min)
+         {
+         if (i>0)
+            {
+            acc += ramp[i].min*(ramp[i].factor-ramp[i-1].factor);
+            }
+         }
+      else
+         {
+         i++;
+         break;
+         }
+      }
+   controlbuf[2]= SWIFTStatus.yaw * ramp[i-1].factor - acc;
+}
+
+
+//******************************************************************************
+//
+// PollControls
+//
+// Gets user or demo input, call once each frame
+//
+// controlx     set between -100 and 100 per tic
+// controly
+//
+//******************************************************************************
+
+
+void PollControls (void)
+{
+   int   i;
+
+   if (standalone==true)
+      return;
+
+   lastpolltime=controlupdatetime;
+
+   memset (buttonpoll, 0, sizeof(buttonpoll));
+
+   controlbuf[0] = controlbuf[1] = controlbuf[2] = 0;
+   CYBERLOOKUP = CYBERLOOKDOWN = false;
+
+   if (gamestate.autorun==1)
+	   buttonpoll[bt_run] = true;
+
+
+//
+// get button states
+//
+   PollKeyboardButtons ();
+
+   if (mouseenabled && !cybermanenabled)
+      PollMouseButtons ();
+
+	if (joystickenabled)
+      PollJoystickButtons ();
+
+
+//
+// get movements
+//
+   if (joystickenabled)
+      PollJoystickMove ();
+
+	if (cybermanenabled)
+      PollCyberman ();
+
+   else if (mouseenabled && MousePresent)
+      PollMouseMove ();
+
+   PollKeyboardMove ();
+
+   if (vrenabled)
+      PollVirtualReality ();
+
+   PollMove ();
+
+   if (spaceballenabled)
+      PollSpaceBall ();
+
+   else if (assassinenabled)
+       PollAssassin ();
+
+
+	buttonbits = 0;
+	if (player->flags & FL_DYING) // Player has died
+      {
+      if ((playerdead==true) &&
+          ( buttonpoll[ bt_strafe ] ||
+            buttonpoll[ bt_attack ] ||
+            buttonpoll[ bt_use ] ||
+            ((gamestate.battlemode == battle_Hunter) &&
+             (BATTLE_Team[player->dirchoosetime] == BATTLE_It)
+            )
+          )
+         )
+         {
+         AddRespawnCommand();
+         }
+      memset (buttonpoll, 0, sizeof(buttonpoll));
+      controlbuf[0] = controlbuf[1] = controlbuf[2] = 0;
+      }
+
+   if ((PausePressed==true) && (modemgame==false))
+      {
+      PausePressed=false;
+      if (GamePaused==true)
+         AddPauseStateCommand(COM_UNPAUSE);
+      else
+         {
+         AddPauseStateCommand(COM_PAUSE);
+         }
+      }
+   if (Keyboard[sc_Insert] && Keyboard[sc_X]){
+	      AddExitCommand();
+   }
+//bna section
+   if (Keyboard[sc_5]){
+	//	 SetTextMode (  );
+      weaponscale +=  1000;
+	  //testval++;
+   }
+   if (Keyboard[sc_6]){
+	//	 SetTextMode (  );
+      weaponscale -=  1000;
+	  	//  testval--;
+   }
+//bna section end 
+
+
+
+
+
+   for (i = (NUMTXBUTTONS-1); i >= 0; i--)
+      {
+      buttonbits <<= 1;
+		if (buttonpoll[i])
+         buttonbits |= 1;
+		}
+
+   UpdateClientControls();
+}
+
+
+void ResetWeapons(objtype *ob)
+{playertype *pstate;
+
+ M_LINKSTATE(ob,pstate);
+
+ pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
+ pstate->new_weapon = pstate->oldweapon;
+ pstate->missileweapon = pstate->oldmissileweapon;
+ ob->shapeoffset = pstate->oldshapeoffset;
+ pstate->attackframe = pstate->weaponframe = 0;
+
+ if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
+	DrawBarAmmo (false);
+}
+
+
+
+
+void SaveWeapons(objtype*ob)
+{playertype *pstate;
+
+ if ((ob->flags&FL_DOGMODE) || (ob->flags&FL_GODMODE))
+    return;
+
+ //pstate = (ob==player)?(&playerstate):(&remoteplayerstate);
+ M_LINKSTATE(ob,pstate);
+
+ pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
+ pstate->oldweapon = pstate->new_weapon;
+ pstate->oldmissileweapon = pstate->missileweapon;
+ pstate->oldshapeoffset = ob->shapeoffset;
+
+}
+
+/*
+void SaveWeapons(objtype*ob)
+{playertype *pstate;
+
+ if ((ob->flags&FL_DOGMODE) || (ob->flags&FL_GODMODE))
+    return;
+
+ //pstate = (ob==player)?(&playerstate):(&remoteplayerstate);
+ M_LINKSTATE(ob,pstate);
+
+ pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
+ pstate->oldweapon = pstate->weapon;
+ pstate->oldmissileweapon = pstate->missileweapon;
+ pstate->oldshapeoffset = ob->shapeoffset;
+
+}
+*/
+
+
+#define GiveProtection(flag,time,sound)                  \
+   {                                                     \
+   if ((ob->flags & flag) || (ob->flags & FL_GODMODE) || \
+       (ob->flags & FL_DOGMODE))                         \
+      return;                                            \
+   ob->flags &= ~(FL_BPV|FL_GASMASK|FL_AV);              \
+   ob->flags |= flag;                                    \
+   SD_PlaySoundRTP(sound,ob->x, ob->y);                  \
+   pstate->protectiontime = time;                        \
+   gamestate.supercount ++;                              \
+   }
+
+
+
+
+boolean GivePowerup(objtype *ob,int flag,int time,int sound)
+   {
+   playertype *pstate;
+
+
+   if ((ob->flags & flag) ||
+       (ob->flags & FL_GODMODE) ||
+       (ob->flags & FL_DOGMODE)
+      )
+      return false;
+
+
+   M_LINKSTATE(ob,pstate);
+
+   /*
+   if (ob->flags & FL_DOGMODE)
+      {
+      ob->temp2 = DOGMODERISE;
+      ResetWeapons(ob);
+      if (ob->state->condition & SF_DOGSTATE)
+         NewState(ob,&s_player);
+      }
+   else if (ob->flags & FL_GODMODE)
+      {
+      ob->temp2 = GODMODEFALL;
+      ResetWeapons(ob);
+      }
+   */
+   ob->flags &= ~(FL_SHROOMS|FL_FLEET|FL_ELASTO|FL_GODMODE|FL_DOGMODE);
+   ob->flags |= flag;
+   pstate->poweruptime = time;
+   pstate->soundtime = 0;
+   SD_PlaySoundRTP(sound,ob->x, ob->y);
+   gamestate.supercount ++;
+   return true;
+
+   }
+
+
+
+void GiveLifePoints(objtype *ob,int points)
+   {
+   SD_PlaySoundRTP(SD_GETBONUSSND,ob->x, ob->y);
+
+   UpdateTriads (ob,points);
+   if (ob==player)
+      DrawTriads (false);
+
+   }
+
+
+boolean GiveBulletWeapon(objtype *ob,int bulletweapon,statobj_t*check)
+   {
+   playertype *pstate;
+
+   M_LINKSTATE(ob,pstate);
+
+   if ((ob->flags & FL_DOGMODE) || (ob->flags & FL_GODMODE))
+      return false;
+
+   if (!ARMED(ob->dirchoosetime))
+      return false;
+
+   if (pstate->HASBULLETWEAPON[bulletweapon])
+      return false;
+
+   GiveWeapon(ob,bulletweapon);
+   if ( gamestate.BattleOptions.WeaponPersistence )
+      {
+      LASTSTAT->z = check->z;
+      }
+   SD_PlaySoundRTP(SD_GETWEAPONSND,ob->x, ob->y);
+   return true;
+
+   }
+
+
+boolean GivePlayerMissileWeapon(objtype *ob, playertype *pstate,
+                                statobj_t *check)
+   {
+   if  ((ob->flags & FL_DOGMODE) || (ob->flags & FL_GODMODE))
+      return false;
+
+
+   if (!ARMED(ob->dirchoosetime))
+      return false;
+
+   if ((GetWeaponForItem(check->itemnumber) == pstate->missileweapon) &&
+       (check->ammo == stats[check->itemnumber].ammo) &&
+       (pstate->ammo == stats[check->itemnumber].ammo)
+      )
+      return false;
+
+   SD_PlaySoundRTP(SD_GETWEAPONSND,ob->x, ob->y);
+   GiveMissileWeapon(ob,GetWeaponForItem(check->itemnumber));
+   if (gamestate.BattleOptions.WeaponPersistence)
+         LASTSTAT->z = check->z;
+
+   gamestate.missilecount ++;
+
+   if (BATTLEMODE && (gamestate.BattleOptions.Ammo != bo_normal_shots))
+      {if (gamestate.BattleOptions.Ammo == bo_one_shot)
+         pstate->ammo = 1;
+      else
+         pstate->ammo = -1;
+      }
+   else
+      pstate->ammo = check->ammo;
+   if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
+      DrawBarAmmo (false);
+
+   return true;
+
+   }
+
+
+#define LocalBonusMessage(string)  \
+   {                               \
+   if (ob == player)               \
+     AddMessage(string,MSG_BONUS); \
+   }
+#define LocalBonus1Message(string)  \
+   {                               \
+   if (ob == player)               \
+     AddMessage(string,MSG_BONUS1); \
+   }
+
+
+/*
+=================================
+=
+=   GetBonusTimeForItem
+=
+=================================
+*/
+
+int GetBonusTimeForItem(int itemnumber)
+   {
+   specials *which;
+
+   if ( BATTLEMODE )
+      {
+      which = &gamestate.SpecialsTimes;
+      }
+   else
+      {
+      which = &CurrentSpecialsTimes;
+      }
+
+   switch(itemnumber)
+      {
+      case stat_godmode:
+         return which->GodModeTime;
+
+      case stat_dogmode:
+         return which->DogModeTime;
+
+      case stat_mushroom:
+         return which->ShroomsModeTime;
+
+      case stat_elastic:
+         return which->ElastoModeTime;
+
+      case stat_asbesto:
+         return which->AsbestosVestTime;
+
+      case stat_bulletproof:
+         return which->BulletProofVestTime;
+
+      case stat_gasmask:
+         return which->GasMaskTime;
+
+      case stat_fleetfeet:
+         return which->MercuryModeTime;
+      }
+
+   return -1;
+
+   }
+
+
+
+
+/*
+=================================
+=
+=   GetRespawnTimeForItem
+=
+=================================
+*/
+
+
+
+int GetRespawnTimeForItem(int itemnumber)
+   {
+   switch(itemnumber)
+      {
+      case stat_godmode:
+         return gamestate.SpecialsTimes.GodModeRespawnTime;
+
+      case stat_dogmode:
+         return gamestate.SpecialsTimes.DogModeRespawnTime;
+
+      case stat_mushroom:
+         return gamestate.SpecialsTimes.ShroomsModeRespawnTime;
+
+      case stat_elastic:
+         return gamestate.SpecialsTimes.ElastoModeRespawnTime;
+
+      case stat_asbesto:
+         return gamestate.SpecialsTimes.AsbestosVestRespawnTime;
+
+      case stat_bulletproof:
+         return gamestate.SpecialsTimes.BulletProofVestRespawnTime;
+
+      case stat_gasmask:
+         return gamestate.SpecialsTimes.GasMaskRespawnTime;
+
+      case stat_fleetfeet:
+         return gamestate.SpecialsTimes.MercuryModeRespawnTime;
+
+      }
+
+   return gamestate.BattleOptions.RespawnTime * VBLCOUNTER;
+
+
+   }
+
+
+/*
+===================
+=
+= GetBonus
+=
+===================
+*/
+void GetBonus (objtype*ob,statobj_t *check)
+{
+	int heal;
+	playertype * pstate;
+   boolean randompowerup;
+
+	M_LINKSTATE(ob,pstate);
+
+   randompowerup=false;
+
+randomlabel:
+	switch (check->itemnumber)
+	{
+
+	case    stat_knifestatue:
+      SD_PlaySoundRTP(SD_GETKNIFESND,ob->x, ob->y);
+      if (ob==player)
+         locplayerstate->HASKNIFE = 1;
+      SD_PlaySoundRTP(PlayerSnds[locplayerstate->player], ob->x, ob->y);
+      LocalBonusMessage("You found a knife.");
+      break;
+   case    stat_pedgoldkey:
+      LocalBonusMessage("You found the \\EGold key.");
+      goto keys;
+   case    stat_pedsilverkey:
+      LocalBonusMessage("You got the \\FSilver key.");
+      goto keys;
+   case    stat_pedironkey:
+      LocalBonusMessage("You got the \\8Iron key.");
+      goto keys;
+   case    stat_pedcrystalkey:
+      LocalBonusMessage("You got the \\4Oscuro key.");
+keys:
+		GiveKey (check->itemnumber - stat_pedgoldkey);
+		SD_PlaySoundRTP (SD_GETKEYSND,ob->x, ob->y);
+		break;
+	case    stat_monkmeal:
+		if (pstate->health == MaxHitpointsForCharacter(pstate))
+			return;
+		SD_PlaySoundRTP (SD_GETHEALTH1SND,ob->x, ob->y);
+      LocalBonusMessage("You ate some Monk Meal.");
+		HealPlayer (10,ob);
+		gamestate.healthcount ++;
+		break;
+	case    stat_monkcrystal1:
+		if (pstate->health == MaxHitpointsForCharacter(pstate))
+			return;
+		SD_PlaySoundRTP (SD_GETHEALTH2SND,ob->x, ob->y);
+      LocalBonusMessage("You picked up a small Monk Crystal.");
+
+		HealPlayer (10,ob);
+		gamestate.healthcount ++;
+		break;
+	case   stat_monkcrystal2:
+		if (pstate->health == MaxHitpointsForCharacter(pstate))
+			return;
+      SD_PlaySoundRTP (SD_GETHEALTH2SND,ob->x, ob->y);
+      LocalBonusMessage("You picked up a large Monk Crystal.");
+
+		HealPlayer (50,ob);
+		gamestate.healthcount ++;
+		break;
+	case    stat_priestporridge:
+		if (pstate->health == MaxHitpointsForCharacter(pstate))
+			return;
+      SD_PlaySoundRTP (SD_GETHEALTH1SND,ob->x, ob->y);
+		if (check->flags & FL_ACTIVE)
+         {
+         HealPlayer (50,ob);
+         LocalBonusMessage("You ate some Priest Porridge Hot.");
+         }
+		else
+         {
+         HealPlayer (20,ob);
+
+         LocalBonusMessage("You ate some Priest Porridge.");
+         }
+		gamestate.healthcount ++;
+		break;
+
+	case   stat_healingbasin:
+		if (pstate->health == MaxHitpointsForCharacter(pstate))
+			return;
+      SD_PlaySoundRTP (SD_GETHEALTH2SND,ob->x, ob->y);
+		heal = 25 + (GameRandomNumber("GetBonus",0) >> 2);
+		HealPlayer (heal,ob);
+      LocalBonusMessage("You drank from the healing basin.");
+
+		gamestate.healthcount ++;
+		gamestate.democraticcount ++;
+		break;
+
+	case stat_oneup:
+		if (abs(pstate->health - MaxHitpointsForCharacter(pstate))
+			 < (MaxHitpointsForCharacter(pstate)>>2) )
+         {
+         GiveLives(1);
+         LocalBonusMessage("Extra Life!");
+         }
+		else
+         {
+         HealPlayer(MaxHitpointsForCharacter(pstate),ob);
+         LocalBonusMessage("Full Health!");
+         }
+		SD_PlaySoundRTP(SD_GET1UPSND,ob->x, ob->y);
+		break;
+	case stat_threeup:
+		if (abs(pstate->health - MaxHitpointsForCharacter(pstate))
+			 < (MaxHitpointsForCharacter(pstate)>>2) )
+			{
+         GiveLives(3);
+         LocalBonusMessage("Three Extra Lives!");
+
+			}
+		else
+         {
+         HealPlayer(MaxHitpointsForCharacter(pstate),ob);
+         GiveLives(2);
+         LocalBonusMessage("Full Health AND Two Extra Lives!");
+
+         }
+		SD_PlaySoundRTP(SD_GET3UPSND,ob->x, ob->y);
+		break;
+
+   case stat_scotthead:
+      // Give Apogee's phone number as points
+      GivePoints( 2764331 );
+      LocalBonusMessage( "Whoa...Scott's Mystical Head!");
+      LocalBonus1Message( "You get 2,764,331 points!");
+      SD_PlaySoundRTP(SD_GETHEADSND,ob->x, ob->y);
+		break;
+
+	case stat_twopistol:
+      if (GiveBulletWeapon(ob,wp_twopistol,check)==false)
+         return;
+      LocalBonusMessage("You got an extra pistol.");
+
+		break;
+	case stat_mp40:
+      if (GiveBulletWeapon(ob,wp_mp40,check)==false)
+         return;
+      LocalBonusMessage("You picked up an MP40.");
+
+      break;
+
+	case stat_bazooka:
+      if (GivePlayerMissileWeapon(ob,pstate,check)==false)
+         return;
+
+      LocalBonusMessage("You bagged a bazooka!");
+      break;
+
+   case stat_firebomb:
+      if (GivePlayerMissileWeapon(ob,pstate,check)==false)
+         return;
+
+      LocalBonusMessage("You found a Firebomb!");
+      break;
+
+
+	case stat_heatseeker:
+      if (GivePlayerMissileWeapon(ob,pstate,check)==false)
+         return;
+
+      LocalBonusMessage("You have a Heat-seeker!");
+      break;
+
+
+	case stat_drunkmissile:
+      if (GivePlayerMissileWeapon(ob,pstate,check)==false)
+         return;
+
+      LocalBonusMessage("You recovered a Drunk Missile!");
+      break;
+
+	case stat_firewall:
+      if (GivePlayerMissileWeapon(ob,pstate,check)==false)
+         return;
+
+      LocalBonusMessage("You filched a FlameWall!");
+      break;
+
+	case stat_splitmissile:
+      if (GivePlayerMissileWeapon(ob,pstate,check)==false)
+         return;
+
+      LocalBonusMessage("You snagged a Split Missile!");
+      break;
+
+	case stat_kes:
+      if (GivePlayerMissileWeapon(ob,pstate,check)==false)
+         return;
+
+      LocalBonusMessage("You wield the Dark Staff!");
+      break;
+
+	case stat_bat:
+      if (GivePlayerMissileWeapon(ob,pstate,check)==false)
+         return;
+
+      LocalBonusMessage("You picked up the Excalibat.");
+      break;
+
+
+	case stat_lifeitem1:
+      GiveLifePoints(ob,1);
+      if (timelimitenabled)
+         timelimit+=(VBLCOUNTER);
+
+		break;
+
+	case stat_lifeitem2:
+      GiveLifePoints(ob,5);
+      if (timelimitenabled)
+         timelimit+=(2*VBLCOUNTER);
+       break;
+
+   case stat_lifeitem3:
+      GiveLifePoints(ob,10);
+      if (timelimitenabled)
+         timelimit+=(5*VBLCOUNTER);
+       break;
+
+   case stat_lifeitem4:
+      GiveLifePoints(ob,25);
+      if (timelimitenabled)
+         timelimit+=(10*VBLCOUNTER);
+       break;
+
+	case stat_random:
+		switch (GameRandomNumber("GetBonus",0)>>6)
+			{
+			case 0:
+				check->itemnumber=stat_godmode;
+				break;
+			case 1:
+				check->itemnumber=stat_elastic;
+				break;
+			case 2:
+				check->itemnumber=stat_dogmode;
+				break;
+			case 3:
+				check->itemnumber=stat_mushroom;
+				break;
+			}
+      randompowerup=true;
+      LocalBonus1Message("Random powerup gives you . . .");
+		goto randomlabel;
+		break;
+
+   case stat_bulletproof:
+      GiveProtection(FL_BPV, GetBonusTimeForItem(stat_bulletproof),
+         SD_GETBVESTSND);
+      LocalBonusMessage("Bulletproof Armor!");
+
+      goto drw;
+
+	case stat_gasmask:
+      GiveProtection(FL_GASMASK, GetBonusTimeForItem(stat_gasmask),
+                     SD_GETMASKSND);
+      LocalBonusMessage("You put on a Gas Mask.");
+
+      goto drw;
+
+	case stat_asbesto:
+      GiveProtection(FL_AV,GetBonusTimeForItem(stat_asbesto),
+                     SD_GETAVESTSND);
+      LocalBonusMessage("Asbestos Armor! Oh so itchy!");
+
+      goto drw;
+
+   case stat_elastic:
+      if (GivePowerup(ob,FL_ELASTO,GetBonusTimeForItem(stat_elastic),
+                  SD_GETELASTSND) == false)
+         return;
+      LocalBonusMessage("Elasto Mode!");
+
+      ob->flags |= FL_NOFRICTION;
+      goto drw;
+
+   case stat_fleetfeet:
+      if (GivePowerup(ob,FL_FLEET,GetBonusTimeForItem(stat_fleetfeet),
+                  SD_GETFLEETSND) == false)
+         return;
+
+      LocalBonus1Message("Mercury Mode!");
+      LocalBonusMessage("Press Look Up and Down to fly.");
+
+      ob->flags &= ~FL_NOFRICTION;
+      goto drw;
+
+
+   case stat_mushroom:
+      if (GivePowerup(ob,FL_SHROOMS,GetBonusTimeForItem(stat_mushroom),
+                  SD_GETSHROOMSSND) == false)
+         return;
+      LocalBonusMessage("Shrooms Mode!");
+
+      ob->flags &= ~FL_NOFRICTION;
+      gamestate.democraticcount ++;
+      goto drw;
+
+
+   case stat_godmode:
+
+      if (ob->flags & FL_GODMODE)
+         return;
+
+      if (!ARMED(ob->dirchoosetime))
+         return;
+
+      ob->flags &= ~FL_NOFRICTION;
+
+      if (ob->flags & FL_DOGMODE)
+         {
+         ob->temp2 = DOGMODERISE;
+         ResetWeapons(ob);
+         if (ob->state->condition & SF_DOGSTATE)
+            NewState(ob,&s_player);
+         }
+
+      SaveWeapons(ob);
+      SpawnNewObj(ob->tilex,ob->tiley,&s_flash1,inertobj);
+      new->flags |= FL_ABP;
+      new->x = new->drawx = ob->x;
+      new->y = new->drawy = ob->y;
+      MakeActive(new);
+      new->z = ob->z;
+
+
+      SetPlayerHorizon(pstate,GODYZANGLE);
+
+      ob->flags &= ~(FL_GODMODE|FL_SHROOMS|FL_ELASTO|FL_FLEET|FL_DOGMODE);
+      ob->flags |= FL_GODMODE;
+      ob->temp2 = GODMODERISE;
+      pstate->poweruptime = GetBonusTimeForItem(stat_godmode);
+      pstate->soundtime = 0;
+      GiveMissileWeapon(ob,wp_godhand);
+      SD_PlaySoundRTP(SD_GETGODSND,ob->x, ob->y);
+      gamestate.supercount ++;
+      LocalBonusMessage("God Mode!");
+
+      goto drw;
+
+
+#if (SHAREWARE == 0)
+	case stat_dogmode:
+      if (ob->flags & FL_DOGMODE)
+         return;
+
+      if (!ARMED(ob->dirchoosetime))
+         return;
+
+      ob->flags &= ~FL_NOFRICTION;
+
+      if (ob->flags & FL_GODMODE)
+         {
+         ob->temp2 = GODMODEFALL;
+         ResetWeapons(ob);
+         }
+
+
+      SaveWeapons(ob);
+      ob->shapeoffset = 0;
+      NewState(ob,&s_serialdog);
+
+      SpawnNewObj(ob->tilex,ob->tiley,&s_flash1,inertobj);
+      new->flags |= FL_ABP;
+      new->x = new->drawx = ob->x;
+      new->y = new->drawy = ob->y;
+      MakeActive(new);
+      new->z = ob->z;
+
+      SetPlayerHorizon(pstate,DOGYZANGLE);
+
+      ob->flags &= ~(FL_DOGMODE|FL_SHROOMS|FL_ELASTO|FL_FLEET|FL_GODMODE);
+      ob->flags |= FL_DOGMODE;
+      ob->temp2 = DOGMODEFALL;
+      pstate->poweruptime = GetBonusTimeForItem(stat_dogmode);
+      pstate->soundtime = 0;
+      GiveMissileWeapon(ob,wp_dog);
+      SD_PlaySoundRTP(SD_GETDOGSND,ob->x, ob->y);
+      gamestate.supercount ++;
+      LocalBonusMessage("Dog Mode!");
+
+      goto drw;
+   #endif
+
+ drw:
+
+		if (ob==player)
+         GM_DrawBonus (check->itemnumber);
+
+		break;
+
+	case stat_dipball1:
+	case stat_dipball2:
+	case stat_dipball3:
+      SD_PlaySoundRTP(SD_GETBONUSSND,ob->x, ob->y);
+		gamestate.dipballs++;
+      LocalBonusMessage("You discovered a Developer Ball!");
+
+	break;
+
+   case stat_collector:
+      if (gamestate.battlemode==battle_CaptureTheTriad)
+        {if (pstate->team == check->hitpoints)
+           return;
+         ob->flags |= FL_DESIGNATED;
+         UpdateKills = true;
+         LocalBonusMessage( "You picked up a triad!  RUN!!!");
+        }
+      else
+        BATTLE_CheckGameStatus(battle_get_collector_item,ob->dirchoosetime);
+
+      SD_PlaySoundRTP(SD_GETBONUSSND,ob->x, ob->y);
+		break;
+#if (SHAREWARE == 0)
+	case stat_mine:
+		SpawnNewObj(check->tilex,check->tiley,&s_grexplosion1,inertobj);
+		new->flags |= FL_ABP;
+		new->whatever = check;
+		new->temp2 = 100;
+		MakeActive(new);
+		SD_PlaySoundRTP(SD_EXPLODESND,check->x,check->y);
+		break;
+#endif
+	default:
+      SD_PlaySoundRTP(SD_GETHEADSND,ob->x, ob->y);
+		break;
+	}
+	//StartBonusFlash ();
+	if (check->flags & FL_CHANGES)
+		{
+		switch (check->itemnumber)
+			{
+			case stat_pedgoldkey:
+			case stat_pedsilverkey:
+			case stat_pedironkey:
+			case stat_pedcrystalkey:
+				check->itemnumber = stat_emptypedestal;
+				check->shapenum = stats[stat_emptypedestal].picnum;
+				check->flags = stats[stat_emptypedestal].flags|FL_ABP;
+				check->count = 0;
+				check->numanims = 0;
+				break;
+			case stat_healingbasin:
+				check->itemnumber = stat_emptybasin;
+				check->shapenum = stats[stat_emptybasin].picnum;
+				check->flags = stats[stat_emptybasin].flags|FL_ABP;
+				check->count = 0;
+				check->numanims = 0;
+				break;
+			/*
+				case stat_tablebullets:
+				check->itemnumber = stat_emptytable;
+				check->shapenum = stats[stat_emptytable].picnum;
+				check->flags = stats[stat_emptytable].flags|FL_ABP;
+				break;
+			case stat_statuewithpole:
+				check->itemnumber = stat_armornopole;
+				check->shapenum = stats[stat_armornopole].picnum;
+				check->flags = stats[stat_armornopole].flags|FL_ABP;
+				break; */
+			case stat_pit:
+				check->shapenum ++;
+				check->flags &= ~FL_CHANGES;
+				check->flags &= ~FL_BONUS;
+				break;
+			case stat_knifestatue:
+				check->itemnumber = stat_emptystatue;
+				check->shapenum = stats[stat_emptystatue].picnum;
+				check->flags = stats[stat_emptystatue].flags|FL_ABP;
+				break;
+
+			default:
+			    ;
+			}
+		}
+	else
+	  {if (check == sprites[check->tilex][check->tiley])
+         {
+         statobj_t *checkstat;
+
+         checkstat = (statobj_t*)DiskAt(check->tilex,check->tiley);
+         if (checkstat && (checkstat->which == SPRITE))
+            sprites[check->tilex][check->tiley] = checkstat;
+         else
+            sprites[check->tilex][check->tiley] = NULL;
+         }
+
+      if (randompowerup==true)
+         check->itemnumber = stat_random;
+      RemoveStatic(check);
+	  }
+}
+
+
+/*
+===================
+=
+= DropWeapon
+=
+===================
+*/
+
+void DropWeapon(objtype *ob)
+{playertype *pstate;
+ int dtilex,dtiley;
+
+
+
+ M_LINKSTATE(ob,pstate);
+
+ if ((pstate->missileweapon == -1) || (pstate->missileweapon == wp_godhand)
+#if (SHAREWARE == 0)
+     || (pstate->missileweapon == wp_dog)
+#endif
+     )
+	return;
+
+ pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/3;
+ pstate->new_weapon = pstate->bulletweapon;
+
+ dtilex = ob->tilex;
+ dtiley = ob->tiley;
+
+ FindEmptyTile(&dtilex, &dtiley);
+
+
+ SpawnStatic(dtilex,dtiley,GetItemForWeapon(pstate->missileweapon),9);
+ gamestate.missiletotal ++;
+
+ LASTSTAT->ammo = pstate->ammo;
+ LASTSTAT->flags |= FL_ABP;
+ LASTSTAT->flags &= ~FL_RESPAWN;
+ MakeStatActive(LASTSTAT);
+ pstate->weaponx = ob->tilex;
+ pstate->weapony = ob->tiley;
+ pstate->ammo = -1;
+ pstate->missileweapon = -1;
+ if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
+	 DrawBarAmmo (false);
+}
+
+
+/*
+===================
+=
+= Thrust
+=
+===================
+*/
+
+void Thrust ( objtype * ob )
+{statobj_t *tstat;
+ int dx,dy,dz,rad,index,otherteam;
+ objtype*temp;
+ playertype * pstate;
+
+	PlayerMove(ob);
+	M_LINKSTATE(ob,pstate);
+
+	if ((gamestate.battlemode == battle_CaptureTheTriad) &&
+		 (ob->flags & FL_DESIGNATED) &&
+       (ob->tilex == TEAM[pstate->team].tilex) &&
+       (ob->tiley == TEAM[pstate->team].tiley))
+      {if (ob == player)
+         SD_Play(PlayerSnds[locplayerstate->player]);
+
+       if (BATTLE_CheckGameStatus(battle_captured_triad,ob->dirchoosetime)==
+           battle_no_event)
+          {
+          ob->flags &= ~FL_DESIGNATED;
+          UpdateKills = true;
+          otherteam = (pstate->team ^ 1);
+          SpawnStatic(TEAM[otherteam].tilex,TEAM[otherteam].tiley,stat_collector,9);
+          LASTSTAT->flags |= FL_COLORED;
+          LASTSTAT->hitpoints = otherteam;
+          LASTSTAT->flags |= FL_ABP;
+          MakeStatActive(LASTSTAT);
+          }
+       return;
+		}
+
+	if ((ob->tilex != pstate->weaponx) || (ob->tiley != pstate->weapony))
+	  pstate->weaponx = pstate->weapony = 0;
+
+   index = touchindices[ob->tilex][ob->tiley];
+	if (index && (abs(ob->z - nominalheight) < 5))
+	 {if (!TRIGGER[index-1]){
+#if (BNACRASHPREVENT == 1)
+		if (touchplate[index-1] != 0) { //	CRASH IN SHAREWARE 'ride em cowboy' BNA FIX
+			 //SetTextMode (  ); qwert  // DONT ALLOW BAD touchplate ( == 0 ) see rt_door.c
+#endif
+			 if (touchplate[index-1]->complete)
+				SD_PlaySoundRTP(SD_BADTOUCHSND,ob->x,ob->y);
+			 else {
+				SD_PlaySoundRTP(SD_TOUCHPLATESND,ob->x,ob->y);
+				if (ob == player)
+					AddMessage("Touchplate triggered.",MSG_GAME);  
+			 }
+#if (BNACRASHPREVENT == 1)
+		}else{SD_PlaySoundRTP(SD_BADTOUCHSND,ob->x,ob->y);} 
+		//	CRASH IN SHAREWARE 'ride em cowboy' BNA FIX
+#endif
+	}
+	  TRIGGER[index-1] = 1;
+	 }
+
+	tstat = sprites[ob->tilex][ob->tiley];
+	if (tstat)
+
+	 {dx = abs(ob->x - tstat->x);
+	  dy = abs(ob->y - tstat->y);
+	  dz = abs(ob->z - tstat->z);
+     if ((dx < 0x8000) && (dy < 0x8000) && (dz<=35))
+		{
+#define OBJECT_IS_BONUS( tstat )                  ( ( tstat )->flags & FL_BONUS )
+#define PLAYER_IS_SWITCHING_WEAPONS( pstate )     ( W_CHANGE( pstate ) )
+//#define IS_ATTACKING( ob )                        ( ( ( ob )->state->think == T_Attack ) || ( ( ob )->state->think == T_BatBlast ) )
+#define IS_WEAPON( tstat )                        ( ( tstat )->flags & FL_WEAPON )
+#define PLAYER_MAY_NOT_GET_WEAPON( pstate, ob )   ( PLAYER_IS_SWITCHING_WEAPONS( pstate ))// || IS_ATTACKING( ob ) )
+#define OK_TO_PICK_UP( tstat, pstate, ob )        ( !( IS_WEAPON( tstat ) && PLAYER_MAY_NOT_GET_WEAPON( pstate, ob ) ) )
+#define WHERE_PLAYER_DROPPED_WEAPON( ob, pstate ) ( ( ( ob )->tilex == ( pstate )->weaponx ) && ( ( ob )->tiley == ( pstate )->weapony ) )
+
+       if ( OBJECT_IS_BONUS( tstat ) &&
+          OK_TO_PICK_UP( tstat, pstate, ob ) &&
+          (!WHERE_PLAYER_DROPPED_WEAPON( ob, pstate ))
+          )
+          {
+           GetBonus(ob,tstat);
+           if (PLAYER_IS_SWITCHING_WEAPONS( pstate ))
+             {statetype *nstate;
+#if (SHAREWARE == 0)
+              if (ob->state->condition & SF_DOGSTATE)
+                nstate = &s_serialdog;
+              else
+#endif
+                nstate = &s_player;
+              pstate->attackframe = pstate->weaponframe = pstate->batblast = 0;
+              NewState(ob,nstate);
+             }
+
+
+          }
+       else if ((tstat->itemnumber == stat_pit) &&
+                (ob->temp2 != PITFALL) &&
+                (!(ob->flags & FL_FLEET))
+               )
+			 {ob->temp2 = PITFALL;
+			  ob->momentumx = ob->momentumy = 0;
+			  //ob->momentumz = 4;
+			  ob->momentumz = GRAVITY;
+
+			  if (ob->whatever == NULL)
+				  {ob->whatever = tstat;
+					SD_PlaySoundRTP(SD_PITTRAPSND,ob->x,ob->y);
+					tstat->shapenum = stats[tstat->itemnumber].picnum + 1;
+					MakeStatInactive(tstat);
+			  //tstat->flags &= ~FL_ABP;
+				  }
+			 }
+       else if ((tstat->itemnumber == stat_heatgrate) &&
+                (!(ob->flags & FL_DYING)) && (!(ob->flags & FL_AV))
+               )
+			 {DamageThing(ob,1);
+           Collision(ob,(objtype*)tstat,0,0);
+           M_CheckPlayerKilled(ob);
+			 }
+
+
+		}
+	 }
+
+//================ Check special player/actor links ======================
+
+   if (ob->whatever)
+	 {temp = (objtype*)(ob->whatever);
+
+		 dx = abs(ob->x - temp->x);
+		 dy = abs(ob->y - temp->y);
+       dz = abs(ob->z - temp->z);
+		 if (ob->flags & FL_RIDING)
+			rad = MINACTORDIST;
+		 else
+         rad = 0x8000;
+
+       if ((dx >rad) || (dy > rad) || (dz > 64))
+			{
+         if ((temp->obclass == bladeobj) || (temp->obclass == diskobj))
+			 {temp->whatever = NULL;
+			  ob->flags &= ~FL_RIDING;
+			 }
+
+			else if (ob->temp2 == COLUMNCRUSH)
+			  ob->temp2 = RENORMALIZE;
+			else if (ob->z < nominalheight)
+			  ob->momentumz = 40000;
+			else if (temp->which == SPRITE)
+			 {tstat = (statobj_t*)(ob->whatever);
+			  MakeStatActive(tstat);
+			  SetNormalHorizon(ob);
+			 }
+			ob->whatever = NULL;
+			}
+	 }
+
+//=========================================================================
+
+
+   if (BATTLEMODE && (MAPSPOT(ob->tilex,ob->tiley,1) == EXITTILE))
+      {
+      Move_Player_From_Exit_To_Start(ob);
+      return;
+      }
+
+   if (ob==player)
+		{
+      if (MAPSPOT(ob->tilex,ob->tiley,1) == EXITTILE)
+         playstate=ex_completed;
+      else if ( ( MAPSPOT( ob->tilex, ob->tiley, 2 ) & 0xff00 ) == 0xe400 )
+         playstate = ex_secretdone;
+		else if (MAPSPOT(ob->tilex,ob->tiley,1) == SECRETEXITTILE)
+			playstate=ex_secretlevel;
+		}
+}
+
+
+
+void Move_Player_From_Exit_To_Start(objtype *ob)
+   {
+   int i = 0,oldarea,newarea;
+   objtype *tplayer;
+   int travelangle,dangle;
+   playertype *pstate;
+
+   M_LINKSTATE(ob,pstate);
+
+
+   oldarea = ob->areanumber;
+   newarea = AREANUMBER(FIRST.x,FIRST.y);
+   if (oldarea != newarea)
+      {
+      RemoveFromArea(ob);
+      ob->areanumber = newarea;
+      MakeLastInArea(ob);
+      }
+
+   SetTilePosition(ob,FIRST.x,FIRST.y);
+   ob->z = PlatformHeight(ob->tilex,ob->tiley);
+   if ((ob->z == -10) || DiskAt(ob->tilex,ob->tiley))
+      ob->z = 0;
+
+   ConnectAreas();
+   travelangle = atan2_appx(ob->momentumx,ob->momentumy);
+   dangle = ob->angle - travelangle;
+
+   ob->angle = (1-FIRST.dir)*ANG90 + dangle;
+	Fix(ob->angle);
+
+	ob->dir   = angletodir[ob->angle];
+	pstate->anglefrac= (ob->angle<<ANGLEBITS);
+	pstate->angle=0;
+
+
+   for(i=0;i<numplayers;i++)
+      {
+      tplayer = PLAYER[i];
+
+      if (ob == tplayer)
+         continue;
+
+      if (
+         (tplayer->tilex == FIRST.x) &&
+         (tplayer->tiley == FIRST.y) &&
+         (!(tplayer->flags & FL_DYING))
+         )
+         {
+         playertype *pstate;
+
+         M_LINKSTATE(tplayer,pstate);
+
+         pstate->health = tplayer->hitpoints = 0;
+         tplayer->flags |= FL_HBM;
+         Collision(tplayer,ob,0,0);
+         BATTLE_PlayerKilledPlayer(battle_kill_by_crushing,ob->dirchoosetime,tplayer->dirchoosetime);\
+
+         }
+      }
+
+
+   }
+
+
+
+void PlayerSlideMove(objtype * ob)
+{int tryx, tryy, tryz;
+
+ tryx = ob->x + ob->momentumx;
+ tryy = ob->y + ob->momentumy;
+ tryz = ob->z + (ob->momentumz >> 16);
+
+ if (ActorTryMove(ob,ob->x,tryy,tryz))
+    {
+	 if (ob->momentumx>HITWALLSPEED)
+	    SD_PlaySoundRTP(SD_HITWALLSND,ob->x,ob->y);
+    ob->momentumx=0;
+    }
+ else if (ActorTryMove(ob,tryx,ob->y,tryz))
+    {
+    if (ob->momentumy>HITWALLSPEED)
+	    SD_PlaySoundRTP(SD_HITWALLSND,ob->x,ob->y);
+	 ob->momentumy=0;
+	 }
+ else
+    {
+	 if (FindDistance(ob->momentumx,ob->momentumy)>(HITWALLSPEED*3/2))
+	    SD_PlaySoundRTP(SD_HITWALLSND,ob->x,ob->y);
+    ob->momentumx=0;
+    ob->momentumy=0;
+    }
+}
+
+/*
+===================
+=
+= SetNormalHorizon
+=
+===================
+*/
+
+void SetNormalHorizon (objtype * ob)
+{
+	playertype * pstate;
+
+	M_LINKSTATE(ob,pstate);
+
+   if (ob->flags&FL_DOGMODE)
+      {
+      SetPlayerHorizon(pstate,DOGYZANGLE);
+      }
+   else if (ob->flags&FL_GODMODE)
+      {
+      SetPlayerHorizon(pstate,GODYZANGLE);
+      }
+   else
+      {
+      SetPlayerHorizon(pstate,NORMALYZANGLE);
+      }
+}
+
+/*
+===================
+=
+= PlayerTiltHead
+=
+===================
+*/
+extern int iG_playerTilt;
+extern double dTopYZANGLELIMIT;
+void PlayerTiltHead (objtype * ob)
+{
+	playertype * pstate;
+   int dyz=0;
+   int yzangle;
+
+//bna++   jumpmode
+  if ((donttilt > 0)){
+	  donttilt--;
+	  return;
+  }
+
+	M_LINKSTATE(ob,pstate);
+
+   yzangle=ob->yzangle+HORIZONYZOFFSET;
+   Fix(yzangle);
+
+   if (
+        (pstate->lastmomz!=ob->momentumz) &&
+        (ob->momentumz==0) &&
+        (
+          (!(ob->flags&FL_FLEET)) ||
+          (
+            (ob->flags&FL_FLEET) &&
+            (ob->z==nominalheight)
+          )
+        )
+      )
+      SetNormalHorizon(ob);
+
+   pstate->lastmomz=ob->momentumz;
+
+   if (ob->flags&FL_SHROOMS)
+      {
+      ob->yzangle = FixedMulShift(SHROOMYZANGLE,sintable[(oldpolltime<<6)&(FINEANGLES-1)],16);
+      Fix(ob->yzangle);
+      return;
+      }
+   else if (pstate->guntarget)
+      {
+		int dx,dy,dz;
+      int xydist;
+      int yzangle;
+
+      dx = ob->x - pstate->guntarget->x;
+		dy = ob->y - pstate->guntarget->y;
+      xydist = FindDistance(dx,dy)-0x8000;
+      if (ob->z==pstate->guntarget->z)
+         dz = 0;
+      else
+         {
+         dz = (ob->z-pstate->guntarget->z)<<10;
+         }
+      yzangle = atan2_appx(xydist,dz);
+
+      yzangle += HORIZONYZOFFSET;
+      Fix(yzangle);
+      SetPlayerHorizon(pstate,yzangle-HORIZONYZOFFSET);
+
+		if (oldpolltime>pstate->targettime)
+         {
+         if (pstate->guntarget)
+            pstate->guntarget->flags &= ~FL_TARGET;
+			pstate->guntarget=NULL;
+         SetNormalHorizon(ob);
+         }
+      }
+   else
+      {
+      if (pstate->buttonstate[bt_horizonup])
+         {
+         if (yzangle!=pstate->horizon)
+            {
+            SetPlayerHorizon(pstate,yzangle-HORIZONYZOFFSET);
+            }
+         else
+            {
+            SetPlayerHorizon(pstate,(pstate->horizon-HORIZONYZOFFSET+YZHORIZONSPEED));
+            }
+         }
+      else if (pstate->buttonstate[bt_horizondown])
+         {
+         if (yzangle!=pstate->horizon)
+            {
+            SetPlayerHorizon(pstate,yzangle-HORIZONYZOFFSET);
+            }
+         else
+            {
+            SetPlayerHorizon(pstate,(pstate->horizon-HORIZONYZOFFSET-YZHORIZONSPEED));
+            }
+         }
+      if (pstate->buttonstate[bt_lookup] || CYBERLOOKUP)
+         {
+         if (!(ob->flags & FL_FLEET))
+            {
+            dyz=YZTILTSPEED;
+            if (pstate->buttonstate[bt_lookdown] || CYBERLOOKDOWN)
+               {
+               dyz=0;
+               }
+
+            SetNormalHorizon(ob);
+            }
+         }
+      if (pstate->buttonstate[bt_lookdown] || CYBERLOOKDOWN)
+         {
+         if (!(ob->flags & FL_FLEET))
+            {
+            dyz=-YZTILTSPEED;
+            if (pstate->buttonstate[bt_lookup] || CYBERLOOKUP)
+               {
+               dyz=0;
+               }
+            SetNormalHorizon(ob);
+            }
+         }
+      if (!(ob->flags&FL_DOGMODE) &&
+               !(ob->flags&FL_GODMODE) &&
+               !(ob->flags&FL_FLEET)   &&
+               !(ob->flags&FL_RIDING)  &&
+               (ob->momentumz > (GRAVITY<<1))//(ob->momentumz>0x1000)
+            )
+         {
+         SetPlayerHorizon(pstate,FALLINGYZANGLE);
+         }
+      }
+
+
+
+   if ((yzangle!=pstate->horizon) && (dyz==0))
+      {
+      int speed;
+
+      speed=SNAPBACKSPEED;
+		if (yzangle<pstate->horizon)
+         yzangle+=speed;
+		else
+         yzangle-=speed;
+      if ((abs(yzangle-pstate->horizon))<SNAPBACKSPEED)
+         yzangle=pstate->horizon;
+      }
+//SetTextMode();
+
+	if (yzangle != 512){
+		FinddTopYZANGLELIMITvalue(ob);
+	}
+
+
+   yzangle+=dyz;
+   if (yzangle-HORIZONYZOFFSET>YZANGLELIMIT)
+       yzangle=HORIZONYZOFFSET+YZANGLELIMIT;
+/*   else if (yzangle-HORIZONYZOFFSET<-TopYZANGLELIMIT)//bnafix
+       yzangle=HORIZONYZOFFSET-TopYZANGLELIMIT;//bnafix
+dTopYZANGLELIMIT*/
+   else if (yzangle-HORIZONYZOFFSET<-dTopYZANGLELIMIT)//bnafix
+       yzangle=HORIZONYZOFFSET-dTopYZANGLELIMIT;//bnafix
+   ob->yzangle=yzangle-HORIZONYZOFFSET;
+   Fix(ob->yzangle);
+
+   iG_playerTilt = ob->yzangle;
+
+}
+
+//----------------------------------------------------------------------
+// bna added function
+// if a player is to close to wall, looking down max
+//,this func limit the dTopYZANGLELIMIT value when
+// facing a wall 
+#define SMALLANGLE 90
+//there is small angles where didnt work
+//so we check for them to = 90/2048 = aprox, 15 degrees
+int FinddTopYZANGLELIMITvalue(objtype *ob)
+{/*
+
+
+checkx = ob->tilex + 1;
+checky = ob->tiley + 1;
+if (actorat[checkx][checky]){
+	return 0;
+}
+return 1;
+
+checkx = ob->tilex ;
+checky = ob->tiley;
+
+// find which direction the player is facing
+//and check if it is a wall
+
+*/
+
+   //use lowest down angle		   	   	
+	dTopYZANGLELIMIT = (26*FINEANGLES/360);
+   
+	if (ob->angle < 256 || ob->angle > 1792) {
+	   if ((tilemap[ob->tilex + 1][ob->tiley])!=0){
+
+			return 0;
+	   }
+       //ob->dir = east;
+   }else if (ob->angle < 768) {
+	   if ((tilemap[ob->tilex][ob->tiley-1])!=0){
+			return 0;
+	   }
+   }else if (ob->angle < 1280) {
+	   if ((tilemap[ob->tilex-1][ob->tiley])!=0){
+			return 0;
+	   }
+   }else{
+	   if ((tilemap[ob->tilex][ob->tiley+1])!=0){
+			return 0;
+	   }
+   }
+
+
+   //use middle down angle
+   dTopYZANGLELIMIT = (42*FINEANGLES/360);
+
+   if ((ob->angle > 768-SMALLANGLE)&&(ob->angle <= 768)) { 
+   	   if ((tilemap[ob->tilex -1][ob->tiley])!=0){//ob->tiley-1
+			return 0;
+	   }
+   }
+   if ((ob->angle < 1280+SMALLANGLE)&&(ob->angle >= 1280)) { 
+   	   if ((tilemap[ob->tilex - 1][ob->tiley])!=0){//ob->tiley+1
+			return 0;
+	   }
+   } 
+   if ((ob->angle > 256)&&(ob->angle <= 256+SMALLANGLE)) { 
+   	   if ((tilemap[ob->tilex + 1][ob->tiley])!=0){//ob->tiley-1
+			return 0;
+	   }
+   }   
+   if ((ob->angle < 1792)&&(ob->angle >= 1792-SMALLANGLE)) { 
+   	   if ((tilemap[ob->tilex + 1][ob->tiley])!=0){//ob->tiley+1
+			return 0;
+	   }
+   } 
+   if ((ob->angle < 1280)&&(ob->angle >= 1280-SMALLANGLE)) { 
+   	   if ((tilemap[ob->tilex ][ob->tiley+1])!=0){//ob->tilex-1
+			return 0;
+	   }
+   } 
+   if ((ob->angle > 1792)&&(ob->angle <= 1792+SMALLANGLE)) { 
+   	   if ((tilemap[ob->tilex ][ob->tiley+1])!=0){//ob->tiley+1
+			return 0;
+	   }
+   } 
+   if ((ob->angle > 768)&&(ob->angle <= 768+SMALLANGLE)) { 
+   	   if ((tilemap[ob->tilex][ob->tiley-1])!=0){//ob->tiley-1
+			return 0;
+	   }
+   }
+   if ((ob->angle < 256)&&(ob->angle >= 256-SMALLANGLE)) { 
+   	   if ((tilemap[ob->tilex][ob->tiley-1])!=0){//ob->tiley-1
+			return 0;
+	   }
+   }
+
+   //use max down angle
+   dTopYZANGLELIMIT = (90*FINEANGLES/360);
+   return 1;
+}
+// bna added function end
+//----------------------------------------------------------------------
+
+
+
+
+/*
+===================
+=
+= UpdatePlayers
+=
+=================== QWERTYU
+*/
+void UpdatePlayers ( void )
+{
+   objtype * obj;
+//   playertype * pstate;
+
+	for (obj = FIRSTACTOR; obj->obclass==playerobj; obj = obj->next)
+		 {
+
+//ErrorDontQuit("obj->next = ",obj->next);
+#if (BNACRASHPREVENT == 1)//crashed here when oscuro and larves were all killed
+		if (obj->next == 0){return;}
+#endif
+       obj->speed=FindDistance(obj->momentumx, obj->momentumy);
+//       M_LINKSTATE(obj,pstate);
+//       pstate->steptime-=obj->speed;
+//       if (pstate->steptime<0)
+//          {
+//          while (pstate->steptime<0)
+//             pstate->steptime+=PLAYERSTEPTIME;
+//          pstate->stepwhich^=1;
+//          SD_PlaySoundRTP(SD_WALK1SND+pstate->stepwhich,obj->x,obj->y);
+//          }
+		 }
+}
+
+
+/*
+===================
+=
+= PlayerMove
+=
+===================
+*/
+
+void PlayerMove ( objtype * ob )
+{playertype *pstate;
+
+   M_LINKSTATE(ob,pstate);
+   if (ob->flags & FL_FLEET)
+      CheckFlying(ob,pstate);
+   ActorMovement(ob);
+   pstate->anglefrac = (pstate->anglefrac+pstate->angle)&((FINEANGLES<<ANGLEBITS)-1);
+	ob->angle = (pstate->anglefrac >> ANGLEBITS);
+	ob->dir = angletodir[ob->angle];
+	if (ob==player)
+		UpdateLightLevel(player->areanumber);
+
+   PlayerTiltHead(ob);
+
+   if (IsWindow(ob->tilex,ob->tiley))
+		{
+		if (!(ob->flags & FL_DYING))
+			{
+         pstate->health = 0;
+         pstate->falling=true;
+         if ((ob->flags & FL_GODMODE) || (ob->flags & FL_DOGMODE) ||
+             (gamestate.battlemode == battle_Eluder) || (godmode==true))
+            {
+            KillActor(ob);
+            NewState(ob,&s_remotedie1);
+            }
+         else
+            Collision(ob,(objtype*)NULL,0,0);
+         ob->flags |= FL_DYING;
+         M_CheckPlayerKilled(ob);
+			}
+		}
+}
+
+/*
+===============
+=
+= T_Tag
+=
+===============
+*/
+
+void  T_Tag (objtype *ob)
+{
+	playertype *pstate;
+
+	CheckPlayerSpecials(ob);
+	//CheckWeaponStates(ob);
+	M_LINKSTATE(ob,pstate);
+	Thrust(ob);
+
+	if (ob->ticcount > 4)
+		pstate->weaponheight -= GMOVE;
+	else
+		pstate->weaponheight += GMOVE;
+
+	if ((ob->ticcount > 1) && (ob->ticcount < 8) && (!(ob->flags & FL_DIDTAG)))
+	  {int i,dx,dy,magangle;
+
+		for(i=0;i<numplayers;i++)
+		  {if (PLAYER[i] == ob)
+			  continue;
+
+			dx = abs(PLAYER[i]->x - ob->x);
+			dy = abs(PLAYER[i]->y - ob->y);
+			if ((dx > 0xc000) || (dy > 0xc000))
+			 continue;
+			magangle = abs(ob->angle - AngleBetween(ob,PLAYER[i]));
+			if (magangle > VANG180)
+				magangle = ANGLES - magangle;
+
+			if (magangle > ANGLES/8)
+				continue;
+         CheckTagGame(ob,PLAYER[i]);
+			break;
+		  }
+
+	  }
+
+
+//Commented out until we find if it's valid
+/*
+	if (!ob->ticcount)
+	  {if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
+			pstate->buttonstate[bt_use] = false;
+		if ( pstate->buttonstate[bt_attack] && !pstate->buttonheld[bt_attack])
+			pstate->buttonstate[bt_attack] = false;
+	  }
+*/
+}
+
+#if (SHAREWARE == 0)
+#define GET_RESETSTATE(ob,resetstate)      \
+   {                                       \
+   if (ob->state->condition & SF_DOGSTATE) \
+      resetstate = &s_serialdog;           \
+   else                                    \
+      resetstate = &s_player;              \
+   }
+#else
+#define GET_RESETSTATE(ob,resetstate)      \
+   {                                       \
+   resetstate = &s_player;                 \
+   }
+#endif
+
+/*
+===============
+=
+= T_Attack
+=
+===============
+*/
+
+void  T_Attack (objtype *ob)
+{
+	attack_t   *cur;
+
+	playertype *pstate;
+   statetype *resetstate;
+
+
+   Thrust(ob);
+   if (ob->flags & FL_DYING)
+     return;
+
+   resetstate = ob->state;
+   CheckPlayerSpecials(ob);
+   if (resetstate != ob->state)
+      {
+      return;
+      }
+
+
+   if ((ob->flags & FL_PAIN) && (!ob->ticcount))
+	  ob->flags &= ~FL_PAIN;
+
+	CheckWeaponStates(ob);
+	M_LINKSTATE(ob,pstate);
+   GET_RESETSTATE(ob,resetstate);
+
+
+   if (ARMED(ob->dirchoosetime)
+   //(gamestate.battlemode != battle_Tag)
+      )
+
+      {
+      if (pstate->weapondowntics == 1)  // change to up; during change, up and down
+                                // are never zero at the same time
+         {
+   #if (SHAREWARE == 0)
+         if (pstate->weapon == wp_kes)
+            {
+            pstate->weapondowntics = 0;
+            pstate->weaponuptics = KESTICS/(2*GMOVE);
+            }
+         else
+   #endif
+            {
+            pstate->weapondowntics = 0;
+            pstate->weaponframe = pstate->attackframe = 0;
+
+            if (pstate->NETCAPTURED == -1)
+               {
+               pstate->weaponuptics = FREE.screenheight/GMOVE;
+               pstate->weaponheight = pstate->weaponuptics*GMOVE ;
+               pstate->NETCAPTURED = 1;
+     //          return;
+               }
+            else if (pstate->NETCAPTURED == -2)
+               {
+               pstate->weaponuptics = WEAPONS[pstate->weapon].screenheight/GMOVE;
+               pstate->weaponheight = pstate->weaponuptics*GMOVE ;
+               pstate->NETCAPTURED = 0;
+
+              //return;
+               }
+            else
+               {
+               pstate->weaponuptics = WEAPONS[pstate->new_weapon].screenheight/GMOVE;
+               pstate->weapon = pstate->new_weapon;
+               pstate->weaponheight = pstate->weaponuptics*GMOVE ;
+               }
+            }
+         }
+      }
+  else if (gamestate.battlemode == battle_Hunter)
+     {
+     if (pstate->weapondowntics == 1)
+
+        {
+        pstate->weapondowntics = 0;
+        pstate->weaponframe = pstate->attackframe = pstate->batblast = 0;
+        pstate->weapon = pstate->new_weapon;
+        NewState(ob,resetstate);
+        return;
+        }
+     }
+
+
+
+
+#if (SHAREWARE==0)
+   if ((pstate->buttonstate[bt_use]) &&
+       (pstate->weapon != wp_dog)
+      )
+#else
+   if (pstate->buttonstate[bt_use])
+#endif
+		Cmd_Use (ob);
+
+   if (pstate->attackframe >= WEAPONS[pstate->weapon].numattacks)
+      Error("\n attackframe %d for weapon %d gt numattacks %d",
+            pstate->attackframe,pstate->weapon,
+            WEAPONS[pstate->weapon].numattacks
+           );
+
+   cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
+	if (! pstate->attackcount)
+      {
+      switch (cur->attack)
+         {
+         case reset:
+            if (vrenabled && (ob==player))
+               {
+               StopVRFeedback();
+               }
+            ob->flags &= ~FL_FULLLIGHT;
+            if (pstate->ammo)
+               {
+               if (BATTLEMODE && (pstate->weapon == wp_firewall))
+                  break;
+               if (BATTLEMODE && (pstate->weapon == wp_firebomb))
+                  break;
+               if ((pstate->buttonstate[bt_attack]) && (pstate->weapon <= wp_firewall))
+                  {
+                  if (pstate->weapon <= wp_mp40)
+                     {
+                     if (pstate->weapon == wp_twopistol)
+                        pstate->attackframe -= 6;
+                     else if (pstate->weapon == wp_pistol)
+                        pstate->attackframe -= 3;
+                     else if (pstate->weapon == wp_mp40)
+                        pstate->attackframe -= 2;
+
+                     if (ob->state == &s_pmissattack2)
+                        NewState(ob,&s_pmissattack1);
+                     else if (ob->state == &s_pgunattack2)
+                        NewState(ob,&s_pgunattack1);
+
+                     }
+
+                  }
+               else
+                  {
+                  NewState(ob,resetstate);
+                  pstate->attackframe = pstate->weaponframe = 0;
+                  pstate->batblast = 0;
+                  return;
+                  }
+               }
+            else
+               {
+               NewState(ob,resetstate);
+               pstate->attackframe = pstate->weaponframe = 0;
+               pstate->new_weapon = pstate->bulletweapon;
+               pstate->batblast = 0;
+               pstate->ammo = -1;
+               pstate->missileweapon = -1;
+               pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
+
+               if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
+                     DrawBarAmmo (false);
+
+               return;
+               }
+            break;
+
+         case reset2:
+            if (vrenabled && (ob==player))
+               {
+               StopVRFeedback();
+               }
+            ob->flags &= ~FL_FULLLIGHT;
+            if (pstate->buttonstate[bt_attack] && pstate->ammo)
+               {
+               pstate->attackframe -= 4;
+               if (ob->state == &s_pmissattack2)
+                  NewState(ob,&s_pmissattack1);
+               else if (ob->state == &s_pgunattack2)
+                  NewState(ob,&s_pgunattack1);
+               }
+            else
+               {
+               NewState(ob,resetstate);
+               pstate->attackframe = pstate->weaponframe = 0;
+               pstate->batblast = 0;
+               return;
+               }
+
+            break;
+
+
+         case at_pulltrigger:
+            if (vrenabled && (ob==player))
+               {
+               StartVRFeedback(1);
+               }
+            ob->flags |= FL_FULLLIGHT;
+
+      #if (SHAREWARE == 0)
+
+            if (pstate->batblast >= BBTIME)
+               DogBlast(ob);
+
+            else if (pstate->weapon == wp_dog)
+               DogAttack(ob);
+            else if (pstate->weapon == wp_bat)
+               BatAttack (ob);
+            else
+      #endif
+               GunAttack(ob);
+
+            break;
+
+         case at_missileweapon:
+            if (!pstate->ammo)
+               {
+               pstate->attackframe = pstate->weaponframe = 0;
+               pstate->batblast = 0;
+               return;
+               }
+
+            if (vrenabled && (ob==player))
+               {
+               StartVRFeedback(1);
+               }
+            ob->flags |= FL_FULLLIGHT;
+            if (ob==player)
+               SetIllumination(2);
+            PlayerMissileAttack(ob);
+
+
+            if (!(ob->flags & FL_GODMODE) && !godmode)
+               {
+               if (!BATTLEMODE || (gamestate.BattleOptions.Ammo != bo_infinite_shots))
+                  pstate->ammo--;
+
+               if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
+                  DrawBarAmmo (false);
+               }
+   #if (SHAREWARE == 0)
+            if (pstate->weapon == wp_kes)
+               pstate->weapondowntics = KESTICS/(2*GMOVE);
+   #endif
+            break;
+
+	 default:
+	     ;
+         }
+
+      pstate->attackframe++;
+      cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
+      pstate->weaponframe = cur->frame;
+      pstate->attackcount = cur->mtics;
+
+      }
+   else
+      pstate->attackcount --;
+   }
+
+/*
+===============
+=
+= T_BatBlast
+=
+===============
+*/
+
+void  T_BatBlast (objtype *ob)
+{
+	attack_t   *cur;
+	playertype *pstate;
+
+
+   Thrust(ob);
+   CheckPlayerSpecials(ob);
+   M_LINKSTATE(ob,pstate);
+
+
+//Commented out until we find if it's valid
+/*
+	if (!ob->ticcount)
+	 {if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
+		pstate->buttonstate[bt_use] = false;
+
+	  if ( pstate->buttonstate[bt_attack] && !pstate->buttonheld[bt_attack])
+		pstate->buttonstate[bt_attack] = false;
+	 }
+*/
+//
+// change frame and fire
+//
+
+	BatBlast(ob);
+
+
+
+   if (pstate->attackframe >= WEAPONS[pstate->weapon].numattacks)
+      Error("\n attackframe %d for weapon %d gt numattacks %d",
+            pstate->attackframe,pstate->weapon,
+            WEAPONS[pstate->weapon].numattacks
+           );
+
+
+
+   cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
+	if (! pstate->attackcount)
+		{if (cur->attack == reset)
+			{
+			 if (!(ob->flags & FL_GODMODE) && (!godmode))
+				{pstate->ammo --;
+             if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
+						DrawBarAmmo (false);
+				}
+
+			 if (!pstate->ammo)
+				{pstate->new_weapon = pstate->bulletweapon;
+				 pstate->ammo = -1;
+				 pstate->missileweapon = -1;
+				 pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
+
+				}
+
+			 NewState(ob,&s_player);
+			 pstate->attackframe = pstate->weaponframe = 0;
+			 pstate->batblast = 0;
+			 return;
+			}
+		 pstate->attackframe++;
+		 pstate->weaponframe = WEAPONS[pstate->weapon].attackinfo[pstate->attackframe].frame;
+		 cur = &(WEAPONS[pstate->weapon].attackinfo[pstate->attackframe]);
+		 pstate->attackcount = cur->mtics;
+		}
+	else
+		pstate->attackcount --;
+
+}
+
+
+
+
+void  T_Free (objtype *ob)
+{
+	attack_t   *cur;
+
+
+  if (!ob->ticcount)
+  {
+
+
+//Commented out until we find if it's valid
+/*
+	if ( locplayerstate->buttonstate[bt_use] && !locplayerstate->buttonheld[bt_use] )
+		locplayerstate->buttonstate[bt_use] = false;
+
+	if ( locplayerstate->buttonstate[bt_attack] && !locplayerstate->buttonheld[bt_attack])
+		locplayerstate->buttonstate[bt_attack] = false;
+*/
+   Thrust(ob);
+
+  }
+  CheckPlayerSpecials(ob);
+
+
+
+
+
+
+  cur = &(FREE.attackinfo[locplayerstate->attackframe]);
+
+	if (!locplayerstate->attackcount)
+	 {
+		if ((locplayerstate->weaponframe > 3) && (locplayerstate->weaponframe < 8))
+		  locplayerstate->NETCAPTURED ++;
+		else if (locplayerstate->weaponframe == 8)
+		 {
+			  locplayerstate->NETCAPTURED = -2;
+			  MISCVARS->NET_IN_FLIGHT = false;
+			  NewState(ob,&s_player);
+			  locplayerstate->weapondowntics = FREE.screenheight/GMOVE;
+		  return;
+		 }
+
+		locplayerstate->attackframe++;
+		cur = &(FREE.attackinfo[locplayerstate->attackframe]);
+		locplayerstate->weaponframe = cur->frame;
+
+		locplayerstate->attackcount = cur->mtics;
+
+	 }
+	else
+	 locplayerstate->attackcount --;
+ }
+
+
+
+void Switch_Who_Is_It_For_Tag(objtype *actor1,objtype *actor2)
+{
+ playertype *pstate;
+
+ M_LINKSTATE(actor1,pstate);
+ if (pstate->buttonstate[bt_use])
+      {playertype *pstate2;
+
+      M_LINKSTATE(actor2,pstate2);
+      pstate2->oldmissileweapon = pstate2->oldweapon = pstate2->new_weapon =
+      pstate2->missileweapon = pstate2->weapon = wp_godhand;
+      pstate2->weaponheight = 144;
+      pstate2->weaponuptics = (144 - TAGHANDHEIGHT)/GMOVE;
+      pstate2->weapondowntics = 0;
+      actor1->flags |= FL_DIDTAG;
+      actor2->flags |= FL_DESIGNATED;
+      UpdateKills = true;
+
+      actor1->flags &= ~FL_DESIGNATED;
+      BATTLE_PlayerKilledPlayer(battle_player_tagged,
+         actor1->dirchoosetime, actor2->dirchoosetime);
+      }
+
+}
+
+
+
+void CheckTagGame(objtype *actor1,objtype*actor2)
+{
+ //if ((actor1->obclass != playerobj) || (actor2->obclass != playerobj))
+	//return;
+
+ if (!BATTLEMODE)
+	return;
+
+ if (gamestate.battlemode != battle_Tag)
+	return;
+
+ SD_PlaySoundRTP(SD_GETBONUSSND,actor1->x,actor1->y);
+
+ if (actor1->flags & FL_DESIGNATED)
+   Switch_Who_Is_It_For_Tag(actor1,actor2);
+ else if (actor2->flags & FL_DESIGNATED)
+   Switch_Who_Is_It_For_Tag(actor2,actor1);
+
+}
+
+
+
+
+
+
+/*
+======================
+=
+= CheckWeaponChange
+=
+= Keys 1-4 change weapons
+=
+======================
+*/
+
+void CheckWeaponChange (objtype * ob)
+{
+//   int     i;
+
+	playertype * pstate;
+
+
+	M_LINKSTATE(ob,pstate);
+	//pstate = (ob == player)?(&playerstate):(&remoteplayerstate);
+	if (W_CHANGE(pstate))
+	 return;
+
+	if (!ARMED(ob->dirchoosetime))
+	  return;
+
+	if ((ob->flags & FL_DOGMODE) || (ob->flags & FL_GODMODE))
+		return;
+
+#if (WEAPONCHEAT==1)
+		if (godmode && Keyboard[sc_Insert])
+			{
+			SD_Play(SD_SELECTWPNSND);
+
+			// FOR DEBUG only
+			/*
+			if (pstate->buttonstate[bt_run])
+			 {
+			 if (pstate->weapon == 0)
+			  pstate->new_weapon = wp_bat;
+			 else
+			  pstate->new_weapon --;
+			 }
+			else
+			 {*/
+			 if (pstate->weapon == MAXWEAPONS-1)
+			  pstate->new_weapon = 0;
+			 else
+			  pstate->new_weapon ++;
+			 //}
+			if (pstate->new_weapon <= wp_mp40)
+			 {pstate->bulletweapon = pstate->new_weapon;
+			  pstate->HASBULLETWEAPON[pstate->new_weapon] = 1;
+			 }
+			else
+			 pstate->missileweapon = pstate->new_weapon;
+
+         pstate->ammo = stats[GetItemForWeapon(pstate->missileweapon)].ammo;
+         if (pstate->ammo<1)
+            pstate->ammo=5;
+         StartWeaponChange;
+         //pstate->weapondowntics = WEAPONS[pstate->weapon].screenheight/GMOVE;
+         //if ((ob==player) && SHOW_BOTTOM_STATUS_BAR() )
+			  //		DrawBarAmmo (false);
+			}
+		else if (pstate->buttonstate[bt_swapweapon])
+#else
+		if (pstate->buttonstate[bt_swapweapon])
+#endif
+		 {
+		  if ((pstate->weapon == pstate->bulletweapon) &&
+				(pstate->missileweapon != -1))
+			  {pstate->new_weapon = pstate->missileweapon;
+				StartWeaponChange;
+			  }
+
+		  else if (pstate->weapon != pstate->bulletweapon)
+			{pstate->new_weapon = pstate->bulletweapon;
+			 StartWeaponChange;
+			}
+		 }
+      else if ((pstate->buttonstate[bt_dropweapon]) &&
+         (!gamestate.BattleOptions.WeaponPersistence))
+			{
+			if (pstate->weapon==pstate->bulletweapon)
+				{
+				if ((ob==player) && (!(pstate->buttonheld[bt_dropweapon])))
+               PlayNoWaySound();
+				}
+			else
+				{
+				if (sprites[ob->tilex][ob->tiley])
+					{
+					if ((ob==player) && (!(pstate->buttonheld[bt_dropweapon])))
+                  PlayNoWaySound();
+					}
+				else
+					{
+					DropWeapon(ob);
+					}
+				}
+			}
+
+
+
+	 if (pstate->buttonstate[bt_pistol])
+		{if (pstate->weapon != wp_pistol)
+			{pstate->new_weapon = pstate->bulletweapon = wp_pistol;
+			 StartWeaponChange;
+			}
+		}
+
+	 else if (pstate->buttonstate[bt_dualpistol])
+		{if ((pstate->weapon != wp_twopistol) && pstate->HASBULLETWEAPON[wp_twopistol])
+			{pstate->new_weapon = pstate->bulletweapon = wp_twopistol;
+			 StartWeaponChange;
+			}
+		}
+	 else if (pstate->buttonstate[bt_mp40])
+		{if ((pstate->weapon != wp_mp40) && pstate->HASBULLETWEAPON[wp_mp40])
+			{pstate->new_weapon = pstate->bulletweapon = wp_mp40;
+			 StartWeaponChange;
+			}
+		}
+	 else if (pstate->buttonstate[bt_missileweapon])
+		{if ((pstate->weapon != pstate->missileweapon) && (pstate->missileweapon != -1))
+			{pstate->new_weapon = pstate->missileweapon;
+			 StartWeaponChange;
+			}
+		}
+}
+
+
+void SetWhoHaveWeapons(void)
+   {
+   playertype *pstate;
+   objtype    *ob;
+   int        i;
+
+   for ( i = 0; i < numplayers; i++ )
+      {
+      ob = PLAYER[ i ];
+		M_LINKSTATE( ob, pstate );
+
+		if ( ARMED( ob->dirchoosetime ))
+         {
+         if (pstate->weapon == -1)
+            {
+            if (( pstate->missileweapon != -1 ) && (pstate->ammo>0))
+               pstate->new_weapon = pstate->missileweapon;
+
+            else
+               {
+               if ( pstate->bulletweapon == -1 )
+                  {
+                  pstate->HASBULLETWEAPON[ wp_pistol ] = 1;
+                  pstate->bulletweapon = wp_pistol;
+                  }
+               pstate->new_weapon = pstate->bulletweapon;
+               pstate->ammo = -1;
+               }
+
+            pstate->weapon = pstate->new_weapon;
+            pstate->weapondowntics = 0;
+            pstate->weaponuptics = WEAPONS[pstate->new_weapon].screenheight/GMOVE;
+            pstate->weaponheight = pstate->weaponuptics*GMOVE ;
+            pstate->attackframe = pstate->weaponframe =
+            pstate->batblast = 0;
+            if (i == consoleplayer)
+               DrawBarAmmo(false);
+            }
+			}
+		else
+			{
+			if (ob->flags & FL_DOGMODE)
+            {
+            ob->temp2 = DOGMODERISE;
+            pstate->oldweapon = -1;
+            ResetWeapons(ob);
+            if (ob->state->condition & SF_DOGSTATE)
+               NewState(ob,&s_player);
+				}
+			else if (ob->flags & FL_GODMODE)
+            {
+            ob->temp2 = GODMODEFALL;
+            pstate->oldweapon = -1;
+            ResetWeapons(ob);
+				}
+			else
+            {
+            pstate->new_weapon = -1;
+            StartWeaponChange;
+				}
+         pstate->attackframe = pstate->weaponframe =
+         pstate->batblast = 0;
+			}
+		}
+	}
+
+
+
+
+
+
+
+
+void CheckWeaponStates(objtype*ob)
+{playertype *pstate;
+
+ M_LINKSTATE(ob,pstate);
+
+ if (gamestate.battlemode == battle_Tag)
+	{if (pstate->weapondowntics)
+		{pstate->weaponheight += GMOVE;
+		 pstate->weapondowntics --;
+		 if (!pstate->weapondowntics)
+			pstate->weapon = pstate->missileweapon = pstate->bulletweapon =
+			pstate->new_weapon = pstate->oldweapon = pstate->oldmissileweapon = -1;
+
+		}
+
+
+	 if (pstate->weaponuptics)
+		{pstate->weaponheight -= GMOVE;
+		 pstate->weaponuptics --;
+		}
+	 return;
+	}
+
+ if (pstate->weapondowntics)
+		{pstate->weaponheight += GMOVE;
+#if (SHAREWARE == 0)
+       if ((pstate->weapon == wp_kes) && pstate->attackframe)
+			pstate->weaponheight += GMOVE;
+#endif
+		 pstate->weapondowntics --;
+		}
+ else if (pstate->weaponuptics)
+		{pstate->weaponheight -= GMOVE;
+#if (SHAREWARE == 0)
+       if ((pstate->weapon == wp_kes) && pstate->attackframe)
+			pstate->weaponheight -= GMOVE;
+#endif
+
+       pstate->weaponuptics --;
+		}
+ else if ((pstate->weapon == pstate->new_weapon) && (!pstate->NETCAPTURED))
+		pstate->weaponheight = 0;
+
+}
+
+
+/*
+=============================
+=
+= CheckSpecialSounds
+=
+=============================
+*/
+
+#define REGDOGSTATE(ob) \
+   ((ob->state == &s_serialdog) || (ob->state == &s_serialdog2) || \
+    (ob->state == &s_serialdog3) || (ob->state == &s_serialdog4)   \
+   )
+
+static int dyingvolume=255;
+void CheckSpecialSounds(objtype *ob, playertype *pstate)
+   {
+   int shift;
+
+   if ((!BATTLEMODE) && (ob == player))
+      {
+      if (pstate->health < MaxHitpointsForCharacter(locplayerstate)/5)
+         {
+         pstate->healthtime ++;
+         if (pstate->healthtime > 2*VBLCOUNTER)
+            {
+            pstate->healthtime = 0;
+            SD_PlayPitchedSound ( SD_PLAYERDYINGSND, dyingvolume, 0 );
+            if (dyingvolume>80)
+               dyingvolume-=40;
+            }
+         }
+      else
+         {
+         dyingvolume=255;
+         }
+      }
+
+   if (((ob->flags & FL_GODMODE) || (ob->flags & FL_DOGMODE)) &&
+       (!W_CHANGE(pstate))
+      )
+      {
+      pstate->soundtime++;
+      if (pstate->soundtime > (2*VBLCOUNTER))
+         {
+         int rand;
+
+         rand = GameRandomNumber("player special sound",0);
+         shift = (pstate->soundtime>>5);
+         if ((rand << shift) > 3500)
+            {
+            int sound;
+
+            pstate->soundtime = 0;
+
+            rand = GameRandomNumber("player god scare",0);
+
+            if (ob->flags & FL_GODMODE)
+               {
+               sound = SD_GODMODE1SND;
+               if (rand < 160)
+                  sound++;
+               if (rand < 80)
+                  sound ++;
+               SD_PlaySoundRTP(sound,ob->x,ob->y);
+               }
+#if (SHAREWARE == 0)
+            else if ((!pstate->batblast) && (!ob->momentumz) &&
+                     (REGDOGSTATE(ob))
+                    )
+               {
+               sound = SD_DOGMODEPANTSND;
+               if (rand < 128)
+                  sound += 2;
+               NewState(ob,&s_doglick);
+               pstate->attackframe = pstate->weaponframe =
+               pstate->batblast = 0;
+               SD_PlaySoundRTP(sound,ob->x,ob->y);
+               }
+#endif
+            }
+         }
+      }
+
+
+
+
+   else if (ob->flags & FL_GASMASK)
+      {
+      pstate->soundtime ++;
+
+      if (pstate->soundtime > (3*VBLCOUNTER))
+         {
+         pstate->soundtime = 0;
+			SD_PlaySoundRTP(SD_GASMASKSND,ob->x,ob->y);
+         }
+      }
+
+
+   else if (MISCVARS->GASON)
+      {
+      pstate->soundtime ++;
+      if (pstate->soundtime > (2*VBLCOUNTER))
+         {
+         int rand;
+
+         rand = GameRandomNumber("player cough sound",0);
+         shift = (pstate->soundtime>>5);
+         if ((rand << shift) > 2000)
+            {
+            pstate->soundtime = 0;
+            if ((pstate->player == 1) || (pstate->player == 3))
+               SD_PlaySoundRTP(SD_PLAYERCOUGHFSND,ob->x,ob->y);
+            else
+               SD_PlaySoundRTP(SD_PLAYERCOUGHMSND,ob->x,ob->y);
+            }
+         }
+      }
+   }
+
+/*
+static int dyingvolume=255;
+void CheckSpecialSounds(objtype *ob, playertype *pstate)
+   {
+   int shift;
+
+   if ((!BATTLEMODE) && (ob == player))
+      {
+      if (pstate->health < MaxHitpointsForCharacter(locplayerstate)/5)
+         {
+         pstate->healthtime ++;
+         if (pstate->healthtime > 2*VBLCOUNTER)
+            {
+            pstate->healthtime = 0;
+            SD_PlayPitchedSound ( SD_PLAYERDYINGSND, dyingvolume, 0 );
+            if (dyingvolume>80)
+               dyingvolume-=40;
+            }
+         }
+      else
+         {
+         dyingvolume=255;
+         }
+      }
+
+   if (((ob->flags & FL_GODMODE) || (ob->flags & FL_DOGMODE)) &&
+       (!W_CHANGE(pstate))
+      )
+      {
+      pstate->soundtime++;
+      if (pstate->soundtime > (2*VBLCOUNTER))
+         {
+         int rand;
+
+         rand = GameRandomNumber("player special sound",0);
+         shift = (pstate->soundtime>>5);
+         if ((rand << shift) > 3500)
+            {
+            int sound;
+
+            pstate->soundtime = 0;
+
+            rand = GameRandomNumber("player god scare",0);
+
+            if (ob->flags & FL_GODMODE)
+               {
+               sound = SD_GODMODE1SND;
+               if (rand < 160)
+                  sound++;
+               if (rand < 80)
+                  sound ++;
+               SD_PlaySoundRTP(sound,ob->x,ob->y);
+               }
+#if (SHAREWARE == 0)
+            else if (!pstate->batblast)
+               {
+               sound = SD_DOGMODEPANTSND;
+               if (rand < 128)
+                  sound += 2;
+               NewState(ob,&s_doglick);
+               pstate->attackframe = pstate->weaponframe =
+               pstate->batblast = 0;
+               SD_PlaySoundRTP(sound,ob->x,ob->y);
+               }
+#endif
+            }
+         }
+      }
+
+
+
+
+   else if (ob->flags & FL_GASMASK)
+      {
+      pstate->soundtime ++;
+
+      if (pstate->soundtime > (3*VBLCOUNTER))
+         {
+         pstate->soundtime = 0;
+			SD_PlaySoundRTP(SD_GASMASKSND,ob->x,ob->y);
+         }
+      }
+
+
+   else if (MISCVARS->GASON)
+      {
+      pstate->soundtime ++;
+      if (pstate->soundtime > (2*VBLCOUNTER))
+         {
+         int rand;
+
+         rand = GameRandomNumber("player cough sound",0);
+         shift = (pstate->soundtime>>5);
+         if ((rand << shift) > 2000)
+            {
+            pstate->soundtime = 0;
+            if ((pstate->player == 1) || (pstate->player == 3))
+               SD_PlaySoundRTP(SD_PLAYERCOUGHFSND,ob->x,ob->y);
+            else
+               SD_PlaySoundRTP(SD_PLAYERCOUGHMSND,ob->x,ob->y);
+            }
+         }
+      }
+   }
+
+*/
+
+
+/*
+=============================
+=
+= CheckProtectionsAndPowerups
+=
+=============================
+*/
+
+
+
+void CheckProtectionsAndPowerups(objtype *ob, playertype *pstate)
+   {
+	if (pstate->poweruptime)
+		{
+		pstate->poweruptime --;
+		if (pstate->poweruptime < 0)
+			pstate->poweruptime = 0;
+		if (ob==player)
+			GM_UpdateBonus (pstate->poweruptime, true);
+		}
+	else
+		{
+		if (ob->flags & FL_ELASTO)
+			{
+			ob->flags &= ~FL_NOFRICTION;
+			if (ob==player)
+				GM_UpdateBonus (pstate->poweruptime, true);
+			SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
+			}
+		else if (ob->flags & FL_GODMODE)
+			{ob->temp2 = GODMODEFALL;
+          if ((pstate->player == 1) || (pstate->player == 3))
+				SD_PlaySoundRTP(SD_GODWOMANSND,ob->x, ob->y);
+			 else
+				SD_PlaySoundRTP(SD_GODMANSND,ob->x, ob->y);
+			 ResetWeapons(ob);
+			}
+		else if (ob->flags & FL_DOGMODE)
+			{int wall;
+
+			 wall = tilemap[ob->tilex][ob->tiley];
+			 if ((wall & 0x4000) && (wall & 0x8000))
+				{maskedwallobj_t * mw;
+
+				 mw=maskobjlist[wall&0x3ff];
+				 if (mw->flags&MW_NONDOGBLOCKING)
+					return;
+				}
+
+
+			 ob->temp2 = DOGMODERISE;
+          if ((pstate->player == 1) || (pstate->player == 3))
+				SD_PlaySoundRTP(SD_DOGWOMANSND,ob->x, ob->y);
+			 else
+				SD_PlaySoundRTP(SD_DOGMANSND,ob->x, ob->y);
+			 ResetWeapons(ob);
+			 if (ob->state->condition & SF_DOGSTATE)
+            {
+            NewState(ob,&s_player);
+            pstate->attackframe = pstate->weaponframe = pstate->batblast = 0;
+            }
+			}
+		else if (ob->flags & FL_SHROOMS)
+			{
+			ResetFocalWidth ();
+			SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
+			}
+		else if (ob->flags & FL_FLEET)
+			SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
+
+      ob->flags &= ~(FL_SHROOMS|FL_ELASTO|FL_FLEET|FL_GODMODE|FL_DOGMODE);
+		}
+
+   if (pstate->protectiontime)
+      {
+      pstate->protectiontime --;
+      if (pstate->protectiontime <= 0)
+         {
+         SD_PlaySoundRTP(SD_LOSEMODESND,ob->x, ob->y);
+         pstate->protectiontime = 0;
+         }
+      if (ob==player)
+         GM_UpdateBonus (pstate->protectiontime, false);
+      }
+   else
+      ob->flags &= ~(FL_BPV|FL_AV|FL_GASMASK);
+
+   }
+
+
+
+/*
+=============================
+=
+= CheckFlying
+=
+=============================
+*/
+
+void CheckFlying(objtype*ob,playertype *pstate)
+   {
+
+
+   if (pstate->buttonstate[bt_lookup] || CYBERLOOKUP)
+      {
+      ob->momentumz = -FLYINGZMOM;
+      }
+   if (pstate->buttonstate[bt_lookdown] || CYBERLOOKDOWN)
+      {
+      ob->momentumz = FLYINGZMOM;
+      }
+
+   /*
+   if (!M_ISDOOR(((ob->x + costable[ob->angle])>>16),
+         ((ob->y - sintable[ob->angle])>>16)) &&
+         (pstate->buttonstate[bt_use]) &&
+         (!pstate->buttonheld[bt_use])
+      )
+      {
+      int op;
+      int dist;
+
+      dist=JETPACKTHRUST;
+      if (ob->z-dist<-15)
+         dist=ob->z+15;
+      if (dist>0)
+         {
+         op = FixedMul(GRAVITY,(dist<<16)) << 1;
+         ob->momentumz = -FixedSqrtHP(op);
+         SD_PlaySoundRTP(SD_FLYINGSND,ob->x,ob->y);
+         }
+      }
+   */
+   }
+
+
+
+/*
+=============================
+=
+= CheckTemp2Codes
+=
+=============================
+*/
+
+
+#define IN_AIR(ob) \
+             (!((ob->z == nominalheight) ||              \
+                (IsPlatform(ob->tilex,ob->tiley)) ||    \
+                (DiskAt(ob->tilex,ob->tiley))           \
+               )                                        \
+             )                                          \
+
+
+void CheckTemp2Codes(objtype *ob,playertype *pstate)
+   {
+	int pitheight;
+	int godheight;
+	int dogheight;
+	int height;
+   int oldz;
+   int destheightoffset;
+
+
+	pitheight    = maxheight - 8;
+	height = ob->z + pstate->playerheight;
+	dogheight    = ob->z + DOGOFFSET;
+	godheight    = ob->z + GODOFFSET;
+
+   //SoftError("\nheightoffset: %d, temp2: %d",pstate->heightoffset,ob->temp2);
+
+
+   if (!((ob->temp2 == PITFALL) || (ob->temp2 == PITRISE)))
+      {
+
+      oldz = ob->z;
+      //SoftError("\n zmom %d, oldz %d, newz %d",ob->momentumz,oldz,ob->z);
+
+      if (ob->flags & FL_FLEET)
+         {
+         if (IN_AIR(ob))
+            pstate->heightoffset = FixedMulShift(0x4000,sintable[(oldpolltime<<6)&2047],28);
+
+         ob->z += ((ob->momentumz+0x8000)>>16);
+         ob->momentumz = 0;
+
+         }
+      else
+         {
+         ob->z += (ob->momentumz>>16);
+         ob->momentumz += GRAVITY;
+         }
+
+
+      if (ob->z >= nominalheight)
+         {
+         ob->z = nominalheight;
+         ob->momentumz = 0;
+			 //if (platform == nominalheight)
+			  //{//ob->temp2 = 0;
+				//ob->momentumz = 0;
+         if ((oldz < nominalheight) && (!(ob->flags & FL_RIDING)))
+            {
+				SD_PlaySoundRTP(SD_PLAYERLANDSND,ob->x,ob->y);
+				}
+
+         if (!(ob->flags & FL_ELASTO))
+				ob->flags &= ~FL_NOFRICTION;
+			//  }
+			}
+      else if (height < 1)
+         {
+         ob->momentumz = 0;
+			ob->z = 1-pstate->playerheight;
+         }
+
+
+
+		switch (ob->temp2)
+			{case RENORMALIZE:
+				 pstate->heightoffset --;
+
+             if (ob->flags & FL_DOGMODE)
+                destheightoffset = DOGOFFSET-pstate->playerheight;
+             else
+                destheightoffset = 0;
+
+             if (pstate->heightoffset <= destheightoffset)
+               {
+               ob->temp2 = 0;
+               pstate->heightoffset = 0;
+               }
+				 pstate->oldheightoffset = pstate->heightoffset;
+
+				 break;
+
+			 case COLUMNCRUSH:
+				 pstate->heightoffset += 4;
+				 if (pstate->heightoffset >= 30)
+					pstate->heightoffset = 30;
+
+				 pstate->oldheightoffset = pstate->heightoffset;
+				 break;
+
+			 case GODMODERISE:
+				 pstate->heightoffset --;
+				 pstate->oldheightoffset = pstate->heightoffset;
+				 if ((height+pstate->heightoffset) <= godheight)
+					{
+					 ob->temp2 = 0;
+					 pstate->poweruptime = POWERUPTICS;
+					}
+				 break;
+
+
+			 case GODMODEFALL:
+				 pstate->heightoffset ++;
+				 pstate->oldheightoffset = pstate->heightoffset;
+				 SetPlayerHorizon(pstate,NORMALYZANGLE);
+				 if (pstate->heightoffset >= 0)
+				  {
+					ob->temp2 = 0;
+					ob->flags &= ~FL_GODMODE;
+					SetNormalHorizon(ob);
+				  }
+				 break;
+
+			 case DOGMODERISE:
+				 pstate->heightoffset --;
+				 pstate->oldheightoffset = pstate->heightoffset;
+             SetPlayerHorizon(pstate,NORMALYZANGLE);
+				 if (pstate->heightoffset <= 0)
+					{
+					 ob->temp2 = 0;
+					 ob->flags &= ~FL_DOGMODE;
+					 SetNormalHorizon(ob);
+					}
+				 break;
+
+
+			 case DOGMODEFALL:
+				 pstate->heightoffset ++;
+				 pstate->oldheightoffset = pstate->heightoffset;
+             if (pstate->heightoffset >= (DOGOFFSET-pstate->playerheight))
+					 {
+					 ob->temp2 = 0;
+					 pstate->poweruptime = POWERUPTICS;
+					 }
+				 break;
+
+          case STEPUP:
+				 //Debug("\n\n heightoffset adjusted from %d to %d",
+					//	 pstate->heightoffset,pstate->heightoffset - STEPADJUST);
+				 pstate->heightoffset -= STEPADJUST;
+				 if (pstate->heightoffset <= pstate->oldheightoffset)
+					{ob->temp2 = 0;
+					 //Debug("\n done adjusting heightoffset");
+					 pstate->heightoffset = pstate->oldheightoffset;
+					}
+				 break;
+
+			 case STEPDOWN:
+				 pstate->heightoffset += STEPADJUST;
+				 if (pstate->heightoffset >= pstate->oldheightoffset)
+					{ob->temp2 = 0;
+					 pstate->heightoffset = pstate->oldheightoffset;
+					}
+				 break;
+
+          case 0:
+             if (!((ob->flags & FL_FLEET) ||
+                   (ob->flags & FL_DOGMODE) ||
+                   (ob->flags & FL_GODMODE)
+                  )
+                )
+                pstate->heightoffset = 0;
+				 break;
+
+			}
+
+
+	  }
+
+
+	else if (ob->temp2 == PITFALL)
+		{
+		if (ob->z != pitheight)
+			{
+			ob->z += (ob->momentumz>>16);
+			ob->momentumz += GRAVITY;
+			if (ob->z >= pitheight)
+				{
+				ob->z = pitheight;
+				ob->momentumz = 0;
+            if (!(ob->flags & FL_DYING))
+               {DamageThing(ob,10);
+                Collision(ob,(objtype*)NULL,0,0);
+                M_CheckPlayerKilled(ob);
+               }
+				}
+			}
+		else if (ob->momentumx || ob->momentumy)
+			{
+			ob->temp2 = PITRISE;
+			ob->momentumz = -2;
+			}
+		}
+
+	else if (ob->temp2 == PITRISE)
+		{ob->z += ob->momentumz;
+		 if (ob->z <= nominalheight)
+			 {ob->z = nominalheight;
+			  ob->temp2 = 0;
+			  ob->momentumz = 0;
+           if (pstate->heightoffset)
+              ob->temp2 = RENORMALIZE;
+			 }
+		}
+
+
+
+
+
+
+   }
+
+
+
+/*
+=============================
+=
+= CheckRemoteRecording
+=
+=============================
+*/
+
+void CheckRemoteRecording(objtype *ob,playertype *pstate)
+   {
+   if (networkgame==true)
+		{
+		if ( (pstate->buttonstate[bt_recordsound]) &&
+			  (!pstate->buttonheld[bt_recordsound])
+			)
+			{
+			if (SD_RecordingActive()==false)
+				{
+				SD_SetRecordingActive ();
+				PlayerRecording=ob->dirchoosetime;
+				if (ob==player)
+					{
+                   SD_StartRecordingSound();
+                   UpdateClientControls();
+					}
+				}
+			}
+		else if ( (pstate->buttonheld[bt_recordsound]) &&
+					 (!pstate->buttonstate[bt_recordsound])
+				  )
+			{
+			if (SD_RecordingActive()==true)
+				{
+				if (ob->dirchoosetime==PlayerRecording)
+					{
+					if (ob==player)
+						SD_StopRecordingSound();
+					SD_ClearRecordingActive();
+					PlayerRecording=-1;
+                   UpdateClientControls();
+                   }
+				}
+			}
+		}
+   }
+
+
+/*
+=============================
+=
+= CheckPlayerSpecials
+=
+=============================
+*/
+
+
+void CheckPlayerSpecials(objtype * ob)
+   {
+	playertype * pstate;
+
+	M_LINKSTATE(ob,pstate);
+
+	// Check for recording of sound
+
+   CheckRemoteRecording(ob,pstate);
+   CheckTemp2Codes(ob,pstate);
+
+	if (ob->flags & FL_DYING)
+	  return;
+
+   CheckSpecialSounds(ob,pstate);
+   CheckProtectionsAndPowerups(ob,pstate);
+   }
+
+#if (SHAREWARE == 0)
+/*
+===============
+=
+= T_DogUse
+=
+===============
+*/
+
+void  T_DogUse (objtype *ob)
+{
+  attack_t   *cur;
+  playertype *pstate;
+  statetype *oldstate;
+
+  M_LINKSTATE(ob,pstate);
+
+  Thrust(ob);
+  oldstate = ob->state;
+  CheckPlayerSpecials(ob);
+  if (ob->state != oldstate)
+    {
+    return;
+    }
+
+
+
+
+//Commented out until we find if it's valid
+/*
+  if (!ob->ticcount)
+	{if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
+		pstate->buttonstate[bt_use] = false;
+	}
+*/
+
+   if (pstate->attackframe >= DOGSCRATCH.numattacks)
+      Error("\n attackframe %d for DOGSCRATCH gt numattacks %d",
+            pstate->attackframe,DOGSCRATCH.numattacks
+           );
+
+
+
+  cur = &(DOGSCRATCH.attackinfo[pstate->attackframe]);
+  if (! pstate->attackcount)
+	 {switch (cur->attack)
+		 {case reset:
+			  {
+           NewState(ob,&s_dogwait);
+           pstate->attackframe = pstate->weaponframe = pstate->batblast = 0;
+			  return;
+			  }
+			  break;
+		  case at_pulltrigger:
+			 pstate->buttonheld[bt_use]=false;
+          Cmd_Use(ob);
+			 break;
+                  default:
+                         break;
+		 }
+	  pstate->attackframe++;
+     cur = &(DOGSCRATCH.attackinfo[pstate->attackframe]);
+     pstate->weaponframe = cur->frame;
+	  pstate->attackcount = cur->mtics;
+
+	 }
+  else
+	  pstate->attackcount --;
+
+
+
+}
+
+/*
+===============
+=
+= T_DogLick
+=
+===============
+*/
+
+
+
+void  T_DogLick (objtype *ob)
+{
+  attack_t   *cur;
+  playertype *pstate;
+  statetype *oldstate;
+
+  M_LINKSTATE(ob,pstate);
+
+  Thrust(ob);
+  oldstate = ob->state;
+  CheckPlayerSpecials(ob);
+  if (ob->state != oldstate)
+    {
+    return;
+    }
+
+
+
+//Commented out until we find if it's valid
+/*
+  if (!ob->ticcount)
+	{if ( pstate->buttonstate[bt_use] && !pstate->buttonheld[bt_use] )
+		pstate->buttonstate[bt_use] = false;
+	}
+*/
+
+
+   if (pstate->attackframe >= DOGLICK.numattacks)
+      Error("\n attackframe %d for DOGLICK gt numattacks %d",
+            pstate->attackframe,DOGLICK.numattacks
+           );
+
+
+  cur = &(DOGLICK.attackinfo[pstate->attackframe]);
+  if (! pstate->attackcount)
+    {if (cur->attack == reset)
+        {
+        NewState(ob,&s_serialdog);
+        pstate->attackframe = pstate->weaponframe = 0;
+        return;
+        }
+	  pstate->attackframe++;
+	  cur = &(DOGLICK.attackinfo[pstate->attackframe]);
+	  pstate->weaponframe = cur->frame;
+	  pstate->attackcount = cur->mtics;
+
+	 }
+  else
+	  pstate->attackcount --;
+
+ //	if ( playerstate.buttonstate[bt_attack] && (!playerstate.buttonheld[bt_attack]) && (!W_CHANGE))
+  //		Cmd_Fire (ob);
+
+
+}
+
+#endif
+
+void T_DeadWait(objtype*ob)
+{
+	playertype *pstate;
+
+   M_LINKSTATE(ob,pstate);
+   if ((ob->flags & FL_DESIGNATED) && (gamestate.battlemode == battle_CaptureTheTriad))
+     {int otherteam = (pstate->team ^ 1);
+
+      ob->flags &= ~FL_DESIGNATED;
+      UpdateKills = true;
+      SpawnStatic(TEAM[otherteam].tilex,TEAM[otherteam].tiley,stat_collector,9);
+		LASTSTAT->flags |= FL_COLORED;
+      LASTSTAT->hitpoints = otherteam;
+      LASTSTAT->flags |= FL_ABP;
+      MakeStatActive(LASTSTAT);
+
+	  }
+   //ob->momentumx=0;
+   //ob->momentumy=0;
+
+	if (pstate->heightoffset<36)
+		{pstate->heightoffset++;
+		 pstate->oldheightoffset = pstate->heightoffset;
+		}
+
+   if (ob==player)
+      {
+      UpdateLightLevel(player->areanumber);
+      if ((pstate->falling==true) || (ob->momentumz==0))
+         {
+         if (BATTLEMODE)
+				playerdead=true;
+         else
+			   playstate = ex_died;
+         }
+		}
+	/*
+   if (BATTLEMODE)
+		{
+		objtype * killer=(objtype *)ob->target;
+
+		dx = killer->x - ob->x;
+		dy = ob->y - killer->y;
+
+		if (dx && dy)
+			ob->angle = atan2_appx (dx,dy);
+		}
+	*/
+	//CheckPlayerSpecials(ob);
+}
+
+/*
+===============
+=
+= T_Player
+=
+===============
+*/
+
+void  T_Player (objtype *ob)
+{
+  playertype *pstate;
+  statetype *oldstate;
+
+#if (SHAREWARE == 0)
+  int eluder;
+#endif
+
+  M_LINKSTATE(ob,pstate);
+
+
+
+#if (SHAREWARE == 0)
+  eluder = ((pstate->weapon == wp_dog) && gamestate.SpawnEluder);
+#endif
+
+  oldstate = ob->state;
+
+  if (ob->flags&FL_DYING)
+	  {
+
+      CheckPlayerSpecials(ob);
+      PlayerMove(ob);
+      if (
+          (pstate->falling==true) ||
+          (
+           (!ob->momentumx) &&
+           (!ob->momentumy) &&
+           (!ob->momentumz) &&
+           (!ob->state->tictime)
+          )
+         )
+		  {
+			KillActor(ob);
+			if (ob->state == &s_remoteguts12)
+           NewState(ob,&s_gutwait);
+			else
+			  NewState(ob,&s_deadwait);
+		  }
+		return;
+	  }
+
+  Thrust(ob);
+  if (ob->flags & FL_DYING)
+    return;
+
+  oldstate = ob->state;
+  CheckPlayerSpecials(ob);
+  if (ob->state != oldstate)
+     {
+     if (ob->flags & FL_DYING)
+        return;
+     }
+
+  if (!(ob->flags & FL_PAIN))
+	 {if (!(ob->state->condition & SF_DOGSTATE))
+		 {if ((ob->momentumx || ob->momentumy) && (ob->state->condition != SF_DOWN))
+			  NewState(ob,&s_remotemove1);
+		  else if (NOMOM && (ob->state != &s_player))
+			  NewState(ob,&s_player);
+		 }
+     else if (NOMOM
+#if (SHAREWARE == 0)
+
+     && (ob->state != &s_dogwait)
+#endif
+
+     )
+
+         NewState(ob,ob->state);
+
+	 }
+  else if (!ob->ticcount)
+    {if (!(ob->state->condition & SF_DOGSTATE))
+		  NewState(ob,&s_player);
+
+	  ob->flags &= ~FL_PAIN;
+
+	 }
+
+  if (ob->flags & FL_DIDTAG)
+	{ob->flags &= ~FL_DIDTAG;
+	 pstate->weapondowntics = (144 - TAGHANDHEIGHT)/GMOVE;
+	}
+
+
+  CheckWeaponStates(ob);
+
+
+  if (ARMED(ob->dirchoosetime)
+     //(gamestate.battlemode != battle_Tag)
+     )
+     {
+     if (pstate->weapondowntics == 1)  // change to up; during change, up and down
+									  // are never zero at the same time
+        {
+        pstate->weapondowntics = 0;
+		  pstate->weaponframe = pstate->attackframe = 0;
+
+		  if (pstate->NETCAPTURED == -1)
+           {
+			  pstate->weaponuptics = FREE.screenheight/GMOVE;
+			  pstate->weaponheight = pstate->weaponuptics*GMOVE ;
+			  pstate->NETCAPTURED = 1;
+  //          return;
+           }
+		  else if (pstate->NETCAPTURED == -2)
+           {
+			  pstate->weaponuptics = WEAPONS[pstate->weapon].screenheight/GMOVE;
+			  pstate->weaponheight = pstate->weaponuptics*GMOVE ;
+			  pstate->NETCAPTURED = 0;
+
+			  //return;
+           }
+		  else
+           {
+           pstate->weaponuptics = WEAPONS[pstate->new_weapon].screenheight/GMOVE;
+           pstate->weapon = pstate->new_weapon;
+
+           pstate->weaponheight = pstate->weaponuptics*GMOVE ;
+			  }
+        }
+
+     else
+        CheckWeaponChange (ob);
+     }
+
+  else if (gamestate.battlemode == battle_Hunter)
+     {
+     if (pstate->weapondowntics == 1)
+
+        {
+        pstate->weapondowntics = 0;
+        pstate->weaponframe = pstate->attackframe = pstate->batblast = 0;
+        pstate->weapon = pstate->new_weapon;
+        }
+     }
+
+//   if ( pstate->buttonstate[bt_use] && (!W_CHANGE(pstate)) )
+
+   if ( pstate->buttonstate[bt_use] )
+      Cmd_Use (ob);
+
+
+	if (W_CHANGE(pstate))
+	  return;
+
+
+
+
+   if ((!ARMED(ob->dirchoosetime))
+#if (SHAREWARE == 0)
+        && (pstate->weapon != wp_dog)
+#endif
+        )
+		return;
+
+	if (pstate->buttonstate[bt_attack])
+      {
+#if (SHAREWARE == 0)
+
+      if (eluder)
+			Cmd_Fire(ob);
+
+      else if ((pstate->weapon == wp_bat) ||
+               (pstate->weapon == wp_dog)
+              )
+         {
+         int oldblast=pstate->batblast;
+
+         pstate->batblast ++;
+
+         if (pstate->weapon==wp_bat)
+            {
+            if (pstate->batblast == 20)
+               SD_PlaySoundRTP(SD_EXCALIBUILDSND,ob->x,ob->y);
+            }
+         else
+            {
+            if ((pstate->batblast>>4)!=(oldblast>>4))
+               {
+               int handle;
+
+               handle=SD_PlaySoundRTP(SD_DOGMODEPREPBLASTSND,ob->x,ob->y);
+               SD_SetSoundPitch(handle,-(BBTIME<<3)+(pstate->batblast<<3));
+               }
+            }
+         if (pstate->batblast < BBTIME)
+			  return;
+
+         if (pstate->weapon == wp_bat)
+				SD_PlaySoundRTP(SD_EXCALIBLASTSND,ob->x,ob->y);
+         else
+            SD_PlaySoundRTP(SD_DOGMODEBLASTSND,ob->x,ob->y);
+         }
+
+      if ((pstate->weapon != wp_split) || (!pstate->buttonheld[bt_attack]))
+#endif
+  //    if (!pstate->buttonheld[bt_attack])
+//#endif
+         {
+
+#if (SHAREWARE == 0)
+
+         if (pstate->weapon == wp_kes)
+			  SD_PlaySoundRTP(SD_GRAVBUILDSND,ob->x,ob->y);
+#endif
+
+			Cmd_Fire (ob);
+         }
+      }
+
+#if (SHAREWARE == 0)
+
+   else if (
+             ((pstate->weapon == wp_bat) ||
+              ((pstate->weapon == wp_dog) && (!eluder))
+             ) &&
+             (pstate->buttonheld[bt_attack])
+           )
+      {
+      if (pstate->weapon == wp_bat)
+         SD_StopSound(SD_EXCALIBUILDSND);
+      pstate->batblast = 0;
+      Cmd_Fire(ob);
+      }
+#endif
+
+}
+
+
+

Added: tags/rott-1.1/rott/rt_playr.h
===================================================================
--- tags/rott-1.1/rott/rt_playr.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_playr.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,295 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//   RT_PLAYR.C - Player movement and stuff
+//
+//***************************************************************************
+
+#ifndef _rt_playr_public
+#define _rt_playr_public
+
+#include "rt_actor.h"
+#include "rt_stat.h"
+#include "states.h"
+#include "rottnet.h"
+#include "rt_battl.h"
+#include "develop.h"
+
+
+
+extern int mouse_ry_input_scale;
+
+#define LOW_GRAVITY    10000
+#define NORMAL_GRAVITY 30000
+#define HIGH_GRAVITY   250000
+#define TAGHANDHEIGHT  40
+
+#define MAXDEAD        32
+#define MAXBULLETS     64
+
+#define MAXCODENAMELENGTH 9
+
+#define ARMED(x)   ( \
+                     (gamestate.PlayerHasGun[x]) || \
+                     (!BATTLEMODE) \
+                   )
+
+
+typedef struct
+    {
+    statetype *state;
+    int       speed;
+    classtype obclass;
+    int       offset;
+    int       flags;
+
+    }missile_stats;
+
+extern missile_stats PlayerMissileData[13];
+
+extern int GetWeaponForItem(int itemnumber);
+extern int GetItemForWeapon(int weapon);
+
+
+typedef enum
+  {reset,
+	reset2,
+	done,
+	at_knife,
+	at_pulltrigger,
+	at_automatic,
+	at_dryheaving,
+	at_missileweapon
+  } attack_action;
+
+
+typedef struct atkinf
+{
+	attack_action attack;
+	char  mtics,frame;      // attack is 1 for gun, 2 for knife, 3 for machine guns,
+											 // 4 for chaingun (orig. game)
+} attack_t;
+
+typedef struct weaptype
+{const int screenheight;
+ int startammo;
+ int base_damage;
+ int impulse;
+ int numattacks;
+ attack_t attackinfo[14];
+}williamdidthis;
+
+//
+// Interactive input status of device, returned by SWIFT_Get3DStatus
+//
+typedef struct {
+   short	x;
+   short	y;
+   short	z;
+   short	pitch;
+   short	roll;
+   short	yaw;
+   short	buttons;
+} SWIFT_3DStatus;
+
+
+//
+// Static data about device, returned by SWIFT_GetStaticDeviceInfo
+//
+typedef struct
+{
+   unsigned char	deviceType;
+   unsigned char	majorVersion;
+	unsigned char	minorVersion;
+   unsigned char	coordDescriptor[6];
+   unsigned char	reserved[1];
+} SWIFT_StaticData;
+
+typedef struct
+{
+        int                lives;
+        int                health;
+        int                triads;
+		  signed char        ammo;
+		  short              poweruptime;
+		  short              protectiontime;
+        int                new_weapon;
+		  int                keys;
+        int                weapon;
+        int                missileweapon;
+        int                bulletweapon;
+		  signed char        HASBULLETWEAPON[3];
+        int                attackframe,attackcount,weaponframe;
+        byte               player;
+        int                topspeed;
+        int                dmomx;
+        int                dmomy;
+		  int                angle;
+		  int                anglefrac;
+        boolean            buttonheld[NUMBUTTONS];
+        boolean            buttonstate[NUMBUTTONS];
+        int                horizon;
+        int                lastmomz;
+		  signed short       playerheight;
+		  signed short       heightoffset;
+		  signed short       weaponheight;
+		  byte               weaponx,weapony;
+		  word               batblast;
+		  signed char        NETCAPTURED;
+		  signed char        HASKNIFE;
+        int                oldweapon, oldmissileweapon;
+		  signed short       weapondowntics,weaponuptics;
+		  int                soundtime;
+        int                healthtime;
+        objtype*           guntarget;
+		  int                targettime;
+//        int                steptime;
+//        int                stepwhich;
+        boolean            falling;
+		  int                oldshapeoffset;
+		  int                uniformcolor;
+        char               codename[MAXCODENAMELENGTH];
+		  int                oldheightoffset;
+        int                team;
+} playertype;
+
+
+typedef struct
+{ int topspeed;
+  int toprunspeed;
+  int hitpoints;
+  int accuracy;
+  int height;
+} ROTTCHARS;
+
+
+#define M_LINKSTATE(x,y) \
+{ y = &PLAYERSTATE[x->dirchoosetime];\
+}
+
+
+extern williamdidthis  DOGSCRATCH;
+extern int        GRAVITY;
+extern int        controlupdatetime;
+extern int        controlupdatestarted;
+extern statobj_t  *DEADPLAYER[MAXDEAD];
+extern int        NUMDEAD;
+extern objtype    *PLAYER[MAXPLAYERS];
+extern objtype    *player;
+extern playertype PLAYERSTATE[MAXPLAYERS],*locplayerstate;
+
+extern ROTTCHARS  characters[5];
+
+extern williamdidthis FREE;
+extern statetype s_player;
+extern williamdidthis WEAPONS[MAXWEAPONS];
+extern boolean cybermanenabled;
+extern boolean spaceballenabled;
+extern boolean SpaceBallPresent;
+extern boolean CybermanPresent;
+extern boolean mouseenabled;
+extern boolean joystickenabled;
+extern boolean joypadenabled;
+extern boolean joystickprogressive;
+extern int joystickport;
+extern int joyxmax, joyymax, joyxmin, joyymin;
+extern int buttonscan[NUMBUTTONS];
+extern int buttonmouse[6];
+extern int buttonjoy[8];
+extern boolean  buttonpoll[NUMBUTTONS];
+extern boolean godmode;
+extern boolean missilecam;
+extern objtype       * missobj;
+extern int lastpolltime;
+
+extern int controlbuf[3];
+extern int buttonbits;
+
+extern int pausedstartedticcount;
+extern boolean RefreshPause;
+
+
+void     PlayNoWaySound(void);
+int      GetBonusTimeForItem(int);
+int      GetRespawnTimeForItem(int);
+int      GetItemForWeapon(int);
+void     SetWhoHaveWeapons(void);
+int      MaxHitpointsForCharacter(playertype*);
+void     RespawnPlayerobj(objtype*);
+void     RevivePlayerobj(int,int,int,objtype*);
+void     OperateElevatorSwitch(objtype*,int,int,int);
+void     ResetPlayerstate(playertype*);
+void     InitializeWeapons(playertype*);
+void     DropWeapon(objtype*ob);
+void     PollKeyboardButtons (void);
+void     PollMouseButtons (void);
+void     PollJoystickButtons (void);
+void     PollKeyboardMove (void);
+void     PollCyberman (void);
+void     PollMouseMove (void);
+void     PollJoystickMove (void);
+void     PollControls (void);
+void     AddDemoCmd (void);
+void     AddRemoteCmd (void);
+void     PlayerSlideMove(objtype * ob);
+void     SpawnSmoke(objtype*);
+void     GetBonus(objtype*,statobj_t*);
+void     SpawnPlayerobj(int,int,int,int);
+void     ClipPlayer(void);
+void     PlayerMove ( objtype * ob );
+void     Cmd_Use(objtype*);
+void     Cmd_Fire (objtype*ob);
+void     SpawnGunSmoke(int x, int y, int z, int angle, int bullethole);
+void     SpawnBlood(objtype * ob, int angle);
+void     SpawnMetalSparks(objtype * ob, int angle);
+void     CheckPlayerSpecials(objtype * ob);
+void     LoadPlayer ( void );
+void     PlayerTiltHead (objtype * ob);
+boolean  InRange (objtype *p, objtype *victim, int distance);
+void     CheckUnPause ( void );
+void     UpdatePlayers ( void );
+void UnTargetActor ( objtype * target );
+
+
+enum
+ { RENORMALIZE = 1,
+	PITFALL,
+	PITRISE,
+	COLUMNCRUSH,
+	GODMODERISE,
+	GODMODEFALL,
+	DOGMODEFALL,
+	DOGMODERISE,
+	STEPUP,
+	STEPDOWN
+ };
+
+extern void ResetWeapons(objtype *);
+extern void SaveWeapons(objtype*);
+
+extern int whichpath;
+extern statobj_t *BulletHoles[MAXBULLETS];
+
+extern boolean vrenabled;
+
+void SetupBulletHoleLink (int num, statobj_t * item);
+
+#endif

Added: tags/rott-1.1/rott/rt_rand.c
===================================================================
--- tags/rott-1.1/rott/rt_rand.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_rand.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,147 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "_rt_rand.h"
+#include "rt_rand.h"
+#include "develop.h"
+#include "rt_util.h"
+#include <time.h>
+
+#if (DEVELOPMENT == 1)
+#include "rt_main.h"
+#endif
+//MED
+#include "memcheck.h"
+
+//****************************************************************************
+//
+// GLOBALS
+//
+//****************************************************************************
+
+static int rndindex;
+static int sndindex = 0;
+
+
+//****************************************************************************
+//
+// GetRandomSeed ()
+//
+//****************************************************************************
+
+int GetRandomSeed ( void )
+{
+   return ( time (NULL) % (SIZE_OF_RANDOM_TABLE) );
+}
+
+//****************************************************************************
+//
+// InitializeRNG ()
+//
+//****************************************************************************
+
+void  InitializeRNG ( void )
+{
+   SetRNGindex(GetRandomSeed());
+   sndindex=GetRandomSeed();
+}
+
+//****************************************************************************
+//
+// SetRNGindex ()
+//
+//****************************************************************************
+
+void  SetRNGindex ( int i )
+{
+   rndindex=i;
+//#if (DEVELOPMENT == 1)
+   SoftError("RNG index set at %d\n",i);
+//#endif
+}
+
+//****************************************************************************
+//
+// GetRNGindex ()
+//
+//****************************************************************************
+
+int GetRNGindex ( void )
+{
+   return rndindex;
+}
+
+
+#if (RANDOMTEST==1)
+//****************************************************************************
+//
+// int GameRNG ( char * string, int val )
+//
+//****************************************************************************
+int   GameRNG ( char * string, int val )
+{
+   rndindex = (rndindex+1)&(SIZE_OF_RANDOM_TABLE-1);
+   SoftError("RNG - num=%3d called from=%s val=%d\n",RandomTable[rndindex],string,val);
+   return RandomTable[rndindex];
+}
+#else
+//****************************************************************************
+//
+// int GameRNG (void)
+//
+//****************************************************************************
+int   GameRNG ( void )
+{
+   rndindex = (rndindex+1)&(SIZE_OF_RANDOM_TABLE-1);
+
+   return RandomTable[rndindex];
+}
+#endif
+
+
+
+#if (RANDOMTEST==1)
+//****************************************************************************
+//
+// int RNG ( char * string, int val )
+//
+//****************************************************************************
+
+int   RNG ( char * string, int val )
+{
+   sndindex = (sndindex+1)&(SIZE_OF_RANDOM_TABLE-1);
+//   SoftError("SRNG - num=%3ld called from=%s val=%ld\n",RandomTable[sndindex],string,val);
+   return RandomTable[sndindex];
+}
+#else
+//****************************************************************************
+//
+// int RNG (void)
+//
+//****************************************************************************
+
+int   RNG( void )
+{
+   sndindex = (sndindex+1)&(SIZE_OF_RANDOM_TABLE-1);
+
+   return RandomTable[sndindex];
+}
+#endif
+

Added: tags/rott-1.1/rott/rt_rand.h
===================================================================
--- tags/rott-1.1/rott/rt_rand.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_rand.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,51 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_rand_public
+#define _rt_rand_public
+
+#include "develop.h"
+
+void  InitializeRNG ( void );
+int   GetRandomSeed ( void );
+
+
+#if RANDOMTEST
+
+int   GameRNG ( char * string, int val );
+#define GameRandomNumber(string,val)   GameRNG(string, val)
+
+int   RNG ( char * string, int val );
+#define RandomNumber(string,val)   RNG(string, val)
+
+#else
+
+int   GameRNG ( void );
+#define GameRandomNumber(string,val)   GameRNG()
+
+int   RNG ( void );
+#define RandomNumber(string,val)   RNG()
+
+#endif
+
+
+
+void  SetRNGindex ( int i );
+int   GetRNGindex ( void );
+#endif

Added: tags/rott-1.1/rott/rt_sc_a.asm
===================================================================
--- tags/rott-1.1/rott/rt_sc_a.asm	                        (rev 0)
+++ tags/rott-1.1/rott/rt_sc_a.asm	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,421 @@
+        .386
+        .MODEL  flat
+
+
+SCREENWIDTH = 96
+
+
+.data
+loopcount       dd      0
+pixelcount      dd      0
+EXTRN   _centery:DWORD
+EXTRN   _centeryclipped:DWORD
+EXTRN   _dc_yl:DWORD
+EXTRN   _dc_yh:DWORD
+EXTRN   _dc_iscale:DWORD
+EXTRN   _dc_texturemid:DWORD
+EXTRN   _ylookup:DWORD
+;EXTRN   _dc_firstsource:DWORD
+EXTRN   _dc_source:DWORD
+EXTRN   _shadingtable:DWORD
+
+.code
+SEGMENT text USE32
+        ALIGN   16
+
+;================
+;
+; R_DrawColumn
+;
+;================
+PROC   R_DrawColumn_
+PUBLIC   R_DrawColumn_
+        push    ebp
+        mov     ebp,[_dc_yl]
+        mov     ebx,ebp
+        add     edi,[_ylookup+ebx*4]
+        mov     eax,[_dc_yh]
+        inc     eax
+        sub     eax,ebp                         ; pixel count
+        mov     [pixelcount],eax                ; save for final pixel
+        js      done                            ; nothing to scale
+        shr     eax,1                           ; double pixel count
+        mov     [loopcount],eax
+
+        mov     ecx,[_dc_iscale]
+
+        mov     eax,[_centery]
+        sub     eax,ebp
+        imul    ecx
+        mov     ebp,[_dc_texturemid]
+        sub     ebp,eax
+
+        mov     esi,[_dc_source]
+
+
+        mov     ebx,[_dc_iscale]
+        mov     eax,OFFSET patch1+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET patch2+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+
+; eax           aligned colormap
+; ebx           aligned colormap
+; ecx,edx       scratch
+; esi           virtual source
+; edi           moving destination pointer
+; ebp           frac
+
+        mov     ecx,ebp                         ; begin calculating first pixel
+        add     ebp,ebx                         ; advance frac pointer
+        shr     ecx,16                          ; finish calculation for first pixel
+        mov     edx,ebp                         ; begin calculating second pixel
+        add     ebp,ebx                         ; advance frac pointer
+        shr     edx,16                          ; finish calculation for second pixel
+        mov     eax,[_shadingtable]
+        mov     ebx,eax
+        ;mov     [_dc_firstsource],esi
+        ;add     [_dc_firstsource],ecx
+        mov     al,[esi+ecx]                    ; get first pixel
+        mov     bl,[esi+edx]                    ; get second pixel
+        mov     al,[eax]                        ; color translate first pixel
+        mov     bl,[ebx]                        ; color translate second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     doubleloop                      ; at least two pixels to map
+        jmp     checklast
+
+        ALIGN   16
+doubleloop:
+        mov     ecx,ebp                         ; begin calculating third pixel
+patch1:
+        add     ebp,12345678h                   ; advance frac pointer
+        mov     [edi],al                        ; write first pixel
+        shr     ecx,16                          ; finish calculation for third pixel
+        mov     edx,ebp                         ; begin calculating fourth pixel
+patch2:
+        add     ebp,12345678h                   ; advance frac pointer
+        mov     [edi+SCREENWIDTH],bl            ; write second pixel
+        shr     edx,16                                      ; finish calculation for fourth pixel
+        mov     al,[esi+ecx]                    ; get third pixel
+        add     edi,SCREENWIDTH*2               ; advance to third pixel destination
+        mov     bl,[esi+edx]                    ; get fourth pixel
+        dec     [loopcount]                     ; done with loop?
+        mov     al,[eax]                        ; color translate third pixel
+        mov     bl,[ebx]                        ; color translate fourth pixel
+        jnz     doubleloop
+
+; check for final pixel
+checklast:
+        test    [pixelcount],1
+        jz      done
+        mov     [edi],al                        ; write final pixel
+done:
+        pop     ebp
+        ret
+
+ENDP
+
+
+;================
+;
+; R_DrawSolidColumn
+;
+;================
+PROC   R_DrawSolidColumn_
+PUBLIC   R_DrawSolidColumn_
+        mov     ecx,[_dc_yl]
+        mov     eax,ecx
+        add     edi,[_ylookup+eax*4]
+        mov     eax,[_dc_yh]
+        inc     eax
+        sub     eax,ecx                         ; pixel count
+        mov     [pixelcount],eax                ; save for final pixel
+        js      soliddone                       ; nothing to scale
+        shr     eax,1                           ; double pixel count
+        mov     [loopcount],eax
+
+        test    [pixelcount],0fffffffeh
+        jnz     soliddoubleloop                      ; at least two pixels to map
+        jmp     solidchecklast
+
+        ALIGN   16
+soliddoubleloop:
+        mov     [edi],bl                        ; write first pixel
+        add     edi,SCREENWIDTH                 ; advance to third pixel destination
+        mov     [edi],bl                        ; write second pixel
+        add     edi,SCREENWIDTH                 ; advance to fourth pixel destination
+        dec     [loopcount]                     ; done with loop?
+        jnz     soliddoubleloop
+
+; check for final pixel
+solidchecklast:
+        test    [pixelcount],1
+        jz      soliddone
+        mov     [edi],bl                        ; write final pixel
+soliddone:
+        ret
+
+ENDP
+
+
+;================
+;
+; R_TransColumn
+;
+;================
+PROC   R_TransColumn_
+PUBLIC   R_TransColumn_
+        mov     ebx,[_dc_yl]
+        mov     eax,[_dc_yh]
+        add     edi,[_ylookup+ebx*4]
+        inc     eax
+        sub     eax,ebx                         ; pixel count
+        mov     [pixelcount],eax                ; save for final pixel
+        js      tdone                           ; nothing to scale
+        shr     eax,1                           ; double pixel count
+        mov     [loopcount],eax
+
+; eax           aligned colormap
+; ebx           aligned colormap
+; esi           moving destination pointer
+; edi           moving destination pointer
+
+        mov     eax,[_shadingtable]
+        mov     esi,edi
+        mov     ebx,eax
+        add     esi,SCREENWIDTH
+        mov     al,[BYTE PTR edi]               ; get first pixel
+        mov     bl,[BYTE PTR esi]               ; get second pixel
+        mov     al,[BYTE PTR eax]               ; color translate first pixel
+        mov     bl,[BYTE PTR ebx]               ; color translate second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     tdoubleloop                     ; at least two pixels to map
+        jmp     tchecklast
+
+        ALIGN   16
+tdoubleloop:
+        mov     [edi],al                        ; write first pixel
+        mov     [esi],bl                        ; write second pixel
+        add     edi,SCREENWIDTH*2               ; advance to third pixel destination
+        add     esi,SCREENWIDTH*2               ; advance to third pixel destination
+        mov     al,[edi]                        ; get third pixel
+        mov     bl,[esi]                        ; get fourth pixel
+        mov     al,[eax]                        ; color translate third pixel
+        dec     [loopcount]                     ; done with loop?
+        mov     bl,[ebx]                        ; color translate fourth pixel
+        jnz     tdoubleloop
+
+; check for final pixel
+tchecklast:
+        test    [pixelcount],1
+        jz      tdone
+        mov     [edi],al                        ; write final pixel
+tdone:
+        ret
+
+ENDP
+
+
+
+
+
+
+
+
+;================
+;
+; R_DrawClippedColumn
+;
+;================
+PROC   R_DrawClippedColumn_
+PUBLIC   R_DrawClippedColumn_
+        push    ebp
+        mov     ebp,[_dc_yl]
+        mov     ebx,ebp
+        add     edi,[_ylookup+ebx*4]
+        mov     eax,[_dc_yh]
+        inc     eax
+        sub     eax,ebp                         ; pixel count
+        mov     [pixelcount],eax                ; save for final pixel
+        js      adone                            ; nothing to scale
+        shr     eax,1                           ; double pixel count
+        mov     [loopcount],eax
+
+        mov     ecx,[_dc_iscale]
+
+        mov     eax,[_centeryclipped]
+        sub     eax,ebp
+        imul    ecx
+        mov     ebp,[_dc_texturemid]
+        sub     ebp,eax
+
+        mov     esi,[_dc_source]
+
+
+        mov     ebx,[_dc_iscale]
+        mov     eax,OFFSET apatch1+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET apatch2+2            ; convice tasm to modify code...
+        mov     [eax],ebx
+
+; eax           aligned colormap
+; ebx           aligned colormap
+; ecx,edx       scratch
+; esi           virtual source
+; edi           moving destination pointer
+; ebp           frac
+
+        mov     ecx,ebp                         ; begin calculating first pixel
+        add     ebp,ebx                         ; advance frac pointer
+        shr     ecx,16                          ; finish calculation for first pixel
+        mov     edx,ebp                         ; begin calculating second pixel
+        add     ebp,ebx                         ; advance frac pointer
+        shr     edx,16                          ; finish calculation for second pixel
+        mov     eax,[_shadingtable]
+        mov     ebx,eax
+        mov     al,[esi+ecx]                    ; get first pixel
+        mov     bl,[esi+edx]                    ; get second pixel
+        mov     al,[eax]                        ; color translate first pixel
+        mov     bl,[ebx]                        ; color translate second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     adoubleloop                     ; at least two pixels to map
+        jmp     achecklast
+
+        ALIGN   16
+adoubleloop:
+        mov     ecx,ebp                         ; begin calculating third pixel
+apatch1:
+        add     ebp,12345678h                   ; advance frac pointer
+        mov     [edi],al                        ; write first pixel
+        shr     ecx,16                          ; finish calculation for third pixel
+        mov     edx,ebp                         ; begin calculating fourth pixel
+apatch2:
+        add     ebp,12345678h                   ; advance frac pointer
+        mov     [edi+SCREENWIDTH],bl            ; write second pixel
+        shr     edx,16                          ; finish calculation for fourth pixel
+        mov     al,[esi+ecx]                    ; get third pixel
+        add     edi,SCREENWIDTH*2               ; advance to third pixel destination
+        mov     bl,[esi+edx]                    ; get fourth pixel
+        dec     [loopcount]                     ; done with loop?
+        mov     al,[eax]                        ; color translate third pixel
+        mov     bl,[ebx]                        ; color translate fourth pixel
+        jnz     adoubleloop
+
+; check for final pixel
+achecklast:
+        test    [pixelcount],1
+        jz      adone
+        mov     [edi],al                                ; write final pixel
+adone:
+        pop     ebp
+        ret
+
+ENDP
+
+
+;================
+;
+; R_DrawWallColumn
+;
+;================
+PROC     R_DrawWallColumn_
+PUBLIC   R_DrawWallColumn_
+        push    ebp
+        mov     ebp,[_dc_yl]
+        mov     ebx,ebp
+        add     edi,[_ylookup+ebx*4]
+        mov     eax,[_dc_yh]
+;        inc     eax
+        sub     eax,ebp                         ; pixel count
+        mov     [pixelcount],eax                ; save for final pixel
+        js      wcdone                            ; nothing to scale
+        shr     eax,1                           ; double pixel count
+        mov     [loopcount],eax
+
+        mov     ecx,[_dc_iscale]
+
+        mov     eax,[_centery]
+        sub     eax,ebp
+        imul    ecx
+        mov     ebp,[_dc_texturemid]
+        sub     ebp,eax
+        shl     ebp,10
+
+        mov     esi,[_dc_source]
+
+
+        mov     ebx,[_dc_iscale]
+        shl     ebx,10
+        mov     eax,OFFSET wcpatch1+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+        mov     eax,OFFSET wcpatch2+2             ; convice tasm to modify code...
+        mov     [eax],ebx
+
+; eax           aligned colormap
+; ebx           aligned colormap
+; ecx,edx       scratch
+; esi           virtual source
+; edi           moving destination pointer
+; ebp           frac
+
+        mov     ecx,ebp                         ; begin calculating first pixel
+        add     ebp,ebx                         ; advance frac pointer
+        shr     ecx,26                          ; finish calculation for first pixel
+        mov     edx,ebp                         ; begin calculating second pixel
+;        and     ecx,63
+        add     ebp,ebx                         ; advance frac pointer
+        shr     edx,26                          ; finish calculation for second pixel
+        mov     eax,[_shadingtable]
+;        and     edx,63
+        mov     ebx,eax
+        mov     al,[esi+ecx]                    ; get first pixel
+        mov     bl,[esi+edx]                    ; get second pixel
+        mov     al,[eax]                        ; color translate first pixel
+        mov     bl,[ebx]                        ; color translate second pixel
+
+        test    [pixelcount],0fffffffeh
+        jnz     wcdoubleloop                      ; at least two pixels to map
+        jmp     wcchecklast
+
+        ALIGN   16
+wcdoubleloop:
+        mov     ecx,ebp                         ; begin calculating third pixel
+wcpatch1:
+        add     ebp,12345678h                   ; advance frac pointer
+        mov     [edi],al                        ; write first pixel
+        shr     ecx,26                          ; finish calculation for third pixel
+        mov     edx,ebp                         ; begin calculating fourth pixel
+;        and     ecx,63
+wcpatch2:
+        add     ebp,12345678h                   ; advance frac pointer
+        mov     [edi+SCREENWIDTH],bl            ; write second pixel
+        shr     edx,26                                      ; finish calculation for fourth pixel
+        mov     al,[esi+ecx]                    ; get third pixel
+;        and     edx,63
+        add     edi,SCREENWIDTH*2               ; advance to third pixel destination
+        mov     bl,[esi+edx]                    ; get fourth pixel
+        dec     [loopcount]                     ; done with loop?
+        mov     al,[eax]                        ; color translate third pixel
+        mov     bl,[ebx]                        ; color translate fourth pixel
+        jnz     wcdoubleloop
+
+; check for final pixel
+wcchecklast:
+        test    [pixelcount],1
+        jz      wcdone
+        mov     [edi],al                        ; write final pixel
+wcdone:
+        pop     ebp
+        ret
+
+ENDP
+
+
+ENDS
+
+
+END
+

Added: tags/rott-1.1/rott/rt_sc_a.h
===================================================================
--- tags/rott-1.1/rott/rt_sc_a.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_sc_a.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,41 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    RT_SC_A.ASM - Low level DrawColumn for masked post
+//
+//***************************************************************************
+
+#ifndef _rt_sc_a_public
+#define _rt_sc_a_public
+
+void R_DrawColumn (byte * buf);
+void R_DrawSolidColumn (int color, byte * buf);
+void R_TransColumn (byte * buf);
+void R_DrawClippedColumn (byte * buf);
+
+#if defined(__WATCOMC__)
+#pragma aux R_DrawColumn parm [EDI] modify exact [eax ebx ecx edx esi edi]
+#pragma aux R_DrawSolidColumn parm [EBX] [EDI]  modify exact [eax ecx edi]
+#pragma aux R_TransColumn parm [EDI] modify exact [eax ebx esi edi]
+#pragma aux R_DrawClippedColumn parm [EDI] modify exact [eax ebx ecx edx esi edi]
+#endif
+
+#endif

Added: tags/rott-1.1/rott/rt_scale.c
===================================================================
--- tags/rott-1.1/rott/rt_scale.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_scale.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1463 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "watcom.h"
+#include <stdio.h>
+#include <string.h>
+
+#ifdef DOS
+#include <malloc.h>
+#include <dos.h>
+#include <conio.h>
+#endif
+
+#include "modexlib.h"
+#include "rt_util.h"
+#include "rt_draw.h"
+#include "rt_scale.h"
+#include "_rt_scal.h"
+#include "rt_sc_a.h"
+#include "engine.h"
+#include "w_wad.h"
+#include "z_zone.h"
+#include "lumpy.h"
+#include "rt_main.h"
+#include "rt_ted.h"
+#include "rt_vid.h"
+#include "rt_view.h"
+#include "rt_playr.h"
+//MED
+#include "memcheck.h"
+
+/*
+=============================================================================
+
+                               GLOBALS
+
+=============================================================================
+*/
+
+// Draw Column vars
+
+int dc_texturemid;
+int dc_iscale;
+int dc_invscale;
+int sprtopoffset;
+int dc_yl;
+int dc_yh;
+//byte * dc_firstsource;
+byte * dc_source;
+int centeryclipped;
+int transparentlevel=0;
+
+/*
+==========================
+=
+= SetPlayerLightLevel
+=
+==========================
+*/
+
+void SetPlayerLightLevel (void)
+{
+   int i;
+   int lv;
+   int intercept;
+   int height;
+
+   whereami=23;
+	if (MISCVARS->GASON==1)
+      {
+		shadingtable=greenmap+(MISCVARS->gasindex<<8);
+      return;
+      }
+
+   if (fulllight || fog)
+      {
+      shadingtable=colormap+(1<<12);
+      return;
+      }
+
+   height=PLAYERHEIGHT;
+
+	if (player->angle < FINEANGLES/8 || player->angle > 7*FINEANGLES/8)
+      intercept=(player->x>>11)&0x1c;
+	else if (player->angle < 3*FINEANGLES/8)
+      intercept=(player->y>>11)&0x1c;
+	else if (player->angle < 5*FINEANGLES/8)
+      intercept=(player->x>>11)&0x1c;
+	else
+      intercept=(player->y>>11)&0x1c;
+
+   if (lightsource)
+      {
+      lv=(((LightSourceAt(player->x>>16,player->y>>16)>>intercept)&0xf)>>1);
+      i=maxshade-(height>>normalshade)-lv;
+      if (i<minshade) i=minshade;
+      shadingtable=colormap+(i<<8);
+      }
+   else
+      {
+      i=maxshade-(height>>normalshade);
+      if (i<minshade) i=minshade;
+      shadingtable=colormap+(i<<8);
+      }
+}
+
+
+
+/*
+==========================
+=
+= SetLightLevel
+=
+==========================
+*/
+
+void SetLightLevel (int height)
+{
+   int i;
+
+   whereami=24;
+	if (MISCVARS->GASON==1)
+		{
+		shadingtable=greenmap+(MISCVARS->gasindex<<8);
+      return;
+      }
+
+   if (fulllight)
+      {
+      shadingtable=colormap+(1<<12);
+      return;
+      }
+   if (fog)
+      {
+      i=(height>>normalshade)+minshade;
+      if (i>maxshade) i=maxshade;
+      shadingtable=colormap+(i<<8);
+      }
+   else
+      {
+      i=maxshade-(height>>normalshade);
+      if (i<minshade) i=minshade;
+      shadingtable=colormap+(i<<8);
+      }
+}
+
+/*
+==========================
+=
+= ScaleTransparentPost
+=
+==========================
+*/
+void ScaleTransparentPost (byte * src, byte * buf, int level)
+{
+   int  offset;
+   int  length;
+   int  topscreen;
+   int  bottomscreen;
+   byte * oldlevel;
+   byte * seelevel;
+#if (DEVELOPMENT == 1)
+   boolean found=false;
+   int  i;
+#endif
+
+   whereami=25;
+#if (DEVELOPMENT == 1)
+   if ((shadingtable>=colormap) && (shadingtable<=(colormap+(31*256))))
+      {
+      found=true;
+      }
+   else if ((shadingtable>=redmap) && (shadingtable<=(redmap+(31*256))))
+      {
+      found=true;
+      }
+   else
+      {
+      for (i=0;i<MAXPLAYERCOLORS;i++)
+         {
+         if ((shadingtable>=playermaps[i]) || (shadingtable<=(playermaps[i]+(31*256))))
+            found=true;
+         }
+      }
+   if (found==false)
+      {
+      Error ("Shadingtable out of range\n");
+      }
+   if ((level<0) || (level>=64))
+      {
+      Error ("translucent level out of range\n");
+      }
+#endif
+
+   seelevel=colormap+(((level+64)>>2)<<8);
+   oldlevel=shadingtable;
+   offset=*(src++);
+   for (;offset!=255;)
+      {
+      length=*(src++);
+      topscreen = sprtopoffset + (dc_invscale*offset);
+      bottomscreen = topscreen + (dc_invscale*length);
+      dc_yl = (topscreen+SFRACUNIT)>>SFRACBITS;
+      dc_yh = ((bottomscreen-1)>>SFRACBITS);
+      if (dc_yh >= viewheight)
+         dc_yh = viewheight-1;
+      if (dc_yl < 0)
+         dc_yl = 0;
+      if ((*src)==254)
+         {
+         shadingtable=seelevel;
+         if (dc_yl <= dc_yh)
+            R_TransColumn (buf);
+         src++;
+         offset=*(src++);
+         shadingtable=oldlevel;
+         }
+      else
+         {
+         if (dc_yl <= dc_yh)
+            {
+            dc_source=src-offset;
+            R_DrawColumn (buf);
+            }
+         src+=length;
+         offset=*(src++);
+         }
+      }
+
+   whereami=-2;
+}
+
+
+void ScaleMaskedPost (byte * src, byte * buf)
+{
+   int  offset;
+   int  length;
+   int  topscreen;
+   int  bottomscreen;
+
+   whereami=26;
+   offset=*(src++);
+   for (;offset!=255;)
+      {
+      length=*(src++);
+      topscreen = sprtopoffset + (dc_invscale*offset);
+      bottomscreen = topscreen + (dc_invscale*length);
+      dc_yl = (topscreen+SFRACUNIT)>>SFRACBITS;
+      dc_yh = ((bottomscreen-1)>>SFRACBITS);
+      if (dc_yh >= viewheight)
+         dc_yh = viewheight-1;
+      if (dc_yl < 0)
+         dc_yl = 0;
+      if (dc_yl <= dc_yh)
+         {
+         dc_source=src-offset;
+         R_DrawColumn (buf);
+#if (DEVELOPMENT == 1)
+//         if (dc_firstsource<src)
+//            SoftError("dc_firstsource=%p src=%p\n",dc_firstsource,src);
+#endif
+         }
+      src+=length;
+      offset=*(src++);
+      }
+}
+
+void ScaleClippedPost (byte * src, byte * buf)
+{
+   int  offset;
+   int  length;
+   int  topscreen;
+   int  bottomscreen;
+
+   whereami=27;
+   offset=*(src++);
+   for (;offset!=255;)
+      {
+      length=*(src++);
+      topscreen = sprtopoffset + (dc_invscale*offset);
+      bottomscreen = topscreen + (dc_invscale*length);
+      dc_yl = (topscreen+SFRACUNIT-1)>>SFRACBITS;
+      dc_yh = ((bottomscreen-1)>>SFRACBITS);
+      if (dc_yh >= viewheight)
+         dc_yh = viewheight-1;
+      if (dc_yl < 0)
+         dc_yl = 0;
+      if (dc_yl <= dc_yh)
+         {
+         dc_source=src-offset;
+         R_DrawClippedColumn (buf);
+         }
+      src+=length;
+      offset=*(src++);
+      }
+}
+
+void ScaleSolidMaskedPost (int color, byte * src, byte * buf)
+{
+   int  offset;
+   int  length;
+   int  topscreen;
+   int  bottomscreen;
+
+   whereami=28;
+   offset=*(src++);
+   for (;offset!=255;)
+      {
+      length=*(src++);
+      topscreen = sprtopoffset + (dc_invscale*offset);
+      bottomscreen = topscreen + (dc_invscale*length);
+      dc_yl = (topscreen+SFRACUNIT)>>SFRACBITS;
+      dc_yh = ((bottomscreen-1)>>SFRACBITS);
+      if (dc_yh >= viewheight)
+         dc_yh = viewheight-1;
+      if (dc_yl < 0)
+         dc_yl = 0;
+      if (dc_yl <= dc_yh)
+         {
+         dc_source=src-offset;
+         R_DrawSolidColumn (color, buf);
+         }
+      src+=length;
+      offset=*(src++);
+      }
+
+}
+
+
+void ScaleTransparentClippedPost (byte * src, byte * buf, int level)
+{
+   int  offset;
+   int  length;
+   int  topscreen;
+   int  bottomscreen;
+   byte * oldlevel;
+   byte * seelevel;
+
+   whereami=29;
+
+   seelevel=colormap+(((level+64)>>2)<<8);
+   oldlevel=shadingtable;
+   offset=*(src++);
+   for (;offset!=255;)
+      {
+      length=*(src++);
+      topscreen = sprtopoffset + (dc_invscale*offset);
+      bottomscreen = topscreen + (dc_invscale*length);
+      dc_yl = (topscreen+SFRACUNIT)>>SFRACBITS;
+      dc_yh = ((bottomscreen-1)>>SFRACBITS);
+      if (dc_yh >= viewheight)
+         dc_yh = viewheight-1;
+      if (dc_yl < 0)
+         dc_yl = 0;
+      if ((*src)==254)
+         {
+         shadingtable=seelevel;
+         if (dc_yl <= dc_yh)
+            R_TransColumn (buf);
+         src++;
+         offset=*(src++);
+         shadingtable=oldlevel;
+         }
+      else
+         {
+         if (dc_yl <= dc_yh)
+            {
+            dc_source=src-offset;
+            R_DrawClippedColumn (buf);
+            }
+         src+=length;
+         offset=*(src++);
+         }
+      }
+
+}
+
+
+void ScaleMaskedWidePost (byte * src, byte * buf, int x, int width)
+{
+#ifdef DOS
+   int  ofs;
+   int  msk;
+
+   whereami=30;
+   buf+=x>>2;
+   ofs=((x&3)<<3)+(x&3)+width-1;
+   VGAMAPMASK(*((byte *)mapmasks1+ofs));
+   ScaleMaskedPost(src,buf);
+   msk=(byte)*((byte *)mapmasks2+ofs);
+   if (msk==0)
+      return;
+   buf++;
+   VGAMAPMASK(msk);
+   ScaleMaskedPost(src,buf);
+   msk=(byte)*((byte *)mapmasks3+ofs);
+   if (msk==0)
+      return;
+   buf++;
+   VGAMAPMASK(msk);
+   ScaleMaskedPost(src,buf);
+#else
+	buf += x;
+	
+	while (width--) {
+		ScaleMaskedPost(src,buf);
+		buf++;
+	}
+#endif
+}
+
+void ScaleClippedWidePost (byte * src, byte * buf, int x, int width)
+{
+#ifdef DOS
+   int  ofs;
+   int  msk;
+
+   whereami=31;
+   buf+=x>>2;
+   ofs=((x&3)<<3)+(x&3)+width-1;
+   VGAMAPMASK(*((byte *)mapmasks1+ofs));
+   ScaleClippedPost(src,buf);
+   msk=(byte)*((byte *)mapmasks2+ofs);
+   if (msk==0)
+      return;
+	buf++;
+   VGAMAPMASK(msk);
+   ScaleClippedPost(src,buf);
+   msk=(byte)*((byte *)mapmasks3+ofs);
+   if (msk==0)
+      return;
+   buf++;
+   VGAMAPMASK(msk);
+   ScaleClippedPost(src,buf);
+#else
+	buf += x;
+	
+	while (width--) {
+		ScaleClippedPost(src,buf);
+		buf++;
+	}
+#endif
+}
+
+
+/*
+=======================
+=
+= ScaleShape
+=
+=======================
+*/
+
+void ScaleShape (visobj_t * sprite)
+{
+   byte *shape;
+   int      frac;
+   patch_t *p;
+   int      x1,x2;
+   int      tx;
+   int      size;
+   int      plane;
+
+   whereami=32;
+   shape=W_CacheLumpNum(sprite->shapenum,PU_CACHE, Cvt_patch_t, 1);
+   p=(patch_t *)shape;
+   size=p->origsize>>7;
+//   sprite->viewheight<<=1;
+   dc_invscale=sprite->viewheight<<((10-HEIGHTFRACTION)-size);
+   tx=-p->leftoffset;
+   sprite->viewx=(sprite->viewx<<SFRACBITS)-(sprite->viewheight<<(SFRACBITS-HEIGHTFRACTION-1))+(SFRACUNIT>>1);
+//
+// calculate edges of the shape
+//
+        x1 = (sprite->viewx+(tx*dc_invscale))>>SFRACBITS;
+        if (x1 >= viewwidth)
+           {
+           return;               // off the right side
+			  }
+        tx+=p->width;
+        x2 = ((sprite->viewx+(tx*dc_invscale)) >>SFRACBITS) - 1 ;
+        if (x2 < 0)
+           {
+           return;         // off the left side
+           }
+
+// dc_iscale=(1<<(16+6+HEIGHTFRACTION+size))/sprite->viewheight;
+   dc_iscale=0xffffffffu/(unsigned)dc_invscale;
+   dc_texturemid=(((sprite->h1<<size) + p->topoffset)<<SFRACBITS);//+(SFRACUNIT>>1);
+   sprtopoffset=centeryfrac -  FixedMul(dc_texturemid,dc_invscale);
+   shadingtable=sprite->colormap;
+
+   if (x1<0)
+      {
+      frac=dc_iscale*(-x1);
+      x1=0;
+      }
+   else
+      frac=0;
+   x2 = x2 >= viewwidth ? viewwidth-1 : x2;
+
+   if (sprite->viewheight>((1<<(HEIGHTFRACTION+6))<<size))
+      {
+      int      texturecolumn;
+      int      lastcolumn;
+      int      startx;
+      int      width;
+
+      width=1;
+      startx=0;
+      lastcolumn=-1;
+      for (; x1<=x2 ; x1++, frac += dc_iscale)
+        {
+         if (posts[x1].wallheight>sprite->viewheight)
+            {
+            if (lastcolumn>=0)
+               {
+               ScaleMaskedWidePost(((p->collumnofs[lastcolumn])+shape),(byte *)bufferofs,startx,width);
+               width=1;
+               lastcolumn=-1;
+               }
+            continue;
+				}
+                texturecolumn = frac>>SFRACBITS;
+         if ((texturecolumn==lastcolumn)&&(width<9))
+            {
+            width++;
+            continue;
+            }
+         else
+            {
+            if (lastcolumn>=0)
+               {
+               ScaleMaskedWidePost(((p->collumnofs[lastcolumn])+shape),(byte *)bufferofs,startx,width);
+               width=1;
+               startx=x1;
+               lastcolumn=texturecolumn;
+               }
+            else
+               {
+               startx=x1;
+               lastcolumn=texturecolumn;
+               }
+            }
+         }
+      if (lastcolumn!=-1)
+         ScaleMaskedWidePost(((p->collumnofs[lastcolumn])+shape),(byte *)bufferofs,startx,width);
+      }
+   else
+      {
+      byte * b;
+      int    startfrac;
+      int    startx;
+
+      startx=x1;
+      startfrac=frac;
+      if (doublestep>1)
+         {
+#ifdef DOS
+         for (plane=startx;plane<startx+4;plane+=2,startfrac+=(dc_iscale<<1))
+#endif
+            {
+            frac=startfrac;
+//   VGAWRITEMAP(plane&3);
+#ifdef DOS
+            for (x1=plane;x1<=x2;x1+=4, frac += (dc_iscale<<2))
+#else
+            for (x1=startx;x1<=x2;x1+=2, frac += (dc_iscale<<1))
+#endif
+               {
+               if (
+                   (posts[x1].wallheight>sprite->viewheight) &&
+                   (posts[x1+1].wallheight>sprite->viewheight)
+                  )
+                  continue;
+               if (x1==viewwidth-1)
+                  ScaleMaskedWidePost(((p->collumnofs[frac>>SFRACBITS])+shape),(byte *)bufferofs,x1,1);
+               else
+                  ScaleMaskedWidePost(((p->collumnofs[frac>>SFRACBITS])+shape),(byte *)bufferofs,x1,2);
+               }
+            }
+         }
+      else
+         {
+#ifdef DOS
+         for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
+#endif
+            {
+            frac=startfrac;
+
+#ifdef DOS
+            b=(byte *)bufferofs+(plane>>2);
+            VGAWRITEMAP(plane&3);
+#else
+            b=(byte *)bufferofs+startx;
+#endif
+
+#ifdef DOS
+            for (x1=plane;x1<=x2;x1+=4, frac += (dc_iscale<<2),b++)
+#else
+            for (x1=startx;x1<=x2;x1++, frac += dc_iscale,b++)
+#endif
+               {
+               if (posts[x1].wallheight>sprite->viewheight)
+                  continue;
+               ScaleMaskedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
+               }
+            }
+         }
+      }
+}
+
+
+/*
+=======================
+=
+= ScaleTranparentShape
+=
+=======================
+*/
+
+void ScaleTransparentShape (visobj_t * sprite)
+{
+   byte *shape;
+   int      frac;
+   transpatch_t *p;
+   int      x1,x2;
+   int      tx;
+   int      size;
+   byte * b;
+   int    startfrac;
+   int    startx;
+   int    plane;
+
+   whereami=33;
+   shape=W_CacheLumpNum(sprite->shapenum,PU_CACHE, Cvt_transpatch_t, 1);
+   p=(transpatch_t *)shape;
+   size=p->origsize>>7;
+   dc_invscale=sprite->viewheight<<((10-HEIGHTFRACTION)-size);
+   tx=-p->leftoffset;
+   sprite->viewx=(sprite->viewx<<SFRACBITS)-(sprite->viewheight<<(SFRACBITS-HEIGHTFRACTION-1));
+//
+// calculate edges of the shape
+//
+        x1 = (sprite->viewx+(tx*dc_invscale))>>SFRACBITS;
+        if (x1 >= viewwidth)
+           {
+           return;               // off the right side
+           }
+        tx+=p->width;
+        x2 = ((sprite->viewx+(tx*dc_invscale)) >>SFRACBITS) - 1 ;
+        if (x2 < 0)
+           {
+           return;         // off the left side
+			  }
+
+//   dc_iscale=(1<<(16+6+HEIGHTFRACTION+size))/sprite->viewheight;
+   dc_iscale=0xffffffffu/(unsigned)dc_invscale;
+   dc_texturemid=(((sprite->h1<<size)+p->topoffset)<<SFRACBITS);//+(SFRACUNIT>>1);
+   sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
+   shadingtable=sprite->colormap;
+
+   if (x1<0)
+      {
+      frac=dc_iscale*(-x1);
+      x1=0;
+      }
+   else
+      frac=0;
+   x2 = x2 >= viewwidth ? viewwidth-1 : x2;
+
+#if 0
+   for (; x1<=x2 ; x1++, frac += dc_iscale)
+      {
+      if (posts[x1].wallheight>sprite->viewheight)
+         continue;
+      VGAWRITEMAP(x1&3);
+      VGAREADMAP(x1&3);
+      ScaleTransparentPost(((p->collumnofs[frac>>SFRACBITS])+shape),(byte *)bufferofs+(x1>>2),sprite->h2);
+      }
+#endif
+   startx=x1;
+   startfrac=frac;
+
+#ifdef DOS
+   for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
+#endif
+
+      {
+      frac=startfrac;
+
+#ifdef DOS
+      b=(byte *)bufferofs+(plane>>2);
+      VGAWRITEMAP(plane&3);
+      VGAREADMAP(plane&3);
+#else
+     b=(byte *)bufferofs+startx;
+#endif
+
+#ifdef DOS
+      for (x1=plane;x1<=x2;x1+=4, frac += (dc_iscale<<2),b++)
+#else
+      for (x1=startx;x1<=x2;x1++, frac += dc_iscale,b++)
+#endif
+         {
+         if (posts[x1].wallheight>sprite->viewheight)
+            continue;
+         ScaleTransparentPost(((p->collumnofs[frac>>SFRACBITS])+shape),b,sprite->h2);
+         }
+      }
+}
+
+/*
+=======================
+=
+= ScaleSolidShape
+=
+=======================
+*/
+
+void ScaleSolidShape (visobj_t * sprite)
+{
+   byte *shape;
+   int      frac;
+   patch_t *p;
+   int      x1,x2;
+   int      tx;
+   int      size;
+   int      plane;
+	byte * b;
+   int    startfrac;
+   int    startx;
+
+   whereami=34;
+   shape=W_CacheLumpNum(sprite->shapenum,PU_CACHE, Cvt_patch_t, 1);
+   p=(patch_t *)shape;
+   size=p->origsize>>7;
+   dc_invscale=sprite->viewheight<<((10-HEIGHTFRACTION)-size);
+   tx=-p->leftoffset;
+   sprite->viewx=(sprite->viewx<<SFRACBITS)-(sprite->viewheight<<(SFRACBITS-HEIGHTFRACTION-1))+(SFRACUNIT>>1);
+//
+// calculate edges of the shape
+//
+        x1 = (sprite->viewx+(tx*dc_invscale))>>SFRACBITS;
+        if (x1 >= viewwidth)
+           {
+           return;               // off the right side
+           }
+        tx+=p->width;
+        x2 = ((sprite->viewx+(tx*dc_invscale)) >>SFRACBITS) - 1 ;
+        if (x2 < 0)
+           {
+           return;         // off the left side
+           }
+
+//   dc_iscale=(1<<(16+6+HEIGHTFRACTION+size))/sprite->viewheight;
+   dc_iscale=0xffffffffu/(unsigned)dc_invscale;
+   dc_texturemid=(((sprite->h1<<size)+p->topoffset)<<SFRACBITS);//+(SFRACUNIT>>1);
+   sprtopoffset=centeryfrac - FixedMul(dc_texturemid,dc_invscale);
+   shadingtable=sprite->colormap;
+
+   if (x1<0)
+      {
+      frac=dc_iscale*(-x1);
+      x1=0;
+      }
+   else
+      frac=0;
+   x2 = x2 >= viewwidth ? viewwidth-1 : x2;
+
+   startx=x1;
+   startfrac=frac;
+
+#ifdef DOS
+   for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
+#endif
+   
+      {
+		frac=startfrac;
+
+#ifdef DOS
+      b=(byte *)bufferofs+(plane>>2);
+      VGAWRITEMAP(plane&3);
+#else
+      b=(byte *)bufferofs+startx;
+#endif
+
+#ifdef DOS
+      for (x1=plane;x1<=x2;x1+=4, frac += (dc_iscale<<2),b++)
+#else
+      for (x1=startx;x1<=x2;x1++, frac += dc_iscale,b++)
+#endif
+         {
+         if (posts[x1].wallheight>sprite->viewheight)
+            continue;
+         ScaleSolidMaskedPost(sprite->h2,((p->collumnofs[frac>>SFRACBITS])+shape),b);
+         }
+      }
+}
+
+
+/*
+=======================
+=
+= ScaleWeapon
+=
+=======================
+*/
+
+void ScaleWeapon (int xoff, int y, int shapenum)
+{
+	byte *shape;
+	int      frac;
+	int      h;
+	patch_t *p;
+	int      x1,x2;
+	int      tx;
+	int      xcent;
+	byte * b;
+	int    startfrac;
+	int    startx;
+   int    plane;
+
+   whereami=35;
+   SetPlayerLightLevel();
+   shape=W_CacheLumpNum(shapenum,PU_CACHE, Cvt_patch_t, 1);
+   p=(patch_t *)shape;
+   h=((p->origsize*weaponscale)>>17);
+   centeryclipped=(viewheight-h)+FixedMul(y,weaponscale);
+   xcent=centerx+FixedMul(xoff,weaponscale);
+   dc_invscale=(h<<17)/p->origsize;
+
+	tx=-p->leftoffset;
+	xcent=(xcent<<SFRACBITS)-(h<<SFRACBITS);
+//
+// calculate edges of the shape
+//
+		  x1 = (xcent+(tx*dc_invscale))>>SFRACBITS;
+		  if (x1 >= viewwidth)
+					 return;               // off the right side
+        tx+=p->width;
+        x2 = ((xcent+(tx*dc_invscale)) >>SFRACBITS) - 1 ;
+        if (x2 < 0)
+                return;         // off the left side
+
+   dc_iscale=0xffffffffu/(unsigned)dc_invscale;
+   dc_texturemid=(((p->origsize>>1)+p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
+   sprtopoffset=(centeryclipped<<16) - FixedMul(dc_texturemid,dc_invscale);
+
+//
+// store information in a vissprite
+//
+   if (x1<0)
+		{
+      frac=dc_iscale*(-x1);
+      x1=0;
+      }
+   else
+      frac=0;
+
+   x2 = x2 >= viewwidth ? viewwidth-1 : x2;
+
+	startx=x1;
+	startfrac=frac;
+
+#ifdef DOS
+   for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
+#endif
+      {
+      frac=startfrac;
+#ifdef DOS
+      b=(byte *)bufferofs+(plane>>2);
+#else
+      b=(byte *)bufferofs+startx;
+#endif
+      VGAWRITEMAP(plane&3);
+#ifdef DOS
+      for (x1=plane; x1<=x2 ; x1+=4, frac += dc_iscale<<2,b++)
+#else
+      for (x1=startx; x1<=x2 ; x1++, frac += dc_iscale,b++)
+#endif
+         ScaleClippedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
+      }
+}
+
+
+
+
+/*
+=======================
+=
+= DrawUnScaledSprite
+=
+=======================
+*/
+
+void DrawUnScaledSprite (int x, int y, int shapenum, int shade)
+{
+   byte *shape;
+   int      frac;
+   patch_t *p;
+   int      x1,x2;
+   int      tx;
+   int      xcent;
+   byte * b;
+   int    startfrac;
+   int    startx;
+	int    plane;
+        
+   whereami=36;
+   shadingtable=colormap+(shade<<8);
+   centeryclipped=y;
+   xcent=x;
+   shape=W_CacheLumpNum(shapenum,PU_CACHE, Cvt_patch_t, 1);
+   p=(patch_t *)shape;
+	dc_invscale=0x10000;
+
+   tx=-p->leftoffset;
+   xcent-=p->origsize>>1;
+//
+// calculate edges of the shape
+//
+		  x1 = xcent+tx;
+		  if (x1 >= viewwidth)
+					 return;               // off the right side
+		  tx+=p->width;
+		  x2 = xcent+tx - 1;
+		  if (x2 < 0)
+					 return;         // off the left side
+
+	dc_iscale=0x10000;
+   dc_texturemid=(((p->height>>1)+p->topoffset)<<SFRACBITS);//+(SFRACUNIT>>1);
+	sprtopoffset=(centeryclipped<<16) - dc_texturemid;
+
+//
+// store information in a vissprite
+//
+   if (x1<0)
+      {
+      frac=dc_iscale*(-x1);
+      x1=0;
+      }
+   else
+      frac = 0;
+
+   x2 = x2 >= viewwidth ? viewwidth-1 : x2;
+
+   startx=x1;
+   startfrac=frac;
+
+#ifdef DOS
+   for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
+#endif
+
+		{
+		frac=startfrac;
+
+#ifdef DOS
+		b=(byte *)bufferofs+(plane>>2);
+      VGAWRITEMAP(plane&3);
+#else
+                b=(byte *)bufferofs+startx;
+#endif
+
+#ifdef DOS
+		for (x1=plane; x1<=x2 ; x1+=4, frac += dc_iscale<<2,b++)
+#else
+		for (x1=startx; x1<=x2 ; x1++, frac += dc_iscale,b++)
+#endif
+			ScaleClippedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
+		}
+}
+
+
+/*
+=======================
+=
+= DrawScreenSprite
+=
+=======================
+*/
+
+void DrawScreenSprite (int x, int y, int shapenum)
+{
+   whereami=37;
+	ScaleWeapon (x-160, y-200, shapenum);
+}
+
+/*
+=======================
+=
+= DrawPositionedScaledSprite
+=
+=======================
+*/
+
+void DrawPositionedScaledSprite (int x, int y, int shapenum, int height, int type)
+{
+	byte *shape;
+	int      frac;
+	patch_t *p;
+	transpatch_t *tp;
+	int      x1,x2;
+	int      tx;
+	int      xcent;
+	byte * b;
+	int    startfrac;
+	int    startx;
+	int    plane;
+	int    size;
+
+   whereami=38;
+   shadingtable=colormap+(1<<12);
+	centeryclipped=y;
+	xcent=x;
+	shape=W_CacheLumpNum(shapenum,PU_CACHE, Cvt_patch_t, 1); // was transpatch, fixed
+	p=(patch_t *)shape;
+	tp=(transpatch_t *)shape;
+
+	size=p->origsize>>7;
+	dc_invscale=height<<(10-size);
+
+	tx=-p->leftoffset;
+	xcent=(xcent<<SFRACBITS)-(height<<(SFRACBITS-1));
+
+//
+// calculate edges of the shape
+//
+		  x1 = (xcent+(tx*dc_invscale))>>SFRACBITS;
+		  if (x1 >= viewwidth)
+					 return;               // off the right side
+		  tx+=p->width;
+		  x2 = ((xcent+(tx*dc_invscale)) >>SFRACBITS) - 1 ;
+		  if (x2 < 0)
+					 return;         // off the left side
+
+   dc_iscale=0xffffffffu/(unsigned)dc_invscale;
+//   dc_iscale=(1<<(16+6+size))/height;
+   dc_texturemid=(((32<<size)+p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
+   sprtopoffset=(centeryclipped<<16) - FixedMul(dc_texturemid,dc_invscale);
+
+//
+// store information in a vissprite
+//
+   if (x1<0)
+      {
+      frac=dc_iscale*(-x1);
+      x1=0;
+      }
+   else
+      frac=0;
+
+   x2 = x2 >= viewwidth ? viewwidth-1 : x2;
+
+	startx=x1;
+   startfrac=frac;
+
+#ifdef DOS
+   for (plane=startx;plane<startx+4;plane++,startfrac+=dc_iscale)
+#endif
+
+      {
+      frac=startfrac;
+
+#ifdef DOS
+      b=(byte *)bufferofs+(plane>>2);
+      VGAWRITEMAP(plane&3);
+      VGAREADMAP(plane&3);
+#else
+      b=(byte *)bufferofs+startx;
+#endif
+
+#ifdef DOS
+      for (x1=plane; x1<=x2 ; x1+=4, frac += dc_iscale<<2,b++)
+#else
+      for (x1=startx; x1<=x2 ; x1++, frac += dc_iscale,b++)
+#endif
+         if (type==0)
+            ScaleClippedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
+         else
+				ScaleTransparentClippedPost(((tp->collumnofs[frac>>SFRACBITS])+shape),b,transparentlevel);
+		}
+}
+
+
+/*
+=================
+=
+= DrawScreenSizedSprite
+=
+=================
+*/
+extern int G_gmasklump;
+void DrawScreenSizedSprite (int lump)
+{
+	//draws gasmask among other things zxcv
+   byte *shape,*src;
+   int      frac;
+   patch_t *p;
+   int      x1,x2;
+   int      tx;
+//   int      plane;
+   byte * b;
+   int    startfrac;
+
+   int  offset;
+   int  length;
+   int  topscreen;
+   int  bottomscreen;
+   byte  *cnt,*Ycnt;
+
+  // SetTextMode (  );
+   whereami=39;
+   shadingtable=colormap+(1<<12);
+   shape=W_CacheLumpNum(lump,PU_CACHE, Cvt_patch_t, 1);
+   p=(patch_t *)shape;
+   dc_invscale=(viewwidth<<16)/p->origsize;
+   tx=-p->leftoffset;
+   centeryclipped=viewheight>>1;
+   //centeryclipped=(viewheight>>1)+43;
+//
+// calculate edges of the shape
+//
+        x1 = (tx*dc_invscale)>>SFRACBITS;
+        if (x1 >= viewwidth)
+           {
+           return;               // off the right side
+			  }
+        tx+=p->width;
+        x2 = ((tx*dc_invscale) >>SFRACBITS) - 1 ;
+        if (x2 < 0)
+           {
+           return;         // off the left side
+           }
+
+   dc_iscale=0xffffffffu/(unsigned)dc_invscale;
+   dc_texturemid=(((p->origsize>>1) + p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
+   sprtopoffset=(centeryclipped<<16) -  FixedMul(dc_texturemid,dc_invscale);
+
+   x2 = (viewwidth-1);
+
+   startfrac=0;
+
+      {
+      frac=startfrac;
+      b=(byte *)bufferofs;
+
+	  /////////////  BNA PATCH //////////////////////////////////////////////////////////
+	     //gmasklump=W_GetNumForName("p_gmask"); //=783
+	     //perhaps I should have painted the mask in a seperate buffer
+	     //and streched it and copyet it back, but that would demand
+	     //a new buffer (size=800x600) and slowed the game down so ?
+
+		 // if its the gasmask, paint black patches at hires
+		 if ((lump == G_gmasklump)&&(iGLOBAL_SCREENWIDTH>320)) { 
+			src = ((p->collumnofs[frac>>SFRACBITS])+shape);
+			offset=*(src++);
+			length=*(src++);
+			topscreen = sprtopoffset + (dc_invscale*offset);
+			bottomscreen = topscreen + (dc_invscale*length);
+			dc_yl = (topscreen+SFRACUNIT-1)>>SFRACBITS;//=41  viewheight=584
+			dc_yh = ((bottomscreen-1)>>SFRACBITS);//=540      viewwidth =800
+			//paint upper black patch in gasmask
+			for (cnt=b;cnt<b+viewwidth;cnt++){
+				for (Ycnt=cnt;Ycnt<cnt+(dc_yl*iGLOBAL_SCREENWIDTH);Ycnt+=iGLOBAL_SCREENWIDTH){
+				 *Ycnt = 36;
+				}
+			}
+			//paint lower black patch in gasmask
+			for (cnt=b+(dc_yh*iGLOBAL_SCREENWIDTH);cnt<b+(dc_yh*iGLOBAL_SCREENWIDTH)+viewwidth;cnt++){
+				for (Ycnt=cnt;Ycnt<b+(viewheight*iGLOBAL_SCREENWIDTH);Ycnt+=iGLOBAL_SCREENWIDTH){
+				 *Ycnt = 36;
+				}
+			}
+		 }
+      ///////////////////////////////////////////////////////////////////////////////////
+      for (x1=0;x1<=x2;x1++, frac += dc_iscale,b++)
+
+         {
+             ScaleClippedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
+         }
+      }
+}
+
+#if 0
+   byte *shape;
+   int      frac;
+   patch_t *p;
+   int      x1,x2;
+   int      tx;
+   int      xdc_invscale;
+   int      xdc_iscale;
+   byte *   buf;
+   byte *   b;
+   int      plane;
+   int      startx,startfrac;
+
+   whereami=39;
+   SetPlayerLightLevel();
+   buf=(byte *)bufferofs;
+   shape=W_CacheLumpNum(lump,PU_CACHE);
+   p=(patch_t *)shape;
+   dc_invscale=(viewheight<<16)/200;
+	xdc_invscale=(viewwidth<<16)/320;
+
+   tx=-p->leftoffset;
+   centeryclipped=viewheight>>1;
+//
+// calculate edges of the shape
+//
+        x1 = (tx*xdc_invscale)>>SFRACBITS;
+        if (x1 >= viewwidth)
+                return;               // off the right side
+        tx+=p->width;
+        x2 = ((tx*xdc_invscale)>>SFRACBITS) - 1 ;
+		  if (x2 < 0)
+                return;         // off the left side
+
+   dc_iscale=(200*65536)/viewheight;
+   xdc_iscale=(320*65536)/viewwidth;
+   dc_texturemid=(((p->height>>1)+p->topoffset)<<SFRACBITS)+(SFRACUNIT>>1);
+   sprtopoffset=(centeryclipped<<16) - FixedMul(dc_texturemid,dc_invscale);
+
+//
+// store information in a vissprite
+//
+   if (x1<0)
+      {
+      frac=xdc_iscale*(-x1);
+      x1=0;
+      }
+   else
+      frac=0;
+        x2 = x2 >= viewwidth ? viewwidth-1 : x2;
+
+   startx=x1;
+   startfrac=frac;
+   for (plane=startx;plane<startx+4;plane++,startfrac+=xdc_iscale)
+      {
+      frac=startfrac;
+      b=(byte *)bufferofs+(plane>>2);
+      VGAWRITEMAP(plane&3);
+      for (x1=plane; x1<=x2 ; x1+=4, frac += xdc_iscale<<2,b++)
+         ScaleClippedPost(((p->collumnofs[frac>>SFRACBITS])+shape),b);
+      }
+}
+#endif
+
+
+
+//******************************************************************************
+//
+// DrawNormalPost
+//
+//******************************************************************************
+
+void DrawNormalPost (byte * src, byte * buf)
+{
+   int  offset;
+   int  length;
+   int  s;
+
+   whereami=40;
+
+   while (1)
+      {
+      offset=*(src++);
+      if (offset==0xff)
+         return;
+      else
+         {
+            length=*(src++);
+            for (s=0;s<length;s++) {
+                // Spaced out a little for tracking a bug. Should be equivalent.
+                byte *saddr = src+s;
+                byte *daddr = buf + ylookup[offset + s];
+                byte val = *saddr;
+                *daddr = val;
+//                *(buf+ylookup[offset+s])=*(src+s);
+            }
+            src+=length;
+         }
+      }
+}
+
+
+
+//******************************************************************************
+//
+// DrawNormalSprite
+//
+//******************************************************************************
+
+void DrawNormalSprite (int x, int y, int shapenum)
+{
+   byte *buffer;
+   int cnt;
+   byte *shape;
+   patch_t *p;
+   int plane;
+   byte * b;
+   int startx;
+
+   whereami=41;
+
+   shape = W_CacheLumpNum (shapenum, PU_CACHE, Cvt_patch_t, 1);
+   p = (patch_t *)shape;
+
+   if (((x-p->leftoffset)<0) || ((x-p->leftoffset+p->width)>iGLOBAL_SCREENWIDTH))
+      Error ("DrawNormalSprite: x is out of range x=%d\n",x-p->leftoffset+p->width);
+   if (((y-p->topoffset)<0) || ((y-p->topoffset+p->height)>iGLOBAL_SCREENHEIGHT))
+      Error ("DrawNormalSprite: y is out of range y=%d\n",y-p->topoffset+p->height);
+
+   startx=x-p->leftoffset;
+   buffer = (byte*)bufferofs+ylookup[y-p->topoffset];
+
+#ifdef DOS
+   for (plane=startx;plane<startx+4;plane++)
+#endif
+      {
+#ifdef DOS
+      b=buffer+(plane>>2);
+      VGAWRITEMAP(plane&3);
+#else
+      b=buffer+startx; 
+#endif
+     
+#ifdef DOS 
+      for (cnt = plane-startx; cnt < p->width; cnt+=4,b++)
+#else
+      for (cnt = 0; cnt < p->width; cnt++,b++)
+#endif
+         DrawNormalPost ((byte *)(p->collumnofs[cnt]+shape), b);
+      }
+}
+
+#ifndef DOS
+
+void R_DrawColumn (byte * buf)
+{
+	// This is *NOT* 100% correct - DDOI
+	int count;
+	int frac, fracstep;
+	byte *dest;
+
+	count = dc_yh - dc_yl + 1;
+	if (count < 0) return;
+
+	dest = buf + ylookup[dc_yl];
+
+	fracstep = dc_iscale;
+	frac = dc_texturemid + (dc_yl-centery)*fracstep;
+
+	while (count--) {
+		//*dest = test++;
+		*dest = shadingtable[dc_source[(frac>>SFRACBITS)]];
+		dest += iGLOBAL_SCREENWIDTH;
+		frac += fracstep;
+	}
+}
+
+void R_TransColumn (byte * buf)
+{
+	int count;
+	byte *dest;
+
+	count = dc_yh - dc_yl + 1;
+	if (count < 0) return;
+
+	dest = buf + ylookup[dc_yl];
+
+	while (count--)
+	{
+		*dest = shadingtable[*dest];
+		dest += iGLOBAL_SCREENWIDTH;
+	}
+}
+
+void R_DrawWallColumn (byte * buf)
+{
+	// This is *NOT* 100% correct - DDOI
+	int count;
+	int frac, fracstep;
+	byte *dest;
+
+	count = dc_yh - dc_yl;
+	if (count < 0) return;
+
+	dest = buf + ylookup[dc_yl];
+
+	fracstep = dc_iscale;
+	frac = dc_texturemid + (dc_yl-centery)*fracstep;
+	frac <<= 10;
+	fracstep <<= 10;
+
+	while (count--) {
+		//*dest = 6;
+		*dest = shadingtable[dc_source[(((unsigned)frac)>>26)]];
+		dest += iGLOBAL_SCREENWIDTH;
+		frac += fracstep;
+	}
+}
+
+void R_DrawClippedColumn (byte * buf)
+{
+	// This is *NOT* 100% correct - DDOI zxcv
+	int count;
+	int frac, fracstep;
+	byte *dest;
+//		byte *b;int y;
+
+	count = dc_yh - dc_yl + 1;
+	if (count < 0) return;
+
+   dest = buf + ylookup[dc_yl];
+
+
+	fracstep = dc_iscale;
+	frac = dc_texturemid + (dc_yl-centeryclipped)*fracstep;
+
+	while (count--) {
+		*dest = shadingtable[dc_source[(((unsigned)frac)>>SFRACBITS)]];
+		dest += iGLOBAL_SCREENWIDTH;
+		frac += fracstep;
+	}
+}
+
+void R_DrawSolidColumn (int color, byte * buf)
+{
+	int count;
+	int frac, fracstep;
+	byte *dest;
+
+	count = dc_yh - dc_yl + 1;
+	if (count < 0) return;
+
+	dest = buf + ylookup[dc_yl];
+
+	while (count--)
+	{
+		*dest = (byte)color;
+		dest += iGLOBAL_SCREENWIDTH;
+	}
+}
+
+#endif

Added: tags/rott-1.1/rott/rt_scale.h
===================================================================
--- tags/rott-1.1/rott/rt_scale.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_scale.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,53 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    RT_SCALE.H - Scale-o-rama
+//
+//***************************************************************************
+#ifndef _rt_scale_public
+#define _rt_scale_public
+
+#include "rt_draw.h"
+
+extern  int dc_texturemid;
+extern  int dc_iscale;
+extern  int dc_invscale;
+extern  int centeryclipped;
+extern  int sprtopoffset;
+extern  int dc_yl;
+extern  int dc_yh;
+extern  byte * dc_source;
+extern  int transparentlevel;
+
+void ScaleShape (visobj_t * vis);
+void ScaleWeapon (int xcent, int yoffset, int shapenum);
+void DrawScreenSprite (int x, int y, int shapenum);
+void SetLightLevel (int height);
+void ScaleMaskedPost (byte * src, byte * buf);
+void DrawScreenSizedSprite (int lump);
+void ScaleTransparentPost (byte * src, byte * buf, int level);
+void ScaleTransparentShape (visobj_t * sprite);
+void ScaleSolidShape (visobj_t * sprite);
+void DrawUnScaledSprite (int x, int y, int shapenum, int shade);
+void DrawPositionedScaledSprite (int x, int y, int shapenum, int height, int type);
+void DrawNormalSprite (int x, int y, int shapenum);
+
+#endif

Added: tags/rott-1.1/rott/rt_sound.c
===================================================================
--- tags/rott-1.1/rott/rt_sound.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_sound.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1548 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "rt_sound.h"
+#include "_rt_soun.h"
+#include "fx_man.h"
+#include "music.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "rt_main.h"
+#include "rt_ted.h"
+#include "rt_menu.h"
+#include "rt_playr.h"
+#include "rt_util.h"
+#include "rt_rand.h"
+#include "watcom.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#if PLATFORM_DOS
+#include <mem.h>
+#include <io.h>
+#elif PLATFORM_UNIX
+#include <unistd.h>
+#endif
+
+#include "rt_cfg.h"
+#include "isr.h"
+#include "develop.h"
+#include "rt_net.h"
+
+#include "rt_str.h"
+
+#if (SHAREWARE==0)
+#include "snd_reg.h"
+#else
+#include "snd_shar.h"
+#endif
+//MED
+#include "memcheck.h"
+
+// Local Variables
+
+static int soundstart;
+static int soundtype;
+int SD_Started=false;
+static boolean PositionStored=false;
+static int NumBadSounds=0;
+static int remotestart;
+static boolean SoundsRemapped = false;
+
+#ifdef DOS
+int musicnums[ 11 ] = {
+   -1, UltraSound, SoundBlaster, SoundMan16, ProAudioSpectrum,
+   Awe32, SoundScape, WaveBlaster, GenMidi, SoundCanvas, Adlib
+   };
+
+int fxnums[ 11 ] = {
+   -1, UltraSound, SoundBlaster, SoundMan16, ProAudioSpectrum,
+   Awe32, SoundScape, Adlib, SoundSource, TandySoundSource, PC
+   };
+#else
+int musicnums[ 11 ] = {
+   -1, -1, -1, -1, -1, -1, SoundScape, -1, -1, -1, -1
+   };
+
+int fxnums[ 11 ] = {
+   -1, -1, -1, -1, -1, -1, SoundScape, -1, -1, -1, -1
+   };
+#endif
+
+#if 0
+void MU_SetupGUSInitFile( void );
+#endif
+
+int MUSIC_GetPosition( void ) {
+   songposition pos;
+
+   MUSIC_GetSongPosition( &pos );
+   return pos.milliseconds;
+}
+
+void MUSIC_SetPosition( int time ) {
+   MUSIC_SetSongTime( ( unsigned long )time );
+}
+
+
+//***************************************************************************
+//
+// SoundNumber
+//
+//***************************************************************************
+
+int SoundNumber ( int x )
+{
+   if ((x>=SD_REMOTEM1SND) && (x<=SD_REMOTEM10SND))
+      return remotestart + x - SD_REMOTEM1SND;
+//      sounds[x].snds[soundtype]+remotestart;
+   else
+      return sounds[x].snds[soundtype]+soundstart;
+}
+
+
+//***************************************************************************
+//
+// SD_MakeCacheable - Make a sound that has just finished playing cacheable again
+//
+//***************************************************************************
+void SD_MakeCacheable( unsigned long sndnum )
+{
+   if (sndnum == (unsigned long) -1)
+      {
+      return;
+      }
+
+   if (sndnum>=MAXSOUNDS)
+      {
+      SoftError ("Illegal sound value in SD_MakeCacheable value=%ld\n",sndnum);
+      return;
+      }
+   sounds[sndnum].count--;
+   if (sounds[sndnum].count>0)
+      return;
+   else
+      W_CacheLumpNum(SoundNumber(sndnum),PU_CACHE, CvtNull, 1);
+}
+
+#if 0
+//***************************************************************************
+//
+// SD_PrintActive
+//
+//***************************************************************************
+void SD_PrintActive ( void )
+{
+   int i;
+
+   myprintf("Active Sounds\n");
+   for (i=0;i<MAXSOUNDS;i++)
+      {
+      if (sounds[i].count>0)
+         {
+         myprintf("sound active #%ld\n",i);
+         }
+      }
+}
+#endif
+
+//***************************************************************************
+//
+// SD_SetupFXCard - Initialize sound Tables and start up sound card
+//
+//***************************************************************************
+
+int SD_SetupFXCard ( int * numvoices, int * numbits, int * numchannels)
+{
+   fx_device device;
+   int status;
+   int card;
+
+   if (SD_Started==true)
+      SD_Shutdown();
+
+   if ( ( FXMode < 0 ) || ( FXMode >= 11 ) )
+      {
+      return( 0 );
+      }
+
+   card = fxnums[ FXMode ];
+   if (card==-1) // Check if it is off
+      return (0);
+#ifdef DOS
+   if ( ( card == SoundBlaster ) || ( card == Awe32 ) )
+      {
+      extern fx_blaster_config SBSettings;
+
+      status = FX_SetupSoundBlaster( SBSettings, numvoices,
+         numbits, numchannels );
+      }
+   else
+      {
+#endif
+      status=FX_SetupCard( card, &device );
+      if ( status == FX_Ok )
+         {
+         *numvoices=device.MaxVoices;
+         *numbits=device.MaxSampleBits;
+         *numchannels=device.MaxChannels;
+         }
+#ifdef DOS
+      }
+#endif
+
+   return (status);
+   }
+
+//***************************************************************************
+//
+// SD_Startup - Initialize sound Tables and start up sound card
+//
+//***************************************************************************
+
+int SD_Startup ( boolean bombonerror )
+{
+   int status;
+   int card;
+   int voices;
+   int channels;
+   int bits;
+   int i;
+   extern boolean IS8250;
+
+   if (SD_Started==true)
+      SD_Shutdown();
+
+   if ( ( FXMode < 0 ) || ( FXMode >= 11 ) )
+      {
+      return( 0 );
+      }
+   card = fxnums[ FXMode ];
+   if (card==-1) // Check if it is off
+      return (0);
+
+   switch (card)
+      {
+#ifdef DOS
+      case UltraSound:
+      case SoundBlaster:
+      case SoundMan16:
+      case ProAudioSpectrum:
+      case Awe32:
+      case SoundSource:
+      case TandySoundSource:
+#endif
+      case SoundScape:
+         soundstart=W_GetNumForName("digistrt")+1;
+         soundtype=fx_digital;
+         break;
+#ifdef DOS
+      case Adlib:
+         soundstart=W_GetNumForName("adstart")+1;
+         soundtype=fx_muse;
+         break;
+      case PC:
+         soundstart=W_GetNumForName("pcstart")+1;
+         soundtype=fx_muse;
+         break;
+#endif
+      default:
+         Error("FX: Unsupported Card number %d",FXMode);
+         break;
+      }
+
+   if ( soundtype == fx_digital )
+      {
+      if ( SoundsRemapped == false )
+         {
+         for( i = 0; i < SD_LASTSOUND; i++ )
+            {
+            int snd;
+
+            snd = sounds[ i ].snds[ fx_digital ];
+            if ( snd >= 0)
+               {
+               sounds[ i ].snds[ fx_digital ] = W_GetNumForName(
+                  W_GetNameForNum( snd + soundstart ) );
+               }
+            }
+         SoundsRemapped = true;
+         }
+      soundstart = 0;
+      }
+
+   voices   = NumVoices;
+   channels = NumChannels;
+   bits     = NumBits;
+
+   if ( IS8250 )
+      {
+      voices   = max( voices, 4 );
+      channels = 1;
+      bits     = 8;
+      }
+
+#ifdef DOS
+   status=FX_Init( card, voices, channels, bits, 11000 );
+#else
+   status=FX_Init( card, voices, channels, bits, 11025 );
+#endif
+
+   if (status != FX_Ok)
+      {
+      if (bombonerror)
+         {
+         DeleteSoundFile ();
+         Error( "%s\n", FX_ErrorString( status ) );
+         }
+
+      return (status);
+      }
+
+   if (stereoreversed == true)
+      {
+      FX_SetReverseStereo(!FX_GetReverseStereo());
+      }
+
+   FX_SetCallBack( SD_MakeCacheable );
+
+   remotestart=W_GetNumForName("remostrt")+1;
+
+   SD_Started=true;
+
+   FX_SetVolume (FXvolume);
+
+   return (0);
+}
+
+//***************************************************************************
+//
+// SD_SoundOkay - checks to see if the sound is okay
+//
+//***************************************************************************
+
+boolean SD_SoundOkay ( int sndnum )
+{
+   if (SD_Started==false)
+      return false;
+
+   if (sndnum>=MAXSOUNDS)
+      Error ("Illegal sound number, sound number = %d\n",sndnum);
+
+   if (SoundOffset(sndnum)==-1)
+      return false;
+
+   if ( ( sounds[ sndnum ].flags & SD_PLAYONCE ) &&
+      ( SD_SoundActive( sounds[ sndnum ].prevhandle ) ) )
+      {
+      return false;
+      }
+
+   return true;
+}
+
+//***************************************************************************
+//
+// SD_PlayIt - Play a pre-setup sound
+//
+//***************************************************************************
+
+int SD_PlayIt ( int sndnum, int angle, int distance, int pitch )
+{
+   int voice;
+   byte * snd;
+
+#if (DEVELOPMENT == 1)
+#if (SOUNDTEST == 1)
+   SoftError("SOUND =%d \n",sndnum);
+#endif
+#endif
+
+   if (!(sounds[sndnum].flags & SD_WRITE))
+      {
+      if (sounds[sndnum].count)
+         {
+         if (distance<=sounds[sndnum].prevdistance)
+            FX_StopSound(sounds[sndnum].prevhandle);
+         else
+            return 0;
+         }
+      }
+
+   if ( !FX_VoiceAvailable( sounds[sndnum].priority ) )
+      {
+      return( 0 );
+      }
+
+   sounds[sndnum].count++;
+
+   snd=W_CacheLumpNum(SoundNumber(sndnum),PU_STATIC, CvtNull, 1);
+
+   if ( *snd == 'C' )
+      {
+      voice = FX_PlayVOC3D( snd, pitch, angle, distance,
+         sounds[sndnum].priority, (unsigned long) sndnum );
+      }
+   else
+      {
+      voice = FX_PlayWAV3D( snd, pitch, angle, distance,
+         sounds[sndnum].priority, (unsigned long) sndnum );
+      }
+
+   if ( voice < FX_Ok )
+      {
+#if (DEVELOPMENT == 1)
+/*
+      if (MV_ErrorCode == MV_InvalidVOCFile)
+         {
+         Error("SD_PlayIt: Invalid VOC File snd=%p sndnum=%ld lump=%ld\n",snd,sndnum,SoundNumber(sndnum));
+         }
+*/
+      NumBadSounds++;
+      SoftError("SD_PlayIt: Error/Warning %s\n",FX_ErrorString( FX_Error ));
+      SoftError("BadSoundNumber %ld time %ld\n",NumBadSounds,GetTicCount());
+#endif
+      SD_MakeCacheable( sndnum );
+
+      return 0;
+      }
+
+   NumBadSounds=0;
+
+   if (!(sounds[sndnum].flags & SD_WRITE))
+      {
+      sounds[sndnum].prevhandle=voice;
+      sounds[sndnum].prevdistance=distance;
+      }
+   return voice;
+}
+
+
+//***************************************************************************
+//
+// SD_Play - Play a sample
+//
+//***************************************************************************
+
+int SD_Play ( int sndnum )
+{
+   int voice;
+   int pitch;
+
+   if ( SD_SoundOkay ( sndnum ) == false )
+      return 0;
+
+   pitch = 0;
+
+   if ( !( sounds[ sndnum ].flags & SD_PITCHSHIFTOFF ) )
+      {
+      pitch = PitchOffset();
+      }
+
+   voice = SD_PlayIt ( sndnum, 0, 0, pitch );
+
+   return voice;
+
+}
+
+//***************************************************************************
+//
+// SD_Play3D - Play a positioned sample
+//
+//***************************************************************************
+
+int SD_Play3D ( int sndnum, int angle, int distance )
+{
+   int voice;
+   int pitch;
+
+   if ( SD_SoundOkay ( sndnum ) == false )
+      return 0;
+
+   pitch = 0;
+   if ( !( sounds[ sndnum ].flags & SD_PITCHSHIFTOFF ) )
+      {
+      pitch = PitchOffset();
+      }
+
+   voice = SD_PlayIt ( sndnum, angle, distance, pitch );
+
+   return voice;
+
+}
+
+//***************************************************************************
+//
+// SD_PlayPositionedSound - Play a positioned sample
+//
+//***************************************************************************
+
+int SD_PlayPositionedSound ( int sndnum, int px, int py, int x, int y )
+{
+   int voice;
+   int angle;
+   int distance;
+   int dx;
+   int dy;
+   int pitch;
+
+   if ( SD_SoundOkay ( sndnum ) == false )
+      return 0;
+
+   dx=(x-px);
+   dy=(py-y);
+
+   distance=FindDistance(dx,dy) >> SD_DISTANCESHIFT;
+
+   if (distance>255)
+      return 0;
+
+   if (distance!=0)
+      {
+      angle = ( atan2_appx(dx,dy) & (FINEANGLES-1) ) >> 6;
+      }
+   else
+      {
+      angle=0;
+      }
+
+   pitch = 0;
+
+   if ( !( sounds[ sndnum ].flags & SD_PITCHSHIFTOFF ) )
+      {
+      pitch = PitchOffset();
+      }
+
+   voice = SD_PlayIt ( sndnum, angle, distance, pitch );
+
+   return voice;
+
+}
+
+//***************************************************************************
+//
+// SD_PlaySoundRTP - Play a positioned sample relative to the player
+//
+//***************************************************************************
+
+int SD_PlaySoundRTP ( int sndnum, int x, int y )
+{
+   int voice;
+   int angle;
+   int distance;
+   int dx;
+   int dy;
+   int pitch;
+
+
+   if ( SD_SoundOkay ( sndnum ) == false )
+      return 0;
+
+   dx=(x-player->x);
+   dy=(player->y-y);
+
+   distance=FindDistance(dx,dy) >> SD_DISTANCESHIFT;
+
+   if (distance>255)
+      return 0;
+
+   if (distance!=0)
+      {
+      angle = ( (player->angle - atan2_appx(dx,dy)) & (FINEANGLES-1) ) >> 6;
+      }
+   else
+      {
+      angle=0;
+      }
+
+   pitch = 0;
+
+   if ( !( sounds[ sndnum ].flags & SD_PITCHSHIFTOFF ) )
+      {
+      pitch = PitchOffset();
+      }
+
+   voice = SD_PlayIt ( sndnum, angle, distance, pitch );
+
+   return voice;
+}
+
+//***************************************************************************
+//
+// SD_PlayPitchedSound - Play a pitched sample
+//
+//***************************************************************************
+
+int SD_PlayPitchedSound ( int sndnum, int volume, int pitch )
+{
+   int voice;
+   int distance;
+
+   if ( SD_SoundOkay ( sndnum ) == false )
+      return 0;
+
+   distance = 255 - volume;
+
+   voice = SD_PlayIt ( sndnum, 0, distance, pitch );
+
+   return voice;
+}
+
+//***************************************************************************
+//
+// SD_SetSoundPitch - sets the pitch of a sound
+//
+//***************************************************************************
+
+void SD_SetSoundPitch ( int sndnum, int pitch )
+{
+   int status;
+
+   if (SD_Started==false)
+      return;
+
+   if (!FX_SoundActive(sndnum))
+      return;
+
+   status=FX_SetPitch( sndnum, pitch );
+   if (status != FX_Ok)
+      {
+#if (DEVELOPMENT == 1)
+      SoftError("SD_SetSoundPitch : %s\n",FX_ErrorString( status ));
+#endif
+      }
+}
+
+//***************************************************************************
+//
+// SD_PanRTP Sound - pan a positioned sample relative to the player
+//
+//***************************************************************************
+
+void SD_PanRTP ( int handle, int x, int y )
+{
+   int angle;
+   int distance;
+   int dx;
+   int dy;
+   int status;
+
+   if (SD_Started==false)
+      return;
+
+   if (!FX_SoundActive(handle))
+      return;
+
+   dx=(x-player->x);
+   dy=(player->y-y);
+
+   distance=FindDistance(dx,dy) >> SD_DISTANCESHIFT;
+
+   if (distance>255)
+      return;
+
+   if (distance!=0)
+      {
+      angle = ( (player->angle - atan2_appx(dx,dy)) & (FINEANGLES-1) ) >> 6;
+      }
+   else
+      {
+      angle = 0;
+      }
+
+   status = FX_Pan3D ( handle, angle, distance );
+
+   if (status != FX_Ok)
+      {
+#if (DEVELOPMENT == 1)
+      SoftError("SD_PanPositionedSound: %s\n",FX_ErrorString( status ));
+#endif
+      }
+}
+
+//***************************************************************************
+//
+// SD_SetPan - set the pan of a sample
+//
+//***************************************************************************
+
+void SD_SetPan ( int handle, int vol, int left, int right )
+{
+   int status;
+
+   if (SD_Started==false)
+      return;
+
+   if (!FX_SoundActive(handle))
+      return;
+
+   status=FX_SetPan( handle, vol, left, right );
+
+   if (status != FX_Ok)
+      {
+#if (DEVELOPMENT == 1)
+      SoftError("SD_SetPan: %s\n",FX_ErrorString( status ));
+#endif
+      }
+}
+
+//***************************************************************************
+//
+// SD_PanPositioned Sound - pan a positioned sample
+//
+//***************************************************************************
+
+void SD_PanPositionedSound ( int handle, int px, int py, int x, int y )
+{
+   int angle;
+   int distance;
+   int dx;
+   int dy;
+   int status;
+
+   if (SD_Started==false)
+      return;
+
+   if (!FX_SoundActive(handle))
+      return;
+
+   dx=(x-px);
+   dy=(py-y);
+
+   distance=FindDistance(dx,dy) >> SD_DISTANCESHIFT;
+
+   if (distance>255)
+      return;
+
+   if (distance!=0)
+      {
+      angle = ( atan2_appx(dx,dy) & (FINEANGLES-1) ) >> 6;
+      }
+   else
+      {
+      angle = 0;
+      }
+
+   status=FX_Pan3D( handle, angle, distance );
+
+   if (status != FX_Ok)
+      {
+#if (DEVELOPMENT == 1)
+      SoftError("SD_PanPositionedSound: %s\n",FX_ErrorString( status ));
+#endif
+      }
+}
+
+
+//***************************************************************************
+//
+// SD_StopSound - Stop the current sound from playing
+//
+//***************************************************************************
+
+void SD_StopSound ( int handle )
+{
+   int status;
+
+   if (SD_Started==false)
+      return;
+
+   status=FX_StopSound( handle);
+
+   if (status != FX_Ok)
+      {
+#if (DEVELOPMENT == 1)
+      SoftError("SD_StopSound: %s\n",FX_ErrorString( status ));
+#endif
+      }
+}
+
+//***************************************************************************
+//
+// SD_StopAllSounds - Stop All the sounds currently playing
+//
+//***************************************************************************
+
+void  SD_StopAllSounds ( void )
+{
+   int status;
+
+   if (SD_Started==false)
+      return;
+
+   status=FX_StopAllSounds();
+
+   if (status != FX_Ok)
+      {
+#if (DEVELOPMENT == 1)
+      SoftError("SD_StopAllSounds: %s\n",FX_ErrorString( status ));
+#endif
+      }
+}
+
+//***************************************************************************
+//
+// SD_SoundActive - See if a sound is active
+//
+//***************************************************************************
+
+int SD_SoundActive ( int handle )
+{
+   if (SD_Started==false)
+      {
+      return false;
+      }
+   else
+      {
+      return (FX_SoundActive(handle));
+      }
+}
+
+//***************************************************************************
+//
+// SD_WaitSound - wait until a sound has finished
+//
+//***************************************************************************
+void SD_WaitSound ( int handle )
+{
+   int time;
+
+   IN_ClearKeysDown();
+
+   while (FX_SoundActive(handle)!=0)
+      {
+      time=GetTicCount()+1;
+      while (time>GetTicCount()) {}
+      if ((LastScan) || IN_GetMouseButtons())
+         break;
+      }
+}
+
+
+//***************************************************************************
+//
+// SD_Shutdown - Shutdown the sound system
+//
+//***************************************************************************
+
+void SD_Shutdown (void)
+{
+   if (SD_Started==false)
+      return;
+
+   FX_Shutdown();
+   SD_Started=false;
+}
+
+
+//***************************************************************************
+//
+// SD_PreCacheSound - PreCache sound
+//
+//***************************************************************************
+
+void SD_PreCacheSound ( int num )
+{
+   if ( SD_SoundOkay ( num ) == false )
+      return;
+
+   PreCacheLump(SoundNumber(num),PU_CACHESOUNDS+sounds[num].priority,cache_other);
+}
+
+//***************************************************************************
+//
+// SD_PreCacheSoundGroup - PreCache sound group
+//
+//***************************************************************************
+
+void SD_PreCacheSoundGroup ( int lo, int hi )
+{
+   int i;
+
+   if (SD_Started==false)
+      return;
+
+   for (i=lo;i<=hi;i++)
+      SD_PreCacheSound(i);
+}
+
+
+#if (SHAREWARE == 1)
+#define MAXSONGS 18
+static song_t rottsongs[MAXSONGS] = {
+      { loop_no,  song_apogee  ,"FANFARE2","Apogee Fanfare"},
+      { loop_yes, song_title   ,"RISE",    "Rise"},
+      { loop_yes, song_menu    ,"MMMENU",  "MMMenu"},
+      { loop_yes, song_christmas,"DEADLY", "Deadly Gentlemen"},
+      { loop_yes, song_elevator,"GOINGUP", "Going up?"},
+      { loop_yes, song_endlevel,"HOWDIDO", "How'd I do?"},
+      { loop_yes, song_secretmenu,"FISHPOLK","Fish Polka"},
+      { loop_yes, song_gameover,"YOUSUCK", "You Suck"},
+      { loop_yes, song_youwin  ,"WATZNEXT","Watz Next?"},
+      { loop_no,  song_gason   ,"GAZZ!",   "Gazz!"},
+      { loop_yes, song_level   ,"FASTWAY", "Goin' Down The Fast Way"},
+      { loop_yes, song_level   ,"MISTACHE","Mist Ache"},
+      { loop_yes, song_level   ,"OWW",     "Oww!!!"},
+      { loop_yes, song_level   ,"SMOKE",   "Smoke And Mirrors"},
+      { loop_yes, song_level   ,"SPRAY",   "Spray"},
+      { loop_yes, song_level   ,"RUNLIKE", "Run Like Smeg"},
+      { loop_yes, song_level   ,"SMOOTH",  "Havana Smooth"},
+      { loop_yes, song_level   ,"CHANT",   "Chant"},
+      };
+#else
+#define MAXSONGS 34
+static song_t rottsongs[MAXSONGS] = {
+      { loop_no,  song_apogee  ,"FANFARE2","Apogee Fanfare"},
+      { loop_yes, song_title   ,"RISE",    "Rise"},
+      { loop_yes, song_menu    ,"MMMENU",  "MMMenu"},
+      { loop_yes, song_christmas,"DEADLY", "Deadly Gentlemen"},
+      { loop_yes, song_elevator,"GOINGUP", "Going up?"},
+      { loop_yes, song_secretmenu,"FISHPOLK","Fish Polka"},
+      { loop_yes, song_endlevel,"HOWDIDO", "How'd I do?"},
+      { loop_yes, song_gameover,"YOUSUCK", "You Suck"},
+      { loop_yes, song_cinematic2,"WATZNEXT","Watz Next?"},
+      { loop_no,  song_gason   ,"GAZZ!",   "Gazz!"},
+      { loop_yes, song_level   ,"FASTWAY", "Goin' Down The Fast Way"},
+      { loop_yes, song_level   ,"MISTACHE","Mist Ache"},
+      { loop_yes, song_level   ,"OWW",     "Oww!!!"},
+      { loop_yes, song_level   ,"SMOKE",   "Smoke And Mirrors"},
+      { loop_yes, song_level   ,"SPRAY",   "Spray"},
+      { loop_yes, song_level   ,"RUNLIKE", "Run Like Smeg"},
+      { loop_yes, song_level   ,"SMOOTH",  "Havana Smooth"},
+      { loop_yes, song_level   ,"CHANT",   "Chant"},
+      { loop_yes, song_level   ,"MEDIEV1A","Funeral of Queen Mary"},
+      { loop_yes, song_level   ,"TASKFORC","Task Force"},
+      { loop_yes, song_level   ,"KISSOFF", "KISS Off"},
+      { loop_yes, song_level   ,"RADAGIO", "Adagio For Strings"},
+      { loop_yes, song_level   ,"SHARDS",  "Shards"},
+      { loop_yes, song_level   ,"STAIRS",  "I Choose the Stairs"},
+      { loop_yes, song_level   ,"SUCKTHIS","Suck This"},
+      { loop_yes, song_level   ,"EXCALIBR","Excalibur"},
+      { loop_yes, song_level   ,"CCCOOL",   "CCCool"},
+      { loop_yes, song_level   ,"WORK_DAY","Work Day"},
+      { loop_yes, song_level   ,"WHERIZIT","Where Iz It?"},
+      { loop_no,  song_bossdie,"BOSSBLOW", "Boss Blow"},
+      { loop_yes, song_bosssee ,"HELLERO", "Hellero"},
+      { loop_yes, song_cinematic1,"EVINRUDE","Evin Rude"},
+      { loop_yes, song_youwin  ,"VICTORY", "Victory!"},
+      { loop_yes, song_dogend  ,"HERE_BOY","Here Boy"}
+      };
+#endif
+
+static byte * currentsong;
+static int MU_Started=false;
+static int lastsongnumber=-1;
+int storedposition=0;
+
+//****************************************************************************
+//
+// MU_JukeBoxMenu()
+//
+//****************************************************************************
+
+void MU_PlayJukeBoxSong
+   (
+   int which
+   )
+
+   {
+   if ( ( MusicMode > 0 ) && ( MU_Started == true ) )
+      {
+      SetMenuHeader( rottsongs[ which ].songname );
+      MU_PlaySong( which );
+      }
+   }
+
+
+//****************************************************************************
+//
+// MU_JukeBoxMenu()
+//
+//****************************************************************************
+
+void MU_JukeBoxRedraw
+   (
+   void
+   )
+
+   {
+   if ( ( MusicMode > 0 ) && ( MU_Started == true ) )
+      {
+      SetMenuHeader( rottsongs[ lastsongnumber ].songname );
+      }
+   }
+
+
+//****************************************************************************
+//
+// MU_JukeBoxMenu()
+//
+//****************************************************************************
+
+void MU_JukeBoxMenu
+   (
+   void
+   )
+
+   {
+   char *SongNames[ MAXSONGS ];
+   int   i;
+
+   for( i = 0; i < MAXSONGS; i++ )
+      {
+      SongNames[ i ] = rottsongs[ i ].songname;
+      }
+
+   HandleMultiPageCustomMenu( SongNames, MAXSONGS, lastsongnumber,
+      "Jukebox", MU_PlayJukeBoxSong, MU_JukeBoxRedraw, false );
+
+   if ( rottsongs[ lastsongnumber ].loopflag == loop_no )
+      {
+      MU_StartSong(song_level);
+      }
+   }
+
+//***************************************************************************
+//
+// MusicStarted - see if the music is started
+//
+//***************************************************************************
+boolean MusicStarted( void )
+{
+   return MU_Started;
+}
+
+//***************************************************************************
+//
+// MU_Startup - Initialize music stuff
+//
+//***************************************************************************
+
+int MU_Startup ( boolean bombonerror )
+{
+   int status;
+   int card;
+
+   if (MU_Started==true)
+      {
+      MU_StopSong();
+      MU_Shutdown();
+      }
+   if ( ( MusicMode < 0 ) || ( MusicMode >= 11 ) )
+      {
+      return( 0 );
+      }
+   card = musicnums[ MusicMode ];
+   if (card==-1) // Check if it is off
+      return (0);
+
+#ifdef DOS
+   if ( ( card == SoundBlaster ) || ( card == Awe32 ) || ( card == WaveBlaster ) )
+      {
+      if ( SD_Started == false )
+         {
+         extern fx_blaster_config SBSettings;
+         int numvoices;
+         int numbits;
+         int numchannels;
+
+         FX_SetupSoundBlaster( SBSettings, &numvoices,
+            &numbits, &numchannels );
+         }
+      }
+
+   if (card== UltraSound)
+      {
+      MU_SetupGUSInitFile();
+      }
+
+   status=MUSIC_Init( card, MidiAddress );
+#else
+   /* Not DOS, no address config needed */
+   status=MUSIC_Init( card, 0 );
+#endif
+
+
+   if (status != MUSIC_Ok) {
+      if (bombonerror)
+         {
+         DeleteSoundFile ();
+         Error( "%s\n", MUSIC_ErrorString( status ) );
+         }
+      else
+         return (status);
+   }
+
+   currentsong=0;
+
+   MU_Started=true;
+
+   MU_SetVolume (MUvolume);
+
+   return (0);
+}
+
+//***************************************************************************
+//
+// MU_Shutdown - Shutdown the music system
+//
+//***************************************************************************
+
+void MU_Shutdown (void)
+{
+   if (MU_Started==false)
+      return;
+   MUSIC_Shutdown();
+   MU_Started=false;
+}
+
+#ifdef DOS
+//***************************************************************************
+//
+// MU_SetupGUSInitFile - initialize GUS stuff
+//
+//***************************************************************************
+
+void MU_SetupGUSInitFile( void )
+{
+   char filename[ 128 ];
+
+   GetPathFromEnvironment( filename, ApogeePath, GUSMIDIINIFILE );
+   if (access (filename, F_OK) != 0)
+      {
+      int lump;
+
+      lump=W_GetNumForName("gusmidi");
+
+      SaveFile (filename, W_CacheLumpNum(lump,PU_CACHE, CvtNull, 1), W_LumpLength(lump));
+      }
+}
+
+#endif
+
+//***************************************************************************
+//
+// MU_GetNumForType - returns number of song in rottsongs of specific type
+//
+//***************************************************************************
+int MU_GetNumForType ( int type )
+{
+   int i;
+
+   for (i=0;i<MAXSONGS;i++)
+      {
+      if (rottsongs[i].songtype == type)
+         return i;
+      }
+   Error("MU_GetNumForType: could not find song type in list\n");
+   return -1;
+}
+
+
+//***************************************************************************
+//
+// MU_PlaySong - Play a specific song number
+//
+//***************************************************************************
+
+void MU_PlaySong ( int num )
+{
+   int lump;
+   int size;
+   
+   if (MU_Started==false)
+      return;
+
+   if (num<0)
+      return;
+
+   if (num>=MAXSONGS)
+      Error("Song number out of range\n");
+
+   MU_StopSong();
+
+   lastsongnumber=num;
+
+   lump = W_GetNumForName(rottsongs[num].lumpname);
+   size = W_LumpLength(lump);
+
+   currentsong=W_CacheLumpNum(lump,PU_STATIC, CvtNull, 1);
+
+#ifdef PLATFORM_DOS
+   if (rottsongs[num].loopflag == loop_yes)
+      MUSIC_PlaySong(currentsong,size,MUSIC_LoopSong);
+   else
+      MUSIC_PlaySong(currentsong,size,MUSIC_PlayOnce);
+#else 
+   if (rottsongs[num].loopflag == loop_yes)
+      MUSIC_PlaySongROTT(currentsong,size,MUSIC_LoopSong);
+   else
+      MUSIC_PlaySongROTT(currentsong,size,MUSIC_PlayOnce);
+#endif
+
+   MU_SetVolume (MUvolume);
+}
+
+//***************************************************************************
+//
+// MU_StopSong - Play a specific song number
+//
+//***************************************************************************
+
+void MU_StopSong ( void )
+{
+   if (MU_Started==false)
+      return;
+
+   MUSIC_StopSong ();
+   if (currentsong)
+      {
+      W_CacheLumpName(rottsongs[lastsongnumber].lumpname,PU_CACHE, CvtNull, 1);
+      currentsong=0;
+      }
+}
+
+//***************************************************************************
+//
+// MU_GetSongNumber - get current song number
+//
+//***************************************************************************
+
+int MU_GetSongNumber ( void )
+{
+   return lastsongnumber;
+}
+
+
+//***************************************************************************
+//
+// MU_FadeToSong - Fade to a specific song in a certain time
+//
+//***************************************************************************
+
+void MU_FadeToSong ( int num, int time )
+{
+   int t;
+
+   if (MU_Started==false)
+      return;
+
+   MU_FadeOut(time>>1);
+
+   while (MU_FadeActive())
+      {
+      t=GetTicCount();
+      while (GetTicCount()==t) {}
+      }
+
+   MU_FadeIn (num,time>>1);
+}
+
+//***************************************************************************
+//
+// MU_FadeIn - Fade in
+//
+//***************************************************************************
+
+void MU_FadeIn ( int num, int time )
+{
+   if (MU_Started==false)
+      return;
+
+   MUSIC_SetVolume(0);
+   MU_PlaySong ( num );
+   MUSIC_FadeVolume (MUvolume, time);
+}
+
+//***************************************************************************
+//
+// MU_FadeOut - Fade out
+//
+//***************************************************************************
+
+void MU_FadeOut ( int time )
+{
+   if (MU_Started==false)
+      return;
+   if (!MUSIC_SongPlaying())
+      {
+#if (DEVELOPMENT == 1)
+      SoftError("Called FadeOut with no song playing\n");
+#endif
+      return;
+      }
+   MUSIC_FadeVolume(0,time);
+}
+
+
+//***************************************************************************
+//
+// MU_StartSong - Start a context sensitive song
+//
+//***************************************************************************
+
+void MU_StartSong ( int songtype )
+{
+   int songnum;
+
+   if (MU_Started==false)
+      return;
+
+   MU_StopSong();
+
+   songnum = MU_GetNumForType ( songtype );
+   switch (songtype)
+      {
+      case song_level:
+         if (IsChristmas())
+            {
+            songnum = MU_GetNumForType ( song_christmas );
+            }
+         else
+            {
+            songnum += GetSongForLevel ();
+            }
+         break;
+      }
+   MU_PlaySong (songnum);
+}
+
+//***************************************************************************
+//
+// MU_StoreSongPostition - Save off Song Position
+//
+//***************************************************************************
+
+void MU_StoreSongPosition ( void )
+{
+   if (MU_Started==false)
+      return;
+   PositionStored=true;
+   storedposition=MUSIC_GetPosition();
+}
+
+//***************************************************************************
+//
+// MU_RestoreSongPostition - Save off Song Position
+//
+//***************************************************************************
+
+void MU_RestoreSongPosition ( void )
+{
+   if (MU_Started==false)
+      return;
+   if (PositionStored==false)
+      return;
+   PositionStored=false;
+
+   MUSIC_SetPosition(storedposition);
+}
+
+//***************************************************************************
+//
+// MU_GetStoredPostition - Get Stored song Position
+//
+//***************************************************************************
+
+int MU_GetStoredPosition ( void )
+{
+   if (PositionStored)
+      return storedposition;
+   else
+      return -1;
+}
+
+//***************************************************************************
+//
+// MU_SetStoredPostition - Get Stored song Position
+//
+//***************************************************************************
+
+void MU_SetStoredPosition ( int position )
+{
+   if (MU_Started==false)
+      return;
+   if (position==-1)
+      return;
+   PositionStored=true;
+   storedposition=position;
+}
+
+
+
+//***************************************************************************
+//
+// MU_GetSongPostition - Get Song Position
+//
+//***************************************************************************
+
+int MU_GetSongPosition ( void )	
+{
+   if (MU_Started==false)
+      return 0;
+   return MUSIC_GetPosition();
+}
+
+//***************************************************************************
+//
+// MU_SetSongPostition - Set Song Position
+//
+//***************************************************************************
+
+void MU_SetSongPosition ( int position )
+{
+   if (MU_Started==false)
+      return;
+   MUSIC_SetPosition(position);
+}
+
+//***************************************************************************
+//
+// MU_SaveMusic
+//
+//***************************************************************************
+
+void MU_SaveMusic (byte ** buf, int * size)
+{
+   int unitsize;
+   byte *ptr;
+   int vsize;
+   int i;
+
+   //
+   // Size
+   //
+
+   unitsize=0;
+
+	unitsize+=sizeof(i);
+	unitsize+=sizeof(i);
+	unitsize+=sizeof(i);
+
+
+   *size = unitsize;
+   *buf = (byte *) SafeMalloc (*size);
+
+   ptr = *buf;
+
+   i=MU_GetSongNumber();
+   if (rottsongs[i].songtype == song_menu)
+      {
+      i = MU_GetNumForType ( song_level );
+      if (IsChristmas())
+         {
+         i = MU_GetNumForType ( song_christmas );
+         }
+      else
+         {
+         i += GetSongForLevel ();
+         }
+      vsize=sizeof(i);
+      memcpy(ptr,&i,vsize);
+      ptr+=vsize;
+
+      i=MU_GetStoredPosition();
+      vsize=sizeof(i);
+      memcpy(ptr,&i,vsize);
+      ptr+=vsize;
+
+      i=-1;
+      vsize=sizeof(i);
+      memcpy(ptr,&i,vsize);
+      ptr+=vsize;
+      }
+   else
+      {
+      vsize=sizeof(i);
+      memcpy(ptr,&i,vsize);
+      ptr+=vsize;
+
+      i=MU_GetSongPosition();
+      vsize=sizeof(i);
+      memcpy(ptr,&i,vsize);
+      ptr+=vsize;
+
+      i=MU_GetStoredPosition();
+      vsize=sizeof(i);
+      memcpy(ptr,&i,vsize);
+      ptr+=vsize;
+      }
+}
+
+
+//***************************************************************************
+//
+// MU_LoadMusic
+//
+//***************************************************************************
+
+void MU_LoadMusic (byte * buf, int size)
+{
+   int unitsize;
+   byte *ptr;
+   int i;
+   int songnumber;
+   boolean differentsong=false;
+   int vsize;
+
+   //
+   // Size
+   //
+
+   unitsize=0;
+
+	unitsize+=sizeof(i);
+	unitsize+=sizeof(i);
+	unitsize+=sizeof(i);
+
+   if (size!=unitsize)
+      Error("LoadMusic: Different number of parameters\n");
+
+   ptr  = buf;
+
+   vsize=sizeof(songnumber);
+   memcpy(&songnumber,ptr,vsize);
+   ptr+=vsize;
+   if (MU_GetSongNumber () != songnumber)
+      {
+      MU_PlaySong(songnumber);
+      differentsong=true;
+      }
+
+   vsize=sizeof(i);
+   memcpy(&i,ptr,vsize);
+   ptr+=vsize;
+   if (differentsong==true)
+      {
+      MU_SetSongPosition(i);
+      }
+
+   vsize=sizeof(i);
+   memcpy(&i,ptr,vsize);
+   ptr+=vsize;
+   MU_SetStoredPosition(i);
+
+   // Check if game was saved with NOSOUND
+
+   if (MU_GetSongNumber () != songnumber)
+      {
+      MU_StartSong ( song_level );
+      }
+}

Added: tags/rott-1.1/rott/rt_sound.h
===================================================================
--- tags/rott-1.1/rott/rt_sound.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_sound.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,689 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_sound_public
+#define _rt_sound_public
+
+#include "music.h"
+#include "develop.h"
+
+typedef enum {
+
+//	MENU SOUNDS
+
+		   SD_MENUFLIP,
+		   SD_ESCPRESSEDSND,
+		   SD_MOVECURSORSND,
+		   SD_SELECTSND,
+		   SD_WARNINGBOXSND,
+		   SD_INFOBOXSND,
+		   SD_QUESTIONBOXSND,
+		   SD_NOPESND,
+		   SD_QUIT1SND,
+		   SD_QUIT2SND,
+		   SD_QUIT3SND,
+		   SD_QUIT4SND,
+		   SD_QUIT5SND,
+		   SD_QUIT6SND,
+		   SD_QUIT7SND,
+
+
+//	GAME SOUNDS
+
+		   SD_LEVELSTARTSND,
+		   SD_LEVELDONESND,
+		   SD_GAMEOVERSND,
+
+//	LEVEL END SCREEN
+
+		   SD_ENDBONUS1SND,
+		   SD_NOBONUSSND,
+		   SD_PERCENT100SND,
+
+//	PLAYER SOUNDS
+
+		   SD_HITWALLSND,
+		   SD_SELECTWPNSND,
+		   SD_NOWAYSND,
+		   SD_DONOTHINGSND,
+		   SD_NOITEMSND,
+		   SD_PLAYERDYINGSND,
+
+         SD_PLAYERTCDEATHSND,
+         SD_PLAYERTBDEATHSND,
+         SD_PLAYERDWDEATHSND,
+         SD_PLAYERLNDEATHSND,
+         SD_PLAYERIPFDEATHSND,
+         SD_PLAYERTCHURTSND,
+         SD_PLAYERTBHURTSND,
+         SD_PLAYERDWHURTSND,
+         SD_PLAYERLNHURTSND,
+         SD_PLAYERIPFHURTSND,
+         SD_PLAYERTCSND,
+         SD_PLAYERTBSND,
+         SD_PLAYERDWSND,
+         SD_PLAYERLNSND,
+         SD_PLAYERIPFSND,
+//         SD_WALK1SND,
+//         SD_WALK2SND,
+		   SD_PLAYERBURNEDSND,
+		   SD_PLAYERLANDSND,
+		   SD_PLAYERCOUGHMSND,
+		   SD_PLAYERCOUGHFSND,
+		   SD_NETWIGGLESND,
+		   SD_NETFALLSND,
+
+//	PLAYER WEAPONS
+
+		   SD_ATKPISTOLSND,
+         SD_ATKTWOPISTOLSND,
+		   SD_ATKMP40SND,
+         SD_RICOCHET1SND,
+         SD_RICOCHET2SND,
+         SD_RICOCHET3SND,
+		   SD_BAZOOKAFIRESND,
+		   SD_FIREBOMBFIRESND,
+		   SD_HEATSEEKFIRESND,
+		   SD_DRUNKFIRESND,
+		   SD_FLAMEWALLFIRESND,
+		   SD_FLAMEWALLSND,
+		   SD_SPLITFIRESND,
+		   SD_SPLITSND,
+		   SD_GRAVBUILDSND,
+		   SD_GRAVFIRESND,
+		   SD_GRAVSND,
+		   SD_GRAVHITSND,
+		   SD_FIREHITSND,
+         SD_MISSILEFLYSND,
+		   SD_MISSILEHITSND,
+		   SD_EXCALIBOUNCESND,
+		   SD_EXCALISWINGSND,
+		   SD_EXCALIHITSND,
+		   SD_EXCALIBUILDSND,
+		   SD_EXCALIBLASTSND,
+		   SD_GODMODEFIRESND,
+		   SD_GODMODE1SND,
+		   SD_GODMODE2SND,
+		   SD_GODMODE3SND,
+		   SD_LOSEMODESND,
+		   SD_DOGMODEPANTSND,
+         SD_DOGMODEBITE1SND,
+         SD_DOGMODEBITE2SND,
+         SD_DOGMODELICKSND,
+         SD_DOGMODEBLASTSND,
+         SD_DOGMODEPREPBLASTSND,
+         SD_DOGMANSND,
+         SD_DOGWOMANSND,
+         SD_GODMANSND,
+         SD_GODWOMANSND,
+         SD_FLYINGSND,
+
+//	PLAYER-CAUSED SOUNDS
+
+		   SD_GLASSBREAKSND,
+		   SD_ITEMBLOWSND,
+		   SD_BONUSBARRELSND,
+		   SD_TOUCHPLATESND,
+		   SD_BADTOUCHSND,
+         SD_EXPLODEFLOORSND,
+		   SD_EXPLODESND,
+		   SD_GASSTARTSND,
+		   SD_GASHISSSND,
+		   SD_GASENDSND,
+		   SD_GASMASKSND,
+
+//	GET ITEM SOUNDS
+
+		   SD_GETKEYSND,
+         SD_GETBONUSSND,
+		   SD_GETHEALTH1SND,
+		   SD_GETHEALTH2SND,
+		   SD_COOKHEALTHSND,
+
+		   SD_GETWEAPONSND,
+		   SD_GETKNIFESND,
+		   SD_GETGODSND,
+		   SD_GETDOGSND,
+		   SD_GETFLEETSND,
+		   SD_GETELASTSND,
+		   SD_GETSHROOMSSND,
+		   SD_GETBVESTSND,
+		   SD_GETAVESTSND,
+		   SD_GETMASKSND,
+		   SD_GETBATSND,
+		   SD_GETHEADSND,
+
+		   SD_GET1UPSND,
+		   SD_GET3UPSND,
+         SD_RESPAWNSND,
+         SD_PLAYERSPAWNSND,
+
+//	ACTOR SOUNDS
+
+		   SD_LOWGUARD1SEESND,
+		   SD_LOWGUARD1ASEESND,
+		   SD_LOWGUARD1SEE3SND,
+		   SD_LOWGUARD2SEESND,
+		   SD_LOWGUARD2ASEESND,
+		   SD_LOWGUARD2SEE3SND,
+		   SD_LOWGUARDFIRESND,
+		   SD_LOWGUARDOUCHSND,
+         SD_LOWGUARD1DIESND,
+         SD_LOWGUARD2DIESND,
+		   SD_SNEAKYSPRINGMSND,
+		   SD_SNEAKYSPRINGFSND,
+
+         SD_HIGHGUARD1SEESND,
+		   SD_HIGHGUARD2SEESND,
+         SD_HIGHGUARDFIRESND,
+		   SD_HIGHGUARDOUCHSND,
+		   SD_HIGHGUARDDIESND,
+
+         SD_OVERP1SEESND,
+		   SD_OVERP2SEESND,
+         SD_OVERPFIRESND,
+		   SD_OVERPNETSND,
+		   SD_OVERPOUCHSND,
+		   SD_OVERPDIESND,
+
+         SD_STRIKE1SEESND,
+		   SD_STRIKE2SEESND,
+         SD_STRIKEFIRESND,
+		   SD_STRIKEROLLSND,
+		   SD_STRIKEOUCHSND,
+		   SD_STRIKEDIESND,
+
+         SD_BLITZ1SEESND,
+         SD_BLITZ2SEESND,
+         SD_BLITZFIRESND,
+		   SD_BLITZSTEALSND,
+		   SD_BLITZOUCHSND,
+		   SD_BLITZDIESND,
+         SD_BLITZPLEADSND,
+         SD_BLITZPLEAD1SND,
+         SD_BLITZPLEAD2SND,
+
+		   SD_ENFORCERSEESND,
+		   SD_ENFORCERFIRESND,
+		   SD_ENFORCERTHROWSND,
+		   SD_ENFORCEROUCHSND,
+		   SD_ENFORCERDIESND,
+
+		   SD_MONKSEESND,
+		   SD_MONKGRABSND,
+		   SD_MONKOUCHSND,
+		   SD_MONKDIESND,
+
+		   SD_FIREMONKSEESND,
+		   SD_FIREMONKFIRESND,
+		   SD_FIREMONKOUCHSND,
+		   SD_FIREMONKDIESND,
+
+		   SD_ROBOTSEESND,
+		   SD_ROBOTFIRESND,
+		   SD_ROBOTDIESND,
+         SD_ROBOTMOVESND,
+
+         SD_BALLISTIKRAFTSEESND,
+         SD_BALLISTIKRAFTFIRESND,
+
+         SD_DARIANSEESND,
+         SD_DARIANFIRESND,
+		   SD_DARIANGONNAUSESND,
+		   SD_DARIANUSESND,
+		   SD_DARIANHIDESND,
+		   SD_DARIANDIESND,
+         SD_DARIANSAY1,
+         SD_DARIANSAY2,
+         SD_DARIANSAY3,
+
+		   SD_KRISTSEESND,
+		   SD_KRISTFIRESND,
+		   SD_KRISTMOTORSND,
+		   SD_KRISTTURNSND,
+		   SD_KRISTDROPSND,
+		   SD_KRISTMINEBEEPSND,
+		   SD_KRISTMINEHITSND,
+		   SD_KRISTDIESND,
+         SD_KRISTSAY1,
+         SD_KRISTSAY2,
+         SD_KRISTSAY3,
+
+		   SD_NMESEESND,
+		   SD_NMEREADYSND,
+		   SD_NMEFIRE1SND,
+		   SD_NMEAPARTSND,
+		   SD_NMEUFOSND,
+		   SD_NMEDIESND,
+
+		   SD_DARKMONKSEESND,
+		   SD_DARKMONKFIRE1SND,
+		   SD_DARKMONKFIRE2SND,
+		   SD_DARKMONKFIRE3SND,
+		   SD_DARKMONKFIRE4SND,
+         SD_DARKMONKRECHARGESND,
+		   SD_DARKMONKFLOATSND,
+		   SD_DARKMONKDIESND,
+         SD_DARKMONKSAY1,
+         SD_DARKMONKSAY2,
+         SD_DARKMONKSAY3,
+
+		   SD_SNAKESEESND,
+		   SD_SNAKEREADYSND,
+		   SD_SNAKECHARGESND,
+		   SD_SNAKEOUCHSND,
+		   SD_SNAKEDIESND,
+		   SD_SNAKESPITSND,
+         SD_SNAKESAY1,
+         SD_SNAKESAY2,
+         SD_SNAKESAY3,
+
+		   SD_EMPLACEMENTSEESND,
+		   SD_EMPLACEMENTFIRESND,
+		   SD_BIGEMPLACEFIRESND,
+
+
+//	ENVIRONMENT SOUNDS
+
+         SD_OPENDOORSND,
+         SD_CLOSEDOORSND,
+         SD_DOORHITSND,
+         SD_FIRECHUTESND,
+		   SD_FIREBALLSND,
+		   SD_FIREBALLHITSND,
+		   SD_BLADESPINSND,
+		   SD_PUSHWALLSND,
+		   SD_PUSHWALLHITSND,
+		   SD_GOWALLSND,
+		   SD_TURBOWALLSND,
+		   SD_BOULDERHITSND,
+		   SD_BOULDERROLLSND,
+		   SD_BOULDERFALLSND,
+		   SD_PITTRAPSND,
+		   SD_FIREJETSND,
+		   SD_ACTORSQUISHSND,
+		   SD_ACTORBURNEDSND,
+         SD_ACTORSKELETONSND,
+
+		   SD_SPEARSTABSND,
+		   SD_CYLINDERMOVESND,
+		   SD_ELEVATORONSND,
+         SD_ELEVATORENDSND,
+
+		   SD_SPRINGBOARDSND,
+         SD_LIGHTNINGSND,
+         SD_WINDSND,
+         SD_WATERSND,
+         SD_BODYLANDSND,
+         SD_GIBSPLASHSND,
+         SD_ACTORLANDSND,
+
+//	SECRET SOUNDS
+
+		   SD_DOPEFISHSND,
+		   SD_YOUSUCKSND,
+
+		   SD_SILLYMOVESND,
+		   SD_SOUNDSELECTSND,
+		   SD_SOUNDESCSND,
+
+//	REMOTE SOUNDS (shift number row)
+
+		   SD_REMOTEM1SND,
+		   SD_REMOTEM2SND,
+		   SD_REMOTEM3SND,
+		   SD_REMOTEM4SND,
+		   SD_REMOTEM5SND,
+		   SD_REMOTEM6SND,
+		   SD_REMOTEM7SND,
+		   SD_REMOTEM8SND,
+		   SD_REMOTEM9SND,
+		   SD_REMOTEM10SND,
+
+         SD_LASTSOUND,
+
+         MAXSOUNDS
+
+	          } game_sounds;
+
+
+typedef enum
+         {
+// REMOTE SOUNDS (shift number row)
+
+		   D_REMOTEM1SND,
+		   D_REMOTEM2SND,
+		   D_REMOTEM3SND,
+		   D_REMOTEM4SND,
+		   D_REMOTEM5SND,
+		   D_REMOTEM6SND,
+		   D_REMOTEM7SND,
+		   D_REMOTEM8SND,
+		   D_REMOTEM9SND,
+		   D_REMOTEM10SND,
+         } remotesounds;
+
+typedef enum {
+		MUSE_MENUFLIPSND,             // 0
+		MUSE_ESCPRESSEDSND,           // 1
+		MUSE_MOVECURSORSND,           // 2
+		MUSE_SELECTSND,               // 3
+		MUSE_WARNINGBOXSND,           // 4
+		MUSE_INFOBOXSND,              // 5
+		MUSE_QUESTIONBOXSND,          // 6
+		MUSE_NOPESND,                 // 7
+		MUSE_LEVELSTARTSND,           // 8
+		MUSE_LEVELENDSND,             // 9
+		MUSE_GAMEOVERSND,             // 10
+		MUSE_ENDBONUS1SND,            // 11
+		MUSE_ENDBONUS2SND,            // 12
+		MUSE_NOBONUSSND,              // 13
+		MUSE_PERCENT100SND,           // 14
+		MUSE_HITWALLSND,              // 15
+		MUSE_SELECTWPNSND,            // 16
+		MUSE_NOWAYSND,                // 17
+		MUSE_DONOTHINGSND,            // 18
+		MUSE_NOITEMSND,               // 19
+		MUSE_PLAYERDYINGSND,          // 20
+		MUSE_PLAYERDEATHSND,          // 21
+		MUSE_PLAYERHURTSND,           // 22
+		MUSE_PLAYERYESSND,            // 23
+		MUSE_WALK1SND,                // 24
+		MUSE_WALK2SND,                // 25
+		MUSE_PLAYERLANDSND,           // 26
+		MUSE_NETFALLSND,              // 27
+		MUSE_ATKKNIFESND,             // 28
+		MUSE_ATKPISTOLSND,            // 29
+		MUSE_ATKMP40SND,              // 30
+		MUSE_RICOCHETSND,             // 31
+		MUSE_MISSILEFIRESND,          // 32
+		MUSE_FLAMEWALLSND,            // 33
+		MUSE_MISSILEHITSND,           // 34
+		MUSE_WEAPONBUILDSND,          // 35
+		MUSE_STABBERSND,              // 36
+		MUSE_ENERGYFIRESND,           // 37
+		MUSE_GAINMODESND,             // 38
+		MUSE_LOSEMODESND,             // 39
+		MUSE_DOGLICKSND,              // 40
+		MUSE_DOGBITESND,              // 41
+		MUSE_GLASSBREAKSND,           // 42
+		MUSE_EXPLOSIONSND,            // 43
+		MUSE_TOUCHPLATESND,           // 44
+		MUSE_BADTOUCHSND,             // 45
+		MUSE_SWITCHSND,               // 46
+		MUSE_GETKEYSND,               // 47
+		MUSE_GETBONUSSND,             // 48
+		MUSE_GETHEALTHSND,            // 49
+		MUSE_GETWEAPONSND,            // 50
+		MUSE_GETMWEAPONSND,           // 51
+		MUSE_GETPOWERUPSND,           // 52
+		MUSE_GETPOWERDOWNSND,         // 53
+		MUSE_GETARMORSND,             // 54
+		MUSE_GETWEIRDSND,             // 55
+		MUSE_GETLIFESND,              // 56
+		MUSE_ACTORSEESND,             // 57
+		MUSE_ACTORFIRESND,            // 58
+		MUSE_ACTOROUCHSND,            // 59
+		MUSE_ACTORDIESND,             // 60
+		MUSE_ACTORTHROWSND,           // 61
+		MUSE_ACTORROLLSND,            // 62
+		MUSE_ACTORDOITSND,            // 63
+		MUSE_ACTORUSESND,             // 64
+		MUSE_BOSSSEESND,              // 65
+		MUSE_BOSSOUCHSND,             // 66
+		MUSE_BOSSDIESND,              // 67
+		MUSE_BOSSDOSND,               // 68
+		MUSE_BOSSBEEPSND,             // 69
+		MUSE_BOSSHEYSND,              // 70
+		MUSE_BOSSFIRESND,             // 71
+		MUSE_BOSSWARNSND,             // 72
+		MUSE_BOSSFIRE2SND,            // 73
+		MUSE_EMPFIRESND,              // 74
+		MUSE_OPENDOORSND,             // 75
+		MUSE_CLOSEDOORSND,            // 76
+		MUSE_SPINBLADESND,            // 77
+		MUSE_PUSHWALLSND,             // 78
+		MUSE_BOULDERSND,              // 79
+		MUSE_PITTRAPSND,              // 80
+		MUSE_FIREJETSND,              // 81
+		MUSE_ACTORSQUISHSND,          // 82
+		MUSE_CYLINDERHITSND,          // 83
+		MUSE_ELEVATORSND,             // 84
+		MUSE_SPRINGBOARDSND,          // 85
+		MUSE_LASTSOUND=-1
+	     } musesounds;
+
+#define NUMCARDS 6
+
+typedef enum {
+   fx_digital,
+   fx_muse
+} fxtypes;
+
+typedef enum {
+   ASS_UltraSound,
+   ASS_SoundBlaster,
+   ASS_SoundMan16,
+   ASS_PAS,
+   ASS_AWE32,
+   ASS_SoundScape,
+   ASS_WaveBlaster,
+   ASS_Adlib,
+   ASS_GeneralMidi,
+   ASS_SoundCanvas,
+   ASS_SoundSource,
+   ASS_TandySoundSource,
+   ASS_PCSpeaker,
+   ASS_Off
+} ASSTypes;
+
+
+extern int SD_Started;
+
+int SD_SetupFXCard ( int * numvoices, int * numbits, int * numchannels);
+int SD_Startup ( boolean bombonerror );
+int SD_Play ( int sndnum );
+void SD_Shutdown (void);
+
+int SD_PlayPositionedSound ( int sndnum, int px, int py, int x, int y );
+int SD_PlaySoundRTP        ( int sndnum, int x, int y );
+void SD_PanPositionedSound ( int handle, int px, int py, int x, int y );
+void SD_PanRTP ( int handle, int x, int y );
+void SD_SetPan ( int handle, int vol, int left, int right );
+int SD_Play3D ( int sndnum, int angle, int distance );
+int SD_PlayPitchedSound ( int sndnum, int volume, int pitch );
+void SD_SetSoundPitch ( int sndnum, int pitch );
+boolean SD_SoundOkay ( int sndnum );
+
+//***************************************************************************
+//
+// SD_WaitSound - wait until a sound has finished
+//
+//***************************************************************************
+void SD_WaitSound ( int handle );
+
+//***************************************************************************
+//
+// SD_StopSound
+//
+//***************************************************************************
+void  SD_StopSound ( int handle );
+
+//***************************************************************************
+//
+// SD_SoundActive
+//
+//***************************************************************************
+int SD_SoundActive ( int handle );
+
+//***************************************************************************
+//
+// SD_StopAllSounds
+//
+//***************************************************************************
+void  SD_StopAllSounds ( void );
+
+
+typedef enum {
+   song_gason,
+   song_bosssee,
+   song_bossdie,
+   song_endlevel,
+   song_dogend,
+   song_title,
+   song_apogee,
+   song_youwin,
+   song_level,
+   song_elevator,
+   song_secretmenu,
+   song_cinematic1,
+   song_cinematic2,
+   song_cinematic3,
+   song_gameover,
+   song_christmas,
+   song_snakechase,
+   song_menu
+} songtypes;
+
+
+
+void MU_Shutdown ( void );
+int MU_Startup ( boolean bombonerror );
+void MU_PlaySong ( int num );
+void MU_StopSong ( void );
+
+//***************************************************************************
+//
+// MU_Continue
+//
+//***************************************************************************
+#define MU_Continue() MUSIC_Continue()
+
+//***************************************************************************
+//
+// MU_Pause
+//
+//***************************************************************************
+#define MU_Pause() MUSIC_Pause()
+
+//***************************************************************************
+//
+// MU_GetVolume
+//
+//***************************************************************************
+#define MU_GetVolume() MUSIC_GetVolume()
+
+//***************************************************************************
+//
+// MU_SetVolume
+//
+//***************************************************************************
+#define MU_SetVolume(x) MUSIC_SetVolume(x)
+
+//***************************************************************************
+//
+// MU_SongPlaying
+//
+//***************************************************************************
+#define MU_SongPlaying() MUSIC_SongPlaying()
+
+//***************************************************************************
+//
+// MU_FadeVolume
+//
+//***************************************************************************
+#define MU_FadeVolume(v,m) MUSIC_FadeVolume(v,m)
+
+//***************************************************************************
+//
+// MU_FadeActive
+//
+//***************************************************************************
+#define MU_FadeActive() MUSIC_FadeActive()
+
+//***************************************************************************
+//
+// MU_StopFade
+//
+//***************************************************************************
+#define MU_StopFade() MUSIC_StopFade()
+
+
+//***************************************************************************
+//
+// MU_FadeIn
+//
+//***************************************************************************
+void MU_FadeIn ( int num, int time );
+
+//***************************************************************************
+//
+// MU_FadeOut
+//
+//***************************************************************************
+void MU_FadeOut ( int time );
+
+//***************************************************************************
+//
+// MU_FadeToSong
+//
+//***************************************************************************
+void MU_FadeToSong ( int num, int time );
+
+//***************************************************************************
+//
+// SD_PreCacheSoundGroup
+//
+//***************************************************************************
+void SD_PreCacheSoundGroup ( int lo, int hi );
+
+//***************************************************************************
+//
+// SD_PreCacheSound
+//
+//***************************************************************************
+
+void SD_PreCacheSound ( int num );
+
+void MU_StartSong ( int songtype );
+
+void MU_JukeBoxMenu( void );
+
+void MU_StoreSongPosition ( void );
+
+void MU_RestoreSongPosition ( void );
+
+int MU_GetSongPosition ( void );
+
+void MU_SetSongPosition ( int position );
+
+int MU_GetSongNumber ( void );
+
+int MU_GetNumForType ( int songtype );
+
+int MU_GetStoredPosition ( void );
+
+void MU_SetStoredPosition ( int position );
+
+void MU_LoadMusic (byte * buf, int size);
+
+void MU_SaveMusic (byte ** buf, int * size);
+
+boolean MusicStarted( void );
+#endif

Added: tags/rott-1.1/rott/rt_spbal.c
===================================================================
--- tags/rott-1.1/rott/rt_spbal.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_spbal.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,506 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "watcom.h"
+#include "splib.h"
+#include "rt_draw.h"
+#include "rt_playr.h"
+#include "isr.h"
+#include <stdlib.h>
+#include "rt_spbal.h"
+#include "_rt_spba.h"
+#include "sbconfig.h"
+#include "rt_main.h"
+#include "rt_map.h"
+
+#include "rt_debug.h"
+#include "rt_game.h"
+#include "rt_str.h"
+#include "rt_vid.h"
+#include "rt_playr.h"
+#include "rt_actor.h"
+#include "rt_main.h"
+#include "rt_util.h"
+#include "rt_draw.h"
+#include "rt_in.h"
+#include "z_zone.h"
+#include "rt_ted.h"
+#include "rt_view.h"
+#include "develop.h"
+#include "version.h"
+#include "scriplib.h"
+#include <stdlib.h>
+
+#ifdef DOS
+#include <conio.h>
+#include <io.h>
+#include <fcntl.h>
+#include <dos.h>
+#include <mem.h>
+#endif
+//MED
+#include "memcheck.h"
+
+#ifdef DOS
+/* This file and associated .h files and Spaceball libraries:
+   Copyright 1995 Spacetec IMC Corporation
+*/
+//static char c[]="Copyright 1995 Spacetec IMC Corporation";
+
+
+#define MSGN(x)    (((x)>0)?1:-1)
+#define MABS(x)    ((x<0)?(-x):(x))
+
+#define FF(n) FLOAT_TO_FIXED(n)
+
+#define MAX_WARPS 1  // maximum number of ranges in all warps in defaultWarps
+static WarpRange defaultWarps[][MAX_WARPS]={
+    {{  0, 511, FF(0.00013)}},   // Tx
+    {{  0, 511, FF(0.0075 )}},   // Ty
+	 {{  0, 511, FF(0.0005 )}},   // Tz
+    {{150, 511, FF(0.0075 )}},   // Rx
+	 {{  0, 511, FF(0.15   )}}	   // Ry
+};
+
+#undef FF
+
+
+static WarpRecord defaultRecords[]={
+	 {"Tx",  defaultWarps[0], 1},
+	 {"Ty",  defaultWarps[1], 1},
+	 {"Tz",  defaultWarps[2], 1},
+	 {"Rx",  defaultWarps[3], 1},
+	 {"Ry",  defaultWarps[4], 1},
+};
+
+WarpRecord *WarpTx, *WarpTy, *WarpTz, *WarpRx, *WarpRy;
+
+static char *SpaceBallConfigName = "spwrott.cfg";
+static char *ApogeePath = "APOGEECD";
+
+#define    TURBO_LIMIT          1000000
+static int turbo_increment    = 500000,
+           turbo_count        = 0,
+           turboFire          = false;
+
+
+// sbbuttons mask: 00FE DCBA
+
+#define BUTTON_A    0x01
+#define BUTTON_B    0x02
+#define BUTTON_C    0x04
+#define BUTTON_D    0x08
+#define BUTTON_E    0x10
+#define BUTTON_F    0x20
+
+// All possible button assignment masks (with defaults)
+static
+short turboFireMask      = BUTTON_A,
+      attackMask         = BUTTON_B,
+      useMask            = BUTTON_C,
+      mapMask            = 0,
+      swapWeaponMask     = BUTTON_D,
+      singleAxisMask     = 0,
+      planarMask         = 0,
+      aimMask            = BUTTON_E,
+      pauseMask          = BUTTON_F;
+
+// Array exists just to make sure two tasks are not assigned to same button
+static short *masks[6]={&turboFireMask,  &attackMask, &useMask,
+                        &swapWeaponMask, &aimMask,    &pauseMask};
+
+
+
+//******************************************************************************
+//
+// ShiftTowardZero ()
+//
+//******************************************************************************
+
+static short
+ShiftTowardZero(short n, short amount)
+{
+   if (MABS(n) >= amount)
+      return n-((n>0)?amount:-amount);
+   else
+      return 0;
+}
+
+
+//******************************************************************************
+//
+// SPW_SingleAxisFilter
+//
+//  Zeroes all but the largest (in absolute value) element in a RawPacket
+//
+//   returns: nothing
+//
+//******************************************************************************
+
+static void
+SPW_SingleAxisFilter(SpwRawData *p)
+{
+    short *array   = &(p->tx),  // hope the data are in contigous locations
+          *largest = array,
+           newabs, large, array_length = 6;
+
+    large = MABS( *array );
+    while (--array_length > 0) {
+        ++array;
+        newabs = MABS(*array);
+        if (newabs > large) {
+            *largest = 0;
+            large = newabs;
+            largest = array;
+        } else
+            *array = 0;
+    }
+
+} /* end of SPW_SingleAxisFilter */
+
+
+
+//******************************************************************************
+//
+// HandleSpaceBallMotion ()
+//
+//******************************************************************************
+
+static void HandleSpaceBallMotion (SpwRawData * npacket, int controlbuf[])
+{
+
+   int    strafeAngle;
+   short  tx, ty, tz, rx, ry;
+   long   sbtx, sbty, sbtz, sbrx, sbry;
+   static short ButtonState;
+
+   // If they are really cranking on it, limit them to one axis at a time
+   if ((MABS(npacket->tx) > 450) ||
+       (MABS(npacket->ty) > 450) ||
+       (MABS(npacket->tz) > 450) ||
+       (MABS(npacket->rx) > 450) ||
+       (MABS(npacket->ry) > 450)) SPW_SingleAxisFilter(npacket);
+
+   // Don't want to lose the low end that the sb null_region calc is losing
+   tx=ShiftTowardZero(npacket->tx,30);   // range now approximately +/- 0-480
+   ty=ShiftTowardZero(npacket->ty,30);   // range now approximately +/- 0-480
+   tz=ShiftTowardZero(npacket->tz,50);   // range now approximately +/- 0-460
+   rx=ShiftTowardZero(npacket->rx,60);   // range now approximately +/- 0-450
+   ry=ShiftTowardZero(npacket->ry,60);   // range now approximately +/- 0-450
+
+   sbtx = SbFxConfigWarp( WarpTx, tx );
+   sbty = SbFxConfigWarp( WarpTy, ty );
+   sbtz = SbFxConfigWarp( WarpTz, tz );
+   sbrx = SbFxConfigWarp( WarpRx, rx );
+   sbry = SbFxConfigWarp( WarpRy, ry );
+
+   strafeAngle = (player->angle - FINEANGLES/4)&(FINEANGLES-1);
+
+   // check for turboFire
+   if (turboFire)
+      {
+      if (MABS(turbo_count) > TURBO_LIMIT)
+         turbo_increment *= -1;
+      turbo_count += turbo_increment;
+      sbry += turbo_increment;
+      }
+
+   controlbuf[0] += -(FixedMul (sbtz, viewcos))+
+                     FixedMul (sbtx, costable[strafeAngle]);
+
+   controlbuf[1] +=  FixedMul (sbtz, viewsin) -
+                    FixedMul (sbtx, sintable[strafeAngle]);
+
+   controlbuf[2] += sbry;
+
+
+
+   // Handle looking up and down ^ flying
+
+   ButtonState=npacket->buttons.cur;
+
+   // should the user be running?
+   buttonpoll[bt_run] = true; //((MABS(tx)+MABS(tz)+MABS(ry)) > 320) ? true : false ;
+
+
+   // TY does flying if the user has acquired the ability to fly.
+   // Currently this is ^'ed with looking up and down
+   if (player->flags & FL_FLEET)
+      {
+      if (sbty != 0)
+         {
+         if (sbty > 0)
+            buttonpoll[bt_lookup  ] = true;
+         else
+            buttonpoll[bt_lookdown] = true;
+         }
+      }
+   else  // Lookup/down || aim up/down ?
+      {
+      if ( sbrx != 0 )
+         {
+         if (sbrx > 0)
+            {
+            if (ButtonState & aimMask)
+               buttonpoll[bt_horizonup] = true;
+            else
+               buttonpoll[bt_lookup] = true;
+            }
+         else
+            {
+            if (ButtonState & aimMask)
+               buttonpoll[bt_horizondown] = true;
+            else
+               buttonpoll[bt_lookdown] = true;
+            }
+         }
+      }
+
+
+}
+
+//******************************************************************************
+//
+// PollSpaceBall ()
+//
+//******************************************************************************
+
+void PollSpaceBall (void)
+{
+   SpwRawData rawpacket;
+	short buttonsChanged;
+   static short buttonState=0;
+   static int reusePacketNTimes=0;
+   static SpwRawData lastPacket;
+
+   memset(&rawpacket,0,sizeof(rawpacket));
+   if (SpwSimpleGet(0,&rawpacket))
+      {
+      lastPacket=rawpacket;
+      reusePacketNTimes=6;
+      }
+   else if (reusePacketNTimes > 0)
+      {
+      rawpacket=lastPacket;
+      --reusePacketNTimes;
+      }
+   else if (buttonState) // did not get a packet but a button is down
+      rawpacket.buttons.cur=lastPacket.buttons.cur;
+   else
+      return;
+
+
+   buttonsChanged=buttonState ^ rawpacket.buttons.cur;
+   buttonState=rawpacket.buttons.cur;
+
+   buttonpoll[bt_attack] = (turboFire = (buttonState & turboFireMask) ? true : false );
+
+   if (buttonState & mapMask)          DoMap(player->tilex,player->tiley);
+   if (buttonState & useMask)          buttonpoll[bt_use]        = true;
+   if (buttonState & attackMask)       buttonpoll[bt_attack]     = true;
+   if (buttonState & swapWeaponMask)   buttonpoll[bt_swapweapon] = true;
+   if (buttonState & singleAxisMask)   SPW_SingleAxisFilter(&rawpacket);
+   if (buttonState & planarMask)       rawpacket.ty=rawpacket.rz=rawpacket.rx=0;
+   if (buttonState & pauseMask)        PausePressed=true;
+   if (!PausePressed)                  HandleSpaceBallMotion(&rawpacket,controlbuf);
+}
+
+
+//******************************************************************************
+//
+// OpenSpaceBall ()
+//
+//******************************************************************************
+
+void OpenSpaceBall (void)
+{
+   int  btn;
+   char filename[ 128 ];
+
+   if (SpwSimpleOpen(0))
+      {
+      SpwRawData sp;
+
+      SpaceBallPresent = true;
+      printf("Test the Spaceball by moving the ball and/or pressing buttons.\n");
+      printf("Exit test by pressing any keyboard key...\n");
+      while(!kbhit())
+         {
+
+         if (SpwSimpleGet(0,&sp))
+            printf("\r# tx: %4d ty: %4d tz: %4d # rx: %4d ry: %4d rz: %4d # b:  %1c-%1c-%1c-%1c-%1c-%1c",
+                  sp.tx, sp.ty, sp.tz,
+                  sp.rx,  sp.ry,  sp.rz,
+                  sp.buttons.cur &  1 ? 'A':' ', sp.buttons.cur &  2 ? 'B':' ',
+                  sp.buttons.cur &  4 ? 'C':' ', sp.buttons.cur &  8 ? 'D':' ',
+                  sp.buttons.cur & 16 ? 'E':' ', sp.buttons.cur & 32 ? 'F':' ');
+         }
+
+      // Check for configuration file, set defaults if none
+
+      GetPathFromEnvironment( filename, ApogeePath, SpaceBallConfigName );
+
+	   SbConfigParse(filename);
+
+      // Check for warp records
+   	WarpTx = SbConfigGetWarpRange("Tx");
+   	WarpTy = SbConfigGetWarpRange("Ty");
+   	WarpTz = SbConfigGetWarpRange("Tz");
+   	WarpRx = SbConfigGetWarpRange("Rx");
+   	WarpRy = SbConfigGetWarpRange("Ry");
+
+	   if(!WarpTx) WarpTx = &defaultRecords[0];
+	   if(!WarpTy) WarpTy = &defaultRecords[1];
+   	if(!WarpTz) WarpTz = &defaultRecords[2];
+   	if(!WarpRx) WarpRx = &defaultRecords[3];
+   	if(!WarpRy) WarpRy = &defaultRecords[4];
+
+      // Check for button assignments
+	   if((btn=SbConfigGetButtonNumber("TURBO_FIRE"))!=-1)
+         {
+         if (masks[btn])
+            *(masks[btn]) = 0; // zero out mask previously assigned to button
+         masks[btn]= &turboFireMask;
+		   turboFireMask=(short)(1<<btn);
+         }
+
+	   if((btn=SbConfigGetButtonNumber("ATTACK"))!=-1)
+         {
+         if (masks[btn])
+            *masks[btn] = 0; // zero out mask previously assigned to button
+         masks[btn]= &attackMask;
+		   attackMask=(short)(1<<btn);
+         }
+
+	   if((btn=SbConfigGetButtonNumber("USE"))!=-1)
+         {
+         if (masks[btn])
+            *masks[btn] = 0; // zero out mask previously assigned to button
+         masks[btn]= &useMask;
+		   useMask=(short)(1<<btn);
+         }
+
+	   if((btn=SbConfigGetButtonNumber("MAP"))!=-1)
+         {
+         if (masks[btn])
+            *masks[btn] = 0; // zero out mask previously assigned to button
+         masks[btn]= &mapMask;
+		   mapMask=(short)(1<<btn);
+         }
+
+	   if((btn=SbConfigGetButtonNumber("SWAP_WEAPON"))!=-1)
+         {
+         if (masks[btn])
+            *masks[btn] = 0; // zero out mask previously assigned to button
+         masks[btn]= &swapWeaponMask;
+		   swapWeaponMask=(short)(1<<btn);
+         }
+
+	   if((btn=SbConfigGetButtonNumber("SINGLE_AXIS_FILTER"))!=-1)
+         {
+         if (masks[btn])
+            *masks[btn] = 0; // zero out mask previously assigned to button
+         masks[btn]= &singleAxisMask;
+		   singleAxisMask=(short)(1<<btn);
+         }
+
+	   if((btn=SbConfigGetButtonNumber("PLANAR_FILTER"))!=-1)
+         {
+         if (masks[btn])
+            *masks[btn] = 0; // zero out mask previously assigned to button
+         masks[btn]= &planarMask;
+		   planarMask=(short)(1<<btn);
+         }
+
+	   if((btn=SbConfigGetButtonNumber("AIM"))!=-1)
+         {
+         if (masks[btn])
+            *masks[btn] = 0; // zero out mask previously assigned to button
+         masks[btn]= &aimMask;
+		   aimMask=(short)(1<<btn);
+         }
+
+	   if((btn=SbConfigGetButtonNumber("PAUSE"))!=-1)
+         {
+         if (masks[btn])
+            *masks[btn] = 0; // zero out mask previously assigned to button
+         masks[btn]= &pauseMask;
+		   pauseMask=(short)(1<<btn);
+         }
+      }
+   else
+      {
+      SpaceBallPresent = false;
+      }
+}
+
+//******************************************************************************
+//
+// CloseSpaceBall ()
+//
+//******************************************************************************
+
+void CloseSpaceBall (void)
+{
+   if (SpaceBallPresent)
+      {
+      SpwSimpleClose(0);
+      }
+}
+
+//******************************************************************************
+//
+// GetSpaceBallButtons ()
+//
+//******************************************************************************
+ 
+unsigned GetSpaceBallButtons (void)
+{
+   SpwRawData sp;
+
+   return ((SpwSimpleGet(0,&sp) & SPW_BUTTON_DOWN));
+}
+
+#else
+
+/* This isn't of much use in Linux. */
+
+void PollSpaceBall (void)
+{
+	STUB_FUNCTION;
+}
+
+void OpenSpaceBall (void)
+{
+	STUB_FUNCTION;
+}
+
+void CloseSpaceBall (void)
+{
+}
+
+unsigned GetSpaceBallButtons (void)
+{
+	STUB_FUNCTION;
+	
+	return 0;
+}
+
+#endif

Added: tags/rott-1.1/rott/rt_spbal.h
===================================================================
--- tags/rott-1.1/rott/rt_spbal.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_spbal.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,34 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//   RT_spbal.h - SpaceBall stuff
+//
+//***************************************************************************
+
+#ifndef _rt_spbal_public
+#define _rt_spbal_public
+
+
+unsigned GetSpaceBallButtons (void);
+void OpenSpaceBall (void);
+void CloseSpaceBall (void);
+void PollSpaceBall (void);
+#endif

Added: tags/rott-1.1/rott/rt_sqrt.c
===================================================================
--- tags/rott-1.1/rott/rt_sqrt.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_sqrt.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,82 @@
+#include "rt_def.h"
+
+#include "rt_sqrt.h"
+
+/* 
+  C version of fixed-point Square Root functions 
+ */
+
+long FixedSqrtLP(long n)  // Low  Precision (8.8)
+{
+	/* 
+	   Not used, so unimplemented.
+	   If it matters, just copy the first half of the HP version,
+	   and multiply the answer by 256.
+	 */
+	STUB_FUNCTION;
+	
+	return 0;
+}
+
+long FixedSqrtHP(long n)  // High Precision (8.16)
+{
+	/* This is more or less a direct C transliteration of the asm code.
+	   I've replaced right shifting with division, since right shifting
+	   signed values is undefined in ANSI C (though it usually works).
+	   ROTT does not use this routine heavily. */
+	unsigned long root, mask, val;
+	signed long d;
+
+	root = 0;
+	mask = 0x40000000;
+	val = (unsigned long)n;
+ hp1:
+	d = val;
+	d -= mask;
+	if (d < 0)
+	    goto hp2;
+	d -= root;
+	if (d < 0)
+	    goto hp2;
+	
+	val = d;
+	root /= 2;
+	root |= mask;
+	mask /= 4;
+	if (mask != 0)
+	    goto hp1;
+	else
+	    goto hp5;
+ hp2:
+	root /= 2;
+	mask /= 4;
+	if (mask != 0)
+	    goto hp1;
+
+ hp5:
+	mask = 0x00004000;
+	root <<= 16;
+	val <<= 16;
+ hp3:
+	/* use add here to properly emulate the asm - SBF */
+	if ((root+mask) > val)
+	    goto hp4;
+	
+	val -= (root+mask);
+	   
+	root /= 2;
+	root |= mask;
+	mask /= 4;
+	if (mask != 0)
+	    goto hp3;
+	else
+	    goto hp6;
+ hp4:
+	root /= 2;
+	mask /= 4;
+	if (mask != 0)
+	    goto hp3;
+ hp6:
+
+	return (long)root;
+}

Added: tags/rott-1.1/rott/rt_sqrt.h
===================================================================
--- tags/rott-1.1/rott/rt_sqrt.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_sqrt.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,109 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_sqrt_public
+#define _rt_sqrt_public
+
+/*
+FUNCTION:
+    Fixed32 FixedSqrtHP(Fixed32 n);
+DESCRIPTION:
+    This does a high-precision square root of a Fixed32.  It has
+    8.16 bit accuracy.  For more speed use FixedSqrtLP().
+
+
+FUNCTION:
+    Fixed32 FixedSqrtLP(Fixed32 n);
+DESCRIPTION:
+    This does a low-precision square root of a Fixed32.  It has
+    8.8 bit accuracy.  For more accuracy use FixedSqrtHP().
+*/
+
+
+
+long FixedSqrtLP(long n);  // Low  Precision (8.8)
+long FixedSqrtHP(long n);  // High Precision (8.16)
+
+#ifdef __WATCOMC__
+#pragma aux FixedSqrtLP =            \
+    "         xor eax, eax"          \
+    "         mov ebx, 40000000h"    \
+    "sqrtLP1: mov edx, ecx"          \
+    "         sub edx, ebx"          \
+    "         jl  sqrtLP2"           \
+    "         sub edx, eax"          \
+    "         jl  sqrtLP2"           \
+    "         mov ecx,edx"           \
+    "         shr eax, 1"            \
+    "         or  eax, ebx"          \
+    "         shr ebx, 2"            \
+    "         jnz sqrtLP1"           \
+    "         shl eax, 8"            \
+    "         jmp sqrtLP3"           \
+    "sqrtLP2: shr eax, 1"            \
+    "         shr ebx, 2"            \
+    "         jnz sqrtLP1"           \
+    "         shl eax, 8"            \
+    "sqrtLP3: nop"                   \
+    parm caller [ecx]                \
+    value [eax]                      \
+    modify [eax ebx ecx edx];
+
+
+#pragma aux FixedSqrtHP =            \
+    "         xor eax, eax"          \
+    "         mov ebx, 40000000h"    \
+    "sqrtHP1: mov edx, ecx"          \
+    "         sub edx, ebx"          \
+    "         jb  sqrtHP2"           \
+    "         sub edx, eax"          \
+    "         jb  sqrtHP2"           \
+    "         mov ecx,edx"           \
+    "         shr eax, 1"            \
+    "         or  eax, ebx"          \
+    "         shr ebx, 2"            \
+    "         jnz sqrtHP1"           \
+    "         jz  sqrtHP5"           \
+    "sqrtHP2: shr eax, 1"            \
+    "         shr ebx, 2"            \
+    "         jnz sqrtHP1"           \
+    "sqrtHP5: mov ebx, 00004000h"    \
+    "         shl eax, 16"           \
+    "         shl ecx, 16"           \
+    "sqrtHP3: mov edx, ecx"          \
+    "         sub edx, ebx"          \
+    "         jb  sqrtHP4"           \
+    "         sub edx, eax"          \
+    "         jb  sqrtHP4"           \
+    "         mov ecx, edx"          \
+    "         shr eax, 1"            \
+    "         or  eax, ebx"          \
+    "         shr ebx, 2"            \
+    "         jnz sqrtHP3"           \
+    "         jmp sqrtHP6"           \
+    "sqrtHP4: shr eax, 1"            \
+    "         shr ebx, 2"            \
+    "         jnz sqrtHP3"           \
+    "sqrtHP6: nop"                   \
+    parm caller [ecx]                \
+    value [eax]                      \
+    modify [eax ebx ecx edx];
+#endif
+
+#endif

Added: tags/rott-1.1/rott/rt_stat.c
===================================================================
--- tags/rott-1.1/rott/rt_stat.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_stat.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1938 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#include "rt_def.h"
+
+#ifdef DOS
+#include <malloc.h>
+#include <dos.h>
+#endif
+
+#include <string.h>
+#include "sprites.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "rt_stat.h"
+#include "z_zone.h"
+#include "lumpy.h"
+#include "rt_util.h"
+#include "rt_draw.h"
+#include "rt_ted.h"
+#include "rt_door.h"
+#include "rt_main.h"
+#include "w_wad.h"
+#include "rt_main.h"
+#include "rt_rand.h"
+#include "rt_menu.h"
+#include "rt_sound.h"
+#include "_rt_stat.h"
+#include "rt_net.h"
+#include "rt_view.h"
+#include "isr.h"
+//MED
+#include "memcheck.h"
+
+
+
+/*
+=============================================================================
+
+Global Variables                                                                                                                                 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+statobj_t   *firstactivestat,*lastactivestat;
+statobj_t   *firstemptystat,*lastemptystat;
+
+wall_t      switches[MAXSWITCHES],*lastswitch;
+respawn_t   *firstrespawn,*lastrespawn;
+statobj_t	*FIRSTSTAT,*LASTSTAT,*sprites[MAPSIZE][MAPSIZE];
+animwall_t  animwalls[MAXANIMWALLS];
+
+dirtype opposite[9] =
+	{west,southwest,south,southeast,east,northeast,north,northwest,nodir};
+
+
+
+
+
+
+statinfo stats[NUMSTATS] =
+{
+{0,SPR0_YLIGHT, stat_ylight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
+{0,SPR1_RLIGHT, stat_rlight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
+{0,SPR2_GLIGHT, stat_glight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
+{0,SPR3_BLIGHT, stat_blight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
+{0,SPR4_CHAND, stat_chandelier,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
+{0,SPR5_LAMPOFF, stat_lamp,FL_LIGHT|FL_BLOCK|FL_SHOOTABLE,0,0,2,0,0},
+{0,SPR73_GKEY1, stat_pedgoldkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_orange,0,0},
+{0,SPR73_GKEY1,stat_pedsilverkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_gray,0,0},
+{0,SPR73_GKEY1, stat_pedironkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_olive,0,0},
+{0,SPR73_GKEY1,stat_pedcrystalkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_red,0,0},
+{0,SPR6_GIBS1,  stat_gibs1,0,0,0,0,0,0},
+{0,SPR7_GIBS2,  stat_gibs2,0,0,0,0,0,0},
+{0,SPR8_GIBS3,  stat_gibs3,0,0,0,0,0,0},
+{0,SPR9_MONKMEAL, stat_monkmeal,FL_BONUS|FL_RESPAWN,0,0,0,0,0},
+{0,PORRIDGE1, stat_priestporridge,FL_BONUS|FL_RESPAWN,2,6,0,0,0},
+{0,MONKCRYSTAL11,stat_monkcrystal1,FL_BONUS|FL_ACTIVE|FL_RESPAWN,2,6,0,0,0},
+{0,MONKCRYSTAL21,stat_monkcrystal2,FL_BONUS|FL_ACTIVE|FL_RESPAWN,2,7,0,0,0},
+{0,ONEUP01,stat_oneup,FL_BONUS|FL_ACTIVE|FL_FULLLIGHT,2,8,0,0,0},
+{0,THREEUP01,stat_threeup,FL_BONUS|FL_ACTIVE|FL_FULLLIGHT,2,8,0,0,0},
+{0,TORCH1,stat_altbrazier1,FL_HEAT|FL_BLOCK|FL_ACTIVE|FL_LIGHT|FL_SHOOTABLE,2,15,2,0,0},
+{0,SPR_ABRAZIER2,stat_altbrazier2,FL_HEAT|FL_BLOCK|FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
+{0,FBASIN1,stat_healingbasin,FL_BONUS|FL_CHANGES|FL_ACTIVE|FL_BLOCK,2,3,0,0,0},
+{20,EBASIN,stat_emptybasin,FL_BLOCK|FL_SHOOTABLE,0,0,0,0,0},
+{0,BAT1,stat_bat,FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_WEAPON,1,16,0,0,10},
+{0,KNIFE_STATUE1,stat_knifestatue,FL_BONUS|FL_CHANGES|FL_BLOCK,0,0,0,0,0},
+{0,SPR_TWOPIST,stat_twopistol,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5},
+{0,SPR_MP40,stat_mp40,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5},
+{0,SPR_BAZOOKA,stat_bazooka,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,10},
+{0,SPR_FIREBOMB,stat_firebomb,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5},
+{0,SPR_HEATSEEK,stat_heatseeker,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7},
+{0,SPR_DRUNK,stat_drunkmissile,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7},
+{0,SPR_FIREWALL,stat_firewall,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5},
+{0,SPR_SPLIT,stat_splitmissile,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7},
+{0,SPR_KES,stat_kes,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7},
+{0,LIFEITEMA01,stat_lifeitem1,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,8, 2,0,0},
+{0,LIFEITEMB01,stat_lifeitem2,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,8, 2,0,0},
+{0,LIFEITEMD01,stat_lifeitem3,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,8, 2,0,0},
+{0,LIFEITEMC01,stat_lifeitem4,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,15, 2,0,0},
+{24,SPR32_EXPLOS,stat_tntcrate,FL_SHOOTABLE|FL_BLOCK|FL_WOODEN,0,0,3,10,0},
+{12,SPR33_CBARREL,stat_bonusbarrel,FL_METALLIC|FL_SHOOTABLE|FL_BLOCK,0,0,3,10,0},
+{0,TORCH1,stat_torch,FL_BLOCK|FL_LIGHT|FL_ACTIVE|FL_HEAT|FL_SHOOTABLE,2,15,2,0,0},
+{30,FFLAME1,stat_floorfire,FL_HEAT|FL_BLOCK|FL_LIGHT|FL_ACTIVE|FL_SHOOTABLE,2,7,30,0,0},
+{0,DIP11,stat_dipball1,FL_BONUS|FL_FULLLIGHT,0,0,0,0,0},
+{0,DIP21,stat_dipball2,FL_BONUS|FL_FULLLIGHT,0,0,0,0,0},
+{0,DIP31,stat_dipball3,FL_BONUS|FL_FULLLIGHT,0,0,0,0,0},
+{0,SPR34_TOUCH1,stat_touch1,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0},
+{0,SPR35_TOUCH2,stat_touch2,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0},
+{0,SPR36_TOUCH3,stat_touch3,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0},
+{0,SPR37_TOUCH4,stat_touch4,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0},
+{20,SPR62_ETOUCH1,stat_dariantouch,FL_METALLIC|FL_BANDF|FL_SHOOTABLE|FL_BLOCK,10,3,50,0,0},
+{0,SCOTHEAD1, stat_scotthead,FL_BONUS|FL_ACTIVE|FL_FULLLIGHT,4,7,0,0,0},
+{0,SPR38_GARBAGE1,stat_garb1,0,0,0,0,0,0},
+{0,SPR39_GARBAGE2,stat_garb2,0,0,0,0,0,0},
+{0,SPR40_GARBAGE3,stat_garb3,0,0,0,0,0,0},
+{0,SPR41_SHIT,stat_shit,0,0,0,0,0,0},
+{0,SPR42_GRATE,stat_grate,0,0,0,0,0,0},
+{0,SPR43_MSHARDS,stat_metalshards,0,0,0,0,0,0},
+{20,SPR44_PEDESTAL,stat_emptypedestal,FL_BLOCK|FL_SHOOTABLE|FL_WOODEN,0,0,60,0,0},
+{20,SPR45_ETABLE,stat_emptytable,FL_BLOCK|FL_SHOOTABLE|FL_WOODEN,0,0,100,0,0},
+{16,SPR46_STOOL,stat_stool,FL_BLOCK|FL_SHOOTABLE|FL_WOODEN,0,0,25,0,0},
+{0,SPR_PUSHCOLUMN1,stat_bcolumn,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0},
+{0,SPR_PUSHCOLUMN1,stat_gcolumn,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0},
+{0,SPR_PUSHCOLUMN1,stat_icolumn,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0},
+{20,SPR50_TREE,stat_tree,FL_SHOOTABLE|FL_BLOCK,0,0,0,0,0},
+{20,SPR51_PLANT,stat_plant,FL_SHOOTABLE|FL_BLOCK,0,0,0,0,0},
+{20,BLUEVASE,stat_urn,FL_SHOOTABLE|FL_BLOCK,0,0,0,0,0},
+{0,SPR54_HAY,stat_haystack,FL_SHOOTABLE|FL_BLOCK,0,0,20,0,0},
+{12,SPR55_IBARREL,stat_ironbarrel,FL_METALLIC|FL_BLOCK|FL_SHOOTABLE,0,0,50,0,0},
+{0,HGRATE1,stat_heatgrate,FL_LIGHT|FL_ACTIVE,2,4,0,5,0},
+{-10,STNPOLE1,stat_standardpole,FL_SHOOTABLE|FL_BLOCK,0,0,25,0,0},
+{0,PREPIT,stat_pit,FL_CHANGES,0,0,0,0,0},
+{0,GODPOWERUP1,stat_godmode,FL_WEAPON|FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0},
+{0,DOGPOWERUP1,stat_dogmode,FL_WEAPON|FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0},
+{0,FLEETFEETPOWERUP1,stat_fleetfeet,FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0},
+{0,ELASTICPOWERUP1, stat_elastic, FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0},
+{0,MUSHROOMPOWERUP1, stat_mushroom, FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0},
+{0,GASMASKPOWERUP, stat_gasmask, FL_BONUS|FL_RESPAWN,0,0,0,0,0},
+{0,BULLETPROOFPOWERUP, stat_bulletproof, FL_BONUS|FL_RESPAWN,0,0,0,0,0},
+{0,ASBESTOSPOWERUP, stat_asbesto, FL_BONUS|FL_RESPAWN,0,0,0,0,0},
+{0,RANDOMPOWERUP1, stat_random, FL_BONUS|FL_ACTIVE|FL_RESPAWN,2,8,0,0,0},
+{0,RUBBLE1, stat_rubble, FL_ACTIVE,2,10,0,0,0},
+{0,WOODFRAG1, stat_woodfrag, FL_ACTIVE,2,14,0,0,0},
+{0,ROBOGRDDIE1, stat_metalfrag, FL_ACTIVE,2,10,0,0,0},
+{0,EMPTY_STATUE1,stat_emptystatue,FL_BLOCK|FL_SHOOTABLE,0,0,50,0,0},
+{16,TOMLARVA1,stat_tomlarva,FL_ACTIVE|FL_SHOOTABLE|FL_BLOCK,2,4,150,0,0},
+{0,BULLETHOLE,stat_bullethole,FL_TRANSLUCENT,0,0,0,0,0},
+//MED
+#if (SHAREWARE == 1)
+{0,COLLECTOR1,stat_collector,FL_ACTIVE|FL_BONUS,2,8,-1,0,0},
+#else
+{0,DOPE1,stat_collector,FL_ACTIVE|FL_BONUS,2,8,-1,0,0},
+#endif
+{0,SPR_MINE1,stat_mine,FL_BONUS|FL_SHOOTABLE|FL_RESPAWN,0,0,10,0,0},
+{0,MISSMOKE1,stat_missmoke,FL_ACTIVE,6,4,0,0,0},
+{0,PLATFORM1,stat_disk,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0},
+{-1,0,0,0,0,0,0,0,0}
+};
+
+
+dirtype diagonal[9][9] =
+{
+/* east */  {nodir,nodir,northeast,nodir,nodir,nodir,southeast,nodir,nodir},
+			{nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir},
+/* north */ {northeast,nodir,nodir,nodir,northwest,nodir,nodir,nodir,nodir},
+			{nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir},
+/* west */  {nodir,nodir,northwest,nodir,nodir,nodir,southwest,nodir,nodir},
+			{nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir},
+/* south */ {southeast,nodir,nodir,nodir,southwest,nodir,nodir,nodir,nodir},
+			{nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir},
+			{nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir}
+};
+
+/*
+=============================================================================
+
+Local Variables                                                                                                                                 GLOBAL VARIABLES
+
+=============================================================================
+*/
+static awallinfo_t animwallsinfo[MAXANIMWALLS] =
+  {{3,4,"FPLACE1\0"}, //lava wall
+   {3,6,"ANIMY1\0"}, //anim red
+   {3,6,"ANIMR1\0"}, //anim yellow
+   {40,4,"ANIMFAC1\0"}, //anim face
+   {3,4,"ANIMONE1\0"}, //anim one
+   {3,4,"ANIMTWO1\0"}, //anim two
+   {3,4,"ANIMTHR1\0"}, //anim three
+   {3,4,"ANIMFOR1\0"}, //anim four
+   {3,6,"ANIMGW1\0"}, //anim grey water
+   {3,6,"ANIMYOU1\0"}, //anim you do not belong
+   {3,6,"ANIMBW1\0"}, //anim brown water
+   {3,6,"ANIMBP1\0"}, //anim brown piston
+   {3,6,"ANIMCHN1\0"}, //anim chain
+   {3,6,"ANIMFW1\0"}, //anim firewall
+   {3,6,"ANIMLAT1\0"}, //anim little blips
+   {3,6,"ANIMST1\0"}, //anim light streams left
+   {3,6,"ANIMRP1\0"}};//anim light streams right
+
+int statcount;
+
+void AddRespawnStatic(respawn_t*stat);
+void DoLights (int tilex, int tiley);
+
+void AddToFreeStaticList(statobj_t*stat)
+{ if (!firstemptystat)
+	 firstemptystat = stat;
+  else
+	 {stat->statprev = lastemptystat;
+	  lastemptystat->statnext = stat;
+	 }
+  lastemptystat = stat;
+
+}
+
+
+void RemoveFromFreeStaticList(statobj_t*stat)
+{
+  if (stat == lastemptystat)
+		lastemptystat = stat->statprev;
+  else
+		stat->statnext->statprev = stat->statprev;
+
+  if (stat == firstemptystat)
+		firstemptystat = stat->statnext;
+  else
+		stat->statprev->statnext = stat->statnext;
+
+  stat->statprev = NULL;
+  stat->statnext = NULL;
+
+}
+
+
+
+
+/*
+===============
+=
+= MakeStatActive
+=
+===============
+*/
+
+void MakeStatActive(statobj_t*x)
+ {if (!firstactivestat)
+	 firstactivestat	= x;
+  else
+	  {x->prevactive = lastactivestat;
+		lastactivestat->nextactive = x;
+	  }
+  lastactivestat = x;
+ }
+
+
+/*
+===============
+=
+= MakeStatInactive
+=
+===============
+*/
+
+void MakeStatInactive(statobj_t*stat)
+{
+ if (stat == lastactivestat)
+	lastactivestat = stat->prevactive;
+ else
+	stat->nextactive->prevactive = stat->prevactive;
+
+ if (stat == firstactivestat)
+	firstactivestat = stat->nextactive;
+ else
+	stat->prevactive->nextactive = stat->nextactive;
+
+ stat->prevactive = NULL;
+ stat->nextactive = NULL;
+
+}
+/*
+===============
+=
+= AddStatic
+=
+===============
+*/
+
+void AddStatic(statobj_t *stat)
+ {if (FIRSTSTAT)
+	 {stat->statprev = LASTSTAT;
+	  LASTSTAT->statnext = stat;
+	 }
+  else
+	 FIRSTSTAT = stat;
+  LASTSTAT = stat;
+ }
+
+
+
+void RemoveStatic(statobj_t*stat)
+{
+   if (stat->flags & FL_ABP) //remove from active list
+      MakeStatInactive(stat);
+
+   if (stat == LASTSTAT)     // remove from master list
+      LASTSTAT = stat->statprev;
+   else
+      stat->statnext->statprev = stat->statprev;
+
+   if (stat == FIRSTSTAT)
+      FIRSTSTAT = stat->statnext;
+   else
+      stat->statprev->statnext = stat->statnext;
+
+   stat->statprev = NULL;
+   stat->statnext = NULL;
+
+   if (stat->flags & FL_WEAPON)
+      MISCVARS->NUMWEAPONS --;
+
+   if ((stat->flags & FL_RESPAWN) &&
+       gamestate.BattleOptions.RespawnItems &&
+       (!((stat->flags & FL_WEAPON ) &&
+          (gamestate.BattleOptions.WeaponPersistence)
+         )
+       )
+      )
+      {
+      respawn_t*temp;
+   //    if ( !( (stat->flags & FL_WEAPON) &&
+   //          (MISCVARS->NUMWEAPONS >= (numplayers+10))
+      //      )
+      // )
+         {
+         temp = (respawn_t*)Z_LevelMalloc(sizeof(respawn_t),PU_LEVELSTRUCT,NULL);
+
+         memset (temp,0,sizeof(*temp));
+         temp->ticcount = GetRespawnTimeForItem(stat->itemnumber);
+         temp->tilex = stat->tilex;
+         temp->tiley = stat->tiley;
+         temp->itemnumber = stat->itemnumber;
+         temp->spawnz = stat->z;
+         temp->linked_to = stat->linked_to;
+         //SoftError("\nrespawn obj created for stattype %d with z = %d",stat->itemnumber,temp->spawnz);
+         AddRespawnStatic(temp);
+         }
+      }
+   //Z_Free(stat);
+   AddToFreeStaticList(stat);
+
+   //Add_To_Delete_Array(stat);
+   statcount --;
+   }
+
+
+void RemoveRespawnStatic(respawn_t*stat)
+{
+	if (stat == lastrespawn)
+		lastrespawn = stat->prev;
+	else
+		stat->next->prev = stat->prev;
+
+	if (stat == firstrespawn)
+		firstrespawn = stat->next;
+	else
+		stat->prev->next = stat->next;
+
+	stat->prev = NULL;
+	stat->next = NULL;
+	Z_Free(stat);
+}
+
+
+void TurnOffLight(int tilex,int tiley)
+{
+  DoLights(tilex,tiley);
+  LightsInArea[MAPSPOT(tilex,tiley,0)-AREATILE]--;
+
+}
+
+
+void ActivateLight(long light)
+{statobj_t*tstat;
+
+ tstat = (statobj_t*)light;
+
+ tstat->shapenum ++;
+ tstat->flags |= FL_LIGHTON;
+ TurnOnLight(tstat->tilex,tstat->tiley);
+
+}
+
+
+void DeactivateLight(long light)
+{statobj_t*tstat;
+
+ tstat = (statobj_t*)light;
+
+ tstat->shapenum --;
+ tstat->flags &= ~(FL_LIGHTON);
+ TurnOffLight(tstat->tilex,tstat->tiley);
+
+}
+
+void TurnOnLight(int i,int j)
+{
+
+ LightsInArea[MAPSPOT(i,j,0)-AREATILE]++;
+
+ if (lightsource==0)
+    return;
+
+ if ((!(tilemap[i+1][j])) && (!(tilemap[i-1][j])))
+	{
+	SetLight(i,j,0xcdeffedc);
+	SetLight(i+1,j,0x135789ab);
+	SetLight(i-1,j,0xba987351);
+	SetLight(i,j+1,0xcdeffedc);
+	SetLight(i,j-1,0xcdeffedc);
+	SetLight(i-1,j-1,0xba987351);
+	SetLight(i+1,j+1,0xba987351);
+	SetLight(i+1,j-1,0x135789ab);
+	SetLight(i-1,j+1,0x135789ab);
+	}
+ else if ((!(tilemap[i][j+1])) && (!(tilemap[i][j-1])))
+	{
+	SetLight(i,j,0xcdeffedc);
+	SetLight(i+1,j,0xcdeffedc);
+	SetLight(i-1,j,0xcdeffedc);
+	SetLight(i,j+1,0x135789ab);
+	SetLight(i,j-1,0xba987531);
+	SetLight(i-1,j-1,0x135789ab);
+	SetLight(i+1,j-1,0xba987531);
+	SetLight(i+1,j+1,0x135789ab);
+	SetLight(i-1,j+1,0xba987531);
+	}
+					//  |
+					//__|
+ else if ((tilemap[i][j+1]) && (tilemap[i+1][j]))
+	{
+	SetLight(i,j,0xcdeffedc);
+	SetLight(i+1,j,0xcdeffedc);
+	SetLight(i-1,j,0xcdeffedc);
+	SetLight(i,j+1,0xcdeffedc);
+	SetLight(i,j-1,0xcdeffedc);
+	SetLight(i-1,j-1,0xba987351);
+	SetLight(i+1,j-1,0xba987351);
+	SetLight(i+1,j+1,0xba987351);
+	SetLight(i-1,j+1,0x135789ab);
+	}
+					//|
+					//|_
+ else if ((tilemap[i][j+1]) && (tilemap[i-1][j]))
+	{
+	SetLight(i,j,0xcdeffedc);
+	SetLight(i+1,j,0xcdeffedc);
+	SetLight(i-1,j,0xcdeffedc);
+	SetLight(i,j+1,0xcdeffedc);
+	SetLight(i,j-1,0xcdeffedc);
+	SetLight(i-1,j-1,0x135789ab);
+	SetLight(i+1,j-1,0xba987531);
+	SetLight(i+1,j+1,0xba987531);
+	SetLight(i-1,j+1,0xba987531);
+	}
+					//_
+					// |
+ else if ((tilemap[i][j-1]) && (tilemap[i+1][j]))
+	{
+	SetLight(i,j,0xcdeffedc);
+	SetLight(i+1,j,0xcdeffedc);
+	SetLight(i-1,j,0xcdeffedc);
+	SetLight(i,j+1,0xcdeffedc);
+	SetLight(i,j-1,0xcdeffedc);
+	SetLight(i-1,j-1,0xba987531);
+	SetLight(i+1,j-1,0x135789ab);
+	SetLight(i+1,j+1,0x135789ab);
+	SetLight(i-1,j+1,0xba987531);
+	}
+					//__
+					//|
+ else if ((tilemap[i][j-1]) && (tilemap[i-1][j]))
+	{
+	SetLight(i,j,0xcdeffedc);
+	SetLight(i+1,j,0xcdeffedc);
+	SetLight(i-1,j,0xcdeffedc);
+	SetLight(i,j+1,0xcdeffedc);
+	SetLight(i,j-1,0xcdeffedc);
+	SetLight(i-1,j-1,0x135789ab);
+	SetLight(i+1,j-1,0x135789ab);
+	SetLight(i+1,j+1,0xba987531);
+	SetLight(i-1,j+1,0xba987531);
+	}
+ else if (tilemap[i][j])
+	{
+	SetLight(i,j,0x58bffb85);
+	}
+ else
+	{
+	SetLight(i,j,0xcdeffedc);
+	SetLight(i+1,j,0xba987654);
+	SetLight(i-1,j,0x456789ab);
+	SetLight(i,j+1,0xba987654);
+	SetLight(i,j-1,0x456789ab);
+	SetLight(i-1,j+1,0x33322211);
+	SetLight(i+1,j+1,0x33322211);
+	SetLight(i+1,j-1,0x11222333);
+	SetLight(i-1,j-1,0x11222333);
+	}
+
+
+}
+
+
+
+
+/*===============
+=
+= AddRespawnStatic
+=
+===============
+*/
+
+void AddRespawnStatic(respawn_t*stat)
+ {
+  if (firstrespawn)
+	{stat->prev = lastrespawn;
+	 lastrespawn->next = stat;
+	}
+  else
+	firstrespawn = stat;
+  lastrespawn = stat;
+ }
+
+
+/*
+===============
+=
+= InitStaticList
+=
+===============
+*/
+
+void InitStaticList (void)
+{
+	FIRSTSTAT = NULL;
+	LASTSTAT = NULL;
+	lastactivestat = NULL;
+	firstactivestat = NULL;
+	firstrespawn = NULL;
+	lastrespawn = NULL;
+	lastemptystat = NULL;
+	firstemptystat = NULL;
+
+	memset(&BulletHoles[0],0,sizeof(BulletHoles));
+   MISCVARS->BulletHoleNum = 0;
+
+
+	memset(sprites,0,sizeof(sprites));
+	if (loadedgame==false)
+		{
+		memset(switches,0,sizeof(switches));
+		lastswitch = &switches[0];
+		}
+	statcount = 0;
+
+}
+
+
+/*
+===============
+=
+= InitAnimatedWallList
+=
+===============
+*/
+
+void InitAnimatedWallList(void)
+{
+ int i;
+
+ for (i=0;i<MAXANIMWALLS;i++)
+	 animwalls[i].active=0;
+}
+
+/*
+===============
+=
+= SetupAnimatedWall
+=
+===============
+*/
+
+void SetupAnimatedWall(int which)
+{
+   animwall_t * aw;
+   int i;
+   int texture;
+
+   aw = &animwalls[which];
+
+   aw->active=1;
+   aw->ticcount=animwallsinfo[which].tictime;
+   aw->count = 1;
+
+   texture=W_GetNumForName(animwallsinfo[which].firstlump);
+
+   aw->basetexture=texture;
+   aw->texture=texture;
+
+   if (DoPanicMapping()==true)
+      {
+      PreCacheLump(aw->basetexture,PU_CACHEWALLS,cache_pic_t);
+      }
+   else
+      {
+      for (i=aw->basetexture;i<aw->basetexture+animwallsinfo[which].numanims;i++)
+         PreCacheLump(i,PU_CACHEWALLS,cache_pic_t);
+      }
+}
+
+
+/*
+===============
+=
+= SaveStatics
+=
+===============
+*/
+
+void SaveStatics (byte **buffer, int * size)
+{statobj_t * temp;
+ saved_stat_type dummy;
+ byte * tptr;
+ int count;
+
+ if (statcount==0)
+	 {
+	 *size=0;
+	 *buffer=SafeMalloc(16);
+	 return;
+	 }
+ *size = statcount*sizeof(saved_stat_type);
+ *buffer = (byte *)SafeMalloc(*size);
+ tptr = *buffer;
+
+ for(count=0,temp=FIRSTSTAT;temp;temp=temp->statnext)
+  {dummy.x = temp->x;
+	dummy.y = temp->y;
+	dummy.z = temp->z;
+	dummy.flags = temp->flags;
+	dummy.ticcount = temp->ticcount;
+	dummy.hitpoints = temp->hitpoints;
+	dummy.shapenum = temp->shapenum;
+	dummy.ammo = temp->ammo;
+	dummy.count = temp->count;
+	dummy.numanims = temp->numanims;
+	dummy.itemnumber = temp->itemnumber;
+	dummy.areanumber = temp->areanumber;
+	temp->whichstat = count;
+	dummy.whichstat = count++;
+	dummy.linked_to = temp->linked_to;
+
+	memcpy(tptr,&(dummy.x),sizeof(saved_stat_type));
+	tptr += sizeof(saved_stat_type);
+
+  }
+
+}
+
+/*
+===============
+=
+= DoLights
+=
+===============
+*/
+
+void DoLights (int tilex, int tiley)
+{
+    if (lightsource==0)
+       return;
+	 if (TurnOffLight0 (tilex, tiley))
+       LightSourceAt(tilex,tiley) = 0;
+
+	 if (TurnOffLight1 (tilex, tiley, -1, -1))
+       LightSourceAt(tilex-1,tiley-1) = 0;
+
+	 if (TurnOffLight2 (tilex, tiley, -1))
+       LightSourceAt(tilex,tiley-1) = 0;
+
+	 if (TurnOffLight1 (tilex, tiley, 1, -1))
+       LightSourceAt(tilex+1,tiley-1) = 0;
+
+	 if (TurnOffLight3 (tilex, tiley, 1))
+       LightSourceAt(tilex+1,tiley) = 0;
+
+	 if (TurnOffLight1 (tilex, tiley, 1, 1))
+       LightSourceAt(tilex+1,tiley+1) = 0;
+
+	 if (TurnOffLight2 (tilex, tiley, 1))
+       LightSourceAt(tilex,tiley+1) = 0;
+
+	 if (TurnOffLight1 (tilex, tiley, -1, 1))
+       LightSourceAt(tilex-1,tiley+1) = 0;
+
+	 if (TurnOffLight3 (tilex, tiley, -1))
+       LightSourceAt(tilex-1,tiley) = 0;
+}
+
+
+/*
+===============
+=
+= TurnOffLight0
+=
+===============
+*/
+
+boolean TurnOffLight0 (int tilex, int tiley)
+{
+   if ( IsLight(tilex-1,tiley  ) ||
+        IsLight(tilex-1,tiley-1) ||
+        IsLight(tilex  ,tiley-1) ||
+        IsLight(tilex+1,tiley-1) ||
+        IsLight(tilex+1,tiley  ) ||
+        IsLight(tilex+1,tiley+1) ||
+        IsLight(tilex  ,tiley+1) ||
+		  IsLight(tilex-1,tiley+1) )
+		return (false);
+	else
+		return (true);
+}
+
+/*
+===============
+=
+= TurnOffLight1
+=
+===============
+*/
+
+boolean TurnOffLight1 (int tilex, int tiley, int i, int j)
+{
+	int tempi = 2*i;
+	int tempy = 2*j;
+
+   if ( IsLight(tilex+i    ,tiley  ) ||
+        IsLight(tilex+i    ,tiley+j) ||
+        IsLight(tilex      ,tiley+j) ||
+        IsLight(tilex      ,tiley+tempy) ||
+        IsLight(tilex+i    ,tiley+tempy) ||
+        IsLight(tilex+tempi,tiley+tempy) ||
+        IsLight(tilex+tempi,tiley+j) ||
+	     IsLight(tilex+tempi,tiley))
+		return (false);
+	else
+		return (true);
+}
+
+
+/*
+===============
+=
+= TurnOffLight2
+=
+===============
+*/
+
+boolean TurnOffLight2 (int tilex, int tiley, int j)
+{
+	int tempy = 2*j;
+
+   if ( IsLight(tilex-1    ,tiley  ) ||
+        IsLight(tilex-1    ,tiley+j) ||
+        IsLight(tilex-1    ,tiley+tempy) ||
+        IsLight(tilex      ,tiley+j) ||
+        IsLight(tilex      ,tiley+tempy) ||
+        IsLight(tilex+1    ,tiley) ||
+        IsLight(tilex+1    ,tiley+j) ||
+	     IsLight(tilex+1    ,tiley+tempy))
+		return (false);
+	else
+		return (true);
+}
+
+
+/*
+===============
+=
+= TurnOffLight3
+=
+===============
+*/
+
+boolean TurnOffLight3 (int tilex, int tiley, int i)
+{
+	int tempx = 2*i;
+
+   if ( IsLight(tilex      ,tiley-1) ||
+        IsLight(tilex+1    ,tiley-1) ||
+        IsLight(tilex+tempx,tiley-1) ||
+        IsLight(tilex+i    ,tiley) ||
+        IsLight(tilex+tempx,tiley) ||
+        IsLight(tilex      ,tiley+1) ||
+        IsLight(tilex+i    ,tiley+1) ||
+	     IsLight(tilex+tempx,tiley+1))
+		return (false);
+	else
+		return (true);
+}
+
+
+
+
+/*
+======================
+=
+= PreCacheStaticFrames
+=
+======================
+*/
+
+
+
+
+void PreCacheStaticFrames(statobj_t*temp)
+   {
+   int z,start,stop;
+   int female=0,black=0;
+
+   if (temp->itemnumber != stat_bullethole &&
+       ((temp->itemnumber < stat_touch1) || (temp->itemnumber > stat_touch4)))
+      PreCacheLump(temp->shapenum+shapestart,PU_CACHESPRITES,cache_patch_t);
+   else
+      PreCacheLump(temp->shapenum+shapestart,PU_CACHESPRITES,cache_transpatch_t);
+   for (z=0;z<temp->numanims;z++)
+      PreCacheLump(temp->shapenum+shapestart+z,PU_CACHESPRITES,cache_patch_t);
+
+   if (temp->flags & FL_ROTATING)
+      {
+      for (z=1;z<8;z++)
+         PreCacheLump(temp->shapenum+shapestart+z,PU_CACHESPRITES,cache_patch_t);
+      }
+
+   if (temp->flags & FL_WOODEN)
+      {
+      start = W_GetNumForName("WFRAG1");
+      stop = W_GetNumForName("WFRAG14");
+      PreCacheGroup(start,stop,cache_patch_t);
+      }
+
+   if (temp->flags & FL_METALLIC)
+      {
+      PreCacheLump(W_GetNumForName("MSHARDS"),PU_CACHESPRITES,cache_patch_t);
+      start = W_GetNumForName("ROBODIE1");
+      stop = W_GetNumForName("ROBODEAD");
+      PreCacheGroup(start,stop,cache_patch_t);
+      }
+
+   female = ((locplayerstate->player == 1) || (locplayerstate->player == 3));
+   black = (locplayerstate->player == 2);
+
+   if (female)
+      {
+      start = W_GetNumForName("FPIST11");
+      stop = W_GetNumForName("FPIST13");
+      }
+   else if (black)
+      {
+      start = W_GetNumForName("BMPIST1");
+      stop = W_GetNumForName("BMPIST3");
+      }
+   else
+      {
+      start = W_GetNumForName("MPIST11");
+      stop = W_GetNumForName("MPIST13");
+		}
+
+   PreCacheGroup(start,stop,cache_patch_t);
+
+   switch (temp->itemnumber)
+      {
+
+      case stat_pedgoldkey:
+      case stat_pedsilverkey:
+      case stat_pedironkey:
+      case stat_pedcrystalkey:
+         PreCacheLump(W_GetNumForName("PEDESTA"),PU_CACHESPRITES,cache_patch_t);
+         break;
+
+      case stat_bat:
+         start = W_GetNumForName("EXBAT1");
+         stop = W_GetNumForName("EXBAT7");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_knifestatue:
+         start = W_GetNumForName("KNIFE1");
+         stop = W_GetNumForName("KNIFE10");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_twopistol:
+         if (female)
+            {
+            start = W_GetNumForName("RFPIST1");
+            stop = W_GetNumForName("LFPIST3");
+            }
+         else if (black)
+            {
+            start = W_GetNumForName("RBMPIST1");
+            stop = W_GetNumForName("LBMPIST3");
+            }
+         else
+            {
+            start = W_GetNumForName("RMPIST1");
+            stop = W_GetNumForName("LMPIST3");
+            }
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_mp40:
+         start = W_GetNumForName("MP401");
+         stop = W_GetNumForName("MP403");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_bazooka:
+         start = W_GetNumForName("BAZOOKA1");
+         stop = W_GetNumForName("BAZOOKA4");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_firebomb:
+         start = W_GetNumForName("FBOMB1");
+         stop = W_GetNumForName("FBOMB4");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_heatseeker:
+         start = W_GetNumForName("HSEEK1");
+         stop = W_GetNumForName("HSEEK4");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_drunkmissile:
+         start = W_GetNumForName("DRUNK1");
+         stop = W_GetNumForName("DRUNK4");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_firewall:
+         start = W_GetNumForName("FIREW1");
+         stop = W_GetNumForName("FIREW3");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_splitmissile:
+         start = W_GetNumForName("SPLIT1");
+         stop = W_GetNumForName("SPLIT4");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_kes:
+         start = W_GetNumForName("KES1");
+         stop = W_GetNumForName("KES6");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+      case stat_godmode:
+         start = W_GetNumForName("GODHAND1");
+         stop = W_GetNumForName("GODHAND8");
+         PreCacheGroup(start,stop,cache_patch_t);
+
+         PreCacheGroup(W_GetNumForName("VAPO1"),
+                       W_GetNumForName("LITSOUL"),
+                       cache_patch_t);
+
+         PreCacheGroup(W_GetNumForName("GODFIRE1"),
+                       W_GetNumForName("GODFIRE4"),
+                       cache_patch_t);
+
+         break;
+      case stat_dogmode:
+         start = W_GetNumForName("DOGNOSE1");
+         stop = W_GetNumForName("DOGPAW4");
+         PreCacheGroup(start,stop,cache_patch_t);
+         break;
+
+      default:
+	  ;
+      }
+
+
+
+   }
+
+
+
+/*
+===============
+=
+= LoadStatics
+=
+===============
+*/
+
+
+
+
+void LoadStatics( byte * buffer, int size)
+{saved_stat_type dummy;
+ int stcount,i;
+ statobj_t*temp;
+
+ stcount = size/sizeof(saved_stat_type);
+ InitStaticList();
+
+ for(i=0;i<stcount;i++)
+	{
+	temp = (statobj_t*)Z_LevelMalloc(sizeof(statobj_t),PU_LEVELSTRUCT,NULL);
+	if (!temp)
+		Error("LoadStatics: Failed on allocation of static %d of %d",i,stcount);
+	memset(temp,0,sizeof(*temp));
+	memcpy(&(dummy.x),buffer,sizeof(saved_stat_type));
+	temp->whichstat = statcount++;
+	temp->x = dummy.x;
+	temp->y = dummy.y;
+	temp->z = dummy.z;
+	temp->flags = dummy.flags;
+	temp->ticcount = dummy.ticcount;
+	temp->hitpoints = dummy.hitpoints;
+	temp->shapenum = dummy.shapenum;
+	temp->ammo = dummy.ammo;
+	temp->count = dummy.count;
+	temp->numanims = dummy.numanims;
+	temp->itemnumber = dummy.itemnumber;
+	temp->areanumber = dummy.areanumber;
+	temp->linked_to = dummy.linked_to;
+
+	temp->which = SPRITE;
+	temp->tilex = temp->x >> TILESHIFT;
+	temp->tiley = temp->y >> TILESHIFT;
+	temp->flags &= ~FL_ABP;
+	temp->visspot = &spotvis[temp->tilex][temp->tiley];
+
+	if ((temp->itemnumber >= stat_touch1) &&
+		 (temp->itemnumber <= stat_touch4))
+	  {touchindices[temp->tilex][temp->tiley] = lasttouch + 1;
+		lasttouch ++;
+		SD_PreCacheSoundGroup(SD_TOUCHPLATESND,SD_BADTOUCHSND);
+	  }
+
+	AddStatic(temp);
+	if (temp->shapenum != -1)
+	  {
+     if (temp->itemnumber == stat_bullethole)
+		  {
+		  SetupBulletHoleLink(temp->linked_to,temp);
+		  }
+
+	  else if (temp->flags & FL_DEADBODY)
+		  {
+        if ( actorat[temp->tilex][temp->tiley] == NULL )
+           actorat[temp->tilex][temp->tiley] = temp;
+		  }
+
+	  else if (!(temp->flags & FL_NONMARK))
+		  {
+		  sprites[temp->tilex][temp->tiley] = temp;
+		  }
+
+     PreCacheStaticFrames(temp);
+
+
+	  }
+	PreCacheStaticSounds(temp->itemnumber);
+
+	buffer += sizeof(saved_stat_type);
+  }
+}
+
+
+void Set_NewZ_to_MapValue(fixed *newz,int zoffset,const char*errorstr,int tilex,int tiley)
+   {
+   int zf,z;
+
+   zoffset&=0xff;
+   z=zoffset>>4;
+   zf=zoffset&0xf;
+   if (z==0xf)
+      *newz = nominalheight+64-(zf<<2);
+   else
+      {
+      if (z>levelheight)
+         Error ("You specified a height of %x for the %s at tilex=%d tiley=%d when\n the level is only %d high\n",
+                 zoffset,errorstr,tilex,tiley,levelheight);
+      else
+         *newz = nominalheight-(z<<6)-(zf<<2);
+      }
+
+   }
+
+
+
+/*
+===============
+=
+= SpawnStatic
+=
+===============
+*/
+
+
+int BaseMarkerZ;//bna++			
+
+void SpawnStatic (int tilex, int tiley, int mtype, int zoffset)
+{statobj_t * temp;
+ boolean onetimer;
+
+
+
+#if (SHAREWARE == 1)
+   switch(mtype)
+      {
+      case stat_rlight:
+      case stat_glight:
+      case stat_ylight:
+      case stat_chandelier:
+         mtype = stat_blight;
+         break;
+
+      case stat_garb1:
+      case stat_garb2:
+      case stat_garb3:
+      case stat_shit:
+         mtype = stat_metalshards;
+         break;
+
+      case stat_lamp:
+         mtype = stat_altbrazier2;
+         break;
+
+      }
+#endif
+
+
+
+   if ( BATTLEMODE )
+      {
+      if ( !gamestate.BattleOptions.SpawnWeapons )
+         {
+         if ( stats[ mtype ].flags & FL_WEAPON )
+            {
+            return;
+            }
+         }
+
+      if (mtype == stat_pit)
+         return;
+
+      // Change lifeitems and extra lives to health
+      switch( mtype )
+         {
+         case stat_lifeitem1 :
+         case stat_lifeitem2 :
+            mtype = stat_monkcrystal1;
+            break;
+
+         case stat_lifeitem3 :
+         case stat_lifeitem4 :
+         case stat_oneup :
+         case stat_threeup :
+            mtype = stat_monkcrystal2;
+            break;
+         }
+
+      switch( mtype )
+         {
+         case stat_monkmeal :
+         case stat_priestporridge :
+         case stat_monkcrystal1 :
+         case stat_monkcrystal2 :
+         case stat_healingbasin :
+            if ( ( gamestate.Product != ROTT_SHAREWARE ) &&
+               ( gamestate.BattleOptions.SpawnMines ) &&
+               ( !IsPlatform( tilex, tiley ) &&
+               ( ( zoffset & 0xff00 ) != 0xb000 ) ) &&
+               ( zoffset == -1 ) )
+               {
+               mtype = stat_mine;
+               }
+            else if ( !gamestate.BattleOptions.SpawnHealth )
+               {
+               return;
+               }
+            break;
+         }
+      }
+
+ if (!firstemptystat)
+	{temp = (statobj_t*)Z_LevelMalloc(sizeof(statobj_t),PU_LEVELSTRUCT,NULL);
+	 //SoftError("\nMalloc-ing actor");
+	 //if (insetupgame)
+	  //	SoftError("in setup");
+	}
+
+ else
+	{temp = lastemptystat;
+	 //SoftError("\nfree actor available");
+	 RemoveFromFreeStaticList(lastemptystat);
+	}
+
+ // Standard pole hack
+
+ if ((zoffset>=14) && (zoffset<=17))
+	 zoffset=-1;
+
+ if (temp)
+  {  memset(temp,0,sizeof(*temp));
+	  temp->shapenum = stats[mtype].picnum;
+	  temp->whichstat = statcount ++;
+	  temp->tilex = tilex;
+	  temp->tiley = tiley;
+	  temp->x = ((long)tilex << TILESHIFT) + 0x8000;
+	  temp->y = ((long)tiley << TILESHIFT) + 0x8000;
+	  temp->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE;
+	  temp->linked_to = -1;
+	  if ((temp->areanumber<=0) || (temp->areanumber>NUMAREAS))
+		  Error ("Sprite at x=%d y=%d type=%d has an illegal areanumber\n",tilex,tiley,mtype);
+     if ( mtype == stat_mine )
+        {
+        temp->z = nominalheight;
+        }
+     else if (zoffset!=-1)
+		  {
+		  if ((zoffset&0xff00)==0xb000)
+           Set_NewZ_to_MapValue(&(temp->z),zoffset,"static",tilex,tiley);
+		  else if (IsPlatform(tilex,tiley))
+			  temp->z = PlatformHeight(tilex,tiley);
+		  else if (zoffset==11)
+			  temp->z=-65;
+		  else if (zoffset==12)
+			  temp->z=-66;
+		  else
+			  temp->z = nominalheight;
+			 // Error ("You didn't specify a valid height over the sprite at tilex=%ld tiley=%ld\n",tilex,tiley);
+		  }
+	  else if (mtype>stat_chandelier)
+		  temp->z = nominalheight;
+
+	  temp->visspot = &spotvis[tilex][tiley];
+	  temp->which = SPRITE;
+	  temp->ticcount = stats[mtype].tictime;
+	  temp->hitpoints = stats[mtype].hitpoints;
+	  temp->itemnumber = stats[mtype].type;
+     temp->flags = stats[mtype].flags;
+	  temp->ammo = stats[mtype].ammo;
+	  temp->numanims = stats[mtype].numanims;
+
+
+
+
+     if (temp->flags & FL_BONUS)
+		switch  (stats[mtype].type)
+		  {case stat_lifeitem1:
+			case stat_lifeitem2:
+			case stat_lifeitem3:
+			case stat_lifeitem4:
+			 gamestate.treasuretotal++;
+			 break;
+		  default:
+		      ;
+		  }
+
+
+
+
+      AddStatic(temp);
+
+     onetimer = ((mtype == stat_rubble) || (mtype == stat_woodfrag) ||
+                 (mtype == stat_metalfrag) || (mtype == stat_missmoke)
+                );
+
+     if (DoPanicMapping())
+        {
+        if (temp->numanims && (!onetimer))
+           {
+           temp->flags &= ~FL_ACTIVE;
+           temp->numanims = 0;
+           GameRandomNumber("SpawnStatic",mtype);
+           }
+        }
+
+     else
+        {
+        if (temp->numanims)
+           {
+           if (!onetimer)
+              temp->count = (int)(((int)GameRandomNumber("SpawnStatic",mtype) % stats[mtype].numanims) + 1);
+           else
+              temp->count = 0;
+           }
+        else if (temp->itemnumber == stat_standardpole)
+           {
+           if (MAPSPOT(temp->tilex,temp->tiley,2))
+              temp->count = 2*(MAPSPOT(temp->tilex,temp->tiley,2)-14);
+           else
+              temp->count = 0;
+           }
+
+        if ((temp->itemnumber == stat_knifestatue) ||
+            (temp->itemnumber == stat_emptystatue) ||
+            (temp->itemnumber == stat_standardpole))
+           temp->flags|=FL_ROTATING;
+        }
+
+
+
+
+     if (mtype != stat_missmoke)
+		  sprites[tilex][tiley] = temp;
+	  else
+		  temp->flags |= FL_NONMARK;
+
+
+//================ check special junk ==================================//
+
+	  if (temp->itemnumber == stat_dariantouch)
+		 {_2Dpoint *tdptr;
+
+		  tdptr = &(MISCVARS->ETOUCH[MISCVARS->nexttouch]);
+
+		  tdptr->x = tilex;
+		  tdptr->y = tiley;
+		  sprites[tilex][tiley]->linked_to = MISCVARS->nexttouch;
+		  MISCVARS->nexttouch ++;
+		 }
+	  else if ((temp->itemnumber >= stat_touch1) &&
+				  (temp->itemnumber <= stat_touch4))
+		 {touchindices[tilex][tiley] = lasttouch + 1;
+		  SD_PreCacheSoundGroup(SD_TOUCHPLATESND,SD_BADTOUCHSND);
+		  lasttouch ++;
+		 }
+
+//=====================================================================//
+	//bna added
+	// BaseMarkerZ used to adjust height in s_basemarker1
+	// in SpawnNewObj(i,j,&s_basemarker1,inertobj); 
+	BaseMarkerZ=temp->z;//bna++	BaseMarkerZ = spawnz;
+
+     PreCacheStaticFrames(temp);
+
+     PreCacheStaticSounds(temp->itemnumber);
+
+	  if (temp->flags & FL_WEAPON)
+		 MISCVARS->NUMWEAPONS ++;
+  }
+ else
+	Error("Z_LevelMalloc failed in SpawnStatic!");
+
+}
+
+/*
+===============
+=
+= SpawnInertStatic
+=
+===============
+*/
+
+void SpawnInertStatic (int x, int y, int z, int mtype)
+{statobj_t * temp;
+
+
+
+
+ if (!firstemptystat)
+	{temp = (statobj_t*)Z_LevelMalloc(sizeof(statobj_t),PU_LEVELSTRUCT,NULL);
+	 //SoftError("\nMalloc-ing actor");
+	 //if (insetupgame)
+	  //	SoftError("in setup");
+	}
+
+ else
+	{temp = lastemptystat;
+	 //SoftError("\nfree actor available");
+	 RemoveFromFreeStaticList(lastemptystat);
+	}
+
+ if (temp)
+  {  memset(temp,0,sizeof(*temp));
+	  temp->shapenum = stats[mtype].picnum;
+
+	  temp->whichstat = statcount ++;
+	  temp->tilex = x>>16;
+	  temp->tiley = y>>16;
+	  temp->x = x;
+	  temp->y = y;
+	  temp->areanumber = MAPSPOT(temp->tilex,temp->tiley,0)-AREATILE;
+	  temp->linked_to = -1;
+	  if ((temp->areanumber<=0) || (temp->areanumber>NUMAREAS))
+		  {
+		  int tilex=temp->tilex;
+		  int tiley=temp->tiley;
+
+		  FindEmptyTile(&tilex,&tiley);
+		  temp->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE;
+		  }
+	  temp->z=z;
+	  temp->visspot = &spotvis[temp->tilex][temp->tiley];
+	  temp->which = SPRITE;
+	  temp->ticcount = stats[mtype].tictime;
+	  temp->hitpoints = stats[mtype].hitpoints;
+	  temp->itemnumber = stats[mtype].type;
+	  temp->flags = (stats[mtype].flags|FL_ABP|FL_NONMARK);
+     if (fog)
+       {temp->shapenum++;
+        temp->flags &= ~FL_TRANSLUCENT;
+       }
+
+     temp->ammo = stats[mtype].ammo;
+	  temp->numanims = stats[mtype].numanims;
+	  AddStatic(temp);
+	  MakeStatActive(temp);
+  }
+ else
+	Error("Z_LevelMalloc failed in SpawnStatic!");
+
+}
+
+/*
+===============
+=
+= SpawnSolidStatic
+=
+===============
+*/
+
+void SpawnSolidStatic (statobj_t * temp)
+{
+	if (temp->flags & FL_ACTIVE)
+	  temp->flags &= ~FL_ACTIVE;
+	temp->hitpoints = INITIALFIRECOLOR;
+   temp->flags = FL_SOLIDCOLOR|FL_SEEN|FL_ABP;
+   if ((gamestate.BattleOptions.RespawnItems) &&
+       (temp->itemnumber == stat_tntcrate)
+      )
+      temp->flags |= FL_RESPAWN;
+
+   temp->ticcount = SOLIDCOLORTICTIME;
+}
+
+
+/*
+======================
+=
+= PreCacheStaticSounds
+=
+======================
+*/
+
+
+
+void PreCacheStaticSounds (int itemnumber)
+{
+
+	if (stats[itemnumber].flags & FL_SHOOTABLE)
+	  SD_PreCacheSound(SD_ITEMBLOWSND);
+
+
+   switch(itemnumber)
+
+      {
+      case    stat_pit:
+        SD_PreCacheSound(SD_PITTRAPSND);
+        break;
+
+      case    stat_bonusbarrel:
+        SD_PreCacheSound(SD_BONUSBARRELSND);
+        break;
+
+      case    stat_knifestatue:
+        SD_PreCacheSound(SD_GETKNIFESND);
+        break;
+      case    stat_gibs1:
+      case    stat_gibs2:
+      case    stat_gibs3:
+         SD_PreCacheSound (SD_ACTORSQUISHSND);
+         break;
+      case    stat_pedgoldkey:
+      case    stat_pedsilverkey:
+      case    stat_pedironkey:
+      case    stat_pedcrystalkey:
+         SD_PreCacheSound (SD_GETKEYSND);
+
+         break;
+      case    stat_monkmeal:
+         SD_PreCacheSound (SD_GETHEALTH1SND);
+         break;
+      case    stat_monkcrystal1:
+         SD_PreCacheSound (SD_GETHEALTH2SND);
+         break;
+      case   stat_monkcrystal2:
+         SD_PreCacheSound (SD_GETHEALTH2SND);
+         break;
+      case    stat_priestporridge:
+         SD_PreCacheSound (SD_GETHEALTH1SND);
+         SD_PreCacheSound(SD_COOKHEALTHSND);
+
+         break;
+
+      case   stat_healingbasin:
+         SD_PreCacheSound (SD_GETHEALTH2SND);
+         break;
+
+      case stat_oneup:
+         SD_PreCacheSound(SD_GET1UPSND);
+         break;
+      case stat_threeup:
+         SD_PreCacheSound(SD_GET3UPSND);
+         break;
+
+      case stat_scotthead:
+         SD_PreCacheSound(SD_GETHEADSND);
+         break;
+
+      case stat_twopistol:
+      case stat_mp40:
+      case stat_bazooka:
+      case stat_firebomb:
+      case stat_heatseeker:
+      case stat_drunkmissile:
+      case stat_firewall:
+      case stat_splitmissile:
+      case stat_kes:
+         SD_PreCacheSound(SD_GETWEAPONSND);
+         break;
+
+      case stat_bat:
+         SD_PreCacheSound(SD_GETBATSND);
+         break;
+
+      case stat_lifeitem1:
+      case stat_lifeitem2:
+      case stat_lifeitem3:
+      case stat_lifeitem4:
+         SD_PreCacheSound(SD_GETBONUSSND);
+         break;
+
+
+      case stat_random:
+         SD_PreCacheSound(SD_GETGODSND);
+         SD_PreCacheSound(SD_GETDOGSND);
+         SD_PreCacheSound(SD_GETELASTSND);
+         SD_PreCacheSound(SD_GETSHROOMSSND);
+         SD_PreCacheSound(SD_LOSEMODESND);
+
+         break;
+      case stat_bulletproof:
+         SD_PreCacheSound(SD_GETBVESTSND);
+         SD_PreCacheSound(SD_LOSEMODESND);
+         break;
+
+      case stat_gasmask:
+         SD_PreCacheSound(SD_GETMASKSND);
+         SD_PreCacheSound(SD_LOSEMODESND);
+         break;
+
+      case stat_asbesto:
+         SD_PreCacheSound(SD_GETAVESTSND);
+         SD_PreCacheSound(SD_LOSEMODESND);
+         break;
+
+      case stat_elastic:
+         SD_PreCacheSound(SD_GETELASTSND);
+         SD_PreCacheSound(SD_LOSEMODESND);
+         break;
+
+      case stat_fleetfeet:
+         SD_PreCacheSound(SD_GETFLEETSND);
+         SD_PreCacheSound(SD_LOSEMODESND);
+         break;
+
+      case stat_godmode:
+         SD_PreCacheSound(SD_GETGODSND);
+         SD_PreCacheSound(SD_GODMODE1SND);
+
+         break;
+
+      case stat_dogmode:
+         SD_PreCacheSound(SD_GETDOGSND);
+         break;
+
+      case stat_mushroom:
+         SD_PreCacheSound(SD_GETSHROOMSSND);
+         SD_PreCacheSound(SD_LOSEMODESND);
+
+         break;
+
+      case stat_dipball1:
+      case stat_dipball2:
+      case stat_dipball3:
+         SD_PreCacheSound(SD_GETBONUSSND);
+         break;
+
+      default:
+         SD_PreCacheSound(SD_GETBONUSSND);
+         break;
+      }
+
+}
+
+
+
+
+
+/*
+===============
+=
+= SaveSwitches
+=
+===============
+*/
+
+void SaveSwitches(byte ** buffer, int * size)
+{int numswitches,i;
+ byte * tptr;
+
+ numswitches = lastswitch-&switches[0];
+ if (numswitches==0)
+	 {
+	 *size=0;
+	 *buffer=SafeMalloc(16);
+	 return;
+	 }
+ *size = numswitches*sizeof(wall_t);
+
+ *buffer = (byte *)SafeMalloc(*size);
+ tptr = *buffer;
+
+ for(i=0;i<numswitches;i++)
+  {memcpy(tptr,&switches[i],sizeof(wall_t));
+	tptr += sizeof(wall_t);
+  }
+
+}
+
+
+/*
+===============
+=
+= LoadSwitches
+=
+===============
+*/
+
+void LoadSwitches (byte * buffer, int size)
+{int numswitches,i,tilex,tiley;
+
+ numswitches = size/sizeof(wall_t);
+
+ for(i=0;i<numswitches;i++)
+  {memcpy(&switches[i],buffer,sizeof(wall_t));
+	tilex = switches[i].tilex;
+	tiley = switches[i].tiley;
+	actorat[tilex][tiley]=&switches[i];
+	if (MAPSPOT(tilex,tiley,0) == 79) // On by default
+      {
+	   if (!(switches[i].flags & FL_ON))
+         tilemap[tilex][tiley]--;
+      }
+   else if (switches[i].flags & FL_W_INVERTED) // Hi masked wall
+      {
+      maskedwallobj_t * lastmaskobj;
+
+      lastmaskobj=maskobjlist[tilemap[tilex][tiley]&0x3ff];
+    	if (switches[i].flags & FL_ON)
+         lastmaskobj->toptexture++;
+      }
+	else if (switches[i].flags & FL_ON)
+	   tilemap[tilex][tiley]++;
+	buffer += sizeof(wall_t);
+   touchindices[tilex][tiley] = lasttouch + 1;
+	lasttouch ++;
+  }
+ lastswitch=&switches[numswitches];
+
+}
+
+
+
+/*
+===============
+=
+= SpawnSwitchThingy
+=
+===============
+*/
+
+void SpawnSwitchThingy(int tilex, int tiley)
+{
+ lastswitch->flags |= FL_SWITCH;
+ lastswitch->which = WALL;
+ lastswitch->tilex = tilex;
+ lastswitch->tiley = tiley;
+ touchindices[tilex][tiley] = lasttouch + 1;
+ lasttouch ++;
+ actorat[tilex][tiley] = lastswitch;
+ lastswitch ++;
+
+}
+
+/*
+===============
+=
+= AnimateWalls
+=
+===============
+*/
+
+void AnimateWalls(void)
+{
+	int i;
+	animwall_t * aw;
+
+   if (DoPanicMapping()==true)
+      return;
+
+   for(i=0;i<MAXANIMWALLS;i++)
+		{
+		aw=&animwalls[i];
+		if (aw->active==0)
+			continue;
+		if (aw->ticcount <= 0)
+			{
+			if (aw->count < animwallsinfo[i].numanims)
+				{
+				aw->texture = aw->basetexture + aw->count;
+				aw->count++;
+				}
+			else
+				{
+				aw->texture = aw->basetexture;
+				aw->count = 1;
+				}
+
+			while (aw->ticcount<=0)
+				aw->ticcount+=animwallsinfo[i].tictime;
+			}
+		else
+			aw->ticcount -= tics;
+		}
+}
+
+
+#define M_ResetSprites(x)  \
+  { if ((index == stat_dariantouch) && (!x->count))\
+		 {x->shapenum = stats[index].picnum;               \
+		  x->count = 1;                                     \
+		  x->ticcount = stats[index].tictime;         \
+		  x->flags &= ~FL_BACKWARDS;                   \
+		  x->flags &= ~FL_ACTIVE;                       \
+		 }                                               \
+	}
+
+
+
+
+void CheckCriticalStatics(void)
+{respawn_t *rtemp,*ddt;
+ int i,stilex,stiley;
+ statobj_t*temp,*stat;
+
+ for(rtemp = firstrespawn;rtemp;)
+	{rtemp->ticcount --;
+	 ddt = rtemp->next;
+
+	 if (rtemp->ticcount <=0)
+		 {int stype;
+
+		  stilex = rtemp->tilex;
+		  stiley = rtemp->tiley;
+
+		  // if another weapon is there, nuke it
+		  if (sprites[stilex][stiley])
+			 {RemoveStatic(sprites[stilex][stiley]);
+			  sprites[stilex][stiley] = NULL;
+			 }
+
+        if (rtemp->itemnumber == stat_tntcrate)
+           {
+           RemoveStatic((statobj_t*)(rtemp->linked_to));
+           stype = stat_tntcrate;
+           }
+        else
+           {
+           for(i=0;i<NUMSTATS;i++)
+              {
+              if (rtemp->itemnumber == stats[i].type)
+                 {
+                 stype = i;
+                 break;
+                 }
+              }
+
+           }
+
+		  SpawnStatic(stilex,stiley,stype,-1);
+		  LASTSTAT->z = rtemp->spawnz;
+		  LASTSTAT->flags |= FL_ABP;
+		  MakeStatActive(LASTSTAT);
+        SpawnNewObj(stilex,stiley,&s_itemspawn1,inertobj);
+        SD_PlaySoundRTP(SD_RESPAWNSND,new->x,new->y);
+		  new->flags |= FL_ABP;
+		  MakeActive(new);
+		  new->z = LASTSTAT->z;
+		  RemoveRespawnStatic(rtemp);
+		 }
+
+	 rtemp = ddt;
+	}
+
+ for (temp = firstactivestat ; temp; )
+	 {stat = temp->nextactive;
+
+	  if (temp->flags & FL_SOLIDCOLOR)
+		  {temp->ticcount--;
+			if (temp->ticcount<=0)
+				{temp->hitpoints+=SOLIDCOLORINCREMENT;
+				 if (temp->hitpoints>MAXFIRECOLOR)
+					 RemoveStatic(temp);
+				 else
+					 temp->ticcount = SOLIDCOLORTICTIME;
+				}
+		  }
+	  temp = stat;
+	 }
+
+
+}
+
+
+
+/*
+===============
+=
+= DoSprites
+=
+===============
+*/
+
+void DoSprites(void)
+{int index,i;
+ statobj_t *temp,*tempnext;
+
+
+#if (0)
+	 Debug("\n");
+#endif
+i=0;
+for(temp = firstactivestat;temp;)
+  {tempnext = temp->nextactive;
+
+	#if (0)
+	 Debug("\nid: %d, shapenum: %d, numanims: %d",i++,temp->shapenum,temp->numanims);
+	#endif
+
+	if ((temp->shapenum != NOTHING) && (temp->flags & FL_ACTIVE))
+		{index = temp->itemnumber;
+		 temp->ticcount -= tics;
+		 while (temp->ticcount <= 0)
+			  {if (temp->count < temp->numanims)
+					 {temp->shapenum = stats[index].picnum + temp->count;
+					  if (index == stat_missmoke)
+						  {RemoveStatic(temp);
+							break;
+						  }
+
+					  if (((index == stat_rubble) && (temp->count == 9)) ||
+							((index == stat_woodfrag) && (temp->count == 13)) ||
+							((index == stat_metalfrag) && (temp->count == 9)))
+						 {temp->flags &= ~FL_ACTIVE;
+						  break;
+						 }
+
+					  if (temp->flags & FL_BACKWARDS)
+						 {temp->count--;
+						  M_ResetSprites(temp);
+						 }
+					  else
+						 temp->count ++;
+					 }
+				else if (!(temp->flags & FL_BANDF))
+					{temp->shapenum = stats[index].picnum;
+					 temp->count=1;
+					}
+				else
+					{temp->flags |= FL_BACKWARDS;
+					 temp->count --;
+					}
+				temp->ticcount += stats[index].tictime;
+			  }
+		}
+  temp = tempnext;
+
+  }
+
+}
+
+void  SpawnStaticDamage(statobj_t * stat, int angle)
+{
+	GetNewActor ();
+	MakeActive(new);
+	NewState(new,&s_gunsmoke1);
+
+	new->obclass = inertobj;
+	new->which = ACTOR;
+	new->x = (stat->x)-(costable[angle]>>4);
+	new->y = (stat->y)+(sintable[angle]>>4);
+	new->z = (stat->z)+stats[stat->itemnumber].heightoffset;
+	new->drawx = new->x;
+	new->drawy = new->y;
+	new->tilex = (new->x >> TILESHIFT);
+	new->tiley = (new->y >> TILESHIFT);
+	new->dir = 0;
+	new->speed = 0;
+	new->flags = (FL_NEVERMARK|FL_ABP);
+	if ((new->x<=0) || (new->y<=0))
+	   Error("SpawnStaticDamage: bad x,y itemnumber=%d\n",stat->itemnumber);
+}

Added: tags/rott-1.1/rott/rt_stat.h
===================================================================
--- tags/rott-1.1/rott/rt_stat.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_stat.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,238 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//                  RT_STAT.C (static object functions)
+//
+//***************************************************************************
+#ifndef _rt_stat_public
+#define _rt_stat_public
+
+#include "rt_ted.h"
+
+#define MAXSWITCHES     64
+#define MAXANIMWALLS    17
+#define NUMSTATS        91
+
+typedef enum {
+		  stat_ylight,
+		  stat_rlight,
+		  stat_glight,
+		  stat_blight,
+		  stat_chandelier,
+		  stat_lamp,
+		  stat_pedgoldkey,
+		  stat_pedsilverkey,
+		  stat_pedironkey,
+		  stat_pedcrystalkey,
+		  stat_gibs1,
+		  stat_gibs2,
+		  stat_gibs3,
+		  stat_monkmeal,
+		  stat_priestporridge,
+		  stat_monkcrystal1,
+		  stat_monkcrystal2,
+		  stat_oneup,
+		  stat_threeup,
+		  stat_altbrazier1,
+		  stat_altbrazier2,
+		  stat_healingbasin,
+		  stat_emptybasin,
+        stat_bat,
+        stat_knifestatue,
+		  stat_twopistol,
+		  stat_mp40,
+		  stat_bazooka,
+        stat_firebomb,
+        stat_heatseeker,
+		  stat_drunkmissile,
+		  stat_firewall,
+        stat_splitmissile,
+		  stat_kes,
+        stat_lifeitem1,
+		  stat_lifeitem2,
+		  stat_lifeitem3,
+		  stat_lifeitem4,
+		  stat_tntcrate,
+		  stat_bonusbarrel,
+		  stat_torch,
+		  stat_floorfire,
+		  stat_dipball1,
+		  stat_dipball2,
+		  stat_dipball3,
+		  stat_touch1,
+		  stat_touch2,
+		  stat_touch3,
+		  stat_touch4,
+		  stat_dariantouch,
+		  stat_scotthead,
+		  stat_garb1,
+		  stat_garb2,
+		  stat_garb3,
+		  stat_shit,
+		  stat_grate,
+		  stat_metalshards,
+		  stat_emptypedestal,
+		  stat_emptytable,
+		  stat_stool,
+		  stat_bcolumn,
+		  stat_gcolumn,
+		  stat_icolumn,
+		  stat_tree,
+		  stat_plant,
+		  stat_urn,
+		  stat_haystack,
+		  stat_ironbarrel,
+		  stat_heatgrate,
+		  stat_standardpole,
+        stat_pit,
+        stat_godmode,
+        stat_dogmode,
+        stat_fleetfeet,
+		  stat_elastic,
+		  stat_mushroom,
+		  stat_gasmask,
+		  stat_bulletproof,
+		  stat_asbesto,
+		  stat_random,
+		  stat_rubble,
+		  stat_woodfrag,
+		  stat_metalfrag,
+		  stat_emptystatue,
+		  stat_tomlarva,
+		  stat_bullethole,
+		  stat_collector,
+		  stat_mine,
+		  stat_missmoke,
+		  stat_disk,
+		  stat_badstatic
+} stat_t;
+
+typedef struct awall
+{
+  byte active;
+  byte count;
+  signed char ticcount;
+  int  texture;
+  int  basetexture;
+} animwall_t;
+
+typedef struct statstruct
+{
+		  thingtype         which;
+		  byte              tilex,tiley;
+		  fixed             x,y,z;
+		  int               shapenum;
+		  unsigned          flags;
+		  signed char       ticcount;
+		  signed char       ammo;
+		  byte              *visspot;
+		  signed char       count;
+		  byte              numanims;
+		  stat_t            itemnumber;
+		  short int         hitpoints;
+		  short int         whichstat;
+		  short int         areanumber;
+
+		  long              linked_to;
+		  struct statstruct *statnext;
+		  struct statstruct *statprev;
+		  struct statstruct *nextactive;
+		  struct statstruct *prevactive;
+
+} statobj_t;
+
+typedef struct respstruct
+{
+		  byte              tilex,tiley;
+		  int               ticcount;
+		  stat_t            itemnumber;
+		  int               spawnz;
+		  struct respstruct *next;
+		  struct respstruct *prev;
+                  long              linked_to;
+} respawn_t;
+
+
+typedef struct
+{
+		  short      heightoffset;
+		  int        picnum;
+		  stat_t     type;
+		  unsigned   flags;
+		  byte       tictime;
+		  byte       numanims;
+		  byte       hitpoints;
+		  byte       damage;
+		  signed char  ammo;
+} statinfo;
+
+extern  statobj_t       *lastactivestat,*firstactivestat;
+extern  statobj_t       *firstemptystat,*lastemptystat;
+extern  int             spritestart;
+extern  wall_t          switches[MAXSWITCHES],*lastswitch;
+
+extern  respawn_t       *firstrespawn,*lastrespawn;
+extern  statobj_t       *FIRSTSTAT,*LASTSTAT,*sprites[MAPSIZE][MAPSIZE];
+extern  statinfo        stats[NUMSTATS];
+extern  dirtype         diagonal[9][9];
+extern  dirtype         opposite[9];
+
+extern  int             statcount;
+
+extern   int            animwallstart;
+extern   animwall_t     animwalls[MAXANIMWALLS];
+
+
+void Set_NewZ_to_MapValue(fixed*,int,const char*,int,int);
+void RemoveFromFreeStaticList(statobj_t*);
+void CheckCriticalStatics(void);
+void ActivateLight(long);
+void DeactivateLight(long);
+void TurnOnLight(int,int);
+void TurnOffLight(int,int);
+void MakeStatActive(statobj_t*);
+void MakeStatInactive(statobj_t*);
+void AddStatic(statobj_t *);
+void RemoveStatic(statobj_t *);
+
+
+void SpawnSwitchThingy(int,int);
+void InitStaticList (void);
+void InitAnimatedWallList(void);
+void SetupAnimatedWall(int which);
+void SpawnStatic (int tilex, int tiley, int mtype, int zoffset);
+void SpawnSolidStatic (statobj_t * temp);
+void AnimateWalls(void);
+void DoSprites(void);
+
+void SaveAnimWalls(byte ** buf, int * size);
+void SaveStatics(byte ** buf, int * size);
+
+void LoadAnimWalls(byte * buf, int size);
+void LoadStatics(byte * buf, int size);
+
+void SaveSwitches(byte ** buf, int * size);
+void LoadSwitches(byte * buf, int size);
+
+void SpawnInertStatic (int x, int y, int z, int mtype);
+void SpawnStaticDamage(statobj_t * stat, int angle);
+
+#endif

Added: tags/rott-1.1/rott/rt_state.c
===================================================================
--- tags/rott-1.1/rott/rt_state.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_state.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1983 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "sprites.h"
+#include "states.h"
+#include "rt_actor.h"
+#include "develop.h"
+#define SPRINGDELAY 3
+//MED
+#include "memcheck.h"
+
+/*
+=============================================================================
+
+					  LOW GUARD (includes sneaky)
+
+=============================================================================
+*/
+
+
+extern void T_ReallyDead(objtype*ob);
+extern void T_PlayDead(objtype*ob);
+extern void T_Xylophone(objtype*ob);
+extern void T_BloodFall(objtype*ob);
+extern void SetShapeoffset(objtype*ob);
+extern void RespawnPlayerobj(objtype*ob);
+extern void T_ElevDisk(objtype*ob);
+extern void T_Plead(objtype*ob);
+extern void T_Blood(objtype*ob);
+extern void T_Convert(objtype*ob);
+extern void T_SlideDownScreen(objtype*ob);
+extern void T_End(objtype*ob);
+extern void T_Reset(objtype*ob);
+extern void T_CollectorWander(objtype*ob);
+extern void T_CollectorFindDoor(objtype*ob);
+extern void T_AutoPath(objtype*);
+extern void T_AutoRealign(objtype*);
+extern void T_AutoShootAlign(objtype*);
+extern void T_NME_SpinFire(objtype*);
+extern void MissileMovement(objtype*);
+extern void T_BatBlast(objtype*);
+extern void T_DeadWait(objtype*);
+extern void ActorMovement(objtype*);
+extern void T_Spring(objtype*);
+extern void T_SnakeFinale(objtype*);
+extern void T_Special(objtype*);
+extern void T_NME_Explode(objtype*);
+extern void T_Guts(objtype*);
+extern void T_Player(objtype*);
+extern void T_ParticleGenerate(objtype*);
+extern void T_Particle(objtype*);
+extern void T_SpawnSoul(objtype*);
+extern void T_NME_WindUp(objtype*);
+extern void T_NME_Attack(objtype*);
+extern void T_Saucer(objtype*);
+extern void T_NMErocket(objtype*);
+extern void T_NME_SpinAttack(objtype*);
+extern void T_NME_HeadShoot(objtype*);
+extern void T_CrushUp(objtype*);
+extern void T_CrushDown(objtype*);
+extern void T_HeinrichChase(objtype*);
+extern void T_KristLeft(objtype*);
+extern void T_KristRight(objtype*);
+extern void T_KristCheckFire(objtype*);
+extern void T_BoulderSpawn(objtype*);
+extern void T_BoulderDrop(objtype*);
+extern void T_BoulderMove(objtype*);
+extern void T_DarkmonkChase(objtype*);
+extern void T_DarkSnakeChase(objtype*);
+extern void T_DarkSnakeSpawn(objtype*);
+extern void A_DmonkAttack(objtype*);
+extern void T_GenericMove(objtype*);
+extern void T_Count(objtype*);
+extern void T_Spears(objtype*);
+extern void T_EsauSpears(objtype*);
+extern void T_Spring(objtype*);
+extern void T_4WayGunStand(objtype*);
+extern void A_GunShoot(objtype*);
+extern void A_4WayGunShoot(objtype*);
+extern void T_Attack(objtype*);
+extern void T_SnakePath(objtype*);
+extern void T_SnakeFindPath(objtype*);
+extern void T_DarkmonkLandAndFire(objtype*ob);
+extern void T_DarkmonkCharge(objtype*ob);
+extern void T_DarkmonkReact(objtype*ob);
+extern void T_BossExplosions(objtype*ob);
+
+statetype s_lowgrdstand	   = {true,SPR_LOWGRD_S1,0,T_Stand,0,&s_lowgrdstand};
+
+
+statetype s_lowgrdpath4    = {true,SPR_LOWGRD_W41,12,T_Path,0,&s_lowgrdpath1};
+statetype s_lowgrdpath3    = {true,SPR_LOWGRD_W31,12,T_Path,SF_CLOSE,&s_lowgrdpath4};
+statetype s_lowgrdpath2    = {true,SPR_LOWGRD_W21,12,T_Path,0,&s_lowgrdpath3};
+statetype s_lowgrdpath1    = {true,SPR_LOWGRD_W11,12,T_Path,SF_CLOSE,&s_lowgrdpath2};
+
+statetype s_lowgrdcollide  = {false,SPR_LOWGRD_PAIN1,0,T_Collide,0,&s_lowgrdcollide};
+statetype s_lowgrdcollide2 = {false,SPR_LOWGRD_PAIN2,0,T_Collide,0,&s_lowgrdcollide2};
+
+
+//statetype s_lowgrduse2     = {true,SPR_LOWGRD_USE21,5,T_Use,0,&s_lowgrdpath1};
+//statetype s_lowgrduse1     = {true,SPR_LOWGRD_USE11,5,T_Use,0,&s_lowgrduse2};
+
+statetype s_lowgrdshoot4 	= {false,SPR_LOWGRD_SHOOT4,8,ActorMovement,0,&s_lowgrdchase1};
+statetype s_lowgrdshoot3   = {false,SPR_LOWGRD_SHOOT3,5,A_Shoot,0,&s_lowgrdshoot4};
+statetype s_lowgrdshoot2   = {false,SPR_LOWGRD_SHOOT2,20,ActorMovement,0,&s_lowgrdshoot3};
+statetype s_lowgrdshoot1 	= {false,SPR_LOWGRD_SHOOT1,6,ActorMovement,0,&s_lowgrdshoot2};
+
+statetype s_lowgrdchase4   = {true,SPR_LOWGRD_W41,12,T_Chase,0,&s_lowgrdchase1};
+statetype s_lowgrdchase3   = {true,SPR_LOWGRD_W31,12,T_Chase,SF_CLOSE,&s_lowgrdchase4};
+statetype s_lowgrdchase2   = {true,SPR_LOWGRD_W21,12,T_Chase,0,&s_lowgrdchase3};
+statetype s_lowgrdchase1   = {true,SPR_LOWGRD_W11,12,T_Chase,SF_CLOSE,&s_lowgrdchase2};
+
+
+
+statetype s_lowgrddead     = {false,SPR_LOWGRD_DEAD,0,T_Collide,0,&s_lowgrddead};
+statetype s_lowgrddie4     = {false,SPR_LOWGRD_DIE4,8,T_Collide,0,&s_lowgrddead};
+statetype s_lowgrddie3     = {false,SPR_LOWGRD_DIE3,8,T_Collide,0,&s_lowgrddie4};
+statetype s_lowgrddie2     = {false,SPR_LOWGRD_DIE2,8,T_Collide,0,&s_lowgrddie3};
+statetype s_lowgrddie1		= {false,SPR_LOWGRD_DIE1,15,T_Collide,0,&s_lowgrddie2};
+
+
+statetype s_lowgrdcrushed2		= {false,SPR_LOWGRD_DIE3,2,NULL,0,&s_lowgrddead};
+statetype s_lowgrdcrushed1		= {false,SPR_LOWGRD_DIE1,2,NULL,0,&s_lowgrdcrushed2};
+
+/************** Sneaky stuff *******************************************/
+
+statetype s_sneakydown     = {false,SPR_SNEAKY_DEAD,0,T_Stand,0,&s_sneakydown};
+statetype s_sneakyrise4    = {false,SPR_RISE4,6,ActorMovement,0,&s_lowgrdchase1};
+statetype s_sneakyrise3    = {false,SPR_RISE3,6,ActorMovement,0,&s_sneakyrise4};
+statetype s_sneakyrise2    = {false,SPR_RISE2,6,ActorMovement,0,&s_sneakyrise3};
+statetype s_sneakyrise1    = {false,SPR_RISE1,6,ActorMovement,0,&s_sneakyrise2};
+
+
+/*
+=============================================================================
+
+					  HIGH GUARD
+
+=============================================================================
+*/
+
+
+
+statetype s_highgrdstand	= {true,SPR_HIGHGRD_S1,0,T_Stand,0,&s_highgrdstand};
+
+
+statetype s_highgrdpath4   = {true,SPR_HIGHGRD_W41,12,T_Path,0,&s_highgrdpath1};
+statetype s_highgrdpath3   = {true,SPR_HIGHGRD_W31,12,T_Path,SF_CLOSE,&s_highgrdpath4};
+statetype s_highgrdpath2   = {true,SPR_HIGHGRD_W21,12,T_Path,0,&s_highgrdpath3};
+statetype s_highgrdpath1   = {true,SPR_HIGHGRD_W11,12,T_Path,SF_CLOSE,&s_highgrdpath2};
+
+
+//statetype s_highgrdpain1 	= {2,SPR_HIGHGRD_PAIN1,10,T_Collide,0,&s_highgrdchase1};
+//statetype s_highgrdpain2 	= {2,SPR_HIGHGRD_PAIN2,10,T_Collide,0,&s_highgrdchase1};
+
+
+statetype s_highgrdcollide  = {false,SPR_HIGHGRD_PAIN1,0,T_Collide,0,&s_highgrdcollide};
+statetype s_highgrdcollide2 = {false,SPR_HIGHGRD_PAIN2,0,T_Collide,0,&s_highgrdcollide2};
+
+
+//statetype s_highgrduse2 	 = {true,SPR_HIGHGRD_USE21,10,T_Use,0,&s_highgrdpath1};
+//statetype s_highgrduse1 	 = {true,SPR_HIGHGRD_USE11,10,T_Use,0,&s_highgrduse2};
+
+
+statetype s_highgrdshoot4  = {false,SPR_HIGHGRD_SHOOT4,3,A_Repeat,0,&s_highgrdshoot3};
+statetype s_highgrdshoot3  = {false,SPR_HIGHGRD_SHOOT3,5,A_Shoot,0,&s_highgrdshoot4};
+statetype s_highgrdshoot2  = {false,SPR_HIGHGRD_SHOOT2,6,ActorMovement,0,&s_highgrdshoot3};
+statetype s_highgrdshoot1 	= {false,SPR_HIGHGRD_SHOOT1,6,ActorMovement,0,&s_highgrdshoot2};
+
+
+statetype s_highgrdchase4  = {true,SPR_HIGHGRD_W41,12,T_Chase,0,&s_highgrdchase1};
+statetype s_highgrdchase3 = {true,SPR_HIGHGRD_W31,12,T_Chase,SF_CLOSE,&s_highgrdchase4};
+statetype s_highgrdchase2 = {true,SPR_HIGHGRD_W21,12,T_Chase,0,&s_highgrdchase3};
+statetype s_highgrdchase1 = {true,SPR_HIGHGRD_W11,12,T_Chase,SF_CLOSE,&s_highgrdchase2};
+
+
+statetype s_highgrddead    = {false,SPR_HIGHGRD_DEAD,0,T_Collide,0,&s_highgrddead};
+statetype s_highgrddie5    = {false,SPR_HIGHGRD_DIE5,0,T_Collide,0,&s_highgrddead};
+statetype s_highgrddie4    = {false,SPR_HIGHGRD_DIE4,8,T_Collide,0,&s_highgrddie5};
+statetype s_highgrddie3    = {false,SPR_HIGHGRD_DIE3,8,T_Collide,0,&s_highgrddie4};
+statetype s_highgrddie2    = {false,SPR_HIGHGRD_DIE2,8,T_Collide,0,&s_highgrddie3};
+statetype s_highgrddie1    = {false,SPR_HIGHGRD_DIE1,8,T_Collide,0,&s_highgrddie2};
+
+statetype s_highgrdcrushed2		= {false,SPR_HIGHGRD_DIE3,2,NULL,0,&s_highgrddead};
+statetype s_highgrdcrushed1		= {false,SPR_HIGHGRD_DIE1,2,NULL,0,&s_highgrdcrushed2};
+
+/*
+===========================================================================
+
+										 STRIKEGUARD
+
+===========================================================================
+*/
+
+
+statetype s_strikestand	= {true,SPR_STRIKE_S1,0,T_Stand,0,&s_strikestand};
+
+
+statetype s_strikepath4    = {true,SPR_STRIKE_W41,12,T_Path,0,&s_strikepath1};
+statetype s_strikepath3    = {true,SPR_STRIKE_W31,12,T_Path,SF_CLOSE,&s_strikepath4};
+statetype s_strikepath2    = {true,SPR_STRIKE_W21,12,T_Path,0,&s_strikepath3};
+statetype s_strikepath1    = {true,SPR_STRIKE_W11,12,T_Path,SF_CLOSE,&s_strikepath2};
+
+statetype s_strikecollide  = {false,SPR_STRIKE_PAIN1,0,T_Collide,0,&s_strikecollide};
+statetype s_strikecollide2 = {false,SPR_STRIKE_PAIN2,0,T_Collide,0,&s_strikecollide2};
+
+statetype s_strikeshoot4 	= {false,SPR_STRIKE_SHOOT4,6,ActorMovement,0,&s_strikechase1};
+statetype s_strikeshoot3 	= {false,SPR_STRIKE_SHOOT3,6,ActorMovement,0,&s_strikeshoot4};
+statetype s_strikeshoot2   = {false,SPR_STRIKE_SHOOT2,5,A_Shoot,0,&s_strikeshoot3};
+statetype s_strikeshoot1   = {false,SPR_STRIKE_SHOOT1,20,ActorMovement,0,&s_strikeshoot2};
+
+
+//statetype s_strikeuse2      = {true,SPR_STRIKE_USE21,10,T_Use,0,&s_strikechase1};
+//statetype s_strikeuse1      = {true,SPR_STRIKE_USE11,10,NULL,0,&s_strikeuse2};
+
+statetype s_strikewait      = {true,SPR_STRIKE_S1,35,NULL,0,&s_strikechase1};
+
+statetype s_strikerollright6    = {false,SPR_STRIKE_LROLL6,8,T_Roll,0,&s_strikeshoot1};
+statetype s_strikerollright5    = {false,SPR_STRIKE_LROLL5,8,T_Roll,0,&s_strikerollright6};
+statetype s_strikerollright4    = {false,SPR_STRIKE_LROLL4,7,T_Reset,0,&s_strikerollright5};
+statetype s_strikerollright3    = {false,SPR_STRIKE_LROLL3,7,T_Roll,0,&s_strikerollright4};
+statetype s_strikerollright2    = {false,SPR_STRIKE_LROLL2,7,T_Roll,0,&s_strikerollright3};
+statetype s_strikerollright1    = {false,SPR_STRIKE_LROLL1,5,T_Roll,0,&s_strikerollright2};
+
+
+
+statetype s_strikerollleft6    = {false,SPR_STRIKE_RROLL6,8,T_Roll,0,&s_strikeshoot1};
+statetype s_strikerollleft5    = {false,SPR_STRIKE_RROLL5,8,T_Roll,0,&s_strikerollleft6};
+statetype s_strikerollleft4    = {false,SPR_STRIKE_RROLL4,7,T_Reset,0,&s_strikerollleft5};
+statetype s_strikerollleft3    = {false,SPR_STRIKE_RROLL3,7,T_Roll,0,&s_strikerollleft4};
+statetype s_strikerollleft2    = {false,SPR_STRIKE_RROLL2,7,T_Roll,0,&s_strikerollleft3};
+statetype s_strikerollleft1    = {false,SPR_STRIKE_RROLL1,5,T_Roll,0,&s_strikerollleft2};
+
+
+statetype s_strikechase4   = {true,SPR_STRIKE_W41,12,T_Chase,0,&s_strikechase1};
+statetype s_strikechase3   = {true,SPR_STRIKE_W31,12,T_Chase,SF_CLOSE,&s_strikechase4};
+statetype s_strikechase2   = {true,SPR_STRIKE_W21,12,T_Chase,0,&s_strikechase3};
+statetype s_strikechase1   = {true,SPR_STRIKE_W11,12,T_Chase,SF_CLOSE,&s_strikechase2};
+
+
+statetype s_strikedead3    = {false,SPR_STRIKE_DEAD3,0,T_Collide,0,&s_strikedead3};
+statetype s_strikedead2    = {false,SPR_STRIKE_DEAD2,0,T_Collide,0,&s_strikedead3};
+statetype s_strikedead     = {false,SPR_STRIKE_DEAD1,7,T_Collide,0,&s_strikedead2};
+statetype s_strikedie4     = {false,SPR_STRIKE_DIE4,7,T_Collide,0,&s_strikedead};
+statetype s_strikedie3     = {false,SPR_STRIKE_DIE3,7,T_Collide,0,&s_strikedie4};
+statetype s_strikedie2     = {false,SPR_STRIKE_DIE2,7,T_Collide,0,&s_strikedie3};
+statetype s_strikedie1     = {false,SPR_STRIKE_DIE1,7,T_Collide,0,&s_strikedie2};
+
+
+statetype s_strikecrushed2		= {false,SPR_STRIKE_DIE3,2,NULL,0,&s_strikedead};
+statetype s_strikecrushed1		= {false,SPR_STRIKE_DIE1,2,NULL,0,&s_strikecrushed2};
+
+/*
+============================================================================
+
+								LIGHTNING GUARD
+
+============================================================================
+*/
+
+statetype s_blitzstand	= {true,SPR_BLITZ_S1,0,T_Stand,0,&s_blitzstand};
+
+statetype s_blitzpath4 = {true,SPR_BLITZ_W41,12,T_Path,0,&s_blitzpath1};
+statetype s_blitzpath3 = {true,SPR_BLITZ_W31,12,T_Path,SF_CLOSE,&s_blitzpath4};
+statetype s_blitzpath2 = {true,SPR_BLITZ_W21,12,T_Path,0,&s_blitzpath3};
+statetype s_blitzpath1 = {true,SPR_BLITZ_W11,12,T_Path,SF_CLOSE,&s_blitzpath2};
+
+
+
+statetype s_blitzcollide  = {false,SPR_BLITZ_PAIN1,0,T_Collide,0,&s_blitzcollide};
+statetype s_blitzcollide2 = {false,SPR_BLITZ_PAIN2,0,T_Collide,0,&s_blitzcollide2};
+
+statetype s_blitzshoot4 = {false,SPR_BLITZ_SHOOT4,10,ActorMovement,0,&s_blitzchase1};
+statetype s_blitzshoot3 = {false,SPR_BLITZ_SHOOT3,10,ActorMovement,0,&s_blitzshoot4};
+statetype s_blitzshoot2 = {false,SPR_BLITZ_SHOOT2,5,A_Shoot,0,&s_blitzshoot3};
+statetype s_blitzshoot1 = {false,SPR_BLITZ_SHOOT1,10,ActorMovement,0,&s_blitzshoot2};
+
+statetype s_blitzrise4 = {false,SPR_BLITZ_RISE4,8,ActorMovement,0,&s_blitzchase1};
+statetype s_blitzrise3 = {false,SPR_BLITZ_RISE3,8,ActorMovement,0,&s_blitzrise4};
+statetype s_blitzrise2 = {false,SPR_BLITZ_RISE2,8,ActorMovement,0,&s_blitzrise3};
+statetype s_blitzrise1 = {false,SPR_BLITZ_RISE1,8,ActorMovement,0,&s_blitzrise2};
+
+statetype s_blitzuse    = {true,SPR_BLITZ_USE,10,T_Use,0,&s_blitzpath1};
+
+
+statetype s_blitzsteal2 = {true,SPR_BLITZ_STEAL2,20,A_Steal,0,&s_blitzchase1};
+statetype s_blitzsteal1 = {true,SPR_BLITZ_STEAL1,20,ActorMovement,0,&s_blitzsteal2};
+
+statetype s_blitzchase4    = {true,SPR_BLITZ_W41,12,T_Chase,0,&s_blitzchase1};
+statetype s_blitzchase3    = {true,SPR_BLITZ_W31,12,T_Chase,SF_CLOSE,&s_blitzchase4};
+statetype s_blitzchase2    = {true,SPR_BLITZ_W21,12,T_Chase,0,&s_blitzchase3};
+statetype s_blitzchase1    = {true,SPR_BLITZ_W11,12,T_Chase,SF_CLOSE,&s_blitzchase2};
+
+
+statetype s_blitzdead2     = {false,SPR_BLITZ_DEAD2,0,T_Collide,0,&s_blitzdead2};
+statetype s_blitzdead      = {false,SPR_BLITZ_DEAD1,0,T_Collide,0,&s_blitzdead2};
+statetype s_blitzdie4      = {false,SPR_BLITZ_DIE4,7,T_Collide,0,&s_blitzdead};
+statetype s_blitzdie3      = {false,SPR_BLITZ_DIE3,7,T_Collide,0,&s_blitzdie4};
+statetype s_blitzdie2      = {false,SPR_BLITZ_DIE2,7,T_Collide,0,&s_blitzdie3};
+statetype s_blitzdie1      = {false,SPR_BLITZ_DIE1,7,T_Collide,0,&s_blitzdie2};
+
+
+statetype s_blitzstruggledead  = {false,SPR_BLITZ_RISE2,0,T_Collide,0,&s_blitzstruggledead};
+statetype s_blitzstruggledie1  = {false,SPR_BLITZ_RISE2,20,T_ReallyDead,0,&s_blitzstruggledead};
+
+
+statetype s_blitzfakedead  = {false,SPR_BLITZ_DEAD2,0,T_PlayDead,SF_FAKING,&s_blitzfakedead};
+statetype s_blitzfakedie3  = {false,SPR_BLITZ_DEAD1,5,ActorMovement,0,&s_blitzfakedead};
+statetype s_blitzfakedie2  = {false,SPR_BLITZ_DIE4,5,ActorMovement,0,&s_blitzfakedie3};
+statetype s_blitzfakedie1  = {false,SPR_BLITZ_DIE3,5,ActorMovement,0,&s_blitzfakedie2};
+
+
+statetype s_blitzcrushed2     = {false,SPR_BLITZ_DIE3,2,NULL,0,&s_blitzdead};
+statetype s_blitzcrushed1		= {false,SPR_BLITZ_DIE1,2,NULL,0,&s_blitzcrushed2};
+
+statetype s_blitzplead11    = {false,SPR_BLITZ_PLEAD11,0,T_Collide,0,&s_blitzplead11};
+statetype s_blitzplead10    = {false,SPR_BLITZ_PLEAD10,6,NULL,0,&s_blitzplead11};
+statetype s_blitzplead9    = {false,SPR_BLITZ_PLEAD9,6,NULL,0,&s_blitzplead10};
+statetype s_blitzplead8    = {false,SPR_BLITZ_PLEAD8,6,NULL,0,&s_blitzplead9};
+statetype s_blitzplead7    = {false,SPR_BLITZ_PLEAD7,6,NULL,0,&s_blitzplead8};
+
+
+
+
+statetype s_blitzaplead4    = {false,SPR_BLITZ_PLEAD4,5,T_Plead,SF_DOWN,&s_blitzplead3};
+statetype s_blitzaplead5    = {false,SPR_BLITZ_PLEAD5,5,T_Plead,SF_DOWN,&s_blitzaplead4};
+
+statetype s_blitzplead6    = {false,SPR_BLITZ_PLEAD6,5,T_Plead,SF_DOWN,&s_blitzaplead5};
+statetype s_blitzplead5    = {false,SPR_BLITZ_PLEAD5,5,T_Plead,SF_DOWN,&s_blitzplead6};
+statetype s_blitzplead4    = {false,SPR_BLITZ_PLEAD4,5,T_Plead,SF_DOWN,&s_blitzplead5};
+statetype s_blitzplead3    = {false,SPR_BLITZ_PLEAD3,5,T_Plead,SF_DOWN,&s_blitzplead4};
+statetype s_blitzplead2    = {false,SPR_BLITZ_PLEAD2,6,ActorMovement,0,&s_blitzplead3};
+statetype s_blitzplead1    = {false,SPR_BLITZ_PLEAD1,6,ActorMovement,0,&s_blitzplead2};
+
+
+
+/*
+============================================================================
+
+								TRIAD ENFORCERS
+
+============================================================================
+*/
+
+
+statetype s_enforcerstand	= {true,SPR_ENFORCER_S1,0,T_Stand,0,&s_enforcerstand};
+
+
+statetype s_enforcerpath4  = {true,SPR_ENFORCER_W41,12,T_Path,0,&s_enforcerpath1};
+statetype s_enforcerpath3  = {true,SPR_ENFORCER_W31,12,T_Path,SF_CLOSE,&s_enforcerpath4};
+statetype s_enforcerpath2  = {true,SPR_ENFORCER_W21,12,T_Path,0,&s_enforcerpath3};
+statetype s_enforcerpath1  = {true,SPR_ENFORCER_W11,12,T_Path,SF_CLOSE,&s_enforcerpath2};
+
+
+statetype s_enforcerchase4    = {true,SPR_ENFORCER_W41,12,T_Chase,0,&s_enforcerchase1};
+statetype s_enforcerchase3    = {true,SPR_ENFORCER_W31,12,T_Chase,SF_CLOSE,&s_enforcerchase4};
+statetype s_enforcerchase2    = {true,SPR_ENFORCER_W21,12,T_Chase,0,&s_enforcerchase3};
+statetype s_enforcerchase1    = {true,SPR_ENFORCER_W11,12,T_Chase,SF_CLOSE,&s_enforcerchase2};
+
+statetype s_enforcercollide  = {false,SPR_ENFORCER_PAIN1,0,T_Collide,0,&s_enforcercollide};
+statetype s_enforcercollide2 = {false,SPR_ENFORCER_PAIN2,0,T_Collide,0,&s_enforcercollide2};
+
+
+//statetype s_enforceruse2    = {true,SPR_ENFORCER_USE21,10,T_Use,0,&s_enforcerchase1};
+//statetype s_enforceruse1    = {true,SPR_ENFORCER_USE11,10,T_Use,0,&s_enforceruse2};
+
+statetype s_enforcershoot4 = {false,SPR_ENFORCER_SHOOT4,6,A_Repeat,0,&s_enforcershoot3};
+statetype s_enforcershoot3 = {false,SPR_ENFORCER_SHOOT3,6,A_Shoot,0,&s_enforcershoot4};
+statetype s_enforcershoot2 = {false,SPR_ENFORCER_SHOOT2,6,ActorMovement,0,&s_enforcershoot3};
+statetype s_enforcershoot1 = {false,SPR_ENFORCER_SHOOT1,6,ActorMovement,0,&s_enforcershoot2};
+
+
+statetype s_enforcerthrow8 = {false,SPR_ENFORCER_THROW8,10,ActorMovement,0,&s_enforcerchase1};
+statetype s_enforcerthrow7 = {false,SPR_ENFORCER_THROW7,10,ActorMovement,0,&s_enforcerthrow8};
+statetype s_enforcerthrow6 = {false,SPR_ENFORCER_THROW6,10,ActorMovement,0,&s_enforcerthrow7};
+statetype s_enforcerthrow5 = {false,SPR_ENFORCER_THROW5,10,A_MissileWeapon,0,&s_enforcerthrow6};
+statetype s_enforcerthrow4 = {false,SPR_ENFORCER_THROW4,10,ActorMovement,0,&s_enforcerthrow5};
+statetype s_enforcerthrow3 = {false,SPR_ENFORCER_THROW3,10,ActorMovement,0,&s_enforcerthrow4};
+statetype s_enforcerthrow2 = {false,SPR_ENFORCER_THROW2,10,ActorMovement,0,&s_enforcerthrow3};
+statetype s_enforcerthrow1 = {false,SPR_ENFORCER_THROW1,10,ActorMovement,0,&s_enforcerthrow2};
+
+
+
+statetype s_grenade10      = {false,SPR_ENFORCER_GR10,2,T_Projectile,0,&s_grenade1};
+statetype s_grenade9       = {false,SPR_ENFORCER_GR9,2,T_Projectile,0,&s_grenade10};
+statetype s_grenade8       = {false,SPR_ENFORCER_GR8,2,T_Projectile,0,&s_grenade9};
+statetype s_grenade7       = {false,SPR_ENFORCER_GR7,2,T_Projectile,0,&s_grenade8};
+statetype s_grenade6       = {false,SPR_ENFORCER_GR6,2,T_Projectile,0,&s_grenade7};
+statetype s_grenade5       = {false,SPR_ENFORCER_GR5,2,T_Projectile,0,&s_grenade6};
+statetype s_grenade4       = {false,SPR_ENFORCER_GR4,2,T_Projectile,0,&s_grenade5};
+statetype s_grenade3       = {false,SPR_ENFORCER_GR3,2,T_Projectile,0,&s_grenade4};
+statetype s_grenade2       = {false,SPR_ENFORCER_GR2,2,T_Projectile,0,&s_grenade3};
+statetype s_grenade1       = {false,SPR_ENFORCER_GR1,2,T_Projectile,0,&s_grenade2};
+
+statetype s_grenade_fall6  = {false,SPR_ENFORCER_FALL6,6,T_Projectile,0,&s_grenade_fall6};
+statetype s_grenade_fall5  = {false,SPR_ENFORCER_FALL5,6,T_Projectile,0,&s_grenade_fall6};
+statetype s_grenade_fall4  = {false,SPR_ENFORCER_FALL4,6,T_Projectile,0,&s_grenade_fall5};
+statetype s_grenade_fall3  = {false,SPR_ENFORCER_FALL3,6,T_Projectile,0,&s_grenade_fall4};
+statetype s_grenade_fall2  = {false,SPR_ENFORCER_FALL1,6,T_Projectile,0,&s_grenade_fall3};
+statetype s_grenade_fall1  = {false,SPR_ENFORCER_FALL1,6,T_Projectile,0,&s_grenade_fall2};
+
+statetype s_grenadehit3     = {false,SPR_GRENADE_HIT3,5,NULL,0,NULL};
+statetype s_grenadehit2     = {false,SPR_GRENADE_HIT2,5,NULL,0,&s_grenadehit3};
+statetype s_grenadehit1     = {false,SPR_GRENADE_HIT1,5,NULL,0,&s_grenadehit2};
+
+
+statetype s_enforcerdead      = {false,SPR_ENFORCER_DEAD,0,T_Collide,0,&s_enforcerdead};
+statetype s_enforcerdie4      = {false,SPR_ENFORCER_DIE4,7,T_Collide,0,&s_enforcerdead};
+statetype s_enforcerdie3      = {false,SPR_ENFORCER_DIE3,7,T_Collide,0,&s_enforcerdie4};
+statetype s_enforcerdie2      = {false,SPR_ENFORCER_DIE2,7,T_Collide,0,&s_enforcerdie3};
+statetype s_enforcerdie1      = {false,SPR_ENFORCER_DIE1,7,T_Collide,0,&s_enforcerdie2};
+
+
+
+statetype s_enforcercrushed2		= {false,SPR_ENFORCER_DIE3,2,NULL,0,&s_enforcerdead};
+statetype s_enforcercrushed1		= {false,SPR_ENFORCER_DIE1,2,NULL,0,&s_enforcercrushed2};
+
+/*
+============================================================================
+
+								 ROBOT GUARD
+
+============================================================================
+*/
+
+
+
+statetype s_robogrdstand	= {16,SPR_ROBOGRD_S11,0,T_Stand,0,&s_robogrdstand};
+
+statetype s_robogrdpath1 	= {16,SPR_ROBOGRD_S11,20,T_AutoPath,0,&s_robogrdpath1};
+
+statetype s_robowait = {16,SPR_ROBOGRD_S11,0,NULL,0,&s_robowait};
+statetype s_roborealign = {16,SPR_ROBOGRD_S11,0,T_AutoRealign,0,&s_roborealign};
+statetype s_roboalign = {16,SPR_ROBOGRD_S11,0,T_AutoShootAlign,0,&s_roboalign};
+
+statetype s_robogrdshoot1 	= {false,SPR_ROBOGRD_S11,35,A_MissileWeapon,0,&s_roborealign};
+
+statetype s_robogrdshuriken4 	= {false,SPR_ROBOGRD_SHURIKEN4,4,T_Projectile,0,&s_robogrdshuriken1};
+statetype s_robogrdshuriken3 	= {false,SPR_ROBOGRD_SHURIKEN3,4,T_Projectile,0,&s_robogrdshuriken4};
+statetype s_robogrdshuriken2 	= {false,SPR_ROBOGRD_SHURIKEN2,4,T_Projectile,0,&s_robogrdshuriken3};
+statetype s_robogrdshuriken1  = {false,SPR_ROBOGRD_SHURIKEN1,4,T_Projectile,0,&s_robogrdshuriken2};
+
+statetype s_shurikenhit3    = {false,SPR_SHURIKEN_HIT3,5,NULL,0,NULL};
+statetype s_shurikenhit2    = {false,SPR_SHURIKEN_HIT2,5,NULL,0,&s_shurikenhit3};
+statetype s_shurikenhit1    = {false,SPR_SHURIKEN_HIT1,5,NULL,0,&s_shurikenhit2};
+
+statetype s_robogrdcollide  = {16,SPR_ROBOGRD_S11,0,T_Collide,0,&s_robogrdcollide};
+statetype s_robogrdcollide2 = {16,SPR_ROBOGRD_S11,0,T_Collide,0,&s_robogrdcollide2};
+
+//statetype s_robogrdchase1 	= {16,SPR_ROBOGRD_S11,10,T_RoboChase,0,&s_robogrdchase1};
+
+statetype s_robogrddead		= {false,ROBOGRDDEAD,0,T_Collide,0,&s_robogrddead};
+statetype s_robogrddie9	   = {false,ROBOGRDDIE9,3,T_Collide,0,&s_robogrddead};
+statetype s_robogrddie8	   = {false,ROBOGRDDIE8,3,T_Collide,0,&s_robogrddie9};
+statetype s_robogrddie7	   = {false,ROBOGRDDIE7,3,T_Collide,0,&s_robogrddie8};
+statetype s_robogrddie6	   = {false,ROBOGRDDIE6,3,T_Collide,0,&s_robogrddie7};
+statetype s_robogrddie5	   = {false,ROBOGRDDIE5,3,T_Collide,0,&s_robogrddie6};
+statetype s_robogrddie4	   = {false,ROBOGRDDIE4,3,T_Collide,0,&s_robogrddie5};
+statetype s_robogrddie3	   = {false,ROBOGRDDIE3,3,T_Collide,0,&s_robogrddie4};
+statetype s_robogrddie2	   = {false,ROBOGRDDIE2,3,T_Collide,0,&s_robogrddie3};
+statetype s_robogrddie1	   = {false,ROBOGRDDIE1,3,T_Collide,0,&s_robogrddie2};
+
+
+statetype s_bstar4 = {false,SPR_BSTAR4,1,T_Projectile,0,&s_bstar1};
+statetype s_bstar3 = {false,SPR_BSTAR3,1,T_Projectile,0,&s_bstar4};
+statetype s_bstar2 = {false,SPR_BSTAR2,1,T_Projectile,0,&s_bstar3};
+statetype s_bstar1 = {false,SPR_BSTAR1,1,T_Projectile,0,&s_bstar2};
+
+
+
+/*
+==========================================================================
+=
+=                             Explosions
+=
+==========================================================================
+*/
+
+statetype s_altexplosion10 = {false,SPR_EXPLOSION19,3,NULL,0,NULL};
+statetype s_altexplosion9 = {false,SPR_EXPLOSION17,3,NULL,0,&s_altexplosion10};
+statetype s_altexplosion8 = {false,SPR_EXPLOSION15,3,NULL,0,&s_altexplosion9};
+statetype s_altexplosion7 = {false,SPR_EXPLOSION13,3,NULL,0,&s_altexplosion8};
+statetype s_altexplosion6 = {false,SPR_EXPLOSION11,3,NULL,0,&s_altexplosion7};
+statetype s_altexplosion5 = {false,SPR_EXPLOSION9,3,NULL,0,&s_altexplosion6};
+statetype s_altexplosion4 = {false,SPR_EXPLOSION7,3,NULL,0,&s_altexplosion5};
+statetype s_altexplosion3 = {false,SPR_EXPLOSION5,3,NULL,0,&s_altexplosion4};
+statetype s_altexplosion2 = {false,SPR_EXPLOSION3,3,T_Explosion,0,&s_altexplosion3};
+statetype s_altexplosion1 = {false,SPR_EXPLOSION1,3,NULL,0,&s_altexplosion2};
+
+
+
+
+
+statetype s_explosion20 = {false,SPR_EXPLOSION20,2,NULL,0,NULL};
+statetype s_explosion19 = {false,SPR_EXPLOSION19,2,NULL,0,&s_explosion20};
+statetype s_explosion18 = {false,SPR_EXPLOSION18,2,NULL,0,&s_explosion19};
+statetype s_explosion17 = {false,SPR_EXPLOSION17,2,NULL,0,&s_explosion18};
+statetype s_explosion16 = {false,SPR_EXPLOSION16,2,NULL,0,&s_explosion17};
+statetype s_explosion15 = {false,SPR_EXPLOSION15,2,NULL,0,&s_explosion16};
+statetype s_explosion14 = {false,SPR_EXPLOSION14,2,NULL,0,&s_explosion15};
+statetype s_explosion13 = {false,SPR_EXPLOSION13,2,NULL,0,&s_explosion14};
+statetype s_explosion12 = {false,SPR_EXPLOSION12,2,NULL,0,&s_explosion13};
+statetype s_explosion11 = {false,SPR_EXPLOSION11,2,NULL,0,&s_explosion12};
+statetype s_explosion10 = {false,SPR_EXPLOSION10,2,NULL,0,&s_explosion11};
+statetype s_explosion9 = {false,SPR_EXPLOSION9,2,NULL,0,&s_explosion10};
+statetype s_explosion8 = {false,SPR_EXPLOSION8,2,NULL,0,&s_explosion9};
+statetype s_explosion7 = {false,SPR_EXPLOSION7,2,NULL,0,&s_explosion8};
+statetype s_explosion6 = {false,SPR_EXPLOSION6,2,NULL,0,&s_explosion7};
+statetype s_explosion5 = {false,SPR_EXPLOSION5,2,NULL,0,&s_explosion6};
+statetype s_explosion4 = {false,SPR_EXPLOSION4,2,NULL,0,&s_explosion5};
+statetype s_explosion3 = {false,SPR_EXPLOSION3,2,T_Explosion,0,&s_explosion4};
+statetype s_explosion2 = {false,SPR_EXPLOSION2,2,NULL,0,&s_explosion3};
+statetype s_explosion1 = {false,SPR_EXPLOSION1,2,NULL,0,&s_explosion2};
+
+
+
+statetype s_grexplosion20 = {false,SPR_GROUNDEXPL20,2,T_Special,0,NULL};
+statetype s_grexplosion19 = {false,SPR_GROUNDEXPL19,2,NULL,0,&s_grexplosion20};
+statetype s_grexplosion18 = {false,SPR_GROUNDEXPL18,2,NULL,0,&s_grexplosion19};
+statetype s_grexplosion17 = {false,SPR_GROUNDEXPL17,2,NULL,0,&s_grexplosion18};
+statetype s_grexplosion16 = {false,SPR_GROUNDEXPL16,2,NULL,0,&s_grexplosion17};
+statetype s_grexplosion15 = {false,SPR_GROUNDEXPL15,2,NULL,0,&s_grexplosion16};
+statetype s_grexplosion14 = {false,SPR_GROUNDEXPL14,2,NULL,0,&s_grexplosion15};
+statetype s_grexplosion13 = {false,SPR_GROUNDEXPL13,2,NULL,0,&s_grexplosion14};
+statetype s_grexplosion12 = {false,SPR_GROUNDEXPL12,2,NULL,0,&s_grexplosion13};
+statetype s_grexplosion11 = {false,SPR_GROUNDEXPL11,2,NULL,0,&s_grexplosion12};
+statetype s_grexplosion10 = {false,SPR_GROUNDEXPL10,2,NULL,0,&s_grexplosion11};
+statetype s_grexplosion9 = {false,SPR_GROUNDEXPL9,2,NULL,0,&s_grexplosion10};
+statetype s_grexplosion8 = {false,SPR_GROUNDEXPL8,2,NULL,0,&s_grexplosion9};
+statetype s_grexplosion7 = {false,SPR_GROUNDEXPL7,2,NULL,0,&s_grexplosion8};
+statetype s_grexplosion6 = {false,SPR_GROUNDEXPL6,2,NULL,0,&s_grexplosion7};
+statetype s_grexplosion5 = {false,SPR_GROUNDEXPL5,2,NULL,0,&s_grexplosion6};
+statetype s_grexplosion4 = {false,SPR_GROUNDEXPL4,2,NULL,0,&s_grexplosion5};
+statetype s_grexplosion3 = {false,SPR_GROUNDEXPL3,2,T_Explosion,0,&s_grexplosion4};
+statetype s_grexplosion2 = {false,SPR_GROUNDEXPL2,2,NULL,0,&s_grexplosion3};
+statetype s_grexplosion1 = {false,SPR_GROUNDEXPL1,2,NULL,0,&s_grexplosion2};
+
+
+
+statetype s_staticexplosion25 = {false,SPR_STATICEXPL25,2,NULL,0,NULL};
+statetype s_staticexplosion24 = {false,SPR_STATICEXPL24,2,NULL,0,&s_staticexplosion25};
+statetype s_staticexplosion23 = {false,SPR_STATICEXPL23,2,NULL,0,&s_staticexplosion24};
+statetype s_staticexplosion22 = {false,SPR_STATICEXPL22,2,NULL,0,&s_staticexplosion23};
+statetype s_staticexplosion21 = {false,SPR_STATICEXPL21,2,NULL,0,&s_staticexplosion22};
+statetype s_staticexplosion20 = {false,SPR_STATICEXPL20,2,NULL,0,&s_staticexplosion21};
+statetype s_staticexplosion19 = {false,SPR_STATICEXPL19,2,NULL,0,&s_staticexplosion20};
+statetype s_staticexplosion18 = {false,SPR_STATICEXPL18,2,NULL,0,&s_staticexplosion19};
+statetype s_staticexplosion17 = {false,SPR_STATICEXPL17,2,NULL,0,&s_staticexplosion18};
+statetype s_staticexplosion16 = {false,SPR_STATICEXPL16,2,NULL,0,&s_staticexplosion17};
+statetype s_staticexplosion15 = {false,SPR_STATICEXPL15,2,NULL,0,&s_staticexplosion16};
+statetype s_staticexplosion14 = {false,SPR_STATICEXPL14,2,NULL,0,&s_staticexplosion15};
+statetype s_staticexplosion13 = {false,SPR_STATICEXPL13,2,NULL,0,&s_staticexplosion14};
+statetype s_staticexplosion12 = {false,SPR_STATICEXPL12,2,NULL,0,&s_staticexplosion13};
+statetype s_staticexplosion11 = {false,SPR_STATICEXPL11,2,NULL,0,&s_staticexplosion12};
+statetype s_staticexplosion10 = {false,SPR_STATICEXPL10,2,NULL,0,&s_staticexplosion11};
+statetype s_staticexplosion9 = {false,SPR_STATICEXPL9,2,NULL,0,&s_staticexplosion10};
+statetype s_staticexplosion8 = {false,SPR_STATICEXPL8,2,NULL,0,&s_staticexplosion9};
+statetype s_staticexplosion7 = {false,SPR_STATICEXPL7,2,NULL,0,&s_staticexplosion8};
+statetype s_staticexplosion6 = {false,SPR_STATICEXPL6,2,NULL,0,&s_staticexplosion7};
+statetype s_staticexplosion5 = {false,SPR_STATICEXPL5,2,NULL,0,&s_staticexplosion6};
+statetype s_staticexplosion4 = {false,SPR_STATICEXPL4,2,NULL,0,&s_staticexplosion5};
+statetype s_staticexplosion3 = {false,SPR_STATICEXPL3,2,T_Explosion,0,&s_staticexplosion4};
+statetype s_staticexplosion2 = {false,SPR_STATICEXPL2,2,NULL,0,&s_staticexplosion3};
+statetype s_staticexplosion1 = {false,SPR_STATICEXPL1,2,NULL,0,&s_staticexplosion2};
+
+
+
+statetype s_upblade16 = {false,UBLADE8,1,T_Path,0,&s_upblade1};
+statetype s_upblade15 = {false,UBLADE7,2,T_Path,0,&s_upblade16};
+statetype s_upblade14 = {false,UBLADE6,1,T_Path,0,&s_upblade15};
+statetype s_upblade13 = {false,UBLADE5,2,T_Path,0,&s_upblade14};
+statetype s_upblade12 = {false,UBLADE4,1,T_Path,0,&s_upblade13};
+statetype s_upblade11 = {false,UBLADE3,2,T_Path,0,&s_upblade12};
+statetype s_upblade10 = {false,UBLADE2,1,T_Path,0,&s_upblade11};
+statetype s_upblade9 = {false,UBLADE9,2,T_Path,0,&s_upblade10};
+statetype s_upblade8 = {false,UBLADE8,1,T_Path,0,&s_upblade9};
+statetype s_upblade7 = {false,UBLADE7,2,T_Path,0,&s_upblade8};
+statetype s_upblade6 = {false,UBLADE6,1,T_Path,0,&s_upblade7};
+statetype s_upblade5 = {false,UBLADE5,2,T_Path,0,&s_upblade6};
+statetype s_upblade4 = {false,UBLADE4,1,T_Path,0,&s_upblade5};
+statetype s_upblade3 = {false,UBLADE3,2,T_Path,0,&s_upblade4};
+statetype s_upblade2 = {false,UBLADE2,1,T_Path,0,&s_upblade3};
+statetype s_upblade1 = {false,UBLADE1,2,T_Path,SF_SOUND,&s_upblade2};
+
+
+statetype s_firejetup23 = {false,FIREJETUP23,3,T_Path,SF_CRUSH,&s_firejetup1};
+statetype s_firejetup22 = {false,FIREJETUP22,3,T_Path,SF_CRUSH,&s_firejetup23};
+statetype s_firejetup21 = {false,FIREJETUP21,3,T_Path,0,&s_firejetup22};
+statetype s_firejetup20 = {false,FIREJETUP20,3,T_Path,0,&s_firejetup21};
+statetype s_firejetup19 = {false,FIREJETUP19,3,T_Path,0,&s_firejetup20};
+statetype s_firejetup18 = {false,FIREJETUP18,3,T_Path,0,&s_firejetup19};
+statetype s_firejetup17 = {false,FIREJETUP17,3,T_Path,0,&s_firejetup18};
+statetype s_firejetup16 = {false,FIREJETUP16,3,T_Path,SF_CRUSH,&s_firejetup17};
+statetype s_firejetup15 = {false,FIREJETUP15,3,T_Path,SF_CRUSH,&s_firejetup16};
+statetype s_firejetup14 = {false,FIREJETUP14,3,T_Path,SF_CRUSH,&s_firejetup15};
+statetype s_firejetup13 = {false,FIREJETUP13,3,T_Path,0,&s_firejetup14};
+statetype s_firejetup12 = {false,FIREJETUP12,3,T_Path,0,&s_firejetup13};
+statetype s_firejetup11 = {false,FIREJETUP11,3,T_Path,0,&s_firejetup12};
+statetype s_firejetup10 = {false,FIREJETUP10,3,T_Path,0,&s_firejetup11};
+statetype s_firejetup9 = {false,FIREJETUP9,3,T_Path,0,&s_firejetup10};
+statetype s_firejetup8 = {false,FIREJETUP8,3,T_Path,SF_CRUSH,&s_firejetup9};
+statetype s_firejetup7 = {false,FIREJETUP7,3,T_Path,SF_CRUSH,&s_firejetup8};
+statetype s_firejetup6 = {false,FIREJETUP6,3,T_Path,SF_CRUSH,&s_firejetup7};
+statetype s_firejetup5 = {false,FIREJETUP5,3,T_Path,0,&s_firejetup6};
+statetype s_firejetup4 = {false,FIREJETUP4,3,T_Path,0,&s_firejetup5};
+statetype s_firejetup3 = {false,FIREJETUP3,3,T_Path,0,&s_firejetup4};
+statetype s_firejetup2 = {false,FIREJETUP2,3,T_Path,0,&s_firejetup3};
+statetype s_firejetup1 = {false,FIREJETUP1,70,T_Path,SF_SOUND,&s_firejetup2};
+
+
+
+statetype s_columndownup6 = {false,CRUSHDOWN7,5,NULL,0,&s_columndowndown1};
+statetype s_columndownup5 = {false,CRUSHDOWN6,5,NULL,0,&s_columndownup6};
+statetype s_columndownup4 = {false,CRUSHDOWN5,5,NULL,SF_BLOCK,&s_columndownup5};
+statetype s_columndownup3 = {false,CRUSHDOWN4,5,NULL,SF_BLOCK,&s_columndownup4};
+statetype s_columndownup2 = {false,CRUSHDOWN3,5,NULL,SF_BLOCK,&s_columndownup3};
+statetype s_columndownup1 = {false,CRUSHDOWN2,5,NULL,SF_BLOCK,&s_columndownup2};
+
+
+statetype s_columndowndown8 = {false,CRUSHDOWN1,5,T_CrushDown,SF_CRUSH|SF_DOWN|SF_BLOCK,&s_columndownup1};
+statetype s_columndowndown7 = {false,CRUSHDOWN2,5,T_CrushDown,SF_CRUSH|SF_DOWN|SF_BLOCK,&s_columndowndown8};
+statetype s_columndowndown6 = {false,CRUSHDOWN3,5,T_CrushDown,SF_DOWN|SF_BLOCK,&s_columndowndown7};
+statetype s_columndowndown5 = {false,CRUSHDOWN4,5,T_CrushDown,SF_DOWN|SF_BLOCK,&s_columndowndown6};
+statetype s_columndowndown4 = {false,CRUSHDOWN5,5,T_CrushDown,SF_DOWN,&s_columndowndown5};
+statetype s_columndowndown3 = {false,CRUSHDOWN6,5,T_CrushDown,SF_DOWN,&s_columndowndown4};
+statetype s_columndowndown2 = {false,CRUSHDOWN7,5,T_CrushDown,SF_DOWN,&s_columndowndown3};
+statetype s_columndowndown1 = {false,CRUSHDOWN8,30,T_CrushDown,SF_DOWN|SF_SOUND,&s_columndowndown2};
+
+
+statetype s_spearup16 = {false,SPEARUP16,2,T_Spears,SF_CRUSH,&s_spearup1};
+statetype s_spearup15 = {false,SPEARUP15,2,T_Spears,SF_CRUSH,&s_spearup16};
+statetype s_spearup14 = {false,SPEARUP14,2,T_Spears,SF_CRUSH,&s_spearup15};
+statetype s_spearup13 = {false,SPEARUP13,2,T_Spears,SF_CRUSH,&s_spearup14};
+statetype s_spearup12 = {false,SPEARUP12,2,T_Spears,SF_CRUSH,&s_spearup13};
+statetype s_spearup11 = {false,SPEARUP11,2,T_Spears,SF_CRUSH,&s_spearup12};
+statetype s_spearup10 = {false,SPEARUP10,2,T_Spears,SF_CRUSH,&s_spearup11};
+statetype s_spearup9 = {false,SPEARUP9,2,T_Spears,SF_DOWN,&s_spearup10};
+
+statetype s_spearup8 = {false,SPEARUP8,35,T_Spears,SF_DOWN|SF_SOUND,&s_spearup9};
+statetype s_spearup7 = {false,SPEARUP7,2,T_Spears,SF_DOWN,&s_spearup8};
+statetype s_spearup6 = {false,SPEARUP6,2,T_Spears,SF_CRUSH,&s_spearup7};
+statetype s_spearup5 = {false,SPEARUP5,2,T_Spears,SF_CRUSH,&s_spearup6};
+statetype s_spearup4 = {false,SPEARUP4,2,T_Spears,SF_CRUSH,&s_spearup5};
+statetype s_spearup3 = {false,SPEARUP3,2,T_Spears,SF_CRUSH,&s_spearup4};
+statetype s_spearup2 = {false,SPEARUP2,2,T_Spears,SF_CRUSH,&s_spearup3};
+statetype s_spearup1 = {false,SPEARUP1,2,T_Spears,SF_CRUSH,&s_spearup2};
+
+
+statetype s_dust = {false,NOTHING,0,NULL,0,&s_dust};
+
+
+
+statetype s_gas2 = {false,SPR42_GRATE,5,T_Count,0,&s_gas2};
+statetype s_gas1 = {false,SPR42_GRATE,0,NULL,0,&s_gas1};
+
+
+//================== player stuff =======================================/
+
+statetype s_p_bazooka1 = {16,SPR_BJMISS11,3,T_Projectile,0,&s_p_bazooka1};
+
+statetype s_p_grenade = {16,SPR_BJMISS11,3,T_Projectile,0,&s_p_grenade};
+
+/*
+statetype s_p_misssmoke4 = {false,MISSSMOKE4,7,NULL,0,NULL};
+statetype s_p_misssmoke3 = {false,MISSSMOKE3,7,NULL,0,&s_p_misssmoke4};
+statetype s_p_misssmoke2 = {false,MISSSMOKE2,7,NULL,0,&s_p_misssmoke3};
+statetype s_p_misssmoke1 = {false,MISSSMOKE1,3,NULL,0,&s_p_misssmoke2};
+*/
+
+
+statetype s_basemarker8 = {false,FLASH8,3,NULL,0,&s_basemarker1};
+statetype s_basemarker7 = {false,FLASH7,3,NULL,0,&s_basemarker8};
+statetype s_basemarker6 = {false,FLASH6,3,NULL,0,&s_basemarker7};
+statetype s_basemarker5 = {false,FLASH5,3,NULL,0,&s_basemarker6};
+statetype s_basemarker4 = {false,FLASH4,3,NULL,0,&s_basemarker5};
+statetype s_basemarker3 = {false,FLASH3,3,NULL,0,&s_basemarker4};
+statetype s_basemarker2 = {false,FLASH2,3,NULL,0,&s_basemarker3};
+statetype s_basemarker1 = {false,FLASH1,3,NULL,0,&s_basemarker2};
+
+
+
+statetype s_flash8 = {false,FLASH8,3,NULL,0,NULL};
+statetype s_flash7 = {false,FLASH7,3,NULL,0,&s_flash8};
+statetype s_flash6 = {false,FLASH6,3,NULL,0,&s_flash7};
+statetype s_flash5 = {false,FLASH5,3,NULL,0,&s_flash6};
+statetype s_flash4 = {false,FLASH4,3,NULL,0,&s_flash5};
+statetype s_flash3 = {false,FLASH3,3,NULL,0,&s_flash4};
+statetype s_flash2 = {false,FLASH2,3,NULL,0,&s_flash3};
+statetype s_flash1 = {false,FLASH1,3,NULL,0,&s_flash2};
+
+statetype s_gunsmoke8 = {false,GUNSMOKE8,3,NULL,0,NULL};
+statetype s_gunsmoke7 = {false,GUNSMOKE7,3,NULL,0,&s_gunsmoke8};
+statetype s_gunsmoke6 = {false,GUNSMOKE6,3,NULL,0,&s_gunsmoke7};
+statetype s_gunsmoke5 = {false,GUNSMOKE5,3,NULL,0,&s_gunsmoke6};
+statetype s_gunsmoke4 = {false,GUNSMOKE4,3,NULL,0,&s_gunsmoke5};
+statetype s_gunsmoke3 = {false,GUNSMOKE3,3,NULL,0,&s_gunsmoke4};
+statetype s_gunsmoke2 = {false,GUNSMOKE2,3,NULL,0,&s_gunsmoke3};
+statetype s_gunsmoke1 = {false,GUNSMOKE1,2,NULL,0,&s_gunsmoke2};
+
+statetype s_bloodspurt8 = {false,BLOODSPURT8,7,NULL,0,NULL};
+statetype s_bloodspurt7 = {false,BLOODSPURT7,7,NULL,0,&s_bloodspurt8};
+statetype s_bloodspurt6 = {false,BLOODSPURT6,7,NULL,0,&s_bloodspurt7};
+statetype s_bloodspurt5 = {false,BLOODSPURT5,7,NULL,0,&s_bloodspurt6};
+statetype s_bloodspurt4 = {false,BLOODSPURT4,7,NULL,0,&s_bloodspurt5};
+statetype s_bloodspurt3 = {false,BLOODSPURT3,7,NULL,0,&s_bloodspurt4};
+statetype s_bloodspurt2 = {false,BLOODSPURT2,7,NULL,0,&s_bloodspurt3};
+statetype s_bloodspurt1 = {false,BLOODSPURT1,5,NULL,0,&s_bloodspurt2};
+
+statetype s_hitmetalwall4 = {false,HITMETALWALL4,7,NULL,0,NULL};
+statetype s_hitmetalwall3 = {false,HITMETALWALL3,7,NULL,0,&s_hitmetalwall4};
+statetype s_hitmetalwall2 = {false,HITMETALWALL2,7,NULL,0,&s_hitmetalwall3};
+statetype s_hitmetalwall1 = {false,HITMETALWALL1,5,NULL,0,&s_hitmetalwall2};
+
+statetype s_hitmetalactor4 = {false,HITMETALACTOR4,7,NULL,0,NULL};
+statetype s_hitmetalactor3 = {false,HITMETALACTOR3,7,NULL,0,&s_hitmetalactor4};
+statetype s_hitmetalactor2 = {false,HITMETALACTOR2,7,NULL,0,&s_hitmetalactor3};
+statetype s_hitmetalactor1 = {false,HITMETALACTOR1,5,NULL,0,&s_hitmetalactor2};
+
+
+
+statetype s_fireunit15 = {false,FIREW15,3,T_Firethink,0,&s_fireunit1};
+statetype s_fireunit14 = {false,FIREW14,3,T_Firethink,0,&s_fireunit15};
+statetype s_fireunit13 = {false,FIREW13,3,T_Firethink,0,&s_fireunit14};
+statetype s_fireunit12 = {false,FIREW12,3,T_Firethink,0,&s_fireunit13};
+statetype s_fireunit11 = {false,FIREW11,3,T_Firethink,0,&s_fireunit12};
+statetype s_fireunit10 = {false,FIREW10,3,T_Firethink,0,&s_fireunit11};
+statetype s_fireunit9 = {false,FIREW9,3,T_Firethink,0,&s_fireunit10};
+statetype s_fireunit8 = {false,FIREW8,3,T_Firethink,0,&s_fireunit9};
+statetype s_fireunit7 = {false,FIREW7,3,T_Firethink,0,&s_fireunit8};
+statetype s_fireunit6 = {false,FIREW6,3,T_Firethink,0,&s_fireunit7};
+statetype s_fireunit5 = {false,FIREW5,3,T_Firethink,0,&s_fireunit6};
+statetype s_fireunit4 = {false,FIREW4,3,T_Firethink,0,&s_fireunit5};
+statetype s_fireunit3 = {false,FIREW3,3,T_Firethink,0,&s_fireunit4};
+statetype s_fireunit2 = {false,FIREW2,3,T_Firethink,0,&s_fireunit3};
+statetype s_fireunit1 = {false,FIREW1,3,T_Firethink,0,&s_fireunit2};
+
+
+
+statetype s_skeleton48 = {false,SKELETON48,0,T_Convert,0,&s_skeleton48};
+statetype s_skeleton47 = {false,SKELETON47,2,NULL,0,&s_skeleton48};
+statetype s_skeleton46 = {false,SKELETON46,2,NULL,0,&s_skeleton47};
+statetype s_skeleton45 = {false,SKELETON45,2,NULL,0,&s_skeleton46};
+statetype s_skeleton44 = {false,SKELETON44,2,NULL,0,&s_skeleton45};
+statetype s_skeleton43 = {false,SKELETON43,2,NULL,0,&s_skeleton44};
+statetype s_skeleton42 = {false,SKELETON42,2,NULL,0,&s_skeleton43};
+statetype s_skeleton41 = {false,SKELETON41,2,T_Xylophone,0,&s_skeleton42};
+statetype s_skeleton40 = {false,SKELETON40,2,NULL,0,&s_skeleton41};
+statetype s_skeleton39 = {false,SKELETON39,2,NULL,0,&s_skeleton40};
+statetype s_skeleton38 = {false,SKELETON38,2,NULL,0,&s_skeleton39};
+statetype s_skeleton37 = {false,SKELETON37,2,NULL,0,&s_skeleton38};
+statetype s_skeleton36 = {false,SKELETON36,2,NULL,0,&s_skeleton37};
+statetype s_skeleton35 = {false,SKELETON35,2,NULL,0,&s_skeleton36};
+statetype s_skeleton34 = {false,SKELETON34,2,NULL,0,&s_skeleton35};
+statetype s_skeleton33 = {false,SKELETON33,2,NULL,0,&s_skeleton34};
+statetype s_skeleton32 = {false,SKELETON32,2,NULL,0,&s_skeleton33};
+statetype s_skeleton31 = {false,SKELETON31,2,NULL,0,&s_skeleton32};
+statetype s_skeleton30 = {false,SKELETON30,2,NULL,0,&s_skeleton31};
+statetype s_skeleton29 = {false,SKELETON29,2,NULL,0,&s_skeleton30};
+statetype s_skeleton28 = {false,SKELETON28,2,NULL,0,&s_skeleton29};
+statetype s_skeleton27 = {false,SKELETON27,2,NULL,0,&s_skeleton28};
+statetype s_skeleton26 = {false,SKELETON26,2,NULL,0,&s_skeleton27};
+statetype s_skeleton25 = {false,SKELETON25,2,NULL,0,&s_skeleton26};
+statetype s_skeleton24 = {false,SKELETON24,2,NULL,0,&s_skeleton25};
+statetype s_skeleton23 = {false,SKELETON23,2,NULL,0,&s_skeleton24};
+statetype s_skeleton22 = {false,SKELETON22,2,NULL,0,&s_skeleton23};
+statetype s_skeleton21 = {false,SKELETON21,2,NULL,0,&s_skeleton22};
+statetype s_skeleton20 = {false,SKELETON20,2,NULL,0,&s_skeleton21};
+statetype s_skeleton19 = {false,SKELETON19,2,NULL,0,&s_skeleton20};
+statetype s_skeleton18 = {false,SKELETON18,2,NULL,0,&s_skeleton19};
+statetype s_skeleton17 = {false,SKELETON17,2,NULL,0,&s_skeleton18};
+statetype s_skeleton16 = {false,SKELETON16,2,NULL,0,&s_skeleton17};
+statetype s_skeleton15 = {false,SKELETON15,2,NULL,0,&s_skeleton16};
+statetype s_skeleton14 = {false,SKELETON14,2,NULL,0,&s_skeleton15};
+statetype s_skeleton13 = {false,SKELETON13,2,NULL,0,&s_skeleton14};
+statetype s_skeleton12 = {false,SKELETON12,2,NULL,0,&s_skeleton13};
+statetype s_skeleton11 = {false,SKELETON11,2,NULL,0,&s_skeleton12};
+statetype s_skeleton10 = {false,SKELETON10,2,NULL,0,&s_skeleton11};
+statetype s_skeleton9 = {false,SKELETON9,2,NULL,0,&s_skeleton10};
+statetype s_skeleton8 = {false,SKELETON8,2,NULL,0,&s_skeleton9};
+statetype s_skeleton7 = {false,SKELETON7,2,NULL,0,&s_skeleton8};
+statetype s_skeleton6 = {false,SKELETON6,2,NULL,0,&s_skeleton7};
+statetype s_skeleton5 = {false,SKELETON5,2,NULL,0,&s_skeleton6};
+statetype s_skeleton4 = {false,SKELETON4,2,NULL,0,&s_skeleton5};
+statetype s_skeleton3 = {false,SKELETON3,2,NULL,0,&s_skeleton4};
+statetype s_skeleton2 = {false,SKELETON2,2,NULL,0,&s_skeleton3};
+statetype s_skeleton1 = {false,SKELETON1,2,NULL,0,&s_skeleton2};
+
+
+
+statetype s_spring9 = {false,SPRING9,4,T_Spring,SF_DOWN,&s_spring1};
+statetype s_spring8 = {false,SPRING8,4,NULL,0,&s_spring9};
+statetype s_spring7 = {false,SPRING7,4,NULL,0,&s_spring8};
+statetype s_spring6 = {false,SPRING6,4,NULL,0,&s_spring7};
+statetype s_spring5 = {false,SPRING5,4,NULL,0,&s_spring6};
+statetype s_spring4 = {false,SPRING4,15,NULL,SF_UP,&s_spring5};
+statetype s_spring3 = {false,SPRING3,1,NULL,SF_UP,&s_spring4};
+statetype s_spring2 = {false,SPRING2,1,NULL,SF_UP,&s_spring3};
+statetype s_spring1 = {false,SPRING1,0,NULL,SF_UP,&s_spring1};
+
+
+statetype s_autospring9 = {false,SPRING9,4,NULL,0,&s_autospring1};
+statetype s_autospring8 = {false,SPRING8,4,NULL,0,&s_autospring9};
+statetype s_autospring7 = {false,SPRING7,4,NULL,0,&s_autospring8};
+statetype s_autospring6 = {false,SPRING6,4,NULL,0,&s_autospring7};
+statetype s_autospring5 = {false,SPRING5,4,NULL,0,&s_autospring6};
+statetype s_autospring4 = {false,SPRING4,15,NULL,SF_UP,&s_autospring5};
+statetype s_autospring3 = {false,SPRING3,1,T_Spring,SF_UP,&s_autospring4};
+statetype s_autospring2 = {false,SPRING2,1,T_Spring,SF_UP,&s_autospring3};
+statetype s_autospring1 = {false,SPRING1,70*SPRINGDELAY,NULL,0,&s_autospring2};
+
+//====================== remote player ==============================//
+
+statetype s_itemspawn8 = {false,ITEMSPAWN8,6,NULL,0,NULL};
+statetype s_itemspawn7 = {false,ITEMSPAWN7,6,NULL,0,&s_itemspawn8};
+statetype s_itemspawn6 = {false,ITEMSPAWN6,6,NULL,0,&s_itemspawn7};
+statetype s_itemspawn5 = {false,ITEMSPAWN5,6,NULL,0,&s_itemspawn6};
+statetype s_itemspawn4 = {false,ITEMSPAWN4,6,NULL,0,&s_itemspawn5};
+statetype s_itemspawn3 = {false,ITEMSPAWN3,6,NULL,0,&s_itemspawn4};
+statetype s_itemspawn2 = {false,ITEMSPAWN2,6,NULL,0,&s_itemspawn3};
+statetype s_itemspawn1 = {false,ITEMSPAWN1,6,NULL,0,&s_itemspawn2};
+
+
+statetype s_player = {true,CASSATT_S1,0,T_Player,0,&s_player};
+
+statetype s_pgunattack2 = {true,CASSATT_SHOOT11,0,T_Attack,0,&s_pgunattack2};
+statetype s_pgunattack1 = {true,CASSATT_SHOOT21,5,T_Attack,0,&s_pgunattack2};
+
+statetype s_pmissattack2 = {true,CASSATTM_SHOOT11,0,T_Attack,0,&s_pmissattack2};
+statetype s_pmissattack1 = {true,CASSATTM_SHOOT21,5,T_Attack,0,&s_pmissattack2};
+
+statetype s_pbatblast = {true,CASSATT_SHOOT21,0,T_BatBlast,0,&s_pbatblast};
+
+
+
+
+statetype s_remotemove4 = {true,CASSATT_W41,5,T_Player,SF_DOWN,&s_remotemove1};
+statetype s_remotemove3 = {true,CASSATT_W31,5,T_Player,SF_DOWN,&s_remotemove4};
+statetype s_remotemove2 = {true,CASSATT_W21,5,T_Player,SF_DOWN,&s_remotemove3};
+statetype s_remotemove1 = {true,CASSATT_W11,5,T_Player,SF_DOWN,&s_remotemove2};
+
+statetype s_remoteinelev = {true,CASSATT_S1,700,T_Player,0,&s_remoteinelev};
+
+statetype s_remotedead = {false,CASSATT_VDEAD,0,T_Player,0,&s_remotedead};
+
+
+
+statetype s_remotedie6 = {false,CASSATT_VDIE6,3,T_Player,0,&s_remotedead};
+statetype s_remotedie5 = {false,CASSATT_VDIE5,3,T_Player,0,&s_remotedie6};
+statetype s_remotedie4 = {false,CASSATT_VDIE4,3,T_Player,0,&s_remotedie5};
+statetype s_remotedie3 = {false,CASSATT_VDIE3,3,T_Player,0,&s_remotedie4};
+statetype s_remotedie2 = {false,CASSATT_VDIE2,3,T_Player,0,&s_remotedie3};
+statetype s_remotedie1 = {false,CASSATT_VDIE1,3,T_Player,0,&s_remotedie2};
+
+
+statetype s_voidwait = {false,NOTHING,0,T_DeadWait,0,&s_voidwait};
+statetype s_ashwait = {false,SKELETON48,0,T_DeadWait,0,&s_ashwait};
+statetype s_deadwait = {false,CASSATT_VDEAD,0,T_DeadWait,0,&s_deadwait};
+statetype s_gutwait = {false,GUTS12,0,T_DeadWait,0,&s_gutwait};
+statetype s_remoteguts12 = {false,GUTS12,0,T_Player,0,&s_remoteguts12};
+statetype s_remoteguts11 = {false,GUTS11,3,T_Player,0,&s_remoteguts12};
+statetype s_remoteguts10 = {false,GUTS10,3,T_Player,0,&s_remoteguts11};
+statetype s_remoteguts9 = {false,GUTS9,3,T_Player,0,&s_remoteguts10};
+statetype s_remoteguts8 = {false,GUTS8,3,T_Player,0,&s_remoteguts9};
+statetype s_remoteguts7 = {false,GUTS7,3,T_Player,0,&s_remoteguts8};
+statetype s_remoteguts6 = {false,GUTS6,3,T_Player,0,&s_remoteguts7};
+statetype s_remoteguts5 = {false,GUTS5,3,T_Player,0,&s_remoteguts6};
+statetype s_remoteguts4 = {false,GUTS4,3,T_Player,0,&s_remoteguts5};
+statetype s_remoteguts3 = {false,GUTS3,3,T_Player,0,&s_remoteguts4};
+statetype s_remoteguts2 = {false,GUTS2,3,T_Player,0,&s_remoteguts3};
+statetype s_remoteguts1 = {false,GUTS1,3,T_Player,0,&s_remoteguts2};
+
+//========================================================================//
+
+statetype s_godfire4 = {false,GODFIRE4,3,T_Projectile,0,&s_godfire1};
+statetype s_godfire3 = {false,GODFIRE3,3,T_Projectile,0,&s_godfire4};
+statetype s_godfire2 = {false,GODFIRE2,3,T_Projectile,0,&s_godfire3};
+statetype s_godfire1 = {false,GODFIRE1,3,T_Projectile,0,&s_godfire2};
+
+
+
+
+statetype s_guts12 = {false,GUTS12,0,T_Collide,SF_GUTS,&s_guts12};
+statetype s_guts11 = {false,GUTS11,3,T_Collide,SF_GUTS,&s_guts12};
+statetype s_guts10 = {false,GUTS10,3,T_Collide,SF_GUTS,&s_guts11};
+statetype s_guts9 = {false,GUTS9,3,T_Collide,SF_GUTS,&s_guts10};
+statetype s_guts8 = {false,GUTS8,3,T_Collide,SF_GUTS,&s_guts9};
+statetype s_guts7 = {false,GUTS7,3,T_Collide,SF_GUTS,&s_guts8};
+statetype s_guts6 = {false,GUTS6,3,T_Collide,SF_GUTS,&s_guts7};
+statetype s_guts5 = {false,GUTS5,3,T_Collide,SF_GUTS,&s_guts6};
+statetype s_guts4 = {false,GUTS4,3,T_Collide,SF_GUTS,&s_guts5};
+statetype s_guts3 = {false,GUTS3,3,T_Collide,SF_GUTS,&s_guts4};
+statetype s_guts2 = {false,GUTS2,3,T_Collide,SF_GUTS,&s_guts3};
+statetype s_guts1 = {false,GUTS1,3,T_Collide,SF_GUTS,&s_guts2};
+
+//MED
+#if (SHAREWARE == 1) || (DOPEFISH == 0)
+statetype s_collectorwander8 = {false,COLLECTOR15,0,T_CollectorWander,0,&s_collectorwander1};
+statetype s_collectorwander7 = {false,COLLECTOR13,1,T_CollectorWander,0,&s_collectorwander8};
+statetype s_collectorwander6 = {false,COLLECTOR11,0,T_CollectorWander,0,&s_collectorwander7};
+statetype s_collectorwander5 = {false,COLLECTOR9,1,T_CollectorWander,0,&s_collectorwander6};
+statetype s_collectorwander4 = {false,COLLECTOR7,0,T_CollectorWander,0,&s_collectorwander5};
+statetype s_collectorwander3 = {false,COLLECTOR5,1,T_CollectorWander,0,&s_collectorwander4};
+statetype s_collectorwander2 = {false,COLLECTOR3,0,T_CollectorWander,0,&s_collectorwander3};
+statetype s_collectorwander1 = {false,COLLECTOR1,1,T_CollectorWander,0,&s_collectorwander2};
+#else
+
+statetype s_collectorwander8 = {false,DOPE8,2,T_CollectorWander,0,&s_collectorwander1};
+statetype s_collectorwander7 = {false,DOPE7,2,T_CollectorWander,0,&s_collectorwander8};
+statetype s_collectorwander6 = {false,DOPE6,2,T_CollectorWander,0,&s_collectorwander7};
+statetype s_collectorwander5 = {false,DOPE5,2,T_CollectorWander,0,&s_collectorwander6};
+statetype s_collectorwander4 = {false,DOPE4,2,T_CollectorWander,0,&s_collectorwander5};
+statetype s_collectorwander3 = {false,DOPE3,2,T_CollectorWander,0,&s_collectorwander4};
+statetype s_collectorwander2 = {false,DOPE2,2,T_CollectorWander,0,&s_collectorwander3};
+statetype s_collectorwander1 = {false,DOPE1,2,T_CollectorWander,0,&s_collectorwander2};
+#endif
+
+
+//MED
+#if (SHAREWARE == 1) || (DOPEFISH == 0)
+statetype s_collectorfdoor8 = {false,COLLECTOR15,0,T_CollectorFindDoor,0,&s_collectorfdoor1};
+statetype s_collectorfdoor7 = {false,COLLECTOR13,1,T_CollectorFindDoor,0,&s_collectorfdoor8};
+statetype s_collectorfdoor6 = {false,COLLECTOR11,0,T_CollectorFindDoor,0,&s_collectorfdoor7};
+statetype s_collectorfdoor5 = {false,COLLECTOR9,1,T_CollectorFindDoor,0,&s_collectorfdoor6};
+statetype s_collectorfdoor4 = {false,COLLECTOR7,0,T_CollectorFindDoor,0,&s_collectorfdoor5};
+statetype s_collectorfdoor3 = {false,COLLECTOR5,1,T_CollectorFindDoor,0,&s_collectorfdoor4};
+statetype s_collectorfdoor2 = {false,COLLECTOR3,0,T_CollectorFindDoor,0,&s_collectorfdoor3};
+statetype s_collectorfdoor1 = {false,COLLECTOR1,1,T_CollectorFindDoor,0,&s_collectorfdoor2};
+#else
+
+statetype s_collectorfdoor8 = {false,DOPE8,2,T_CollectorFindDoor,0,&s_collectorfdoor1};
+statetype s_collectorfdoor7 = {false,DOPE7,2,T_CollectorFindDoor,0,&s_collectorfdoor8};
+statetype s_collectorfdoor6 = {false,DOPE6,2,T_CollectorFindDoor,0,&s_collectorfdoor7};
+statetype s_collectorfdoor5 = {false,DOPE5,2,T_CollectorFindDoor,0,&s_collectorfdoor6};
+statetype s_collectorfdoor4 = {false,DOPE4,2,T_CollectorFindDoor,0,&s_collectorfdoor5};
+statetype s_collectorfdoor3 = {false,DOPE3,2,T_CollectorFindDoor,0,&s_collectorfdoor4};
+statetype s_collectorfdoor2 = {false,DOPE2,2,T_CollectorFindDoor,0,&s_collectorfdoor3};
+statetype s_collectorfdoor1 = {false,DOPE1,2,T_CollectorFindDoor,0,&s_collectorfdoor2};
+
+#endif
+
+statetype s_timekeeper = {false,NOTHING,140,T_End,0,NULL};
+
+statetype s_wind = {false,-1,10,T_Wind,0,&s_wind};
+
+
+statetype s_deadblood8 = {false,NOTHING,0,T_Blood,0,&s_deadblood8};
+statetype s_deadblood7 = {false,DEADBLOOD7,5,NULL,0,&s_deadblood8};
+statetype s_deadblood6 = {false,DEADBLOOD6,5,NULL,0,&s_deadblood7};
+statetype s_deadblood5 = {false,DEADBLOOD5,5,NULL,0,&s_deadblood6};
+statetype s_deadblood4 = {false,DEADBLOOD4,5,NULL,0,&s_deadblood5};
+statetype s_deadblood3 = {false,DEADBLOOD3,5,NULL,0,&s_deadblood4};
+statetype s_deadblood2 = {false,DEADBLOOD2,5,NULL,0,&s_deadblood3};
+statetype s_deadblood1 = {false,DEADBLOOD1,5,NULL,0,&s_deadblood2};
+
+/*
+statetype s_rain7 = {false,RAINDROP6,0,NULL,0,NULL};
+statetype s_rain6 = {false,RAINDROP5,3,NULL,0,&s_rain7};
+statetype s_rain5 = {false,RAINDROP4,0,NULL,0,&s_rain6};
+statetype s_rain4 = {false,RAINDROP3,3,NULL,0,&s_rain5};
+statetype s_rain3 = {false,RAINDROP2,0,NULL,0,&s_rain4};
+statetype s_rain2 = {false,RAINDROP1,0,T_RainFall,0,&s_rain2};
+statetype s_rain1 = {false,NOTHING,50,T_RainSpawn,0,&s_rain1};
+
+statetype s_rainmaster = {false,NOTHING,0,T_RainMaster,0,&s_rainmaster};
+*/
+
+statetype s_pathdisk = {false,PLATFORM1,0,T_Path,0,&s_pathdisk};
+statetype s_elevdisk = {false,PLATFORM1,0,T_ElevDisk,0,&s_elevdisk};
+
+statetype s_diskmaster = {false,NOTHING,0,T_ElevDisk,0,&s_diskmaster};
+
+
+
+statetype s_blooddrip4 = {false,WALLGIB4,3,T_BloodFall,0,&s_blooddrip1};
+statetype s_blooddrip3 = {false,WALLGIB3,3,T_BloodFall,0,&s_blooddrip4};
+statetype s_blooddrip2 = {false,WALLGIB2,3,T_BloodFall,0,&s_blooddrip3};
+statetype s_blooddrip1 = {false,WALLGIB1,3,T_BloodFall,0,&s_blooddrip2};
+
+
+
+//==================== Push column =====================================//
+
+
+statetype s_pushcolumn1 = {false,SPR_PUSHCOLUMN1,6,T_MoveColumn,0,&s_pushcolumn1};
+statetype s_pushcolumn2 = {false,SPR_PUSHCOLUMN1,6,T_MoveColumn,0,&s_pushcolumn2};
+statetype s_pushcolumn3 = {false,SPR_PUSHCOLUMN1,6,T_MoveColumn,0,&s_pushcolumn3};
+
+
+//=================== Wall Fire =======================================/
+
+statetype s_wallfireball = {false,NOTHING,50,A_Wallfire,0,&s_wallfireball};
+
+statetype s_crossfire2 = {true,SPR_CROSSFIRE31,6,T_Projectile,0,&s_crossfire1};
+statetype s_crossfire1 = {true,SPR_CROSSFIRE11,6,T_Projectile,0,&s_crossfire2};
+
+statetype s_crossdone5 = {false,SPR_CREXP5,6,NULL,0,NULL};
+statetype s_crossdone4 = {false,SPR_CREXP4,6,NULL,0,&s_crossdone5};
+statetype s_crossdone3 = {false,SPR_CREXP3,6,NULL,0,&s_crossdone4};
+statetype s_crossdone2 = {false,SPR_CREXP2,6,NULL,0,&s_crossdone3};
+statetype s_crossdone1 = {false,SPR_CREXP1,6,NULL,0,&s_crossdone2};
+
+
+
+//=============== gib/related states ===========================================//
+
+
+statetype s_bossdeath = {false,NOTHING,140,T_BossDied,0,NULL};
+
+statetype s_megaremove     = {false,NOTHING,0,NULL,0,NULL};
+statetype s_megaexplosions = {false,NOTHING,0,T_BossExplosions,0,&s_megaexplosions};
+statetype s_superparticles = {false,NOTHING,0,T_ParticleGenerate,0,&s_superparticles};
+
+
+statetype s_gibsdone8 = {false,PARTICLE12,2,NULL,0,NULL};
+statetype s_gibsdone7 = {false,PARTICLE11,2,NULL,0,&s_gibsdone8};
+//MED
+statetype s_gibsdone6 = {false,PARTICLE10,2,NULL,0,&s_gibsdone7};
+statetype s_gibsdone5 = {false,PARTICLE09,2,NULL,0,&s_gibsdone6};
+statetype s_gibsdone4 = {false,PARTICLE08,2,NULL,0,&s_gibsdone5};
+statetype s_gibsdone3 = {false,PARTICLE07,2,NULL,0,&s_gibsdone4};
+statetype s_gibsdone2 = {false,PARTICLE06,2,NULL,0,&s_gibsdone3};
+statetype s_gibsdone1 = {false,PARTICLE05,2,NULL,0,&s_gibsdone2};
+
+statetype s_gibs4 = {false,PARTICLE04,2,T_Particle,0,&s_gibs1};
+statetype s_gibs3 = {false,PARTICLE03,2,T_Particle,0,&s_gibs4};
+statetype s_gibs2 = {false,PARTICLE02,2,T_Particle,0,&s_gibs3};
+statetype s_gibs1 = {false,PARTICLE01,2,T_Particle,0,&s_gibs2};
+
+
+
+//statetype s_head = {false,DEADHEAD,4200,NULL,0,&s_gibsdone2};
+
+statetype s_eye3 = {false,NOTHING,7,T_SlideDownScreen,SF_EYE3,&s_eye1};
+statetype s_eye2 = {false,NOTHING,7,T_SlideDownScreen,SF_EYE2,&s_eye3};
+statetype s_eye1 = {false,NOTHING,7,T_SlideDownScreen,SF_EYE1,&s_eye2};
+
+statetype s_littlesoul = {false,LITTLESOUL,0,MissileMovement,0,&s_littlesoul};
+statetype s_bigsoul = {false,BIGSOUL,0,MissileMovement,0,&s_bigsoul};
+
+
+statetype s_vaporized8 = {false,VAPORIZED8,0,T_Convert,0,NULL};
+statetype s_vaporized7 = {false,VAPORIZED7,3,NULL,0,&s_vaporized8};
+statetype s_vaporized6 = {false,VAPORIZED6,3,NULL,0,&s_vaporized7};
+statetype s_vaporized5 = {false,VAPORIZED5,3,NULL,0,&s_vaporized6};
+statetype s_vaporized4 = {false,VAPORIZED4,3,NULL,0,&s_vaporized5};
+statetype s_vaporized3 = {false,VAPORIZED3,3,NULL,0,&s_vaporized4};
+statetype s_vaporized2 = {false,VAPORIZED2,3,NULL,0,&s_vaporized3};
+statetype s_vaporized1 = {false,VAPORIZED1,3,NULL,0,&s_vaporized2};
+
+statetype s_respawn8 = {false,VAPORIZED1,0,SetShapeoffset,0,&s_player};
+statetype s_respawn7 = {false,VAPORIZED2,3,NULL,0,&s_respawn8};
+statetype s_respawn6 = {false,VAPORIZED3,3,NULL,0,&s_respawn7};
+statetype s_respawn5 = {false,VAPORIZED4,3,NULL,0,&s_respawn6};
+statetype s_respawn4 = {false,VAPORIZED5,3,NULL,0,&s_respawn5};
+statetype s_respawn3 = {false,VAPORIZED6,3,NULL,0,&s_respawn4};
+statetype s_respawn2 = {false,VAPORIZED7,3,NULL,0,&s_respawn3};
+statetype s_respawn1 = {false,VAPORIZED8,3,NULL,0,&s_respawn2};
+
+
+
+#if (SHAREWARE == 0)
+
+
+//========================= NON-SHAREWARE STATES ============================
+
+
+statetype s_scottwander7 = {false,SCOTHEAD7,4,T_CollectorWander,0,&s_scottwander1};
+statetype s_scottwander6 = {false,SCOTHEAD6,4,T_CollectorWander,0,&s_scottwander7};
+statetype s_scottwander5 = {false,SCOTHEAD5,4,T_CollectorWander,0,&s_scottwander6};
+statetype s_scottwander4 = {false,SCOTHEAD4,4,T_CollectorWander,0,&s_scottwander5};
+statetype s_scottwander3 = {false,SCOTHEAD3,4,T_CollectorWander,0,&s_scottwander4};
+statetype s_scottwander2 = {false,SCOTHEAD2,4,T_CollectorWander,0,&s_scottwander3};
+statetype s_scottwander1 = {false,SCOTHEAD1,4,T_CollectorWander,0,&s_scottwander2};
+
+statetype s_scottwanderdoor7 = {false,SCOTHEAD7,4,T_CollectorWander,0,&s_scottwanderdoor1};
+statetype s_scottwanderdoor6 = {false,SCOTHEAD6,4,T_CollectorWander,0,&s_scottwanderdoor7};
+statetype s_scottwanderdoor5 = {false,SCOTHEAD5,4,T_CollectorWander,0,&s_scottwanderdoor6};
+statetype s_scottwanderdoor4 = {false,SCOTHEAD4,4,T_CollectorWander,0,&s_scottwanderdoor5};
+statetype s_scottwanderdoor3 = {false,SCOTHEAD3,4,T_CollectorWander,0,&s_scottwanderdoor4};
+statetype s_scottwanderdoor2 = {false,SCOTHEAD2,4,T_CollectorWander,0,&s_scottwanderdoor3};
+statetype s_scottwanderdoor1 = {false,SCOTHEAD1,4,T_CollectorWander,0,&s_scottwanderdoor2};
+
+
+
+/*
+===========================================================================
+
+							 OVERPATROLS (op)
+																			,
+===========================================================================
+*/
+
+statetype s_opstand	   = {true,SPR_OP_S1,0,T_Stand,0,&s_opstand};
+
+statetype s_oppath4 	   = {true,SPR_OP_W41,10,T_Path,0,&s_oppath1};
+statetype s_oppath3 	   = {true,SPR_OP_W31,10,T_Path,SF_CLOSE,&s_oppath4};
+statetype s_oppath2	   = {true,SPR_OP_W21,10,T_Path,0,&s_oppath3};
+statetype s_oppath1 	   = {true,SPR_OP_W11,10,T_Path,SF_CLOSE,&s_oppath2};
+
+
+statetype s_opcollide  = {false,SPR_OP_PAIN1,0,T_Collide,0,&s_opcollide};
+statetype s_opcollide2 = {false,SPR_OP_PAIN2,0,T_Collide,0,&s_opcollide2};
+
+
+//statetype s_opuse2 	   = {true,SPR_OP_USE21,10,T_Use,0,&s_oppath1};
+//statetype s_opuse1 	   = {true,SPR_OP_USE11,10,T_Use,0,&s_opuse2};
+
+
+statetype s_opshoot4 	= {false,SPR_OP_SHOOT4,10,ActorMovement,0,&s_opchase1};
+statetype s_opshoot3 	= {false,SPR_OP_SHOOT3,10,ActorMovement,0,&s_opshoot4};
+statetype s_opshoot2 	= {false,SPR_OP_SHOOT2,20,A_Shoot,0,&s_opshoot3};
+statetype s_opshoot1 	= {false,SPR_OP_SHOOT1,6,ActorMovement,0,&s_opshoot2};
+
+
+
+statetype s_opbolo5     = {false,SPR_OP_BOLOSHOOT5,6,ActorMovement,0,&s_opchase1};
+statetype s_opbolo4     = {false,SPR_OP_BOLOSHOOT4,6,ActorMovement,0,&s_opbolo5};
+statetype s_opbolo3     = {false,SPR_OP_BOLOSHOOT3,20,A_MissileWeapon,0,&s_opbolo4};
+statetype s_opbolo2     = {false,SPR_OP_BOLOSHOOT2,6,ActorMovement,0,&s_opbolo3};
+statetype s_opbolo1     = {false,SPR_OP_BOLOSHOOT1,6,ActorMovement,0,&s_opbolo2};
+
+
+statetype s_bolocast4   = {false,SPR_BOLO4,6,T_Projectile,0,&s_bolocast4};
+statetype s_bolocast3   = {false,SPR_BOLO3,6,T_Projectile,0,&s_bolocast4};
+statetype s_bolocast2   = {false,SPR_BOLO2,6,T_Projectile,0,&s_bolocast3};
+statetype s_bolocast1   = {false,SPR_BOLO1,6,T_Projectile,0,&s_bolocast2};
+
+
+statetype s_opchase4	   = {true,SPR_OP_W41,6,T_Chase,0,&s_opchase1};
+statetype s_opchase3	   = {true,SPR_OP_W31,6,T_Chase,SF_CLOSE,&s_opchase4};
+statetype s_opchase2	   = {true,SPR_OP_W21,6,T_Chase,0,&s_opchase3};
+statetype s_opchase1	   = {true,SPR_OP_W11,6,T_Chase,SF_CLOSE,&s_opchase2};
+
+
+statetype s_opdead		= {false,SPR_OP_ALTDEAD,0,T_Collide,0,&s_opdead};
+statetype s_opdie5		= {false,SPR_OP_ALTDIE5,5,T_Collide,0,&s_opdead};
+statetype s_opdie4		= {false,SPR_OP_ALTDIE4,5,T_Collide,0,&s_opdie5};
+statetype s_opdie3		= {false,SPR_OP_ALTDIE3,5,T_Collide,0,&s_opdie4};
+statetype s_opdie2		= {false,SPR_OP_ALTDIE2,5,T_Collide,0,&s_opdie3};
+statetype s_opdie1		= {false,SPR_OP_ALTDIE1,5,T_Collide,0,&s_opdie2};
+
+
+statetype s_opcrushed2		= {false,SPR_OP_DIE3,2,NULL,0,&s_opdead};
+statetype s_opcrushed1		= {false,SPR_OP_DIE1,2,NULL,0,&s_opcrushed2};
+
+
+
+/*
+============================================================================
+
+								DEATH MONKS
+
+============================================================================
+*/
+
+
+statetype s_dmonkstand	= {true,SPR_MONK_S1,0,T_Stand,0,&s_dmonkstand};
+
+statetype s_dmonkpath4	= {true,SPR_MONK_W41,10,T_Path,0,&s_dmonkpath1};
+statetype s_dmonkpath3  = {true,SPR_MONK_W31,10,T_Path,SF_CLOSE,&s_dmonkpath4};
+statetype s_dmonkpath2	= {true,SPR_MONK_W21,10,T_Path,0,&s_dmonkpath3};
+statetype s_dmonkpath1  = {true,SPR_MONK_W11,10,T_Path,SF_CLOSE,&s_dmonkpath2};
+
+
+statetype s_dmonkcollide  = {false,SPR_MONK_PAIN1,0,T_Collide,0,&s_dmonkcollide};
+statetype s_dmonkcollide2 = {false,SPR_MONK_PAIN2,0,T_Collide,0,&s_dmonkcollide2};
+
+
+statetype s_dmonkshoot6 = {false,SPR_MONK_DRAIN6,20,ActorMovement,0,&s_dmonkchase1};
+statetype s_dmonkshoot5 = {false,SPR_MONK_DRAIN5,20,ActorMovement,0,&s_dmonkshoot6};
+statetype s_dmonkshoot4 = {false,SPR_MONK_DRAIN4,20,ActorMovement,0,&s_dmonkshoot3};
+statetype s_dmonkshoot3 = {false,SPR_MONK_DRAIN3,20,A_Drain,0,&s_dmonkshoot4};
+statetype s_dmonkshoot2 = {false,SPR_MONK_DRAIN2,20,ActorMovement,0,&s_dmonkshoot3};
+statetype s_dmonkshoot1 = {false,SPR_MONK_DRAIN1,20,A_Drain,0,&s_dmonkshoot2};
+
+statetype s_dmonkchase4	   = {true,SPR_MONK_W41,6,T_Chase,0,&s_dmonkchase1};
+statetype s_dmonkchase3 	= {true,SPR_MONK_W31,6,T_Chase,SF_CLOSE,&s_dmonkchase4};
+statetype s_dmonkchase2	   = {true,SPR_MONK_W21,6,T_Chase,0,&s_dmonkchase3};
+statetype s_dmonkchase1 	= {true,SPR_MONK_W11,6,T_Chase,SF_CLOSE,&s_dmonkchase2};
+
+statetype s_dmonkdead		= {false,SPR_MONK_DEAD,0,T_Collide,0,&s_dmonkdead};
+statetype s_dmonkdie4		= {false,SPR_MONK_DIE4,5,T_Collide,0,&s_dmonkdead};
+statetype s_dmonkdie3		= {false,SPR_MONK_DIE3,5,T_Collide,0,&s_dmonkdie4};
+statetype s_dmonkdie2		= {false,SPR_MONK_DIE2,5,T_Collide,0,&s_dmonkdie3};
+statetype s_dmonkdie1		= {false,SPR_MONK_DIE1,5,T_Collide,0,&s_dmonkdie2};
+
+
+statetype s_dmonkcrushed2		= {false,SPR_MONK_DIE3,2,NULL,0,&s_dmonkdead};
+statetype s_dmonkcrushed1		= {false,SPR_MONK_DIE1,2,NULL,0,&s_dmonkcrushed2};
+
+/*
+============================================================================
+
+								DEATH FIRE MONKS
+
+============================================================================
+*/
+
+statetype s_firemonkstand	= {true,SPR_FIREMONK_S1,0,T_Stand,0,&s_firemonkstand};
+
+statetype s_firemonkpath4	= {true,SPR_FIREMONK_W41,10,T_Path,0,&s_firemonkpath1};
+statetype s_firemonkpath3  = {true,SPR_FIREMONK_W31,10,T_Path,SF_CLOSE,&s_firemonkpath4};
+statetype s_firemonkpath2	= {true,SPR_FIREMONK_W21,10,T_Path,0,&s_firemonkpath3};
+statetype s_firemonkpath1  = {true,SPR_FIREMONK_W11,10,T_Path,SF_CLOSE,&s_firemonkpath2};
+
+
+statetype s_firemonkcollide  = {false,SPR_FIREMONK_PAIN1,0,T_Collide,0,&s_firemonkcollide};
+statetype s_firemonkcollide2 = {false,SPR_FIREMONK_PAIN2,0,T_Collide,0,&s_firemonkcollide2};
+
+statetype s_firemonkcast7 = {false,SPR_FIREMONK_CAST7,6,ActorMovement,0,&s_firemonkchase1};
+statetype s_firemonkcast6 = {false,SPR_FIREMONK_CAST6,40,A_MissileWeapon,0,&s_firemonkcast7};
+statetype s_firemonkcast5 = {false,SPR_FIREMONK_CAST5,6,ActorMovement,0,&s_firemonkcast6};
+statetype s_firemonkcast4 = {false,SPR_FIREMONK_CAST4,6,ActorMovement,0,&s_firemonkcast5};
+statetype s_firemonkcast3 = {false,SPR_FIREMONK_CAST3,6,ActorMovement,0,&s_firemonkcast4};
+statetype s_firemonkcast2 = {false,SPR_FIREMONK_CAST2,6,ActorMovement,0,&s_firemonkcast3};
+statetype s_firemonkcast1 = {false,SPR_FIREMONK_CAST1,6,ActorMovement,0,&s_firemonkcast2};
+
+statetype s_monkfire4 = {false,MONKFIRE4,3,T_Projectile,0,&s_monkfire1};
+statetype s_monkfire3 = {false,MONKFIRE3,3,T_Projectile,0,&s_monkfire4};
+statetype s_monkfire2 = {false,MONKFIRE2,3,T_Projectile,0,&s_monkfire3};
+statetype s_monkfire1 = {false,MONKFIRE1,3,T_Projectile,0,&s_monkfire2};
+
+
+statetype s_fireballhit3 = {false,SPR_FIREBALL_HIT3,5,NULL,0,NULL};
+statetype s_fireballhit2 = {false,SPR_FIREBALL_HIT2,5,NULL,0,&s_fireballhit3};
+statetype s_fireballhit1 = {false,SPR_FIREBALL_HIT1,5,NULL,0,&s_fireballhit2};
+
+statetype s_firemonkchase4 	= {true,SPR_FIREMONK_W41,6,T_Chase,0,&s_firemonkchase1};
+statetype s_firemonkchase3 	= {true,SPR_FIREMONK_W31,6,T_Chase,SF_CLOSE,&s_firemonkchase4};
+statetype s_firemonkchase2	   = {true,SPR_FIREMONK_W21,6,T_Chase,0,&s_firemonkchase3};
+statetype s_firemonkchase1 	= {true,SPR_FIREMONK_W11,6,T_Chase,SF_CLOSE,&s_firemonkchase2};
+
+
+statetype s_firemonkdead7		= {false,SPR_FIREMONK_DEAD7,0,T_Collide,0,&s_firemonkdead7};
+statetype s_firemonkdead6	   = {false,SPR_FIREMONK_DEAD6,5,T_Collide,0,&s_firemonkdead7};
+statetype s_firemonkdead5	   = {false,SPR_FIREMONK_DEAD5,5,T_Collide,0,&s_firemonkdead6};
+statetype s_firemonkdead4	   = {false,SPR_FIREMONK_DEAD4,5,T_Collide,0,&s_firemonkdead5};
+statetype s_firemonkdead3	   = {false,SPR_FIREMONK_DEAD3,5,T_Collide,0,&s_firemonkdead4};
+statetype s_firemonkdead2	   = {false,SPR_FIREMONK_DEAD2,5,T_Collide,0,&s_firemonkdead3};
+statetype s_firemonkdead		= {false,SPR_FIREMONK_DEAD1,5,T_Collide,0,&s_firemonkdead2};
+statetype s_firemonkdie4		= {false,SPR_FIREMONK_DIE3,5,T_Collide,0,&s_firemonkdead};
+statetype s_firemonkdie3		= {false,SPR_FIREMONK_DIE3,5,T_Collide,0,&s_firemonkdie4};
+statetype s_firemonkdie2		= {false,SPR_FIREMONK_DIE2,5,T_Collide,0,&s_firemonkdie3};
+statetype s_firemonkdie1		= {false,SPR_FIREMONK_DIE1,5,T_Collide,0,&s_firemonkdie2};
+
+
+statetype s_firemonkcrushed2		= {false,SPR_FIREMONK_DIE3,2,NULL,0,&s_firemonkdead};
+statetype s_firemonkcrushed1		= {false,SPR_FIREMONK_DIE1,2,NULL,0,&s_firemonkcrushed2};
+
+/*===========================================================================
+
+								  INSANE WALL DUDE
+
+============================================================================*/
+
+
+statetype s_wallstand = {16,BCRAFT01,0,T_Stand,0,&s_wallstand};
+
+statetype s_wallpath = {16,BCRAFT01,20,T_AutoPath,0,&s_wallpath};
+
+statetype s_wallshoot = {16,BCRAFT01,15,A_MissileWeapon,0,&s_wallshoot};
+
+statetype s_wallalign = {16,BCRAFT01,0,T_AutoShootAlign,0,&s_wallalign};
+statetype s_wallwait = {16,BCRAFT01,0,NULL,0,&s_wallwait};
+statetype s_wallrestore = {16,BCRAFT01,0,T_AutoRealign,0,&s_wallrestore};
+
+
+
+statetype s_wallcollide  = {16,BCRAFT01,0,T_Collide,0,&s_wallcollide};
+
+
+/*
+===========================================================================
+
+									  ESAU GUDERIAN
+
+===========================================================================
+*/
+
+
+
+
+statetype s_darianstand = {true,SPR_DARIAN_S1,0,T_Stand,0,&s_darianstand};
+
+statetype s_darianchase4	= {true,SPR_DARIAN_W41,8,T_EsauChase,0,&s_darianchase1};
+statetype s_darianchase3	= {true,SPR_DARIAN_W31,8,T_EsauChase,SF_CLOSE,&s_darianchase4};
+statetype s_darianchase2	= {true,SPR_DARIAN_W21,8,T_EsauChase,0,&s_darianchase3};
+statetype s_darianchase1	= {true,SPR_DARIAN_W11,8,T_EsauChase,SF_CLOSE,&s_darianchase2};
+
+
+statetype s_darianrise8 = {false,SPR_DARIAN_SINK1,3,NULL,0,&s_darianwait};
+statetype s_darianrise7 = {false,SPR_DARIAN_SINK2,3,NULL,0,&s_darianrise8};
+statetype s_darianrise6 = {false,SPR_DARIAN_SINK3,3,NULL,0,&s_darianrise7};
+statetype s_darianrise5 = {false,SPR_DARIAN_SINK4,3,NULL,0,&s_darianrise6};
+statetype s_darianrise4 = {false,SPR_DARIAN_SINK5,3,NULL,0,&s_darianrise5};
+statetype s_darianrise3 = {false,SPR_DARIAN_SINK6,3,NULL,0,&s_darianrise4};
+statetype s_darianrise2 = {false,SPR_DARIAN_SINK7,3,NULL,0,&s_darianrise3};
+statetype s_darianrise1 = {false,SPR_DARIAN_SINK8,3,NULL,0,&s_darianrise2};
+
+
+statetype s_dariansink9 = {false,NOTHING,110,T_EsauRise,0,&s_darianrise1};
+statetype s_dariansink8 = {false,SPR_DARIAN_SINK8,3,NULL,0,&s_dariansink9};
+statetype s_dariansink7 = {false,SPR_DARIAN_SINK7,3,NULL,0,&s_dariansink8};
+statetype s_dariansink6 = {false,SPR_DARIAN_SINK6,3,NULL,0,&s_dariansink7};
+statetype s_dariansink5 = {false,SPR_DARIAN_SINK5,3,NULL,0,&s_dariansink6};
+statetype s_dariansink4 = {false,SPR_DARIAN_SINK4,3,NULL,0,&s_dariansink5};
+statetype s_dariansink3 = {false,SPR_DARIAN_SINK3,3,NULL,0,&s_dariansink4};
+statetype s_dariansink2 = {false,SPR_DARIAN_SINK2,3,NULL,0,&s_dariansink3};
+statetype s_dariansink1 = {false,SPR_DARIAN_SINK1,3,NULL,0,&s_dariansink2};
+
+
+statetype s_dariancollide  = {false,SPR_DARIAN_PAIN1,0,T_Collide,0,&s_dariancollide};
+statetype s_dariancollide2 = {false,SPR_DARIAN_PAIN2,0,T_Collide,0,&s_dariancollide2};
+
+
+statetype s_darianshoot4  = {false,SPR_DARIAN_SHOOT4,10,NULL,0,&s_darianchase1};
+statetype s_darianshoot3  = {false,SPR_DARIAN_SHOOT3,10,NULL,0,&s_darianshoot4};
+statetype s_darianshoot2  = {false,SPR_DARIAN_SHOOT2,20,A_MissileWeapon,0,&s_darianshoot3};
+statetype s_darianshoot1  = {false,SPR_DARIAN_SHOOT1,10,NULL,0,&s_darianshoot2};
+
+statetype s_dariandefend3  = {false,SPR_DARIAN_SHOOT3,10,NULL,0,&s_darianwait};
+statetype s_dariandefend2  = {false,SPR_DARIAN_SHOOT2,20,A_MissileWeapon,0,&s_dariandefend3};
+statetype s_dariandefend1  = {false,SPR_DARIAN_SHOOT1,10,NULL,0,&s_dariandefend2};
+
+
+statetype s_darianuse4  = {true,SPR_DARIAN_USE11,10,NULL,0,&s_darianspears};
+statetype s_darianuse3  = {true,SPR_DARIAN_USE21,10,T_Use,0,&s_darianuse4};
+statetype s_darianuse2  = {true,SPR_DARIAN_USE11,30,NULL,0,&s_darianuse3};
+statetype s_darianuse1  = {true,SPR_DARIAN_S1,40,NULL,0,&s_darianuse2};
+
+statetype s_darianwait = {false,SPR_DARIAN_SHOOT1,0,T_EsauWait,0,&s_darianwait};
+
+statetype s_darianspears  = {true,SPR_DARIAN_S1,280,NULL,0,&s_darianchase1};
+
+
+statetype s_dspear16 = {false,SPEARDOWN7,2,T_Spears,SF_DOWN,NULL};
+statetype s_dspear15 = {false,SPEARDOWN6,2,T_Spears,SF_CRUSH,&s_dspear16};
+statetype s_dspear14 = {false,SPEARDOWN5,2,T_Spears,SF_CRUSH,&s_dspear15};
+statetype s_dspear13 = {false,SPEARDOWN4,2,T_Spears,SF_CRUSH,&s_dspear14};
+statetype s_dspear12 = {false,SPEARDOWN3,2,T_Spears,SF_CRUSH,&s_dspear13};
+statetype s_dspear11 = {false,SPEARDOWN2,2,T_Spears,SF_CRUSH,&s_dspear12};
+statetype s_dspear10 = {false,SPEARDOWN1,2,T_Spears,SF_CRUSH,&s_dspear11};
+statetype s_dspear9 = {false,SPEARDOWN16,2,T_Spears,SF_CRUSH,&s_dspear10};
+statetype s_dspear8 = {false,SPEARDOWN15,2,T_Spears,SF_CRUSH,&s_dspear9};
+statetype s_dspear7 = {false,SPEARDOWN14,2,T_Spears,SF_CRUSH,&s_dspear8};
+statetype s_dspear6 = {false,SPEARDOWN13,2,T_Spears,SF_CRUSH,&s_dspear7};
+statetype s_dspear5 = {false,SPEARDOWN12,2,T_Spears,SF_CRUSH,&s_dspear6};
+statetype s_dspear4 = {false,SPEARDOWN11,2,T_Spears,SF_CRUSH,&s_dspear5};
+statetype s_dspear3 = {false,SPEARDOWN10,2,T_Spears,SF_CRUSH,&s_dspear4};
+statetype s_dspear2 = {false,SPEARDOWN9,2,T_Spears,SF_DOWN,&s_dspear3};
+statetype s_dspear1 = {false,SPEARDOWN8,2,T_Spears,SF_DOWN,&s_dspear2};
+
+
+statetype s_dariandead2 	= {false,SPR_DARIAN_DEAD,0,T_BossDied,0,&s_dariandead2};
+statetype s_dariandead1 	= {false,SPR_DARIAN_DEAD,140,NULL,0,&s_dariandead2};
+statetype s_dariandead 	= {false,SPR_DARIAN_DEAD,0,NULL,0,&s_dariandead1};
+
+statetype s_dariandie10 = {false,SPR_DARIAN_DIE10,5,NULL,0,&s_dariandead};
+statetype s_dariandie9 	= {false,SPR_DARIAN_DIE9,5,NULL,0,&s_dariandie10};
+statetype s_dariandie8 	= {false,SPR_DARIAN_DIE8,5,NULL,0,&s_dariandie9};
+statetype s_dariandie7 	= {false,SPR_DARIAN_DIE7,5,NULL,0,&s_dariandie8};
+statetype s_dariandie6 	= {false,SPR_DARIAN_DIE6,5,T_Guts,0,&s_dariandie7};
+statetype s_dariandie5 	= {false,SPR_DARIAN_DIE5,5,NULL,0,&s_dariandie6};
+statetype s_dariandie4 	= {false,SPR_DARIAN_DIE4,5,NULL,0,&s_dariandie5};
+statetype s_dariandie3 	= {false,SPR_DARIAN_DIE3,5,NULL,0,&s_dariandie4};
+statetype s_dariandie2 	= {false,SPR_DARIAN_DIE2,5,NULL,0,&s_dariandie3};
+statetype s_dariandie1 	= {false,SPR_DARIAN_DIE1,70,T_Collide,0,&s_dariandie2};
+
+
+
+/*
+===========================================================================
+
+									HEINRICH KRIST
+
+===========================================================================
+*/
+
+
+statetype s_heinrichstand	= {true,SPR_KRIST_S1,0,T_Stand,0,&s_heinrichstand};
+
+statetype s_heinrichchase 	= {true,SPR_KRIST_FOR1,10,T_HeinrichChase,0,&s_heinrichchase};
+
+
+statetype s_kristleft = {true,SPR_KRIST_LEFT1,10,T_KristLeft,0,&s_kristleft};
+
+statetype s_kristright = {true,SPR_KRIST_RIGHT1,10,T_KristRight,0,&s_kristright};
+
+statetype s_heinrichshoot11  = {false,SPR_KRIST_SHOOT11,8,NULL,0,&s_heinrichchase};
+statetype s_heinrichshoot10  = {false,SPR_KRIST_SHOOT10,8,NULL,0,&s_heinrichshoot11};
+statetype s_heinrichshoot9  = {false,SPR_KRIST_SHOOT9,8,A_HeinrichShoot,0,&s_heinrichshoot10};
+statetype s_heinrichshoot8  = {false,SPR_KRIST_SHOOT8,8,NULL,0,&s_heinrichshoot9};
+statetype s_heinrichshoot7  = {false,SPR_KRIST_SHOOT7,8,T_KristCheckFire,0,&s_heinrichshoot8};
+statetype s_heinrichshoot6  = {false,SPR_KRIST_SHOOT6,8,NULL,0,&s_heinrichshoot7};
+statetype s_heinrichshoot5  = {false,SPR_KRIST_SHOOT5,8,NULL,0,&s_heinrichshoot6};
+statetype s_heinrichshoot4  = {false,SPR_KRIST_SHOOT4,8,A_HeinrichShoot,0,&s_heinrichshoot5};
+statetype s_heinrichshoot3  = {false,SPR_KRIST_SHOOT3,8,NULL,0,&s_heinrichshoot4};
+statetype s_heinrichshoot2  = {false,SPR_KRIST_SHOOT2,8,NULL,0,&s_heinrichshoot3};
+statetype s_heinrichshoot1  = {false,SPR_KRIST_SHOOT1,8,T_KristCheckFire,0,&s_heinrichshoot2};
+
+statetype s_missile1       = {16,SPR_BJMISS11,6,T_Projectile,0,&s_missile1};
+
+
+statetype s_missilehit3    = {false,SPR_MISSILEHIT3,6,NULL,0,NULL};
+statetype s_missilehit2    = {false,SPR_MISSILEHIT2,6,NULL,0,&s_missilehit3};
+statetype s_missilehit1    = {false,SPR_MISSILEHIT1,6,NULL,0,&s_missilehit2};
+
+statetype s_mine4          = {false,SPR_MINE4,3,T_Projectile,0,&s_mine1};
+statetype s_mine3          = {false,SPR_MINE3,3,T_Projectile,0,&s_mine4};
+statetype s_mine2          = {false,SPR_MINE2,3,T_Projectile,0,&s_mine3};
+statetype s_mine1          = {false,SPR_MINE1,3,T_Projectile,0,&s_mine2};
+
+statetype s_heinrichdefend = {true,SPR_KRIST_MINERIGHT1,35,T_Heinrich_Defend,0,&s_heinrichdefend};
+
+
+statetype s_heinrichooc    = {true,SPR_KRIST_DEAD1,0,T_Heinrich_Out_of_Control,0,&s_heinrichooc};
+
+statetype s_heinrichdead 	= {false,SPR_KRIST_DEAD1,35,T_Collide,0,&s_heinrichooc};
+
+statetype s_heinrichdie2 	= {false,SPR_KRIST_DIE2,35,T_Collide,0,&s_heinrichdead};
+statetype s_heinrichdie1 	= {false,SPR_KRIST_DIE1,35,T_Collide,0,&s_heinrichdie2};
+
+statetype s_heindead2 = {false,-1,0,T_BossDied,0,NULL};
+statetype s_heindead1 = {false, -1, 140,NULL,0,&s_heindead2};
+statetype s_heinexp13 = {false,SPR_EXPLOSION13,2,NULL,0,&s_heindead1};
+statetype s_heinexp12 = {false,SPR_EXPLOSION12,2,NULL,0,&s_heinexp13};
+statetype s_heinexp11 = {false,SPR_EXPLOSION11,2,NULL,0,&s_heinexp12};
+statetype s_heinexp10 = {false,SPR_EXPLOSION10,2,NULL,0,&s_heinexp11};
+statetype s_heinexp9 = {false,SPR_EXPLOSION9,2,NULL,0,&s_heinexp10};
+statetype s_heinexp8 = {false,SPR_EXPLOSION8,2,NULL,0,&s_heinexp9};
+statetype s_heinexp7 = {false,SPR_EXPLOSION7,2,NULL,0,&s_heinexp8};
+statetype s_heinexp6 = {false,SPR_EXPLOSION6,2,NULL,0,&s_heinexp7};
+statetype s_heinexp5 = {false,SPR_EXPLOSION5,2,NULL,0,&s_heinexp6};
+statetype s_heinexp4 = {false,SPR_EXPLOSION4,2,NULL,0,&s_heinexp5};
+statetype s_heinexp3 = {false,SPR_EXPLOSION3,2,T_Explosion,0,&s_heinexp4};
+statetype s_heinexp2 = {false,SPR_EXPLOSION2,2,NULL,0,&s_heinexp3};
+statetype s_heinexp1 = {false,SPR_EXPLOSION1,0,NULL,0,&s_heinexp2};
+
+
+/*
+===========================================================================
+
+								  DARK MONK (TOM)
+
+===========================================================================
+*/
+
+
+statetype s_darkmonkstand	= {true,TOMS1,0,T_Stand,0,&s_darkmonkstand};
+
+statetype s_darkmonkland	= {true,TOMFLY11,6,NULL,0,&s_darkmonkstand};
+
+
+statetype s_darkmonkchase2	= {true,TOMFLY21,10,T_DarkmonkChase,0,&s_darkmonkchase2};
+statetype s_darkmonkchase1	= {true,TOMFLY11,3,T_DarkmonkChase,0,&s_darkmonkchase2};
+
+statetype s_dmlandandfire = {true,TOMFLY11,0,T_DarkmonkLandAndFire,0,&s_dmlandandfire};
+
+statetype s_darkmonkcover3	= {false,TAWAKEN1,1,NULL,0,&s_darkmonkawaken1};
+statetype s_darkmonkcover2	= {false,TAWAKEN2,1,NULL,0,&s_darkmonkcover3};
+statetype s_darkmonkcover1	= {false,TAWAKEN3,1,NULL,0,&s_darkmonkcover2};
+
+
+statetype s_darkmonkawaken5	= {false,TAWAKEN5,3,NULL,0,&s_darkmonkchase1};
+statetype s_darkmonkawaken4	= {false,TAWAKEN4,3,NULL,0,&s_darkmonkawaken5};
+statetype s_darkmonkawaken3	= {false,TAWAKEN3,3,NULL,0,&s_darkmonkawaken4};
+statetype s_darkmonkawaken2	= {false,TAWAKEN2,3,NULL,0,&s_darkmonkawaken3};
+statetype s_darkmonkawaken1 	= {false,TAWAKEN1,3,NULL,0,&s_darkmonkawaken2};
+
+
+statetype s_darkmonklightning11	= {false,TOMLG11,3,NULL,0,&s_darkmonkchase1};
+statetype s_darkmonklightning10	= {false,TOMLG10,3,NULL,0,&s_darkmonklightning11};
+statetype s_darkmonklightning9	= {false,TOMLG9,70,A_DmonkAttack,0,&s_darkmonklightning10};
+statetype s_darkmonklightning8	= {false,TOMLG8,3,NULL,0,&s_darkmonklightning9};
+statetype s_darkmonklightning7 	= {false,TOMLG7,3,NULL,0,&s_darkmonklightning8};
+statetype s_darkmonklightning6	= {false,TOMLG6,3,NULL,0,&s_darkmonklightning7};
+statetype s_darkmonklightning5	= {false,TOMLG5,3,NULL,0,&s_darkmonklightning6};
+statetype s_darkmonklightning4	= {false,TOMLG4,3,NULL,0,&s_darkmonklightning5};
+statetype s_darkmonklightning3	= {false,TOMLG3,3,NULL,0,&s_darkmonklightning4};
+statetype s_darkmonklightning2 	= {false,TOMLG2,3,NULL,0,&s_darkmonklightning3};
+statetype s_darkmonklightning1 	= {false,TOMLG1,3,NULL,0,&s_darkmonklightning2};
+
+statetype s_darkmonkfspark6	= {false,TOMFS6,3,NULL,0,&s_darkmonkchase1};
+statetype s_darkmonkfspark5	= {false,TOMFS5,70,A_DmonkAttack,0,&s_darkmonkfspark6};
+statetype s_darkmonkfspark4	= {false,TOMFS4,3,NULL,0,&s_darkmonkfspark5};
+statetype s_darkmonkfspark3	= {false,TOMFS3,3,NULL,0,&s_darkmonkfspark4};
+statetype s_darkmonkfspark2 	= {false,TOMFS2,3,NULL,0,&s_darkmonkfspark3};
+statetype s_darkmonkfspark1 	= {false,TOMFS1,3,NULL,0,&s_darkmonkfspark2};
+
+
+statetype s_darkmonkbreathe8	= {false,TOMBR8,3,NULL,0,&s_darkmonkchase1};
+statetype s_darkmonkbreathe7 	= {false,TOMBR7,3,NULL,0,&s_darkmonkbreathe8};
+statetype s_darkmonkbreathe6	= {false,TOMBR6,70,A_DmonkAttack,0,&s_darkmonkbreathe7};
+statetype s_darkmonkbreathe5	= {false,TOMBR5,3,NULL,0,&s_darkmonkbreathe6};
+statetype s_darkmonkbreathe4	= {false,TOMBR4,3,NULL,0,&s_darkmonkbreathe5};
+statetype s_darkmonkbreathe3	= {false,TOMBR3,3,NULL,0,&s_darkmonkbreathe4};
+statetype s_darkmonkbreathe2 	= {false,TOMBR2,3,NULL,0,&s_darkmonkbreathe3};
+statetype s_darkmonkbreathe1 	= {false,TOMBR1,70,NULL,0,&s_darkmonkbreathe2};
+
+statetype s_darkmonksummon3	= {false,TOMBR1,3,NULL,0,&s_darkmonkchase1};
+statetype s_darkmonksummon2 	= {false,TOMBR3,3,NULL,0,&s_darkmonksummon3};
+statetype s_darkmonksummon1 	= {false,TOMBR2,3,NULL,0,&s_darkmonksummon2};
+
+statetype s_snakepath = {true,TOMHEAD1,0,T_SnakePath,0,&s_snakepath};
+statetype s_snakefindpath = {true,TOMHEAD1,0,T_SnakeFindPath,0,&s_snakefindpath};
+
+statetype s_darkmonkhead	= {true,TOMHEAD1,0,T_DarkSnakeChase,0,&s_darkmonkhead};
+statetype s_darkmonksnakelink	= {true,TOMHEAD1,0,T_GenericMove,0,&s_darkmonksnakelink};
+
+
+statetype s_darkmonkhspawn = {false,NOTHING,78,T_DarkSnakeSpawn,0,NULL};
+statetype s_darkmonkfastspawn = {false,NOTHING,35,T_DarkSnakeSpawn,0,NULL};
+
+statetype s_darkmonkheaddead	= {false,THDIE2,0,NULL,0,&s_darkmonkheaddead};
+statetype s_darkmonkheaddie1	= {false,THDIE1,1400,T_SnakeFinale,0,&s_snakefireworks1};
+
+statetype s_snakefireworks2 = {false,THDIE2,10,T_SnakeFinale,0,&s_snakefireworks1};
+statetype s_snakefireworks1 = {false,THDIE1,10,T_SnakeFinale,0,&s_snakefireworks2};
+
+statetype s_darkmonkhball9	= {false,THBALL9,5,NULL,0,&s_darkmonkchase1};
+statetype s_darkmonkhball8	= {false,THBALL8,5,NULL,0,&s_darkmonkhball9};
+statetype s_darkmonkhball7 = {false,THBALL7,5,A_DmonkAttack,0,&s_darkmonkhball8};
+statetype s_darkmonkhball6	= {false,THBALL6,5,NULL,0,&s_darkmonkhball7};
+statetype s_darkmonkhball5	= {false,THBALL5,5,NULL,0,&s_darkmonkhball6};
+statetype s_darkmonkhball4	= {false,THBALL4,5,NULL,0,&s_darkmonkhball5};
+statetype s_darkmonkhball3	= {false,THBALL3,5,NULL,0,&s_darkmonkhball4};
+statetype s_darkmonkhball2 = {false,THBALL2,5,NULL,0,&s_darkmonkhball3};
+statetype s_darkmonkhball1 = {false,THBALL1,70,NULL,0,&s_darkmonkhball2};
+
+statetype s_darkmonkabsorb9	= {false,THBALL9,3,NULL,0,&s_darkmonksphere1};
+statetype s_darkmonkabsorb8	= {false,THBALL8,3,NULL,0,&s_darkmonkabsorb9};
+statetype s_darkmonkabsorb7 = {false,THBALL7,3,NULL,0,&s_darkmonkabsorb8};
+statetype s_darkmonkabsorb6	= {false,THBALL6,3,NULL,0,&s_darkmonkabsorb7};
+statetype s_darkmonkabsorb5	= {false,THBALL5,3,NULL,0,&s_darkmonkabsorb6};
+statetype s_darkmonkabsorb4	= {false,THBALL4,3,NULL,0,&s_darkmonkabsorb5};
+statetype s_darkmonkabsorb3	= {false,THBALL3,3,NULL,0,&s_darkmonkabsorb4};
+statetype s_darkmonkabsorb2 = {false,THBALL2,3,NULL,0,&s_darkmonkabsorb3};
+statetype s_darkmonkabsorb1 = {false,THBALL1,3,NULL,0,&s_darkmonkabsorb2};
+
+
+statetype s_darkmonksphere10 = {false,TSPHERE10,4,NULL,0,&s_darkmonkchase1};
+statetype s_darkmonksphere9 = {false,TSPHERE9,4,NULL,0,&s_darkmonksphere10};
+statetype s_darkmonksphere8 = {false,TSPHERE8,4,A_DmonkAttack,0,&s_darkmonksphere9};
+statetype s_darkmonksphere7 = {false,TSPHERE7,4,NULL,0,&s_darkmonksphere8};
+statetype s_darkmonksphere6 = {false,TSPHERE6,4,NULL,0,&s_darkmonksphere7};
+statetype s_darkmonksphere5 = {false,TSPHERE5,4,NULL,0,&s_darkmonksphere6};
+statetype s_darkmonksphere4 = {false,TSPHERE4,4,NULL,0,&s_darkmonksphere5};
+statetype s_darkmonksphere3 = {false,TSPHERE3,4,NULL,0,&s_darkmonksphere4};
+statetype s_darkmonksphere2 = {false,TSPHERE2,4,NULL,0,&s_darkmonksphere3};
+statetype s_darkmonksphere1 = {false,TSPHERE1,4,NULL,0,&s_darkmonksphere2};
+
+statetype s_dmgreenthing10 = {false,TSPHERE10,4,NULL,0,&s_darkmonkchase1};
+statetype s_dmgreenthing9 = {false,TSPHERE9,4,NULL,0,&s_dmgreenthing10};
+statetype s_dmgreenthing8 = {false,TSPHERE8,4,A_DmonkAttack,0,&s_dmgreenthing9};
+statetype s_dmgreenthing7 = {false,TSPHERE7,4,NULL,0,&s_dmgreenthing8};
+statetype s_dmgreenthing6 = {false,TSPHERE6,4,NULL,0,&s_dmgreenthing7};
+statetype s_dmgreenthing5 = {false,TSPHERE5,4,NULL,0,&s_dmgreenthing6};
+statetype s_dmgreenthing4 = {false,TSPHERE4,4,NULL,0,&s_dmgreenthing5};
+statetype s_dmgreenthing3 = {false,TSPHERE3,4,NULL,0,&s_dmgreenthing4};
+statetype s_dmgreenthing2 = {false,TSPHERE2,4,NULL,0,&s_dmgreenthing3};
+statetype s_dmgreenthing1 = {false,TSPHERE1,4,NULL,0,&s_dmgreenthing2};
+
+
+statetype s_energysphere4 = {false,TOMSPHERE4,4,T_Projectile,0,&s_energysphere1};
+statetype s_energysphere3 = {false,TOMSPHERE3,4,T_Projectile,0,&s_energysphere4};
+statetype s_energysphere2 = {false,TOMSPHERE2,4,T_Projectile,0,&s_energysphere3};
+statetype s_energysphere1 = {false,TOMSPHERE1,4,T_Projectile,0,&s_energysphere2};
+
+
+statetype s_lightning = {true,TOMLIGHTNING1,0,T_Projectile,0,&s_lightning};
+
+
+statetype s_handball2 = {false,TOMHANDBALL2,3,T_Projectile,0,&s_handball1};
+statetype s_handball1 = {false,TOMHANDBALL1,3,T_Projectile,0,&s_handball2};
+
+statetype s_faceball2 = {false,TOMFACEBALL2,3,T_Projectile,0,&s_faceball1};
+statetype s_faceball1 = {false,TOMFACEBALL1,3,T_Projectile,0,&s_faceball2};
+
+statetype s_floorspark4 = {false,TOMFLOORSPARK4,3,T_Projectile,0,&s_floorspark1};
+statetype s_floorspark3 = {false,TOMFLOORSPARK3,3,T_Projectile,0,&s_floorspark4};
+statetype s_floorspark2 = {false,TOMFLOORSPARK2,3,T_Projectile,0,&s_floorspark3};
+statetype s_floorspark1 = {false,TOMFLOORSPARK1,3,T_Projectile,0,&s_floorspark2};
+
+
+
+statetype s_darkmonkreact = {true,TOMFLY11,0,T_DarkmonkReact,0,&s_darkmonkreact};
+
+statetype s_darkmonkbball9	= {false,TBBALL9,4,NULL,0,&s_darkmonkchase1};
+statetype s_darkmonkbball8	= {false,TBBALL8,4,NULL,0,&s_darkmonkbball9};
+statetype s_darkmonkbball7 = {false,TBBALL7,4,A_DmonkAttack,0,&s_darkmonkbball8};
+statetype s_darkmonkbball6	= {false,TBBALL6,4,NULL,0,&s_darkmonkbball7};
+statetype s_darkmonkbball5	= {false,TBBALL5,4,NULL,0,&s_darkmonkbball6};
+statetype s_darkmonkbball4	= {false,TBBALL4,4,NULL,0,&s_darkmonkbball5};
+statetype s_darkmonkbball3	= {false,TBBALL3,4,NULL,0,&s_darkmonkbball4};
+statetype s_darkmonkbball2 = {false,TBBALL2,4,NULL,0,&s_darkmonkbball3};
+statetype s_darkmonkbball1 = {false,TBBALL1,70,NULL,0,&s_darkmonkbball2};
+
+
+statetype s_darkmonkcharge10 = {false,TSCAREB3,140,T_DarkmonkCharge,0,&s_darkmonkchase1};
+statetype s_darkmonkcharge9	= {false,TAWAKEN5,3,NULL,0,&s_darkmonkcharge10};
+statetype s_darkmonkcharge8	= {false,TAWAKEN4,3,NULL,0,&s_darkmonkcharge9};
+statetype s_darkmonkcharge7	= {false,TAWAKEN3,3,NULL,0,&s_darkmonkcharge8};
+statetype s_darkmonkcharge6 	= {false,TAWAKEN2,3,NULL,0,&s_darkmonkcharge7};
+statetype s_darkmonkcharge5	= {false,TAWAKEN1,3,NULL,0,&s_darkmonkcharge6};
+statetype s_darkmonkcharge4	= {false,TAWAKEN2,3,NULL,0,&s_darkmonkcharge5};
+statetype s_darkmonkcharge3	= {false,TAWAKEN3,3,NULL,0,&s_darkmonkcharge4};
+statetype s_darkmonkcharge2	= {false,TAWAKEN4,3,NULL,0,&s_darkmonkcharge3};
+statetype s_darkmonkcharge1 	= {false,TAWAKEN5,3,NULL,0,&s_darkmonkcharge2};
+
+
+statetype s_darkmonkscare5	= {false,TSCAREB5,3,NULL,0,&s_darkmonkcharge1};
+statetype s_darkmonkscare4	= {false,TSCAREB4,3,NULL,0,&s_darkmonkscare5};
+statetype s_darkmonkscare3	= {false,TSCAREB3,3,NULL,0,&s_darkmonkscare4};
+statetype s_darkmonkscare2 = {false,TSCAREB2,3,NULL,0,&s_darkmonkscare3};
+statetype s_darkmonkscare1 = {false,TSCAREB1,3,NULL,0,&s_darkmonkscare2};
+
+statetype s_darkmonkdead = {false,TOMDIE8,0,T_Collide,0,&s_darkmonkdead};
+statetype s_darkmonkdie7 = {false,TOMDIE7,3,T_Collide,0,&s_darkmonkdead};
+statetype s_darkmonkdie6 = {false,TOMDIE6,3,T_Collide,0,&s_darkmonkdie7};
+statetype s_darkmonkdie5 = {false,TOMDIE5,3,T_Collide,0,&s_darkmonkdie6};
+statetype s_darkmonkdie4 = {false,TOMDIE4,3,T_Collide,0,&s_darkmonkdie5};
+statetype s_darkmonkdie3 = {false,TOMDIE3,3,T_Collide,0,&s_darkmonkdie4};
+statetype s_darkmonkdie2 = {false,TOMDIE2,3,T_Collide,0,&s_darkmonkdie3};
+statetype s_darkmonkdie1 = {false,TOMDIE1,3,T_Collide,0,&s_darkmonkdie2};
+
+
+
+statetype s_darkmonkredhead = {true,TOMRH1,50,T_DarkSnakeChase,0,&s_darkmonkhead};
+statetype s_darkmonkredlink = {true,TOMRH1,50,T_GenericMove,0,&s_darkmonksnakelink};
+
+statetype s_redheadhit = {false,THDIE1,35,T_DarkSnakeChase,0,&s_darkmonkhead};
+statetype s_redlinkhit = {false,THDIE1,35,T_GenericMove,0,&s_darkmonksnakelink};
+
+
+statetype s_spithit4 = {false,SPITHIT4,3,NULL,0,NULL};
+statetype s_spithit3 = {false,SPITHIT3,3,NULL,0,&s_spithit4};
+statetype s_spithit2 = {false,SPITHIT2,3,NULL,0,&s_spithit3};
+statetype s_spithit1 = {false,SPITHIT1,3,NULL,0,&s_spithit2};
+
+statetype s_spit4 = {false,TOMSPIT4,3,T_Projectile,0,&s_spit1};
+statetype s_spit3 = {false,TOMSPIT3,3,T_Projectile,0,&s_spit4};
+statetype s_spit2 = {false,TOMSPIT2,3,T_Projectile,0,&s_spit3};
+statetype s_spit1 = {false,TOMSPIT1,3,T_Projectile,0,&s_spit2};
+
+statetype s_snakefire2 = {true,TOMHEAD1,1,T_DarkSnakeChase,SF_DOWN|SF_UP,&s_darkmonkhead};
+statetype s_snakefire1 = {false,TPREPARE,30,T_DarkSnakeChase,SF_DOWN,&s_snakefire2};
+
+statetype s_dexplosion22 = {false,-1,0,T_BossDied,0,NULL};
+statetype s_dexplosion21 = {false, -1, 240,NULL,0,&s_dexplosion22};
+statetype s_dexplosion20 = {false,SPR_EXPLOSION20,2,NULL,0,&s_dexplosion21};
+statetype s_dexplosion19 = {false,SPR_EXPLOSION19,2,NULL,0,&s_dexplosion20};
+statetype s_dexplosion18 = {false,SPR_EXPLOSION18,2,NULL,0,&s_dexplosion19};
+statetype s_dexplosion17 = {false,SPR_EXPLOSION17,2,NULL,0,&s_dexplosion18};
+statetype s_dexplosion16 = {false,SPR_EXPLOSION16,2,NULL,0,&s_dexplosion17};
+statetype s_dexplosion15 = {false,SPR_EXPLOSION15,2,NULL,0,&s_dexplosion16};
+statetype s_dexplosion14 = {false,SPR_EXPLOSION14,2,NULL,0,&s_dexplosion15};
+statetype s_dexplosion13 = {false,SPR_EXPLOSION13,2,NULL,0,&s_dexplosion14};
+statetype s_dexplosion12 = {false,SPR_EXPLOSION12,2,NULL,0,&s_dexplosion13};
+statetype s_dexplosion11 = {false,SPR_EXPLOSION11,2,NULL,0,&s_dexplosion12};
+statetype s_dexplosion10 = {false,SPR_EXPLOSION10,2,NULL,0,&s_dexplosion11};
+statetype s_dexplosion9 = {false,SPR_EXPLOSION9,2,NULL,0,&s_dexplosion10};
+statetype s_dexplosion8 = {false,SPR_EXPLOSION8,2,NULL,0,&s_dexplosion9};
+statetype s_dexplosion7 = {false,SPR_EXPLOSION7,2,NULL,0,&s_dexplosion8};
+statetype s_dexplosion6 = {false,SPR_EXPLOSION6,2,NULL,0,&s_dexplosion7};
+statetype s_dexplosion5 = {false,SPR_EXPLOSION5,2,NULL,0,&s_dexplosion6};
+statetype s_dexplosion4 = {false,SPR_EXPLOSION4,2,NULL,0,&s_dexplosion5};
+statetype s_dexplosion3 = {false,SPR_EXPLOSION3,2,T_Explosion,0,&s_dexplosion4};
+statetype s_dexplosion2 = {false,SPR_EXPLOSION2,2,NULL,0,&s_dexplosion3};
+statetype s_dexplosion1 = {false,SPR_EXPLOSION1,2,NULL,0,&s_dexplosion2};
+
+
+/*
+===========================================================================
+
+									OROBOT
+
+===========================================================================
+*/
+
+statetype s_NMEdeathbuildup = {16,NMEBODY1_01,210,T_NME_Explode,0,NULL};
+statetype s_NMEheadexplosion = {16,NMEHEAD1_01,140,T_Special,0,&s_grexplosion1};
+
+statetype s_NMEstand = {16,NMEBODY1_01,0,T_Stand,0,&s_NMEstand};
+statetype s_NMEhead1 = {16,NMEHEAD1_01,0,NULL,0,&s_NMEhead1};
+statetype s_NMEhead2 = {16,NMEHEAD2_01,0,NULL,0,&s_NMEhead2};
+statetype s_NMEchase = {16,NMEBODY1_01,20,T_OrobotChase,0,&s_NMEchase};
+statetype s_NMEwheels1 = {16,NMEWHEEL1_01,0,NULL,0,&s_NMEwheels1};
+statetype s_NMEwheels2 = {16,NMEWHEEL2_01,0,NULL,0,&s_NMEwheels2};
+statetype s_NMEwheels3 = {16,NMEWHEEL3_01,0,NULL,0,&s_NMEwheels3};
+statetype s_NMEwheels4 = {16,NMEWHEEL4_01,0,NULL,0,&s_NMEwheels4};
+statetype s_NMEwheels5 = {16,NMEWHEEL5_01,0,NULL,0,&s_NMEwheels5};
+
+statetype s_shootinghead = {16,NMEHEAD1_01,140,T_NME_HeadShoot,0,&s_shootinghead};
+
+statetype s_NMEspinattack = {16,NMEBODY1_01,70,T_NME_SpinAttack,0,&s_NMEchase};
+statetype s_NMEwheelspin = {16,NMEWHEEL1_01,70,NULL,0,&s_NMEwheels2};
+
+statetype s_NMEminiball4 = {false,NMEMINIBALL_04,4,T_Projectile,0,&s_NMEminiball1};
+statetype s_NMEminiball3 = {false,NMEMINIBALL_03,4,T_Projectile,0,&s_NMEminiball4};
+statetype s_NMEminiball2 = {false,NMEMINIBALL_02,4,T_Projectile,0,&s_NMEminiball3};
+statetype s_NMEminiball1 = {false,NMEMINIBALL_01,4,T_Projectile,0,&s_NMEminiball2};
+
+statetype s_NMEsaucer4 = {false,NMESAUCER_04,6,T_Saucer,0,&s_NMEsaucer1};
+statetype s_NMEsaucer3 = {false,NMESAUCER_03,6,T_Saucer,0,&s_NMEsaucer4};
+statetype s_NMEsaucer2 = {false,NMESAUCER_02,6,T_Saucer,0,&s_NMEsaucer3};
+statetype s_NMEsaucer1 = {false,NMESAUCER_01,6,T_Saucer,SF_SOUND,&s_NMEsaucer2};
+
+statetype s_NMEdie = {16,NMEBODY1_01,0,T_Collide,0,&s_NMEdie};
+
+
+statetype s_NMEspinfire = {16,NMEBODY1_01,0,T_NME_SpinFire,0,&s_NMEspinfire};
+statetype s_NMEattack = {16,NMEBODY1_01,0,T_NME_Attack,0,&s_NMEattack};
+statetype s_NMEhead1rl = {16,NMEROCKET_01,0,NULL,0,&s_NMEhead1rl};
+statetype s_NMEhead2rl = {16,NMEROCKET2_01,0,NULL,0,&s_NMEhead2rl};
+
+statetype s_NMEwindup = {16,NMEBODY1_01,0,T_NME_WindUp,0,&s_NMEwindup};
+
+statetype s_NMEwheels120 = {16,NMEWHEEL1_01,0,NULL,0,&s_NMEwheels120};
+
+statetype s_NMEwrotleft3 = {16,NMEWHEEL4_01,10,NULL,0,&s_NMEwrotleft3};
+statetype s_NMEwrotleft2 = {16,NMEWHEEL3_01,10,NULL,0,&s_NMEwrotleft3};
+statetype s_NMEwrotleft1 = {16,NMEWHEEL2_01,10,NULL,0,&s_NMEwrotleft2};
+
+statetype s_NMEwrotright3 = {16,NMEWHEEL4_01,10,NULL,0,&s_NMEwrotleft3};
+statetype s_NMEwrotright2 = {16,NMEWHEEL5_01,10,NULL,0,&s_NMEwrotleft3};
+statetype s_NMEwrotright1 = {16,NMEWHEEL2_01,10,NULL,0,&s_NMEwrotleft2};
+
+statetype  s_oshuriken4 = {false,SPR_OSHUR4,1,T_Projectile,0,&s_oshuriken1};
+statetype  s_oshuriken3 = {false,SPR_OSHUR3,1,T_Projectile,0,&s_oshuriken4};
+statetype  s_oshuriken2 = {false,SPR_OSHUR2,1,T_Projectile,0,&s_oshuriken3};
+statetype  s_oshuriken1 = {false,SPR_OSHUR1,1,T_Projectile,0,&s_oshuriken2};
+
+statetype  s_oshurikenhit3 = {false,SPR_OSHURHIT3,3,NULL,0,NULL};
+statetype  s_oshurikenhit2 = {false,SPR_OSHURHIT2,3,NULL,0,&s_oshurikenhit3};
+statetype  s_oshurikenhit1 = {false,SPR_OSHURHIT1,3,NULL,0,&s_oshurikenhit2};
+
+statetype s_speardown16 = {false,SPEARDOWN16,2,T_Spears,SF_CRUSH,&s_speardown1};
+statetype s_speardown15 = {false,SPEARDOWN15,2,T_Spears,SF_CRUSH,&s_speardown16};
+statetype s_speardown14 = {false,SPEARDOWN14,2,T_Spears,SF_CRUSH,&s_speardown15};
+statetype s_speardown13 = {false,SPEARDOWN13,2,T_Spears,SF_CRUSH,&s_speardown14};
+statetype s_speardown12 = {false,SPEARDOWN12,2,T_Spears,SF_CRUSH,&s_speardown13};
+statetype s_speardown11 = {false,SPEARDOWN11,2,T_Spears,SF_CRUSH,&s_speardown12};
+statetype s_speardown10 = {false,SPEARDOWN10,2,T_Spears,SF_CRUSH,&s_speardown11};
+statetype s_speardown9 = {false,SPEARDOWN9,2,T_Spears,SF_DOWN,&s_speardown10};
+
+statetype s_speardown8 = {false,SPEARDOWN8,35,T_Spears,SF_DOWN|SF_SOUND,&s_speardown9};
+statetype s_speardown7 = {false,SPEARDOWN7,2,T_Spears,SF_DOWN,&s_speardown8};
+statetype s_speardown6 = {false,SPEARDOWN6,2,T_Spears,SF_CRUSH,&s_speardown7};
+statetype s_speardown5 = {false,SPEARDOWN5,2,T_Spears,SF_CRUSH,&s_speardown6};
+statetype s_speardown4 = {false,SPEARDOWN4,2,T_Spears,SF_CRUSH,&s_speardown5};
+statetype s_speardown3 = {false,SPEARDOWN3,2,T_Spears,SF_CRUSH,&s_speardown4};
+statetype s_speardown2 = {false,SPEARDOWN2,2,T_Spears,SF_CRUSH,&s_speardown3};
+statetype s_speardown1 = {false,SPEARDOWN1,2,T_Spears,SF_CRUSH,&s_speardown2};
+
+
+
+statetype s_downblade16 = {false,DBLADE8,1,T_Path,0,&s_downblade1};
+statetype s_downblade15 = {false,DBLADE7,2,T_Path,0,&s_downblade16};
+statetype s_downblade14 = {false,DBLADE6,1,T_Path,0,&s_downblade15};
+statetype s_downblade13 = {false,DBLADE5,2,T_Path,0,&s_downblade14};
+statetype s_downblade12 = {false,DBLADE4,1,T_Path,0,&s_downblade13};
+statetype s_downblade11 = {false,DBLADE3,2,T_Path,0,&s_downblade12};
+statetype s_downblade10 = {false,DBLADE2,1,T_Path,0,&s_downblade11};
+statetype s_downblade9 = {false,DBLADE9,2,T_Path,0,&s_downblade10};
+statetype s_downblade8 = {false,DBLADE8,1,T_Path,0,&s_downblade9};
+statetype s_downblade7 = {false,DBLADE7,2,T_Path,0,&s_downblade8};
+statetype s_downblade6 = {false,DBLADE6,1,T_Path,0,&s_downblade7};
+statetype s_downblade5 = {false,DBLADE5,2,T_Path,0,&s_downblade6};
+statetype s_downblade4 = {false,DBLADE4,1,T_Path,0,&s_downblade5};
+statetype s_downblade3 = {false,DBLADE3,2,T_Path,0,&s_downblade4};
+statetype s_downblade2 = {false,DBLADE2,1,T_Path,0,&s_downblade3};
+statetype s_downblade1 = {false,DBLADE1,2,T_Path,SF_SOUND,&s_downblade2};
+
+
+statetype s_firejetdown23 = {false,FIREJETDOWN23,3,T_Path,SF_CRUSH,&s_firejetdown1};
+statetype s_firejetdown22 = {false,FIREJETDOWN22,3,T_Path,SF_CRUSH,&s_firejetdown23};
+statetype s_firejetdown21 = {false,FIREJETDOWN21,3,T_Path,0,&s_firejetdown22};
+statetype s_firejetdown20 = {false,FIREJETDOWN20,3,T_Path,0,&s_firejetdown21};
+statetype s_firejetdown19 = {false,FIREJETDOWN19,3,T_Path,0,&s_firejetdown20};
+statetype s_firejetdown18 = {false,FIREJETDOWN18,3,T_Path,0,&s_firejetdown19};
+statetype s_firejetdown17 = {false,FIREJETDOWN17,3,T_Path,0,&s_firejetdown18};
+statetype s_firejetdown16 = {false,FIREJETDOWN16,3,T_Path,SF_CRUSH,&s_firejetdown17};
+statetype s_firejetdown15 = {false,FIREJETDOWN15,3,T_Path,SF_CRUSH,&s_firejetdown16};
+statetype s_firejetdown14 = {false,FIREJETDOWN14,3,T_Path,SF_CRUSH,&s_firejetdown15};
+statetype s_firejetdown13 = {false,FIREJETDOWN13,3,T_Path,0,&s_firejetdown14};
+statetype s_firejetdown12 = {false,FIREJETDOWN12,3,T_Path,0,&s_firejetdown13};
+statetype s_firejetdown11 = {false,FIREJETDOWN11,3,T_Path,0,&s_firejetdown12};
+statetype s_firejetdown10 = {false,FIREJETDOWN10,3,T_Path,0,&s_firejetdown11};
+statetype s_firejetdown9 = {false,FIREJETDOWN9,3,T_Path,0,&s_firejetdown10};
+statetype s_firejetdown8 = {false,FIREJETDOWN8,3,T_Path,SF_CRUSH,&s_firejetdown9};
+statetype s_firejetdown7 = {false,FIREJETDOWN7,3,T_Path,SF_CRUSH,&s_firejetdown8};
+statetype s_firejetdown6 = {false,FIREJETDOWN6,3,T_Path,SF_CRUSH,&s_firejetdown7};
+statetype s_firejetdown5 = {false,FIREJETDOWN5,3,T_Path,0,&s_firejetdown6};
+statetype s_firejetdown4 = {false,FIREJETDOWN4,3,T_Path,0,&s_firejetdown5};
+statetype s_firejetdown3 = {false,FIREJETDOWN3,3,T_Path,0,&s_firejetdown4};
+statetype s_firejetdown2 = {false,FIREJETDOWN2,3,T_Path,0,&s_firejetdown3};
+statetype s_firejetdown1 = {false,FIREJETDOWN1,70,T_Path,SF_SOUND,&s_firejetdown2};
+
+
+
+statetype s_columnupdown6 = {false,CRUSHUP7,5,T_CrushUp,SF_DOWN,&s_columnupup1};
+statetype s_columnupdown5 = {false,CRUSHUP6,2,T_CrushUp,SF_DOWN,&s_columnupdown6};
+statetype s_columnupdown4 = {false,CRUSHUP5,5,T_CrushUp,SF_DOWN|SF_BLOCK,&s_columnupdown5};
+statetype s_columnupdown3 = {false,CRUSHUP4,5,T_CrushUp,SF_DOWN|SF_BLOCK,&s_columnupdown4};
+statetype s_columnupdown2 = {false,CRUSHUP3,5,T_CrushUp,SF_DOWN|SF_BLOCK,&s_columnupdown3};
+statetype s_columnupdown1 = {false,CRUSHUP2,2,T_CrushUp,SF_DOWN|SF_BLOCK,&s_columnupdown2};
+
+
+statetype s_columnupup8 = {false,CRUSHUP1,5,T_CrushUp,SF_CRUSH|SF_BLOCK,&s_columnupdown1};
+statetype s_columnupup7 = {false,CRUSHUP2,2,T_CrushUp,SF_CRUSH|SF_UP|SF_BLOCK,&s_columnupup8};
+statetype s_columnupup6 = {false,CRUSHUP3,5,T_CrushUp,SF_UP|SF_BLOCK,&s_columnupup7};
+statetype s_columnupup5 = {false,CRUSHUP4,5,T_CrushUp,SF_UP|SF_BLOCK,&s_columnupup6};
+statetype s_columnupup4 = {false,CRUSHUP5,5,T_CrushUp,SF_UP,&s_columnupup5};
+statetype s_columnupup3 = {false,CRUSHUP6,2,T_CrushUp,SF_UP,&s_columnupup4};
+statetype s_columnupup2 = {false,CRUSHUP7,5,T_CrushUp,SF_UP,&s_columnupup3};
+statetype s_columnupup1 = {false,CRUSHUP8,30,T_CrushUp,SF_SOUND,&s_columnupup2};
+
+
+
+statetype s_spinupblade16 = {false,SPINUBLADE_16,2,T_Path,SF_DOWN,&s_spinupblade1};
+statetype s_spinupblade15 = {false,SPINUBLADE_15,2,T_Path,0,&s_spinupblade16};
+statetype s_spinupblade14 = {false,SPINUBLADE_14,2,T_Path,0,&s_spinupblade15};
+statetype s_spinupblade13 = {false,SPINUBLADE_13,2,T_Path,0,&s_spinupblade14};
+statetype s_spinupblade12 = {false,SPINUBLADE_12,2,T_Path,0,&s_spinupblade13};
+statetype s_spinupblade11 = {false,SPINUBLADE_11,2,T_Path,0,&s_spinupblade12};
+statetype s_spinupblade10 = {false,SPINUBLADE_10,2,T_Path,0,&s_spinupblade11};
+statetype s_spinupblade9 = {false,SPINUBLADE_09,2,T_Path,0,&s_spinupblade10};
+
+statetype s_spinupblade8 = {false,SPINUBLADE_08,2,T_Path,0,&s_spinupblade9};
+statetype s_spinupblade7 = {false,SPINUBLADE_07,2,T_Path,0,&s_spinupblade8};
+statetype s_spinupblade6 = {false,SPINUBLADE_06,2,T_Path,0,&s_spinupblade7};
+statetype s_spinupblade5 = {false,SPINUBLADE_05,2,T_Path,0,&s_spinupblade6};
+statetype s_spinupblade4 = {false,SPINUBLADE_04,2,T_Path,0,&s_spinupblade5};
+statetype s_spinupblade3 = {false,SPINUBLADE_03,2,T_Path,0,&s_spinupblade4};
+statetype s_spinupblade2 = {false,SPINUBLADE_02,2,T_Path,0,&s_spinupblade3};
+statetype s_spinupblade1 = {false,SPINUBLADE_01,35,T_Path,SF_UP|SF_SOUND,&s_spinupblade2};
+
+
+statetype s_spindownblade16 = {false,SPINDBLADE_16,2,T_Path,SF_DOWN,&s_spindownblade1};
+statetype s_spindownblade15 = {false,SPINDBLADE_15,2,T_Path,0,&s_spindownblade16};
+statetype s_spindownblade14 = {false,SPINDBLADE_14,2,T_Path,0,&s_spindownblade15};
+statetype s_spindownblade13 = {false,SPINDBLADE_13,2,T_Path,0,&s_spindownblade14};
+statetype s_spindownblade12 = {false,SPINDBLADE_12,2,T_Path,0,&s_spindownblade13};
+statetype s_spindownblade11 = {false,SPINDBLADE_11,2,T_Path,0,&s_spindownblade12};
+statetype s_spindownblade10 = {false,SPINDBLADE_10,2,T_Path,0,&s_spindownblade11};
+statetype s_spindownblade9 = {false,SPINDBLADE_09,2,T_Path,0,&s_spindownblade10};
+
+statetype s_spindownblade8 = {false,SPINDBLADE_08,2,T_Path,0,&s_spindownblade9};
+statetype s_spindownblade7 = {false,SPINDBLADE_07,2,T_Path,0,&s_spindownblade8};
+statetype s_spindownblade6 = {false,SPINDBLADE_06,2,T_Path,0,&s_spindownblade7};
+statetype s_spindownblade5 = {false,SPINDBLADE_05,2,T_Path,0,&s_spindownblade6};
+statetype s_spindownblade4 = {false,SPINDBLADE_04,2,T_Path,0,&s_spindownblade5};
+statetype s_spindownblade3 = {false,SPINDBLADE_03,2,T_Path,0,&s_spindownblade4};
+statetype s_spindownblade2 = {false,SPINDBLADE_02,2,T_Path,0,&s_spindownblade3};
+statetype s_spindownblade1 = {false,SPINDBLADE_01,35,T_Path,SF_UP|SF_SOUND,&s_spindownblade2};
+
+
+statetype s_bouldersink9 = {false,BSINK9,2,NULL,0,NULL};
+statetype s_bouldersink8 = {false,BSINK8,2,NULL,0,&s_bouldersink9};
+statetype s_bouldersink7 = {false,BSINK7,2,NULL,0,&s_bouldersink8};
+statetype s_bouldersink6 = {false,BSINK6,2,NULL,0,&s_bouldersink7};
+statetype s_bouldersink5 = {false,BSINK5,2,NULL,0,&s_bouldersink6};
+statetype s_bouldersink4 = {false,BSINK4,2,NULL,0,&s_bouldersink5};
+statetype s_bouldersink3 = {false,BSINK3,2,NULL,0,&s_bouldersink4};
+statetype s_bouldersink2 = {false,BSINK2,2,NULL,0,&s_bouldersink3};
+statetype s_bouldersink1 = {false,BSINK1,2,NULL,0,&s_bouldersink2};
+
+
+statetype s_boulderroll8 = {false,BOULDER41,3,T_BoulderMove,0,&s_boulderroll1};
+statetype s_boulderroll7 = {false,BOULDER31,3,T_BoulderMove,0,&s_boulderroll8};
+statetype s_boulderroll6 = {false,BOULDER21,3,T_BoulderMove,0,&s_boulderroll7};
+statetype s_boulderroll5 = {false,BOULDER11,3,T_BoulderMove,0,&s_boulderroll6};
+statetype s_boulderroll4 = {false,BOULDER41,3,T_BoulderMove,0,&s_boulderroll5};
+statetype s_boulderroll3 = {false,BOULDER31,3,T_BoulderMove,0,&s_boulderroll4};
+statetype s_boulderroll2 = {false,BOULDER21,3,T_BoulderMove,0,&s_boulderroll3};
+statetype s_boulderroll1 = {false,BOULDER11,3,T_BoulderMove,SF_SOUND,&s_boulderroll2};
+
+
+
+
+statetype s_boulderdrop12 = {false,BOULDER11,0,T_BoulderDrop,0,&s_boulderdrop12};
+statetype s_boulderdrop11 = {false,BDROP11,1,T_BoulderDrop,0,&s_boulderdrop12};
+statetype s_boulderdrop10 = {false,BDROP10,1,T_BoulderDrop,0,&s_boulderdrop11};
+statetype s_boulderdrop9 = {false,BDROP9,2,T_BoulderDrop,0,&s_boulderdrop10};
+statetype s_boulderdrop8 = {false,BDROP8,1,T_BoulderDrop,0,&s_boulderdrop9};
+statetype s_boulderdrop7 = {false,BDROP7,1,T_BoulderDrop,0,&s_boulderdrop8};
+statetype s_boulderdrop6 = {false,BDROP6,2,T_BoulderDrop,0,&s_boulderdrop7};
+statetype s_boulderdrop5 = {false,BDROP5,3,T_BoulderDrop,0,&s_boulderdrop6};
+statetype s_boulderdrop4 = {false,BDROP4,4,T_BoulderDrop,0,&s_boulderdrop5};
+statetype s_boulderdrop3 = {false,BDROP3,5,T_BoulderDrop,SF_SOUND,&s_boulderdrop4};
+statetype s_boulderdrop2 = {false,BDROP2,6,NULL,0,&s_boulderdrop3};
+statetype s_boulderdrop1 = {false,BDROP1,6,NULL,0,&s_boulderdrop2};
+
+statetype s_boulderspawn = {false,NOTHING,70,T_BoulderSpawn,0,&s_boulderspawn};
+
+
+
+/*==========================================================================
+
+									GUN STUFF
+
+============================================================================*/
+
+statetype s_gunfire2 = {true,GUNRISE51,5,A_GunShoot,0,&s_gunfire1};
+statetype s_gunfire1 = {true,GUNFIRE1,5,A_GunShoot,0,&s_gunfire2};
+
+statetype s_gunstand = {true,GUNRISE11,0,T_GunStand,0,&s_gunstand};
+
+statetype s_gunraise4 = {true,GUNRISE51,2,NULL,0,&s_gunfire1};
+statetype s_gunraise3 = {true,GUNRISE41,2,NULL,0,&s_gunraise4};
+statetype s_gunraise2 = {true,GUNRISE31,2,NULL,0,&s_gunraise3};
+statetype s_gunraise1 = {true,GUNRISE21,2,NULL,0,&s_gunraise2};
+
+statetype s_gunlower3 = {true,GUNRISE21,2,NULL,0,&s_gunstand};
+statetype s_gunlower2 = {true,GUNRISE31,2,NULL,0,&s_gunlower3};
+statetype s_gunlower1 = {true,GUNRISE41,2,NULL,0,&s_gunlower2};
+
+
+statetype s_gundead = {false,GUNDEAD2,0,T_Collide,0,&s_gundead};
+statetype s_gundie1 = {false,GUNDEAD1,5,NULL,0,&s_gundead};
+
+
+
+//======================================================================//
+
+statetype s_4waygunfire1 = {true,FOURWAYFIRE01,5,A_4WayGunShoot,0,&s_4waygunfire2};
+statetype s_4waygunfire2 = {true,FOURWAY01,5,NULL,0,&s_4waygunfire1};
+
+statetype s_4waygun = {true,FOURWAY01,0,T_4WayGunStand,0,&s_4waygun};
+
+
+
+
+statetype s_kessphere8 = {false,KESSPHERE8,2,T_Projectile,0,&s_kessphere1};
+statetype s_kessphere7 = {false,KESSPHERE7,2,T_Projectile,0,&s_kessphere8};
+statetype s_kessphere6 = {false,KESSPHERE6,2,T_Projectile,0,&s_kessphere7};
+statetype s_kessphere5 = {false,KESSPHERE5,2,T_Projectile,0,&s_kessphere6};
+statetype s_kessphere4 = {false,KESSPHERE4,2,T_Projectile,0,&s_kessphere5};
+statetype s_kessphere3 = {false,KESSPHERE3,2,T_Projectile,0,&s_kessphere4};
+statetype s_kessphere2 = {false,KESSPHERE2,2,T_Projectile,0,&s_kessphere3};
+statetype s_kessphere1 = {false,KESSPHERE1,2,T_Projectile,0,&s_kessphere2};
+
+
+statetype s_slop4 = {false,TOMSPIT4,3,T_Particle,0,&s_slop1};
+statetype s_slop3 = {false,TOMSPIT3,3,T_Particle,0,&s_slop4};
+statetype s_slop2 = {false,TOMSPIT2,3,T_Particle,0,&s_slop3};
+statetype s_slop1 = {false,TOMSPIT1,3,T_Particle,0,&s_slop2};
+
+
+statetype s_batblast4 = {false,BATBLAST4,3,T_Projectile,SF_BAT,&s_batblast1};
+statetype s_batblast3 = {false,BATBLAST3,3,T_Projectile,SF_BAT,&s_batblast4};
+statetype s_batblast2 = {false,BATBLAST2,3,T_Projectile,SF_BAT,&s_batblast3};
+statetype s_batblast1 = {false,BATBLAST1,3,T_Projectile,SF_BAT,&s_batblast2};
+
+
+statetype s_serialdog4 = {true,SERIALDOG_W41,5,T_Player,SF_DOGSTATE,&s_serialdog};
+statetype s_serialdog3 = {true,SERIALDOG_W31,5,T_Player,SF_DOGSTATE,&s_serialdog4};
+statetype s_serialdog2 = {true,SERIALDOG_W21,5,T_Player,SF_DOGSTATE,&s_serialdog3};
+statetype s_serialdog = {true,SERIALDOG_W11,5,T_Player,SF_DOGSTATE,&s_serialdog2};
+statetype s_serialdogattack = {true,SERIALDOG_ATTACK1,0,T_Attack,SF_DOGSTATE,&s_serialdogattack };
+
+
+#endif
+
+
+#include "rt_table.h"

Added: tags/rott-1.1/rott/rt_str.c
===================================================================
--- tags/rott-1.1/rott/rt_str.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_str.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,2053 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//******************************************************************************
+//
+// RT_STR.C
+//    Contains the menu stuff!
+//
+//******************************************************************************
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <string.h>
+#include <ctype.h>
+#include "rt_def.h"
+#include "rt_menu.h"
+#include "rt_util.h"
+#include "rt_vid.h"
+#include "rt_build.h"
+#include "lumpy.h"
+#include "rt_str.h"
+#include "_rt_str.h"
+#include "isr.h"
+#include "rt_in.h"
+#include "rt_menu.h"
+#include "rt_view.h"
+#include "w_wad.h"
+#include "z_zone.h"
+#include "modexlib.h"
+#include "rt_main.h"
+#include "rt_msg.h"
+#include "rt_playr.h"
+#include "rt_sound.h"
+#include "myprint.h"
+//MED
+#include "memcheck.h"
+
+
+//******************************************************************************
+//
+// GLOBALS
+//
+//******************************************************************************
+
+int fontcolor;
+
+//******************************************************************************
+//
+// LOCALS
+//
+//******************************************************************************
+
+static int BKw;
+static int BKh;
+   
+static char strbuf[MaxString];
+
+//******************************************************************************
+//
+// VW_DrawClippedString ()
+//
+// Draws a string at x, y to bufferofs
+//
+//******************************************************************************
+
+void VW_DrawClippedString (int x, int y, const char *string)
+{
+   int   width,height,ht;
+   byte  *source;
+   int   ch;
+   int   oy;
+
+   ht = CurrentFont->height;
+
+   oy=y;
+
+   while ((ch = (unsigned char)*string++)!=0)
+      {
+      ch -= 31;
+      width = CurrentFont->width[ch];
+      source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
+      while (width--)
+         {
+         if ((x>=0) && (x<iGLOBAL_SCREENWIDTH))
+            {
+            y=oy;
+            VGAWRITEMAP(x&3);
+            height = ht;
+            while (height--)
+               {
+               if ((y>=0) && (y<iGLOBAL_SCREENHEIGHT))
+                  {
+                  if (*source>0)
+#ifdef DOS
+                     *((byte *)(bufferofs+ylookup[y]+(x>>2))) = *source;
+#else
+                     *((byte *)(bufferofs+ylookup[y]+x)) = *source;
+#endif
+                  }
+               source++;
+               y++;
+               }
+            }
+         x++;
+         }
+      }
+}
+
+//******************************************************************************
+//
+// US_ClippedPrint() - Prints a string in bufferofs. Newlines are supported.
+//
+//******************************************************************************
+
+void US_ClippedPrint (int x, int y, const char *string)
+{
+   char  c,
+         *se;
+   char  *s;
+   int   startx;
+
+   strcpy(strbuf, string);
+   s = strbuf;
+   
+   startx=x;
+   while (*s)
+   {
+      se = s;
+      while ((c = *se) && (c != '\n'))
+         se++;
+      *se = '\0';
+
+      VW_DrawClippedString ( x, y, s);
+
+      s = se;
+      if (c)
+         {
+         *se = c;
+         s++;
+         y += CurrentFont->height;
+         }
+   }
+}
+
+
+//******************************************************************************
+//
+// VW_DrawPropString ()
+//
+// Draws a string at px, py to bufferofs
+//
+//******************************************************************************
+
+void VW_DrawPropString (const char *string)
+{
+#ifdef DOS
+   byte  pix;
+   int   width,step,height,ht;
+   byte  *source, *dest, *origdest;
+   int   ch,mask;
+
+
+   ht = CurrentFont->height;
+   dest = origdest = (byte *)(bufferofs+ylookup[py]+(px>>2));
+
+
+   mask = 1<<(px&3);
+
+
+   while ((ch = *string++)!=0)
+   {
+      ch -= 31;
+      width = step = CurrentFont->width[ch];
+      source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
+      while (width--)
+      {
+         VGAMAPMASK(mask);
+
+         height = ht;
+         while (height--)
+         {
+            pix = *source;
+            if (pix)
+               *dest = pix;
+
+            source++;
+            dest += linewidth;
+         }
+
+         px++;
+         mask <<= 1;
+         if (mask == 16)
+         {
+            mask = 1;
+            origdest++;
+         }
+         dest = origdest;
+      }
+   }
+   bufferheight = ht;
+   bufferwidth = ((dest+1)-origdest)*4;
+#else
+   byte  pix;
+   int   width,step,height,ht;
+   byte  *source, *dest, *origdest;
+   int   ch,mask;
+
+   ht = CurrentFont->height;
+   dest = origdest = (byte *)(bufferofs+ylookup[py]+px);
+
+   while ((ch = (unsigned char)*string++)!=0)
+   {
+      ch -= 31;
+      width = step = CurrentFont->width[ch];
+      source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
+      while (width--)
+      {
+         height = ht;
+         while (height--)
+         {
+            pix = *source;
+            if (pix)
+               *dest = pix;
+
+            source++;
+            dest += linewidth;
+         }
+
+         px++;
+	 origdest++;
+         dest = origdest;
+      }
+   }
+   bufferheight = ht;
+   bufferwidth = ((dest+1)-origdest);
+#endif
+}
+
+
+
+//******************************************************************************
+//
+// VWB_DrawPropString ()
+//
+// Calls VW_DrawPropString then updates the mark block.
+//
+//******************************************************************************
+
+void VWB_DrawPropString  (const char *string)
+{
+   int x;
+   x = px;
+   VW_DrawPropString (string);
+   VW_MarkUpdateBlock (x, py, px-1, py+bufferheight-1);
+}
+
+
+
+//******************************************************************************
+//
+// VW_DrawIPropString ()
+//
+// Draws a string at px, py to bufferofs
+//
+//******************************************************************************
+
+void VW_DrawIPropString (const char *string)
+{
+   byte  pix;
+   int   width,step,height,ht;
+   byte  *source, *dest, *origdest;
+   int   ch,mask;
+
+
+   ht = CurrentFont->height;
+#ifdef DOS
+   dest = origdest = (byte *)(bufferofs+ylookup[py]+(px>>2));
+#else
+   dest = origdest = (byte *)(bufferofs+ylookup[py]+px);
+#endif
+
+
+   mask = 1<<(px&3);
+
+
+   while ((ch = (unsigned char)*string++)!=0)
+   {
+      ch -= 31;
+      width = step = CurrentFont->width[ch];
+      source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
+      while (width--)
+      {
+         VGAMAPMASK(mask);
+
+         height = ht;
+         while (height--)
+         {
+            pix = *source;
+            if (pix)
+               *dest = pix;
+
+            source++;
+            dest += linewidth;
+         }
+
+         px++;
+#ifdef DOS
+         mask <<= 1;
+         if (mask == 16)
+         {
+            mask = 1;
+            origdest++;
+         }
+#else
+	 origdest++;
+#endif
+         dest = origdest;
+      }
+   }
+   bufferheight = ht;
+#ifdef DOS
+   bufferwidth = ((dest+1)-origdest)*4;
+#else
+   bufferwidth = ((dest+1)-origdest);
+#endif
+
+}
+
+
+
+//******************************************************************************
+//
+// VWB_DrawIPropString ()
+//
+// Calls VW_DrawIPropString then updates the mark block.
+//
+//******************************************************************************
+
+void VWB_DrawIPropString  (const char *string)
+{
+   int x;
+   x = px;
+   VW_DrawIPropString (string);
+   VW_MarkUpdateBlock (x, py, px-1, py+bufferheight-1);
+}
+
+
+
+//******************************************************************************
+//
+// VWL_MeasureString ()
+//
+//******************************************************************************
+
+void VWL_MeasureString (const char *s, int *width, int *height, const font_t *font)
+{
+   *height = font->height;
+
+   for (*width = 0; *s; s++)
+      *width += font->width[(*((byte *)s))-31];   // proportional width
+}
+
+//******************************************************************************
+//
+// VWL_MeasureIntensityString ()
+//
+//******************************************************************************
+
+void VWL_MeasureIntensityString (const char *s, int *width, int *height, const cfont_t *font)
+{
+   *height = font->height;
+
+   for (*width = 0; *s; s++)
+      *width += font->width[(*((byte *)s))-31];   // proportional width
+}
+
+//******************************************************************************
+//
+// VW_MeasureIntensityPropString ()
+//
+//******************************************************************************
+
+void VW_MeasureIntensityPropString (const char *string, int *width, int *height)
+{
+   VWL_MeasureIntensityString (string, width, height, IFont);
+}
+
+//******************************************************************************
+//
+// VW_MeasurePropString ()
+//
+//******************************************************************************
+
+void VW_MeasurePropString (const char *string, int *width, int *height)
+{
+   VWL_MeasureString (string, width, height, CurrentFont);
+}
+
+
+//******************************************************************************
+//
+// US_MeasureStr ()
+//
+//******************************************************************************
+
+void US_MeasureStr (int *width, int *height, const char * s, ...)
+{
+   char  c,
+         *se,
+         *ss;
+   int   w,h;
+   va_list strptr;
+   char buf[300];
+
+   *width  = 0;
+   *height = 0;
+
+   memset (&buf[0], 0, sizeof (buf));
+   va_start (strptr, s);
+   vsprintf (&buf[0], s, strptr);
+   va_end (strptr);
+
+   ss = &buf[0];
+
+   while (*ss)
+   {
+      se = ss;
+      while ((c = *se) && (c != '\n'))
+         se++;
+      *se = '\0';
+
+      VWL_MeasureString (ss, &w, &h, CurrentFont);
+
+      *height += h;
+
+      if (w > *width)
+         *width = w;
+
+      ss = se;
+      if (c)
+      {
+         *se = c;
+         ss++;
+      }
+   }
+}
+
+
+//******************************************************************************
+//
+// US_SetPrintRoutines() - Sets the routines used to measure and print
+//    from within the User Mgr. Primarily provided to allow switching
+//    between masked and non-masked fonts
+//
+//******************************************************************************
+
+void US_SetPrintRoutines (void (*measure)(const char *, int *, int *, font_t *),
+                          void (*print)(const char *))
+{
+   USL_MeasureString = measure;
+   USL_DrawString    = print;
+}
+
+
+//******************************************************************************
+//
+// US_Print() - Prints a string in the current window. Newlines are
+//    supported.
+//
+//******************************************************************************
+
+void US_Print (const char *string)
+{
+   char  c,
+         *se,
+         *s;
+   int   w,h;
+
+   strcpy(strbuf, string);
+   s = strbuf;
+   
+   while (*s)
+   {
+      se = s;
+      while ((c = *se) && (c != '\n'))
+         se++;
+      *se = '\0';
+
+      USL_MeasureString (s, &w, &h, CurrentFont);
+      px = PrintX;
+      py = PrintY;
+      USL_DrawString (s);
+
+      s = se;
+      if (c)
+      {
+         *se = c;
+         s++;
+
+         PrintX = WindowX;
+         PrintY += h;
+      }
+      else
+         PrintX += w;
+   }
+}
+
+//******************************************************************************
+//
+// US_BufPrint() - Prints a string in bufferofs. Newlines are supported.
+//
+//******************************************************************************
+
+void US_BufPrint (const char *string)
+{
+   char  c,
+         *se,
+         *s;
+   int   startx;
+
+   strcpy(strbuf, string);
+   s = strbuf;
+
+   startx=PrintX;
+   while (*s)
+   {
+      se = s;
+      while ((c = *se) && (c != '\n'))
+         se++;
+      *se = '\0';
+
+      px = PrintX;
+      py = PrintY;
+      USL_DrawString (s);
+
+      PrintY = py;
+      PrintX = px;
+
+      s = se;
+      if (c)
+         {
+         *se = c;
+         s++;
+         PrintY += CurrentFont->height;
+         PrintX = startx;
+         }
+   }
+}
+
+
+//******************************************************************************
+//
+// US_PrintUnsigned () - Prints an unsigned long int
+//
+//******************************************************************************
+
+void US_PrintUnsigned (unsigned long int n)
+{
+   char  buffer[32];
+
+   US_Print (ultoa (n, buffer, 10));
+}
+
+//******************************************************************************
+//
+// US_PrintSigned() - Prints a signed long
+//
+//******************************************************************************
+
+void US_PrintSigned (long int n)
+{
+   char  buffer[32];
+
+   US_Print (ltoa (n, buffer, 10));
+}
+
+//******************************************************************************
+//
+// USL_PrintInCenter() - Prints a string in the center of the given rect
+//
+//******************************************************************************
+
+void USL_PrintInCenter (const char *s, Rect r)
+{
+   int   w,h,
+         rw,rh;
+
+   USL_MeasureString (s,&w,&h, CurrentFont);
+   rw = r.lr.x - r.ul.x;
+   rh = r.lr.y - r.ul.y;
+
+   px = r.ul.x + ((rw - w) / 2);
+   py = r.ul.y + ((rh - h) / 2);
+   USL_DrawString (s);
+}
+
+//******************************************************************************
+//
+// US_PrintCentered() - Prints a string centered in the current window.
+//
+//******************************************************************************
+
+void US_PrintCentered (const char *s)
+{
+   Rect  r;
+
+   r.ul.x = WindowX;
+   r.ul.y = WindowY;
+   r.lr.x = r.ul.x + WindowW;
+   r.lr.y = r.ul.y + WindowH;
+
+   USL_PrintInCenter (s, r);
+}
+
+//******************************************************************************
+//
+// US_CPrintLine() - Prints a string centered on the current line and
+//    advances to the next line. Newlines are not supported.
+//
+//******************************************************************************
+
+void US_CPrintLine (const char *s)
+{
+   int w, h;
+
+   USL_MeasureString (s, &w, &h, CurrentFont);
+
+   if (w > WindowW)
+      Error("US_CPrintLine() - String exceeds width");
+
+   px = WindowX + ((WindowW - w) / 2);
+   py = PrintY;
+   USL_DrawString (s);
+   PrintY += h;
+}
+
+//******************************************************************************
+//
+// US_CPrint() - Prints a string in the current window. Newlines are
+//    supported.
+//
+//******************************************************************************
+
+void US_CPrint (const char *string)
+{
+   char  c,
+         *se,
+         *s;
+
+   strcpy(strbuf, string);
+   s = strbuf;
+
+   while (*s)
+   {
+      se = s;
+      while ((c = *se) && (c != '\n'))
+         se++;
+      *se = '\0';
+
+      US_CPrintLine (s);
+
+      s = se;
+      if (c)
+      {
+         *se = c;
+         s++;
+      }
+   }
+}
+
+
+
+//
+//
+// Text Input routines
+//
+//
+//
+
+
+
+//******************************************************************************
+//
+// USL_XORICursor() - XORs the I-bar text cursor. Used by  US_LineInput()
+//
+//******************************************************************************
+
+static void USL_XORICursor (int x, int y, const char *s, int cursor, int color)
+{
+   static   boolean  status;     // VGA doesn't XOR...
+   char     buf[MaxString];
+
+   int      w,h;
+   int      oldx = px;
+   int      oldy = py;
+
+   strcpy (buf,s);
+   buf[cursor] = '\0';
+   USL_MeasureString (buf, &w, &h, CurrentFont);
+
+
+   if (status^=1)
+   {
+      px = x + w;
+      py = y;
+      if (color)
+         USL_DrawString ("\x80");
+      else
+         DrawMenuBufPropString (px, py, "\x80");
+   }
+   else
+   {
+      if (color)
+      {
+         VWB_Bar (px, py, BKw, BKh, color);
+         USL_DrawString (s);
+      }
+      else
+      {
+         EraseMenuBufRegion (px, py, BKw, BKh);
+//         EraseMenuBufRegion (px, py+1, BKw, BKh-2);
+         DrawMenuBufPropString (px, py, s);
+      }
+   }
+   px = oldx;
+   py = oldy;
+}
+
+
+
+
+
+
+//******************************************************************************
+//
+// US_LineInput() - Gets a line of user input at (x,y), the string defaults
+//    to whatever is pointed at by def. Input is restricted to maxchars
+//    chars or maxwidth pixels wide. If the user hits escape (and escok is
+//    true), nothing is copied into buf, and false is returned. If the
+//    user hits return, the current string is copied into buf, and true is
+//    returned
+//
+///******************************************************************************
+
+extern byte * IN_GetScanName (ScanCode scan);
+
+boolean US_LineInput (int x, int y, char *buf, const char *def, boolean escok,
+                      int maxchars, int maxwidth, int color)
+{
+   boolean  redraw,
+            cursorvis,
+            cursormoved,
+            done,
+            result;
+   char     s[MaxString],
+            olds[MaxString];
+   int      i,
+            cursor,
+            w,h,
+            len;
+
+   int      lasttime;
+
+
+   int      lastkey;
+   int      cursorwidth;
+
+   cursorwidth = CurrentFont->width[80-31];
+
+   memset (s, 0, MaxString);
+   memset (olds, 0, MaxString);
+   IN_ClearKeyboardQueue ();
+
+   BKw = maxwidth;
+   BKh = CurrentFont->height;
+
+
+   if (def)
+      strcpy (s, def);
+   else
+      *s = '\0';
+
+   *olds = '\0';
+
+   cursor      = strlen (s);
+   cursormoved = redraw = true;
+   cursorvis   = done   = false;
+
+   lasttime  = GetTicCount();
+
+
+   lastkey = getASCII ();
+
+   while (!done)
+   {
+//      if (GameEscaped==true)
+//         PauseLoop ();
+
+      IN_PumpEvents();
+
+      if (cursorvis)
+         USL_XORICursor (x, y, s, cursor, color);
+
+      LastScan = IN_InputUpdateKeyboard ();
+      if (Keyboard[sc_LShift] || Keyboard[sc_RShift])
+         lastkey = ShiftNames[LastScan];
+      else
+         lastkey = ASCIINames[LastScan];
+
+
+      switch (LastScan)
+      {
+      case sc_LeftArrow:
+
+         if (cursor)
+            {
+            cursor--;
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            }
+         lastkey = key_None;
+         Keyboard[sc_LeftArrow] = 0;
+         break;
+
+      case sc_RightArrow:
+
+         if (s[cursor])
+            {
+            cursor++;
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            }
+         lastkey = key_None;
+         Keyboard[sc_RightArrow] = 0;
+         break;
+
+      case sc_Home:
+
+         if ( cursor )
+            {
+            cursor = 0;
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            }
+         Keyboard[sc_Home] = 0;
+         lastkey = key_None;
+         break;
+
+      case sc_End:
+
+         if ( cursor != (int)strlen (s) )
+            {
+            cursor = strlen (s);
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            }
+         lastkey = key_None;
+         Keyboard[sc_End] = 0;
+         break;
+
+
+      case sc_Return:
+         strcpy (buf,s);
+         done = true;
+         result = true;
+         lastkey = key_None;
+         MN_PlayMenuSnd (SD_SELECTSND);
+         break;
+
+      case sc_Escape:
+         if (escok)
+         {
+            done = true;
+            result = false;
+            MN_PlayMenuSnd (SD_ESCPRESSEDSND);
+         }
+         lastkey = key_None;
+         break;
+
+      case sc_BackSpace:
+
+         if (cursor)
+            {
+            strcpy (s + cursor - 1,s + cursor);
+            cursor--;
+            redraw = true;
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            }
+         lastkey = key_None;
+         Keyboard[sc_BackSpace] = 0;
+         IN_ClearKeyboardQueue ();
+         break;
+
+      case sc_Delete:
+
+         if (s[cursor])
+         {
+            strcpy (s + cursor,s + cursor + 1);
+            redraw = true;
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+         }
+         lastkey = key_None;
+         Keyboard[sc_Delete] = 0;
+         IN_ClearKeyboardQueue ();
+         break;
+
+      case 0x4c:  // Keypad 5
+      case sc_UpArrow:
+      case sc_DownArrow:
+      case sc_PgUp:
+      case sc_PgDn:
+      case sc_Insert:
+         lastkey = key_None;
+         break;
+      }
+
+//      if (GameEscaped==true)
+//         PauseLoop ();
+
+      if (lastkey)
+      {
+         len = strlen (s);
+         USL_MeasureString (s, &w, &h, CurrentFont);
+
+         if
+         (
+            isprint(lastkey)
+         && (len < MaxString - 1)
+         && ((!maxchars) || (len < maxchars))
+         && ((!maxwidth) || ((w+2) < (maxwidth-cursorwidth-2)))
+         )
+         {
+            int ls;
+            int rs;
+
+            for (i = len + 1;i > cursor;i--)
+               s[i] = s[i - 1];
+            s[cursor++] = lastkey;
+            redraw = true;
+
+            ls = Keyboard[sc_LShift];
+            rs = Keyboard[sc_RShift];
+            memset ((void*)Keyboard, 0, 127*sizeof(int));       // Clear printable keys
+            Keyboard[sc_LShift] = ls;
+            Keyboard[sc_RShift] = rs;
+
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+         }
+      }
+
+//      if (GameEscaped==true)
+//         PauseLoop ();
+
+      if (redraw)
+      {
+         if (color)
+            VWB_Bar (x, y, BKw, BKh, color);
+         else
+            EraseMenuBufRegion (x, y, BKw, BKh);
+
+         strcpy (olds, s);
+
+         px = x;
+         py = y;
+         if (color)
+            USL_DrawString (s);
+         else
+            DrawMenuBufPropString (px, py, s);
+         px = x;
+         py = y;
+
+         redraw = false;
+      }
+
+      if (cursormoved)
+      {
+         cursorvis = false;
+         lasttime = GetTicCount() - VBLCOUNTER;
+
+         cursormoved = false;
+      }
+      if (GetTicCount() - lasttime > VBLCOUNTER / 2)
+      {
+         lasttime = GetTicCount();
+
+         cursorvis ^= true;
+      }
+      if (cursorvis)
+         USL_XORICursor (x, y, s, cursor, color);
+
+//      if (GameEscaped==true)
+//         PauseLoop ();
+
+      if (color)
+         VW_UpdateScreen ();
+      else
+         RefreshMenuBuf (0);
+   }
+
+   if (cursorvis)
+      USL_XORICursor (x, y, s, cursor, color);
+
+   if (!result)
+   {
+      px = x;
+      py = y;
+      if (color)
+         USL_DrawString (olds);
+      else
+         DrawMenuBufPropString (px, py, olds);
+   }
+
+//   if (GameEscaped==true)
+//      PauseLoop ();
+
+   if (color)
+      VW_UpdateScreen ();
+   else
+      RefreshMenuBuf (0);
+
+   IN_ClearKeyboardQueue ();
+   return (result);
+}
+
+
+//******************************************************************************
+//
+// US_lineinput() - Gets a line of user input at (x,y), the string defaults
+//    to whatever is pointed at by def. Input is restricted to maxchars
+//    chars or maxwidth pixels wide. If the user hits escape (and escok is
+//    true), nothing is copied into buf, and false is returned. If the
+//    user hits return, the current string is copied into buf, and true is
+//    returned - PASSWORD INPUT
+//
+///******************************************************************************
+
+boolean US_lineinput (int x, int y, char *buf, const char *def, boolean escok,
+                      int maxchars, int maxwidth, int color)
+{
+   boolean  redraw,
+            cursorvis,
+            cursormoved,
+            done,
+            result;
+   char     s[MaxString],
+            xx[MaxString],
+            olds[MaxString];
+   int      i,
+            cursor,
+            w,h,
+            len;
+
+   int      lasttime;
+
+
+   int      lastkey;
+   int      cursorwidth;
+
+   cursorwidth = CurrentFont->width[80-31];
+
+   memset (s, 0, MaxString);
+   memset (xx, 0, MaxString);
+   memset (olds, 0, MaxString);
+   IN_ClearKeyboardQueue ();
+
+   BKw = maxwidth;
+   BKh = CurrentFont->height;
+
+
+   if (def)
+      strcpy (s, def);
+   else
+      *s = '\0';
+
+   *olds = '\0';
+
+   cursor      = strlen (s);
+   cursormoved = redraw = true;
+   cursorvis   = done   = false;
+
+   lasttime  = GetTicCount();
+
+
+   lastkey = getASCII ();
+
+   while (!done)
+   {
+//      if (GameEscaped == true)
+//         PauseLoop ();
+
+      IN_PumpEvents();
+      
+      if (cursorvis)
+         USL_XORICursor (x, y, xx, cursor, color);
+
+      LastScan = IN_InputUpdateKeyboard ();
+      if (Keyboard[sc_LShift] || Keyboard[sc_RShift])
+         lastkey = ShiftNames[LastScan];
+      else
+         lastkey = ASCIINames[LastScan];
+
+
+      switch (LastScan)
+      {
+      case sc_LeftArrow:
+
+         if (cursor)
+            {
+            cursor--;
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            }
+         lastkey = key_None;
+         Keyboard[sc_LeftArrow] = 0;
+         break;
+
+      case sc_RightArrow:
+
+         if (s[cursor])
+            {
+            cursor++;
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            }
+         lastkey = key_None;
+         Keyboard[sc_RightArrow] = 0;
+         break;
+
+      case sc_Home:
+
+         if ( cursor != 0 )
+            {
+            cursor = 0;
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            }
+         Keyboard[sc_Home] = 0;
+         lastkey = key_None;
+         break;
+
+      case sc_End:
+
+         if ( cursor != (int)strlen( s ) )
+            {
+            cursor = strlen (s);
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            }
+         lastkey = key_None;
+         Keyboard[sc_End] = 0;
+         break;
+
+      case sc_Return:
+         strcpy (buf,s);
+         done = true;
+         result = true;
+         lastkey = key_None;
+         MN_PlayMenuSnd (SD_SELECTSND);
+         break;
+
+      case sc_Escape:
+         if (escok)
+         {
+            done = true;
+            result = false;
+            MN_PlayMenuSnd (SD_ESCPRESSEDSND);
+         }
+         lastkey = key_None;
+         break;
+
+      case sc_BackSpace:
+
+         if (cursor)
+            {
+            strcpy (s + cursor - 1,s + cursor);
+            strcpy (xx + cursor - 1,xx + cursor);
+            cursor--;
+            redraw = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            cursormoved = true;
+            }
+         lastkey = key_None;
+         Keyboard[sc_BackSpace] = 0;
+         IN_ClearKeyboardQueue ();
+         break;
+
+      case sc_Delete:
+
+         if (s[cursor])
+            {
+            strcpy (s + cursor,s + cursor + 1);
+            strcpy (xx + cursor,xx + cursor + 1);
+            redraw = true;
+            cursormoved = true;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+            }
+         lastkey = key_None;
+         Keyboard[sc_Delete] = 0;
+         IN_ClearKeyboardQueue ();
+         break;
+
+      case 0x4c:  // Keypad 5
+      case sc_UpArrow:
+      case sc_DownArrow:
+      case sc_PgUp:
+      case sc_PgDn:
+      case sc_Insert:
+         lastkey = key_None;
+         break;
+      }
+
+//      if (GameEscaped==true)
+//         PauseLoop ();
+
+      if (lastkey)
+      {
+         len = strlen (s);
+         USL_MeasureString (xx, &w, &h, CurrentFont);
+
+         if
+         (
+            isprint(lastkey)
+         && (len < MaxString - 1)
+         && ((!maxchars) || (len < maxchars))
+         && ((!maxwidth) || ((w+2) < (maxwidth-cursorwidth-2)))
+         )
+         {
+            int ls;
+            int rs;
+
+            for (i = len + 1;i > cursor;i--)
+               s[i] = s[i - 1];
+            s[cursor]   = lastkey;
+            xx[cursor++] = '*';
+            redraw = true;
+
+            ls = Keyboard[sc_LShift];
+            rs = Keyboard[sc_RShift];
+            memset ((void*)Keyboard, 0, 127*sizeof(int));       // Clear printable keys
+            Keyboard[sc_LShift] = ls;
+            Keyboard[sc_RShift] = rs;
+            MN_PlayMenuSnd (SD_MOVECURSORSND);
+         }
+      }
+
+//      if (GameEscaped==true)
+//         PauseLoop ();
+
+      if (redraw)
+      {
+         if (color)
+            VWB_Bar (x, y, BKw, BKh, color);
+         else
+            EraseMenuBufRegion (x, y, BKw, BKh);
+
+         strcpy (olds, s);
+
+         px = x;
+         py = y;
+         if (color)
+            USL_DrawString (xx);
+         else
+            DrawMenuBufPropString (px, py, xx);
+         px = x;
+         py = y;
+
+         redraw = false;
+      }
+
+      if (cursormoved)
+      {
+         cursorvis = false;
+         lasttime = GetTicCount() - VBLCOUNTER;
+
+         cursormoved = false;
+      }
+      if (GetTicCount() - lasttime > VBLCOUNTER / 2)
+      {
+         lasttime = GetTicCount();
+
+         cursorvis ^= true;
+      }
+      if (cursorvis)
+         USL_XORICursor (x, y, xx, cursor, color);
+
+      if (color)
+         VW_UpdateScreen ();
+      else
+         RefreshMenuBuf (0);
+   }
+
+   if (cursorvis)
+      USL_XORICursor (x, y, xx, cursor, color);
+
+   if (!result)
+   {
+      px = x;
+      py = y;
+      if (color)
+         USL_DrawString (xx);
+      else
+         DrawMenuBufPropString (px, py, xx);
+   }
+
+//   if (GameEscaped==true)
+//      PauseLoop ();
+
+   if (color)
+      VW_UpdateScreen ();
+   else
+      RefreshMenuBuf (0);
+
+   IN_ClearKeyboardQueue ();
+   return (result);
+}
+
+
+
+//******************************************************************************
+//******************************************************************************
+//
+// WINDOWING ROUTINES
+//
+//******************************************************************************
+//******************************************************************************
+
+
+//******************************************************************************
+//
+// US_ClearWindow() - Clears the current window to white and homes the
+//    cursor
+//
+//******************************************************************************
+
+void US_ClearWindow (void)
+{
+   VWB_Bar (WindowX, WindowY, WindowW, WindowH, 13);
+   PrintX = WindowX;
+   PrintY = WindowY;
+}
+
+
+
+
+//******************************************************************************
+//
+// US_DrawWindow() - Draws a frame and sets the current window parms
+//
+//******************************************************************************
+
+void US_DrawWindow (int x, int y, int w, int h)
+{
+   int  i,
+        sx,
+        sy,
+        sw,
+        sh;
+   byte * shape;
+
+   pic_t *Win1;
+   pic_t *Win2;
+   pic_t *Win3;
+   pic_t *Win4;
+   pic_t *Win5;
+   pic_t *Win6;
+   pic_t *Win7;
+   pic_t *Win8;
+   pic_t *Win9;
+
+	// Cache in windowing shapes
+	shape = W_CacheLumpNum (W_GetNumForName ("window1"), PU_CACHE, Cvt_pic_t, 1);
+	Win1 = (pic_t *) shape;
+	shape = W_CacheLumpNum (W_GetNumForName ("window2"), PU_CACHE, Cvt_pic_t, 1);
+	Win2 = (pic_t *) shape;
+	shape = W_CacheLumpNum (W_GetNumForName ("window3"), PU_CACHE, Cvt_pic_t, 1);
+	Win3 = (pic_t *) shape;
+	shape = W_CacheLumpNum (W_GetNumForName ("window4"), PU_CACHE, Cvt_pic_t, 1);
+	Win4 = (pic_t *) shape;
+	shape = W_CacheLumpNum (W_GetNumForName ("window5"), PU_CACHE, Cvt_pic_t, 1);
+	Win5 = (pic_t *) shape;
+	shape = W_CacheLumpNum (W_GetNumForName ("window6"), PU_CACHE, Cvt_pic_t, 1);
+	Win6 = (pic_t *) shape;
+	shape = W_CacheLumpNum (W_GetNumForName ("window7"), PU_CACHE, Cvt_pic_t, 1);
+	Win7 = (pic_t *) shape;
+	shape = W_CacheLumpNum (W_GetNumForName ("window8"), PU_CACHE, Cvt_pic_t, 1);
+	Win8 = (pic_t *) shape;
+	shape = W_CacheLumpNum (W_GetNumForName ("window9"), PU_CACHE, Cvt_pic_t, 1);
+	Win9 = (pic_t *) shape;
+
+   WindowX = x * 8;
+   WindowY = y * 8;
+   WindowW = w * 8;
+   WindowH = h * 8;
+
+   PrintX = WindowX;
+   PrintY = WindowY;
+
+   sx = (x - 1) * 8;
+   sy = (y - 1) * 8;
+   sw = (w + 1) * 8;
+   sh = (h + 1) * 8;
+
+   US_ClearWindow ();
+
+
+   VWB_DrawPic (sx, sy, Win1);
+
+   VWB_DrawPic (sx, sy + sh, Win7);
+
+   for (i = sx + 8;i <= sx + sw - 8; i += 8)
+   {
+      VWB_DrawPic (i, sy, Win2);
+      VWB_DrawPic (i, sy + sh, Win8);
+   }
+
+   VWB_DrawPic (i, sy, Win3);
+   VWB_DrawPic (i, sy + sh, Win9);
+
+   for (i = sy + 8;i <= sy + sh - 8; i += 8)
+   {
+      VWB_DrawPic (sx, i, Win4);
+      VWB_DrawPic (sx + sw, i, Win6);
+   }
+}
+
+
+
+//******************************************************************************
+//
+// US_CenterWindow() - Generates a window of a given width & height in the
+//    middle of the screen
+//
+//******************************************************************************
+
+void US_CenterWindow (int w, int h)
+{
+   //HDG US_DrawWindow (((MaxX / 8) - w) / 2,  ((MaxY / 8) - h) / 2, w, h);
+   US_DrawWindow (((iGLOBAL_SCREENWIDTH / 8) - w) / 2,((iGLOBAL_SCREENHEIGHT / 8) - h) / 2, w, h);
+}
+
+
+
+//==============================================================================
+//
+// Intensity Font stuff
+//
+// TEXT FORMATTING COMMANDS - (Use EGA colors ONLY!)
+// -------------------------------------------------
+// /<hex digit> - Change the following word to <hex digit> color
+// `            - Highlights the following word with lighter color of fontcolor
+// /N<hex digit> - Change the fontcolor to a certain color
+//
+//==============================================================================
+
+//******************************************************************************
+//
+// GetIntensityColor ()
+//
+//******************************************************************************
+
+byte GetIntensityColor (byte pix)
+{
+   if ((fontcolor<0) || (fontcolor>255))
+      Error("Intensity Color out of range\n");
+   return ((byte) intensitytable[(pix<<8)+fontcolor]);
+}
+
+
+//******************************************************************************
+//
+// DrawIntensityChar ()
+//
+// Draws an intensity character at px, py
+//
+//******************************************************************************
+
+void DrawIntensityChar  ( char ch )
+   {
+
+   byte  pix;
+   int   px1,py1;
+   int   width,w1;
+   int   height,h1;
+   int   ht;
+   byte  *source,*src1;
+   byte  *dest;
+   byte  *origdest,*orgdst1;
+   int   mask;
+
+   px1 = px;py1 = py;
+
+   ht = IFont->height;
+
+   origdest = ( byte * )( bufferofs + ylookup[ py ] + px );
+
+   dest = origdest;
+
+   ch -= 31;
+   width = IFont->width[ (unsigned char)ch ];
+   source = ( ( byte * )IFont ) + IFont->charofs[ (unsigned char)ch ];
+
+   mask = 1 << ( px & 3 );
+
+   if ((iGLOBAL_SCREENWIDTH <= 320)||(StretchScreen == true)){
+	   while( width-- )
+	   {
+		  VGAMAPMASK( mask );
+
+		  height = ht;
+		  while( height-- )
+			 {
+			 pix = *source;
+			 if ( pix != 0xFE )
+				{
+				*dest = GetIntensityColor( pix );
+				}
+
+			 source++;
+			 dest += linewidth;
+			 }
+
+		  px++;
+		  origdest++;
+		  dest = origdest;
+	   }
+	}else{//strech letter in x any direction
+	   w1 = width;
+	   h1 = ht;
+	   orgdst1 = origdest;
+	   src1 = source;
+	   while( width-- )
+	   {
+		  VGAMAPMASK( mask );
+
+		  height = ht;
+		  while( height-- )
+			 {
+			 pix = *source;
+			 if ( pix != 0xFE )
+				{
+				*dest = GetIntensityColor( pix );
+				*(dest+iGLOBAL_SCREENWIDTH) = GetIntensityColor( pix );
+
+				*(dest+1) = GetIntensityColor( pix );
+				*(dest+1+iGLOBAL_SCREENWIDTH) = GetIntensityColor( pix );
+				}
+
+			 source++;
+			 dest += linewidth*2;
+			 }
+
+		  px++;px++;
+		  origdest++;origdest++;
+		  dest = origdest;
+	   }
+
+	}
+
+}
+
+
+//******************************************************************************
+//
+// GetColor ()
+//
+//******************************************************************************
+
+int GetColor (int num)
+{
+   int returnval;
+
+   if ((num >= '0') && (num <= '9'))
+      returnval = egacolor[num - '0'];
+   else
+      if ((num >= 'A') && (num <= 'F'))
+         returnval = egacolor[((num - 'A') + 10)];
+
+   return (returnval);
+}
+
+//******************************************************************************
+//
+// DrawIString ()
+//
+//******************************************************************************
+
+static int oldfontcolor = 0;
+static boolean highlight = false;
+
+void DrawIString (unsigned short int x, unsigned short int y, const char *string, int flags)
+{
+   char ch;
+   char temp;
+
+   px = x;
+   py = y;
+
+   while ((ch = *string++) != 0)
+   {
+      if ( !PERMANENT_MSG( flags ) )
+      {
+         // Highlighting is done only for 1 word - if we get a "space"
+         //  and highlight is on ...., reset variables.
+         //
+         if ((ch == ' ') && (highlight == true))
+         {
+            highlight = false;
+            fontcolor = oldfontcolor;
+            DrawIntensityChar (ch);
+         }
+         else
+            // '\\' is color change to a specific EGA color (ie. egacolor)
+            //
+            if (ch == '\\')
+            {
+               temp = *string++;
+               temp = toupper (temp);
+
+               // Force fontcolor to a specific color egacolor[ RED ];
+               if (temp == 'N')
+               {
+                  temp         = *string++;
+                  fontcolor    = GetColor (temp);
+                  oldfontcolor = fontcolor;
+               }
+			   //bna added
+               else if (temp == 'X')
+               {
+				  temp         = *string;
+                  fontcolor    = egacolor[ RED ];
+                  oldfontcolor = fontcolor;
+               }
+               else if (temp == 'Y')
+               {
+				   temp         = *string;
+                  fontcolor    = egacolor[ YELLOW ];
+                  oldfontcolor = fontcolor;
+               }
+               else if (temp == 'Z')
+               {
+				   temp         = *string;
+                  fontcolor    = egacolor[ GREEN ];
+                  oldfontcolor = fontcolor;
+               }
+			   //bna added end
+               // Restore fontcolor to a previous color
+               else if (temp == 'O')
+               {
+                  fontcolor    = oldfontcolor;
+               }
+               else
+               {
+                  oldfontcolor = fontcolor;           // save off old font color
+                  highlight    = true;                // set highlight
+                  fontcolor    = GetColor (temp);
+               }
+            }
+            else
+               // '`' is highlight the current fontcolor
+               //
+               if (ch == '`')
+               {
+                  oldfontcolor = fontcolor;        // save off old font color
+                  highlight    = true;             // set highlight
+                  if (fontcolor < 8)               // only highlight the
+                     fontcolor    = fontcolor-10;  //  lower colors
+               }
+               else
+                  DrawIntensityChar (ch);
+      }
+      else
+         DrawIntensityChar (ch);
+   }
+
+   if (highlight == true)
+   {
+      highlight = false;
+      fontcolor = oldfontcolor;
+   }
+}
+
+
+//******************************************************************************
+//
+// DrawIntensityString ()
+//
+//******************************************************************************
+
+void DrawIntensityString (unsigned short int x, unsigned short int y, const char *string, int color)
+{
+   char ch;
+
+   px = x;
+   py = y;
+
+   fontcolor=color;
+
+   while ((ch = *string++) != 0)
+      {
+      DrawIntensityChar (ch);
+      }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+static unsigned short disp_offset = 160 * 24;
+
+void DrawRottText
+   (
+   int x,
+   int y,
+   int ch,
+   int foreground,
+   int background
+   )
+
+   {
+   char *vid;
+
+   vid  = ( char * )( 0xb0000 );
+   vid += y * 160;
+   vid += x * 2;
+
+   if ( ch != NONE )
+      {
+      *vid = ch;
+      }
+   vid++;
+   *vid = ( ( background & 0x0f ) << 4 ) | ( foreground & 0x0f );
+   }
+
+void TextBox
+   (
+   int  x1,
+   int  y1,
+   int  x2,
+   int  y2,
+   int ch,
+   int  foreground,
+   int  background
+   )
+
+   {
+   int x;
+   int y;
+
+   for( x = x1; x <= x2; x++ )
+      {
+      for( y = y1; y <= y2; y++ )
+         {
+         DrawRottText( x, y, ch, foreground, background );
+         }
+      }
+   }
+
+void TextFrame
+   (
+   int x1,
+   int y1,
+   int x2,
+   int y2,
+   int type,
+   int foreground,
+   int background
+   )
+
+   {
+   int x;
+   int y;
+
+   if ( type == 0 )
+      {
+      for( x = x1 + 1; x < x2; x++ )
+         {
+         DrawRottText( x, y1, type, foreground, background );
+         DrawRottText( x, y2, type, foreground, background );
+         }
+      for( y = y1 + 1; y < y2; y++ )
+         {
+         DrawRottText( x1, y, type, foreground, background );
+         DrawRottText( x2, y, type, foreground, background );
+         }
+      }
+   if ( type == SINGLE_FRAME )
+      {
+      DrawRottText( x1, y1, 'Ú', foreground, background );
+      DrawRottText( x2, y1, '¿', foreground, background );
+      DrawRottText( x1, y2, 'À', foreground, background );
+      DrawRottText( x2, y2, 'Ù', foreground, background );
+      for( x = x1 + 1; x < x2; x++ )
+         {
+         DrawRottText( x, y1, 'Ä', foreground, background );
+         DrawRottText( x, y2, 'Ä', foreground, background );
+         }
+      for( y = y1 + 1; y < y2; y++ )
+         {
+         DrawRottText( x1, y, '³', foreground, background );
+         DrawRottText( x2, y, '³', foreground, background );
+         }
+      }
+   if ( type == DOUBLE_FRAME )
+      {
+      DrawRottText( x1, y1, 'É', foreground, background );
+      DrawRottText( x2, y1, '»', foreground, background );
+      DrawRottText( x1, y2, 'È', foreground, background );
+      DrawRottText( x2, y2, '¼', foreground, background );
+      for( x = x1 + 1; x < x2; x++ )
+         {
+         DrawRottText( x, y1, 'Í', foreground, background );
+         DrawRottText( x, y2, 'Í', foreground, background );
+         }
+      for( y = y1 + 1; y < y2; y++ )
+         {
+         DrawRottText( x1, y, 'º', foreground, background );
+         DrawRottText( x2, y, 'º', foreground, background );
+         }
+      }
+   }
+
+void mysetxy
+   (
+   int x,
+   int y
+   )
+
+   {
+   disp_offset = ( x * 2 ) + ( y * 160 );
+   }
+
+void myputch
+   (
+   char ch
+   )
+
+   {
+   int j;
+   char *disp_start = (char *)( 0xb0000 );
+
+   if ( disp_offset >= 160 * 24 )
+      {
+      for ( j = 160; j < 160 * 24; j += 2 )
+         {
+         *( disp_start + j - 160 ) = *( disp_start + j );
+         }
+
+      disp_offset = 160 * 23;
+
+      for ( j = disp_offset; j < ( 160 * 24 ); j += 2 )
+         {
+         *( disp_start + j ) = ' ';
+         }
+      }
+
+   if ( ch >= 32 )
+      {
+      *( disp_start + disp_offset ) = ch;
+      disp_offset = disp_offset + 2;
+      }
+
+   if ( ch == '\r' )
+      {
+      disp_offset = disp_offset / 160;
+      disp_offset = disp_offset * 160;
+      }
+
+   if ( ch == '\n' )
+      {
+      disp_offset = disp_offset + 160;
+      if ( disp_offset < 160 * 24 )
+         {
+         for ( j = disp_offset; j < ( ( ( disp_offset / 160 ) + 1 ) *
+            160 ); j += 2 )
+            {
+            *( disp_start + j ) = ' ';
+            }
+         }
+      }
+   }
+
+int printstring
+   (
+   char *string
+   )
+
+   {
+   int count;
+   char *ptr;
+
+   ptr = string;
+   count = 0;
+
+   while ( *ptr )
+      {
+      myputch( *ptr );
+      count++;
+      ptr++;
+      }
+
+   return( count );
+   }
+
+
+int printnum
+   (
+   int number
+   )
+
+   {
+   char string[ 100 ];
+   int  count;
+
+   itoa( number, string, 10 );
+   count = printstring( string );
+
+   return( count );
+   }
+
+int printunsigned
+   (
+   unsigned long number,
+   int radix
+   )
+
+   {
+   char string[ 100 ];
+   int  count;
+
+   ultoa( number, string, radix );
+   count = printstring( string );
+
+   return( count );
+   }
+
+int myprintf
+   (
+   char *fmt,
+   ...
+   )
+
+   {
+   va_list argptr;
+   int     count;
+   char    *ptr;
+   if (MONOPRESENT==false)
+      {
+      Debug(fmt);
+      return 0;
+      }
+   va_start( argptr, fmt );
+   ptr = fmt;
+   count = 0;
+
+   while( *ptr != 0 )
+      {
+      if ( *ptr == '%' )
+         {
+         ptr++;
+         switch( *ptr )
+            {
+            case 0 :
+               return( EOF );
+               break;
+            case 'l' :
+               count += printnum( va_arg( argptr, int ) );
+               ptr++;
+               break;
+            case 'd' :
+               count += printnum( va_arg( argptr, int ) );
+               break;
+            case 's' :
+               count += printstring( va_arg( argptr, char * ) );
+               break;
+            case 'u' :
+               count += printunsigned( va_arg( argptr, int ), 10 );
+               break;
+            case 'x' :
+            case 'X' :
+               count += printunsigned( va_arg( argptr, int ), 16 );
+               break;
+            }
+         ptr++;
+         }
+      else
+         {
+         myputch( *ptr );
+         count++;
+         ptr++;
+         }
+      }
+
+   va_end( argptr );
+
+   return( count );
+   }

Added: tags/rott-1.1/rott/rt_str.h
===================================================================
--- tags/rott-1.1/rott/rt_str.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_str.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,125 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+// Public header for RT_STR.C.
+//
+//***************************************************************************
+
+#ifndef _rt_str_public
+#define _rt_str_public
+
+#include "lumpy.h"
+
+
+//***************************************************************************
+//
+// GLOBALS
+//
+//***************************************************************************
+
+extern int fontcolor;
+
+
+//***************************************************************************
+//
+// TYPEDEFS
+//
+//***************************************************************************
+
+typedef  struct
+{
+   int   x,y;
+} Point;
+
+typedef  struct
+{
+   int   x, y,
+         w, h,
+         px, py;
+} WindowRec;            // Record used to save & restore screen windows
+
+typedef  struct
+{
+	Point ul,lr;
+} Rect;
+
+
+//***************************************************************************
+//
+// PROTOTYPES
+//
+//***************************************************************************
+
+//
+// String rtns
+//
+
+void VW_DrawClippedString (int x, int y, const char *string);
+void US_ClippedPrint (int x, int y, const char *s);
+
+void VWB_DrawPropString  (const char *string);
+void VW_MeasurePropString (const char *string, int *width, int *height);
+
+void US_MeasureStr (int *width, int *height, const char * s, ...) __attribute__((format(printf,3,4)));
+
+void VW_DrawPropString (const char *string);
+
+void US_SetPrintRoutines (void (*measure)(const char *, int *, int *, font_t *),
+                          void (*print)(const char *));
+void US_Print (const char *s);
+void US_BufPrint (const char *s);
+void US_PrintUnsigned (unsigned long int n);
+void US_PrintSigned (long int n);
+void USL_PrintInCenter (const char *s, Rect r);
+void US_PrintCentered (const char *s);
+void US_CPrintLine (const char *s);
+void US_CPrint (const char *s);
+
+
+//
+// Input rtns
+//
+
+boolean US_LineInput (int x, int y, char *buf, const char *def, boolean escok,
+                      int maxchars, int maxwidth, int color);
+boolean US_lineinput (int x, int y, char *buf, const char *def, boolean escok,
+                      int maxchars, int maxwidth, int color);
+int CalibrateJoystick(void);
+
+//
+// Window rtns
+//
+
+void US_DrawWindow (int x, int y, int w, int h);
+void US_CenterWindow (int w, int h);
+
+//
+// Intensity font rtns
+//
+
+void DrawIString (unsigned short int x, unsigned short int y, const char *string, int flags);
+void DrawIntensityString (unsigned short int x, unsigned short int y, const char *string, int color);
+void VW_MeasureIntensityPropString (const char *string, int *width, int *height);
+byte GetIntensityColor (byte pix);
+
+#include "myprint.h"
+
+#endif

Added: tags/rott-1.1/rott/rt_swift.c
===================================================================
--- tags/rott-1.1/rott/rt_swift.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_swift.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,430 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//****************************************************************************
+//
+// RT_SWIFT.C
+//
+// SWIFT services module - for CYBERMAN use in ROTT.
+//
+//****************************************************************************
+
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef DOS
+#include <dos.h>
+#endif
+
+#include "rt_def.h"
+#include "rt_swift.h"
+#include "_rt_swft.h"
+//MED
+#include "memcheck.h"
+
+
+#ifdef DOS
+
+//****************************************************************************
+//
+// SWIFT_Initialize ()
+//
+// Test for presence of SWIFT extensions and SWIFT device.
+// Returns 1 (TRUE) if SWIFT features are available, 0 otherwise.
+// Remember to call SWIFT_Terminate() if SWIFT_Initialize succeeds!
+//
+//****************************************************************************
+
+int SWIFT_Initialize (void)
+{
+   SWIFT_StaticData sdBuf;
+   int fSwift = 0;
+
+   if (fActive)                     // SWIFT extensions already active
+   {
+#ifdef DEGUB
+      SoftError( "SWIFT_Initialize: Already active.\n");
+      SoftError( "SWIFT_Initialize: returns TRUE\n");
+#endif
+      return (1);
+   }
+
+   nAttached = SWIFT_DEV_NONE;
+
+
+   if (_dos_getvect(0x33) == NULL)  // No mouse driver loaded
+   {
+#ifdef DBUG
+      SoftError( "SWIFT_Initialize: No mouse driver loaded.\n");
+      SoftError( "SWIFT_Initialize: returns FALSE\n");
+#endif
+      return (0);
+   }
+
+
+   // Reset the mouse and driver
+   AX (regs) = 0;
+   int386( 0x33, &regs, &regs);
+
+   if (AX (regs) == 0)
+   {                                // no mouse
+#ifdef DBUG
+      SoftError( "SWIFT_Initialize: No pointing device attached.\n");
+      SoftError( "SWIFT_Initialize: returns FALSE\n");
+#endif
+      return (0);
+   }
+
+#ifdef DBUG
+   AX (regs) = 36;   // Get Mouse Information
+   BX (regs) = 0xffff;
+   CX (regs) = 0xffff;
+   DX (regs) = 0xffff;
+   int386 (0x33, &regs, &regs);
+   SoftError( "SWIFT_Initialize: driver version %d.%02d\n", regs.h.bh, regs.h.bl);
+   SoftError( "SWIFT_Initialize: %s mouse using IRQ %d\n",
+          (regs.h.ch==1) ? "bus" :
+          (regs.h.ch==2) ? "serial" :
+          (regs.h.ch==3) ? "inport" :
+          (regs.h.ch==4) ? "PS/2" :
+                           "unknown", regs.h.cl);
+#endif
+
+
+   // allocate a DOS real-mode buffer
+   pdosmem = allocDOS(DOSMEMSIZE, &segment, &selector);
+   if (!pdosmem)
+   {
+#ifdef DBUG
+      SoftError( "SWIFT_Initialize: DOS Alloc failed!\n");
+      SoftError( "SWIFT_Initialize: returns FALSE\n");
+#endif
+      return (0);
+   }
+
+//
+// SWIFT device supported and attached
+//
+   if (SWIFT_GetStaticDeviceInfo (&sdBuf))
+      fSwift = 1;
+
+
+   if (!fSwift)
+   {  // SWIFT functions not present
+#ifdef DBUG
+      SoftError( "SWIFT_Initialize: no SWIFT support in mouse driver.\n");
+#endif
+   }
+   else
+      if (sdBuf.deviceType == SWIFT_DEV_NONE)
+      {
+#ifdef DBUG
+         SoftError( "SWIFT_Initialize: no SWIFT device connected.\n");
+#endif
+      }
+      else
+      {
+         nAttached = sdBuf.deviceType;
+#ifdef DBUG
+         SoftError( "SWIFT_Initialize: ");
+
+         switch (nAttached)
+         {
+            case SWIFT_DEV_CYBERMAN:
+               SoftError( "CyberMan %d.%02d connected.\n",
+                                sdBuf.majorVersion, sdBuf.minorVersion);
+            break;
+
+            default:
+               SoftError( "Unknown SWIFT device (type %d) connected.\n",
+                                nAttached);
+            break;
+         }
+#endif
+      fActive = 1;
+   }
+
+   if (!fActive)
+   {                    // activation of SWIFT module failed for some reason
+      if (pdosmem)
+      {                 // if DOS buffer was allocated, free it
+         freeDOS(selector);
+         pdosmem = 0;
+      }
+   }
+
+#ifdef DBUG
+   SoftError( "SWIFT_Initialize: returns %s.\n", (fActive ? "TRUE" : "FALSE"));
+#endif
+   return fActive;
+}
+
+
+
+//****************************************************************************
+//
+// SWIFT_Terminate ()
+//
+// Free resources required for SWIFT support.  If SWIFT_Initialize has
+// not been called, or returned FALSE, this function does nothing.
+// SWIFT_Terminate should always be called at some time after a call to
+// SWIFT_Initialize has returned TRUE.
+//
+//****************************************************************************
+
+void SWIFT_Terminate (void)
+{
+#ifdef DBUG
+   SoftError( "SWIFT_Terminate called.\n");
+#endif
+
+   if (fActive)
+   {
+     // free DOS buffer
+      if (pdosmem)
+      {
+         freeDOS(selector);
+         pdosmem = 0;
+      }
+
+      fActive = 0;
+   }
+}
+
+
+//****************************************************************************
+//
+// SWIFT_GetAttachedDevice ()
+//
+// Returns the device-type code for the attached SWIFT device, if any.
+//
+//****************************************************************************
+
+int SWIFT_GetAttachedDevice (void)
+{
+   return (nAttached);
+}
+
+
+
+//****************************************************************************
+//
+// SWIFT_GetStaticDeviceInfo ()
+//
+// Reads static device data.
+//
+//****************************************************************************
+
+int SWIFT_GetStaticDeviceInfo (SWIFT_StaticData far *psd)
+{
+   memset (&RMI, 0, sizeof (RMI));
+   RMI.ax = 0x53C1;                       // SWIFT: Get Static Device Data
+   RMI.es = segment;                      // DOS buffer real-mode segment
+   RMI.dx = 0;                            //  "    "      "   "   offset
+   MouseInt (&RMI);                       // get data into DOS buffer
+
+   *psd = *(SWIFT_StaticData *)pdosmem;   // then copy into caller's buffer
+   return (RMI.ax == 1);                  // return success
+}
+
+
+
+//****************************************************************************
+//
+// SWIFT_Get3DStatus ()
+//
+// Read the current input state of the device.
+//
+//****************************************************************************
+
+
+void SWIFT_Get3DStatus (SWIFT_3DStatus far *pstat)
+{
+#ifdef DBUG
+   if (!fActive)
+   {
+      SoftError( "SWIFT_Get3DStatus: SWIFT module not active!\n");
+   }
+#endif
+
+   memset (&RMI, 0, sizeof (RMI));
+   RMI.ax = 0x5301;
+   RMI.es = segment;
+   RMI.dx = 0;
+   MouseInt(&RMI);
+   *pstat = *(SWIFT_3DStatus *)pdosmem;
+}
+
+
+
+
+//****************************************************************************
+//
+// SWIFT_TactileFeedback ()
+//
+// Generates tactile feedback to user.
+// d   = duration of tactile burst, in milliseconds.
+// on  = motor on-time per cycle, in milliseconds.
+// off = motor off-time per cycle, in milliseconds.
+//
+//****************************************************************************
+
+void SWIFT_TactileFeedback (int d, int on, int off)
+{
+  // Use DPMI call 300h to issue mouse interrupt
+   memset (&RMI, 0, sizeof(RMI));
+   RMI.ax = 0x5330;                    // SWIFT: Get Position & Buttons
+   RMI.bx = (on / 5) << 8 + (off / 5);
+   RMI.cx = d / 40;
+   MouseInt (&RMI);
+
+#ifdef DBUG
+   SoftError( "SWIFT_TactileFeedback (dur=%d ms, on=%d ms, off=%d ms)\n",
+                   d / 40 * 40, on/5*5, off/5*5);
+#endif
+}
+
+
+
+//****************************************************************************
+//
+// SWIFT_GetDynamicDeviceData ()
+//
+// Returns Dynamic Device Data word - see SDD_* above
+//
+//****************************************************************************
+
+unsigned SWIFT_GetDynamicDeviceData (void)
+{
+   memset (&RMI, 0, sizeof(RMI));
+   RMI.ax = 0x53C2;                       // SWIFT: Get Dynamic Device Data
+   MouseInt (&RMI);
+   return ((unsigned)RMI.ax);
+}
+
+
+//****************************************************************************
+//
+// MouseInt ()
+//
+// Generate a call to the mouse driver (interrupt 33h) in real mode,
+// using the DPMI function 'Simulate Real-Mode Interrupt'.
+//
+//****************************************************************************
+
+void MouseInt (struct rminfo *prmi)
+{
+   memset (&sregs, 0, sizeof (sregs));
+   AX (regs) = 0x0300;                    // DPMI: simulate interrupt
+   BX (regs) = MOUSE_INT;
+   CX (regs) = 0;
+   DI (regs) = FP_OFF (prmi);
+   sregs.es = FP_SEG (prmi);
+   int386x( DPMI_INT, &regs, &regs, &sregs );
+}
+
+
+//****************************************************************************
+//
+// freeDOS ()
+//
+// Release real-mode DOS memory block via DPMI
+//
+//****************************************************************************
+
+void freeDOS (short sel)
+{
+   AX(regs) = 0x0101;      // DPMI free DOS memory
+   DX(regs) = sel;
+
+   int386( DPMI_INT, &regs, &regs);
+}
+
+
+//****************************************************************************
+//
+// allocDOS ()
+//
+// Allocate a real-mode DOS memory block via DPMI
+//
+//****************************************************************************
+
+void far *allocDOS (unsigned nbytes, short *pseg, short *psel)
+{
+   unsigned npara = (nbytes + 15) / 16;
+   void far *pprot;
+   pprot = NULL;
+   *pseg = 0;        // assume will fail
+   *psel = 0;
+
+   // DPMI call 100h allocates DOS memory
+   segread (&sregs);
+   AX (regs) = 0x0100;        // DPMI: Allocate DOS Memory
+   BX (regs) = npara;         // number of paragraphs to alloc
+   int386( DPMI_INT, &regs, &regs);
+
+   if (regs.w.cflag == 0)
+   {
+      *pseg = AX (regs);      // the real-mode segment
+      *psel = DX (regs);      // equivalent protected-mode selector
+      // pprot is the protected mode address of the same allocated block.
+      // The Rational extender maps the 1 MB physical DOS memory into
+      // the bottom of our virtual address space.
+      pprot = (void far *) ((unsigned)*pseg << 4);
+   }
+   return pprot;
+}
+
+#else
+
+/* This isn't of much use in Linux. */
+
+int SWIFT_Initialize (void)
+{
+	STUB_FUNCTION;
+	
+	return 0;
+}
+
+void SWIFT_Terminate (void)
+{
+	STUB_FUNCTION;
+}
+
+void SWIFT_Get3DStatus (SWIFT_3DStatus far *pstat)
+{
+	STUB_FUNCTION;
+}
+
+void SWIFT_TactileFeedback (int d, int on, int off)
+{
+	STUB_FUNCTION;
+}
+
+unsigned SWIFT_GetDynamicDeviceData (void)
+{
+	STUB_FUNCTION;
+	
+	return 0;
+}
+
+#endif

Added: tags/rott-1.1/rott/rt_swift.h
===================================================================
--- tags/rott-1.1/rott/rt_swift.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_swift.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,81 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_swift_public
+#define _rt_swift_public
+
+//***************************************************************************
+//
+// Public header for RT_SWIFT.C.
+//
+//***************************************************************************
+
+#include "rt_playr.h"
+
+//***************************************************************************
+//
+// PROTOTYPES
+//
+//***************************************************************************
+
+int SWIFT_Initialize (void);
+//
+// Test for presence of SWIFT extensions and SWIFT device
+// Returns 1 (TRUE) if SWIFT features are available, 0 otherwise.
+// Remember to call SWIFT_Terminate() if SWIFT_Initialize succeeds!
+//
+
+void SWIFT_Terminate (void);
+//
+// Free resources required for SWIFT support.  If SWIFT_Initialize has
+// not been called, or returned FALSE, this function does nothing.
+// SWIFT_Terminate should always be called at some time after a call to
+// SWIFT_Initialize has returned TRUE.
+//
+
+int SWIFT_GetAttachedDevice (void);
+//
+// Returns the device-type code for the attached SWIFT device, if any.
+//
+
+int SWIFT_GetStaticDeviceInfo (SWIFT_StaticData far *psd);
+//
+// Reads static device data.						
+//
+
+void SWIFT_Get3DStatus (SWIFT_3DStatus far *pstat);
+//
+// Read the current input state of the device.				
+//
+
+void SWIFT_TactileFeedback (int d, int on, int off);
+//
+// Generates tactile feedback to user.					
+// d   = duration of tactile burst, in milliseconds.			
+// on  = motor on-time per cycle, in milliseconds.			
+// off = motor off-time per cycle, in milliseconds.			
+//
+
+unsigned SWIFT_GetDynamicDeviceData (void);
+//
+// Returns Dynamic Device Data word - see SDD_* above			
+//
+
+
+#endif

Added: tags/rott-1.1/rott/rt_table.h
===================================================================
--- tags/rott-1.1/rott/rt_table.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_table.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1331 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_table_public
+#define _rt_table_public
+
+#include "states.h"
+
+statetype * statetable[MAXSTATES]=
+		{
+&s_lowgrdstand	   ,
+&s_lowgrdpath4 	,
+&s_lowgrdpath3 	,
+&s_lowgrdpath2 	,
+&s_lowgrdpath1 	,
+&s_lowgrdcollide  ,
+&s_lowgrdcollide2 ,
+&s_lowgrdshoot4 	,
+&s_lowgrdshoot3 	,
+&s_lowgrdshoot2 	,
+&s_lowgrdshoot1 	,
+&s_lowgrdchase4 	,
+&s_lowgrdchase3 	,
+&s_lowgrdchase2 	,
+&s_lowgrdchase1 	,
+&s_lowgrddead		,
+&s_lowgrddie4		,
+&s_lowgrddie3		,
+&s_lowgrddie2		,
+&s_lowgrddie1		,
+&s_lowgrdcrushed2		,
+&s_lowgrdcrushed1		,
+&s_sneakydown     ,
+&s_sneakyrise4    ,
+&s_sneakyrise3    ,
+&s_sneakyrise2    ,
+&s_sneakyrise1    ,
+&s_highgrdstand	,
+&s_highgrdpath4 	,
+&s_highgrdpath3 	,
+&s_highgrdpath2 	,
+&s_highgrdpath1 	,
+&s_highgrdcollide  ,
+&s_highgrdcollide2 ,
+&s_highgrdshoot4  ,
+&s_highgrdshoot3  ,
+&s_highgrdshoot2 	,
+&s_highgrdshoot1 	,
+&s_highgrdchase4 	,
+&s_highgrdchase3 	,
+&s_highgrdchase2 	,
+&s_highgrdchase1 	,
+&s_highgrddead		,
+&s_highgrddie5		,
+&s_highgrddie4		,
+&s_highgrddie3		,
+&s_highgrddie2		,
+&s_highgrddie1		,
+&s_highgrdcrushed2		,
+&s_highgrdcrushed1		,
+&s_strikestand	,
+&s_strikepath4 	,
+&s_strikepath3 	,
+&s_strikepath2 	,
+&s_strikepath1 	,
+&s_strikecollide  ,
+&s_strikecollide2 ,
+&s_strikeshoot4 	,
+&s_strikeshoot3 	,
+&s_strikeshoot2 	,
+&s_strikeshoot1 	,
+&s_strikewait      ,
+&s_strikerollright6    ,
+&s_strikerollright5    ,
+&s_strikerollright4    ,
+&s_strikerollright3    ,
+&s_strikerollright2    ,
+&s_strikerollright1    ,
+&s_strikerollleft6    ,
+&s_strikerollleft5    ,
+&s_strikerollleft4    ,
+&s_strikerollleft3    ,
+&s_strikerollleft2    ,
+&s_strikerollleft1    ,
+&s_strikechase4 	,
+&s_strikechase3 	,
+&s_strikechase2 	,
+&s_strikechase1 	,
+&s_strikedead3		,
+&s_strikedead2		,
+&s_strikedead		,
+&s_strikedie4		,
+&s_strikedie3		,
+&s_strikedie2		,
+&s_strikedie1		,
+&s_strikecrushed2		,
+&s_strikecrushed1		,
+&s_blitzstand  ,
+&s_blitzpath4 ,
+&s_blitzpath3 ,
+&s_blitzpath2 ,
+&s_blitzpath1 ,
+&s_blitzcollide  ,
+&s_blitzcollide2 ,
+&s_blitzshoot4 ,
+&s_blitzshoot3 ,
+&s_blitzshoot2 ,
+&s_blitzshoot1 ,
+&s_blitzrise4 ,
+&s_blitzrise3 ,
+&s_blitzrise2 ,
+&s_blitzrise1 ,
+&s_blitzuse    ,
+&s_blitzsteal2 ,
+&s_blitzsteal1 ,
+&s_blitzchase4 	,
+&s_blitzchase3 	,
+&s_blitzchase2 	,
+&s_blitzchase1 	,
+&s_blitzdead2		,
+&s_blitzdead		,
+&s_blitzdie4		,
+&s_blitzdie3		,
+&s_blitzdie2		,
+&s_blitzdie1		,
+&s_blitzcrushed2		,
+&s_blitzcrushed1		,
+&s_blitzplead1,
+&s_blitzplead2,
+&s_blitzplead3,
+&s_blitzplead4,
+&s_blitzplead5,
+&s_blitzplead6,
+&s_blitzplead7,
+&s_blitzplead8,
+&s_blitzplead9,
+&s_blitzplead10,
+&s_blitzplead11,
+&s_blitzaplead5,
+&s_blitzaplead4,
+&s_blitzfakedead,
+&s_blitzfakedie3,
+&s_blitzfakedie2,
+&s_blitzfakedie1,
+&s_blitzstruggledie1,
+&s_blitzstruggledead,
+&s_enforcerstand  ,
+&s_enforcerpath4 	,
+&s_enforcerpath3 	,
+&s_enforcerpath2 	,
+&s_enforcerpath1 	,
+&s_enforcerchase4 	,
+&s_enforcerchase3 	,
+&s_enforcerchase2 	,
+&s_enforcerchase1 	,
+&s_enforcercollide  ,
+&s_enforcercollide2 ,
+&s_enforcershoot4 ,
+&s_enforcershoot3 ,
+&s_enforcershoot2 ,
+&s_enforcershoot1 ,
+&s_enforcerthrow8 ,
+&s_enforcerthrow7 ,
+&s_enforcerthrow6 ,
+&s_enforcerthrow5 ,
+&s_enforcerthrow4 ,
+&s_enforcerthrow3 ,
+&s_enforcerthrow2 ,
+&s_enforcerthrow1 ,
+&s_grenade10      ,
+&s_grenade9       ,
+&s_grenade8       ,
+&s_grenade7       ,
+&s_grenade6       ,
+&s_grenade5       ,
+&s_grenade4       ,
+&s_grenade3       ,
+&s_grenade2       ,
+&s_grenade1       ,
+&s_grenade_fall6  ,
+&s_grenade_fall5  ,
+&s_grenade_fall4  ,
+&s_grenade_fall3  ,
+&s_grenade_fall2  ,
+&s_grenade_fall1  ,
+&s_grenadehit3     ,
+&s_grenadehit2     ,
+&s_grenadehit1     ,
+&s_enforcerdead		,
+&s_enforcerdie4		,
+&s_enforcerdie3		,
+&s_enforcerdie2		,
+&s_enforcerdie1		,
+&s_enforcercrushed2		,
+&s_enforcercrushed1		,
+
+
+&s_robogrdstand	,
+&s_robogrdpath1 	,
+&s_robogrdshoot1 	,
+&s_robogrdshuriken4 	,
+&s_robogrdshuriken3 	,
+&s_robogrdshuriken2 	,
+&s_robogrdshuriken1 	,
+&s_shurikenhit3    ,
+&s_shurikenhit2    ,
+&s_shurikenhit1    ,
+&s_robogrdcollide  ,
+&s_robogrdcollide2 ,
+&s_robogrddead		,
+&s_robogrddie9	   ,
+&s_robogrddie8	   ,
+&s_robogrddie7	   ,
+&s_robogrddie6	   ,
+&s_robogrddie5	   ,
+&s_robogrddie4	   ,
+&s_robogrddie3	   ,
+&s_robogrddie2	   ,
+&s_robogrddie1	   ,
+&s_roboalign,
+&s_roborealign,
+&s_robowait,
+
+&s_altexplosion10 ,
+&s_altexplosion9  ,
+&s_altexplosion8  ,
+&s_altexplosion7  ,
+&s_altexplosion6  ,
+&s_altexplosion5  ,
+&s_altexplosion4  ,
+&s_altexplosion3  ,
+&s_altexplosion2  ,
+&s_altexplosion1  ,
+
+
+&s_explosion20 ,
+&s_explosion19 ,
+&s_explosion18 ,
+&s_explosion17 ,
+&s_explosion16 ,
+&s_explosion15 ,
+&s_explosion14 ,
+&s_explosion13 ,
+&s_explosion12 ,
+&s_explosion11 ,
+&s_explosion10 ,
+&s_explosion9 ,
+&s_explosion8 ,
+&s_explosion7 ,
+&s_explosion6 ,
+&s_explosion5 ,
+&s_explosion4 ,
+&s_explosion3 ,
+&s_explosion2 ,
+&s_explosion1 ,
+&s_grexplosion20 ,
+&s_grexplosion19 ,
+&s_grexplosion18 ,
+&s_grexplosion17 ,
+&s_grexplosion16 ,
+&s_grexplosion15 ,
+&s_grexplosion14 ,
+&s_grexplosion13 ,
+&s_grexplosion12 ,
+&s_grexplosion11 ,
+&s_grexplosion10 ,
+&s_grexplosion9 ,
+&s_grexplosion8 ,
+&s_grexplosion7 ,
+&s_grexplosion6 ,
+&s_grexplosion5 ,
+&s_grexplosion4 ,
+&s_grexplosion3 ,
+&s_grexplosion2 ,
+&s_grexplosion1 ,
+
+&s_staticexplosion25 ,
+&s_staticexplosion24 ,
+&s_staticexplosion23 ,
+&s_staticexplosion22 ,
+&s_staticexplosion21 ,
+&s_staticexplosion20 ,
+&s_staticexplosion19 ,
+&s_staticexplosion18 ,
+&s_staticexplosion17 ,
+&s_staticexplosion16 ,
+&s_staticexplosion15 ,
+&s_staticexplosion14 ,
+&s_staticexplosion13 ,
+&s_staticexplosion12 ,
+&s_staticexplosion11 ,
+&s_staticexplosion10 ,
+&s_staticexplosion9 ,
+&s_staticexplosion8 ,
+&s_staticexplosion7 ,
+&s_staticexplosion6 ,
+&s_staticexplosion5 ,
+&s_staticexplosion4 ,
+&s_staticexplosion3 ,
+&s_staticexplosion2 ,
+&s_staticexplosion1 ,
+
+
+&s_upblade16 ,
+&s_upblade15 ,
+&s_upblade14 ,
+&s_upblade13 ,
+&s_upblade12 ,
+&s_upblade11 ,
+&s_upblade10 ,
+&s_upblade9 ,
+&s_upblade8 ,
+&s_upblade7 ,
+&s_upblade6 ,
+&s_upblade5 ,
+&s_upblade4 ,
+&s_upblade3 ,
+&s_upblade2 ,
+&s_upblade1 ,
+
+
+&s_firejetup23 ,
+&s_firejetup22 ,
+&s_firejetup21 ,
+&s_firejetup20 ,
+&s_firejetup19 ,
+&s_firejetup18 ,
+&s_firejetup17 ,
+&s_firejetup16 ,
+&s_firejetup15 ,
+&s_firejetup14 ,
+&s_firejetup13 ,
+&s_firejetup12 ,
+&s_firejetup11 ,
+&s_firejetup10 ,
+&s_firejetup9 ,
+&s_firejetup8 ,
+&s_firejetup7 ,
+&s_firejetup6 ,
+&s_firejetup5 ,
+&s_firejetup4 ,
+&s_firejetup3 ,
+&s_firejetup2 ,
+&s_firejetup1 ,
+
+
+&s_columndownup6 ,
+&s_columndownup5 ,
+&s_columndownup4 ,
+&s_columndownup3 ,
+&s_columndownup2 ,
+&s_columndownup1 ,
+&s_columndowndown8 ,
+&s_columndowndown7 ,
+&s_columndowndown6 ,
+&s_columndowndown5 ,
+&s_columndowndown4 ,
+&s_columndowndown3 ,
+&s_columndowndown2 ,
+&s_columndowndown1 ,
+
+
+&s_spearup16 ,
+&s_spearup15 ,
+&s_spearup14 ,
+&s_spearup13 ,
+&s_spearup12 ,
+&s_spearup11 ,
+&s_spearup10 ,
+&s_spearup9 ,
+&s_spearup8 ,
+&s_spearup7 ,
+&s_spearup6 ,
+&s_spearup5 ,
+&s_spearup4 ,
+&s_spearup3 ,
+&s_spearup2 ,
+&s_spearup1 ,
+
+&s_pushcolumn1 ,
+&s_pushcolumn2 ,
+&s_pushcolumn3 ,
+&s_wallfireball ,
+&s_crossfire2 ,
+&s_crossfire1 ,
+&s_crossdone5 ,
+&s_crossdone4 ,
+&s_crossdone3 ,
+&s_crossdone2 ,
+&s_crossdone1 ,
+&s_dust ,
+&s_gas2 ,
+&s_gas1 ,
+&s_p_bazooka1 ,
+&s_p_grenade ,
+&s_gunsmoke8 ,
+&s_gunsmoke7 ,
+&s_gunsmoke6 ,
+&s_gunsmoke5 ,
+&s_gunsmoke4 ,
+&s_gunsmoke3 ,
+&s_gunsmoke2 ,
+&s_gunsmoke1 ,
+&s_bloodspurt8 ,
+&s_bloodspurt7 ,
+&s_bloodspurt6 ,
+&s_bloodspurt5 ,
+&s_bloodspurt4 ,
+&s_bloodspurt3 ,
+&s_bloodspurt2 ,
+&s_bloodspurt1 ,
+&s_hitmetalwall4 ,
+&s_hitmetalwall3 ,
+&s_hitmetalwall2 ,
+&s_hitmetalwall1 ,
+&s_hitmetalactor4 ,
+&s_hitmetalactor3 ,
+&s_hitmetalactor2 ,
+&s_hitmetalactor1 ,
+&s_fireunit15 ,
+&s_fireunit14 ,
+&s_fireunit13 ,
+&s_fireunit12 ,
+&s_fireunit11 ,
+&s_fireunit10 ,
+&s_fireunit9 ,
+&s_fireunit8 ,
+&s_fireunit7 ,
+&s_fireunit6 ,
+&s_fireunit5 ,
+&s_fireunit4 ,
+&s_fireunit3 ,
+&s_fireunit2 ,
+&s_fireunit1 ,
+&s_skeleton48 ,
+&s_skeleton47 ,
+&s_skeleton46 ,
+&s_skeleton45 ,
+&s_skeleton44 ,
+&s_skeleton43 ,
+&s_skeleton42 ,
+&s_skeleton41 ,
+&s_skeleton40 ,
+&s_skeleton39 ,
+&s_skeleton38 ,
+&s_skeleton37 ,
+&s_skeleton36 ,
+&s_skeleton35 ,
+&s_skeleton34 ,
+&s_skeleton33 ,
+&s_skeleton32 ,
+&s_skeleton31 ,
+&s_skeleton30 ,
+&s_skeleton29 ,
+&s_skeleton28 ,
+&s_skeleton27 ,
+&s_skeleton26 ,
+&s_skeleton25 ,
+&s_skeleton24 ,
+&s_skeleton23 ,
+&s_skeleton22 ,
+&s_skeleton21 ,
+&s_skeleton20 ,
+&s_skeleton19 ,
+&s_skeleton18 ,
+&s_skeleton17 ,
+&s_skeleton16 ,
+&s_skeleton15 ,
+&s_skeleton14 ,
+&s_skeleton13 ,
+&s_skeleton12 ,
+&s_skeleton11 ,
+&s_skeleton10 ,
+&s_skeleton9 ,
+&s_skeleton8 ,
+&s_skeleton7 ,
+&s_skeleton6 ,
+&s_skeleton5 ,
+&s_skeleton4 ,
+&s_skeleton3 ,
+&s_skeleton2 ,
+&s_skeleton1 ,
+&s_spring9 ,
+&s_spring8 ,
+&s_spring7 ,
+&s_spring6 ,
+&s_spring5 ,
+&s_spring4 ,
+&s_spring3 ,
+&s_spring2 ,
+&s_spring1 ,
+&s_pgunattack1 ,
+&s_pmissattack1 ,
+&s_pgunattack2 ,
+&s_pmissattack2 ,
+&s_pbatblast,
+&s_remotemove4 ,
+&s_remotemove3 ,
+&s_remotemove2 ,
+&s_remotemove1 ,
+&s_remoteinelev ,
+&s_remotedead ,
+&s_remotedie5 ,
+&s_remotedie4 ,
+&s_remotedie3 ,
+&s_remotedie2 ,
+&s_remotedie1 ,
+&s_godfire4 ,
+&s_godfire3 ,
+&s_godfire2 ,
+&s_godfire1 ,
+&s_guts12 ,
+&s_guts11 ,
+&s_guts10 ,
+&s_guts9 ,
+&s_guts8 ,
+&s_guts7 ,
+&s_guts6 ,
+&s_guts5 ,
+&s_guts4 ,
+&s_guts3 ,
+&s_guts2 ,
+&s_guts1 ,
+&s_player ,
+&s_free ,
+&s_megaexplosions,
+&s_bossdeath,
+&s_superparticles,
+&s_littlesoul,
+&s_bigsoul,
+&s_vaporized8,
+&s_vaporized7,
+&s_vaporized6,
+&s_vaporized5,
+&s_vaporized4,
+&s_vaporized3,
+&s_vaporized2,
+&s_vaporized1,
+
+&s_autospring1,
+&s_autospring2,
+&s_autospring3,
+&s_autospring4,
+&s_autospring5,
+&s_autospring6,
+&s_autospring7,
+&s_autospring8,
+&s_autospring9,
+
+
+&s_gibsdone8,
+&s_gibsdone7,
+&s_gibsdone6,
+&s_gibsdone5,
+&s_gibsdone4,
+&s_gibsdone3,
+&s_gibsdone2,
+&s_gibsdone1,
+&s_gibs4,
+&s_gibs3,
+&s_gibs2,
+&s_gibs1,
+
+
+
+&s_collectorwander8,
+&s_collectorwander7,
+&s_collectorwander6,
+&s_collectorwander5,
+&s_collectorwander4,
+&s_collectorwander3,
+&s_collectorwander2,
+&s_collectorwander1,
+&s_collectorfdoor8,
+&s_collectorfdoor7,
+&s_collectorfdoor6,
+&s_collectorfdoor5,
+&s_collectorfdoor4,
+&s_collectorfdoor3,
+&s_collectorfdoor2,
+&s_collectorfdoor1,
+&s_tag,
+&s_wind,
+&s_timekeeper,
+&s_remoteguts1,
+&s_remoteguts2,
+&s_remoteguts3,
+&s_remoteguts4,
+&s_remoteguts5,
+&s_remoteguts6,
+&s_remoteguts7,
+&s_remoteguts8,
+&s_remoteguts9,
+&s_remoteguts10,
+&s_remoteguts11,
+&s_remoteguts12,
+&s_voidwait,
+&s_ashwait,
+&s_deadwait,
+&s_gutwait,
+&s_eye1,
+&s_eye2,
+&s_eye3,
+&s_itemspawn1,
+&s_itemspawn2,
+&s_itemspawn3,
+&s_itemspawn4,
+&s_itemspawn5,
+&s_itemspawn6,
+&s_itemspawn7,
+&s_itemspawn8,
+&s_deadblood1,
+&s_deadblood2,
+&s_deadblood3,
+&s_deadblood4,
+&s_deadblood5,
+&s_deadblood6,
+&s_deadblood7,
+&s_deadblood8,
+&s_flash1,
+&s_flash2,
+&s_flash3,
+&s_flash4,
+&s_flash5,
+&s_flash6,
+&s_flash7,
+&s_flash8,
+&s_basemarker1,
+&s_basemarker2,
+&s_basemarker3,
+&s_basemarker4,
+&s_basemarker5,
+&s_basemarker6,
+&s_basemarker7,
+&s_basemarker8,
+&s_pathdisk,
+&s_elevdisk,
+&s_megaremove,
+/*&s_rain7,
+&s_rain6,
+&s_rain5,
+&s_rain4,
+&s_rain3,
+&s_rain2,
+&s_rain1,
+&s_rainmaster,*/
+&s_respawn8,
+&s_respawn7,
+&s_respawn6,
+&s_respawn5,
+&s_respawn4,
+&s_respawn3,
+&s_respawn2,
+&s_respawn1,
+&s_blooddrip1,
+&s_blooddrip2,
+&s_blooddrip3,
+&s_blooddrip4,
+&s_diskmaster,
+&s_bstar4 ,
+&s_bstar3 ,
+&s_bstar2 ,
+&s_bstar1 ,
+
+
+
+#if (SHAREWARE == 0)
+&s_scottwander7,
+&s_scottwander6,
+&s_scottwander5,
+&s_scottwander4,
+&s_scottwander3,
+&s_scottwander2,
+&s_scottwander1,
+&s_scottwanderdoor7,
+&s_scottwanderdoor6,
+&s_scottwanderdoor5,
+&s_scottwanderdoor4,
+&s_scottwanderdoor3,
+&s_scottwanderdoor2,
+&s_scottwanderdoor1,
+
+
+&s_opstand     ,
+&s_oppath4 	   ,
+&s_oppath3 	   ,
+&s_oppath2 	   ,
+&s_oppath1 	   ,
+&s_opcollide  ,
+&s_opcollide2 ,
+&s_opshoot4 	,
+&s_opshoot3 	,
+&s_opshoot2 	,
+&s_opshoot1 	,
+&s_opbolo5     ,
+&s_opbolo4     ,
+&s_opbolo3     ,
+&s_opbolo2     ,
+&s_opbolo1     ,
+&s_bolocast4   ,
+&s_bolocast3   ,
+&s_bolocast2   ,
+&s_bolocast1   ,
+&s_opchase4 	,
+&s_opchase3 	,
+&s_opchase2 	,
+&s_opchase1 	,
+&s_opdead		,
+&s_opdie5		,
+&s_opdie4		,
+&s_opdie3		,
+&s_opdie2		,
+&s_opdie1		,
+&s_opcrushed2		,
+&s_opcrushed1		,
+
+
+
+&s_dmonkstand  ,
+&s_dmonkpath4 	,
+&s_dmonkpath3 	,
+&s_dmonkpath2 	,
+&s_dmonkpath1 	,
+&s_dmonkcollide  ,
+&s_dmonkcollide2 ,
+&s_dmonkshoot6 ,
+&s_dmonkshoot5 ,
+&s_dmonkshoot4 ,
+&s_dmonkshoot3 ,
+&s_dmonkshoot2 ,
+&s_dmonkshoot1 ,
+&s_dmonkchase4 	,
+&s_dmonkchase3 	,
+&s_dmonkchase2 	,
+&s_dmonkchase1 	,
+&s_dmonkdead		,
+&s_dmonkdie4		,
+&s_dmonkdie3		,
+&s_dmonkdie2		,
+&s_dmonkdie1		,
+&s_dmonkcrushed2		,
+&s_dmonkcrushed1		,
+&s_firemonkstand	,
+&s_firemonkpath4 	,
+&s_firemonkpath3 	,
+&s_firemonkpath2 	,
+&s_firemonkpath1 	,
+&s_firemonkcollide  ,
+&s_firemonkcollide2 ,
+&s_firemonkcast7 ,
+&s_firemonkcast6 ,
+&s_firemonkcast5 ,
+&s_firemonkcast4 ,
+&s_firemonkcast3 ,
+&s_firemonkcast2 ,
+&s_firemonkcast1 ,
+&s_monkfire4 ,
+&s_monkfire3 ,
+&s_monkfire2 ,
+&s_monkfire1 ,
+&s_fireballhit3 ,
+&s_fireballhit2 ,
+&s_fireballhit1 ,
+&s_firemonkchase4 	,
+&s_firemonkchase3 	,
+&s_firemonkchase2 	,
+&s_firemonkchase1 	,
+&s_firemonkdead7		,
+&s_firemonkdead6	   ,
+&s_firemonkdead5	   ,
+&s_firemonkdead4	   ,
+&s_firemonkdead3	   ,
+&s_firemonkdead2	   ,
+&s_firemonkdead		,
+&s_firemonkdie4		,
+&s_firemonkdie3		,
+&s_firemonkdie2		,
+&s_firemonkdie1		,
+&s_firemonkcrushed2		,
+&s_firemonkcrushed1		,
+
+
+&s_wallstand ,
+&s_wallpath ,
+&s_wallshoot ,
+&s_wallcollide  ,
+&s_wallalign,
+&s_wallrestore,
+&s_wallwait,
+
+
+
+
+&s_darianstand ,
+&s_darianchase4 	,
+&s_darianchase3 	,
+&s_darianchase2 	,
+&s_darianchase1 	,
+&s_darianrise8 ,
+&s_darianrise7 ,
+&s_darianrise6 ,
+&s_darianrise5 ,
+&s_darianrise4 ,
+&s_darianrise3 ,
+&s_darianrise2 ,
+&s_darianrise1 ,
+&s_dariansink9 ,
+&s_dariansink8 ,
+&s_dariansink7 ,
+&s_dariansink6 ,
+&s_dariansink5 ,
+&s_dariansink4 ,
+&s_dariansink3 ,
+&s_dariansink2 ,
+&s_dariansink1 ,
+&s_dariancollide  ,
+&s_dariancollide2 ,
+&s_darianshoot4  ,
+&s_darianshoot3  ,
+&s_darianshoot2  ,
+&s_darianshoot1  ,
+&s_dariandefend3  ,
+&s_dariandefend2  ,
+&s_dariandefend1  ,
+&s_darianuse4  ,
+&s_darianuse3  ,
+&s_darianuse2  ,
+&s_darianuse1  ,
+&s_darianwait ,
+&s_darianspears  ,
+&s_dspear16 ,
+&s_dspear15 ,
+&s_dspear14 ,
+&s_dspear13 ,
+&s_dspear12 ,
+&s_dspear11 ,
+&s_dspear10 ,
+&s_dspear9 ,
+&s_dspear8 ,
+&s_dspear7 ,
+&s_dspear6 ,
+&s_dspear5 ,
+&s_dspear4 ,
+&s_dspear3 ,
+&s_dspear2 ,
+&s_dspear1 ,
+&s_dariandead2 	,
+&s_dariandead1 	,
+&s_dariandead 	,
+&s_dariandie10 ,
+&s_dariandie9 	,
+&s_dariandie8 	,
+&s_dariandie7 	,
+&s_dariandie6 	,
+&s_dariandie5 	,
+&s_dariandie4 	,
+&s_dariandie3 	,
+&s_dariandie2 	,
+&s_dariandie1 	,
+&s_heinrichstand	,
+&s_heinrichchase 	,
+&s_kristleft ,
+&s_kristright ,
+&s_heinrichshoot11  ,
+&s_heinrichshoot10  ,
+&s_heinrichshoot9  ,
+&s_heinrichshoot8  ,
+&s_heinrichshoot7  ,
+&s_heinrichshoot6  ,
+&s_heinrichshoot5  ,
+&s_heinrichshoot4  ,
+&s_heinrichshoot3  ,
+&s_heinrichshoot2  ,
+&s_heinrichshoot1  ,
+&s_missile1       ,
+&s_missilehit3    ,
+&s_missilehit2    ,
+&s_missilehit1    ,
+&s_mine4          ,
+&s_mine3          ,
+&s_mine2          ,
+&s_mine1          ,
+&s_heinrichdefend ,
+&s_heinrichooc    ,
+&s_heinrichdead 	,
+&s_heinrichdie2 	,
+&s_heinrichdie1 	,
+&s_heindead2 ,
+&s_heindead1 ,
+&s_heinexp13 ,
+&s_heinexp12 ,
+&s_heinexp11 ,
+&s_heinexp10 ,
+&s_heinexp9 ,
+&s_heinexp8 ,
+&s_heinexp7 ,
+&s_heinexp6 ,
+&s_heinexp5 ,
+&s_heinexp4 ,
+&s_heinexp3 ,
+&s_heinexp2 ,
+&s_heinexp1 ,
+&s_darkmonkstand	,
+&s_darkmonkland	,
+&s_darkmonkchase2	,
+&s_darkmonkchase1	,
+&s_dmlandandfire ,
+&s_darkmonkcover3	,
+&s_darkmonkcover2	,
+&s_darkmonkcover1	,
+&s_darkmonkawaken5	,
+&s_darkmonkawaken4	,
+&s_darkmonkawaken3	,
+&s_darkmonkawaken2	,
+&s_darkmonkawaken1 	,
+&s_darkmonklightning11	,
+&s_darkmonklightning10	,
+&s_darkmonklightning9	,
+&s_darkmonklightning8	,
+&s_darkmonklightning7 	,
+&s_darkmonklightning6	,
+&s_darkmonklightning5	,
+&s_darkmonklightning4	,
+&s_darkmonklightning3	,
+&s_darkmonklightning2 	,
+&s_darkmonklightning1 	,
+&s_darkmonkfspark6	,
+&s_darkmonkfspark5	,
+&s_darkmonkfspark4	,
+&s_darkmonkfspark3	,
+&s_darkmonkfspark2 	,
+&s_darkmonkfspark1 	,
+&s_darkmonkbreathe8	,
+&s_darkmonkbreathe7 	,
+&s_darkmonkbreathe6	,
+&s_darkmonkbreathe5	,
+&s_darkmonkbreathe4	,
+&s_darkmonkbreathe3	,
+&s_darkmonkbreathe2 	,
+&s_darkmonkbreathe1 	,
+&s_darkmonksummon3	,
+&s_darkmonksummon2 	,
+&s_darkmonksummon1 	,
+&s_snakepath ,
+&s_snakefindpath ,
+&s_darkmonkhead	,
+&s_darkmonksnakelink	,
+&s_darkmonkhspawn ,
+&s_darkmonkfastspawn ,
+&s_darkmonkheaddead	,
+&s_darkmonkheaddie1	,
+&s_darkmonkhball9	,
+&s_darkmonkhball8	,
+&s_darkmonkhball7 ,
+&s_darkmonkhball6	,
+&s_darkmonkhball5	,
+&s_darkmonkhball4	,
+&s_darkmonkhball3	,
+&s_darkmonkhball2 ,
+&s_darkmonkhball1 ,
+&s_darkmonkabsorb9	,
+&s_darkmonkabsorb8	,
+&s_darkmonkabsorb7 ,
+&s_darkmonkabsorb6	,
+&s_darkmonkabsorb5	,
+&s_darkmonkabsorb4	,
+&s_darkmonkabsorb3	,
+&s_darkmonkabsorb2 ,
+&s_darkmonkabsorb1 ,
+&s_darkmonksphere10 ,
+&s_darkmonksphere9 ,
+&s_darkmonksphere8 ,
+&s_darkmonksphere7 ,
+&s_darkmonksphere6 ,
+&s_darkmonksphere5 ,
+&s_darkmonksphere4 ,
+&s_darkmonksphere3 ,
+&s_darkmonksphere2 ,
+&s_darkmonksphere1 ,
+&s_dmgreenthing10 ,
+&s_dmgreenthing9 ,
+&s_dmgreenthing8 ,
+&s_dmgreenthing7 ,
+&s_dmgreenthing6 ,
+&s_dmgreenthing5 ,
+&s_dmgreenthing4 ,
+&s_dmgreenthing3 ,
+&s_dmgreenthing2 ,
+&s_dmgreenthing1 ,
+&s_energysphere4 ,
+&s_energysphere3 ,
+&s_energysphere2 ,
+&s_energysphere1 ,
+&s_lightning ,
+&s_handball2 ,
+&s_handball1 ,
+&s_faceball2 ,
+&s_faceball1 ,
+&s_floorspark4 ,
+&s_floorspark3 ,
+&s_floorspark2 ,
+&s_floorspark1 ,
+&s_darkmonkreact ,
+&s_darkmonkbball9	,
+&s_darkmonkbball8	,
+&s_darkmonkbball7 ,
+&s_darkmonkbball6	,
+&s_darkmonkbball5	,
+&s_darkmonkbball4	,
+&s_darkmonkbball3	,
+&s_darkmonkbball2 ,
+&s_darkmonkbball1 ,
+&s_darkmonkcharge10 ,
+&s_darkmonkcharge9	,
+&s_darkmonkcharge8	,
+&s_darkmonkcharge7	,
+&s_darkmonkcharge6 	,
+&s_darkmonkcharge5	,
+&s_darkmonkcharge4	,
+&s_darkmonkcharge3	,
+&s_darkmonkcharge2	,
+&s_darkmonkcharge1 	,
+&s_darkmonkscare5	,
+&s_darkmonkscare4	,
+&s_darkmonkscare3	,
+&s_darkmonkscare2 ,
+&s_darkmonkscare1 ,
+&s_darkmonkdead ,
+&s_darkmonkdie7 ,
+&s_darkmonkdie6 ,
+&s_darkmonkdie5 ,
+&s_darkmonkdie4 ,
+&s_darkmonkdie3 ,
+&s_darkmonkdie2 ,
+&s_darkmonkdie1 ,
+&s_darkmonkredhead ,
+&s_darkmonkredlink ,
+&s_redheadhit ,
+&s_redlinkhit ,
+&s_spithit4 ,
+&s_spithit3 ,
+&s_spithit2 ,
+&s_spithit1 ,
+&s_spit4 ,
+&s_spit3 ,
+&s_spit2 ,
+&s_spit1 ,
+&s_snakefire2 ,
+&s_snakefire1 ,
+&s_snakefireworks1,
+&s_snakefireworks2,
+
+&s_dexplosion22 ,
+&s_dexplosion21 ,
+&s_dexplosion20 ,
+&s_dexplosion19 ,
+&s_dexplosion18 ,
+&s_dexplosion17 ,
+&s_dexplosion16 ,
+&s_dexplosion15 ,
+&s_dexplosion14 ,
+&s_dexplosion13 ,
+&s_dexplosion12 ,
+&s_dexplosion11 ,
+&s_dexplosion10 ,
+&s_dexplosion9 ,
+&s_dexplosion8 ,
+&s_dexplosion7 ,
+&s_dexplosion6 ,
+&s_dexplosion5 ,
+&s_dexplosion4 ,
+&s_dexplosion3 ,
+&s_dexplosion2 ,
+&s_dexplosion1 ,
+&s_NMEhead1 ,
+&s_NMEhead2 ,
+&s_NMEchase ,
+&s_NMEwheels1 ,
+&s_NMEwheels2 ,
+&s_NMEwheels3 ,
+&s_NMEwheels4 ,
+&s_NMEwheels5 ,
+&s_NMEspinattack ,
+&s_NMEwheelspin ,
+&s_NMEminiball4 ,
+&s_NMEminiball3 ,
+&s_NMEminiball2 ,
+&s_NMEminiball1 ,
+&s_NMEsaucer4 ,
+&s_NMEsaucer3 ,
+&s_NMEsaucer2 ,
+&s_NMEsaucer1 ,
+&s_NMEdie ,
+&s_NMEattack ,
+&s_NMEhead1rl ,
+&s_NMEhead2rl ,
+&s_NMEwindup ,
+&s_NMEwheels120 ,
+&s_NMEwrotleft3 ,
+&s_NMEwrotleft2 ,
+&s_NMEwrotleft1 ,
+&s_NMEwrotright3 ,
+&s_NMEwrotright2 ,
+&s_NMEwrotright1 ,
+&s_NMEdeathbuildup,
+&s_NMEheadexplosion,
+&s_NMEstand,
+&s_NMEspinfire,
+&s_oshuriken4 ,
+&s_oshuriken3 ,
+&s_oshuriken2 ,
+&s_oshuriken1 ,
+&s_oshurikenhit3 ,
+&s_oshurikenhit2 ,
+&s_oshurikenhit1 ,
+&s_shootinghead,
+
+
+&s_speardown16 ,
+&s_speardown15 ,
+&s_speardown14 ,
+&s_speardown13 ,
+&s_speardown12 ,
+&s_speardown11 ,
+&s_speardown10 ,
+&s_speardown9 ,
+&s_speardown8 ,
+&s_speardown7 ,
+&s_speardown6 ,
+&s_speardown5 ,
+&s_speardown4 ,
+&s_speardown3 ,
+&s_speardown2 ,
+&s_speardown1 ,
+
+
+&s_downblade16 ,
+&s_downblade15 ,
+&s_downblade14 ,
+&s_downblade13 ,
+&s_downblade12 ,
+&s_downblade11 ,
+&s_downblade10 ,
+&s_downblade9 ,
+&s_downblade8 ,
+&s_downblade7 ,
+&s_downblade6 ,
+&s_downblade5 ,
+&s_downblade4 ,
+&s_downblade3 ,
+&s_downblade2 ,
+&s_downblade1 ,
+
+&s_firejetdown23 ,
+&s_firejetdown22 ,
+&s_firejetdown21 ,
+&s_firejetdown20 ,
+&s_firejetdown19 ,
+&s_firejetdown18 ,
+&s_firejetdown17 ,
+&s_firejetdown16 ,
+&s_firejetdown15 ,
+&s_firejetdown14 ,
+&s_firejetdown13 ,
+&s_firejetdown12 ,
+&s_firejetdown11 ,
+&s_firejetdown10 ,
+&s_firejetdown9 ,
+&s_firejetdown8 ,
+&s_firejetdown7 ,
+&s_firejetdown6 ,
+&s_firejetdown5 ,
+&s_firejetdown4 ,
+&s_firejetdown3 ,
+&s_firejetdown2 ,
+&s_firejetdown1 ,
+
+&s_columnupdown6 ,
+&s_columnupdown5 ,
+&s_columnupdown4 ,
+&s_columnupdown3 ,
+&s_columnupdown2 ,
+&s_columnupdown1 ,
+&s_columnupup8 ,
+&s_columnupup7 ,
+&s_columnupup6 ,
+&s_columnupup5 ,
+&s_columnupup4 ,
+&s_columnupup3 ,
+&s_columnupup2 ,
+&s_columnupup1 ,
+
+
+&s_spinupblade16 ,
+&s_spinupblade15 ,
+&s_spinupblade14 ,
+&s_spinupblade13 ,
+&s_spinupblade12 ,
+&s_spinupblade11 ,
+&s_spinupblade10 ,
+&s_spinupblade9 ,
+&s_spinupblade8 ,
+&s_spinupblade7 ,
+&s_spinupblade6 ,
+&s_spinupblade5 ,
+&s_spinupblade4 ,
+&s_spinupblade3 ,
+&s_spinupblade2 ,
+&s_spinupblade1 ,
+
+
+&s_spindownblade16 ,
+&s_spindownblade15 ,
+&s_spindownblade14 ,
+&s_spindownblade13 ,
+&s_spindownblade12 ,
+&s_spindownblade11 ,
+&s_spindownblade10 ,
+&s_spindownblade9 ,
+&s_spindownblade8 ,
+&s_spindownblade7 ,
+&s_spindownblade6 ,
+&s_spindownblade5 ,
+&s_spindownblade4 ,
+&s_spindownblade3 ,
+&s_spindownblade2 ,
+&s_spindownblade1 ,
+
+
+&s_bouldersink9 ,
+&s_bouldersink8 ,
+&s_bouldersink7 ,
+&s_bouldersink6 ,
+&s_bouldersink5 ,
+&s_bouldersink4 ,
+&s_bouldersink3 ,
+&s_bouldersink2 ,
+&s_bouldersink1 ,
+&s_boulderroll8 ,
+&s_boulderroll7 ,
+&s_boulderroll6 ,
+&s_boulderroll5 ,
+&s_boulderroll4 ,
+&s_boulderroll3 ,
+&s_boulderroll2 ,
+&s_boulderroll1 ,
+&s_boulderdrop12 ,
+&s_boulderdrop11 ,
+&s_boulderdrop10 ,
+&s_boulderdrop9 ,
+&s_boulderdrop8 ,
+&s_boulderdrop7 ,
+&s_boulderdrop6 ,
+&s_boulderdrop5 ,
+&s_boulderdrop4 ,
+&s_boulderdrop3 ,
+&s_boulderdrop2 ,
+&s_boulderdrop1 ,
+&s_boulderspawn ,
+
+
+&s_gunfire2 ,
+&s_gunfire1 ,
+&s_gunstand ,
+&s_gunraise4 ,
+&s_gunraise3 ,
+&s_gunraise2 ,
+&s_gunraise1 ,
+&s_gunlower3 ,
+&s_gunlower2 ,
+&s_gunlower1 ,
+&s_gundead ,
+&s_gundie1 ,
+&s_4waygunfire1 ,
+&s_4waygunfire2 ,
+&s_4waygun ,
+
+
+
+&s_kessphere8 ,
+&s_kessphere7 ,
+&s_kessphere6 ,
+&s_kessphere5 ,
+&s_kessphere4 ,
+&s_kessphere3 ,
+&s_kessphere2 ,
+&s_kessphere1 ,
+
+
+&s_slop1,
+&s_slop2,
+&s_slop3,
+&s_slop4,
+
+&s_batblast1,
+&s_batblast2,
+&s_batblast3,
+&s_batblast4,
+
+&s_serialdog4,
+&s_serialdog3,
+&s_serialdog2,
+&s_serialdog,
+&s_serialdogattack,
+&s_doguse ,
+&s_doglick,
+&s_dogwait,
+
+
+
+
+#endif //SHAREWARE
+
+};
+#endif

Added: tags/rott-1.1/rott/rt_ted.c
===================================================================
--- tags/rott-1.1/rott/rt_ted.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_ted.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,7071 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+ // make sure word alignment is OFF!
+
+#include "rt_def.h"
+#include "rt_sound.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+
+#ifdef DOS
+#include <io.h>
+#include <conio.h>
+#include <dos.h>
+#else
+#include <errno.h>
+#endif
+
+#include "states.h"
+#include "watcom.h"
+#include "rt_ted.h"
+#include "_rt_ted.h"
+#include "w_wad.h"
+#include "z_zone.h"
+#include "rt_util.h"
+#include "lumpy.h"
+#include "rt_vid.h"
+#include "rt_actor.h"
+#include "rt_stat.h"
+#include "rt_menu.h"
+#include "rt_draw.h"
+#include "rt_com.h"
+#include "rt_main.h"
+#include "rt_door.h"
+#include "rt_playr.h"
+#include "rt_view.h"
+#include "rt_str.h"
+#include "isr.h"
+#include "rt_floor.h"
+#include "rt_game.h"
+#include "rt_rand.h"
+#include "rt_cfg.h"
+#include "develop.h"
+#include "modexlib.h"
+#include "engine.h"
+#include "rt_debug.h"
+#include "rt_scale.h"
+#include "rt_net.h"
+//MED
+#include "memcheck.h"
+
+
+
+
+//========================================
+// GLOBAL VARIABLES
+//========================================
+
+extern boolean  UseBaseMarker;
+
+teamtype TEAM[MAXPLAYERS];
+int numareatiles[NUMAREAS+1];
+int shapestart,shapestop;
+_2dvec SPAWNLOC[MAXSPAWNLOCATIONS],FIRST,SECOND;
+int NUMSPAWNLOCATIONS,numteams=0;
+wall_t    walls[MAXWALLTILES];
+str_clock Clocks[MAXCLOCKS];
+int numclocks;
+int LightsInArea[NUMAREAS+1];
+
+int maxheight;
+int nominalheight;
+int elevatorstart;
+int gunsstart;
+int fog;
+int lightsource;
+int SNAKELEVEL;
+int whichpath;
+
+word *mapplanes[3];
+int  mapwidth;
+int  mapheight;
+int  lastlevelloaded=-1;
+
+boolean insetupgame;
+boolean ISRTL = false;
+
+unsigned MapSpecials = 0;
+
+char LevelName[80];
+
+//========================================
+// LOCAL VARIABLES
+//========================================
+
+static cachetype * cachelist;
+static word cacheindex;
+static boolean CachingStarted=false;
+static char * ROTTMAPS = STANDARDGAMELEVELS;
+static char * BATTMAPS = STANDARDBATTLELEVELS;
+
+static char NormalWeaponTiles[ 10 ] =
+   {
+   46, 48, 49, 50, 51, 52, 53, 54, 55, 56
+   };
+static char SharewareWeaponTiles[ 7 ] =
+   {
+   48, 49, 50, 51, 52, 53, 54
+   };
+
+static char CacheStrings[MAXSILLYSTRINGS][80]=
+{
+   {"Ready yourself\nfor destruction!\0\0"},
+   {"Here comes the enemy!\0\0"},
+   {"Hope you wrote\nyour will!\0\0"},
+   {"Did you bring your\nextra bullets?\0\0"},
+   {"Try not to bleed\non the rug.\0\0"},
+   {"Let's see...bandages,\ntape, splints,...\0\0"},
+   {"Couldn't we just\ntalk this over?\0\0"},
+   {"Cache as cache can...\0\0"},
+   {"You are smart.\nMake us strong.\0\0"},
+	{"Bleh!\0\0"},
+   {"I am as far\nabove you...\0\0"},
+   {"Just keep thinkin':\nBut it's loadin' COOL\nstuff...\0\0"},
+   {"Guess which line\nwill win!\0\0"},
+   {"Oh, no. Not again.\0\0"},
+   {"Wait! I'm not ready!\nToo late.\0\0"},
+	{"Hope this doesn't\ncrash.\0\0"},
+	{"Have a sandwich.\0\0"},
+   {"Smoke 'em if\nya got 'em...and\nif ya like cancer.\0\0"},
+   {"Ummmmm...\0\0"},
+   {"Bang! Bang! Bang!\nFreeze!\0\0"},
+   {"You have the right\nto...DIE.\0\0"},
+   {"Insert funny phrase\nhere.\0\0"},
+   {"Blood, bullets,\nnicely decorated\nhallways.\0\0"},
+   {"You are to be killed,\nnot hurt.\0\0"},
+   {"It's time for you to\ngo down the stairs!\0\0"},
+   {"This game, like,\nrules and stuff.\0\0"},
+   {"We get money for this!\nHa ha ha ha!\0\0"},
+   {"Let's not start any\nreligious wars...\0\0"},
+   {"I don't wanna start\nno ting...\0\0"},
+   {"Ah, another sacrifice!\0\0"},
+   {"If you were dead,\nyou'd be the\nsame thing.\0\0"},
+   {"This Game isn't\nhuman; it can't\nbe reasoned with!\0\0"}
+};
+
+void SetupGameLevel (void);
+void ScanInfoPlane(void);
+
+void DrawPreCache( void );
+void InitializePlayerstates(void);
+void SetupSnakePath(void);
+void SetupRandomActors(void);
+void SetupActors(void);
+void SetupStatics(void);
+void LoftSprites( void );
+int GetLumpForTile(int tile);
+
+//========================================
+
+/*
+======================
+=
+= SortPreCache
+= Sort the Precache for cachelevel precedence using a HEAPSORT
+=
+======================
+*/
+#define SGN(x)          ((x>0) ? (1) : ((x==0) ? (0) : (-1)))
+
+/*--------------------------------------------------------------------------*/
+int CompareTags(s1p,s2p) cachetype *s1p,*s2p;
+{
+// Sort according to lump
+   if (DoPanicMapping()==true)
+      return SGN(s1p->cachelevel-s2p->cachelevel);
+// Sort according to cachelevel
+   else
+      return SGN(s1p->lump-s2p->lump);
+}
+
+void SwitchCacheEntries(s1p,s2p) cachetype *s1p,*s2p;
+{
+   cachetype temp;
+
+	temp=*s1p;
+   *s1p=*s2p;
+   *s2p=temp;
+}
+
+
+
+void SortPreCache( void )
+{
+   hsort((char *)cachelist,cacheindex,sizeof(cachetype),&CompareTags,&SwitchCacheEntries);
+}
+
+//========================================
+
+
+/*
+======================
+=
+= SetupPreCache
+= Setup the cache for pre-cacheing
+=
+======================
+*/
+void SetupPreCache( void )
+{
+
+   CachingStarted=true;
+   cacheindex=0;
+   cachelist=(cachetype *)SafeMalloc(MAXPRECACHE*(sizeof(cachetype)));
+   DrawPreCache();
+}
+
+
+/*
+======================
+=
+= ShutdownPreCache
+= Setup the cache for pre-cacheing
+=
+======================
+*/
+void ShutdownPreCache( void )
+{
+
+   CachingStarted=false;
+   SafeFree((byte *)cachelist);
+}
+
+
+/*
+======================
+=
+= PreCacheLump
+= precache the lump and check to see if it is already tagged
+=
+======================
+*/
+void PreCacheLump( int lump, int level, int type ) // added type
+{
+   int i;
+
+   if (CachingStarted==false)
+      return;
+   if (!W_LumpLength(lump))
+      {
+#if (PRECACHETEST == 1)
+      SoftError("Tried to precache a label, lump = %ld tag=%ld maskednum=%ld\n",lump, level, maskednum);
+#endif
+      return;
+      }
+   for (i=1;i<cacheindex;i++)
+      if (cachelist[i].lump==lump)
+         return;
+   cachelist[cacheindex].lump=lump;
+   cachelist[cacheindex].cachelevel=level;
+   cachelist[cacheindex++].type=type;
+   if (cacheindex==MAXPRECACHE)
+      Error("MaxPreCache reached\n");
+}
+
+
+
+/*
+======================
+=
+= PreCacheGroup
+= precache the lump and check to see if it is already tagged
+=
+======================
+*/
+void PreCacheGroup( int start, int end, int type ) // added type
+{
+	int i;
+   int j;
+   int k;
+   int found;
+
+   if (CachingStarted==false)
+      return;
+   k=cacheindex;
+   for (j=start;j<=end;j++)
+      {
+      if (!W_LumpLength(j))
+         {
+#if (PRECACHETEST == 1)
+         SoftError("Tried to precache a label, lump = %ld\n",j);
+#endif
+         continue;
+         }
+      found=0;
+      for (i=1;i<k;i++)
+         if (cachelist[i].lump==j)
+            {
+            found=1;
+            break;
+				}
+      if (found==0)
+         {
+         cachelist[cacheindex].lump=j;
+         cachelist[cacheindex].cachelevel=PU_CACHEACTORS;
+         cachelist[cacheindex++].type=type;
+
+         if (cacheindex==MAXPRECACHE)
+            Error("MaxPreCache reached\n");
+			}
+      }
+
+}
+
+
+/*
+======================
+=
+= PreCachePlayers
+= precache the lump and check to see if it is already tagged
+=
+======================
+*/
+void PreCachePlayers(void )
+{
+	int start;
+	int end;
+	int i;
+	playertype*pstate;
+
+	for(i=0;i<numplayers;i++)
+	 {if (i!=consoleplayer) // don't cache consoleplayer
+		 {pstate = &PLAYERSTATE[i];
+        start=W_GetNumForName("CASSHO11")+(pstate->player*REMOTEOFFSET);
+        end  =W_GetNumForName("CASWDEAD")+(pstate->player*REMOTEOFFSET);
+		  PreCacheGroup(start,end,cache_patch_t);
+		 }
+	 }
+}
+
+
+
+
+void PreCachePlayerSound(void)
+   {
+   switch (locplayerstate->player)
+      {
+      case 0:
+         SD_PreCacheSound(SD_PLAYERTCSND);
+
+         break;
+      case 1:
+         SD_PreCacheSound(SD_PLAYERTBSND);
+
+         break;
+      case 2:
+         SD_PreCacheSound(SD_PLAYERDWSND);
+
+         break;
+      case 3:
+         SD_PreCacheSound(SD_PLAYERLNSND);
+
+         break;
+      case 4:
+         SD_PreCacheSound(SD_PLAYERIPFSND);
+         break;
+      }
+   }
+
+
+#define IS_ALTERNATE_ACTOR(ob)                                 \
+        ((ob->shapeoffset - deathshapeoffset[ob->obclass]) > 0)\
+
+/*
+======================
+=
+= PreCacheActor
+= precache the lump and check to see if it is already tagged
+=
+======================
+*/
+void PreCacheActor( int actor, int which )
+{
+	int start;
+	int end;
+
+	switch (actor)
+		{
+		case lowguardobj:
+         if (IS_ALTERNATE_ACTOR(new))
+				{
+				 start = SD_LOWGUARD2SEESND;
+				 end = SD_LOWGUARD2SEE3SND;
+				 SD_PreCacheSoundGroup(start,end);
+
+             start = SD_LOWGUARD2DIESND;
+             end = SD_LOWGUARD2DIESND;
+				 SD_PreCacheSoundGroup(start,end);
+
+				 start = SD_LOWGUARDFIRESND;
+				 end = SD_SNEAKYSPRINGFSND;
+				 SD_PreCacheSoundGroup(start,end);
+
+				 start=W_GetNumForName("MARSHOO1");
+				 end  =W_GetNumForName("MNGRISE4");
+				 //end  =W_GetNumForName("MARUSE28");
+				}
+
+			else
+				{start = SD_LOWGUARD1SEESND;
+				 end = SD_LOWGUARD1SEE3SND;
+				 SD_PreCacheSoundGroup(start,end);
+
+             start = SD_LOWGUARD1DIESND;
+             end = SD_LOWGUARD1DIESND;
+				 SD_PreCacheSoundGroup(start,end);
+
+				 start = SD_LOWGUARDFIRESND;
+				 end = SD_SNEAKYSPRINGFSND;
+				 SD_PreCacheSoundGroup(start,end);
+
+				 start=W_GetNumForName("LWGSHOO1");
+				 end = W_GetNumForName("SNGRISE4");
+				 //end  =W_GetNumForName("LOWUSE28");
+				}
+
+			break;
+		case highguardobj:
+
+			start = SD_HIGHGUARD1SEESND;
+			end = SD_HIGHGUARDDIESND;
+			SD_PreCacheSoundGroup(start,end);
+
+         if (IS_ALTERNATE_ACTOR(new))
+				{
+				start=W_GetNumForName("HIGSHOO1");
+				end  =W_GetNumForName("HIGWDEAD");
+				//end  =W_GetNumForName("HIHUSE28");
+				}
+			else
+				{
+				start=W_GetNumForName("HG2SHOO1");
+				end  =W_GetNumForName("HG2WDEAD");
+				//end  =W_GetNumForName("H2HUSE28");
+				}
+			break;
+
+		case overpatrolobj:
+
+			start=W_GetNumForName("OBBOLO1");
+         end  =W_GetNumForName("OBBOLO4");
+			PreCacheGroup(start,end,cache_patch_t);
+			start=W_GetNumForName("NET1");
+			end  =W_GetNumForName("NET4");
+			PreCacheGroup(start,end,cache_patch_t);
+
+			start = SD_OVERP1SEESND;
+			end = SD_OVERPDIESND;
+			SD_PreCacheSoundGroup(start,end);
+			SD_PreCacheSoundGroup(SD_NETWIGGLESND,SD_NETFALLSND);
+
+         if (IS_ALTERNATE_ACTOR(new))
+				{
+            start=W_GetNumForName("PATSHOO1");
+            end  =W_GetNumForName("PATDEAD");
+
+				//end  =W_GetNumForName("OBPUSE28");
+            }
+
+			else
+				{
+            start=W_GetNumForName("OBPSHOO1");
+				end  =W_GetNumForName("OBPDEAD");
+
+				//end  =W_GetNumForName("PATUSE28");
+            }
+
+			break;
+		case strikeguardobj:
+
+
+			start = SD_STRIKE1SEESND;
+			end = SD_STRIKEDIESND;
+			SD_PreCacheSoundGroup(start,end);
+
+         if (IS_ALTERNATE_ACTOR(new))
+            {
+				start=W_GetNumForName("XYGSHOO1");
+				end  =W_GetNumForName("XYLROLL6");
+				//end  =W_GetNumForName("XYUSE28");
+				}
+
+			else
+				{
+				start=W_GetNumForName("ANGSHOO1");
+				end  =W_GetNumForName("ANLROLL6");
+				//end  =W_GetNumForName("ANUSE28");
+				}
+
+			break;
+
+		case blitzguardobj:
+
+			start = SD_BLITZ1SEESND;
+			end = SD_BLITZDIESND;
+			SD_PreCacheSoundGroup(start,end);
+
+         if (IS_ALTERNATE_ACTOR(new))
+				{
+				start=W_GetNumForName("WIGSHOO1");
+				end  =W_GetNumForName("WIHUSE28");
+				}
+
+			else
+				{
+				start=W_GetNumForName("LIGSHOO1");
+            end  =W_GetNumForName("LIPEAD11");
+				}
+
+			break;
+
+		case triadenforcerobj:
+
+			start = SD_ENFORCERSEESND;
+			end = SD_ENFORCERDIESND;
+			SD_PreCacheSoundGroup(start,end);
+
+			start=W_GetNumForName("TEGREN1");
+			end  =W_GetNumForName("TGRENF6");
+			PreCacheGroup(start,end,cache_patch_t);
+			start=W_GetNumForName("TRISHOO1");
+			end  =W_GetNumForName("TRIWDEAD");
+			//end  =W_GetNumForName("TRIUSE28");
+			break;
+		case deathmonkobj:
+
+
+			start = SD_MONKSEESND;
+			end = SD_MONKDIESND;
+			SD_PreCacheSoundGroup(start,end);
+
+			start=W_GetNumForName("MONKDR1");
+			end  =W_GetNumForName("MONDEAD");
+			//end  =W_GetNumForName("MONUSE28");
+			break;
+
+
+		case dfiremonkobj:
+
+			start = SD_FIREMONKSEESND;
+			end = SD_FIREMONKDIESND;
+			SD_PreCacheSoundGroup(start,end);
+
+         start = W_GetNumForName("MONFIRE1");
+         end = W_GetNumForName("MONFIRE4");
+         PreCacheGroup(start,end,cache_patch_t);
+
+
+         if (IS_ALTERNATE_ACTOR(new))
+				{
+            start=W_GetNumForName("MRKKSH1");
+				end  =W_GetNumForName("MRKDEAD7");
+				}
+
+			else
+				{
+            start=W_GetNumForName("ALLKSH1");
+				end  =W_GetNumForName("ALLDEAD7");
+				}
+
+			break;
+
+		case roboguardobj:
+
+			start = SD_ROBOTSEESND;
+			end = SD_ROBOTDIESND;
+			SD_PreCacheSoundGroup(start,end);
+			start=W_GetNumForName("ROBOGRD1");
+         end  =W_GetNumForName("ROBGRD16");
+			break;
+
+		case b_darianobj:
+
+         PreCachePlayerSound();
+
+         start = SD_DARIANSEESND;
+			end = SD_DARIANSAY3;
+			SD_PreCacheSoundGroup(start,end);
+
+
+			start=W_GetNumForName("DARSHOO1");
+			end  =W_GetNumForName("DARUSE28");
+			break;
+
+
+		case b_heinrichobj:
+
+         PreCachePlayerSound();
+
+			start = SD_KRISTSEESND;
+			end = SD_KRISTSAY3;
+			SD_PreCacheSoundGroup(start,end);
+
+			start=W_GetNumForName("MINE1");
+			end  =W_GetNumForName("MINE4");
+			PreCacheGroup(start,end,cache_patch_t);
+			start=W_GetNumForName("HSIT1");
+			end  =W_GetNumForName("HDOPE8");
+			break;
+
+		case b_darkmonkobj:
+
+			start = SD_DARKMONKSEESND;
+			end = SD_DARKMONKSAY3;
+			SD_PreCacheSoundGroup(start,end);
+
+			start=W_GetNumForName("LIGNING1");
+			end  =W_GetNumForName("FSPARK4");
+			PreCacheGroup(start,end,cache_patch_t);
+			start=W_GetNumForName("TOMS1");
+			end  =W_GetNumForName("TOHRH8");
+			break;
+
+		case b_darksnakeobj:
+
+         PreCachePlayerSound();
+
+			start = SD_SNAKESEESND;
+			end = SD_SNAKESAY3;
+			SD_PreCacheSoundGroup(start,end);
+
+			start=W_GetNumForName("TOMRH1");
+			end  =W_GetNumForName("TOHRH8");
+		case b_robobossobj:
+
+         PreCachePlayerSound();
+
+			start = SD_NMESEESND;
+         end = SD_NMESEESND;
+			SD_PreCacheSoundGroup(start,end);
+
+			start=W_GetNumForName("RHEAD101");
+			end  =W_GetNumForName("NMESAUC4");
+			break;
+		case patrolgunobj:
+
+			start = SD_EMPLACEMENTSEESND;
+			end = SD_BIGEMPLACEFIRESND;
+			SD_PreCacheSoundGroup(start,end);
+
+
+			start=W_GetNumForName("GUNEMP1");
+			end  =W_GetNumForName("GUNEMPF8");
+			PreCacheGroup(start,end,cache_patch_t);
+			start=W_GetNumForName("GRISE11");
+			end  =W_GetNumForName("GDEAD2");
+			break;
+
+		case wallopobj:
+			start=W_GetNumForName("BSTAR1");
+			end  =W_GetNumForName("BSTAR4");
+			PreCacheGroup(start,end,cache_patch_t);
+			start=W_GetNumForName("BCRAFT1");
+			end  =W_GetNumForName("BCRAFT16");
+			break;
+
+		case wallfireobj:
+
+			SD_PreCacheSound(SD_FIRECHUTESND);
+			SD_PreCacheSound(SD_FIREBALLSND);
+			SD_PreCacheSound(SD_FIREBALLHITSND);
+
+			start = W_GetNumForName("CRFIRE11");
+			end = W_GetNumForName("CREXP5");
+
+		case pillarobj:
+
+			start=W_GetNumForName("PUSHCOL1");
+         end  =W_GetNumForName("PSHCOL1A");
+         //end  =W_GetNumForName("PUSHCOL3");
+			break;
+
+		case firejetobj:
+
+         SD_PreCacheSound(SD_FIREJETSND);
+
+         if (which)
+            {
+            start=W_GetNumForName("FJUP0");
+            end  =W_GetNumForName("FJUP22");
+            }
+  #if (SHAREWARE == 0)
+         else
+            {
+            start=W_GetNumForName("FJDOWN0");
+            end  =W_GetNumForName("FJDOWN22");
+            }
+  #endif
+
+			break;
+
+		case bladeobj:
+
+			SD_PreCacheSound(SD_BLADESPINSND);
+
+
+  #if (SHAREWARE == 0)
+
+
+         if (which&2)
+            {
+            if (which&1)
+               {
+               start=W_GetNumForName("SPSTUP1");
+               end  =W_GetNumForName("SPSTUP16");
+               }
+            else
+               {
+               start=W_GetNumForName("SPSTDN1");
+               end  =W_GetNumForName("SPSTDN16");
+               }
+            }
+         else
+            {
+            if (which&1)
+               {
+               start=W_GetNumForName("UBLADE1");
+               end  =W_GetNumForName("UBLADE9");
+               }
+            else
+               {
+               start=W_GetNumForName("DBLADE1");
+               end  =W_GetNumForName("DBLADE9");
+               }
+            }
+  #else
+         start=W_GetNumForName("UBLADE1");
+         end  =W_GetNumForName("UBLADE9");
+  #endif
+
+			break;
+		case crushcolobj:
+
+			SD_PreCacheSound(SD_CYLINDERMOVESND);
+         if (which)
+            {
+            start=W_GetNumForName("CRDOWN1");
+            end  =W_GetNumForName("CRDOWN8");
+            }
+  #if (SHAREWARE == 0)
+         else
+            {
+            start=W_GetNumForName("CRUP1");
+            end  =W_GetNumForName("CRUP8");
+            }
+  #endif
+         break;
+
+		case boulderobj:
+			start=W_GetNumForName("BOL11");
+			end  =W_GetNumForName("BSINK9");
+			SD_PreCacheSound(SD_BOULDERHITSND);
+			SD_PreCacheSound(SD_BOULDERROLLSND);
+			SD_PreCacheSound(SD_BOULDERFALLSND);
+
+			break;
+
+		case spearobj:
+			SD_PreCacheSound(SD_SPEARSTABSND);
+
+         if (which)
+            {
+            start=W_GetNumForName("SPEARUP1");
+            end  =W_GetNumForName("SPERUP16");
+            }
+#if (SHAREWARE == 0)
+         else
+            {
+            start=W_GetNumForName("SPEARDN1");
+            end  =W_GetNumForName("SPERDN16");
+            }
+#endif
+
+			break;
+
+		case gasgrateobj:
+
+			start = SD_GASSTARTSND;
+			end = SD_GASMASKSND;
+         SD_PreCacheSoundGroup(start,end);
+         if ((locplayerstate->player == 1) || (locplayerstate->player == 3))
+			  SD_PreCacheSound(SD_PLAYERCOUGHFSND);
+			else
+			  SD_PreCacheSound(SD_PLAYERCOUGHMSND);
+         start=-1;
+         end=-1;
+			break;
+
+		case springobj:
+
+			SD_PreCacheSound(SD_SPRINGBOARDSND);
+
+			start=W_GetNumForName("SPRING1");
+			end  =W_GetNumForName("SPRING9");
+			break;
+		default:
+			return;
+			break;
+		}
+   if ((start>=0) && (end>=0))
+      PreCacheGroup(start,end,cache_patch_t);
+}
+
+
+
+/*
+======================
+=
+= MiscPreCache
+= precache the lump and check to see if it is already tagged
+=
+======================
+*/
+void MiscPreCache( void )
+{
+   int start;
+   int end;
+
+	//essential sounds
+
+   SD_PreCacheSoundGroup(SD_HITWALLSND,SD_PLAYERDWHURTSND);
+	SD_PreCacheSoundGroup(SD_RICOCHET1SND,SD_RICOCHET3SND);
+	SD_PreCacheSound(SD_ATKPISTOLSND);
+	SD_PreCacheSoundGroup(SD_PLAYERBURNEDSND,SD_PLAYERLANDSND);
+	SD_PreCacheSoundGroup(SD_EXPLODEFLOORSND,SD_EXPLODESND);
+
+   if (lightning==true)
+      SD_PreCacheSound(SD_LIGHTNINGSND);
+
+   SD_PreCacheSound(SD_BODYLANDSND);
+   SD_PreCacheSound(SD_GIBSPLASHSND);
+   SD_PreCacheSound(SD_ACTORLANDSND);
+   SD_PreCacheSound(SD_ACTORSQUISHSND);
+
+
+   // cache in bullet hole graphics
+   start=W_GetNumForName("BULLETHO");
+   end=W_GetNumForName("ALTBHO");
+	PreCacheGroup(start,end,cache_transpatch_t);
+
+
+   // cache in explosions
+
+   if (DoPanicMapping()==true)
+      {
+      start=W_GetNumForName("EXPLOS1");
+      end  =W_GetNumForName("EXPLOS20");
+      PreCacheGroup(start,end,cache_patch_t);
+      }
+   else
+      {
+      start=W_GetNumForName("EXPLOS1");
+      end  =W_GetNumForName("GREXP25");
+      PreCacheGroup(start,end,cache_patch_t);
+      }
+
+	// cache in misc player sprites
+	start=W_GetNumForName("BLOODS1");
+	end  =W_GetNumForName("PLATFRM5");
+	PreCacheGroup(start,end,cache_patch_t);
+
+   // cache in missile smoke
+	start=W_GetNumForName("MISSMO11");
+	end  =W_GetNumForName("MISSMO14");
+   PreCacheGroup(start,end,cache_patch_t);
+
+#if (DEVELOPMENT == 1)
+	// cache in all weapon sounds
+   SD_PreCacheSoundGroup(SD_ATKPISTOLSND,SD_LOSEMODESND);
+
+	// cache in misc player weapons
+#if (SHAREWARE == 0)
+   start=W_GetNumForName("KNIFE1");
+   end  =W_GetNumForName("DOGPAW4");
+   PreCacheGroup(start,end,cache_patch_t);
+	// cache in kinetic sphere
+   start=W_GetNumForName("KSPHERE1");
+	end  =W_GetNumForName("KSPHERE4");
+   PreCacheGroup(start,end,cache_patch_t);
+
+#else
+   start=W_GetNumForName("MPIST11");
+   end  =W_GetNumForName("GODHAND8");
+   PreCacheGroup(start,end,cache_patch_t);
+#endif
+
+
+   // cache in god mode stuff
+
+	PreCacheGroup(W_GetNumForName("VAPO1"),
+	              W_GetNumForName("LITSOUL"),
+	              cache_patch_t);
+
+	PreCacheGroup(W_GetNumForName("GODFIRE1"),
+					  W_GetNumForName("GODFIRE4"),
+					  cache_patch_t);
+
+
+#endif
+   // cache in player's gun
+
+   // cache in rubble
+   start=W_GetNumForName("RUBBLE1");
+	end  =W_GetNumForName("RUBBLE10");
+   PreCacheGroup(start,end,cache_patch_t);
+
+   // cache in guts
+   start=W_GetNumForName("GUTS1");
+   end  =W_GetNumForName("GUTS12");
+   PreCacheGroup(start,end,cache_patch_t);
+
+   // cache in player missile
+   start=W_GetNumForName("BJMISS1");
+	end  =W_GetNumForName("BJMISS16");
+   PreCacheGroup(start,end,cache_patch_t);
+
+   if (gamestate.violence >= vl_high)
+      {                                  // cache in all gibs
+      if (DoPanicMapping()==true)
+         {
+         start = W_GetNumForName("ORGAN1");
+         end = W_GetNumForName("ORGAN12");
+         }
+      else
+         {
+         start = W_GetNumForName("PART1");
+         end = W_GetNumForName("GEYE3");
+         }
+      PreCacheGroup(start,end,cache_patch_t);
+      }
+}
+
+
+/*
+========================
+=
+= IsChristmas
+=
+========================
+*/
+
+boolean IsChristmas(void)
+   {
+   struct dosdate_t date;
+
+   _dos_getdate(&date);
+
+   if (((date.day == 24) || (date.day == 25)) &&      //Christmas
+       (date.month == 12)
+      )
+      return true;
+
+   return false;
+
+   }
+
+
+/*
+========================
+=
+= CheckHolidays
+=
+========================
+*/
+
+void CheckHolidays(void)
+   {
+   struct dosdate_t date;
+
+   _dos_getdate(&date);
+
+
+   if (IsChristmas())
+      DrawNormalSprite(0,0,W_GetNumForName("santahat"));
+
+   else if ((date.month == 5) && (date.day == 5))    // Cinco de Mayo
+      DrawNormalSprite(0,0,W_GetNumForName("sombrero"));
+
+   else if ((date.month == 7) && (date.day == 4))     // 4th of July
+      DrawNormalSprite(0,0,W_GetNumForName("amflag"));
+
+   else if ((date.month == 10) && (date.day == 31))    // Halloween
+      DrawNormalSprite(0,0,W_GetNumForName("witchhat"));
+
+   else if ((date.month == 4) && (date.dayofweek == 0))   //Easter
+      {
+      int i;
+
+      for(i=15;i<=21;i++)
+         {
+         if (date.day == i)
+            DrawNormalSprite(0,0,W_GetNumForName("esterhat"));
+         }
+      }
+   }
+
+
+/*
+======================
+=
+= DrawPreCache
+=
+======================
+*/
+extern boolean dopefish;
+void DrawPreCache( void )
+{
+   if (loadedgame==false)
+      {
+      char temp[80];
+      int width, height, num;
+      char buf[30];
+
+      if ( BATTLEMODE )
+			{
+         VL_DrawPostPic (W_GetNumForName("trilogo"));
+         VWB_TBar ( 30, 23, 260, 82 );
+         ShowBattleOptions( false, 56, 26 );
+
+         DrawPlayers ();
+         }
+      else
+         {
+         pic_t * pic;
+         pic=(pic_t *)W_CacheLumpName("mmbk",PU_CACHE, Cvt_pic_t, 1);
+         VWB_DrawPic (0, 0, pic);
+
+         CheckHolidays();
+         }
+
+      DrawNormalSprite (PRECACHEBARX, PRECACHEBARY, W_GetNumForName ("cachebar"));
+
+      CurrentFont=smallfont;
+
+      PrintY = PRECACHEESTRINGY;
+      PrintX = PRECACHEESTRINGX;
+
+      memset (&buf[0], 0, sizeof (buf));
+
+      if ( !BATTLEMODE )
+      {
+         memcpy (&buf[0], "EPISODE ", 8);
+         itoa (gamestate.episode,&buf[8],10);
+      }
+      else
+			memcpy (&buf[0], "COMM-BAT", 8);
+
+      US_MeasureStr (&width, &height, &buf[0]);
+      VWB_TBar (PrintX-2, PrintY-2, width+4, height+4);
+      US_BufPrint (&buf[0]);
+
+
+      PrintY = PRECACHEASTRINGY;
+
+      memset (&buf[0], 0, sizeof (buf));
+      memcpy (&buf[0], "AREA ", 5);
+
+      if ( !BATTLEMODE )
+         {
+         itoa( GetLevel( gamestate.episode, gamestate.mapon ),
+            &buf[ 5 ], 10 );
+         }
+      else
+         {
+         itoa( gamestate.mapon + 1, &buf[ 5 ], 10 );
+         }
+      US_MeasureStr (&width, &height, &buf[0]);
+      PrintX = (300-width);
+      VWB_TBar (PrintX-2, PrintY-2, width+4, height+4);
+      US_BufPrint (&buf[0]);
+
+
+      PrintY = PRECACHESTRINGY;
+
+      num = (RandomNumber ("PreCacheString", 0)) % MAXSILLYSTRINGS;
+
+      if ((dopefish==true) || (tedlevel == true))
+         strcpy (temp, &(CacheStrings[num][0]));
+      else
+         strcpy (temp, &(LevelName[0]));
+
+      US_MeasureStr (&width, &height, &temp[0]);
+
+      PrintX = (320-width) >> 1;
+      PrintY = PRECACHESTRINGY;
+      VWB_TBar (PrintX-2, PrintY-2, width+4, height+4);
+
+      US_BufPrint (&temp[0]);
+
+      VW_UpdateScreen();
+
+      MenuFadeIn ();
+      }
+}
+
+#define CACHETICDELAY (6)
+/*
+======================
+=
+= PreCache
+= precache all the lumps for the level
+=
+======================
+*/
+void PreCache( void )
+{
+   int i;
+	int total;
+   byte * dummy;
+   int maxheapsize;
+   int newheap;
+
+   int currentmem;
+   int currentcache;
+   int lastmem=0;
+   int lastcache=0;
+   int ticdelay;
+   byte *tempbuf;
+
+   double Gs;
+   Gs = (iGLOBAL_SCREENWIDTH*100/320);
+   Gs = Gs / 100;
+
+//SetTextMode (  );
+
+/*
+#define  PRECACHEBARX 28
+#define  PRECACHEBARY 178
+
+#define  PRECACHELED1X 9
+#define  PRECACHELED1Y 8
+
+#define  PRECACHELED2X 9
+#define  PRECACHELED2Y 12
+*/
+
+   if (CachingStarted==false)
+      {
+      if (loadedgame==false)
+         {
+         ClearGraphicsScreen();
+         MenuFadeIn ();
+         }
+      return;
+      }
+
+	MiscPreCache();
+
+   SortPreCache();
+
+   if (loadedgame==false)
+      {
+		maxheapsize=Z_HeapSize();
+      total=0;
+
+      tempbuf=bufferofs;
+      bufferofs=page1start; // fixed, was displayofs
+      ticdelay=CACHETICDELAY;
+      for (i=1;i<cacheindex;i++)
+			{
+         dummy=W_CacheLumpNum(cachelist[i].lump,cachelist[i].cachelevel, CvtForType(cachelist[i].type), 1);
+         total+=W_LumpLength(cachelist[i].lump);
+         newheap=Z_UsedHeap();
+			currentmem=(newheap*MAXLEDS)/maxheapsize;
+         while (lastmem<=currentmem)
+            {//SetTextMode (  );
+   			if ( iGLOBAL_SCREENWIDTH == 320) {
+				DrawNormalSprite (PRECACHEBARX+PRECACHELED1X+(lastmem<<2),
+                              PRECACHEBARY+PRECACHELED1Y,
+                              W_GetNumForName ("led1"));//led1 progressbar
+			}else if ( iGLOBAL_SCREENWIDTH == 640) {
+				DrawNormalSprite (72+(Gs*(lastmem<<2)),446,W_GetNumForName ("led1"));//led1 progressbar
+				DrawNormalSprite (72+(Gs*(lastmem<<2)),446+3,W_GetNumForName ("led1"));//led1 progressbar
+				DrawNormalSprite (72+3+(Gs*(lastmem<<2)),446,W_GetNumForName ("led1"));//led1 progressbar
+				DrawNormalSprite (72+3+(Gs*(lastmem<<2)),446+3,W_GetNumForName ("led1"));//led1 progressbar
+			}else if ( iGLOBAL_SCREENWIDTH == 800) {
+				DrawNormalSprite (91+(Gs*(lastmem<<2)),559,W_GetNumForName ("led1"));//led1 progressbar
+				DrawNormalSprite (91+(Gs*(lastmem<<2)),559+3,W_GetNumForName ("led1"));//led1 progressbar
+				DrawNormalSprite (91+3+(Gs*(lastmem<<2)),559,W_GetNumForName ("led1"));//led1 progressbar
+				DrawNormalSprite (91+3+(Gs*(lastmem<<2)),559+3,W_GetNumForName ("led1"));//led1 progressbar
+			}
+
+            lastmem++;
+				VW_UpdateScreen (); // was missing, fixed
+            }
+         currentcache=(i*MAXLEDS)/(cacheindex+1);
+         while (lastcache<=currentcache)
+            {
+
+   			if ( iGLOBAL_SCREENWIDTH == 320) {
+				DrawNormalSprite (PRECACHEBARX+PRECACHELED2X+(lastcache<<2),
+                              PRECACHEBARY+PRECACHELED2Y,
+                              W_GetNumForName ("led2"));//led2 progressbar
+			}else if ( iGLOBAL_SCREENWIDTH == 640) {
+				DrawNormalSprite (72+(Gs*(lastcache<<2)),458,W_GetNumForName ("led2"));//led2 progressbar
+				DrawNormalSprite (72+(Gs*(lastcache<<2)),458+3,W_GetNumForName ("led2"));//led2 progressbar
+				DrawNormalSprite (72+3+(Gs*(lastcache<<2)),458,W_GetNumForName ("led2"));//led2 progressbar
+				DrawNormalSprite (72+3+(Gs*(lastcache<<2)),458+3,W_GetNumForName ("led2"));//led2 progressbar
+			
+			}else if ( iGLOBAL_SCREENWIDTH == 800) {
+				DrawNormalSprite (91+(Gs*(lastcache<<2)),573,W_GetNumForName ("led2"));//led2 progressbar
+				DrawNormalSprite (91+(Gs*(lastcache<<2)),573+3,W_GetNumForName ("led2"));//led2 progressbar
+				DrawNormalSprite (91+3+(Gs*(lastcache<<2)),573,W_GetNumForName ("led2"));//led2 progressbar
+				DrawNormalSprite (91+3+(Gs*(lastcache<<2)),573+3,W_GetNumForName ("led2"));//led2 progressbar
+			}
+			DisableScreenStretch();//bna++
+			VW_UpdateScreen ();//bna++
+            lastcache++;
+            ticdelay--;
+            if (ticdelay==0)
+               {
+               extern boolean dopefish;
+
+               if ( dopefish==true )
+                  {
+                  SD_PlayPitchedSound ( SD_DOPEFISHSND, 255, 0 );
+                  }
+               ticdelay=CACHETICDELAY;
+               }
+				VW_UpdateScreen (); // was missing, fixed
+            }
+         }
+	  DisableScreenStretch();//bna++
+	  VW_UpdateScreen ();//bna++
+	  //I_Delay(200);
+      bufferofs=tempbuf;
+      ShutdownPreCache ();
+
+      if ( BATTLEMODE )
+         {
+         int width,height;
+         char buf[30];//byte * shape;
+		double WHratio = 16200/200;
+		WHratio = WHratio/100;
+///	iGLOBAL_SCREENWIDTH = 640;
+//	iGLOBAL_SCREENHEIGHT = 480;
+DisableScreenStretch();
+
+	// Cache in fonts
+//	shape = W_CacheLumpNum (W_GetNumForName ("newfnt1"), PU_STATIC, Cvt_font_t, 1);
+//	bigfont = (font_t *)shape;
+         CurrentFont = newfont1;//smallfont;
+
+         strcpy( buf, "Press Any Key" );
+         US_MeasureStr (&width, &height, &buf[ 0 ] );
+         PrintX = (iGLOBAL_SCREENWIDTH-(width)) / 2;
+         PrintY = WHratio*iGLOBAL_SCREENHEIGHT;//162;
+         //VWB_TBar (PrintX-2, PrintY-2, width+4, height+4);
+         US_BufPrint (&buf[0]);
+
+         VW_UpdateScreen();
+
+         IN_StartAck();
+         while (!IN_CheckAck ())
+            ;
+         }
+ //  EnableScreenStretch();
+#if (DEVELOPMENT == 1)
+      tempbuf=bufferofs;
+      bufferofs=displayofs;
+      CurrentFont = smallfont;
+      US_CenterWindow(30,6);
+      PrintY+=6;
+      US_Print("Max  Heap Size:");
+      US_PrintUnsigned(maxheapsize);
+		US_Print("\n");
+      US_Print("Used Heap Size:");
+      US_PrintUnsigned(newheap);
+      US_Print("\n");
+      US_Print("Percentage Used:");
+      US_PrintUnsigned(newheap*100/maxheapsize);
+		US_Print("\n");
+      US_Print("TotalPrecached:");
+      US_PrintUnsigned(total);
+      bufferofs=tempbuf;
+      I_Delay (40);
+#endif
+#if (PRECACHETEST == 1)
+      SoftError("Max  Heap Size: %ld\n",maxheapsize);
+      SoftError("Used Heap Size: %ld\n",newheap);
+      SoftError("TotalPrecached: %ld\n",total);
+#endif
+      }
+   else
+      {
+      for (i=1;i<cacheindex;i++)
+         {
+			dummy=W_CacheLumpNum(cachelist[i].lump,cachelist[i].cachelevel, CvtForType(cachelist[i].type), 1);
+         DoLoadGameAction ();
+         }
+      ShutdownPreCache ();
+      }
+   if (CheckParm("LEVELSIZE")!=0)
+      {
+      OpenMapDebug();
+
+      MapDebug("Map Number %d\n",gamestate.mapon);
+      MapDebug("sizeoflevel=%d\n",Z_UsedLevelHeap());
+      }
+#if (PRECACHETEST == 1)
+   SoftError("<<<<<<<<<<<<<<<<<<<<<<<Precaching done\n");
+#endif
+}
+
+
+
+/*
+======================
+=
+= CA_RLEWexpand
+= length is EXPANDED length
+=
+======================
+*/
+
+void CA_RLEWexpand (word *source, word *dest,long length, unsigned rlewtag)
+{
+        word  value,count,i;
+        word          *end;
+
+        end = dest + length;
+        //
+        // expand it
+        //
+        do
+        {
+					 value = IntelShort(*source++);
+                if (value != rlewtag)
+                //
+					 // uncompressed
+					 //
+                        *dest++=value;
+                else
+                {
+                //
+                // compressed string
+                //
+                        count = IntelShort(*source++);
+                        value = IntelShort(*source++);
+                        for (i=1;i<=count;i++)
+                                *dest++ = value;
+					 }
+        } while (dest<end);
+}
+
+/*
+======================
+=
+= CheckRTLVersion
+=
+======================
+*/
+
+void CheckRTLVersion
+   (
+   char *filename
+   )
+
+   {
+   int  filehandle;
+   char RTLSignature[ 4 ];
+   unsigned int RTLVersion;
+
+   filehandle = SafeOpenRead( filename );
+
+   //
+   // Load RTL signature
+   //
+   SafeRead( filehandle, RTLSignature, sizeof( RTLSignature ) );
+
+   if ( ( strcmp( RTLSignature, COMMBAT_SIGNATURE ) != 0 ) &&
+      ( strcmp( RTLSignature, NORMAL_SIGNATURE ) != 0 ) )
+      {
+      Error( "The file '%s' is not a valid level file.", filename );
+      }
+
+   //
+   // Check the version number
+   //
+   SafeRead( filehandle, &RTLVersion, sizeof( RTLVersion ) );
+   SwapIntelLong(&RTLVersion);
+   if ( RTLVersion > RTL_VERSION )
+      {
+      Error(
+         "The file '%s' is a version %d.%d %s file.\n"
+         "The highest this version of ROTT can load is %d.%d.", filename,
+         RTLVersion >> 8, RTLVersion & 0xff, RTLSignature,
+         RTL_VERSION >> 8, RTL_VERSION & 0xff );
+      }
+
+   close( filehandle );
+   }
+
+
+/*
+======================
+=
+= ReadROTTMap
+=
+======================
+*/
+
+void ReadROTTMap
+   (
+   char *filename,
+   int mapnum
+   )
+
+   {
+   RTLMAP RTLMap;
+   int    filehandle;
+   long   pos;
+   long   compressed;
+   long   expanded;
+   int    plane;
+   byte  *buffer;
+
+   CheckRTLVersion( filename );
+   filehandle = SafeOpenRead( filename );
+
+   //
+   // Load map header
+   //
+   lseek( filehandle, RTL_HEADER_OFFSET + mapnum * sizeof( RTLMap ),
+      SEEK_SET );
+   SafeRead( filehandle, &RTLMap, sizeof( RTLMap ) );
+
+    SwapIntelLong((int *)&RTLMap.used);
+    SwapIntelLong((int *)&RTLMap.CRC);
+    SwapIntelLong((int *)&RTLMap.RLEWtag);
+    SwapIntelLong((int *)&RTLMap.MapSpecials);
+    SwapIntelLongArray((int *)&RTLMap.planestart, NUMPLANES);
+    SwapIntelLongArray((int *)&RTLMap.planelength, NUMPLANES);
+
+   if ( !RTLMap.used )
+      {
+      Error( "ReadROTTMap: Tried to load a non existent map!" );
+      }
+
+   #if ( SHAREWARE == 1 )
+      if ( RTLMap.RLEWtag == REGISTERED_TAG )
+         {
+         Error( "Can't use maps from the registered game in shareware version." );
+         }
+
+      if ( RTLMap.RLEWtag != SHAREWARE_TAG )
+         {
+         Error( "Can't use modified maps in shareware version." );
+         }
+   #endif
+
+   mapwidth  = 128;
+   mapheight = 128;
+
+   // Get special map flags
+   MapSpecials = RTLMap.MapSpecials;
+
+   //
+   // load the planes in
+   //
+   expanded = mapwidth * mapheight * 2;
+
+	for( plane = 0; plane <= 2; plane++ )
+      {
+      pos        = RTLMap.planestart[ plane ];
+      compressed = RTLMap.planelength[ plane ];
+		buffer     = SafeMalloc( compressed );
+      lseek( filehandle, pos, SEEK_SET );
+      SafeRead( filehandle, buffer, compressed );
+
+      mapplanes[ plane ] = Z_Malloc( expanded, PU_LEVEL, &mapplanes[ plane ] );
+
+      //
+      // unRLEW, skipping expanded length
+      //
+      #if ( SHAREWARE == 1 )
+         CA_RLEWexpand( ( word * )buffer, ( word * )mapplanes[ plane ],
+            expanded >> 1, SHAREWARE_TAG );
+      #else
+         CA_RLEWexpand( ( word * )buffer, ( word * )mapplanes[ plane ],
+            expanded >> 1, RTLMap.RLEWtag );
+      #endif
+
+		SafeFree( buffer );
+      }
+   close(filehandle);
+
+   //
+   // get map name
+   //
+   strcpy( LevelName, RTLMap.Name );
+   }
+
+
+
+/*
+======================
+=
+= GetNextMap
+=
+======================
+*/
+int GetNextMap ( int tilex, int tiley )
+   {
+   word next;
+   word icon;
+   boolean done;
+
+   next = MAPSPOT( tilex, tiley, 2 );
+   icon = MAPSPOT( tilex, tiley, 1 );
+   done=false;
+   if ( ( ( icon != EXITTILE ) && ( icon != SECRETEXITTILE ) ) ||
+      ( ( ( next&0xff00 ) != 0xe200 ) && ( ( next&0xff00 ) != 0xe400 ) ) )
+      {
+      int i,j;
+
+	   for ( j = 0; j < mapheight; j++ )
+         {
+	      for ( i = 0; i < mapwidth; i++ )
+            {
+            icon = MAPSPOT( i, j, 1 );
+            next = MAPSPOT( i, j, 2 );
+            if ( ( ( icon == EXITTILE ) || ( icon == SECRETEXITTILE ) ) &&
+               ( ( ( next&0xff00 ) == 0xe200 ) ||
+               ( ( next&0xff00 ) == 0xe400 ) ) )
+               {
+               done=true;
+               break;
+               }
+            }
+
+         if ( done == true )
+            {
+            break;
+            }
+         }
+
+      if ( !done )
+         {
+         Error( "GetNextMap : No exit tile on map %d.", gamestate.mapon );
+         }
+      }
+   if ( ( ( next & 0xff00 ) != 0xe200 ) &&
+      ( ( next & 0xff00 ) != 0xe400 ) )
+      {
+      // Should this be DEVELOPMENT only?
+      Error( "GetNextMap : Illegal destination map %xh at exit "
+         "tile on map %d.", next, gamestate.mapon );
+      }
+
+   if ( next == 0xe2ff )
+      {
+      return -1;
+      }
+
+   return ( next & 0xff );
+   }
+
+/*
+======================
+=
+= GetMapFileInfo
+=
+======================
+*/
+void GetMapFileInfo
+   (
+   mapfileinfo_t *mapinfo,
+   char *filename
+   )
+
+   {
+   RTLMAP RTLMap[ 100 ];
+   int    filehandle;
+   int    i;
+   int    nummaps;
+
+   CheckRTLVersion( filename );
+
+   filehandle = SafeOpenRead( filename );
+
+   //
+   // Load map header
+   //
+   lseek( filehandle, RTL_HEADER_OFFSET, SEEK_SET );
+   SafeRead( filehandle, &RTLMap, sizeof( RTLMap ) );
+   close( filehandle );
+
+   nummaps = 0;
+   for( i = 0; i < 100; i++ )
+      {
+      if ( !RTLMap[ i ].used )
+         {
+         continue;
+         }
+
+      mapinfo->maps[ nummaps ].number = i;
+
+      strcpy( mapinfo->maps[ nummaps ].mapname, RTLMap[ i ].Name );
+
+      nummaps++;
+      }
+
+   mapinfo->nummaps = nummaps;
+   }
+
+/*
+======================
+=
+= GetMapFileName
+=
+======================
+*/
+void GetMapFileName ( char * filename )
+{
+   if ( ( BATTLEMODE ) && (BattleLevels.avail == true) )
+      {
+      strcpy(filename,BattleLevels.file);
+      }
+   else if (GameLevels.avail == true)
+      {
+      strcpy(filename,GameLevels.file);
+      }
+   else if ( BATTLEMODE )
+      {
+      strcpy(filename,BATTMAPS);
+      }
+   else
+      {
+      strcpy(filename,ROTTMAPS);
+      }
+}
+
+/*
+======================
+=
+= SetBattleMapFileName
+=
+======================
+*/
+void SetBattleMapFileName ( char * filename )
+{
+   BattleLevels.avail = true;
+   memset (&(BattleLevels.file[0]), 0, sizeof (BattleLevels.file));
+   strcpy (&(BattleLevels.file[0]), filename);
+}
+
+/*
+======================
+=
+= GetMapCRC
+=
+======================
+*/
+word GetMapCRC
+   (
+   int num
+   )
+
+   {
+   int  filehandle;
+   char filename[ 80 ];
+   RTLMAP RTLMap;
+
+   GetMapFileName( &filename[ 0 ] );
+   CheckRTLVersion( filename );
+   filehandle = SafeOpenRead( filename );
+
+   //
+   // Load map header
+   //
+   lseek( filehandle, RTL_HEADER_OFFSET + num * sizeof( RTLMap ), SEEK_SET );
+   SafeRead( filehandle, &RTLMap, sizeof( RTLMap ) );
+
+   close( filehandle );
+
+   return( RTLMap.CRC );
+   }
+
+
+/*
+======================
+=
+= GetAlternateMapInfo
+=
+======================
+*/
+
+void GetAlternateMapInfo (mapfileinfo_t * mapinfo, AlternateInformation *info)
+{
+   if (UL_ChangeDirectory (info->path) == false)
+      Error ("ERROR : Can't change to alternate directory %s!\n", info->path);
+
+   GetMapFileInfo (mapinfo, info->file);
+
+   UL_ChangeDirectory (&CWD[0]);
+}
+
+/*
+======================
+=
+= GetMapInfo
+=
+======================
+*/
+void GetMapInfo
+   (
+   mapfileinfo_t *mapinfo
+   )
+
+   {
+   if ( ( BATTLEMODE ) && ( BattleLevels.avail == true ) )
+      {
+      GetAlternateMapInfo( mapinfo, &BattleLevels );
+      }
+   else if ( GameLevels.avail == true )
+      {
+      GetAlternateMapInfo( mapinfo, &GameLevels );
+      }
+   else if ( BATTLEMODE )
+      {
+      GetMapFileInfo( mapinfo, BATTMAPS );
+      }
+   else
+      {
+      GetMapFileInfo( mapinfo, ROTTMAPS );
+      }
+   }
+
+/*
+======================
+=
+= LoadTedMap
+=
+======================
+*/
+void LoadTedMap
+   (
+   const char *extension,
+   int mapnum
+   )
+
+   {
+   long    pos;
+   long    compressed;
+   long    expanded;
+   int     plane;
+   int     i;
+   int     maphandle;
+   byte   *buffer;
+   maptype mapheader;
+   char    name[ 200 ];
+   mapfiletype *tinf;
+
+   //
+   // load maphead.ext (offsets and tileinfo for map file)
+   //
+   strcpy( name, "maphead." );
+   strcat( name, extension );
+   LoadFile( name, ( void * )&tinf );
+
+   // fix structure alignment
+   tinf = ( void * )( ( word * )tinf - 1 );
+
+   for( i = 0 ; i < 100 ; i++ )
+      {
+      tinf->headeroffsets[ i ] = IntelLong( tinf->headeroffsets[ i ] );
+      }
+
+   //
+   // open the data file
+   //
+   strcpy( name, "maptemp." );
+   strcat( name, extension );
+   maphandle = SafeOpenRead( name );
+
+   //
+   // load map header
+   //
+   pos = tinf->headeroffsets[ mapnum ];
+
+   // $FFFFFFFF start is a sparse map
+   if ( pos < 0 )
+      {
+      Error( "LoadTedMap : Tried to load a non existent map!" );
+      }
+
+   lseek( maphandle, pos, SEEK_SET );
+   SafeRead( maphandle, &mapheader, sizeof( maptype ) );
+
+   for( i = 0 ; i < 3; i++ )
+      {
+      mapheader.planestart[ i ]  = IntelLong( mapheader.planestart[ i ] );
+      mapheader.planelength[ i ] = IntelShort( mapheader.planelength[ i ] );
+      }
+
+   mapheader.width  = IntelShort( mapheader.width );
+   mapheader.height = IntelShort( mapheader.height );
+
+   mapwidth  = mapheader.width;
+   mapheight = mapheader.height;
+
+   // Set special map flags
+   MapSpecials = 0;
+
+   //
+   // load the planes in
+   //
+   expanded = mapheader.width * mapheader.height * 2;
+
+   for( plane = 0; plane <= 2; plane++ )
+      {
+      pos = mapheader.planestart[ plane ];
+      lseek( maphandle, pos, SEEK_SET );
+
+      compressed = mapheader.planelength[ plane ];
+      buffer = SafeMalloc( compressed );
+      SafeRead( maphandle, buffer, compressed );
+
+      mapplanes[ plane ] = Z_Malloc( expanded, PU_LEVEL, &mapplanes[ plane ] );
+
+      //
+      // unRLEW, skipping expanded length
+      //
+      CA_RLEWexpand( ( word * )( buffer + 2 ), ( word * )mapplanes[ plane ],
+         expanded >> 1, 0xabcd );
+
+      SafeFree( buffer );
+      }
+
+   // fix structure alignment
+	tinf = ( void * )( ( word * )tinf + 1 );
+
+	SafeFree( tinf );
+
+   if ( close( maphandle ) )
+      {
+      Error( "Error closing Ted file Error #%d", errno );
+      }
+   }
+
+
+/*
+======================
+=
+= LoadAlternateMap
+=
+======================
+*/
+
+void LoadAlternateMap (AlternateInformation *info, int mapnum)
+{
+   if (UL_ChangeDirectory (info->path) == false)
+      Error ("ERROR : Can't change to alternate directory %s!\n",info->path);
+
+   ReadROTTMap (info->file, mapnum);
+
+   UL_ChangeDirectory (&CWD[0]);
+}
+
+/*
+======================
+=
+= LoadROTTMap
+=
+======================
+*/
+void LoadROTTMap
+   (
+   int mapnum
+   )
+
+   {
+   if ( tedlevel == true )
+      {
+      LoadTedMap( "rot", mapnum );
+      }
+   else if ( ( BATTLEMODE ) && ( BattleLevels.avail == true ) )
+      {
+      LoadAlternateMap( &BattleLevels, mapnum );
+      }
+   else if ( GameLevels.avail == true )
+      {
+      LoadAlternateMap( &GameLevels, mapnum );
+      }
+   else if ( BATTLEMODE )
+      {
+      ReadROTTMap( BATTMAPS, mapnum );
+      }
+   else
+      {
+      ReadROTTMap( ROTTMAPS, mapnum );
+      }
+   }
+
+
+void CountAreaTiles(void)
+{int i,j,areanumber;
+ word*map,tile;
+
+ memset(numareatiles,0,sizeof(numareatiles));
+ map  = mapplanes[0];
+
+ for(i=0;i<MAPSIZE;i++)
+   for(j=0;j<MAPSIZE;j++)
+      {tile = *map++;
+
+       areanumber = tile - AREATILE;
+       if ((areanumber >= 0) && (areanumber <= NUMAREAS))
+         numareatiles[areanumber] ++;
+      }
+
+}
+
+
+
+#define InitWall(lump,index,newx,newy)      \
+   {                                        \
+   PreCacheLump(lump,PU_CACHEWALLS,cache_pic_t);  \
+   if (W_LumpLength(lump) == 0)                   \
+      Error("%s being used in shareware at %d %d",\
+      W_GetNameForNum(lump),newx,newy);           \
+   actorat[newx][newy]= &walls[index];      \
+   tempwall = (wall_t*)actorat[newx][newy]; \
+   tempwall->which = WALL;                  \
+   tempwall->tile = index;                  \
+   }                                        \
+
+
+/*
+==================
+=
+= SetupWalls
+=
+==================
+*/
+void SetupWalls( void )
+   {
+   int   i,j,lump,index;
+	word   *map,tile;
+   wall_t * tempwall;
+
+
+	for (i=0;i<MAXWALLTILES;i++)
+      memset(&walls[i],0,sizeof(wall_t));
+
+	map = mapplanes[0];
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+			{
+         if ((i>=0) && (i<=3) && (j==0))
+			   {
+			   map++;
+			   continue;
+			   }
+			if ((loadedgame == false) && (MAPSPOT(i,j,2) == 0xeeee))
+				{_2Dpoint *tdptr;
+
+				 tdptr = &(MISCVARS->EPOP[MISCVARS->nextpop]);
+				 tdptr->x = i;
+				 tdptr->y = j;
+				 MISCVARS->nextpop ++;
+				 MISCVARS->popsleft ++;
+			   }
+		   tile= *map++;
+
+         if ((tile > 89) ||
+             ((tile > 32) && (tile < 36)) ||
+             (tile == 44) ||
+             (tile == 45) ||
+             (tile == 0)
+            )
+            {
+            tilemap[i][j] = 0;
+            continue;
+            }
+
+         if (tile <= 32)
+            {
+            index = tile;
+#if 0
+            if (tile==12)
+               {
+               if (MAPSPOT(i,j,2)==0)
+                  MAPSPOT(i,j,2)=21;
+               }
+#endif
+            }
+         else
+            index = tile-3;
+
+         if ((tile > 75) && (tile <= 79))
+            {
+            lump = tilemap[i][j] = GetLumpForTile(tile);
+            PreCacheLump(lump,PU_CACHEWALLS,cache_pic_t);
+            PreCacheLump(elevatorstart+5,PU_CACHEWALLS,cache_pic_t);
+            PreCacheLump(elevatorstart+6,PU_CACHEWALLS,cache_pic_t);
+            PreCacheLump(elevatorstart+7,PU_CACHEWALLS,cache_pic_t);
+            tilemap[i][j]|=0x2000;
+            if (MAPSPOT(i,j,2)==0)
+               MAPSPOT(i,j,2)=21;
+            }
+         else if ((tile >= 47) && (tile <= 48))
+            {
+            lump = tilemap[i][j] = GetLumpForTile(tile);
+            InitWall(lump,index,i,j);
+            tilemap[i][j]|=0x2000;
+            if (MAPSPOT(i,j,2)==0)
+               MAPSPOT(i,j,2)=21;
+            }
+         else
+            {
+            lump = tilemap[i][j] = GetLumpForTile(tile);
+            InitWall(lump,index,i,j);
+            if (MAPSPOT(i,j,2))
+               tilemap[i][j]|=0x2000;
+            }
+         }
+      }
+   }
+
+
+/*
+===============
+=
+= GetNearestAreaNumber
+=
+===============
+*/
+word GetNearestAreaNumber ( int tilex, int tiley )
+{
+	int up,dn,lt,rt;
+   int tile;
+
+  	tile=MAPSPOT(tilex,tiley,0)-AREATILE;
+
+  	if ((tile<=NUMAREAS) && (tile>0))
+      return (tile+AREATILE);
+
+	up=MAPSPOT(tilex,tiley-1,0)-AREATILE;
+	dn=MAPSPOT(tilex,tiley+1,0)-AREATILE;
+	lt=MAPSPOT(tilex-1,tiley,0)-AREATILE;
+	rt=MAPSPOT(tilex+1,tiley,0)-AREATILE;
+
+	up = ((up>0) && (up<=NUMAREAS));
+	dn = ((dn>0) && (dn<=NUMAREAS));
+	lt = ((lt>0) && (lt<=NUMAREAS));
+	rt = ((rt>0) && (rt<=NUMAREAS));
+
+	if (rt)
+		return (MAPSPOT(tilex+1,tiley,0) + AREATILE);
+	else if (lt)
+		return (MAPSPOT(tilex-1,tiley,0) + AREATILE);
+	else if (up)
+		return (MAPSPOT(tilex,tiley-1,0) + AREATILE);
+	else if (dn)
+		return (MAPSPOT(tilex,tiley+1,0) + AREATILE);
+//	else
+//		Error("GetNearestAreaNumber: Couldn't fix up area at x=%ld y=%ld\n",tilex,tiley);
+   return (NUMAREAS+AREATILE-1);
+}
+
+/*
+===============
+=
+= SetupWindows
+=
+===============
+*/
+void SetupWindows ( void )
+{
+   int i,j;
+   boolean skythere;
+
+   skythere = SkyExists();
+
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+         {
+         if ((i>=0) && (i<=3) && (j==0))
+			   continue;
+         if (IsWindow(i,j))
+            {
+            actorat[i][j]=0;
+            if (skythere==true)
+               {
+               tilemap[i][j]|=0x2000;
+               }
+            else
+               {
+               MAPSPOT(i,j,2)=0;
+               }
+            MAPSPOT(i,j,0)=(word)(GetNearestAreaNumber(i,j));
+            }
+         }
+      }
+
+}
+
+
+/*
+==================
+=
+= GetWallIndex
+=
+==================
+*/
+
+int GetWallIndex( int texture )
+{
+	int wallstart;
+   int exitstart;
+
+	wallstart=W_GetNumForName("WALLSTRT");
+	exitstart=W_GetNumForName("EXITSTRT");
+	elevatorstart = W_GetNumForName("ELEVSTRT");
+
+   if (texture&0x1000)
+      {
+      texture&=~0x1000;
+      if (texture==0)
+         return 41;
+      else if (texture==1)
+         return 90;
+      else if (texture==2)
+         return 91;
+      else if (texture==3)
+         return 42;
+      else if (texture==4)
+         return 92;
+      else if (texture==5)
+         return 93;
+      else if (texture==6)
+         return 94;
+      else if (texture==7)
+         return 95;
+      else if (texture==8)
+         return 96;
+      else if (texture==9)
+         return 97;
+      else if (texture==10)
+         return 98;
+      else if (texture==11)
+         return 99;
+      else if (texture==12)
+         return 100;
+      else if (texture==13)
+         return 101;
+      else if (texture==14)
+         return 102;
+      else if (texture==15)
+         return 103;
+		else if (texture==16)
+         return 104;
+      }
+   else if (texture > elevatorstart)
+      return (texture - elevatorstart + 68);
+//	else if (texture > specialstart)
+//      return (texture - specialstart + 41);
+   else if (texture > exitstart)
+      return (texture - exitstart + 43);
+   else
+      {
+		if (texture>wallstart+63)
+         return (texture - (wallstart + 63) + 76 );
+      else if (texture>wallstart+40)
+         return (texture - (wallstart + 40) + 45 );
+      else
+         return (texture - wallstart);
+      }
+   return 0x8000;
+}
+
+/*
+==================
+=
+= SetupAnimatedWalls
+=
+==================
+*/
+void SetupAnimatedWalls( void )
+{
+	int   i,j;
+	word   *map,tile;
+   wall_t * tempwall;
+
+	InitAnimatedWallList();
+	map = mapplanes[0];
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+		   {
+         if ((i>=0) && (i<=3) && (j==0))
+			   {
+			   map++;
+			   continue;
+			   }
+			tile= *map++;
+			if (tile == 44)
+			   {
+			   actorat[i][j]= &walls[tile-3];
+			   tempwall = (wall_t*)actorat[i][j];
+			   tempwall->which = WALL;
+			 	tempwall->tile = tile-3;
+			   tempwall->flags = FL_W_DAMAGE;
+    	      SetupAnimatedWall(0);
+				tilemap[i][j]=0;
+            tilemap[i][j]|=0x1000;
+			   }
+			else if (tile == 45)
+			   {
+				actorat[i][j]= &walls[tile-3];
+				tempwall = (wall_t*)actorat[i][j];
+				tempwall->which = WALL;
+				tempwall->tile = tile-3;
+    	      SetupAnimatedWall(3);
+				tilemap[i][j]=3;
+            tilemap[i][j]|=0x1000;
+			   }
+			else if ((tile >= 106) && (tile <= 107))
+			   {
+			   actorat[i][j]= &walls[tile-16];
+			   tempwall = (wall_t*)actorat[i][j];
+			   tempwall->which = WALL;
+			   tempwall->tile = tile-16;
+	         SetupAnimatedWall(tile-105);
+            tilemap[i][j]=tile-105;
+            tilemap[i][j]|=0x1000;
+            }
+			else if ((tile >= 224) && (tile <= 233))
+			   {
+			   actorat[i][j]= &walls[tile-224+92];
+			   tempwall = (wall_t*)actorat[i][j];
+			   tempwall->which = WALL;
+			   tempwall->tile = tile-224+94;
+            if (tile==233)
+               tempwall->flags = FL_W_DAMAGE;
+	         SetupAnimatedWall(tile-224+4);
+            tilemap[i][j]=tile-224+4;
+            tilemap[i][j]|=0x1000;
+            }
+			else if ((tile >= 242) && (tile <= 244))
+				{
+			   actorat[i][j]= &walls[tile-242+102];
+			   tempwall = (wall_t*)actorat[i][j];
+			   tempwall->which = WALL;
+			   tempwall->tile = tile-242+102;
+	         SetupAnimatedWall(tile-242+14);
+            tilemap[i][j]=tile-242+14;
+            tilemap[i][j]|=0x1000;
+            }
+         }
+		}
+}
+
+
+/*
+==================
+=
+= SetupSwitches
+=
+==================
+*/
+
+void SetupSwitches( void )
+{
+	int   i,j;
+	word   *map,tile;
+
+	map = mapplanes[0];
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+		   {
+         if ((i>=0) && (i<=3) && (j==0))
+			   {
+			   map++;
+			   continue;
+			   }
+		   tile= *map++;
+			if ((tile >= 76) && (tile <= 79))
+            {
+				if (tile == 79)
+				   lastswitch->flags |= FL_ON;
+				SpawnSwitchThingy(i,j);
+				}
+			else if ((tile == 157) || (tile == 175)) // hi masked switches
+				{
+				lastswitch->flags |= FL_W_INVERTED;
+				lastswitch->flags |= FL_REVERSIBLE;
+				if (tile==175)
+					lastswitch->flags |= FL_ON;
+				SpawnSwitchThingy(i,j);
+				}
+			}
+		}
+}
+
+
+
+void RespawnPlayerobj(objtype *ob)
+{int rand,numchecked=0;
+ int oldsetupgame,nx,ny,ndir;
+ playertype *pstate;
+
+ M_LINKSTATE(ob,pstate);
+
+ if (gamestate.battlemode != battle_CaptureTheTriad)
+     {
+      rand = (GameRandomNumber("playerobj respawn",0) % NUMSPAWNLOCATIONS);
+
+      while(numchecked < NUMSPAWNLOCATIONS)
+         {
+         if (!actorat[SPAWNLOC[rand].x][SPAWNLOC[rand].y])
+            {RevivePlayerobj(SPAWNLOC[rand].x,SPAWNLOC[rand].y,SPAWNLOC[rand].dir,ob);
+            return;
+            }
+         numchecked ++;
+         rand = (rand + 1) % NUMSPAWNLOCATIONS;
+         }
+#if (DEVELOPMENT == 1)
+      SoftError("\nno spawn locations available, using FindEmptyTile");
+#endif
+      nx = SPAWNLOC[rand].x;
+      ny = SPAWNLOC[rand].y;
+      ndir = SPAWNLOC[rand].dir;
+     }
+ else
+     {nx = TEAM[pstate->team].tilex;
+      ny = TEAM[pstate->team].tiley;
+      ndir = TEAM[pstate->team].dir;
+     }
+
+ oldsetupgame = insetupgame;
+ insetupgame = true;
+ FindEmptyTile(&nx,&ny);
+ insetupgame = oldsetupgame;
+ RevivePlayerobj(nx,ny,ndir,ob);
+
+
+}
+
+#define SetupSpecificFlagTeamAt(whichteam, spawnlocindex) \
+{int newx,newy;                                           \
+                                                          \
+ newx = SPAWNLOC[spawnlocindex].x;                        \
+ newy = SPAWNLOC[spawnlocindex].y;                        \
+ TEAM[whichteam].tilex = newx;                            \
+ TEAM[whichteam].tiley = newy;                            \
+ TEAM[whichteam].dir = SPAWNLOC[spawnlocindex].x;         \
+ SpawnStatic(newx,newy,stat_collector,9);                  \
+ SpawnNewObj(newx,newy,&s_basemarker1,inertobj);          \
+ LASTACTOR->z = LASTSTAT->z;                              \
+ LASTSTAT->flags |= FL_COLORED;                           \
+ LASTSTAT->hitpoints = whichteam;                         \
+ locspawned[spawnlocindex]=1;                             \
+ for(j=0;j<numplayers;j++)                                \
+    {if (PLAYERSTATE[j].uniformcolor !=                   \
+         TEAM[whichteam].uniformcolor)                    \
+        continue;                                         \
+                                                          \
+     ntilex = newx;                                       \
+     ntiley = newy;                                       \
+     FindEmptyTile(&ntilex,&ntiley);                      \
+     SpawnPlayerobj(ntilex,ntiley,dir,j);                 \
+    }                                                     \
+}                                                         \
+
+
+/*
+=============
+=
+= AssignTeams called from SetGameDescription in rt_net.c
+=
+=============
+*/
+
+void AssignTeams(void)
+{int i,color;
+ int teamforcolor[MAXPLAYERCOLORS];
+
+ numteams = 0;
+ if (!gamestate.teamplay)
+    return;
+
+ memset(teamforcolor,-1,sizeof(teamforcolor));
+ memset(TEAM,0,sizeof(TEAM));
+
+ for(i=0;i<numplayers;i++)
+    {color = PLAYERSTATE[i].uniformcolor;
+     if (teamforcolor[color] == -1)
+        {TEAM[numteams].uniformcolor = color;
+
+         TEAM[numteams].nummembers ++;
+         teamforcolor[color] = numteams;
+         numteams++;
+         if ((gamestate.battlemode == battle_CaptureTheTriad) &&
+             (numteams > 2))
+           Error("players selected more colors(%d) than Capture the Triad allows",numteams);
+        }
+     else
+        TEAM[teamforcolor[color]].nummembers ++;
+
+     PLAYERSTATE[i].team = teamforcolor[color];
+
+    }
+
+}
+
+
+
+/*
+=============
+=
+= SetupTeams
+=
+=============
+*/
+
+
+void SetupTeams(void)
+{
+
+  int i,j,rand,sx,sy,ntilex,ntiley,dir,
+      maxdist,currdist,spawnindex,cnt;
+  int locspawned[MAXSPAWNLOCATIONS] = {0};
+
+  if (gamestate.battlemode == battle_CaptureTheTriad)
+        {rand = (GameRandomNumber("net player spawn",0) % NUMSPAWNLOCATIONS);
+
+         for(i=0;i<NUMSPAWNLOCATIONS;i++)
+           {sx = SPAWNLOC[rand].x;
+            sy = SPAWNLOC[rand].y;
+            dir = SPAWNLOC[rand].dir;
+
+            if (CheckTile(sx,sy) && (!IsPlatform(sx,sy)) &&
+               (Number_of_Empty_Tiles_In_Area_Around(sx,sy) > TEAM[0].nummembers)
+               )
+               {SetupSpecificFlagTeamAt(0,rand);
+               break;
+               }
+
+            rand = (rand + 1)%NUMSPAWNLOCATIONS;
+            }
+
+         if (i == NUMSPAWNLOCATIONS)
+            Error("No spawn location available for team 0, capture the flag");
+
+         maxdist = 0x80000000;
+         for(i=0;i<NUMSPAWNLOCATIONS;i++)
+            {if (locspawned[i])
+               continue;
+
+            sx = SPAWNLOC[i].x;
+            sy = SPAWNLOC[i].y;
+            dir = SPAWNLOC[i].dir;
+
+            if ((Number_of_Empty_Tiles_In_Area_Around(sx,sy) < TEAM[1].nummembers)
+               || (!CheckTile(sx,sy) || IsPlatform(sx,sy))
+               )
+               continue;
+
+            currdist = FindDistance(sx-TEAM[0].tilex,sy-TEAM[0].tiley);
+            if (currdist > maxdist)
+               {maxdist = currdist;
+               spawnindex = i;
+               }
+            }
+
+         SetupSpecificFlagTeamAt(1,spawnindex);
+        }
+  else
+     {
+       int badcount = 0,teamindex;
+
+       if (numteams > NUMSPAWNLOCATIONS)
+          Error("More teams than spawn locations !");
+       //cnt =0;
+       //for(rand = 0;rand < NUMSPAWNLOCATIONS;rand++)
+       for(cnt=0;cnt<numteams;)
+          {
+          rand = (GameRandomNumber("team spawn",0) % NUMSPAWNLOCATIONS);
+
+          if (locspawned[rand])
+            continue;
+
+
+          sx = SPAWNLOC[rand].x;
+          sy = SPAWNLOC[rand].y;
+          dir = SPAWNLOC[rand].dir;
+
+          if (Number_of_Empty_Tiles_In_Area_Around(sx,sy) < TEAM[cnt].nummembers)
+             {
+             badcount ++;
+             if (badcount == (NUMSPAWNLOCATIONS - cnt))
+                Error("\n%s team cannot spawn in this level",colorname[TEAM[cnt].uniformcolor]);
+             continue;
+             }
+
+          badcount = 0;
+          //Debug("\n\nSpawn Location %d",rand);
+          //Debug("\n-----------------");
+          TEAM[cnt].tilex = sx;
+          TEAM[cnt].tiley = sy;
+          TEAM[cnt].dir = dir;
+          locspawned[rand]=1;
+          cnt++;
+
+          }
+
+       for(j=0;j<numplayers;j++)
+          {
+          teamindex = PLAYERSTATE[j].team;
+
+          sx = TEAM[teamindex].tilex;
+          sy = TEAM[teamindex].tiley;
+          dir = TEAM[teamindex].dir;
+
+          FindEmptyTile(&sx,&sy);
+
+         //Debug("\n x: %3d, y: %3d",sx,sy);
+          SpawnPlayerobj(sx,sy,dir,j);
+          }
+
+
+     }
+
+
+
+
+//numplayers = 1;
+//Error("Okay");
+#if ((DEVELOPMENT == 1))
+#if (TEAMTEST == 1)
+
+  Debug("Team Spawn Location\n");
+  Debug("-------------------\n");
+  for(i=0;i<numteams;i++)
+    Debug("%d   %3d,%3d\n",i,TEAM[i].tilex,TEAM[i].tiley);
+
+
+  Debug("Player            Team          Location\n");
+  Debug("------            ----          --------\n");
+  for(i=0;i<numplayers;i++)
+    Debug("  %d             %d            %3d,%3d\n",i,PLAYERSTATE[i].team,PLAYER[i]->tilex,PLAYER[i]->tiley);
+
+//  Error("done");
+#endif
+#endif
+
+}
+
+
+/*
+==================
+=
+= SetupPlayers
+=
+==================
+*/
+
+void SetupPlayers( void )
+{
+	int   i,j;
+	word   *map,tile;
+
+	//START in icon plane = 10
+
+	map = mapplanes[1];
+	for(j=0;j<mapheight;j++)
+		for(i=0;i<mapwidth;i++)
+			{
+			tile = *map++;
+			switch (tile)
+				{
+				case 19:
+				case 20:
+				case 21:
+				case 22:
+					FIRST.x = i;
+					FIRST.y = j;
+					FIRST.dir = tile-19;
+					SPAWNLOC[NUMSPAWNLOCATIONS].x  = i;
+					SPAWNLOC[NUMSPAWNLOCATIONS].y  = j;
+					SPAWNLOC[NUMSPAWNLOCATIONS].dir  = tile-19;
+					if (NUMSPAWNLOCATIONS<MAXSPAWNLOCATIONS)
+						NUMSPAWNLOCATIONS ++;
+					break;
+
+				case 274:
+				case 275:
+				case 276:
+				case 277:
+					SPAWNLOC[NUMSPAWNLOCATIONS].x  = i;
+					SPAWNLOC[NUMSPAWNLOCATIONS].y  = j;
+					SPAWNLOC[NUMSPAWNLOCATIONS].dir  = tile-274;
+					if (NUMSPAWNLOCATIONS<MAXSPAWNLOCATIONS)
+						NUMSPAWNLOCATIONS ++;
+					break;
+				}
+
+			}
+
+   if ( NUMSPAWNLOCATIONS <= 0 )
+      {
+      Error( "No spawn locations found on map." );
+      }
+
+   /*modemgame=true;
+   gamestate.teamplay = true;
+   PLAYERSTATE[0].uniformcolor = 2;
+   PLAYERSTATE[1].uniformcolor = 2;
+   numplayers = 2;
+   AssignTeams();*/
+
+   if (!BATTLEMODE)
+		{
+		if (tedlevel)
+			{
+			if ((tedx==0) || (tedy == 0))
+				SpawnPlayerobj (FIRST.x, FIRST.y, FIRST.dir,0);
+			else
+				SpawnPlayerobj(tedx,tedy,FIRST.dir,0);
+			}
+		else
+			SpawnPlayerobj(FIRST.x,FIRST.y,FIRST.dir,0);
+		}
+
+   else if (gamestate.teamplay == true)
+	  SetupTeams();
+
+	else
+      {
+      int rand,cnt,locspawned[MAXSPAWNLOCATIONS]={0};
+      int locsleft;
+
+      locsleft=NUMSPAWNLOCATIONS;
+      for(cnt=0;cnt<numplayers;)
+         {rand = (GameRandomNumber("net player spawn",0) % NUMSPAWNLOCATIONS);
+         if (locsleft==0)
+            {
+            int x,y;
+
+            x=SPAWNLOC[rand].x;
+            y=SPAWNLOC[rand].y;
+            FindEmptyTile(&x,&y);
+            SpawnPlayerobj(x,y,SPAWNLOC[rand].dir,cnt);
+            cnt++;
+            }
+         else if (!locspawned[rand])
+            {SpawnPlayerobj(SPAWNLOC[rand].x,SPAWNLOC[rand].y,SPAWNLOC[rand].dir,cnt);
+            locspawned[rand]=1;
+            locsleft--;
+            cnt++;
+            }
+         }
+		}
+
+	if (gamestate.battlemode == battle_Tag)
+	  {int i;
+		playertype *pstate;
+
+      BATTLE_It = GameRandomNumber("tag choose",0) % numplayers;
+
+		PLAYER[BATTLE_It]->flags |= FL_DESIGNATED;
+		for(i=0;i<numplayers;i++)
+		  {M_LINKSTATE(PLAYER[i],pstate);
+
+			if (i == BATTLE_It)
+			  {pstate->missileweapon = pstate->oldweapon = pstate->new_weapon =
+				pstate->oldmissileweapon = pstate->weapon = wp_godhand;
+				pstate->bulletweapon = -1;
+			  }
+			else
+			  {pstate->missileweapon = pstate->oldweapon = pstate->new_weapon =
+				pstate->oldmissileweapon = pstate->bulletweapon = pstate->weapon = -1;
+			  }
+		  }
+	  }
+
+	PreCachePlayers();
+}
+
+
+
+/*
+==================
+=
+= SetupMaskedWalls
+=
+==================
+*/
+
+void SetupMaskedWalls( void )
+{
+	int   i,j;
+	word   *map,tile;
+
+	map = mapplanes[0];
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+	      {
+         tile = *map++;
+		   if ((tile >= 158) && (tile <= 160)) // Multi glassed walls
+            {
+            SpawnMaskedWall(i,j,mw_multi1+(tile-158),MW_MULTI|MW_BLOCKING|MW_BLOCKINGCHANGES|MW_SHOOTABLE);
+            }
+	      else if ((tile >= 176) && (tile <= 178)) // Multi shot out glassed walls
+            {
+            SpawnMaskedWall(i,j,mw_multi1+(tile-176),MW_BOTTOMPASSABLE);
+            }
+		   else if ((tile >= 162) && (tile <= 171))
+            {
+            switch (tile)
+               {
+               case 162:
+                  SpawnMaskedWall(i,j,mw_normal1,MW_SHOOTABLE|MW_BLOCKING);
+                  break;
+               case 163:
+                  SpawnMaskedWall(i,j,mw_normal1,MW_BLOCKING);
+                  break;
+               case 164:
+                  SpawnMaskedWall(i,j,mw_normal2,MW_SHOOTABLE|MW_BLOCKING);
+                  break;
+               case 165:
+                  SpawnMaskedWall(i,j,mw_normal2,MW_BLOCKING);
+                  break;
+               case 166:
+                  SpawnMaskedWall(i,j,mw_normal3,MW_SHOOTABLE|MW_BLOCKING);
+                  break;
+               case 167:
+                  SpawnMaskedWall(i,j,mw_normal3,MW_BLOCKING);
+                  break;
+               case 168:
+                  SpawnMaskedWall(i,j,mw_singlepane,MW_SHOOTABLE|MW_BLOCKINGCHANGES|MW_BLOCKING);
+                  break;
+               case 169:
+                  SpawnMaskedWall(i,j,mw_singlepane,MW_BOTTOMPASSABLE);
+                  break;
+               case 170:
+                  SpawnMaskedWall(i,j,mw_dogwall,MW_NONDOGBLOCKING|MW_WEAPONBLOCKING);
+                  break;
+               case 171:
+                  SpawnMaskedWall(i,j,mw_peephole,MW_WEAPONBLOCKING|MW_BLOCKING);
+                  break;
+               }
+            }
+         else if (tile == 172)
+            SpawnMaskedWall(i,j,mw_exitarch,MW_BOTTOMPASSABLE);
+         else if (tile == 173)
+            SpawnMaskedWall(i,j,mw_secretexitarch,MW_BOTTOMPASSABLE);
+         else if (tile == 174) // entry gate
+            SpawnMaskedWall(i,j,mw_entrygate,MW_BLOCKING);
+		   else if (tile == 157) // hi switch off
+            SpawnMaskedWall(i,j,mw_hiswitchoff,MW_BLOCKING);
+		   else if (tile == 175) // hi switch on
+            SpawnMaskedWall(i,j,mw_hiswitchon,MW_BLOCKING|MW_SWITCHON);
+		   else if (tile == 179) // railing;
+            SpawnMaskedWall(i,j,mw_railing,MW_ABOVEPASSABLE|MW_MIDDLEPASSABLE);
+//         else if (tile == 161) // pillar
+//            SpawnMaskedWall(i,j,mw_pillar,MW_BLOCKING);
+	      }
+      }
+	for (j=0;j<mapheight;j++)
+	   for(i=0;i<mapwidth;i++)
+			{
+		   if (IsPlatform(i,j)) // tall platform in icon plane
+            {
+            if ((MAPSPOT(i,j,0)-AREATILE>=0) || (MAPSPOT(i,j,0)==21))
+               // check to see we are not on a wall
+               {
+               int which;
+
+               which=MAPSPOT(i,j,2)-4;
+               switch (which)
+                  {
+                  case 0:
+                     SpawnMaskedWall(i,j,mw_platform1,MW_BOTTOMPASSABLE|MW_MIDDLEPASSABLE);
+                     break;
+                  case 1:
+                     SpawnMaskedWall(i,j,mw_platform2,MW_ABOVEPASSABLE|MW_MIDDLEPASSABLE);
+                     break;
+                  case 2:
+                     SpawnMaskedWall(i,j,mw_platform3,MW_MIDDLEPASSABLE);
+                     break;
+                  case 3:
+                     SpawnMaskedWall(i,j,mw_platform4,MW_BOTTOMPASSABLE);
+                     break;
+                  case 4:
+                     SpawnMaskedWall(i,j,mw_platform5,MW_BOTTOMPASSABLE|MW_ABOVEPASSABLE);
+                     break;
+                  case 5:
+                     SpawnMaskedWall(i,j,mw_platform6,MW_ABOVEPASSABLE);
+                     break;
+                  case -3:
+                     SpawnMaskedWall(i,j,mw_platform7,MW_ABOVEPASSABLE);
+                     break;
+                  default:
+                     Error ("Illegal Maskedwall platform value at x=%d y=%d\n",i,j);
+                     break;
+						}
+#if 0
+               if (IsPlatform(i+1,j))
+                  {
+                  if ( (IsPlatform(i,j+1)) || (IsPlatform(i,j-1)) )
+			            SpawnStatic(i,j,83,MAPSPOT(i,j,2));
+                  }
+               else if (IsPlatform(i-1,j))
+                  {
+                  if ( (IsPlatform(i,j+1)) || (IsPlatform(i,j-1)) )
+			            SpawnStatic(i,j,83,MAPSPOT(i,j,2));
+                  }
+#endif
+               }
+            else
+               Error("You have what appears to be a platform ontop\n a wall at x=%d y=%d\n",i,j);
+            }
+         }
+}
+
+/*
+int GetAreaNumber ( int tilex, int tiley, int dir );
+void RemoveDangerWalls
+   (
+   void
+   )
+
+   {
+   int   i;
+   int   j;
+   word *map;
+   word  tile;
+
+   map = mapplanes[ 1 ];
+
+   for( j = 0; j < mapheight; j++ )
+      {
+      for( i = 0; i < mapwidth; i++ )
+	      {
+         tile = *map++;
+         switch( tile )
+		      {
+            case 256:
+		      case 257:
+		      case 258:
+		      case 259:
+               if ( MAPSPOT( i, j, 2 ) == 0 )
+                  {
+                  MAPSPOT( i, j, 0 ) = ( word )( GetAreaNumber( i, j,
+                     ( tile - 256 ) << 1 ) + AREATILE );
+                  MAPSPOT( i, j, 1 ) = 0;
+                  }
+		         break;
+
+            case 300:
+		      case 318:
+		      case 336:
+		      case 354:
+               if ( MAPSPOT( i, j, 2 ) == 0 )
+                  {
+                  MAPSPOT( i, j, 0 ) = ( word )( GetAreaNumber( i, j,
+                     ( ( tile - 300 ) / 9 ) + AREATILE ) );
+                  MAPSPOT( i, j, 1 ) = 0;
+                  }
+		         break;
+            }
+         }
+      }
+   }
+*/
+
+
+/*
+==================
+=
+= SetupPushWalls
+=
+==================
+*/
+
+void SetupPushWalls( void )
+{
+	int   i,j;
+	word   *map,tile;
+	int   temp;
+
+   map = mapplanes[1];
+   for(j=0;j<mapheight;j++)
+      {
+    	for(i=0;i<mapwidth;i++)
+	      {
+         tile = *map++;
+	      switch(tile)
+		      {
+            case 72:
+            case 73:
+            case 74:
+            case 75:
+            case 76:
+            case 77:
+            case 78:
+            case 79:
+					if (tilemap[i][j] && ActorIsWall(i,j))
+		            {
+                  temp=tilemap[i][j]&0x1fff;
+			         tilemap[i][j] = pwallnum;
+			         if (MAPSPOT(i,j,2))
+			            SpawnPushWall(i,j,1,temp,tile-72,0);
+			         else
+			            SpawnPushWall(i,j,0,temp,tile-72,0);
+			         }
+		         break;
+
+		      case 80: //OldPushWall
+		         if (tilemap[i][j])
+		            {
+                  temp=tilemap[i][j]&0x1fff;
+			         tilemap[i][j] = pwallnum;
+			         if (MAPSPOT(i,j,2))
+                     Error("You cannot link a pushwall which has no direction associated\n with it at x=%d y=%d\n",i,j);
+						else
+			            SpawnPushWall(i,j,0,temp,nodir,0);
+			         }
+			      break;
+
+
+            case 256:
+		      case 257:
+		      case 258:
+		      case 259:
+               if (tilemap[i][j])
+			         {
+                  temp=tilemap[i][j]&0x1fff;
+			         tilemap[i][j] = pwallnum;
+			         if (MAPSPOT(i,j,2))
+			            SpawnPushWall(i,j,0,temp,(tile-256)<<1,2);
+                  else
+			            SpawnPushWall(i,j,0,temp,(tile-256)<<1,4);
+                  }
+               else
+                  Error("You have to place a turbomovewall icon on a wall at x=%d y=%d",i,j);
+		         break;
+
+            case 300:
+		      case 318:
+		      case 336:
+		      case 354:
+		         if (tilemap[i][j])
+			         {
+                  temp=tilemap[i][j]&0x1fff;
+			         tilemap[i][j] = pwallnum;
+			         if (MAPSPOT(i,j,2))
+							SpawnPushWall(i,j,0,temp,(tile-300)/9,1);
+                  else
+  	                  SpawnPushWall(i,j,0,temp,(tile-300)/9,3);
+                  }
+               else
+                  Error("You have to place a movewall icon on a wall at x=%d y=%d",i,j);
+		         break;
+            }
+         }
+      }
+}
+
+
+/*
+==================
+=
+= GetPushWallNumber
+=
+==================
+*/
+
+int GetPushWallNumber( int tx, int ty )
+{
+   int i;
+
+   for (i=0;i<pwallnum;i++)
+      if ( (pwallobjlist[i]->tilex==tx) && (pwallobjlist[i]->tiley==ty))
+         return i;
+   Error ("Could not find a push wall at x=%d y=%d\n",tx,ty);
+   return -1;
+}
+
+
+/*
+==================
+=
+= SetupPushWallLinks
+=
+==================
+*/
+void SetupPushWallLinks( void )
+{
+	int   i,j;
+	word   *map,tile;
+   word  touchx,touchy;
+
+   map = mapplanes[1];
+   for(j=0;j<mapheight;j++)
+      {
+    	for(i=0;i<mapwidth;i++)
+	      {
+         tile = *map++;
+	      switch(tile)
+		      {
+            case 72:
+            case 73:
+            case 74:
+            case 75:
+            case 76:
+            case 77:
+            case 78:
+            case 79:
+		         if (ActorIsPushWall(i,j))
+		            {
+			         if (MAPSPOT(i,j,2))
+			            {
+                     touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff);
+							touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff);
+				         if (touchindices[touchx][touchy])
+                        {
+                        if (MAPSPOT(i,j+1,2)!=0)
+                           {
+#if (DEVELOPMENT == 1)
+                           SoftError("MAPWARNING:You left a delay for a linked push wall under the pushwall\n at x=%ld y=%ld\n",i,j);
+#endif
+                           }
+								Link_To_Touchplate(touchx,touchy,ActivatePushWall,NULL,GetPushWallNumber(i,j),0);
+                        }
+				         else
+				            Error("tried to link a pushwall at x=%d y=%d to a non-existent touchplate\n",i,j);
+			            }
+			         }
+		         break;
+
+            case 80:
+		         if (ActorIsPushWall(i,j))
+		            {
+			         if (MAPSPOT(i,j,2))
+			            {
+                     Error("You shouldn't be linking a nondirectional-push wall at x=%d y=%d\n",i,j);
+                     }
+                  }
+               break;
+            case 256:
+		      case 257:
+		      case 258:
+		      case 259:
+		         if (ActorIsPushWall(i,j))
+			         {
+						if (MAPSPOT(i,j,2))
+			            {
+                     touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff);
+				         touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff);
+				         if (touchindices[touchx][touchy])
+                        {
+                        if (MAPSPOT(i,j+1,2)!=0)
+                           {
+#if (DEVELOPMENT == 1)
+                           SoftError("MAPWARNING:You left a delay for a linked push wall under the pushwall\n at x=%ld y=%ld\n",i,j);
+#endif
+                           }
+								Link_To_Touchplate(touchx,touchy,ActivateMoveWall,NULL,GetPushWallNumber(i,j),0);
+                        }
+				         else
+				            Error("tried to link a turbomovewall at x=%d y=%d to a non-existent touchplate\n",i,j);
+                     }
+                  }
+		         break;
+
+            case 300:
+		      case 318:
+		      case 336:
+		      case 354:
+		         if (ActorIsPushWall(i,j))
+			         {
+			         if (MAPSPOT(i,j,2))
+			            {
+                     touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff);
+				         touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff);
+				         if (touchindices[touchx][touchy])
+                        {
+								if (MAPSPOT(i,j+1,2)!=0)
+                           {
+#if (DEVELOPMENT == 1)
+                           SoftError("MAPWARNING:You left a delay for a linked push wall under the pushwall\n at x=%ld y=%ld\n",i,j);
+#endif
+                           }
+								Link_To_Touchplate(touchx,touchy,ActivateMoveWall,NULL,GetPushWallNumber(i,j),0);
+                        }
+				         else
+				            Error("tried to link a movewall at x=%d y=%d to a non-existent touchplate\n",i,j);
+                     }
+                  }
+		         break;
+            }
+         }
+      }
+}
+
+/*
+=================
+=
+= SetupElevators
+=
+=================
+*/
+
+void SetupElevators (void)
+{
+	int j, i,x,y,starti;
+	word *map;
+	word tile;
+	elevator_t *elev;
+	doorobj_t* dptr;
+
+	map = mapplanes[1];
+	map += 4 ;
+
+	for (j = 0; j < mapheight; j++)
+	{
+		if (j == 0)
+			starti = 4;
+		else
+			starti = 0;
+
+		for (i = starti; i < mapwidth; i++)
+		  {tile = *map++;
+
+			if ((tile > 89) && (tile < 98))
+				{elev = &ELEVATOR[tile-90];
+				 if (!elev->sx)
+					{elev->sx = i;
+					 elev->sy = j;
+					 elev->doortoopen = -1;
+					 elev->doorclosing = -1;
+					 elev->nextaction = -1;
+					 _numelevators ++;
+					}
+				 else
+					{elev->dx = i;
+					 elev->dy = j;
+					}
+				}
+		  }
+	  }
+
+	if (_numelevators && (!ELEVATOR[0].sx))
+	 Error("Elevators must start at 1, dumb ass.");
+
+	for(i=0;i<_numelevators;i++)
+	  {elev = &ELEVATOR[i];
+		x = elev->sx;
+		y = elev->sy;
+		for(j=0;j<doornum;j++)
+		  {dptr = doorobjlist[j];
+			if (((dptr->tilex == (x+1)) && (dptr->tiley == y)) ||
+				 ((dptr->tilex == (x-1)) && (dptr->tiley == y)) ||
+				 ((dptr->tilex == x) && (dptr->tiley == (y+1))) ||
+				 ((dptr->tilex == x) && (dptr->tiley == (y-1))))
+			  {elev->door1 = j;
+				dptr->eindex = i;
+				if ((dptr->tilex == (x+1)) && (dptr->tiley == y))
+				  {elev->esx = x-1;
+					elev->esy = y;
+				  }
+				else if ((dptr->tilex == (x-1)) && (dptr->tiley == y))
+				  {elev->esx = x+1;
+					elev->esy = y;
+				  }
+				else if ((dptr->tilex == x) && (dptr->tiley == (y+1)))
+				  {elev->esx = x;
+					elev->esy = y-1;
+				  }
+				else if ((dptr->tilex == x) && (dptr->tiley == (y-1)))
+				  {elev->esx = x;
+					elev->esy = y+1;
+				  }
+				break;
+			  }
+		  }
+
+		x = elev->dx;
+		y = elev->dy;
+		for(j=0;j<doornum;j++)
+		  {dptr = doorobjlist[j];
+			if (((dptr->tilex == (x+1)) && (dptr->tiley == y)) ||
+				 ((dptr->tilex == (x-1)) && (dptr->tiley == y)) ||
+				 ((dptr->tilex == x) && (dptr->tiley == (y+1))) ||
+				 ((dptr->tilex == x) && (dptr->tiley == (y-1))))
+			  {elev->door2 = j;
+				dptr->eindex = i;
+				dptr->flags |= DF_ELEVLOCKED;
+				if ((dptr->tilex == (x+1)) && (dptr->tiley == y))
+				  {elev->edx = x-1;
+					elev->edy = y;
+				  }
+				else if ((dptr->tilex == (x-1)) && (dptr->tiley == y))
+				  {elev->edx = x+1;
+					elev->edy = y;
+				  }
+				else if ((dptr->tilex == x) && (dptr->tiley == (y+1)))
+				  {elev->edx = x;
+					elev->edy = y-1;
+				  }
+				else if ((dptr->tilex == x) && (dptr->tiley == (y-1)))
+				  {elev->edx = x;
+					elev->edy = y+1;
+				  }
+				break;
+			  }
+
+		  }
+	  }
+  #if ((DEVELOPMENT == 1))
+  #if ((ELEVATORTEST == 1))
+	 for(i=0;i<_numelevators;i++)
+		Debug("\nelevator %d door1 %2d, door2 %2d",i,ELEVATOR[i].door1,ELEVATOR[i].door2);
+  #endif
+  #endif
+}
+
+
+/*
+=================
+=
+= SetupDoors
+=
+=================
+*/
+
+void SetupDoors (void)
+{
+   int j, i;
+   word *map;
+	word tile;
+   byte locked;
+
+   map = mapplanes[0];
+
+   for (j = 0; j < mapheight; j++)
+      for (i = 0; i < mapwidth; i++)
+      {
+         tile = *map++;
+
+         if ((tile >= 33) && (tile <= 35))
+         {
+            tilemap[i][j] = doornum;
+
+            locked=0;
+            if (MAPSPOT (i, j, 2))
+               locked = 5;
+
+            SpawnDoor (i, j, locked, (tile-33)+15);
+         }
+
+         else if ((tile > 89) && (tile < 94))
+         {
+            tilemap[i][j] = doornum;
+
+            locked = 0;
+            if (MAPSPOT (i, j, 2))
+               locked = 5;
+
+            SpawnDoor (i, j, locked, tile-90);
+         }
+
+         else if ((tile > 93) && (tile < 98))
+         {
+            Error("locked door %d being used at %d,%d",tile,i,j);
+         }
+
+
+         else if ((tile > 97) && (tile < 105))
+         {
+            tilemap[i][j] = doornum;
+
+            locked = 0;
+            if (MAPSPOT (i, j, 2))
+               locked = 5;
+
+            SpawnDoor (i, j, locked, tile-90);
+         }
+         else if ((tile >= 154) && (tile <= 156))
+         {
+            tilemap[i][j] = doornum;
+
+            locked=0;
+            if (MAPSPOT (i, j, 2))
+               locked = 5;
+
+            SpawnDoor (i, j, locked, (tile-154)+18);
+         }
+      }
+}
+
+/*
+==================
+=
+= GetDoorNumber
+=
+==================
+*/
+
+int GetDoorNumber( int tx, int ty )
+{
+   int i;
+
+   for (i=0;i<doornum;i++)
+      if ( (doorobjlist[i]->tilex==tx) && (doorobjlist[i]->tiley==ty))
+         return i;
+   Error ("Could not find a door at x=%d y=%d\n",tx,ty);
+   return -1;
+}
+
+/*
+=================
+=
+= SetupDoorLinks
+=
+=================
+*/
+
+void SetupDoorLinks (void)
+{
+   int  j,
+        i,
+        k;
+   word *map;
+   int  clocklinked;
+   int  clockx,clocky;
+   int  doornumber;
+	word touchx,
+        tile,
+		  touchy;
+
+   map = mapplanes[0];
+
+   for (j = 0; j < mapheight; j++)
+      for (i = 0; i < mapwidth; i++)
+      {
+         tile = *map++;
+
+         if (MAPSPOT (i, j, 2))
+         {
+            if (IsDoor(i,j)==1)
+            {
+               clocklinked = 0;
+
+               doornumber=GetDoorNumber(i,j);
+
+               for (k = 0; k < numclocks; k++)
+               {
+                  clockx = Clocks[k].points_to_tilex;
+                  clocky = Clocks[k].points_to_tiley;
+
+                  if ((clockx == i) && (clocky == j))
+                  {
+                     clocklinked = 1;
+                     ClockLink (LinkedOpenDoor, LinkedCloseDoor, doornumber, k);
+                     doorobjlist[doornumber]->lock   = 5;
+                     doorobjlist[doornumber]->flags |= DF_TIMED;
+                  }
+               }
+
+               if (!clocklinked)
+					{
+                  touchx = (word) ((MAPSPOT (i, j, 2) >> 8) & 0xff);
+                  touchy = (word) ((MAPSPOT (i, j, 2) >> 0) & 0xff);
+
+                  if (touchindices[touchx][touchy])
+                  {
+							if (MAPSPOT (i, j, 1) == 192)
+								Link_To_Touchplate (touchx, touchy, LinkedCloseDoor,
+                                            LinkedCloseDoor, doornumber, 0);
+							else
+								Link_To_Touchplate (touchx, touchy, LinkedOpenDoor,
+                                            LinkedOpenDoor, doornumber, 0);
+                  }
+                  else
+                     Error ("tried to link a door at x=%d y=%d to a non-existent touchplate",i,j);
+               }
+            }
+         }
+      }
+}
+
+
+/*
+=================
+=
+= FindTimeTile
+=
+=================
+*/
+void FindTimeTile ( int * x, int * y )
+{
+  int xx,yy;
+
+  xx=*x;
+  yy=*y;
+
+  if (!(tilemap[xx+1][yy]) && MAPSPOT(xx+1,yy,2))
+     {
+     *x=xx+1;
+     return;
+     }
+  if (!(tilemap[xx-1][yy]) && MAPSPOT(xx-1,yy,2))
+     {
+     *x=xx-1;
+     return;
+     }
+  if (!(tilemap[xx][yy+1]) && MAPSPOT(xx,yy+1,2))
+     {
+     *y=yy+1;
+     return;
+     }
+  if (!(tilemap[xx][yy-1]) && MAPSPOT(xx,yy-1,2))
+     {
+     *y=yy-1;
+     return;
+     }
+  Error ("Could not find an end time for a clock linked item\nat x=%d y=%d\n",*x,*y);
+}
+
+
+
+/*
+=================
+=
+= SetupClocks
+=
+=================
+*/
+
+void SetupClocks (void)
+{
+   int  i,
+        j,
+        minutes,
+        seconds,
+        starti;
+   word *map,
+        tile,
+        mapx,
+        mapy;
+   int  endtimex,
+        endtimey;
+
+
+   map  = mapplanes[1];
+	map += 4 ;
+
+   for (j = 0; j < mapheight; j++)
+   {
+      if (j == 0)
+         starti = 4;
+      else
+         starti = 0;
+
+      for (i = starti; i < mapwidth; i++)
+      {
+			tile = *map++;
+
+         if (tile == 121)
+         {
+            mapx = (word) ((MAPSPOT (i, j, 2) >> 8) & 0xff);
+            mapy = (word) ((MAPSPOT (i, j, 2) >> 0) & 0xff);
+
+            minutes = (int) ((MAPSPOT (mapx, mapy, 2) >> 8) & 0xff);
+            seconds = (int) ((MAPSPOT (mapx, mapy, 2) >> 0) & 0xff);
+
+            if (seconds > 0x59)
+               Error ("seconds of clock time must be below 0x5a (60 secs) ");
+
+            seconds = 10 * (seconds/16) + (seconds % 16);
+            minutes = 60 * (10*(minutes/16) + (minutes % 16));
+
+            // total seconds
+            Clocks[numclocks].time1 = VBLCOUNTER*(seconds + minutes);
+
+            endtimex=mapx;
+            endtimey=mapy;
+
+            FindTimeTile (&endtimex, &endtimey);
+
+            minutes = (int) ((MAPSPOT (endtimex, endtimey, 2) >> 8) & 0xff);
+            seconds = (int) ((MAPSPOT (endtimex, endtimey, 2) >> 0) & 0xff);
+
+            if (seconds > 0x59)
+                  Error("seconds of clock time must be below 0x5a (60 secs)");
+
+            seconds = 10 * (seconds/16) + (seconds % 16);
+            minutes = 60 * (10*(minutes/16) + (minutes % 16));
+
+            // total seconds
+            Clocks[numclocks].time2 = VBLCOUNTER * (seconds + minutes);
+            Clocks[numclocks].points_to_tilex = mapx;
+            Clocks[numclocks].points_to_tiley = mapy;
+            Clocks[numclocks].linkindex       = lasttouch;
+
+            numclocks ++;
+
+				// clocks treated as virtual touchplates
+				lasttouch ++;
+			}
+		}
+	}
+}
+
+
+
+/*
+=================
+=
+= LinkElevatorDiskGroups
+=
+=================
+*/
+
+void LinkElevatorDiskGroups(void)
+   {
+   objtype *diskfinder1,*temp,*master;
+   int maxplatformheight[30]={-1};
+   int num_distinct_max_heights=0;
+   int i;
+   boolean newdiskheight;
+
+
+ #define M_ISELEVDISK(actor) \
+    ((actor->obclass == diskobj) && (actor->state == &s_elevdisk))
+
+
+
+   for(diskfinder1 = FIRSTACTOR;diskfinder1;diskfinder1 = diskfinder1->next)
+      {
+      if (!M_ISELEVDISK(diskfinder1))
+         continue;
+
+      newdiskheight = true;
+      for(i=0;i<num_distinct_max_heights;i++)
+         {
+         if (maxplatformheight[i] == diskfinder1->temp2)
+            {
+            newdiskheight = false;
+            break;
+            }
+         }
+
+      if (newdiskheight == true)
+         maxplatformheight[num_distinct_max_heights++] = diskfinder1->temp2;
+
+      }
+
+
+   for(i=0;i<num_distinct_max_heights;i++)
+      {
+
+      SpawnDisk(64,64,0,true);
+      master = new;
+      master->temp2 = maxplatformheight[i];
+
+      for(temp = FIRSTACTOR;temp;temp = temp->next)
+         {
+         if (temp == master)
+            continue;
+
+         if (!M_ISELEVDISK(temp))
+            continue;
+
+         if (temp->temp2 != maxplatformheight[i])
+            continue;
+
+         temp->target = master;
+         SetTilePosition(master,temp->tilex,temp->tiley);
+         master->areanumber=AREANUMBER(master->tilex,master->tiley);
+
+         }
+      master->flags |= FL_ABP;
+      MakeActive(master);
+      }
+
+
+   }
+
+
+/*
+=================
+=
+= LinkActor
+=
+=================
+*/
+
+
+void LinkActor (objtype *ob,int tilex,int tiley,
+                void (*action)(long),void (*swapaction)(long)
+               )
+   {
+	word  touchx,touchy;
+	int   clockx,clocky;
+   int   clocklinked,k;
+	wall_t * tswitch;
+
+
+   clocklinked = 0;
+   for(k=0;k<numclocks;k++)
+      {
+      clockx = Clocks[k].points_to_tilex;
+      clocky = Clocks[k].points_to_tiley;
+      if ((clockx == tilex) && (clocky == tiley))
+         {
+         clocklinked = 1;
+         ClockLink(EnableObject,DisableObject,(long)ob,k);
+         }
+      }
+
+   if (!clocklinked)
+      {
+      touchx = (word) ((MAPSPOT(tilex,tiley,2) >> 8) & 0xff);
+      touchy = (word) ((MAPSPOT(tilex,tiley,2) >> 0) & 0xff);
+      if ((MISCVARS->TOMLOC.x == touchx) && (MISCVARS->TOMLOC.y == touchy))
+         {
+         objtype *tom = (objtype*)actorat[touchx][touchy];
+         tom->whatever = ob;
+         }
+
+      else if (touchindices[touchx][touchy])
+         {
+         tswitch = (wall_t*) actorat[touchx][touchy];
+
+         if (tswitch && (ob->obclass == wallfireobj))
+            {
+            tswitch->flags |= FL_REVERSIBLE;
+            if (tswitch->flags & FL_ON)
+               ob->flags |= FL_ACTIVE;
+            }
+
+
+         if (tswitch && (tswitch->flags & FL_ON))
+            Link_To_Touchplate(touchx,touchy,swapaction,action,(long)ob,0);
+         else
+            Link_To_Touchplate(touchx,touchy,action,swapaction,(long)ob,0);
+         if (ob->obclass == gasgrateobj)
+            {
+            ob->temp1 = touchx;
+            ob->temp2 = touchy;
+            }
+         }
+      else
+         Error("tried to link an object at x=%d y=%d to a non-existent touchplate supposedly at x=%d y=%d",tilex,tiley,touchx,touchy);
+      }
+
+   if (tilemap[tilex][tiley])
+      (MAPSPOT(tilex,tiley,2))=21;
+   }
+
+
+
+
+/*
+======================
+=
+= SetupInanimateActors
+=
+======================
+*/
+
+
+void SetupInanimateActors (void)
+   {
+   int   i,j,linked;
+	word   *map,tile;
+	void (*action)(long),(*swapaction)(long);
+
+
+   map = mapplanes[1];
+
+
+   // non-linked, harmless inanimate actors
+   for(j=0;j<mapheight;j++)
+      {
+      for(i=0;i<mapwidth;i++)
+         {
+         tile = *map++;
+
+         switch(tile)
+            {
+
+            case 193:
+               SpawnSpring(i,j);
+               break;
+
+#if 0
+            case 460:
+//               if ( gamestate.Product != ROTT_SHAREWARE )
+                  {
+                  SpawnNewObj(i,j,&s_wind,inertobj);
+                  }
+               break;
+#endif
+
+            case 462:
+            case 463:
+            case 464:
+            case 465:
+            case 466:
+
+               SpawnDisk(i,j,tile-462,false);
+               break;
+
+            case 285:
+            case 286:
+            case 287:
+               SpawnPushColumn(i,j,tile-285,nodir,0);
+               break;
+            }
+         }
+      }
+
+
+   // linked, harmless actors
+   map = mapplanes[1];
+   for(j=0;j<mapheight;j++)
+      {
+      for(i=0;i<mapwidth;i++)
+         {
+         tile = *map++;
+         action = EnableObject;
+         swapaction = DisableObject;
+         linked = (MAPSPOT(i,j,2) && (!IsPlatform(i,j)));
+
+
+         switch(tile)
+            {
+
+            case 140:
+            case 141:
+            case 142:
+            case 143:
+
+               if ((!BATTLEMODE) || (gamestate.BattleOptions.SpawnDangers))
+                  {
+                  PreCacheActor(wallfireobj,0);
+                  SpawnWallfire(i,j,tile-140);
+                  if (!linked)
+                     {
+                     new->flags |= FL_ACTIVE;
+                     if (tilemap[i][j])
+                        MAPSPOT(i,j,2) = 21;
+                     }
+                  else
+                     LinkActor(new,i,j,action,swapaction);
+                  }
+               else if (tilemap[i][j])
+                  MAPSPOT(i,j,2) = 21;
+
+               break;
+
+
+
+
+
+            case 303:
+            case 304:
+            case 305:
+               SpawnPushColumn(i,j,tile-303,east,linked);
+               swapaction = NULL;
+               if (linked)
+                  LinkActor(new,i,j,action,swapaction);
+
+               break;
+
+            case 321:
+            case 322:
+            case 323:
+               SpawnPushColumn(i,j,tile-321,north,linked);
+               swapaction = NULL;
+               if (linked)
+                  LinkActor(new,i,j,action,swapaction);
+
+               break;
+
+            case 339:
+            case 340:
+            case 341:
+               SpawnPushColumn(i,j,tile-339,west,linked);
+               swapaction = NULL;
+               if (linked)
+                  LinkActor(new,i,j,action,swapaction);
+
+               break;
+
+            case 357:
+            case 358:
+            case 359:
+               SpawnPushColumn(i,j,tile-357,south,linked);
+               swapaction = NULL;
+               if (linked)
+                  LinkActor(new,i,j,action,swapaction);
+
+               break;
+
+
+            }
+
+         }
+      }
+
+   //harmful actors
+
+   if ((!BATTLEMODE) || (gamestate.BattleOptions.SpawnDangers))
+      {
+      map = mapplanes[1];
+      for(j=0;j<mapheight;j++)
+         {
+         for(i=0;i<mapwidth;i++)
+            {
+            tile = *map++;
+            action = EnableObject;
+            swapaction = DisableObject;
+            linked = (MAPSPOT(i,j,2) && (!IsPlatform(i,j)));
+
+            switch(tile)
+               {
+               case 89:
+                  SpawnFourWayGun(i,j);
+                  break;
+
+
+               case 156:
+               case 157:
+                  SpawnBlade(i,j,nodir,0,tile-156);
+                  if (linked)
+                     LinkActor(new,i,j,action,swapaction);
+
+                  break;
+
+               case 174:
+               case 175:
+                  SpawnBlade(i,j,nodir,1,tile-174);
+                  if (linked)
+                     LinkActor(new,i,j,action,swapaction);
+
+                  break;
+
+
+
+               case 412:
+                  SpawnSpear(i,j,0);
+                  break;
+
+               case 430:
+                  SpawnSpear(i,j,1);
+                  break;
+
+               case 413:
+                  SpawnCrushingColumn(i,j,1); //down
+                  break;
+
+               case 431:
+                  SpawnCrushingColumn(i,j,0); // up
+                  break;
+
+
+               case 192:
+                  if (!tilemap[i][j])
+                     {
+                     SpawnNewObj(i,j,&s_gas1,gasgrateobj);
+                     PreCacheActor(gasgrateobj,0);
+                     new->flags |= FL_ABP;
+                     MakeActive(new);
+                     swapaction = NULL;
+                     if (linked)
+                        LinkActor(new,i,j,action,swapaction);
+
+                     }
+                  break;
+
+
+               case 301:
+               case 302:
+                  SpawnBlade(i,j,east,tile-301,0);
+                  if (!linked)
+                     new->flags |= FL_ACTIVE;
+                  else
+                     LinkActor(new,i,j,action,swapaction);
+
+                  break;
+
+               case 319:
+               case 320:
+                  SpawnBlade(i,j,north,tile-319,0);
+                  if (!linked)
+                     new->flags |= FL_ACTIVE;
+                  else
+                     LinkActor(new,i,j,action,swapaction);
+
+                  break;
+
+               case 337:
+               case 338:
+                  SpawnBlade(i,j,west,tile-337,0);
+                  if (!linked)
+                     new->flags |= FL_ACTIVE;
+                  else
+                     LinkActor(new,i,j,action,swapaction);
+
+                  break;
+
+               case 355:
+               case 356:
+                  SpawnBlade(i,j,south,tile-355,0);
+                  if (!linked)
+                     new->flags |= FL_ACTIVE;
+                  else
+                     LinkActor(new,i,j,action,swapaction);
+
+                  break;
+
+               case 372:
+                  SpawnFirejet(i,j,nodir,0);
+                  break;
+
+               case 373:
+               case 374:
+               case 375:
+               case 376:
+                  SpawnFirejet(i,j,tile-373,0);
+                  break;
+
+               case 390:
+                  SpawnFirejet(i,j,nodir,1);
+                  break;
+
+               case 391:
+               case 392:
+               case 393:
+               case 394:
+                  SpawnFirejet(i,j,tile-391,1);
+                  break;
+
+               case 278:
+               case 279:
+               case 280:
+               case 281:
+                  SpawnBoulder(i,j,tile-278);
+                  if (!linked)
+                     new->flags |= FL_ACTIVE;
+                  else
+                     LinkActor(new,i,j,action,swapaction);
+
+                  break;
+
+               }
+
+
+            }
+         }
+      }
+
+   LinkElevatorDiskGroups();
+
+   }
+
+
+/*
+===================
+=
+= FixTiles
+=
+===================
+*/
+
+void FixTiles(void)
+   {
+   word *map,tile;
+   int i,j;
+
+   map = mapplanes[1];
+   for(j=0;j<mapheight;j++)
+      {
+      for(i=0;i<mapwidth;i++)
+         {
+         tile = *map++;
+         switch(tile)
+            {
+            case 140:
+            case 141:
+            case 142:
+            case 143:
+            case 192:
+            case 278:
+            case 279:
+            case 280:
+            case 281:
+               if (tilemap[i][j])
+                  (MAPSPOT(i,j,2))=21;
+               break;
+            }
+         }
+      }
+
+   }
+
+
+void Illuminate(void)
+{statobj_t*temp;
+
+ if (lightsource==0)
+    return;
+ for(temp=FIRSTSTAT;temp;temp=temp->statnext)
+	if (temp->flags & FL_LIGHTON)
+	  TurnOnLight(temp->tilex,temp->tiley);
+}
+
+
+/*
+=================
+=
+= SetupLights
+=
+=================
+*/
+void SetupLights(void)
+{
+	int i,j,touchx,touchy;
+	wall_t *tswitch;
+	word *map,tile;
+	int starti;
+
+// Initialize Lights in Area
+
+	memset(LightsInArea,0,sizeof(LightsInArea));
+
+	map = mapplanes[1];
+	map+=5;
+
+	for (j=0;j<mapheight;j++)
+		{
+		if (j==0)
+			starti=5;
+		else
+			starti=0;
+		for(i=starti;i<mapwidth;i++)
+			{
+			tile= *map++;
+
+
+
+			switch (tile)
+				{
+
+				// Add light sourcing to these objects
+
+				case 23:
+				case 24:
+				case 25:
+				case 26:
+				case 27:
+				case 42:
+				case 63:
+				case 64:
+					sprites[i][j]->flags |= FL_LIGHTON;
+					break;
+
+				case 28:
+				case 43:
+					if (MAPSPOT(i,j,2))
+					  {
+						touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff);
+						touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff);
+						tswitch = (wall_t*) actorat[touchx][touchy];
+
+						if (tswitch && (tswitch->which == WALL))
+							{tswitch->flags |= FL_REVERSIBLE;
+							 if (!(tswitch->flags & FL_ON))
+								{sprites[i][j]->shapenum --;
+								 if (touchindices[touchx][touchy])
+									 {Link_To_Touchplate(touchx,touchy,ActivateLight,DeactivateLight,(long)(sprites[i][j]),0);
+									  sprites[i][j]->linked_to = touchindices[touchx][touchy]-1;
+									 }
+								 else
+									 Error("tried to link a light at x=%d y=%d to a non-existent touchplate",i,j);
+								}
+							 else
+								{if (touchindices[touchx][touchy])
+									 {Link_To_Touchplate(touchx,touchy,DeactivateLight,ActivateLight,(long)(sprites[i][j]),0);
+									  sprites[i][j]->linked_to = touchindices[touchx][touchy]-1;
+									 }
+								 else
+									 Error("tried to link a light at x=%d y=%d to a non-existent touchplate",i,j);
+								 sprites[i][j]->flags |= FL_LIGHTON;
+								}
+							}
+					  else
+						 {if (touchindices[touchx][touchy])
+							 {Link_To_Touchplate(touchx,touchy,DeactivateLight,ActivateLight,(long)(sprites[i][j]),0);
+							  sprites[i][j]->linked_to = touchindices[touchx][touchy]-1;
+							 }
+						  else
+							 Error("tried to link a light at x=%d y=%d to a non-existent touchplate",i,j);
+						  sprites[i][j]->flags |= FL_LIGHTON;
+						 }
+
+					  }
+				  else
+					  sprites[i][j]->flags |= FL_LIGHTON;
+
+				  break;
+				}
+			}
+		}
+}
+
+/*
+==================
+=
+= PrintMapStats
+=
+==================
+*/
+void PrintMapStats (void)
+{
+   int size;
+   int total;
+
+   if (MAPSTATS==false)
+      return;
+
+   OpenMapDebug();
+
+   total=0;
+   MapDebug("MAP STATS Map Number %d\n",gamestate.mapon);
+   MapDebug("=======================\n");
+   size=pwallnum*sizeof(pwallobj_t);
+   total+=size;
+   MapDebug("Number of PushWalls   : %4d size = %6d\n",pwallnum,size);
+   size=maskednum*sizeof(maskedwallobj_t);
+   total+=size;
+   MapDebug("Number of MaskedWalls : %4d size = %6d\n",maskednum,size);
+   size=doornum*sizeof(doorobj_t);
+   total+=size;
+   MapDebug("Number of Doors       : %4d size = %6d\n",doornum,size);
+   size=lasttouch*sizeof(touchplatetype);
+   total+=size;
+   MapDebug("Number of TouchPlates : %4d size = %6d\n",lasttouch,size);
+   size=_numelevators*sizeof(elevator_t);
+   total+=size;
+   MapDebug("Number of Elevators   : %4d size = %6d\n",_numelevators,size);
+   size=statcount*sizeof(statobj_t);
+   total+=size;
+   MapDebug("Number of Sprites     : %4d size = %6d\n",statcount,size);
+   size=objcount*sizeof(objtype);
+   total+=size;
+   MapDebug("Number of Actors      : %4d size = %6d\n",objcount,size);
+   MapDebug("Number of Clocks      : %4d\n",numclocks);
+   MapDebug("\nTotal size of level : %6d\n",total);
+}
+
+
+boolean IsWeapon(int tile)
+{
+ if ((tile >= 46) && (tile <= 56))
+   return true;
+
+ return  false;
+
+}
+
+
+char *WeaponName(int tile)
+{
+ switch(tile)
+   {
+    case 46:
+      return "Bat           ";
+      break;
+
+    case 47:
+      return "Knife         ";
+      break;
+
+    case 48:
+      return "Double Pistol ";
+      break;
+
+    case 49:
+      return "MP40          ";
+      break;
+
+    case 50:
+      return "Bazooka       ";
+      break;
+
+    case 51:
+      return "Firebomb      ";
+      break;
+
+    case 52:
+      return "Heatseeker    ";
+      break;
+
+    case 53:
+      return "Drunk Missile ";
+      break;
+
+    case 54:
+      return "Flamewall     ";
+      break;
+
+    case 55:
+      return "Split Missile ";
+      break;
+
+    case 56:
+      return "KES           ";
+      break;
+   }
+   return " ";
+}
+
+
+
+int GetLumpForTile(int tile)
+   {
+   int wallstart;
+   int exitstart;
+
+	wallstart=W_GetNumForName("WALLSTRT");
+	exitstart=W_GetNumForName("EXITSTRT");
+	elevatorstart = W_GetNumForName("ELEVSTRT");
+
+   if ((tile >= 1) && (tile <= 32))
+      {
+      return (tile + wallstart);
+      }
+   else if ((tile >= 36) && (tile <= 45))
+      {
+      return (tile + wallstart - 3);
+      }
+   else if (tile == 46)
+      {
+      return (wallstart + 74);
+      }
+   else if ((tile >= 47) && (tile <= 48))
+      {
+      return (tile + exitstart - 46);
+      }
+   else if ((tile >= 49) && (tile <= 71))
+      {
+      return (tile + wallstart - 8);
+      }
+   else if ((tile >= 72) && (tile <= 79))
+      {
+      return (tile - 72 + elevatorstart + 1);
+      }
+   else if ((tile >= 80) && (tile <= 89))
+      {
+      return (tile + wallstart - 16);
+      }
+   return -1;
+   }
+
+
+
+
+#if (DEVELOPMENT == 1)
+
+
+/*
+==================
+=
+= Insane Dump
+=
+==================
+*/
+
+void InsaneDump(void)
+{
+   int i,j,level;
+   word *map,tile;
+   int tally[1000];
+   int inlevel[1000][10];
+
+   if (TILESTATS==false)
+      return;
+
+   OpenMapDebug();
+
+
+// WALLS
+   memset(tally,0,sizeof(tally));
+   memset(inlevel,0,sizeof(inlevel));
+   MapDebug("=======================\n");
+   MapDebug("= WALLS\n");
+   MapDebug("=======================\n");
+   mapheight = mapwidth = 128;
+   BATTLEMODE = 1;
+   for(level=0;level<8;level ++)
+    {
+     GetEpisode(level);
+     LoadROTTMap(level);
+     map = mapplanes[0];
+     for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+         {tile = *map++;
+         if (IsWall(i,j)==true)
+            {tally[tile]++;
+             inlevel[tile][level]=1;
+            }
+
+         }
+      }
+    }
+
+   MapDebug("Wall #   Frequency    Levels\n");
+   MapDebug("----------------------------\n");
+   for (i=0;i<1000;i++)
+     if (i < 90)
+       {MapDebug("%4d      %4d       %s",i,tally[i],
+                 W_GetNameForNum(GetLumpForTile(i)));
+        MapDebug("     ");
+        for(level=0;level < 10;level ++)
+          if (inlevel[i][level])
+           MapDebug("%d,",level);
+        MapDebug("\n");
+       }
+
+
+
+
+
+// Doors
+   memset(tally,0,sizeof(tally));
+   memset(inlevel,0,sizeof(inlevel));
+   MapDebug("=======================\n");
+   MapDebug("= DOORS\n");
+   MapDebug("=======================\n");
+   for(level=0;level<10;level ++)
+    {
+     GetEpisode(level);
+     LoadROTTMap(level);
+     map = mapplanes[0];
+     for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+         {tile = *map++;
+         if (IsDoor(i,j)==true)
+            {tally[tile]++;
+             inlevel[tile][level]=1;
+            }
+
+         }
+      }
+    }
+
+   MapDebug("Door #   Frequency    Levels\n");
+   MapDebug("----------------------------\n");
+   for (i=0;i<1000;i++)
+     if (tally[i]!=0)
+       {MapDebug("%4d      %4d         ",i,tally[i]);
+        for(level=0;level < 10;level ++)
+          if (inlevel[i][level])
+           MapDebug("%d,",level);
+        MapDebug("\n");
+
+       }
+
+// MaskedWalls
+   memset(tally,0,sizeof(tally));
+   memset(inlevel,0,sizeof(inlevel));
+   MapDebug("=======================\n");
+   MapDebug("= MASKED WALLS\n");
+   MapDebug("=======================\n");
+   for(level=0;level<10;level ++)
+    {
+     GetEpisode(level);
+     LoadROTTMap(level);
+     map = mapplanes[0];
+     for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+         {tile = *map++;
+         if ((IsMaskedWall(i,j)) && (!IsPlatform(i,j)))
+            {tally[tile]++;
+             inlevel[tile][level]=1;
+            }
+
+         }
+      }
+    }
+
+   MapDebug("MWall #   Frequency    Levels\n");
+   MapDebug("----------------------------\n");
+   for (i=0;i<1000;i++)
+     if (tally[i]!=0)
+       {MapDebug("%4d      %4d         ",i,tally[i]);
+        for(level=0;level < 10;level ++)
+          if (inlevel[i][level])
+           MapDebug("%d,",level);
+        MapDebug("\n");
+
+       }
+
+}
+
+#endif
+
+/*
+==================
+=
+= PrintTileStats
+=
+==================
+*/
+void PrintTileStats (void)
+{
+   int i,j;
+   word *map;
+   int easytotal;
+   int hardtotal;
+   int tally[1000];
+
+   if (TILESTATS==false)
+      return;
+
+   OpenMapDebug();
+
+   MapDebug("TILE STATS Map Number %d\n",gamestate.mapon);
+   MapDebug("=======================\n\n");
+
+
+// Weapons
+   memset(tally,0,sizeof(tally));
+   MapDebug("=======================\n");
+   MapDebug("= WEAPONS\n");
+   MapDebug("=======================\n");
+   map = mapplanes[1];
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+			{
+         if (IsWeapon(*map))
+           MapDebug("\n %s at %3d,%3d",WeaponName(*map),i,j);
+         map++;
+         }
+      }
+   MapDebug("\n\n");
+// WALLS
+   memset(tally,0,sizeof(tally));
+   MapDebug("=======================\n");
+   MapDebug("= WALLS\n");
+   MapDebug("=======================\n");
+	map = mapplanes[0];
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+			{
+         if (IsWall(i,j)==true)
+            tally[(*map)]++;
+         map++;
+         }
+      }
+   MapDebug("Wall #        Frequency\n");
+   MapDebug("-----------------------\n");
+   for (i=0;i<1000;i++)
+     if (tally[i]!=0)
+        MapDebug("  %4d    %4d\n",i,tally[i]);
+
+// Doors
+   memset(tally,0,sizeof(tally));
+   MapDebug("=======================\n");
+   MapDebug("= DOORS\n");
+   MapDebug("=======================\n");
+	map = mapplanes[0];
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+			{
+         if (IsDoor(i,j)==true)
+            tally[(*map)]++;
+         map++;
+         }
+      }
+   MapDebug("Door #        Frequency\n");
+   MapDebug("-----------------------\n");
+   for (i=0;i<1000;i++)
+     if (tally[i]!=0)
+        MapDebug("  %4d    %4d\n",i,tally[i]);
+
+// MaskedWalls
+   memset(tally,0,sizeof(tally));
+   MapDebug("=======================\n");
+   MapDebug("= MASKEDWALLS\n");
+   MapDebug("=======================\n");
+	map = mapplanes[0];
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+			{
+         if (IsMaskedWall(i,j)==true)
+            if (IsPlatform(i,j)==false)
+               tally[(*map)]++;
+         map++;
+         }
+      }
+   MapDebug("Mwall #       Frequency\n");
+   MapDebug("-----------------------\n");
+   for (i=0;i<1000;i++)
+     if (tally[i]!=0)
+        MapDebug("  %4d    %4d\n",i,tally[i]);
+// Platforms
+   memset(tally,0,sizeof(tally));
+   MapDebug("=======================\n");
+   MapDebug("= PLATFORMS\n");
+   MapDebug("=======================\n");
+	map = mapplanes[2];
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+			{
+         if (IsPlatform(i,j)==true)
+            tally[(*map)]++;
+         map++;
+         }
+      }
+   MapDebug("Pform #        Frequency\n");
+   MapDebug("-----------------------\n");
+   for (i=0;i<1000;i++)
+     if (tally[i]!=0)
+        MapDebug("  %4d    %4d\n",i,tally[i]);
+
+// Actors
+   memset(tally,0,sizeof(tally));
+   MapDebug("=======================\n");
+   MapDebug("= ACTORS\n");
+   MapDebug("=======================\n");
+	map = mapplanes[1];
+	for (j=0;j<mapheight;j++)
+      {
+	   for(i=0;i<mapwidth;i++)
+			{
+         if ((*map)>0)
+            tally[(*map)]++;
+         map++;
+         }
+      }
+
+// Low Guards
+   easytotal=0;
+   hardtotal=0;
+   for (i=108;i<=119;i++)
+      easytotal+=tally[i];
+   for (i=126;i<=137;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nLowGuards\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// Sneaky Low Guards
+   easytotal=0;
+   hardtotal=0;
+   for (i=120;i<=120;i++)
+      easytotal+=tally[i];
+   for (i=138;i<=138;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nSneakyLowGuards\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// High Guards
+   easytotal=0;
+   hardtotal=0;
+   for (i=144;i<=155;i++)
+      easytotal+=tally[i];
+   for (i=162;i<=173;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nHighGuards\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// OverPatrol Guards
+   easytotal=0;
+   hardtotal=0;
+   for (i=216;i<=227;i++)
+      easytotal+=tally[i];
+   for (i=234;i<=245;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nOverPatrolGuards\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// Strike Guards
+   easytotal=0;
+   hardtotal=0;
+   for (i=180;i<=191;i++)
+      easytotal+=tally[i];
+   for (i=198;i<=204;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nStrikeGuards\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// TriadEnforcer Guards
+   easytotal=0;
+   hardtotal=0;
+   for (i=288;i<=299;i++)
+      easytotal+=tally[i];
+   for (i=306;i<=317;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nTriadEnforcer Guards\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// Lightning Guards
+   easytotal=0;
+   hardtotal=0;
+   for (i=324;i<=335;i++)
+      easytotal+=tally[i];
+   for (i=342;i<=353;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nLightningGuards\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// Random Actors
+   easytotal=0;
+   hardtotal=0;
+   for (i=122;i<=125;i++)
+      easytotal+=tally[i];
+   MapDebug("\nRandom Actors\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",easytotal);
+
+// Monks
+   easytotal=0;
+   hardtotal=0;
+   for (i=360;i<=371;i++)
+      easytotal+=tally[i];
+   for (i=378;i<=389;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nMonks\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// Fire Monks
+   easytotal=0;
+   hardtotal=0;
+   for (i=396;i<=407;i++)
+      easytotal+=tally[i];
+   for (i=414;i<=425;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nFire Monks\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// Robo Guards
+   easytotal=0;
+   hardtotal=0;
+   for (i=158;i<=161;i++)
+      easytotal+=tally[i];
+   for (i=176;i<=179;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nRoboGuards\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// Ballistikrafts
+   easytotal=0;
+   hardtotal=0;
+   for (i=408;i<=411;i++)
+      easytotal+=tally[i];
+   for (i=426;i<=429;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nBallistikrafts\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// Boulders
+   easytotal=0;
+   hardtotal=0;
+   for (i=278;i<=281;i++)
+      easytotal+=tally[i];
+   for (i=395;i<=395;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nBoulders\n");
+   MapDebug("-----------------------\n");
+   MapDebug("Boulders=%4d\n",easytotal);
+   MapDebug("BoulderHoles=%4d\n",hardtotal);
+
+// PushColumns
+   easytotal=0;
+   hardtotal=0;
+   for (i=285;i<=287;i++)
+      easytotal+=tally[i];
+   for (i=303;i<=305;i++)
+      easytotal+=tally[i];
+   for (i=321;i<=323;i++)
+      easytotal+=tally[i];
+   for (i=339;i<=341;i++)
+      easytotal+=tally[i];
+   for (i=357;i<=359;i++)
+      easytotal+=tally[i];
+   MapDebug("\nPushColumns\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",easytotal);
+
+// Gun Emplacements
+   easytotal=0;
+   hardtotal=0;
+   for (i=194;i<=197;i++)
+      easytotal+=tally[i];
+   for (i=212;i<=215;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nGun Emplacements\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// 4-way guns
+   easytotal=0;
+   hardtotal=0;
+   for (i=89;i<=89;i++)
+      easytotal+=tally[i];
+   for (i=211;i<=211;i++)
+      hardtotal+=tally[i];
+   MapDebug("\n4-way guns\n");
+   MapDebug("-----------------------\n");
+   MapDebug("EasyTotal=%4d\n",easytotal);
+   MapDebug("HardTotal=%4d\n",hardtotal);
+   MapDebug("    Total=%4d\n",easytotal+hardtotal);
+
+// Stabbers from above
+   MapDebug("\nStabbers from above\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",tally[412]);
+
+// Stabbers from below
+   MapDebug("\nStabbers from below\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",tally[430]);
+
+// Crushing pillar from above
+   MapDebug("\nCrushing pillar from above\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",tally[413]);
+
+// Crushing pillar from below
+   MapDebug("\nCrushing pillar from below\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",tally[431]);
+
+// Above Spinner
+   MapDebug("\nAbove Spinner\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",tally[156]);
+
+// Ground Spinner
+   MapDebug("\nGround Spinner\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",tally[174]);
+
+// Spinner from above
+   MapDebug("\nSpinner from above\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",tally[157]);
+
+// Spinner from below
+   MapDebug("\nSpinner from below\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",tally[175]);
+
+// Bosses
+   easytotal=0;
+   for (i=99;i<=103;i++)
+      easytotal+=tally[i];
+   MapDebug("\nBosses\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",easytotal);
+
+// Spring Boards
+   MapDebug("\nSpring Boards\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",tally[193]);
+
+// Above FlameJets
+   easytotal=0;
+   hardtotal=0;
+   for (i=372;i<=376;i++)
+      easytotal+=tally[i];
+   for (i=390;i<=394;i++)
+      hardtotal+=tally[i];
+   MapDebug("\nFlameJets\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Above=%4d\n",easytotal);
+   MapDebug("   Ground=%4d\n",hardtotal);
+
+// Fire Chutes
+   easytotal=0;
+   for (i=140;i<=143;i++)
+      easytotal+=tally[i];
+   MapDebug("\nFireChutes\n");
+   MapDebug("-----------------------\n");
+   MapDebug("    Total=%4d\n",easytotal);
+
+// Sprites
+   MapDebug("=======================\n");
+   MapDebug("= SPRITES\n");
+   MapDebug("=======================\n");
+   MapDebug("Sprite #       Frequency\n");
+   MapDebug("-----------------------\n");
+   for (i=1;i<=72;i++)
+      if (tally[i]!=0)
+         MapDebug("  %4d    %4d\n",i,tally[i]);
+   for (i=210;i<=210;i++)
+      if (tally[i]!=0)
+         MapDebug("  %4d    %4d\n",i,tally[i]);
+   for (i=228;i<=233;i++)
+      if (tally[i]!=0)
+         MapDebug("  %4d    %4d\n",i,tally[i]);
+   for (i=246;i<=255;i++)
+      if (tally[i]!=0)
+         MapDebug("  %4d    %4d\n",i,tally[i]);
+   for (i=260;i<=273;i++)
+      if (tally[i]!=0)
+         MapDebug("  %4d    %4d\n",i,tally[i]);
+   for (i=282;i<=284;i++)
+      if (tally[i]!=0)
+         MapDebug("  %4d    %4d\n",i,tally[i]);
+}
+
+//***************************************************************************
+//
+// GetSongForLevel - returns song to play for current level
+//
+//***************************************************************************
+int GetSongForLevel ( void )
+{
+   int i;
+   int num;
+
+   for (i=0;i<mapwidth;i++)
+      {
+      num = MAPSPOT(i,0,2);
+      if ( (num>>8) == 0xba )
+         return (num&0xff);
+      }
+//   Error("GetSongForLevel: could not find song in level %ld\n",gamestate.mapon);
+//   return -1;
+     return 0;
+}
+
+/*
+==================
+=
+= DoSharewareConversionBackgroundPlane
+=
+==================
+*/
+void DoSharewareConversionBackgroundPlane (void)
+{
+   int i,j;
+   word * map;
+
+
+	for (j=0;j<mapheight;j++)
+      {
+      for(i=0;i<mapwidth;i++)
+			{
+         map=&(mapplanes[0][MAPSIZE*(j)+(i)]);
+         switch (*map)
+            {
+
+            // Tom Face
+            case 45:
+               *map=44;
+               break;
+            // Doors
+            case 90:
+            case 92:
+            case 93:
+            case 98:
+            case 99:
+            case 100:
+               *map=91;
+               break;
+            case 103:
+            case 104:
+               *map=101;
+               break;
+            case 154:
+               *map=33;
+               break;
+            case 155:
+               *map=34;
+               break;
+            case 156:
+               *map=35;
+               break;
+
+            //locked doors
+            case 94:
+               *map = 101;
+               *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=29;
+               break;
+            case 95:
+               *map = 101;
+               *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=30;
+               break;
+            case 96:
+               *map = 101;
+               *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=31;
+               break;
+            case 97:
+               *map = 101;
+               *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=32;
+               break;
+            // Tall pillar
+            case 161:
+               *map=0;
+               break;
+            // Masked Walls
+            case 162:
+            case 166:
+               *map=164;
+               break;
+            case 163:
+            case 167:
+            case 170:
+            case 171:
+               *map=165;
+               break;
+
+            // Floors and Ceilings
+            case 180:
+            case 183:
+            case 184:
+               *map=181;
+               break;
+            case 198:
+            case 201:
+            case 202:
+               *map=199;
+               break;
+            case 188:
+               *map=187;
+               break;
+            case 206:
+               *map=205;
+               break;
+            case 190:
+               *map=191;
+               break;
+            case 208:
+               *map=209;
+               break;
+            case 192:
+            case 193:
+            case 194:
+            case 195:
+               *map=189;
+               break;
+            case 210:
+            case 211:
+            case 212:
+            case 213:
+               *map=207;
+               break;
+            // Skys
+            case 237:
+            case 238:
+            case 239:
+               *map=234;
+               break;
+            // Animating walls
+            case 107:
+               *map=106;
+               break;
+            case 228:
+            case 229:
+            case 230:
+            case 242:
+               *map=21;
+               break;
+            case 233:
+               *map=44;
+               break;
+            case 232:
+               *map=231;
+               break;
+            }
+         }
+      }
+}
+
+
+/*
+========================================
+=
+= DoLowMemoryConversionBackgroundPlane
+=
+========================================
+*/
+void DoLowMemoryConversionBackgroundPlane (void)
+   {
+   int i,j;
+   word * map;
+
+
+	for (j=0;j<mapheight;j++)
+      {
+      for(i=0;i<mapwidth;i++)
+			{
+         map=&(mapplanes[0][MAPSIZE*(j)+(i)]);
+         switch (*map)
+            {
+            //Walls
+
+            case 2:
+            case 3:
+            case 4:
+               *map = 1;
+               break;
+
+            case 6:
+            case 7:
+            case 8:
+               *map = 5;
+               break;
+
+            case 14:
+            case 15:
+            case 16:
+               *map = 13;
+               break;
+
+            case 18:
+            case 19:
+            case 20:
+               *map = 17;
+               break;
+
+            case 26:
+            case 27:
+            case 28:
+               *map = 25;
+               break;
+
+            case 30:
+            case 31:
+            case 32:
+               *map = 29;
+               break;
+
+#if 0
+            case 37:
+            case 38:
+            case 39:
+               *map = 36;
+               break;
+
+            case 41:
+            case 42:
+            case 43:
+               *map = 40;
+               break;
+#endif
+
+            case 50:
+            case 51:
+            case 52:
+               *map = 49;
+               break;
+
+#if 0
+            case 55:
+            case 56:
+            case 57:
+               *map = 54;
+               break;
+
+            case 59:
+            case 60:
+            case 61:
+               *map = 58;
+               break;
+#endif
+
+            case 66:
+            case 67:
+            case 68:
+               *map = 65;
+               break;
+
+            case 70:
+            case 71:
+               *map = 69;
+               break;
+
+            case 81:
+            case 82:
+            case 84:
+               *map = 83;
+               break;
+
+            // Masked Walls
+            case 158:
+            case 159:
+            case 160:
+            case 168:
+            case 169:
+            case 176:
+            case 178:
+               *map=177;
+               break;
+            case 162:
+            case 163:
+            case 164:
+            case 166:
+            case 167:
+               *map=165;
+               break;
+
+            //Doors
+            case 90:
+            case 91:
+            case 92:
+            case 93:
+            case 98:
+            case 99:
+            case 100:
+            case 101:
+            case 103:
+            case 104:
+            case 33:
+            case 34:
+            case 35:
+            case 154:
+            case 155:
+            case 156:
+               *map = 101;
+               break;
+
+            //Animating Walls
+            case 22:
+            case 23:
+            case 24:
+            case 228:
+            case 229:
+            case 230:
+            case 231:
+            case 232:
+            case 242:
+            case 243:
+            case 244:
+               *map = 21;
+               break;
+            case 233:
+               *map = 44;
+               break;
+
+#if 0
+            //Skys
+            case 234:
+            case 235:
+            case 236:
+            case 237:
+            case 238:
+            case 239:
+               *map=(*(&(mapplanes[0][MAPSIZE*(0)+(0)]))) + 18;
+               break;
+#endif
+            }
+         }
+      }
+   }
+
+
+/*
+========================================
+=
+= DoLowMemoryConversionIconPlane
+=
+========================================
+*/
+void DoLowMemoryConversionIconPlane (void)
+   {
+#if 0
+   int i,j;
+   word * map;
+
+
+	for (j=0;j<mapheight;j++)
+      {
+      for(i=0;i<mapwidth;i++)
+			{
+         map=&(mapplanes[2][MAPSIZE*(j)+(i)]);
+         switch (*map)
+            {
+            case 13:
+               *(&(mapplanes[0][MAPSIZE*(j)+(i)]))=21;
+               *map=0;
+               break;
+            }
+         }
+      }
+#endif
+   }
+
+
+
+/*
+========================================
+=
+= DoLowMemoryConversionForegroundPlane
+=
+========================================
+*/
+
+void DoLowMemoryConversionForegroundPlane (void)
+   {
+   int i,j;
+   word * map;
+
+
+	for (j=0;j<mapheight;j++)
+      {
+      for(i=0;i<mapwidth;i++)
+			{
+         map=&MAPSPOT(i,j,1);
+         switch (*map)
+            {
+            // light sourcing
+            case 139:
+               *map=0;
+               break;
+
+            //sprites
+            case 42:
+            case 43:
+            case 63:
+            case 64:
+               *map = 43;
+               break;
+
+            case 246:
+            case 247:
+            case 248:
+            case 264:
+            case 265:
+            case 267:
+            case 283:
+               *map = 266;
+               break;
+
+            //lightning
+            case 377:
+               *map = 0;
+               break;
+
+            // actor guards
+
+            // normal low guards
+            case 108:
+            case 109:
+            case 110:
+            case 111:
+            case 112:
+            case 113:
+            case 114:
+            case 115:
+            case 116:
+            case 117:
+            case 118:
+            case 119:
+
+            case 126:
+            case 127:
+            case 128:
+            case 129:
+            case 130:
+            case 131:
+            case 132:
+            case 133:
+            case 134:
+            case 135:
+            case 136:
+            case 137:
+               (*map)+=216;
+               break;
+
+            // sneaky low guards
+            case 120:
+            case 138:
+               *map = 0;
+               break;
+
+            // normal over patrol
+            case 216:
+            case 217:
+            case 218:
+            case 219:
+            case 220:
+            case 221:
+            case 222:
+            case 223:
+            case 224:
+            case 225:
+            case 226:
+            case 227:
+
+
+            case 234:
+            case 235:
+            case 236:
+            case 237:
+            case 238:
+            case 239:
+            case 240:
+            case 241:
+            case 242:
+            case 243:
+            case 244:
+            case 245:
+               (*map)-=36;
+               break;
+
+            //environment dangers
+
+#if (SHAREWARE==0)
+            case 412:      //spears to firejets
+               *map = 372;
+               break;
+
+            case 430:
+               *map = 390;
+               break;
+
+            case 413:       //cylinders down to firejets
+               *map = 372;
+               break;
+#endif
+
+            case 156:
+            case 157:
+               *map = 372;    //spinblade stabbers to firejets
+               break;
+
+            case 174:
+            case 175:
+               *map = 390;
+               break;
+
+            case 301:          // directional spin blades
+               *map = 373;
+               break;
+
+            case 319:          // directional spin blades
+               *map = 374;
+               break;
+
+            case 337:          // directional spin blades
+               *map = 375;
+               break;
+
+            case 355:          // directional spin blades
+               *map = 376;
+               break;
+
+            case 302:          // directional spin blades
+               *map = 391;
+               break;
+
+            case 320:          // directional spin blades
+               *map = 392;
+               break;
+
+            case 338:          // directional spin blades
+               *map = 393;
+               break;
+
+            case 356:          // directional spin blades
+               *map = 394;
+               break;
+
+            case 194:      // directional emplacements to four-way
+            case 195:      // easy
+            case 196:
+            case 197:
+               *map = 89;
+               break;
+
+            case 212:      // hard
+            case 213:
+            case 214:
+            case 215:
+               *map = 211;
+               break;
+
+            }
+         }
+      }
+   }
+
+
+/*
+==================
+=
+= DoSharewareConversionForegroundPlane
+=
+==================
+*/
+void DoSharewareConversionForegroundPlane (void)
+{
+   int i,j;
+   word * map;
+
+
+	for (j=0;j<mapheight;j++)
+      {
+      for(i=0;i<mapwidth;i++)
+			{
+         map=&(mapplanes[1][MAPSIZE*(j)+(i)]);
+         switch (*map)
+            {
+            case 32:  // Crystal Key
+            case 47:  // Knife
+            case 65:  // DIP BALL D
+            case 66:  // DIP BALL I
+            case 67:  // DIP BALL P
+            case 99:  // Boss
+            case 100:  // Boss
+            case 101:  // Boss
+            case 102:  // Boss
+            case 103:  // Boss
+            case 210:  // Scott's head
+            case 278:  // Boulder
+            case 279:  // Boulder
+            case 280:  // Boulder
+            case 281:  // Boulder
+            case 395:  // Boulder
+               *map=0;
+               break;
+            case 41:  // 3-UP to 1-UP
+               *map=40;
+               break;
+            case 46:  // Bat
+               *map=50;
+               break;
+            case 55:  // Split Missile
+               *map=52;
+               break;
+            case 56:  // KES
+               *map=53;
+               break;
+            case 253:  // Dog Mode
+               *map=254;
+               break;
+            case 262:  // Tom Larva
+               *map=263;
+               break;
+            }
+         }
+      }
+}
+
+/*
+========================================
+=
+= DoRegisterConversionBackgroundPlane
+=
+========================================
+*/
+void DoRegisterConversionBackgroundPlane (void)
+   {
+   int i,j;
+   word * map;
+
+
+	for (j=0;j<mapheight;j++)
+      {
+      for(i=0;i<mapwidth;i++)
+			{
+         map=&(mapplanes[0][MAPSIZE*(j)+(i)]);
+         switch (*map)
+            {
+            //locked doors
+
+            case 94:
+               *map = 101;
+               *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=29;
+               break;
+            case 95:
+               *map = 101;
+               *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=30;
+               break;
+            case 96:
+               *map = 101;
+               *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=31;
+               break;
+            case 97:
+               *map = 101;
+               *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=32;
+               break;
+
+            case 232:
+               *map = 231; //map chains to machinery
+               break;
+
+            case 228:
+               *map = 230; //map gray water to blue water
+               break;
+
+            }
+         }
+      }
+   }
+
+
+
+/*
+========================================
+=
+= DoRegisterConversionForegroundPlane
+=
+========================================
+*/
+void DoRegisterConversionForegroundPlane (void)
+   {
+//   int i,j;
+//   word * map;
+
+
+#if 0
+	for (j=0;j<mapheight;j++)
+      {
+      for(i=0;i<mapwidth;i++)
+			{
+         map=&MAPSPOT(i,j,1);
+         switch (*map)
+            {
+            //sprites
+            case 42:
+            case 43:
+            case 63:
+            case 64:
+               *map = 43;
+               break;
+
+            }
+         }
+      }
+#endif
+   }
+
+/*
+==================
+=
+= DoSharewareConversion
+=
+==================
+*/
+void DoSharewareConversion (void)
+{
+   DoSharewareConversionBackgroundPlane ();
+   DoSharewareConversionForegroundPlane ();
+}
+
+
+/*
+==================
+=
+= DoRegisterConversion
+=
+==================
+*/
+void DoRegisterConversion (void)
+{
+   DoRegisterConversionBackgroundPlane ();
+   DoRegisterConversionForegroundPlane ();
+}
+
+/*
+=======================
+=
+= DoPanicMapping
+=
+=======================
+*/
+boolean DoPanicMapping (void)
+   {
+   if ((lowmemory==true) && (modemgame==false) && (demorecord==false) && (demoplayback==false))
+      return true;
+   else
+      return false;
+   }
+
+/*
+=======================
+=
+= DoLowMemoryConversion
+=
+=======================
+*/
+void DoLowMemoryConversion (void)
+   {
+   DoLowMemoryConversionBackgroundPlane ();
+   if ((modemgame==false) && (demorecord==false) && (demoplayback==false))
+      DoLowMemoryConversionForegroundPlane ();
+   DoLowMemoryConversionIconPlane ();
+   }
+
+
+
+/*
+==================
+=
+= SetupGameLevel
+=
+==================
+*/
+void SetupGameLevel (void)
+{
+	int crud;
+	int i;
+
+#if 0
+   mapwidth = mapheight = 128;
+
+   InsaneDump();
+   /*
+   for(i=0;i<11;i++)
+     {GetEpisode(i);
+      LoadROTTMap(i);
+      MapDebug("\n//================================//");
+      MapDebug("\n//   SHAREWARE LEVEL %d            //",i);
+      MapDebug("\n//================================//\n\n");
+
+      PrintTileStats();
+     }
+   */
+   Error("okay");
+#endif
+
+	insetupgame=true;
+
+   InitializeRNG ();
+
+	if ((demoplayback==true) || (demorecord==true))
+      SetRNGindex ( 0 );
+
+   if (gamestate.randomseed!=-1)
+      SetRNGindex ( gamestate.randomseed );
+
+	if (tedlevel)
+		{
+		GetEpisode (tedlevelnum);
+		LoadROTTMap(tedlevelnum);
+		gamestate.mapon=tedlevelnum;
+		}
+	else
+		{
+		GetEpisode (gamestate.mapon);
+		LoadROTTMap(gamestate.mapon);
+		}
+   if (DoPanicMapping())
+      {
+      DoLowMemoryConversion();
+      }
+   if ( gamestate.Product == ROTT_SHAREWARE )
+      {
+      DoSharewareConversion ();
+      }
+   else
+      {
+      DoRegisterConversion ();
+      }
+   if ( (NewGame) || (lastlevelloaded!=gamestate.mapon) )
+		{
+		SetupPreCache();
+		lastlevelloaded=gamestate.mapon;
+      MU_StartSong(song_level);
+		}
+   shapestart = W_GetNumForName("SHAPSTRT");
+   shapestop = W_GetNumForName("SHAPSTOP");
+	gunsstart=W_GetNumForName("GUNSTART");
+
+	playstate = ex_stillplaying;
+	SNAKELEVEL = 0;
+	whichpath = 0;
+
+	// som of the code / calls below need bufferofs & friends to point
+	// to to the real screen, not the stretch buffer
+	DisableScreenStretch();//bna++ shut off streech mode
+
+	InitializePlayerstates();
+
+	ResetCheatCodes();
+
+	gamestate.killtotal     = gamestate.killcount     = 0;
+	gamestate.secrettotal   = gamestate.secretcount   = 0;
+	gamestate.treasuretotal = gamestate.treasurecount = 0;
+	gamestate.supertotal    = gamestate.supercount    = 0;
+	gamestate.healthtotal   = gamestate.healthcount   = 0;
+	gamestate.missiletotal  = gamestate.missilecount  = 0;
+	gamestate.democratictotal = gamestate.democraticcount = 0;
+	gamestate.planttotal    = gamestate.plantcount    = 0;
+	gamestate.DODEMOCRATICBONUS1 = true;
+	gamestate.DOGROUNDZEROBONUS  = false;
+
+	if (gamestate.mapon == 30)
+	 SNAKELEVEL = 1;
+	else if (gamestate.mapon == 32)
+	 SNAKELEVEL = 2;
+	else if (gamestate.mapon == 33)
+	 SNAKELEVEL = 3;
+
+	InitAreas();
+	InitDoorList();
+	InitElevators();
+	if (loadedgame==false)
+		{
+		InitStaticList ();
+		InitActorList();
+		}
+	memset (tilemap,0,sizeof(tilemap));
+	memset (actorat,0,sizeof(actorat));
+	memset (sprites,0,sizeof(sprites));
+	memset (mapseen,0,sizeof(mapseen));
+	memset (LightsInArea,0,sizeof(LightsInArea));
+
+	PrintTileStats();
+
+	SetupLightLevels();
+
+   crud=(word)MAPSPOT(0,0,1);
+	if ((crud>=90) && (crud<=97))
+		{
+		levelheight=crud-89;
+		maxheight = (levelheight << 6)-32;
+		nominalheight = maxheight-32;
+		}
+	else if ((crud>=450) && (crud<=457))
+		{
+		levelheight=crud-450+9;
+		maxheight = (levelheight << 6)-32;
+		nominalheight = maxheight-32;
+		}
+	else
+		Error("You must specify a valid height sprite icon at (2,0) on map %d\n",gamestate.mapon);
+
+/*
+   if ( ( BATTLEMODE ) && ( !gamestate.BattleOptions.SpawnDangers ) )
+      {
+      RemoveDangerWalls();
+      }
+*/
+// pheight=maxheight-32;
+   CountAreaTiles();
+	SetupWalls();
+
+	SetupClocks();
+	SetupAnimatedWalls();
+
+	if (loadedgame==false)
+		{
+		SetupSwitches();
+		SetupStatics ();
+		SetupMaskedWalls();
+		SetupDoors();
+		SetupPushWalls();
+		SetupPlayers();
+      if (!BATTLEMODE)
+         {
+	     	SetupActors();
+	      SetupRandomActors();
+         }
+		SetupElevators();
+		SetupDoorLinks();
+		SetupPushWallLinks();
+		FixDoorAreaNumbers();
+		FixMaskedWallAreaNumbers();
+		SetupWindows();
+		SetupLights();
+      SetupInanimateActors();
+      }
+   else {
+      FixTiles();
+   }
+   
+	if (gamestate.SpawnEluder || gamestate.SpawnDeluder)
+      {
+//MED
+      for (i=0;i<25;i++)
+         RespawnEluder();
+      }
+
+
+   if ( ( BATTLEMODE ) && ( MapSpecials & MAP_SPECIAL_TOGGLE_PUSHWALLS ) )
+      {
+      ActivateAllPushWalls();
+      }
+   Illuminate();
+
+	if (SNAKELEVEL == 1)
+		SetupSnakePath();
+
+	LoftSprites();
+
+	SetPlaneViewSize();
+	if (loadedgame==false)
+		{
+		ConnectAreas();
+#if (DEVELOPMENT == 1)
+#if (PRECACHETEST == 1)
+		SoftError("Start PreCaching\n");
+#endif
+#endif
+#if (DEVELOPMENT == 1)
+      PrintMapStats();
+#endif
+		PreCache();
+#if (DEVELOPMENT == 1)
+#if (PRECACHETEST == 1)
+		SoftError("Done PreCaching\n");
+#endif
+#endif
+		SetupPlayScreen();
+		SetupScreen(false);
+	}
+
+        if (BATTLEMODE) {
+           SetModemLightLevel ( gamestate.BattleOptions.LightLevel );
+        }
+
+        if (player != NULL) {
+            for (i=0;i<100;i++) {
+		UpdateLightLevel(player->areanumber);
+            }
+        }
+        
+	insetupgame=false;
+
+	tedlevel = false;   // turn it off once we have done any ted stuff
+	
+	EnableScreenStretch();
+}
+
+
+void InitializePlayerstates(void)
+{int i;
+ playertype * pstate;
+
+ if (NewGame || (gamestate.mapon == 0) || tedlevel)
+		{for(i=0;i<numplayers;i++)
+			InitializeWeapons(&PLAYERSTATE[i]);
+		}
+
+ for(i=0;i<numplayers;i++)
+	 {
+    pstate=&PLAYERSTATE[i];
+    if (
+         (pstate->missileweapon == wp_godhand)
+#if (SHAREWARE == 0)
+         ||
+         (pstate->missileweapon == wp_dog)
+#endif
+       )
+		 {
+       pstate->weapon=pstate->new_weapon=pstate->oldweapon;
+		 pstate->missileweapon = pstate->oldmissileweapon;
+
+		 }
+
+	 ResetPlayerstate(pstate);
+	 }
+
+ NewGame = false;
+
+}
+
+
+void SetupSnakePath(void)
+{
+#if (SHAREWARE == 0)
+ int i,j;
+ word *map,tile;
+
+ map = mapplanes[1];
+
+ for(j=0;j<mapheight;j++)
+  for(i=0;i<mapwidth;i++)
+	{tile = *map++;
+	 if ((tile >= 72) && (tile <= 79) && (!tilemap[i][j]))
+	  {SNAKEPATH[whichpath].x = i;
+		SNAKEPATH[whichpath].y = j;
+		whichpath ++;
+	  }
+
+	}
+#endif
+}
+
+
+void SetupRandomActors(void)
+{int i,j;
+ word *map,tile;
+ int starti,totalrandom=0,count=0,ambush,locindex,orig;
+ byte actorpresent[10]={0},index=0,randomtype,used[100]={0};
+ _2Dpoint randloc[100];
+
+
+ map = mapplanes[1];
+ map+=5;
+ for(i=0;i<10;i++)
+  {if (RANDOMACTORTYPE[i])
+	  actorpresent[index++]=i;
+  }
+
+
+ if (!index)
+  return;
+
+ for (j=0;j<mapheight;j++)
+	{if (j==0)
+		starti=5;
+	 else
+		starti=0;
+	 for(i=starti;i<mapwidth;i++)
+		{tile= *map++;
+
+		 if ((tile >= 122) && (tile <= 125))
+			 {randloc[totalrandom].x = i;
+			  randloc[totalrandom].y = j;
+			  totalrandom++;
+			  if (totalrandom >= 100)
+				Error("Max random actors (100) exceeded");
+			 }
+
+		}
+	}
+
+ orig = totalrandom;
+ switch(gamestate.difficulty)
+    {
+    case gd_baby:
+       totalrandom = 7*totalrandom/10;
+       break;
+
+    case gd_easy:
+       totalrandom = 8*totalrandom/10;
+       break;
+
+    case gd_medium:
+       totalrandom = 9*totalrandom/10;
+       break;
+
+    }
+
+
+ while(count<totalrandom)
+	{ locindex = (GameRandomNumber("rand loc index",0) % orig);
+
+	  if (!used[locindex])
+       {randomtype = actorpresent[GameRandomNumber("SetupRandomActors",0) % index];
+		  ambush = (GameRandomNumber("rand actor",0) < 128);
+		  i = randloc[locindex].x;
+		  j = randloc[locindex].y;
+		  tile = mapplanes[1][j*mapwidth + i];
+		  SpawnStand(randomtype,i,j,tile-122,ambush);
+		  used[locindex] = 1;
+        PreCacheActor(randomtype,0);
+		  count++;
+		 }
+	}
+
+}
+
+void SetupActors(void)
+{
+  int i,j;
+  word *map,tile;
+  int starti;
+
+
+  //GetRainActors();
+
+  map = mapplanes[1];
+  map+=5;
+
+  for (j=0;j<mapheight;j++)
+		{
+		if (j==0)
+			starti=5;
+		else
+			starti=0;
+		for(i=starti;i<mapwidth;i++)
+			{
+			tile= *map++;
+
+			switch(tile)
+			  {
+
+				case 126:
+				case 127:
+				case 128:
+				case 129:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 108:
+				case 109:
+				case 110:
+				case 111:
+					SpawnStand(lowguardobj,i,j,tile-108,0);
+					break;
+
+
+
+
+				case 130:
+				case 131:
+				case 132:
+				case 133:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 112:
+				case 113:
+				case 114:
+				case 115:
+					SpawnPatrol(lowguardobj,i,j,tile-112);
+					break;
+
+				case 134:
+				case 135:
+				case 136:
+				case 137:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 116:
+				case 117:
+				case 118:
+				case 119:
+					SpawnStand(lowguardobj,i,j,tile-116,1);
+					break;
+
+				case 138:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 120:
+					SpawnSneaky(i,j);
+					break;
+
+				case 162:
+				case 163:
+				case 164:
+				case 165:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 144:
+				case 145:
+				case 146:
+				case 147:
+					SpawnStand(highguardobj,i,j,tile-144,0);
+					break;
+
+				case 170:
+				case 171:
+				case 172:
+				case 173:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 152:
+				case 153:
+				case 154:
+				case 155:
+					SpawnStand(highguardobj,i,j,tile-152,1);
+					break;
+
+
+
+				case 166:
+				case 167:
+				case 168:
+				case 169:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 148:
+				case 149:
+				case 150:
+				case 151:
+					SpawnPatrol(highguardobj,i,j,tile-148);
+					break;
+
+				case 176:
+				case 177:
+				case 178:
+				case 179:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 158:
+				case 159:
+				case 160:
+				case 161:
+					SpawnPatrol(roboguardobj,i,j,tile-158);
+					break;
+
+				case 212:
+				case 213:
+				case 214:
+				case 215:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 194:
+				case 195:
+				case 196:
+				case 197:
+					SpawnGunThingy(patrolgunobj,i,j,tile-194);
+					break;
+
+				case 198:
+				case 199:
+				case 200:
+				case 201:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 180:
+				case 181:
+				case 182:
+				case 183:
+					SpawnStand(strikeguardobj,i,j,tile-180,0);
+					break;
+
+				case 206:
+				case 207:
+				case 208:
+				case 209:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 188:
+				case 189:
+				case 190:
+				case 191:
+					SpawnStand(strikeguardobj,i,j,tile-188,1);
+					break;
+
+				case 202:
+				case 203:
+				case 204:
+				case 205:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 184:
+				case 185:
+				case 186:
+				case 187:
+					SpawnPatrol(strikeguardobj,i,j,tile-184);
+					break;
+
+				case 234:
+				case 235:
+				case 236:
+				case 237:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 216:
+				case 217:
+				case 218:
+				case 219:
+					SpawnStand(overpatrolobj,i,j,tile-216,0);
+					break;
+
+				case 242:
+				case 243:
+				case 244:
+				case 245:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 224:
+				case 225:
+				case 226:
+				case 227:
+					SpawnStand(overpatrolobj,i,j,tile-224,1);
+					break;
+
+				case 238:
+				case 239:
+				case 240:
+				case 241:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 220:
+				case 221:
+				case 222:
+				case 223:
+					SpawnPatrol(overpatrolobj,i,j,tile-220);
+					break;
+				case 306:
+				case 307:
+				case 308:
+				case 309:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 288:
+				case 289:
+				case 290:
+				case 291:
+					SpawnStand(triadenforcerobj,i,j,tile-288,0);
+					break;
+
+				case 314:
+				case 315:
+				case 316:
+				case 317:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 296:
+				case 297:
+				case 298:
+				case 299:
+					SpawnStand(triadenforcerobj,i,j,tile-296,1);
+					break;
+
+				case 310:
+				case 311:
+				case 312:
+				case 313:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 292:
+				case 293:
+				case 294:
+				case 295:
+					SpawnPatrol(triadenforcerobj,i,j,tile-292);
+					break;
+
+				case 342:
+				case 343:
+				case 344:
+				case 345:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 324:
+				case 325:
+				case 326:
+				case 327:
+					SpawnStand(blitzguardobj,i,j,tile-324,0);
+					break;
+
+				case 350:
+				case 351:
+				case 352:
+				case 353:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 332:
+				case 333:
+				case 334:
+				case 335:
+					SpawnStand(blitzguardobj,i,j,tile-332,1);
+					break;
+
+				case 346:
+				case 347:
+				case 348:
+				case 349:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+				case 328:
+				case 329:
+				case 330:
+				case 331:
+					SpawnPatrol(blitzguardobj,i,j,tile-328);
+					break;
+
+				case 378:
+				case 379:
+				case 380:
+				case 381:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 360:
+				case 361:
+				case 362:
+				case 363:
+					SpawnStand(deathmonkobj,i,j,tile-360,0);
+					break;
+
+				case 386:
+				case 387:
+				case 388:
+				case 389:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 368:
+				case 369:
+				case 370:
+				case 371:
+					SpawnStand(deathmonkobj,i,j,tile-368,1);
+					break;
+
+				case 382:
+				case 383:
+				case 384:
+				case 385:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 364:
+				case 365:
+				case 366:
+				case 367:
+					SpawnPatrol(deathmonkobj,i,j,tile-364);
+					break;
+
+				case 414:
+				case 415:
+				case 416:
+				case 417:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 396:
+				case 397:
+				case 398:
+				case 399:
+					SpawnStand(dfiremonkobj,i,j,tile-396,0);
+					break;
+
+
+
+				case 422:
+				case 423:
+				case 424:
+				case 425:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+
+				case 404:
+				case 405:
+				case 406:
+				case 407:
+					SpawnStand(dfiremonkobj,i,j,tile-404,1);
+					break;
+
+				case 418:
+				case 419:
+				case 420:
+				case 421:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 400:
+				case 401:
+				case 402:
+				case 403:
+					SpawnPatrol(dfiremonkobj,i,j,tile-400);
+					break;
+
+				case 99:
+					SpawnStand(b_darianobj,i,j,tile-99,0);
+					break;
+				case 100:
+					SpawnStand(b_heinrichobj,i,j,tile-100,0);
+					break;
+				case 101:
+					SpawnStand(b_darkmonkobj,i,j,tile-101,0);
+					MISCVARS->TOMLOC.x = i;
+					MISCVARS->TOMLOC.y = j;
+					break;
+				case 102:
+					SpawnMultiSpriteActor(b_robobossobj,i,j,tile-102);
+					break;
+
+				case 103:
+					SpawnSnake(i,j);
+					break;
+
+				case 426:
+				case 427:
+				case 428:
+				case 429:
+					if (gamestate.difficulty < gd_hard)
+						break;
+					tile -= 18;
+
+				case 408:
+				case 409:
+				case 410:
+				case 411:
+					SpawnPatrol(wallopobj,i,j,tile-408);
+					break;
+
+
+			  }
+			}
+		 }
+}
+
+void SetupStatics(void)
+{
+	int i,j,spawnz;
+	word *map,tile;
+	int starti;
+
+	map = mapplanes[1];
+	map+=5;
+
+   BATTLE_NumCollectorItems = 0;
+	for (j=0;j<mapheight;j++)
+		{
+		if (j==0)
+			starti=5;
+		else
+			starti=0;
+		for(i=starti;i<mapwidth;i++)
+			{
+			tile= *map++;
+			spawnz = (MAPSPOT(i,j,2))?(MAPSPOT(i,j,2)):(-1);
+
+         if ( gamestate.BattleOptions.RandomWeapons )
+            {
+            int num;
+
+            switch( tile )
+               {
+               case 46:
+               case 48:
+               case 49:
+               case 50:
+               case 51:
+               case 52:
+               case 53:
+               case 54:
+               case 55:
+               case 56:
+                  if ( gamestate.Product == ROTT_SHAREWARE )
+                     {
+                     num = ( GameRandomNumber( "Random Weapon", 0 ) % 7 );
+                     tile = SharewareWeaponTiles[ num ];
+                     }
+                  else
+                     {
+                     num = ( GameRandomNumber( "Random Weapon", 1 ) % 10 );
+                     tile = NormalWeaponTiles[ num ];
+                     }
+                  break;
+               }
+            }
+
+			switch (tile)
+				{
+
+				// Add light sourcing to these objects
+
+				case 23:
+				case 24:
+				case 25:
+				case 26:
+				case 27:
+				case 28:
+				case 42:
+				case 43:
+				case 63:
+				case 64:
+						SpawnStatic(i,j,tile-23,spawnz);
+					break;
+
+				case 44:
+						SpawnStatic(i,j,tile-23,spawnz);
+					if (loadedgame == false)
+					{
+						gamestate.healthtotal ++;
+						gamestate.democratictotal ++;
+					}
+					break;
+
+
+				case 36:
+				case 37:
+				case 38:
+				case 39:
+						SpawnStatic(i,j,tile-23,spawnz);
+					if (loadedgame == false)
+						gamestate.healthtotal ++;
+					break;
+
+				case 29:
+				case 30:
+				case 31:
+				case 32:
+               if (IsDoor (i, j) == 0)
+                  {
+                  if ( BATTLEMODE )
+                     {
+                     // Spawn empty table
+                     SpawnStatic( i, j, 247 - 246 + 57, spawnz );
+                     }
+                  else
+                     {
+                     // Spawn key table
+                     SpawnStatic( i, j, tile - 23, spawnz );
+                     }
+                  }
+					break;
+
+				case 33:
+				case 34:
+				case 35:
+				case 40:
+				case 41:
+				case 45:
+						SpawnStatic(i,j,tile-23,spawnz);
+					break;
+
+				case 46:
+               #if (SHAREWARE == 1)
+                 Error("\n tried to spawn excalibat at %d,%d in shareware !",i,j);
+               #endif
+
+
+               SD_PreCacheSoundGroup(SD_EXCALIBOUNCESND,SD_EXCALIBLASTSND);
+
+
+					PreCacheGroup(W_GetNumForName("EXBAT1"),
+									  W_GetNumForName("EXBAT7"),
+									  cache_patch_t);
+
+
+
+						SpawnStatic(i,j,tile-23,spawnz);
+					if (loadedgame == false)
+						gamestate.missiletotal ++;
+					break;
+				case 47:
+					PreCacheGroup(W_GetNumForName("KNIFE1"),
+									  W_GetNumForName("KNIFE10"),
+									  cache_patch_t);
+					PreCacheGroup(W_GetNumForName("ESTATUE1"),
+									  W_GetNumForName("ESTATUE8"),
+									  cache_patch_t);
+
+						SpawnStatic(i,j,tile-23,spawnz);
+					break;
+
+				case 48:
+					SD_PreCacheSound(SD_ATKTWOPISTOLSND);
+
+               if ((locplayerstate->player == 1) || (locplayerstate->player == 3))
+					  PreCacheGroup(W_GetNumForName("RFPIST1"),
+										 W_GetNumForName("LFPIST3"),
+										 cache_patch_t);
+
+               else if (locplayerstate->player == 2)
+					  PreCacheGroup(W_GetNumForName("RBMPIST1"),
+										 W_GetNumForName("LBMPIST3"),
+										 cache_patch_t);
+
+					else
+					  PreCacheGroup(W_GetNumForName("RMPIST1"),
+										 W_GetNumForName("LMPIST3"),
+										 cache_patch_t);
+
+               SpawnStatic(i,j,tile-23,spawnz);
+
+               break;
+				case 49:
+
+					SD_PreCacheSound(SD_ATKMP40SND);
+					PreCacheGroup(W_GetNumForName("MP401"),
+									  W_GetNumForName("MP403"),
+									  cache_patch_t);
+						SpawnStatic(i,j,tile-23,spawnz);
+					break;
+
+				case 50:
+					SD_PreCacheSound(SD_MISSILEHITSND);
+					SD_PreCacheSound(SD_MISSILEFLYSND);
+					SD_PreCacheSound(SD_BAZOOKAFIRESND);
+					PreCacheGroup(W_GetNumForName("BAZOOKA1"),
+									  W_GetNumForName("BAZOOKA4"),
+									  cache_patch_t);
+						SpawnStatic(i,j,tile-23,spawnz);
+					if (loadedgame == false)
+						gamestate.missiletotal ++;
+					break;
+				case 51:
+
+
+               SD_PreCacheSound(SD_MISSILEHITSND);
+					SD_PreCacheSound(SD_MISSILEFLYSND);
+					SD_PreCacheSound(SD_FIREBOMBFIRESND);
+					PreCacheGroup(W_GetNumForName("FBOMB1"),
+									  W_GetNumForName("FBOMB4"),
+									  cache_patch_t);
+						SpawnStatic(i,j,tile-23,spawnz);
+					if (loadedgame == false)
+						gamestate.missiletotal ++;
+					break;
+				case 52:
+					SD_PreCacheSound(SD_MISSILEHITSND);
+					SD_PreCacheSound(SD_MISSILEFLYSND);
+					SD_PreCacheSound(SD_HEATSEEKFIRESND);
+					PreCacheGroup(W_GetNumForName("HSEEK1"),
+									  W_GetNumForName("HSEEK4"),
+									  cache_patch_t);
+						SpawnStatic(i,j,tile-23,spawnz);
+					if (loadedgame == false)
+						gamestate.missiletotal ++;
+					break;
+				case 53:
+               SD_PreCacheSound(SD_MISSILEHITSND);
+					SD_PreCacheSound(SD_MISSILEFLYSND);
+					SD_PreCacheSound(SD_DRUNKFIRESND);
+					PreCacheGroup(W_GetNumForName("DRUNK1"),
+									  W_GetNumForName("DRUNK4"),
+									  cache_patch_t);
+						SpawnStatic(i,j,tile-23,spawnz);
+					if (loadedgame == false)
+						gamestate.missiletotal ++;
+					break;
+				case 54:
+					SD_PreCacheSound(SD_MISSILEHITSND);
+					SD_PreCacheSound(SD_MISSILEFLYSND);
+					SD_PreCacheSound(SD_FLAMEWALLFIRESND);
+					SD_PreCacheSound(SD_FLAMEWALLSND);
+					PreCacheGroup(W_GetNumForName("FIREW1"),
+									  W_GetNumForName("FIREW3"),
+									  cache_patch_t);
+					PreCacheGroup(W_GetNumForName("FWALL1"),
+									  W_GetNumForName("FWALL15"),
+									  cache_patch_t);
+					PreCacheGroup(W_GetNumForName("SKEL1"),
+									  W_GetNumForName("SKEL48"),
+									  cache_patch_t);
+						SpawnStatic(i,j,tile-23,spawnz);
+					if (loadedgame == false)
+						gamestate.missiletotal ++;
+					break;
+				case 55:
+               #if (SHAREWARE == 1)
+                 Error("\n tried to spawn split missile at %d,%d in shareware !",i,j);
+               #endif
+               SD_PreCacheSound(SD_MISSILEHITSND);
+					SD_PreCacheSound(SD_MISSILEFLYSND);
+					SD_PreCacheSound(SD_SPLITFIRESND);
+					SD_PreCacheSound(SD_SPLITSND);
+					PreCacheGroup(W_GetNumForName("SPLIT1"),
+									  W_GetNumForName("SPLIT4"),
+									  cache_patch_t);
+						SpawnStatic(i,j,tile-23,spawnz);
+					if (loadedgame == false)
+						gamestate.missiletotal ++;
+					break;
+				case 56:
+               #if (SHAREWARE == 1)
+                 Error("\n tried to spawn kes at %d,%d in shareware !",i,j);
+               #endif
+
+
+
+               SD_PreCacheSound(SD_GRAVSND);
+					SD_PreCacheSound(SD_GRAVHITSND);
+					SD_PreCacheSound(SD_GRAVFIRESND);
+					SD_PreCacheSound(SD_GRAVBUILDSND);
+
+					PreCacheGroup(W_GetNumForName("KES1"),
+									  W_GetNumForName("KES6"),
+									  cache_patch_t);
+					PreCacheGroup(W_GetNumForName("KSPHERE1"),
+									  W_GetNumForName("KSPHERE4"),
+									  cache_patch_t);
+						SpawnStatic(i,j,tile-23,spawnz);
+					if (loadedgame == false)
+						gamestate.missiletotal ++;
+					break;
+
+				case 57:
+				case 58:
+				case 59:
+				case 60:
+				case 61:
+				case 62:
+				case 65:
+				case 66:
+				case 67:
+						SpawnStatic(i,j,tile-23,spawnz);
+					break;
+
+				case 68:
+				case 69:
+				case 70:
+				case 71:
+						SpawnStatic(i,j,tile-23,spawnz);
+					break;
+
+				case  98:
+						SpawnStatic(i,j,tile-98+49,spawnz);
+					break;
+
+				case 210:
+						SpawnStatic(i,j,stat_scotthead,spawnz);
+					break;
+
+				case 228:
+				case 229:
+				case 230:
+				case 231:
+				case 232:
+				case 233:
+						SpawnStatic(i,j,tile-228+51,spawnz);
+					break;
+				case 246:
+				case 247:
+				case 248:
+				case 249:
+				case 250:
+				case 251:
+						SpawnStatic(i,j,tile-246+57,spawnz);
+					break;
+				case 264:
+				case 265:
+						SpawnStatic(i,j,tile-264+63,spawnz);
+					gamestate.planttotal ++;
+					break;
+
+				case 266:
+						SpawnStatic(i,j,stat_urn,spawnz);
+					break;
+
+            case 268:
+               SpawnStatic(i,j,tile-265+63,spawnz);
+               break;
+
+            case 269:
+						SpawnStatic(i,j,tile-265+63,spawnz);
+					break;
+
+				case 267:
+						SpawnStatic(i,j,stat_emptystatue,spawnz);
+					break;
+
+				case 282:
+					SpawnStatic(i,j,stat_heatgrate,spawnz);
+					break;
+
+				case 283:
+					SpawnStatic(i,j,stat_standardpole,spawnz);
+					break;
+
+            case 284:
+               if ( !BATTLEMODE )
+                  {
+                  SpawnStatic(i,j,stat_pit,spawnz);
+                  }
+               break;
+
+
+
+
+				case 252:
+					SD_PreCacheSound(SD_GRAVSND);
+					SD_PreCacheSound(SD_GRAVHITSND);
+               SD_PreCacheSoundGroup(SD_GODMODEFIRESND,SD_LOSEMODESND);
+               if ((locplayerstate->player == 1) || (locplayerstate->player ==3))
+					  SD_PreCacheSound(SD_GODWOMANSND);
+					else
+					  SD_PreCacheSound(SD_GODMANSND);
+
+
+					PreCacheGroup(W_GetNumForName("GODHAND1"),
+									  W_GetNumForName("GODHAND8"),
+									  cache_patch_t);
+
+					PreCacheGroup(W_GetNumForName("VAPO1"),
+									  W_GetNumForName("LITSOUL"),
+									  cache_patch_t);
+
+					PreCacheGroup(W_GetNumForName("GODFIRE1"),
+									  W_GetNumForName("GODFIRE4"),
+									  cache_patch_t);
+
+						SpawnStatic(i,j,stat_godmode,spawnz);
+					if (loadedgame == false)
+						gamestate.supertotal ++;
+					break;
+
+				case 253:
+
+               #if (SHAREWARE == 1)
+                  Error("DogMode Power up in shareware at x=%d y=%d\n",i,j);
+               #endif
+
+               SD_PreCacheSoundGroup(SD_DOGMODEPANTSND,SD_DOGMODELICKSND);
+               if ((locplayerstate->player == 1) || (locplayerstate->player ==3))
+					  SD_PreCacheSound(SD_DOGWOMANSND);
+					else
+					  SD_PreCacheSound(SD_DOGMANSND);
+
+
+
+					PreCacheGroup(W_GetNumForName("DOGNOSE1"),
+									  W_GetNumForName("DOGPAW4"),
+									  cache_patch_t);
+						SpawnStatic(i,j,stat_dogmode,spawnz);
+					if (loadedgame == false)
+						gamestate.supertotal ++;
+					break;
+
+				case 254:
+						SpawnStatic(i,j,stat_fleetfeet,spawnz);
+					if (loadedgame == false)
+						gamestate.supertotal ++;
+					break;
+
+				case 255:
+						SpawnStatic(i,j,stat_random,spawnz);
+					if (loadedgame == false)
+						gamestate.supertotal ++;
+					break;
+
+				case 260:
+						SpawnStatic(i,j,stat_elastic,spawnz);
+					if (loadedgame == false)
+						gamestate.supertotal ++;
+					break;
+
+				case 261:
+						SpawnStatic(i,j,stat_mushroom,spawnz);
+					if (loadedgame == false)
+						{
+						gamestate.supertotal ++;
+						gamestate.democratictotal ++;
+						}
+					break;
+
+
+				case 262:
+						SpawnStatic(i,j,stat_tomlarva,spawnz);
+					break;
+
+				case 263:
+						if (gamestate.SpawnCollectItems)
+                     {
+							SpawnStatic(i,j,stat_collector,spawnz);
+                     LASTSTAT->flags |= FL_COLORED;
+                     LASTSTAT->hitpoints =
+                        ( GameRandomNumber("colors",0) % MAXPLAYERCOLORS );
+                     BATTLE_NumCollectorItems++;
+                     }
+					break;
+
+				case 270:
+						SpawnStatic(i,j,stat_bulletproof,spawnz);
+					if (loadedgame == false)
+						gamestate.supertotal ++;
+					break;
+				case 271:
+						SpawnStatic(i,j,stat_asbesto,spawnz);
+					if (loadedgame == false)
+						gamestate.supertotal ++;
+					break;
+				case 272:
+						SpawnStatic(i,j,stat_gasmask,spawnz);
+					if (loadedgame == false)
+						gamestate.supertotal ++;
+					break;
+				case 461:
+						SpawnStatic(i,j,stat_disk,spawnz);
+					break;
+				 }
+			}
+		}
+   }
+
+
+
+void RaiseSprites( int x, int y, int count, int dir )
+{
+	int a,c;
+	int dx,dy;
+	int h;
+   int i;
+   int xx;
+   int hc;
+   int d;
+
+   dx=0;
+   dy=0;
+   if (dir==1)
+      dx=1;
+   else
+      dy=1;
+
+
+   if (((statobj_t *)sprites[x][y])->z==-65)
+      {
+      c=(maxheight+20)<<8;
+      hc=(count+1)<<7;
+      a=(c<<8)/(hc*hc);
+      for (i=0;i<count;i++)
+         {
+         xx=-hc+((i+1)<<8);
+         h=(c-FixedMulShift(a,(xx*xx),8) )>>8;
+         ((statobj_t *)sprites[x+(dx*i)][y+(dy*i)])->z=maxheight-h;
+         }
+      }
+   else
+      {
+      if (ActorIsSpring(x-(dx),y-(dy)))
+         d=1;
+      else if (ActorIsSpring(x+(dx*count),y+(dy*count)))
+         d=0;
+      else
+         Error("Cannot find a spring board around a ramp ascension near x=%d y=%d\n",x,y);
+
+      hc=((maxheight+20)<<16)/(count+1);
+      h=hc<<1;
+      for (i=0;i<count;i++)
+         {
+         if (d==1)
+            ((statobj_t *)sprites[x+(dx*i)][y+(dy*i)])->z=maxheight-(h>>16);
+         else
+            ((statobj_t *)sprites[x+(dx*(count-i-1))][y+(dy*(count-i-1))])->z=maxheight-(h>>16);
+         h+=hc;
+         }
+      }
+}
+
+void LoftSprites( void )
+{
+   int x,y;
+   int count;
+
+   for(y=1;y<mapheight-1;y++)
+      {
+    	for(x=1;x<mapwidth-1;x++)
+         {
+         if (StaticUndefined(x,y))
+            {
+            if (StaticUndefined(x+1,y))
+               {
+               count=1;
+               while (StaticUndefined(x+count,y))
+                  count++;
+               if (count<3)
+                  Error ("Are You kidding me? You are trying to loft <3 sprites in an arc??? \n x=%d y=%d\n",x,y);
+               RaiseSprites(x,y,count,1);
+               }
+            else if (StaticUndefined(x,y+1))
+               {
+               count=1;
+               while (StaticUndefined(x,y+count))
+                  count++;
+               if (count<3)
+                  Error ("Are You kidding me? You are trying to loft <3 sprites??? \n x=%d y=%d\n",x,y);
+               RaiseSprites(x,y,count,0);
+               }
+            else
+               Error ("Sprite Lofter is confused around x=%d y=%d\n",x,y);
+            }
+         }
+      }
+}
+

Added: tags/rott-1.1/rott/rt_ted.h
===================================================================
--- tags/rott-1.1/rott/rt_ted.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_ted.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,184 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    RT_TED.C - Ted stuff for maps and such
+//
+//***************************************************************************
+
+#include "rottnet.h"
+
+
+#ifndef _rt_ted_public
+#define _rt_ted_public
+
+#define MAXCLOCKS 10
+#define MAXSPAWNLOCATIONS 50
+#define POWERUPTICS  ((VBLCOUNTER*60)+6)
+#define IsPlatform(x,y)  ( (MAPSPOT((x),(y),2)==1) || ((MAPSPOT((x),(y),2)>=4) && (MAPSPOT((x),(y),2)<=9)))
+
+#define EXITTILE             (107)
+#define SECRETEXITTILE       (106)
+
+#define FL_SWITCH      0x01
+#define FL_ON          0x02
+#define FL_REVERSIBLE  0x04
+#define FL_W_DAMAGE    0x08
+#define FL_W_INVERTED  0x10
+#define FL_S_FLIPPED   0x20
+
+
+
+#define MAXTEAMS 11
+
+typedef struct
+{
+ int nummembers;
+ int uniformcolor;
+ int tilex,tiley;
+ byte dir;
+
+} teamtype;
+
+extern teamtype TEAM[MAXPLAYERS];
+
+typedef struct
+{ thingtype   which;
+  byte        flags;
+  byte        hitpoints;
+  word        tile;
+  byte        tilex,tiley;
+
+
+} wall_t;
+
+typedef struct
+{
+  int  number;
+  char mapname[23];
+} mapinfo_t;
+
+typedef struct
+{
+  int  nummaps;
+  mapinfo_t maps[100];
+} mapfileinfo_t;
+
+#define MAXLEVELNAMELENGTH 23
+#define ALLOCATEDLEVELNAMELENGTH 24
+#define NUMPLANES        3
+#define NUMHEADEROFFSETS 100
+
+#define MAP_SPECIAL_TOGGLE_PUSHWALLS 0x0001
+
+typedef struct
+   {
+   unsigned used;
+   unsigned CRC;
+   unsigned RLEWtag;
+   unsigned MapSpecials;
+   unsigned planestart[ NUMPLANES ];
+   unsigned planelength[ NUMPLANES ];
+   char     Name[ ALLOCATEDLEVELNAMELENGTH ];
+   } RTLMAP;
+
+
+typedef struct
+ {int x,y,dir;
+ }_2dvec;
+
+extern _2dvec SPAWNLOC[MAXSPAWNLOCATIONS],FIRST,SECOND;
+
+typedef struct
+ {int time1;
+  int time2;
+  byte points_to_tilex;
+  byte points_to_tiley;
+  int linkindex;
+ }str_clock;
+
+
+extern int  numareatiles[NUMAREAS+1];
+extern int  shapestart,shapestop;
+extern int  NUMSPAWNLOCATIONS;
+extern int  mapwidth;
+extern int  mapheight;
+
+extern  wall_t walls[MAXWALLTILES];
+extern str_clock Clocks[MAXCLOCKS];
+extern int LightsInArea[NUMAREAS+1];
+extern int numclocks;
+extern word ELEVATORLOCATION;
+
+extern unsigned short int *mapplanes[3];
+extern int gunsstart;
+extern int elevatorstart;
+extern int spritestop;
+extern int fog;
+extern int lightsource;
+extern int SNAKELEVEL;
+extern boolean insetupgame;
+extern char LevelName[80];
+extern boolean ISRTL;
+
+void PreCacheGroup(int,int,int); // added type
+void AssignTeams(void);
+void LoadTedMap( const char *extension, int mapnum );
+void SetupGameLevel(void);
+void ScanInfoPlane(void);
+void PreCacheLump( int lump, int level, int type ); // added type
+void SetupGameLevelAgain (void);
+void ScanInfoPlaneAgain (void);
+void PreCacheActor( int actor, int which );
+void PreCache( void );
+
+void SetupWalls( void );
+void SetupAnimatedWalls( void );
+void SetupSwitches( void );
+void SetupPlayers( void );
+void SetupMaskedWalls( void );
+void SetupPushWalls( void );
+void SetupPushWallLinks( void );
+void SetupDoors (void);
+void SetupDoorLinks (void);
+void SetupClocks (void);
+void SetupLinkedActors (void);
+void SetupLights(void);
+void SetupWindows ( void );
+
+int GetWallIndex( int texture );
+void PrintMapStats (void);
+void PrintTileStats (void);
+
+void GetMapInfo (mapfileinfo_t * mapinfo);
+void GetMapFileName ( char * filename );
+void SetBattleMapFileName ( char * filename );
+word GetMapCRC ( int num );
+
+int GetNextMap ( int tilex, int tiley );
+void Illuminate();
+
+int GetSongForLevel ( void );
+void CheckHolidays(void);
+boolean IsChristmas(void);
+
+boolean DoPanicMapping (void);
+
+#endif

Added: tags/rott-1.1/rott/rt_util.c
===================================================================
--- tags/rott-1.1/rott/rt_util.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_util.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1923 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#include "rt_def.h"
+
+#ifdef DOS
+#include <malloc.h>
+#include <dos.h>
+#include <conio.h>
+#include <io.h>
+#include <direct.h>
+#elif USE_SDL
+#include "SDL.h"
+#endif
+
+#include <stdarg.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <time.h>
+#include "watcom.h"
+#include "_rt_util.h"
+#include "rt_util.h"
+#include "isr.h"
+#include "z_zone.h"
+#include "rt_dr_a.h"
+#include "rt_in.h"
+#include "rt_main.h"
+#include "scriplib.h"
+#include "rt_menu.h"
+#include "rt_playr.h"
+#include "version.h"
+#include "develop.h"
+#include "rt_vid.h"
+#include "rt_view.h"
+#include "modexlib.h"
+#include "rt_cfg.h"
+//MED
+#include "memcheck.h"
+
+int    egacolor[16];
+byte   *  origpal;
+FILE   *  errout;
+FILE   *  debugout;
+FILE   *  mapdebugout;
+
+static boolean SoftErrorStarted=false;
+static boolean DebugStarted=false;
+static boolean MapDebugStarted=false;
+
+static unsigned char egargb[48]={ 0x00,0x00,0x00,
+									 0x00,0x00,0xab,
+                            0x00,0xab,0x00,
+                            0x00,0xab,0xab,
+                            0xab,0x00,0x00,
+                            0xab,0x00,0xab,
+                            0xab,0x57,0x00,
+                            0xab,0xab,0xab,
+                            0x57,0x57,0x57,
+                            0x57,0x57,0xff,
+                            0x57,0xff,0x57,
+                            0x57,0xff,0xff,
+                            0xff,0x57,0x57,
+                            0xff,0x57,0xff,
+                            0xff,0xff,0x57,
+									 0xff,0xff,0xff};
+
+extern const byte * ROTT_ERR;
+
+#if (DEVELOPMENT == 1)
+int TotalStaticMemory=0;
+#endif
+
+#define SWAP(a,b) \
+   {              \
+   a=(a)^(b);     \
+   b=(a)^(b);     \
+   a=(a)^(b);     \
+   }              \
+
+//******************************************************************************
+//
+// FindDistance
+//
+//******************************************************************************
+
+int FindDistance(int ix, int iy)
+{
+  int   t;
+
+  ix= abs(ix);        /* absolute values */
+  iy= abs(iy);
+
+  if (ix<iy)
+     SWAP(ix,iy);
+
+  t = iy + (iy>>1);
+
+  return (ix - (ix>>5) - (ix>>7)  + (t>>2) + (t>>6));
+}
+
+
+//******************************************************************************
+//
+// Find_3D_Distance
+//
+//******************************************************************************
+
+int Find_3D_Distance(int ix, int iy, int iz)
+   {
+   int   t;
+
+   ix= abs(ix);           /* absolute values */
+   iy= abs(iy);
+   iz= abs(iz);
+
+   if (ix<iy)
+     SWAP(ix,iy);
+
+   if (ix<iz)
+     SWAP(ix,iz);
+
+   t = iy + iz;
+
+   return (ix - (ix>>4) + (t>>2) + (t>>3));
+   }
+
+//******************************************************************************
+//
+// atan2_appx
+//
+//******************************************************************************
+
+int atan2_appx(int dx, int dy)
+{int absdx, absdy;
+ fixed angle;
+ fixed ratio;
+
+
+ if (!(dx||dy))
+  return 0;
+ absdx = abs(dx);
+ absdy = abs(dy);
+ if (absdx >= absdy)
+  ratio = FixedDiv2(absdy,absdx);
+ else
+  ratio = FixedDiv2(absdx,absdy);
+
+ if (dx >= 0)
+  {if (dy >= 0)
+	 {if (absdx >= absdy)
+		angle = ratio;	    // 1st octant
+	  else
+		angle = (2<<16) - ratio; // 2nd octant
+	 }
+	else
+	 {if (absdx >= absdy)
+		angle = (8<<16) - ratio; // 8th octant
+	  else
+		angle = (6<<16) + ratio; // 7th octant
+	 }
+  }
+ else
+  {if (dy >= 0)
+	 {if (absdx >= absdy)
+		angle = (4<<16) - ratio; // 4th octant
+	  else
+		angle = (2<<16) + ratio; // 3rd octant
+	 }
+	else
+	 {if (absdx >= absdy)
+		angle = (4<<16) + ratio; // 5th octant
+	  else
+		angle = (6<<16) - ratio; // 6th octant
+	 }
+  }
+
+ return (((int)FixedMul(angle,ANGLESDIV8))&(FINEANGLES-1));
+}
+
+
+
+//******************************************************************************
+//
+// StringsNotEqual
+//
+//******************************************************************************
+boolean StringsNotEqual (char * s1, char * s2, int length)
+{
+   int i;
+
+   for (i=0;i<length;i++)
+      if (s1[i]!=s2[i])
+         return true;
+   return false;
+}
+
+
+
+void markgetch( void )
+{
+   int done;
+   int i;
+
+   done=0;
+   while (done==0)
+      {
+      IN_UpdateKeyboard ();
+      for (i=0;i<127;i++)
+         if (Keyboard[i]==1)
+            done=i;
+      }
+   while (Keyboard[done])
+      IN_UpdateKeyboard ();
+}
+
+/*
+====================
+=
+= FindEGAColors
+=
+====================
+*/
+
+void FindEGAColors ( void )
+{
+   int i;
+
+	for (i=0;i<16;i++)
+		egacolor[i]=BestColor((int)egargb[i*3],(int)egargb[i*3+1],(int)egargb[i*3+2],origpal);
+}
+
+//===========================================================================
+
+
+byte BestColor (int r, int g, int b, byte *palette)
+{
+	int	i;
+	long	dr, dg, db;
+	long	bestdistortion, distortion;
+	int	bestcolor;
+	byte	*pal;
+
+//
+// let any color go to 0 as a last resort
+//
+   bestdistortion = ( (long)WeightR*r*r + (long)WeightG*g*g + (long)WeightB*b*b )*2;
+	bestcolor = 0;
+
+	pal = &palette[0];
+	for (i=0 ; i<= 255 ; i++,pal+=3)
+	{
+		dr = r - (int)pal[0];
+		dg = g - (int)pal[1];
+		db = b - (int)pal[2];
+      distortion = WeightR*dr*dr + WeightG*dg*dg + WeightB*db*db;
+		if (distortion < bestdistortion)
+		{
+			if (!distortion)
+				return i;		// perfect match
+
+			bestdistortion = distortion;
+			bestcolor = i;
+		}
+	}
+
+	return bestcolor;
+}
+
+void ClearGraphicsScreen( void )
+{
+VL_ClearVideo(0);
+}
+
+void ClearBuffer( char * buf, int size )
+{
+        memset(buf,0,size);
+}
+
+/*
+=============================================================================
+
+						MISC FUNCTIONS
+
+=============================================================================
+*/
+
+/*
+=================
+=
+= Error
+=
+= For abnormal program terminations
+=
+=================
+*/
+
+void Error (char *error, ...)
+{
+   char msgbuf[300];
+	va_list	argptr;
+   char i;
+   int size;
+   char * sptr;
+   char buf[30];
+   int handle;
+   int x,y;
+   int level;
+   static int inerror = 0;
+   char filename[ 128 ];
+
+
+   inerror++;
+   if (inerror > 1)
+      abort();
+
+
+	SetTextMode ();
+#ifdef DOS
+   memcpy ((byte *)0xB8000, &ROTT_ERR, 160*7);
+#elif defined (ANSIESC)
+   DisplayTextSplash (&ROTT_ERR, 7);
+#endif
+   memset (msgbuf, 0, 300);
+
+#ifdef DOS
+   px = ERRORVERSIONCOL-1;
+   py = ERRORVERSIONROW;
+#if (SHAREWARE == 1)
+   UL_printf ("S");
+#else
+   UL_printf ("R");
+#endif
+
+   px = ERRORVERSIONCOL;
+   py = ERRORVERSIONROW;
+#if (BETA == 1)
+   UL_printf ("á");
+#else
+   UL_printf (itoa(ROTTMAJORVERSION,&buf[0],10));
+#endif
+
+   // Skip the dot
+   px++;
+
+   UL_printf (itoa(ROTTMINORVERSION,&buf[0],10));
+#endif
+
+	va_start (argptr, error);
+   vsprintf (&msgbuf[0], error, argptr);
+	va_end (argptr);
+
+   scriptbuffer = &msgbuf[0];
+	size = strlen (msgbuf);
+
+	sptr = script_p = scriptbuffer;
+	scriptend_p = script_p + size;
+	scriptline = 1;
+	endofscript = false;
+	tokenready = false;
+
+   px = ERRORCOL;
+   py = ERRORROW;
+
+   GetToken (true);
+   while (!endofscript)
+   {
+      if ((script_p - sptr) >= 60)
+      {
+         px = ERRORCOL;
+         py++;
+         sptr = script_p;
+      }
+
+      UL_printf (token);
+      px++;                //SPACE
+      GetToken (true);
+   }
+
+#ifdef ANSIESC
+   for (i = 0; i < 8; i++)
+      printf ("\n");
+#endif
+
+   if (player!=NULL)
+      {
+      printf ("Player X     = %lx\n", (long int)player->x);
+      printf ("Player Y     = %lx\n", (long int)player->y);
+      printf ("Player Angle = %lx\n\n", (long int)player->angle);
+      }
+   printf ("Episode      = %ld\n", (long int)gamestate.episode);
+
+   if (gamestate.episode > 1)
+      level = (gamestate.mapon+1) - ((gamestate.episode-1) << 3);
+   else
+      level = gamestate.mapon+1;
+
+   printf ("Area         = %ld\n", (long int)level);
+
+   ShutDown();	// DDOI - moved this so that it doesn't try to access player
+   		// which is freed by this function.
+
+#ifdef DOS
+   GetPathFromEnvironment( filename, ApogeePath, ERRORFILE );
+   handle=SafeOpenAppend ( filename );
+   for (y=0;y<16;y++)
+      {
+      for (x=0;x<160;x+=2)
+         SafeWrite(handle,(byte *)0xB8000+(y*160)+x,1);
+      i=10;
+      SafeWrite(handle,&i,1);
+      i=13;
+      SafeWrite(handle,&i,1);
+      }
+
+   close(handle);
+
+   if ( SOUNDSETUP )
+      {
+      getch();
+      }
+
+#endif
+
+   #if USE_SDL
+   SDL_Quit();
+   #endif
+
+   exit (1);
+}
+
+//#if (SOFTERROR==1)
+
+/*
+=================
+=
+= SoftwareError
+=
+=================
+*/
+void SoftwareError (char *error, ...)
+{
+	va_list	argptr;
+
+	if (SoftErrorStarted==false)
+      return;
+	va_start (argptr, error);
+   vfprintf (errout, error, argptr);
+	va_end (argptr);
+}
+
+//#endif
+
+
+//#if (DEBUG == 1)
+
+/*
+=================
+=
+= DebugError
+=
+=================
+*/
+void DebugError (char *error, ...)
+{
+	va_list	argptr;
+
+   if (DebugStarted==false)
+      return;
+	va_start (argptr, error);
+   vfprintf (debugout, error, argptr);
+	va_end (argptr);
+}
+
+//#endif
+
+/*
+=================
+=
+= OpenSoftError
+=
+=================
+*/
+void OpenSoftError ( void )
+{
+  errout = fopen(SOFTERRORFILE,"wt+");
+  SoftErrorStarted=true;
+}
+
+/*
+=================
+=
+= MapDebug
+=
+=================
+*/
+void MapDebug (char *error, ...)
+{
+	va_list	argptr;
+
+   if (MapDebugStarted==false)
+      return;
+	va_start (argptr, error);
+   vfprintf (mapdebugout, error, argptr);
+	va_end (argptr);
+}
+
+/*
+=================
+=
+= OpenMapDebug
+=
+=================
+*/
+void OpenMapDebug ( void )
+{
+  char filename[ 128 ];
+
+  if (MapDebugStarted==true)
+     return;
+  GetPathFromEnvironment( filename, ApogeePath, MAPDEBUGFILE );
+  mapdebugout = fopen(filename,"wt+");
+  MapDebugStarted=true;
+}
+
+
+/*
+=================
+=
+= StartupSoftError
+=
+=================
+*/
+void StartupSoftError ( void )
+{
+#if (DEBUG == 1)
+  if (DebugStarted==false)
+     {
+     debugout = fopen(DEBUGFILE,"wt+");
+     DebugStarted=true;
+     }
+#endif
+#if (SOFTERROR == 1)
+  if (SoftErrorStarted==false)
+     OpenSoftError();
+#endif
+}
+
+/*
+=================
+=
+= ShutdownSoftError
+=
+=================
+*/
+void ShutdownSoftError ( void )
+{
+  if (DebugStarted==true)
+     {
+     fclose(debugout);
+     DebugStarted=false;
+     }
+  if (SoftErrorStarted==true)
+     {
+     fclose(errout);
+     SoftErrorStarted=false;
+     }
+  if (MapDebugStarted==true)
+     {
+     fclose(mapdebugout);
+     MapDebugStarted=false;
+     }
+}
+
+
+/*
+=================
+=
+= CheckParm
+=
+= Checks for the given parameter in the program's command line arguments
+=
+= Returns the argument number (1 to argc-1) or 0 if not present
+=
+=================
+*/
+
+int CheckParm (char *check)
+{
+	int		i;
+	char	*parm;
+
+	for (i = 1;i<_argc;i++)
+	{
+		parm = _argv[i];
+		if ( !isalpha(*parm) )	// skip - / \ etc.. in front of parm
+         {
+         parm++;
+         if (!*parm)
+				continue;		// parm was only one char
+         }
+
+		if ( !_fstricmp(check,parm) )
+			return i;
+	}
+
+	return 0;
+}
+
+
+
+int SafeOpenAppend (char *_filename)
+{
+	int	handle;
+    char filename[MAX_PATH];
+    strncpy(filename, _filename, sizeof (filename));
+    filename[sizeof (filename) - 1] = '\0';
+    FixFilePath(filename);
+
+	handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_APPEND
+	, S_IREAD | S_IWRITE);
+
+	if (handle == -1)
+		Error ("Error opening for append %s: %s",filename,strerror(errno));
+
+	return handle;
+}
+
+int SafeOpenWrite (char *_filename)
+{
+	int	handle;
+    char filename[MAX_PATH];
+    strncpy(filename, _filename, sizeof (filename));
+    filename[sizeof (filename) - 1] = '\0';
+    FixFilePath(filename);
+
+	handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_TRUNC
+	, S_IREAD | S_IWRITE);
+
+	if (handle == -1)
+		Error ("Error opening %s: %s",filename,strerror(errno));
+
+	return handle;
+}
+
+int SafeOpenRead (char *_filename)
+{
+	int	handle;
+    char filename[MAX_PATH];
+    strncpy(filename, _filename, sizeof (filename));
+    filename[sizeof (filename) - 1] = '\0';
+    FixFilePath(filename);
+
+	handle = open(filename,O_RDONLY | O_BINARY);
+
+	if (handle == -1)
+		Error ("Error opening %s: %s",filename,strerror(errno));
+
+	return handle;
+}
+
+
+void SafeRead (int handle, void *buffer, long count)
+{
+	unsigned	iocount;
+
+	while (count)
+	{
+		iocount = count > 0x8000 ? 0x8000 : count;
+		if (read (handle,buffer,iocount) != (int)iocount)
+			Error ("File read failure reading %ld bytes",count);
+		buffer = (void *)( (byte *)buffer + iocount );
+		count -= iocount;
+	}
+}
+
+
+void SafeWrite (int handle, void *buffer, long count)
+{
+	unsigned	iocount;
+
+	while (count)
+	{
+		iocount = count > 0x8000 ? 0x8000 : count;
+		if (write (handle,buffer,iocount) != (int)iocount)
+			Error ("File write failure writing %ld bytes",count);
+		buffer = (void *)( (byte *)buffer + iocount );
+		count -= iocount;
+	}
+}
+
+void SafeWriteString (int handle, char * buffer)
+{
+	unsigned	iocount;
+
+   iocount=strlen(buffer);
+	if (write (handle,buffer,iocount) != (int)iocount)
+			Error ("File write string failure writing %s\n",buffer);
+}
+
+void *SafeMalloc (long size)
+{
+	void *ptr;
+
+   if (zonememorystarted==false)
+      Error("Called SafeMalloc without starting zone memory\n");
+	ptr = Z_Malloc (size,PU_STATIC,NULL);
+
+	if (!ptr)
+      Error ("SafeMalloc failure for %lu bytes",size);
+
+	return ptr;
+}
+
+void *SafeLevelMalloc (long size)
+{
+	void *ptr;
+
+   if (zonememorystarted==false)
+      Error("Called SafeLevelMalloc without starting zone memory\n");
+   ptr = Z_LevelMalloc (size,PU_STATIC,NULL);
+
+	if (!ptr)
+      Error ("SafeLevelMalloc failure for %lu bytes",size);
+
+	return ptr;
+}
+
+void SafeFree (void * ptr)
+{
+   if ( ptr == NULL )
+      Error ("SafeFree : Tried to free a freed pointer\n");
+
+	Z_Free (ptr);
+}
+
+/*
+==============
+=
+= LoadFile
+=
+==============
+*/
+
+long	LoadFile (char *filename, void **bufferptr)
+{
+	int		handle;
+	long	length;
+
+	handle = SafeOpenRead (filename);
+	length = filelength (handle);
+	*bufferptr = SafeMalloc (length);
+	SafeRead (handle,*bufferptr, length);
+	close (handle);
+	return length;
+}
+
+
+/*
+==============
+=
+= SaveFile
+=
+==============
+*/
+
+void	SaveFile (char *filename, void *buffer, long count)
+{
+	int		handle;
+
+	handle = SafeOpenWrite (filename);
+	SafeWrite (handle, buffer, count);
+	close (handle);
+}
+
+
+void FixFilePath(char *filename)
+{
+#if PLATFORM_UNIX
+    char *ptr;
+    char *lastsep = filename;
+
+    if ((!filename) || (*filename == '\0'))
+        return;
+
+    if (access(filename, F_OK) == 0)  /* File exists; we're good to go. */
+        return;
+
+    for (ptr = filename; 1; ptr++)
+    {
+        if (*ptr == '\\')
+            *ptr = PATH_SEP_CHAR;
+
+        if ((*ptr == PATH_SEP_CHAR) || (*ptr == '\0'))
+        {
+            char pch = *ptr;
+            struct dirent *dent = NULL;
+            DIR *dir;
+
+            if ((pch == PATH_SEP_CHAR) && (*(ptr + 1) == '\0'))
+                return; /* eos is pathsep; we're done. */
+
+            if (lastsep == ptr)
+                continue;  /* absolute path; skip to next one. */
+
+            *ptr = '\0';
+            if (lastsep == filename) {
+                dir = opendir((*lastsep == PATH_SEP_CHAR) ? ROOTDIR : CURDIR);
+                
+                if (*lastsep == PATH_SEP_CHAR) {
+                    lastsep++;
+                }
+            } 
+            else
+            {
+                *lastsep = '\0';
+                dir = opendir(filename);
+                *lastsep = PATH_SEP_CHAR;
+                lastsep++;
+            }
+
+            if (dir == NULL)
+            {
+                *ptr = PATH_SEP_CHAR;
+                return;  /* maybe dir doesn't exist? give up. */
+            }
+
+            while ((dent = readdir(dir)) != NULL)
+            {
+                if (strcasecmp(dent->d_name, lastsep) == 0)
+                {
+                    /* found match; replace it. */
+                    strcpy(lastsep, dent->d_name);
+                    break;
+                }
+            }
+
+            closedir(dir);
+            *ptr = pch;
+            lastsep = ptr;
+
+            if (dent == NULL)
+                return;  /* no match. oh well. */
+
+            if (pch == '\0')  /* eos? */
+                return;
+        }
+    }
+#endif
+}
+
+
+#if PLATFORM_DOS
+ /* no-op. */
+
+#elif PLATFORM_WIN32
+int _dos_findfirst(char *filename, int x, struct find_t *f)
+{
+    long rc = _findfirst(filename, &f->data);
+    f->handle = rc;
+    if (rc != -1)
+    {
+        strncpy(f->name, f->data.name, sizeof (f->name) - 1);
+        f->name[sizeof (f->name) - 1] = '\0';
+        return(0);
+    }
+    return(1);
+}
+
+int _dos_findnext(struct find_t *f)
+{
+    int rc = 0;
+    if (f->handle == -1)
+        return(1);   /* invalid handle. */
+
+    rc = _findnext(f->handle, &f->data);
+    if (rc == -1)
+    {
+        _findclose(f->handle);
+        f->handle = -1;
+        return(1);
+    }
+
+    strncpy(f->name, f->data.name, sizeof (f->name) - 1);
+    f->name[sizeof (f->name) - 1] = '\0';
+    return(0);
+}
+
+#elif PLATFORM_UNIX 
+int _dos_findfirst(char *filename, int x, struct find_t *f)
+{
+    char *ptr;
+
+    if (strlen(filename) >= sizeof (f->pattern))
+        return(1);
+
+    strcpy(f->pattern, filename);
+    FixFilePath(f->pattern);
+    ptr = strrchr(f->pattern, PATH_SEP_CHAR);
+
+    if (ptr == NULL)
+    {
+        ptr = filename;
+        f->dir = opendir(CURDIR);
+    }
+    else
+    {
+        *ptr = '\0';
+        f->dir = opendir(f->pattern);
+        memmove(f->pattern, ptr + 1, strlen(ptr + 1) + 1);
+    }
+
+    return(_dos_findnext(f));
+}
+
+
+static int check_pattern_nocase(const char *x, const char *y)
+{
+    if ((x == NULL) || (y == NULL))
+        return(0);  /* not a match. */
+
+    while ((*x) && (*y))
+    {
+        if (*x == '*')
+            Error("Unexpected wildcard!");  /* FIXME? */
+
+        else if (*x == '?')
+        {
+            if (*y == '\0')
+                return(0);  /* anything but EOS is okay. */
+        }
+
+        else
+        {
+            if (toupper((int) *x) != toupper((int) *y))
+                return(0);  /* not a match. */
+        }
+
+        x++;
+        y++;
+    }
+
+    return(*x == *y);  /* it's a match (both should be EOS). */
+}
+
+int _dos_findnext(struct find_t *f)
+{
+    struct dirent *dent;
+
+    if (f->dir == NULL)
+        return(1);  /* no such dir or we're just done searching. */
+
+    while ((dent = readdir(f->dir)) != NULL)
+    {
+        if (check_pattern_nocase(f->pattern, dent->d_name))
+        {
+            if (strlen(dent->d_name) < sizeof (f->name))
+            {
+                strcpy(f->name, dent->d_name);
+                return(0);  /* match. */
+            }
+        }
+    }
+
+    closedir(f->dir);
+    f->dir = NULL;
+    return(1);  /* no match in whole directory. */
+}
+#else
+#error please define for your platform.
+#endif
+
+
+#if !PLATFORM_DOS
+void _dos_getdate(struct dosdate_t *date)
+{
+	time_t curtime = time(NULL);
+	struct tm *tm;
+	
+	if (date == NULL) {
+		return;
+	}
+	
+	memset(date, 0, sizeof(struct dosdate_t));
+	
+	if ((tm = localtime(&curtime)) != NULL) {
+		date->day = tm->tm_mday;
+		date->month = tm->tm_mon + 1;
+		date->year = tm->tm_year + 1900;
+		date->dayofweek = tm->tm_wday + 1;
+	}
+}
+#endif
+
+
+void GetPathFromEnvironment( char *fullname, const char *envname, const char *filename )
+   {
+
+#ifdef DOS
+   char *path;
+   path = getenv( envname );
+#else
+   const char *path;
+   path = envname;
+#endif
+
+   if ( path != NULL )
+      {
+      strcpy( fullname, path );
+      if ( fullname[ strlen( fullname ) - 1 ] != PATH_SEP_CHAR )
+         {
+         strcat( fullname, PATH_SEP_STR );
+         }
+      strcat( fullname, filename );
+      }
+   else
+      {
+      strcpy( fullname, filename );
+      }
+
+      FixFilePath(fullname);
+   }
+
+void DefaultExtension (char *path, char *extension)
+{
+	char	*src;
+//
+// if path doesn't have a .EXT, append extension
+// (extension should include the .)
+//
+	src = path + strlen(path) - 1;
+
+	while (*src != PATH_SEP_CHAR && src != path)
+	{
+		if (*src == '.')
+			return;			// it has an extension
+		src--;
+	}
+
+	strcat (path, extension);
+}
+
+void DefaultPath (char *path, char *basepath)
+{
+	char	temp[128];
+
+	if (path[0] == PATH_SEP_CHAR)
+		return;							// absolute path location
+	strcpy (temp,path);
+	strcpy (path,basepath);
+	strcat (path,temp);
+}
+
+
+void ExtractFileBase (char *path, char *dest)
+{
+	char	*src;
+	int		length;
+
+	src = path + strlen(path) - 1;
+
+//
+// back up until a \ or the start
+//
+	while (src != path && *(src-1) != PATH_SEP_CHAR)
+		src--;
+
+//
+// copy up to eight characters
+//
+	memset (dest,0,8);
+	length = 0;
+	while (*src && *src != '.')
+	{
+		if (++length == 9)
+			Error ("Filename base of %s >8 chars",path);
+		*dest++ = toupper(*src++);
+	}
+}
+
+
+/*
+==============
+=
+= ParseNum / ParseHex
+=
+==============
+*/
+
+long ParseHex (char *hex)
+{
+	char	*str;
+	long	num;
+
+	num = 0;
+	str = hex;
+
+	while (*str)
+	{
+		num <<= 4;
+		if (*str >= '0' && *str <= '9')
+			num += *str-'0';
+		else if (*str >= 'a' && *str <= 'f')
+			num += 10 + *str-'a';
+		else if (*str >= 'A' && *str <= 'F')
+			num += 10 + *str-'A';
+		else
+			Error ("Bad hex number: %s",hex);
+		str++;
+	}
+
+	return num;
+}
+
+
+long ParseNum (char *str)
+{
+	if (str[0] == '$')
+		return ParseHex (str+1);
+	if (str[0] == '0' && str[1] == 'x')
+		return ParseHex (str+2);
+	return atol (str);
+}
+
+
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+#define KeepShort IntelShort
+#define SwapShort MotoShort
+#define KeepLong IntelLong
+#define SwapLong MotoLong
+#else
+#define KeepShort MotoShort
+#define SwapShort IntelShort
+#define KeepLong MotoLong
+#define SwapLong IntelLong
+#endif
+
+short	SwapShort (short l)
+{
+	byte	b1,b2;
+
+	b1 = l&255;
+	b2 = (l>>8)&255;
+
+	return (b1<<8) + b2;
+}
+
+short	KeepShort (short l)
+{
+	return l;
+}
+
+
+int	SwapLong (int l)
+{
+	byte	b1,b2,b3,b4;
+
+	b1 = l&255;
+	b2 = (l>>8)&255;
+	b3 = (l>>16)&255;
+	b4 = (l>>24)&255;
+
+	return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
+}
+
+int	KeepLong (int l)
+{
+	return l;
+}
+
+
+#undef KeepShort
+#undef KeepLong
+#undef SwapShort
+#undef SwapLong
+
+void SwapIntelLong(int *l)
+{
+    *l = IntelLong(*l);
+}
+
+void SwapIntelShort(short *s)
+{
+    *s = IntelShort(*s);
+}
+
+void SwapIntelLongArray(int *l, int num)
+{
+    while (num--) {
+        SwapIntelLong(l);
+        l++;
+    }
+}
+
+void SwapIntelShortArray(short *s, int num)
+{
+    while (num--) {
+        SwapIntelShort(s);
+        s++;
+    }
+}
+
+/*
+============================================================================
+
+						BASIC GRAPHICS
+
+============================================================================
+*/
+
+/*
+==============
+=
+= GetaPalette
+=
+= Return an 8 bit / color palette
+=
+==============
+*/
+
+void GetaPalette (byte *palette)
+{
+#ifdef DOS
+	int	i;
+
+	OUTP (PEL_READ_ADR,0);
+	for (i=0 ; i<768 ; i++)
+		palette[i] = inp (PEL_DATA)<<2;
+#else
+	int i;
+	SDL_Palette *pal = SDL_GetVideoSurface()->format->palette;
+	
+	for (i = 0; i < 256; i++) {
+		palette[0] = pal->colors[i].r;
+		palette[1] = pal->colors[i].g;
+		palette[2] = pal->colors[i].b;
+		
+		palette += 3;
+	}
+#endif
+}
+
+/*
+==============
+=
+= SetaPalette
+=
+= Sets an 8 bit / color palette
+=
+==============
+*/
+
+void SetaPalette (byte *pal)
+{
+#ifdef DOS
+	int	i;
+
+	OUTP (PEL_WRITE_ADR,0);
+	for (i=0 ; i<768 ; i++)
+		OUTP (PEL_DATA, pal[i]>>2);
+#else
+   SDL_Color cmap[256];
+   int i;
+
+   for (i = 0; i < 256; i++)
+   {
+	   cmap[i].r = pal[i*3+0];
+	   cmap[i].g = pal[i*3+1];
+	   cmap[i].b = pal[i*3+2];
+   }
+
+   SDL_SetColors (SDL_GetVideoSurface (), cmap, 0, 256);
+#endif
+}
+
+void GetPalette(char * palette)
+{
+#ifdef DOS
+  int i;
+
+  OUTP(0x03c7,0);
+  for (i=0;i<256*3;i++)
+     *(palette+(unsigned char)i)=inp(0x3c9)<<2;
+#else
+	int i;
+	SDL_Palette *pal = SDL_GetVideoSurface()->format->palette;
+	
+	for (i = 0; i < 256; i++) {
+		palette[0] = pal->colors[i].r;
+		palette[1] = pal->colors[i].g;
+		palette[2] = pal->colors[i].b;
+		
+		palette += 3;
+	}
+#endif
+}
+
+void SetPalette ( char * pal )
+{
+   VL_SetPalette (pal);
+}
+
+
+
+//******************************************************************************
+//
+// US_CheckParm() - checks to see if a string matches one of a set of
+//    strings. The check is case insensitive. The routine returns the
+//    index of the string that matched, or -1 if no matches were found
+//
+//******************************************************************************
+
+int US_CheckParm (char *parm, char **strings)
+{
+   char  cp,cs,
+         *p,*s;
+   int      i;
+   int      length;
+
+   length=strlen(parm);
+   while ( (!isalpha(*parm)) && (length>0)) // Skip non-alphas
+      {
+      length--;
+      parm++;
+      }
+
+   for (i = 0;*strings && **strings;i++)
+   {
+      for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)
+      {
+         cs = *s++;
+         if (!cs)
+            return(i);
+         cp = *p++;
+
+         if (isupper(cs))
+            cs = tolower(cs);
+         if (isupper(cp))
+            cp = tolower(cp);
+      }
+   }
+   return(-1);
+}
+
+/*
+=============================================================================
+
+                  PALETTE OPS
+
+      To avoid snow, do a WaitVBL BEFORE calling these
+
+=============================================================================
+*/
+
+
+/*
+=================
+=
+= VL_FillPalette
+=
+=================
+*/
+
+void VL_FillPalette (int red, int green, int blue)
+{
+#ifdef DOS
+   int   i;
+
+   OUTP (PEL_WRITE_ADR,0);
+   for (i=0;i<256;i++)
+   {
+      OUTP (PEL_DATA,red);
+      OUTP (PEL_DATA,green);
+      OUTP (PEL_DATA,blue);
+   }
+#else
+   SDL_Color cmap[256];
+   int i;
+
+   for (i = 0; i < 256; i++)
+   {
+           cmap[i].r = red << 2;
+           cmap[i].g = green << 2;
+           cmap[i].b = blue << 2;
+   }
+
+   SDL_SetColors (SDL_GetVideoSurface (), cmap, 0, 256);
+#endif
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_SetColor
+=
+=================
+*/
+
+void VL_SetColor  (int color, int red, int green, int blue)
+{
+#ifdef DOS
+   OUTP (PEL_WRITE_ADR,color);
+   OUTP (PEL_DATA,red);
+   OUTP (PEL_DATA,green);
+   OUTP (PEL_DATA,blue);
+#else
+	STUB_FUNCTION;
+#endif
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_GetColor
+=
+=================
+*/
+
+void VL_GetColor  (int color, int *red, int *green, int *blue)
+{
+#ifdef DOS
+   OUTP (PEL_READ_ADR,color);
+   *red   = inp (PEL_DATA);
+   *green = inp (PEL_DATA);
+   *blue  = inp (PEL_DATA);
+#else
+	STUB_FUNCTION;
+#endif
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_NormalizePalette
+=
+=================
+*/
+
+void VL_NormalizePalette (byte *palette)
+{
+   int   i;
+
+   for (i = 0; i < 768; i++)
+      *(palette+i)=(*(palette+i))>>2;
+}
+
+
+/*
+=================
+=
+= VL_SetPalette
+=
+= If fast palette setting has been tested for, it is used
+= -some cards don't like outsb palette setting-
+=
+=================
+*/
+
+void VL_SetPalette (byte *palette)
+{
+#ifdef DOS
+   int   i;
+
+   OUTP (PEL_WRITE_ADR, 0);
+
+   for (i = 0; i < 768; i++)
+      {
+      OUTP (PEL_DATA, gammatable[(gammaindex<<6)+(*palette++)]);
+      }
+#else
+   SDL_Color cmap[256];
+   int i;
+
+   for (i = 0; i < 256; i++)
+   {
+	   cmap[i].r = gammatable[(gammaindex<<6)+(*palette++)] << 2;
+	   cmap[i].g = gammatable[(gammaindex<<6)+(*palette++)] << 2;
+	   cmap[i].b = gammatable[(gammaindex<<6)+(*palette++)] << 2;
+   }
+
+   SDL_SetColors (SDL_GetVideoSurface (), cmap, 0, 256);
+#endif
+}
+
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_GetPalette
+=
+= This does not use the port string instructions,
+= due to some incompatabilities
+=
+=================
+*/
+
+void VL_GetPalette (byte *palette)
+{
+#ifdef DOS
+   int   i;
+
+   OUTP (PEL_READ_ADR, 0);
+
+   for (i = 0; i < 768; i++)
+      *palette++ = inp (PEL_DATA);
+#else
+	int i;
+	SDL_Palette *pal = SDL_GetVideoSurface()->format->palette;
+	
+	for (i = 0; i < 256; i++) {
+		palette[0] = pal->colors[i].r >> 2;
+		palette[1] = pal->colors[i].g >> 2;
+		palette[2] = pal->colors[i].b >> 2;
+		
+		palette += 3;
+	}
+#endif
+}
+
+
+/*
+=================
+=
+= UL_DisplayMemoryError ()
+=
+=================
+*/
+
+void UL_DisplayMemoryError ( int memneeded )
+{
+#ifdef DOS
+   char buf[4000];
+   int i;
+
+   ShutDown ();
+   TextMode ();
+
+   for (i = 0; i < 19; i++)
+      printf ("\n");
+
+   memcpy (buf, &ROTT_ERR, 4000);
+   memcpy ((byte *)0xB8000, &buf[160*7], 4000-(160*7));
+
+   px = ERRORVERSIONCOL;
+   py = ERRORVERSIONROW;
+#if (BETA == 1)
+   UL_printf ("á");
+#else
+   UL_printf (itoa(ROTTMAJORVERSION,&buf[0],10));
+#endif
+   px++;
+
+   UL_printf (itoa(ROTTMINORVERSION,&buf[0],10));
+
+   px = LOWMEMORYCOL;
+   py = LOWMEMORYROW;
+   UL_printf ("You need ");
+   UL_printf (itoa(memneeded,&buf[0],10));
+   UL_printf (" bytes more memory");
+   if ( SOUNDSETUP )
+      {
+      getch();
+      }
+#else
+	STUB_FUNCTION;
+#endif
+   exit (0);
+}
+
+
+/*
+=================
+=
+= UL_printf
+=
+=================
+*/
+
+void UL_printf (byte *str)
+{
+#ifdef DOS
+   byte *s;
+   byte *screen;
+
+   s = str;
+   screen = (byte *)(0xB8000 + (py*160) + (px<<1));
+
+   while (*s)
+   {
+      *screen = *s;
+      s++;
+      screen += 2;
+      px++;
+
+      if ((*s < 32) && (*s > 0))
+         s++;
+   }
+#else
+#ifdef ANSIESC
+   printf ("\x1b[%d;%dH%s",py,px,str);
+#else
+   printf ("%s ",str);	// Hackish but works - DDOI
+#endif
+#endif
+}
+
+/*
+=================
+=
+= UL_ColorBox
+=
+=================
+*/
+
+void UL_ColorBox (int x, int y, int w, int h, int color)
+{
+#ifdef DOS
+   byte *screen;
+   int i,j;
+
+
+   for (j=0;j<h;j++)
+      {
+      screen = (byte *)(0xB8000 + ((y+j)*160) + (x<<1) + 1);
+      for (i=0;i<w;i++)
+         {
+         *screen = (byte)color;
+         screen+=2;
+         }
+      }
+#elif defined (ANSIESC)
+   int i,j;
+
+
+   for (j=0;j<h;j++)
+      {
+      for (i=0;i<w;i++)
+         {
+         printf ("\x1b[%d;%dH",y+j,x+i);
+         put_dos2ansi(color);
+         }
+      }
+#endif
+}
+
+//******************************************************************************
+//
+// SideOfLine
+//
+//******************************************************************************
+
+int SideOfLine(int x1, int y1, int x2, int y2, int x3, int y3)
+{
+   int a1,b1,c1;
+
+   /* Compute a1, b1, c1, where line joining points 1 and 2
+    * is "a1 x  +  b1 y  +  c1  =  0".
+    */
+
+   a1 = y2 - y1;
+   b1 = x1 - x2;
+   c1 = FixedMulShift(x2,y1,16) - FixedMulShift(x1,y2,16);
+
+   return SGN(FixedMulShift(a1,x3,16) + FixedMulShift(b1,y3,16) + c1);
+}
+
+
+
+//******************************************************************************
+//
+// HSORT - heap sort
+//
+//******************************************************************************
+
+typedef int (*PFI)();           /* pointer to a function returning int  */
+typedef void (*PFV)();           /* pointer to a function returning int  */
+static PFI Comp;                        /* pointer to comparison routine                */
+static PFV Switch;                        /* pointer to comparison routine                */
+static int Width;                       /* width of an object in bytes                  */
+static char *Base;                      /* pointer to element [-1] of array             */
+
+
+static void newsift_down(L,U) int L,U;
+{  int c;
+
+   while(1)
+      {c=L+L;
+      if(c>U) break;
+      if( (c+Width <= U) && ((*Comp)(Base+c+Width,Base+c)>0) ) c+= Width;
+      if ((*Comp)(Base+L,Base+c)>=0) break;
+      (*Switch)(Base+L, Base+c);
+      L=c;
+      }
+}
+
+void hsort(char * base, int nel, int width, int (*compare)(), void (*switcher)())
+{
+static int i,n,stop;
+        /*      Perform a heap sort on an array starting at base.  The array is
+                nel elements large and width is the size of a single element in
+                bytes.  Compare is a pointer to a comparison routine which will
+                be passed pointers to two elements of the array.  It should
+                return a negative number if the left-most argument is less than
+                the rightmost, 0 if the two arguments are equal, a positive
+                number if the left argument is greater than the right.  (That
+                is, it acts like a "subtract" operator.) If compare is 0 then
+                the default comparison routine, argvcmp (which sorts an
+                argv-like array of pointers to strings), is used.                                       */
+
+   Width=width;
+   Comp= compare;
+   Switch= switcher;
+   n=nel*Width;
+   Base=base-Width;
+   for (i=(n/Width/2)*Width; i>=Width; i-=Width) newsift_down(i,n);
+   stop=Width+Width;
+   for (i=n; i>=stop; )
+      {
+      (*Switch)(base, Base+i);
+      newsift_down(Width,i-=Width);
+      }
+
+}
+
+/*---------------------------------------------------------------------------*/
+
+//******************************************************************************
+//
+// UL_GetPath
+//
+// Purpose
+//    To parse the directory entered by the user to make the directory.
+//
+// Parms
+//    Path - the path to be parsed.
+//
+// Returns
+//    Pointer to next path
+//
+//******************************************************************************
+
+char * UL_GetPath (char * path, char *dir)
+{
+   boolean done      = 0;
+   char *dr          = dir;
+   int cnt           = 0;
+
+   if (*path == SLASHES)
+      path++;
+
+   while (!done)
+   {
+      *dr = *path;
+
+      cnt++;                  // make sure the number of characters in the dir
+      if (cnt > MAXCHARS)     // name doesn't exceed acceptable limits.
+         Error ("ERROR : Directory name can only be %d characters long.\n", MAXCHARS);
+
+      path++;
+      dr++;
+
+      if ((*path == SLASHES) || (*path == 0))
+         done = true;
+   }
+
+   *dr = 0;
+   return (path);
+}
+
+
+//******************************************************************************
+//
+// UL_ChangeDirectory ()
+//
+// Purpose
+//    To change to a directory.  Checks for drive changes.
+//
+// Parms
+//    path - The path to change to.
+//
+// Returns
+//    TRUE  - If successful.
+//    FALSE - If unsuccessful.
+//
+//******************************************************************************
+
+boolean UL_ChangeDirectory (char *path)
+{
+#ifdef DOS
+   char *p;
+   char dir[9];
+   char *d;
+
+   d = &dir[0];
+   p = path;
+   memset (dir, 0, 9);
+
+   // Check for a drive at the beginning of the path
+   if (*(p+1) == ':')
+   {
+      *d++ = *p++;      // drive letter
+      *d++ = *p++;      // colon
+
+      if (UL_ChangeDrive (dir) == false)
+         return (false);
+   }
+
+   if (*p == SLASHES)
+   {
+      chdir ("\\");
+      p++;
+   }
+
+   d = &dir[0];
+   while (*p)
+   {
+      p = UL_GetPath (p, d);
+
+      if (chdir (d) == -1)
+         return (false);
+   }
+
+   return (true);
+#else
+	if (!*path) {
+		return true;
+	}
+	
+	if (chdir (path) == -1) {
+	         return (false);
+	}
+	
+	return true;
+#endif
+}
+
+
+
+//******************************************************************************
+//
+// UL_ChangeDrive ()
+//
+// Purpose
+//    To change drives.
+//
+// Parms
+//    drive - The drive to change to.
+//
+// Returns
+//    TRUE  - If drive change successful.
+//    FALSE - If drive change unsuccessful.
+//
+//******************************************************************************
+
+boolean UL_ChangeDrive (char *drive)
+{
+#ifdef DOS
+   unsigned d, total, tempd;
+
+   d = toupper (*drive);
+
+   d = d - 'A' + 1;
+
+   _dos_setdrive (d, &total);
+   _dos_getdrive (&tempd);
+
+   if (d != tempd)
+      return (false);
+
+   return (true);
+#else
+	STUB_FUNCTION;
+	
+	return false;
+#endif
+}
+
+
+/*
+=============
+=
+= AbortCheck
+=
+=============
+*/
+void AbortCheck (char * abortstring)
+{
+   // User abort check
+
+   IN_UpdateKeyboard ();
+
+   if (Keyboard[sc_Escape])
+      Error("%s\n",abortstring);
+}

Added: tags/rott-1.1/rott/rt_util.h
===================================================================
--- tags/rott-1.1/rott/rt_util.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_util.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,210 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    RT_UTIL.C - various utils palette funcs and modex stuff
+//
+//***************************************************************************
+
+#ifndef _rt_util_public
+#define _rt_util_public
+
+#define ERRORVERSIONROW 1
+#define ERRORVERSIONCOL 67
+
+#define LOWMEMORYROW 18
+#define LOWMEMORYCOL 1
+
+#include "develop.h"
+
+extern  int    egacolor[16];
+extern  byte   *  origpal;
+extern  int      _argc;
+extern  char **  _argv;
+
+void  markgetch( void );
+boolean StringsNotEqual (char * s1, char * s2, int length);
+void  GetPalette(char * pal);
+void  ClearGraphicsScreen( void );
+void  ClearBuffer( char * buf, int size );
+void  Error (char *error, ...) __attribute__((noreturn,format(printf,1,2)));
+void  StartupSoftError ( void );
+void  ShutdownSoftError ( void );
+int   CheckParm (char *check);
+int   SafeOpenWrite (char *filename);
+int   SafeOpenAppend (char *filename);
+int   SafeOpenRead (char *filename);
+void  SafeRead (int handle, void *buffer, long count);
+void  SafeWrite (int handle, void *buffer, long count);
+void  SafeWriteString (int handle, char * buffer);
+void  *SafeMalloc (long size);
+void  *SafeLevelMalloc (long size);
+void  SafeFree (void * ptr);
+long  LoadFile (char *filename, void **bufferptr);
+void  SaveFile (char *filename, void *buffer, long count);
+void  GetPathFromEnvironment( char *fullname, const char *envname, const char *filename );
+void  DefaultExtension (char *path, char *extension);
+void  DefaultPath (char *path, char *basepath);
+void  ExtractFileBase (char *path, char *dest);
+long  ParseHex (char *hex);
+long  ParseNum (char *str);
+short MotoShort (short l);
+short IntelShort (short l);
+int   MotoLong (int l);
+int   IntelLong (int l);
+void  SwapIntelLong (int *l);
+void  SwapIntelShort(short *s);
+void  SwapIntelLongArray (int *l, int num);
+void  SwapIntelShortArray (short *s, int num);
+int   US_CheckParm (char *parm, char **strings);
+byte  BestColor (int r, int g, int b, byte *palette);
+int   atan2_appx(int,int);
+int   FindDistance(int ix, int iy);
+int   Find_3D_Distance(int ix, int iy, int iz);
+void  SetPalette ( char * pal );
+void  SetaPalette ( byte * pal );
+void  FindEGAColors ( void );
+void  VL_FillPalette (int red, int green, int blue);
+void  VL_SetColor  (int color, int red, int green, int blue);
+void  VL_GetColor  (int color, int *red, int *green, int *blue);
+void  VL_SetPalette (byte *palette);
+void  VL_GetPalette (byte *palette);
+void  UL_printf (byte *str);
+void  VL_NormalizePalette (byte *palette);
+void  MapDebug (char *error, ...) __attribute__((format(printf,1,2)));
+void  OpenMapDebug ( void );
+void  UL_ColorBox (int x, int y, int w, int h, int color);
+
+void UL_DisplayMemoryError ( int memneeded );
+
+int   SideOfLine(int x1, int y1, int x2, int y2, int x3, int y3);
+
+void hsort(char * base, int nel, int width, int (*compare)(), void (*switcher)());
+
+char * UL_GetPath (char * path, char *dir);
+boolean UL_ChangeDirectory (char *path);
+boolean UL_ChangeDrive (char *drive);
+void AbortCheck (char * abortstring);
+
+void FixFilePath(char *filename);
+
+
+#if PLATFORM_WIN32
+#include <io.h>
+struct find_t
+{
+	long handle;
+    struct _finddata_t data;
+	char name[MAX_PATH];
+};
+int _dos_findfirst(char *filename, int x, struct find_t *f);
+int _dos_findnext(struct find_t *f);
+
+#elif PLATFORM_UNIX
+struct find_t
+{
+    DIR *dir;
+    char pattern[MAX_PATH];
+    char name[MAX_PATH];
+};
+int _dos_findfirst(char *filename, int x, struct find_t *f);
+int _dos_findnext(struct find_t *f);
+
+#elif PLATFORM_DOS
+   /* no-op */
+#else
+#error please define for your platform.
+#endif
+
+
+#if !PLATFORM_DOS
+struct dosdate_t
+{
+    unsigned char day;
+    unsigned char month;
+    unsigned int year;
+    unsigned char dayofweek;
+};
+
+void _dos_getdate(struct dosdate_t *date);
+#endif
+
+
+#if (SOFTERROR==1)
+
+void  SoftwareError (char *error, ...) __attribute__((format(printf,1,2)));
+#define SoftError  SoftwareError
+
+#else
+void  SoftwareError (char *error, ...) __attribute__((format(printf,1,2)));
+//#define SoftError  SoftwareError
+
+#define SoftError  if (1) {} else SoftwareError
+
+//#define SoftError
+
+#endif
+
+#if (DEBUG==1)
+
+void  DebugError (char *error, ...) __attribute__((format(printf,1,2)));
+#define Debug  DebugError
+
+#else
+
+void  DebugError (char *error, ...) __attribute__((format(printf,1,2)));
+#define Debug  DebugError
+//#define Debug
+
+#endif
+
+void Square (void);
+
+#ifdef __WATCOMC__
+#pragma aux Square=\
+   "mov edx,03c4h",  \
+   "mov eax,0100h",  \
+	"out dx,ax",      \
+   "mov eax,0e3h",    \
+   "mov edx,03c2h",  \
+   "out dx,ax",      \
+   "mov eax,0300h",  \
+   "mov edx,03c4h",  \
+   "out dx,ax"      \
+   modify exact [eax edx]
+#endif
+
+
+#ifdef DOS
+void my_outp(int port, int data);
+#else
+#define my_outp(a,b)
+#endif
+
+#ifdef __WATCOMC__
+#pragma aux my_outp =  \
+        "out dx,al",                     \
+        parm    [edx] [eax] \
+        modify exact []
+#endif
+
+#define OUTP                              my_outp
+
+#endif

Added: tags/rott-1.1/rott/rt_vh_a.asm
===================================================================
--- tags/rott-1.1/rott/rt_vh_a.asm	                        (rev 0)
+++ tags/rott-1.1/rott/rt_vh_a.asm	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,195 @@
+.386p
+.model small
+
+
+ SC_INDEX   =  03C4h
+ SC_MAPMASK =  2
+ GC_INDEX   =  03CEh
+ GC_MODE    =  5
+
+
+ UPDATEWIDE =  20
+ UPDATEHIGH =  13
+
+ MaxJoyValue = 5000
+
+.DATA
+
+
+EXTRN _bufferofs        :DWORD
+EXTRN _displayofs       :DWORD
+EXTRN _ylookup          :DWORD
+EXTRN _linewidth        :DWORD
+EXTRN _blockstarts      :DWORD ;offsets from drawofs for each update block
+
+EXTRN _Joy_xb : BYTE
+EXTRN _Joy_yb : BYTE
+EXTRN _Joy_xs : BYTE
+EXTRN _Joy_ys : BYTE
+EXTRN _Joy_x  : WORD
+EXTRN _Joy_y  : WORD
+
+EXTRN _update            :DWORD
+
+
+
+.CODE
+
+ALIGN  4
+
+;=================
+;
+; VH_UpdateScreen
+;
+;=================
+
+PROC   VH_UpdateScreen_
+PUBLIC VH_UpdateScreen_
+
+   pushad
+
+   mov   edx,SC_INDEX
+   mov   eax,SC_MAPMASK+15*256
+
+; write through all planes
+
+   out   dx, ax
+
+   mov   edx, GC_INDEX
+   mov   al, GC_MODE
+   out   dx, al
+
+   inc   dx
+   in    al, dx
+   and   al, 252
+   or    al, 1
+   out   dx, al
+
+   mov   ebx, UPDATEWIDE*UPDATEHIGH-1    ; bx is the tile number
+   mov   edx, [_linewidth]
+
+;
+; see if the tile needs to be copied
+;
+@@checktile:
+   test  [_update+ebx],1
+   jnz   @@copytile
+@@next:
+   dec   ebx
+   jns   @@checktile
+
+;
+; done
+;
+   mov   dx, GC_INDEX+1
+   in    al, dx
+   and   al, NOT 3
+   or    al, 0
+   out   dx, al
+
+
+   popad
+
+   ret
+
+;
+; copy a tile
+;
+@@copytile:
+   mov   [BYTE PTR _update+ebx], 0
+   mov   esi, [_blockstarts+ebx*4]
+   mov   edi, esi
+   add   esi, [_bufferofs]
+   add   edi, [_displayofs]
+
+;   mov   ax, SCREENSEG
+;   mov   ds, ax
+
+REPT  16
+   mov   al, [esi]
+   mov   [edi],   al
+   mov   al, [esi+1]
+   mov   [edi+1], al
+   mov   al, [esi+2]
+   mov   [edi+2], al
+   mov   al, [esi+3]
+   mov   [edi+3], al
+   add   esi, edx
+   add   edi, edx
+ENDM
+
+   jmp   @@next
+
+ENDP VH_UpdateScreen_
+
+
+ALIGN  4
+
+;=================
+;
+; JoyStick_Vals
+;
+;=================
+
+PROC   JoyStick_Vals_
+PUBLIC JoyStick_Vals_
+
+
+; Read the absolute joystick values
+
+   pushf                ; Save some registers
+   push  ebp
+   cli                  ; Make sure an interrupt doesn't screw the timings
+
+   mov   dx, 0201h
+   in    al, dx
+   out   dx, al         ; Clear the resistors
+
+   mov   ah, BYTE PTR [_Joy_xb]   ; Get masks into registers
+   mov   ch, BYTE PTR [_Joy_yb]
+
+   xor   si, si         ; Clear count registers
+   xor   di, di
+   xor   bh, bh         ; Clear high byte of bx for later
+
+   mov   ebp, MaxJoyValue
+
+   @@LOOP:
+   in    al, dx         ; Get bits indicating whether all are finished
+
+   dec   ebp             ; Check bounding register
+   jz    done           ; We have a silly value - abort
+
+   mov   bl, al         ; Duplicate the bits
+   and   bl, ah         ; Mask off useless bits (in [xb])
+   add   si, bx         ; Possibly increment count register
+   mov   cl, bl         ; Save for testing later
+
+   mov   bl, al
+   and   bl, ch         ; [yb]
+   add   di, bx
+
+   add   cl, bl
+   jnz   @@LOOP         ; If both bits were 0, drop out
+
+   done:
+
+   mov   cl, [_Joy_xs]  ; Get the number of bits to shift
+   shr   si, cl         ;  and shift the count that many times
+
+   mov   cl, [_Joy_ys]
+   shr   di, cl
+
+   mov   [_Joy_x], si   ; Store the values into the variables
+   mov   [_Joy_y], di
+
+   pop   ebp
+   popf                 ; Restore the registers
+
+   ret
+
+ENDP   JoyStick_Vals_
+
+
+END
+

Added: tags/rott-1.1/rott/rt_vh_a.h
===================================================================
--- tags/rott-1.1/rott/rt_vh_a.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_vh_a.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,36 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_vh_a_public
+#define _rt_vh_a_public
+
+//***************************************************************************
+//
+// Public header for RT_VH_A.ASM.
+//
+//***************************************************************************
+
+void VH_UpdateScreen (void);
+void JoyStick_Vals (void);
+
+#ifdef __WATCOMC__
+#pragma aux JoyStick_Vals modify exact [eax ebx ecx edx esi edi]
+#endif
+
+#endif

Added: tags/rott-1.1/rott/rt_vid.c
===================================================================
--- tags/rott-1.1/rott/rt_vid.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_vid.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1387 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef DOS
+#include <dos.h>
+#include <conio.h>
+#endif
+
+#include "rt_def.h"
+#include "rt_vid.h"
+#include "_rt_vid.h"
+#include "rt_menu.h"
+#include "rt_util.h"
+#include "modexlib.h"
+#include "profile.h"
+#include "watcom.h"
+#include "rt_str.h"
+#include "rt_draw.h"
+#include "rt_in.h"
+#include "rt_main.h"
+#include "z_zone.h"
+#include "lumpy.h"
+#include "rt_vh_a.h"
+#include "isr.h"
+#include "rt_view.h"
+#include "cin_efct.h"
+#include "w_wad.h"
+//MED
+#include "memcheck.h"
+
+
+//******************************************************************************
+//
+// GLOBALS
+//
+//******************************************************************************
+
+byte     *updateptr;
+unsigned mapwidthtable[64];
+unsigned uwidthtable[UPDATEHIGH];
+unsigned blockstarts[UPDATEWIDE*UPDATEHIGH];
+byte     update[UPDATESIZE];
+byte     palette1[256][3], palette2[256][3];
+boolean  screenfaded;
+
+
+//******************************************************************************
+//
+// LOCALS
+//
+//******************************************************************************
+
+static byte  pixmasks[4] = {1,2,4,8};
+static byte  leftmasks[4] = {15,14,12,8};
+static byte  rightmasks[4] = {1,3,7,15};
+
+
+
+//******************************************************************************
+//
+// VL_MemToScreen ()
+//
+//******************************************************************************
+
+void VL_MemToScreen (byte *source, int width, int height, int x, int y)
+{
+#ifdef DOS
+   byte *screen, *dest, mask;
+   int  plane;
+
+   dest = (byte *)(bufferofs+ylookup[y]+(x>>2));
+//   dest = (byte *)(displayofs+ylookup[y]+(x>>2));
+   mask = 1 << (x&3);
+
+
+   for (plane = 0; plane<4; plane++)
+   {
+      VGAMAPMASK (mask);
+
+      screen = dest;
+      for (y = 0; y < height; y++, screen += linewidth, source+=width)
+         memcpy (screen, source, width);
+
+
+      mask <<= 1;
+
+      if (mask == 16)
+      {
+         mask = 1;
+         dest++;
+      }
+   }
+#else
+	/* TODO please optimize me */
+	
+	byte *ptr, *destline;
+	int plane, i, j;
+	
+	ptr = source;
+	
+	for (plane = 0; plane < 4; plane++) {
+		for (j = 0; j < height; j++) {
+			destline = (byte *)(bufferofs+ylookup[y+j]+x);
+
+			for (i = 0; i < width; i++) {
+//				if (ptr < bufferofs + toplimit) { //bnafix zxcvb
+					*(destline + i*4 + plane) = *ptr++;
+//				}
+			}			
+		}
+	}
+#endif
+}
+// bna function start
+void VL_MemToScreenClipped (byte *source, int width, int height, int x, int y);
+void VL_MemToScreenClipped (byte *source, int width, int height, int x, int y)
+{
+	byte *ptr, *destline;
+	int plane, i, j;//,toplimit;
+	ptr = source;
+	for (plane = 0; plane < 4; plane++) {
+		for (j = 0; j < height; j++) {
+			destline = (byte *)(bufferofs+ylookup[y+j]+x);
+			for (i = 0; i < width; i++) {
+				if (*ptr != 255){
+					*(destline + i*4 + plane) = *ptr++;
+				}else{ptr++;}
+			}			
+		}
+	}
+}
+
+//copy picture to mem (bufferofs) in doublesize
+void VL_MemStrechedToScreen (byte *source, int width, int height, int x, int y)
+{
+	byte *ptr, *destline,*tmp,*o;
+	int plane, i, j;
+	
+	tmp = bufferofs;
+	ptr = source;
+	
+	for (plane = 0; plane < 4; plane++) {
+		for (j = 0; j < height; j++) {
+			destline = (byte *)(bufferofs+(iGLOBAL_SCREENWIDTH*j)+ylookup[y+j]+x);
+			o = ptr;
+			for (i = 0; i < width; i+=1) {
+				*(destline + i*4 + plane) = *ptr;
+				destline++;
+				*(destline + i*4 + plane) = *ptr++;
+			}
+			ptr = o;
+
+			destline = (byte *)(bufferofs+iGLOBAL_SCREENWIDTH+(iGLOBAL_SCREENWIDTH*j)+ylookup[y+j]+x);
+			for (i = 0; i < width; i+=1) {
+				*(destline + i*4 + plane) = *ptr;
+				destline++;
+				*(destline + i*4 + plane) = *ptr++;
+
+			}	
+
+		}
+	}
+	bufferofs = tmp;
+}
+// bna function end
+
+
+//*************************************************************************
+//
+// DrawTiledRegion () - Fills the specified region with a tiled image
+//
+//*************************************************************************
+void DrawTiledRegion
+   (
+   int x,
+   int y,
+   int width,
+   int height,
+   int offx,
+   int offy,
+   pic_t *tile
+   )
+
+   {
+   byte  *source;
+   byte  *sourceoff;
+   int    sourcex;
+   int    sourcey;
+   int    sourcewidth;
+   int    sourceheight;
+   int    mask;
+   int    plane;
+   int    planesize;
+   byte  *start;
+   byte  *origdest;
+   byte  *dest;
+   int    startoffset;
+   int    HeightIndex;
+   int    WidthIndex;
+
+#ifdef DOS
+   start = ( byte * )( bufferofs + ( x>>2 ) + ylookup[ y ] );
+#else
+   start = ( byte * )( bufferofs +  x + ylookup[ y ] );
+#endif
+
+   source       = &tile->data;
+   sourcewidth  = tile->width;
+   sourceheight = tile->height;
+#ifdef DOS
+   offx >>= 2;
+#endif
+   if ( offx >= sourcewidth )
+      {
+      offx %= sourcewidth;
+      }
+   if ( offy >= sourceheight )
+      {
+      offy %= sourceheight;
+      }
+
+   startoffset = offy * sourcewidth;
+   planesize = sourcewidth * sourceheight;
+
+#ifdef DOS
+   width >>= 2;
+
+   mask  = 1 << ( x & 3 );
+#endif
+   plane = 4;
+   while( plane > 0 )
+      {
+      VGAMAPMASK( mask );
+      
+#ifdef DOS
+      origdest = start;
+#else
+      origdest = start+(4-plane);
+#endif
+
+      sourcey     = offy;
+      sourceoff   = source + startoffset;
+      HeightIndex = height;
+
+      while( HeightIndex-- )
+         {
+         dest       = origdest;
+         sourcex    = offx;
+         WidthIndex = width;
+         while( WidthIndex-- )
+            {
+            *dest = sourceoff[ sourcex ];
+#ifdef DOS
+            dest++;
+#else
+            dest += 4;
+#endif
+            
+            sourcex++;
+            if ( sourcex >= sourcewidth )
+               {
+               sourcex = 0;
+               }
+            }
+
+#ifdef DOS
+         origdest  += iGLOBAL_SCREENBWIDE;
+#else 
+         origdest += iGLOBAL_SCREENWIDTH;
+#endif
+
+         sourceoff += sourcewidth;
+         sourcey++;
+         if ( sourcey >= sourceheight )
+            {
+            sourcey   = 0;
+            sourceoff = source;
+            }
+         }
+
+      source += planesize;
+
+#ifdef DOS
+      mask <<= 1;
+      if ( mask > 8 )
+         {
+         mask = 1;
+         }
+#endif
+
+      plane--;
+      }
+   }
+
+
+//******************************************************************************
+//
+// VWB_DrawPic () - Draws a linear pic and marks the update block
+//
+//******************************************************************************
+
+void VWB_DrawPic (int x, int y, pic_t *pic)
+{
+   if (((iGLOBAL_SCREENWIDTH > 320) && !StretchScreen) ||
+       VW_MarkUpdateBlock (x, y, x+(pic->width<<2)-1, y+(pic->height)-1))
+      VL_MemToScreen ((byte *)&pic->data, pic->width, pic->height, x, y);
+}
+
+
+
+//******************************************************************************
+//
+// VL_Bar () - Draws a bar
+//
+//******************************************************************************
+
+void VL_Bar (int x, int y, int width, int height, int color)
+{
+#ifdef DOS
+   byte  *dest;
+   byte  leftmask,rightmask;
+   int   midbytes,linedelta;
+
+   leftmask = leftmasks[x&3];
+   rightmask = rightmasks[(x+width-1)&3];
+   midbytes = ((x+width+3)>>2) - (x>>2) - 2;
+   linedelta = linewidth-(midbytes+1);
+
+   dest = (byte *)(bufferofs+ylookup[y]+(x>>2));
+
+   if (midbytes < 0)
+   {
+   // all in one byte
+      VGAMAPMASK (leftmask&rightmask);
+      while (height--)
+      {
+         *dest = color;
+         dest += linewidth;
+      }
+      VGAMAPMASK (15);
+      return;
+   }
+
+   while (height--)
+   {
+      VGAMAPMASK (leftmask);
+      *dest++ = color;
+
+      VGAMAPMASK (15);
+      memset (dest,color,midbytes);
+      dest += midbytes;
+
+      VGAMAPMASK (rightmask);
+      *dest = color;
+
+      dest += linedelta;
+   }
+
+   VGAMAPMASK(15);
+#else
+	byte *dest = (byte *)(bufferofs+ylookup[y]+x);
+	
+	while (height--) {
+		memset(dest, color, width);
+		
+		dest += linewidth;
+	}
+#endif
+}
+
+
+
+//******************************************************************************
+//
+// VWB_Bar () - Draws a block and marks the update block
+//
+//******************************************************************************
+
+void VWB_Bar (int x, int y, int width, int height, int color)
+{
+   if (((iGLOBAL_SCREENWIDTH > 320) && !StretchScreen) ||
+       VW_MarkUpdateBlock (x,y,x+width,y+height-1) )
+      VL_Bar (x, y, width, height, color);
+}
+
+
+//******************************************************************************
+//
+// VL_TBar () - Draws a bar
+//
+//******************************************************************************
+
+void VL_TBar (int x, int y, int width, int height)
+{
+#ifdef DOS
+   byte  *dest;
+   byte  pixel;
+   byte  readmask;
+   byte  writemask;
+   int   w = width;
+
+   while (height--)
+   {
+      width = w;
+
+      dest = (byte*)(bufferofs+ylookup[y]+(x>>2));
+      readmask    = (x&3);
+      writemask   = 1 << readmask;
+
+      VGAREADMAP (readmask);
+      VGAMAPMASK (writemask);
+
+      while (width--)
+      {
+         pixel = *dest;
+
+         pixel = *(colormap+(27<<8)+pixel);
+
+         *dest = pixel;
+
+         writemask <<= 1;
+         if (writemask == 16)
+         {
+            writemask = 1;
+            dest++;
+         }
+
+         readmask++;
+         if (readmask == 4)
+            readmask = 0;
+
+         VGAREADMAP (readmask);
+         VGAMAPMASK (writemask);
+      }
+
+      y++;
+   }
+#else
+	int w = width;
+	
+	while (height--) {
+		byte *dest = (byte *)(bufferofs+ylookup[y]+x);
+		
+		width = w;
+		
+		while (width--) {
+			byte pixel = *dest;
+			
+			pixel = *(colormap+(27<<8)+pixel);
+			
+			*dest = pixel;
+			
+			dest++;
+		}
+		
+		y++;
+	}
+			
+#endif
+}
+
+
+
+//******************************************************************************
+//
+// VWB_TBar () - Draws a block and marks the update block
+//
+//******************************************************************************
+
+void VWB_TBar (int x, int y, int width, int height)
+{
+   if (VW_MarkUpdateBlock (x,y,x+width,y+height-1))
+      VL_TBar (x, y, width, height);
+}
+
+
+//******************************************************************************
+//
+// VL_Hlin () - Draws a horizontal line
+//
+//******************************************************************************
+
+void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color)
+{
+#ifdef DOS
+   unsigned xbyte;
+   byte     *dest;
+   byte     leftmask,
+            rightmask;
+   int      midbytes;
+
+   xbyte =      x >> 2;
+   leftmask    = leftmasks[x&3];
+   rightmask   = rightmasks[(x+width-1)&3];
+   midbytes    = ((x+width+3)>>2) - xbyte - 2;
+
+   dest = (byte*)(bufferofs+ylookup[y]+xbyte);
+
+   if (midbytes<0)
+   {
+     // all in one byte
+      VGAMAPMASK (leftmask & rightmask);
+      *dest = color;
+      VGAMAPMASK(15);
+      return;
+   }
+
+   VGAMAPMASK (leftmask);
+   *dest++ = color;
+
+   VGAMAPMASK (15);
+   memset (dest, color, midbytes);
+   dest += midbytes;
+
+   VGAMAPMASK (rightmask);
+   *dest = color;
+
+   VGAMAPMASK (15);
+#else
+	byte *dest = (byte*)(bufferofs+ylookup[y]+x);
+	
+	memset(dest, color, width);
+#endif
+}
+
+
+//******************************************************************************
+//
+// VL_Vlin () - Draws a vertical line
+//
+//******************************************************************************
+
+void VL_Vlin (int x, int y, int height, int color)
+{
+#ifdef DOS
+   byte  *dest,
+         mask;
+
+   mask = pixmasks[x&3];
+   VGAMAPMASK (mask);
+
+   dest = (byte *)(bufferofs+ylookup[y]+(x>>2));
+
+   while (height--)
+   {
+      *dest = color;
+      dest += linewidth;
+   }
+
+   VGAMAPMASK (15);
+#else
+	byte *dest = (byte*)(bufferofs+ylookup[y]+x);
+	
+	while (height--) {
+		*dest = color;
+		
+		dest += linewidth;
+	}
+#endif
+}
+
+
+
+//******************************************************************************
+//
+// VWB_Hlin () - Draws a horizontal line and marks the update block
+//
+//******************************************************************************
+
+void VWB_Hlin (int x1, int x2, int y, int color)
+{
+   if (VW_MarkUpdateBlock (x1,y,x2,y))
+      VW_Hlin(x1,x2,y,color);
+}
+
+
+//******************************************************************************
+//
+// VWB_Vlin () - Draws a vertical line and marks the update block
+//
+//******************************************************************************
+
+void VWB_Vlin (int y1, int y2, int x, int color)
+{
+   if (VW_MarkUpdateBlock (x,y1,x,y2))
+      VW_Vlin(y1,y2,x,color);
+}
+
+
+
+
+//******************************************************************************
+//
+// VL_THlin ()
+//
+//******************************************************************************
+
+void VL_THlin (unsigned x, unsigned y, unsigned width, boolean up)
+{
+#ifdef DOS
+   byte     *dest;
+   byte     pixel;
+   byte     readmask;
+   byte     writemask;
+
+
+   readmask    = (x&3);
+   writemask   = 1 << readmask;
+
+   dest = (byte*)(bufferofs+ylookup[y]+(x>>2));
+
+   VGAREADMAP (readmask);
+   VGAMAPMASK (writemask);
+
+   while (width--)
+   {
+      pixel = *dest;
+
+      if (up)
+         pixel = *(colormap+(13<<8)+pixel);
+      else
+         pixel = *(colormap+(27<<8)+pixel);
+
+      *dest = pixel;
+
+      writemask <<= 1;
+      if (writemask == 16)
+      {
+         writemask = 1;
+         dest++;
+      }
+
+      readmask++;
+      if (readmask == 4)
+         readmask = 0;
+
+      VGAREADMAP (readmask);
+      VGAMAPMASK (writemask);
+   }
+#else
+	byte *dest = (byte*)(bufferofs+ylookup[y]+x);
+	
+	while (width--) {
+		byte pixel = *dest;
+
+		if (up) {
+			pixel = *(colormap+(13<<8)+pixel);
+		} else {
+			pixel = *(colormap+(27<<8)+pixel);
+		}
+		
+		*dest = pixel;
+		
+		dest++;
+	}
+#endif
+}
+
+
+
+//******************************************************************************
+//
+// VL_TVlin ()
+//
+//******************************************************************************
+
+void VL_TVlin (unsigned x, unsigned y, unsigned height, boolean up)
+{
+#ifdef DOS
+   byte     *dest;
+   byte     pixel;
+   byte     readmask;
+   byte     writemask;
+
+
+
+   readmask    = (x&3);
+   writemask   = 1 << readmask;
+
+   dest = (byte*)(bufferofs+ylookup[y]+(x>>2));
+
+   VGAREADMAP (readmask);
+   VGAMAPMASK (writemask);
+
+   while (height--)
+   {
+      pixel = *dest;
+
+      if (up)
+         pixel = *(colormap+(13<<8)+pixel);
+      else
+         pixel = *(colormap+(27<<8)+pixel);
+
+      *dest = pixel;
+
+      dest += linewidth;
+   }
+#else
+	byte *dest = (byte*)(bufferofs+ylookup[y]+x);
+	
+	while (height--) {
+		byte pixel = *dest;
+
+		if (up) {
+			pixel = *(colormap+(13<<8)+pixel);
+		} else {
+			pixel = *(colormap+(27<<8)+pixel);
+		}
+		
+		*dest = pixel;
+		
+		dest += linewidth;
+	}
+#endif
+}
+
+
+
+//******************************************************************************
+//
+// VWB_THlin () - Draws a horizontal line and marks the update block
+//
+//******************************************************************************
+
+void VWB_THlin (int x1, int x2, int y, boolean up)
+{
+   if (VW_MarkUpdateBlock (x1,y,x2,y))
+      VW_THlin (x1,x2,y,up);
+}
+
+
+//******************************************************************************
+//
+// VWB_TVlin () - Draws a vertical line and marks the update block
+//
+//******************************************************************************
+
+void VWB_TVlin (int y1, int y2, int x, boolean up)
+{
+   if (VW_MarkUpdateBlock (x,y1,x,y2))
+      VW_TVlin (y1,y2,x,up);
+}
+
+
+
+/*
+================================================================================
+
+            Double buffer management routines
+
+================================================================================
+*/
+
+
+//******************************************************************************
+//
+// VW_MarkUpdateBlock
+//
+// Takes a pixel bounded block and marks the tiles in bufferblocks
+// Returns 0 if the entire block is off the buffer screen
+//
+//******************************************************************************
+
+int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2)
+{
+   int   x,
+         y,
+         xt1,
+         yt1,
+         xt2,
+         yt2,
+         nextline;
+   byte  *mark;
+
+   xt1 = x1 >> PIXTOBLOCK;
+   yt1 = y1 >> PIXTOBLOCK;
+
+   xt2 = x2 >> PIXTOBLOCK;
+   yt2 = y2 >> PIXTOBLOCK;
+
+   if (xt1 < 0)
+      xt1 = 0;
+   else
+      if (xt1 >= UPDATEWIDE)
+         return 0;
+
+   if (yt1 < 0)
+      yt1 = 0;
+   else
+      if (yt1 > UPDATEHIGH)
+         return 0;
+
+   if (xt2 < 0)
+      return 0;
+   else
+      if (xt2 >= UPDATEWIDE)
+         xt2 = UPDATEWIDE-1;
+
+   if (yt2 < 0)
+      return 0;
+   else
+      if (yt2 >= UPDATEHIGH)
+         yt2 = UPDATEHIGH-1;
+
+   mark = updateptr + uwidthtable[yt1] + xt1;
+   nextline = UPDATEWIDE - (xt2-xt1) - 1;
+
+   for (y = yt1; y <= yt2; y++)
+   {
+      for (x = xt1; x <= xt2; x++)
+         *mark++ = 1;                  // this tile will need to be updated
+
+      mark += nextline;
+   }
+
+   return 1;
+}
+
+
+//******************************************************************************
+//
+// VW_UpdateScreen ()
+//
+//******************************************************************************
+
+
+void VW_UpdateScreen (void)
+{
+   VH_UpdateScreen ();
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_FadeOut
+=
+= Fades the current palette to the given color in the given number of steps
+=
+=================
+*/
+
+void VL_FadeOut (int start, int end, int red, int green, int blue, int steps)
+{
+   int      i,j,orig,delta;
+   byte  *origptr, *newptr;
+
+   if (screenfaded)
+      return;
+
+   WaitVBL ();
+   VL_GetPalette (&palette1[0][0]);
+   memcpy (palette2, palette1, 768);
+
+//
+// fade through intermediate frames
+//
+   for (i = 0; i < steps; i++)
+   {
+      origptr = &palette1[start][0];
+      newptr = &palette2[start][0];
+
+      for (j = start; j <= end; j++)
+      {
+         orig = *origptr++;
+         delta = red-orig;
+         *newptr++ = orig + delta * i / steps;
+         orig = *origptr++;
+         delta = green-orig;
+         *newptr++ = orig + delta * i / steps;
+         orig = *origptr++;
+         delta = blue-orig;
+         *newptr++ = orig + delta * i / steps;
+      }
+
+      WaitVBL ();
+      VL_SetPalette (&palette2[0][0]);
+   }
+
+//
+// final color
+//
+   VL_FillPalette (red,green,blue);
+
+   screenfaded = true;
+}
+
+
+/*
+=================
+=
+= VL_FadeToColor
+=
+= Fades the current palette to the given color in the given number of steps
+=
+=================
+*/
+
+void VL_FadeToColor (int time, int red, int green, int blue)
+{
+   int      i,j,orig,delta;
+   byte  *origptr, *newptr;
+   int dmax,dmin;
+
+   if (screenfaded)
+      return;
+
+   WaitVBL ();
+   VL_GetPalette (&palette1[0][0]);
+   memcpy (palette2, palette1, 768);
+
+   dmax=(maxshade<<16)/time;
+   dmin=(minshade<<16)/time;
+//
+// fade through intermediate frames
+//
+   for (i = 0; i < time; i+=tics)
+   {
+      origptr = &palette1[0][0];
+      newptr = &palette2[0][0];
+
+      for (j = 0; j <= 255; j++)
+      {
+         orig = *origptr++;
+         delta = ((red>>2)-orig)<<16;
+         *newptr++ = orig + FixedMul(delta/time,i);
+         orig = *origptr++;
+         delta = ((green>>2)-orig)<<16;
+         *newptr++ = orig + FixedMul(delta/time,i);
+         orig = *origptr++;
+         delta = ((blue>>2)-orig)<<16;
+         *newptr++ = orig + FixedMul(delta/time,i);
+      }
+
+      maxshade=(dmax*(time-i))>>16;
+      minshade=(dmin*(time-i))>>16;
+      WaitVBL ();
+      VL_SetPalette (&palette2[0][0]);
+      ThreeDRefresh();
+      CalcTics();
+
+   }
+
+//
+// final color
+//
+   VL_FillPalette (red>>2,green>>2,blue>>2);
+
+   screenfaded = true;
+}
+
+
+
+
+/*
+=================
+=
+= VL_FadeIn
+=
+=================
+*/
+
+void VL_FadeIn (int start, int end, byte *palette, int steps)
+{
+   int      i,j,delta;
+
+   WaitVBL ();
+   VL_GetPalette (&palette1[0][0]);
+
+   memcpy (&palette2[0][0], &palette1[0][0], sizeof(palette1));
+
+   start *= 3;
+   end = end*3+2;
+
+//
+// fade through intermediate frames
+//
+   for (i=0;i<steps;i++)
+   {
+      for (j=start;j<=end;j++)
+      {
+         delta = palette[j]-palette1[0][j];
+         palette2[0][j] = palette1[0][j] + delta * i / steps;
+      }
+
+      WaitVBL ();
+      VL_SetPalette (&palette2[0][0]);
+   }
+
+//
+// final color
+//
+   VL_SetPalette (palette);
+   screenfaded = false;
+}
+
+
+
+//******************************************************************************
+//
+// SwitchPalette
+//
+//******************************************************************************
+
+void SwitchPalette (byte * newpal, int steps)
+{
+   byte *temp;
+
+   VL_FadeOut(0,255,0,0,0,steps>>1);
+
+   temp = bufferofs;
+   bufferofs = displayofs;
+   VL_Bar (0, 0, 320, 200, 0);
+   bufferofs = temp;
+
+   VL_FadeIn(0,255,newpal,steps>>1);
+}
+
+
+#if 0
+
+/*
+=================
+=
+= VL_TestPaletteSet
+=
+= Sets the palette with outsb, then reads it in and compares
+= If it compares ok, fastpalette is set to true.
+=
+=================
+*/
+
+void VL_TestPaletteSet (void)
+{
+   int   i;
+
+   for (i=0;i<768;i++)
+      palette1[0][i] = i;
+
+   fastpalette = true;
+   VL_SetPalette (&palette1[0][0]);
+   VL_GetPalette (&palette2[0][0]);
+   if (_fmemcmp (&palette1[0][0],&palette2[0][0],768))
+      fastpalette = false;
+}
+
+
+/*
+==================
+=
+= VL_ColorBorder
+=
+==================
+*/
+
+void VL_ColorBorder (int color)
+{
+   _AH=0x10;
+   _AL=1;
+   _BH=color;
+   geninterrupt (0x10);
+   bordercolor = color;
+}
+
+
+#endif
+
+
+//==========================================================================
+
+//****************************************************************************
+//
+// VL_DecompressLBM ()
+//
+// LIMITATIONS - Only works with 320x200!!!
+//
+//****************************************************************************
+
+void VL_DecompressLBM (lbm_t *lbminfo, boolean flip)
+{
+   byte *screen = (byte *)bufferofs;
+   byte *orig;
+	int  count;
+	byte b,
+        rept;
+   byte *source = (byte *)&lbminfo->data;
+   byte *buf;
+   int  ht = lbminfo->height;
+
+   int  x = 0;
+   int  y;
+   byte *origbuf;
+   byte pal[768];
+
+
+   orig = screen;
+
+   if (iGLOBAL_SCREENWIDTH <= 320){
+		buf = (byte *) SafeMalloc (64000);
+   }else{
+		buf = (byte *) SafeMalloc (iGLOBAL_SCREENWIDTH*iGLOBAL_SCREENHEIGHT);
+   }
+   origbuf = buf;
+
+   VL_ClearBuffer (displayofs, 0);
+
+   memcpy(&pal[0],lbminfo->palette,768);
+
+   VL_NormalizePalette (&pal[0]);
+
+   VW_MarkUpdateBlock (0, 0, 320, 200);
+
+   while (ht--)
+   {
+      count = 0;
+
+   	do
+	   {
+		   rept = *source++;
+
+   		if (rept > 0x80)
+	   	{
+		   	rept = (rept^0xff)+2;
+			   b = *source++;
+   			memset (buf, b, rept);
+	   		buf += rept;
+		   }
+   		else if (rept < 0x80)
+	   	{
+		   	rept++;
+			   memcpy (buf, source, rept);
+   			buf += rept;
+	   		source += rept;
+		   }
+   		else
+	   		rept = 0;               // rept of 0x80 is NOP
+
+		   count += rept;
+
+   	} while (count < lbminfo->width);
+	  if (iGLOBAL_SCREENWIDTH > 320){
+		 buf += (iGLOBAL_SCREENWIDTH-320); //eg 800 - 320)
+	  }
+   }
+	   //SetTextMode (  ); //12345678
+
+   {
+      int cnt;
+
+      cnt = 0;
+      screen = orig; 
+      buf = origbuf;
+      VGAMAPMASK (writemask);
+
+	  //bna section start
+	  if (iGLOBAL_SCREENWIDTH <= 320){
+		  for (y = 0; y < (lbminfo->height*lbminfo->width); y++)
+
+		  {
+			 *screen++ = *(buf+y);
+		  }
+	  }else{
+		  for (y = 0; y < (lbminfo->height); y++){
+			  for (x = 0; x < iGLOBAL_SCREENWIDTH; x++){
+				 *screen++ = *(buf++);
+			  }
+		  }
+	  }
+	  // bna section end
+
+   }
+
+   SafeFree(origbuf);
+   EnableScreenStretch();//bna++ shut on streech mode
+   if (flip==true)
+      VW_UpdateScreen ();
+
+   VL_FadeIn (0, 255, &pal[0], 15);
+
+}
+
+//****************************************************************************
+//
+// SetBorderColor
+//
+//****************************************************************************
+
+void SetBorderColor (int color)
+{
+   // bna section start
+
+   byte  *cnt,*Ycnt,*b;
+
+   b=(byte *)bufferofs;
+
+   // color 56 could be used
+
+   //paint top red line
+   for (cnt=b;cnt<b+viewwidth;cnt++){
+	for (Ycnt=cnt;Ycnt<cnt+(5*iGLOBAL_SCREENWIDTH);Ycnt+=iGLOBAL_SCREENWIDTH){
+			*Ycnt = color;
+		}
+   }
+   //paint left red line
+   for (cnt=b;cnt<b+5;cnt++){
+	for (Ycnt=cnt;Ycnt<cnt+(viewheight*iGLOBAL_SCREENWIDTH);Ycnt+=iGLOBAL_SCREENWIDTH){
+			*Ycnt = color;
+		}
+   }
+   //paint right red line
+   for (cnt=b+(viewwidth-5);cnt<b+viewwidth;cnt++){
+	for (Ycnt=cnt;Ycnt<cnt+(viewheight*iGLOBAL_SCREENWIDTH);Ycnt+=iGLOBAL_SCREENWIDTH){
+			*Ycnt = color;
+		}
+   }
+   //paint lower red line
+   for (cnt=b+((viewheight-5)*iGLOBAL_SCREENWIDTH);cnt<b+((viewheight-5)*iGLOBAL_SCREENWIDTH)+viewwidth;cnt++){
+		for (Ycnt=cnt;Ycnt<b+(viewheight*iGLOBAL_SCREENWIDTH);Ycnt+=iGLOBAL_SCREENWIDTH){
+			 *Ycnt = color;
+		}
+   }
+   // bna section end
+
+#ifdef DOS
+   inp  (STATUS_REGISTER_1);
+   outp (ATR_INDEX,0x31);
+   outp (ATR_INDEX,color);
+#endif
+}
+
+//****************************************************************************
+//
+// SetBorderColorInterrupt
+//
+//****************************************************************************
+
+void SetBorderColorInterrupt (int color)
+{
+#ifdef DOS
+   union REGS regs;
+
+   regs.w.ax = 0x1001;
+   regs.w.bx = color<<8;
+   int386(0x10,&regs,&regs);
+#else
+	STUB_FUNCTION;
+#endif
+}
+
+
+//****************************************************************************
+//
+// VL_DrawPostPic
+//
+//****************************************************************************
+
+void VL_DrawPostPic (int lumpnum)
+{
+   DrawPostPic(lumpnum);
+   VW_MarkUpdateBlock (0, 0, 319, 199);
+}
+
+//****************************************************************************
+//
+// VL_DrawLine
+//
+//****************************************************************************
+
+void VL_DrawLine (int x1, int y1, int x2, int y2, byte color)
+{
+   int dx;
+   int dy;
+   int xinc;
+   int yinc;
+   int count;
+
+   dx=(x2-x1);
+   dy=(y2-y1);
+   if (abs(dy)>=abs(dx))
+      {
+      count=abs(dy);
+      yinc=(dy<<16)/count;
+      if (dy==0)
+         {
+         return;
+         }
+      else
+         {
+         xinc=(dx<<16)/count;
+         }
+      }
+   else
+      {
+      count=abs(dx);
+      xinc=(dx<<16)/count;
+      if (dx==0)
+         {
+         return;
+         }
+      else
+         {
+         yinc=(dy<<16)/count;
+         }
+      }
+   x1<<=16;
+   y1<<=16;
+   while (count>0)
+      {
+#ifdef DOS
+      VGAWRITEMAP((x1>>16)&3);
+      *((byte *)bufferofs+(x1>>18)+(ylookup[y1>>16]))=color;
+#else
+      *((byte *)bufferofs+(x1>>16)+(ylookup[y1>>16]))=color;
+#endif
+      x1+=xinc;
+      y1+=yinc;
+      count--;
+      }
+}
+
+
+//******************************************************************************
+//
+// DrawXYPic
+//
+//******************************************************************************
+
+void DrawXYPic (int x, int y, int shapenum)
+{
+   byte *buffer;
+   byte *buf;
+   int xx,yy;
+   int plane;
+   byte *src;
+   pic_t *p;
+
+   p = (pic_t *) W_CacheLumpNum (shapenum, PU_CACHE, Cvt_pic_t, 1);
+
+   if ((x<0) || ((x+(p->width<<2))>=320))
+      Error ("DrawXYPic: x is out of range\n");
+   if ((y<0) || ((y+p->height)>=200))
+      Error ("DrawXYPic: y is out of range\n");
+
+#ifdef DOS
+   buffer = (byte*)bufferofs+(x>>2)+ylookup[y];
+#else
+   buffer = (byte*)bufferofs+ylookup[y];
+#endif
+
+   src=(byte *)&p->data;
+
+   for (plane=x;plane<x+4;plane++)
+      {
+      VGAWRITEMAP((plane&3));
+      for (yy = 0; yy < p->height; yy++)
+         {
+         buf=buffer+ylookup[yy];
+         for (xx = 0; xx < p->width; xx++,buf++)
+#ifdef DOS
+            *(buf)=*(src++);
+#else
+            *(buf+plane+xx*4)=*(src++);
+#endif
+         }
+      }
+}

Added: tags/rott-1.1/rott/rt_vid.h
===================================================================
--- tags/rott-1.1/rott/rt_vid.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_vid.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,94 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _rt_vid_public
+#define _rt_vid_public
+
+//***************************************************************************
+//
+// Public header for RT_VID.C
+//
+//***************************************************************************
+
+#include "lumpy.h"
+
+//***************************************************************************
+//
+// DEFINES
+//
+//***************************************************************************
+
+#define PORTTILESWIDE      20       // all drawing takes place inside a
+#define PORTTILESHIGH      13       // non displayed port of this size
+
+#define UPDATEWIDE         PORTTILESWIDE
+#define UPDATEHIGH         PORTTILESHIGH
+#define UPDATESIZE         (UPDATEWIDE*UPDATEHIGH)
+
+
+//***************************************************************************
+//
+// GLOBALS
+//
+//***************************************************************************
+
+extern byte     *updateptr;
+extern unsigned mapwidthtable[64];
+extern unsigned uwidthtable[UPDATEHIGH];
+extern unsigned blockstarts[UPDATEWIDE*UPDATEHIGH];
+extern byte     update[UPDATESIZE];
+extern boolean  screenfaded;
+
+
+//***************************************************************************
+//
+// PROTOTYPES
+//
+//***************************************************************************
+void VL_MemStrechedToScreen (byte *source, int width, int height, int x, int y);
+void VL_MemToScreen (byte *source, int width, int height, int x, int y);
+void DrawTiledRegion( int x, int y, int width, int height, int offx, int offy, pic_t *tile );
+void VWB_DrawPic (int x, int y, pic_t *pic);
+void VL_Bar (int x, int y, int width, int height, int color);
+void VWB_Bar (int x, int y, int width, int height, int color);
+void VWB_Hlin (int x1, int x2, int y, int color);
+void VWB_Vlin (int y1, int y2, int x, int color);
+void VWB_THlin (int x1, int x2, int y, boolean up);
+void VWB_TVlin (int y1, int y2, int x, boolean up);
+int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2);
+void VW_UpdateScreen (void);
+
+void VL_FadeOut (int start, int end, int red, int green, int blue, int steps);
+void VL_FadeIn (int start, int end, byte *palette, int steps);
+void VL_DecompressLBM (lbm_t *lbminfo, boolean flip);
+void VL_FadeToColor (int time, int red, int green, int blue);
+void VWB_TBar (int x, int y, int width, int height);
+
+void SwitchPalette (byte * newpal, int steps);
+void SetBorderColor (int color);
+
+void VL_DrawPostPic (int lumpnum);
+void VL_DrawLine (int x1, int y1, int x2, int y2, byte color);
+
+#define MenuFadeOut()	VL_FadeOut (0, 255, 0, 0, 0, 10)
+#define MenuFadeIn()	   VL_FadeIn (0, 255, origpal, 10)
+
+void DrawXYPic (int x, int y, int shapenum);
+
+#endif

Added: tags/rott-1.1/rott/rt_view.c
===================================================================
--- tags/rott-1.1/rott/rt_view.c	                        (rev 0)
+++ tags/rott-1.1/rott/rt_view.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,933 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "rt_def.h"
+#include "rt_view.h"
+#include "z_zone.h"
+#include "w_wad.h"
+#include "lumpy.h"
+#include "rt_util.h"
+#include "rt_vid.h"
+#include "rt_game.h"
+#include "rt_draw.h"
+#include "rt_ted.h"
+#include "isr.h"
+#include "rt_rand.h"
+#include "rt_sound.h"
+#include "modexlib.h"
+#include "rt_menu.h"
+
+#ifdef DOS
+#include <mem.h>
+#endif
+
+#include <stdlib.h>
+
+#include "rt_main.h"
+#include "rt_battl.h"
+#include "rt_floor.h"
+#include "rt_str.h"
+#include "watcom.h"
+#include "develop.h"
+//MED
+#include "memcheck.h"
+
+#define LIGHTNINGLEVEL 4
+#define MINLIGHTNINGLEVEL   2
+#define MAXLIGHTNINGLEVEL   10
+
+/*
+=============================================================================
+
+                               GLOBALS
+
+=============================================================================
+*/
+extern int G_weaponscale;
+
+
+int    StatusBar = 0;
+int    lightninglevel=0;
+boolean  lightning=false;
+int    normalshade;
+int    darknesslevel;
+int    maxshade;
+int    minshade;
+int    baseminshade;
+int    basemaxshade;
+int    viewheight;
+int    viewwidth;
+longword   heightnumerator;
+fixed  scale;
+int    screenofs;
+int    centerx;
+int    centery;
+int    centeryfrac;
+int    fulllight;
+int    weaponscale;
+int    viewsize;
+byte * colormap;
+byte * redmap;
+byte * greenmap;
+byte * playermaps[MAXPLAYERCOLORS];
+//short  pixelangle[MAXVIEWWIDTH];
+short  pixelangle[800];
+byte   gammatable[GAMMAENTRIES];
+int    gammaindex;
+int    focalwidth=160;
+int    yzangleconverter;
+byte   uniformcolors[MAXPLAYERCOLORS]={
+                                       25,
+                                       222,
+                                       29,
+                                       206,
+                                       52,
+                                       6,
+                                       155,
+                                       16,
+                                       90,
+                                       129,
+                                       109
+                                       };
+
+#ifdef DOS
+byte    mapmasks1[4][9] = {
+{1 ,3 ,7 ,15,15,15,15,15,15},
+{2 ,6 ,14,14,14,14,14,14,14},
+{4 ,12,12,12,12,12,12,12,12},
+{8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8} };
+
+byte    mapmasks2[4][9] = {
+{0 ,0 ,0 ,0 ,1 ,3 ,7 ,15,15},
+{0 ,0 ,0 ,1 ,3 ,7 ,15,15,15},
+{0 ,0 ,1 ,3 ,7 ,15,15,15,15},
+{0 ,1 ,3 ,7 ,15,15,15,15,15} };
+
+byte    mapmasks3[4][9] = {
+{0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1},
+{0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,3},
+{0 ,0 ,0 ,0 ,0 ,0 ,1 ,3 ,7},
+{0 ,0 ,0 ,0 ,0 ,1 ,3 ,7 ,15} };
+#endif
+
+
+/*
+=============================================================================
+
+                               LOCAL
+
+=============================================================================
+*/
+
+static char *YourComputerSucksString = "Buy a 486! :)";
+
+static int viewsizes[MAXVIEWSIZES*2]={ 80,48,
+                           128,72,
+                           160,88,
+                           192,104,
+                           224,120,
+                           256,136,
+                           288,152,
+                           320,168,
+                           320,184,
+                           320,200,
+                           320,200};
+
+static int ColorMapLoaded=0;
+
+static int      lightningtime=0;
+static int      lightningdelta=0;
+static int      lightningdistance=0;
+static int      lightningsoundtime=0;
+static boolean  periodic=false;
+static int      periodictime=0;
+
+void SetViewDelta ( void );
+void UpdatePeriodicLighting (void);
+
+/*
+====================
+=
+= ResetFocalWidth
+=
+====================
+*/
+void ResetFocalWidth ( void )
+{
+   focalwidth=iGLOBAL_FOCALWIDTH;//FOCALWIDTH;
+   SetViewDelta();
+}
+
+/*
+====================
+=
+= ChangeFocalWidth
+=
+====================
+*/
+void ChangeFocalWidth ( int amount )
+{
+   focalwidth=iGLOBAL_FOCALWIDTH+amount;//FOCALWIDTH+amount;
+   SetViewDelta();
+}
+
+
+/*
+====================
+=
+= SetViewDelta
+=
+====================
+*/
+
+void SetViewDelta ( void )
+{
+//iGLOBAL_SCREENHEIGHT
+//iGLOBAL_SCREENWIDTH
+//
+// calculate scale value for vertical height calculations
+// and sprite x calculations
+//
+	if ( iGLOBAL_SCREENWIDTH == 320) {
+		scale = (centerx*focalwidth)/(160);
+	}else if ( iGLOBAL_SCREENWIDTH == 640) {
+		scale = (centerx*focalwidth)/(160);
+	}else if ( iGLOBAL_SCREENWIDTH == 800) {
+		scale = (centerx*focalwidth)/(160);
+	}
+//
+// divide heightnumerator by a posts distance to get the posts height for
+// the heightbuffer.  The pixel height is height>>HEIGHTFRACTION
+//
+   heightnumerator = (((focalwidth/10)*centerx*4096)<<HEIGHTFRACTION);
+}
+
+/*
+====================
+=
+= CalcProjection
+=
+====================
+*/
+
+void CalcProjection ( void )
+{
+    int   i;
+    int   frac;
+    int   intang;
+    byte * table;
+    byte * ptr;
+    int   length;
+    int  * pangle;
+
+
+
+// Already being called in ResetFocalWidth
+//    SetViewDelta();
+
+//
+// load in tables file
+//
+
+
+//Hey, isn't this stuff already loaded in?
+//Why don't we make this a lump?
+   table=W_CacheLumpName("tables",PU_STATIC, CvtNull, 1);
+   ptr=table;
+
+//
+// get size of table
+//
+
+   memcpy(&length,ptr,sizeof(int));
+   SwapIntelLong(&length);
+   ptr+=sizeof(int);
+   pangle=SafeMalloc(length*sizeof(int));
+   memcpy(pangle,ptr,length*sizeof(int));
+
+   frac=((length*65536/centerx))>>1;
+   for (i=0;i<centerx;i++)
+      {
+      // start 1/2 pixel over, so viewangle bisects two middle pixels
+      intang=pangle[frac>>16];
+      SwapIntelLong(&intang);
+      pixelangle[centerx-1-i] =(short) intang;
+      pixelangle[centerx+i] =(short) -intang;
+      frac+=(length*65536/centerx);
+      }
+   table=W_CacheLumpName("tables",PU_CACHE, CvtNull, 1);
+   SafeFree(pangle);
+}
+
+
+/*
+==========================
+=
+= SetViewSize
+=
+==========================
+*/
+
+void SetViewSize
+   (
+   int size
+   )
+
+   {
+   int height;
+   int maxheight;
+   int screenx;
+   int screeny;
+   int topy;
+   /*
+  if (size>=10){
+
+	   SetTextMode (  );
+	   screenx=screenx;
+	   return;
+   }
+*/
+
+	if ( iGLOBAL_SCREENWIDTH == 640) {
+		height = 0;//we use height as dummy cnt
+		viewsizes[height++]= 380; viewsizes[height++]= 336;
+        viewsizes[height++]= 428; viewsizes[height++]= 352;
+        viewsizes[height++]= 460; viewsizes[height++]= 368;
+        viewsizes[height++]= 492; viewsizes[height++]= 384;
+        viewsizes[height++]= 524; viewsizes[height++]= 400;
+        viewsizes[height++]= 556; viewsizes[height++]= 416;
+        viewsizes[height++]= 588; viewsizes[height++]= 432;
+        viewsizes[height++]= 640; viewsizes[height++]= 448;
+        viewsizes[height++]= 640; viewsizes[height++]= 464;
+        viewsizes[height++]= 640; viewsizes[height++]= 480;
+        viewsizes[height++]= 640; viewsizes[height++]= 480;
+	}else if ( iGLOBAL_SCREENWIDTH == 800) {
+		height = 0;
+		viewsizes[height++]= 556; viewsizes[height++]= 488;
+        viewsizes[height++]= 588; viewsizes[height++]= 504;
+        viewsizes[height++]= 620; viewsizes[height++]= 520;
+        viewsizes[height++]= 652; viewsizes[height++]= 536;
+        viewsizes[height++]= 684; viewsizes[height++]= 552;
+        viewsizes[height++]= 716; viewsizes[height++]= 568;
+        viewsizes[height++]= 748; viewsizes[height++]= 584;
+        viewsizes[height++]= 800; viewsizes[height++]= 600;
+        viewsizes[height++]= 800; viewsizes[height++]= 600;
+        viewsizes[height++]= 800; viewsizes[height++]= 600;
+        viewsizes[height++]= 800; viewsizes[height++]= 600;
+	}
+
+
+	if ((size<0) || (size>=MAXVIEWSIZES)){//bna added
+        printf("Illegal screen size = %d\n",size);
+		size = 8;//set default value
+		viewsize = 8;
+	}
+
+   //if ((size<0) || (size>=MAXVIEWSIZES))
+   //   Error("Illegal screen size = %ld\n",size);
+
+   viewwidth  = viewsizes[ size << 1 ];         // must be divisable by 16
+   viewheight = viewsizes[ ( size << 1 ) + 1 ]; // must be even
+
+   maxheight = iGLOBAL_SCREENHEIGHT;
+   topy      = 0;
+
+   // Only keep the kills flag
+   StatusBar &= ~( BOTTOM_STATUS_BAR | TOP_STATUS_BAR |
+      STATUS_PLAYER_STATS );
+
+   if ( SHOW_KILLS() )
+      {
+      // Account for height of kill boxes
+      maxheight -= 24;
+      }
+
+   if ( size < 9 )
+      {
+      StatusBar |= TOP_STATUS_BAR;
+
+      // Account for height of top status bar
+      maxheight -= 16;
+      topy      += 16;
+      }
+
+//   if ( size == 7 ){maxheight -= 16;}//bna++
+//   if ( size <= 6 ){topy -= 8;}//bna++
+
+   if ( size < 8 )
+      {
+      // Turn on health and ammo bar
+      StatusBar |= BOTTOM_STATUS_BAR;
+
+      maxheight -= 16;
+
+      }
+   else if ( size < 10 )
+      {
+      // Turn on transparent health and ammo bar
+      StatusBar |= STATUS_PLAYER_STATS;
+      }
+   //   SetTextMode (  );
+   //   viewheight=viewheight;
+   height = viewheight;
+   if ( height > 168 )
+   {
+        // Prevent weapon from being scaled too big
+	    height = 168;
+	  	if ( iGLOBAL_SCREENWIDTH == 640) {
+			height = 260;
+		}else if ( iGLOBAL_SCREENWIDTH == 800) {
+			height = 360;
+		}
+   }
+
+   if ((G_weaponscale > 150)&&(G_weaponscale <600)){height = G_weaponscale;}
+   if ( iGLOBAL_SCREENWIDTH == 320) {G_weaponscale=G_weaponscale/2;}
+   weaponscale = ( height << 16 ) / 168;//( height << 16 ) = 170 * 65536
+
+  
+   centerx     = viewwidth >> 1;
+   centery     = viewheight >> 1;
+   centeryfrac = (centery << 16);
+   yzangleconverter = ( 0xaf85 * viewheight ) / iGLOBAL_SCREENHEIGHT;
+
+   // Center the view horizontally
+   screenx = ( iGLOBAL_SCREENWIDTH - viewwidth ) >> 1;
+
+   if ( viewheight >= maxheight )
+      {
+      screeny = topy;
+      viewheight = maxheight;
+      }
+   else
+      {
+      // Center the view vertically
+      screeny = ( ( maxheight - viewheight ) >> 1 ) + topy;
+      }
+
+   // Calculate offset of view window
+#ifdef DOS
+   screenofs = ( screenx >> 2 ) + ylookup[ screeny ];
+#else
+   screenofs = screenx + ylookup[ screeny ];
+#endif
+
+//
+// calculate trace angles and projection constants
+//
+
+   ResetFocalWidth();
+
+
+// Already being called in ResetFocalWidth
+//   SetViewDelta();
+
+
+     CalcProjection();
+
+   }
+
+
+//******************************************************************************
+//
+// DrawCPUJape ()
+//
+//******************************************************************************
+
+void DrawCPUJape
+   (
+   void
+   )
+
+   {
+   int width;
+   int height;
+
+   CurrentFont = tinyfont;
+   VW_MeasurePropString( YourComputerSucksString, &width, &height );
+
+   DrawGameString( 160 - width / 2, 100 + 48 / 2 + 2,
+      YourComputerSucksString, true );
+   }
+
+
+/*
+==========================
+=
+= SetupScreen
+=
+==========================
+*/
+
+void SetupScreen ( boolean flip )
+{
+   pic_t *shape;
+
+   SetViewSize(viewsize);
+
+   if ( viewsize < 7 )
+      {
+      shape =  ( pic_t * )W_CacheLumpName( "backtile", PU_CACHE, Cvt_pic_t, 1 );
+      //DrawTiledRegion( 0, 16, 320, 200 - 32, 0, 16, shape );
+      DrawTiledRegion( 0, 16, iGLOBAL_SCREENWIDTH, iGLOBAL_SCREENHEIGHT - 32, 0, 16, shape );//bna++
+      }
+
+   if ( viewsize == 0 )
+      {
+      DrawCPUJape();
+      }
+
+   DrawPlayScreen (true);
+   if (flip==true)
+      {
+      ThreeDRefresh();
+      VL_CopyDisplayToHidden();
+      }
+}
+
+
+
+void LoadColorMap( void )
+{
+   int i,j;
+   int lump, length;
+
+   if (ColorMapLoaded==1)
+      Error("Called LoadColorMap twice\n");
+   ColorMapLoaded=1;
+//
+//   load in the light tables
+//   256 byte align tables
+//
+
+	lump = W_GetNumForName("colormap");
+	length = W_LumpLength (lump) + 255;
+	colormap = SafeMalloc (length);
+	colormap = (byte *)( ((long)colormap + 255)&~0xff);
+	W_ReadLump (lump,colormap);
+
+// Fix fire colors in colormap
+
+   for (i=31;i>=16;i--)
+		for (j=0xea;j<0xf9;j++)
+         colormap[i*256+j]=colormap[(((i-16)/4+16))*256+j];
+
+// Get special maps
+
+	lump = W_GetNumForName("specmaps");
+	length = W_LumpLength (lump+1) + 255;
+	redmap = SafeMalloc (length);
+	redmap = (byte *)( ((long)redmap + 255)&~0xff);
+	W_ReadLump (lump+1,redmap);
+   greenmap = redmap+(16*256);
+
+// Get player colormaps
+
+//   if (modemgame==true)
+      {
+      lump = W_GetNumForName("playmaps")+1;
+      for (i=0;i<MAXPLAYERCOLORS;i++)
+         {
+	      length = W_LumpLength (lump+i) + 255;
+	      playermaps[i] = SafeMalloc (length);
+	      playermaps[i] = (byte *)( ((long)playermaps[i] + 255)&~0xff);
+	      W_ReadLump (lump+i,playermaps[i]);
+         }
+      }
+
+   if (!quiet)
+      printf("RT_VIEW: Colormaps Initialized\n");
+
+}
+
+/*
+==========================
+=
+= SetupLightLevels
+=
+==========================
+*/
+#define LIGHTRATEBASE 252
+#define LIGHTRATEEND  267
+#define LIGHTLEVELBASE 216
+#define LIGHTLEVELEND  223
+void SetupLightLevels ( void )
+{
+   int glevel;
+
+   periodic=false;
+	fog=0;
+	lightsource=0;
+
+// Set up light level for level
+
+	if (((word)MAPSPOT(2,0,1)>=104) && ((word)MAPSPOT(2,0,1)<=105))
+		fog=(word)MAPSPOT(2,0,1)-104;
+	else
+		Error ("There is no Fog icon on map %d\n",gamestate.mapon);
+	if ((word)MAPSPOT(3,0,1)==139)
+      {
+      if (fog==0)
+         {
+		   lightsource=1;
+         lights=Z_Malloc(MAPSIZE*MAPSIZE*(sizeof(unsigned long)),PU_LEVEL,NULL);
+         memset (lights,0,MAPSIZE*MAPSIZE*(sizeof(unsigned long)));
+         }
+      else
+		   Error("You cannot use light sourcing on a level with fog on map %d\n",gamestate.mapon);
+      }
+	else if ((word)MAPSPOT(3,0,1))
+		Error("You must use the lightsource icon or nothing at all at (3,0) in plane 1 on map %d\n",gamestate.mapon);
+   if (((word)MAPSPOT(2,0,0)>=LIGHTLEVELBASE) && ((word)MAPSPOT(2,0,0)<=LIGHTLEVELEND))
+      glevel=(MAPSPOT(2,0,0)-LIGHTLEVELBASE);
+	else
+		Error("You must specify a valid darkness level icon at (2,0) on map %d\n",gamestate.mapon);
+
+   SetLightLevels ( glevel );
+
+   if (((word)MAPSPOT(3,0,0)>=LIGHTRATEBASE) && ((word)MAPSPOT(3,0,0)<=LIGHTRATEEND))
+      glevel=(MAPSPOT(3,0,0)-LIGHTRATEBASE);
+	else
+      {
+//      Error("You must specify a valid darkness rate icon at (3,0) on map %ld\n",gamestate.mapon);
+      glevel = 4;
+      }
+
+   SetLightRate ( glevel );
+   lightningtime=0;
+   lightningdistance=0;
+   lightninglevel=0;
+   lightningdelta=0;
+   lightningsoundtime=0;
+}
+
+/*
+==========================
+=
+= SetLightLevels
+=
+==========================
+*/
+void SetLightLevels ( int darkness )
+{
+   if (fog==0)
+      {
+      baseminshade=0x10+((7-darkness)>>1);
+      basemaxshade=0x1f-(darkness>>1);
+      }
+   else
+      {
+      baseminshade=darkness;
+      basemaxshade=0x10;
+      }
+   minshade=baseminshade;
+   maxshade=basemaxshade;
+   darknesslevel=darkness;
+}
+
+/*
+==========================
+=
+= GetLightLevelTile
+=
+==========================
+*/
+int GetLightLevelTile ( void )
+{
+   if (fog==0)
+      {
+      return ((7-((baseminshade-0x10)<<1))+LIGHTLEVELBASE);
+      }
+   else
+      {
+      return (baseminshade+LIGHTLEVELBASE);
+      }
+}
+
+
+/*
+==========================
+=
+= SetLightRate
+=
+==========================
+*/
+void SetLightRate ( int rate )
+{
+   normalshade=(HEIGHTFRACTION+8)-rate;
+   if (normalshade>14) normalshade=14;
+   if (normalshade<3) normalshade=3;
+}
+
+/*
+==========================
+=
+= GetLightRate
+=
+==========================
+*/
+int GetLightRate ( void )
+{
+   return ((HEIGHTFRACTION+8)-normalshade);
+}
+
+/*
+==========================
+=
+= GetLightRateTile
+=
+==========================
+*/
+int GetLightRateTile ( void )
+{
+   return ((HEIGHTFRACTION+8)-normalshade+LIGHTRATEBASE);
+}
+
+
+
+/*
+==========================
+=
+= UpdateLightLevel
+=
+==========================
+*/
+void UpdateLightLevel (int area)
+{
+   int numlights;
+   int targetmin;
+   int targetmax;
+   int numtiles;
+
+   if (fog==true)
+      return;
+
+   numtiles=(numareatiles[area]>>5)-2;
+   numlights=(LightsInArea[area]-numtiles)>>1;
+
+   if (numlights<0)
+      numlights=0;
+   if (numlights>GENERALNUMLIGHTS)
+      numlights=GENERALNUMLIGHTS;
+   targetmin=baseminshade+(GENERALNUMLIGHTS-numlights);
+   targetmax=basemaxshade-numlights;
+   if (targetmax<baseminshade)
+      targetmax=baseminshade;
+   if (targetmin>targetmax)
+      targetmin=targetmax;
+
+   if (minshade>targetmin)
+      minshade-=1;
+   else if (minshade<targetmin)
+      minshade+=1;
+
+   if (maxshade>targetmax)
+      maxshade-=1;
+   else if (maxshade<targetmax)
+      maxshade+=1;
+
+#if 0
+   targetlevel=baseminshade+(GENERALNUMLIGHTS-numlights);
+   if (abs(minshade-targetlevel)==1)
+      minshade=targetlevel;
+   else if (minshade>targetlevel)
+      minshade-=2;
+   else if (minshade<targetlevel)
+      minshade+=2;
+#endif
+}
+
+/*
+==========================
+=
+= SetIllumination
+=
+= Postive value lightens
+= Negative value darkens
+=
+==========================
+*/
+void SetIllumination (int level)
+{
+   if (fog)
+      return;
+	maxshade-=level;
+   if (maxshade>31)
+      maxshade=31;
+   if (maxshade<0x10)
+      maxshade=0x10;
+	minshade-=level;
+   if (minshade<0x10)
+      minshade=0x10;
+   if (minshade>31)
+      minshade=31;
+}
+
+/*
+==========================
+=
+= GetIlluminationDelta
+=
+==========================
+*/
+int GetIlluminationDelta (void)
+{
+   if (fog)
+      return 0;
+   else
+      return maxshade-basemaxshade;
+}
+
+/*
+==========================
+=
+= UpdateLightning
+=
+==========================
+*/
+void UpdateLightning (void)
+{
+   if (periodic==true)
+      {
+      UpdatePeriodicLighting();
+      return;
+      }
+   if ((fog==1) || (lightning==false))
+      return;
+
+   if (lightningtime<=0)
+      {
+      if (lightningsoundtime>0)
+         SD_Play3D (SD_LIGHTNINGSND, 0, lightningdistance);
+      lightningtime=GameRandomNumber("UpdateLightning",0)<<1;
+      lightningdistance=GameRandomNumber("UpdateLightning",0);
+      lightninglevel=(255-lightningdistance)>>LIGHTNINGLEVEL;
+      if (lightninglevel<MINLIGHTNINGLEVEL)
+         lightninglevel=MINLIGHTNINGLEVEL;
+      if (lightninglevel>MAXLIGHTNINGLEVEL)
+         lightninglevel=MAXLIGHTNINGLEVEL;
+      lightningdelta=lightninglevel>>1;
+      lightningsoundtime=lightningdistance>>1;
+      if (lightningdistance<100)
+         {
+         SetIllumination(lightninglevel);
+         }
+      }
+   else if (lightninglevel>0)
+      {
+      lightninglevel-=lightningdelta;
+      if (lightninglevel<=0)
+         {
+         lightninglevel=0;
+         }
+      }
+   else
+      lightningtime--;
+   if (lightningsoundtime)
+      {
+      lightningsoundtime--;
+      if (lightningsoundtime<=0)
+         {
+         int volume;
+
+         volume=255-lightningdistance;
+         if (volume>170) volume=170;
+         SD_PlayPitchedSound ( SD_LIGHTNINGSND, volume,-(lightningdistance<<2));
+         lightningsoundtime=0;
+         }
+      }
+}
+
+/*
+==========================
+=
+= UpdatePeriodicLighting
+=
+==========================
+*/
+#define PERIODICMAG (6)
+#define PERIODICSTEP (20)
+#define PERIODICBASE (0x0f)
+void UpdatePeriodicLighting (void)
+{
+   int val;
+
+   val=FixedMul(PERIODICMAG,sintable[periodictime]);
+   periodictime=(periodictime+PERIODICSTEP)&(FINEANGLES-1);
+   basemaxshade=PERIODICBASE+(PERIODICMAG)+val;
+   baseminshade=basemaxshade-GENERALNUMLIGHTS-1;
+}
+
+/*
+==========================
+=
+= SetModemLightLevel
+=
+==========================
+*/
+void SetModemLightLevel ( int type )
+{
+   periodic=false;
+   fulllight=false;
+   switch (type)
+      {
+      case bo_light_dark:
+         MAPSPOT(2,0,0)=(word)216;
+         MAPSPOT(3,0,0)=(word)255;
+         MAPSPOT(3,0,1)=(word)139;
+         MAPSPOT(2,0,1)=(word)104;
+         SetupLightLevels ();
+         break;
+      case bo_light_normal:
+         break;
+      case bo_light_bright:
+         MAPSPOT(2,0,0)=(word)223;
+         MAPSPOT(3,0,0)=(word)267;
+         MAPSPOT(3,0,1)=(word)0;
+         MAPSPOT(2,0,1)=(word)104;
+         SetupLightLevels ();
+         break;
+      case bo_light_fog:
+         MAPSPOT(2,0,0)=(word)219;
+         MAPSPOT(3,0,0)=(word)259;
+         MAPSPOT(2,0,1)=(word)105;
+         MAPSPOT(3,0,1)=(word)0;
+         SetupLightLevels ();
+         break;
+      case bo_light_periodic:
+         fog=0;
+         MAPSPOT(2,0,1)=(word)104;
+         MAPSPOT(3,0,1)=(word)139;
+         SetupLightLevels ();
+         periodic=true;
+         break;
+      case bo_light_lightning:
+         if (sky!=0)
+            {
+            MAPSPOT(2,0,0)=(word)222;
+            MAPSPOT(3,0,0)=(word)255;
+            MAPSPOT(3,0,1)=(word)139;
+            MAPSPOT(2,0,1)=(word)104;
+            SetupLightLevels ();
+            lightning=true;
+            }
+         break;
+      }
+}
+

Added: tags/rott-1.1/rott/rt_view.h
===================================================================
--- tags/rott-1.1/rott/rt_view.h	                        (rev 0)
+++ tags/rott-1.1/rott/rt_view.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,131 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    RT_VIEW.H
+//
+//***************************************************************************
+#ifndef _rt_view_public
+#define _rt_view_public
+
+#include "modexlib.h"
+
+#define HEIGHTFRACTION 6
+#define MAXVIEWSIZES   11
+
+//#define FOCALWIDTH 160//160
+//#define FPFOCALWIDTH 160.0//160.0
+ 
+
+#define NUMGAMMALEVELS 8
+#define GAMMAENTRIES (64*8)
+
+#define GENERALNUMLIGHTS (5)
+
+extern int StatusBar;
+
+// Kill count
+#define STATUS_KILLS        0x1
+// Transparent health bar
+#define STATUS_PLAYER_STATS 0x2
+// Bottom status bar
+#define BOTTOM_STATUS_BAR   0x4
+// Top status bar
+#define TOP_STATUS_BAR      0x8
+
+#define SHOW_KILLS()             ( StatusBar & STATUS_KILLS )
+#define SHOW_PLAYER_STATS()      ( StatusBar & STATUS_PLAYER_STATS )
+#define SHOW_BOTTOM_STATUS_BAR() ( StatusBar & BOTTOM_STATUS_BAR )
+#define SHOW_TOP_STATUS_BAR()    ( StatusBar & TOP_STATUS_BAR )
+
+#define YOURCPUSUCKS_Y      ( 100 + 48 / 2 + 2 )
+#define YOURCPUSUCKS_HEIGHT 8
+
+#define MAXPLAYERCOLORS (11)
+typedef enum
+   {
+   pc_gray,
+   pc_brown,
+   pc_black,
+   pc_tan,
+   pc_red,
+   pc_olive,
+   pc_blue,
+   pc_white,
+   pc_green,
+   pc_purple,
+   pc_orange
+   } playercolors;
+
+extern byte * playermaps[MAXPLAYERCOLORS];
+//extern short  pixelangle[MAXVIEWWIDTH];
+extern short  pixelangle[800];
+extern byte   gammatable[GAMMAENTRIES];
+extern int    gammaindex;
+extern byte   uniformcolors[MAXPLAYERCOLORS];
+
+extern  byte mapmasks1[4][9];                   // Map Mask for post scaling
+extern  byte mapmasks2[4][9];                   // Map Mask for post scaling
+extern  byte mapmasks3[4][9];                   // Map Mask for post scaling
+
+extern  int normalshade;                        // Normal shading level for stuff
+extern  int maxshade;                           // max shading level
+extern  int minshade;                           // min shading level
+extern  int baseminshade;
+extern  int basemaxshade;
+extern  int    viewheight;
+extern  int    viewwidth;
+extern  longword heightnumerator;
+extern  fixed  scale;
+extern  int    screenofs;
+extern  int    centerx;
+extern  int centery;
+extern  int centeryfrac;
+extern  int fulllight;
+extern  byte * colormap;
+extern  byte * greenmap;
+extern  byte * redmap;
+extern  int weaponscale;
+extern  int viewsize;
+extern  int focalwidth;
+extern  int yzangleconverter;
+extern  int lightninglevel;
+extern  boolean  lightning;
+extern  int    darknesslevel;
+
+void DrawCPUJape( void );
+void SetupScreen ( boolean flip );
+void ResetFocalWidth ( void );
+void ChangeFocalWidth ( int amount );
+void SetViewSize ( int size );
+void LoadColorMap( void );
+void UpdateLightLevel (int area);
+void SetIllumination (int level);
+int  GetIlluminationDelta (void);
+void UpdateLightning (void);
+void SetLightLevels ( int darkness );
+void SetupLightLevels ( void );
+void SetLightRate ( int rate );
+int GetLightRate ( void );
+void SetModemLightLevel ( int type );
+int GetLightRateTile ( void );
+int GetLightLevelTile ( void );
+
+#endif

Added: tags/rott-1.1/rott/sbconfig.c
===================================================================
--- tags/rott-1.1/rott/sbconfig.c	                        (rev 0)
+++ tags/rott-1.1/rott/sbconfig.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,499 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/* Copyright 1995 Spacetec IMC Corporation */
+
+#if defined(__BORLANDC__)
+#  pragma inline
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <dos.h>
+
+typedef long fixed;
+
+#include "rt_def.h"
+
+#include "develop.h"
+#include "sbconfig.h"
+//MED
+#include "memcheck.h"
+
+/* ----------------------------------------------------------------------- */
+
+#define DEFAULT_CONFIG_FILENAME  "sbconfig.dat"
+
+#define NUM_ELEMENTS(x) (sizeof(x)/sizeof(x[0]))
+#define SIGN(x) ((x<0)?-1:1)
+
+/* ----------------------------------------------------------------------- */
+
+#if defined(__BORLANDC__)
+
+fixed FIXED_MUL(fixed a, fixed b)
+{
+
+   fixed ret_code;
+
+   asm {
+
+      mov  eax,a
+      mov  edx,b
+      imul edx
+      shrd eax,edx,16
+      mov  ret_code,eax
+   }
+
+   return ret_code;
+}
+
+#elif defined(_MSC_VER)
+
+/* Microsoft C7.0 can not be done with inline assembler because it
+   can not handle 32-bit instructions
+*/
+fixed FIXED_MUL(fixed a,fixed b)
+{
+   fixed sgn,ah,al,bh,bl;
+
+   sgn = (SIGN(a) ^ SIGN(b)) ? -1 : 1 ;
+   ah = (a >> 16) & 0xffff ;
+   al = (a        & 0xffff);
+   bh = (b >> 16) & 0xffff ;
+   bl = (b        & 0xffff);
+
+   return sgn * ( ((al*bl)>>16) + (ah*bl) + (al*bh) + ((ah*bh)<<16) );
+}
+
+#elif defined(__WATCOMC__)
+
+fixed FIXED_MUL(fixed a, fixed b);
+
+#pragma aux FIXED_MUL =     \
+   "imul    edx"            \
+   "shrd    eax,edx,16"     \
+   parm     [eax] [edx]     \
+   value    [eax]           \
+   modify   exact [eax]     ;
+
+#endif /* definition of inline FIXED_MUL */
+
+
+static
+fixed StrToFx1616(char *string, char **ret_string)
+{
+	long  whole;
+	long  fract;
+	fixed result;
+	int   sign;
+
+	/* Skip whitespace */
+	while((*string==' ')||(*string=='\t')||(*string=='\n')) string++;
+
+	/* Accept numbers in the form: [+-]?[0-9]+(.[0-9]*)
+	*/
+
+	sign=1;
+	if(*string=='-')
+		{
+			string++;
+			sign=-1;
+		}
+	else if(*string=='+')
+		{
+			string++;
+			sign=1;
+		}
+
+	/* Read in the whole part */
+	whole=0;
+	while((*string>='0')&&(*string<='9'))
+		whole=whole*10+(*string++)-'0';
+
+	/* Read the optional fraction part */
+	fract=0;
+	if(*string=='.')
+		{
+			long place=1;
+			string++;
+			while((*string>='0')&&(*string<='9'))
+				{
+					fract=fract*10+(*string++)-'0';
+					place*=10;
+				}
+			/* Convert to fixed point */
+			fract=(fract<<16)/place;
+		}
+
+	if(ret_string) *ret_string=string;
+
+	if(sign==1)
+		result= (whole<<16) + fract;
+	else
+		result=-(whole<<16) + fract;
+
+	return result;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static char *SbButtonNames[]={
+	"BUTTON_A",
+	"BUTTON_B",
+	"BUTTON_C",
+	"BUTTON_D",
+	"BUTTON_E",
+	"BUTTON_F"};
+
+static int         cfgFileVersion=0;
+static char        cfgButtons[NUM_ELEMENTS(SbButtonNames)][MAX_STRING_LENGTH];
+static WarpRecord *pCfgWarps;
+static int         nCfgWarps=0;
+
+/*-------------------------------------------------------------------------*/
+
+/* Read a string in the form: "{#, #, #}"
+ * and return a pointer to the character AFTER the '}'
+ * or NULL if error
+ */
+static char *GetWarpLevels(char *string, WarpRange *pw)
+{
+	short value;
+   fixed fxvalue;
+
+	if((*string++)!='{')
+  		return NULL;
+
+	if(!*string)
+  		return NULL;
+
+	/* Expecting the first number - low */
+	value=(short)strtol(string, &string, 0);
+	if(pw) pw->low=value;
+
+	/* Skip any whitespace */
+	while(isspace(*string)) string++;
+
+	if(*string++!=',')
+  		return NULL;
+
+	/* Expecting the second number - high */
+	value=(short)strtol(string, &string, 0);
+	if(pw) pw->high=value;
+
+	/* Skip any whitespace */
+	while(isspace(*string)) string++;
+
+	if(*string++!=',')
+  		return NULL;
+
+	/* Expecting the third number - multiplier */
+	fxvalue=StrToFx1616(string, &string);
+	if(pw) pw->mult=fxvalue;
+
+	/* Skip any whitespace */
+	while(isspace(*string)) string++;
+
+	if(*string!='}')
+		return NULL;
+
+	return string+1;
+}
+
+
+
+static int GetWarp(char *string, WarpRecord *pRecord)
+{
+	int        nWarp;
+	WarpRange *pWarp;
+
+	/* Only update the field if we successfully read the entire line */
+	nWarp=0;
+	pWarp=NULL;
+
+	/* Skip whitespace */
+	while(isspace(*string)) string++;
+
+	if(*string++!='{') return 0;
+
+	while(string && *string)
+		{
+			switch(*string)
+				{
+				case ' ':
+				case '\t':
+				case '\n':
+					string++;
+					break;
+
+				case ',':
+					string++;
+					break;
+
+				case '{':
+					if(nWarp++==0)
+						pWarp=malloc(sizeof(WarpRange));
+					else
+						pWarp=realloc(pWarp, nWarp*sizeof(WarpRange));
+
+					string=GetWarpLevels(string, pWarp+nWarp-1);
+					break;
+
+				case '}':
+					pRecord->nWarp=nWarp;
+					pRecord->pWarp=pWarp;
+					return 1;
+				}
+		}
+
+	/* Early EOL (didn't get closing '}') */
+	if(nWarp) free(pWarp);
+	return 0;
+}
+	
+
+/*-------------------------------------------------------------------------*/
+
+int SbConfigParse(char *_filename)
+{
+	int             i;
+	FILE           *file;
+	char           *pc;
+	char            buffer[128];
+    char filename[MAX_PATH];
+
+   if(!_filename) _filename=DEFAULT_CONFIG_FILENAME;
+
+    strncpy(filename, _filename, sizeof (filename));
+    filename[sizeof (filename) - 1] = '\0';
+    FixFilePath(filename);
+
+	if(!(file=fopen(filename, "r")))
+      {
+			printf("Config file: %s, not found\n", filename);
+			return 0;
+      }
+
+	while(fgets(buffer, sizeof(buffer), file))
+		{
+			int lineParsed=0;
+
+			/* each line in config file starts with either a ;, VERSION or an
+	      ** element of GameButtonNames or WarpNames
+			*/
+	      pc=strtok(buffer, " \t\n,");
+
+	      if(*pc==';')									/* commented out line? */
+				continue;
+
+			/* VERSION?  The version will be used in the future to allow fx1616
+			**           values in the config file
+			*/
+			if(!stricmp(pc,"VERSION"))
+				{
+					pc=strtok(NULL, " \t\n,");
+					cfgFileVersion=atoi(pc);
+				}
+
+			/* Check if first token is an element of SbButtonNames */
+			for(i=0; i<NUM_ELEMENTS(SbButtonNames); i++)
+				if(!stricmp(pc, SbButtonNames[i]))
+					{
+						lineParsed=1;
+
+						/* Save the next token in the appropriate slot */
+						pc=strtok(NULL," \t\n,");
+
+						strncpy(cfgButtons[i], pc, MAX_STRING_LENGTH-1);
+						cfgButtons[i][MAX_STRING_LENGTH-1]=0;
+					}
+
+			/* If the first token is not from GameButtonNames,
+			** it must be a WarpName
+			*/
+			if(!lineParsed)
+				{
+					char *name;
+
+					name=pc;
+					pc=pc+strlen(pc)+1;			/* Skip this token */
+					while(isspace(*pc)) pc++;	/* Skip any whitespace */
+
+					if(*pc=='{')
+						{
+							WarpRecord warpRec;
+
+							strcpy(warpRec.name, name);
+							warpRec.pWarp=NULL;
+							warpRec.nWarp=0;
+
+							if(GetWarp(pc, &warpRec))
+								{
+									if(nCfgWarps++==0)
+										pCfgWarps=(WarpRecord *)malloc(sizeof(WarpRecord));
+									else
+										pCfgWarps=(WarpRecord *)realloc(pCfgWarps, nCfgWarps*sizeof(WarpRecord));
+									pCfgWarps[nCfgWarps-1]=warpRec;
+								}
+						}
+				}
+		} /* end of while getting lines from config file */
+
+	fclose(file);
+   return 1;
+}
+
+/*-------------------------------------------------------------------------*/
+
+char *SbConfigGetButton(char *btnName)
+{
+	int i;
+	for(i=0; i<NUM_ELEMENTS(SbButtonNames); i++)
+		{
+			if(!stricmp(btnName, SbButtonNames[i]))
+				if(cfgButtons[i][0])
+					return cfgButtons[i];
+				else
+					return NULL;	/* Empty slot */
+
+			if(!stricmp(btnName, cfgButtons[i]))
+				return SbButtonNames[i];
+		}
+
+	/* Unknown button name */
+	return NULL;
+}
+
+
+
+int SbConfigGetButtonNumber(char *btnName)
+{
+	int i;
+	for(i=0; i<NUM_ELEMENTS(SbButtonNames); i++)
+		{
+			if(!stricmp(btnName, cfgButtons[i]))
+				return i;
+		}
+
+	/* Unknown button name */
+	return -1;
+}
+
+/*-------------------------------------------------------------------------*/
+
+WarpRecord *SbConfigGetWarpRange(char *rngName)
+{
+	int i;
+	for(i=0; i<nCfgWarps; i++)
+		if(!stricmp(rngName, pCfgWarps[i].name))
+			return &pCfgWarps[i];
+
+	return NULL;
+}
+
+/*-------------------------------------------------------------------------*/
+
+fixed SbFxConfigWarp(WarpRecord *warp, short value)
+{
+	int  i;
+	short absValue;
+	fixed accum;
+	int   sign;
+
+	if(!warp) return INT_TO_FIXED(value);
+	
+	absValue=value;
+	sign=1;
+	if(absValue<0)
+		{
+			absValue= (short)-absValue;
+			sign=-1;
+		}
+
+	accum=INT_TO_FIXED(0);
+
+	for(i=0; i<warp->nWarp; i++)
+		{
+      if(absValue<=warp->pWarp[i].low)
+		      ;	/* Ignore it if below this range (if required, will have
+					**	been caught by the previous warp)
+					*/
+			else if((absValue>warp->pWarp[i].low) && (absValue<=warp->pWarp[i].high))
+				{
+					fixed diff;
+					fixed partial;
+					diff=INT_TO_FIXED((long)absValue-(long)warp->pWarp[i].low);
+               partial=FIXED_MUL(diff, warp->pWarp[i].mult);
+					accum=FIXED_ADD(accum, partial);
+					break;	/* Exit the for loop */
+				}
+			else	/* Accumulate if greater than this range */
+				{
+					fixed partial;
+					partial=FIXED_MUL(INT_TO_FIXED((long)warp->pWarp[i].high-(long)warp->pWarp[i].low),
+										   warp->pWarp[i].mult);
+					accum=FIXED_ADD(accum, partial);
+				}
+		}
+
+	if(sign==1)
+		return  accum;
+	else
+		return -accum;
+
+#if 0	/* Old technique */
+		if((absValue>=warp->pWarp[i].low) && (absValue<=warp->pWarp[i].high))
+			if(warp->pWarp[i].shift>=0)
+				value=accum+((absValue-warp->pWarp[i].low)<<warp->pWarp[i].shift);
+			else
+				value=accum+((absValue-warp->pWarp[i].low)>>abs(warp->pWarp[i].shift));
+		else
+			if(warp->pWarp[i].shift>=0)
+				accum+=(warp->pWarp[i].high-warp->pWarp[i].low)<<warp->pWarp[i].shift;
+			else
+				accum+=(warp->pWarp[i].high-warp->pWarp[i].low)>>abs(warp->pWarp[i].shift);
+
+	if(absValue>warp->pWarp[warp->nWarp-1].high)
+		value=accum;
+
+	return sign*value;
+#endif
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+long SbConfigWarp(WarpRecord *warp, short value)
+{
+   /* An apparent bug in the msc70 compiler, trashes r
+      if it is on the stack.  Leave in unitialized global segment.
+   */
+   static fixed r;
+
+   r = SbFxConfigWarp(warp,value);
+
+   return r >> 16 ;
+}
+
+
+/*-------------------------------------------------------------------------*/
+

Added: tags/rott-1.1/rott/sbconfig.h
===================================================================
--- tags/rott-1.1/rott/sbconfig.h	                        (rev 0)
+++ tags/rott-1.1/rott/sbconfig.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,132 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef SBCONFIG_H
+#define SBCONFIG_H
+/* ----------------------------------------------------------------------- */
+/* See the bottom of this file for a syntax diagram for the config file */
+
+#define MAX_STRING_LENGTH 40
+
+/* ----------------------------------------------------------------------- */
+
+//typedef long fixed;	/* 16.16 fixed pt number */
+
+#define INT_TO_FIXED(n)   ((fixed)((long)(n)<<16))
+#define FIXED_TO_INT(n)   ((long)((n)>>16))
+#define FLOAT_TO_FIXED(n) ((fixed)((n)*65536.0))
+
+#define FIXED_ADD(a, b)		((a)+(b))
+#define FIXED_SUB(a, b)		((a)-(b))
+
+/* ----------------------------------------------------------------------- */
+
+typedef struct {
+	short low; 			/* range of input values this warp covers */
+	short high;
+	fixed mult;		/* multiplier to be applied to this range */
+} WarpRange;
+
+
+
+typedef struct {
+	char       name[MAX_STRING_LENGTH];
+	WarpRange *pWarp;
+	int        nWarp;
+} WarpRecord;
+
+/* ----------------------------------------------------------------------- */
+
+/* Parse the config file */
+int   SbConfigParse(char *filename);
+
+/* Get the button config name for the button named <btnName> or return NULL
+ * if none exists.  <btnName> can be either the left or the right side name.
+ * So, for the config line:
+ *
+ * BUTTON_A MY_BUTTON
+ *
+ * ConfigGetButton("BUTTON_A") will return "MY_BUTTON"
+ * ConfigGetButton("MY_BUTTON") will return "BUTTON_A"
+ *
+ * Note that this makes it illegal to have game button names have the names
+ * "BUTTON_A", "BUTTON_B", "BUTTON_C", etc...
+ *
+ * Also, the comparison is CASE INSENSITIVE.
+ */
+char *SbConfigGetButton(char *btnName);
+int   SbConfigGetButtonNumber(char *btnName);
+
+/*
+ * Get the warp ranges for the config range named <rngName> or return NULL
+ * if none exists.
+ */
+WarpRecord *SbConfigGetWarpRange(char *rngName);
+
+/*
+ * Warp a value based on the given warp range
+ */
+fixed SbFxConfigWarp(WarpRecord *warp, short value);  /* returns fixed pt */
+long    SbConfigWarp(WarpRecord *warp, short value);  /* returns integer */
+
+/* ----------------------------------------------------------------------- */
+/* Lexical Definitions:
+**
+** comment:	;[^\n]*\n
+** integer: [0-9]+
+** identifier: [A-Za-z_][A-Za-z_0-9]*
+**
+*/
+/* Syntax Diagram:	(Line by Line parsing)
+**
+**
+** ConfigFile:
+**           |	ConfigLine ConfigFile
+**	          ;
+**
+** ConfigLine:
+**           | comment
+**           | VersionLine comment
+**           | ButtonLine comment
+**           | RangeLine comment
+**           ;
+**
+** VersionLine:	'VERSION' integer
+**            ;
+**
+** ButtonLine:	'BUTTON_A' identifier
+**           |	'BUTTON_B' identifier
+**           |	'BUTTON_C' identifier
+**           |	'BUTTON_D' identifier
+**           |	'BUTTON_E' identifier
+**           |	'BUTTON_F' identifier
+**           ;
+**
+** RangeLine: identifier '{' RangeList '}'
+**          ;
+**
+** RangeList:
+**          | '{' integer ',' integer ',' integer '}'
+**          | '{' integer ',' integer ',' integer '}' ',' RangeList
+**          ;
+**
+*/
+/* ----------------------------------------------------------------------- */
+#endif
+

Added: tags/rott-1.1/rott/scriplib.c
===================================================================
--- tags/rott-1.1/rott/scriplib.c	                        (rev 0)
+++ tags/rott-1.1/rott/scriplib.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,319 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// scriplib.c
+
+#ifdef DOS
+#include <io.h>
+#include <dos.h>
+#endif
+
+#include <fcntl.h>
+#include <string.h>
+
+#include "rt_def.h"
+#include "scriplib.h"
+#include "rt_util.h"
+//MED
+#include "memcheck.h"
+
+/*
+=============================================================================
+
+						PARSING STUFF
+
+=============================================================================
+*/
+
+char    token[MAXTOKEN];
+char    name[MAXTOKEN*2];
+char    scriptfilename[512];
+char    *scriptbuffer,*script_p,*scriptend_p;
+int     scriptline;
+boolean endofscript;
+boolean tokenready;                     // only true if UnGetToken was just called
+
+/*
+==============
+=
+= LoadScriptFile
+=
+==============
+*/
+
+void LoadScriptFile (char *filename)
+{
+	long            size;
+
+	size = LoadFile (filename, (void **)&scriptbuffer);
+
+	snprintf(scriptfilename, sizeof(scriptfilename), "%s", filename);
+	script_p = scriptbuffer;
+	scriptend_p = script_p + size;
+	scriptline = 1;
+	endofscript = false;
+	tokenready = false;
+}
+
+
+/*
+==============
+=
+= UnGetToken
+=
+= Signals that the current token was not used, and should be reported
+= for the next GetToken.  Note that
+
+GetToken (true);
+UnGetToken ();
+GetToken (false);
+
+= could cross a line boundary.
+=
+==============
+*/
+
+void UnGetToken (void)
+{
+	tokenready = true;
+}
+
+
+/*
+==============
+=
+= GetToken
+=
+==============
+*/
+
+void GetToken (boolean crossline)
+{
+	char    *token_p;
+
+	if (tokenready)                         // is a token allready waiting?
+	{
+		tokenready = false;
+		return;
+	}
+
+	if (script_p >= scriptend_p)
+	{
+		if (!crossline)
+         Error ("Line %i is incomplete\nin file %s\n",
+                 scriptline,scriptfilename);
+		endofscript = true;
+		return;
+	}
+
+//
+// skip space
+//
+skipspace:
+	while (*script_p <= 32)
+	{
+		if (script_p >= scriptend_p)
+		{
+			if (!crossline)
+            Error ("Line %i is incomplete\nin file %s\n",
+                   scriptline,scriptfilename);
+			endofscript = true;
+			return;
+		}
+		if (*script_p++ == '\n')
+		{
+			if (!crossline)
+            Error ("Line %i is incomplete\nin file %s\n",
+                  scriptline,scriptfilename);
+			scriptline++;
+		}
+	}
+
+	if (script_p >= scriptend_p)
+	{
+		if (!crossline)
+         Error ("Line %i is incomplete\nin file %s\n",
+                 scriptline,scriptfilename);
+		endofscript = true;
+		return;
+	}
+
+	if (*script_p == ';')   // semicolon is comment field
+	{
+		if (!crossline)
+         Error ("Line %i is incomplete\nin file %s\n",
+                 scriptline,scriptfilename);
+		while (*script_p++ != '\n')
+			if (script_p >= scriptend_p)
+			{
+				endofscript = true;
+				return;
+			}
+		goto skipspace;
+	}
+
+//
+// copy token
+//
+	token_p = token;
+
+	while ( *script_p > 32 && *script_p != ';')
+	{
+		*token_p++ = *script_p++;
+		if (script_p == scriptend_p)
+			break;
+		if (token_p == &token[MAXTOKEN])
+         Error ("Token too large on line %i\nin file %s\n",
+                 scriptline,scriptfilename);
+   }
+
+	*token_p = 0;
+}
+
+
+
+/*
+==============
+=
+= GetTokenEOL
+=
+==============
+*/
+
+void GetTokenEOL (boolean crossline)
+{
+   char    *name_p;
+
+	if (tokenready)                         // is a token allready waiting?
+	{
+		tokenready = false;
+		return;
+	}
+
+	if (script_p >= scriptend_p)
+	{
+		if (!crossline)
+         Error ("Line %i is incomplete\nin file %s\n",
+                 scriptline,scriptfilename);
+      endofscript = true;
+		return;
+	}
+
+//
+// skip space
+//
+skipspace:
+	while (*script_p <= 32)
+	{
+		if (script_p >= scriptend_p)
+		{
+			if (!crossline)
+            Error ("Line %i is incomplete\nin file %s\n",
+                   scriptline,scriptfilename);
+			endofscript = true;
+			return;
+		}
+		if (*script_p++ == '\n')
+		{
+			if (!crossline)
+            Error ("Line %i is incomplete\nin file %s\n",
+                   scriptline,scriptfilename);
+			scriptline++;
+		}
+	}
+
+	if (script_p >= scriptend_p)
+	{
+		if (!crossline)
+         Error ("Line %i is incomplete\nin file %s\n",
+                 scriptline,scriptfilename);
+		endofscript = true;
+		return;
+	}
+
+	if (*script_p == ';')   // semicolon is comment field
+	{
+		if (!crossline)
+         Error ("Line %i is incomplete\nin file %s\n",
+                 scriptline,scriptfilename);
+		while (*script_p++ != '\n')
+			if (script_p >= scriptend_p)
+			{
+				endofscript = true;
+				return;
+			}
+		goto skipspace;
+	}
+
+//
+// copy token
+//
+   name_p  = name;
+
+	while (*script_p >= 32)
+	{
+		*name_p++ = *script_p++;
+		if (script_p == scriptend_p)
+			break;
+		if (name_p == &name[MAXTOKEN*2])
+         Error ("Name too large on line %i\nin file %s\n",
+                 scriptline,scriptfilename);
+	}
+
+	*name_p = 0;
+}
+
+
+
+/*
+==============
+=
+= TokenAvailable
+=
+= Returns true if there is another token on the line
+=
+==============
+*/
+
+boolean TokenAvailable (void)
+{
+	char    *search_p;
+
+	search_p = script_p;
+
+	if (search_p >= scriptend_p)
+		return false;
+
+	while ( *search_p <= 32)
+	{
+		if (*search_p == '\n')
+			return false;
+		search_p++;
+		if (search_p == scriptend_p)
+			return false;
+
+	}
+
+	if (*search_p == ';')
+		return false;
+
+	return true;
+}
+
+

Added: tags/rott-1.1/rott/scriplib.h
===================================================================
--- tags/rott-1.1/rott/scriplib.h	                        (rev 0)
+++ tags/rott-1.1/rott/scriplib.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,41 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// scriplib.h
+
+#ifndef _scriplib_public
+#define _scriplib_public
+
+#define	MAXTOKEN	128
+
+extern	char	token[MAXTOKEN];
+extern	char	name[MAXTOKEN*2];
+extern	char	*scriptbuffer,*script_p,*scriptend_p;
+extern	int		scriptline;
+extern	boolean	endofscript;
+extern   boolean tokenready;      // only true if UnGetToken was just called
+
+
+void LoadScriptFile (char *filename);
+void GetToken (boolean crossline);
+void GetTokenEOL (boolean crossline);
+void UnGetToken (void);
+boolean TokenAvailable (void);
+
+#endif

Added: tags/rott-1.1/rott/snd_reg.h
===================================================================
--- tags/rott-1.1/rott/snd_reg.h	                        (rev 0)
+++ tags/rott-1.1/rott/snd_reg.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1435 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+typedef enum {
+
+//	MENU SOUNDS
+
+		   D_MENUFLIP,
+		   D_ESCPRESSEDSND,
+		   D_MOVECURSORSND,
+		   D_SELECTSND,
+		   D_WARNINGBOXSND,
+		   D_INFOBOXSND,
+		   D_QUESTIONBOXSND,
+		   D_NOPESND,
+		   D_QUIT1SND,
+		   D_QUIT2SND,
+		   D_QUIT3SND,
+		   D_QUIT4SND,
+		   D_QUIT5SND,
+		   D_QUIT6SND,
+		   D_QUIT7SND,
+
+
+//	GAME SOUNDS
+
+		   D_LEVELSTARTSND,
+		   D_LEVELDONESND,
+		   D_GAMEOVERSND,
+
+//	LEVEL END SCREEN
+
+		   D_ENDBONUS1SND,
+		   D_NOBONUSSND,
+		   D_PERCENT100SND,
+
+//	PLAYER SOUNDS
+
+		   D_HITWALLSND,
+		   D_SELECTWPNSND,
+		   D_NOWAYSND,
+		   D_DONOTHINGSND,
+//         D_NOITEMSND,
+		   D_PLAYERDYINGSND,
+
+         D_PLAYERTBDEATHSND,
+         D_PLAYERTCDEATHSND,
+         D_PLAYERLNDEATHSND,
+         D_PLAYERDWDEATHSND,
+         D_PLAYERIPFDEATHSND,
+         D_PLAYERTBHURTSND,
+         D_PLAYERTCHURTSND,
+         D_PLAYERLNHURTSND,
+         D_PLAYERDWHURTSND,
+         D_PLAYERIPFHURTSND,
+		   D_PLAYERTBSND,
+		   D_PLAYERTCSND,
+		   D_PLAYERLNSND,
+		   D_PLAYERDWSND,
+		   D_PLAYERIPFSND,
+//         D_WALK1SND,
+//         D_WALK2SND,
+		   D_PLAYERBURNEDSND,
+		   D_PLAYERLANDSND,
+		   D_PLAYERCOUGHMSND,
+		   D_PLAYERCOUGHFSND,
+		   D_NETWIGGLESND,
+		   D_NETFALLSND,
+
+//	PLAYER WEAPONS
+
+		   D_ATKPISTOLSND,
+         D_ATKTWOPISTOLSND,
+		   D_ATKMP40SND,
+         D_RICOCHET1SND,
+         D_RICOCHET2SND,
+         D_RICOCHET3SND,
+		   D_BAZOOKAFIRESND,
+		   D_FIREBOMBFIRESND,
+		   D_HEATSEEKFIRESND,
+		   D_DRUNKFIRESND,
+		   D_FLAMEWALLFIRESND,
+		   D_FLAMEWALLSND,
+		   D_SPLITFIRESND,
+		   D_SPLITSND,
+		   D_GRAVBUILDSND,
+		   D_GRAVFIRESND,
+		   D_GRAVSND,
+		   D_GRAVHITSND,
+		   D_FIREHITSND,
+         D_MISSILEFLYSND,
+		   D_MISSILEHITSND,
+		   D_EXCALIBOUNCESND,
+		   D_EXCALISWINGSND,
+		   D_EXCALIHITSND,
+		   D_EXCALIBUILDSND,
+		   D_EXCALIBLASTSND,
+		   D_GODMODEFIRESND,
+		   D_GODMODE1SND,
+		   D_GODMODE2SND,
+		   D_GODMODE3SND,
+		   D_LOSEMODESND,
+		   D_DOGMODEPANTSND,
+         D_DOGMODEBITE1SND,
+         D_DOGMODEBITE2SND,
+         D_DOGMODELICKSND,
+         D_DOGMODEBLASTSND,
+         D_DOGMODEPREPBLASTSND,
+         D_DOGMANSND,
+         D_DOGWOMANSND,
+         D_GODMANSND,
+         D_GODWOMANSND,
+         D_FLYINGSND,
+
+//	PLAYER-CAUSED SOUNDS
+
+		   D_GLASSBREAKSND,
+		   D_ITEMBLOWSND,
+		   D_BONUSBARRELSND,
+		   D_TOUCHPLATESND,
+		   D_BADTOUCHSND,
+         D_EXPLODEFLOORSND,
+		   D_EXPLODESND,
+//         D_GASSTARTSND,
+		   D_GASHISSSND,
+		   D_GASENDSND,
+		   D_GASMASKSND,
+
+//	GET ITEM SOUNDS
+
+		   D_GETKEYSND,
+         D_GETBONUSSND,
+		   D_GETHEALTH1SND,
+		   D_GETHEALTH2SND,
+		   D_COOKHEALTHSND,
+
+		   D_GETWEAPONSND,
+		   D_GETKNIFESND,
+		   D_GETGODSND,
+		   D_GETDOGSND,
+		   D_GETFLEETSND,
+		   D_GETELASTSND,
+		   D_GETSHROOMSSND,
+		   D_GETBVESTSND,
+		   D_GETAVESTSND,
+		   D_GETMASKSND,
+		   D_GETBATSND,
+		   D_GETHEADSND,
+
+		   D_GET1UPSND,
+		   D_GET3UPSND,
+         D_RESPAWNSND,
+         D_PLAYERSPAWNSND,
+
+//	ACTOR SOUNDS
+
+		   D_LOWGUARD1SEESND,
+		   D_LOWGUARD1ASEESND,
+         D_LOWGUARD1SEE2SND,
+//         D_LOWGUARD2SEESND,
+//         D_LOWGUARD2ASEESND,
+//         D_LOWGUARD2SEE2SND,
+		   D_LOWGUARDOUCHSND,
+         D_LOWGUARD1DIESND,
+//         D_LOWGUARD2DIESND,
+		   D_SNEAKYSPRINGMSND,
+//         D_SNEAKYSPRINGFSND,
+
+         D_HIGHGUARD1SEESND,
+		   D_HIGHGUARD2SEESND,
+		   D_HIGHGUARDOUCHSND,
+		   D_HIGHGUARDDIESND,
+
+         D_OVERP1SEESND,
+//         D_OVERP2SEESND,
+		   D_OVERPNETSND,
+		   D_OVERPOUCHSND,
+		   D_OVERPDIESND,
+
+         D_STRIKE1SEESND,
+//         D_STRIKE2SEESND,
+		   D_STRIKEROLLSND,
+		   D_STRIKEOUCHSND,
+		   D_STRIKEDIESND,
+
+         D_BLITZ1SEESND,
+         D_BLITZ2SEESND,
+		   D_BLITZSTEALSND,
+		   D_BLITZOUCHSND,
+		   D_BLITZDIESND,
+         D_BLITZPLEADSND,
+         D_BLITZPLEAD1SND,
+         D_BLITZPLEAD2SND,
+
+		   D_ENFORCERSEESND,
+		   D_ENFORCERFIRESND,
+		   D_ENFORCERTHROWSND,
+		   D_ENFORCEROUCHSND,
+		   D_ENFORCERDIESND,
+
+		   D_MONKSEESND,
+		   D_MONKGRABSND,
+		   D_MONKOUCHSND,
+		   D_MONKDIESND,
+
+		   D_FIREMONKSEESND,
+		   D_FIREMONKFIRESND,
+		   D_FIREMONKOUCHSND,
+		   D_FIREMONKDIESND,
+
+		   D_ROBOTSEESND,
+		   D_ROBOTFIRESND,
+		   D_ROBOTDIESND,
+
+		   D_DARIANSEESND,
+		   D_DARIANGONNAUSESND,
+		   D_DARIANHIDESND,
+		   D_DARIANDIESND,
+         D_DARIANSAY1,
+         D_DARIANSAY2,
+         D_DARIANSAY3,
+
+		   D_KRISTSEESND,
+		   D_KRISTMOTORSND,
+		   D_KRISTTURNSND,
+		   D_KRISTDROPSND,
+		   D_KRISTMINEBEEPSND,
+		   D_KRISTMINEHITSND,
+		   D_KRISTDIESND,
+         D_KRISTSAY1,
+         D_KRISTSAY2,
+         D_KRISTSAY3,
+
+		   D_NMESEESND,
+		   D_NMEREADYSND,
+		   D_NMEAPARTSND,
+		   D_NMEUFOSND,
+
+		   D_DARKMONKSEESND,
+		   D_DARKMONKFIRE1SND,
+		   D_DARKMONKFIRE2SND,
+		   D_DARKMONKFIRE3SND,
+		   D_DARKMONKFIRE4SND,
+         D_DARKMONKRECHARGESND,
+		   D_DARKMONKFLOATSND,
+		   D_DARKMONKDIESND,
+         D_DARKMONKSAY1,
+         D_DARKMONKSAY2,
+         D_DARKMONKSAY3,
+
+		   D_SNAKESEESND,
+		   D_SNAKEREADYSND,
+		   D_SNAKECHARGESND,
+		   D_SNAKEOUCHSND,
+		   D_SNAKEDIESND,
+		   D_SNAKESPITSND,
+         D_SNAKESAY1,
+         D_SNAKESAY2,
+         D_SNAKESAY3,
+
+		   D_EMPLACEMENTSEESND,
+		   D_EMPLACEMENTFIRESND,
+		   D_BIGEMPLACEFIRESND,
+
+
+//	ENVIRONMENT SOUNDS
+
+         D_OPENDOORSND,
+         D_CLOSEDOORSND,
+         D_DOORHITSND,
+         D_FIRECHUTESND,
+		   D_FIREBALLSND,
+		   D_FIREBALLHITSND,
+		   D_BLADESPINSND,
+		   D_PUSHWALLSND,
+		   D_PUSHWALLHITSND,
+		   D_GOWALLSND,
+		   D_TURBOWALLSND,
+		   D_BOULDERHITSND,
+		   D_BOULDERROLLSND,
+		   D_PITTRAPSND,
+		   D_FIREJETSND,
+		   D_ACTORSQUISHSND,
+		   D_ACTORBURNEDSND,
+         D_ACTORSKELETONSND,
+
+		   D_SPEARSTABSND,
+		   D_CYLINDERMOVESND,
+		   D_ELEVATORONSND,
+         D_ELEVATORENDSND,
+
+		   D_SPRINGBOARDSND,
+         D_LIGHTNINGSND,
+         D_WINDSND,
+//         D_WATERSND,
+
+//	SECRET SOUNDS
+
+		   D_DOPEFISHSND,
+		   D_YOUSUCKSND,
+
+		   D_SILLYMOVESND,
+		   D_SOUNDSELECTSND,
+		   D_SOUNDESCSND,
+         D_BODYLANDSND,
+         D_GIBSPLASHSND,
+         D_ACTORLANDSND,
+
+    		D_LASTSOUND=-1
+
+	          } digisounds;
+
+static sound_t sounds[MAXSOUNDS] = {
+//SD_MENUFLIP,
+//|-------DIGITAL--------|---------MUSE---------|----FLAGS---|
+ {{D_MENUFLIP,            MUSE_MENUFLIPSND,      },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ESCPRESSEDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ESCPRESSEDSND,       MUSE_ESCPRESSEDSND,    },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MOVECURSORSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_MOVECURSORSND,       MUSE_MOVECURSORSND,    },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SELECTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SELECTSND,           MUSE_SELECTSND,        },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_WARNINGBOXSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_WARNINGBOXSND,       MUSE_WARNINGBOXSND,    },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_INFOBOXSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_INFOBOXSND,          MUSE_INFOBOXSND,       },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUESTIONBOXSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_QUESTIONBOXSND,      MUSE_QUESTIONBOXSND,   },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NOPESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NOPESND,             MUSE_NOPESND,          },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_QUIT1SND,            MUSE_SELECTSND,        },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_QUIT2SND,            MUSE_SELECTSND,        },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_QUIT3SND,            MUSE_SELECTSND,        },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT4SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_QUIT4SND,            MUSE_SELECTSND,        },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT5SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_QUIT5SND,            MUSE_SELECTSND,        },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT6SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_QUIT6SND,            MUSE_SELECTSND,        },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT7SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_QUIT7SND,            MUSE_SELECTSND,        },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LEVELSTARTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LEVELSTARTSND,       MUSE_LEVELSTARTSND,    },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LEVELDONESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LEVELDONESND,        MUSE_LEVELENDSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GAMEOVERSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GAMEOVERSND,         MUSE_GAMEOVERSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENDBONUS1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENDBONUS1SND,        MUSE_ENDBONUS1SND,     },  SD_PITCHSHIFTOFF,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NOBONUSSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NOBONUSSND,          MUSE_NOBONUSSND,       },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PERCENT100SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PERCENT100SND,       MUSE_PERCENT100SND,    },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HITWALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HITWALLSND,          MUSE_HITWALLSND,       },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SELECTWPNSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SELECTWPNSND,        MUSE_SELECTWPNSND,     },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NOWAYSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NOWAYSND,            MUSE_NOWAYSND,         },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DONOTHINGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DONOTHINGSND,        MUSE_DONOTHINGSND,     },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NOITEMSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NOWAYSND,            MUSE_NOITEMSND,        },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERDYINGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERDYINGSND,      MUSE_PLAYERDYINGSND,   },  SD_PITCHSHIFTOFF,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTCDEATHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCDEATHSND,    MUSE_PLAYERDEATHSND,   },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTBDEATHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTBDEATHSND,    MUSE_PLAYERDEATHSND,   },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERDWDEATHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERDWDEATHSND,    MUSE_PLAYERDEATHSND,   },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERLNDEATHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERLNDEATHSND,    MUSE_PLAYERDEATHSND,   },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERIPFDEATHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERIPFDEATHSND,   MUSE_PLAYERDEATHSND,   },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTCHURTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCHURTSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE, SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTBHURTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTBHURTSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE, SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERDWHURTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERDWHURTSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE, SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERLNHURTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERLNHURTSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE, SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERIPFHURTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERIPFHURTSND,    MUSE_PLAYERHURTSND,    },  SD_PLAYONCE, SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTCSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCSND,         MUSE_PLAYERYESSND,     },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTBSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTBSND,         MUSE_PLAYERYESSND,     },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERDWSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERDWSND,         MUSE_PLAYERYESSND,     },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERLNSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERLNSND,         MUSE_PLAYERYESSND,     },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERIPFSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERIPFSND,        MUSE_PLAYERYESSND,     },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_WALK1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+// {{D_WALK1SND,            MUSE_WALK1SND,       },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_WALK2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+// {{D_WALK2SND,            MUSE_WALK2SND,       },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERBURNEDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERBURNEDSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE,SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERLANDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERLANDSND,       MUSE_PLAYERLANDSND,    },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERCOUGHMSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERCOUGHMSND,     MUSE_LASTSOUND,        },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERCOUGHFSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERCOUGHFSND,     MUSE_LASTSOUND,        },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NETWIGGLESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NETWIGGLESND,        MUSE_LASTSOUND,        },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NETFALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NETFALLSND,          MUSE_NETFALLSND,       },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ATKPISTOLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKPISTOLSND,        MUSE_ATKPISTOLSND,     },  SD_WRITE,SD_PRIOPGUNS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ATKTWOPISTOLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKTWOPISTOLSND,     MUSE_ATKPISTOLSND,     },  SD_WRITE,SD_PRIOPGUNS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ATKMP40SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKMP40SND,          MUSE_ATKMP40SND,       },  SD_WRITE,SD_PRIOPMP40, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_RICOCHET1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_RICOCHET1SND,        MUSE_RICOCHETSND,      },  SD_WRITE,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_RICOCHET2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_RICOCHET2SND,        MUSE_RICOCHETSND,      },  SD_WRITE,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_RICOCHET3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_RICOCHET3SND,        MUSE_RICOCHETSND,      },  SD_WRITE,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BAZOOKAFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BAZOOKAFIRESND,      MUSE_MISSILEFIRESND,   },  SD_WRITE,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREBOMBFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREBOMBFIRESND,     MUSE_MISSILEFIRESND,   },  SD_WRITE,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HEATSEEKFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HEATSEEKFIRESND,     MUSE_MISSILEFIRESND,   },  SD_WRITE,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DRUNKFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DRUNKFIRESND,        MUSE_MISSILEFIRESND,   },  SD_WRITE,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FLAMEWALLFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FLAMEWALLFIRESND,    MUSE_MISSILEFIRESND,   },  SD_WRITE,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FLAMEWALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FLAMEWALLSND,        MUSE_FLAMEWALLSND,     },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SPLITFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SPLITFIRESND,        MUSE_MISSILEFIRESND,   },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SPLITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SPLITSND,            MUSE_MISSILEFIRESND,   },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GRAVBUILDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GRAVBUILDSND,        MUSE_WEAPONBUILDSND,   },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GRAVFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GRAVFIRESND,         MUSE_ENERGYFIRESND,    },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GRAVSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GRAVSND,             MUSE_LASTSOUND,        },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GRAVHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GRAVHITSND,          MUSE_MISSILEHITSND,    },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREHITSND,          MUSE_MISSILEHITSND,    },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MISSILEFLYSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_MISSILEFLYSND,       MUSE_LASTSOUND,        },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MISSILEHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_MISSILEHITSND,       MUSE_MISSILEHITSND,    },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXCALIBOUNCESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXCALIBOUNCESND,     MUSE_LASTSOUND,        },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXCALISWINGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXCALISWINGSND,      MUSE_MISSILEFIRESND,   },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXCALIHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXCALIHITSND,        MUSE_MISSILEHITSND,    },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXCALIBUILDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXCALIBUILDSND,      MUSE_WEAPONBUILDSND,   },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXCALIBLASTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXCALIBLASTSND,      MUSE_ENERGYFIRESND,    },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODMODEFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODMODEFIRESND,      MUSE_ENERGYFIRESND,    },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODMODE1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODMODE1SND,         MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODMODE2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODMODE2SND,         MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODMODE3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODMODE3SND,         MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOSEMODESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOSEMODESND,         MUSE_LOSEMODESND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODEPANTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DOGMODEPANTSND,      MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODEBITE1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DOGMODEBITE1SND,      MUSE_DOGBITESND,      },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODEBITE2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DOGMODEBITE2SND,      MUSE_DOGBITESND,      },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODELICKSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DOGMODELICKSND,      MUSE_DOGLICKSND,       },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODEBLASTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DOGMODEBLASTSND,      MUSE_DOGBITESND,      },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODEPREPBLASTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DOGMODEPREPBLASTSND, MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMANSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DOGMANSND,           MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGWOMANSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DOGWOMANSND,         MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODMANSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODMANSND,           MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODWOMANSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODWOMANSND,         MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FLYINGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FLYINGSND,           MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GLASSBREAKSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GLASSBREAKSND,       MUSE_GLASSBREAKSND,    },  0,SD_PRIOGLASS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ITEMBLOWSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ITEMBLOWSND,         MUSE_EXPLOSIONSND,     },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BONUSBARRELSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BONUSBARRELSND,      MUSE_EXPLOSIONSND,     },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_TOUCHPLATESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_TOUCHPLATESND,       MUSE_TOUCHPLATESND,    },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BADTOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BADTOUCHSND,         MUSE_BADTOUCHSND,      },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXPLODEFLOORSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXPLODEFLOORSND,     MUSE_EXPLOSIONSND,     },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXPLODESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXPLODESND,          MUSE_EXPLOSIONSND,     },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GASSTARTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_TOUCHPLATESND,         MUSE_SWITCHSND,      },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GASHISSSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GASHISSSND,          MUSE_LASTSOUND,        },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GASENDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GASENDSND,           MUSE_SWITCHSND,        },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GASMASKSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GASMASKSND,          MUSE_LASTSOUND,        },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETKEYSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETKEYSND,           MUSE_GETKEYSND,        },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETBONUSSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETBONUSSND,         MUSE_GETBONUSSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETHEALTH1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETHEALTH1SND,       MUSE_GETHEALTHSND,     },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETHEALTH2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETHEALTH2SND,       MUSE_GETHEALTHSND,     },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_COOKHEALTHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_COOKHEALTHSND,       MUSE_GETBONUSSND,      },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETWEAPONSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETWEAPONSND,        MUSE_GETWEAPONSND,     },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETKNIFESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETKNIFESND,         MUSE_GETWEAPONSND,     },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETGODSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETGODSND,           MUSE_GETPOWERUPSND,    },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETDOGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETDOGSND,           MUSE_GETPOWERUPSND,    },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETFLEETSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETFLEETSND,         MUSE_GETPOWERUPSND,    },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETELASTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETELASTSND,         MUSE_GETPOWERDOWNSND,  },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETSHROOMSSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETSHROOMSSND,       MUSE_GETPOWERDOWNSND,  },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETBVESTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETBVESTSND,         MUSE_GETARMORSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETAVESTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETAVESTSND,         MUSE_GETARMORSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETMASKSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETMASKSND,          MUSE_GETARMORSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETBATSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETBATSND,           MUSE_GETWEIRDSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETHEADSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETHEADSND,          MUSE_GETWEIRDSND,      },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GET1UPSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GET1UPSND,           MUSE_GETLIFESND,       },   SD_PITCHSHIFTOFF,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GET3UPSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GET3UPSND,           MUSE_GETLIFESND,       },   SD_PITCHSHIFTOFF,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_RESPAWNSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_RESPAWNSND,          MUSE_GETBONUSSND,      },   SD_PITCHSHIFTOFF,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERSPAWNSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERSPAWNSND,      MUSE_GETLIFESND,       },   SD_PITCHSHIFTOFF,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD1SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1SEESND,     MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD1ASEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1ASEESND,    MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD1SEE3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1SEE2SND,    MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD2SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1SEESND,     MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD2ASEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1ASEESND,    MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD2SEE3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1SEE2SND,    MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARDFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKPISTOLSND,     MUSE_ACTORFIRESND,        },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARDOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARDOUCHSND,     MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD1DIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1DIESND,    MUSE_ACTORDIESND,       },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD2DIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1DIESND,    MUSE_ACTORDIESND,       },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNEAKYSPRINGMSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNEAKYSPRINGMSND,    MUSE_ACTORDOITSND,     },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNEAKYSPRINGFSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNEAKYSPRINGMSND,    MUSE_ACTORDOITSND,     },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HIGHGUARD1SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HIGHGUARD1SEESND,    MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HIGHGUARD2SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HIGHGUARD2SEESND,    MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HIGHGUARDFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKMP40SND,          MUSE_ACTORFIRESND,     },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HIGHGUARDOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HIGHGUARDOUCHSND,    MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HIGHGUARDDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HIGHGUARDDIESND,     MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERP1SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_OVERP1SEESND,        MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERP2SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_OVERP1SEESND,        MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERPFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKPISTOLSND,     MUSE_ACTORFIRESND,        },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERPNETSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_OVERPNETSND,         MUSE_ACTORTHROWSND,    },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERPOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_OVERPOUCHSND,        MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERPDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_OVERPDIESND,         MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKE1SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_STRIKE1SEESND,       MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKE2SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_STRIKE1SEESND,       MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKEFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKPISTOLSND,     MUSE_ACTORFIRESND,        },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKEROLLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_STRIKEROLLSND,       MUSE_ACTORROLLSND,     },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKEOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_STRIKEOUCHSND,       MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKEDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_STRIKEDIESND,        MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZ1SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZ1SEESND,        MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZ2SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZ2SEESND,        MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKPISTOLSND,     MUSE_ACTORFIRESND,        },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZSTEALSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZSTEALSND,       MUSE_GETPOWERDOWNSND,  },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZOUCHSND,        MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZDIESND,         MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZPLEADSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZPLEADSND,       MUSE_LASTSOUND,        },  SD_PLAYONCE,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZPLEAD1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZPLEAD1SND,       MUSE_LASTSOUND,       },  SD_PLAYONCE,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZPLEAD2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZPLEAD2SND,       MUSE_LASTSOUND,       },  SD_PLAYONCE,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENFORCERSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENFORCERSEESND,      MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENFORCERFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENFORCERFIRESND,     MUSE_ACTORFIRESND,     },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENFORCERTHROWSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENFORCERTHROWSND,    MUSE_ACTORTHROWSND,    },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENFORCEROUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENFORCEROUCHSND,     MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENFORCERDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENFORCERDIESND,      MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MONKSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_MONKSEESND,          MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MONKGRABSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_MONKGRABSND,         MUSE_ACTORDOITSND,     },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MONKOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_MONKOUCHSND,         MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MONKDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_MONKDIESND,          MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREMONKSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREMONKSEESND,      MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREMONKFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREMONKFIRESND,     MUSE_ACTORFIRESND,     },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREMONKOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREMONKOUCHSND,     MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREMONKDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREMONKDIESND,      MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ROBOTSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ROBOTSEESND,         MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ROBOTFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ROBOTFIRESND,        MUSE_ACTORFIRESND,     },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ROBOTDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ROBOTDIESND,         MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ROBOTMOVESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTMOTORSND,       MUSE_LASTSOUND,        },  SD_PLAYONCE,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BALLISTIKRAFTSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BAZOOKAFIRESND,         MUSE_ACTORSEESND,   },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BALLISTIKRAFTFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ROBOTFIRESND,        MUSE_ACTORFIRESND,     },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARIANSEESND,        MUSE_BOSSSEESND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BAZOOKAFIRESND,       MUSE_BOSSFIRESND,     },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANGONNAUSESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARIANGONNAUSESND,   MUSE_BOSSDOSND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANUSESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_TOUCHPLATESND,       MUSE_BOSSDOSND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANHIDESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARIANHIDESND,       MUSE_BOSSDOSND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARIANDIESND,        MUSE_BOSSDIESND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANSAY1,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARIANSAY1,          MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANSAY2,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARIANSAY2,          MUSE_BOSSHEYSND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANSAY3,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARIANSAY3,          MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTSEESND,         MUSE_BOSSSEESND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BAZOOKAFIRESND,      MUSE_BOSSFIRESND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTMOTORSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTMOTORSND,       MUSE_LASTSOUND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTTURNSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTTURNSND,        MUSE_BOSSBEEPSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTDROPSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTDROPSND,        MUSE_BOSSDOSND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTMINEBEEPSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTMINEBEEPSND,    MUSE_BOSSBEEPSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTMINEHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTMINEHITSND,     MUSE_MISSILEHITSND,    },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTDIESND,         MUSE_BOSSDIESND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTSAY1,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTSAY1,           MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTSAY2,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTSAY2,           MUSE_BOSSHEYSND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTSAY3,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTSAY3,           MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMESEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NMESEESND,           MUSE_BOSSSEESND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMEREADYSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NMEREADYSND,         MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMEFIRE1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BAZOOKAFIRESND,      MUSE_BOSSFIRESND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMEAPARTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NMEAPARTSND,         MUSE_BOSSBEEPSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMEUFOSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NMEUFOSND,           MUSE_MISSILEFIRESND,   },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMEDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXPLODESND,           MUSE_BOSSDIESND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKSEESND,      MUSE_BOSSSEESND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKFIRE1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKFIRE1SND,    MUSE_BOSSFIRESND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKFIRE2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKFIRE2SND,    MUSE_BOSSFIRE2SND,     },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKFIRE3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKFIRE3SND,    MUSE_BOSSFIRESND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKFIRE4SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKFIRE4SND,    MUSE_BOSSFIRE2SND,     },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKRECHARGESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKRECHARGESND,   MUSE_WEAPONBUILDSND, },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKFLOATSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKFLOATSND,    MUSE_LASTSOUND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKDIESND,      MUSE_BOSSDIESND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKSAY1,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKSAY1,        MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKSAY2,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKSAY2,        MUSE_BOSSHEYSND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKSAY3,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DARKMONKSAY3,        MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKESEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNAKESEESND,         MUSE_BOSSSEESND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKEREADYSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNAKEREADYSND,       MUSE_BOSSBEEPSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKECHARGESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNAKECHARGESND,      MUSE_WEAPONBUILDSND,   },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKEOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNAKEOUCHSND,        MUSE_BOSSOUCHSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKEDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNAKEDIESND,         MUSE_BOSSDIESND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKESPITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNAKESPITSND,        MUSE_BOSSFIRESND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKESAY1,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNAKESAY1,           MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKESAY2,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNAKESAY2,           MUSE_BOSSHEYSND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKESAY3,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNAKESAY3,           MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EMPLACEMENTSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EMPLACEMENTSEESND,   MUSE_SWITCHSND,        },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EMPLACEMENTFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EMPLACEMENTFIRESND,  MUSE_EMPFIRESND,       },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BIGEMPLACEFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BIGEMPLACEFIRESND,   MUSE_EMPFIRESND,       },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OPENDOORSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_OPENDOORSND,        MUSE_OPENDOORSND,       },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_CLOSEDOORSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_CLOSEDOORSND,       MUSE_CLOSEDOORSND,      },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOORHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ELEVATORENDSND,       MUSE_LASTSOUND,           },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIRECHUTESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIRECHUTESND,        MUSE_MISSILEFIRESND,   },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREBALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREBALLSND,         MUSE_LASTSOUND,        },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREBALLHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREBALLHITSND,      MUSE_MISSILEHITSND,    },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLADESPINSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLADESPINSND,        MUSE_SPINBLADESND,     },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PUSHWALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PUSHWALLSND,         MUSE_PUSHWALLSND,      },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PUSHWALLHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PUSHWALLHITSND,      MUSE_MISSILEHITSND,    },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GOWALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GOWALLSND,           MUSE_PUSHWALLSND,      },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_TURBOWALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_TURBOWALLSND,        MUSE_PUSHWALLSND,      },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BOULDERHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BOULDERHITSND,       MUSE_MISSILEHITSND,    },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BOULDERROLLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BOULDERROLLSND,      MUSE_BOULDERSND,       },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BOULDERFALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BOULDERHITSND,       MUSE_PITTRAPSND,       },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PITTRAPSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PITTRAPSND,          MUSE_PITTRAPSND,       },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREJETSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREJETSND,          MUSE_FIREJETSND,       },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ACTORSQUISHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ACTORSQUISHSND,      MUSE_ACTORSQUISHSND,   },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ACTORBURNEDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ACTORBURNEDSND,      MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ACTORSKELETONSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ACTORSKELETONSND,    MUSE_LASTSOUND,        },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SPEARSTABSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SPEARSTABSND,        MUSE_STABBERSND,       },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_CYLINDERMOVESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_CYLINDERMOVESND,     MUSE_CYLINDERHITSND,   },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ELEVATORONSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ELEVATORONSND,       MUSE_ELEVATORSND,      },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ELEVATORENDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ELEVATORENDSND,      MUSE_LASTSOUND,        },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SPRINGBOARDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SPRINGBOARDSND,      MUSE_SPRINGBOARDSND,   },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LIGHTNINGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LIGHTNINGSND,        MUSE_LASTSOUND,        },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_WINDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_WINDSND,             MUSE_LASTSOUND,        },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_WATERSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_LASTSOUND,        },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BODYLANDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BODYLANDSND,         MUSE_LASTSOUND,        },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GIBSPLASHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GIBSPLASHSND,         MUSE_LASTSOUND,       },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ACTORLANDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ACTORLANDSND,         MUSE_LASTSOUND,       },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOPEFISHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DOPEFISHSND,         MUSE_LASTSOUND,        },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_YOUSUCKSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_YOUSUCKSND,          MUSE_LASTSOUND,        },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SILLYMOVESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SILLYMOVESND,        MUSE_LASTSOUND,        },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SOUNDSELECTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SOUNDSELECTSND,      MUSE_LASTSOUND,        },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SOUNDESCSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SOUNDESCSND,         MUSE_LASTSOUND,        },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM1SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM2SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM3SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM4SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM4SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM5SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM5SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM6SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM6SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM7SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM7SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM8SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM8SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM9SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM9SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM10SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM10SND,        MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LASTSOUND
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_LASTSOUND,        },  0,SD_PRIOSECRET, 0, 0, 0}
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+};
+

Added: tags/rott-1.1/rott/snd_shar.h
===================================================================
--- tags/rott-1.1/rott/snd_shar.h	                        (rev 0)
+++ tags/rott-1.1/rott/snd_shar.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1302 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+typedef enum {
+
+D_LASTSOUND=-1,
+// MENU SOUNDS
+
+D_MENUFLIP,
+D_ESCPRESSEDSND,
+D_MOVECURSORSND,
+D_SELECTSND,
+D_WARNINGBOXSND,
+D_INFOBOXSND,
+D_QUESTIONBOXSND,
+D_NOPESND,
+
+// GAME SOUNDS
+
+D_LEVELSTARTSND,
+D_LEVELDONESND,
+D_GAMEOVERSND,
+
+// LEVEL END SCREEN
+
+D_ENDBONUS1SND,
+
+// PLAYER SOUNDS
+
+D_HITWALLSND,
+D_SELECTWPNSND,
+D_NOWAYSND,
+D_DONOTHINGSND,
+//D_NOITEMSND,
+D_PLAYERDYINGSND,
+
+D_PLAYERTCDEATHSND,
+D_PLAYERTCHURTSND,
+D_PLAYERTCSND,
+//D_WALK1SND,
+//D_WALK2SND,
+D_PLAYERBURNEDSND,
+D_PLAYERLANDSND,
+D_PLAYERCOUGHMSND,
+
+// PLAYER WEAPONS
+
+D_ATKPISTOLSND,
+D_ATKTWOPISTOLSND,
+D_ATKMP40SND,
+D_RICOCHET1SND,
+D_RICOCHET2SND,
+D_RICOCHET3SND,
+D_BAZOOKAFIRESND,
+D_HEATSEEKFIRESND,
+D_FIREBOMBFIRESND,
+D_DRUNKFIRESND,
+D_FLAMEWALLFIRESND,
+D_FLAMEWALLSND,
+D_GRAVSND,
+D_FIREHITSND,
+D_MISSILEFLYSND,
+D_MISSILEHITSND,
+D_GODMODEFIRESND,
+D_GODMODE1SND,
+D_GODMODE2SND,
+D_GODMODE3SND,
+D_LOSEMODESND,
+D_GODMANSND,
+D_FLYINGSND,
+
+// PLAYER-CAUSED SOUNDS
+
+D_GLASSBREAKSND,
+D_ITEMBLOWSND,
+D_BONUSBARRELSND,
+D_TOUCHPLATESND,
+D_BADTOUCHSND,
+D_EXPLODEFLOORSND,
+D_EXPLODESND,
+//D_GASSTARTSND,
+D_GASHISSSND,
+D_GASENDSND,
+D_GASMASKSND,
+
+// GET ITEM SOUNDS
+
+D_GETKEYSND,
+D_GETBONUSSND,
+D_GETHEALTH1SND,
+D_COOKHEALTHSND,
+
+D_GETWEAPONSND,
+D_GETGODSND,
+D_GETFLEETSND,
+D_GETELASTSND,
+D_GETSHROOMSSND,
+D_GETBVESTSND,
+D_GETAVESTSND,
+D_GETMASKSND,
+
+D_GET1UPSND,
+D_RESPAWNSND,
+D_PLAYERSPAWNSND,
+
+// ACTOR SOUNDS
+
+D_LOWGUARD1SEESND,
+D_LOWGUARD1SEE2SND,
+D_LOWGUARDOUCHSND,
+D_LOWGUARD1DIESND,
+D_SNEAKYSPRINGMSND,
+
+D_HIGHGUARD1SEESND,
+D_HIGHGUARDOUCHSND,
+D_HIGHGUARDDIESND,
+
+D_STRIKE1SEESND,
+D_STRIKEROLLSND,
+D_STRIKEOUCHSND,
+D_STRIKEDIESND,
+
+D_BLITZ1SEESND,
+D_BLITZSTEALSND,
+D_BLITZOUCHSND,
+D_BLITZDIESND,
+D_BLITZPLEADSND,
+D_BLITZPLEAD1SND,
+D_BLITZPLEAD2SND,
+
+D_ENFORCERSEESND,
+D_ENFORCERFIRESND,
+D_ENFORCERTHROWSND,
+D_ENFORCEROUCHSND,
+D_ENFORCERDIESND,
+
+D_ROBOTSEESND,
+D_ROBOTFIRESND,
+D_ROBOTDIESND,
+
+D_KRISTMOTORSND,
+
+// ENVIRONMENT SOUNDS
+
+D_OPENDOORSND,
+D_CLOSEDOORSND,
+D_DOORHITSND,
+
+D_FIRECHUTESND,
+D_FIREBALLSND,
+D_FIREBALLHITSND,
+D_BLADESPINSND,
+D_PUSHWALLSND,
+D_PUSHWALLHITSND,
+D_GOWALLSND,
+D_TURBOWALLSND,
+D_PITTRAPSND,
+D_FIREJETSND,
+D_ACTORSQUISHSND,
+D_ACTORBURNEDSND,
+D_ACTORSKELETONSND,
+
+D_SPEARSTABSND,
+D_CYLINDERMOVESND,
+D_ELEVATORONSND,
+D_ELEVATORENDSND,
+D_SPRINGBOARDSND,
+D_LIGHTNINGSND,
+//D_WINDSND,
+
+// SECRET SOUNDS
+
+D_YOUSUCKSND,
+D_BODYLANDSND,
+D_GIBSPLASHSND,
+D_ACTORLANDSND
+
+} digisounds;
+
+
+static sound_t sounds[MAXSOUNDS] = {
+//SD_MENUFLIP,
+//|-------DIGITAL--------|---------MUSE---------|-MIDI----------FLAGS---|
+ {{D_MENUFLIP,            MUSE_MENUFLIPSND,      },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ESCPRESSEDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ESCPRESSEDSND,       MUSE_ESCPRESSEDSND,    },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MOVECURSORSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_MOVECURSORSND,       MUSE_MOVECURSORSND,    },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SELECTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SELECTSND,           MUSE_SELECTSND,        },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_WARNINGBOXSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_WARNINGBOXSND,       MUSE_WARNINGBOXSND,    },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_INFOBOXSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_INFOBOXSND,          MUSE_INFOBOXSND,       },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUESTIONBOXSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_QUESTIONBOXSND,      MUSE_QUESTIONBOXSND,   },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NOPESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NOPESND,             MUSE_NOPESND,          },  0,SD_PRIOMENU, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_SELECTSND,        },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,            MUSE_SELECTSND,       },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,            MUSE_SELECTSND,       },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT4SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,            MUSE_SELECTSND,       },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT5SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,            MUSE_SELECTSND,       },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT6SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,            MUSE_SELECTSND,       },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_QUIT7SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,            MUSE_SELECTSND,       },  0,SD_PRIOQUIT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LEVELSTARTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LEVELSTARTSND,       MUSE_LEVELSTARTSND,    },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LEVELDONESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LEVELDONESND,        MUSE_LEVELENDSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GAMEOVERSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GAMEOVERSND,         MUSE_GAMEOVERSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENDBONUS1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENDBONUS1SND,        MUSE_ENDBONUS1SND,     },  SD_PITCHSHIFTOFF,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NOBONUSSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,          MUSE_NOBONUSSND,        },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PERCENT100SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,       MUSE_PERCENT100SND,        },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HITWALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HITWALLSND,          MUSE_HITWALLSND,       },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SELECTWPNSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SELECTWPNSND,        MUSE_SELECTWPNSND,     },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NOWAYSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NOWAYSND,            MUSE_NOWAYSND,         },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DONOTHINGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DONOTHINGSND,        MUSE_DONOTHINGSND,     },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NOITEMSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_NOWAYSND,            MUSE_NOITEMSND,        },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERDYINGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERDYINGSND,      MUSE_PLAYERDYINGSND,   },  SD_PITCHSHIFTOFF,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTCDEATHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCDEATHSND,    MUSE_PLAYERDEATHSND,   },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTBDEATHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCDEATHSND,    MUSE_PLAYERDEATHSND,   },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERDWDEATHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCDEATHSND,    MUSE_PLAYERDEATHSND,   },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERLNDEATHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCDEATHSND,    MUSE_PLAYERDEATHSND,   },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERIPFDEATHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCDEATHSND,    MUSE_PLAYERDEATHSND,   },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTCHURTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCHURTSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE, SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTBHURTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCHURTSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE, SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERDWHURTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCHURTSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE, SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERLNHURTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCHURTSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE, SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERIPFHURTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCHURTSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE, SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTCSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCSND,         MUSE_PLAYERYESSND,     },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERTBSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCSND,         MUSE_PLAYERYESSND,     },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERDWSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCSND,         MUSE_PLAYERYESSND,     },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERLNSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCSND,         MUSE_PLAYERYESSND,     },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERIPFSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERTCSND,         MUSE_PLAYERYESSND,     },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_WALK1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+// {{D_WALK1SND,            MUSE_WALK1SND,       },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_WALK2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+// {{D_WALK2SND,            MUSE_WALK2SND,       },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERBURNEDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERBURNEDSND,     MUSE_PLAYERHURTSND,    },  SD_PLAYONCE,SD_PRIOPHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERLANDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERLANDSND,       MUSE_PLAYERLANDSND,    },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERCOUGHMSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERCOUGHMSND,     MUSE_LASTSOUND,        },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERCOUGHFSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,     MUSE_LASTSOUND,              },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NETWIGGLESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_LASTSOUND,           },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NETFALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,          MUSE_NETFALLSND,        },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ATKPISTOLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKPISTOLSND,        MUSE_ATKPISTOLSND,     },  SD_WRITE,SD_PRIOPGUNS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ATKTWOPISTOLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKTWOPISTOLSND,     MUSE_ATKPISTOLSND,     },  SD_WRITE,SD_PRIOPGUNS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ATKMP40SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKMP40SND,          MUSE_ATKMP40SND,       },  SD_WRITE,SD_PRIOPMP40, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_RICOCHET1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_RICOCHET1SND,        MUSE_RICOCHETSND,      },  SD_WRITE,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_RICOCHET2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_RICOCHET2SND,        MUSE_RICOCHETSND,      },  SD_WRITE,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_RICOCHET3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_RICOCHET3SND,        MUSE_RICOCHETSND,      },  SD_WRITE,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BAZOOKAFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BAZOOKAFIRESND,      MUSE_MISSILEFIRESND,   },  SD_WRITE,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREBOMBFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREBOMBFIRESND,     MUSE_MISSILEFIRESND,   },  SD_WRITE,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HEATSEEKFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HEATSEEKFIRESND,     MUSE_MISSILEFIRESND,   },  SD_WRITE,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DRUNKFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_DRUNKFIRESND,        MUSE_MISSILEFIRESND,   },  SD_WRITE,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FLAMEWALLFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FLAMEWALLFIRESND,    MUSE_MISSILEFIRESND,   },  SD_WRITE,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FLAMEWALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FLAMEWALLSND,        MUSE_FLAMEWALLSND,     },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SPLITFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_MISSILEFIRESND,      },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SPLITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,            MUSE_MISSILEFIRESND,  },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GRAVBUILDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_WEAPONBUILDSND,      },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GRAVFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_ENERGYFIRESND,      },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GRAVSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GRAVSND,             MUSE_LASTSOUND,        },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GRAVHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,          MUSE_MISSILEHITSND,     },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREHITSND,          MUSE_MISSILEHITSND,    },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MISSILEFLYSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_MISSILEFLYSND,       MUSE_LASTSOUND,        },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MISSILEHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_MISSILEHITSND,       MUSE_MISSILEHITSND,    },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXCALIBOUNCESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,     MUSE_LASTSOUND,              },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXCALISWINGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_MISSILEFIRESND,        },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXCALIHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_MISSILEHITSND,       },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXCALIBUILDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_WEAPONBUILDSND,        },  0,SD_PRIOPSNDS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXCALIBLASTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_ENERGYFIRESND,         },  0,SD_PRIOPMISS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODMODEFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODMODEFIRESND,      MUSE_ENERGYFIRESND,    },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODMODE1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODMODE1SND,         MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODMODE2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODMODE2SND,         MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODMODE3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODMODE3SND,         MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOSEMODESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOSEMODESND,         MUSE_LOSEMODESND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODEPANTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_LASTSOUND,             },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODEBITE1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_DOGBITESND,            },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODEBITE2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_DOGBITESND,            },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODELICKSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_DOGLICKSND,            },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODEBLASTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_DOGBITESND,            },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMODEPREPBLASTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND, MUSE_LASTSOUND,                  },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGMANSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOGWOMANSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_LASTSOUND,          },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODMANSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GODMANSND,           MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GODWOMANSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_LASTSOUND,          },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FLYINGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FLYINGSND,           MUSE_LASTSOUND,        },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GLASSBREAKSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GLASSBREAKSND,       MUSE_GLASSBREAKSND,    },  0,SD_PRIOGLASS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ITEMBLOWSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ITEMBLOWSND,         MUSE_EXPLOSIONSND,     },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BONUSBARRELSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BONUSBARRELSND,      MUSE_EXPLOSIONSND,     },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_TOUCHPLATESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_TOUCHPLATESND,       MUSE_TOUCHPLATESND,    },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BADTOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BADTOUCHSND,         MUSE_BADTOUCHSND,      },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXPLODEFLOORSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXPLODEFLOORSND,     MUSE_EXPLOSIONSND,     },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EXPLODESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXPLODESND,          MUSE_EXPLOSIONSND,     },  0,SD_PRIOEXPL, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GASSTARTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_TOUCHPLATESND,         MUSE_SWITCHSND,      },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GASHISSSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GASHISSSND,          MUSE_LASTSOUND,        },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GASENDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GASENDSND,           MUSE_SWITCHSND,        },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GASMASKSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GASMASKSND,          MUSE_LASTSOUND,        },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETKEYSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETKEYSND,           MUSE_GETKEYSND,        },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETBONUSSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETBONUSSND,         MUSE_GETBONUSSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETHEALTH1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETHEALTH1SND,       MUSE_GETHEALTHSND,     },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETHEALTH2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETHEALTH1SND,       MUSE_GETHEALTHSND,     },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_COOKHEALTHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_COOKHEALTHSND,       MUSE_GETBONUSSND,      },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETWEAPONSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETWEAPONSND,        MUSE_GETWEAPONSND,     },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETKNIFESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_GETWEAPONSND,       },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETGODSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETGODSND,           MUSE_GETPOWERUPSND,    },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETDOGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_GETPOWERUPSND,    },  0,SD_PRIOGODDOG, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETFLEETSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETFLEETSND,         MUSE_GETPOWERUPSND,    },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETELASTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETELASTSND,         MUSE_GETPOWERDOWNSND,  },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETSHROOMSSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETSHROOMSSND,       MUSE_GETPOWERDOWNSND,  },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETBVESTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETBVESTSND,         MUSE_GETARMORSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETAVESTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETAVESTSND,         MUSE_GETARMORSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETMASKSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GETMASKSND,          MUSE_GETARMORSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETBATSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_GETWEIRDSND,      },  0,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GETHEADSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,          MUSE_GETWEIRDSND,       },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GET1UPSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GET1UPSND,           MUSE_GETLIFESND,       },   SD_PITCHSHIFTOFF,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GET3UPSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_GETLIFESND,       },   SD_PITCHSHIFTOFF,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_RESPAWNSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_RESPAWNSND,          MUSE_GETBONUSSND,      },   SD_PITCHSHIFTOFF,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PLAYERSPAWNSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PLAYERSPAWNSND,      MUSE_GETLIFESND,       },   SD_PITCHSHIFTOFF,SD_PRIOGAME, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD1SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1SEESND,     MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD1ASEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1SEESND,    MUSE_ACTORSEESND,       },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD1SEE3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1SEE2SND,    MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD2SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1SEESND,     MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD2ASEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1SEESND,    MUSE_ACTORSEESND,       },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD2SEE3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1SEE2SND,    MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARDFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKPISTOLSND,     MUSE_ACTORFIRESND,        },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARDOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARDOUCHSND,     MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD1DIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1DIESND,    MUSE_ACTORDIESND,       },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LOWGUARD2DIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LOWGUARD1DIESND,    MUSE_ACTORDIESND,       },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNEAKYSPRINGMSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNEAKYSPRINGMSND,    MUSE_ACTORDOITSND,     },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNEAKYSPRINGFSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SNEAKYSPRINGMSND,    MUSE_ACTORDOITSND,     },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HIGHGUARD1SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HIGHGUARD1SEESND,    MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HIGHGUARD2SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HIGHGUARD1SEESND,    MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HIGHGUARDFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKMP40SND,          MUSE_ACTORFIRESND,     },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HIGHGUARDOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HIGHGUARDOUCHSND,    MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_HIGHGUARDDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_HIGHGUARDDIESND,     MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERP1SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_ACTORSEESND,         },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERP2SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_ACTORSEESND,         },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERPFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKPISTOLSND,     MUSE_ACTORFIRESND,        },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERPNETSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_ACTORTHROWSND,      },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERPOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_ACTOROUCHSND,        },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OVERPDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_ACTORDIESND,        },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKE1SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_STRIKE1SEESND,       MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKE2SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_STRIKE1SEESND,       MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKEFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKPISTOLSND,     MUSE_ACTORFIRESND,        },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKEROLLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_STRIKEROLLSND,       MUSE_ACTORROLLSND,     },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKEOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_STRIKEOUCHSND,       MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_STRIKEDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_STRIKEDIESND,        MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZ1SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZ1SEESND,        MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZ2SEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZ1SEESND,        MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ATKPISTOLSND,     MUSE_ACTORFIRESND,        },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZSTEALSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZSTEALSND,       MUSE_GETPOWERDOWNSND,  },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZOUCHSND,        MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZDIESND,         MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZPLEADSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZPLEADSND,       MUSE_LASTSOUND,        },  SD_PLAYONCE,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZPLEAD1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZPLEAD1SND,       MUSE_LASTSOUND,       },  SD_PLAYONCE,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLITZPLEAD2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLITZPLEAD2SND,       MUSE_LASTSOUND,       },  SD_PLAYONCE,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENFORCERSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENFORCERSEESND,      MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENFORCERFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENFORCERFIRESND,     MUSE_ACTORFIRESND,     },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENFORCERTHROWSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENFORCERTHROWSND,    MUSE_ACTORTHROWSND,    },  0,SD_PRIOASNEAK, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENFORCEROUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENFORCEROUCHSND,     MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ENFORCERDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ENFORCERDIESND,      MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MONKSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,          MUSE_ACTORSEESND,       },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MONKGRABSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_ACTORDOITSND,       },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MONKOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_ACTOROUCHSND,       },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_MONKDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,          MUSE_ACTORDIESND,       },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREMONKSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_ACTORSEESND,           },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREMONKFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,     MUSE_ACTORFIRESND,           },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREMONKOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,     MUSE_ACTOROUCHSND,           },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREMONKDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_ACTORDIESND,           },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ROBOTSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ROBOTSEESND,         MUSE_ACTORSEESND,      },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ROBOTFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ROBOTFIRESND,        MUSE_ACTORFIRESND,     },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ROBOTDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ROBOTDIESND,         MUSE_ACTORDIESND,      },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ROBOTMOVESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_KRISTMOTORSND,       MUSE_LASTSOUND,        },  SD_PLAYONCE,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BALLISTIKRAFTSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BAZOOKAFIRESND,         MUSE_ACTORSEESND,   },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BALLISTIKRAFTFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ROBOTFIRESND,        MUSE_ACTORFIRESND,     },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_BOSSSEESND,          },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BAZOOKAFIRESND,       MUSE_BOSSFIRESND,     },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANGONNAUSESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,   MUSE_BOSSDOSND,                },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANUSESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_TOUCHPLATESND,       MUSE_BOSSDOSND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANHIDESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,       MUSE_BOSSDOSND,            },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_BOSSDIESND,          },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANSAY1,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,          MUSE_BOSSWARNSND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANSAY2,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,          MUSE_BOSSHEYSND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARIANSAY3,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,          MUSE_BOSSWARNSND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_BOSSSEESND,         },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BAZOOKAFIRESND,      MUSE_BOSSFIRESND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTMOTORSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,       MUSE_LASTSOUND,            },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTTURNSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_BOSSBEEPSND,         },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTDROPSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_BOSSDOSND,           },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTMINEBEEPSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,    MUSE_BOSSBEEPSND,             },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTMINEHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,     MUSE_MISSILEHITSND,          },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_BOSSDIESND,         },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTSAY1,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTSAY2,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_BOSSHEYSND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_KRISTSAY3,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMESEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_BOSSSEESND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMEREADYSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_BOSSWARNSND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMEFIRE1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BAZOOKAFIRESND,      MUSE_BOSSFIRESND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMEAPARTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_BOSSBEEPSND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMEUFOSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_MISSILEFIRESND,   },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_NMEDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_EXPLODESND,           MUSE_BOSSDIESND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_BOSSSEESND,            },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKFIRE1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,    MUSE_BOSSFIRESND,             },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKFIRE2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,    MUSE_BOSSFIRE2SND,            },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKFIRE3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,    MUSE_BOSSFIRESND,             },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKFIRE4SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,    MUSE_BOSSFIRE2SND,            },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKRECHARGESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,   MUSE_WEAPONBUILDSND,           },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKFLOATSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,    MUSE_LASTSOUND,               },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_BOSSDIESND,            },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKSAY1,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_BOSSWARNSND,         },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKSAY2,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_BOSSHEYSND,          },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DARKMONKSAY3,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_BOSSWARNSND,         },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKESEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_BOSSSEESND,         },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKEREADYSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,       MUSE_BOSSBEEPSND,          },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKECHARGESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_WEAPONBUILDSND,        },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKEOUCHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_BOSSOUCHSND,         },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKEDIESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_BOSSDIESND,         },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKESPITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_BOSSFIRESND,         },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKESAY1,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKESAY2,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_BOSSHEYSND,       },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SNAKESAY3,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_BOSSWARNSND,      },  0,SD_PRIOBOSS, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EMPLACEMENTSEESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,   MUSE_SWITCHSND,                },  0,SD_PRIOAGREET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_EMPLACEMENTFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,  MUSE_EMPFIRESND,                },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BIGEMPLACEFIRESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,   MUSE_EMPFIRESND,               },  0,SD_PRIOAFIRE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_OPENDOORSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_OPENDOORSND,        MUSE_OPENDOORSND,       },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_CLOSEDOORSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_CLOSEDOORSND,       MUSE_CLOSEDOORSND,      },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOORHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ELEVATORENDSND,       MUSE_LASTSOUND,           },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIRECHUTESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIRECHUTESND,        MUSE_MISSILEFIRESND,   },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREBALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREBALLSND,         MUSE_LASTSOUND,        },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREBALLHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREBALLHITSND,      MUSE_MISSILEHITSND,    },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BLADESPINSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BLADESPINSND,        MUSE_SPINBLADESND,     },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PUSHWALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PUSHWALLSND,         MUSE_PUSHWALLSND,      },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PUSHWALLHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PUSHWALLHITSND,      MUSE_MISSILEHITSND,    },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GOWALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GOWALLSND,           MUSE_PUSHWALLSND,      },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_TURBOWALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_TURBOWALLSND,        MUSE_PUSHWALLSND,      },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BOULDERHITSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,       MUSE_MISSILEHITSND,        },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BOULDERROLLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_BOULDERSND,            },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BOULDERFALLSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,       MUSE_PITTRAPSND,           },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_PITTRAPSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_PITTRAPSND,          MUSE_PITTRAPSND,       },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_FIREJETSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_FIREJETSND,          MUSE_FIREJETSND,       },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ACTORSQUISHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ACTORSQUISHSND,      MUSE_ACTORSQUISHSND,   },  0,SD_PRIOADEATH, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ACTORBURNEDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ACTORBURNEDSND,      MUSE_ACTOROUCHSND,     },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ACTORSKELETONSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ACTORSKELETONSND,    MUSE_LASTSOUND,        },  0,SD_PRIOAHURT, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SPEARSTABSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SPEARSTABSND,        MUSE_STABBERSND,       },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_CYLINDERMOVESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_CYLINDERMOVESND,     MUSE_CYLINDERHITSND,   },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ELEVATORONSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ELEVATORONSND,       MUSE_ELEVATORSND,      },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ELEVATORENDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ELEVATORENDSND,      MUSE_LASTSOUND,        },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SPRINGBOARDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_SPRINGBOARDSND,      MUSE_SPRINGBOARDSND,   },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LIGHTNINGSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LIGHTNINGSND,        MUSE_LASTSOUND,        },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_WINDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,             MUSE_LASTSOUND,        },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_WATERSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,            MUSE_LASTSOUND,       },  0,SD_PRIOPCAUSD, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_BODYLANDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_BODYLANDSND,         MUSE_LASTSOUND,        },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_GIBSPLASHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_GIBSPLASHSND,         MUSE_LASTSOUND,       },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_ACTORLANDSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_ACTORLANDSND,         MUSE_LASTSOUND,       },  0,SD_PRIOENVRON, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_DOPEFISHSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,         MUSE_LASTSOUND,          },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_YOUSUCKSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_YOUSUCKSND,          MUSE_LASTSOUND,        },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SILLYMOVESND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,        MUSE_LASTSOUND,           },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SOUNDSELECTSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,      MUSE_LASTSOUND,             },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_SOUNDESCSND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_YOUSUCKSND,         MUSE_LASTSOUND,         },  0,SD_PRIOSECRET, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM1SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM1SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM2SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM2SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM3SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM3SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM4SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM4SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM5SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM5SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM6SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM6SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM7SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM7SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM8SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM8SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM9SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM9SND,         MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_REMOTEM10SND,
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_REMOTEM10SND,        MUSE_LASTSOUND,        },  0,SD_PRIOREMOTE, 0, 0, 0},
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+//SD_LASTSOUND
+//|-------DIGITAL--------|--------MUSE----------|----FLAGS---|
+ {{D_LASTSOUND,           MUSE_LASTSOUND,        },  0,SD_PRIOSECRET, 0, 0, 0}
+//ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+};

Added: tags/rott-1.1/rott/sndcards.h
===================================================================
--- tags/rott-1.1/rott/sndcards.h	                        (rev 0)
+++ tags/rott-1.1/rott/sndcards.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,60 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: SNDCARDS.H
+
+   author: James R. Dose
+   phone:  (214)-271-1365 Ext #221
+   date:   March 31, 1994
+
+   Contains enumerated type definitions for sound cards.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __SNDCARDS_H
+#define __SNDCARDS_H
+
+#define ASS_VERSION_STRING "1.04"
+
+typedef enum
+   {
+//   ASS_NoSound,
+   SoundBlaster,
+#ifdef DOS
+   ProAudioSpectrum,
+   SoundMan16,
+   Adlib,
+   GenMidi,
+   SoundCanvas,
+   Awe32,
+   WaveBlaster,
+#endif
+   SoundScape,
+   UltraSound,
+#ifdef DOS
+   SoundSource,
+   TandySoundSource,
+   PC,
+#endif
+   NumSoundCards
+   } soundcardnames;
+
+#endif

Added: tags/rott-1.1/rott/splib.h
===================================================================
--- tags/rott-1.1/rott/splib.h	                        (rev 0)
+++ tags/rott-1.1/rott/splib.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,213 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef SPLIB_H
+#define SPLIB_H
+
+/* ======================================================================= *
+ * Please Read "SpReadme.doc" for usage                                    *
+ * ======================================================================= */
+
+/* ======================================================================= *
+ * Compiler & Memory Mode Wrappers.                                        *
+ * ----------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#  if PLATFORM_DOS
+#    define REALMODE
+#  endif
+#endif
+
+#if defined(REALMODE)
+#define FAR __far
+#else
+#define FAR
+#endif
+
+//---------------------------------------------------------------------------
+// Constants
+
+#define TSR_SERIAL_LENGTH		14
+#define TSR_MAX_LENGTH			80
+
+//---------------------------------------------------------------------------
+
+typedef struct {
+	char           copyright[TSR_MAX_LENGTH];	// driver copyright
+	short          major;							// driver version number
+	short				minor;
+	short				count;							// # of available devices
+} SpwDrvOpenPacket;
+
+
+
+typedef struct {
+	char           copyright[TSR_MAX_LENGTH];	// device copyright
+	char           serial[TSR_SERIAL_LENGTH];	// device serial number
+} SpwDevOpenPacket;
+
+
+
+typedef struct {
+	long				timestamp;						// time of event
+	unsigned short	period;							// period since last MOVEMENT
+	unsigned short button;							// button pressed mask
+	short          tx;								// Translation X
+	short          ty;								//					Y
+	short          tz;								//					Z
+	short          rx;								// Rotation X
+	short          ry;								//				Y
+	short          rz;								//				Z
+} SpwForcePacket;
+
+
+
+typedef struct {
+	long           timestamp;						// time of event
+	unsigned short period;							// period since last BUTTON
+	unsigned short button;							// button pressed mask
+} SpwButtonPacket;
+
+
+
+typedef struct {
+	unsigned long data;								// MUST be TSRCMD_DATA
+} SpwCommandPacket;
+
+#define TSRCMD_DATA	0xFF0000FF
+
+//---------------------------------------------------------------------------
+
+typedef union {
+	char              padding[128];		/* Extra room for future expansion */
+
+	SpwCommandPacket	command;
+
+	SpwDrvOpenPacket	drvOpen;
+	SpwDevOpenPacket	devOpen;
+
+	SpwForcePacket		force;
+	SpwButtonPacket	button;
+} SpwPacket;
+
+
+
+// TSR Interrupt Functions
+#define TSR_DRIVER_CLOSE		 		0x0000
+#define TSR_DRIVER_OPEN					0x8001
+#define TSR_DEVICE_CLOSE				0x0002
+#define TSR_DEVICE_OPEN					0x8003
+
+#define TSR_DEVICE_DISABLE				0x0010
+#define TSR_DEVICE_ENABLE				0x0011
+
+#define TSR_DEVICE_GETFORCE			0x8020
+#define TSR_DEVICE_GETBUTTONS			0x8021
+
+/* ======================================================================= *
+ * Function Prototypes                                                     *
+ * ======================================================================= */
+
+short SpwOpenDriver(SpwPacket FAR *packet);
+short SpwCloseDriver(void);
+
+short SpwOpenDevice(short device, SpwPacket FAR *packet);
+short SpwCloseDevice(short device);
+
+short SpwEnableDevice(short device);
+short SpwDisableDevice(short device);
+
+short SpwGetForce(short device, SpwPacket FAR *packet);
+short SpwGetButton(short device, SpwPacket FAR *packet);
+
+/* ======================================================================= *
+ * Convience functions                                                     *
+ * ======================================================================= */
+
+/* ----------------------------------------------------------------------- *
+ * The SpwSimple... functions are just convienence wrappers for the above  *
+ * functions.                                                              *
+ * ----------------------------------------------------------------------- */
+
+#ifndef SPWSTRUCTS
+#define SPWSTRUCTS
+
+enum SpwDeviceType {
+	SPW_AVENGER=1,
+};
+
+
+
+enum SpwEventType {
+	SPW_NO_EVENT=0,
+   SPW_BUTTON_HELD=1,
+   SPW_BUTTON_DOWN=2,
+   SPW_BUTTON_UP=4,
+   SPW_MOTION=8
+};
+
+
+
+/* ----------------------------------------------------------------------- *
+ * Data struct for handling library calls                                  *
+ * ----------------------------------------------------------------------- */
+
+typedef struct {
+	short new;
+   short cur;
+   short old;
+} SpwButtonRec;
+
+
+
+typedef struct {
+	short 		 tx;			/* Current Translation vector */
+   short 		 ty;
+   short 		 tz;
+   short 		 rx;			/* Current Rotation vector    */
+   short 		 ry;
+   short        rz;
+   SpwButtonRec buttons;   /* Current Button Record      */
+   short			 newData;   /* An SpEventType mask of newData, 0 if none */
+} SpwRawData;
+
+#endif
+
+
+
+short SpwSimpleGet(short devNum, SpwRawData FAR *splayer);
+short SpwSimpleOpen(short devNum);
+short SpwSimpleClose(short devNum);
+
+/* ======================================================================= *
+ * Compiler & Memory Mode Wrappers.                                        *
+ * ======================================================================= *
+ */
+
+#ifdef __cplusplus
+};
+#endif
+
+/* ======================================================================= */
+#endif
+

Added: tags/rott-1.1/rott/sprites.h
===================================================================
--- tags/rott-1.1/rott/sprites.h	                        (rev 0)
+++ tags/rott-1.1/rott/sprites.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,1611 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _sprites_public
+#define _sprites_public
+
+#include "develop.h"
+
+typedef enum {ACTOR_START_LABEL,
+
+
+/***************    UNTERWACHE  *************************************/
+
+
+SPR_LOWGRD_SHOOT1,SPR_LOWGRD_SHOOT2,SPR_LOWGRD_SHOOT3,SPR_LOWGRD_SHOOT4,
+
+SPR_LOWGRD_S1,SPR_LOWGRD_S2,SPR_LOWGRD_S3,SPR_LOWGRD_S4,
+SPR_LOWGRD_S5,SPR_LOWGRD_S6,SPR_LOWGRD_S7,SPR_LOWGRD_S8,
+
+SPR_LOWGRD_W11,SPR_LOWGRD_W12,SPR_LOWGRD_W13,SPR_LOWGRD_W14,
+SPR_LOWGRD_W15,SPR_LOWGRD_W16,SPR_LOWGRD_W17,SPR_LOWGRD_W18,
+
+SPR_LOWGRD_W21,SPR_LOWGRD_W22,SPR_LOWGRD_W23,SPR_LOWGRD_W24,
+SPR_LOWGRD_W25,SPR_LOWGRD_W26,SPR_LOWGRD_W27,SPR_LOWGRD_W28,
+
+SPR_LOWGRD_W31,SPR_LOWGRD_W32,SPR_LOWGRD_W33,SPR_LOWGRD_W34,
+SPR_LOWGRD_W35,SPR_LOWGRD_W36,SPR_LOWGRD_W37,SPR_LOWGRD_W38,
+
+SPR_LOWGRD_W41,SPR_LOWGRD_W42,SPR_LOWGRD_W43,SPR_LOWGRD_W44,
+SPR_LOWGRD_W45,SPR_LOWGRD_W46,SPR_LOWGRD_W47,SPR_LOWGRD_W48,
+
+
+SPR_LOWGRD_PAIN1, SPR_LOWGRD_PAIN2, SPR_LOWGRD_DIE1, SPR_LOWGRD_DIE2,
+SPR_LOWGRD_DIE3, SPR_LOWGRD_DIE4, SPR_LOWGRD_DEAD,
+
+SPR_LOWGRD_WPAIN1, SPR_LOWGRD_WPAIN2, SPR_LOWGRD_WDIE1, SPR_LOWGRD_WDIE2,
+SPR_LOWGRD_WDIE3, SPR_LOWGRD_WDIE4, SPR_LOWGRD_WDEAD,
+
+
+SPR_SNEAKY_DEAD, SPR_RISE1, SPR_RISE2, SPR_RISE3, SPR_RISE4,
+
+/*
+SPR_LOWGRD_USE11,SPR_LOWGRD_USE12,SPR_LOWGRD_USE13,SPR_LOWGRD_USE14,
+SPR_LOWGRD_USE15,SPR_LOWGRD_USE16,SPR_LOWGRD_USE17,SPR_LOWGRD_USE18,
+
+SPR_LOWGRD_USE21,SPR_LOWGRD_USE22,SPR_LOWGRD_USE23,SPR_LOWGRD_USE24,
+SPR_LOWGRD_USE25,SPR_LOWGRD_USE26,SPR_LOWGRD_USE27,SPR_LOWGRD_USE28,
+*/
+
+
+/*****************  Highguard 1 (Steve B.)  ***************************************/
+
+
+
+
+SPR_HIGHGRD_SHOOT1,SPR_HIGHGRD_SHOOT2,SPR_HIGHGRD_SHOOT3,SPR_HIGHGRD_SHOOT4,
+
+SPR_HIGHGRD_S1,SPR_HIGHGRD_S2,SPR_HIGHGRD_S3,SPR_HIGHGRD_S4,
+SPR_HIGHGRD_S5,SPR_HIGHGRD_S6,SPR_HIGHGRD_S7,SPR_HIGHGRD_S8,
+
+SPR_HIGHGRD_W11,SPR_HIGHGRD_W12,SPR_HIGHGRD_W13,SPR_HIGHGRD_W14,
+SPR_HIGHGRD_W15,SPR_HIGHGRD_W16,SPR_HIGHGRD_W17,SPR_HIGHGRD_W18,
+
+SPR_HIGHGRD_W21,SPR_HIGHGRD_W22,SPR_HIGHGRD_W23,SPR_HIGHGRD_W24,
+SPR_HIGHGRD_W25,SPR_HIGHGRD_W26,SPR_HIGHGRD_W27,SPR_HIGHGRD_W28,
+
+SPR_HIGHGRD_W31,SPR_HIGHGRD_W32,SPR_HIGHGRD_W33,SPR_HIGHGRD_W34,
+SPR_HIGHGRD_W35,SPR_HIGHGRD_W36,SPR_HIGHGRD_W37,SPR_HIGHGRD_W38,
+
+SPR_HIGHGRD_W41,SPR_HIGHGRD_W42,SPR_HIGHGRD_W43,SPR_HIGHGRD_W44,
+SPR_HIGHGRD_W45,SPR_HIGHGRD_W46,SPR_HIGHGRD_W47,SPR_HIGHGRD_W48,
+
+
+SPR_HIGHGRD_PAIN1,SPR_HIGHGRD_PAIN2,
+SPR_HIGHGRD_DIE1,SPR_HIGHGRD_DIE2,SPR_HIGHGRD_DIE3,SPR_HIGHGRD_DIE4,
+SPR_HIGHGRD_DIE5,SPR_HIGHGRD_DEAD,
+
+SPR_HIGHGRD_WPAIN1,SPR_HIGHGRD_WPAIN2,
+SPR_HIGHGRD_WDIE1,SPR_HIGHGRD_WDIE2,SPR_HIGHGRD_WDIE3,SPR_HIGHGRD_WDIE4,
+SPR_HIGHGRD_WDIE5,SPR_HIGHGRD_WDEAD,
+
+/*
+SPR_HIGHGRD_USE11,SPR_HIGHGRD_USE12,SPR_HIGHGRD_USE13,SPR_HIGHGRD_USE14,
+SPR_HIGHGRD_USE15,SPR_HIGHGRD_USE16,SPR_HIGHGRD_USE17,SPR_HIGHGRD_USE18,
+
+SPR_HIGHGRD_USE21,SPR_HIGHGRD_USE22,SPR_HIGHGRD_USE23,SPR_HIGHGRD_USE24,
+SPR_HIGHGRD_USE25,SPR_HIGHGRD_USE26,SPR_HIGHGRD_USE27,SPR_HIGHGRD_USE28,
+*/
+
+
+
+
+/******************** ANGRIFFSTUPPE **********************************/
+
+
+SPR_STRIKE_SHOOT1,SPR_STRIKE_SHOOT2,SPR_STRIKE_SHOOT3,SPR_STRIKE_SHOOT4,
+SPR_STRIKE_KSHOOT1,SPR_STRIKE_KSHOOT2,SPR_STRIKE_KSHOOT3,
+
+
+SPR_STRIKE_S1,SPR_STRIKE_S2,SPR_STRIKE_S3,SPR_STRIKE_S4,
+SPR_STRIKE_S5,SPR_STRIKE_S6,SPR_STRIKE_S7,SPR_STRIKE_S8,
+
+SPR_STRIKE_W11,SPR_STRIKE_W12,SPR_STRIKE_W13,SPR_STRIKE_W14,
+SPR_STRIKE_W15,SPR_STRIKE_W16,SPR_STRIKE_W17,SPR_STRIKE_W18,
+
+SPR_STRIKE_W21,SPR_STRIKE_W22,SPR_STRIKE_W23,SPR_STRIKE_W24,
+SPR_STRIKE_W25,SPR_STRIKE_W26,SPR_STRIKE_W27,SPR_STRIKE_W28,
+
+SPR_STRIKE_W31,SPR_STRIKE_W32,SPR_STRIKE_W33,SPR_STRIKE_W34,
+SPR_STRIKE_W35,SPR_STRIKE_W36,SPR_STRIKE_W37,SPR_STRIKE_W38,
+
+SPR_STRIKE_W41,SPR_STRIKE_W42,SPR_STRIKE_W43,SPR_STRIKE_W44,
+SPR_STRIKE_W45,SPR_STRIKE_W46,SPR_STRIKE_W47,SPR_STRIKE_W48,
+
+
+SPR_STRIKE_PAIN1,SPR_STRIKE_PAIN2,
+SPR_STRIKE_DIE1,SPR_STRIKE_DIE2,SPR_STRIKE_DIE3,
+SPR_STRIKE_DIE4,SPR_STRIKE_DEAD1,SPR_STRIKE_DEAD2,SPR_STRIKE_DEAD3,
+
+SPR_STRIKE_WPAIN1,SPR_STRIKE_WPAIN2,
+SPR_STRIKE_WDIE1,SPR_STRIKE_WDIE2,SPR_STRIKE_WDIE3,
+SPR_STRIKE_WDIE4,SPR_STRIKE_WDEAD1,SPR_STRIKE_WDEAD2,SPR_STRIKE_WDEAD3,
+
+SPR_STRIKE_RROLL1,SPR_STRIKE_RROLL2,SPR_STRIKE_RROLL3,SPR_STRIKE_RROLL4,
+SPR_STRIKE_RROLL5,SPR_STRIKE_RROLL6,
+
+SPR_STRIKE_LROLL1,SPR_STRIKE_LROLL2,SPR_STRIKE_LROLL3,SPR_STRIKE_LROLL4,
+SPR_STRIKE_LROLL5,SPR_STRIKE_LROLL6,
+
+
+
+
+/********************** BLITZWACHE **********************************/
+
+
+SPR_BLITZ_SHOOT1,SPR_BLITZ_SHOOT2,SPR_BLITZ_SHOOT3,SPR_BLITZ_SHOOT4,
+
+SPR_BLITZ_S1,SPR_BLITZ_S2,SPR_BLITZ_S3,SPR_BLITZ_S4,
+SPR_BLITZ_S5,SPR_BLITZ_S6,SPR_BLITZ_S7,SPR_BLITZ_S8,
+
+SPR_BLITZ_W11,SPR_BLITZ_W12,SPR_BLITZ_W13,SPR_BLITZ_W14,
+SPR_BLITZ_W15,SPR_BLITZ_W16,SPR_BLITZ_W17,SPR_BLITZ_W18,
+
+SPR_BLITZ_W21,SPR_BLITZ_W22,SPR_BLITZ_W23,SPR_BLITZ_W24,
+SPR_BLITZ_W25,SPR_BLITZ_W26,SPR_BLITZ_W27,SPR_BLITZ_W28,
+
+SPR_BLITZ_W31,SPR_BLITZ_W32,SPR_BLITZ_W33,SPR_BLITZ_W34,
+SPR_BLITZ_W35,SPR_BLITZ_W36,SPR_BLITZ_W37,SPR_BLITZ_W38,
+
+SPR_BLITZ_W41,SPR_BLITZ_W42,SPR_BLITZ_W43,SPR_BLITZ_W44,
+SPR_BLITZ_W45,SPR_BLITZ_W46,SPR_BLITZ_W47,SPR_BLITZ_W48,
+
+
+SPR_BLITZ_PAIN1, SPR_BLITZ_PAIN2,SPR_BLITZ_DIE1,SPR_BLITZ_DIE2,
+SPR_BLITZ_DIE3,SPR_BLITZ_DIE4,SPR_BLITZ_DEAD1, SPR_BLITZ_DEAD2,
+
+SPR_BLITZ_WPAIN1, SPR_BLITZ_WPAIN2,SPR_BLITZ_WDIE1,SPR_BLITZ_WDIE2,
+SPR_BLITZ_WDIE3,SPR_BLITZ_WDIE4,SPR_BLITZ_WDEAD1, SPR_BLITZ_WDEAD2,
+
+SPR_BLITZ_RISE1, SPR_BLITZ_RISE2, SPR_BLITZ_RISE3, SPR_BLITZ_RISE4,
+
+SPR_BLITZ_USE11,SPR_BLITZ_USE12,SPR_BLITZ_USE13,SPR_BLITZ_USE14,
+SPR_BLITZ_USE15,SPR_BLITZ_USE16,SPR_BLITZ_USE17,SPR_BLITZ_USE18,
+
+SPR_BLITZ_USE21,SPR_BLITZ_USE22,SPR_BLITZ_USE23,SPR_BLITZ_USE24,
+SPR_BLITZ_USE25,SPR_BLITZ_USE26,SPR_BLITZ_USE27,SPR_BLITZ_USE28,
+
+SPR_BLITZ_PLEAD1,SPR_BLITZ_PLEAD2,SPR_BLITZ_PLEAD3,SPR_BLITZ_PLEAD4,
+SPR_BLITZ_PLEAD5,SPR_BLITZ_PLEAD6,SPR_BLITZ_PLEAD7,SPR_BLITZ_PLEAD8,
+SPR_BLITZ_PLEAD9,SPR_BLITZ_PLEAD10,SPR_BLITZ_PLEAD11,
+
+
+
+
+/******************** DREIHEITWACHE ***********************************/
+
+
+SPR_ENFORCER_SHOOT1,SPR_ENFORCER_SHOOT2,SPR_ENFORCER_SHOOT3,
+SPR_ENFORCER_SHOOT4,
+
+SPR_ENFORCER_S1,SPR_ENFORCER_S2,SPR_ENFORCER_S3,SPR_ENFORCER_S4,
+SPR_ENFORCER_S5,SPR_ENFORCER_S6,SPR_ENFORCER_S7,SPR_ENFORCER_S8,
+
+SPR_ENFORCER_W11,SPR_ENFORCER_W12,SPR_ENFORCER_W13,SPR_ENFORCER_W14,
+SPR_ENFORCER_W15,SPR_ENFORCER_W16,SPR_ENFORCER_W17,SPR_ENFORCER_W18,
+
+SPR_ENFORCER_W21,SPR_ENFORCER_W22,SPR_ENFORCER_W23,SPR_ENFORCER_W24,
+SPR_ENFORCER_W25,SPR_ENFORCER_W26,SPR_ENFORCER_W27,SPR_ENFORCER_W28,
+
+SPR_ENFORCER_W31,SPR_ENFORCER_W32,SPR_ENFORCER_W33,SPR_ENFORCER_W34,
+SPR_ENFORCER_W35,SPR_ENFORCER_W36,SPR_ENFORCER_W37,SPR_ENFORCER_W38,
+
+SPR_ENFORCER_W41,SPR_ENFORCER_W42,SPR_ENFORCER_W43,SPR_ENFORCER_W44,
+SPR_ENFORCER_W45,SPR_ENFORCER_W46,SPR_ENFORCER_W47,SPR_ENFORCER_W48,
+
+
+SPR_ENFORCER_THROW1,SPR_ENFORCER_THROW2,SPR_ENFORCER_THROW3,SPR_ENFORCER_THROW4,
+SPR_ENFORCER_THROW5,SPR_ENFORCER_THROW6,SPR_ENFORCER_THROW7,SPR_ENFORCER_THROW8,
+
+SPR_ENFORCER_PAIN1,SPR_ENFORCER_PAIN2,
+SPR_ENFORCER_DIE1,SPR_ENFORCER_DIE2,SPR_ENFORCER_DIE3,SPR_ENFORCER_DIE4,
+SPR_ENFORCER_DEAD,
+
+SPR_ENFORCER_WPAIN1,SPR_ENFORCER_WPAIN2,
+SPR_ENFORCER_WDIE1,SPR_ENFORCER_WDIE2,SPR_ENFORCER_WDIE3,SPR_ENFORCER_WDIE4,
+SPR_ENFORCER_WDEAD,
+
+/*
+SPR_ENFORCER_USE11,SPR_ENFORCER_USE12,SPR_ENFORCER_USE13,SPR_ENFORCER_USE14,
+SPR_ENFORCER_USE15,SPR_ENFORCER_USE16,SPR_ENFORCER_USE17,SPR_ENFORCER_USE18,
+
+SPR_ENFORCER_USE21,SPR_ENFORCER_USE22,SPR_ENFORCER_USE23,SPR_ENFORCER_USE24,
+SPR_ENFORCER_USE25,SPR_ENFORCER_USE26,SPR_ENFORCER_USE27,SPR_ENFORCER_USE28,
+*/
+
+
+/************************* ROBOT GUARD *********************************/
+
+
+SPR_ROBOGRD_S11,SPR_ROBOGRD_S12,SPR_ROBOGRD_S13,SPR_ROBOGRD_S14,
+SPR_ROBOGRD_S15,SPR_ROBOGRD_S16,SPR_ROBOGRD_S17,SPR_ROBOGRD_S18,
+
+SPR_ROBOGRD_S21,SPR_ROBOGRD_S22,SPR_ROBOGRD_S23,SPR_ROBOGRD_S24,
+SPR_ROBOGRD_S25,SPR_ROBOGRD_S26,SPR_ROBOGRD_S27,SPR_ROBOGRD_S28,
+
+ROBOGRDDIE1,ROBOGRDDIE2,ROBOGRDDIE3,ROBOGRDDIE4,
+ROBOGRDDIE5,ROBOGRDDIE6,ROBOGRDDIE7,ROBOGRDDIE8,
+ROBOGRDDIE9,ROBOGRDDEAD,
+
+
+
+/************************* EXPLOSIONS *******************************/
+
+SPR_EXPLOSION1,SPR_EXPLOSION2,SPR_EXPLOSION3,SPR_EXPLOSION4,
+SPR_EXPLOSION5,SPR_EXPLOSION6,SPR_EXPLOSION7,SPR_EXPLOSION8,
+SPR_EXPLOSION9,SPR_EXPLOSION10,SPR_EXPLOSION11,SPR_EXPLOSION12,
+SPR_EXPLOSION13,SPR_EXPLOSION14,SPR_EXPLOSION15,SPR_EXPLOSION16,
+SPR_EXPLOSION17,SPR_EXPLOSION18,SPR_EXPLOSION19,SPR_EXPLOSION20,
+
+
+
+SPR_STATICEXPL1,SPR_STATICEXPL2,SPR_STATICEXPL3,SPR_STATICEXPL4,
+SPR_STATICEXPL5,SPR_STATICEXPL6,SPR_STATICEXPL7,SPR_STATICEXPL8,
+SPR_STATICEXPL9,SPR_STATICEXPL10,SPR_STATICEXPL11,SPR_STATICEXPL12,
+SPR_STATICEXPL13,SPR_STATICEXPL14,SPR_STATICEXPL15,SPR_STATICEXPL16,
+SPR_STATICEXPL17,SPR_STATICEXPL18,SPR_STATICEXPL19,SPR_STATICEXPL20,
+SPR_STATICEXPL21,SPR_STATICEXPL22,SPR_STATICEXPL23,SPR_STATICEXPL24,
+SPR_STATICEXPL25,
+
+SPR_GROUNDEXPL1,SPR_GROUNDEXPL2,SPR_GROUNDEXPL3,SPR_GROUNDEXPL4,
+SPR_GROUNDEXPL5,SPR_GROUNDEXPL6,SPR_GROUNDEXPL7,SPR_GROUNDEXPL8,
+SPR_GROUNDEXPL9,SPR_GROUNDEXPL10,SPR_GROUNDEXPL11,SPR_GROUNDEXPL12,
+SPR_GROUNDEXPL13,SPR_GROUNDEXPL14,SPR_GROUNDEXPL15,SPR_GROUNDEXPL16,
+SPR_GROUNDEXPL17,SPR_GROUNDEXPL18,SPR_GROUNDEXPL19,SPR_GROUNDEXPL20,
+
+
+/************************* HAZARDS *******************************/
+
+
+
+UBLADE1,UBLADE2,UBLADE3,UBLADE4,
+UBLADE5,UBLADE6,UBLADE7,UBLADE8,
+UBLADE9,//UBLADE10,UBLADE11,UBLADE12,
+//UBLADE13,UBLADE14,UBLADE15,UBLADE16,
+
+
+
+
+FIREJETUP1,FIREJETUP2,FIREJETUP3,FIREJETUP4,
+FIREJETUP5,FIREJETUP6,FIREJETUP7,FIREJETUP8,
+FIREJETUP9,FIREJETUP10,FIREJETUP11,FIREJETUP12,
+FIREJETUP13,FIREJETUP14,FIREJETUP15,FIREJETUP16,
+FIREJETUP17,FIREJETUP18,FIREJETUP19,FIREJETUP20,
+FIREJETUP21,FIREJETUP22,FIREJETUP23,
+
+
+
+CRUSHDOWN1,CRUSHDOWN2,CRUSHDOWN3,CRUSHDOWN4,
+CRUSHDOWN5,CRUSHDOWN6,CRUSHDOWN7,CRUSHDOWN8,
+//CRUSHDOWN9,CRUSHDOWN10,CRUSHDOWN11,CRUSHDOWN12,
+//CRUSHDOWN13,CRUSHDOWN14,CRUSHDOWN15,CRUSHDOWN16,
+
+
+
+SPEARUP1,SPEARUP2,SPEARUP3,SPEARUP4,
+SPEARUP5,SPEARUP6,SPEARUP7,SPEARUP8,
+SPEARUP9,SPEARUP10,SPEARUP11,SPEARUP12,
+SPEARUP13,SPEARUP14,SPEARUP15,SPEARUP16,
+
+
+
+
+
+SPRING1,SPRING2,SPRING3,SPRING4,
+SPRING5,SPRING6,SPRING7,SPRING8,
+SPRING9,SPRING10,
+
+
+
+
+FIREW1,FIREW2,FIREW3,FIREW4,FIREW5,FIREW6,FIREW7,FIREW8,
+FIREW9,FIREW10,FIREW11,FIREW12,FIREW13,FIREW14,FIREW15,
+
+
+
+
+GUTS1,GUTS2,GUTS3,GUTS4,
+GUTS5,GUTS6,GUTS7,GUTS8,
+GUTS9,GUTS10,GUTS11,GUTS12,
+
+
+PARTICLE01,PARTICLE02,PARTICLE03,PARTICLE04,
+PARTICLE05,PARTICLE06,PARTICLE07,PARTICLE08,
+PARTICLE09,PARTICLE10,PARTICLE11,PARTICLE12,
+
+ORGAN01,ORGAN02,ORGAN03,ORGAN04,
+ORGAN05,ORGAN06,ORGAN07,ORGAN08,
+ORGAN09,ORGAN10,ORGAN11,ORGAN12,
+
+RIB01,RIB02,RIB03,RIB04,
+RIB05,RIB06,RIB07,RIB08,
+RIB09,RIB10,RIB11,RIB12,
+
+PINK01, PINK02, PINK03, PINK04,
+PINK05, PINK06, PINK07, PINK08,
+PINK09, PINK10, PINK11, PINK12,
+
+GIBHEAD01,GIBHEAD02,GIBHEAD03,GIBHEAD04,
+GIBHEAD05,GIBHEAD06,GIBHEAD07,GIBHEAD08,
+GIBHEAD09,GIBHEAD10,GIBHEAD11,GIBHEAD12,
+
+GARM01,GARM02,GARM03,GARM04,
+GARM05,GARM06,GARM07,GARM08,
+GARM09,GARM10,GARM11,GARM12,
+
+GLEG01,GLEG02,GLEG03,GLEG04,
+GLEG05,GLEG06,GLEG07,GLEG08,
+GLEG09,GLEG10,GLEG11,GLEG12,
+
+HUMERUS01, HUMERUS02, HUMERUS03, HUMERUS04,
+HUMERUS05, HUMERUS06, HUMERUS07, HUMERUS08,
+HUMERUS09, HUMERUS10, HUMERUS11, HUMERUS12,
+
+PELVIS01, PELVIS02, PELVIS03, PELVIS04,
+PELVIS05, PELVIS06, PELVIS07, PELVIS08,
+PELVIS09, PELVIS10, PELVIS11, PELVIS12,
+
+LIMB01, LIMB02, LIMB03, LIMB04,
+LIMB05, LIMB06, LIMB07, LIMB08,
+LIMB09, LIMB10, LIMB11, LIMB12,
+
+
+DEADHEAD,
+
+WALLGIB1,WALLGIB2,WALLGIB3,WALLGIB4,
+
+GIBEYE1,GIBEYE2,GIBEYE3,
+
+VAPORIZED1,VAPORIZED2,VAPORIZED3,VAPORIZED4,
+VAPORIZED5,VAPORIZED6,VAPORIZED7,VAPORIZED8,
+
+BIGSOUL,LITTLESOUL,
+COLLECTOR1,
+COLLECTOR3,
+COLLECTOR5,
+COLLECTOR7,
+COLLECTOR9,
+COLLECTOR11,
+COLLECTOR13,
+COLLECTOR15,
+
+
+ITEMSPAWN1,ITEMSPAWN2,ITEMSPAWN3,ITEMSPAWN4,
+ITEMSPAWN5,ITEMSPAWN6,ITEMSPAWN7,ITEMSPAWN8,
+
+DEADBLOOD1,DEADBLOOD2,DEADBLOOD3,DEADBLOOD4,
+DEADBLOOD5,DEADBLOOD6,DEADBLOOD7,
+
+
+FLASH1,FLASH2,FLASH3,FLASH4,
+FLASH5,FLASH6,FLASH7,FLASH8,
+
+
+SKELETON1,SKELETON2,SKELETON3,SKELETON4,
+SKELETON5,SKELETON6,SKELETON7,SKELETON8,
+
+SKELETON9,SKELETON10,SKELETON11,SKELETON12,
+SKELETON13,SKELETON14,SKELETON15,SKELETON16,
+
+SKELETON17,SKELETON18,SKELETON19,SKELETON20,
+SKELETON21,SKELETON22,SKELETON23,SKELETON24,
+
+SKELETON25,SKELETON26,SKELETON27,SKELETON28,
+SKELETON29,SKELETON30,SKELETON31,SKELETON32,
+
+SKELETON33,SKELETON34,SKELETON35,SKELETON36,
+SKELETON37,SKELETON38,SKELETON39,SKELETON40,
+
+SKELETON41,SKELETON42,SKELETON43,SKELETON44,
+SKELETON45,SKELETON46,SKELETON47,SKELETON48,
+
+
+SPR_PUSHCOLUMN1,SPR_PUSHCOLUMN1a,
+/*
+SPR_PUSHCOLUMN2,SPR_PUSHCOLUMN2a,
+SPR_PUSHCOLUMN3,SPR_PUSHCOLUMN3a,
+*/
+
+BLOODSPURT1,BLOODSPURT2,BLOODSPURT3,BLOODSPURT4,
+BLOODSPURT5,BLOODSPURT6,BLOODSPURT7,BLOODSPURT8,
+
+GUNSMOKE1,GUNSMOKE2,GUNSMOKE3,GUNSMOKE4,
+GUNSMOKE5,GUNSMOKE6,GUNSMOKE7,GUNSMOKE8,
+
+
+
+HITMETALWALL1,HITMETALWALL2,HITMETALWALL3,HITMETALWALL4,
+
+HITMETALACTOR1,HITMETALACTOR2,HITMETALACTOR3,HITMETALACTOR4,
+
+
+PLATFORM1,  PLATFORM2,  PLATFORM3,  PLATFORM4,  PLATFORM5,
+
+
+SPR_CROSSFIRE11, SPR_CROSSFIRE12,SPR_CROSSFIRE13, SPR_CROSSFIRE14,
+SPR_CROSSFIRE15, SPR_CROSSFIRE16,SPR_CROSSFIRE17, SPR_CROSSFIRE18,
+
+SPR_CROSSFIRE31, SPR_CROSSFIRE32,SPR_CROSSFIRE33, SPR_CROSSFIRE34,
+SPR_CROSSFIRE35, SPR_CROSSFIRE36,SPR_CROSSFIRE37, SPR_CROSSFIRE38,
+
+SPR_CREXP1,SPR_CREXP2,SPR_CREXP3,SPR_CREXP4,SPR_CREXP5,
+
+
+GODFIRE1,GODFIRE2,GODFIRE3,GODFIRE4,
+
+
+
+SPR_ENFORCER_GR1,SPR_ENFORCER_GR2,SPR_ENFORCER_GR3,SPR_ENFORCER_GR4,
+SPR_ENFORCER_GR5,SPR_ENFORCER_GR6,SPR_ENFORCER_GR7,SPR_ENFORCER_GR8,
+SPR_ENFORCER_GR9,SPR_ENFORCER_GR10,
+
+SPR_ENFORCER_FALL1,SPR_ENFORCER_FALL2,SPR_ENFORCER_FALL3,SPR_ENFORCER_FALL4,
+SPR_ENFORCER_FALL5,SPR_ENFORCER_FALL6,
+
+
+SPR_MINE1,SPR_MINE2,SPR_MINE3,SPR_MINE4,
+
+SPR_BJMISS11,SPR_BJMISS12,SPR_BJMISS13,SPR_BJMISS14,
+SPR_BJMISS15,SPR_BJMISS16,SPR_BJMISS17,SPR_BJMISS18,
+SPR_BJMISS19,SPR_BJMISS110,SPR_BJMISS111,SPR_BJMISS112,
+SPR_BJMISS113,SPR_BJMISS114,SPR_BJMISS115,SPR_BJMISS116,
+
+
+SPR_BSTAR1,SPR_BSTAR2,SPR_BSTAR3,SPR_BSTAR4,
+
+
+
+GODPOWERUP1,   GODPOWERUP2,   GODPOWERUP3, GODPOWERUP4,
+GODPOWERUP5,   GODPOWERUP6,   GODPOWERUP7, GODPOWERUP8,
+
+
+
+ELASTICPOWERUP1, ELASTICPOWERUP2, ELASTICPOWERUP3, ELASTICPOWERUP4,
+ELASTICPOWERUP5, ELASTICPOWERUP6, ELASTICPOWERUP7, ELASTICPOWERUP8,
+
+RANDOMPOWERUP1,  RANDOMPOWERUP2,  RANDOMPOWERUP3,  RANDOMPOWERUP4,
+RANDOMPOWERUP5,  RANDOMPOWERUP6,  RANDOMPOWERUP7,	RANDOMPOWERUP8,
+
+FLEETFEETPOWERUP1,  FLEETFEETPOWERUP2, FLEETFEETPOWERUP3, FLEETFEETPOWERUP4,
+FLEETFEETPOWERUP5,  FLEETFEETPOWERUP6, FLEETFEETPOWERUP7, FLEETFEETPOWERUP8,
+
+MUSHROOMPOWERUP1, MUSHROOMPOWERUP2, MUSHROOMPOWERUP3, MUSHROOMPOWERUP4,
+MUSHROOMPOWERUP5, MUSHROOMPOWERUP6,	MUSHROOMPOWERUP7, MUSHROOMPOWERUP8,
+
+
+ONEUP01,       ONEUP02,       ONEUP03,    ONEUP04,
+ONEUP05,       ONEUP06,       ONEUP07,		ONEUP08,
+
+
+LIFEITEMA01,   LIFEITEMA02,   LIFEITEMA03,   LIFEITEMA04,
+LIFEITEMA05,   LIFEITEMA06,   LIFEITEMA07,   LIFEITEMA08,
+
+LIFEITEMB01,   LIFEITEMB02,   LIFEITEMB03,   LIFEITEMB04,
+LIFEITEMB05,   LIFEITEMB06,   LIFEITEMB07,   LIFEITEMB08,
+
+LIFEITEMC01,   LIFEITEMC02,   LIFEITEMC03,   LIFEITEMC04,
+LIFEITEMC05,   LIFEITEMC06,   LIFEITEMC07,   LIFEITEMC08,
+LIFEITEMC09,   LIFEITEMC10,   LIFEITEMC11,   LIFEITEMC12,
+LIFEITEMC13,   LIFEITEMC14,   LIFEITEMC15,
+
+LIFEITEMD01,   LIFEITEMD02,   LIFEITEMD03,   LIFEITEMD04,
+LIFEITEMD05,   LIFEITEMD06,   LIFEITEMD07,   LIFEITEMD08,
+
+
+RUBBLE1,RUBBLE2,RUBBLE3,RUBBLE4,RUBBLE5,RUBBLE6,RUBBLE7,
+RUBBLE8,RUBBLE9,RUBBLE10,
+
+WOODFRAG1,WOODFRAG2,WOODFRAG3,WOODFRAG4,WOODFRAG5,WOODFRAG6,
+WOODFRAG7,WOODFRAG8,WOODFRAG9,WOODFRAG10,WOODFRAG11,WOODFRAG12,
+WOODFRAG13,WOODFRAG14,
+
+
+
+MISSMOKE1,MISSMOKE2,MISSMOKE3,MISSMOKE4,
+
+SPR62_ETOUCH1, SPR63_ETOUCH2,	SPR64_ETOUCH3,
+
+SPR73_GKEY1,   SPR74_GKEY2,   SPR75_GKEY3,   SPR76_GKEY4,
+SPR77_GKEY5,   SPR78_GKEY6,   SPR79_GKEY7,   SPR80_GKEY8,
+SPR81_GKEY9,   SPR82_GKEY10,  SPR83_GKEY11,  SPR84_GKEY12,
+SPR85_GKEY13,  SPR86_GKEY14,  SPR87_GKEY15,  SPR88_GKEY16,
+
+
+SPR6_GIBS1,    SPR7_GIBS2,	   SPR8_GIBS3,    SPR33_CBARREL,
+SPR34_TOUCH1,  SPR35_TOUCH2,  SPR36_TOUCH3,	SPR37_TOUCH4,
+SPR40_GARBAGE3,SPR41_SHIT,    BLUEVASE,   SPR54_HAY,
+BULLETHOLE,    ALTBULLETHO,
+STNPOLE1,      STNPOLE2,      STNPOLE3,      STNPOLE4,
+STNPOLE5,      STNPOLE6,      STNPOLE7,      STNPOLE8,
+
+
+HGRATE1,       HGRATE2,       HGRATE3,
+HGRATE4,
+
+SPR0_YLIGHT,   SPR1_RLIGHT,   SPR2_GLIGHT,
+SPR3_BLIGHT,	SPR4_CHAND,    SPR5_LAMPOFF, 	SPR5_LAMP,
+SPR9_MONKMEAL, SPR_ABRAZIEROFF, SPR_ABRAZIER2,
+SPR32_EXPLOS,  SPR38_GARBAGE1,SPR39_GARBAGE2,
+SPR42_GRATE,   SPR43_MSHARDS, SPR44_PEDESTAL,SPR45_ETABLE,
+SPR46_STOOL,   SPR50_TREE,    SPR51_PLANT,
+SPR55_IBARREL, FBASIN1,       FBASIN2,       FBASIN3,
+EBASIN,		   PORRIDGE1,     PORRIDGE2,     PORRIDGE3,
+PORRIDGE4,	   PORRIDGE5,     PORRIDGE6,		MONKCRYSTAL11,
+MONKCRYSTAL12, MONKCRYSTAL13, MONKCRYSTAL14,	MONKCRYSTAL15,
+MONKCRYSTAL16, MONKCRYSTAL21,
+MONKCRYSTAL22, MONKCRYSTAL23, MONKCRYSTAL24, MONKCRYSTAL25,
+MONKCRYSTAL26, MONKCRYSTAL27, TORCH1,
+TORCH2,        TORCH3,        TORCH4,		   TORCH5,
+TORCH6,        TORCH7,        TORCH8,		   TORCH9,
+TORCH10,       TORCH11,       TORCH12,		   TORCH13,
+TORCH14,       TORCH15,
+
+/*
+ATORCH2,       ATORCH3,
+ATORCH4,		   ATORCH5,       ATORCH6,       ATORCH7,
+ATORCH8,		   ATORCH9,       ATORCH10,      ATORCH11,
+ATORCH12,		ATORCH13,		ATORCH14,      ATORCH15,
+ATORCH16,
+*/
+
+FFLAME1,
+FFLAME2,       FFLAME3,       FFLAME4,		   FFLAME5,
+FFLAME6,       FFLAME7,       SPR_TWOPIST,   SPR_MP40,
+SPR_BAZOOKA,   SPR_FIREBOMB,	SPR_HEATSEEK,  SPR_DRUNK,
+SPR_FIREWALL,  SPR_KES,       SPR_SPLIT,
+
+
+
+GASMASKPOWERUP,
+BULLETPROOFPOWERUP, ASBESTOSPOWERUP,PREPIT,POSTPIT,
+
+
+CASSATT_SHOOT11,CASSATT_SHOOT12,CASSATT_SHOOT13,CASSATT_SHOOT14,
+CASSATT_SHOOT15,CASSATT_SHOOT16,CASSATT_SHOOT17,CASSATT_SHOOT18,
+
+CASSATT_SHOOT21,CASSATT_SHOOT22,CASSATT_SHOOT23,CASSATT_SHOOT24,
+CASSATT_SHOOT25,CASSATT_SHOOT26,CASSATT_SHOOT27,CASSATT_SHOOT28,
+
+
+
+CASSATTM_SHOOT11,CASSATTM_SHOOT12,CASSATTM_SHOOT13,CASSATTM_SHOOT14,
+CASSATTM_SHOOT15,CASSATTM_SHOOT16,CASSATTM_SHOOT17,CASSATTM_SHOOT18,
+
+CASSATTM_SHOOT21,CASSATTM_SHOOT22,CASSATTM_SHOOT23,CASSATTM_SHOOT24,
+CASSATTM_SHOOT25,CASSATTM_SHOOT26,CASSATTM_SHOOT27,CASSATTM_SHOOT28,
+
+
+
+CASSATT_S1,CASSATT_S2,CASSATT_S3,CASSATT_S4,
+CASSATT_S5,CASSATT_S6,CASSATT_S7,CASSATT_S8,
+
+CASSATT_W11,CASSATT_W12,CASSATT_W13,CASSATT_W14,
+CASSATT_W15,CASSATT_W16,CASSATT_W17,CASSATT_W18,
+
+CASSATT_W21,CASSATT_W22,CASSATT_W23,CASSATT_W24,
+CASSATT_W25,CASSATT_W26,CASSATT_W27,CASSATT_W28,
+
+CASSATT_W31,CASSATT_W32,CASSATT_W33,CASSATT_W34,
+CASSATT_W35,CASSATT_W36,CASSATT_W37,CASSATT_W38,
+
+CASSATT_W41,CASSATT_W42,CASSATT_W43,CASSATT_W44,
+CASSATT_W45,CASSATT_W46,CASSATT_W47,CASSATT_W48,
+
+
+CASSATT_VDIE1,CASSATT_VDIE2,CASSATT_VDIE3,CASSATT_VDIE4,CASSATT_VDIE5,
+CASSATT_VDIE6,
+CASSATT_VDEAD,
+
+CASSATT_DIE1,CASSATT_DIE2,CASSATT_DIE3,CASSATT_DIE4,CASSATT_DIE5,
+CASSATT_DIE6,
+CASSATT_DEAD,
+
+
+// DDOI - Wad ends here
+
+BARRETT_SHOOT11,BARRETT_SHOOT12,BARRETT_SHOOT13,BARRETT_SHOOT14,
+BARRETT_SHOOT15,BARRETT_SHOOT16,BARRETT_SHOOT17,BARRETT_SHOOT18,
+
+
+BARRETT_SHOOT21,BARRETT_SHOOT22,BARRETT_SHOOT23,BARRETT_SHOOT24,
+BARRETT_SHOOT25,BARRETT_SHOOT26,BARRETT_SHOOT27,BARRETT_SHOOT28,
+
+
+BARRETTM_SHOOT11,BARRETTM_SHOOT12,BARRETTM_SHOOT13,BARRETTM_SHOOT14,
+BARRETTM_SHOOT15,BARRETTM_SHOOT16,BARRETTM_SHOOT17,BARRETTM_SHOOT18,
+
+BARRETTM_SHOOT21,BARRETTM_SHOOT22,BARRETTM_SHOOT23,BARRETTM_SHOOT24,
+BARRETTM_SHOOT25,BARRETTM_SHOOT26,BARRETTM_SHOOT27,BARRETTM_SHOOT28,
+
+
+
+BARRETT_S1,BARRETT_S2,BARRETT_S3,BARRETT_S4,
+BARRETT_S5,BARRETT_S6,BARRETT_S7,BARRETT_S8,
+
+BARRETT_W11,BARRETT_W12,BARRETT_W13,BARRETT_W14,
+BARRETT_W15,BARRETT_W16,BARRETT_W17,BARRETT_W18,
+
+BARRETT_W21,BARRETT_W22,BARRETT_W23,BARRETT_W24,
+BARRETT_W25,BARRETT_W26,BARRETT_W27,BARRETT_W28,
+
+BARRETT_W31,BARRETT_W32,BARRETT_W33,BARRETT_W34,
+BARRETT_W35,BARRETT_W36,BARRETT_W37,BARRETT_W38,
+
+BARRETT_W41,BARRETT_W42,BARRETT_W43,BARRETT_W44,
+BARRETT_W45,BARRETT_W46,BARRETT_W47,BARRETT_W48,
+
+
+BARRETT_VDIE1,BARRETT_VDIE2,BARRETT_VDIE3,BARRETT_VDIE4,BARRETT_VDIE5,
+BARRETT_VDIE6,
+BARRETT_VDEAD,
+
+BARRETT_DIE1,BARRETT_DIE2,BARRETT_DIE3,BARRETT_DIE4,BARRETT_DIE5,
+BARRETT_DIE6,
+BARRETT_DEAD,
+
+
+
+WENDT_SHOOT11,WENDT_SHOOT12,WENDT_SHOOT13,WENDT_SHOOT14,
+WENDT_SHOOT15,WENDT_SHOOT16,WENDT_SHOOT17,WENDT_SHOOT18,
+
+WENDT_SHOOT21,WENDT_SHOOT22,WENDT_SHOOT23,WENDT_SHOOT24,
+WENDT_SHOOT25,WENDT_SHOOT26,WENDT_SHOOT27,WENDT_SHOOT28,
+
+
+
+WENDTM_SHOOT11,WENDTM_SHOOT12,WENDTM_SHOOT13,WENDTM_SHOOT14,
+WENDTM_SHOOT15,WENDTM_SHOOT16,WENDTM_SHOOT17,WENDTM_SHOOT18,
+
+WENDTM_SHOOT21,WENDTM_SHOOT22,WENDTM_SHOOT23,WENDTM_SHOOT24,
+WENDTM_SHOOT25,WENDTM_SHOOT26,WENDTM_SHOOT27,WENDTM_SHOOT28,
+
+
+
+WENDT_S1,WENDT_S2,WENDT_S3,WENDT_S4,
+WENDT_S5,WENDT_S6,WENDT_S7,WENDT_S8,
+
+WENDT_W11,WENDT_W12,WENDT_W13,WENDT_W14,
+WENDT_W15,WENDT_W16,WENDT_W17,WENDT_W18,
+
+WENDT_W21,WENDT_W22,WENDT_W23,WENDT_W24,
+WENDT_W25,WENDT_W26,WENDT_W27,WENDT_W28,
+
+WENDT_W31,WENDT_W32,WENDT_W33,WENDT_W34,
+WENDT_W35,WENDT_W36,WENDT_W37,WENDT_W38,
+
+WENDT_W41,WENDT_W42,WENDT_W43,WENDT_W44,
+WENDT_W45,WENDT_W46,WENDT_W47,WENDT_W48,
+
+
+WENDT_VDIE1,WENDT_VDIE2,WENDT_VDIE3,WENDT_VDIE4,WENDT_VDIE5,WENDT_VDIE6,
+WENDT_VDEAD,
+
+WENDT_DIE1,WENDT_DIE2,WENDT_DIE3,WENDT_DIE4,WENDT_DIE5,WENDT_DIE6,
+WENDT_DEAD,
+
+
+//======
+
+
+NI_SHOOT11,NI_SHOOT12,NI_SHOOT13,NI_SHOOT14,
+NI_SHOOT15,NI_SHOOT16,NI_SHOOT17,NI_SHOOT18,
+
+NI_SHOOT21,NI_SHOOT22,NI_SHOOT23,NI_SHOOT24,
+NI_SHOOT25,NI_SHOOT26,NI_SHOOT27,NI_SHOOT28,
+
+
+
+NIM_SHOOT11,NIM_SHOOT12,NIM_SHOOT13,NIM_SHOOT14,
+NIM_SHOOT15,NIM_SHOOT16,NIM_SHOOT17,NIM_SHOOT18,
+
+NIM_SHOOT21,NIM_SHOOT22,NIM_SHOOT23,NIM_SHOOT24,
+NIM_SHOOT25,NIM_SHOOT26,NIM_SHOOT27,NIM_SHOOT28,
+
+
+
+NI_S1,NI_S2,NI_S3,NI_S4,
+NI_S5,NI_S6,NI_S7,NI_S8,
+
+NI_W11,NI_W12,NI_W13,NI_W14,
+NI_W15,NI_W16,NI_W17,NI_W18,
+
+NI_W21,NI_W22,NI_W23,NI_W24,
+NI_W25,NI_W26,NI_W27,NI_W28,
+
+NI_W31,NI_W32,NI_W33,NI_W34,
+NI_W35,NI_W36,NI_W37,NI_W38,
+
+NI_W41,NI_W42,NI_W43,NI_W44,
+NI_W45,NI_W46,NI_W47,NI_W48,
+
+
+NI_VDIE1,NI_VDIE2,NI_VDIE3,NI_VDIE4,NI_VDIE5,NI_VDIE6,
+NI_VDEAD,
+
+NI_DIE1,NI_DIE2,NI_DIE3,NI_DIE4,NI_DIE5,NI_DIE6,
+NI_DEAD,
+
+
+
+
+IPF_SHOOT11,IPF_SHOOT12,IPF_SHOOT13,IPF_SHOOT14,
+IPF_SHOOT15,IPF_SHOOT16,IPF_SHOOT17,IPF_SHOOT18,
+
+IPF_SHOOT21,IPF_SHOOT22,IPF_SHOOT23,IPF_SHOOT24,
+IPF_SHOOT25,IPF_SHOOT26,IPF_SHOOT27,IPF_SHOOT28,
+
+
+IPFM_SHOOT11,IPFM_SHOOT12,IPFM_SHOOT13,IPFM_SHOOT14,
+IPFM_SHOOT15,IPFM_SHOOT16,IPFM_SHOOT17,IPFM_SHOOT18,
+
+IPFM_SHOOT21,IPFM_SHOOT22,IPFM_SHOOT23,IPFM_SHOOT24,
+IPFM_SHOOT25,IPFM_SHOOT26,IPFM_SHOOT27,IPFM_SHOOT28,
+
+
+
+IPF_S1,IPF_S2,IPF_S3,IPF_S4,
+IPF_S5,IPF_S6,IPF_S7,IPF_S8,
+
+IPF_W11,IPF_W12,IPF_W13,IPF_W14,
+IPF_W15,IPF_W16,IPF_W17,IPF_W18,
+
+IPF_W21,IPF_W22,IPF_W23,IPF_W24,
+IPF_W25,IPF_W26,IPF_W27,IPF_W28,
+
+IPF_W31,IPF_W32,IPF_W33,IPF_W34,
+IPF_W35,IPF_W36,IPF_W37,IPF_W38,
+
+IPF_W41,IPF_W42,IPF_W43,IPF_W44,
+IPF_W45,IPF_W46,IPF_W47,IPF_W48,
+
+
+IPF_VDIE1,IPF_VDIE2,IPF_VDIE3,IPF_VDIE4,IPF_VDIE5,IPF_VDIE6,
+IPF_VDEAD,
+
+IPF_DIE1,IPF_DIE2,IPF_DIE3,IPF_DIE4,IPF_DIE5,IPF_DIE6,
+IPF_DEAD,
+
+
+SERIALDOG_W11,SERIALDOG_W12,SERIALDOG_W13,SERIALDOG_W14,
+SERIALDOG_W15,SERIALDOG_W16,SERIALDOG_W17,SERIALDOG_W18,
+
+SERIALDOG_W21,SERIALDOG_W22,SERIALDOG_W23,SERIALDOG_W24,
+SERIALDOG_W25,SERIALDOG_W26,SERIALDOG_W27,SERIALDOG_W28,
+
+SERIALDOG_W31,SERIALDOG_W32,SERIALDOG_W33,SERIALDOG_W34,
+SERIALDOG_W35,SERIALDOG_W36,SERIALDOG_W37,SERIALDOG_W38,
+
+SERIALDOG_W41,SERIALDOG_W42,SERIALDOG_W43,SERIALDOG_W44,
+SERIALDOG_W45,SERIALDOG_W46,SERIALDOG_W47,SERIALDOG_W48,
+
+SERIALDOG_ATTACK1,SERIALDOG_ATTACK2,SERIALDOG_ATTACK3,SERIALDOG_ATTACK4,
+SERIALDOG_ATTACK5,SERIALDOG_ATTACK6,SERIALDOG_ATTACK7,SERIALDOG_ATTACK8,
+
+
+/***************   Lowguard 2 (Marianna)  *************************************/
+
+
+/*
+SPR_MARIANNA_SHOOT1,SPR_MARIANNA_SHOOT2,SPR_MARIANNA_SHOOT3,SPR_MARIANNA_SHOOT4,
+
+SPR_MARIANNA_S1,SPR_MARIANNA_S2,SPR_MARIANNA_S3,SPR_MARIANNA_S4,
+SPR_MARIANNA_S5,SPR_MARIANNA_S6,SPR_MARIANNA_S7,SPR_MARIANNA_S8,
+
+SPR_MARIANNA_W11,SPR_MARIANNA_W12,SPR_MARIANNA_W13,SPR_MARIANNA_W14,
+SPR_MARIANNA_W15,SPR_MARIANNA_W16,SPR_MARIANNA_W17,SPR_MARIANNA_W18,
+
+SPR_MARIANNA_W21,SPR_MARIANNA_W22,SPR_MARIANNA_W23,SPR_MARIANNA_W24,
+SPR_MARIANNA_W25,SPR_MARIANNA_W26,SPR_MARIANNA_W27,SPR_MARIANNA_W28,
+
+SPR_MARIANNA_W31,SPR_MARIANNA_W32,SPR_MARIANNA_W33,SPR_MARIANNA_W34,
+SPR_MARIANNA_W35,SPR_MARIANNA_W36,SPR_MARIANNA_W37,SPR_MARIANNA_W38,
+
+SPR_MARIANNA_W41,SPR_MARIANNA_W42,SPR_MARIANNA_W43,SPR_MARIANNA_W44,
+SPR_MARIANNA_W45,SPR_MARIANNA_W46,SPR_MARIANNA_W47,SPR_MARIANNA_W48,
+
+
+SPR_MARIANNA_PAIN1, SPR_MARIANNA_PAIN2, SPR_MARIANNA_DIE1, SPR_MARIANNA_DIE2,
+SPR_MARIANNA_DIE3, SPR_MARIANNA_DIE4, SPR_MARIANNA_DEAD,
+
+SPR_MARIANNA_WPAIN1, SPR_MARIANNA_WPAIN2, SPR_MARIANNA_WDIE1, SPR_MARIANNA_WDIE2,
+SPR_MARIANNA_WDIE3, SPR_MARIANNA_WDIE4, SPR_MARIANNA_WDEAD,
+
+
+SPR_SNMAR_DEAD, SPR_MARISE1, SPR_MARISE2, SPR_MARISE3, SPR_MARISE4,
+*/
+
+
+/****************** OBERPATROLLE (Nolan) ***********************************/
+
+
+SPR_OP_SHOOT1,SPR_OP_SHOOT2,SPR_OP_SHOOT3,SPR_OP_SHOOT4,
+
+SPR_OP_BOLOSHOOT1,SPR_OP_BOLOSHOOT2,SPR_OP_BOLOSHOOT3,SPR_OP_BOLOSHOOT4,
+SPR_OP_BOLOSHOOT5,
+
+SPR_OP_S1,SPR_OP_S2,SPR_OP_S3,SPR_OP_S4,
+SPR_OP_S5,SPR_OP_S6,SPR_OP_S7,SPR_OP_S8,
+
+SPR_OP_W11,SPR_OP_W12,SPR_OP_W13,SPR_OP_W14,
+SPR_OP_W15,SPR_OP_W16,SPR_OP_W17,SPR_OP_W18,
+
+SPR_OP_W21,SPR_OP_W22,SPR_OP_W23,SPR_OP_W24,
+SPR_OP_W25,SPR_OP_W26,SPR_OP_W27,SPR_OP_W28,
+
+SPR_OP_W31,SPR_OP_W32,SPR_OP_W33,SPR_OP_W34,
+SPR_OP_W35,SPR_OP_W36,SPR_OP_W37,SPR_OP_W38,
+
+SPR_OP_W41,SPR_OP_W42,SPR_OP_W43,SPR_OP_W44,
+SPR_OP_W45,SPR_OP_W46,SPR_OP_W47,SPR_OP_W48,
+
+
+SPR_OP_PAIN1,SPR_OP_PAIN2,
+SPR_OP_ALTDIE1,SPR_OP_ALTDIE2,SPR_OP_ALTDIE3,
+SPR_OP_ALTDIE4,SPR_OP_ALTDIE5,SPR_OP_ALTDEAD,
+
+SPR_OP_WPAIN1,SPR_OP_WPAIN2,
+SPR_OP_WALTDIE1,SPR_OP_WALTDIE2,SPR_OP_WALTDIE3,
+SPR_OP_WALTDIE4,SPR_OP_WALTDIE5,SPR_OP_WALTDEAD,
+
+SPR_OP_DIE1,SPR_OP_DIE2,SPR_OP_DIE3,
+SPR_OP_DIE4,SPR_OP_DIE5,SPR_OP_DIE6,
+SPR_OP_DEAD,
+
+
+
+
+
+/******************* Normal monk (Lee)**********************************/
+
+
+SPR_MONK_DRAIN1,SPR_MONK_DRAIN2,SPR_MONK_DRAIN3,SPR_MONK_DRAIN4,
+SPR_MONK_DRAIN5,SPR_MONK_DRAIN6,
+
+/*SPR_MONK_CAST1,SPR_MONK_CAST2,SPR_MONK_CAST3,SPR_MONK_CAST4,
+SPR_MONK_CAST5,SPR_MONK_CAST6,SPR_MONK_CAST7,SPR_MONK_CAST8,*/
+
+SPR_MONK_S1,SPR_MONK_S2,SPR_MONK_S3,SPR_MONK_S4,
+SPR_MONK_S5,SPR_MONK_S6,SPR_MONK_S7,SPR_MONK_S8,
+
+SPR_MONK_W11,SPR_MONK_W12,SPR_MONK_W13,SPR_MONK_W14,
+SPR_MONK_W15,SPR_MONK_W16,SPR_MONK_W17,SPR_MONK_W18,
+
+SPR_MONK_W21,SPR_MONK_W22,SPR_MONK_W23,SPR_MONK_W24,
+SPR_MONK_W25,SPR_MONK_W26,SPR_MONK_W27,SPR_MONK_W28,
+
+SPR_MONK_W31,SPR_MONK_W32,SPR_MONK_W33,SPR_MONK_W34,
+SPR_MONK_W35,SPR_MONK_W36,SPR_MONK_W37,SPR_MONK_W38,
+
+SPR_MONK_W41,SPR_MONK_W42,SPR_MONK_W43,SPR_MONK_W44,
+SPR_MONK_W45,SPR_MONK_W46,SPR_MONK_W47,SPR_MONK_W48,
+
+SPR_MONK_PAIN1,SPR_MONK_PAIN2,
+
+SPR_MONK_DIE1,SPR_MONK_DIE2,SPR_MONK_DIE3,SPR_MONK_DIE4,
+SPR_MONK_DEAD,
+
+/*SPR_MONK_USE11,SPR_MONK_USE12,SPR_MONK_USE13,SPR_MONK_USE14,
+SPR_MONK_USE15,SPR_MONK_USE16,SPR_MONK_USE17,SPR_MONK_USE18,
+
+SPR_MONK_USE21,SPR_MONK_USE22,SPR_MONK_USE23,SPR_MONK_USE24,
+SPR_MONK_USE25,SPR_MONK_USE26,SPR_MONK_USE27,SPR_MONK_USE28,
+*/
+
+
+/******************* Fire monk (Allen)**********************************/
+
+SPR_FIREMONK_CAST1,SPR_FIREMONK_CAST2,SPR_FIREMONK_CAST3,SPR_FIREMONK_CAST4,
+SPR_FIREMONK_CAST5,SPR_FIREMONK_CAST6,SPR_FIREMONK_CAST7,
+
+SPR_FIREMONK_S1,SPR_FIREMONK_S2,SPR_FIREMONK_S3,SPR_FIREMONK_S4,
+SPR_FIREMONK_S5,SPR_FIREMONK_S6,SPR_FIREMONK_S7,SPR_FIREMONK_S8,
+
+SPR_FIREMONK_W11,SPR_FIREMONK_W12,SPR_FIREMONK_W13,SPR_FIREMONK_W14,
+SPR_FIREMONK_W15,SPR_FIREMONK_W16,SPR_FIREMONK_W17,SPR_FIREMONK_W18,
+
+SPR_FIREMONK_W21,SPR_FIREMONK_W22,SPR_FIREMONK_W23,SPR_FIREMONK_W24,
+SPR_FIREMONK_W25,SPR_FIREMONK_W26,SPR_FIREMONK_W27,SPR_FIREMONK_W28,
+
+SPR_FIREMONK_W31,SPR_FIREMONK_W32,SPR_FIREMONK_W33,SPR_FIREMONK_W34,
+SPR_FIREMONK_W35,SPR_FIREMONK_W36,SPR_FIREMONK_W37,SPR_FIREMONK_W38,
+
+SPR_FIREMONK_W41,SPR_FIREMONK_W42,SPR_FIREMONK_W43,SPR_FIREMONK_W44,
+SPR_FIREMONK_W45,SPR_FIREMONK_W46,SPR_FIREMONK_W47,SPR_FIREMONK_W48,
+
+SPR_FIREMONK_PAIN1,SPR_FIREMONK_PAIN2,
+
+SPR_FIREMONK_DIE1,SPR_FIREMONK_DIE2,SPR_FIREMONK_DIE3,SPR_FIREMONK_DIE4,
+SPR_FIREMONK_DEAD1,SPR_FIREMONK_DEAD2,SPR_FIREMONK_DEAD3,SPR_FIREMONK_DEAD4,
+SPR_FIREMONK_DEAD5,SPR_FIREMONK_DEAD6,SPR_FIREMONK_DEAD7,
+
+
+
+/*
+SPR_ALLEN_USE11,SPR_ALLEN_USE12,SPR_ALLEN_USE13,SPR_ALLEN_USE14,
+SPR_ALLEN_USE15,SPR_ALLEN_USE16,SPR_ALLEN_USE17,SPR_ALLEN_USE18,
+
+SPR_ALLEN_USE21,SPR_ALLEN_USE22,SPR_ALLEN_USE23,SPR_ALLEN_USE24,
+SPR_ALLEN_USE25,SPR_ALLEN_USE26,SPR_ALLEN_USE27,SPR_ALLEN_USE28,
+*/
+BCRAFT01,BCRAFT02,BCRAFT03,BCRAFT04,
+BCRAFT05,BCRAFT06,BCRAFT07,BCRAFT08,
+BCRAFT09,BCRAFT10,BCRAFT11,BCRAFT12,
+BCRAFT13,BCRAFT14,BCRAFT15,BCRAFT16,
+
+
+/************************* GENERAL DARIAN *******************************/
+
+
+SPR_DARIAN_SHOOT1,SPR_DARIAN_SHOOT2,SPR_DARIAN_SHOOT3,SPR_DARIAN_SHOOT4,
+
+SPR_DARIAN_SINK1,SPR_DARIAN_SINK2,SPR_DARIAN_SINK3,SPR_DARIAN_SINK4,
+SPR_DARIAN_SINK5,SPR_DARIAN_SINK6,SPR_DARIAN_SINK7,SPR_DARIAN_SINK8,
+
+
+SPR_DARIAN_S1,SPR_DARIAN_S2,SPR_DARIAN_S3,SPR_DARIAN_S4,
+SPR_DARIAN_S5,SPR_DARIAN_S6,SPR_DARIAN_S7,SPR_DARIAN_S8,
+
+SPR_DARIAN_W11,SPR_DARIAN_W12,SPR_DARIAN_W13,SPR_DARIAN_W14,
+SPR_DARIAN_W15,SPR_DARIAN_W16,SPR_DARIAN_W17,SPR_DARIAN_W18,
+
+SPR_DARIAN_W21,SPR_DARIAN_W22,SPR_DARIAN_W23,SPR_DARIAN_W24,
+SPR_DARIAN_W25,SPR_DARIAN_W26,SPR_DARIAN_W27,SPR_DARIAN_W28,
+
+SPR_DARIAN_W31,SPR_DARIAN_W32,SPR_DARIAN_W33,SPR_DARIAN_W34,
+SPR_DARIAN_W35,SPR_DARIAN_W36,SPR_DARIAN_W37,SPR_DARIAN_W38,
+
+SPR_DARIAN_W41,SPR_DARIAN_W42,SPR_DARIAN_W43,SPR_DARIAN_W44,
+SPR_DARIAN_W45,SPR_DARIAN_W46,SPR_DARIAN_W47,SPR_DARIAN_W48,
+
+
+SPR_DARIAN_PAIN1, SPR_DARIAN_PAIN2, SPR_DARIAN_DIE1, SPR_DARIAN_DIE2,
+SPR_DARIAN_DIE3, SPR_DARIAN_DIE4,SPR_DARIAN_DIE5, SPR_DARIAN_DIE6,
+SPR_DARIAN_DIE7, SPR_DARIAN_DIE8,SPR_DARIAN_DIE9, SPR_DARIAN_DIE10,
+SPR_DARIAN_DEAD,
+
+SPR_DARIAN_WPAIN1, SPR_DARIAN_WPAIN2, SPR_WDARIAN_DIE1, SPR_WDARIAN_DIE2,
+SPR_DARIAN_WDIE3, SPR_DARIAN_WDIE4,SPR_WDARIAN_DIE5, SPR_WDARIAN_DIE6,
+SPR_DARIAN_WDIE7, SPR_DARIAN_WDIE8,SPR_WDARIAN_DIE9, SPR_WDARIAN_DIE10,
+SPR_DARIAN_WDEAD,
+
+
+SPR_DARIAN_USE11,SPR_DARIAN_USE12,SPR_DARIAN_USE13,SPR_DARIAN_USE14,
+SPR_DARIAN_USE15,SPR_DARIAN_USE16,SPR_DARIAN_USE17,SPR_DARIAN_USE18,
+
+SPR_DARIAN_USE21,SPR_DARIAN_USE22,SPR_DARIAN_USE23,SPR_DARIAN_USE24,
+SPR_DARIAN_USE25,SPR_DARIAN_USE26,SPR_DARIAN_USE27,SPR_DARIAN_USE28,
+
+
+
+/************************* HEINRICH KRIST ******************************/
+
+
+SPR_KRIST_S1,SPR_KRIST_S2,SPR_KRIST_S3,SPR_KRIST_S4,
+SPR_KRIST_S5,SPR_KRIST_S6,SPR_KRIST_S7,SPR_KRIST_S8,
+
+SPR_KRIST_LEFT1,SPR_KRIST_LEFT2,SPR_KRIST_LEFT3,SPR_KRIST_LEFT4,
+SPR_KRIST_LEFT5,SPR_KRIST_LEFT6,SPR_KRIST_LEFT7,SPR_KRIST_LEFT8,
+
+
+SPR_KRIST_SHOOT1,SPR_KRIST_SHOOT2,SPR_KRIST_SHOOT3,SPR_KRIST_SHOOT4,
+SPR_KRIST_SHOOT5,SPR_KRIST_SHOOT6,SPR_KRIST_SHOOT7,SPR_KRIST_SHOOT8,
+SPR_KRIST_SHOOT9,SPR_KRIST_SHOOT10,SPR_KRIST_SHOOT11,
+
+//SPR_KRIST_PAIN1,SPR_KRIST_PAIN2,SPR_KRIST_PAIN3,SPR_KRIST_PAIN4,
+//SPR_KRIST_PAIN5,SPR_KRIST_PAIN6,SPR_KRIST_PAIN7,SPR_KRIST_PAIN8,
+
+SPR_KRIST_DIE1,SPR_KRIST_DIE2,SPR_KRIST_DEAD1,SPR_KRIST_DEAD2,
+SPR_KRIST_DEAD3,SPR_KRIST_DEAD4,SPR_KRIST_DEAD5,SPR_KRIST_DEAD6,
+SPR_KRIST_DEAD7,SPR_KRIST_DEAD8,
+
+SPR_KRIST_RIGHT1,SPR_KRIST_RIGHT2,SPR_KRIST_RIGHT3,SPR_KRIST_RIGHT4,
+SPR_KRIST_RIGHT5,SPR_KRIST_RIGHT6,SPR_KRIST_RIGHT7,SPR_KRIST_RIGHT8,
+
+SPR_KRIST_FOR1,SPR_KRIST_FOR2,SPR_KRIST_FOR3,SPR_KRIST_FOR4,
+SPR_KRIST_FOR5,SPR_KRIST_FOR6,SPR_KRIST_FOR7,SPR_KRIST_FOR8,
+
+//SPR_KRIST_BACK1,SPR_KRIST_BACK2,SPR_KRIST_BACK3,SPR_KRIST_BACK4,
+//SPR_KRIST_BACK5,SPR_KRIST_BACK6,SPR_KRIST_BACK7,SPR_KRIST_BACK8,
+
+SPR_KRIST_MINERIGHT1,SPR_KRIST_MINERIGHT2,SPR_KRIST_MINERIGHT3,SPR_KRIST_MINERIGHT4,
+SPR_KRIST_MINERIGHT5,SPR_KRIST_MINERIGHT6,SPR_KRIST_MINERIGHT7,SPR_KRIST_MINERIGHT8,
+
+//SPR_KRIST_MINELEFT1,SPR_KRIST_MINELEFT2,SPR_KRIST_MINELEFT3,SPR_KRIST_MINELEFT4,
+//SPR_KRIST_MINELEFT5,SPR_KRIST_MINELEFT6,SPR_KRIST_MINELEFT7,SPR_KRIST_MINELEFT8,
+
+SPR_KRIST_DOPE1,SPR_KRIST_DOPE2,SPR_KRIST_DOPE3,
+
+
+/************************* NME  ******************************/
+
+NMEHEAD1_01,NMEHEAD1_02,NMEHEAD1_03,NMEHEAD1_04,
+NMEHEAD1_05,NMEHEAD1_06,NMEHEAD1_07,NMEHEAD1_08,
+NMEHEAD1_09,NMEHEAD1_10,NMEHEAD1_11,NMEHEAD1_12,
+NMEHEAD1_13,NMEHEAD1_14,NMEHEAD1_15,NMEHEAD1_16,
+
+NMEHEAD2_01,NMEHEAD2_02,NMEHEAD2_03,NMEHEAD2_04,
+NMEHEAD2_05,NMEHEAD2_06,NMEHEAD2_07,NMEHEAD2_08,
+NMEHEAD2_09,NMEHEAD2_10,NMEHEAD2_11,NMEHEAD2_12,
+NMEHEAD2_13,NMEHEAD2_14,NMEHEAD2_15,NMEHEAD2_16,
+
+NMEBODY1_01,NMEBODY1_02,NMEBODY1_03,NMEBODY1_04,
+NMEBODY1_05,NMEBODY1_06,NMEBODY1_07,NMEBODY1_08,
+NMEBODY1_09,NMEBODY1_10,NMEBODY1_11,NMEBODY1_12,
+NMEBODY1_13,NMEBODY1_14,NMEBODY1_15,NMEBODY1_16,
+
+NMEBODY2_01,NMEBODY2_02,NMEBODY2_03,NMEBODY2_04,
+NMEBODY2_05,NMEBODY2_06,NMEBODY2_07,NMEBODY2_08,
+NMEBODY2_09,NMEBODY2_10,NMEBODY2_11,NMEBODY2_12,
+NMEBODY2_13,NMEBODY2_14,NMEBODY2_15,NMEBODY2_16,
+
+NMEBODY3_01,NMEBODY3_02,NMEBODY3_03,NMEBODY3_04,
+NMEBODY3_05,NMEBODY3_06,NMEBODY3_07,NMEBODY3_08,
+NMEBODY3_09,NMEBODY3_10,NMEBODY3_11,NMEBODY3_12,
+NMEBODY3_13,NMEBODY3_14,NMEBODY3_15,NMEBODY3_16,
+
+NMEBODY4_01,NMEBODY4_02,NMEBODY4_03,NMEBODY4_04,
+NMEBODY4_05,NMEBODY4_06,NMEBODY4_07,NMEBODY4_08,
+NMEBODY4_09,NMEBODY4_10,NMEBODY4_11,NMEBODY4_12,
+NMEBODY4_13,NMEBODY4_14,NMEBODY4_15,NMEBODY4_16,
+
+NMEWHEEL1_01,NMEWHEEL1_02,NMEWHEEL1_03,NMEWHEEL1_04,
+NMEWHEEL1_05,NMEWHEEL1_06,NMEWHEEL1_07,NMEWHEEL1_08,
+NMEWHEEL1_09,NMEWHEEL1_10,NMEWHEEL1_11,NMEWHEEL1_12,
+NMEWHEEL1_13,NMEWHEEL1_14,NMEWHEEL1_15,NMEWHEEL1_16,
+
+NMEWHEEL2_01,NMEWHEEL2_02,NMEWHEEL2_03,NMEWHEEL2_04,
+NMEWHEEL2_05,NMEWHEEL2_06,NMEWHEEL2_07,NMEWHEEL2_08,
+NMEWHEEL2_09,NMEWHEEL2_10,NMEWHEEL2_11,NMEWHEEL2_12,
+NMEWHEEL2_13,NMEWHEEL2_14,NMEWHEEL2_15,NMEWHEEL2_16,
+
+NMEWHEEL3_01,NMEWHEEL3_02,NMEWHEEL3_03,NMEWHEEL3_04,
+NMEWHEEL3_05,NMEWHEEL3_06,NMEWHEEL3_07,NMEWHEEL3_08,
+NMEWHEEL3_09,NMEWHEEL3_10,NMEWHEEL3_11,NMEWHEEL3_12,
+NMEWHEEL3_13,NMEWHEEL3_14,NMEWHEEL3_15,NMEWHEEL3_16,
+
+NMEWHEEL4_01,NMEWHEEL4_02,NMEWHEEL4_03,NMEWHEEL4_04,
+NMEWHEEL4_05,NMEWHEEL4_06,NMEWHEEL4_07,NMEWHEEL4_08,
+NMEWHEEL4_09,NMEWHEEL4_10,NMEWHEEL4_11,NMEWHEEL4_12,
+NMEWHEEL4_13,NMEWHEEL4_14,NMEWHEEL4_15,NMEWHEEL4_16,
+
+NMEWHEEL5_01,NMEWHEEL5_02,NMEWHEEL5_03,NMEWHEEL5_04,
+NMEWHEEL5_05,NMEWHEEL5_06,NMEWHEEL5_07,NMEWHEEL5_08,
+NMEWHEEL5_09,NMEWHEEL5_10,NMEWHEEL5_11,NMEWHEEL5_12,
+NMEWHEEL5_13,NMEWHEEL5_14,NMEWHEEL5_15,NMEWHEEL5_16,
+
+NMEROCKET_01,NMEROCKET_02,NMEROCKET_03,NMEROCKET_04,
+NMEROCKET_05,NMEROCKET_06,NMEROCKET_07,NMEROCKET_08,
+NMEROCKET_09,NMEROCKET_10,NMEROCKET_11,NMEROCKET_12,
+NMEROCKET_13,NMEROCKET_14,NMEROCKET_15,NMEROCKET_16,
+
+NMEROCKET2_01,NMEROCKET2_02,NMEROCKET2_03,NMEROCKET2_04,
+NMEROCKET2_05,NMEROCKET2_06,NMEROCKET2_07,NMEROCKET2_08,
+NMEROCKET2_09,NMEROCKET2_10,NMEROCKET2_11,NMEROCKET2_12,
+NMEROCKET2_13,NMEROCKET2_14,NMEROCKET2_15,NMEROCKET2_16,
+
+NMEMINIBALL_01,NMEMINIBALL_02,NMEMINIBALL_03,NMEMINIBALL_04,
+NMESAUCER_01,NMESAUCER_02,NMESAUCER_03,NMESAUCER_04,
+
+
+/************************** TOM ****************************************/
+
+  TOMS1,TOMS2,TOMS3,TOMS4,TOMS5,TOMS6,TOMS7,TOMS8,
+
+  TOMFLY11,TOMFLY12,TOMFLY13,TOMFLY14,
+  TOMFLY15,TOMFLY16,TOMFLY17,TOMFLY18,
+
+  TOMFLY21,TOMFLY22,TOMFLY23,TOMFLY24,
+  TOMFLY25,TOMFLY26,TOMFLY27,TOMFLY28,
+
+  TOMLG1,TOMLG2,TOMLG3,TOMLG4,
+  TOMLG5,TOMLG6,TOMLG7,TOMLG8,
+
+  TOMLG9,TOMLG10,TOMLG11,
+
+  TOMFS1,TOMFS2,TOMFS3,TOMFS4,
+  TOMFS5,TOMFS6,
+
+  TOMBR1,TOMBR2,TOMBR3,TOMBR4,
+  TOMBR5,TOMBR6,TOMBR7,TOMBR8,
+
+  TOMHEAD1,TOMHEAD2,TOMHEAD3,TOMHEAD4,
+  TOMHEAD5,TOMHEAD6,TOMHEAD7,TOMHEAD8,
+
+  TPREPARE ,
+  THDIE1  ,
+  THDIE2  ,
+  TAWAKEN1,TAWAKEN2,TAWAKEN3,TAWAKEN4,
+  TAWAKEN5,
+
+  THBALL1 ,THBALL2 ,THBALL3 ,THBALL4 ,
+  THBALL5 ,THBALL6 ,THBALL7 ,THBALL8 ,
+  THBALL9 ,
+
+  TSPHERE1,TSPHERE2,TSPHERE3,TSPHERE4,
+  TSPHERE5,TSPHERE6,TSPHERE7,TSPHERE8,
+  TSPHERE9,TSPHERE10,
+
+  TBBALL1 ,TBBALL2 ,TBBALL3 ,TBBALL4 ,
+  TBBALL5 ,TBBALL6 ,TBBALL7 ,TBBALL8 ,
+  TBBALL9 ,
+
+  TSCAREB1,TSCAREB2,TSCAREB3,TSCAREB4,
+  TSCAREB5,
+
+  TOMDIE1 ,TOMDIE2 ,TOMDIE3 ,TOMDIE4 ,
+  TOMDIE5 ,TOMDIE6 ,TOMDIE7 ,TOMDIE8 ,
+
+  TOMRH1  ,TOMRH2  ,TOMRH3  ,TOMRH4  ,
+  TOMRH5  ,TOMRH6  ,TOMRH7  ,TOMRH8  ,
+
+  TOHRH1  ,TOHRH2  ,TOHRH3  ,TOHRH4  ,
+  TOHRH5  ,TOHRH6  ,TOHRH7  ,TOHRH8  ,
+
+
+
+
+SPEARDOWN1,SPEARDOWN2,SPEARDOWN3,SPEARDOWN4,
+SPEARDOWN5,SPEARDOWN6,SPEARDOWN7,SPEARDOWN8,
+SPEARDOWN9,SPEARDOWN10,SPEARDOWN11,SPEARDOWN12,
+SPEARDOWN13,SPEARDOWN14,SPEARDOWN15,SPEARDOWN16,
+
+
+DBLADE1,DBLADE2,DBLADE3,DBLADE4,
+DBLADE5,DBLADE6,DBLADE7,DBLADE8,
+DBLADE9,//DBLADE10,DBLADE11,DBLADE12,
+//DBLADE13,DBLADE14,DBLADE15,DBLADE16,
+
+FIREJETDOWN1,FIREJETDOWN2,FIREJETDOWN3,FIREJETDOWN4,
+FIREJETDOWN5,FIREJETDOWN6,FIREJETDOWN7,FIREJETDOWN8,
+FIREJETDOWN9,FIREJETDOWN10,FIREJETDOWN11,FIREJETDOWN12,
+FIREJETDOWN13,FIREJETDOWN14,FIREJETDOWN15,FIREJETDOWN16,
+FIREJETDOWN17,FIREJETDOWN18,FIREJETDOWN19,FIREJETDOWN20,
+FIREJETDOWN21,FIREJETDOWN22,FIREJETDOWN23,
+
+
+CRUSHUP1,CRUSHUP2,CRUSHUP3,CRUSHUP4,
+CRUSHUP5,CRUSHUP6,CRUSHUP7,CRUSHUP8,
+
+
+
+SPINUBLADE_01,SPINUBLADE_02,SPINUBLADE_03,SPINUBLADE_04,
+SPINUBLADE_05,SPINUBLADE_06,SPINUBLADE_07,SPINUBLADE_08,
+
+SPINUBLADE_09,SPINUBLADE_10,SPINUBLADE_11,SPINUBLADE_12,
+SPINUBLADE_13,SPINUBLADE_14,SPINUBLADE_15,SPINUBLADE_16,
+
+
+
+
+SPINDBLADE_01,SPINDBLADE_02,SPINDBLADE_03,SPINDBLADE_04,
+SPINDBLADE_05,SPINDBLADE_06,SPINDBLADE_07,SPINDBLADE_08,
+
+SPINDBLADE_09,SPINDBLADE_10,SPINDBLADE_11,SPINDBLADE_12,
+SPINDBLADE_13,SPINDBLADE_14,SPINDBLADE_15,SPINDBLADE_16,
+
+
+
+DIP11,DIP21,DIP31,
+TOMLARVA1, TOMLARVA2, TOMLARVA3, TOMLARVA4,
+
+SCOTHEAD1,SCOTHEAD2,SCOTHEAD3,SCOTHEAD4,
+SCOTHEAD5,SCOTHEAD6,SCOTHEAD7,
+
+KNIFE_STATUE1,KNIFE_STATUE2,KNIFE_STATUE3,KNIFE_STATUE4,
+KNIFE_STATUE5,KNIFE_STATUE6,KNIFE_STATUE7,KNIFE_STATUE8,
+
+EMPTY_STATUE1,EMPTY_STATUE2,EMPTY_STATUE3,EMPTY_STATUE4,
+EMPTY_STATUE5,EMPTY_STATUE6,EMPTY_STATUE7,EMPTY_STATUE8,
+
+
+BAT1,BAT2,BAT3,BAT4,
+BAT5,BAT6,BAT7,BAT8,
+BAT9,BAT10,BAT11,BAT12,
+BAT13,BAT14,BAT15,BAT16,
+
+DOGPOWERUP1,   DOGPOWERUP2,   DOGPOWERUP3, DOGPOWERUP4,
+DOGPOWERUP5,   DOGPOWERUP6,   DOGPOWERUP7, DOGPOWERUP8,
+
+
+THREEUP01,     THREEUP02,     THREEUP03,	THREEUP04,
+THREEUP05,     THREEUP06,     THREEUP07,	THREEUP08,
+
+
+
+BOULDER11,BOULDER21,BOULDER31,BOULDER41,
+
+BDROP1,BDROP2,BDROP3,BDROP4,BDROP5,BDROP6,BDROP7,BDROP8,BDROP9,
+BDROP10,BDROP11,
+
+BSINK1,BSINK2,BSINK3,BSINK4,BSINK5,BSINK6,BSINK7,BSINK8,BSINK9,
+
+
+GUNRISE11,GUNRISE12,GUNRISE13,GUNRISE14,
+GUNRISE15,GUNRISE16,GUNRISE17,GUNRISE18,
+
+GUNRISE21,GUNRISE22,GUNRISE23,GUNRISE24,
+GUNRISE25,GUNRISE26,GUNRISE27,GUNRISE28,
+
+GUNRISE31,GUNRISE32,GUNRISE33,GUNRISE34,
+GUNRISE35,GUNRISE36,GUNRISE37,GUNRISE38,
+
+GUNRISE41,GUNRISE42,GUNRISE43,GUNRISE44,
+GUNRISE45,GUNRISE46,GUNRISE47,GUNRISE48,
+
+GUNRISE51,GUNRISE52,GUNRISE53,GUNRISE54,
+GUNRISE55,GUNRISE56,GUNRISE57,GUNRISE58,
+
+GUNFIRE1,GUNFIRE2,GUNFIRE3,GUNFIRE4,
+GUNFIRE5,GUNFIRE6,GUNFIRE7,GUNFIRE8,
+
+GUNDEAD1,GUNDEAD2,
+
+
+FOURWAY01,FOURWAY02,FOURWAY03,FOURWAY04,
+FOURWAY05,FOURWAY06,FOURWAY07,FOURWAY08,
+FOURWAYFIRE01,FOURWAYFIRE02,FOURWAYFIRE03,FOURWAYFIRE04,
+FOURWAYFIRE05,FOURWAYFIRE06,FOURWAYFIRE07,FOURWAYFIRE08,
+
+
+
+
+TOMLIGHTNING1,TOMLIGHTNING2,TOMLIGHTNING3,TOMLIGHTNING4,
+TOMLIGHTNING5,TOMLIGHTNING6,TOMLIGHTNING7,TOMLIGHTNING8,
+
+TOMSPHERE1,TOMSPHERE2,TOMSPHERE3,TOMSPHERE4,
+
+TOMHANDBALL1,TOMHANDBALL2,
+
+TOMFACEBALL1,TOMFACEBALL2,
+
+TOMFLOORSPARK1,TOMFLOORSPARK2,TOMFLOORSPARK3,TOMFLOORSPARK4,
+
+
+TOMSPIT1,TOMSPIT2,TOMSPIT3,TOMSPIT4,
+
+SPITHIT1,SPITHIT2,SPITHIT3,SPITHIT4,
+
+
+
+MONKFIRE1,MONKFIRE2,MONKFIRE3,MONKFIRE4,
+
+
+BATBLAST1,BATBLAST2,BATBLAST3,BATBLAST4,
+
+KESSPHERE1,KESSPHERE2,KESSPHERE3,KESSPHERE4,
+KESSPHERE5,KESSPHERE6,KESSPHERE7,KESSPHERE8,
+
+SPR_BOLO1,SPR_BOLO2,SPR_BOLO3,SPR_BOLO4,
+
+//MED
+DOPE1,DOPE2,DOPE3,DOPE4,DOPE5,DOPE6,DOPE7,DOPE8,
+//CRUSHUP9,CRUSHUP10,CRUSHUP11,CRUSHUP12,
+//CRUSHUP13,CRUSHUP14,CRUSHUP15,CRUSHUP16,
+
+
+/*****************  Highguard 2 (Steve H.)  ***************************************/
+
+
+SPR_HIGHGRD2_SHOOT1,SPR_HIGHGRD2_SHOOT2,SPR_HIGHGRD2_SHOOT3,SPR_HIGHGRD2_SHOOT4,
+
+
+SPR_HIGHGRD2_S1,SPR_HIGHGRD2_S2,SPR_HIGHGRD2_S3,SPR_HIGHGRD2_S4,
+SPR_HIGHGRD2_S5,SPR_HIGHGRD2_S6,SPR_HIGHGRD2_S7,SPR_HIGHGRD2_S8,
+
+SPR_HIGHGRD2_W11,SPR_HIGHGRD2_W12,SPR_HIGHGRD2_W13,SPR_HIGHGRD2_W14,
+SPR_HIGHGRD2_W15,SPR_HIGHGRD2_W16,SPR_HIGHGRD2_W17,SPR_HIGHGRD2_W18,
+
+SPR_HIGHGRD2_W21,SPR_HIGHGRD2_W22,SPR_HIGHGRD2_W23,SPR_HIGHGRD2_W24,
+SPR_HIGHGRD2_W25,SPR_HIGHGRD2_W26,SPR_HIGHGRD2_W27,SPR_HIGHGRD2_W28,
+
+SPR_HIGHGRD2_W31,SPR_HIGHGRD2_W32,SPR_HIGHGRD2_W33,SPR_HIGHGRD2_W34,
+SPR_HIGHGRD2_W35,SPR_HIGHGRD2_W36,SPR_HIGHGRD2_W37,SPR_HIGHGRD2_W38,
+
+SPR_HIGHGRD2_W41,SPR_HIGHGRD2_W42,SPR_HIGHGRD2_W43,SPR_HIGHGRD2_W44,
+SPR_HIGHGRD2_W45,SPR_HIGHGRD2_W46,SPR_HIGHGRD2_W47,SPR_HIGHGRD2_W48,
+
+
+SPR_HIGHGRD2_PAIN1,SPR_HIGHGRD2_PAIN2,
+SPR_HIGHGRD2_DIE1,SPR_HIGHGRD2_DIE2,SPR_HIGHGRD2_DIE3,SPR_HIGHGRD2_DIE4,
+SPR_HIGHGRD2_DIE5,SPR_HIGHGRD2_DEAD,
+
+SPR_HIGHGRD2_WPAIN1,SPR_HIGHGRD2_WPAIN2,
+SPR_HIGHGRD2_WDIE1,SPR_HIGHGRD2_WDIE2,SPR_HIGHGRD2_WDIE3,SPR_HIGHGRD2_WDIE4,
+SPR_HIGHGRD2_WDIE5,SPR_HIGHGRD2_WDEAD,
+
+/*
+SPR_HIGHGRD2_USE11,SPR_HIGHGRD2_USE12,SPR_HIGHGRD2_USE13,SPR_HIGHGRD2_USE14,
+SPR_HIGHGRD2_USE15,SPR_HIGHGRD2_USE16,SPR_HIGHGRD2_USE17,SPR_HIGHGRD2_USE18,
+
+SPR_HIGHGRD2_USE21,SPR_HIGHGRD2_USE22,SPR_HIGHGRD2_USE23,SPR_HIGHGRD2_USE24,
+SPR_HIGHGRD2_USE25,SPR_HIGHGRD2_USE26,SPR_HIGHGRD2_USE27,SPR_HIGHGRD2_USE28,
+*/
+
+
+/****************** Alt. Overpatrol (Pat) ***********************************/
+
+SPR_PAT_SHOOT1,SPR_PAT_SHOOT2,SPR_PAT_SHOOT3,SPR_PAT_SHOOT4,
+
+SPR_PAT_BOLOSHOOT1,SPR_PAT_BOLOSHOOT2,SPR_PAT_BOLOSHOOT3,SPR_PAT_BOLOSHOOT4,
+SPR_PAT_BOLOSHOOT5,
+
+SPR_PAT_S1,SPR_PAT_S2,SPR_PAT_S3,SPR_PAT_S4,
+SPR_PAT_S5,SPR_PAT_S6,SPR_PAT_S7,SPR_PAT_S8,
+
+SPR_PAT_W11,SPR_PAT_W12,SPR_PAT_W13,SPR_PAT_W14,
+SPR_PAT_W15,SPR_PAT_W16,SPR_PAT_W17,SPR_PAT_W18,
+
+SPR_PAT_W21,SPR_PAT_W22,SPR_PAT_W23,SPR_PAT_W24,
+SPR_PAT_W25,SPR_PAT_W26,SPR_PAT_W27,SPR_PAT_W28,
+
+SPR_PAT_W31,SPR_PAT_W32,SPR_PAT_W33,SPR_PAT_W34,
+SPR_PAT_W35,SPR_PAT_W36,SPR_PAT_W37,SPR_PAT_W38,
+
+SPR_PAT_W41,SPR_PAT_W42,SPR_PAT_W43,SPR_PAT_W44,
+SPR_PAT_W45,SPR_PAT_W46,SPR_PAT_W47,SPR_PAT_W48,
+
+
+SPR_PAT_PAIN1,SPR_PAT_PAIN2,
+SPR_PAT_ALTDIE1,SPR_PAT_ALTDIE2,SPR_PAT_ALTDIE3,
+SPR_PAT_ALTDIE4,SPR_PAT_ALTDIE5,SPR_PAT_ALTDEAD,
+
+SPR_PAT_WPAIN1,SPR_PAT_WPAIN2,
+SPR_PAT_WALTDIE1,SPR_PAT_WALTDIE2,SPR_PAT_WALTDIE3,
+SPR_PAT_WALTDIE4,SPR_PAT_WALTDIE5,SPR_PAT_WALTDEAD,
+
+SPR_PAT_DIE1,SPR_PAT_DIE2,SPR_PAT_DIE3,
+SPR_PAT_DIE4,SPR_PAT_DIE5,SPR_PAT_DIE6,
+SPR_PAT_DEAD,
+
+
+/******************** Alt. Lightning Guard (Ann) **********************************/
+
+
+SPR_ANN_SHOOT1,SPR_ANN_SHOOT2,SPR_ANN_SHOOT3,SPR_ANN_SHOOT4,
+SPR_ANN_KSHOOT1,SPR_ANN_KSHOOT2,SPR_ANN_KSHOOT3,
+
+
+SPR_ANN_S1,SPR_ANN_S2,SPR_ANN_S3,SPR_ANN_S4,
+SPR_ANN_S5,SPR_ANN_S6,SPR_ANN_S7,SPR_ANN_S8,
+
+SPR_ANN_W11,SPR_ANN_W12,SPR_ANN_W13,SPR_ANN_W14,
+SPR_ANN_W15,SPR_ANN_W16,SPR_ANN_W17,SPR_ANN_W18,
+
+SPR_ANN_W21,SPR_ANN_W22,SPR_ANN_W23,SPR_ANN_W24,
+SPR_ANN_W25,SPR_ANN_W26,SPR_ANN_W27,SPR_ANN_W28,
+
+SPR_ANN_W31,SPR_ANN_W32,SPR_ANN_W33,SPR_ANN_W34,
+SPR_ANN_W35,SPR_ANN_W36,SPR_ANN_W37,SPR_ANN_W38,
+
+SPR_ANN_W41,SPR_ANN_W42,SPR_ANN_W43,SPR_ANN_W44,
+SPR_ANN_W45,SPR_ANN_W46,SPR_ANN_W47,SPR_ANN_W48,
+
+
+SPR_ANN_PAIN1,SPR_ANN_PAIN2,
+SPR_ANN_DIE1,SPR_ANN_DIE2,SPR_ANN_DIE3,
+SPR_ANN_DIE4,SPR_ANN_DEAD1,SPR_ANN_DEAD2,SPR_ANN_DEAD3,
+
+SPR_ANN_WPAIN1,SPR_ANN_WPAIN2,
+SPR_ANN_WDIE1,SPR_ANN_WDIE2,SPR_ANN_WDIE3,
+SPR_ANN_WDIE4,SPR_ANN_WDEAD1,SPR_ANN_WDEAD2,SPR_ANN_WDEAD3,
+
+SPR_ANN_RROLL1,SPR_ANN_RROLL2,SPR_ANN_RROLL3,SPR_ANN_RROLL4,
+SPR_ANN_RROLL5,SPR_ANN_RROLL6,
+
+SPR_ANN_LROLL1,SPR_ANN_LROLL2,SPR_ANN_LROLL3,SPR_ANN_LROLL4,
+SPR_ANN_LROLL5,SPR_ANN_LROLL6,
+
+
+/********************** Alt. Blitzguard (William) **********************************/
+
+
+SPR_WILLIAM_SHOOT1,SPR_WILLIAM_SHOOT2,SPR_WILLIAM_SHOOT3,SPR_WILLIAM_SHOOT4,
+
+SPR_WILLIAM_S1,SPR_WILLIAM_S2,SPR_WILLIAM_S3,SPR_WILLIAM_S4,
+SPR_WILLIAM_S5,SPR_WILLIAM_S6,SPR_WILLIAM_S7,SPR_WILLIAM_S8,
+
+SPR_WILLIAM_W11,SPR_WILLIAM_W12,SPR_WILLIAM_W13,SPR_WILLIAM_W14,
+SPR_WILLIAM_W15,SPR_WILLIAM_W16,SPR_WILLIAM_W17,SPR_WILLIAM_W18,
+
+SPR_WILLIAM_W21,SPR_WILLIAM_W22,SPR_WILLIAM_W23,SPR_WILLIAM_W24,
+SPR_WILLIAM_W25,SPR_WILLIAM_W26,SPR_WILLIAM_W27,SPR_WILLIAM_W28,
+
+SPR_WILLIAM_W31,SPR_WILLIAM_W32,SPR_WILLIAM_W33,SPR_WILLIAM_W34,
+SPR_WILLIAM_W35,SPR_WILLIAM_W36,SPR_WILLIAM_W37,SPR_WILLIAM_W38,
+
+SPR_WILLIAM_W41,SPR_WILLIAM_W42,SPR_WILLIAM_W43,SPR_WILLIAM_W44,
+SPR_WILLIAM_W45,SPR_WILLIAM_W46,SPR_WILLIAM_W47,SPR_WILLIAM_W48,
+
+
+SPR_WILLIAM_PAIN1, SPR_WILLIAM_PAIN2,SPR_WILLIAM_DIE1,SPR_WILLIAM_DIE2,
+SPR_WILLIAM_DIE3,SPR_WILLIAM_DIE4,SPR_WILLIAM_DEAD1, SPR_WILLIAM_DEAD2,
+
+SPR_WILLIAM_WPAIN1, SPR_WILLIAM_WPAIN2,SPR_WILLIAM_WDIE1,SPR_WILLIAM_WDIE2,
+SPR_WILLIAM_WDIE3,SPR_WILLIAM_WDIE4,SPR_WILLIAM_WDEAD1, SPR_WILLIAM_WDEAD2,
+
+SPR_WILLIAM_RISE1, SPR_WILLIAM_RISE2, SPR_WILLIAM_RISE3, SPR_WILLIAM_RISE4,
+
+SPR_WILLIAM_USE11,SPR_WILLIAM_USE12,SPR_WILLIAM_USE13,SPR_WILLIAM_USE14,
+SPR_WILLIAM_USE15,SPR_WILLIAM_USE16,SPR_WILLIAM_USE17,SPR_WILLIAM_USE18,
+
+SPR_WILLIAM_USE21,SPR_WILLIAM_USE22,SPR_WILLIAM_USE23,SPR_WILLIAM_USE24,
+SPR_WILLIAM_USE25,SPR_WILLIAM_USE26,SPR_WILLIAM_USE27,SPR_WILLIAM_USE28,
+
+/******************* Fire monk (Mark)**********************************/
+
+
+SPR_MARK_CAST1,SPR_MARK_CAST2,SPR_MARK_CAST3,SPR_MARK_CAST4,
+SPR_MARK_CAST5,SPR_MARK_CAST6,SPR_MARK_CAST7,
+
+SPR_MARK_S1,SPR_MARK_S2,SPR_MARK_S3,SPR_MARK_S4,
+SPR_MARK_S5,SPR_MARK_S6,SPR_MARK_S7,SPR_MARK_S8,
+
+SPR_MARK_W11,SPR_MARK_W12,SPR_MARK_W13,SPR_MARK_W14,
+SPR_MARK_W15,SPR_MARK_W16,SPR_MARK_W17,SPR_MARK_W18,
+
+SPR_MARK_W21,SPR_MARK_W22,SPR_MARK_W23,SPR_MARK_W24,
+SPR_MARK_W25,SPR_MARK_W26,SPR_MARK_W27,SPR_MARK_W28,
+
+SPR_MARK_W31,SPR_MARK_W32,SPR_MARK_W33,SPR_MARK_W34,
+SPR_MARK_W35,SPR_MARK_W36,SPR_MARK_W37,SPR_MARK_W38,
+
+SPR_MARK_W41,SPR_MARK_W42,SPR_MARK_W43,SPR_MARK_W44,
+SPR_MARK_W45,SPR_MARK_W46,SPR_MARK_W47,SPR_MARK_W48,
+
+SPR_MARK_PAIN1,SPR_MARK_PAIN2,
+
+SPR_MARK_DIE1,SPR_MARK_DIE2,SPR_MARK_DIE3,SPR_MARK_DIE4,
+SPR_MARK_DEAD1,SPR_MARK_DEAD2,SPR_MARK_DEAD3,SPR_MARK_DEAD4,
+SPR_MARK_DEAD5,SPR_MARK_DEAD6,SPR_MARK_DEAD7,
+
+
+/*
+SPR_FIREMONK_USE11,SPR_FIREMONK_USE12,SPR_FIREMONK_USE13,SPR_FIREMONK_USE14,
+SPR_FIREMONK_USE15,SPR_FIREMONK_USE16,SPR_FIREMONK_USE17,SPR_FIREMONK_USE18,
+
+SPR_FIREMONK_USE21,SPR_FIREMONK_USE22,SPR_FIREMONK_USE23,SPR_FIREMONK_USE24,
+SPR_FIREMONK_USE25,SPR_FIREMONK_USE26,SPR_FIREMONK_USE27,SPR_FIREMONK_USE28,
+*/
+
+//#endif
+
+} actornames_t;
+
+typedef enum
+ {GUNSTART_LABEL,
+
+#if (SHAREWARE == 0)
+
+  W_KNIFE,WK2,WK3,WK4,WK5,WK6,WK7,WK8,WK9,WK10,
+
+  W_BMALEPISTOL1,xab,xcd,
+  W_BMRIGHTPISTOL1,xef,xgh,
+  W_BMLEFTPISTOL1,xij,xkl,
+#endif
+
+  W_MALEPISTOL1,x5,x6,
+  W_MRIGHTPISTOL1,x7,x8,
+  W_MLEFTPISTOL1,x9,x10,
+
+#if (SHAREWARE == 0)
+  W_FEMALEPISTOL1,x11,x12,
+  W_FRIGHTPISTOL1,x13,x14,
+  W_FLEFTPISTOL1,x15,x16,
+#endif
+
+  W_MP40,FN7,FN8,
+  W_BAZOOKA,FN22,fn104,fn105,
+  W_HEATSEEKER,FN80,fn108,fn109,
+  W_DRUNK,FN72,FN73,FN74,
+  W_FIREBOMB,FN33,fn106,fn107,
+  W_FIREWALL,FN66,FN67,
+  W_GODHAND,ded1,ded2,ded3,ded4,ded5,ded6,ded7,
+
+#if (SHAREWARE == 0)
+
+  W_SPLIT,FN69,FN70,FN71,
+  W_KES,fn101,fn102,fn103,x99,x100,
+  W_BAT,fn111,fn112,fn113,fn114,fn115,fn117,
+  W_DOG,bite1,bite2,bite3,nose1,nose2,nose3,nose4,paw1,paw2,paw3,paw4
+#endif
+ } weaponsprites;
+
+
+#define SPR_DDOG_FIRE1 SPR_DDOG_JUMP1
+#define SPR_DDOG_FIRE2 SPR_DDOG_JUMP2
+#define SPR_DDOG_BOLTS2 SPR_DDOG_BOLTS1
+#define SPR_DDOG_BOLTS3 SPR_DDOG_BOLTS1
+#define SPR_DDOG_BOLTS4 SPR_DDOG_BOLTS1
+#define SPR_DDOG_HIT1 -1
+#define SPR_DDOG_HIT2 -1
+#define SPR_DDOG_HIT3 -1
+#define SPR_DDOG_PAIN1 SPR_DDOG_DIE1
+#define SPR_DDOG_PAIN2 SPR_DDOG_DIE1
+
+
+#define SPR_BLITZ_USE SPR_BLITZ_S1
+
+#define SPR_BLITZ_STEAL1 SPR_BLITZ_USE11
+#define SPR_BLITZ_STEAL2 SPR_BLITZ_USE12
+
+
+
+#define SPR_GRENADE_HIT1 -1
+#define SPR_GRENADE_HIT2 -1
+#define SPR_GRENADE_HIT3 -1
+
+#define SPR_FIREBALL_HIT1 -1
+#define SPR_FIREBALL_HIT2 -1
+#define SPR_FIREBALL_HIT3 -1
+
+#define SPR_ROBOGRD_SHURIKEN1 SPR_BSTAR1
+#define SPR_ROBOGRD_SHURIKEN2 SPR_BSTAR2
+#define SPR_ROBOGRD_SHURIKEN3 SPR_BSTAR3
+#define SPR_ROBOGRD_SHURIKEN4 SPR_BSTAR4
+#define SPR_SHURIKEN_HIT1 -1
+#define SPR_SHURIKEN_HIT2 -1
+#define SPR_SHURIKEN_HIT3 -1
+
+
+#define SPR_ESAU_USE SPR_ESAU_S1
+#define SPR_ESAU_WINS SPR_ESAU_S1
+#define SPR_ESAU_DIE4 SPR_ESAU_DIE3
+#define SPR_ESAU_DIE5 SPR_ESAU_DIE3
+#define SPR_ESAU_DIE6 SPR_ESAU_DIE3
+#define SPR_ESAU_DIE7 SPR_ESAU_DIE3
+
+
+#define SPR_MISSILEHIT1 -1
+#define SPR_MISSILEHIT2 -1
+#define SPR_MISSILEHIT3 -1
+#define SPR_HEINRICH_DIE4 SPR_HEINRICH_DIE3
+#define SPR_HEINRICH_DIE5 SPR_HEINRICH_DIE3
+#define SPR_HEINRICH_DIE6 SPR_HEINRICH_DIE3
+#define SPR_HEINRICH_DIE7 SPR_HEINRICH_DIE3
+#define SPR_HEINRICH_DEAD SPR_HEINRICH_DIE3
+#define SPR_HEINRICH_MINE SPR_HEINRICH_S1
+#define SPR_HEINRICH_USE SPR_HEINRICH_S1
+
+#define SPR_DMFBALL11 SPR_FIREBALL1
+#define SPR_DMFBALL21 SPR_FIREBALL2
+#define SPR_DMFBALL31 SPR_FIREBALL3
+#define SPR_DMFBALL41 SPR_FIREBALL4
+#define SPR_DMFBALLHIT1 -1
+#define SPR_DMFBALLHIT2 -1
+#define SPR_DMFBALLHIT3 -1
+#define SPR_DARKMONK_DIE4 SPR_DARKMONK_DIE3
+#define SPR_DARKMONK_DIE5 SPR_DARKMONK_DIE3
+#define SPR_DARKMONK_DIE6 SPR_DARKMONK_DIE3
+#define SPR_DARKMONK_DIE7 SPR_DARKMONK_DIE3
+#define SPR_DARKMONK_PAIN1 SPR_DARKMONK_DIE1
+#define SPR_DARKMONK_PAIN2 SPR_DARKMONK_DIE5
+
+#define SPR_OSHURHIT1 -1
+#define SPR_OSHURHIT2 -1
+#define SPR_OSHURHIT3 -1
+
+#define SPR_OSHUR1 SPR_BSTAR1
+#define SPR_OSHUR2 SPR_BSTAR2
+#define SPR_OSHUR3 SPR_BSTAR4
+#define SPR_OSHUR4 SPR_BSTAR4
+
+#define SPR_WALLSHOOT SPR_WALLSTAND1
+#define SPR_WALLPATH1 SPR_WALLSTAND1
+
+#endif

Added: tags/rott-1.1/rott/states.h
===================================================================
--- tags/rott-1.1/rott/states.h	                        (rev 0)
+++ tags/rott-1.1/rott/states.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,644 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _states_public
+#define _states_public
+
+#include "develop.h"
+
+#if (SHAREWARE == 0)
+#define MAXSTATES 1300+17+8+32+32
+#else
+#define MAXSTATES 660+17+8+32+32
+#endif
+
+#define SF_CLOSE   0x01
+#define SF_CRUSH   0x02
+#define SF_UP      0x04
+#define SF_DOWN    0x08
+#define SF_SOUND   0x10
+#define SF_BLOCK   0x20
+#define SF_EYE1    0
+#define SF_EYE2    1
+#define SF_EYE3    2
+#define SF_DOGSTATE 0x40
+#define SF_BAT      0x80
+#define SF_FAKING   0x80
+#define SF_DEAD     0x80
+
+typedef struct  statestruct
+{
+		  byte            rotate;
+		  short           shapenum;  // a shapenum of -1 means get from ob->temp1
+		  short           tictime;
+		  void            (*think) ();
+		  signed char     condition;
+		  struct  statestruct     *next;
+} statetype;
+
+extern   statetype * statetable[MAXSTATES];
+
+extern   statetype s_lowgrdstand;
+extern   statetype s_lowgrdpath4;
+extern   statetype s_lowgrdpath3;
+extern   statetype s_lowgrdpath2;
+extern   statetype s_lowgrdpath1;
+extern   statetype s_lowgrdcollide;
+extern   statetype s_lowgrdcollide2;
+//extern   statetype s_lowgrduse1;
+extern   statetype s_lowgrdshoot1;
+extern   statetype s_lowgrdchase1;
+extern   statetype s_lowgrddie1;
+extern   statetype s_lowgrdcrushed1;
+extern   statetype s_lowgrdcrushed1;
+extern   statetype s_sneakydown;
+extern   statetype s_sneakyrise1;
+
+
+extern   statetype s_highgrdstand;
+extern   statetype s_highgrdpath1;
+extern   statetype s_highgrdcollide;
+extern   statetype s_highgrdcollide2;
+//extern   statetype s_highgrduse1;
+extern   statetype s_highgrdshoot1;
+extern   statetype s_highgrdshoot3;
+extern   statetype s_highgrdchase1;
+extern   statetype s_highgrddie1;
+extern   statetype s_highgrdcrushed1;
+
+
+extern   statetype s_strikestand;
+extern   statetype s_strikepath1;
+extern   statetype s_strikecollide;
+extern   statetype s_strikecollide2;
+extern   statetype s_strikeshoot1;
+//extern   statetype s_strikeuse1;
+extern   statetype s_strikerollright1;
+extern   statetype s_strikerollright3;
+extern   statetype s_strikerollleft1;
+extern   statetype s_strikerollleft3;
+extern   statetype s_strikechase1;
+extern   statetype s_strikedie1;
+extern   statetype s_strikewait;
+extern   statetype s_strikecrushed1;
+
+
+extern   statetype s_blitzstand;
+extern   statetype s_blitzpath1;
+extern   statetype s_blitzcollide;
+extern   statetype s_blitzcollide2;
+extern   statetype s_blitzshoot1;
+extern   statetype s_blitzuse;
+extern   statetype s_blitzsteal1;
+extern   statetype s_blitzchase1;
+extern   statetype s_blitzdie1;
+extern   statetype s_blitzdie3;
+extern   statetype s_blitzplead1;
+extern   statetype s_blitzplead3;
+extern   statetype s_blitzplead4;
+extern   statetype s_blitzplead7;
+extern   statetype s_blitzaplead5;
+extern   statetype s_blitzaplead4;
+extern   statetype s_blitzcrushed1;
+extern   statetype s_blitzfakedie1;
+extern   statetype s_blitzrise2;
+extern   statetype s_blitzstruggledie1;
+extern   statetype s_blitzstruggledead;
+
+extern   statetype s_enforcerstand;
+extern   statetype s_enforcerpath1;
+extern   statetype s_enforcercollide;
+extern   statetype s_enforcercollide2;
+//extern   statetype s_enforceruse1;
+extern   statetype s_enforcershoot1;
+extern   statetype s_enforcershoot3;
+extern   statetype s_enforcerthrow1;
+extern   statetype s_grenade1;
+extern   statetype s_grenadehit1;
+extern   statetype s_enforcerchase1;
+extern   statetype s_enforcerdie1;
+extern   statetype s_grenade_fall1;
+extern   statetype s_grenade_fall6;
+extern   statetype s_enforcercrushed1;
+
+
+extern   statetype s_robogrdstand;
+extern   statetype s_robogrdpath1;
+extern   statetype s_robogrdshoot1;
+extern   statetype s_robogrdshuriken1;
+extern   statetype s_shurikenhit1;
+extern   statetype s_robogrdchase1;
+extern   statetype s_robogrddie1;
+extern   statetype s_robogrdcollide;
+extern   statetype s_robogrdcollide2;
+extern   statetype s_robogrdcrushed1;
+extern   statetype s_roboalign;
+extern   statetype s_robowait;
+extern   statetype s_roborealign;
+
+
+
+
+
+extern statetype s_altexplosion10;
+extern statetype s_altexplosion9 ;
+extern statetype s_altexplosion8 ;
+extern statetype s_altexplosion7 ;
+extern statetype s_altexplosion6 ;
+extern statetype s_altexplosion5 ;
+extern statetype s_altexplosion4 ;
+extern statetype s_altexplosion3  ;
+extern statetype s_altexplosion2  ;
+extern statetype s_altexplosion1  ;
+
+
+
+extern   statetype s_explosion1;
+extern   statetype s_explosion2;
+extern   statetype s_explosion3;
+extern   statetype s_explosion4;
+extern   statetype s_explosion5;
+extern   statetype s_explosion6;
+extern   statetype s_explosion7;
+extern   statetype s_explosion8;
+extern   statetype s_explosion9;
+extern   statetype s_explosion10;
+extern   statetype s_explosion11;
+extern   statetype s_explosion12;
+extern   statetype s_explosion13;
+extern   statetype s_explosion14;
+extern   statetype s_explosion15;
+extern   statetype s_explosion16;
+extern   statetype s_explosion17;
+extern   statetype s_explosion18;
+extern   statetype s_explosion19;
+extern   statetype s_explosion20;
+
+extern   statetype s_grexplosion1;
+extern   statetype s_grexplosion2;
+extern   statetype s_grexplosion3;
+extern   statetype s_grexplosion4;
+extern   statetype s_grexplosion5;
+extern   statetype s_grexplosion6;
+extern   statetype s_grexplosion7;
+extern   statetype s_grexplosion8;
+extern   statetype s_grexplosion9;
+extern   statetype s_grexplosion10;
+extern   statetype s_grexplosion11;
+extern   statetype s_grexplosion12;
+extern   statetype s_grexplosion13;
+extern   statetype s_grexplosion14;
+extern   statetype s_grexplosion15;
+extern   statetype s_grexplosion16;
+extern   statetype s_grexplosion17;
+extern   statetype s_grexplosion18;
+extern   statetype s_grexplosion19;
+extern   statetype s_grexplosion20;
+
+
+
+extern   statetype s_staticexplosion1;
+extern   statetype s_staticexplosion2;
+extern   statetype s_staticexplosion3;
+extern   statetype s_staticexplosion4;
+extern   statetype s_staticexplosion5;
+extern   statetype s_staticexplosion6;
+extern   statetype s_staticexplosion7;
+extern   statetype s_staticexplosion8;
+extern   statetype s_staticexplosion9;
+extern   statetype s_staticexplosion10;
+extern   statetype s_staticexplosion11;
+extern   statetype s_staticexplosion12;
+extern   statetype s_staticexplosion13;
+extern   statetype s_staticexplosion14;
+extern   statetype s_staticexplosion15;
+extern   statetype s_staticexplosion16;
+extern   statetype s_staticexplosion17;
+extern   statetype s_staticexplosion18;
+extern   statetype s_staticexplosion19;
+extern   statetype s_staticexplosion20;
+extern   statetype s_staticexplosion21;
+extern   statetype s_staticexplosion22;
+extern   statetype s_staticexplosion23;
+extern   statetype s_staticexplosion24;
+extern   statetype s_staticexplosion25;
+
+extern   statetype s_upblade1;
+
+extern   statetype s_firejetup1;
+
+
+extern   statetype s_columndowndown1;
+
+
+extern   statetype s_spearup1;
+extern   statetype s_pushcolumn1;
+extern   statetype s_pushcolumn2;
+extern   statetype s_pushcolumn3;
+
+extern   statetype s_wallfireball;
+extern   statetype s_crossfire1;
+extern   statetype s_crossdone1;
+
+
+
+
+extern   statetype s_fireunit1;
+extern   statetype s_firespan1;
+
+extern   statetype s_p_bazooka1;
+extern   statetype s_p_bazooka2;
+
+extern   statetype s_p_grenade;
+extern   statetype s_p_gfall1;
+extern   statetype s_p_gfall2;
+extern   statetype s_p_gfall3;
+extern   statetype s_p_gfall4;
+
+extern   statetype s_gunsmoke1;
+extern   statetype s_bloodspurt1;
+extern   statetype s_hitmetalwall1;
+extern   statetype s_hitmetalactor1;
+
+
+
+
+
+
+extern   statetype s_dust;
+
+
+
+extern   statetype s_skeleton1;
+
+
+extern   statetype s_gas2;
+extern   statetype s_gas1;
+
+
+extern   statetype s_spring1;
+extern   statetype s_spring2;
+
+
+
+
+extern   statetype s_player;
+extern   statetype s_free;
+
+extern   statetype s_pgunattack1;
+extern   statetype s_pmissattack1;
+extern   statetype s_pgunattack2;
+extern   statetype s_pmissattack2;
+extern   statetype s_remoteinelev;
+extern   statetype s_remotemove1;
+
+
+extern   statetype s_godfire1;
+
+
+
+extern   statetype s_remotedie1;
+
+
+extern   statetype s_guts1;
+extern   statetype s_guts12;
+
+
+extern   statetype s_bossdeath;
+extern   statetype s_megaexplosions;
+
+extern   statetype s_superparticles;
+extern   statetype s_gibs1;
+extern   statetype s_gibsdone1;
+extern   statetype s_bigsoul;
+extern   statetype s_littlesoul;
+extern   statetype s_vaporized1;
+extern   statetype s_autospring1;
+extern   statetype s_pbatblast;
+
+
+
+extern   statetype s_collectorwander1;
+extern   statetype s_collectorfdoor1;
+extern   statetype s_tag;
+extern   statetype s_timekeeper;
+extern   statetype s_skeleton48;
+extern   statetype s_skeleton24;
+
+extern   statetype s_wind;
+extern   statetype s_remoteguts1;
+extern   statetype s_voidwait;
+extern   statetype s_ashwait;
+extern   statetype s_deadwait;
+extern   statetype s_gutwait;
+extern   statetype s_vaporized8;
+extern   statetype s_remoteguts12;
+extern   statetype s_eye1;
+extern   statetype s_itemspawn1;
+extern   statetype s_deadblood1;
+
+
+extern   statetype s_flash1;
+
+extern   statetype s_elevdisk;
+extern   statetype s_pathdisk;
+extern   statetype s_megaremove;
+
+extern   statetype s_respawn1;
+extern   statetype s_basemarker1;
+
+extern   statetype s_blooddrip1;
+
+extern   statetype s_diskmaster;
+extern   statetype s_bstar1;
+
+
+#if (SHAREWARE == 0)
+
+extern   statetype s_scottwander1;
+extern   statetype s_scottwanderdoor1;
+
+extern   statetype s_opstand;
+extern   statetype s_oppath1;
+extern   statetype s_opcollide;
+extern   statetype s_opcollide2;
+extern   statetype s_opgiveup;
+//extern   statetype s_opuse1;
+extern   statetype s_opshoot1;
+extern   statetype s_opbolo1;
+extern   statetype s_bolocast1;
+extern   statetype s_opchase1;
+extern   statetype s_opdie1;
+extern   statetype s_opcrushed1;
+
+
+extern   statetype s_dmonkstand;
+extern   statetype s_dmonkpath1;
+extern   statetype s_dmonkshoot1;
+extern   statetype s_dmonkshoot2;
+extern   statetype s_dmonkchase1;
+extern   statetype s_dmonkdie1;
+extern   statetype s_dmonkcollide;
+extern   statetype s_dmonkcollide2;
+extern   statetype s_dmonkcrushed1;
+extern   statetype s_dmonkshoot5;
+extern   statetype s_dmonkshoot3;
+extern   statetype s_dmonkshoot4;
+
+
+extern   statetype s_firemonkstand;
+extern   statetype s_firemonkpath1;
+extern   statetype s_firemonkcast1;
+extern   statetype s_monkfire1;
+extern   statetype s_fireballhit1;
+extern   statetype s_firemonkchase1;
+extern   statetype s_firemonkdie1;
+extern   statetype s_firemonkcollide;
+extern   statetype s_firemonkcollide2;
+extern   statetype s_firemonkcrushed1;
+
+
+extern   statetype s_wallstand;
+extern   statetype s_wallpath;
+extern   statetype s_wallshoot;
+extern   statetype s_wallcollide;
+extern   statetype s_wallalign;
+extern   statetype s_wallwait;
+extern   statetype s_wallrestore;
+
+
+extern   statetype s_darianstand;
+extern   statetype s_darianchase1;
+extern   statetype s_darianuse;
+extern   statetype s_darianshoot1;
+extern   statetype s_dariancollide;
+extern   statetype s_dariancollide2;
+extern   statetype s_dariandie1;
+extern   statetype s_darianspears;
+extern   statetype s_darianuse1;
+extern   statetype s_dariansink1;
+extern   statetype s_dariansink9;
+extern   statetype s_darianrise1;
+extern   statetype s_darianwait;
+extern   statetype s_dariandefend1;
+
+
+extern   statetype s_heinrichstand;
+extern   statetype s_heinrichshoot1;
+extern   statetype s_heinrichshoot4;
+extern   statetype s_heinrichshoot9;
+extern   statetype s_heinrichooc;
+extern   statetype s_heinrichchase;
+extern   statetype s_heinexp1;
+extern   statetype s_kristleft;
+extern   statetype s_kristright;
+
+
+extern   statetype s_missile1;
+extern   statetype s_missilehit1;
+extern   statetype s_mine1;
+extern   statetype s_heinrichchase1;
+extern   statetype s_heinrichuse;
+extern   statetype s_heinrichmine;
+extern   statetype s_heinrichdie1;
+extern   statetype s_heinrichdead;
+extern   statetype s_heinrichdefend;
+
+extern   statetype s_dexplosion22;
+extern   statetype s_dexplosion21;
+extern   statetype s_dexplosion20;
+extern   statetype s_dexplosion19;
+extern   statetype s_dexplosion18;
+extern   statetype s_dexplosion17;
+extern   statetype s_dexplosion16;
+extern   statetype s_dexplosion15;
+extern   statetype s_dexplosion14;
+extern   statetype s_dexplosion13;
+extern   statetype s_dexplosion12;
+extern   statetype s_dexplosion11;
+extern   statetype s_dexplosion10;
+extern   statetype s_dexplosion9;
+extern   statetype s_dexplosion8;
+extern   statetype s_dexplosion7;
+extern   statetype s_dexplosion6;
+extern   statetype s_dexplosion5;
+extern   statetype s_dexplosion4;
+extern   statetype s_dexplosion3;
+extern   statetype s_dexplosion2;
+extern   statetype s_dexplosion1;
+extern   statetype s_dspear1;
+
+
+
+extern   statetype s_NMEchase;
+extern   statetype s_NMEdie;
+extern   statetype s_NMEhead1;
+extern   statetype s_NMEhead2;
+extern   statetype s_NMEwheels1;
+extern   statetype s_NMEwheels2;
+extern   statetype s_NMEwheels3;
+extern   statetype s_NMEwheels4;
+extern   statetype s_NMEwheels5;
+extern   statetype s_NMEwindup;
+extern   statetype s_NMEwheels120;
+
+extern   statetype s_NMEwrotleft3;
+extern   statetype s_NMEwrotleft2;
+extern   statetype s_NMEwrotleft1;
+
+extern   statetype s_NMEwrotright3;
+extern   statetype s_NMEwrotright2;
+extern   statetype s_NMEwrotright1;
+extern   statetype s_NMEminiball1;
+extern   statetype s_NMEattack;
+extern   statetype s_NMEsaucer1;
+extern   statetype s_NMEhead1rl;
+extern   statetype s_NMEhead2rl;
+extern   statetype s_NMEspinattack;
+extern   statetype s_NMEwheelspin;
+extern   statetype s_NMEcollide;
+extern   statetype s_NMEdeathbuildup;
+extern   statetype s_NMEheadexplosion;
+extern   statetype s_NMEstand;
+extern   statetype s_NMEspinfire;
+extern   statetype s_shootinghead;
+extern   statetype s_oshuriken1;
+extern   statetype s_oshurikenhit1;
+
+
+
+
+extern   statetype s_darkmonkstand;
+extern   statetype s_darkmonkcharge1;
+extern   statetype s_darkmonkreact;
+extern   statetype s_darkmonkland;
+extern   statetype s_darkmonkchase1;
+extern   statetype s_darkmonkcover1;
+extern   statetype s_darkmonkawaken1;
+extern   statetype s_darkmonklightning1;
+extern   statetype s_darkmonkfspark1;
+extern   statetype s_darkmonkbreathe1;
+extern   statetype s_darkmonksummon1;
+extern   statetype s_darkmonkhead;
+extern   statetype s_darkmonkhspawn;
+extern   statetype s_darkmonksneer1;
+extern   statetype s_darkmonkheadhappy;
+extern   statetype s_darkmonkheaddie1;
+extern   statetype s_darkmonkhball1;
+extern   statetype s_darkmonksphere1;
+extern   statetype s_darkmonksphere8;
+extern   statetype s_darkmonkbball1;
+extern   statetype s_darkmonkscare1;
+extern   statetype s_darkmonkdie1;
+extern   statetype s_darkmonkredhead;
+extern   statetype s_redheadhit;
+extern   statetype s_darkmonksnakelink;
+extern   statetype s_darkmonkredlink;
+extern   statetype s_redlinkhit;
+extern   statetype s_energysphere1;
+extern   statetype s_lightning;
+extern   statetype s_handball2;
+extern   statetype s_handball1;
+extern   statetype s_faceball2;
+extern   statetype s_faceball1;
+extern   statetype s_floorspark1;
+extern   statetype s_dmlandandfire;
+
+extern   statetype s_darkmonkhball7;
+extern   statetype s_darkmonkbball7;
+extern   statetype s_darkmonklightning9;
+extern   statetype s_darkmonkfspark5;
+extern   statetype s_darkmonkbreathe6;
+extern   statetype s_darkmonkabsorb1;
+extern   statetype s_dmgreenthing1;
+extern   statetype s_dmgreenthing8;
+extern   statetype s_darkmonkfastspawn;
+extern   statetype s_spit1;
+extern   statetype s_spithit1;
+extern   statetype s_snakefire1;
+extern   statetype s_snakepath;
+extern   statetype s_snakefindpath;
+extern   statetype s_snakefireworks1;
+extern   statetype s_snakefireworks2;
+
+
+extern   statetype s_speardown1;
+
+
+extern   statetype s_downblade1;
+
+
+extern   statetype s_firejetdown1;
+
+extern   statetype s_columnupup1;
+extern   statetype s_columnupup2;
+extern   statetype s_columnupup8;
+extern   statetype s_columnupup7;
+extern   statetype s_columnupdown1;
+extern   statetype s_columnupdown6;
+
+extern   statetype s_spinupblade1;
+extern   statetype s_spindownblade1;
+
+extern   statetype s_boulderdrop12;
+extern   statetype s_boulderdrop10;
+extern   statetype s_boulderdrop8;
+
+
+extern   statetype s_boulderdrop1;
+extern   statetype s_boulderspawn;
+extern   statetype s_bouldersink1;
+extern   statetype s_boulderroll1;
+
+extern   statetype s_gunfire1;
+extern   statetype s_gunfire2;
+extern   statetype s_gundie1;
+extern   statetype s_gunstand;
+extern   statetype s_gunraise1;
+extern   statetype s_gunlower1;
+extern   statetype s_4waygunfire1;
+extern   statetype s_4waygunfire2;
+extern   statetype s_4waygun;
+
+
+extern   statetype s_kessphere1;
+extern   statetype s_batblast1;
+extern   statetype s_slop1;
+
+
+
+extern   statetype s_serialdog4;
+extern   statetype s_serialdog3;
+extern   statetype s_serialdog2;
+extern   statetype s_serialdog;
+extern   statetype s_serialdogattack;
+extern   statetype s_doguse;
+extern   statetype s_doglick;
+extern   statetype s_dogwait;
+
+
+
+#endif
+
+
+
+
+
+
+#endif

Added: tags/rott-1.1/rott/task_man.h
===================================================================
--- tags/rott-1.1/rott/task_man.h	                        (rev 0)
+++ tags/rott-1.1/rott/task_man.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,69 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+/**********************************************************************
+   module: TASK_MAN.C
+
+   author: James R. Dose
+   phone:  (214)-271-1365 Ext #221
+   date:   July 25, 1994
+
+   Public header for TASK_MAN.C, a low level timer task scheduler.
+
+   (c) Copyright 1994 James R. Dose.  All Rights Reserved.
+**********************************************************************/
+
+#ifndef __TASK_MAN_H
+#define __TASK_MAN_H
+
+enum TASK_ERRORS
+   {
+   TASK_Warning = -2,
+   TASK_Error = -1,
+   TASK_Ok = 0
+   };
+
+typedef struct task
+{
+    struct   task *next;
+    struct   task *prev;
+    void          ( *TaskService )( struct task * );
+    void          *data;
+    long          rate;
+    volatile long count;
+    int           priority;
+    int           active;
+} task;
+
+// TS_InInterrupt is TRUE during a taskman interrupt.
+// Use this if you have code that may be used both outside
+// and within interrupts.
+
+extern volatile int TS_InInterrupt;
+
+void    TS_Shutdown( void );
+task    *TS_ScheduleTask( void ( *Function )( task * ), int rate,
+                          int priority, void *data );
+int     TS_Terminate( task *ptr );
+void    TS_Dispatch( void );
+void    TS_SetTaskRate( task *Task, int rate );
+void    TS_UnlockMemory( void );
+int     TS_LockMemory( void );
+
+#endif

Added: tags/rott-1.1/rott/version.h
===================================================================
--- tags/rott-1.1/rott/version.h	                        (rev 0)
+++ tags/rott-1.1/rott/version.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,28 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#ifndef VERSION_H
+#define VERSION_H
+
+#define ROTTMAJORVERSION 1
+#define ROTTMINORVERSION 4
+#define ROTTVERSION ((ROTTMAJORVERSION*10)+(ROTTMINORVERSION))
+
+#endif

Added: tags/rott-1.1/rott/w_wad.c
===================================================================
--- tags/rott-1.1/rott/w_wad.c	                        (rev 0)
+++ tags/rott-1.1/rott/w_wad.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,544 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// W_wad.c
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#if PLATFORM_DOS
+#include <malloc.h>
+#include <conio.h>
+#include <io.h>
+#endif
+
+#include "rt_def.h"
+#include "rt_util.h"
+#include "_w_wad.h"
+#include "w_wad.h"
+#include "z_zone.h"
+#include "isr.h"
+#include "develop.h"
+
+#include "rt_crc.h"
+#include "rt_main.h"
+
+//=============
+// GLOBALS
+//=============
+
+int             numlumps;
+void            **lumpcache;
+
+//=============
+// STATICS
+//=============
+
+static lumpinfo_t      *lumpinfo;              // location of each lump on disk
+
+
+#if (DATACORRUPTIONTEST == 1)
+static byte *lumpcheck;
+#endif
+
+/*
+============================================================================
+
+                                                LUMP BASED ROUTINES
+
+============================================================================
+*/
+
+/*
+====================
+=
+= W_AddFile
+=
+= All files are optional, but at least one file must be found
+= Files with a .wad extension are wadlink files with multiple lumps
+= Other files are single lumps with the base filename for the lump name
+=
+====================
+*/
+
+void W_AddFile (char *_filename)
+{
+        wadinfo_t               header;
+        lumpinfo_t              *lump_p;
+        unsigned                i;
+        int                     handle, length;
+        int                     startlump;
+        filelump_t              *fileinfo, singleinfo;
+
+        char filename[MAX_PATH];
+        char buf[MAX_PATH+100];//bna++
+
+        strncpy(filename, _filename, sizeof (filename));
+        filename[sizeof (filename) - 1] = '\0';
+        FixFilePath(filename);
+
+		//bna section start
+		if (access (filename, 0) != 0) {
+			strcpy (buf,"Error, Could not find User file '");
+			strcat (buf,filename);
+			strcat (buf,"', ignoring file");
+			printf(buf);
+		}
+		//bna section end
+
+//
+// read the entire file in
+//      FIXME: shared opens
+
+#ifdef PLATFORM_DOS
+        if ( (handle = open (filename,O_RDWR | O_BINARY)) == -1)
+#else
+        if ( (handle = open (filename,O_RDONLY | O_BINARY)) == -1)
+#endif
+                return;
+
+        startlump = numlumps;
+
+        if ( (strcmpi (filename+strlen(filename)-3 , "wad" ) ) &&
+             (strcmpi (filename+strlen(filename)-3 , "rts" ) ) )
+        {
+        // single lump file
+                if (!quiet)
+                   printf("    Adding single file %s.\n",filename);
+                fileinfo = &singleinfo;
+                singleinfo.filepos = 0;
+                singleinfo.size = LONG(filelength(handle));
+                ExtractFileBase (filename, singleinfo.name);
+                numlumps++;
+        }
+        else
+        {
+        // WAD file
+                if (!quiet)
+                   printf("    Adding %s.\n",filename);
+                read (handle, &header, sizeof(header));
+                if (strncmp(header.identification,"IWAD",4))
+                        Error ("Wad file %s doesn't have IWAD id\n",filename);
+                header.numlumps = IntelLong(LONG(header.numlumps));
+                header.infotableofs = IntelLong(LONG(header.infotableofs));
+                length = header.numlumps*sizeof(filelump_t);
+                fileinfo = alloca (length);
+                if (!fileinfo)
+                   Error ("Wad file could not allocate header info on stack");
+                lseek (handle, header.infotableofs, SEEK_SET);
+                read (handle, fileinfo, length);
+                
+                numlumps += header.numlumps;
+        }
+
+//
+// Fill in lumpinfo
+//
+        Z_Realloc((void **)&lumpinfo,numlumps*sizeof(lumpinfo_t));
+//        lumpinfo = realloc (lumpinfo, numlumps*sizeof(lumpinfo_t));
+//        if (!lumpinfo)
+//           Error("W_AddFile: Could not realloc %ld bytes",numlumps*sizeof(lumpinfo_t));
+        lump_p = &lumpinfo[startlump];
+
+        for (i=startlump ; i<(unsigned int)numlumps ; i++,lump_p++, fileinfo++)
+        {
+                fileinfo->filepos = IntelLong(LONG(fileinfo->filepos));
+                fileinfo->size = IntelLong(LONG(fileinfo->size));
+                lump_p->handle = handle;
+                lump_p->position = LONG(fileinfo->filepos);
+                lump_p->size = LONG(fileinfo->size);
+                strncpy (lump_p->name, fileinfo->name, 8);
+        }
+}
+
+
+
+/*
+====================
+=
+= W_CheckWADIntegrity
+=
+====================
+*/
+
+void W_CheckWADIntegrity ( void )
+{
+   int crc;
+
+// CRC disabled because it's not very useful these days
+
+#ifdef DOS
+   crc = CalculateCRC ((byte *)lumpinfo, numlumps*sizeof(lumpinfo_t) );
+
+   if (crc != WADCHECKSUM)
+      {
+      printf("==============================================================================\n");
+      printf("ATTENTION: This version of ROTT has been modified.  If you would like to get\n");
+      printf("a copy of the original game, call 1-800-APOGEE1 or run ROTTHELP.EXE.\n");
+      printf("      You will not receive technical support for this modified version.\n");
+//      printf("                        Press any key to continue\n");
+      printf("==============================================================================\n");
+//      printf("crc=%ld\n",crc);
+//      getch();
+      }
+#endif
+}
+
+
+
+/*
+====================
+=
+= W_InitMultipleFiles
+=
+= Pass a null terminated list of files to use.
+=
+= All files are optional, but at least one file must be found
+=
+= Files with a .wad extension are idlink files with multiple lumps
+=
+= Other files are single lumps with the base filename for the lump name
+=
+= Lump names can appear multiple times. The name searcher looks backwards,
+= so a later file can override an earlier one.
+=
+====================
+*/
+
+void W_InitMultipleFiles (char **filenames)
+{
+//
+// open all the files, load headers, and count lumps
+//
+        numlumps = 0;
+        lumpinfo = SafeMalloc(5);   // will be realloced as lumps are added
+
+        for ( ; *filenames ; filenames++)
+                W_AddFile (*filenames);
+
+        if (!numlumps)
+                Error ("W_InitFiles: no files found");
+
+//
+// set up caching
+//
+        lumpcache = calloc (numlumps, sizeof(*lumpcache));
+        if (!lumpcache)
+           Error("W_InitFiles: lumpcache malloc failed size=%d\n",numlumps<<2);
+
+        if (!quiet)
+           printf("W_Wad: Wad Manager Started NUMLUMPS=%ld\n",(long int)numlumps);
+#if (DATACORRUPTIONTEST == 1)
+        lumpcheck=SafeMalloc(numlumps);
+        memset(lumpcheck,255,numlumps);
+#endif
+#ifdef DOS
+        if (!SOUNDSETUP)
+#endif
+           W_CheckWADIntegrity ();
+}
+
+
+
+
+/*
+====================
+=
+= W_InitFile
+=
+= Just initialize from a single file
+=
+====================
+*/
+
+void W_InitFile (char *filename)
+{
+        char    *names[2];
+
+        names[0] = filename;
+        names[1] = NULL;
+        W_InitMultipleFiles (names);
+}
+
+
+
+/*
+====================
+=
+= W_NumLumps
+=
+====================
+*/
+
+int     W_NumLumps (void)
+{
+        return numlumps;
+}
+
+
+
+/*
+====================
+=
+= W_CheckNumForName
+=
+= Returns -1 if name not found
+=
+====================
+*/
+
+int     W_CheckNumForName (char *name)
+{
+        char    name8[9];
+        int             v1,v2;
+        lumpinfo_t      *lump_p;
+        lumpinfo_t      *endlump;
+
+// make the name into two integers for easy compares
+
+        strncpy (name8,name,8);
+        name8[8] = 0;                   // in case the name was a fill 8 chars
+        strupr (name8);                 // case insensitive
+
+        v1 = *(int *)name8;
+        v2 = *(int *)&name8[4];
+
+
+// scan backwards so patch lump files take precedence
+
+        lump_p = lumpinfo;
+        endlump = lumpinfo + numlumps;
+
+        while (lump_p != endlump)
+           {
+           if ( *(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2)
+              return lump_p - lumpinfo;
+           lump_p++;
+           }
+
+
+        return -1;
+}
+
+
+/*
+====================
+=
+= W_GetNumForName
+=
+= Calls W_CheckNumForName, but bombs out if not found
+=
+====================
+*/
+
+int     W_GetNumForName (char *name)
+{
+        int     i;
+
+        i = W_CheckNumForName (name);
+        if (i != -1)
+                return i;
+
+        Error ("W_GetNumForName: %s not found!",name);
+        return -1;
+}
+
+
+/*
+====================
+=
+= W_LumpLength
+=
+= Returns the buffer size needed to load the given lump
+=
+====================
+*/
+
+int W_LumpLength (int lump)
+{
+        if (lump >= numlumps)
+                Error ("W_LumpLength: %i >= numlumps",lump);
+        return lumpinfo[lump].size;
+}
+
+/*
+====================
+=
+= W_GetNameForNum
+=
+====================
+*/
+
+char *  W_GetNameForNum (int i)
+{
+
+        if (i>=numlumps)
+           Error ("W_GetNameForNum: %i >= numlumps",i);
+        return &(lumpinfo[i].name[0]);
+}
+
+/*
+====================
+=
+= W_ReadLump
+=
+= Loads the lump into the given buffer, which must be >= W_LumpLength()
+=
+====================
+*/
+int readinglump;
+byte * lumpdest;
+void W_ReadLump (int lump, void *dest)
+{
+        int                     c;
+        lumpinfo_t      *l;
+
+        readinglump=lump;
+        lumpdest=dest;
+        if (lump >= numlumps)
+                Error ("W_ReadLump: %i >= numlumps",lump);
+        if (lump < 0)
+                Error ("W_ReadLump: %i < 0",lump);
+        l = lumpinfo+lump;
+
+        lseek (l->handle, l->position, SEEK_SET);
+        c = read (l->handle, dest, l->size);
+        if (c < l->size)
+                Error ("W_ReadLump: only read %i of %i on lump %i",c,l->size,lump);
+}
+
+
+/*
+====================
+=
+= W_WriteLump
+=
+= Writes the lump into the given buffer, which must be >= W_LumpLength()
+=
+====================
+*/
+
+void W_WriteLump (int lump, void *src)
+{
+   int        c;
+   lumpinfo_t *l;
+
+   if (lump >= numlumps)
+      Error ("W_WriteLump: %i >= numlumps",lump);
+   if (lump < 0)
+      Error ("W_WriteLump: %i < 0",lump);
+   l = lumpinfo+lump;
+
+   lseek (l->handle, l->position, SEEK_SET);
+   c = write (l->handle, src, l->size);
+   if (c < l->size)
+      Error ("W_WriteLump: only wrote %i of %i on lump %i",c,l->size,lump);
+}
+
+
+/*
+====================
+=
+= W_CacheLumpNum
+=
+====================
+*/
+void    *W_CacheLumpNum (int lump, int tag, converter_t converter, int numrec)
+{
+        if (lump >= (int)numlumps)
+                Error ("W_CacheLumpNum: %i >= numlumps",lump);
+
+        else if (lump < 0)
+                Error ("W_CacheLumpNum: %i < 0  Taglevel: %i",lump,tag);
+
+        if (!lumpcache[lump])
+        {
+                // read the lump in
+#if (PRECACHETEST == 1)
+                char str[9];
+                strncpy(&str[0],W_GetNameForNum(lump),8);
+                str[8]=0;
+                SoftError("Lump #%d, %s cached at %ld tics size=%ld tag=%ld\n",lump,str,ticcount,W_LumpLength (lump),tag);
+                if (W_LumpLength(lump)==0)
+                   SoftError("Caching in zero length lump #%d, %s cached at %ld tics size=%ld tag=%ld\n",lump,str,ticcount,W_LumpLength (lump),tag);
+#endif
+
+#if (DATACORRUPTIONTEST == 1)
+                {
+                int length;
+
+                *(lumpcheck+lump)=CHECKPERIOD;
+                length=W_LumpLength(lump);
+                Z_Malloc (length+sizeof(word), tag, &lumpcache[lump]);
+                W_ReadLump (lump, lumpcache[lump]);
+                Debug("Invoking endian converter on %p, %i records.\n", lumpcache[lump], numrec);
+                converter(lumpcache[lump], numrec);
+
+                *( (word *) ((byte *)lumpcache[lump]+length) ) = CalculateCRC (lumpcache[lump], length);
+                }
+#else
+                Z_Malloc (W_LumpLength (lump), tag, &lumpcache[lump]);
+                W_ReadLump (lump, lumpcache[lump]);
+                Debug("Invoking endian converter on %p, %i records\n", lumpcache[lump], numrec);
+                converter(lumpcache[lump], numrec);
+#endif
+        }
+        else
+           {
+#if (DATACORRUPTIONTEST == 1)
+
+               if (*(lumpcheck+lump)==255)
+                  Error("Tried using lump%ld before reading it in\n",lump);
+               (*(lumpcheck+lump))--;
+               if (*(lumpcheck+lump)==0)
+                  {
+                  word storedcrc;
+                  word crc;
+                  int length;
+
+                  *(lumpcheck+lump)=CHECKPERIOD;
+
+                  length=W_LumpLength(lump);
+                  storedcrc = *( (word *) ((byte *)lumpcache[lump]+length) );
+                  crc = CalculateCRC (lumpcache[lump], length);
+                  if (crc!=storedcrc)
+                     Error("Data corruption lump=%ld\n",lump);
+                  }
+#endif
+               Z_ChangeTag (lumpcache[lump],tag);
+           }
+
+        return lumpcache[lump];
+}
+
+
+/*
+====================
+=
+= W_CacheLumpName
+=
+====================
+*/
+
+void    *W_CacheLumpName (char *name, int tag, converter_t converter, int numrec)
+{
+        return W_CacheLumpNum (W_GetNumForName(name), tag, converter, numrec);
+}

Added: tags/rott-1.1/rott/w_wad.h
===================================================================
--- tags/rott-1.1/rott/w_wad.h	                        (rev 0)
+++ tags/rott-1.1/rott/w_wad.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,51 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    W_WAD.C - Wad managment utilities
+//
+//***************************************************************************
+
+#ifndef _w_wad_public
+#define _w_wad_public
+
+#include "byteordr.h"
+
+void    W_InitMultipleFiles (char **filenames); // Initialize multiple wads
+void    W_InitFile (char *filename);            // Init a single wad file
+
+int     W_CheckNumForName (char *name);         // Check to see if the named lump exists
+int     W_GetNumForName (char *name);           // Get the number for the named lump
+char *  W_GetNameForNum (int i);                // Get the name for a number
+
+int     W_NumLumps (void);                      // Get the current number of lumps managed
+int     W_LumpLength (int lump);                // Get the length of the numbered lump
+void    W_ReadLump (int lump, void *dest);      // Read the numbered lump into a buffer
+void W_WriteLump (int lump, void *src);
+
+void    *W_CacheLumpNum (int lump, int tag, converter_t converter, int numrecs);
+                                                // Cache in the numbered lump with the appropriate memory tag
+void    *W_CacheLumpName (char *name, int tag, converter_t converter, int numrecs);
+                                                // Cache in the named lump with the appropriate memory tag
+
+extern int             numlumps;
+extern void            **lumpcache;
+
+#endif

Added: tags/rott-1.1/rott/watcom.c
===================================================================
--- tags/rott-1.1/rott/watcom.c	                        (rev 0)
+++ tags/rott-1.1/rott/watcom.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,43 @@
+#include "rt_def.h"
+
+#include "watcom.h"
+
+/* 
+  C versions of watcom.h assembly.
+  Uses the '__int64' type (see rt_def.h).
+ */
+
+fixed FixedMul(fixed a, fixed b)
+{
+	__int64 scratch1 = (__int64) a * (__int64) b + (__int64) 0x8000;
+	return (scratch1 >> 16) & 0xffffffff;
+}
+
+fixed FixedMulShift(fixed a, fixed b, fixed shift)
+{
+	__int64 x = a;
+	__int64 y = b;
+	__int64 z = x * y;
+	
+	return (((unsigned __int64)z) >> shift) & 0xffffffff;
+}
+
+fixed FixedDiv2(fixed a, fixed b)
+{
+	__int64 x = (signed int)a;
+	__int64 y = (signed int)b;
+	__int64 z = x * 65536 / y;
+	
+	return (z) & 0xffffffff;
+}
+
+fixed FixedScale(fixed orig, fixed factor, fixed divisor)
+{
+	__int64 x = orig;
+	__int64 y = factor;
+	__int64 z = divisor;
+	
+	__int64 w = (x * y) / z;
+	
+	return (w) & 0xffffffff;
+}

Added: tags/rott-1.1/rott/watcom.h
===================================================================
--- tags/rott-1.1/rott/watcom.h	                        (rev 0)
+++ tags/rott-1.1/rott/watcom.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,59 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#ifndef _watcom_h_public
+#define _watcom_h_public
+fixed FixedMul(fixed a, fixed b);
+fixed FixedDiv2(fixed a, fixed b);
+fixed FixedScale(fixed orig, fixed factor, fixed divisor);
+fixed FixedMulShift(fixed a, fixed b, fixed shift);
+#ifdef __WATCOMC__
+#pragma aux FixedMul =  \
+        "imul ebx",                     \
+        "add  eax, 8000h"        \
+        "adc  edx,0h"            \
+        "shrd eax,edx,16"       \
+        parm    [eax] [ebx] \
+        value   [eax]           \
+        modify exact [eax edx]
+
+#pragma aux FixedMulShift =  \
+        "imul ebx",                     \
+        "shrd eax,edx,cl"       \
+        parm    [eax] [ebx] [ecx]\
+        value   [eax]           \
+        modify exact [eax edx]
+
+#pragma aux FixedDiv2 = \
+        "cdq",                          \
+        "shld edx,eax,16",      \
+        "sal eax,16",           \
+        "idiv ebx"                      \
+        parm    [eax] [ebx] \
+        value   [eax]           \
+        modify exact [eax edx]
+#pragma aux FixedScale = \
+        "imul ebx",                     \
+        "idiv ecx"                      \
+        parm    [eax] [ebx] [ecx]\
+        value   [eax]           \
+        modify exact [eax edx]
+#endif
+
+#endif

Added: tags/rott-1.1/rott/winrott.c
===================================================================
--- tags/rott-1.1/rott/winrott.c	                        (rev 0)
+++ tags/rott-1.1/rott/winrott.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,160 @@
+/* Routines from winrott needed for the highres support for the SDL port */
+#include <stdlib.h>
+#include <string.h>
+#include "WinRott.h"
+#include "modexlib.h"
+
+//typedef unsigned char byte;
+
+int iGLOBAL_SCREENWIDTH  = 640;//bna val 800
+int iGLOBAL_SCREENHEIGHT = 480;//bna val 600
+int iGLOBAL_SCREENBWIDE ;
+int iG_SCREENWIDTH;// default screen width in bytes
+
+int iGLOBAL_HEALTH_X;
+int iGLOBAL_HEALTH_Y;
+int iGLOBAL_AMMO_X;
+int iGLOBAL_AMMO_Y;
+
+int iGLOBAL_FOCALWIDTH;
+double dGLOBAL_FPFOCALWIDTH;
+
+double dTopYZANGLELIMIT;
+
+int iG_X_center;
+int iG_Y_center;
+
+boolean iG_aimCross = 0;
+
+extern int  viewheight;
+extern int  viewwidth;
+
+//----------------------------------------------------------------------
+#define FINEANGLES                        2048
+void SetRottScreenRes (int Width, int Height) 
+{
+	
+	iGLOBAL_SCREENWIDTH = Width;
+	iGLOBAL_SCREENHEIGHT = Height;
+
+
+    iGLOBAL_SCREENBWIDE = iGLOBAL_SCREENWIDTH*(96/320);
+	iG_SCREENWIDTH = iGLOBAL_SCREENWIDTH*(96/320);;// default screen width in bytes
+
+	if (iGLOBAL_SCREENWIDTH == 320) {
+		iGLOBAL_FOCALWIDTH = 160;
+		dGLOBAL_FPFOCALWIDTH = 160.0; 
+		iGLOBAL_HEALTH_X = 20;
+		iGLOBAL_HEALTH_Y = 185;
+		iGLOBAL_AMMO_X = 300;
+		iGLOBAL_AMMO_Y = 184;
+
+		dTopYZANGLELIMIT = (44*FINEANGLES/360);;
+	}
+	if (iGLOBAL_SCREENWIDTH == 640) {
+		iGLOBAL_FOCALWIDTH = 180;
+		dGLOBAL_FPFOCALWIDTH = 180.0 ;
+		iGLOBAL_HEALTH_X = 40;//20*2;
+		iGLOBAL_HEALTH_Y = 466;//(185*2)+16;
+		iGLOBAL_AMMO_X = 600;//300*2;
+		iGLOBAL_AMMO_Y = 464;//480-16;
+
+		dTopYZANGLELIMIT = (42*FINEANGLES/360);;
+	}
+	if (iGLOBAL_SCREENWIDTH == 800) {
+		iGLOBAL_FOCALWIDTH = 200;
+		dGLOBAL_FPFOCALWIDTH = 200.0 ;
+		iGLOBAL_HEALTH_X = 40;//20*2;
+		iGLOBAL_HEALTH_Y = 585;//(185/200)*600;
+		iGLOBAL_AMMO_X = 750;//(300/320)*800;
+		iGLOBAL_AMMO_Y = 584;//600-16;
+	
+		dTopYZANGLELIMIT = (90*FINEANGLES/360);;
+	}
+
+	//dYZANGLELIMIT = (12*FINEANGLES/360);
+	//#define YZANGLELIMIT  (12*FINEANGLES/360)//bna--(30*FINEANGLES/360)
+
+	//#define TopYZANGLELIMIT  (44*FINEANGLES/360)//bna added
+
+//	GetCurrentDirectory(sizeof(ApogeePath),ApogeePath);// curent directory name
+
+}
+
+//----------------------------------------------------------------------
+//luckey for me that I am not programmin a 386 or the next
+//4 function would never have worked. bna++
+extern int     viewsize;
+void MoveScreenUpLeft()
+{
+	int startX,startY,startoffset;
+    byte  *Ycnt,*b;
+//   SetTextMode (  );
+    b=(byte *)bufferofs;
+	b += (((iGLOBAL_SCREENHEIGHT-viewheight)/2)*iGLOBAL_SCREENWIDTH)+((iGLOBAL_SCREENWIDTH-viewwidth)/2);
+	if (viewsize == 8) {b += 8*iGLOBAL_SCREENWIDTH;}
+	startX = 3; //take 3 pixels to the right
+	startY = 3; //take 3 lines down
+	startoffset = (startY*iGLOBAL_SCREENWIDTH)+startX;
+
+	for (Ycnt=b;Ycnt<b+((viewheight-startY)*iGLOBAL_SCREENWIDTH);Ycnt+=iGLOBAL_SCREENWIDTH){
+		memcpy(Ycnt,Ycnt+startoffset, viewwidth-startX);
+	}
+}
+//----------------------------------------------------------------------
+void MoveScreenDownLeft()
+{
+	int startX,startY,startoffset;
+    byte  *Ycnt,*b;
+//   SetTextMode (  );
+    b=(byte *)bufferofs;
+	b += (((iGLOBAL_SCREENHEIGHT-viewheight)/2)*iGLOBAL_SCREENWIDTH)+((iGLOBAL_SCREENWIDTH-viewwidth)/2);
+	if (viewsize == 8) {b += 8*iGLOBAL_SCREENWIDTH;}
+	startX = 3; //take 3 pixels to the right
+	startY = 3; //take 3 lines down
+	startoffset = (startY*iGLOBAL_SCREENWIDTH);//+startX;
+
+	//Ycnt starts in botton of screen and copys lines upwards
+	for (Ycnt=b+((viewheight-startY-1)*iGLOBAL_SCREENWIDTH);Ycnt>b;Ycnt-=iGLOBAL_SCREENWIDTH){
+		memcpy(Ycnt+startoffset,Ycnt+startX,viewwidth-startX);
+	}
+}
+//----------------------------------------------------------------------
+void MoveScreenUpRight()
+{
+	int startX,startY,startoffset;
+    byte  *Ycnt,*b;
+//   SetTextMode (  );
+    b=(byte *)bufferofs;
+
+	b += (((iGLOBAL_SCREENHEIGHT-viewheight)/2)*iGLOBAL_SCREENWIDTH)+((iGLOBAL_SCREENWIDTH-viewwidth)/2);
+	if (viewsize == 8) {b += 8*iGLOBAL_SCREENWIDTH;}
+	startX = 3; //take 3 pixels to the right
+	startY = 3; //take 3 lines down
+	startoffset = (startY*iGLOBAL_SCREENWIDTH);//+startX;
+
+	for (Ycnt=b;Ycnt<b+((viewheight-startY)*iGLOBAL_SCREENWIDTH);Ycnt+=iGLOBAL_SCREENWIDTH){
+		memcpy(Ycnt+startX,Ycnt+startoffset, viewwidth-startX);
+	}
+}
+//----------------------------------------------------------------------
+void MoveScreenDownRight()
+{
+	int startX,startY,startoffset;
+    byte  *Ycnt,*b;
+//   SetTextMode (  );
+    b=(byte *)bufferofs;
+
+	b += (((iGLOBAL_SCREENHEIGHT-viewheight)/2)*iGLOBAL_SCREENWIDTH)+((iGLOBAL_SCREENWIDTH-viewwidth)/2);
+	if (viewsize == 8) {b += 8*iGLOBAL_SCREENWIDTH;}
+	startX = 3; //take 3 pixels to the right
+	startY = 3; //take 3 lines down
+	startoffset = (startY*iGLOBAL_SCREENWIDTH)+startX;
+
+	//Ycnt starts in botton of screen and copys lines upwards
+	for (Ycnt=b+((viewheight-startY-1)*iGLOBAL_SCREENWIDTH);Ycnt>b;Ycnt-=iGLOBAL_SCREENWIDTH){
+		memcpy(Ycnt+startoffset,Ycnt,viewwidth-startX);
+	}
+}
+
+

Added: tags/rott-1.1/rott/z_zone.c
===================================================================
--- tags/rott-1.1/rott/z_zone.c	                        (rev 0)
+++ tags/rott-1.1/rott/z_zone.c	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,798 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// Z_zone.c
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef DOS
+#include <dos.h>
+#include <conio.h>
+#endif
+
+#include "rt_def.h"
+#include "_z_zone.h"
+#include "z_zone.h"
+#include "rt_util.h"
+#include "develop.h"
+#include "rt_net.h"
+
+#if (DEVELOPMENT == 1)
+#include "rt_main.h"
+#endif
+//MED
+#include "memcheck.h"
+
+int lowmemory=0;
+
+/*
+==============================================================================
+
+                                                ZONE MEMORY ALLOCATION
+
+There is never any space between memblocks, and there will never be two
+contiguous free memblocks.
+
+The rover can be left pointing at a non-empty block
+
+It is of no value to free a cachable block, because it will get overwritten
+automatically if needed
+
+==============================================================================
+*/
+
+//Globals
+
+int zonememorystarted=0;
+
+// Statics
+
+static memzone_t       *mainzone;
+static memzone_t       *levelzone;
+static int levelzonesize=LEVELZONESIZE;
+static struct meminfo
+   {
+   unsigned LargestBlockAvail;
+   unsigned MaxUnlockedPage;
+   unsigned LargestLockablePage;
+   unsigned LinAddrSpace;
+   unsigned NumFreePagesAvail;
+   unsigned NumPhysicalPagesFree;
+   unsigned TotalPhysicalPages;
+   unsigned FreeLinAddrSpace;
+   unsigned SizeOfPageFile;
+   unsigned Reserved[3];
+   } MemInfo;
+
+/*
+========================
+=
+= Z_ClearZone
+=
+========================
+*/
+
+void Z_ClearZone (memzone_t *zone)
+{
+        memblock_t      *block;
+
+// set the entire zone to one free block
+
+        zone->blocklist.next = zone->blocklist.prev = block =
+                (memblock_t *)( (byte *)zone + sizeof(memzone_t) );
+        zone->blocklist.user = (void *)zone;
+        zone->blocklist.tag = PU_STATIC;
+        zone->rover = block;
+
+        block->prev = block->next = &zone->blocklist;
+        block->user = NULL;     // free block
+        block->size = zone->size - sizeof(memzone_t);
+}
+
+
+/*
+========================
+=
+= Z_AllocateZone
+=
+========================
+*/
+
+memzone_t *Z_AllocateZone (int size)
+{
+        memzone_t       *header;
+
+        header = malloc (size+sizeof(memzone_t));
+        if (!header)
+                Error ("Z_AllocateZone: Couldn't malloc %zd bytes avail=%d\n",
+                size+sizeof(memzone_t), Z_AvailHeap());
+        header->size = size;
+        Z_ClearZone (header);
+        return header;
+}
+
+/*
+========================
+=
+= Z_Init
+=
+========================
+*/
+void Z_Init (int size, int min)
+{
+   int maxsize;
+   int sz;
+
+   if (zonememorystarted==1)
+      return;
+   zonememorystarted=1;
+
+   sz = GamePacketSize();
+
+   sz*=MAXCMDS;
+
+   if (ConsoleIsServer() == true)
+      levelzonesize+=((numplayers*2)+1)*sz;
+   else
+      levelzonesize+=(numplayers+1)*sz;
+
+   maxsize=((int)(Z_AvailHeap())-size-levelzonesize);
+   if (maxsize<min)
+      {
+      UL_DisplayMemoryError (min-maxsize);
+      }
+   if (maxsize>MAXMEMORYSIZE)
+      maxsize=(MAXMEMORYSIZE-levelzonesize);
+
+   mainzone = Z_AllocateZone (maxsize);
+   levelzone = Z_AllocateZone (levelzonesize);
+
+   if (!quiet)
+      printf("Z_INIT: %ld bytes\n",(long int)(maxsize+levelzonesize));
+
+   if (maxsize<(min+(min>>1)))
+      {
+      lowmemory = 1;
+
+      printf("==============================================================================\n");
+      printf("WARNING: You are running ROTT with very little memory.  ROTT runs best with\n");
+      printf("8 Megabytes of memory and no TSR's loaded in memory.  If you can free up more\n");
+      printf("memory for ROTT then you should press CTRL-BREAK at this time. If you are\n");
+      printf("unable to do this you will experience momentary pauses in game-play whenever\n");
+      printf("you enter new areas of the game as well as an overall decreased performance.\n");
+      printf("                        Press any key to continue\n");
+      printf("==============================================================================\n");
+      getch();
+      }
+}
+
+/*
+========================
+=
+= Z_ShutDown
+=
+========================
+*/
+
+void Z_ShutDown( void )
+{
+   if (zonememorystarted==0)
+      return;
+   zonememorystarted=0;
+   free(mainzone);
+   free(levelzone);
+}
+
+/*
+========================
+=
+= Z_GetSize
+=
+========================
+*/
+
+int Z_GetSize (void *ptr)
+{
+        memblock_t      *block;
+
+        block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
+        return (block->size - sizeof(memblock_t));
+}
+
+
+/*
+========================
+=
+= Z_Free
+=
+========================
+*/
+
+void Z_Free (void *ptr)
+{
+        memblock_t      *block, *other;
+
+        block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
+        if (!block->user)
+                Error ("Z_Free: freed a freed pointer");
+
+        if (block->user > (void **)0x100)       // smaller values are not pointers
+                *block->user = 0;               // clear the user's mark
+        block->user = NULL;     // mark as free
+
+        other = block->prev;
+        if (!other->user)
+        {       // merge with previous free block
+                other->size += block->size;
+                other->next = block->next;
+                other->next->prev = other;
+                if (block == mainzone->rover)
+                        mainzone->rover = other;
+                else if (block == levelzone->rover)
+                        levelzone->rover = other;
+                block = other;
+        }
+
+        other = block->next;
+        if (!other->user)
+        {       // merge the next free block onto the end
+                block->size += other->size;
+                block->next = other->next;
+                block->next->prev = block;
+                if (other == mainzone->rover)
+                        mainzone->rover = block;
+                else if (other == levelzone->rover)
+                        levelzone->rover = block;
+        }
+}
+
+
+/*
+========================
+=
+= Z_Malloc
+=
+= You can pass a NULL user if the tag is < PU_PURGELEVEL
+========================
+*/
+
+#if (DEVELOPMENT == 1)
+int totallevelsize=0;
+#endif
+
+void *Z_Malloc (int size, int tag, void *user)
+{
+        int             extra;
+        memblock_t      *start, *rover, *new, *base;
+
+//
+// scan through the block list looking for the first free block
+// of sufficient size, throwing out any purgable blocks along the way
+//
+//        size += sizeof(memblock_t);     // account for size of block header
+        size = (size + sizeof(memblock_t) + 3)&~3;     // account for size of block header
+
+
+//
+// if there is a free block behind the rover, back up over them
+//
+        base = mainzone->rover;
+        if (!base->prev->user)
+                base = base->prev;
+
+        rover = base;
+        start = base->prev;
+
+        do
+        {
+                if (rover == start)     // scaned all the way around the list
+                        {
+                        SoftError("OHSHIT\n");
+                        Z_DumpHeap(0,200);
+                        Error ("Z_Malloc: failed on allocation of %i bytes",size);
+                        }
+                if (rover->user)
+                {
+                        if (rover->tag < PU_PURGELEVEL)
+                        // hit a block that can't be purged, so move base past it
+                                base = rover = rover->next;
+                        else
+                        {
+                        // free the rover block (adding the size to base)
+                                base = base->prev;      // the rover can be the base block
+                                Z_Free ((byte *)rover+sizeof(memblock_t));
+                                base = base->next;
+                                rover = base->next;
+                        }
+                }
+                else
+                        rover = rover->next;
+        } while (base->user || base->size < size);
+
+//
+// found a block big enough
+//
+        extra = base->size - size;
+        if (extra >  MINFRAGMENT)
+        {       // there will be a free fragment after the allocated block
+                new = (memblock_t *) ((byte *)base + size );
+                new->size = extra;
+                new->user = NULL;               // free block
+                new->tag = 0;
+                new->prev = base;
+                new->next = base->next;
+                new->next->prev = new;
+                base->next = new;
+                base->size = size;
+        }
+
+        if (user)
+        {
+                base->user = user;                      // mark as an in use block
+                *(void **)user = (void *) ((byte *)base + sizeof(memblock_t));
+        }
+        else
+        {
+                if (tag >= PU_PURGELEVEL)
+                        Error ("Z_Malloc: an owner is required for purgable blocks");
+                base->user = (void *)2;         // mark as in use, but unowned
+        }
+        base->tag = tag;
+
+        mainzone->rover = base->next;   // next allocation will start looking here
+
+
+#if (MEMORYCORRUPTIONTEST==1)
+         base->posttag=MEMORYPOSTTAG;
+         base->pretag=MEMORYPRETAG;
+#endif
+
+        return (void *) ((byte *)base + sizeof(memblock_t));
+}
+
+/*
+========================
+=
+= Z_LevelMalloc
+=
+= Only use this for level structures.
+= You can pass a NULL user if the tag is < PU_PURGELEVEL
+========================
+*/
+
+void *Z_LevelMalloc (int size, int tag, void *user)
+{
+        int             extra;
+        memblock_t      *start, *rover, *new, *base;
+
+//
+// scan through the block list looking for the first free block
+// of sufficient size, throwing out any purgable blocks along the way
+//
+//        size += sizeof(memblock_t);     // account for size of block header
+        size = (size + sizeof(memblock_t) + 3)&~3;     // account for size of block header
+
+
+//
+// if there is a free block behind the rover, back up over them
+//
+        base = levelzone->rover;
+        if (!base->prev->user)
+                base = base->prev;
+
+        rover = base;
+        start = base->prev;
+
+        do
+        {
+                if (rover == start)     // scaned all the way around the list
+                        {
+                        SoftError("OHSHIT\n");
+                        Z_DumpHeap(0,200);
+                        Error ("Z_LevelMalloc: failed on allocation of %i bytes",size);
+                        }
+                if (rover->user)
+                {
+                        if (rover->tag < PU_PURGELEVEL)
+                        // hit a block that can't be purged, so move base past it
+                                base = rover = rover->next;
+                        else
+                        {
+                        // free the rover block (adding the size to base)
+                                base = base->prev;      // the rover can be the base block
+                                Z_Free ((byte *)rover+sizeof(memblock_t));
+                                base = base->next;
+                                rover = base->next;
+                        }
+                }
+                else
+                        rover = rover->next;
+        } while (base->user || base->size < size);
+
+//
+// found a block big enough
+//
+        extra = base->size - size;
+        if (extra >  MINFRAGMENT)
+        {       // there will be a free fragment after the allocated block
+                new = (memblock_t *) ((byte *)base + size );
+                new->size = extra;
+                new->user = NULL;               // free block
+                new->tag = 0;
+                new->prev = base;
+                new->next = base->next;
+                new->next->prev = new;
+                base->next = new;
+                base->size = size;
+        }
+
+        if (user)
+        {
+                base->user = user;                      // mark as an in use block
+                *(void **)user = (void *) ((byte *)base + sizeof(memblock_t));
+        }
+        else
+        {
+                if (tag >= PU_PURGELEVEL)
+                        Error ("Z_Malloc: an owner is required for purgable blocks");
+                base->user = (void *)2;         // mark as in use, but unowned
+        }
+        base->tag = tag;
+
+        levelzone->rover = base->next;   // next allocation will start looking here
+
+#if (MEMORYCORRUPTIONTEST==1)
+         base->posttag=MEMORYPOSTTAG;
+         base->pretag=MEMORYPRETAG;
+#endif
+
+        return (void *) ((byte *)base + sizeof(memblock_t));
+}
+
+
+
+/*
+========================
+=
+= Z_FreeTags
+=
+========================
+*/
+
+void Z_FreeTags (int lowtag, int hightag)
+{
+        memblock_t      *block, *next;
+
+        for (block = mainzone->blocklist.next ; block != &mainzone->blocklist
+        ; block = next)
+        {
+                next = block->next;             // get link before freeing
+                if (!block->user)
+                        continue;                       // free block
+                if (block->tag >= lowtag && block->tag <= hightag)
+                        Z_Free ( (byte *)block+sizeof(memblock_t));
+        }
+        for (block = levelzone->blocklist.next ; block != &levelzone->blocklist
+        ; block = next)
+        {
+                next = block->next;             // get link before freeing
+                if (!block->user)
+                        continue;                       // free block
+                if (block->tag >= lowtag && block->tag <= hightag)
+                        Z_Free ( (byte *)block+sizeof(memblock_t));
+        }
+}
+
+/*
+========================
+=
+= Z_DumpHeap
+=
+========================
+*/
+
+void Z_DumpHeap (int lowtag, int hightag)
+{
+        memblock_t      *block;
+        int             totalsize;
+
+        SoftError("MAIN ZONE\n");
+        SoftError("zone size: %i  location: %p\n",mainzone->size,mainzone);
+        SoftError("tag range: %i to %i\n",lowtag, hightag);
+
+        totalsize=0;
+
+        for (block = mainzone->blocklist.next ; ; block = block->next)
+        {
+                if (block->tag >= lowtag && block->tag <= hightag)
+                        {
+                        SoftError("block:%p    size:%7i    user:%p    tag:%3i\n",
+                        block, block->size, block->user, block->tag);
+                        totalsize+=block->size;
+                        }
+
+                if (block->next == &mainzone->blocklist) {
+                        break;                  // all blocks have been hit
+		}
+                if ( (byte *)block + block->size != (byte *)block->next) {
+                        SoftError("ERROR: block size does not touch the next block\n");
+		}
+                if ( block->next->prev != block) {
+                        SoftError("ERROR: next block doesn't have proper back link\n");
+		}
+                if (!block->user && !block->next->user) {
+                        SoftError("ERROR: two consecutive free blocks\n");
+		}
+        }
+        SoftError("Total Size of blocks = %d\n",totalsize);
+
+        SoftError("LEVEL ZONE\n");
+        SoftError("zone size: %i  location: %p\n",levelzone->size,levelzone);
+        SoftError("tag range: %i to %i\n",lowtag, hightag);
+
+        totalsize=0;
+
+        for (block = levelzone->blocklist.next ; ; block = block->next)
+        {
+                if (block->tag >= lowtag && block->tag <= hightag)
+                        {
+                        SoftError("block:%p    size:%7i    user:%p    tag:%3i\n",
+                        block, block->size, block->user, block->tag);
+                        totalsize+=block->size;
+                        }
+
+                if (block->next == &levelzone->blocklist)
+                        break;                  // all blocks have been hit
+                if ( (byte *)block + block->size != (byte *)block->next) {
+                        SoftError("ERROR: block size does not touch the next block\n");
+		}
+                if ( block->next->prev != block) {
+                        SoftError("ERROR: next block doesn't have proper back link\n");
+		}
+                if (!block->user && !block->next->user) {
+                        SoftError("ERROR: two consecutive free blocks\n");
+		}
+        }
+        SoftError("Total Size of blocks = %d\n",totalsize);
+
+}
+
+/*
+========================
+=
+= Z_UsedHeap
+=
+========================
+*/
+
+int Z_UsedHeap ( void )
+{
+        memblock_t      *block;
+        int heapsize;
+
+
+        heapsize=0;
+        for (block = mainzone->blocklist.next ; ; block = block->next)
+        {
+                if ((block->tag>0) && (block->user>(void **)0))
+                   heapsize+=(block->size);
+                if (block->next == &mainzone->blocklist)
+                   break;                  // all blocks have been hit
+        }
+        return heapsize;
+}
+
+/*
+========================
+=
+= Z_UsedLevelHeap
+=
+========================
+*/
+
+int Z_UsedLevelHeap ( void )
+{
+        memblock_t      *block;
+        int heapsize;
+
+
+        heapsize=0;
+        for (block = levelzone->blocklist.next ; ; block = block->next)
+        {
+                if ((block->tag>0) && (block->user>(void **)0))
+                   heapsize+=(block->size);
+                if (block->next == &levelzone->blocklist)
+                   break;                  // all blocks have been hit
+        }
+        return heapsize;
+}
+
+
+/*
+========================
+=
+= Z_UsedStaticHeap
+=
+========================
+*/
+
+int Z_UsedStaticHeap ( void )
+{
+        memblock_t      *block;
+        int heapsize;
+
+
+        heapsize=0;
+        for (block = mainzone->blocklist.next ; ; block = block->next)
+        {
+                if ((block->tag>0) && (block->tag<PU_PURGELEVEL) && (block->user>(void **)0))
+                   heapsize+=(block->size);
+                if (block->next == &mainzone->blocklist)
+                   break;                  // all blocks have been hit
+        }
+        return heapsize;
+}
+
+
+/*
+========================
+=
+= Z_HeapSize
+=
+========================
+*/
+
+int Z_HeapSize ( void )
+{
+   return mainzone->size;
+}
+
+
+/*
+========================
+=
+= Z_CheckHeap
+=
+========================
+*/
+
+void Z_CheckHeap (void)
+{
+        memblock_t      *block;
+
+        // Check mainzone
+
+        for (block = mainzone->blocklist.next ; ; block = block->next)
+        {
+                if (block->next == &mainzone->blocklist)
+                        break;                  // all blocks have been hit
+                if ( (byte *)block + block->size != (byte *)block->next)
+                        Error ("Z_CheckHeap: block size does not touch the next block\n");
+                if ( block->next->prev != block)
+                        Error ("Z_CheckHeap: next block doesn't have proper back link\n");
+                if (!block->user && !block->next->user)
+                        Error ("Z_CheckHeap: two consecutive free blocks\n");
+#if (MEMORYCORRUPTIONTEST==1)
+                if ((block->tag>0) && (block->user>0))
+                   {
+                   if (block->posttag!=MEMORYPOSTTAG)
+                      Error("Z_CheckHeap: Corrupted posttag\n");
+                   if (block->pretag!=MEMORYPRETAG)
+                      Error("Z_CheckHeap: Corrupted pretag\n");
+                   }
+#endif
+        }
+
+        // Check levelzone
+
+        for (block = levelzone->blocklist.next ; ; block = block->next)
+        {
+                if (block->next == &levelzone->blocklist)
+                        break;                  // all blocks have been hit
+                if ( (byte *)block + block->size != (byte *)block->next)
+                        Error ("Z_CheckHeap: block size does not touch the next block\n");
+                if ( block->next->prev != block)
+                        Error ("Z_CheckHeap: next block doesn't have proper back link\n");
+                if (!block->user && !block->next->user)
+                        Error ("Z_CheckHeap: two consecutive free blocks\n");
+#if (MEMORYCORRUPTIONTEST==1)
+                if ((block->tag>0) && (block->user>0))
+                   {
+                   if (block->posttag!=MEMORYPOSTTAG)
+                      Error("Z_CheckHeap: Corrupted posttag\n");
+                   if (block->pretag!=MEMORYPRETAG)
+                      Error("Z_CheckHeap: Corrupted pretag\n");
+                   }
+#endif
+        }
+}
+
+
+/*
+========================
+=
+= Z_ChangeTag
+=
+========================
+*/
+
+void Z_ChangeTag (void *ptr, int tag)
+{
+        memblock_t      *block;
+
+        block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
+        block->tag = tag;
+}
+
+/*
+========================
+=
+= Z_AvailHeap
+=
+========================
+*/
+
+int Z_AvailHeap ( void )
+{
+#ifdef DOS
+   union REGS zregs;
+   struct SREGS zsregs;
+
+
+   zregs.x.eax = 0x00000500;
+   memset( &zsregs, 0, sizeof(zsregs) );
+   zsregs.es = FP_SEG( &MemInfo );
+   zregs.x.edi = FP_OFF( &MemInfo );
+
+   int386x( DPMI_INT, &zregs, &zregs, &zsregs );
+
+   return ((int)MemInfo.LargestBlockAvail);
+#else
+	return MAXMEMORYSIZE;
+#endif
+}
+
+/*
+========================
+=
+= Z_Realloc
+=
+========================
+*/
+
+void Z_Realloc (void ** ptr, int newsize)
+{
+   memblock_t      *block;
+   void * newptr;
+   int oldsize;
+
+   block = (memblock_t *) ( (byte *)(*ptr) - sizeof(memblock_t));
+   oldsize = block->size;
+   newptr = SafeMalloc(newsize);
+   if (oldsize > newsize)
+      {
+      oldsize = newsize;
+      }
+   memcpy( newptr, *ptr, oldsize );
+   SafeFree( *ptr );
+   *ptr = newptr;
+}
+

Added: tags/rott-1.1/rott/z_zone.h
===================================================================
--- tags/rott-1.1/rott/z_zone.h	                        (rev 0)
+++ tags/rott-1.1/rott/z_zone.h	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,79 @@
+/*
+Copyright (C) 1994-1995 Apogee Software, Ltd.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+//***************************************************************************
+//
+//    Z_Zone Memory management Constants
+//
+//***************************************************************************
+
+
+#ifndef _z_zone_public
+#define _z_zone_public
+
+
+extern int lowmemory;
+
+// tags < 100 are not overwritten until freed
+#define PU_STATIC               1                       // static entire execution time
+#define PU_GAME                 20                      // static until game completed
+#define PU_LEVELSTRUCT          49                      // start of static until level exited
+#define PU_LEVEL                50                      // start of static until level exited
+#define PU_LEVELEND             51                      // end of static until level exited
+
+// tags >= 100 are purgable whenever needed
+#define PU_PURGELEVEL           100
+#define PU_CACHE                101
+#define PU_CACHEWALLS           155
+#define PU_CACHESPRITES         154
+#define PU_CACHEBJWEAP          153
+#define PU_CACHEACTORS          152
+#define PU_CACHESOUNDS          120
+#define PU_FLAT                 102
+#define PU_PATCH                103
+#define PU_TEXTURE              104
+
+#define URGENTLEVELSTART PU_LEVEL
+
+//***************************************************************************
+//
+//    Z_ZONE.C - Carmack's Memory manager for protected mode
+//
+//***************************************************************************
+
+extern int zonememorystarted;
+
+void Z_Init (int size, int min);                // Starts up Memory manager (size is in bytes), (min is minimum requirement)
+void Z_Free (void *ptr);                        // Free a pointer in Z_Zone's domain
+void *Z_Malloc (int size, int tag, void *user); // Malloc You can pass a NULL user if the tag is < PU_PURGELEVEL
+void *Z_LevelMalloc (int size, int tag, void *user); // Level Malloc for level structures
+void Z_FreeTags (int lowtag, int hightag);      // Free a series of memory tags
+void Z_DumpHeap (int lowtag, int hightag);      // Dump the heap (for debugging purposes)
+void Z_CheckHeap (void);                        // Check the heap for corruption
+void Z_ChangeTag (void *ptr, int tag);          // Change the tag of a memory item
+int Z_HeapSize ( void );                        // Return the total heap size
+int Z_UsedHeap ( void );                        // Return used portion of heap size
+int Z_AvailHeap ( void );                       // Returns largest available contiguous block
+int Z_UsedStaticHeap ( void );                  // Returns amount of heap which is static ( < PURGELEVEL )
+void Z_ShutDown( void );
+int Z_GetSize (void *ptr);
+int Z_UsedLevelHeap ( void );
+void Z_Realloc (void ** ptr, int newsize);
+
+#endif

Added: tags/rott-1.1/vs.net/rott.vcproj
===================================================================
--- tags/rott-1.1/vs.net/rott.vcproj	                        (rev 0)
+++ tags/rott-1.1/vs.net/rott.vcproj	2008-07-14 17:09:15 UTC (rev 239)
@@ -0,0 +1,616 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.00"
+	Name="rott"
+	ProjectGUID="{A70C3657-7C4E-481A-8729-5952458EC048}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="C:\SDL\include"
+				PreprocessorDefinitions="PLATFORM_WIN32;USE_SDL"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="1"
+				Detect64BitPortabilityProblems="FALSE"
+				DebugInformationFormat="4"
+				CompileAs="1"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="SDL.lib SDL_mixer.lib SDLmain.lib"
+				OutputFile="$(OutDir)/rott.exe"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="C:\SDL\lib"
+				IgnoreAllDefaultLibraries="FALSE"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/rott.pdb"
+				SubSystem="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="TRUE"
+				AdditionalIncludeDirectories="C:\SDL\include"
+				PreprocessorDefinitions="PLATFORM_WIN32;USE_SDL"
+				StringPooling="TRUE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="1"
+				Detect64BitPortabilityProblems="FALSE"
+				DebugInformationFormat="3"
+				CompileAs="1"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="SDL.lib SDL_mixer.lib SDLmain.lib"
+				OutputFile="$(OutDir)/rott.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="C:\SDL\lib"
+				IgnoreAllDefaultLibraries="FALSE"
+				GenerateDebugInformation="TRUE"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+		</Configuration>
+	</Configurations>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+			<File
+				RelativePath="..\rott\byteordr.c">
+			</File>
+			<File
+				RelativePath="..\rott\cin_actr.c">
+			</File>
+			<File
+				RelativePath="..\rott\cin_efct.c">
+			</File>
+			<File
+				RelativePath="..\rott\cin_evnt.c">
+			</File>
+			<File
+				RelativePath="..\rott\cin_glob.c">
+			</File>
+			<File
+				RelativePath="..\rott\cin_main.c">
+			</File>
+			<File
+				RelativePath="..\rott\cin_util.c">
+			</File>
+			<File
+				RelativePath="..\rott\dosutil.c">
+			</File>
+			<File
+				RelativePath="..\rott\engine.c">
+			</File>
+			<File
+				RelativePath="..\rott\fx_man.c">
+			</File>
+			<File
+				RelativePath="..\rott\isr.c">
+			</File>
+			<File
+				RelativePath="..\rott\modexlib.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_actor.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_battl.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_build.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_cfg.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_com.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_crc.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_debug.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_dmand.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_door.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_draw.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_err.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_floor.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_game.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_in.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_main.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_map.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_menu.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_msg.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_net.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_playr.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_rand.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_scale.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_sound.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_spbal.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_sqrt.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_stat.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_state.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_str.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_swift.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_ted.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_util.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_vid.c">
+			</File>
+			<File
+				RelativePath="..\rott\rt_view.c">
+			</File>
+			<File
+				RelativePath="..\rott\scriplib.c">
+			</File>
+			<File
+				RelativePath="..\rott\w_wad.c">
+			</File>
+			<File
+				RelativePath="..\rott\watcom.c">
+			</File>
+			<File
+				RelativePath="..\rott\z_zone.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc">
+			<File
+				RelativePath="..\rott\_engine.h">
+			</File>
+			<File
+				RelativePath="..\rott\_isr.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_acto.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_buil.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_com.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_dman.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_door.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_draw.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_film.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_floo.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_game.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_in.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_main.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_map.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_menu.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_msg.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_net.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_play.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_rand.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_scal.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_ser.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_soun.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_spba.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_stat.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_str.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_swft.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_ted.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_util.h">
+			</File>
+			<File
+				RelativePath="..\rott\_rt_vid.h">
+			</File>
+			<File
+				RelativePath="..\rott\_w_wad.h">
+			</File>
+			<File
+				RelativePath="..\rott\_z_zone.h">
+			</File>
+			<File
+				RelativePath="..\rott\byteordr.h">
+			</File>
+			<File
+				RelativePath="..\rott\cin_actr.h">
+			</File>
+			<File
+				RelativePath="..\rott\cin_def.h">
+			</File>
+			<File
+				RelativePath="..\rott\cin_efct.h">
+			</File>
+			<File
+				RelativePath="..\rott\cin_evnt.h">
+			</File>
+			<File
+				RelativePath="..\rott\cin_glob.h">
+			</File>
+			<File
+				RelativePath="..\rott\cin_main.h">
+			</File>
+			<File
+				RelativePath="..\rott\cin_util.h">
+			</File>
+			<File
+				RelativePath="..\rott\develop.h">
+			</File>
+			<File
+				RelativePath="..\rott\engine.h">
+			</File>
+			<File
+				RelativePath="..\rott\f_scale.h">
+			</File>
+			<File
+				RelativePath="..\rott\fli_def.h">
+			</File>
+			<File
+				RelativePath="..\rott\fli_glob.h">
+			</File>
+			<File
+				RelativePath="..\rott\fli_main.h">
+			</File>
+			<File
+				RelativePath="..\rott\fli_type.h">
+			</File>
+			<File
+				RelativePath="..\rott\fli_util.h">
+			</File>
+			<File
+				RelativePath="..\rott\fx_man.h">
+			</File>
+			<File
+				RelativePath="..\rott\gmove.h">
+			</File>
+			<File
+				RelativePath="..\rott\isr.h">
+			</File>
+			<File
+				RelativePath="..\rott\keyb.h">
+			</File>
+			<File
+				RelativePath="..\rott\lumpy.h">
+			</File>
+			<File
+				RelativePath="..\rott\memcheck.h">
+			</File>
+			<File
+				RelativePath="..\rott\modexlib.h">
+			</File>
+			<File
+				RelativePath="..\rott\mouse.h">
+			</File>
+			<File
+				RelativePath="..\rott\music.h">
+			</File>
+			<File
+				RelativePath="..\rott\myprint.h">
+			</File>
+			<File
+				RelativePath="..\rott\profile.h">
+			</File>
+			<File
+				RelativePath="..\rott\rottnet.h">
+			</File>
+			<File
+				RelativePath="..\rott\rottser.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_actor.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_battl.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_build.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_cfg.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_com.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_crc.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_debug.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_def.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_dmand.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_door.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_dr_a.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_draw.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_eng.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_error.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_fc_a.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_film.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_floor.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_game.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_in.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_main.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_map.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_menu.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_msg.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_net.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_playr.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_rand.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_sc_a.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_scale.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_ser.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_sound.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_spbal.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_sqrt.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_stat.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_str.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_swift.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_table.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_ted.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_util.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_vh_a.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_vid.h">
+			</File>
+			<File
+				RelativePath="..\rott\rt_view.h">
+			</File>
+			<File
+				RelativePath="..\rott\sbconfig.h">
+			</File>
+			<File
+				RelativePath="..\rott\scriplib.h">
+			</File>
+			<File
+				RelativePath="..\rott\snd_reg.h">
+			</File>
+			<File
+				RelativePath="..\rott\snd_shar.h">
+			</File>
+			<File
+				RelativePath="..\rott\sndcards.h">
+			</File>
+			<File
+				RelativePath="..\rott\splib.h">
+			</File>
+			<File
+				RelativePath="..\rott\sprites.h">
+			</File>
+			<File
+				RelativePath="..\rott\states.h">
+			</File>
+			<File
+				RelativePath="..\rott\task_man.h">
+			</File>
+			<File
+				RelativePath="..\rott\version.h">
+			</File>
+			<File
+				RelativePath="..\rott\w_wad.h">
+			</File>
+			<File
+				RelativePath="..\rott\watcom.h">
+			</File>
+			<File
+				RelativePath="..\rott\z_zone.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>


Property changes on: tags/rott-1.1/vs.net/rott.vcproj
___________________________________________________________________
Name: svn:executable
   + *




More information about the rott-commits mailing list