shithub: wl3d

Download patch

ref: 7137844284106fef0b1f5481d53ef40e16d699e2
author: Travis Bradshaw <travis.bradshaw@idsoftware.com>
date: Mon Feb 6 05:31:54 EST 2012

The Wolfenstein 3D source as originally released.

binary files /dev/null b/DEICE.EXE differ
--- /dev/null
+++ b/INSTALL.BAT
@@ -1,0 +1,12 @@
+@echo off
+DEICE.EXE
+if ERRORLEVEL == 1 GOTO END
+WOLFSRC.EXE -d
+if ERRORLEVEL == 1 GOTO ERROR
+DEL WOLFSRC.EXE
+GO
+goto END
+:ERROR
+echo Error installing WOLFSRC.EXE!
+:END
+
--- /dev/null
+++ b/README.rst
@@ -1,0 +1,208 @@
+Wolfenstein 3D
+==============
+
+The original source release was made using the DEICE.EXE installer (DeIce) in the root directory.  (Basically a way to split self-extracting zip files over multiple floppy disks.)  After execution, that installer will create the contents of the WOLFSRC directory.  In the "installed" directory, the the README.TXT, RELEASE.TXT, and LICENCE.DOC reside in the README directory.  They are duplicated below.
+
+Travis "Ash" Bradshaw
+travis.bradshaw@idsoftware.com
+February 6, 2012
+
+RELEASE.TXT
+-----------
+
+We are releasing this code for the entertainment of the 
+user community.  We don't guarentee that anything even 
+builds in here.  Projects just seem to rot when you leave 
+them alone for long periods of time.
+
+This is all the source we have relating to the original 
+PC wolfenstein 3D project.  We haven't looked at this 
+stuff in years, and I would probably be horribly embarassed 
+to dig through my old code, so please don't ask any questions 
+about it. The original project was built in borland c++ 3.0.  
+I think some minor changes were required for later versions.
+
+You will need the data from a released version of wolf or spear 
+to use the exe built from this code.  You can just use a 
+shareware version if you are really cheap.
+
+
+Some coding comments in retrospect:
+
+The ray casting refresh architecture is still reasonably 
+appropriate for the game.  A BSP based texture mapper could 
+go faster, but ray casting was a lot simpler to do at the time.
+
+The dynamically compiled scaling routines are now a Bad Thing.  
+On uncached machines (the original target) they are the fastest 
+possible way to scale walls, but on modern processors you just 
+wind up thrashing the code cash and wrecking performance.  
+A simple looping texture mapper would be faster on 486+ machines.
+
+The whole page manager caching scheme is unecessarily complex.
+
+Way too many #ifdefs in the code!
+
+
+Some project ideas with this code:
+
+Add new monsters or weapons.
+
+Add taller walls and vertical motion.   This should only be 
+done if the texture mapper is rewritten.
+
+Convert to a 32 bit compiler.  This would be a fair amount 
+of work, but I would hate to even mess with crusty old 16 
+bit code.  The code would get a LOT smaller.
+
+Make a multi-player game that runs on DOOM sersetup / ipxsetup drivers.
+
+
+Have fun...
+
+John Carmack
+Technical Director
+Id Software
+
+README.TXT
+----------
+
+NOTES:
+
+This version will compile under BORLAND C++ 3.0/3.1 and compiled perfectly
+before it was uploaded. 
+
+Please do not send your questions to id Software.
+
+LICENCE.DOC
+
+	LIMITED USE SOFTWARE LICENSE AGREEMENT
+
+	This Limited Use Software License Agreement (the "Agreement") 
+is a legal agreement between you, the end-user, and Id Software, Inc. 
+("ID").  By continuing the downloading of this Wolfenstein 3D 
+(the "Trademark") software material, which includes source code 
+(the "Source Code"), artwork data, music and software tools 
+(collectively, the "Software"), you are agreeing to be bound by the 
+terms of this Agreement.  If you do not agree to the terms of this 
+Agreement, promptly destroy the Software you may have downloaded.  
+
+ID SOFTWARE LICENSE
+
+	Grant of License.  ID grants to you the right to use one (1) 
+copy of the Software on a single computer.  You have no ownership or 
+proprietary rights in or to the Software, or the Trademark.  For purposes 
+of this section, "use" means loading the Software into RAM, as well as 
+installation on a hard disk or other storage device.  The Software, 
+together with any archive copy thereof, shall be destroyed when no longer 
+used in accordance with this Agreement, or when the right to use the 
+Software is terminated.  You agree that the Software will not be shipped, 
+transferred or exported into any country in violation of the U.S. 
+Export Administration Act (or any other law governing such matters) and 
+that you will not utilize, in any other manner, the Software in violation 
+of any applicable law.
+
+	Permitted Uses.  For educational purposes only, you, the end-user, 
+may use portions of the Source Code, such as particular routines, to 
+develop your own software, but may not duplicate the Source Code, except 
+as noted in paragraph 4.  The limited right referenced in the preceding 
+sentence is hereinafter referred to as "Educational Use."  By so exercising 
+the Educational Use right you shall not obtain any ownership, copyright,
+proprietary or other interest in or to the Source Code, or any portion of
+the Source Code.  You may dispose of your own software in your sole
+discretion.  With the exception of the Educational Use right, you may not
+otherwise use the Software, or an portion of the Software, which includes
+the Source Code, for commercial gain.
+
+	Prohibited Uses:  Under no circumstances shall you, the end-user, 
+be permitted, allowed or authorized to commercially exploit the Software.
+Neither you nor anyone at your direction shall do any of the following acts
+with regard to the Software, or any portion thereof:
+
+	Rent;
+
+	Sell;
+
+	Lease;
+
+	Offer on a pay-per-play basis;
+
+	Distribute for money or any other consideration; or
+
+	In any other manner and through any medium whatsoever commercially 
+exploit or use for any commercial purpose.
+
+Notwithstanding the foregoing prohibitions, you may commercially exploit the
+software you develop by exercising the Educational Use right, referenced in
+paragraph 2. hereinabove. 
+
+	Copyright.  The Software and all copyrights related thereto 
+(including all characters and other images generated by the Software 
+or depicted in the Software) are owned by ID and is protected by 
+United States copyright laws and international treaty provisions.  
+Id shall retain exclusive ownership and copyright in and to the Software 
+and all portions of the Software and you shall have no ownership or other 
+proprietary interest in such materials. You must treat the Software like 
+any other copyrighted material, except that you may either (a) make one 
+copy of the Software solely for back-up or archival purposes, or (b) 
+transfer the Software to a single hard disk provided you keep the original 
+solely for back-up or archival purposes.  You may not otherwise reproduce, 
+copy or disclose to others, in whole or in any part, the Software.  You 
+may not copy the written materials accompanying the Software.  You agree 
+to use your best efforts to see that any user of the Software licensed 
+hereunder complies with this Agreement.
+
+	NO WARRANTIES.  ID DISCLAIMS ALL WARRANTIES, BOTH EXPRESS IMPLIED,
+INCLUDING BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE WITH RESPECT TO THE SOFTWARE.  THIS LIMITED
+WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS.  YOU MAY HAVE OTHER RIGHTS WHICH
+VARY FROM JURISDICTION TO JURISDICTION.  ID DOES NOT WARRANT THAT THE
+OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED, ERROR FREE OR MEET YOUR
+SPECIFIC REQUIREMENTS.  THE WARRANTY SET FORTH ABOVE IS IN LIEU OF ALL OTHER
+EXPRESS WARRANTIES WHETHER ORAL OR WRITTEN.  THE AGENTS, EMPLOYEES,
+DISTRIBUTORS, AND DEALERS OF ID ARE NOT AUTHORIZED TO MAKE MODIFICATIONS TO
+THIS WARRANTY, OR ADDITIONAL WARRANTIES ON BEHALF OF ID. 
+
+	Exclusive Remedies.  The Software is being offered to you free of any
+charge.  You agree that you have no remedy against ID, its affiliates,
+contractors, suppliers, and agents for loss or damage caused by any defect
+or failure in the Software regardless of the form of action, whether in
+contract, tort, includinegligence, strict liability or otherwise, with
+regard to the Software.  This Agreement shall be construed in accordance
+with and governed by the laws of the State of Texas.  Copyright and other
+proprietary matters will be governed by United States laws and international
+treaties.  IN ANY CASE, ID SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF
+PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT OR OTHER
+SIMILAR DAMAGES ARISING FROM BREACH OF WARRANTY, BREACH OF CONTRACT,
+NEGLIGENCE, OR OTHER LEGAL THEORY EVEN IF ID OR ITS AGENT HAS BEEN ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+Some jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so the above limitation or exclusion may not apply to
+you.
+
+	General Provisions.  Neither this Agreement nor any part or portion 
+hereof shall be assigned, sublicensed or otherwise transferred by you.  
+Should any provision of this Agreement be held to be void, invalid, 
+unenforceable or illegal by a court, the validity and enforceability of the 
+other provisions shall not be affected thereby.  If any provision is 
+determined to be unenforceable, you agree to a modification of such 
+provision to provide for enforcement of the provision's intent, to the 
+extent permitted by applicable law.  Failure of a party to enforce any 
+provision of this Agreement shall not constitute or be construed as a 
+waiver of such provision or of the right to enforce such provision.  If 
+you fail to comply with any terms of this Agreement, YOUR LICENSE IS 
+AUTOMATICALLY TERMINATED and you agree to the issuance of an injunction 
+against you in favor of Id.  You agree that Id shall not have to post 
+bond or other security to obtain an injunction against you to prohibit 
+you from violating Id's rights.
+
+	YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, THAT YOU 
+UNDERSTAND THIS AGREEMENT, AND UNDERSTAND THAT BY CONTINUING THE 
+DOWNLOADING OF THE SOFTWARE, YOU AGREE TO BE BOUND BY THIS AGREEMENT'S 
+TERMS AND CONDITIONS. YOU FURTHER AGREE THAT, EXCEPT FOR WRITTEN SEPARATE 
+AGREEMENTS BETWEEN ID AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE 
+STATEMENT OF THE RIGHTS AND LIABILITIES OF THE PARTIES.  THIS AGREEMENT 
+SUPERSEDES ALL PRIOR ORAL AGREEMENTS, PROPOSALS OR UNDERSTANDINGS, AND 
+ANY OTHER COMMUNICATIONS BETWEEN ID AND YOU RELATING TO THE SUBJECT MATTER 
+OF THIS AGREEMENT 
+
binary files /dev/null b/WOLFSRC.1 differ
--- /dev/null
+++ b/WOLFSRC.DAT
@@ -1,0 +1,9 @@
+PATH=\WOLFSRC
+SIZE=566432
+EXPSIZE=1776000
+SPACE=0
+LINE0=Wolfenstein Source Code
+LINE1=Official Public Domain Release
+LINE3=Please *DO NOT* e-mail us with questions!
+LINE5=Have Fun!
+DEICE=F:\IDUTILS\DEICE.EXE
--- /dev/null
+++ b/WOLFSRC/AUDIOSDM.H
@@ -1,0 +1,142 @@
+/////////////////////////////////////////////////
+//
+// MUSE Header for .SDM
+// Created Thu Aug 27 07:12:39 1992
+//
+/////////////////////////////////////////////////
+
+#define NUMSOUNDS		81
+#define NUMSNDCHUNKS		267
+
+//
+// Sound names & indexes
+//
+typedef enum {
+		HITWALLSND,              // 0
+		MISSILEHITSND,           // 1
+		SELECTITEMSND,           // 2
+		GHOSTSIGHTSND,           // 3
+		MOVEGUN2SND,             // 4
+		MOVEGUN1SND,             // 5
+		NOWAYSND,                // 6
+		NAZIHITPLAYERSND,        // 7
+		MISSILEFIRESND,          // 8
+		PLAYERDEATHSND,          // 9
+		DOGDEATHSND,             // 10
+		ATKGATLINGSND,           // 11
+		GETKEYSND,               // 12
+		NOITEMSND,               // 13
+		WALK1SND,                // 14
+		WALK2SND,                // 15
+		TAKEDAMAGESND,           // 16
+		GAMEOVERSND,             // 17
+		OPENDOORSND,             // 18
+		CLOSEDOORSND,            // 19
+		DONOTHINGSND,            // 20
+		HALTSND,                 // 21
+		DEATHSCREAM2SND,         // 22
+		ATKKNIFESND,             // 23
+		ATKPISTOLSND,            // 24
+		DEATHSCREAM3SND,         // 25
+		ATKMACHINEGUNSND,        // 26
+		HITENEMYSND,             // 27
+		SHOOTDOORSND,            // 28
+		DEATHSCREAM1SND,         // 29
+		GETMACHINESND,           // 30
+		GETAMMOSND,              // 31
+		SHOOTSND,                // 32
+		HEALTH1SND,              // 33
+		HEALTH2SND,              // 34
+		BONUS1SND,               // 35
+		BONUS2SND,               // 36
+		BONUS3SND,               // 37
+		GETGATLINGSND,           // 38
+		ESCPRESSEDSND,           // 39
+		LEVELDONESND,            // 40
+		DOGBARKSND,              // 41
+		ENDBONUS1SND,            // 42
+		ENDBONUS2SND,            // 43
+		BONUS1UPSND,             // 44
+		BONUS4SND,               // 45
+		PUSHWALLSND,             // 46
+		NOBONUSSND,              // 47
+		PERCENT100SND,           // 48
+		BOSSACTIVESND,           // 49
+		DEATHSCREAM4SND,         // 50
+		SCHUTZADSND,             // 51
+		AHHHGSND,                // 52
+		DEATHSCREAM5SND,         // 53
+		DEATHSCREAM7SND,         // 54
+		DEATHSCREAM8SND,         // 55
+		LEBENSND,                // 56
+		DEATHSCREAM6SND,         // 57
+		NAZIFIRESND,             // 58
+		BOSSFIRESND,             // 59
+		SSFIRESND,               // 60
+		SLURPIESND,              // 61
+		GHOSTFADESND,            // 62
+		DEATHSCREAM9SND,         // 63
+		GETAMMOBOXSND,           // 64
+		ANGELSIGHTSND,           // 65
+		SPIONSND,                // 66
+		NEINSOVASSND,            // 67
+		DOGATTACKSND,            // 68
+		ANGELFIRESND,            // 69
+		TRANSSIGHTSND,           // 70
+		TRANSDEATHSND,           // 71
+		WILHELMSIGHTSND,         // 72
+		WILHELMDEATHSND,         // 73
+		UBERDEATHSND,            // 74
+		KNIGHTSIGHTSND,          // 75
+		KNIGHTDEATHSND,          // 76
+		ANGELDEATHSND,           // 77
+		KNIGHTMISSILESND,        // 78
+		GETSPEARSND,             // 79
+		ANGELTIREDSND,           // 80
+		LASTSOUND
+	     } soundnames;
+
+//
+// Base offsets
+//
+#define STARTPCSOUNDS		0
+#define STARTADLIBSOUNDS	81
+#define STARTDIGISOUNDS		162
+#define STARTMUSIC		243
+
+//
+// Music names & indexes
+//
+typedef enum {
+		XFUNKIE_MUS,             // 0
+		DUNGEON_MUS,             // 1
+		XDEATH_MUS,              // 2
+		GETTHEM_MUS,             // 3
+		XTIPTOE_MUS,             // 4
+		GOINGAFT_MUS,            // 5
+		URAHERO_MUS,             // 6
+		XTHEEND_MUS,             // 7
+		NAZI_OMI_MUS,            // 8
+		POW_MUS,                 // 9
+		TWELFTH_MUS,             // 10
+		SEARCHN_MUS,             // 11
+		SUSPENSE_MUS,            // 12
+		ZEROHOUR_MUS,            // 13
+		WONDERIN_MUS,            // 14
+		ULTIMATE_MUS,            // 15
+		ENDLEVEL_MUS,            // 16
+		XEVIL_MUS,               // 17
+		XJAZNAZI_MUS,            // 18
+		COPYPRO_MUS,             // 19
+		XAWARD_MUS,              // 20
+		XPUTIT_MUS,              // 21
+		XGETYOU_MUS,             // 22
+		XTOWER2_MUS,             // 23
+		LASTMUSIC
+	     } musicnames;
+
+/////////////////////////////////////////////////
+//
+// Thanks for playing with MUSE!
+//
+/////////////////////////////////////////////////
--- /dev/null
+++ b/WOLFSRC/AUDIOSOD.H
@@ -1,0 +1,142 @@
+/////////////////////////////////////////////////
+//
+// MUSE Header for .SOD
+// Created Thu Aug 13 09:25:58 1992
+//
+/////////////////////////////////////////////////
+
+#define NUMSOUNDS		81
+#define NUMSNDCHUNKS		267
+
+//
+// Sound names & indexes
+//
+typedef enum {
+		HITWALLSND,              // 0
+		MISSILEHITSND,           // 1
+		SELECTITEMSND,           // 2
+		GHOSTSIGHTSND,           // 3
+		MOVEGUN2SND,             // 4
+		MOVEGUN1SND,             // 5
+		NOWAYSND,                // 6
+		NAZIHITPLAYERSND,        // 7
+		MISSILEFIRESND,          // 8
+		PLAYERDEATHSND,          // 9
+		DOGDEATHSND,             // 10
+		ATKGATLINGSND,           // 11
+		GETKEYSND,               // 12
+		NOITEMSND,               // 13
+		WALK1SND,                // 14
+		WALK2SND,                // 15
+		TAKEDAMAGESND,           // 16
+		GAMEOVERSND,             // 17
+		OPENDOORSND,             // 18
+		CLOSEDOORSND,            // 19
+		DONOTHINGSND,            // 20
+		HALTSND,                 // 21
+		DEATHSCREAM2SND,         // 22
+		ATKKNIFESND,             // 23
+		ATKPISTOLSND,            // 24
+		DEATHSCREAM3SND,         // 25
+		ATKMACHINEGUNSND,        // 26
+		HITENEMYSND,             // 27
+		SHOOTDOORSND,            // 28
+		DEATHSCREAM1SND,         // 29
+		GETMACHINESND,           // 30
+		GETAMMOSND,              // 31
+		SHOOTSND,                // 32
+		HEALTH1SND,              // 33
+		HEALTH2SND,              // 34
+		BONUS1SND,               // 35
+		BONUS2SND,               // 36
+		BONUS3SND,               // 37
+		GETGATLINGSND,           // 38
+		ESCPRESSEDSND,           // 39
+		LEVELDONESND,            // 40
+		DOGBARKSND,              // 41
+		ENDBONUS1SND,            // 42
+		ENDBONUS2SND,            // 43
+		BONUS1UPSND,             // 44
+		BONUS4SND,               // 45
+		PUSHWALLSND,             // 46
+		NOBONUSSND,              // 47
+		PERCENT100SND,           // 48
+		BOSSACTIVESND,           // 49
+		DEATHSCREAM4SND,         // 50
+		SCHUTZADSND,             // 51
+		AHHHGSND,                // 52
+		DEATHSCREAM5SND,         // 53
+		DEATHSCREAM7SND,         // 54
+		DEATHSCREAM8SND,         // 55
+		LEBENSND,                // 56
+		DEATHSCREAM6SND,         // 57
+		NAZIFIRESND,             // 58
+		BOSSFIRESND,             // 59
+		SSFIRESND,               // 60
+		SLURPIESND,              // 61
+		GHOSTFADESND,            // 62
+		DEATHSCREAM9SND,         // 63
+		GETAMMOBOXSND,           // 64
+		ANGELSIGHTSND,           // 65
+		SPIONSND,                // 66
+		NEINSOVASSND,            // 67
+		DOGATTACKSND,            // 68
+		ANGELFIRESND,            // 69
+		TRANSSIGHTSND,           // 70
+		TRANSDEATHSND,           // 71
+		WILHELMSIGHTSND,         // 72
+		WILHELMDEATHSND,         // 73
+		UBERDEATHSND,            // 74
+		KNIGHTSIGHTSND,          // 75
+		KNIGHTDEATHSND,          // 76
+		ANGELDEATHSND,           // 77
+		KNIGHTMISSILESND,        // 78
+		GETSPEARSND,             // 79
+		ANGELTIREDSND,           // 80
+		LASTSOUND
+	     } soundnames;
+
+//
+// Base offsets
+//
+#define STARTPCSOUNDS		0
+#define STARTADLIBSOUNDS	81
+#define STARTDIGISOUNDS		162
+#define STARTMUSIC		243
+
+//
+// Music names & indexes
+//
+typedef enum {
+		XFUNKIE_MUS,             // 0
+		DUNGEON_MUS,             // 1
+		XDEATH_MUS,              // 2
+		GETTHEM_MUS,             // 3
+		XTIPTOE_MUS,             // 4
+		GOINGAFT_MUS,            // 5
+		URAHERO_MUS,             // 6
+		XTHEEND_MUS,             // 7
+		NAZI_OMI_MUS,            // 8
+		POW_MUS,                 // 9
+		TWELFTH_MUS,             // 10
+		SEARCHN_MUS,             // 11
+		SUSPENSE_MUS,            // 12
+		ZEROHOUR_MUS,            // 13
+		WONDERIN_MUS,            // 14
+		ULTIMATE_MUS,            // 15
+		ENDLEVEL_MUS,            // 16
+		XEVIL_MUS,               // 17
+		XJAZNAZI_MUS,            // 18
+		COPYPRO_MUS,             // 19
+		XAWARD_MUS,              // 20
+		XPUTIT_MUS,              // 21
+		XGETYOU_MUS,             // 22
+		XTOWER2_MUS,             // 23
+		LASTMUSIC
+	     } musicnames;
+
+/////////////////////////////////////////////////
+//
+// Thanks for playing with MUSE!
+//
+/////////////////////////////////////////////////
--- /dev/null
+++ b/WOLFSRC/AUDIOWL1.H
@@ -1,0 +1,133 @@
+/////////////////////////////////////////////////
+//
+// MUSE Header for .WL1
+// Created Tue Apr 28 23:57:08 1992
+//
+/////////////////////////////////////////////////
+
+#define NUMSOUNDS		69
+#define NUMSNDCHUNKS		234
+
+//
+// Sound names & indexes
+//
+typedef enum {
+		HITWALLSND,              // 0
+		SELECTWPNSND,            // 1
+		SELECTITEMSND,           // 2
+		HEARTBEATSND,            // 3
+		MOVEGUN2SND,             // 4
+		MOVEGUN1SND,             // 5
+		NOWAYSND,                // 6
+		NAZIHITPLAYERSND,        // 7
+		NAZIMISSSND,             // 8
+		PLAYERDEATHSND,          // 9
+		DOGDEATHSND,             // 10
+		ATKGATLINGSND,           // 11
+		GETKEYSND,               // 12
+		NOITEMSND,               // 13
+		WALK1SND,                // 14
+		WALK2SND,                // 15
+		TAKEDAMAGESND,           // 16
+		GAMEOVERSND,             // 17
+		OPENDOORSND,             // 18
+		CLOSEDOORSND,            // 19
+		DONOTHINGSND,            // 20
+		HALTSND,                 // 21
+		DEATHSCREAM2SND,         // 22
+		ATKKNIFESND,             // 23
+		ATKPISTOLSND,            // 24
+		DEATHSCREAM3SND,         // 25
+		ATKMACHINEGUNSND,        // 26
+		HITENEMYSND,             // 27
+		SHOOTDOORSND,            // 28
+		DEATHSCREAM1SND,         // 29
+		GETMACHINESND,           // 30
+		GETAMMOSND,              // 31
+		SHOOTSND,                // 32
+		HEALTH1SND,              // 33
+		HEALTH2SND,              // 34
+		BONUS1SND,               // 35
+		BONUS2SND,               // 36
+		BONUS3SND,               // 37
+		GETGATLINGSND,           // 38
+		ESCPRESSEDSND,           // 39
+		LEVELDONESND,            // 40
+		DOGBARKSND,              // 41
+		ENDBONUS1SND,            // 42
+		ENDBONUS2SND,            // 43
+		BONUS1UPSND,             // 44
+		BONUS4SND,               // 45
+		PUSHWALLSND,             // 46
+		NOBONUSSND,              // 47
+		PERCENT100SND,           // 48
+		BOSSACTIVESND,           // 49
+		BOSSDIESSND,             // 50
+		SCHUTZADSND,             // 51
+		AHHHGSND,                // 52
+		DIESND,                  // 53
+		EVASND,                  // 54
+		GUTENTAGSND,             // 55
+		LEBENSND,                // 56
+		MUTTISND,                // 57
+		NAZIFIRESND,             // 58
+		BOSSFIRESND,             // 59
+		SSFIRESND,               // 60
+		SLURPIESND,              // 61
+		TOT_HUNDSND,             // 62
+		MEINGOTTSND,             // 63
+		SCHABBSHASND,            // 64
+		HILTERHASND,             // 65
+		SPIONSND,                // 66
+		NEINSOVASSND,            // 67
+		DOGATTACKSND,            // 68
+		LASTSOUND
+	     } soundnames;
+
+//
+// Base offsets
+//
+#define STARTPCSOUNDS		0
+#define STARTADLIBSOUNDS	69
+#define STARTDIGISOUNDS		138
+#define STARTMUSIC		207
+
+//
+// Music names & indexes
+//
+typedef enum {
+		CORNER_MUS,              // 0
+		DUNGEON_MUS,             // 1
+		GETOUT_MUS,              // 2
+		GETTHEM_MUS,             // 3
+		HEADACHE_MUS,            // 4
+		HITLWLTZ_MUS,            // 5
+		INTROCW3_MUS,            // 6
+		NAZI_NOR_MUS,            // 7
+		NAZI_OMI_MUS,            // 8
+		POW_MUS,                 // 9
+		SALUTE_MUS,              // 10
+		SEARCHN_MUS,             // 11
+		SUSPENSE_MUS,            // 12
+		VICTORS_MUS,             // 13
+		WONDERIN_MUS,            // 14
+		FUNKYOU_MUS,             // 15
+		ENDLEVEL_MUS,            // 16
+		GOINGAFT_MUS,            // 17
+		PREGNANT_MUS,            // 18
+		ULTIMATE_MUS,            // 19
+		NAZI_RAP_MUS,            // 20
+		ZEROHOUR_MUS,            // 21
+		TWELFTH_MUS,             // 22
+		ROSTER_MUS,              // 23
+		URAHERO_MUS,             // 24
+		VICMARCH_MUS,            // 25
+		WARMRCH1_MUS,            // 26
+		LASTMUSIC
+	     } musicnames;
+
+/////////////////////////////////////////////////
+//
+// Thanks for playing with MUSE!
+//
+/////////////////////////////////////////////////
--- /dev/null
+++ b/WOLFSRC/AUDIOWL6.H
@@ -1,0 +1,151 @@
+/////////////////////////////////////////////////
+//
+// MUSE Header for .WL6
+// Created Tue Jul 14 15:04:53 1992
+//
+/////////////////////////////////////////////////
+
+#define NUMSOUNDS		87
+#define NUMSNDCHUNKS		288
+
+//
+// Sound names & indexes
+//
+typedef enum {
+		HITWALLSND,              // 0
+		SELECTWPNSND,            // 1
+		SELECTITEMSND,           // 2
+		HEARTBEATSND,            // 3
+		MOVEGUN2SND,             // 4
+		MOVEGUN1SND,             // 5
+		NOWAYSND,                // 6
+		NAZIHITPLAYERSND,        // 7
+		SCHABBSTHROWSND,         // 8
+		PLAYERDEATHSND,          // 9
+		DOGDEATHSND,             // 10
+		ATKGATLINGSND,           // 11
+		GETKEYSND,               // 12
+		NOITEMSND,               // 13
+		WALK1SND,                // 14
+		WALK2SND,                // 15
+		TAKEDAMAGESND,           // 16
+		GAMEOVERSND,             // 17
+		OPENDOORSND,             // 18
+		CLOSEDOORSND,            // 19
+		DONOTHINGSND,            // 20
+		HALTSND,                 // 21
+		DEATHSCREAM2SND,         // 22
+		ATKKNIFESND,             // 23
+		ATKPISTOLSND,            // 24
+		DEATHSCREAM3SND,         // 25
+		ATKMACHINEGUNSND,        // 26
+		HITENEMYSND,             // 27
+		SHOOTDOORSND,            // 28
+		DEATHSCREAM1SND,         // 29
+		GETMACHINESND,           // 30
+		GETAMMOSND,              // 31
+		SHOOTSND,                // 32
+		HEALTH1SND,              // 33
+		HEALTH2SND,              // 34
+		BONUS1SND,               // 35
+		BONUS2SND,               // 36
+		BONUS3SND,               // 37
+		GETGATLINGSND,           // 38
+		ESCPRESSEDSND,           // 39
+		LEVELDONESND,            // 40
+		DOGBARKSND,              // 41
+		ENDBONUS1SND,            // 42
+		ENDBONUS2SND,            // 43
+		BONUS1UPSND,             // 44
+		BONUS4SND,               // 45
+		PUSHWALLSND,             // 46
+		NOBONUSSND,              // 47
+		PERCENT100SND,           // 48
+		BOSSACTIVESND,           // 49
+		MUTTISND,                // 50
+		SCHUTZADSND,             // 51
+		AHHHGSND,                // 52
+		DIESND,                  // 53
+		EVASND,                  // 54
+		GUTENTAGSND,             // 55
+		LEBENSND,                // 56
+		SCHEISTSND,              // 57
+		NAZIFIRESND,             // 58
+		BOSSFIRESND,             // 59
+		SSFIRESND,               // 60
+		SLURPIESND,              // 61
+		TOT_HUNDSND,             // 62
+		MEINGOTTSND,             // 63
+		SCHABBSHASND,            // 64
+		HITLERHASND,             // 65
+		SPIONSND,                // 66
+		NEINSOVASSND,            // 67
+		DOGATTACKSND,            // 68
+		FLAMETHROWERSND,         // 69
+		MECHSTEPSND,             // 70
+		GOOBSSND,                // 71
+		YEAHSND,                 // 72
+		DEATHSCREAM4SND,         // 73
+		DEATHSCREAM5SND,         // 74
+		DEATHSCREAM6SND,         // 75
+		DEATHSCREAM7SND,         // 76
+		DEATHSCREAM8SND,         // 77
+		DEATHSCREAM9SND,         // 78
+		DONNERSND,               // 79
+		EINESND,                 // 80
+		ERLAUBENSND,             // 81
+		KEINSND,                 // 82
+		MEINSND,                 // 83
+		ROSESND,                 // 84
+		MISSILEFIRESND,          // 85
+		MISSILEHITSND,           // 86
+		LASTSOUND
+	     } soundnames;
+
+//
+// Base offsets
+//
+#define STARTPCSOUNDS		0
+#define STARTADLIBSOUNDS	87
+#define STARTDIGISOUNDS		174
+#define STARTMUSIC		261
+
+//
+// Music names & indexes
+//
+typedef enum {
+		CORNER_MUS,              // 0
+		DUNGEON_MUS,             // 1
+		WARMARCH_MUS,            // 2
+		GETTHEM_MUS,             // 3
+		HEADACHE_MUS,            // 4
+		HITLWLTZ_MUS,            // 5
+		INTROCW3_MUS,            // 6
+		NAZI_NOR_MUS,            // 7
+		NAZI_OMI_MUS,            // 8
+		POW_MUS,                 // 9
+		SALUTE_MUS,              // 10
+		SEARCHN_MUS,             // 11
+		SUSPENSE_MUS,            // 12
+		VICTORS_MUS,             // 13
+		WONDERIN_MUS,            // 14
+		FUNKYOU_MUS,             // 15
+		ENDLEVEL_MUS,            // 16
+		GOINGAFT_MUS,            // 17
+		PREGNANT_MUS,            // 18
+		ULTIMATE_MUS,            // 19
+		NAZI_RAP_MUS,            // 20
+		ZEROHOUR_MUS,            // 21
+		TWELFTH_MUS,             // 22
+		ROSTER_MUS,              // 23
+		URAHERO_MUS,             // 24
+		VICMARCH_MUS,            // 25
+		PACMAN_MUS,              // 26
+		LASTMUSIC
+	     } musicnames;
+
+/////////////////////////////////////////////////
+//
+// Thanks for playing with MUSE!
+//
+/////////////////////////////////////////////////
--- /dev/null
+++ b/WOLFSRC/BUDIOSOD.H
@@ -1,0 +1,142 @@
+/////////////////////////////////////////////////
+//
+// MUSE Header for .SOD
+// Created Thu Aug 13 09:25:58 1992
+//
+/////////////////////////////////////////////////
+
+#define NUMSOUNDS		81
+#define NUMSNDCHUNKS		267
+
+//
+// Sound names & indexes
+//
+typedef enum {
+		HITWALLSND,              // 0
+		MISSILEHITSND,           // 1
+		SELECTITEMSND,           // 2
+		GHOSTSIGHTSND,           // 3
+		MOVEGUN2SND,             // 4
+		MOVEGUN1SND,             // 5
+		NOWAYSND,                // 6
+		NAZIHITPLAYERSND,        // 7
+		MISSILEFIRESND,          // 8
+		PLAYERDEATHSND,          // 9
+		DOGDEATHSND,             // 10
+		ATKGATLINGSND,           // 11
+		GETKEYSND,               // 12
+		NOITEMSND,               // 13
+		WALK1SND,                // 14
+		WALK2SND,                // 15
+		TAKEDAMAGESND,           // 16
+		GAMEOVERSND,             // 17
+		OPENDOORSND,             // 18
+		CLOSEDOORSND,            // 19
+		DONOTHINGSND,            // 20
+		HALTSND,                 // 21
+		DEATHSCREAM2SND,         // 22
+		ATKKNIFESND,             // 23
+		ATKPISTOLSND,            // 24
+		DEATHSCREAM3SND,         // 25
+		ATKMACHINEGUNSND,        // 26
+		HITENEMYSND,             // 27
+		SHOOTDOORSND,            // 28
+		DEATHSCREAM1SND,         // 29
+		GETMACHINESND,           // 30
+		GETAMMOSND,              // 31
+		SHOOTSND,                // 32
+		HEALTH1SND,              // 33
+		HEALTH2SND,              // 34
+		BONUS1SND,               // 35
+		BONUS2SND,               // 36
+		BONUS3SND,               // 37
+		GETGATLINGSND,           // 38
+		ESCPRESSEDSND,           // 39
+		LEVELDONESND,            // 40
+		DOGBARKSND,              // 41
+		ENDBONUS1SND,            // 42
+		ENDBONUS2SND,            // 43
+		BONUS1UPSND,             // 44
+		BONUS4SND,               // 45
+		PUSHWALLSND,             // 46
+		NOBONUSSND,              // 47
+		PERCENT100SND,           // 48
+		BOSSACTIVESND,           // 49
+		DEATHSCREAM4SND,         // 50
+		SCHUTZADSND,             // 51
+		AHHHGSND,                // 52
+		DEATHSCREAM5SND,         // 53
+		DEATHSCREAM7SND,         // 54
+		DEATHSCREAM8SND,         // 55
+		LEBENSND,                // 56
+		DEATHSCREAM6SND,         // 57
+		NAZIFIRESND,             // 58
+		BOSSFIRESND,             // 59
+		SSFIRESND,               // 60
+		SLURPIESND,              // 61
+		GHOSTFADESND,            // 62
+		DEATHSCREAM9SND,         // 63
+		GETAMMOBOXSND,           // 64
+		ANGELSIGHTSND,           // 65
+		SPIONSND,                // 66
+		NEINSOVASSND,            // 67
+		DOGATTACKSND,            // 68
+		ANGELFIRESND,            // 69
+		TRANSSIGHTSND,           // 70
+		TRANSDEATHSND,           // 71
+		WILHELMSIGHTSND,         // 72
+		WILHELMDEATHSND,         // 73
+		UBERDEATHSND,            // 74
+		KNIGHTSIGHTSND,          // 75
+		KNIGHTDEATHSND,          // 76
+		ANGELDEATHSND,           // 77
+		KNIGHTMISSILESND,        // 78
+		GETSPEARSND,             // 79
+		ANGELTIREDSND,           // 80
+		LASTSOUND
+	     } soundnames;
+
+//
+// Base offsets
+//
+#define STARTPCSOUNDS		0
+#define STARTADLIBSOUNDS	81
+#define STARTDIGISOUNDS		162
+#define STARTMUSIC		243
+
+//
+// Music names & indexes
+//
+typedef enum {
+		XFUNKIE_MUS,             // 0
+		DUNGEON_MUS,             // 1
+		XDEATH_MUS,              // 2
+		GETTHEM_MUS,             // 3
+		XTIPTOE_MUS,             // 4
+		GOINGAFT_MUS,            // 5
+		URAHERO_MUS,             // 6
+		XTHEEND_MUS,             // 7
+		NAZI_OMI_MUS,            // 8
+		POW_MUS,                 // 9
+		TWELFTH_MUS,             // 10
+		SEARCHN_MUS,             // 11
+		SUSPENSE_MUS,            // 12
+		ZEROHOUR_MUS,            // 13
+		WONDERIN_MUS,            // 14
+		ULTIMATE_MUS,            // 15
+		ENDLEVEL_MUS,            // 16
+		XEVIL_MUS,               // 17
+		XJAZNAZI_MUS,            // 18
+		COPYPRO_MUS,             // 19
+		XAWARD_MUS,              // 20
+		XPUTIT_MUS,              // 21
+		XGETYOU_MUS,             // 22
+		XTOWER2_MUS,             // 23
+		LASTMUSIC
+	     } musicnames;
+
+/////////////////////////////////////////////////
+//
+// Thanks for playing with MUSE!
+//
+/////////////////////////////////////////////////
--- /dev/null
+++ b/WOLFSRC/BUDIOWL6.H
@@ -1,0 +1,151 @@
+/////////////////////////////////////////////////
+//
+// MUSE Header for .WL6
+// Created Sat May 30 18:41:31 1992
+//
+/////////////////////////////////////////////////
+
+#define NUMSOUNDS		87
+#define NUMSNDCHUNKS		288
+
+//
+// Sound names & indexes
+//
+typedef enum {
+		HITWALLSND,              // 0
+		SELECTWPNSND,            // 1
+		SELECTITEMSND,           // 2
+		HEARTBEATSND,            // 3
+		MOVEGUN2SND,             // 4
+		MOVEGUN1SND,             // 5
+		NOWAYSND,                // 6
+		NAZIHITPLAYERSND,        // 7
+		SCHABBSTHROWSND,         // 8
+		PLAYERDEATHSND,          // 9
+		DOGDEATHSND,             // 10
+		ATKGATLINGSND,           // 11
+		GETKEYSND,               // 12
+		NOITEMSND,               // 13
+		WALK1SND,                // 14
+		WALK2SND,                // 15
+		TAKEDAMAGESND,           // 16
+		GAMEOVERSND,             // 17
+		OPENDOORSND,             // 18
+		CLOSEDOORSND,            // 19
+		DONOTHINGSND,            // 20
+		HALTSND,                 // 21
+		DEATHSCREAM2SND,         // 22
+		ATKKNIFESND,             // 23
+		ATKPISTOLSND,            // 24
+		DEATHSCREAM3SND,         // 25
+		ATKMACHINEGUNSND,        // 26
+		HITENEMYSND,             // 27
+		SHOOTDOORSND,            // 28
+		DEATHSCREAM1SND,         // 29
+		GETMACHINESND,           // 30
+		GETAMMOSND,              // 31
+		SHOOTSND,                // 32
+		HEALTH1SND,              // 33
+		HEALTH2SND,              // 34
+		BONUS1SND,               // 35
+		BONUS2SND,               // 36
+		BONUS3SND,               // 37
+		GETGATLINGSND,           // 38
+		ESCPRESSEDSND,           // 39
+		LEVELDONESND,            // 40
+		DOGBARKSND,              // 41
+		ENDBONUS1SND,            // 42
+		ENDBONUS2SND,            // 43
+		BONUS1UPSND,             // 44
+		BONUS4SND,               // 45
+		PUSHWALLSND,             // 46
+		NOBONUSSND,              // 47
+		PERCENT100SND,           // 48
+		BOSSACTIVESND,           // 49
+		MUTTISND,                // 50
+		SCHUTZADSND,             // 51
+		AHHHGSND,                // 52
+		DIESND,                  // 53
+		EVASND,                  // 54
+		GUTENTAGSND,             // 55
+		LEBENSND,                // 56
+		SCHEISTSND,              // 57
+		NAZIFIRESND,             // 58
+		BOSSFIRESND,             // 59
+		SSFIRESND,               // 60
+		SLURPIESND,              // 61
+		TOT_HUNDSND,             // 62
+		MEINGOTTSND,             // 63
+		SCHABBSHASND,            // 64
+		HITLERHASND,             // 65
+		SPIONSND,                // 66
+		NEINSOVASSND,            // 67
+		DOGATTACKSND,            // 68
+		FLAMETHROWERSND,         // 69
+		MECHSTEPSND,             // 70
+		GOOBSSND,                // 71
+		YEAHSND,                 // 72
+		DEATHSCREAM4SND,         // 73
+		DEATHSCREAM5SND,         // 74
+		DEATHSCREAM6SND,         // 75
+		DEATHSCREAM7SND,         // 76
+		DEATHSCREAM8SND,         // 77
+		DEATHSCREAM9SND,         // 78
+		DONNERSND,               // 79
+		EINESND,                 // 80
+		ERLAUBENSND,             // 81
+		KEINSND,                 // 82
+		MEINSND,                 // 83
+		ROSESND,                 // 84
+		MISSILEFIRESND,          // 85
+		MISSILEHITSND,           // 86
+		LASTSOUND
+	     } soundnames;
+
+//
+// Base offsets
+//
+#define STARTPCSOUNDS		0
+#define STARTADLIBSOUNDS	87
+#define STARTDIGISOUNDS		174
+#define STARTMUSIC		261
+
+//
+// Music names & indexes
+//
+typedef enum {
+		CORNER_MUS,              // 0
+		DUNGEON_MUS,             // 1
+		WARMARCH_MUS,            // 2
+		GETTHEM_MUS,             // 3
+		HEADACHE_MUS,            // 4
+		HITLWLTZ_MUS,            // 5
+		INTROCW3_MUS,            // 6
+		NAZI_NOR_MUS,            // 7
+		NAZI_OMI_MUS,            // 8
+		POW_MUS,                 // 9
+		SALUTE_MUS,              // 10
+		SEARCHN_MUS,             // 11
+		SUSPENSE_MUS,            // 12
+		VICTORS_MUS,             // 13
+		WONDERIN_MUS,            // 14
+		FUNKYOU_MUS,             // 15
+		ENDLEVEL_MUS,            // 16
+		GOINGAFT_MUS,            // 17
+		PREGNANT_MUS,            // 18
+		ULTIMATE_MUS,            // 19
+		NAZI_RAP_MUS,            // 20
+		ZEROHOUR_MUS,            // 21
+		TWELFTH_MUS,             // 22
+		ROSTER_MUS,              // 23
+		URAHERO_MUS,             // 24
+		VICMARCH_MUS,            // 25
+		PACMAN_MUS,              // 26
+		LASTMUSIC
+	     } musicnames;
+
+/////////////////////////////////////////////////
+//
+// Thanks for playing with MUSE!
+//
+/////////////////////////////////////////////////
--- /dev/null
+++ b/WOLFSRC/C0.ASM
@@ -1,0 +1,841 @@
+        NAME    c0
+        PAGE    60,132
+        LOCALS
+;[]------------------------------------------------------------[]
+;|      C0.ASM -- Start Up Code                                 |
+;|                                                              |
+;|      Turbo C++ Run Time Library                              |
+;|                                                              |
+;|      Copyright (c) 1987, 1991 by Borland International Inc.  |
+;|      All Rights Reserved.                                    |
+;[]------------------------------------------------------------[]
+
+                __C0__ = 1
+INCLUDE         RULES.ASI
+
+;       Segment and Group declarations
+
+_TEXT           SEGMENT BYTE PUBLIC 'CODE'
+                ENDS
+_FARDATA        SEGMENT PARA PUBLIC 'FAR_DATA'
+                ENDS
+_FARBSS         SEGMENT PARA PUBLIC 'FAR_BSS'
+                ENDS
+IFNDEF __TINY__
+_OVERLAY_       SEGMENT PARA PUBLIC 'OVRINFO'
+        ENDS
+_1STUB_     SEGMENT PARA PUBLIC 'STUBSEG'
+        ENDS
+ENDIF
+_DATA           SEGMENT PARA PUBLIC 'DATA'
+                ENDS
+_INIT_          SEGMENT WORD PUBLIC 'INITDATA'
+InitStart       label byte
+                ENDS
+_INITEND_       SEGMENT BYTE PUBLIC 'INITDATA'
+InitEnd         label byte
+                ENDS
+_EXIT_          SEGMENT WORD PUBLIC 'EXITDATA'
+ExitStart       label byte
+                ENDS
+_EXITEND_       SEGMENT BYTE PUBLIC 'EXITDATA'
+ExitEnd         label byte
+                ENDS
+_CVTSEG         SEGMENT WORD PUBLIC 'DATA'
+                ENDS
+_SCNSEG         SEGMENT WORD PUBLIC 'DATA'
+                ENDS
+IFNDEF __HUGE__
+  _BSS          SEGMENT WORD PUBLIC 'BSS'
+                ENDS
+  _BSSEND       SEGMENT BYTE PUBLIC 'BSSEND'
+                ENDS
+ENDIF
+IFNDEF __TINY__
+  _STACK        SEGMENT STACK 'STACK'
+                ENDS
+ENDIF
+
+        ASSUME  CS:_TEXT, DS:DGROUP
+
+;       External References
+
+extrn       _main:DIST
+extrn       _exit:DIST
+extrn       __exit:DIST
+extrn       __nfile:word
+extrn       __setupio:near          ;required!
+extrn       __stklen:word
+IF LDATA EQ false
+extrn       __heaplen:word
+ENDIF
+
+        SUBTTL  Start Up Code
+        PAGE
+;/*                                                     */
+;/*-----------------------------------------------------*/
+;/*                                                     */
+;/*     Start Up Code                                   */
+;/*     -------------                                   */
+;/*                                                     */
+;/*-----------------------------------------------------*/
+;/*                                                     */
+PSPHigh         equ     00002h
+PSPEnv          equ     0002ch
+PSPCmd          equ     00080h
+
+                public  __AHINCR
+__AHINCR        equ     1000h
+                public  __AHSHIFT
+__AHSHIFT       equ     12
+
+IFDEF   __NOFLOAT__
+MINSTACK        equ     128     ; minimal stack size in words
+ELSE
+MINSTACK        equ     256     ; minimal stack size in words
+ENDIF
+;
+;       At the start, DS and ES both point to the segment prefix.
+;       SS points to the stack segment except in TINY model where
+;       SS is equal to CS
+;
+_TEXT           SEGMENT
+IFDEF           __TINY__
+                ORG     100h
+ENDIF
+STARTX          PROC    NEAR
+;       Save general information, such as :
+;               DGROUP segment address
+;               DOS version number
+;               Program Segment Prefix address
+;               Environment address
+;               Top of far heap
+
+IFDEF   __TINY__
+				mov     dx, cs          ; DX = GROUP Segment address
+ELSE
+				mov     dx, DGROUP      ; DX = GROUP Segment address
+ENDIF
+IFNDEF	__BOSS__
+				mov     cs:DGROUP@@, dx ;  __BOSS__
+ENDIF
+				mov     ah, 30h
+				int     21h             ; get DOS version number
+				mov     bp, ds:[PSPHigh]; BP = Highest Memory Segment Addr
+				mov     bx, ds:[PSPEnv] ; BX = Environment Segment address
+				mov     ds, dx
+				mov     _version@, ax   ; Keep major and minor version number
+				mov     _psp@, es       ; Keep Program Segment Prefix address
+				mov     _envseg@, bx    ; Keep Environment Segment address
+				mov     word ptr _heaptop@ + 2, bp
+;
+;       Save several vectors and install default divide by zero handler.
+;
+				call    SaveVectors
+
+;===================
+;
+; 		IDsoft - Check to make sure that we're running on a 286 or better
+
+				pushf					; Save original flags
+				xor		ax,ax			; Clear AX
+				push	ax
+				popf					; Try to pop the 0
+				pushf
+				pop		ax				; Get results of popping 0 into flags
+				popf					; Restore original flags
+				or		ax,ax
+				jns		@@Have286		; If no sign bit, have a 286
+
+				mov     cx, lgth_no286MSG
+				mov     dx, offset DGROUP: no286MSG
+				jmp		MsgExit3
+
+@@Have286:
+;		IDsoft - End of modifications (there's also a code segment string)
+;
+;===================
+
+IFDEF	__BOSS__
+; Determine if in real mode
+			mov	ax,0FB42h	; find out if DPMI loader is here
+		mov	bx,1		; get info function
+		int	2fh		;
+
+		push	ax		;
+		mov	ax, cs		; now, save DGROUP
+		add	ax, cx		;
+		mov	es, ax		;
+		mov	dx, ds		;
+		mov	es:DGROUP@@, dx	 ;
+		mov	es:CSalias@@, ax ;
+		pop	ax		 ;
+
+;		cmp	ax,0001h	; if not "TRUE"
+;		JNE	InRealMode
+
+; 8 is the value of the alias selector
+; in this system
+		MOV	_protected@, cx
+		MOV	_hugeincval@, cx
+		clc
+		mov	ax, cx
+		xor	cx, cx
+		or	ax, ax
+		je	@@gotshift
+@@shiftcnt:
+		rcr	ax,1
+		jc	@@gotshift
+		inc	cx
+		jmp	@@shiftcnt
+@@gotshift:
+		mov	_shiftcount@,cx
+
+; used by emulator
+;		PUSH	DS
+;		MOV	AX, 0E502H      ; prot kernel function, get LDT alias
+;		INT	21H
+;		POP	DS
+;		MOV	_LDT@, AX
+
+;		cmp	_protected@,0001h	; if not "TRUE"
+;		JNE	InRealMode
+
+		.286P
+IFE	LDATA					
+		mov	dx, ds			;
+;		LSL	AX, DX			;
+;		DEC	AX			;
+		MOV	AX, 0FFFEh		;
+		MOV	SP, AX			;
+		MOV	SS, DX			;
+ENDIF						
+		.8086
+;		JMP	BossSkip
+
+InRealMode	label	near
+
+ENDIF
+
+;       Count the number of environment variables and compute the size.
+;       Each variable is ended by a 0 and a zero-length variable stops
+;       the environment. The environment can NOT be greater than 32k.
+
+                les     di, dword ptr _envLng@
+                mov     ax, di
+                mov     bx, ax
+                mov     cx, 07FFFh      ; Environment cannot be > 32 Kbytes
+                cld
+@@EnvLoop:
+                repnz   scasb
+                jcxz    InitFailed      ; Bad environment !!!
+IFDEF __BOSS__
+                jmp     InitOK
+InitFailed:     jmp     near ptr _abort
+InitOK:
+ENDIF
+     
+                inc     bx              ; BX = Nb environment variables
+                cmp     es:[di], al
+                jne     @@EnvLoop       ; Next variable ...
+                or      ch, 10000000b
+                neg     cx
+                mov     _envLng@, cx    ; Save Environment size
+                mov     cx, dPtrSize / 2
+                shl     bx, cl
+                add     bx, dPtrSize * 4
+                and     bx, not ((dPtrSize * 4) - 1)
+                mov     _envSize@, bx   ; Save Environment Variables Nb.
+
+IFNDEF __BOSS__
+
+;       Determine the amount of memory that we need to keep
+
+IFDEF _DSSTACK_
+                mov     dx, ds
+ELSE
+                mov     dx, ss
+ENDIF
+                sub     bp, dx          ; BP = remaining size in paragraphs
+IF LDATA
+                mov     di, seg __stklen
+                mov     es, di
+                mov     di, es:__stklen ; DI = Requested stack size
+ELSE
+                mov     di, __stklen    ; DI = Requested stack size
+ENDIF
+;
+; Make sure that the requested stack size is at least MINSTACK words.
+;
+                cmp     di, 2*MINSTACK  ; requested stack big enough ?
+                jae     AskedStackOK
+                mov     di, 2*MINSTACK  ; no --> use minimal value
+IF LDATA
+                mov     es:__stklen, di ; override requested stack size
+ELSE
+                mov        __stklen, di ; override requested stack size
+ENDIF
+
+AskedStackOK    label   near
+IFDEF _DSSTACK_
+                add     di, offset DGROUP: edata@
+                jb      InitFailed      ; DATA segment can NOT be > 64 Kbytes
+ENDIF
+IF LDATA EQ false
+                add     di, __heaplen
+                jb      InitFailed      ; DATA segment can NOT be > 64 Kbytes
+ENDIF
+                mov     cl, 4
+                shr     di, cl          ; $$$ Do not destroy CL $$$
+                inc     di              ; DI = DS size in paragraphs
+                cmp     bp, di
+IF LDATA EQ false
+                jb      InitFailed      ; Not enough memory
+                cmp     __stklen, 0
+                je      ExpandDS        ; Expand DS up to 64 Kb
+                cmp     __heaplen, 0
+                jne     ExcessOfMemory  ; Much more available than needed
+ExpandDS        label   near
+                mov     di, 1000h
+                cmp     bp, di
+                ja      ExcessOfMemory  ; Enough to run the program
+                mov     di, bp
+                jmp     short ExcessOfMemory  ; Enough to run the program
+ELSE
+                jnb     ExcessOfMemory  ; Much more available than needed
+ENDIF
+
+;       All initialization errors arrive here
+
+InitFailed      label   near
+                jmp     near ptr _abort
+
+;       Return to DOS the amount of memory in excess
+;       Set far heap base and pointer
+
+ExcessOfMemory  label   near
+                mov     bx, di
+                add     bx, dx
+                mov     word ptr _heapbase@ + 2, bx
+                mov     word ptr _brklvl@ + 2, bx
+                mov     ax, _psp@
+                sub     bx, ax          ; BX = Number of paragraphs to keep
+                mov     es, ax          ; ES = Program Segment Prefix address
+                mov     ah, 04Ah
+                push    di              ; preserve DI
+                int     021h            ; this call clobbers SI,DI,BP !!!!!!
+                pop     di              ; restore  DI
+
+                shl     di, cl          ; $$$ CX is still equal to 4 $$$
+
+                cli                     ; req'd for pre-1983 88/86s
+                mov     ss, dx          ; Set the program stack
+                mov     sp, di
+                sti
+
+IFNDEF _DSSTACK_
+                mov     ax, seg __stklen
+                mov     es, ax
+                mov     es:__stklen, di ; If separate stack segment, save size
+ENDIF
+
+ENDIF ; __BOSS__
+
+IFNDEF  __HUGE__
+
+;       Reset uninitialized data area
+
+                xor     ax, ax
+                mov     es, cs:DGROUP@@
+                mov     di, offset DGROUP: bdata@
+                mov     cx, offset DGROUP: edata@
+                sub     cx, di
+                cld
+                rep     stosb
+ENDIF
+
+;   If default number of file handles have changed then tell DOS
+                cmp     __nfile, 20
+                jbe     @@NoChange
+
+                cmp     _osmajor@, 3   ; Check for >= DOS 3.3
+                jb      @@NoChange
+                ja      @@DoChange
+                cmp     _osminor@, 1Eh
+                jb      @@NoChange
+@@DoChange:
+                mov     ax, 5801h      ; Set last fit allocation
+                mov     bx, 2
+                int     21h
+                jc      @@BadInit
+
+                mov     ah, 67h        ; Expand handle table
+                mov     bx, __nfile
+                int     21h
+                jc      @@BadInit
+
+                mov     ah, 48h        ; Allocate 16 bytes to find new
+                mov     bx, 1          ;   top of memory address
+                int     21h
+                jc      @@BadInit
+                inc     ax             ; Adjust address to point after block
+                mov     word ptr _heaptop@ + 2, ax
+
+                dec     ax             ; Change back and release block
+                mov     es, ax
+                mov     ah, 49h
+                int     21h
+                jc      @@BadInit
+
+                mov     ax, 5801h      ; Set first fit allocation
+                mov     bx, 0
+                int     21h
+                jnc     @@NoChange
+
+@@BadInit:      jmp near ptr _abort
+
+@@NoChange:
+
+;       Prepare main arguments
+
+                mov     ah, 0
+                int     1ah                     ; get current BIOS time in ticks
+                mov     word ptr _StartTime@,dx ; save it for clock() fn
+                mov     word ptr _StartTime@+2,cx
+		or	al,al			; was midnight flag set?
+		jz	@@NotMidnight
+		mov	ax,40h			; set BIOS midnight flag
+		mov	es,ax			;  at 40:70
+		mov	bx,70h
+		mov	byte ptr es:[bx],1
+			
+@@NotMidnight:
+                xor     bp,bp                   ; set BP to 0 for overlay mgr
+
+                mov     es, cs:DGROUP@@
+                mov     si,offset DGROUP:InitStart      ;si = start of table
+                mov     di,offset DGROUP:InitEnd        ;di = end of table
+                call    StartExit
+
+;       ExitCode = main(argc,argv,envp);
+
+IF      LDATA
+                push    word ptr __C0environ+2
+                push    word ptr __C0environ
+                push    word ptr __C0argv+2
+                push    word ptr __C0argv
+ELSE
+                push    word ptr __C0environ
+                push    word ptr __C0argv
+ENDIF
+                push    __C0argc
+                call    _main
+
+;       Flush and close streams and files
+
+                push    ax
+                call    _exit
+
+;---------------------------------------------------------------------------
+;       _cleanup()      call all #pragma exit cleanup routines.
+;       _checknull()    check for null pointer zapping copyright message
+;       _terminate(int) exit program with error code
+;
+;       These functions are called by exit(), _exit(), _cexit(),
+;       and _c_exit().
+;---------------------------------------------------------------------------
+
+;       Call cleanup routines
+
+__cleanup       PROC    DIST
+                PUBLIC  __cleanup
+
+                mov     es, cs:DGROUP@@
+                push    si
+                push    di
+                mov     si,offset DGROUP:ExitStart
+                mov     di,offset DGROUP:ExitEnd
+                call    StartExit
+                pop     di
+                pop     si
+                ret
+__cleanup       ENDP
+
+;       Check for null pointers before exit
+
+__checknull     PROC    DIST
+                PUBLIC  __checknull
+
+IF      LDATA EQ false
+  IFNDEF  __TINY__
+                push    si
+                push    di
+                mov     es, cs:DGROUP@@
+                xor     ax, ax
+                mov     si, ax
+                mov     cx, lgth_CopyRight
+ComputeChecksum label   near
+                add     al, es:[si]
+                adc     ah, 0
+                inc     si
+                loop    ComputeChecksum
+                sub     ax, CheckSum
+                jz      @@SumOk
+                mov     cx, lgth_NullCheck
+                mov     dx, offset DGROUP: NullCheck
+                call    ErrorDisplay
+@@SumOK:        pop     di
+                pop     si
+  ENDIF
+ENDIF
+                ret
+__checknull     ENDP
+
+;       Exit to DOS
+
+__terminate     PROC    DIST
+                PUBLIC  __terminate
+                mov     bp,sp
+                mov     ah,4Ch
+                mov     al,[bp+cPtrSize]
+                int     21h                     ; Exit to DOS
+__terminate     ENDP
+
+STARTX          ENDP
+
+        SUBTTL  Vector save/restore & default Zero divide routines
+        PAGE
+;[]------------------------------------------------------------[]
+;|                                                              |
+;| Interrupt Save/Restore routines and default divide by zero   |
+;| handler.                                                     |
+;|                                                              |
+;[]------------------------------------------------------------[]
+
+ZeroDivision    PROC    FAR
+                mov     cx, lgth_ZeroDivMSG
+                mov     dx, offset DGROUP: ZeroDivMSG
+                jmp     MsgExit3
+ZeroDivision    ENDP
+
+;--------------------------------------------------------------------------
+;       savevectors()
+;
+;       Save vectors for 0, 4, 5 & 6 interrupts.  This is for extended
+;       signal()/raise() support as the signal functions can steal these
+;       vectors during runtime.
+;--------------------------------------------------------------------------
+SaveVectors     PROC    NEAR
+                push    ds
+; Save INT 0
+                mov     ax, 3500h
+                int     021h
+                mov     word ptr _Int0Vector@, bx
+                mov     word ptr _Int0Vector@+2, es
+; Save INT 4
+                mov     ax, 3504h
+                int     021h
+                mov     word ptr _Int4Vector@, bx
+                mov     word ptr _Int4Vector@+2, es
+; Save INT 5
+                mov     ax, 3505h
+                int     021h
+                mov     word ptr _Int5Vector@, bx
+                mov     word ptr _Int5Vector@+2, es
+; Save INT 6
+                mov     ax, 3506h
+                int     021h
+                mov     word ptr _Int6Vector@, bx
+                mov     word ptr _Int6Vector@+2, es
+;
+;       Install default divide by zero handler.
+;
+                mov     ax, 2500h
+                mov     dx, cs
+                mov     ds, dx
+                mov     dx, offset ZeroDivision
+                int     21h
+
+                pop     ds
+                ret
+SaveVectors     ENDP
+
+;--------------------------------------------------------------------------
+;       _restorezero() puts back all the vectors that SaveVectors took.
+;
+;NOTE : TSRs must BE AWARE that signal() functions which take these 
+;       vectors will be deactivated if the keep() function is executed.
+;       If a TSR wants to use the signal functions when it is active it 
+;       will have to save/restore these vectors itself when activated and
+;       deactivated.
+;--------------------------------------------------------------------------
+__restorezero   PROC    DIST
+                PUBLIC  __restorezero
+IFDEF   __HUGE__
+                push    ds
+                mov     ds, cs: DGROUP@@
+ENDIF
+                push    ds
+                mov     ax, 2500h
+                lds     dx, _Int0Vector@
+                int     21h
+                pop     ds
+
+                push    ds
+                mov     ax, 2504h
+                lds     dx, _Int4Vector@
+                int     21h
+                pop     ds
+
+                push    ds
+                mov     ax, 2505h
+                lds     dx, _Int5Vector@
+                int     21h
+                pop     ds
+
+IFNDEF   __HUGE__
+                push    ds
+ENDIF
+                mov     ax, 2506h
+                lds     dx, _Int6Vector@
+                int     21h
+                pop     ds
+
+                ret
+                ENDP
+
+;------------------------------------------------------------------
+;  Loop through a startup/exit (SE) table, 
+;  calling functions in order of priority.
+;  ES:SI is assumed to point to the beginning of the SE table
+;  ES:DI is assumed to point to the end of the SE table
+;  First 64 priorities are reserved by Borland
+;------------------------------------------------------------------
+PNEAR           EQU     0
+PFAR            EQU     1
+NOTUSED         EQU     0ffh
+
+SE              STRUC
+calltype        db      ?                       ; 0=near,1=far,ff=not used
+priority        db      ?                       ; 0=highest,ff=lowest
+addrlow         dw      ?
+addrhigh        dw      ?
+SE              ENDS
+
+StartExit       proc near
+@@Start:        cmp     si,offset DGROUP:InitStart      ; startup or exit?
+                je      @@StartLow              ; it's startup
+                xor     ah,ah                   ; start with high priority
+                jmp     short @@SaveEnd
+@@StartLow:     mov     ah,0ffh                 ;start with lowest priority
+@@SaveEnd:      mov     dx,di                   ;set sentinel to end of table
+                mov     bx,si                   ;bx = start of table
+
+@@TopOfTable:   cmp     bx,di                   ;and the end of the table?
+                je      @@EndOfTable            ;yes, exit the loop
+                cmp     es:[bx.calltype],NOTUSED;check the call type
+                je      @@Next
+                cmp     si,offset DGROUP:InitStart      ; startup or exit?
+                je      @@CompareHigh           ; it's startup
+                cmp     ah,es:[bx.priority]     ; it's exit
+                jmp     short @@CheckPrior      ; if priority too low, skip
+@@CompareHigh:  cmp     es:[bx.priority],ah     ;check the priority
+@@CheckPrior:   ja      @@Next                  ;too high?  skip
+                mov     ah,es:[bx.priority]     ;keep priority
+                mov     dx,bx                   ;keep index in dx
+@@Next:         add     bx,SIZE SE              ;bx = next item in table
+                jmp     @@TopOfTable
+
+@@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
+                je      @@Done                  ;yes, quit
+                mov     bx,dx                   ;bx = highest priority item
+                cmp     es:[bx.calltype],PNEAR  ;is it near or far?
+                mov     es:[bx.calltype],NOTUSED;wipe the call type
+                push    es                      ;save es
+                je      @@NearCall
+
+@@FarCall:      call    DWORD PTR es:[bx.addrlow]
+                pop     es                      ;restore es
+                jmp     short @@Start
+
+@@NearCall:     call    WORD PTR es:[bx.addrlow]
+                pop     es                      ;restore es
+                jmp     short @@Start
+
+@@Done:         ret
+                endp
+
+;------------------------------------------------------------------
+
+ErrorDisplay    PROC    NEAR
+                mov     ah, 040h
+                mov     bx, 2
+                int     021h
+                ret
+ErrorDisplay    ENDP
+
+_abort          PROC    DIST
+                PUBLIC  _abort
+                mov     cx, lgth_abortMSG
+                mov     dx, offset DGROUP: abortMSG
+MsgExit3        label   near
+                mov     ds, cs: DGROUP@@
+                call    ErrorDisplay
+CallExit3       label   near
+                mov     ax, 3
+                push    ax
+                call    __exit           ; _exit(3);
+                ENDP
+
+; The DGROUP@ variable is used to reload DS with DGROUP
+
+PubSym@         DGROUP@, <dw    ?>, __PASCAL__
+
+IFDEF	__BOSS__
+PubSym@		CSalias@,<dw    ?>, __PASCAL__
+ENDIF
+
+
+; __MMODEL is used to determine the memory model or the default
+; pointer types at run time.
+
+                public __MMODEL
+__MMODEL        dw      MMODEL
+
+_TEXT           ENDS
+
+                SUBTTL  Start Up Data Area
+                PAGE
+;[]------------------------------------------------------------[]
+;|      Start Up Data Area                                      |
+;|                                                              |
+;|      WARNING         Do not move any variables in the data   |
+;|                      segment unless you're absolutely sure   |
+;|                      that it does not matter.                |
+;[]------------------------------------------------------------[]
+
+_DATA           SEGMENT
+
+;       Magic symbol used by the debug info to locate the data segment
+                public DATASEG@
+DATASEG@        label   byte
+
+;       The CopyRight string must NOT be moved or changed without
+;       changing the null pointer check logic
+
+CopyRight       db      4 dup(0)
+                db      'Borland C++ - Copyright 1991 Borland Intl.',0
+lgth_CopyRight  equ     $ - CopyRight
+
+IF      LDATA EQ false
+IFNDEF  __TINY__
+CheckSum        equ     00D5Ch
+NullCheck       db      'Null pointer assignment', 13, 10
+lgth_NullCheck  equ     $ - NullCheck
+ENDIF
+ENDIF
+
+ZeroDivMSG      db      'Divide error', 13, 10
+lgth_ZeroDivMSG equ     $ - ZeroDivMSG
+
+abortMSG        db      'Abnormal program termination', 13, 10
+lgth_abortMSG   equ     $ - abortMSG
+
+; JAB - Added string for no 286
+no286MSG		db		'Sorry, this program requires a 286 or better.', 13, 10
+lgth_no286MSG	equ		$ - no286MSG
+; JAB - End of modifications
+
+;
+;                       Interrupt vector save areas
+;       
+;       Interrupt vectors 0,4,5 & 6 are saved at startup and then restored
+;       when the program terminates.  The signal/raise functions might
+;       steal these vectors during execution.
+;
+;       Note: These vectors save area must not be altered 
+;             without changing the save/restore logic.
+;
+PubSym@         _Int0Vector     <dd     0>,             __CDECL__
+PubSym@         _Int4Vector     <dd     0>,             __CDECL__
+PubSym@         _Int5Vector     <dd     0>,             __CDECL__
+PubSym@         _Int6Vector     <dd     0>,             __CDECL__
+;
+;                       Miscellaneous variables
+;       
+PubSym@         _C0argc,        <dw     0>,             __CDECL__
+dPtrPub@        _C0argv,        0,                      __CDECL__
+dPtrPub@        _C0environ,     0,                      __CDECL__
+PubSym@         _envLng,        <dw     0>,             __CDECL__
+PubSym@         _envseg,        <dw     0>,             __CDECL__
+PubSym@         _envSize,       <dw     0>,             __CDECL__
+PubSym@         _psp,           <dw     0>,             __CDECL__
+PubSym@         _version,       <label word>,           __CDECL__
+PubSym@         _osversion,     <label word>,           __CDECL__
+PubSym@         _osmajor,       <db     0>,             __CDECL__
+PubSym@         _osminor,       <db     0>,             __CDECL__
+PubSym@         errno,          <dw     0>,             __CDECL__
+PubSym@         _StartTime,     <dw   0,0>,             __CDECL__
+
+
+IFDEF __BOSS__
+PubSym@		_protected	<dw    0>,		__CDECL__
+PubSym@ 	_shiftcount,	<dw    12>,		__CDECL__
+PubSym@ 	_hugeincval,	<dw    1000h>,		__CDECL__
+ENDIF
+
+;       Memory management variables
+
+IF      LDATA EQ false
+PubSym@         __heapbase,     <dw   DGROUP:edata@>,   __CDECL__
+ENDIF
+IFNDEF __HUGE__
+PubSym@         __brklvl,       <dw   DGROUP:edata@>,   __CDECL__
+ENDIF
+PubSym@         _heapbase,      <dd   0>,       __CDECL__
+PubSym@         _brklvl,        <dd   0>,       __CDECL__
+PubSym@         _heaptop,       <dd   0>,       __CDECL__
+
+;       If stack in DS and Large data model then override location of __emu
+
+IFDEF   _DSSTACK_
+IF      LDATA
+public  __emu
+__emu   db      044h    DUP (0)
+        db      0CCh    DUP (?)
+ENDIF
+ENDIF
+
+_DATA           ENDS
+
+
+_CVTSEG         SEGMENT
+PubSym@         _RealCvtVector, <label  word>,  __CDECL__
+                ENDS
+
+_SCNSEG         SEGMENT
+PubSym@         _ScanTodVector,  <label word>,  __CDECL__
+                ENDS
+
+IFNDEF __HUGE__
+_BSS            SEGMENT
+bdata@          label   byte
+                ENDS
+
+_BSSEND         SEGMENT
+edata@          label   byte
+                ENDS
+ENDIF
+
+IFNDEF __TINY__
+_STACK          SEGMENT
+IFDEF __BOSS__
+    IF LDATA
+                db      1400h dup(?)
+    ENDIF
+ELSE
+                db      128 dup(?)               ;minimum stack size
+ENDIF  ; __BOSS__
+                ENDS
+ENDIF  ; __TINY__
+                END     STARTX
--- /dev/null
+++ b/WOLFSRC/CONTIGSC.C
@@ -1,0 +1,733 @@
+// WL_SCALE.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+
+#define OP_RETF	0xcb
+
+/*
+=============================================================================
+
+						  GLOBALS
+
+=============================================================================
+*/
+
+t_compscale far *scaledirectory[MAXSCALEHEIGHT+1];
+long			fullscalefarcall[MAXSCALEHEIGHT+1];
+
+int			maxscale,maxscaleshl2;
+
+byte far	*scalermemory;
+byte _seg	*endscalermemory;
+long		freescalermemory;
+
+
+/*
+=============================================================================
+
+						  LOCALS
+
+=============================================================================
+*/
+
+unsigned BuildCompScale (int height, byte far *code);
+
+int			stepbytwo;
+
+//===========================================================================
+
+/*
+==============
+=
+= BadScale
+=
+==============
+*/
+
+void far BadScale (void)
+{
+	Quit ("BadScale called!");
+}
+
+
+/*
+==========================
+=
+= SetupScaling
+=
+==========================
+*/
+
+long SetupScaling (int maxscaleheight)
+{
+	int		i,x,y;
+	byte	far *dest;
+	unsigned	seg,ofs;
+	long	size;
+
+
+	maxscaleheight/=2;			// one scaler every two pixels
+
+	maxscale = maxscaleheight-1;
+	maxscaleshl2 = maxscale<<2;
+
+	dest = scalermemory;
+
+//
+// build the compiled scalers
+//
+	stepbytwo = viewheight/2;	// save space by double stepping
+
+	for (i=1;i<=maxscaleheight;i++)
+	{
+		seg = FP_SEG(dest);
+		ofs = (FP_OFF(dest)+15)&~15;
+		dest = MK_FP(seg+ofs/16,0);
+
+		scaledirectory[i] = (t_compscale far *)dest;
+		size = BuildCompScale (i*2,dest);
+		dest += size;
+
+		if ((byte huge *)dest-(byte huge *)scalermemory > MAXSCALERMEMORY)
+			Quit ("Compiled scalars exceeded allocated space!");
+
+		if (i>=stepbytwo)
+			i+= 2;
+	}
+
+//
+// get far call addresses
+//
+	for (i=1;i<=maxscaleheight;i++)
+	{
+		fullscalefarcall[i] = (long)scaledirectory[i] + scaledirectory[i]->codeofs[0];
+		if (i>=stepbytwo)
+		{
+			scaledirectory[i+1] = scaledirectory[i];
+			fullscalefarcall[i+1] = (long)scaledirectory[i] + scaledirectory[i]->codeofs[0];
+			scaledirectory[i+2] = scaledirectory[i];
+			fullscalefarcall[i+2] = (long)scaledirectory[i] + scaledirectory[i]->codeofs[0];
+			i+=2;
+		}
+	}
+	scaledirectory[0] = scaledirectory[1];
+	fullscalefarcall[0] = fullscalefarcall[1];
+
+//
+// check for oversize wall drawing
+//
+	for (i=maxscaleheight;i<MAXSCALEHEIGHT;i++)
+		fullscalefarcall[i] = (long)BadScale;
+
+	seg = FP_SEG(dest);
+	ofs = (FP_OFF(dest)+15)&~15;
+	endscalermemory = (void _seg *)(seg+ofs/16);
+	size = (byte huge *)dest-(byte huge *)scalermemory;
+	freescalermemory = MAXSCALERMEMORY-16-size;
+
+	return size;
+}
+
+//===========================================================================
+
+/*
+========================
+=
+= BuildCompScale
+=
+= Builds a compiled scaler object that will scale a 64 tall object to
+= the given height (centered vertically on the screen)
+=
+= height should be even
+=
+= Call with
+= ---------
+= DS:SI		Source for scale
+= ES:DI		Dest for scale
+=
+= Calling the compiled scaler only destroys AL
+=
+========================
+*/
+
+unsigned BuildCompScale (int height, byte far *code)
+{
+	t_compscale 	far *work;
+
+	int			i;
+	long		fix,step;
+	unsigned	src,totalscaled,totalsize;
+	int			startpix,endpix,toppix;
+
+	work = (t_compscale far *)code;
+
+	step = ((long)height<<16) / 64;
+	code = &work->code[0];
+	toppix = (viewheight-height)/2;
+	fix = 0;
+
+	for (src=0;src<=64;src++)
+	{
+		startpix = fix>>16;
+		fix += step;
+		endpix = fix>>16;
+
+		if (endpix>startpix)
+			work->width[src] = endpix-startpix;
+		else
+			work->width[src] = 0;
+
+//
+// mark the start of the code
+//
+		work->codeofs[src] = FP_OFF(code);
+
+//
+// compile some code if the source pixel generates any screen pixels
+//
+		startpix+=toppix;
+		endpix+=toppix;
+
+		if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64)
+			continue;
+
+	//
+	// mov al,[si+src]
+	//
+		*code++ = 0x8a;
+		*code++ = 0x44;
+		*code++ = src;
+
+		for (;startpix<endpix;startpix++)
+		{
+			if (startpix >= viewheight)
+				break;						// off the bottom of the view area
+			if (startpix < 0)
+				continue;					// not into the view area
+
+		//
+		// mov [es:di+heightofs],al
+		//
+			*code++ = 0x26;
+			*code++ = 0x88;
+			*code++ = 0x85;
+			*((unsigned far *)code)++ = startpix*SCREENBWIDE;
+		}
+
+	}
+
+//
+// retf
+//
+	*code++ = 0xcb;
+
+	totalsize = FP_OFF(code);
+
+	return totalsize;
+}
+
+
+/*
+=======================
+=
+= ScaleLine
+=
+= linescale should have the high word set to the segment of the scaler
+=
+=======================
+*/
+
+extern	int			slinex,slinewidth;
+extern	unsigned	far *linecmds;
+extern	long		linescale;
+extern	unsigned	maskword;
+
+byte	mask1,mask2,mask3;
+
+
+void near ScaleLine (void)
+{
+asm	mov	cx,WORD PTR [linescale+2]
+asm	mov	es,cx						// segment of scaler
+
+asm	mov bp,WORD PTR [linecmds]
+asm	mov	dx,SC_INDEX+1				// to set SC_MAPMASK
+
+asm	mov	bx,[slinex]
+asm	mov	di,bx
+asm	shr	di,2						// X in bytes
+asm	add	di,[bufferofs]
+asm	and	bx,3
+asm	shl	bx,3
+asm	add	bx,[slinewidth]				// bx = (pixel*8+pixwidth)
+asm	mov	al,BYTE [mapmasks3-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ds,WORD PTR [linecmds+2]
+asm	or	al,al
+asm	jz	notthreebyte				// scale across three bytes
+asm	jmp	threebyte
+notthreebyte:
+asm	mov	al,BYTE PTR ss:[mapmasks2-1+bx]	// -1 because pixwidth of 1 is first
+asm	or	al,al
+asm	jnz	twobyte						// scale across two bytes
+
+//
+// one byte scaling
+//
+asm	mov	al,BYTE PTR ss:[mapmasks1-1+bx]	// -1 because pixwidth of 1 is first
+asm	out	dx,al						// set map mask register
+
+scalesingle:
+
+asm	mov	bx,[ds:bp]					// table location of rtl to patch
+asm	or	bx,bx
+asm	jz	linedone					// 0 signals end of segment list
+asm	mov	bx,[es:bx]
+asm	mov	dl,[es:bx]					// save old value
+asm	mov	BYTE PTR es:[bx],OP_RETF	// patch a RETF in
+asm	mov	si,[ds:bp+4]				// table location of entry spot
+asm	mov	ax,[es:si]
+asm	mov	WORD PTR ss:[linescale],ax	// call here to start scaling
+asm	mov	si,[ds:bp+2]				// corrected top of shape for this segment
+asm	add	bp,6						// next segment list
+
+asm	mov	ax,SCREENSEG
+asm	mov	es,ax
+asm	call ss:[linescale]				// scale the segment of pixels
+
+asm	mov	es,cx						// segment of scaler
+asm	mov	BYTE PTR es:[bx],dl			// unpatch the RETF
+asm	jmp	scalesingle					// do the next segment
+
+
+//
+// done
+//
+linedone:
+asm	mov	ax,ss
+asm	mov	ds,ax
+return;
+
+//
+// two byte scaling
+//
+twobyte:
+asm	mov	ss:[mask2],al
+asm	mov	al,BYTE PTR ss:[mapmasks1-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ss:[mask1],al
+
+scaledouble:
+
+asm	mov	bx,[ds:bp]					// table location of rtl to patch
+asm	or	bx,bx
+asm	jz	linedone					// 0 signals end of segment list
+asm	mov	bx,[es:bx]
+asm	mov	cl,[es:bx]					// save old value
+asm	mov	BYTE PTR es:[bx],OP_RETF	// patch a RETF in
+asm	mov	si,[ds:bp+4]				// table location of entry spot
+asm	mov	ax,[es:si]
+asm	mov	WORD PTR ss:[linescale],ax	// call here to start scaling
+asm	mov	si,[ds:bp+2]				// corrected top of shape for this segment
+asm	add	bp,6						// next segment list
+
+asm	mov	ax,SCREENSEG
+asm	mov	es,ax
+asm	mov	al,ss:[mask1]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	inc	di
+asm	mov	al,ss:[mask2]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	dec	di
+
+asm	mov	es,WORD PTR ss:[linescale+2] // segment of scaler
+asm	mov	BYTE PTR es:[bx],cl			// unpatch the RETF
+asm	jmp	scaledouble					// do the next segment
+
+
+//
+// three byte scaling
+//
+threebyte:
+asm	mov	ss:[mask3],al
+asm	mov	al,BYTE PTR ss:[mapmasks2-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ss:[mask2],al
+asm	mov	al,BYTE PTR ss:[mapmasks1-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ss:[mask1],al
+
+scaletriple:
+
+asm	mov	bx,[ds:bp]					// table location of rtl to patch
+asm	or	bx,bx
+asm	jz	linedone					// 0 signals end of segment list
+asm	mov	bx,[es:bx]
+asm	mov	cl,[es:bx]					// save old value
+asm	mov	BYTE PTR es:[bx],OP_RETF	// patch a RETF in
+asm	mov	si,[ds:bp+4]				// table location of entry spot
+asm	mov	ax,[es:si]
+asm	mov	WORD PTR ss:[linescale],ax	// call here to start scaling
+asm	mov	si,[ds:bp+2]				// corrected top of shape for this segment
+asm	add	bp,6						// next segment list
+
+asm	mov	ax,SCREENSEG
+asm	mov	es,ax
+asm	mov	al,ss:[mask1]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	inc	di
+asm	mov	al,ss:[mask2]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	inc	di
+asm	mov	al,ss:[mask3]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	dec	di
+asm	dec	di
+
+asm	mov	es,WORD PTR ss:[linescale+2] // segment of scaler
+asm	mov	BYTE PTR es:[bx],cl			// unpatch the RETF
+asm	jmp	scaletriple					// do the next segment
+
+
+}
+
+
+/*
+=======================
+=
+= ScaleShape
+=
+= Draws a compiled shape at [scale] pixels high
+=
+= each vertical line of the shape has a pointer to segment data:
+= 	end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
+= 	top of virtual line with segment in proper place
+=	start of segment pixel*2, used to jsl into compiled scaler
+=	<repeat>
+=
+= Setup for call
+= --------------
+= GC_MODE			read mode 1, write mode 2
+= GC_COLORDONTCARE  set to 0, so all reads from video memory return 0xff
+= GC_INDEX			pointing at GC_BITMASK
+=
+=======================
+*/
+
+static	long		longtemp;
+
+void ScaleShape (int xcenter, int shapenum, unsigned height)
+{
+	t_compshape	_seg *shape;
+	t_compscale far *comptable;
+	unsigned	scale,srcx,stopx,tempx;
+	int			t;
+	unsigned	far *cmdptr;
+	boolean		leftvis,rightvis;
+
+
+	shape = PM_GetSpritePage (shapenum);
+
+	scale = height>>3;						// low three bits are fractional
+	if (!scale || scale>maxscale)
+		return;								// too close or far away
+	comptable = scaledirectory[scale];
+
+	*(((unsigned *)&linescale)+1)=FP_SEG(comptable);	// seg of far call
+	*(((unsigned *)&linecmds)+1)=(unsigned)shape;		// seg of shape
+
+//
+// scale to the left (from pixel 31 to shape->leftpix)
+//
+	srcx = 32;
+	slinex = xcenter;
+	stopx = shape->leftpix;
+	cmdptr = &shape->dataofs[31-stopx];
+
+	while ( --srcx >=stopx && slinex>0)
+	{
+		(unsigned)linecmds = *cmdptr--;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		if (slinewidth == 1)
+		{
+			slinex--;
+			if (slinex<viewwidth)
+			{
+				if (wallheight[slinex] >= height)
+					continue;		// obscured by closer wall
+				ScaleLine ();
+			}
+			continue;
+		}
+
+		//
+		// handle multi pixel lines
+		//
+		if (slinex>viewwidth)
+		{
+			slinex -= slinewidth;
+			slinewidth = viewwidth-slinex;
+			if (slinewidth<1)
+				continue;		// still off the right side
+		}
+		else
+		{
+			if (slinewidth>slinex)
+				slinewidth = slinex;
+			slinex -= slinewidth;
+		}
+
+
+		leftvis = (wallheight[slinex] < height);
+		rightvis = (wallheight[slinex+slinewidth-1] < height);
+
+		if (leftvis)
+		{
+			if (rightvis)
+				ScaleLine ();
+			else
+			{
+				while (wallheight[slinex+slinewidth-1] >= height)
+					slinewidth--;
+				ScaleLine ();
+			}
+		}
+		else
+		{
+			if (!rightvis)
+				continue;		// totally obscured
+
+			while (wallheight[slinex] >= height)
+			{
+				slinex++;
+				slinewidth--;
+			}
+			ScaleLine ();
+			break;			// the rest of the shape is gone
+		}
+	}
+
+
+//
+// scale to the right
+//
+	slinex = xcenter;
+	stopx = shape->rightpix;
+	if (shape->leftpix<31)
+	{
+		srcx = 31;
+		cmdptr = &shape->dataofs[32-shape->leftpix];
+	}
+	else
+	{
+		srcx = shape->leftpix-1;
+		cmdptr = &shape->dataofs[0];
+	}
+	slinewidth = 0;
+
+	while ( ++srcx <= stopx && (slinex+=slinewidth)<viewwidth)
+	{
+		(unsigned)linecmds = *cmdptr++;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		if (slinewidth == 1)
+		{
+			if (slinex>=0 && wallheight[slinex] < height)
+			{
+				ScaleLine ();
+			}
+			continue;
+		}
+
+		//
+		// handle multi pixel lines
+		//
+		if (slinex<0)
+		{
+			if (slinewidth <= -slinex)
+				continue;		// still off the left edge
+
+			slinewidth += slinex;
+			slinex = 0;
+		}
+		else
+		{
+			if (slinex + slinewidth > viewwidth)
+				slinewidth = viewwidth-slinex;
+		}
+
+
+		leftvis = (wallheight[slinex] < height);
+		rightvis = (wallheight[slinex+slinewidth-1] < height);
+
+		if (leftvis)
+		{
+			if (rightvis)
+			{
+				ScaleLine ();
+			}
+			else
+			{
+				while (wallheight[slinex+slinewidth-1] >= height)
+					slinewidth--;
+				ScaleLine ();
+				break;			// the rest of the shape is gone
+			}
+		}
+		else
+		{
+			if (rightvis)
+			{
+				while (wallheight[slinex] >= height)
+				{
+					slinex++;
+					slinewidth--;
+				}
+				ScaleLine ();
+			}
+			else
+				continue;		// totally obscured
+		}
+	}
+}
+
+
+
+/*
+=======================
+=
+= SimpleScaleShape
+=
+= NO CLIPPING, height in pixels
+=
+= Draws a compiled shape at [scale] pixels high
+=
+= each vertical line of the shape has a pointer to segment data:
+= 	end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
+= 	top of virtual line with segment in proper place
+=	start of segment pixel*2, used to jsl into compiled scaler
+=	<repeat>
+=
+= Setup for call
+= --------------
+= GC_MODE			read mode 1, write mode 2
+= GC_COLORDONTCARE  set to 0, so all reads from video memory return 0xff
+= GC_INDEX			pointing at GC_BITMASK
+=
+=======================
+*/
+
+void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
+{
+	t_compshape	_seg *shape;
+	t_compscale far *comptable;
+	unsigned	scale,srcx,stopx,tempx;
+	int			t;
+	unsigned	far *cmdptr;
+	boolean		leftvis,rightvis;
+
+
+	shape = PM_GetSpritePage (shapenum);
+
+	scale = height>>1;
+	comptable = scaledirectory[scale];
+
+	*(((unsigned *)&linescale)+1)=FP_SEG(comptable);	// seg of far call
+	*(((unsigned *)&linecmds)+1)=(unsigned)shape;		// seg of shape
+
+//
+// scale to the left (from pixel 31 to shape->leftpix)
+//
+	srcx = 32;
+	slinex = xcenter;
+	stopx = shape->leftpix;
+	cmdptr = &shape->dataofs[31-stopx];
+
+	while ( --srcx >=stopx )
+	{
+		(unsigned)linecmds = *cmdptr--;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		slinex -= slinewidth;
+		ScaleLine ();
+	}
+
+
+//
+// scale to the right
+//
+	slinex = xcenter;
+	stopx = shape->rightpix;
+	if (shape->leftpix<31)
+	{
+		srcx = 31;
+		cmdptr = &shape->dataofs[32-shape->leftpix];
+	}
+	else
+	{
+		srcx = shape->leftpix-1;
+		cmdptr = &shape->dataofs[0];
+	}
+	slinewidth = 0;
+
+	while ( ++srcx <= stopx )
+	{
+		(unsigned)linecmds = *cmdptr++;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		ScaleLine ();
+		slinex+=slinewidth;
+	}
+}
+
+
+
+
+//
+// bit mask tables for drawing scaled strips up to eight pixels wide
+//
+// down here so the STUPID inline assembler doesn't get confused!
+//
+
+
+byte	mapmasks1[4][8] = {
+{1 ,3 ,7 ,15,15,15,15,15},
+{2 ,6 ,14,14,14,14,14,14},
+{4 ,12,12,12,12,12,12,12},
+{8 ,8 ,8 ,8 ,8 ,8 ,8 ,8} };
+
+byte	mapmasks2[4][8] = {
+{0 ,0 ,0 ,0 ,1 ,3 ,7 ,15},
+{0 ,0 ,0 ,1 ,3 ,7 ,15,15},
+{0 ,0 ,1 ,3 ,7 ,15,15,15},
+{0 ,1 ,3 ,7 ,15,15,15,15} };
+
+byte	mapmasks3[4][8] = {
+{0 ,0 ,0 ,0 ,0 ,0 ,0 ,0},
+{0 ,0 ,0 ,0 ,0 ,0 ,0 ,1},
+{0 ,0 ,0 ,0 ,0 ,0 ,1 ,3},
+{0 ,0 ,0 ,0 ,0 ,1 ,3 ,7} };
+
+
+unsigned	wordmasks[8][8] = {
+{0x0080,0x00c0,0x00e0,0x00f0,0x00f8,0x00fc,0x00fe,0x00ff},
+{0x0040,0x0060,0x0070,0x0078,0x007c,0x007e,0x007f,0x807f},
+{0x0020,0x0030,0x0038,0x003c,0x003e,0x003f,0x803f,0xc03f},
+{0x0010,0x0018,0x001c,0x001e,0x001f,0x801f,0xc01f,0xe01f},
+{0x0008,0x000c,0x000e,0x000f,0x800f,0xc00f,0xe00f,0xf00f},
+{0x0004,0x0006,0x0007,0x8007,0xc007,0xe007,0xf007,0xf807},
+{0x0002,0x0003,0x8003,0xc003,0xe003,0xf003,0xf803,0xfc03},
+{0x0001,0x8001,0xc001,0xe001,0xf001,0xf801,0xfc01,0xfe01} };
+
+int			slinex,slinewidth;
+unsigned	far *linecmds;
+long		linescale;
+unsigned	maskword;
+
--- /dev/null
+++ b/WOLFSRC/DETECT.C
@@ -1,0 +1,87 @@
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_CheckSB() - Checks to see if a SoundBlaster resides at a
+//		particular I/O location
+//
+///////////////////////////////////////////////////////////////////////////
+static boolean
+SDL_CheckSB(int port)
+{
+	int	i;
+
+	sbLocation = port << 4;		// Initialize stuff for later use
+
+	sbOut(sbReset,true);		// Reset the SoundBlaster DSP
+asm	mov	dx,0x388				// Wait >4usec
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+
+	sbOut(sbReset,false);		// Turn off sb DSP reset
+asm	mov	dx,0x388				// Wait >100usec
+asm	mov	cx,100
+usecloop:
+asm	in	al,dx
+asm	loop usecloop
+
+	for (i = 0;i < 100;i++)
+	{
+		if (sbIn(sbDataAvail) & 0x80)		// If data is available...
+		{
+			if (sbIn(sbReadData) == 0xaa)	// If it matches correct value
+				return(true);
+			else
+			{
+				sbLocation = -1;			// Otherwise not a SoundBlaster
+				return(false);
+			}
+		}
+	}
+	sbLocation = -1;						// Retry count exceeded - fail
+	return(false);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	Checks to see if a SoundBlaster is in the system. If the port passed is
+//		-1, then it scans through all possible I/O locations. If the port
+//		passed is 0, then it uses the default (2). If the port is >0, then
+//		it just passes it directly to SDL_CheckSB()
+//
+///////////////////////////////////////////////////////////////////////////
+static boolean
+SDL_DetectSoundBlaster(int port)
+{
+	int	i;
+
+	if (port == 0)					// If user specifies default, use 2
+		port = 2;
+	if (port == -1)
+	{
+		if (SDL_CheckSB(2))			// Check default before scanning
+			return(true);
+
+		if (SDL_CheckSB(4))			// Check other SB Pro location before scan
+			return(true);
+
+		for (i = 1;i <= 6;i++)		// Scan through possible SB locations
+		{
+			if ((i == 2) || (i == 4))
+				continue;
+
+			if (SDL_CheckSB(i))		// If found at this address,
+				return(true);		//	return success
+		}
+		return(false);				// All addresses failed, return failure
+	}
+	else
+		return(SDL_CheckSB(port));	// User specified address or default
+}
+
+
\ No newline at end of file
--- /dev/null
+++ b/WOLFSRC/FOREIGN.H
@@ -1,0 +1,110 @@
+#define QUITSUR	"Are you sure you want\n"\
+		"to quit this great game?"
+
+#define CURGAME	"You are currently in\n"\
+		"a game. Continuing will\n"\
+		"erase old game. Ok?"
+
+#define GAMESVD	"There's already a game\n"\
+		"saved at this position.\n"\
+		"      Overwrite?"
+
+#define ENDGAMESTR	"Are you sure you want\n"\
+					"to end the game you\n"\
+					"are playing? (Y or N):"
+
+#define STR_NG	"New Game"
+#define	STR_SD	"Sound"
+#define	STR_CL	"Control"
+#define	STR_LG	"Load Game"
+#define	STR_SG	"Save Game"
+#define	STR_CV	"Change View"
+#define	STR_VS	"View Scores"
+#define STR_EG	"End Game"
+#define	STR_BD	"Back to Demo"
+#define STR_QT	"Quit"
+
+#define STR_LOADING	"Loading"
+#define STR_SAVING	"Saving"
+
+#define STR_GAME	"Game"
+#define STR_DEMO	"Demo"
+#define STR_LGC		"Load Game called\n\""
+#define STR_EMPTY	"empty"
+#define STR_CALIB	"Calibrate"
+#define STR_JOYST	"Joystick"
+#define STR_MOVEJOY	"Move joystick to\nupper left and\npress button 0\n"
+#define STR_MOVEJOY2 "Move joystick to\nlower right and\npress button 1\n"
+#define STR_ESCEXIT	"ESC to exit"
+
+#define STR_NONE	"None"
+#define	STR_PC		"PC Speaker"
+#define	STR_ALSB	"AdLib/Sound Blaster"
+#define	STR_DISNEY	"Disney Sound Source"
+#define	STR_SB		"Sound Blaster"
+
+#define	STR_MOUSEEN	"Mouse Enabled"
+#define	STR_JOYEN	"Joystick Enabled"
+#define	STR_PORT2	"Use joystick port 2"
+#define	STR_GAMEPAD	"Gravis GamePad Enabled"
+#define	STR_SENS	"Mouse Sensitivity"
+#define	STR_CUSTOM	"Customize controls"
+
+#define	STR_DADDY	"Can I play, Daddy?"
+#define	STR_HURTME	"Don't hurt me."
+#define	STR_BRINGEM	"Bring 'em on!"
+#define	STR_DEATH	"I am Death incarnate!"
+
+#define	STR_MOUSEADJ	"Adjust Mouse Sensitivity"
+#define STR_SLOW	"Slow"
+#define STR_FAST	"Fast"
+
+#define	STR_CRUN	"Run"
+#define STR_COPEN	"Open"
+#define STR_CFIRE	"Fire"
+#define STR_CSTRAFE	"Strafe"
+
+#define	STR_LEFT	"Left"
+#define	STR_RIGHT	"Right"
+#define	STR_FRWD	"Frwd"
+#define	STR_BKWD	"Bkwrd"
+#define	STR_THINK	"Thinking"
+
+#define STR_SIZE1	"Use arrows to size"
+#define STR_SIZE2	"ENTER to accept"
+#define STR_SIZE3	"ESC to cancel"
+
+#define STR_YOUWIN	"you win!"
+
+#define STR_TOTALTIME	"total time"
+
+#define STR_RATKILL		    "kill    %"
+#define STR_RATSECRET  	  "secret    %"
+#define STR_RATTREASURE	"treasure    %"
+
+#define STR_BONUS	"bonus"
+#define STR_TIME	"time"
+#define STR_PAR		" par"
+
+#define STR_RAT2KILL            "kill ratio    %"
+#define STR_RAT2SECRET  	  "secret ratio    %"
+#define STR_RAT2TREASURE	"treasure ratio    %"
+
+#define STR_DEFEATED	"defeated!"
+
+#define STR_CHEATER1	"You now have 100% Health,"
+#define STR_CHEATER2    "99 Ammo and both Keys!"
+#define STR_CHEATER3	"Note that you have basically"
+#define STR_CHEATER4	"eliminated your chances of"
+#define STR_CHEATER5	"getting a high score!"
+
+#define STR_NOSPACE1	"There is not enough space"
+#define STR_NOSPACE2	"on your disk to Save Game!"
+
+#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	STR_SEEAGAIN	"Let's see that again!"
+
\ No newline at end of file
--- /dev/null
+++ b/WOLFSRC/F_SPEAR.H
@@ -1,0 +1,87 @@
+#define ENDSTR1	"Heroes don't quit, but\ngo ahead and press Y\nif you aren't one."
+#define ENDSTR2	"Press Y to quit,\nor press N to enjoy\nmore violent diversion."
+#define ENDSTR3	"Depressing the Y key means\nyou must return to the\nhumdrum workday world."
+#define ENDSTR4	"Hey, quit or play,\nY or N:\nit's your choice."
+#define ENDSTR5	"Sure you don't want to\nwaste a few more\nproductive hours?"
+#define ENDSTR6	"I think you had better\nplay some more. Please\npress N...please?"
+#define ENDSTR7	"If you are tough, press N.\nIf not, press Y daintily."
+#define ENDSTR8	"I'm thinkin' that\nyou might wanna press N\nto play more. You do it."
+#define ENDSTR9	"Sure. Fine. Quit.\nSee if we care.\nGet it over with.\nPress Y."
+
+#define STR_ENDGAME1	"We owe you a great debt, Mr. Blazkowicz."
+#define STR_ENDGAME2	"You have served your country well."
+#define STR_ENDGAME3	"With the spear gone, the Allies will finally"
+#define STR_ENDGAME4	"by able to destroy Hitler..."
+
+#define STR_COPY1		"That's close, but not close enough to get"
+#define STR_COPY2		"you into the game."
+
+#define STR_COPY3		"Wow, you must have the early version of the"
+#define STR_COPY4		"manual with the totally false information in it."
+
+#define STR_COPY5		"I would let you into the game, but seeing"
+#define STR_COPY6		"as that was not at all the right answer..."
+
+#define STR_COPY7		"It's just too bad we can't get together on"
+#define STR_COPY8		"this one.  Sorry."
+
+#define STR_COPY9		"Hey, you're just SO off base!"
+
+#define STR_COPY10		"You know, I once typed that myself when"
+#define STR_COPY11		"I was your age."
+
+#define STR_COPY12		"Nops.  Zero points.  Zugga."
+
+#define STR_COPY13		"Yeah...right."
+
+#define STR_COPY14		"You must like these quizzes."
+
+#define STR_COPY15		"Could be called \"PixelMeister\"?"
+
+#define STR_COPY16		"Might engineer some software?"
+
+#define STR_COPY17		"Would be found"
+#define STR_COPY18		"directing creatively?"
+
+#define STR_COPY19		"Might be found"
+#define STR_COPY20		"handling operations?"
+
+#define STR_COPY21		"Has a name familiar"
+#define STR_COPY22		"to your weatherman?"
+
+#define STR_NOPE1		"Welcome to the DOS prompt, pirate!"
+#define STR_NOPE2		"Eat hot DOS prompt, goober!"
+#define STR_NOPE3		"Ya know, this program doesn't cost that much."
+#define STR_NOPE4		"Hey...weren't you just AT this DOS prompt?"
+#define STR_NOPE5		"What's a nice user like you doin' at a DOS prompt like this?"
+#define STR_NOPE6		"Well, I'm sure you just \"misplaced\" the manual..."
+#define STR_NOPE7		"Run me again when you've boned up on your manual a bit."
+#define STR_NOPE8		"Nice try, but no Spear."
+#define STR_NOPE9		"That information is in the Spear of Destiny manual, by the way."
+
+#define STR_MISC1		"Under \"Killing the Enemy\", what"
+#define STR_MISC2		"type of enemy is pictured?"
+
+#define STR_MISC3		"How many eyelets are on B.J.'s"
+#define STR_MISC4		"boots? (see page 2)"
+
+#define STR_MISC5		"The word \"minister\" appears in"
+#define STR_MISC6		"what gray shape on page 2?"
+
+#define STR_MISC7		"How many bullets does B.J. have"
+#define STR_MISC8		"on the screen-shot in the middle"
+#define STR_MISC9		"of page 9?"
+
+#define STR_STAR	"star"
+#define STR_DEBRIEF	" DEBRIEFING\n SESSION\n"
+#define STR_ENEMY1	"Name the member of the"
+#define STR_ENEMY2	"enemy forces shown above"
+
+#define STR_CHECKMAN	"CHECK YER MANUAL!"
+#define STR_MAN1	"Which manual page"
+#define STR_MAN2	"is the Options Menu"
+#define STR_MAN3	"function"
+#define STR_MAN4	"on?"
+
+#define STR_ID1		"Which member of Id Software:"
+
\ No newline at end of file
--- /dev/null
+++ b/WOLFSRC/GFXE_SOD.EQU
@@ -1,0 +1,47 @@
+;=====================================
+;
+; Graphics .EQU file for .SOD
+; IGRAB-ed on Fri Jul 31 18:31:00 1992
+;
+;=====================================
+
+
+
+
+
+
+;
+; Amount of each data item
+;
+NUMCHUNKS	=	414
+NUMFONT  	=	0
+NUMFONTM  	=	0
+NUMPICS  	=	0
+NUMPICM  	=	0
+NUMSPRITES  	=	0
+NUMTILE8  	=	0
+NUMTILE8M  	=	0
+NUMTILE16  	=	144
+NUMTILE16M  	=	270
+NUMTILE32  	=	0
+NUMTILE32M  	=	0
+NUMEXTERN  	=	0
+;
+; File offsets for data items
+;
+STARTFONT  	=	0
+STARTFONTM  	=	0
+STARTPICS  	=	0
+STARTPICM  	=	0
+STARTSPRITES  	=	0
+STARTTILE8  	=	0
+STARTTILE8M  	=	0
+STARTTILE16  	=	0
+STARTTILE16M  	=	144
+STARTTILE32  	=	414
+STARTTILE32M  	=	414
+STARTEXTERN  	=	414
+
+;
+; Thank you for using IGRAB!
+;
--- /dev/null
+++ b/WOLFSRC/GFXE_SOD.H
@@ -1,0 +1,53 @@
+//////////////////////////////////////
+//
+// Graphics .H file for .SOD
+// IGRAB-ed on Fri Jul 31 18:31:00 1992
+//
+//////////////////////////////////////
+
+typedef enum {
+
+
+
+		ENUMEND
+	     } graphicnums;
+
+//
+// Data LUMPs
+//
+
+//
+// Amount of each data item
+//
+#define NUMCHUNKS    414
+#define NUMFONT      0
+#define NUMFONTM     0
+#define NUMPICS      0
+#define NUMPICM      0
+#define NUMSPRITES   0
+#define NUMTILE8     0
+#define NUMTILE8M    0
+#define NUMTILE16    144
+#define NUMTILE16M   270
+#define NUMTILE32    0
+#define NUMTILE32M   0
+#define NUMEXTERNS   0
+//
+// File offsets for data items
+//
+#define STARTFONT    0
+#define STARTFONTM   0
+#define STARTPICS    0
+#define STARTPICM    0
+#define STARTSPRITES 0
+#define STARTTILE8   0
+#define STARTTILE8M  0
+#define STARTTILE16  0
+#define STARTTILE16M 144
+#define STARTTILE32  414
+#define STARTTILE32M 414
+#define STARTEXTERNS 414
+
+//
+// Thank you for using IGRAB!
+//
--- /dev/null
+++ b/WOLFSRC/GFXE_WL1.EQU
@@ -1,0 +1,201 @@
+;=====================================
+;
+; Graphics .EQU file for .WL1
+; IGRAB-ed on Sat May 02 02:16:56 1992
+;
+;=====================================
+
+H_BJPIC				=	3
+H_CASTLEPIC			=	4
+H_KEYBOARDPIC			=	5
+H_JOYPIC			=	6
+H_MOUSEPIC			=	7
+H_BOTHPIC			=	8
+H_GAMEPADPIC			=	9
+H_HEALPIC			=	10
+H_TREASUREPIC			=	11
+H_GUNPIC			=	12
+H_KEYPIC			=	13
+H_BLAZEPIC			=	14
+H_WEAPON1234PIC			=	15
+H_WOLFLOGOPIC			=	16
+H_VISAPIC			=	17
+H_MCPIC				=	18
+H_IDLOGOPIC			=	19
+H_FAXPIC			=	20
+H_GALACTIXPIC			=	21
+H_FGODMOMPIC			=	22
+H_AUSTRALIAPIC			=	23
+H_CANADAPIC			=	24
+H_UKPIC				=	25
+C_OPTIONSPIC			=	26
+C_CURSOR1PIC			=	27
+C_CURSOR2PIC			=	28
+C_NOTSELECTEDPIC		=	29
+C_SELECTEDPIC			=	30
+C_FXTITLEPIC			=	31
+C_DIGITITLEPIC			=	32
+C_MUSICTITLEPIC			=	33
+C_MOUSELBACKPIC			=	34
+C_BABYMODEPIC			=	35
+C_EASYPIC			=	36
+C_NORMALPIC			=	37
+C_HARDPIC			=	38
+C_LOADSAVEDISKPIC		=	39
+C_DISKLOADING1PIC		=	40
+C_DISKLOADING2PIC		=	41
+C_CONTROLPIC			=	42
+C_CUSTOMIZEPIC			=	43
+C_LOADGAMEPIC			=	44
+C_SAVEGAMEPIC			=	45
+C_EPISODE1PIC			=	46
+C_EPISODE2PIC			=	47
+C_EPISODE3PIC			=	48
+C_EPISODE4PIC			=	49
+C_EPISODE5PIC			=	50
+C_EPISODE6PIC			=	51
+C_CODEPIC			=	52
+L_GUYPIC			=	53
+L_COLONPIC			=	54
+L_NUM0PIC			=	55
+L_NUM1PIC			=	56
+L_NUM2PIC			=	57
+L_NUM3PIC			=	58
+L_NUM4PIC			=	59
+L_NUM5PIC			=	60
+L_NUM6PIC			=	61
+L_NUM7PIC			=	62
+L_NUM8PIC			=	63
+L_NUM9PIC			=	64
+L_PERCENTPIC			=	65
+L_APIC				=	66
+L_BPIC				=	67
+L_CPIC				=	68
+L_DPIC				=	69
+L_EPIC				=	70
+L_FPIC				=	71
+L_GPIC				=	72
+L_HPIC				=	73
+L_IPIC				=	74
+L_JPIC				=	75
+L_KPIC				=	76
+L_LPIC				=	77
+L_MPIC				=	78
+L_NPIC				=	79
+L_OPIC				=	80
+L_PPIC				=	81
+L_QPIC				=	82
+L_RPIC				=	83
+L_SPIC				=	84
+L_TPIC				=	85
+L_UPIC				=	86
+L_VPIC				=	87
+L_WPIC				=	88
+L_XPIC				=	89
+L_YPIC				=	90
+L_ZPIC				=	91
+L_GUY2PIC			=	92
+L_BJWINSPIC			=	93
+STATUSBARPIC			=	94
+TITLEPIC			=	95
+PG13PIC				=	96
+CREDITSPIC			=	97
+HIGHSCORESPIC			=	98
+KNIFEPIC			=	99
+GUNPIC				=	100
+MACHINEGUNPIC			=	101
+GATLINGGUNPIC			=	102
+NOKEYPIC			=	103
+GOLDKEYPIC			=	104
+SILVERKEYPIC			=	105
+N_BLANKPIC			=	106
+N_0PIC				=	107
+N_1PIC				=	108
+N_2PIC				=	109
+N_3PIC				=	110
+N_4PIC				=	111
+N_5PIC				=	112
+N_6PIC				=	113
+N_7PIC				=	114
+N_8PIC				=	115
+N_9PIC				=	116
+FACE1APIC			=	117
+FACE1BPIC			=	118
+FACE1CPIC			=	119
+FACE2APIC			=	120
+FACE2BPIC			=	121
+FACE2CPIC			=	122
+FACE3APIC			=	123
+FACE3BPIC			=	124
+FACE3CPIC			=	125
+FACE4APIC			=	126
+FACE4BPIC			=	127
+FACE4CPIC			=	128
+FACE5APIC			=	129
+FACE5BPIC			=	130
+FACE5CPIC			=	131
+FACE6APIC			=	132
+FACE6BPIC			=	133
+FACE6CPIC			=	134
+FACE7APIC			=	135
+FACE7BPIC			=	136
+FACE7CPIC			=	137
+FACE8APIC			=	138
+GOTGATLINGPIC			=	139
+PAUSEDPIC			=	140
+GETPSYCHEDPIC			=	141
+
+
+
+ORDERSCREEN			=	557
+
+README_LUMP_START		=	3
+README_LUMP_END			=	25
+
+CONTROLS_LUMP_START		=	26
+CONTROLS_LUMP_END		=	52
+
+LEVELEND_LUMP_START		=	53
+LEVELEND_LUMP_END		=	93
+
+LATCHPICS_LUMP_START		=	99
+LATCHPICS_LUMP_END		=	141
+
+
+;
+; Amount of each data item
+;
+NUMCHUNKS	=	558
+NUMFONT  	=	2
+NUMFONTM  	=	0
+NUMPICS  	=	139
+NUMPICM  	=	0
+NUMSPRITES  	=	0
+NUMTILE8  	=	72
+NUMTILE8M  	=	0
+NUMTILE16  	=	144
+NUMTILE16M  	=	270
+NUMTILE32  	=	0
+NUMTILE32M  	=	0
+NUMEXTERN  	=	1
+;
+; File offsets for data items
+;
+STRUCTPIC  	=	0
+
+STARTFONT  	=	1
+STARTFONTM  	=	3
+STARTPICS  	=	3
+STARTPICM  	=	142
+STARTSPRITES  	=	142
+STARTTILE8  	=	142
+STARTTILE8M  	=	143
+STARTTILE16  	=	143
+STARTTILE16M  	=	287
+STARTTILE32  	=	557
+STARTTILE32M  	=	557
+STARTEXTERN  	=	557
+
+;
+; Thank you for using IGRAB!
+;
--- /dev/null
+++ b/WOLFSRC/GFXE_WL1.H
@@ -1,0 +1,211 @@
+//////////////////////////////////////
+//
+// Graphics .H file for .WL1
+// IGRAB-ed on Sat May 02 02:16:56 1992
+//
+//////////////////////////////////////
+
+typedef enum {
+		// Lump Start
+		H_BJPIC=3,
+		H_CASTLEPIC,                 // 4
+		H_KEYBOARDPIC,               // 5
+		H_JOYPIC,                    // 6
+		H_MOUSEPIC,                  // 7
+		H_BOTHPIC,                   // 8
+		H_GAMEPADPIC,                // 9
+		H_HEALPIC,                   // 10
+		H_TREASUREPIC,               // 11
+		H_GUNPIC,                    // 12
+		H_KEYPIC,                    // 13
+		H_BLAZEPIC,                  // 14
+		H_WEAPON1234PIC,             // 15
+		H_WOLFLOGOPIC,               // 16
+		H_VISAPIC,                   // 17
+		H_MCPIC,                     // 18
+		H_IDLOGOPIC,                 // 19
+		H_FAXPIC,                    // 20
+		H_GALACTIXPIC,               // 21
+		H_FGODMOMPIC,                // 22
+		H_AUSTRALIAPIC,              // 23
+		H_CANADAPIC,                 // 24
+		H_UKPIC,                     // 25
+		// Lump Start
+		C_OPTIONSPIC,                // 26
+		C_CURSOR1PIC,                // 27
+		C_CURSOR2PIC,                // 28
+		C_NOTSELECTEDPIC,            // 29
+		C_SELECTEDPIC,               // 30
+		C_FXTITLEPIC,                // 31
+		C_DIGITITLEPIC,              // 32
+		C_MUSICTITLEPIC,             // 33
+		C_MOUSELBACKPIC,             // 34
+		C_BABYMODEPIC,               // 35
+		C_EASYPIC,                   // 36
+		C_NORMALPIC,                 // 37
+		C_HARDPIC,                   // 38
+		C_LOADSAVEDISKPIC,           // 39
+		C_DISKLOADING1PIC,           // 40
+		C_DISKLOADING2PIC,           // 41
+		C_CONTROLPIC,                // 42
+		C_CUSTOMIZEPIC,              // 43
+		C_LOADGAMEPIC,               // 44
+		C_SAVEGAMEPIC,               // 45
+		C_EPISODE1PIC,               // 46
+		C_EPISODE2PIC,               // 47
+		C_EPISODE3PIC,               // 48
+		C_EPISODE4PIC,               // 49
+		C_EPISODE5PIC,               // 50
+		C_EPISODE6PIC,               // 51
+		C_CODEPIC,                   // 52
+		// Lump Start
+		L_GUYPIC,                    // 53
+		L_COLONPIC,                  // 54
+		L_NUM0PIC,                   // 55
+		L_NUM1PIC,                   // 56
+		L_NUM2PIC,                   // 57
+		L_NUM3PIC,                   // 58
+		L_NUM4PIC,                   // 59
+		L_NUM5PIC,                   // 60
+		L_NUM6PIC,                   // 61
+		L_NUM7PIC,                   // 62
+		L_NUM8PIC,                   // 63
+		L_NUM9PIC,                   // 64
+		L_PERCENTPIC,                // 65
+		L_APIC,                      // 66
+		L_BPIC,                      // 67
+		L_CPIC,                      // 68
+		L_DPIC,                      // 69
+		L_EPIC,                      // 70
+		L_FPIC,                      // 71
+		L_GPIC,                      // 72
+		L_HPIC,                      // 73
+		L_IPIC,                      // 74
+		L_JPIC,                      // 75
+		L_KPIC,                      // 76
+		L_LPIC,                      // 77
+		L_MPIC,                      // 78
+		L_NPIC,                      // 79
+		L_OPIC,                      // 80
+		L_PPIC,                      // 81
+		L_QPIC,                      // 82
+		L_RPIC,                      // 83
+		L_SPIC,                      // 84
+		L_TPIC,                      // 85
+		L_UPIC,                      // 86
+		L_VPIC,                      // 87
+		L_WPIC,                      // 88
+		L_XPIC,                      // 89
+		L_YPIC,                      // 90
+		L_ZPIC,                      // 91
+		L_GUY2PIC,                   // 92
+		L_BJWINSPIC,                 // 93
+		STATUSBARPIC,                // 94
+		TITLEPIC,                    // 95
+		PG13PIC,                     // 96
+		CREDITSPIC,                  // 97
+		HIGHSCORESPIC,               // 98
+		// Lump Start
+		KNIFEPIC,                    // 99
+		GUNPIC,                      // 100
+		MACHINEGUNPIC,               // 101
+		GATLINGGUNPIC,               // 102
+		NOKEYPIC,                    // 103
+		GOLDKEYPIC,                  // 104
+		SILVERKEYPIC,                // 105
+		N_BLANKPIC,                  // 106
+		N_0PIC,                      // 107
+		N_1PIC,                      // 108
+		N_2PIC,                      // 109
+		N_3PIC,                      // 110
+		N_4PIC,                      // 111
+		N_5PIC,                      // 112
+		N_6PIC,                      // 113
+		N_7PIC,                      // 114
+		N_8PIC,                      // 115
+		N_9PIC,                      // 116
+		FACE1APIC,                   // 117
+		FACE1BPIC,                   // 118
+		FACE1CPIC,                   // 119
+		FACE2APIC,                   // 120
+		FACE2BPIC,                   // 121
+		FACE2CPIC,                   // 122
+		FACE3APIC,                   // 123
+		FACE3BPIC,                   // 124
+		FACE3CPIC,                   // 125
+		FACE4APIC,                   // 126
+		FACE4BPIC,                   // 127
+		FACE4CPIC,                   // 128
+		FACE5APIC,                   // 129
+		FACE5BPIC,                   // 130
+		FACE5CPIC,                   // 131
+		FACE6APIC,                   // 132
+		FACE6BPIC,                   // 133
+		FACE6CPIC,                   // 134
+		FACE7APIC,                   // 135
+		FACE7BPIC,                   // 136
+		FACE7CPIC,                   // 137
+		FACE8APIC,                   // 138
+		GOTGATLINGPIC,               // 139
+		PAUSEDPIC,                   // 140
+		GETPSYCHEDPIC,               // 141
+
+
+
+		ORDERSCREEN=557,
+		ENUMEND
+	     } graphicnums;
+
+//
+// Data LUMPs
+//
+#define README_LUMP_START		3
+#define README_LUMP_END			25
+
+#define CONTROLS_LUMP_START		26
+#define CONTROLS_LUMP_END		52
+
+#define LEVELEND_LUMP_START		53
+#define LEVELEND_LUMP_END		93
+
+#define LATCHPICS_LUMP_START		99
+#define LATCHPICS_LUMP_END		141
+
+
+//
+// Amount of each data item
+//
+#define NUMCHUNKS    558
+#define NUMFONT      2
+#define NUMFONTM     0
+#define NUMPICS      139
+#define NUMPICM      0
+#define NUMSPRITES   0
+#define NUMTILE8     72
+#define NUMTILE8M    0
+#define NUMTILE16    144
+#define NUMTILE16M   270
+#define NUMTILE32    0
+#define NUMTILE32M   0
+#define NUMEXTERNS   1
+//
+// File offsets for data items
+//
+#define STRUCTPIC    0
+
+#define STARTFONT    1
+#define STARTFONTM   3
+#define STARTPICS    3
+#define STARTPICM    142
+#define STARTSPRITES 142
+#define STARTTILE8   142
+#define STARTTILE8M  143
+#define STARTTILE16  143
+#define STARTTILE16M 287
+#define STARTTILE32  557
+#define STARTTILE32M 557
+#define STARTEXTERNS 557
+
+//
+// Thank you for using IGRAB!
+//
--- /dev/null
+++ b/WOLFSRC/GFXE_WL6.EQU
@@ -1,0 +1,47 @@
+;=====================================
+;
+; Graphics .EQU file for .WL6
+; IGRAB-ed on Sun Aug 09 22:17:20 1992
+;
+;=====================================
+
+
+
+
+
+
+;
+; Amount of each data item
+;
+NUMCHUNKS	=	414
+NUMFONT  	=	0
+NUMFONTM  	=	0
+NUMPICS  	=	0
+NUMPICM  	=	0
+NUMSPRITES  	=	0
+NUMTILE8  	=	0
+NUMTILE8M  	=	0
+NUMTILE16  	=	144
+NUMTILE16M  	=	270
+NUMTILE32  	=	0
+NUMTILE32M  	=	0
+NUMEXTERN  	=	0
+;
+; File offsets for data items
+;
+STARTFONT  	=	0
+STARTFONTM  	=	0
+STARTPICS  	=	0
+STARTPICM  	=	0
+STARTSPRITES  	=	0
+STARTTILE8  	=	0
+STARTTILE8M  	=	0
+STARTTILE16  	=	0
+STARTTILE16M  	=	144
+STARTTILE32  	=	414
+STARTTILE32M  	=	414
+STARTEXTERN  	=	414
+
+;
+; Thank you for using IGRAB!
+;
--- /dev/null
+++ b/WOLFSRC/GFXE_WL6.H
@@ -1,0 +1,53 @@
+//////////////////////////////////////
+//
+// Graphics .H file for .WL6
+// IGRAB-ed on Sun Aug 09 22:17:20 1992
+//
+//////////////////////////////////////
+
+typedef enum {
+
+
+
+		ENUMEND
+	     } graphicnums;
+
+//
+// Data LUMPs
+//
+
+//
+// Amount of each data item
+//
+#define NUMCHUNKS    414
+#define NUMFONT      0
+#define NUMFONTM     0
+#define NUMPICS      0
+#define NUMPICM      0
+#define NUMSPRITES   0
+#define NUMTILE8     0
+#define NUMTILE8M    0
+#define NUMTILE16    144
+#define NUMTILE16M   270
+#define NUMTILE32    0
+#define NUMTILE32M   0
+#define NUMEXTERNS   0
+//
+// File offsets for data items
+//
+#define STARTFONT    0
+#define STARTFONTM   0
+#define STARTPICS    0
+#define STARTPICM    0
+#define STARTSPRITES 0
+#define STARTTILE8   0
+#define STARTTILE8M  0
+#define STARTTILE16  0
+#define STARTTILE16M 144
+#define STARTTILE32  414
+#define STARTTILE32M 414
+#define STARTEXTERNS 414
+
+//
+// Thank you for using IGRAB!
+//
--- /dev/null
+++ b/WOLFSRC/GFXV_SDM.EQU
@@ -1,0 +1,208 @@
+;=====================================
+;
+; Graphics .EQU file for .SDM
+; IGRAB-ed on Mon Sep 21 14:20:19 1992
+;
+;=====================================
+
+C_BACKDROPPIC			=	3
+C_MOUSELBACKPIC			=	4
+C_CURSOR1PIC			=	5
+C_CURSOR2PIC			=	6
+C_NOTSELECTEDPIC		=	7
+C_SELECTEDPIC			=	8
+C_CUSTOMIZEPIC			=	9
+C_JOY1PIC			=	10
+C_JOY2PIC			=	11
+C_MOUSEPIC			=	12
+C_JOYSTICKPIC			=	13
+C_KEYBOARDPIC			=	14
+C_CONTROLPIC			=	15
+C_OPTIONSPIC			=	16
+C_FXTITLEPIC			=	17
+C_DIGITITLEPIC			=	18
+C_MUSICTITLEPIC			=	19
+C_HOWTOUGHPIC			=	20
+C_BABYMODEPIC			=	21
+C_EASYPIC			=	22
+C_NORMALPIC			=	23
+C_HARDPIC			=	24
+C_DISKLOADING1PIC		=	25
+C_DISKLOADING2PIC		=	26
+C_LOADGAMEPIC			=	27
+C_SAVEGAMEPIC			=	28
+HIGHSCORESPIC			=	29
+C_WONSPEARPIC			=	30
+L_GUYPIC			=	31
+L_COLONPIC			=	32
+L_NUM0PIC			=	33
+L_NUM1PIC			=	34
+L_NUM2PIC			=	35
+L_NUM3PIC			=	36
+L_NUM4PIC			=	37
+L_NUM5PIC			=	38
+L_NUM6PIC			=	39
+L_NUM7PIC			=	40
+L_NUM8PIC			=	41
+L_NUM9PIC			=	42
+L_PERCENTPIC			=	43
+L_APIC				=	44
+L_BPIC				=	45
+L_CPIC				=	46
+L_DPIC				=	47
+L_EPIC				=	48
+L_FPIC				=	49
+L_GPIC				=	50
+L_HPIC				=	51
+L_IPIC				=	52
+L_JPIC				=	53
+L_KPIC				=	54
+L_LPIC				=	55
+L_MPIC				=	56
+L_NPIC				=	57
+L_OPIC				=	58
+L_PPIC				=	59
+L_QPIC				=	60
+L_RPIC				=	61
+L_SPIC				=	62
+L_TPIC				=	63
+L_UPIC				=	64
+L_VPIC				=	65
+L_WPIC				=	66
+L_XPIC				=	67
+L_YPIC				=	68
+L_ZPIC				=	69
+L_EXPOINTPIC			=	70
+L_APOSTROPHEPIC			=	71
+L_GUY2PIC			=	72
+L_BJWINSPIC			=	73
+TITLE1PIC			=	74
+TITLE2PIC			=	75
+STATUSBARPIC			=	76
+PG13PIC				=	77
+CREDITSPIC			=	78
+KNIFEPIC			=	79
+GUNPIC				=	80
+MACHINEGUNPIC			=	81
+GATLINGGUNPIC			=	82
+NOKEYPIC			=	83
+GOLDKEYPIC			=	84
+SILVERKEYPIC			=	85
+N_BLANKPIC			=	86
+N_0PIC				=	87
+N_1PIC				=	88
+N_2PIC				=	89
+N_3PIC				=	90
+N_4PIC				=	91
+N_5PIC				=	92
+N_6PIC				=	93
+N_7PIC				=	94
+N_8PIC				=	95
+N_9PIC				=	96
+FACE1APIC			=	97
+FACE1BPIC			=	98
+FACE1CPIC			=	99
+FACE2APIC			=	100
+FACE2BPIC			=	101
+FACE2CPIC			=	102
+FACE3APIC			=	103
+FACE3BPIC			=	104
+FACE3CPIC			=	105
+FACE4APIC			=	106
+FACE4BPIC			=	107
+FACE4CPIC			=	108
+FACE5APIC			=	109
+FACE5BPIC			=	110
+FACE5CPIC			=	111
+FACE6APIC			=	112
+FACE6BPIC			=	113
+FACE6CPIC			=	114
+FACE7APIC			=	115
+FACE7BPIC			=	116
+FACE7CPIC			=	117
+FACE8APIC			=	118
+GOTGATLINGPIC			=	119
+GODMODEFACE1PIC			=	120
+GODMODEFACE2PIC			=	121
+GODMODEFACE3PIC			=	122
+BJWAITING1PIC			=	123
+BJWAITING2PIC			=	124
+BJOUCHPIC			=	125
+PAUSEDPIC			=	126
+GETPSYCHEDPIC			=	127
+
+
+
+ORDERSCREEN			=	129
+ERRORSCREEN			=	130
+TITLEPALETTE			=	131
+T_DEMO0				=	132
+
+BACKDROP_LUMP_START		=	3
+BACKDROP_LUMP_END		=	8
+
+CONTROL_LUMP_START		=	9
+CONTROL_LUMP_END		=	15
+
+OPTIONS_LUMP_START		=	16
+OPTIONS_LUMP_END		=	16
+
+SOUND_LUMP_START		=	17
+SOUND_LUMP_END			=	19
+
+NEWGAME_LUMP_START		=	20
+NEWGAME_LUMP_END		=	24
+
+LOADSAVE_LUMP_START		=	25
+LOADSAVE_LUMP_END		=	28
+
+HIGHSCORES_LUMP_START		=	29
+HIGHSCORES_LUMP_END		=	30
+
+LEVELEND_LUMP_START		=	31
+LEVELEND_LUMP_END		=	73
+
+TITLESCREEN_LUMP_START		=	74
+TITLESCREEN_LUMP_END		=	75
+
+LATCHPICS_LUMP_START		=	79
+LATCHPICS_LUMP_END		=	127
+
+
+;
+; Amount of each data item
+;
+NUMCHUNKS	=	133
+NUMFONT  	=	2
+NUMFONTM  	=	0
+NUMPICS  	=	125
+NUMPICM  	=	0
+NUMSPRITES  	=	0
+NUMTILE8  	=	72
+NUMTILE8M  	=	0
+NUMTILE16  	=	0
+NUMTILE16M  	=	0
+NUMTILE32  	=	0
+NUMTILE32M  	=	0
+NUMEXTERN  	=	4
+;
+; File offsets for data items
+;
+STRUCTPIC  	=	0
+
+STARTFONT  	=	1
+STARTFONTM  	=	3
+STARTPICS  	=	3
+STARTPICM  	=	128
+STARTSPRITES  	=	128
+STARTTILE8  	=	128
+STARTTILE8M  	=	129
+STARTTILE16  	=	129
+STARTTILE16M  	=	129
+STARTTILE32  	=	129
+STARTTILE32M  	=	129
+STARTEXTERN  	=	129
+
+;
+; Thank you for using IGRAB!
+;
--- /dev/null
+++ b/WOLFSRC/GFXV_SDM.H
@@ -1,0 +1,224 @@
+//////////////////////////////////////
+//
+// Graphics .H file for .SDM
+// IGRAB-ed on Mon Sep 21 14:20:19 1992
+//
+//////////////////////////////////////
+
+typedef enum {
+		// Lump Start
+		C_BACKDROPPIC=3,
+		C_MOUSELBACKPIC,                     // 4
+		C_CURSOR1PIC,                        // 5
+		C_CURSOR2PIC,                        // 6
+		C_NOTSELECTEDPIC,                    // 7
+		C_SELECTEDPIC,                       // 8
+		// Lump Start
+		C_CUSTOMIZEPIC,                      // 9
+		C_JOY1PIC,                           // 10
+		C_JOY2PIC,                           // 11
+		C_MOUSEPIC,                          // 12
+		C_JOYSTICKPIC,                       // 13
+		C_KEYBOARDPIC,                       // 14
+		C_CONTROLPIC,                        // 15
+		// Lump Start
+		C_OPTIONSPIC,                        // 16
+		// Lump Start
+		C_FXTITLEPIC,                        // 17
+		C_DIGITITLEPIC,                      // 18
+		C_MUSICTITLEPIC,                     // 19
+		// Lump Start
+		C_HOWTOUGHPIC,                       // 20
+		C_BABYMODEPIC,                       // 21
+		C_EASYPIC,                           // 22
+		C_NORMALPIC,                         // 23
+		C_HARDPIC,                           // 24
+		// Lump Start
+		C_DISKLOADING1PIC,                   // 25
+		C_DISKLOADING2PIC,                   // 26
+		C_LOADGAMEPIC,                       // 27
+		C_SAVEGAMEPIC,                       // 28
+		// Lump Start
+		HIGHSCORESPIC,                       // 29
+		C_WONSPEARPIC,                       // 30
+		// Lump Start
+		L_GUYPIC,                            // 31
+		L_COLONPIC,                          // 32
+		L_NUM0PIC,                           // 33
+		L_NUM1PIC,                           // 34
+		L_NUM2PIC,                           // 35
+		L_NUM3PIC,                           // 36
+		L_NUM4PIC,                           // 37
+		L_NUM5PIC,                           // 38
+		L_NUM6PIC,                           // 39
+		L_NUM7PIC,                           // 40
+		L_NUM8PIC,                           // 41
+		L_NUM9PIC,                           // 42
+		L_PERCENTPIC,                        // 43
+		L_APIC,                              // 44
+		L_BPIC,                              // 45
+		L_CPIC,                              // 46
+		L_DPIC,                              // 47
+		L_EPIC,                              // 48
+		L_FPIC,                              // 49
+		L_GPIC,                              // 50
+		L_HPIC,                              // 51
+		L_IPIC,                              // 52
+		L_JPIC,                              // 53
+		L_KPIC,                              // 54
+		L_LPIC,                              // 55
+		L_MPIC,                              // 56
+		L_NPIC,                              // 57
+		L_OPIC,                              // 58
+		L_PPIC,                              // 59
+		L_QPIC,                              // 60
+		L_RPIC,                              // 61
+		L_SPIC,                              // 62
+		L_TPIC,                              // 63
+		L_UPIC,                              // 64
+		L_VPIC,                              // 65
+		L_WPIC,                              // 66
+		L_XPIC,                              // 67
+		L_YPIC,                              // 68
+		L_ZPIC,                              // 69
+		L_EXPOINTPIC,                        // 70
+		L_APOSTROPHEPIC,                     // 71
+		L_GUY2PIC,                           // 72
+		L_BJWINSPIC,                         // 73
+		// Lump Start
+		TITLE1PIC,                           // 74
+		TITLE2PIC,                           // 75
+		STATUSBARPIC,                        // 76
+		PG13PIC,                             // 77
+		CREDITSPIC,                          // 78
+		// Lump Start
+		KNIFEPIC,                            // 79
+		GUNPIC,                              // 80
+		MACHINEGUNPIC,                       // 81
+		GATLINGGUNPIC,                       // 82
+		NOKEYPIC,                            // 83
+		GOLDKEYPIC,                          // 84
+		SILVERKEYPIC,                        // 85
+		N_BLANKPIC,                          // 86
+		N_0PIC,                              // 87
+		N_1PIC,                              // 88
+		N_2PIC,                              // 89
+		N_3PIC,                              // 90
+		N_4PIC,                              // 91
+		N_5PIC,                              // 92
+		N_6PIC,                              // 93
+		N_7PIC,                              // 94
+		N_8PIC,                              // 95
+		N_9PIC,                              // 96
+		FACE1APIC,                           // 97
+		FACE1BPIC,                           // 98
+		FACE1CPIC,                           // 99
+		FACE2APIC,                           // 100
+		FACE2BPIC,                           // 101
+		FACE2CPIC,                           // 102
+		FACE3APIC,                           // 103
+		FACE3BPIC,                           // 104
+		FACE3CPIC,                           // 105
+		FACE4APIC,                           // 106
+		FACE4BPIC,                           // 107
+		FACE4CPIC,                           // 108
+		FACE5APIC,                           // 109
+		FACE5BPIC,                           // 110
+		FACE5CPIC,                           // 111
+		FACE6APIC,                           // 112
+		FACE6BPIC,                           // 113
+		FACE6CPIC,                           // 114
+		FACE7APIC,                           // 115
+		FACE7BPIC,                           // 116
+		FACE7CPIC,                           // 117
+		FACE8APIC,                           // 118
+		GOTGATLINGPIC,                       // 119
+		GODMODEFACE1PIC,                     // 120
+		GODMODEFACE2PIC,                     // 121
+		GODMODEFACE3PIC,                     // 122
+		BJWAITING1PIC,                       // 123
+		BJWAITING2PIC,                       // 124
+		BJOUCHPIC,                           // 125
+		PAUSEDPIC,                           // 126
+		GETPSYCHEDPIC,                       // 127
+
+
+
+		ORDERSCREEN=129,
+		ERRORSCREEN,                         // 130
+		TITLEPALETTE,                        // 131
+		T_DEMO0,                             // 132
+		ENUMEND
+	     } graphicnums;
+
+//
+// Data LUMPs
+//
+#define BACKDROP_LUMP_START		3
+#define BACKDROP_LUMP_END		8
+
+#define CONTROL_LUMP_START		9
+#define CONTROL_LUMP_END		15
+
+#define OPTIONS_LUMP_START		16
+#define OPTIONS_LUMP_END		16
+
+#define SOUND_LUMP_START		17
+#define SOUND_LUMP_END			19
+
+#define NEWGAME_LUMP_START		20
+#define NEWGAME_LUMP_END		24
+
+#define LOADSAVE_LUMP_START		25
+#define LOADSAVE_LUMP_END		28
+
+#define HIGHSCORES_LUMP_START		29
+#define HIGHSCORES_LUMP_END		30
+
+#define LEVELEND_LUMP_START		31
+#define LEVELEND_LUMP_END		73
+
+#define TITLESCREEN_LUMP_START		74
+#define TITLESCREEN_LUMP_END		75
+
+#define LATCHPICS_LUMP_START		79
+#define LATCHPICS_LUMP_END		127
+
+
+//
+// Amount of each data item
+//
+#define NUMCHUNKS    133
+#define NUMFONT      2
+#define NUMFONTM     0
+#define NUMPICS      125
+#define NUMPICM      0
+#define NUMSPRITES   0
+#define NUMTILE8     72
+#define NUMTILE8M    0
+#define NUMTILE16    0
+#define NUMTILE16M   0
+#define NUMTILE32    0
+#define NUMTILE32M   0
+#define NUMEXTERNS   4
+//
+// File offsets for data items
+//
+#define STRUCTPIC    0
+
+#define STARTFONT    1
+#define STARTFONTM   3
+#define STARTPICS    3
+#define STARTPICM    128
+#define STARTSPRITES 128
+#define STARTTILE8   128
+#define STARTTILE8M  129
+#define STARTTILE16  129
+#define STARTTILE16M 129
+#define STARTTILE32  129
+#define STARTTILE32M 129
+#define STARTEXTERNS 129
+
+//
+// Thank you for using IGRAB!
+//
--- /dev/null
+++ b/WOLFSRC/GFXV_SOD.EQU
@@ -1,0 +1,259 @@
+;=====================================
+;
+; Graphics .EQU file for .SOD
+; IGRAB-ed on Thu Oct 08 20:38:29 1992
+;
+;=====================================
+
+C_BACKDROPPIC			=	3
+C_MOUSELBACKPIC			=	4
+C_CURSOR1PIC			=	5
+C_CURSOR2PIC			=	6
+C_NOTSELECTEDPIC		=	7
+C_SELECTEDPIC			=	8
+C_CUSTOMIZEPIC			=	9
+C_JOY1PIC			=	10
+C_JOY2PIC			=	11
+C_MOUSEPIC			=	12
+C_JOYSTICKPIC			=	13
+C_KEYBOARDPIC			=	14
+C_CONTROLPIC			=	15
+C_OPTIONSPIC			=	16
+C_FXTITLEPIC			=	17
+C_DIGITITLEPIC			=	18
+C_MUSICTITLEPIC			=	19
+C_HOWTOUGHPIC			=	20
+C_BABYMODEPIC			=	21
+C_EASYPIC			=	22
+C_NORMALPIC			=	23
+C_HARDPIC			=	24
+C_DISKLOADING1PIC		=	25
+C_DISKLOADING2PIC		=	26
+C_LOADGAMEPIC			=	27
+C_SAVEGAMEPIC			=	28
+HIGHSCORESPIC			=	29
+C_WONSPEARPIC			=	30
+BJCOLLAPSE1PIC			=	31
+BJCOLLAPSE2PIC			=	32
+BJCOLLAPSE3PIC			=	33
+BJCOLLAPSE4PIC			=	34
+ENDPICPIC			=	35
+L_GUYPIC			=	36
+L_COLONPIC			=	37
+L_NUM0PIC			=	38
+L_NUM1PIC			=	39
+L_NUM2PIC			=	40
+L_NUM3PIC			=	41
+L_NUM4PIC			=	42
+L_NUM5PIC			=	43
+L_NUM6PIC			=	44
+L_NUM7PIC			=	45
+L_NUM8PIC			=	46
+L_NUM9PIC			=	47
+L_PERCENTPIC			=	48
+L_APIC				=	49
+L_BPIC				=	50
+L_CPIC				=	51
+L_DPIC				=	52
+L_EPIC				=	53
+L_FPIC				=	54
+L_GPIC				=	55
+L_HPIC				=	56
+L_IPIC				=	57
+L_JPIC				=	58
+L_KPIC				=	59
+L_LPIC				=	60
+L_MPIC				=	61
+L_NPIC				=	62
+L_OPIC				=	63
+L_PPIC				=	64
+L_QPIC				=	65
+L_RPIC				=	66
+L_SPIC				=	67
+L_TPIC				=	68
+L_UPIC				=	69
+L_VPIC				=	70
+L_WPIC				=	71
+L_XPIC				=	72
+L_YPIC				=	73
+L_ZPIC				=	74
+L_EXPOINTPIC			=	75
+L_APOSTROPHEPIC			=	76
+L_GUY2PIC			=	77
+L_BJWINSPIC			=	78
+TITLE1PIC			=	79
+TITLE2PIC			=	80
+ENDSCREEN11PIC			=	81
+ENDSCREEN12PIC			=	82
+ENDSCREEN3PIC			=	83
+ENDSCREEN4PIC			=	84
+ENDSCREEN5PIC			=	85
+ENDSCREEN6PIC			=	86
+ENDSCREEN7PIC			=	87
+ENDSCREEN8PIC			=	88
+ENDSCREEN9PIC			=	89
+STATUSBARPIC			=	90
+PG13PIC				=	91
+CREDITSPIC			=	92
+IDGUYS1PIC			=	93
+IDGUYS2PIC			=	94
+COPYPROTTOPPIC			=	95
+COPYPROTBOXPIC			=	96
+BOSSPIC1PIC			=	97
+BOSSPIC2PIC			=	98
+BOSSPIC3PIC			=	99
+BOSSPIC4PIC			=	100
+KNIFEPIC			=	101
+GUNPIC				=	102
+MACHINEGUNPIC			=	103
+GATLINGGUNPIC			=	104
+NOKEYPIC			=	105
+GOLDKEYPIC			=	106
+SILVERKEYPIC			=	107
+N_BLANKPIC			=	108
+N_0PIC				=	109
+N_1PIC				=	110
+N_2PIC				=	111
+N_3PIC				=	112
+N_4PIC				=	113
+N_5PIC				=	114
+N_6PIC				=	115
+N_7PIC				=	116
+N_8PIC				=	117
+N_9PIC				=	118
+FACE1APIC			=	119
+FACE1BPIC			=	120
+FACE1CPIC			=	121
+FACE2APIC			=	122
+FACE2BPIC			=	123
+FACE2CPIC			=	124
+FACE3APIC			=	125
+FACE3BPIC			=	126
+FACE3CPIC			=	127
+FACE4APIC			=	128
+FACE4BPIC			=	129
+FACE4CPIC			=	130
+FACE5APIC			=	131
+FACE5BPIC			=	132
+FACE5CPIC			=	133
+FACE6APIC			=	134
+FACE6BPIC			=	135
+FACE6CPIC			=	136
+FACE7APIC			=	137
+FACE7BPIC			=	138
+FACE7CPIC			=	139
+FACE8APIC			=	140
+GOTGATLINGPIC			=	141
+GODMODEFACE1PIC			=	142
+GODMODEFACE2PIC			=	143
+GODMODEFACE3PIC			=	144
+BJWAITING1PIC			=	145
+BJWAITING2PIC			=	146
+BJOUCHPIC			=	147
+PAUSEDPIC			=	148
+GETPSYCHEDPIC			=	149
+
+
+
+ORDERSCREEN			=	151
+ERRORSCREEN			=	152
+TITLEPALETTE			=	153
+END1PALETTE			=	154
+END2PALETTE			=	155
+END3PALETTE			=	156
+END4PALETTE			=	157
+END5PALETTE			=	158
+END6PALETTE			=	159
+END7PALETTE			=	160
+END8PALETTE			=	161
+END9PALETTE			=	162
+IDGUYSPALETTE			=	163
+T_DEMO0				=	164
+T_DEMO1				=	165
+T_DEMO2				=	166
+T_DEMO3				=	167
+T_ENDART1			=	168
+
+BACKDROP_LUMP_START		=	3
+BACKDROP_LUMP_END		=	8
+
+CONTROL_LUMP_START		=	9
+CONTROL_LUMP_END		=	15
+
+OPTIONS_LUMP_START		=	16
+OPTIONS_LUMP_END		=	16
+
+SOUND_LUMP_START		=	17
+SOUND_LUMP_END			=	19
+
+NEWGAME_LUMP_START		=	20
+NEWGAME_LUMP_END		=	24
+
+LOADSAVE_LUMP_START		=	25
+LOADSAVE_LUMP_END		=	28
+
+HIGHSCORES_LUMP_START		=	29
+HIGHSCORES_LUMP_END		=	30
+
+ENDGAME_LUMP_START		=	31
+ENDGAME_LUMP_END		=	35
+
+LEVELEND_LUMP_START		=	36
+LEVELEND_LUMP_END		=	78
+
+TITLESCREEN_LUMP_START		=	79
+TITLESCREEN_LUMP_END		=	80
+
+ENDGAME1_LUMP_START		=	81
+ENDGAME1_LUMP_END		=	81
+
+ENDGAME2_LUMP_START		=	82
+ENDGAME2_LUMP_END		=	82
+
+EASTEREGG_LUMP_START		=	93
+EASTEREGG_LUMP_END		=	94
+
+COPYPROT_LUMP_START		=	95
+COPYPROT_LUMP_END		=	100
+
+LATCHPICS_LUMP_START		=	101
+LATCHPICS_LUMP_END		=	149
+
+
+;
+; Amount of each data item
+;
+NUMCHUNKS	=	169
+NUMFONT  	=	2
+NUMFONTM  	=	0
+NUMPICS  	=	147
+NUMPICM  	=	0
+NUMSPRITES  	=	0
+NUMTILE8  	=	72
+NUMTILE8M  	=	0
+NUMTILE16  	=	0
+NUMTILE16M  	=	0
+NUMTILE32  	=	0
+NUMTILE32M  	=	0
+NUMEXTERN  	=	18
+;
+; File offsets for data items
+;
+STRUCTPIC  	=	0
+
+STARTFONT  	=	1
+STARTFONTM  	=	3
+STARTPICS  	=	3
+STARTPICM  	=	150
+STARTSPRITES  	=	150
+STARTTILE8  	=	150
+STARTTILE8M  	=	151
+STARTTILE16  	=	151
+STARTTILE16M  	=	151
+STARTTILE32  	=	151
+STARTTILE32M  	=	151
+STARTEXTERN  	=	151
+
+;
+; Thank you for using IGRAB!
+;
--- /dev/null
+++ b/WOLFSRC/GFXV_SOD.H
@@ -1,0 +1,280 @@
+//////////////////////////////////////
+//
+// Graphics .H file for .SOD
+// IGRAB-ed on Thu Oct 08 20:38:29 1992
+//
+//////////////////////////////////////
+
+typedef enum {
+		// Lump Start
+		C_BACKDROPPIC=3,
+		C_MOUSELBACKPIC,                     // 4
+		C_CURSOR1PIC,                        // 5
+		C_CURSOR2PIC,                        // 6
+		C_NOTSELECTEDPIC,                    // 7
+		C_SELECTEDPIC,                       // 8
+		// Lump Start
+		C_CUSTOMIZEPIC,                      // 9
+		C_JOY1PIC,                           // 10
+		C_JOY2PIC,                           // 11
+		C_MOUSEPIC,                          // 12
+		C_JOYSTICKPIC,                       // 13
+		C_KEYBOARDPIC,                       // 14
+		C_CONTROLPIC,                        // 15
+		// Lump Start
+		C_OPTIONSPIC,                        // 16
+		// Lump Start
+		C_FXTITLEPIC,                        // 17
+		C_DIGITITLEPIC,                      // 18
+		C_MUSICTITLEPIC,                     // 19
+		// Lump Start
+		C_HOWTOUGHPIC,                       // 20
+		C_BABYMODEPIC,                       // 21
+		C_EASYPIC,                           // 22
+		C_NORMALPIC,                         // 23
+		C_HARDPIC,                           // 24
+		// Lump Start
+		C_DISKLOADING1PIC,                   // 25
+		C_DISKLOADING2PIC,                   // 26
+		C_LOADGAMEPIC,                       // 27
+		C_SAVEGAMEPIC,                       // 28
+		// Lump Start
+		HIGHSCORESPIC,                       // 29
+		C_WONSPEARPIC,                       // 30
+		// Lump Start
+		BJCOLLAPSE1PIC,                      // 31
+		BJCOLLAPSE2PIC,                      // 32
+		BJCOLLAPSE3PIC,                      // 33
+		BJCOLLAPSE4PIC,                      // 34
+		ENDPICPIC,                           // 35
+		// Lump Start
+		L_GUYPIC,                            // 36
+		L_COLONPIC,                          // 37
+		L_NUM0PIC,                           // 38
+		L_NUM1PIC,                           // 39
+		L_NUM2PIC,                           // 40
+		L_NUM3PIC,                           // 41
+		L_NUM4PIC,                           // 42
+		L_NUM5PIC,                           // 43
+		L_NUM6PIC,                           // 44
+		L_NUM7PIC,                           // 45
+		L_NUM8PIC,                           // 46
+		L_NUM9PIC,                           // 47
+		L_PERCENTPIC,                        // 48
+		L_APIC,                              // 49
+		L_BPIC,                              // 50
+		L_CPIC,                              // 51
+		L_DPIC,                              // 52
+		L_EPIC,                              // 53
+		L_FPIC,                              // 54
+		L_GPIC,                              // 55
+		L_HPIC,                              // 56
+		L_IPIC,                              // 57
+		L_JPIC,                              // 58
+		L_KPIC,                              // 59
+		L_LPIC,                              // 60
+		L_MPIC,                              // 61
+		L_NPIC,                              // 62
+		L_OPIC,                              // 63
+		L_PPIC,                              // 64
+		L_QPIC,                              // 65
+		L_RPIC,                              // 66
+		L_SPIC,                              // 67
+		L_TPIC,                              // 68
+		L_UPIC,                              // 69
+		L_VPIC,                              // 70
+		L_WPIC,                              // 71
+		L_XPIC,                              // 72
+		L_YPIC,                              // 73
+		L_ZPIC,                              // 74
+		L_EXPOINTPIC,                        // 75
+		L_APOSTROPHEPIC,                     // 76
+		L_GUY2PIC,                           // 77
+		L_BJWINSPIC,                         // 78
+		// Lump Start
+		TITLE1PIC,                           // 79
+		TITLE2PIC,                           // 80
+		// Lump Start
+		ENDSCREEN11PIC,                      // 81
+		// Lump Start
+		ENDSCREEN12PIC,                      // 82
+		ENDSCREEN3PIC,                       // 83
+		ENDSCREEN4PIC,                       // 84
+		ENDSCREEN5PIC,                       // 85
+		ENDSCREEN6PIC,                       // 86
+		ENDSCREEN7PIC,                       // 87
+		ENDSCREEN8PIC,                       // 88
+		ENDSCREEN9PIC,                       // 89
+		STATUSBARPIC,                        // 90
+		PG13PIC,                             // 91
+		CREDITSPIC,                          // 92
+		// Lump Start
+		IDGUYS1PIC,                          // 93
+		IDGUYS2PIC,                          // 94
+		// Lump Start
+		COPYPROTTOPPIC,                      // 95
+		COPYPROTBOXPIC,                      // 96
+		BOSSPIC1PIC,                         // 97
+		BOSSPIC2PIC,                         // 98
+		BOSSPIC3PIC,                         // 99
+		BOSSPIC4PIC,                         // 100
+		// Lump Start
+		KNIFEPIC,                            // 101
+		GUNPIC,                              // 102
+		MACHINEGUNPIC,                       // 103
+		GATLINGGUNPIC,                       // 104
+		NOKEYPIC,                            // 105
+		GOLDKEYPIC,                          // 106
+		SILVERKEYPIC,                        // 107
+		N_BLANKPIC,                          // 108
+		N_0PIC,                              // 109
+		N_1PIC,                              // 110
+		N_2PIC,                              // 111
+		N_3PIC,                              // 112
+		N_4PIC,                              // 113
+		N_5PIC,                              // 114
+		N_6PIC,                              // 115
+		N_7PIC,                              // 116
+		N_8PIC,                              // 117
+		N_9PIC,                              // 118
+		FACE1APIC,                           // 119
+		FACE1BPIC,                           // 120
+		FACE1CPIC,                           // 121
+		FACE2APIC,                           // 122
+		FACE2BPIC,                           // 123
+		FACE2CPIC,                           // 124
+		FACE3APIC,                           // 125
+		FACE3BPIC,                           // 126
+		FACE3CPIC,                           // 127
+		FACE4APIC,                           // 128
+		FACE4BPIC,                           // 129
+		FACE4CPIC,                           // 130
+		FACE5APIC,                           // 131
+		FACE5BPIC,                           // 132
+		FACE5CPIC,                           // 133
+		FACE6APIC,                           // 134
+		FACE6BPIC,                           // 135
+		FACE6CPIC,                           // 136
+		FACE7APIC,                           // 137
+		FACE7BPIC,                           // 138
+		FACE7CPIC,                           // 139
+		FACE8APIC,                           // 140
+		GOTGATLINGPIC,                       // 141
+		GODMODEFACE1PIC,                     // 142
+		GODMODEFACE2PIC,                     // 143
+		GODMODEFACE3PIC,                     // 144
+		BJWAITING1PIC,                       // 145
+		BJWAITING2PIC,                       // 146
+		BJOUCHPIC,                           // 147
+		PAUSEDPIC,                           // 148
+		GETPSYCHEDPIC,                       // 149
+
+
+
+		ORDERSCREEN=151,
+		ERRORSCREEN,                         // 152
+		TITLEPALETTE,                        // 153
+		END1PALETTE,                         // 154
+		END2PALETTE,                         // 155
+		END3PALETTE,                         // 156
+		END4PALETTE,                         // 157
+		END5PALETTE,                         // 158
+		END6PALETTE,                         // 159
+		END7PALETTE,                         // 160
+		END8PALETTE,                         // 161
+		END9PALETTE,                         // 162
+		IDGUYSPALETTE,                       // 163
+		T_DEMO0,                             // 164
+		T_DEMO1,                             // 165
+		T_DEMO2,                             // 166
+		T_DEMO3,                             // 167
+		T_ENDART1,                           // 168
+		ENUMEND
+	     } graphicnums;
+
+//
+// Data LUMPs
+//
+#define BACKDROP_LUMP_START		3
+#define BACKDROP_LUMP_END		8
+
+#define CONTROL_LUMP_START		9
+#define CONTROL_LUMP_END		15
+
+#define OPTIONS_LUMP_START		16
+#define OPTIONS_LUMP_END		16
+
+#define SOUND_LUMP_START		17
+#define SOUND_LUMP_END			19
+
+#define NEWGAME_LUMP_START		20
+#define NEWGAME_LUMP_END		24
+
+#define LOADSAVE_LUMP_START		25
+#define LOADSAVE_LUMP_END		28
+
+#define HIGHSCORES_LUMP_START		29
+#define HIGHSCORES_LUMP_END		30
+
+#define ENDGAME_LUMP_START		31
+#define ENDGAME_LUMP_END		35
+
+#define LEVELEND_LUMP_START		36
+#define LEVELEND_LUMP_END		78
+
+#define TITLESCREEN_LUMP_START		79
+#define TITLESCREEN_LUMP_END		80
+
+#define ENDGAME1_LUMP_START		81
+#define ENDGAME1_LUMP_END		81
+
+#define ENDGAME2_LUMP_START		82
+#define ENDGAME2_LUMP_END		82
+
+#define EASTEREGG_LUMP_START		93
+#define EASTEREGG_LUMP_END		94
+
+#define COPYPROT_LUMP_START		95
+#define COPYPROT_LUMP_END		100
+
+#define LATCHPICS_LUMP_START		101
+#define LATCHPICS_LUMP_END		149
+
+
+//
+// Amount of each data item
+//
+#define NUMCHUNKS    169
+#define NUMFONT      2
+#define NUMFONTM     0
+#define NUMPICS      147
+#define NUMPICM      0
+#define NUMSPRITES   0
+#define NUMTILE8     72
+#define NUMTILE8M    0
+#define NUMTILE16    0
+#define NUMTILE16M   0
+#define NUMTILE32    0
+#define NUMTILE32M   0
+#define NUMEXTERNS   18
+//
+// File offsets for data items
+//
+#define STRUCTPIC    0
+
+#define STARTFONT    1
+#define STARTFONTM   3
+#define STARTPICS    3
+#define STARTPICM    150
+#define STARTSPRITES 150
+#define STARTTILE8   150
+#define STARTTILE8M  151
+#define STARTTILE16  151
+#define STARTTILE16M 151
+#define STARTTILE32  151
+#define STARTTILE32M 151
+#define STARTEXTERNS 151
+
+//
+// Thank you for using IGRAB!
+//
--- /dev/null
+++ b/WOLFSRC/GFXV_WL1.EQU
@@ -1,0 +1,199 @@
+;=====================================
+;
+; Graphics .EQU file for .WL1
+; IGRAB-ed on Sun May 03 01:19:32 1992
+;
+;=====================================
+
+H_BJPIC				=	3
+H_CASTLEPIC			=	4
+H_KEYBOARDPIC			=	5
+H_JOYPIC			=	6
+H_HEALPIC			=	7
+H_TREASUREPIC			=	8
+H_GUNPIC			=	9
+H_KEYPIC			=	10
+H_BLAZEPIC			=	11
+H_WEAPON1234PIC			=	12
+H_WOLFLOGOPIC			=	13
+H_VISAPIC			=	14
+H_MCPIC				=	15
+H_IDLOGOPIC			=	16
+H_TOPWINDOWPIC			=	17
+H_LEFTWINDOWPIC			=	18
+H_RIGHTWINDOWPIC		=	19
+H_BOTTOMINFOPIC			=	20
+C_OPTIONSPIC			=	21
+C_CURSOR1PIC			=	22
+C_CURSOR2PIC			=	23
+C_NOTSELECTEDPIC		=	24
+C_SELECTEDPIC			=	25
+C_FXTITLEPIC			=	26
+C_DIGITITLEPIC			=	27
+C_MUSICTITLEPIC			=	28
+C_MOUSELBACKPIC			=	29
+C_BABYMODEPIC			=	30
+C_EASYPIC			=	31
+C_NORMALPIC			=	32
+C_HARDPIC			=	33
+C_LOADSAVEDISKPIC		=	34
+C_DISKLOADING1PIC		=	35
+C_DISKLOADING2PIC		=	36
+C_CONTROLPIC			=	37
+C_CUSTOMIZEPIC			=	38
+C_LOADGAMEPIC			=	39
+C_SAVEGAMEPIC			=	40
+C_EPISODE1PIC			=	41
+C_EPISODE2PIC			=	42
+C_EPISODE3PIC			=	43
+C_EPISODE4PIC			=	44
+C_EPISODE5PIC			=	45
+C_EPISODE6PIC			=	46
+C_CODEPIC			=	47
+L_GUYPIC			=	48
+L_COLONPIC			=	49
+L_NUM0PIC			=	50
+L_NUM1PIC			=	51
+L_NUM2PIC			=	52
+L_NUM3PIC			=	53
+L_NUM4PIC			=	54
+L_NUM5PIC			=	55
+L_NUM6PIC			=	56
+L_NUM7PIC			=	57
+L_NUM8PIC			=	58
+L_NUM9PIC			=	59
+L_PERCENTPIC			=	60
+L_APIC				=	61
+L_BPIC				=	62
+L_CPIC				=	63
+L_DPIC				=	64
+L_EPIC				=	65
+L_FPIC				=	66
+L_GPIC				=	67
+L_HPIC				=	68
+L_IPIC				=	69
+L_JPIC				=	70
+L_KPIC				=	71
+L_LPIC				=	72
+L_MPIC				=	73
+L_NPIC				=	74
+L_OPIC				=	75
+L_PPIC				=	76
+L_QPIC				=	77
+L_RPIC				=	78
+L_SPIC				=	79
+L_TPIC				=	80
+L_UPIC				=	81
+L_VPIC				=	82
+L_WPIC				=	83
+L_XPIC				=	84
+L_YPIC				=	85
+L_ZPIC				=	86
+L_EXPOINTPIC			=	87
+L_GUY2PIC			=	88
+L_BJWINSPIC			=	89
+STATUSBARPIC			=	90
+TITLEPIC			=	91
+PG13PIC				=	92
+CREDITSPIC			=	93
+HIGHSCORESPIC			=	94
+KNIFEPIC			=	95
+GUNPIC				=	96
+MACHINEGUNPIC			=	97
+GATLINGGUNPIC			=	98
+NOKEYPIC			=	99
+GOLDKEYPIC			=	100
+SILVERKEYPIC			=	101
+N_BLANKPIC			=	102
+N_0PIC				=	103
+N_1PIC				=	104
+N_2PIC				=	105
+N_3PIC				=	106
+N_4PIC				=	107
+N_5PIC				=	108
+N_6PIC				=	109
+N_7PIC				=	110
+N_8PIC				=	111
+N_9PIC				=	112
+FACE1APIC			=	113
+FACE1BPIC			=	114
+FACE1CPIC			=	115
+FACE2APIC			=	116
+FACE2BPIC			=	117
+FACE2CPIC			=	118
+FACE3APIC			=	119
+FACE3BPIC			=	120
+FACE3CPIC			=	121
+FACE4APIC			=	122
+FACE4BPIC			=	123
+FACE4CPIC			=	124
+FACE5APIC			=	125
+FACE5BPIC			=	126
+FACE5CPIC			=	127
+FACE6APIC			=	128
+FACE6BPIC			=	129
+FACE6CPIC			=	130
+FACE7APIC			=	131
+FACE7BPIC			=	132
+FACE7CPIC			=	133
+FACE8APIC			=	134
+GOTGATLINGPIC			=	135
+MUTANTBJPIC			=	136
+PAUSEDPIC			=	137
+GETPSYCHEDPIC			=	138
+
+
+
+ORDERSCREEN			=	554
+ERRORSCREEN			=	555
+
+README_LUMP_START		=	3
+README_LUMP_END			=	20
+
+CONTROLS_LUMP_START		=	21
+CONTROLS_LUMP_END		=	47
+
+LEVELEND_LUMP_START		=	48
+LEVELEND_LUMP_END		=	89
+
+LATCHPICS_LUMP_START		=	95
+LATCHPICS_LUMP_END		=	138
+
+
+;
+; Amount of each data item
+;
+NUMCHUNKS	=	556
+NUMFONT  	=	2
+NUMFONTM  	=	0
+NUMPICS  	=	136
+NUMPICM  	=	0
+NUMSPRITES  	=	0
+NUMTILE8  	=	72
+NUMTILE8M  	=	0
+NUMTILE16  	=	144
+NUMTILE16M  	=	270
+NUMTILE32  	=	0
+NUMTILE32M  	=	0
+NUMEXTERN  	=	2
+;
+; File offsets for data items
+;
+STRUCTPIC  	=	0
+
+STARTFONT  	=	1
+STARTFONTM  	=	3
+STARTPICS  	=	3
+STARTPICM  	=	139
+STARTSPRITES  	=	139
+STARTTILE8  	=	139
+STARTTILE8M  	=	140
+STARTTILE16  	=	140
+STARTTILE16M  	=	284
+STARTTILE32  	=	554
+STARTTILE32M  	=	554
+STARTEXTERN  	=	554
+
+;
+; Thank you for using IGRAB!
+;
--- /dev/null
+++ b/WOLFSRC/GFXV_WL1.H
@@ -1,0 +1,209 @@
+//////////////////////////////////////
+//
+// Graphics .H file for .WL1
+// IGRAB-ed on Sun May 03 01:19:32 1992
+//
+//////////////////////////////////////
+
+typedef enum {
+		// Lump Start
+		H_BJPIC=3,
+		H_CASTLEPIC,                 // 4
+		H_KEYBOARDPIC,               // 5
+		H_JOYPIC,                    // 6
+		H_HEALPIC,                   // 7
+		H_TREASUREPIC,               // 8
+		H_GUNPIC,                    // 9
+		H_KEYPIC,                    // 10
+		H_BLAZEPIC,                  // 11
+		H_WEAPON1234PIC,             // 12
+		H_WOLFLOGOPIC,               // 13
+		H_VISAPIC,                   // 14
+		H_MCPIC,                     // 15
+		H_IDLOGOPIC,                 // 16
+		H_TOPWINDOWPIC,              // 17
+		H_LEFTWINDOWPIC,             // 18
+		H_RIGHTWINDOWPIC,            // 19
+		H_BOTTOMINFOPIC,             // 20
+		// Lump Start
+		C_OPTIONSPIC,                // 21
+		C_CURSOR1PIC,                // 22
+		C_CURSOR2PIC,                // 23
+		C_NOTSELECTEDPIC,            // 24
+		C_SELECTEDPIC,               // 25
+		C_FXTITLEPIC,                // 26
+		C_DIGITITLEPIC,              // 27
+		C_MUSICTITLEPIC,             // 28
+		C_MOUSELBACKPIC,             // 29
+		C_BABYMODEPIC,               // 30
+		C_EASYPIC,                   // 31
+		C_NORMALPIC,                 // 32
+		C_HARDPIC,                   // 33
+		C_LOADSAVEDISKPIC,           // 34
+		C_DISKLOADING1PIC,           // 35
+		C_DISKLOADING2PIC,           // 36
+		C_CONTROLPIC,                // 37
+		C_CUSTOMIZEPIC,              // 38
+		C_LOADGAMEPIC,               // 39
+		C_SAVEGAMEPIC,               // 40
+		C_EPISODE1PIC,               // 41
+		C_EPISODE2PIC,               // 42
+		C_EPISODE3PIC,               // 43
+		C_EPISODE4PIC,               // 44
+		C_EPISODE5PIC,               // 45
+		C_EPISODE6PIC,               // 46
+		C_CODEPIC,                   // 47
+		// Lump Start
+		L_GUYPIC,                    // 48
+		L_COLONPIC,                  // 49
+		L_NUM0PIC,                   // 50
+		L_NUM1PIC,                   // 51
+		L_NUM2PIC,                   // 52
+		L_NUM3PIC,                   // 53
+		L_NUM4PIC,                   // 54
+		L_NUM5PIC,                   // 55
+		L_NUM6PIC,                   // 56
+		L_NUM7PIC,                   // 57
+		L_NUM8PIC,                   // 58
+		L_NUM9PIC,                   // 59
+		L_PERCENTPIC,                // 60
+		L_APIC,                      // 61
+		L_BPIC,                      // 62
+		L_CPIC,                      // 63
+		L_DPIC,                      // 64
+		L_EPIC,                      // 65
+		L_FPIC,                      // 66
+		L_GPIC,                      // 67
+		L_HPIC,                      // 68
+		L_IPIC,                      // 69
+		L_JPIC,                      // 70
+		L_KPIC,                      // 71
+		L_LPIC,                      // 72
+		L_MPIC,                      // 73
+		L_NPIC,                      // 74
+		L_OPIC,                      // 75
+		L_PPIC,                      // 76
+		L_QPIC,                      // 77
+		L_RPIC,                      // 78
+		L_SPIC,                      // 79
+		L_TPIC,                      // 80
+		L_UPIC,                      // 81
+		L_VPIC,                      // 82
+		L_WPIC,                      // 83
+		L_XPIC,                      // 84
+		L_YPIC,                      // 85
+		L_ZPIC,                      // 86
+		L_EXPOINTPIC,                // 87
+		L_GUY2PIC,                   // 88
+		L_BJWINSPIC,                 // 89
+		STATUSBARPIC,                // 90
+		TITLEPIC,                    // 91
+		PG13PIC,                     // 92
+		CREDITSPIC,                  // 93
+		HIGHSCORESPIC,               // 94
+		// Lump Start
+		KNIFEPIC,                    // 95
+		GUNPIC,                      // 96
+		MACHINEGUNPIC,               // 97
+		GATLINGGUNPIC,               // 98
+		NOKEYPIC,                    // 99
+		GOLDKEYPIC,                  // 100
+		SILVERKEYPIC,                // 101
+		N_BLANKPIC,                  // 102
+		N_0PIC,                      // 103
+		N_1PIC,                      // 104
+		N_2PIC,                      // 105
+		N_3PIC,                      // 106
+		N_4PIC,                      // 107
+		N_5PIC,                      // 108
+		N_6PIC,                      // 109
+		N_7PIC,                      // 110
+		N_8PIC,                      // 111
+		N_9PIC,                      // 112
+		FACE1APIC,                   // 113
+		FACE1BPIC,                   // 114
+		FACE1CPIC,                   // 115
+		FACE2APIC,                   // 116
+		FACE2BPIC,                   // 117
+		FACE2CPIC,                   // 118
+		FACE3APIC,                   // 119
+		FACE3BPIC,                   // 120
+		FACE3CPIC,                   // 121
+		FACE4APIC,                   // 122
+		FACE4BPIC,                   // 123
+		FACE4CPIC,                   // 124
+		FACE5APIC,                   // 125
+		FACE5BPIC,                   // 126
+		FACE5CPIC,                   // 127
+		FACE6APIC,                   // 128
+		FACE6BPIC,                   // 129
+		FACE6CPIC,                   // 130
+		FACE7APIC,                   // 131
+		FACE7BPIC,                   // 132
+		FACE7CPIC,                   // 133
+		FACE8APIC,                   // 134
+		GOTGATLINGPIC,               // 135
+		MUTANTBJPIC,                 // 136
+		PAUSEDPIC,                   // 137
+		GETPSYCHEDPIC,               // 138
+
+
+
+		ORDERSCREEN=554,
+		ERRORSCREEN,                 // 555
+		ENUMEND
+	     } graphicnums;
+
+//
+// Data LUMPs
+//
+#define README_LUMP_START		3
+#define README_LUMP_END			20
+
+#define CONTROLS_LUMP_START		21
+#define CONTROLS_LUMP_END		47
+
+#define LEVELEND_LUMP_START		48
+#define LEVELEND_LUMP_END		89
+
+#define LATCHPICS_LUMP_START		95
+#define LATCHPICS_LUMP_END		138
+
+
+//
+// Amount of each data item
+//
+#define NUMCHUNKS    556
+#define NUMFONT      2
+#define NUMFONTM     0
+#define NUMPICS      136
+#define NUMPICM      0
+#define NUMSPRITES   0
+#define NUMTILE8     72
+#define NUMTILE8M    0
+#define NUMTILE16    144
+#define NUMTILE16M   270
+#define NUMTILE32    0
+#define NUMTILE32M   0
+#define NUMEXTERNS   2
+//
+// File offsets for data items
+//
+#define STRUCTPIC    0
+
+#define STARTFONT    1
+#define STARTFONTM   3
+#define STARTPICS    3
+#define STARTPICM    139
+#define STARTSPRITES 139
+#define STARTTILE8   139
+#define STARTTILE8M  140
+#define STARTTILE16  140
+#define STARTTILE16M 284
+#define STARTTILE32  554
+#define STARTTILE32M 554
+#define STARTEXTERNS 554
+
+//
+// Thank you for using IGRAB!
+//
--- /dev/null
+++ b/WOLFSRC/GFXV_WL6.EQU
@@ -1,0 +1,206 @@
+;=====================================
+;
+; Graphics .EQU file for .WL6
+; IGRAB-ed on Wed Apr 13 06:58:44 1994
+;
+;=====================================
+
+H_BJPIC				=	3
+H_CASTLEPIC			=	4
+H_BLAZEPIC			=	5
+H_TOPWINDOWPIC			=	6
+H_LEFTWINDOWPIC			=	7
+H_RIGHTWINDOWPIC		=	8
+H_BOTTOMINFOPIC			=	9
+C_OPTIONSPIC			=	10
+C_CURSOR1PIC			=	11
+C_CURSOR2PIC			=	12
+C_NOTSELECTEDPIC		=	13
+C_SELECTEDPIC			=	14
+C_FXTITLEPIC			=	15
+C_DIGITITLEPIC			=	16
+C_MUSICTITLEPIC			=	17
+C_MOUSELBACKPIC			=	18
+C_BABYMODEPIC			=	19
+C_EASYPIC			=	20
+C_NORMALPIC			=	21
+C_HARDPIC			=	22
+C_LOADSAVEDISKPIC		=	23
+C_DISKLOADING1PIC		=	24
+C_DISKLOADING2PIC		=	25
+C_CONTROLPIC			=	26
+C_CUSTOMIZEPIC			=	27
+C_LOADGAMEPIC			=	28
+C_SAVEGAMEPIC			=	29
+C_EPISODE1PIC			=	30
+C_EPISODE2PIC			=	31
+C_EPISODE3PIC			=	32
+C_EPISODE4PIC			=	33
+C_EPISODE5PIC			=	34
+C_EPISODE6PIC			=	35
+C_CODEPIC			=	36
+C_TIMECODEPIC			=	37
+C_LEVELPIC			=	38
+C_NAMEPIC			=	39
+C_SCOREPIC			=	40
+C_JOY1PIC			=	41
+C_JOY2PIC			=	42
+L_GUYPIC			=	43
+L_COLONPIC			=	44
+L_NUM0PIC			=	45
+L_NUM1PIC			=	46
+L_NUM2PIC			=	47
+L_NUM3PIC			=	48
+L_NUM4PIC			=	49
+L_NUM5PIC			=	50
+L_NUM6PIC			=	51
+L_NUM7PIC			=	52
+L_NUM8PIC			=	53
+L_NUM9PIC			=	54
+L_PERCENTPIC			=	55
+L_APIC				=	56
+L_BPIC				=	57
+L_CPIC				=	58
+L_DPIC				=	59
+L_EPIC				=	60
+L_FPIC				=	61
+L_GPIC				=	62
+L_HPIC				=	63
+L_IPIC				=	64
+L_JPIC				=	65
+L_KPIC				=	66
+L_LPIC				=	67
+L_MPIC				=	68
+L_NPIC				=	69
+L_OPIC				=	70
+L_PPIC				=	71
+L_QPIC				=	72
+L_RPIC				=	73
+L_SPIC				=	74
+L_TPIC				=	75
+L_UPIC				=	76
+L_VPIC				=	77
+L_WPIC				=	78
+L_XPIC				=	79
+L_YPIC				=	80
+L_ZPIC				=	81
+L_EXPOINTPIC			=	82
+L_APOSTROPHEPIC			=	83
+L_GUY2PIC			=	84
+L_BJWINSPIC			=	85
+STATUSBARPIC			=	86
+TITLEPIC			=	87
+PG13PIC				=	88
+CREDITSPIC			=	89
+HIGHSCORESPIC			=	90
+KNIFEPIC			=	91
+GUNPIC				=	92
+MACHINEGUNPIC			=	93
+GATLINGGUNPIC			=	94
+NOKEYPIC			=	95
+GOLDKEYPIC			=	96
+SILVERKEYPIC			=	97
+N_BLANKPIC			=	98
+N_0PIC				=	99
+N_1PIC				=	100
+N_2PIC				=	101
+N_3PIC				=	102
+N_4PIC				=	103
+N_5PIC				=	104
+N_6PIC				=	105
+N_7PIC				=	106
+N_8PIC				=	107
+N_9PIC				=	108
+FACE1APIC			=	109
+FACE1BPIC			=	110
+FACE1CPIC			=	111
+FACE2APIC			=	112
+FACE2BPIC			=	113
+FACE2CPIC			=	114
+FACE3APIC			=	115
+FACE3BPIC			=	116
+FACE3CPIC			=	117
+FACE4APIC			=	118
+FACE4BPIC			=	119
+FACE4CPIC			=	120
+FACE5APIC			=	121
+FACE5BPIC			=	122
+FACE5CPIC			=	123
+FACE6APIC			=	124
+FACE6BPIC			=	125
+FACE6CPIC			=	126
+FACE7APIC			=	127
+FACE7BPIC			=	128
+FACE7CPIC			=	129
+FACE8APIC			=	130
+GOTGATLINGPIC			=	131
+MUTANTBJPIC			=	132
+PAUSEDPIC			=	133
+GETPSYCHEDPIC			=	134
+
+
+
+ORDERSCREEN			=	136
+ERRORSCREEN			=	137
+T_HELPART			=	138
+T_DEMO0				=	139
+T_DEMO1				=	140
+T_DEMO2				=	141
+T_DEMO3				=	142
+T_ENDART1			=	143
+T_ENDART2			=	144
+T_ENDART3			=	145
+T_ENDART4			=	146
+T_ENDART5			=	147
+T_ENDART6			=	148
+
+README_LUMP_START		=	3
+README_LUMP_END			=	9
+
+CONTROLS_LUMP_START		=	10
+CONTROLS_LUMP_END		=	42
+
+LEVELEND_LUMP_START		=	43
+LEVELEND_LUMP_END		=	85
+
+LATCHPICS_LUMP_START		=	91
+LATCHPICS_LUMP_END		=	134
+
+
+;
+; Amount of each data item
+;
+NUMCHUNKS	=	149
+NUMFONT  	=	2
+NUMFONTM  	=	0
+NUMPICS  	=	132
+NUMPICM  	=	0
+NUMSPRITES  	=	0
+NUMTILE8  	=	72
+NUMTILE8M  	=	0
+NUMTILE16  	=	0
+NUMTILE16M  	=	0
+NUMTILE32  	=	0
+NUMTILE32M  	=	0
+NUMEXTERN  	=	13
+;
+; File offsets for data items
+;
+STRUCTPIC  	=	0
+
+STARTFONT  	=	1
+STARTFONTM  	=	3
+STARTPICS  	=	3
+STARTPICM  	=	135
+STARTSPRITES  	=	135
+STARTTILE8  	=	135
+STARTTILE8M  	=	136
+STARTTILE16  	=	136
+STARTTILE16M  	=	136
+STARTTILE32  	=	136
+STARTTILE32M  	=	136
+STARTEXTERN  	=	136
+
+;
+; Thank you for using IGRAB!
+;
--- /dev/null
+++ b/WOLFSRC/GFXV_WL6.H
@@ -1,0 +1,216 @@
+//////////////////////////////////////
+//
+// Graphics .H file for .WL6
+// IGRAB-ed on Wed Apr 13 06:58:44 1994
+//
+//////////////////////////////////////
+
+typedef enum {
+		// Lump Start
+		H_BJPIC=3,
+		H_CASTLEPIC,                         // 4
+		H_BLAZEPIC,                          // 5
+		H_TOPWINDOWPIC,                      // 6
+		H_LEFTWINDOWPIC,                     // 7
+		H_RIGHTWINDOWPIC,                    // 8
+		H_BOTTOMINFOPIC,                     // 9
+		// Lump Start
+		C_OPTIONSPIC,                        // 10
+		C_CURSOR1PIC,                        // 11
+		C_CURSOR2PIC,                        // 12
+		C_NOTSELECTEDPIC,                    // 13
+		C_SELECTEDPIC,                       // 14
+		C_FXTITLEPIC,                        // 15
+		C_DIGITITLEPIC,                      // 16
+		C_MUSICTITLEPIC,                     // 17
+		C_MOUSELBACKPIC,                     // 18
+		C_BABYMODEPIC,                       // 19
+		C_EASYPIC,                           // 20
+		C_NORMALPIC,                         // 21
+		C_HARDPIC,                           // 22
+		C_LOADSAVEDISKPIC,                   // 23
+		C_DISKLOADING1PIC,                   // 24
+		C_DISKLOADING2PIC,                   // 25
+		C_CONTROLPIC,                        // 26
+		C_CUSTOMIZEPIC,                      // 27
+		C_LOADGAMEPIC,                       // 28
+		C_SAVEGAMEPIC,                       // 29
+		C_EPISODE1PIC,                       // 30
+		C_EPISODE2PIC,                       // 31
+		C_EPISODE3PIC,                       // 32
+		C_EPISODE4PIC,                       // 33
+		C_EPISODE5PIC,                       // 34
+		C_EPISODE6PIC,                       // 35
+		C_CODEPIC,                           // 36
+		C_TIMECODEPIC,                       // 37
+		C_LEVELPIC,                          // 38
+		C_NAMEPIC,                           // 39
+		C_SCOREPIC,                          // 40
+		C_JOY1PIC,                           // 41
+		C_JOY2PIC,                           // 42
+		// Lump Start
+		L_GUYPIC,                            // 43
+		L_COLONPIC,                          // 44
+		L_NUM0PIC,                           // 45
+		L_NUM1PIC,                           // 46
+		L_NUM2PIC,                           // 47
+		L_NUM3PIC,                           // 48
+		L_NUM4PIC,                           // 49
+		L_NUM5PIC,                           // 50
+		L_NUM6PIC,                           // 51
+		L_NUM7PIC,                           // 52
+		L_NUM8PIC,                           // 53
+		L_NUM9PIC,                           // 54
+		L_PERCENTPIC,                        // 55
+		L_APIC,                              // 56
+		L_BPIC,                              // 57
+		L_CPIC,                              // 58
+		L_DPIC,                              // 59
+		L_EPIC,                              // 60
+		L_FPIC,                              // 61
+		L_GPIC,                              // 62
+		L_HPIC,                              // 63
+		L_IPIC,                              // 64
+		L_JPIC,                              // 65
+		L_KPIC,                              // 66
+		L_LPIC,                              // 67
+		L_MPIC,                              // 68
+		L_NPIC,                              // 69
+		L_OPIC,                              // 70
+		L_PPIC,                              // 71
+		L_QPIC,                              // 72
+		L_RPIC,                              // 73
+		L_SPIC,                              // 74
+		L_TPIC,                              // 75
+		L_UPIC,                              // 76
+		L_VPIC,                              // 77
+		L_WPIC,                              // 78
+		L_XPIC,                              // 79
+		L_YPIC,                              // 80
+		L_ZPIC,                              // 81
+		L_EXPOINTPIC,                        // 82
+		L_APOSTROPHEPIC,                     // 83
+		L_GUY2PIC,                           // 84
+		L_BJWINSPIC,                         // 85
+		STATUSBARPIC,                        // 86
+		TITLEPIC,                            // 87
+		PG13PIC,                             // 88
+		CREDITSPIC,                          // 89
+		HIGHSCORESPIC,                       // 90
+		// Lump Start
+		KNIFEPIC,                            // 91
+		GUNPIC,                              // 92
+		MACHINEGUNPIC,                       // 93
+		GATLINGGUNPIC,                       // 94
+		NOKEYPIC,                            // 95
+		GOLDKEYPIC,                          // 96
+		SILVERKEYPIC,                        // 97
+		N_BLANKPIC,                          // 98
+		N_0PIC,                              // 99
+		N_1PIC,                              // 100
+		N_2PIC,                              // 101
+		N_3PIC,                              // 102
+		N_4PIC,                              // 103
+		N_5PIC,                              // 104
+		N_6PIC,                              // 105
+		N_7PIC,                              // 106
+		N_8PIC,                              // 107
+		N_9PIC,                              // 108
+		FACE1APIC,                           // 109
+		FACE1BPIC,                           // 110
+		FACE1CPIC,                           // 111
+		FACE2APIC,                           // 112
+		FACE2BPIC,                           // 113
+		FACE2CPIC,                           // 114
+		FACE3APIC,                           // 115
+		FACE3BPIC,                           // 116
+		FACE3CPIC,                           // 117
+		FACE4APIC,                           // 118
+		FACE4BPIC,                           // 119
+		FACE4CPIC,                           // 120
+		FACE5APIC,                           // 121
+		FACE5BPIC,                           // 122
+		FACE5CPIC,                           // 123
+		FACE6APIC,                           // 124
+		FACE6BPIC,                           // 125
+		FACE6CPIC,                           // 126
+		FACE7APIC,                           // 127
+		FACE7BPIC,                           // 128
+		FACE7CPIC,                           // 129
+		FACE8APIC,                           // 130
+		GOTGATLINGPIC,                       // 131
+		MUTANTBJPIC,                         // 132
+		PAUSEDPIC,                           // 133
+		GETPSYCHEDPIC,                       // 134
+
+
+
+		ORDERSCREEN=136,
+		ERRORSCREEN,                         // 137
+		T_HELPART,                           // 138
+		T_DEMO0,                             // 139
+		T_DEMO1,                             // 140
+		T_DEMO2,                             // 141
+		T_DEMO3,                             // 142
+		T_ENDART1,                           // 143
+		T_ENDART2,                           // 144
+		T_ENDART3,                           // 145
+		T_ENDART4,                           // 146
+		T_ENDART5,                           // 147
+		T_ENDART6,                           // 148
+		ENUMEND
+	     } graphicnums;
+
+//
+// Data LUMPs
+//
+#define README_LUMP_START		3
+#define README_LUMP_END			9
+
+#define CONTROLS_LUMP_START		10
+#define CONTROLS_LUMP_END		42
+
+#define LEVELEND_LUMP_START		43
+#define LEVELEND_LUMP_END		85
+
+#define LATCHPICS_LUMP_START		91
+#define LATCHPICS_LUMP_END		134
+
+
+//
+// Amount of each data item
+//
+#define NUMCHUNKS    149
+#define NUMFONT      2
+#define NUMFONTM     0
+#define NUMPICS      132
+#define NUMPICM      0
+#define NUMSPRITES   0
+#define NUMTILE8     72
+#define NUMTILE8M    0
+#define NUMTILE16    0
+#define NUMTILE16M   0
+#define NUMTILE32    0
+#define NUMTILE32M   0
+#define NUMEXTERNS   13
+//
+// File offsets for data items
+//
+#define STRUCTPIC    0
+
+#define STARTFONT    1
+#define STARTFONTM   3
+#define STARTPICS    3
+#define STARTPICM    135
+#define STARTSPRITES 135
+#define STARTTILE8   135
+#define STARTTILE8M  136
+#define STARTTILE16  136
+#define STARTTILE16M 136
+#define STARTTILE32  136
+#define STARTTILE32M 136
+#define STARTEXTERNS 136
+
+//
+// Thank you for using IGRAB!
+//
--- /dev/null
+++ b/WOLFSRC/GO.BAT
@@ -1,0 +1,5 @@
+sv readme\license.doc
+sv readme\release.txt
+sv readme\readme.txt
+@ECHO Get to Work!
+
--- /dev/null
+++ b/WOLFSRC/GOODSTUF.TXT
@@ -1,0 +1,56 @@
+To:             ROMERO,TOM
+From:           LOTHAR/JAY
+Date:           9 Aug 92 21:06:46
+Subject:        AOL Message
+X-mailer:       Pegasus Mail v2.3 (R2).
+
+Subj:   DREAMS, FLASHBACKS
+Date:   92-08-09 03:59:55 EDT
+From:   Tug Hill 2
+Posted on: America Online
+
+On a serious note...
+
+As a former POW (Vietnam), I hesitated to play WOLF for over a
+month after downloading as I feared flashbacks.  I didn't want to
+remember all that I had been through all those years ago, when, as
+POW's, my friend and I decided an escape attempt would be better than
+a slow death by torture and starvation.
+
+My friend and I made crude maps and hoarded food. The day of the
+escape we clubbed the guard with stones, took his gun and fought our
+way through two levels of underground tunnels (only a few guards and
+had to crawl).  I made it, my friend didn't.
+
+Dreams...NO!  NIGHTMARES...YES!!  However, the more I play
+WOLF the less frequently I have nightmares.  The chilling part is
+turning a corner and seeing a guard with his gun drawn.
+
+WOLF is a powerful game.  Fearful as well.  I believe that a
+person should face the past.  So... when I can play EPISODE 1
+comfortably (no nightmares), I plan on ordering the full series.
+
+Don't let a few bad dreams make you discard this game.
+
+-------------------------------------------------------------------------
+
+Subj:   Wolf-3D                 Section: Action/Arcade Games
+From:   Ty Graham 72350,2636    # 191387, * No Replies *
+To:     Id Software 72600,1333  Date: 24-Jul-92 18:27:27
+
+Jay, just thought I'd drop a note to let you know how popular Wolf3D is
+here at Microsoft.  It seems like I can't walk down a hall without hearing
+'Mein Leben' from someone's office.  I hope you guys are getting revenue
+from all this.
+
+Anyway, we were sitting around talking the other day, discussing games for
+Windows, and someone said 'What are those cool guys at Id doing?'.  So how
+about it.  Are you guys looking at Win games at all?  Win32?
+
+In a perfect world, I'd have you guys port the Wolf engine to a multiuser
+maze game for Windows for Workgroups.  We need a good M'user Win game.
+
+Anyway some thoughts.
+
+Ty Graham (Microsoft)
+
--- /dev/null
+++ b/WOLFSRC/H_LDIV.ASM
@@ -1,0 +1,227 @@
+;[]-----------------------------------------------------------------[]
+;|      H_LDIV.ASM -- long division routine                          |
+;|                                                                   |
+;|      C/C++ Run Time Library        Version 4.0                    |
+;|                                                                   |
+;|      Copyright (c) 1987, 1991 by Borland International Inc.       |
+;|      All Rights Reserved.                                         |
+;[]-----------------------------------------------------------------[]
+.model medium
+	INCLUDE RULES.ASI
+.386C   ;JAB - we use 386 instructions
+
+_TEXT   segment public byte 'CODE'
+	assume  cs:_TEXT
+	public  LDIV@
+	public  F_LDIV@
+	public  N_LDIV@
+	public  LUDIV@
+	public  F_LUDIV@
+		public  N_LUDIV@
+	public  LMOD@
+	public  F_LMOD@
+		public  N_LMOD@
+	public  LUMOD@
+	public  F_LUMOD@
+		public  N_LUMOD@
+
+N_LDIV@:
+		pop     cx                      ;fix up far return
+		push    cs
+		push    cx
+LDIV@:
+F_LDIV@:
+	xor     cx,cx                   ; signed divide
+	jmp     short common
+
+;       JAB
+;
+;       If we're using a 386 or better, the two instructions above get patched
+;               to be NOP's (4 of them). So, instead of using the looping code,
+;               we use the 386's long divide instruction.
+;
+;       The stack after setting up the stack frame:
+;               12[bp]: divisor (high word)
+;               10[bp]: divisor (low word)
+;                8[bp]: dividend (high word)
+;                6[bp]: dividend (low word)
+;                4[bp]: return CS
+;                2[bp]: return IP
+;                0[bp]: previous BP
+;
+	IDEAL
+
+	push bp
+	mov     bp,sp   ;Save BP, and set it equal to stack
+
+	mov     eax,[DWORD PTR bp+6]
+	cdq
+	idiv [DWORD PTR bp+10]
+	mov     edx,eax
+	shr     edx,16
+
+	pop     bp              ;Restore BP
+	retf    8       ;Return to original caller
+
+	MASM
+
+N_LUDIV@:
+		pop     cx                      ;fix up far return
+		push    cs
+		push    cx
+LUDIV@:
+F_LUDIV@:
+	mov     cx,1                    ; unsigned divide
+	jmp     short common
+
+N_LMOD@:
+		pop     cx                      ;fix up far return
+		push    cs
+		push    cx
+LMOD@:
+F_LMOD@:
+	mov     cx,2                    ; signed remainder
+	jmp     short   common
+
+N_LUMOD@:
+		pop     cx                      ;fix up far return
+		push    cs
+		push    cx
+LUMOD@:
+F_LUMOD@:
+	mov     cx,3                    ; unsigned remainder
+
+;
+;       di now contains a two bit control value.  The low order
+;       bit (test mask of 1) is on if the operation is unsigned,
+;       signed otherwise.  The next bit (test mask of 2) is on if
+;       the operation returns the remainder, quotient otherwise.
+;
+common:
+	push    bp
+	push    si
+	push    di
+	mov     bp,sp                   ; set up frame
+	mov     di,cx
+;
+;       dividend is pushed last, therefore the first in the args
+;       divisor next.
+;
+	mov     ax,10[bp]               ; get the first low word
+	mov     dx,12[bp]               ; get the first high word
+	mov     bx,14[bp]               ; get the second low word
+	mov     cx,16[bp]               ; get the second high word
+
+	or      cx,cx
+	jnz     slow@ldiv               ; both high words are zero
+
+	or      dx,dx
+	jz      quick@ldiv
+
+	or      bx,bx
+	jz      quick@ldiv              ; if cx:bx == 0 force a zero divide
+					; we don't expect this to actually
+					; work
+
+slow@ldiv:
+
+	test    di,1                    ; signed divide?
+	jnz     positive                ; no: skip
+;
+;               Signed division should be done.  Convert negative
+;               values to positive and do an unsigned division.
+;               Store the sign value in the next higher bit of
+;               di (test mask of 4).  Thus when we are done, testing
+;               that bit will determine the sign of the result.
+;
+	or      dx,dx                   ; test sign of dividend
+	jns     onepos
+	neg     dx
+	neg     ax
+	sbb     dx,0                    ; negate dividend
+	or      di,0Ch
+onepos:
+	or      cx,cx                   ; test sign of divisor
+	jns     positive
+	neg     cx
+	neg     bx
+	sbb     cx,0                    ; negate divisor
+	xor     di,4
+positive:
+	mov     bp,cx
+	mov     cx,32                   ; shift counter
+	push    di                      ; save the flags
+;
+;       Now the stack looks something like this:
+;
+;               16[bp]: divisor (high word)
+;               14[bp]: divisor (low word)
+;               12[bp]: dividend (high word)
+;               10[bp]: dividend (low word)
+;                8[bp]: return CS
+;                6[bp]: return IP
+;                4[bp]: previous BP
+;                2[bp]: previous SI
+;                 [bp]: previous DI
+;               -2[bp]: control bits
+;                       01 - Unsigned divide
+;                       02 - Remainder wanted
+;                       04 - Negative quotient
+;                       08 - Negative remainder
+;
+	xor     di,di                   ; fake a 64 bit dividend
+	xor     si,si                   ;
+xloop:
+	shl     ax,1                    ; shift dividend left one bit
+	rcl     dx,1
+	rcl     si,1
+	rcl     di,1
+	cmp     di,bp                   ; dividend larger?
+	jb      nosub
+	ja      subtract
+	cmp     si,bx                   ; maybe
+	jb      nosub
+subtract:
+	sub     si,bx
+	sbb     di,bp                   ; subtract the divisor
+	inc     ax                      ; build quotient
+nosub:
+	loop    xloop
+;
+;       When done with the loop the four register value look like:
+;
+;       |     di     |     si     |     dx     |     ax     |
+;       |        remainder        |         quotient        |
+;
+	pop     bx                      ; get control bits
+	test    bx,2                    ; remainder?
+	jz      usequo
+	mov     ax,si
+	mov     dx,di                   ; use remainder
+	shr     bx,1                    ; shift in the remainder sign bit
+usequo:
+	test    bx,4                    ; needs negative
+	jz      finish
+	neg     dx
+	neg     ax
+	sbb     dx,0                    ; negate
+finish:
+	pop     di
+	pop     si
+	pop     bp
+	retf    8
+
+quick@ldiv:
+	div     bx                      ; unsigned divide
+					; DX = remainder AX = quotient
+	test    di,2                    ; want remainder?
+	jz      quick@quo
+		xchg    ax,dx
+
+quick@quo:
+
+	xor     dx,dx
+		jmp     short finish
+
+_TEXT   ends
+	end
--- /dev/null
+++ b/WOLFSRC/ID_CA.C
@@ -1,0 +1,1768 @@
+// ID_CA.C
+
+// this has been customized for WOLF
+
+/*
+=============================================================================
+
+Id Software Caching Manager
+---------------------------
+
+Must be started BEFORE the memory manager, because it needs to get the headers
+loaded into the data segment
+
+=============================================================================
+*/
+
+#include "ID_HEADS.H"
+#pragma hdrstop
+
+#pragma warn -pro
+#pragma warn -use
+
+#define THREEBYTEGRSTARTS
+
+/*
+=============================================================================
+
+						 LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+typedef struct
+{
+  unsigned bit0,bit1;	// 0-255 is a character, > is a pointer to a node
+} huffnode;
+
+
+typedef struct
+{
+	unsigned	RLEWtag;
+	long		headeroffsets[100];
+	byte		tileinfo[];
+} mapfiletype;
+
+
+/*
+=============================================================================
+
+						 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+byte 		_seg	*tinf;
+int			mapon;
+
+unsigned	_seg	*mapsegs[MAPPLANES];
+maptype		_seg	*mapheaderseg[NUMMAPS];
+byte		_seg	*audiosegs[NUMSNDCHUNKS];
+void		_seg	*grsegs[NUMCHUNKS];
+
+byte		far	grneeded[NUMCHUNKS];
+byte		ca_levelbit,ca_levelnum;
+
+int			profilehandle,debughandle;
+
+char		audioname[13]="AUDIO.";
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+extern	long	far	CGAhead;
+extern	long	far	EGAhead;
+extern	byte	CGAdict;
+extern	byte	EGAdict;
+extern	byte	far	maphead;
+extern	byte	mapdict;
+extern	byte	far	audiohead;
+extern	byte	audiodict;
+
+
+char extension[5],	// Need a string, not constant to change cache files
+     gheadname[10]=GREXT"HEAD.",
+     gfilename[10]=GREXT"GRAPH.",
+     gdictname[10]=GREXT"DICT.",
+     mheadname[10]="MAPHEAD.",
+     mfilename[10]="MAPTEMP.",
+     aheadname[10]="AUDIOHED.",
+     afilename[10]="AUDIOT.";
+
+void CA_CannotOpen(char *string);
+
+long		_seg *grstarts;	// array of offsets in egagraph, -1 for sparse
+long		_seg *audiostarts;	// array of offsets in audio / audiot
+
+#ifdef GRHEADERLINKED
+huffnode	*grhuffman;
+#else
+huffnode	grhuffman[255];
+#endif
+
+#ifdef AUDIOHEADERLINKED
+huffnode	*audiohuffman;
+#else
+huffnode	audiohuffman[255];
+#endif
+
+
+int			grhandle;		// handle to EGAGRAPH
+int			maphandle;		// handle to MAPTEMP / GAMEMAPS
+int			audiohandle;	// handle to AUDIOT / AUDIO
+
+long		chunkcomplen,chunkexplen;
+
+SDMode		oldsoundmode;
+
+
+
+void	CAL_CarmackExpand (unsigned far *source, unsigned far *dest,
+		unsigned length);
+
+
+#ifdef THREEBYTEGRSTARTS
+#define FILEPOSSIZE	3
+//#define	GRFILEPOS(c) (*(long far *)(((byte far *)grstarts)+(c)*3)&0xffffff)
+long GRFILEPOS(int c)
+{
+	long value;
+	int	offset;
+
+	offset = c*3;
+
+	value = *(long far *)(((byte far *)grstarts)+offset);
+
+	value &= 0x00ffffffl;
+
+	if (value == 0xffffffl)
+		value = -1;
+
+	return value;
+};
+#else
+#define FILEPOSSIZE	4
+#define	GRFILEPOS(c) (grstarts[c])
+#endif
+
+/*
+=============================================================================
+
+					   LOW LEVEL ROUTINES
+
+=============================================================================
+*/
+
+/*
+============================
+=
+= CA_OpenDebug / CA_CloseDebug
+=
+= Opens a binary file with the handle "debughandle"
+=
+============================
+*/
+
+void CA_OpenDebug (void)
+{
+	unlink ("DEBUG.TXT");
+	debughandle = open("DEBUG.TXT", O_CREAT | O_WRONLY | O_TEXT);
+}
+
+void CA_CloseDebug (void)
+{
+	close (debughandle);
+}
+
+
+
+/*
+============================
+=
+= CAL_GetGrChunkLength
+=
+= Gets the length of an explicit length chunk (not tiles)
+= The file pointer is positioned so the compressed data can be read in next.
+=
+============================
+*/
+
+void CAL_GetGrChunkLength (int chunk)
+{
+	lseek(grhandle,GRFILEPOS(chunk),SEEK_SET);
+	read(grhandle,&chunkexplen,sizeof(chunkexplen));
+	chunkcomplen = GRFILEPOS(chunk+1)-GRFILEPOS(chunk)-4;
+}
+
+
+/*
+==========================
+=
+= CA_FarRead
+=
+= Read from a file to a far pointer
+=
+==========================
+*/
+
+boolean CA_FarRead (int handle, byte far *dest, long length)
+{
+	if (length>0xffffl)
+		Quit ("CA_FarRead doesn't support 64K reads yet!");
+
+asm		push	ds
+asm		mov	bx,[handle]
+asm		mov	cx,[WORD PTR length]
+asm		mov	dx,[WORD PTR dest]
+asm		mov	ds,[WORD PTR dest+2]
+asm		mov	ah,0x3f				// READ w/handle
+asm		int	21h
+asm		pop	ds
+asm		jnc	good
+	errno = _AX;
+	return	false;
+good:
+asm		cmp	ax,[WORD PTR length]
+asm		je	done
+	errno = EINVFMT;			// user manager knows this is bad read
+	return	false;
+done:
+	return	true;
+}
+
+
+/*
+==========================
+=
+= CA_SegWrite
+=
+= Write from a file to a far pointer
+=
+==========================
+*/
+
+boolean CA_FarWrite (int handle, byte far *source, long length)
+{
+	if (length>0xffffl)
+		Quit ("CA_FarWrite doesn't support 64K reads yet!");
+
+asm		push	ds
+asm		mov	bx,[handle]
+asm		mov	cx,[WORD PTR length]
+asm		mov	dx,[WORD PTR source]
+asm		mov	ds,[WORD PTR source+2]
+asm		mov	ah,0x40			// WRITE w/handle
+asm		int	21h
+asm		pop	ds
+asm		jnc	good
+	errno = _AX;
+	return	false;
+good:
+asm		cmp	ax,[WORD PTR length]
+asm		je	done
+	errno = ENOMEM;				// user manager knows this is bad write
+	return	false;
+
+done:
+	return	true;
+}
+
+
+/*
+==========================
+=
+= CA_ReadFile
+=
+= Reads a file into an allready allocated buffer
+=
+==========================
+*/
+
+boolean CA_ReadFile (char *filename, memptr *ptr)
+{
+	int handle;
+	long size;
+
+	if ((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)
+		return false;
+
+	size = filelength (handle);
+	if (!CA_FarRead (handle,*ptr,size))
+	{
+		close (handle);
+		return false;
+	}
+	close (handle);
+	return true;
+}
+
+
+/*
+==========================
+=
+= CA_WriteFile
+=
+= Writes a file from a memory buffer
+=
+==========================
+*/
+
+boolean CA_WriteFile (char *filename, void far *ptr, long length)
+{
+	int handle;
+	long size;
+
+	handle = open(filename,O_CREAT | O_BINARY | O_WRONLY,
+				S_IREAD | S_IWRITE | S_IFREG);
+
+	if (handle == -1)
+		return false;
+
+	if (!CA_FarWrite (handle,ptr,length))
+	{
+		close (handle);
+		return false;
+	}
+	close (handle);
+	return true;
+}
+
+
+
+/*
+==========================
+=
+= CA_LoadFile
+=
+= Allocate space for and load a file
+=
+==========================
+*/
+
+boolean CA_LoadFile (char *filename, memptr *ptr)
+{
+	int handle;
+	long size;
+
+	if ((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)
+		return false;
+
+	size = filelength (handle);
+	MM_GetPtr (ptr,size);
+	if (!CA_FarRead (handle,*ptr,size))
+	{
+		close (handle);
+		return false;
+	}
+	close (handle);
+	return true;
+}
+
+/*
+============================================================================
+
+		COMPRESSION routines, see JHUFF.C for more
+
+============================================================================
+*/
+
+
+
+/*
+===============
+=
+= CAL_OptimizeNodes
+=
+= Goes through a huffman table and changes the 256-511 node numbers to the
+= actular address of the node.  Must be called before CAL_HuffExpand
+=
+===============
+*/
+
+void CAL_OptimizeNodes (huffnode *table)
+{
+  huffnode *node;
+  int i;
+
+  node = table;
+
+  for (i=0;i<255;i++)
+  {
+	if (node->bit0 >= 256)
+	  node->bit0 = (unsigned)(table+(node->bit0-256));
+	if (node->bit1 >= 256)
+	  node->bit1 = (unsigned)(table+(node->bit1-256));
+	node++;
+  }
+}
+
+
+
+/*
+======================
+=
+= CAL_HuffExpand
+=
+= Length is the length of the EXPANDED data
+= If screenhack, the data is decompressed in four planes directly
+= to the screen
+=
+======================
+*/
+
+void CAL_HuffExpand (byte huge *source, byte huge *dest,
+  long length,huffnode *hufftable, boolean screenhack)
+{
+//  unsigned bit,byte,node,code;
+  unsigned sourceseg,sourceoff,destseg,destoff,endoff;
+  huffnode *headptr;
+  byte		mapmask;
+//  huffnode *nodeon;
+
+  headptr = hufftable+254;	// head node is allways node 254
+
+  source++;	// normalize
+  source--;
+  dest++;
+  dest--;
+
+  if (screenhack)
+  {
+	mapmask = 1;
+asm	mov	dx,SC_INDEX
+asm	mov	ax,SC_MAPMASK + 256
+asm	out	dx,ax
+	length >>= 2;
+  }
+
+  sourceseg = FP_SEG(source);
+  sourceoff = FP_OFF(source);
+  destseg = FP_SEG(dest);
+  destoff = FP_OFF(dest);
+  endoff = destoff+length;
+
+//
+// ds:si source
+// es:di dest
+// ss:bx node pointer
+//
+
+	if (length <0xfff0)
+	{
+
+//--------------------------
+// expand less than 64k of data
+//--------------------------
+
+asm mov	bx,[headptr]
+
+asm	mov	si,[sourceoff]
+asm	mov	di,[destoff]
+asm	mov	es,[destseg]
+asm	mov	ds,[sourceseg]
+asm	mov	ax,[endoff]
+
+asm	mov	ch,[si]				// load first byte
+asm	inc	si
+asm	mov	cl,1
+
+expandshort:
+asm	test	ch,cl			// bit set?
+asm	jnz	bit1short
+asm	mov	dx,[ss:bx]			// take bit0 path from node
+asm	shl	cl,1				// advance to next bit position
+asm	jc	newbyteshort
+asm	jnc	sourceupshort
+
+bit1short:
+asm	mov	dx,[ss:bx+2]		// take bit1 path
+asm	shl	cl,1				// advance to next bit position
+asm	jnc	sourceupshort
+
+newbyteshort:
+asm	mov	ch,[si]				// load next byte
+asm	inc	si
+asm	mov	cl,1				// back to first bit
+
+sourceupshort:
+asm	or	dh,dh				// if dx<256 its a byte, else move node
+asm	jz	storebyteshort
+asm	mov	bx,dx				// next node = (huffnode *)code
+asm	jmp	expandshort
+
+storebyteshort:
+asm	mov	[es:di],dl
+asm	inc	di					// write a decopmpressed byte out
+asm	mov	bx,[headptr]		// back to the head node for next bit
+
+asm	cmp	di,ax				// done?
+asm	jne	expandshort
+
+//
+// perform screenhack if needed
+//
+asm	test	[screenhack],1
+asm	jz	notscreen
+asm	shl	[mapmask],1
+asm	mov	ah,[mapmask]
+asm	cmp	ah,16
+asm	je	notscreen			// all four planes done
+asm	mov	dx,SC_INDEX
+asm	mov	al,SC_MAPMASK
+asm	out	dx,ax
+asm	mov	di,[destoff]
+asm	mov	ax,[endoff]
+asm	jmp	expandshort
+
+notscreen:;
+	}
+	else
+	{
+
+//--------------------------
+// expand more than 64k of data
+//--------------------------
+
+  length--;
+
+asm mov	bx,[headptr]
+asm	mov	cl,1
+
+asm	mov	si,[sourceoff]
+asm	mov	di,[destoff]
+asm	mov	es,[destseg]
+asm	mov	ds,[sourceseg]
+
+asm	lodsb			// load first byte
+
+expand:
+asm	test	al,cl		// bit set?
+asm	jnz	bit1
+asm	mov	dx,[ss:bx]	// take bit0 path from node
+asm	jmp	gotcode
+bit1:
+asm	mov	dx,[ss:bx+2]	// take bit1 path
+
+gotcode:
+asm	shl	cl,1		// advance to next bit position
+asm	jnc	sourceup
+asm	lodsb
+asm	cmp	si,0x10		// normalize ds:si
+asm  	jb	sinorm
+asm	mov	cx,ds
+asm	inc	cx
+asm	mov	ds,cx
+asm	xor	si,si
+sinorm:
+asm	mov	cl,1		// back to first bit
+
+sourceup:
+asm	or	dh,dh		// if dx<256 its a byte, else move node
+asm	jz	storebyte
+asm	mov	bx,dx		// next node = (huffnode *)code
+asm	jmp	expand
+
+storebyte:
+asm	mov	[es:di],dl
+asm	inc	di		// write a decopmpressed byte out
+asm	mov	bx,[headptr]	// back to the head node for next bit
+
+asm	cmp	di,0x10		// normalize es:di
+asm  	jb	dinorm
+asm	mov	dx,es
+asm	inc	dx
+asm	mov	es,dx
+asm	xor	di,di
+dinorm:
+
+asm	sub	[WORD PTR ss:length],1
+asm	jnc	expand
+asm  	dec	[WORD PTR ss:length+2]
+asm	jns	expand		// when length = ffff ffff, done
+
+	}
+
+asm	mov	ax,ss
+asm	mov	ds,ax
+
+}
+
+
+/*
+======================
+=
+= CAL_CarmackExpand
+=
+= Length is the length of the EXPANDED data
+=
+======================
+*/
+
+#define NEARTAG	0xa7
+#define FARTAG	0xa8
+
+void CAL_CarmackExpand (unsigned far *source, unsigned far *dest, unsigned length)
+{
+	unsigned	ch,chhigh,count,offset;
+	unsigned	far *copyptr, far *inptr, far *outptr;
+
+	length/=2;
+
+	inptr = source;
+	outptr = dest;
+
+	while (length)
+	{
+		ch = *inptr++;
+		chhigh = ch>>8;
+		if (chhigh == NEARTAG)
+		{
+			count = ch&0xff;
+			if (!count)
+			{				// have to insert a word containing the tag byte
+				ch |= *((unsigned char far *)inptr)++;
+				*outptr++ = ch;
+				length--;
+			}
+			else
+			{
+				offset = *((unsigned char far *)inptr)++;
+				copyptr = outptr - offset;
+				length -= count;
+				while (count--)
+					*outptr++ = *copyptr++;
+			}
+		}
+		else if (chhigh == FARTAG)
+		{
+			count = ch&0xff;
+			if (!count)
+			{				// have to insert a word containing the tag byte
+				ch |= *((unsigned char far *)inptr)++;
+				*outptr++ = ch;
+				length --;
+			}
+			else
+			{
+				offset = *inptr++;
+				copyptr = dest + offset;
+				length -= count;
+				while (count--)
+					*outptr++ = *copyptr++;
+			}
+		}
+		else
+		{
+			*outptr++ = ch;
+			length --;
+		}
+	}
+}
+
+
+
+/*
+======================
+=
+= CA_RLEWcompress
+=
+======================
+*/
+
+long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,
+  unsigned rlewtag)
+{
+  long complength;
+  unsigned value,count,i;
+  unsigned huge *start,huge *end;
+
+  start = dest;
+
+  end = source + (length+1)/2;
+
+//
+// compress it
+//
+  do
+  {
+	count = 1;
+	value = *source++;
+	while (*source == value && source<end)
+	{
+	  count++;
+	  source++;
+	}
+	if (count>3 || value == rlewtag)
+	{
+    //
+    // send a tag / count / value string
+    //
+      *dest++ = rlewtag;
+      *dest++ = count;
+      *dest++ = value;
+    }
+    else
+    {
+    //
+    // send word without compressing
+    //
+      for (i=1;i<=count;i++)
+	*dest++ = value;
+	}
+
+  } while (source<end);
+
+  complength = 2*(dest-start);
+  return complength;
+}
+
+
+/*
+======================
+=
+= CA_RLEWexpand
+= length is EXPANDED length
+=
+======================
+*/
+
+void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,
+  unsigned rlewtag)
+{
+//  unsigned value,count,i;
+  unsigned huge *end;
+  unsigned sourceseg,sourceoff,destseg,destoff,endseg,endoff;
+
+
+//
+// expand it
+//
+#if 0
+  do
+  {
+	value = *source++;
+	if (value != rlewtag)
+	//
+	// uncompressed
+	//
+	  *dest++=value;
+	else
+	{
+	//
+	// compressed string
+	//
+	  count = *source++;
+	  value = *source++;
+	  for (i=1;i<=count;i++)
+	*dest++ = value;
+	}
+  } while (dest<end);
+#endif
+
+  end = dest + (length)/2;
+  sourceseg = FP_SEG(source);
+  sourceoff = FP_OFF(source);
+  destseg = FP_SEG(dest);
+  destoff = FP_OFF(dest);
+  endseg = FP_SEG(end);
+  endoff = FP_OFF(end);
+
+
+//
+// ax = source value
+// bx = tag value
+// cx = repeat counts
+// dx = scratch
+//
+// NOTE: A repeat count that produces 0xfff0 bytes can blow this!
+//
+
+asm	mov	bx,rlewtag
+asm	mov	si,sourceoff
+asm	mov	di,destoff
+asm	mov	es,destseg
+asm	mov	ds,sourceseg
+
+expand:
+asm	lodsw
+asm	cmp	ax,bx
+asm	je	repeat
+asm	stosw
+asm	jmp	next
+
+repeat:
+asm	lodsw
+asm	mov	cx,ax		// repeat count
+asm	lodsw			// repeat value
+asm	rep stosw
+
+next:
+
+asm	cmp	si,0x10		// normalize ds:si
+asm  	jb	sinorm
+asm	mov	ax,si
+asm	shr	ax,1
+asm	shr	ax,1
+asm	shr	ax,1
+asm	shr	ax,1
+asm	mov	dx,ds
+asm	add	dx,ax
+asm	mov	ds,dx
+asm	and	si,0xf
+sinorm:
+asm	cmp	di,0x10		// normalize es:di
+asm  	jb	dinorm
+asm	mov	ax,di
+asm	shr	ax,1
+asm	shr	ax,1
+asm	shr	ax,1
+asm	shr	ax,1
+asm	mov	dx,es
+asm	add	dx,ax
+asm	mov	es,dx
+asm	and	di,0xf
+dinorm:
+
+asm	cmp     di,ss:endoff
+asm	jne	expand
+asm	mov	ax,es
+asm	cmp	ax,ss:endseg
+asm	jb	expand
+
+asm	mov	ax,ss
+asm	mov	ds,ax
+
+}
+
+
+
+/*
+=============================================================================
+
+					 CACHE MANAGER ROUTINES
+
+=============================================================================
+*/
+
+
+/*
+======================
+=
+= CAL_SetupGrFile
+=
+======================
+*/
+
+void CAL_SetupGrFile (void)
+{
+	char fname[13];
+	int handle;
+	memptr compseg;
+
+#ifdef GRHEADERLINKED
+
+	grhuffman = (huffnode *)&EGAdict;
+	grstarts = (long _seg *)FP_SEG(&EGAhead);
+
+	CAL_OptimizeNodes (grhuffman);
+
+#else
+
+//
+// load ???dict.ext (huffman dictionary for graphics files)
+//
+
+	strcpy(fname,gdictname);
+	strcat(fname,extension);
+
+	if ((handle = open(fname,
+		 O_RDONLY | O_BINARY, S_IREAD)) == -1)
+		CA_CannotOpen(fname);
+
+	read(handle, &grhuffman, sizeof(grhuffman));
+	close(handle);
+	CAL_OptimizeNodes (grhuffman);
+//
+// load the data offsets from ???head.ext
+//
+	MM_GetPtr (&(memptr)grstarts,(NUMCHUNKS+1)*FILEPOSSIZE);
+
+	strcpy(fname,gheadname);
+	strcat(fname,extension);
+
+	if ((handle = open(fname,
+		 O_RDONLY | O_BINARY, S_IREAD)) == -1)
+		CA_CannotOpen(fname);
+
+	CA_FarRead(handle, (memptr)grstarts, (NUMCHUNKS+1)*FILEPOSSIZE);
+
+	close(handle);
+
+
+#endif
+
+//
+// Open the graphics file, leaving it open until the game is finished
+//
+	strcpy(fname,gfilename);
+	strcat(fname,extension);
+
+	grhandle = open(fname, O_RDONLY | O_BINARY);
+	if (grhandle == -1)
+		CA_CannotOpen(fname);
+
+
+//
+// load the pic and sprite headers into the arrays in the data segment
+//
+	MM_GetPtr(&(memptr)pictable,NUMPICS*sizeof(pictabletype));
+	CAL_GetGrChunkLength(STRUCTPIC);		// position file pointer
+	MM_GetPtr(&compseg,chunkcomplen);
+	CA_FarRead (grhandle,compseg,chunkcomplen);
+	CAL_HuffExpand (compseg, (byte huge *)pictable,NUMPICS*sizeof(pictabletype),grhuffman,false);
+	MM_FreePtr(&compseg);
+}
+
+//==========================================================================
+
+
+/*
+======================
+=
+= CAL_SetupMapFile
+=
+======================
+*/
+
+void CAL_SetupMapFile (void)
+{
+	int	i;
+	int handle;
+	long length,pos;
+	char fname[13];
+
+//
+// load maphead.ext (offsets and tileinfo for map file)
+//
+#ifndef MAPHEADERLINKED
+	strcpy(fname,mheadname);
+	strcat(fname,extension);
+
+	if ((handle = open(fname,
+		 O_RDONLY | O_BINARY, S_IREAD)) == -1)
+		CA_CannotOpen(fname);
+
+	length = filelength(handle);
+	MM_GetPtr (&(memptr)tinf,length);
+	CA_FarRead(handle, tinf, length);
+	close(handle);
+#else
+
+	tinf = (byte _seg *)FP_SEG(&maphead);
+
+#endif
+
+//
+// open the data file
+//
+#ifdef CARMACIZED
+	strcpy(fname,"GAMEMAPS.");
+	strcat(fname,extension);
+
+	if ((maphandle = open(fname,
+		 O_RDONLY | O_BINARY, S_IREAD)) == -1)
+		CA_CannotOpen(fname);
+#else
+	strcpy(fname,mfilename);
+	strcat(fname,extension);
+
+	if ((maphandle = open(fname,
+		 O_RDONLY | O_BINARY, S_IREAD)) == -1)
+		CA_CannotOpen(fname);
+#endif
+
+//
+// load all map header
+//
+	for (i=0;i<NUMMAPS;i++)
+	{
+		pos = ((mapfiletype	_seg *)tinf)->headeroffsets[i];
+		if (pos<0)						// $FFFFFFFF start is a sparse map
+			continue;
+
+		MM_GetPtr(&(memptr)mapheaderseg[i],sizeof(maptype));
+		MM_SetLock(&(memptr)mapheaderseg[i],true);
+		lseek(maphandle,pos,SEEK_SET);
+		CA_FarRead (maphandle,(memptr)mapheaderseg[i],sizeof(maptype));
+	}
+
+//
+// allocate space for 3 64*64 planes
+//
+	for (i=0;i<MAPPLANES;i++)
+	{
+		MM_GetPtr (&(memptr)mapsegs[i],64*64*2);
+		MM_SetLock (&(memptr)mapsegs[i],true);
+	}
+}
+
+
+//==========================================================================
+
+
+/*
+======================
+=
+= CAL_SetupAudioFile
+=
+======================
+*/
+
+void CAL_SetupAudioFile (void)
+{
+	int handle;
+	long length;
+	char fname[13];
+
+//
+// load maphead.ext (offsets and tileinfo for map file)
+//
+#ifndef AUDIOHEADERLINKED
+	strcpy(fname,aheadname);
+	strcat(fname,extension);
+
+	if ((handle = open(fname,
+		 O_RDONLY | O_BINARY, S_IREAD)) == -1)
+		CA_CannotOpen(fname);
+
+	length = filelength(handle);
+	MM_GetPtr (&(memptr)audiostarts,length);
+	CA_FarRead(handle, (byte far *)audiostarts, length);
+	close(handle);
+#else
+	audiohuffman = (huffnode *)&audiodict;
+	CAL_OptimizeNodes (audiohuffman);
+	audiostarts = (long _seg *)FP_SEG(&audiohead);
+#endif
+
+//
+// open the data file
+//
+#ifndef AUDIOHEADERLINKED
+	strcpy(fname,afilename);
+	strcat(fname,extension);
+
+	if ((audiohandle = open(fname,
+		 O_RDONLY | O_BINARY, S_IREAD)) == -1)
+		CA_CannotOpen(fname);
+#else
+	if ((audiohandle = open("AUDIO."EXTENSION,
+		 O_RDONLY | O_BINARY, S_IREAD)) == -1)
+		Quit ("Can't open AUDIO."EXTENSION"!");
+#endif
+}
+
+//==========================================================================
+
+
+/*
+======================
+=
+= CA_Startup
+=
+= Open all files and load in headers
+=
+======================
+*/
+
+void CA_Startup (void)
+{
+#ifdef PROFILE
+	unlink ("PROFILE.TXT");
+	profilehandle = open("PROFILE.TXT", O_CREAT | O_WRONLY | O_TEXT);
+#endif
+
+	CAL_SetupMapFile ();
+	CAL_SetupGrFile ();
+	CAL_SetupAudioFile ();
+
+	mapon = -1;
+	ca_levelbit = 1;
+	ca_levelnum = 0;
+
+}
+
+//==========================================================================
+
+
+/*
+======================
+=
+= CA_Shutdown
+=
+= Closes all files
+=
+======================
+*/
+
+void CA_Shutdown (void)
+{
+#ifdef PROFILE
+	close (profilehandle);
+#endif
+
+	close (maphandle);
+	close (grhandle);
+	close (audiohandle);
+}
+
+//===========================================================================
+
+/*
+======================
+=
+= CA_CacheAudioChunk
+=
+======================
+*/
+
+void CA_CacheAudioChunk (int chunk)
+{
+	long	pos,compressed;
+#ifdef AUDIOHEADERLINKED
+	long	expanded;
+	memptr	bigbufferseg;
+	byte	far *source;
+#endif
+
+	if (audiosegs[chunk])
+	{
+		MM_SetPurge (&(memptr)audiosegs[chunk],0);
+		return;							// allready in memory
+	}
+
+//
+// load the chunk into a buffer, either the miscbuffer if it fits, or allocate
+// a larger buffer
+//
+	pos = audiostarts[chunk];
+	compressed = audiostarts[chunk+1]-pos;
+
+	lseek(audiohandle,pos,SEEK_SET);
+
+#ifndef AUDIOHEADERLINKED
+
+	MM_GetPtr (&(memptr)audiosegs[chunk],compressed);
+	if (mmerror)
+		return;
+
+	CA_FarRead(audiohandle,audiosegs[chunk],compressed);
+
+#else
+
+	if (compressed<=BUFFERSIZE)
+	{
+		CA_FarRead(audiohandle,bufferseg,compressed);
+		source = bufferseg;
+	}
+	else
+	{
+		MM_GetPtr(&bigbufferseg,compressed);
+		if (mmerror)
+			return;
+		MM_SetLock (&bigbufferseg,true);
+		CA_FarRead(audiohandle,bigbufferseg,compressed);
+		source = bigbufferseg;
+	}
+
+	expanded = *(long far *)source;
+	source += 4;			// skip over length
+	MM_GetPtr (&(memptr)audiosegs[chunk],expanded);
+	if (mmerror)
+		goto done;
+	CAL_HuffExpand (source,audiosegs[chunk],expanded,audiohuffman,false);
+
+done:
+	if (compressed>BUFFERSIZE)
+		MM_FreePtr(&bigbufferseg);
+#endif
+}
+
+//===========================================================================
+
+/*
+======================
+=
+= CA_LoadAllSounds
+=
+= Purges all sounds, then loads all new ones (mode switch)
+=
+======================
+*/
+
+void CA_LoadAllSounds (void)
+{
+	unsigned	start,i;
+
+	switch (oldsoundmode)
+	{
+	case sdm_Off:
+		goto cachein;
+	case sdm_PC:
+		start = STARTPCSOUNDS;
+		break;
+	case sdm_AdLib:
+		start = STARTADLIBSOUNDS;
+		break;
+	}
+
+	for (i=0;i<NUMSOUNDS;i++,start++)
+		if (audiosegs[start])
+			MM_SetPurge (&(memptr)audiosegs[start],3);		// make purgable
+
+cachein:
+
+	switch (SoundMode)
+	{
+	case sdm_Off:
+		return;
+	case sdm_PC:
+		start = STARTPCSOUNDS;
+		break;
+	case sdm_AdLib:
+		start = STARTADLIBSOUNDS;
+		break;
+	}
+
+	for (i=0;i<NUMSOUNDS;i++,start++)
+		CA_CacheAudioChunk (start);
+
+	oldsoundmode = SoundMode;
+}
+
+//===========================================================================
+
+
+/*
+======================
+=
+= CAL_ExpandGrChunk
+=
+= Does whatever is needed with a pointer to a compressed chunk
+=
+======================
+*/
+
+void CAL_ExpandGrChunk (int chunk, byte far *source)
+{
+	long	expanded;
+
+
+	if (chunk >= STARTTILE8 && chunk < STARTEXTERNS)
+	{
+	//
+	// expanded sizes of tile8/16/32 are implicit
+	//
+
+#define BLOCK		64
+#define MASKBLOCK	128
+
+		if (chunk<STARTTILE8M)			// tile 8s are all in one chunk!
+			expanded = BLOCK*NUMTILE8;
+		else if (chunk<STARTTILE16)
+			expanded = MASKBLOCK*NUMTILE8M;
+		else if (chunk<STARTTILE16M)	// all other tiles are one/chunk
+			expanded = BLOCK*4;
+		else if (chunk<STARTTILE32)
+			expanded = MASKBLOCK*4;
+		else if (chunk<STARTTILE32M)
+			expanded = BLOCK*16;
+		else
+			expanded = MASKBLOCK*16;
+	}
+	else
+	{
+	//
+	// everything else has an explicit size longword
+	//
+		expanded = *(long far *)source;
+		source += 4;			// skip over length
+	}
+
+//
+// allocate final space, decompress it, and free bigbuffer
+// Sprites need to have shifts made and various other junk
+//
+	MM_GetPtr (&grsegs[chunk],expanded);
+	if (mmerror)
+		return;
+	CAL_HuffExpand (source,grsegs[chunk],expanded,grhuffman,false);
+}
+
+
+/*
+======================
+=
+= CA_CacheGrChunk
+=
+= Makes sure a given chunk is in memory, loadiing it if needed
+=
+======================
+*/
+
+void CA_CacheGrChunk (int chunk)
+{
+	long	pos,compressed;
+	memptr	bigbufferseg;
+	byte	far *source;
+	int		next;
+
+	grneeded[chunk] |= ca_levelbit;		// make sure it doesn't get removed
+	if (grsegs[chunk])
+	{
+		MM_SetPurge (&grsegs[chunk],0);
+		return;							// allready in memory
+	}
+
+//
+// load the chunk into a buffer, either the miscbuffer if it fits, or allocate
+// a larger buffer
+//
+	pos = GRFILEPOS(chunk);
+	if (pos<0)							// $FFFFFFFF start is a sparse tile
+	  return;
+
+	next = chunk +1;
+	while (GRFILEPOS(next) == -1)		// skip past any sparse tiles
+		next++;
+
+	compressed = GRFILEPOS(next)-pos;
+
+	lseek(grhandle,pos,SEEK_SET);
+
+	if (compressed<=BUFFERSIZE)
+	{
+		CA_FarRead(grhandle,bufferseg,compressed);
+		source = bufferseg;
+	}
+	else
+	{
+		MM_GetPtr(&bigbufferseg,compressed);
+		MM_SetLock (&bigbufferseg,true);
+		CA_FarRead(grhandle,bigbufferseg,compressed);
+		source = bigbufferseg;
+	}
+
+	CAL_ExpandGrChunk (chunk,source);
+
+	if (compressed>BUFFERSIZE)
+		MM_FreePtr(&bigbufferseg);
+}
+
+
+
+//==========================================================================
+
+/*
+======================
+=
+= CA_CacheScreen
+=
+= Decompresses a chunk from disk straight onto the screen
+=
+======================
+*/
+
+void CA_CacheScreen (int chunk)
+{
+	long	pos,compressed,expanded;
+	memptr	bigbufferseg;
+	byte	far *source;
+	int		next;
+
+//
+// load the chunk into a buffer
+//
+	pos = GRFILEPOS(chunk);
+	next = chunk +1;
+	while (GRFILEPOS(next) == -1)		// skip past any sparse tiles
+		next++;
+	compressed = GRFILEPOS(next)-pos;
+
+	lseek(grhandle,pos,SEEK_SET);
+
+	MM_GetPtr(&bigbufferseg,compressed);
+	MM_SetLock (&bigbufferseg,true);
+	CA_FarRead(grhandle,bigbufferseg,compressed);
+	source = bigbufferseg;
+
+	expanded = *(long far *)source;
+	source += 4;			// skip over length
+
+//
+// allocate final space, decompress it, and free bigbuffer
+// Sprites need to have shifts made and various other junk
+//
+	CAL_HuffExpand (source,MK_FP(SCREENSEG,bufferofs),expanded,grhuffman,true);
+	VW_MarkUpdateBlock (0,0,319,199);
+	MM_FreePtr(&bigbufferseg);
+}
+
+//==========================================================================
+
+/*
+======================
+=
+= CA_CacheMap
+=
+= WOLF: This is specialized for a 64*64 map size
+=
+======================
+*/
+
+void CA_CacheMap (int mapnum)
+{
+	long	pos,compressed;
+	int		plane;
+	memptr	*dest,bigbufferseg;
+	unsigned	size;
+	unsigned	far	*source;
+#ifdef CARMACIZED
+	memptr	buffer2seg;
+	long	expanded;
+#endif
+
+	mapon = mapnum;
+
+//
+// load the planes into the allready allocated buffers
+//
+	size = 64*64*2;
+
+	for (plane = 0; plane<MAPPLANES; plane++)
+	{
+		pos = mapheaderseg[mapnum]->planestart[plane];
+		compressed = mapheaderseg[mapnum]->planelength[plane];
+
+		dest = &(memptr)mapsegs[plane];
+
+		lseek(maphandle,pos,SEEK_SET);
+		if (compressed<=BUFFERSIZE)
+			source = bufferseg;
+		else
+		{
+			MM_GetPtr(&bigbufferseg,compressed);
+			MM_SetLock (&bigbufferseg,true);
+			source = bigbufferseg;
+		}
+
+		CA_FarRead(maphandle,(byte far *)source,compressed);
+#ifdef CARMACIZED
+		//
+		// unhuffman, then unRLEW
+		// The huffman'd chunk has a two byte expanded length first
+		// The resulting RLEW chunk also does, even though it's not really
+		// needed
+		//
+		expanded = *source;
+		source++;
+		MM_GetPtr (&buffer2seg,expanded);
+		CAL_CarmackExpand (source, (unsigned far *)buffer2seg,expanded);
+		CA_RLEWexpand (((unsigned far *)buffer2seg)+1,*dest,size,
+		((mapfiletype _seg *)tinf)->RLEWtag);
+		MM_FreePtr (&buffer2seg);
+
+#else
+		//
+		// unRLEW, skipping expanded length
+		//
+		CA_RLEWexpand (source+1, *dest,size,
+		((mapfiletype _seg *)tinf)->RLEWtag);
+#endif
+
+		if (compressed>BUFFERSIZE)
+			MM_FreePtr(&bigbufferseg);
+	}
+}
+
+//===========================================================================
+
+/*
+======================
+=
+= CA_UpLevel
+=
+= Goes up a bit level in the needed lists and clears it out.
+= Everything is made purgable
+=
+======================
+*/
+
+void CA_UpLevel (void)
+{
+	int	i;
+
+	if (ca_levelnum==7)
+		Quit ("CA_UpLevel: Up past level 7!");
+
+	for (i=0;i<NUMCHUNKS;i++)
+		if (grsegs[i])
+			MM_SetPurge (&(memptr)grsegs[i],3);
+	ca_levelbit<<=1;
+	ca_levelnum++;
+}
+
+//===========================================================================
+
+/*
+======================
+=
+= CA_DownLevel
+=
+= Goes down a bit level in the needed lists and recaches
+= everything from the lower level
+=
+======================
+*/
+
+void CA_DownLevel (void)
+{
+	if (!ca_levelnum)
+		Quit ("CA_DownLevel: Down past level 0!");
+	ca_levelbit>>=1;
+	ca_levelnum--;
+	CA_CacheMarks();
+}
+
+//===========================================================================
+
+/*
+======================
+=
+= CA_ClearMarks
+=
+= Clears out all the marks at the current level
+=
+======================
+*/
+
+void CA_ClearMarks (void)
+{
+	int i;
+
+	for (i=0;i<NUMCHUNKS;i++)
+		grneeded[i]&=~ca_levelbit;
+}
+
+
+//===========================================================================
+
+/*
+======================
+=
+= CA_ClearAllMarks
+=
+= Clears out all the marks on all the levels
+=
+======================
+*/
+
+void CA_ClearAllMarks (void)
+{
+	_fmemset (grneeded,0,sizeof(grneeded));
+	ca_levelbit = 1;
+	ca_levelnum = 0;
+}
+
+
+//===========================================================================
+
+
+/*
+======================
+=
+= CA_FreeGraphics
+=
+======================
+*/
+
+
+void CA_SetGrPurge (void)
+{
+	int i;
+
+//
+// free graphics
+//
+	CA_ClearMarks ();
+
+	for (i=0;i<NUMCHUNKS;i++)
+		if (grsegs[i])
+			MM_SetPurge (&(memptr)grsegs[i],3);
+}
+
+
+
+/*
+======================
+=
+= CA_SetAllPurge
+=
+= Make everything possible purgable
+=
+======================
+*/
+
+void CA_SetAllPurge (void)
+{
+	int i;
+
+
+//
+// free sounds
+//
+	for (i=0;i<NUMSNDCHUNKS;i++)
+		if (audiosegs[i])
+			MM_SetPurge (&(memptr)audiosegs[i],3);
+
+//
+// free graphics
+//
+	CA_SetGrPurge ();
+}
+
+
+//===========================================================================
+
+/*
+======================
+=
+= CA_CacheMarks
+=
+======================
+*/
+#define MAXEMPTYREAD	1024
+
+void CA_CacheMarks (void)
+{
+	int 	i,next,numcache;
+	long	pos,endpos,nextpos,nextendpos,compressed;
+	long	bufferstart,bufferend;	// file position of general buffer
+	byte	far *source;
+	memptr	bigbufferseg;
+
+	numcache = 0;
+//
+// go through and make everything not needed purgable
+//
+	for (i=0;i<NUMCHUNKS;i++)
+		if (grneeded[i]&ca_levelbit)
+		{
+			if (grsegs[i])					// its allready in memory, make
+				MM_SetPurge(&grsegs[i],0);	// sure it stays there!
+			else
+				numcache++;
+		}
+		else
+		{
+			if (grsegs[i])					// not needed, so make it purgeable
+				MM_SetPurge(&grsegs[i],3);
+		}
+
+	if (!numcache)			// nothing to cache!
+		return;
+
+
+//
+// go through and load in anything still needed
+//
+	bufferstart = bufferend = 0;		// nothing good in buffer now
+
+	for (i=0;i<NUMCHUNKS;i++)
+		if ( (grneeded[i]&ca_levelbit) && !grsegs[i])
+		{
+			pos = GRFILEPOS(i);
+			if (pos<0)
+				continue;
+
+			next = i +1;
+			while (GRFILEPOS(next) == -1)		// skip past any sparse tiles
+				next++;
+
+			compressed = GRFILEPOS(next)-pos;
+			endpos = pos+compressed;
+
+			if (compressed<=BUFFERSIZE)
+			{
+				if (bufferstart<=pos
+				&& bufferend>= endpos)
+				{
+				// data is allready in buffer
+					source = (byte _seg *)bufferseg+(pos-bufferstart);
+				}
+				else
+				{
+				// load buffer with a new block from disk
+				// try to get as many of the needed blocks in as possible
+					while ( next < NUMCHUNKS )
+					{
+						while (next < NUMCHUNKS &&
+						!(grneeded[next]&ca_levelbit && !grsegs[next]))
+							next++;
+						if (next == NUMCHUNKS)
+							continue;
+
+						nextpos = GRFILEPOS(next);
+						while (GRFILEPOS(++next) == -1)	// skip past any sparse tiles
+							;
+						nextendpos = GRFILEPOS(next);
+						if (nextpos - endpos <= MAXEMPTYREAD
+						&& nextendpos-pos <= BUFFERSIZE)
+							endpos = nextendpos;
+						else
+							next = NUMCHUNKS;			// read pos to posend
+					}
+
+					lseek(grhandle,pos,SEEK_SET);
+					CA_FarRead(grhandle,bufferseg,endpos-pos);
+					bufferstart = pos;
+					bufferend = endpos;
+					source = bufferseg;
+				}
+			}
+			else
+			{
+			// big chunk, allocate temporary buffer
+				MM_GetPtr(&bigbufferseg,compressed);
+				if (mmerror)
+					return;
+				MM_SetLock (&bigbufferseg,true);
+				lseek(grhandle,pos,SEEK_SET);
+				CA_FarRead(grhandle,bigbufferseg,compressed);
+				source = bigbufferseg;
+			}
+
+			CAL_ExpandGrChunk (i,source);
+			if (mmerror)
+				return;
+
+			if (compressed>BUFFERSIZE)
+				MM_FreePtr(&bigbufferseg);
+
+		}
+}
+
+void CA_CannotOpen(char *string)
+{
+ char str[30];
+
+ strcpy(str,"Can't open ");
+ strcat(str,string);
+ strcat(str,"!\n");
+ Quit (str);
+}
\ No newline at end of file
--- /dev/null
+++ b/WOLFSRC/ID_CA.H
@@ -1,0 +1,101 @@
+// ID_CA.H
+//===========================================================================
+
+#define NUMMAPS		60
+#define MAPPLANES	2
+
+#define UNCACHEGRCHUNK(chunk)	{MM_FreePtr(&grsegs[chunk]);grneeded[chunk]&=~ca_levelbit;}
+
+//===========================================================================
+
+typedef	struct
+{
+	long		planestart[3];
+	unsigned	planelength[3];
+	unsigned	width,height;
+	char		name[16];
+} maptype;
+
+//===========================================================================
+
+extern	char		audioname[13];
+
+extern	byte 		_seg	*tinf;
+extern	int			mapon;
+
+extern	unsigned	_seg	*mapsegs[MAPPLANES];
+extern	maptype		_seg	*mapheaderseg[NUMMAPS];
+extern	byte		_seg	*audiosegs[NUMSNDCHUNKS];
+extern	void		_seg	*grsegs[NUMCHUNKS];
+
+extern	byte		far	grneeded[NUMCHUNKS];
+extern	byte		ca_levelbit,ca_levelnum;
+
+extern	char		*titleptr[8];
+
+extern	int			profilehandle,debughandle;
+
+extern	char		extension[5],
+			gheadname[10],
+			gfilename[10],
+			gdictname[10],
+			mheadname[10],
+			mfilename[10],
+			aheadname[10],
+			afilename[10];
+
+extern long		_seg *grstarts;	// array of offsets in egagraph, -1 for sparse
+extern long		_seg *audiostarts;	// array of offsets in audio / audiot
+//
+// hooks for custom cache dialogs
+//
+extern	void	(*drawcachebox)		(char *title, unsigned numcache);
+extern	void	(*updatecachebox)	(void);
+extern	void	(*finishcachebox)	(void);
+
+//===========================================================================
+
+// just for the score box reshifting
+
+void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,
+	unsigned width, unsigned height, unsigned pixshift);
+
+//===========================================================================
+
+void CA_OpenDebug (void);
+void CA_CloseDebug (void);
+boolean CA_FarRead (int handle, byte far *dest, long length);
+boolean CA_FarWrite (int handle, byte far *source, long length);
+boolean CA_ReadFile (char *filename, memptr *ptr);
+boolean CA_LoadFile (char *filename, memptr *ptr);
+boolean CA_WriteFile (char *filename, void far *ptr, long length);
+
+long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,
+  unsigned rlewtag);
+
+void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,
+  unsigned rlewtag);
+
+void CA_Startup (void);
+void CA_Shutdown (void);
+
+void CA_SetGrPurge (void);
+void CA_CacheAudioChunk (int chunk);
+void CA_LoadAllSounds (void);
+
+void CA_UpLevel (void);
+void CA_DownLevel (void);
+
+void CA_SetAllPurge (void);
+
+void CA_ClearMarks (void);
+void CA_ClearAllMarks (void);
+
+#define CA_MarkGrChunk(chunk)	grneeded[chunk]|=ca_levelbit
+
+void CA_CacheGrChunk (int chunk);
+void CA_CacheMap (int mapnum);
+
+void CA_CacheMarks (void);
+
+void CA_CacheScreen (int chunk);
--- /dev/null
+++ b/WOLFSRC/ID_HEAD.H
@@ -1,0 +1,34 @@
+// ID_HEAD.H
+
+
+#define	EXTENSION	"WLF"
+#define WOLF
+
+#define	TEXTGR	0
+#define	CGAGR	1
+#define	EGAGR	2
+#define	VGAGR	3
+
+#define GRMODE	VGAGR
+
+#include "VERSION.H"
+
+typedef	enum	{false,true}	boolean;
+typedef	unsigned	char		byte;
+typedef	unsigned	int			word;
+typedef	unsigned	long		longword;
+typedef	byte *					Ptr;
+
+typedef	struct
+		{
+			int	x,y;
+		} Point;
+
+typedef	struct
+		{
+			Point	ul,lr;
+		} Rect;
+
+
+void	Quit (char *error);		// defined in user program
+
--- /dev/null
+++ b/WOLFSRC/ID_HEADS.H
@@ -1,0 +1,123 @@
+// ID_GLOB.H
+
+
+#include <ALLOC.H>
+#include <CTYPE.H>
+#include <DOS.H>
+#include <ERRNO.H>
+#include <FCNTL.H>
+#include <IO.H>
+#include <MEM.H>
+#include <PROCESS.H>
+#include <STDIO.H>
+#include <STDLIB.H>
+#include <STRING.H>
+#include <SYS\STAT.H>
+#include <VALUES.H>
+#include <DIR.H>
+#define __ID_GLOB__
+#include "VERSION.H"
+
+//--------------------------------------------------------------------------
+
+extern	char		far signon;
+
+#define	introscn	signon
+
+#ifdef JAPAN
+#ifdef JAPDEMO
+#include "FOREIGN\JAPAN\GFXV_WJ1.H"
+#else
+#include "FOREIGN\JAPAN\GFXV_WJ6.H"
+#endif
+#include "AUDIOWL6.H"
+#include "MAPSWL6.H"
+#else
+
+#ifndef SPEAR
+
+#include "GFXV_WL6.H"
+#include "AUDIOWL6.H"
+#include "MAPSWL6.H"
+
+#else
+
+#ifndef SPEARDEMO
+#include "GFXV_SOD.H"
+#include "AUDIOSOD.H"
+#include "MAPSSOD.H"
+#else
+#include "GFXV_SDM.H"
+#include "AUDIOSDM.H"
+#include "MAPSSDM.H"
+#endif
+
+#endif
+#endif
+//-----------------
+
+
+#define GREXT	"VGA"
+
+//
+//	ID Engine
+//	Types.h - Generic types, #defines, etc.
+//	v1.0d1
+//
+
+typedef	enum	{false,true}	boolean;
+typedef	unsigned	char		byte;
+typedef	unsigned	int			word;
+typedef	unsigned	long		longword;
+typedef	byte *					Ptr;
+
+typedef	struct
+		{
+			int	x,y;
+		} Point;
+typedef	struct
+		{
+			Point	ul,lr;
+		} Rect;
+
+#define	nil	((void *)0)
+
+
+#include "ID_MM.H"
+#include "ID_PM.H"
+#include "ID_CA.H"
+#include "ID_VL.H"
+#include "ID_VH.H"
+#include "ID_IN.H"
+#include "ID_SD.H"
+#include "ID_US.H"
+
+
+void	Quit (char *error);		// defined in user program
+
+//
+// replacing refresh manager with custom routines
+//
+
+#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	MAXTICS				10
+#define DEMOTICS			4
+
+#define	UPDATETERMINATE	0x0301
+
+extern	unsigned	mapwidth,mapheight,tics;
+extern	boolean		compatability;
+
+extern	byte		*updateptr;
+extern	unsigned	uwidthtable[UPDATEHIGH];
+extern	unsigned	blockstarts[UPDATEWIDE*UPDATEHIGH];
+
+extern	byte		fontcolor,backcolor;
+
+#define SETFONTCOLOR(f,b) fontcolor=f;backcolor=b;
+
--- /dev/null
+++ b/WOLFSRC/ID_IN.C
@@ -1,0 +1,990 @@
+//
+//	ID Engine
+//	ID_IN.c - Input Manager
+//	v1.0d1
+//	By Jason Blochowiak
+//
+
+//
+//	This module handles dealing with the various input devices
+//
+//	Depends on: Memory Mgr (for demo recording), Sound Mgr (for timing stuff),
+//				User Mgr (for command line parms)
+//
+//	Globals:
+//		LastScan - The keyboard scan code of the last key pressed
+//		LastASCII - The ASCII value of the last key pressed
+//	DEBUG - there are more globals
+//
+
+#include "ID_HEADS.H"
+#pragma	hdrstop
+
+#define	KeyInt		9	// The keyboard ISR number
+
+//
+// mouse constants
+//
+#define	MReset		0
+#define	MButtons	3
+#define	MDelta		11
+
+#define	MouseInt	0x33
+#define	Mouse(x)	_AX = x,geninterrupt(MouseInt)
+
+//
+// joystick constants
+//
+#define	JoyScaleMax		32768
+#define	JoyScaleShift	8
+#define	MaxJoyValue		5000
+
+/*
+=============================================================================
+
+					GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+//
+// configuration variables
+//
+boolean			MousePresent;
+boolean			JoysPresent[MaxJoys];
+boolean			JoyPadPresent;
+
+
+// 	Global variables
+		boolean		Keyboard[NumCodes];
+		boolean		Paused;
+		char		LastASCII;
+		ScanCode	LastScan;
+
+		KeyboardDef	KbdDefs = {0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51};
+		JoystickDef	JoyDefs[MaxJoys];
+		ControlType	Controls[MaxPlayers];
+
+		longword	MouseDownCount;
+
+		Demo		DemoMode = demo_Off;
+		byte _seg	*DemoBuffer;
+		word		DemoOffset,DemoSize;
+
+/*
+=============================================================================
+
+					LOCAL VARIABLES
+
+=============================================================================
+*/
+static	byte        far 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
+					},
+					far 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
+					},
+					far SpecialNames[] =	// ASCII for 0xe0 prefixed codes
+					{
+//	 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+	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  ,13 ,0  ,0  ,0  ,	// 1
+	0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,	// 2
+	0  ,0  ,0  ,0  ,0  ,'/',0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,	// 3
+	0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,	// 4
+	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  ,	// 6
+	0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0   	// 7
+					};
+
+
+static	boolean		IN_Started;
+static	boolean		CapsLock;
+static	ScanCode	CurCode,LastCode;
+
+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
+					};
+
+static	void			(*INL_KeyHook)(void);
+static	void interrupt	(*OldKeyVect)(void);
+
+static	char			*ParmStrings[] = {"nojoys","nomouse",nil};
+
+//	Internal routines
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	INL_KeyService() - Handles a keyboard interrupt (key up/down)
+//
+///////////////////////////////////////////////////////////////////////////
+static void interrupt
+INL_KeyService(void)
+{
+static	boolean	special;
+		byte	k,c,
+				temp;
+		int		i;
+
+	k = inportb(0x60);	// Get the scan code
+
+	// Tell the XT keyboard controller to clear the key
+	outportb(0x61,(temp = inportb(0x61)) | 0x80);
+	outportb(0x61,temp);
+
+	if (k == 0xe0)		// Special key prefix
+		special = true;
+	else if (k == 0xe1)	// Handle Pause key
+		Paused = true;
+	else
+	{
+		if (k & 0x80)	// Break code
+		{
+			k &= 0x7f;
+
+// DEBUG - handle special keys: ctl-alt-delete, print scrn
+
+			Keyboard[k] = false;
+		}
+		else			// Make code
+		{
+			LastCode = CurCode;
+			CurCode = LastScan = k;
+			Keyboard[k] = true;
+
+			if (special)
+				c = SpecialNames[k];
+			else
+			{
+				if (k == sc_CapsLock)
+				{
+					CapsLock ^= true;
+					// DEBUG - make caps lock light work
+				}
+
+				if (Keyboard[sc_LShift] || Keyboard[sc_RShift])	// If shifted
+				{
+					c = ShiftNames[k];
+					if ((c >= 'A') && (c <= 'Z') && CapsLock)
+						c += 'a' - 'A';
+				}
+				else
+				{
+					c = ASCIINames[k];
+					if ((c >= 'a') && (c <= 'z') && CapsLock)
+						c -= 'a' - 'A';
+				}
+			}
+			if (c)
+				LastASCII = c;
+		}
+
+		special = false;
+	}
+
+	if (INL_KeyHook && !special)
+		INL_KeyHook();
+	outportb(0x20,0x20);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	INL_GetMouseDelta() - Gets the amount that the mouse has moved from the
+//		mouse driver
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+INL_GetMouseDelta(int *x,int *y)
+{
+	Mouse(MDelta);
+	*x = _CX;
+	*y = _DX;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	INL_GetMouseButtons() - Gets the status of the mouse buttons from the
+//		mouse driver
+//
+///////////////////////////////////////////////////////////////////////////
+static word
+INL_GetMouseButtons(void)
+{
+	word	buttons;
+
+	Mouse(MButtons);
+	buttons = _BX;
+	return(buttons);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	IN_GetJoyAbs() - Reads the absolute position of the specified joystick
+//
+///////////////////////////////////////////////////////////////////////////
+void
+IN_GetJoyAbs(word joy,word *xp,word *yp)
+{
+	byte	xb,yb,
+			xs,ys;
+	word	x,y;
+
+	x = y = 0;
+	xs = joy? 2 : 0;		// Find shift value for x axis
+	xb = 1 << xs;			// Use shift value to get x bit mask
+	ys = joy? 3 : 1;		// Do the same for y axis
+	yb = 1 << ys;
+
+// Read the absolute joystick values
+asm		pushf				// Save some registers
+asm		push	si
+asm		push	di
+asm		cli					// Make sure an interrupt doesn't screw the timings
+
+
+asm		mov		dx,0x201
+asm		in		al,dx
+asm		out		dx,al		// Clear the resistors
+
+asm		mov		ah,[xb]		// Get masks into registers
+asm		mov		ch,[yb]
+
+asm		xor		si,si		// Clear count registers
+asm		xor		di,di
+asm		xor		bh,bh		// Clear high byte of bx for later
+
+asm		push	bp			// Don't mess up stack frame
+asm		mov		bp,MaxJoyValue
+
+loop:
+asm		in		al,dx		// Get bits indicating whether all are finished
+
+asm		dec		bp			// Check bounding register
+asm		jz		done		// We have a silly value - abort
+
+asm		mov		bl,al		// Duplicate the bits
+asm		and		bl,ah		// Mask off useless bits (in [xb])
+asm		add		si,bx		// Possibly increment count register
+asm		mov		cl,bl		// Save for testing later
+
+asm		mov		bl,al
+asm		and		bl,ch		// [yb]
+asm		add		di,bx
+
+asm		add		cl,bl
+asm		jnz		loop 		// If both bits were 0, drop out
+
+done:
+asm     pop		bp
+
+asm		mov		cl,[xs]		// Get the number of bits to shift
+asm		shr		si,cl		//  and shift the count that many times
+
+asm		mov		cl,[ys]
+asm		shr		di,cl
+
+asm		mov		[x],si		// Store the values into the variables
+asm		mov		[y],di
+
+asm		pop		di
+asm		pop		si
+asm		popf				// Restore the registers
+
+	*xp = x;
+	*yp = y;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	INL_GetJoyDelta() - Returns the relative movement of the specified
+//		joystick (from +/-127)
+//
+///////////////////////////////////////////////////////////////////////////
+void INL_GetJoyDelta(word joy,int *dx,int *dy)
+{
+	word		x,y;
+	longword	time;
+	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 = TimeCount;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	INL_GetJoyButtons() - Returns the button status of the specified
+//		joystick
+//
+///////////////////////////////////////////////////////////////////////////
+static word
+INL_GetJoyButtons(word joy)
+{
+register	word	result;
+
+	result = inportb(0x201);	// Get all the joystick buttons
+	result >>= joy? 6 : 4;	// Shift into bits 0-1
+	result &= 3;				// Mask off the useless bits
+	result ^= 3;
+	return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	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 = TimeCount;
+		while (TimeCount == lasttime)
+			;
+		result2 = INL_GetJoyButtons(joy);
+	} while (result1 != result2);
+	return(result1);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	INL_StartKbd() - Sets up my keyboard stuff for use
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+INL_StartKbd(void)
+{
+	INL_KeyHook = NULL;			// no key hook routine
+
+	IN_ClearKeysDown();
+
+	OldKeyVect = getvect(KeyInt);
+	setvect(KeyInt,INL_KeyService);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	INL_ShutKbd() - Restores keyboard control to the BIOS
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+INL_ShutKbd(void)
+{
+	poke(0x40,0x17,peek(0x40,0x17) & 0xfaf0);	// Clear ctrl/alt/shift flags
+
+	setvect(KeyInt,OldKeyVect);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	INL_StartMouse() - Detects and sets up the mouse
+//
+///////////////////////////////////////////////////////////////////////////
+static boolean
+INL_StartMouse(void)
+{
+#if 0
+	if (getvect(MouseInt))
+	{
+		Mouse(MReset);
+		if (_AX == 0xffff)
+			return(true);
+	}
+	return(false);
+#endif
+ union REGS regs;
+ unsigned char far *vector;
+
+
+ if ((vector=MK_FP(peek(0,0x33*4+2),peek(0,0x33*4)))==NULL)
+   return false;
+
+ if (*vector == 207)
+   return false;
+
+ Mouse(MReset);
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	INL_ShutMouse() - Cleans up after the mouse
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+INL_ShutMouse(void)
+{
+}
+
+//
+//	INL_SetJoyScale() - Sets up scaling values for the specified joystick
+//
+static 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
+//
+///////////////////////////////////////////////////////////////////////////
+static boolean
+INL_StartJoy(word joy)
+{
+	word		x,y;
+
+	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
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+INL_ShutJoy(word joy)
+{
+	JoysPresent[joy] = false;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	IN_Startup() - Starts up the Input Mgr
+//
+///////////////////////////////////////////////////////////////////////////
+void
+IN_Startup(void)
+{
+	boolean	checkjoys,checkmouse;
+	word	i;
+
+	if (IN_Started)
+		return;
+
+	checkjoys = true;
+	checkmouse = true;
+	for (i = 1;i < _argc;i++)
+	{
+		switch (US_CheckParm(_argv[i],ParmStrings))
+		{
+		case 0:
+			checkjoys = false;
+			break;
+		case 1:
+			checkmouse = false;
+			break;
+		}
+	}
+
+	INL_StartKbd();
+	MousePresent = checkmouse? INL_StartMouse() : false;
+
+	for (i = 0;i < MaxJoys;i++)
+		JoysPresent[i] = checkjoys? INL_StartJoy(i) : false;
+
+	IN_Started = true;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	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);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	IN_Shutdown() - Shuts down the Input Mgr
+//
+///////////////////////////////////////////////////////////////////////////
+void
+IN_Shutdown(void)
+{
+	word	i;
+
+	if (!IN_Started)
+		return;
+
+	INL_ShutMouse();
+	for (i = 0;i < MaxJoys;i++)
+		INL_ShutJoy(i);
+	INL_ShutKbd();
+
+	IN_Started = false;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	IN_SetKeyHook() - Sets the routine that gets called by INL_KeyService()
+//			everytime a real make/break code gets hit
+//
+///////////////////////////////////////////////////////////////////////////
+void
+IN_SetKeyHook(void (*hook)())
+{
+	INL_KeyHook = hook;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	IN_ClearKeysDown() - Clears the keyboard array
+//
+///////////////////////////////////////////////////////////////////////////
+void
+IN_ClearKeysDown(void)
+{
+	int	i;
+
+	LastScan = sc_None;
+	LastASCII = key_None;
+	memset (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;
+			byte		dbyte;
+			word		buttons;
+			int			dx,dy;
+			Motion		mx,my;
+			ControlType	type;
+register	KeyboardDef	*def;
+
+	dx = dy = 0;
+	mx = my = motion_None;
+	buttons = 0;
+
+	if (DemoMode == demo_Playback)
+	{
+		dbyte = DemoBuffer[DemoOffset + 1];
+		my = (dbyte & 3) - 1;
+		mx = ((dbyte >> 2) & 3) - 1;
+		buttons = (dbyte >> 4) & 3;
+
+		if (!(--DemoBuffer[DemoOffset]))
+		{
+			DemoOffset += 2;
+			if (DemoOffset >= DemoSize)
+				DemoMode = demo_PlayDone;
+		}
+
+		realdelta = false;
+	}
+	else if (DemoMode == demo_PlayDone)
+		Quit("Demo playback exceeded");
+	else
+	{
+		switch (type = Controls[player])
+		{
+		case ctrl_Keyboard:
+			def = &KbdDefs;
+
+			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;
+
+			if (Keyboard[def->up])
+				my = motion_Up;
+			else if (Keyboard[def->down])
+				my = motion_Down;
+
+			if (Keyboard[def->left])
+				mx = motion_Left;
+			else if (Keyboard[def->right])
+				mx = motion_Right;
+
+			if (Keyboard[def->button0])
+				buttons += 1 << 0;
+			if (Keyboard[def->button1])
+				buttons += 1 << 1;
+			realdelta = false;
+			break;
+		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 = INL_GetMouseButtons();
+			realdelta = true;
+			break;
+		}
+	}
+
+	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)];
+
+	if (DemoMode == demo_Record)
+	{
+		// Pack the control info into a byte
+		dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1);
+
+		if
+		(
+			(DemoBuffer[DemoOffset + 1] == dbyte)
+		&&	(DemoBuffer[DemoOffset] < 255)
+		)
+			(DemoBuffer[DemoOffset])++;
+		else
+		{
+			if (DemoOffset || DemoBuffer[DemoOffset])
+				DemoOffset += 2;
+
+			if (DemoOffset >= DemoSize)
+				Quit("Demo buffer overflow");
+
+			DemoBuffer[DemoOffset] = 1;
+			DemoBuffer[DemoOffset + 1] = dbyte;
+		}
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	IN_SetControlType() - Sets the control type to be used by the specified
+//		player
+//
+///////////////////////////////////////////////////////////////////////////
+void
+IN_SetControlType(int player,ControlType type)
+{
+	// DEBUG - check that requested type is present?
+	Controls[player] = type;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	IN_WaitForKey() - Waits for a scan code, then clears LastScan and
+//		returns the scan code
+//
+///////////////////////////////////////////////////////////////////////////
+ScanCode
+IN_WaitForKey(void)
+{
+	ScanCode	result;
+
+	while (!(result = LastScan))
+		;
+	LastScan = 0;
+	return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and
+//		returns the ASCII value
+//
+///////////////////////////////////////////////////////////////////////////
+char
+IN_WaitForASCII(void)
+{
+	char		result;
+
+	while (!(result = LastASCII))
+		;
+	LastASCII = '\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;
+
+//
+// get initial state of everything
+//
+	IN_ClearKeysDown();
+	memset (btnstate,0,sizeof(btnstate));
+
+	buttons = IN_JoyButtons () << 4;
+	if (MousePresent)
+		buttons |= IN_MouseButtons ();
+
+	for (i=0;i<8;i++,buttons>>=1)
+		if (buttons&1)
+			btnstate[i] = true;
+}
+
+
+boolean IN_CheckAck (void)
+{
+	unsigned	i,buttons;
+
+//
+// see if something has been pressed
+//
+	if (LastScan)
+		return true;
+
+	buttons = IN_JoyButtons () << 4;
+	if (MousePresent)
+		buttons |= IN_MouseButtons ();
+
+	for (i=0;i<8;i++,buttons>>=1)
+		if ( buttons&1 )
+		{
+			if (!btnstate[i])
+				return true;
+		}
+		else
+			btnstate[i]=false;
+
+	return false;
+}
+
+
+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(longword delay)
+{
+	longword	lasttime;
+
+	lasttime = TimeCount;
+	IN_StartAck ();
+	do
+	{
+		if (IN_CheckAck())
+			return true;
+	} while (TimeCount - lasttime < delay);
+	return(false);
+}
+
+//===========================================================================
+
+/*
+===================
+=
+= IN_MouseButtons
+=
+===================
+*/
+
+byte	IN_MouseButtons (void)
+{
+	if (MousePresent)
+	{
+		Mouse(MButtons);
+		return _BX;
+	}
+	else
+		return 0;
+}
+
+
+/*
+===================
+=
+= IN_JoyButtons
+=
+===================
+*/
+
+byte	IN_JoyButtons (void)
+{
+	unsigned joybits;
+
+	joybits = inportb(0x201);	// Get all the joystick buttons
+	joybits >>= 4;				// only the high bits are useful
+	joybits ^= 15;				// return with 1=pressed
+
+	return joybits;
+}
+
+
--- /dev/null
+++ b/WOLFSRC/ID_IN.H
@@ -1,0 +1,202 @@
+//
+//	ID Engine
+//	ID_IN.h - Header file for Input Manager
+//	v1.0d1
+//	By Jason Blochowiak
+//
+
+#ifndef	__ID_IN__
+#define	__ID_IN__
+
+#ifdef	__DEBUG__
+#define	__DEBUG_InputMgr__
+#endif
+
+#define	MaxPlayers	4
+#define	MaxKbds		2
+#define	MaxJoys		2
+#define	NumCodes	128
+
+typedef	byte		ScanCode;
+#define	sc_None			0
+#define	sc_Bad			0xff
+#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			0x59
+
+#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_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
+
+#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
+
+// 	Stuff for the mouse
+#define	MReset		0
+#define	MButtons	3
+#define	MDelta		11
+
+#define	MouseInt	0x33
+#define	Mouse(x)	_AX = x,geninterrupt(MouseInt)
+
+typedef	enum		{
+						demo_Off,demo_Record,demo_Playback,demo_PlayDone
+					} Demo;
+typedef	enum		{
+						ctrl_Keyboard,
+							ctrl_Keyboard1 = ctrl_Keyboard,ctrl_Keyboard2,
+						ctrl_Joystick,
+							ctrl_Joystick1 = ctrl_Joystick,ctrl_Joystick2,
+						ctrl_Mouse
+					} ControlType;
+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	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;
+// Global variables
+extern	boolean		Keyboard[],
+					MousePresent,
+					JoysPresent[];
+extern	boolean		Paused;
+extern	char		LastASCII;
+extern	ScanCode	LastScan;
+extern	KeyboardDef	KbdDefs;
+extern	JoystickDef	JoyDefs[];
+extern	ControlType	Controls[MaxPlayers];
+
+extern	Demo		DemoMode;
+extern	byte _seg	*DemoBuffer;
+extern	word		DemoOffset,DemoSize;
+
+// Function prototypes
+#define	IN_KeyDown(code)	(Keyboard[(code)])
+#define	IN_ClearKey(code)	{Keyboard[code] = false;\
+							if (code == LastScan) LastScan = sc_None;}
+
+// DEBUG - put names in prototypes
+extern	void		IN_Startup(void),IN_Shutdown(void),
+					IN_Default(boolean gotit,ControlType in),
+					IN_SetKeyHook(void (*)()),
+					IN_ClearKeysDown(void),
+					IN_ReadCursor(CursorInfo *),
+					IN_ReadControl(int,ControlInfo *),
+					IN_SetControlType(int,ControlType),
+					IN_GetJoyAbs(word joy,word *xp,word *yp),
+					IN_SetupJoy(word joy,word minx,word maxx,
+								word miny,word maxy),
+					IN_StopDemo(void),IN_FreeDemoBuffer(void),
+					IN_Ack(void),IN_AckBack(void);
+extern	boolean		IN_UserInput(longword delay);
+extern	char		IN_WaitForASCII(void);
+extern	ScanCode	IN_WaitForKey(void);
+extern	word		IN_GetJoyButtonsDB(word joy);
+extern	byte		*IN_GetScanName(ScanCode);
+
+
+byte	IN_MouseButtons (void);
+byte	IN_JoyButtons (void);
+
+void INL_GetJoyDelta(word joy,int *dx,int *dy);
+void IN_StartAck(void);
+boolean IN_CheckAck (void);
+
+#endif
--- /dev/null
+++ b/WOLFSRC/ID_MM.C
@@ -1,0 +1,953 @@
+// NEWMM.C
+
+/*
+=============================================================================
+
+		   ID software memory manager
+		   --------------------------
+
+Primary coder: John Carmack
+
+RELIES ON
+---------
+Quit (char *error) function
+
+
+WORK TO DO
+----------
+MM_SizePtr to change the size of a given pointer
+
+Multiple purge levels utilized
+
+EMS / XMS unmanaged routines
+
+=============================================================================
+*/
+
+#include "ID_HEADS.H"
+#pragma hdrstop
+
+#pragma warn -pro
+#pragma warn -use
+
+/*
+=============================================================================
+
+							LOCAL INFO
+
+=============================================================================
+*/
+
+#define LOCKBIT		0x80	// if set in attributes, block cannot be moved
+#define PURGEBITS	3		// 0-3 level, 0= unpurgable, 3= purge first
+#define PURGEMASK	0xfffc
+#define BASEATTRIBUTES	0	// unlocked, non purgable
+
+#define MAXUMBS		10
+
+typedef struct mmblockstruct
+{
+	unsigned	start,length;
+	unsigned	attributes;
+	memptr		*useptr;	// pointer to the segment start
+	struct mmblockstruct far *next;
+} mmblocktype;
+
+
+//#define GETNEWBLOCK {if(!(mmnew=mmfree))Quit("MM_GETNEWBLOCK: No free blocks!")\
+//	;mmfree=mmfree->next;}
+
+#define GETNEWBLOCK {if(!mmfree)MML_ClearBlock();mmnew=mmfree;mmfree=mmfree->next;}
+
+#define FREEBLOCK(x) {*x->useptr=NULL;x->next=mmfree;mmfree=x;}
+
+/*
+=============================================================================
+
+						 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+mminfotype	mminfo;
+memptr		bufferseg;
+boolean		mmerror;
+
+void		(* beforesort) (void);
+void		(* aftersort) (void);
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+boolean		mmstarted;
+
+void far	*farheap;
+void		*nearheap;
+
+mmblocktype	far mmblocks[MAXBLOCKS]
+			,far *mmhead,far *mmfree,far *mmrover,far *mmnew;
+
+boolean		bombonerror;
+
+//unsigned	totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle;
+
+void		(* XMSaddr) (void);		// far pointer to XMS driver
+
+unsigned	numUMBs,UMBbase[MAXUMBS];
+
+//==========================================================================
+
+//
+// local prototypes
+//
+
+boolean		MML_CheckForEMS (void);
+void 		MML_ShutdownEMS (void);
+void 		MM_MapEMS (void);
+boolean 	MML_CheckForXMS (void);
+void 		MML_ShutdownXMS (void);
+void		MML_UseSpace (unsigned segstart, unsigned seglength);
+void 		MML_ClearBlock (void);
+
+//==========================================================================
+
+/*
+======================
+=
+= MML_CheckForXMS
+=
+= Check for XMM driver
+=
+=======================
+*/
+
+boolean MML_CheckForXMS (void)
+{
+	numUMBs = 0;
+
+asm {
+	mov	ax,0x4300
+	int	0x2f				// query status of installed diver
+	cmp	al,0x80
+	je	good
+	}
+
+	return false;
+good:
+	return true;
+}
+
+
+/*
+======================
+=
+= MML_SetupXMS
+=
+= Try to allocate all upper memory block
+=
+=======================
+*/
+
+void MML_SetupXMS (void)
+{
+	unsigned	base,size;
+
+asm	{
+	mov	ax,0x4310
+	int	0x2f
+	mov	[WORD PTR XMSaddr],bx
+	mov	[WORD PTR XMSaddr+2],es		// function pointer to XMS driver
+	}
+
+getmemory:
+asm	{
+	mov	ah,XMS_ALLOCUMB
+	mov	dx,0xffff					// try for largest block possible
+	call	[DWORD PTR XMSaddr]
+	or	ax,ax
+	jnz	gotone
+
+	cmp	bl,0xb0						// error: smaller UMB is available
+	jne	done;
+
+	mov	ah,XMS_ALLOCUMB
+	call	[DWORD PTR XMSaddr]		// DX holds largest available UMB
+	or	ax,ax
+	jz	done						// another error...
+	}
+
+gotone:
+asm	{
+	mov	[base],bx
+	mov	[size],dx
+	}
+	MML_UseSpace (base,size);
+	mminfo.XMSmem += size*16;
+	UMBbase[numUMBs] = base;
+	numUMBs++;
+	if (numUMBs < MAXUMBS)
+		goto getmemory;
+
+done:;
+}
+
+
+/*
+======================
+=
+= MML_ShutdownXMS
+=
+======================
+*/
+
+void MML_ShutdownXMS (void)
+{
+	int	i;
+	unsigned	base;
+
+	for (i=0;i<numUMBs;i++)
+	{
+		base = UMBbase[i];
+
+asm	mov	ah,XMS_FREEUMB
+asm	mov	dx,[base]
+asm	call	[DWORD PTR XMSaddr]
+	}
+}
+
+//==========================================================================
+
+/*
+======================
+=
+= MML_UseSpace
+=
+= Marks a range of paragraphs as usable by the memory manager
+= This is used to mark space for the near heap, far heap, ems page frame,
+= and upper memory blocks
+=
+======================
+*/
+
+void MML_UseSpace (unsigned segstart, unsigned seglength)
+{
+	mmblocktype far *scan,far *last;
+	unsigned	oldend;
+	long		extra;
+
+	scan = last = mmhead;
+	mmrover = mmhead;		// reset rover to start of memory
+
+//
+// search for the block that contains the range of segments
+//
+	while (scan->start+scan->length < segstart)
+	{
+		last = scan;
+		scan = scan->next;
+	}
+
+//
+// take the given range out of the block
+//
+	oldend = scan->start + scan->length;
+	extra = oldend - (segstart+seglength);
+	if (extra < 0)
+		Quit ("MML_UseSpace: Segment spans two blocks!");
+
+	if (segstart == scan->start)
+	{
+		last->next = scan->next;			// unlink block
+		FREEBLOCK(scan);
+		scan = last;
+	}
+	else
+		scan->length = segstart-scan->start;	// shorten block
+
+	if (extra > 0)
+	{
+		GETNEWBLOCK;
+		mmnew->useptr = NULL;
+
+		mmnew->next = scan->next;
+		scan->next = mmnew;
+		mmnew->start = segstart+seglength;
+		mmnew->length = extra;
+		mmnew->attributes = LOCKBIT;
+	}
+
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= MML_ClearBlock
+=
+= We are out of blocks, so free a purgable block
+=
+====================
+*/
+
+void MML_ClearBlock (void)
+{
+	mmblocktype far *scan,far *last;
+
+	scan = mmhead->next;
+
+	while (scan)
+	{
+		if (!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS) )
+		{
+			MM_FreePtr(scan->useptr);
+			return;
+		}
+		scan = scan->next;
+	}
+
+	Quit ("MM_ClearBlock: No purgable blocks!");
+}
+
+
+//==========================================================================
+
+/*
+===================
+=
+= MM_Startup
+=
+= Grabs all space from turbo with malloc/farmalloc
+= Allocates bufferseg misc buffer
+=
+===================
+*/
+
+static	char *ParmStrings[] = {"noems","noxms",""};
+
+void MM_Startup (void)
+{
+	int i;
+	unsigned 	long length;
+	void far 	*start;
+	unsigned 	segstart,seglength,endfree;
+
+	if (mmstarted)
+		MM_Shutdown ();
+
+
+	mmstarted = true;
+	bombonerror = true;
+//
+// set up the linked list (everything in the free list;
+//
+	mmhead = NULL;
+	mmfree = &mmblocks[0];
+	for (i=0;i<MAXBLOCKS-1;i++)
+		mmblocks[i].next = &mmblocks[i+1];
+	mmblocks[i].next = NULL;
+
+//
+// locked block of all memory until we punch out free space
+//
+	GETNEWBLOCK;
+	mmhead = mmnew;				// this will allways be the first node
+	mmnew->start = 0;
+	mmnew->length = 0xffff;
+	mmnew->attributes = LOCKBIT;
+	mmnew->next = NULL;
+	mmrover = mmhead;
+
+
+//
+// get all available near conventional memory segments
+//
+	length=coreleft();
+	start = (void far *)(nearheap = malloc(length));
+
+	length -= 16-(FP_OFF(start)&15);
+	length -= SAVENEARHEAP;
+	seglength = length / 16;			// now in paragraphs
+	segstart = FP_SEG(start)+(FP_OFF(start)+15)/16;
+	MML_UseSpace (segstart,seglength);
+	mminfo.nearheap = length;
+
+//
+// get all available far conventional memory segments
+//
+	length=farcoreleft();
+	start = farheap = farmalloc(length);
+	length -= 16-(FP_OFF(start)&15);
+	length -= SAVEFARHEAP;
+	seglength = length / 16;			// now in paragraphs
+	segstart = FP_SEG(start)+(FP_OFF(start)+15)/16;
+	MML_UseSpace (segstart,seglength);
+	mminfo.farheap = length;
+	mminfo.mainmem = mminfo.nearheap + mminfo.farheap;
+
+//
+// allocate the misc buffer
+//
+	mmrover = mmhead;		// start looking for space after low block
+
+	MM_GetPtr (&bufferseg,BUFFERSIZE);
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= MM_Shutdown
+=
+= Frees all conventional, EMS, and XMS allocated
+=
+====================
+*/
+
+void MM_Shutdown (void)
+{
+  if (!mmstarted)
+	return;
+
+  farfree (farheap);
+  free (nearheap);
+//  MML_ShutdownXMS ();
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= MM_GetPtr
+=
+= Allocates an unlocked, unpurgable block
+=
+====================
+*/
+
+void MM_GetPtr (memptr *baseptr,unsigned long size)
+{
+	mmblocktype far *scan,far *lastscan,far *endscan
+				,far *purge,far *next;
+	int			search;
+	unsigned	needed,startseg;
+
+	needed = (size+15)/16;		// convert size from bytes to paragraphs
+
+	GETNEWBLOCK;				// fill in start and next after a spot is found
+	mmnew->length = needed;
+	mmnew->useptr = baseptr;
+	mmnew->attributes = BASEATTRIBUTES;
+
+tryagain:
+	for (search = 0; search<3; search++)
+	{
+	//
+	// first search:	try to allocate right after the rover, then on up
+	// second search: 	search from the head pointer up to the rover
+	// third search:	compress memory, then scan from start
+		if (search == 1 && mmrover == mmhead)
+			search++;
+
+		switch (search)
+		{
+		case 0:
+			lastscan = mmrover;
+			scan = mmrover->next;
+			endscan = NULL;
+			break;
+		case 1:
+			lastscan = mmhead;
+			scan = mmhead->next;
+			endscan = mmrover;
+			break;
+		case 2:
+			MM_SortMem ();
+			lastscan = mmhead;
+			scan = mmhead->next;
+			endscan = NULL;
+			break;
+		}
+
+		startseg = lastscan->start + lastscan->length;
+
+		while (scan != endscan)
+		{
+			if (scan->start - startseg >= needed)
+			{
+			//
+			// got enough space between the end of lastscan and
+			// the start of scan, so throw out anything in the middle
+			// and allocate the new block
+			//
+				purge = lastscan->next;
+				lastscan->next = mmnew;
+				mmnew->start = *(unsigned *)baseptr = startseg;
+				mmnew->next = scan;
+				while ( purge != scan)
+				{	// free the purgable block
+					next = purge->next;
+					FREEBLOCK(purge);
+					purge = next;		// purge another if not at scan
+				}
+				mmrover = mmnew;
+				return;	// good allocation!
+			}
+
+			//
+			// if this block is purge level zero or locked, skip past it
+			//
+			if ( (scan->attributes & LOCKBIT)
+				|| !(scan->attributes & PURGEBITS) )
+			{
+				lastscan = scan;
+				startseg = lastscan->start + lastscan->length;
+			}
+
+
+			scan=scan->next;		// look at next line
+		}
+	}
+
+	if (bombonerror)
+	{
+
+extern char configname[];
+extern	boolean	insetupscaling;
+extern	int	viewsize;
+boolean SetViewSize (unsigned width, unsigned height);
+#define HEIGHTRATIO		0.50
+//
+// wolf hack -- size the view down
+//
+		if (!insetupscaling && viewsize>10)
+		{
+mmblocktype	far *savedmmnew;
+			savedmmnew = mmnew;
+			viewsize -= 2;
+			SetViewSize (viewsize*16,viewsize*16*HEIGHTRATIO);
+			mmnew = savedmmnew;
+			goto tryagain;
+		}
+
+//		unlink(configname);
+		Quit ("MM_GetPtr: Out of memory!");
+	}
+	else
+		mmerror = true;
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= MM_FreePtr
+=
+= Deallocates an unlocked, purgable block
+=
+====================
+*/
+
+void MM_FreePtr (memptr *baseptr)
+{
+	mmblocktype far *scan,far *last;
+
+	last = mmhead;
+	scan = last->next;
+
+	if (baseptr == mmrover->useptr)	// removed the last allocated block
+		mmrover = mmhead;
+
+	while (scan->useptr != baseptr && scan)
+	{
+		last = scan;
+		scan = scan->next;
+	}
+
+	if (!scan)
+		Quit ("MM_FreePtr: Block not found!");
+
+	last->next = scan->next;
+
+	FREEBLOCK(scan);
+}
+//==========================================================================
+
+/*
+=====================
+=
+= MM_SetPurge
+=
+= Sets the purge level for a block (locked blocks cannot be made purgable)
+=
+=====================
+*/
+
+void MM_SetPurge (memptr *baseptr, int purge)
+{
+	mmblocktype far *start;
+
+	start = mmrover;
+
+	do
+	{
+		if (mmrover->useptr == baseptr)
+			break;
+
+		mmrover = mmrover->next;
+
+		if (!mmrover)
+			mmrover = mmhead;
+		else if (mmrover == start)
+			Quit ("MM_SetPurge: Block not found!");
+
+	} while (1);
+
+	mmrover->attributes &= ~PURGEBITS;
+	mmrover->attributes |= purge;
+}
+
+//==========================================================================
+
+/*
+=====================
+=
+= MM_SetLock
+=
+= Locks / unlocks the block
+=
+=====================
+*/
+
+void MM_SetLock (memptr *baseptr, boolean locked)
+{
+	mmblocktype far *start;
+
+	start = mmrover;
+
+	do
+	{
+		if (mmrover->useptr == baseptr)
+			break;
+
+		mmrover = mmrover->next;
+
+		if (!mmrover)
+			mmrover = mmhead;
+		else if (mmrover == start)
+			Quit ("MM_SetLock: Block not found!");
+
+	} while (1);
+
+	mmrover->attributes &= ~LOCKBIT;
+	mmrover->attributes |= locked*LOCKBIT;
+}
+
+//==========================================================================
+
+/*
+=====================
+=
+= MM_SortMem
+=
+= Throws out all purgable stuff and compresses movable blocks
+=
+=====================
+*/
+
+void MM_SortMem (void)
+{
+	mmblocktype far *scan,far *last,far *next;
+	unsigned	start,length,source,dest;
+	int			playing;
+
+	//
+	// lock down a currently playing sound
+	//
+	playing = SD_SoundPlaying ();
+	if (playing)
+	{
+		switch (SoundMode)
+		{
+		case sdm_PC:
+			playing += STARTPCSOUNDS;
+			break;
+		case sdm_AdLib:
+			playing += STARTADLIBSOUNDS;
+			break;
+		}
+		MM_SetLock(&(memptr)audiosegs[playing],true);
+	}
+
+
+	SD_StopSound();
+
+	if (beforesort)
+		beforesort();
+
+	scan = mmhead;
+
+	last = NULL;		// shut up compiler warning
+
+	while (scan)
+	{
+		if (scan->attributes & LOCKBIT)
+		{
+		//
+		// block is locked, so try to pile later blocks right after it
+		//
+			start = scan->start + scan->length;
+		}
+		else
+		{
+			if (scan->attributes & PURGEBITS)
+			{
+			//
+			// throw out the purgable block
+			//
+				next = scan->next;
+				FREEBLOCK(scan);
+				last->next = next;
+				scan = next;
+				continue;
+			}
+			else
+			{
+			//
+			// push the non purgable block on top of the last moved block
+			//
+				if (scan->start != start)
+				{
+					length = scan->length;
+					source = scan->start;
+					dest = start;
+					while (length > 0xf00)
+					{
+						movedata(source,0,dest,0,0xf00*16);
+						length -= 0xf00;
+						source += 0xf00;
+						dest += 0xf00;
+					}
+					movedata(source,0,dest,0,length*16);
+
+					scan->start = start;
+					*(unsigned *)scan->useptr = start;
+				}
+				start = scan->start + scan->length;
+			}
+		}
+
+		last = scan;
+		scan = scan->next;		// go to next block
+	}
+
+	mmrover = mmhead;
+
+	if (aftersort)
+		aftersort();
+
+	if (playing)
+		MM_SetLock(&(memptr)audiosegs[playing],false);
+}
+
+
+//==========================================================================
+
+/*
+=====================
+=
+= MM_ShowMemory
+=
+=====================
+*/
+
+void MM_ShowMemory (void)
+{
+	mmblocktype far *scan;
+	unsigned color,temp,x,y;
+	long	end,owner;
+	char    scratch[80],str[10];
+
+	temp = bufferofs;
+	bufferofs = displayofs;
+	scan = mmhead;
+
+	end = -1;
+
+	while (scan)
+	{
+		if (scan->attributes & PURGEBITS)
+			color = 5;		// dark purple = purgable
+		else
+			color = 9;		// medium blue = non purgable
+		if (scan->attributes & LOCKBIT)
+			color = 12;		// red = locked
+		if (scan->start<=end)
+			Quit ("MM_ShowMemory: Memory block order currupted!");
+		end = scan->length-1;
+		y = scan->start/320;
+		x = scan->start%320;
+		VW_Hlin(x,x+end,y,color);
+		VW_Plot(x,y,15);
+		if (scan->next && scan->next->start > end+1)
+			VW_Hlin(x+end+1,x+(scan->next->start-scan->start),y,0);	// black = free
+
+		scan = scan->next;
+	}
+
+	VW_FadeIn ();
+	IN_Ack();
+
+	bufferofs = temp;
+}
+
+//==========================================================================
+
+/*
+=====================
+=
+= MM_DumpData
+=
+=====================
+*/
+
+void MM_DumpData (void)
+{
+	mmblocktype far *scan,far *best;
+	long	lowest,oldlowest;
+	unsigned	owner;
+	char	lock,purge;
+	FILE	*dumpfile;
+
+
+	free (nearheap);
+	dumpfile = fopen ("MMDUMP.TXT","w");
+	if (!dumpfile)
+		Quit ("MM_DumpData: Couldn't open MMDUMP.TXT!");
+
+	lowest = -1;
+	do
+	{
+		oldlowest = lowest;
+		lowest = 0xffff;
+
+		scan = mmhead;
+		while (scan)
+		{
+			owner = (unsigned)scan->useptr;
+
+			if (owner && owner<lowest && owner > oldlowest)
+			{
+				best = scan;
+				lowest = owner;
+			}
+
+			scan = scan->next;
+		}
+
+		if (lowest != 0xffff)
+		{
+			if (best->attributes & PURGEBITS)
+				purge = 'P';
+			else
+				purge = '-';
+			if (best->attributes & LOCKBIT)
+				lock = 'L';
+			else
+				lock = '-';
+			fprintf (dumpfile,"0x%p (%c%c) = %u\n"
+			,(unsigned)lowest,lock,purge,best->length);
+		}
+
+	} while (lowest != 0xffff);
+
+	fclose (dumpfile);
+	Quit ("MMDUMP.TXT created.");
+}
+
+//==========================================================================
+
+
+/*
+======================
+=
+= MM_UnusedMemory
+=
+= Returns the total free space without purging
+=
+======================
+*/
+
+long MM_UnusedMemory (void)
+{
+	unsigned free;
+	mmblocktype far *scan;
+
+	free = 0;
+	scan = mmhead;
+
+	while (scan->next)
+	{
+		free += scan->next->start - (scan->start + scan->length);
+		scan = scan->next;
+	}
+
+	return free*16l;
+}
+
+//==========================================================================
+
+
+/*
+======================
+=
+= MM_TotalFree
+=
+= Returns the total free space with purging
+=
+======================
+*/
+
+long MM_TotalFree (void)
+{
+	unsigned free;
+	mmblocktype far *scan;
+
+	free = 0;
+	scan = mmhead;
+
+	while (scan->next)
+	{
+		if ((scan->attributes&PURGEBITS) && !(scan->attributes&LOCKBIT))
+			free += scan->length;
+		free += scan->next->start - (scan->start + scan->length);
+		scan = scan->next;
+	}
+
+	return free*16l;
+}
+
+//==========================================================================
+
+/*
+=====================
+=
+= MM_BombOnError
+=
+=====================
+*/
+
+void MM_BombOnError (boolean bomb)
+{
+	bombonerror = bomb;
+}
+
+
--- /dev/null
+++ b/WOLFSRC/ID_MM.H
@@ -1,0 +1,96 @@
+// ID_MM.H
+
+#ifndef __ID_CA__
+
+#define __ID_CA__
+
+#define SAVENEARHEAP	0x400		// space to leave in data segment
+#define SAVEFARHEAP		0			// space to leave in far heap
+
+#define	BUFFERSIZE		0x1000		// miscelanious, allways available buffer
+
+#define MAXBLOCKS		700
+
+
+//--------
+
+#define	EMS_INT			0x67
+
+#define	EMS_STATUS		0x40
+#define	EMS_GETFRAME	0x41
+#define	EMS_GETPAGES	0x42
+#define	EMS_ALLOCPAGES	0x43
+#define	EMS_MAPPAGE		0x44
+#define	EMS_FREEPAGES	0x45
+#define	EMS_VERSION		0x46
+
+//--------
+
+#define	XMS_INT			0x2f
+#define	XMS_CALL(v)		_AH = (v);\
+						asm call [DWORD PTR XMSDriver]
+
+#define	XMS_VERSION		0x00
+
+#define	XMS_ALLOCHMA	0x01
+#define	XMS_FREEHMA		0x02
+
+#define	XMS_GENABLEA20	0x03
+#define	XMS_GDISABLEA20	0x04
+#define	XMS_LENABLEA20	0x05
+#define	XMS_LDISABLEA20	0x06
+#define	XMS_QUERYA20	0x07
+
+#define	XMS_QUERYFREE	0x08
+#define	XMS_ALLOC		0x09
+#define	XMS_FREE		0x0A
+#define	XMS_MOVE		0x0B
+#define	XMS_LOCK		0x0C
+#define	XMS_UNLOCK		0x0D
+#define	XMS_GETINFO		0x0E
+#define	XMS_RESIZE		0x0F
+
+#define	XMS_ALLOCUMB	0x10
+#define	XMS_FREEUMB		0x11
+
+//==========================================================================
+
+typedef void _seg * memptr;
+
+typedef struct
+{
+	long	nearheap,farheap,EMSmem,XMSmem,mainmem;
+} mminfotype;
+
+//==========================================================================
+
+extern	mminfotype	mminfo;
+extern	memptr		bufferseg;
+extern	boolean		mmerror;
+
+extern	void		(* beforesort) (void);
+extern	void		(* aftersort) (void);
+
+//==========================================================================
+
+void MM_Startup (void);
+void MM_Shutdown (void);
+void MM_MapEMS (void);
+
+void MM_GetPtr (memptr *baseptr,unsigned long size);
+void MM_FreePtr (memptr *baseptr);
+
+void MM_SetPurge (memptr *baseptr, int purge);
+void MM_SetLock (memptr *baseptr, boolean locked);
+void MM_SortMem (void);
+
+void MM_ShowMemory (void);
+
+long MM_UnusedMemory (void);
+long MM_TotalFree (void);
+
+void MM_BombOnError (boolean bomb);
+
+void MML_UseSpace (unsigned segstart, unsigned seglength);
+
+#endif
\ No newline at end of file
--- /dev/null
+++ b/WOLFSRC/ID_PM.C
@@ -1,0 +1,1199 @@
+//
+//	ID_PM.C
+//	Id Engine's Page Manager v1.0
+//	Primary coder: Jason Blochowiak
+//
+
+#include "ID_HEADS.H"
+#pragma hdrstop
+
+//	Main Mem specific variables
+	boolean			MainPresent;
+	memptr			MainMemPages[PMMaxMainMem];
+	PMBlockAttr		MainMemUsed[PMMaxMainMem];
+	int				MainPagesAvail;
+
+//	EMS specific variables
+	boolean			EMSPresent;
+	word			EMSAvail,EMSPagesAvail,EMSHandle,
+					EMSPageFrame,EMSPhysicalPage;
+	EMSListStruct	EMSList[EMSFrameCount];
+
+//	XMS specific variables
+	boolean			XMSPresent;
+	word			XMSAvail,XMSPagesAvail,XMSHandle;
+	longword		XMSDriver;
+	int				XMSProtectPage = -1;
+
+//	File specific variables
+	char			PageFileName[13] = {"VSWAP."};
+	int				PageFile = -1;
+	word			ChunksInFile;
+	word			PMSpriteStart,PMSoundStart;
+
+//	General usage variables
+	boolean			PMStarted,
+					PMPanicMode,
+					PMThrashing;
+	word			XMSPagesUsed,
+					EMSPagesUsed,
+					MainPagesUsed,
+					PMNumBlocks;
+	long			PMFrameCount;
+	PageListStruct	far *PMPages,
+					_seg *PMSegPages;
+
+static	char		*ParmStrings[] = {"nomain","noems","noxms",nil};
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//	EMS Management code
+//
+/////////////////////////////////////////////////////////////////////////////
+
+//
+//	PML_MapEMS() - Maps a logical page to a physical page
+//
+void
+PML_MapEMS(word logical,word physical)
+{
+	_AL = physical;
+	_BX = logical;
+	_DX = EMSHandle;
+	_AH = EMS_MAPPAGE;
+asm	int	EMS_INT
+
+	if (_AH)
+		Quit("PML_MapEMS: Page mapping failed");
+}
+
+//
+//	PML_StartupEMS() - Sets up EMS for Page Mgr's use
+//		Checks to see if EMS driver is present
+//      Verifies that EMS hardware is present
+//		Make sure that EMS version is 3.2 or later
+//		If there's more than our minimum (2 pages) available, allocate it (up
+//			to the maximum we need)
+//
+
+	char	EMMDriverName[9] = "EMMXXXX0";
+
+boolean
+PML_StartupEMS(void)
+{
+	int		i;
+	long	size;
+
+	EMSPresent = false;			// Assume that we'll fail
+	EMSAvail = 0;
+
+	_DX = (word)EMMDriverName;
+	_AX = 0x3d00;
+	geninterrupt(0x21);			// try to open EMMXXXX0 device
+asm	jnc	gothandle
+	goto error;
+
+gothandle:
+	_BX = _AX;
+	_AX = 0x4400;
+	geninterrupt(0x21);			// get device info
+asm	jnc	gotinfo;
+	goto error;
+
+gotinfo:
+asm	and	dx,0x80
+	if (!_DX)
+		goto error;
+
+	_AX = 0x4407;
+	geninterrupt(0x21);			// get status
+asm	jc	error
+	if (!_AL)
+		goto error;
+
+	_AH = 0x3e;
+	geninterrupt(0x21);			// close handle
+
+	_AH = EMS_STATUS;
+	geninterrupt(EMS_INT);
+	if (_AH)
+		goto error;				// make sure EMS hardware is present
+
+	_AH = EMS_VERSION;
+	geninterrupt(EMS_INT);
+	if (_AH || (_AL < 0x32))	// only work on EMS 3.2 or greater (silly, but...)
+		goto error;
+
+	_AH = EMS_GETFRAME;
+	geninterrupt(EMS_INT);
+	if (_AH)
+		goto error;				// find the page frame address
+	EMSPageFrame = _BX;
+
+	_AH = EMS_GETPAGES;
+	geninterrupt(EMS_INT);
+	if (_AH)
+		goto error;
+	if (_BX < 2)
+		goto error;         	// Require at least 2 pages (32k)
+	EMSAvail = _BX;
+
+	// Don't hog all available EMS
+	size = EMSAvail * (long)EMSPageSize;
+	if (size - (EMSPageSize * 2) > (ChunksInFile * (long)PMPageSize))
+	{
+		size = (ChunksInFile * (long)PMPageSize) + EMSPageSize;
+		EMSAvail = size / EMSPageSize;
+	}
+
+	_AH = EMS_ALLOCPAGES;
+	_BX = EMSAvail;
+	geninterrupt(EMS_INT);
+	if (_AH)
+		goto error;
+	EMSHandle = _DX;
+
+	mminfo.EMSmem += EMSAvail * (long)EMSPageSize;
+
+	// Initialize EMS mapping cache
+	for (i = 0;i < EMSFrameCount;i++)
+		EMSList[i].baseEMSPage = -1;
+
+	EMSPresent = true;			// We have EMS
+
+error:
+	return(EMSPresent);
+}
+
+//
+//	PML_ShutdownEMS() - If EMS was used, deallocate it
+//
+void
+PML_ShutdownEMS(void)
+{
+	if (EMSPresent)
+	{
+	asm	mov	ah,EMS_FREEPAGES
+	asm	mov	dx,[EMSHandle]
+	asm	int	EMS_INT
+		if (_AH)
+			Quit ("PML_ShutdownEMS: Error freeing EMS");
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//	XMS Management code
+//
+/////////////////////////////////////////////////////////////////////////////
+
+//
+//	PML_StartupXMS() - Starts up XMS for the Page Mgr's use
+//		Checks for presence of an XMS driver
+//		Makes sure that there's at least a page of XMS available
+//		Allocates any remaining XMS (rounded down to the nearest page size)
+//
+boolean
+PML_StartupXMS(void)
+{
+	XMSPresent = false;					// Assume failure
+	XMSAvail = 0;
+
+asm	mov	ax,0x4300
+asm	int	XMS_INT         				// Check for presence of XMS driver
+	if (_AL != 0x80)
+		goto error;
+
+
+asm	mov	ax,0x4310
+asm	int	XMS_INT							// Get address of XMS driver
+asm	mov	[WORD PTR XMSDriver],bx
+asm	mov	[WORD PTR XMSDriver+2],es		// function pointer to XMS driver
+
+	XMS_CALL(XMS_QUERYFREE);			// Find out how much XMS is available
+	XMSAvail = _AX;
+	if (!_AX)				// AJR: bugfix 10/8/92
+		goto error;
+
+	XMSAvail &= ~(PMPageSizeKB - 1);	// Round off to nearest page size
+	if (XMSAvail < (PMPageSizeKB * 2))	// Need at least 2 pages
+		goto error;
+
+	_DX = XMSAvail;
+	XMS_CALL(XMS_ALLOC);				// And do the allocation
+	XMSHandle = _DX;
+
+	if (!_AX)				// AJR: bugfix 10/8/92
+	{
+		XMSAvail = 0;
+		goto error;
+	}
+
+	mminfo.XMSmem += XMSAvail * 1024;
+
+	XMSPresent = true;
+error:
+	return(XMSPresent);
+}
+
+//
+//	PML_XMSCopy() - Copies a main/EMS page to or from XMS
+//		Will round an odd-length request up to the next even value
+//
+void
+PML_XMSCopy(boolean toxms,byte far *addr,word xmspage,word length)
+{
+	longword	xoffset;
+	struct
+	{
+		longword	length;
+		word		source_handle;
+		longword	source_offset;
+		word		target_handle;
+		longword	target_offset;
+	} copy;
+
+	if (!addr)
+		Quit("PML_XMSCopy: zero address");
+
+	xoffset = (longword)xmspage * PMPageSize;
+
+	copy.length = (length + 1) & ~1;
+	copy.source_handle = toxms? 0 : XMSHandle;
+	copy.source_offset = toxms? (long)addr : xoffset;
+	copy.target_handle = toxms? XMSHandle : 0;
+	copy.target_offset = toxms? xoffset : (long)addr;
+
+asm	push si
+	_SI = (word)&copy;
+	XMS_CALL(XMS_MOVE);
+asm	pop	si
+	if (!_AX)
+		Quit("PML_XMSCopy: Error on copy");
+}
+
+#if 1
+#define	PML_CopyToXMS(s,t,l)	PML_XMSCopy(true,(s),(t),(l))
+#define	PML_CopyFromXMS(t,s,l)	PML_XMSCopy(false,(t),(s),(l))
+#else
+//
+//	PML_CopyToXMS() - Copies the specified number of bytes from the real mode
+//		segment address to the specified XMS page
+//
+void
+PML_CopyToXMS(byte far *source,int targetpage,word length)
+{
+	PML_XMSCopy(true,source,targetpage,length);
+}
+
+//
+//	PML_CopyFromXMS() - Copies the specified number of bytes from an XMS
+//		page to the specified real mode address
+//
+void
+PML_CopyFromXMS(byte far *target,int sourcepage,word length)
+{
+	PML_XMSCopy(false,target,sourcepage,length);
+}
+#endif
+
+//
+//	PML_ShutdownXMS()
+//
+void
+PML_ShutdownXMS(void)
+{
+	if (XMSPresent)
+	{
+		_DX = XMSHandle;
+		XMS_CALL(XMS_FREE);
+		if (_BL)
+			Quit("PML_ShutdownXMS: Error freeing XMS");
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//	Main memory code
+//
+/////////////////////////////////////////////////////////////////////////////
+
+//
+//	PM_SetMainMemPurge() - Sets the purge level for all allocated main memory
+//		blocks. This shouldn't be called directly - the PM_LockMainMem() and
+//		PM_UnlockMainMem() macros should be used instead.
+//
+void
+PM_SetMainMemPurge(int level)
+{
+	int	i;
+
+	for (i = 0;i < PMMaxMainMem;i++)
+		if (MainMemPages[i])
+			MM_SetPurge(&MainMemPages[i],level);
+}
+
+//
+//	PM_CheckMainMem() - If something besides the Page Mgr makes requests of
+//		the Memory Mgr, some of the Page Mgr's blocks may have been purged,
+//		so this function runs through the block list and checks to see if
+//		any of the blocks have been purged. If so, it marks the corresponding
+//		page as purged & unlocked, then goes through the block list and
+//		tries to reallocate any blocks that have been purged.
+//	This routine now calls PM_LockMainMem() to make sure that any allocation
+//		attempts made during the block reallocation sweep don't purge any
+//		of the other blocks. Because PM_LockMainMem() is called,
+//		PM_UnlockMainMem() needs to be called before any other part of the
+//		program makes allocation requests of the Memory Mgr.
+//
+void
+PM_CheckMainMem(void)
+{
+	boolean			allocfailed;
+	int				i,n;
+	memptr			*p;
+	PMBlockAttr		*used;
+	PageListStruct	far *page;
+
+	if (!MainPresent)
+		return;
+
+	for (i = 0,page = PMPages;i < ChunksInFile;i++,page++)
+	{
+		n = page->mainPage;
+		if (n != -1)						// Is the page using main memory?
+		{
+			if (!MainMemPages[n])			// Yep, was the block purged?
+			{
+				page->mainPage = -1;		// Yes, mark page as purged & unlocked
+				page->locked = pml_Unlocked;
+			}
+		}
+	}
+
+	// Prevent allocation attempts from purging any of our other blocks
+	PM_LockMainMem();
+	allocfailed = false;
+	for (i = 0,p = MainMemPages,used = MainMemUsed;i < PMMaxMainMem;i++,p++,used++)
+	{
+		if (!*p)							// If the page got purged
+		{
+			if (*used & pmba_Allocated)		// If it was allocated
+			{
+				*used &= ~pmba_Allocated;	// Mark as unallocated
+				MainPagesAvail--;			// and decrease available count
+			}
+
+			if (*used & pmba_Used)			// If it was used
+			{
+				*used &= ~pmba_Used;		// Mark as unused
+				MainPagesUsed--;			// and decrease used count
+			}
+
+			if (!allocfailed)
+			{
+				MM_BombOnError(false);
+				MM_GetPtr(p,PMPageSize);		// Try to reallocate
+				if (mmerror)					// If it failed,
+					allocfailed = true;			//  don't try any more allocations
+				else							// If it worked,
+				{
+					*used |= pmba_Allocated;	// Mark as allocated
+					MainPagesAvail++;			// and increase available count
+				}
+				MM_BombOnError(true);
+			}
+		}
+	}
+	if (mmerror)
+		mmerror = false;
+}
+
+//
+//	PML_StartupMainMem() - Allocates as much main memory as is possible for
+//		the Page Mgr. The memory is allocated as non-purgeable, so if it's
+//		necessary to make requests of the Memory Mgr, PM_UnlockMainMem()
+//		needs to be called.
+//
+void
+PML_StartupMainMem(void)
+{
+	int		i,n;
+	memptr	*p;
+
+	MainPagesAvail = 0;
+	MM_BombOnError(false);
+	for (i = 0,p = MainMemPages;i < PMMaxMainMem;i++,p++)
+	{
+		MM_GetPtr(p,PMPageSize);
+		if (mmerror)
+			break;
+
+		MainPagesAvail++;
+		MainMemUsed[i] = pmba_Allocated;
+	}
+	MM_BombOnError(true);
+	if (mmerror)
+		mmerror = false;
+	if (MainPagesAvail < PMMinMainMem)
+		Quit("PM_SetupMainMem: Not enough main memory");
+	MainPresent = true;
+}
+
+//
+//	PML_ShutdownMainMem() - Frees all of the main memory blocks used by the
+//		Page Mgr.
+//
+void
+PML_ShutdownMainMem(void)
+{
+	int		i;
+	memptr	*p;
+
+	// DEBUG - mark pages as unallocated & decrease page count as appropriate
+	for (i = 0,p = MainMemPages;i < PMMaxMainMem;i++,p++)
+		if (*p)
+			MM_FreePtr(p);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//	File management code
+//
+/////////////////////////////////////////////////////////////////////////////
+
+//
+//	PML_ReadFromFile() - Reads some data in from the page file
+//
+void
+PML_ReadFromFile(byte far *buf,long offset,word length)
+{
+	if (!buf)
+		Quit("PML_ReadFromFile: Null pointer");
+	if (!offset)
+		Quit("PML_ReadFromFile: Zero offset");
+	if (lseek(PageFile,offset,SEEK_SET) != offset)
+		Quit("PML_ReadFromFile: Seek failed");
+	if (!CA_FarRead(PageFile,buf,length))
+		Quit("PML_ReadFromFile: Read failed");
+}
+
+//
+//	PML_OpenPageFile() - Opens the page file and sets up the page info
+//
+void
+PML_OpenPageFile(void)
+{
+	int				i;
+	long			size;
+	void			_seg *buf;
+	longword		far *offsetptr;
+	word			far *lengthptr;
+	PageListStruct	far *page;
+
+	PageFile = open(PageFileName,O_RDONLY + O_BINARY);
+	if (PageFile == -1)
+		Quit("PML_OpenPageFile: Unable to open page file");
+
+	// Read in header variables
+	read(PageFile,&ChunksInFile,sizeof(ChunksInFile));
+	read(PageFile,&PMSpriteStart,sizeof(PMSpriteStart));
+	read(PageFile,&PMSoundStart,sizeof(PMSoundStart));
+
+	// Allocate and clear the page list
+	PMNumBlocks = ChunksInFile;
+	MM_GetPtr(&(memptr)PMSegPages,sizeof(PageListStruct) * PMNumBlocks);
+	MM_SetLock(&(memptr)PMSegPages,true);
+	PMPages = (PageListStruct far *)PMSegPages;
+	_fmemset(PMPages,0,sizeof(PageListStruct) * PMNumBlocks);
+
+	// Read in the chunk offsets
+	size = sizeof(longword) * ChunksInFile;
+	MM_GetPtr(&buf,size);
+	if (!CA_FarRead(PageFile,(byte far *)buf,size))
+		Quit("PML_OpenPageFile: Offset read failed");
+	offsetptr = (longword far *)buf;
+	for (i = 0,page = PMPages;i < ChunksInFile;i++,page++)
+		page->offset = *offsetptr++;
+	MM_FreePtr(&buf);
+
+	// Read in the chunk lengths
+	size = sizeof(word) * ChunksInFile;
+	MM_GetPtr(&buf,size);
+	if (!CA_FarRead(PageFile,(byte far *)buf,size))
+		Quit("PML_OpenPageFile: Length read failed");
+	lengthptr = (word far *)buf;
+	for (i = 0,page = PMPages;i < ChunksInFile;i++,page++)
+		page->length = *lengthptr++;
+	MM_FreePtr(&buf);
+}
+
+//
+//  PML_ClosePageFile() - Closes the page file
+//
+void
+PML_ClosePageFile(void)
+{
+	if (PageFile != -1)
+		close(PageFile);
+	if (PMSegPages)
+	{
+		MM_SetLock(&(memptr)PMSegPages,false);
+		MM_FreePtr(&(void _seg *)PMSegPages);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//	Allocation, etc., code
+//
+/////////////////////////////////////////////////////////////////////////////
+
+//
+//	PML_GetEMSAddress()
+//
+// 		Page is in EMS, so figure out which EMS physical page should be used
+//  		to map our page in. If normal page, use EMS physical page 3, else
+//  		use the physical page specified by the lock type
+//
+#if 1
+#pragma argsused	// DEBUG - remove lock parameter
+memptr
+PML_GetEMSAddress(int page,PMLockType lock)
+{
+	int		i,emspage;
+	word	emsoff,emsbase,offset;
+
+	emsoff = page & (PMEMSSubPage - 1);
+	emsbase = page - emsoff;
+
+	emspage = -1;
+	// See if this page is already mapped in
+	for (i = 0;i < EMSFrameCount;i++)
+	{
+		if (EMSList[i].baseEMSPage == emsbase)
+		{
+			emspage = i;	// Yep - don't do a redundant remapping
+			break;
+		}
+	}
+
+	// If page isn't already mapped in, find LRU EMS frame, and use it
+	if (emspage == -1)
+	{
+		longword last = MAXLONG;
+		for (i = 0;i < EMSFrameCount;i++)
+		{
+			if (EMSList[i].lastHit < last)
+			{
+				emspage = i;
+				last = EMSList[i].lastHit;
+			}
+		}
+
+		EMSList[emspage].baseEMSPage = emsbase;
+		PML_MapEMS(page / PMEMSSubPage,emspage);
+	}
+
+	if (emspage == -1)
+		Quit("PML_GetEMSAddress: EMS find failed");
+
+	EMSList[emspage].lastHit = PMFrameCount;
+	offset = emspage * EMSPageSizeSeg;
+	offset += emsoff * PMPageSizeSeg;
+	return((memptr)(EMSPageFrame + offset));
+}
+#else
+memptr
+PML_GetEMSAddress(int page,PMLockType lock)
+{
+	word	emspage;
+
+	emspage = (lock < pml_EMSLock)? 3 : (lock - pml_EMSLock);
+
+	PML_MapEMS(page / PMEMSSubPage,emspage);
+
+	return((memptr)(EMSPageFrame + (emspage * EMSPageSizeSeg)
+			+ ((page & (PMEMSSubPage - 1)) * PMPageSizeSeg)));
+}
+#endif
+
+//
+//	PM_GetPageAddress() - Returns the address of a given page
+//		Maps in EMS if necessary
+//		Returns nil if block isn't cached into Main Memory or EMS
+//
+//
+memptr
+PM_GetPageAddress(int pagenum)
+{
+	PageListStruct	far *page;
+
+	page = &PMPages[pagenum];
+	if (page->mainPage != -1)
+		return(MainMemPages[page->mainPage]);
+	else if (page->emsPage != -1)
+		return(PML_GetEMSAddress(page->emsPage,page->locked));
+	else
+		return(nil);
+}
+
+//
+//	PML_GiveLRUPage() - Returns the page # of the least recently used
+//		present & unlocked main/EMS page (or main page if mainonly is true)
+//
+int
+PML_GiveLRUPage(boolean mainonly)
+{
+	int				i,lru;
+	long			last;
+	PageListStruct	far *page;
+
+	for (i = 0,page = PMPages,lru = -1,last = MAXLONG;i < ChunksInFile;i++,page++)
+	{
+		if
+		(
+			(page->lastHit < last)
+		&&	((page->emsPage != -1) || (page->mainPage != -1))
+		&& 	(page->locked == pml_Unlocked)
+		&&	(!(mainonly && (page->mainPage == -1)))
+		)
+		{
+			last = page->lastHit;
+			lru = i;
+		}
+	}
+
+	if (lru == -1)
+		Quit("PML_GiveLRUPage: LRU Search failed");
+	return(lru);
+}
+
+//
+//	PML_GiveLRUXMSPage() - Returns the page # of the least recently used
+//		(and present) XMS page.
+//	This routine won't return the XMS page protected (by XMSProtectPage)
+//
+int
+PML_GiveLRUXMSPage(void)
+{
+	int				i,lru;
+	long			last;
+	PageListStruct	far *page;
+
+	for (i = 0,page = PMPages,lru = -1,last = MAXLONG;i < ChunksInFile;i++,page++)
+	{
+		if
+		(
+			(page->xmsPage != -1)
+		&&	(page->lastHit < last)
+		&&	(i != XMSProtectPage)
+		)
+		{
+			last = page->lastHit;
+			lru = i;
+		}
+	}
+	return(lru);
+}
+
+//
+//	PML_PutPageInXMS() - If page isn't in XMS, find LRU XMS page and replace
+//		it with the main/EMS page
+//
+void
+PML_PutPageInXMS(int pagenum)
+{
+	int				usexms;
+	PageListStruct	far *page;
+
+	if (!XMSPresent)
+		return;
+
+	page = &PMPages[pagenum];
+	if (page->xmsPage != -1)
+		return;					// Already in XMS
+
+	if (XMSPagesUsed < XMSPagesAvail)
+		page->xmsPage = XMSPagesUsed++;
+	else
+	{
+		usexms = PML_GiveLRUXMSPage();
+		if (usexms == -1)
+			Quit("PML_PutPageInXMS: No XMS LRU");
+		page->xmsPage = PMPages[usexms].xmsPage;
+		PMPages[usexms].xmsPage = -1;
+	}
+	PML_CopyToXMS(PM_GetPageAddress(pagenum),page->xmsPage,page->length);
+}
+
+//
+//	PML_TransferPageSpace() - A page is being replaced, so give the new page
+//		the old one's address space. Returns the address of the new page.
+//
+memptr
+PML_TransferPageSpace(int orig,int new)
+{
+	memptr			addr;
+	PageListStruct	far *origpage,far *newpage;
+
+	if (orig == new)
+		Quit("PML_TransferPageSpace: Identity replacement");
+
+	origpage = &PMPages[orig];
+	newpage = &PMPages[new];
+
+	if (origpage->locked != pml_Unlocked)
+		Quit("PML_TransferPageSpace: Killing locked page");
+
+	if ((origpage->emsPage == -1) && (origpage->mainPage == -1))
+		Quit("PML_TransferPageSpace: Reusing non-existent page");
+
+	// Copy page that's about to be purged into XMS
+	PML_PutPageInXMS(orig);
+
+	// Get the address, and force EMS into a physical page if necessary
+	addr = PM_GetPageAddress(orig);
+
+	// Steal the address
+	newpage->emsPage = origpage->emsPage;
+	newpage->mainPage = origpage->mainPage;
+
+	// Mark replaced page as purged
+	origpage->mainPage = origpage->emsPage = -1;
+
+	if (!addr)
+		Quit("PML_TransferPageSpace: Zero replacement");
+
+	return(addr);
+}
+
+//
+//	PML_GetAPageBuffer() - A page buffer is needed. Either get it from the
+//		main/EMS free pool, or use PML_GiveLRUPage() to find which page to
+//		steal the buffer from. Returns a far pointer to the page buffer, and
+//		sets the fields inside the given page structure appropriately.
+//		If mainonly is true, free EMS will be ignored, and only main pages
+//		will be looked at by PML_GiveLRUPage().
+//
+byte far *
+PML_GetAPageBuffer(int pagenum,boolean mainonly)
+{
+	byte			far *addr = nil;
+	int				i,n;
+	PMBlockAttr		*used;
+	PageListStruct	far *page;
+
+	page = &PMPages[pagenum];
+	if ((EMSPagesUsed < EMSPagesAvail) && !mainonly)
+	{
+		// There's remaining EMS - use it
+		page->emsPage = EMSPagesUsed++;
+		addr = PML_GetEMSAddress(page->emsPage,page->locked);
+	}
+	else if (MainPagesUsed < MainPagesAvail)
+	{
+		// There's remaining main memory - use it
+		for (i = 0,n = -1,used = MainMemUsed;i < PMMaxMainMem;i++,used++)
+		{
+			if ((*used & pmba_Allocated) && !(*used & pmba_Used))
+			{
+				n = i;
+				*used |= pmba_Used;
+				break;
+			}
+		}
+		if (n == -1)
+			Quit("PML_GetPageBuffer: MainPagesAvail lied");
+		addr = MainMemPages[n];
+		if (!addr)
+			Quit("PML_GetPageBuffer: Purged main block");
+		page->mainPage = n;
+		MainPagesUsed++;
+	}
+	else
+		addr = PML_TransferPageSpace(PML_GiveLRUPage(mainonly),pagenum);
+
+	if (!addr)
+		Quit("PML_GetPageBuffer: Search failed");
+	return(addr);
+}
+
+//
+//	PML_GetPageFromXMS() - If page is in XMS, find LRU main/EMS page and
+//		replace it with the page from XMS. If mainonly is true, will only
+//		search for LRU main page.
+//	XMSProtectPage is set to the page to be retrieved from XMS, so that if
+//		the page from which we're stealing the main/EMS from isn't in XMS,
+//		it won't copy over the page that we're trying to get from XMS.
+//		(pages that are being purged are copied into XMS, if possible)
+//
+memptr
+PML_GetPageFromXMS(int pagenum,boolean mainonly)
+{
+	byte			far *checkaddr;
+	memptr			addr = nil;
+	PageListStruct	far *page;
+
+	page = &PMPages[pagenum];
+	if (XMSPresent && (page->xmsPage != -1))
+	{
+		XMSProtectPage = pagenum;
+		checkaddr = PML_GetAPageBuffer(pagenum,mainonly);
+		if (FP_OFF(checkaddr))
+			Quit("PML_GetPageFromXMS: Non segment pointer");
+		addr = (memptr)FP_SEG(checkaddr);
+		PML_CopyFromXMS(addr,page->xmsPage,page->length);
+		XMSProtectPage = -1;
+	}
+
+	return(addr);
+}
+
+//
+//	PML_LoadPage() - A page is not in main/EMS memory, and it's not in XMS.
+//		Load it into either main or EMS. If mainonly is true, the page will
+//		only be loaded into main.
+//
+void
+PML_LoadPage(int pagenum,boolean mainonly)
+{
+	byte			far *addr;
+	PageListStruct	far *page;
+
+	addr = PML_GetAPageBuffer(pagenum,mainonly);
+	page = &PMPages[pagenum];
+	PML_ReadFromFile(addr,page->offset,page->length);
+}
+
+//
+//	PM_GetPage() - Returns the address of the page, loading it if necessary
+//		First, check if in Main Memory or EMS
+//		Then, check XMS
+//		If not in XMS, load into Main Memory or EMS
+//
+#pragma warn -pia
+memptr
+PM_GetPage(int pagenum)
+{
+	memptr	result;
+
+	if (pagenum >= ChunksInFile)
+		Quit("PM_GetPage: Invalid page request");
+
+#if 0	// for debugging
+asm	mov	dx,STATUS_REGISTER_1
+asm	in	al,dx
+asm	mov	dx,ATR_INDEX
+asm	mov	al,ATR_OVERSCAN
+asm	out	dx,al
+asm	mov	al,10	// bright green
+asm	out	dx,al
+#endif
+
+	if (!(result = PM_GetPageAddress(pagenum)))
+	{
+		boolean mainonly = (pagenum >= PMSoundStart);
+if (!PMPages[pagenum].offset)	// JDC: sparse page
+	Quit ("Tried to load a sparse page!");
+		if (!(result = PML_GetPageFromXMS(pagenum,mainonly)))
+		{
+			if (PMPages[pagenum].lastHit == PMFrameCount)
+				PMThrashing++;
+
+			PML_LoadPage(pagenum,mainonly);
+			result = PM_GetPageAddress(pagenum);
+		}
+	}
+	PMPages[pagenum].lastHit = PMFrameCount;
+
+#if 0	// for debugging
+asm	mov	dx,STATUS_REGISTER_1
+asm	in	al,dx
+asm	mov	dx,ATR_INDEX
+asm	mov	al,ATR_OVERSCAN
+asm	out	dx,al
+asm	mov	al,3	// blue
+asm	out	dx,al
+asm	mov	al,0x20	// normal
+asm	out	dx,al
+#endif
+
+	return(result);
+}
+#pragma warn +pia
+
+//
+//	PM_SetPageLock() - Sets the lock type on a given page
+//		pml_Unlocked: Normal, page can be purged
+//		pml_Locked: Cannot be purged
+//		pml_EMS?: Same as pml_Locked, but if in EMS, use the physical page
+//					specified when returning the address. For sound stuff.
+//
+void
+PM_SetPageLock(int pagenum,PMLockType lock)
+{
+	if (pagenum < PMSoundStart)
+		Quit("PM_SetPageLock: Locking/unlocking non-sound page");
+
+	PMPages[pagenum].locked = lock;
+}
+
+//
+//	PM_Preload() - Loads as many pages as possible into all types of memory.
+//		Calls the update function after each load, indicating the current
+//		page, and the total pages that need to be loaded (for thermometer).
+//
+void
+PM_Preload(boolean (*update)(word current,word total))
+{
+	int				i,j,
+					page,oogypage;
+	word			current,total,
+					totalnonxms,totalxms,
+					mainfree,maintotal,
+					emsfree,emstotal,
+					xmsfree,xmstotal;
+	memptr			addr;
+	PageListStruct	far *p;
+
+	mainfree = (MainPagesAvail - MainPagesUsed) + (EMSPagesAvail - EMSPagesUsed);
+	xmsfree = (XMSPagesAvail - XMSPagesUsed);
+
+	xmstotal = maintotal = 0;
+
+	for (i = 0;i < ChunksInFile;i++)
+	{
+		if (!PMPages[i].offset)
+			continue;			// sparse
+
+		if ( PMPages[i].emsPage != -1 || PMPages[i].mainPage != -1 )
+			continue;			// already in main mem
+
+		if ( mainfree )
+		{
+			maintotal++;
+			mainfree--;
+		}
+		else if ( xmsfree && (PMPages[i].xmsPage == -1) )
+		{
+			xmstotal++;
+			xmsfree--;
+		}
+	}
+
+
+	total = maintotal + xmstotal;
+
+	if (!total)
+		return;
+
+	page = 0;
+	current = 0;
+
+//
+// cache main/ems blocks
+//
+	while (maintotal)
+	{
+		while ( !PMPages[page].offset || PMPages[page].mainPage != -1
+			||	PMPages[page].emsPage != -1 )
+			page++;
+
+		if (page >= ChunksInFile)
+			Quit ("PM_Preload: Pages>=ChunksInFile");
+
+		PM_GetPage(page);
+
+		page++;
+		current++;
+		maintotal--;
+		update(current,total);
+	}
+
+//
+// load stuff to XMS
+//
+	if (xmstotal)
+	{
+		for (oogypage = 0 ; PMPages[oogypage].mainPage == -1 ; oogypage++)
+		;
+		addr = PM_GetPage(oogypage);
+		if (!addr)
+			Quit("PM_Preload: XMS buffer failed");
+
+		while (xmstotal)
+		{
+			while ( !PMPages[page].offset || PMPages[page].xmsPage != -1 )
+				page++;
+
+			if (page >= ChunksInFile)
+				Quit ("PM_Preload: Pages>=ChunksInFile");
+
+			p = &PMPages[page];
+
+			p->xmsPage = XMSPagesUsed++;
+			if (XMSPagesUsed > XMSPagesAvail)
+				Quit("PM_Preload: Exceeded XMS pages");
+			if (p->length > PMPageSize)
+				Quit("PM_Preload: Page too long");
+
+			PML_ReadFromFile((byte far *)addr,p->offset,p->length);
+			PML_CopyToXMS((byte far *)addr,p->xmsPage,p->length);
+
+			page++;
+			current++;
+			xmstotal--;
+			update(current,total);
+		}
+
+		p = &PMPages[oogypage];
+		PML_ReadFromFile((byte far *)addr,p->offset,p->length);
+	}
+
+	update(total,total);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//	General code
+//
+/////////////////////////////////////////////////////////////////////////////
+
+//
+//	PM_NextFrame() - Increments the frame counter and adjusts the thrash
+//		avoidence variables
+//
+//		If currently in panic mode (to avoid thrashing), check to see if the
+//			appropriate number of frames have passed since the last time that
+//			we would have thrashed. If so, take us out of panic mode.
+//
+//
+void
+PM_NextFrame(void)
+{
+	int	i;
+
+	// Frame count overrun - kill the LRU hit entries & reset frame count
+	if (++PMFrameCount >= MAXLONG - 4)
+	{
+		for (i = 0;i < PMNumBlocks;i++)
+			PMPages[i].lastHit = 0;
+		PMFrameCount = 0;
+	}
+
+#if 0
+	for (i = 0;i < PMSoundStart;i++)
+	{
+		if (PMPages[i].locked)
+		{
+			char buf[40];
+			sprintf(buf,"PM_NextFrame: Page %d is locked",i);
+			Quit(buf);
+		}
+	}
+#endif
+
+	if (PMPanicMode)
+	{
+		// DEBUG - set border color
+		if ((!PMThrashing) && (!--PMPanicMode))
+		{
+			// DEBUG - reset border color
+		}
+	}
+	if (PMThrashing >= PMThrashThreshold)
+		PMPanicMode = PMUnThrashThreshold;
+	PMThrashing = false;
+}
+
+//
+//	PM_Reset() - Sets up caching structures
+//
+void
+PM_Reset(void)
+{
+	int				i;
+	PageListStruct	far *page;
+
+	XMSPagesAvail = XMSAvail / PMPageSizeKB;
+
+	EMSPagesAvail = EMSAvail * (EMSPageSizeKB / PMPageSizeKB);
+	EMSPhysicalPage = 0;
+
+	MainPagesUsed = EMSPagesUsed = XMSPagesUsed = 0;
+
+	PMPanicMode = false;
+
+	// Initialize page list
+	for (i = 0,page = PMPages;i < PMNumBlocks;i++,page++)
+	{
+		page->mainPage = -1;
+		page->emsPage = -1;
+		page->xmsPage = -1;
+		page->locked = false;
+	}
+}
+
+//
+//	PM_Startup() - Start up the Page Mgr
+//
+void
+PM_Startup(void)
+{
+	boolean	nomain,noems,noxms;
+	int		i;
+
+	if (PMStarted)
+		return;
+
+	nomain = noems = noxms = false;
+	for (i = 1;i < _argc;i++)
+	{
+		switch (US_CheckParm(_argv[i],ParmStrings))
+		{
+		case 0:
+			nomain = true;
+			break;
+		case 1:
+			noems = true;
+			break;
+		case 2:
+			noxms = true;
+			break;
+		}
+	}
+
+	PML_OpenPageFile();
+
+	if (!noems)
+		PML_StartupEMS();
+	if (!noxms)
+		PML_StartupXMS();
+
+	if (nomain && !EMSPresent)
+		Quit("PM_Startup: No main or EMS");
+	else
+		PML_StartupMainMem();
+
+	PM_Reset();
+
+	PMStarted = true;
+}
+
+//
+//	PM_Shutdown() - Shut down the Page Mgr
+//
+void
+PM_Shutdown(void)
+{
+	PML_ShutdownXMS();
+	PML_ShutdownEMS();
+
+	if (!PMStarted)
+		return;
+
+	PML_ClosePageFile();
+
+	PML_ShutdownMainMem();
+}
--- /dev/null
+++ b/WOLFSRC/ID_PM.H
@@ -1,0 +1,83 @@
+//
+//	ID_PM.H
+//	Header file for Id Engine's Page Manager
+//
+
+//	NOTE! PMPageSize must be an even divisor of EMSPageSize, and >= 1024
+#define	EMSPageSize		16384
+#define	EMSPageSizeSeg	(EMSPageSize >> 4)
+#define	EMSPageSizeKB	(EMSPageSize >> 10)
+#define	EMSFrameCount	4
+#define	PMPageSize		4096
+#define	PMPageSizeSeg	(PMPageSize >> 4)
+#define	PMPageSizeKB	(PMPageSize >> 10)
+#define	PMEMSSubPage	(EMSPageSize / PMPageSize)
+
+#define	PMMinMainMem	10			// Min acceptable # of pages from main
+#define	PMMaxMainMem	100			// Max number of pages in main memory
+
+#define	PMThrashThreshold	1	// Number of page thrashes before panic mode
+#define	PMUnThrashThreshold	5	// Number of non-thrashing frames before leaving panic mode
+
+typedef	enum
+		{
+			pml_Unlocked,
+			pml_Locked
+		} PMLockType;
+
+typedef	enum
+		{
+			pmba_Unused = 0,
+			pmba_Used = 1,
+			pmba_Allocated = 2
+		} PMBlockAttr;
+
+typedef	struct
+		{
+			longword	offset;		// Offset of chunk into file
+			word		length;		// Length of the chunk
+
+			int			xmsPage;	// If in XMS, (xmsPage * PMPageSize) gives offset into XMS handle
+
+			PMLockType	locked;		// If set, this page can't be purged
+			int			emsPage;	// If in EMS, logical page/offset into page
+			int			mainPage;	// If in Main, index into handle array
+
+			longword	lastHit;	// Last frame number of hit
+		} PageListStruct;
+
+typedef	struct
+		{
+			int			baseEMSPage;	// Base EMS page for this phys frame
+			longword	lastHit;		// Last frame number of hit
+		} EMSListStruct;
+
+extern	boolean			XMSPresent,EMSPresent;
+extern	word			XMSPagesAvail,EMSPagesAvail;
+
+extern	word			ChunksInFile,
+						PMSpriteStart,PMSoundStart;
+extern	PageListStruct	far *PMPages;
+
+#define	PM_GetSoundPage(v)	PM_GetPage(PMSoundStart + (v))
+#define	PM_GetSpritePage(v)	PM_GetPage(PMSpriteStart + (v))
+
+#define	PM_LockMainMem()	PM_SetMainMemPurge(0)
+#define	PM_UnlockMainMem()	PM_SetMainMemPurge(3)
+
+
+extern	char	PageFileName[13];
+
+
+extern	void	PM_Startup(void),
+				PM_Shutdown(void),
+				PM_Reset(void),
+				PM_Preload(boolean (*update)(word current,word total)),
+				PM_NextFrame(void),
+				PM_SetPageLock(int pagenum,PMLockType lock),
+				PM_SetMainPurge(int level),
+				PM_CheckMainMem(void);
+extern	memptr	PM_GetPageAddress(int pagenum),
+				PM_GetPage(int pagenum);		// Use this one to cache page
+
+void PM_SetMainMemPurge(int level);
--- /dev/null
+++ b/WOLFSRC/ID_SD.C
@@ -1,0 +1,2367 @@
+//
+//	ID Engine
+//	ID_SD.c - Sound Manager for Wolfenstein 3D
+//	v1.2
+//	By Jason Blochowiak
+//
+
+//
+//	This module handles dealing with generating sound on the appropriate
+//		hardware
+//
+//	Depends on: User Mgr (for parm checking)
+//
+//	Globals:
+//		For User Mgr:
+//			SoundSourcePresent - Sound Source thingie present?
+//			SoundBlasterPresent - SoundBlaster card present?
+//			AdLibPresent - AdLib card present?
+//			SoundMode - What device is used for sound effects
+//				(Use SM_SetSoundMode() to set)
+//			MusicMode - What device is used for music
+//				(Use SM_SetMusicMode() to set)
+//			DigiMode - What device is used for digitized sound effects
+//				(Use SM_SetDigiDevice() to set)
+//
+//		For Cache Mgr:
+//			NeedsDigitized - load digitized sounds?
+//			NeedsMusic - load music?
+//
+
+#pragma hdrstop		// Wierdo thing with MUSE
+
+#include <dos.h>
+
+#ifdef	_MUSE_      // Will be defined in ID_Types.h
+#include "ID_SD.h"
+#else
+#include "ID_HEADS.H"
+#endif
+#pragma	hdrstop
+#pragma	warn	-pia
+
+#ifdef	nil
+#undef	nil
+#endif
+#define	nil	0
+
+#define	SDL_SoundFinished()	{SoundNumber = SoundPriority = 0;}
+
+// Macros for SoundBlaster stuff
+#define	sbOut(n,b)	outportb((n) + sbLocation,b)
+#define	sbIn(n)		inportb((n) + sbLocation)
+#define	sbWriteDelay()	while (sbIn(sbWriteStat) & 0x80);
+#define	sbReadDelay()	while (sbIn(sbDataAvail) & 0x80);
+
+// Macros for AdLib stuff
+#define	selreg(n)	outportb(alFMAddr,n)
+#define	writereg(n)	outportb(alFMData,n)
+#define	readstat()	inportb(alFMStatus)
+
+//	Imports from ID_SD_A.ASM
+extern	void			SDL_SetDS(void),
+						SDL_IndicatePC(boolean on);
+extern	void interrupt	SDL_t0ExtremeAsmService(void),
+						SDL_t0FastAsmService(void),
+						SDL_t0SlowAsmService(void);
+
+//	Global variables
+	boolean		SoundSourcePresent,
+				AdLibPresent,
+				SoundBlasterPresent,SBProPresent,
+				NeedsDigitized,NeedsMusic,
+				SoundPositioned;
+	SDMode		SoundMode;
+	SMMode		MusicMode;
+	SDSMode		DigiMode;
+	longword	TimeCount;
+	word		HackCount;
+	word		*SoundTable;	// Really * _seg *SoundTable, but that don't work
+	boolean		ssIsTandy;
+	word		ssPort = 2;
+	int			DigiMap[LASTSOUND];
+
+//	Internal variables
+static	boolean			SD_Started;
+		boolean			nextsoundpos;
+		longword		TimerDivisor,TimerCount;
+static	char			*ParmStrings[] =
+						{
+							"noal",
+							"nosb",
+							"nopro",
+							"noss",
+							"sst",
+							"ss1",
+							"ss2",
+							"ss3",
+							nil
+						};
+static	void			(*SoundUserHook)(void);
+		soundnames		SoundNumber,DigiNumber;
+		word			SoundPriority,DigiPriority;
+		int				LeftPosition,RightPosition;
+		void interrupt	(*t0OldService)(void);
+		long			LocalTime;
+		word			TimerRate;
+
+		word			NumDigi,DigiLeft,DigiPage;
+		word			_seg *DigiList;
+		word			DigiLastStart,DigiLastEnd;
+		boolean			DigiPlaying;
+static	boolean			DigiMissed,DigiLastSegment;
+static	memptr			DigiNextAddr;
+static	word			DigiNextLen;
+
+//	SoundBlaster variables
+static	boolean					sbNoCheck,sbNoProCheck;
+static	volatile boolean		sbSamplePlaying;
+static	byte					sbOldIntMask = -1;
+static	volatile byte			huge *sbNextSegPtr;
+static	byte					sbDMA = 1,
+								sbDMAa1 = 0x83,sbDMAa2 = 2,sbDMAa3 = 3,
+								sba1Vals[] = {0x87,0x83,0,0x82},
+								sba2Vals[] = {0,2,0,6},
+								sba3Vals[] = {1,3,0,7};
+static	int						sbLocation = -1,sbInterrupt = 7,sbIntVec = 0xf,
+								sbIntVectors[] = {-1,-1,0xa,0xb,-1,0xd,-1,0xf,-1,-1,-1};
+static	volatile longword		sbNextSegLen;
+static	volatile SampledSound	huge *sbSamples;
+static	void interrupt			(*sbOldIntHand)(void);
+static	byte					sbpOldFMMix,sbpOldVOCMix;
+
+//	SoundSource variables
+		boolean				ssNoCheck;
+		boolean				ssActive;
+		word				ssControl,ssStatus,ssData;
+		byte				ssOn,ssOff;
+		volatile byte		far *ssSample;
+		volatile longword	ssLengthLeft;
+
+//	PC Sound variables
+		volatile byte	pcLastSample,far *pcSound;
+		longword		pcLengthLeft;
+		word			pcSoundLookup[255];
+
+//	AdLib variables
+		boolean			alNoCheck;
+		byte			far *alSound;
+		word			alBlock;
+		longword		alLengthLeft;
+		longword		alTimeCount;
+		Instrument		alZeroInst;
+
+// This table maps channel numbers to carrier and modulator op cells
+static	byte			carriers[9] =  { 3, 4, 5,11,12,13,19,20,21},
+						modifiers[9] = { 0, 1, 2, 8, 9,10,16,17,18},
+// This table maps percussive voice numbers to op cells
+						pcarriers[5] = {19,0xff,0xff,0xff,0xff},
+						pmodifiers[5] = {16,17,18,20,21};
+
+//	Sequencer variables
+		boolean			sqActive;
+static	word			alFXReg;
+static	ActiveTrack		*tracks[sqMaxTracks],
+						mytracks[sqMaxTracks];
+static	word			sqMode,sqFadeStep;
+		word			far *sqHack,far *sqHackPtr,sqHackLen,sqHackSeqLen;
+		long			sqHackTime;
+
+//	Internal routines
+		void			SDL_DigitizedDone(void);
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SetTimer0() - Sets system timer 0 to the specified speed
+//
+///////////////////////////////////////////////////////////////////////////
+#pragma	argsused
+static void
+SDL_SetTimer0(word speed)
+{
+#ifndef TPROF	// If using Borland's profiling, don't screw with the timer
+asm	pushf
+asm	cli
+
+	outportb(0x43,0x36);				// Change timer 0
+	outportb(0x40,speed);
+	outportb(0x40,speed >> 8);
+	// Kludge to handle special case for digitized PC sounds
+	if (TimerDivisor == (1192030 / (TickBase * 100)))
+		TimerDivisor = (1192030 / (TickBase * 10));
+	else
+		TimerDivisor = speed;
+
+asm	popf
+#else
+	TimerDivisor = 0x10000;
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SetIntsPerSec() - Uses SDL_SetTimer0() to set the number of
+//		interrupts generated by system timer 0 per second
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_SetIntsPerSec(word ints)
+{
+	TimerRate = ints;
+	SDL_SetTimer0(1192030 / ints);
+}
+
+static void
+SDL_SetTimerSpeed(void)
+{
+	word	rate;
+	void interrupt	(*isr)(void);
+
+	if ((DigiMode == sds_PC) && DigiPlaying)
+	{
+		rate = TickBase * 100;
+		isr = SDL_t0ExtremeAsmService;
+	}
+	else if
+	(
+		(MusicMode == smm_AdLib)
+	||	((DigiMode == sds_SoundSource) && DigiPlaying)
+	)
+	{
+		rate = TickBase * 10;
+		isr = SDL_t0FastAsmService;
+	}
+	else
+	{
+		rate = TickBase * 2;
+		isr = SDL_t0SlowAsmService;
+	}
+
+	if (rate != TimerRate)
+	{
+		setvect(8,isr);
+		SDL_SetIntsPerSec(rate);
+		TimerRate = rate;
+	}
+}
+
+//
+//	SoundBlaster code
+//
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SBStopSample() - Stops any active sampled sound and causes DMA
+//		requests from the SoundBlaster to cease
+//
+///////////////////////////////////////////////////////////////////////////
+#ifdef	_MUSE_
+void
+#else
+static void
+#endif
+SDL_SBStopSample(void)
+{
+	byte	is;
+
+asm	pushf
+asm	cli
+
+	if (sbSamplePlaying)
+	{
+		sbSamplePlaying = false;
+
+		sbWriteDelay();
+		sbOut(sbWriteCmd,0xd0);	// Turn off DSP DMA
+
+		is = inportb(0x21);	// Restore interrupt mask bit
+		if (sbOldIntMask & (1 << sbInterrupt))
+			is |= (1 << sbInterrupt);
+		else
+			is &= ~(1 << sbInterrupt);
+		outportb(0x21,is);
+	}
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SBPlaySeg() - Plays a chunk of sampled sound on the SoundBlaster
+//	Insures that the chunk doesn't cross a bank boundary, programs the DMA
+//	 controller, and tells the SB to start doing DMA requests for DAC
+//
+///////////////////////////////////////////////////////////////////////////
+static longword
+SDL_SBPlaySeg(volatile byte huge *data,longword length)
+{
+	unsigned		datapage;
+	longword		dataofs,uselen;
+
+	uselen = length;
+	datapage = FP_SEG(data) >> 12;
+	dataofs = ((FP_SEG(data) & 0xfff) << 4) + FP_OFF(data);
+	if (dataofs >= 0x10000)
+	{
+		datapage++;
+		dataofs -= 0x10000;
+	}
+
+	if (dataofs + uselen > 0x10000)
+		uselen = 0x10000 - dataofs;
+
+	uselen--;
+
+	// Program the DMA controller
+asm	pushf
+asm	cli
+	outportb(0x0a,sbDMA | 4);					// Mask off DMA on channel sbDMA
+	outportb(0x0c,0);							// Clear byte ptr flip-flop to lower byte
+	outportb(0x0b,0x49);						// Set transfer mode for D/A conv
+	outportb(sbDMAa2,(byte)dataofs);			// Give LSB of address
+	outportb(sbDMAa2,(byte)(dataofs >> 8));		// Give MSB of address
+	outportb(sbDMAa1,(byte)datapage);			// Give page of address
+	outportb(sbDMAa3,(byte)uselen);				// Give LSB of length
+	outportb(sbDMAa3,(byte)(uselen >> 8));		// Give MSB of length
+	outportb(0x0a,sbDMA);						// Re-enable DMA on channel sbDMA
+
+	// Start playing the thing
+	sbWriteDelay();
+	sbOut(sbWriteCmd,0x14);
+	sbWriteDelay();
+	sbOut(sbWriteData,(byte)uselen);
+	sbWriteDelay();
+	sbOut(sbWriteData,(byte)(uselen >> 8));
+asm	popf
+
+	return(uselen + 1);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SBService() - Services the SoundBlaster DMA interrupt
+//
+///////////////////////////////////////////////////////////////////////////
+static void interrupt
+SDL_SBService(void)
+{
+	longword	used;
+
+	sbIn(sbDataAvail);	// Ack interrupt to SB
+
+	if (sbNextSegPtr)
+	{
+		used = SDL_SBPlaySeg(sbNextSegPtr,sbNextSegLen);
+		if (sbNextSegLen <= used)
+			sbNextSegPtr = nil;
+		else
+		{
+			sbNextSegPtr += used;
+			sbNextSegLen -= used;
+		}
+	}
+	else
+	{
+		SDL_SBStopSample();
+		SDL_DigitizedDone();
+	}
+
+	outportb(0x20,0x20);	// Ack interrupt
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SBPlaySample() - Plays a sampled sound on the SoundBlaster. Sets up
+//		DMA to play the sound
+//
+///////////////////////////////////////////////////////////////////////////
+#ifdef	_MUSE_
+void
+#else
+static void
+#endif
+SDL_SBPlaySample(byte huge *data,longword len)
+{
+	longword	used;
+
+	SDL_SBStopSample();
+
+asm	pushf
+asm	cli
+
+	used = SDL_SBPlaySeg(data,len);
+	if (len <= used)
+		sbNextSegPtr = nil;
+	else
+	{
+		sbNextSegPtr = data + used;
+		sbNextSegLen = len - used;
+	}
+
+	// Save old interrupt status and unmask ours
+	sbOldIntMask = inportb(0x21);
+	outportb(0x21,sbOldIntMask & ~(1 << sbInterrupt));
+
+	sbWriteDelay();
+	sbOut(sbWriteCmd,0xd4);						// Make sure DSP DMA is enabled
+
+	sbSamplePlaying = true;
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_PositionSBP() - Sets the attenuation levels for the left and right
+//		channels by using the mixer chip on the SB Pro. This hits a hole in
+//		the address map for normal SBs.
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_PositionSBP(int leftpos,int rightpos)
+{
+	byte	v;
+
+	if (!SBProPresent)
+		return;
+
+	leftpos = 15 - leftpos;
+	rightpos = 15 - rightpos;
+	v = ((leftpos & 0x0f) << 4) | (rightpos & 0x0f);
+
+asm	pushf
+asm	cli
+
+	sbOut(sbpMixerAddr,sbpmVoiceVol);
+	sbOut(sbpMixerData,v);
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_CheckSB() - Checks to see if a SoundBlaster resides at a
+//		particular I/O location
+//
+///////////////////////////////////////////////////////////////////////////
+static boolean
+SDL_CheckSB(int port)
+{
+	int	i;
+
+	sbLocation = port << 4;		// Initialize stuff for later use
+
+	sbOut(sbReset,true);		// Reset the SoundBlaster DSP
+asm	mov	dx,0x388				// Wait >4usec
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+asm	in	al, dx
+
+	sbOut(sbReset,false);		// Turn off sb DSP reset
+asm	mov	dx,0x388				// Wait >100usec
+asm	mov	cx,100
+usecloop:
+asm	in	al,dx
+asm	loop usecloop
+
+	for (i = 0;i < 100;i++)
+	{
+		if (sbIn(sbDataAvail) & 0x80)		// If data is available...
+		{
+			if (sbIn(sbReadData) == 0xaa)	// If it matches correct value
+				return(true);
+			else
+			{
+				sbLocation = -1;			// Otherwise not a SoundBlaster
+				return(false);
+			}
+		}
+	}
+	sbLocation = -1;						// Retry count exceeded - fail
+	return(false);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	Checks to see if a SoundBlaster is in the system. If the port passed is
+//		-1, then it scans through all possible I/O locations. If the port
+//		passed is 0, then it uses the default (2). If the port is >0, then
+//		it just passes it directly to SDL_CheckSB()
+//
+///////////////////////////////////////////////////////////////////////////
+static boolean
+SDL_DetectSoundBlaster(int port)
+{
+	int	i;
+
+	if (port == 0)					// If user specifies default, use 2
+		port = 2;
+	if (port == -1)
+	{
+		if (SDL_CheckSB(2))			// Check default before scanning
+			return(true);
+
+		if (SDL_CheckSB(4))			// Check other SB Pro location before scan
+			return(true);
+
+		for (i = 1;i <= 6;i++)		// Scan through possible SB locations
+		{
+			if ((i == 2) || (i == 4))
+				continue;
+
+			if (SDL_CheckSB(i))		// If found at this address,
+				return(true);		//	return success
+		}
+		return(false);				// All addresses failed, return failure
+	}
+	else
+		return(SDL_CheckSB(port));	// User specified address or default
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SBSetDMA() - Sets the DMA channel to be used by the SoundBlaster
+//		code. Sets up sbDMA, and sbDMAa1-sbDMAa3 (used by SDL_SBPlaySeg()).
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SDL_SBSetDMA(byte channel)
+{
+	if (channel > 3)
+		Quit("SDL_SBSetDMA() - invalid SoundBlaster DMA channel");
+
+	sbDMA = channel;
+	sbDMAa1 = sba1Vals[channel];
+	sbDMAa2 = sba2Vals[channel];
+	sbDMAa3 = sba3Vals[channel];
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_StartSB() - Turns on the SoundBlaster
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_StartSB(void)
+{
+	byte	timevalue,test;
+
+	sbIntVec = sbIntVectors[sbInterrupt];
+	if (sbIntVec < 0)
+		Quit("SDL_StartSB: Illegal or unsupported interrupt number for SoundBlaster");
+
+	sbOldIntHand = getvect(sbIntVec);	// Get old interrupt handler
+	setvect(sbIntVec,SDL_SBService);	// Set mine
+
+	sbWriteDelay();
+	sbOut(sbWriteCmd,0xd1);				// Turn on DSP speaker
+
+	// Set the SoundBlaster DAC time constant for 7KHz
+	timevalue = 256 - (1000000 / 7000);
+	sbWriteDelay();
+	sbOut(sbWriteCmd,0x40);
+	sbWriteDelay();
+	sbOut(sbWriteData,timevalue);
+
+	SBProPresent = false;
+	if (sbNoProCheck)
+		return;
+
+	// Check to see if this is a SB Pro
+	sbOut(sbpMixerAddr,sbpmFMVol);
+	sbpOldFMMix = sbIn(sbpMixerData);
+	sbOut(sbpMixerData,0xbb);
+	test = sbIn(sbpMixerData);
+	if (test == 0xbb)
+	{
+		// Boost FM output levels to be equivilent with digitized output
+		sbOut(sbpMixerData,0xff);
+		test = sbIn(sbpMixerData);
+		if (test == 0xff)
+		{
+			SBProPresent = true;
+
+			// Save old Voice output levels (SB Pro)
+			sbOut(sbpMixerAddr,sbpmVoiceVol);
+			sbpOldVOCMix = sbIn(sbpMixerData);
+
+			// Turn SB Pro stereo DAC off
+			sbOut(sbpMixerAddr,sbpmControl);
+			sbOut(sbpMixerData,0);				// 0=off,2=on
+		}
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_ShutSB() - Turns off the SoundBlaster
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_ShutSB(void)
+{
+	SDL_SBStopSample();
+
+	if (SBProPresent)
+	{
+		// Restore FM output levels (SB Pro)
+		sbOut(sbpMixerAddr,sbpmFMVol);
+		sbOut(sbpMixerData,sbpOldFMMix);
+
+		// Restore Voice output levels (SB Pro)
+		sbOut(sbpMixerAddr,sbpmVoiceVol);
+		sbOut(sbpMixerData,sbpOldVOCMix);
+	}
+
+	setvect(sbIntVec,sbOldIntHand);		// Set vector back
+}
+
+//	Sound Source Code
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SSStopSample() - Stops a sample playing on the Sound Source
+//
+///////////////////////////////////////////////////////////////////////////
+#ifdef	_MUSE_
+void
+#else
+static void
+#endif
+SDL_SSStopSample(void)
+{
+asm	pushf
+asm	cli
+
+	(long)ssSample = 0;
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SSService() - Handles playing the next sample on the Sound Source
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_SSService(void)
+{
+	boolean	gotit;
+	byte	v;
+
+	while (ssSample)
+	{
+	asm	mov		dx,[ssStatus]	// Check to see if FIFO is currently empty
+	asm	in		al,dx
+	asm	test	al,0x40
+	asm	jnz		done			// Nope - don't push any more data out
+
+		v = *ssSample++;
+		if (!(--ssLengthLeft))
+		{
+			(long)ssSample = 0;
+			SDL_DigitizedDone();
+		}
+
+	asm	mov		dx,[ssData]		// Pump the value out
+	asm	mov		al,[v]
+	asm	out		dx,al
+
+	asm	mov		dx,[ssControl]	// Pulse printer select
+	asm	mov		al,[ssOff]
+	asm	out		dx,al
+	asm	push	ax
+	asm	pop		ax
+	asm	mov		al,[ssOn]
+	asm	out		dx,al
+
+	asm	push	ax				// Delay a short while
+	asm	pop		ax
+	asm	push	ax
+	asm	pop		ax
+	}
+done:;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SSPlaySample() - Plays the specified sample on the Sound Source
+//
+///////////////////////////////////////////////////////////////////////////
+#ifdef	_MUSE_
+void
+#else
+static void
+#endif
+SDL_SSPlaySample(byte huge *data,longword len)
+{
+asm	pushf
+asm	cli
+
+	ssLengthLeft = len;
+	ssSample = (volatile byte far *)data;
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_StartSS() - Sets up for and turns on the Sound Source
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_StartSS(void)
+{
+	if (ssPort == 3)
+		ssControl = 0x27a;	// If using LPT3
+	else if (ssPort == 2)
+		ssControl = 0x37a;	// If using LPT2
+	else
+		ssControl = 0x3be;	// If using LPT1
+	ssStatus = ssControl - 1;
+	ssData = ssStatus - 1;
+
+	ssOn = 0x04;
+	if (ssIsTandy)
+		ssOff = 0x0e;				// Tandy wierdness
+	else
+		ssOff = 0x0c;				// For normal machines
+
+	outportb(ssControl,ssOn);		// Enable SS
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_ShutSS() - Turns off the Sound Source
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_ShutSS(void)
+{
+	outportb(ssControl,ssOff);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_CheckSS() - Checks to see if a Sound Source is present at the
+//		location specified by the sound source variables
+//
+///////////////////////////////////////////////////////////////////////////
+static boolean
+SDL_CheckSS(void)
+{
+	boolean		present = false;
+	longword	lasttime;
+
+	// Turn the Sound Source on and wait awhile (4 ticks)
+	SDL_StartSS();
+
+	lasttime = TimeCount;
+	while (TimeCount < lasttime + 4)
+		;
+
+asm	mov		dx,[ssStatus]	// Check to see if FIFO is currently empty
+asm	in		al,dx
+asm	test	al,0x40
+asm	jnz		checkdone		// Nope - Sound Source not here
+
+asm	mov		cx,32			// Force FIFO overflow (FIFO is 16 bytes)
+outloop:
+asm	mov		dx,[ssData]		// Pump a neutral value out
+asm	mov		al,0x80
+asm	out		dx,al
+
+asm	mov		dx,[ssControl]	// Pulse printer select
+asm	mov		al,[ssOff]
+asm	out		dx,al
+asm	push	ax
+asm	pop		ax
+asm	mov		al,[ssOn]
+asm	out		dx,al
+
+asm	push	ax				// Delay a short while before we do this again
+asm	pop		ax
+asm	push	ax
+asm	pop		ax
+
+asm	loop	outloop
+
+asm	mov		dx,[ssStatus]	// Is FIFO overflowed now?
+asm	in		al,dx
+asm	test	al,0x40
+asm	jz		checkdone		// Nope, still not - Sound Source not here
+
+	present = true;			// Yes - it's here!
+
+checkdone:
+	SDL_ShutSS();
+	return(present);
+}
+
+static boolean
+SDL_DetectSoundSource(void)
+{
+	for (ssPort = 1;ssPort <= 3;ssPort++)
+		if (SDL_CheckSS())
+			return(true);
+	return(false);
+}
+
+//
+//	PC Sound code
+//
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_PCPlaySample() - Plays the specified sample on the PC speaker
+//
+///////////////////////////////////////////////////////////////////////////
+#ifdef	_MUSE_
+void
+#else
+static void
+#endif
+SDL_PCPlaySample(byte huge *data,longword len)
+{
+asm	pushf
+asm	cli
+
+	SDL_IndicatePC(true);
+
+	pcLengthLeft = len;
+	pcSound = (volatile byte far *)data;
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_PCStopSample() - Stops a sample playing on the PC speaker
+//
+///////////////////////////////////////////////////////////////////////////
+#ifdef	_MUSE_
+void
+#else
+static void
+#endif
+SDL_PCStopSample(void)
+{
+asm	pushf
+asm	cli
+
+	(long)pcSound = 0;
+
+	SDL_IndicatePC(false);
+
+asm	in	al,0x61		  	// Turn the speaker off
+asm	and	al,0xfd			// ~2
+asm	out	0x61,al
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_PCPlaySound() - Plays the specified sound on the PC speaker
+//
+///////////////////////////////////////////////////////////////////////////
+#ifdef	_MUSE_
+void
+#else
+static void
+#endif
+SDL_PCPlaySound(PCSound far *sound)
+{
+asm	pushf
+asm	cli
+
+	pcLastSample = -1;
+	pcLengthLeft = sound->common.length;
+	pcSound = sound->data;
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_PCStopSound() - Stops the current sound playing on the PC Speaker
+//
+///////////////////////////////////////////////////////////////////////////
+#ifdef	_MUSE_
+void
+#else
+static void
+#endif
+SDL_PCStopSound(void)
+{
+asm	pushf
+asm	cli
+
+	(long)pcSound = 0;
+
+asm	in	al,0x61		  	// Turn the speaker off
+asm	and	al,0xfd			// ~2
+asm	out	0x61,al
+
+asm	popf
+}
+
+#if 0
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_PCService() - Handles playing the next sample in a PC sound
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_PCService(void)
+{
+	byte	s;
+	word	t;
+
+	if (pcSound)
+	{
+		s = *pcSound++;
+		if (s != pcLastSample)
+		{
+		asm	pushf
+		asm	cli
+
+			pcLastSample = s;
+			if (s)					// We have a frequency!
+			{
+				t = pcSoundLookup[s];
+			asm	mov	bx,[t]
+
+			asm	mov	al,0xb6			// Write to channel 2 (speaker) timer
+			asm	out	43h,al
+			asm	mov	al,bl
+			asm	out	42h,al			// Low byte
+			asm	mov	al,bh
+			asm	out	42h,al			// High byte
+
+			asm	in	al,0x61			// Turn the speaker & gate on
+			asm	or	al,3
+			asm	out	0x61,al
+			}
+			else					// Time for some silence
+			{
+			asm	in	al,0x61		  	// Turn the speaker & gate off
+			asm	and	al,0xfc			// ~3
+			asm	out	0x61,al
+			}
+
+		asm	popf
+		}
+
+		if (!(--pcLengthLeft))
+		{
+			SDL_PCStopSound();
+			SDL_SoundFinished();
+		}
+	}
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_ShutPC() - Turns off the pc speaker
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_ShutPC(void)
+{
+asm	pushf
+asm	cli
+
+	pcSound = 0;
+
+asm	in	al,0x61		  	// Turn the speaker & gate off
+asm	and	al,0xfc			// ~3
+asm	out	0x61,al
+
+asm	popf
+}
+
+//
+//	Stuff for digitized sounds
+//
+memptr
+SDL_LoadDigiSegment(word page)
+{
+	memptr	addr;
+
+#if 0	// for debugging
+asm	mov	dx,STATUS_REGISTER_1
+asm	in	al,dx
+asm	mov	dx,ATR_INDEX
+asm	mov	al,ATR_OVERSCAN
+asm	out	dx,al
+asm	mov	al,10	// bright green
+asm	out	dx,al
+#endif
+
+	addr = PM_GetSoundPage(page);
+	PM_SetPageLock(PMSoundStart + page,pml_Locked);
+
+#if 0	// for debugging
+asm	mov	dx,STATUS_REGISTER_1
+asm	in	al,dx
+asm	mov	dx,ATR_INDEX
+asm	mov	al,ATR_OVERSCAN
+asm	out	dx,al
+asm	mov	al,3	// blue
+asm	out	dx,al
+asm	mov	al,0x20	// normal
+asm	out	dx,al
+#endif
+
+	return(addr);
+}
+
+void
+SDL_PlayDigiSegment(memptr addr,word len)
+{
+	switch (DigiMode)
+	{
+	case sds_PC:
+    	SDL_PCPlaySample(addr,len);
+		break;
+	case sds_SoundSource:
+		SDL_SSPlaySample(addr,len);
+		break;
+	case sds_SoundBlaster:
+		SDL_SBPlaySample(addr,len);
+		break;
+	}
+}
+
+void
+SD_StopDigitized(void)
+{
+	int	i;
+
+asm	pushf
+asm	cli
+
+	DigiLeft = 0;
+	DigiNextAddr = nil;
+	DigiNextLen = 0;
+	DigiMissed = false;
+	DigiPlaying = false;
+	DigiNumber = DigiPriority = 0;
+	SoundPositioned = false;
+	if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))
+		SDL_SoundFinished();
+
+	switch (DigiMode)
+	{
+	case sds_PC:
+		SDL_PCStopSample();
+		break;
+	case sds_SoundSource:
+		SDL_SSStopSample();
+		break;
+	case sds_SoundBlaster:
+		SDL_SBStopSample();
+		break;
+	}
+
+asm	popf
+
+	for (i = DigiLastStart;i < DigiLastEnd;i++)
+		PM_SetPageLock(i + PMSoundStart,pml_Unlocked);
+	DigiLastStart = 1;
+	DigiLastEnd = 0;
+}
+
+void
+SD_Poll(void)
+{
+	if (DigiLeft && !DigiNextAddr)
+	{
+		DigiNextLen = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);
+		DigiLeft -= DigiNextLen;
+		if (!DigiLeft)
+			DigiLastSegment = true;
+		DigiNextAddr = SDL_LoadDigiSegment(DigiPage++);
+	}
+	if (DigiMissed && DigiNextAddr)
+	{
+		SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);
+		DigiNextAddr = nil;
+		DigiMissed = false;
+		if (DigiLastSegment)
+		{
+			DigiPlaying = false;
+			DigiLastSegment = false;
+		}
+	}
+	SDL_SetTimerSpeed();
+}
+
+void
+SD_SetPosition(int leftpos,int rightpos)
+{
+	if
+	(
+		(leftpos < 0)
+	||	(leftpos > 15)
+	||	(rightpos < 0)
+	||	(rightpos > 15)
+	||	((leftpos == 15) && (rightpos == 15))
+	)
+		Quit("SD_SetPosition: Illegal position");
+
+	switch (DigiMode)
+	{
+	case sds_SoundBlaster:
+		SDL_PositionSBP(leftpos,rightpos);
+		break;
+	}
+}
+
+void
+SD_PlayDigitized(word which,int leftpos,int rightpos)
+{
+	word	len;
+	memptr	addr;
+
+	if (!DigiMode)
+		return;
+
+	SD_StopDigitized();
+	if (which >= NumDigi)
+		Quit("SD_PlayDigitized: bad sound number");
+
+	SD_SetPosition(leftpos,rightpos);
+
+	DigiPage = DigiList[(which * 2) + 0];
+	DigiLeft = DigiList[(which * 2) + 1];
+
+	DigiLastStart = DigiPage;
+	DigiLastEnd = DigiPage + ((DigiLeft + (PMPageSize - 1)) / PMPageSize);
+
+	len = (DigiLeft >= PMPageSize)? PMPageSize : (DigiLeft % PMPageSize);
+	addr = SDL_LoadDigiSegment(DigiPage++);
+
+	DigiPlaying = true;
+	DigiLastSegment = false;
+
+	SDL_PlayDigiSegment(addr,len);
+	DigiLeft -= len;
+	if (!DigiLeft)
+		DigiLastSegment = true;
+
+	SD_Poll();
+}
+
+void
+SDL_DigitizedDone(void)
+{
+	if (DigiNextAddr)
+	{
+		SDL_PlayDigiSegment(DigiNextAddr,DigiNextLen);
+		DigiNextAddr = nil;
+		DigiMissed = false;
+	}
+	else
+	{
+		if (DigiLastSegment)
+		{
+			DigiPlaying = false;
+			DigiLastSegment = false;
+			if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))
+			{
+				SDL_SoundFinished();
+			}
+			else
+				DigiNumber = DigiPriority = 0;
+			SoundPositioned = false;
+		}
+		else
+			DigiMissed = true;
+	}
+}
+
+void
+SD_SetDigiDevice(SDSMode mode)
+{
+	boolean	devicenotpresent;
+
+	if (mode == DigiMode)
+		return;
+
+	SD_StopDigitized();
+
+	devicenotpresent = false;
+	switch (mode)
+	{
+	case sds_SoundBlaster:
+		if (!SoundBlasterPresent)
+		{
+			if (SoundSourcePresent)
+				mode = sds_SoundSource;
+			else
+				devicenotpresent = true;
+		}
+		break;
+	case sds_SoundSource:
+		if (!SoundSourcePresent)
+			devicenotpresent = true;
+		break;
+	}
+
+	if (!devicenotpresent)
+	{
+		if (DigiMode == sds_SoundSource)
+			SDL_ShutSS();
+
+		DigiMode = mode;
+
+		if (mode == sds_SoundSource)
+			SDL_StartSS();
+
+		SDL_SetTimerSpeed();
+	}
+}
+
+void
+SDL_SetupDigi(void)
+{
+	memptr	list;
+	word	far *p,
+			pg;
+	int		i;
+
+	PM_UnlockMainMem();
+	MM_GetPtr(&list,PMPageSize);
+	PM_CheckMainMem();
+	p = (word far *)MK_FP(PM_GetPage(ChunksInFile - 1),0);
+	_fmemcpy((void far *)list,(void far *)p,PMPageSize);
+	pg = PMSoundStart;
+	for (i = 0;i < PMPageSize / (sizeof(word) * 2);i++,p += 2)
+	{
+		if (pg >= ChunksInFile - 1)
+			break;
+		pg += (p[1] + (PMPageSize - 1)) / PMPageSize;
+	}
+	PM_UnlockMainMem();
+	MM_GetPtr((memptr *)&DigiList,i * sizeof(word) * 2);
+	_fmemcpy((void far *)DigiList,(void far *)list,i * sizeof(word) * 2);
+	MM_FreePtr(&list);
+	NumDigi = i;
+
+	for (i = 0;i < LASTSOUND;i++)
+		DigiMap[i] = -1;
+}
+
+// 	AdLib Code
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	alOut(n,b) - Puts b in AdLib card register n
+//
+///////////////////////////////////////////////////////////////////////////
+void
+alOut(byte n,byte b)
+{
+asm	pushf
+asm	cli
+
+asm	mov	dx,0x388
+asm	mov	al,[n]
+asm	out	dx,al
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	inc	dx
+asm	mov	al,[b]
+asm	out	dx,al
+
+asm	popf
+
+asm	dec	dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+asm	in	al,dx
+}
+
+#if 0
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_SetInstrument() - Puts an instrument into a generator
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_SetInstrument(int track,int which,Instrument far *inst,boolean percussive)
+{
+	byte		c,m;
+
+	if (percussive)
+	{
+		c = pcarriers[which];
+		m = pmodifiers[which];
+	}
+	else
+	{
+		c = carriers[which];
+		m = modifiers[which];
+	}
+
+	tracks[track - 1]->inst = *inst;
+	tracks[track - 1]->percussive = percussive;
+
+	alOut(m + alChar,inst->mChar);
+	alOut(m + alScale,inst->mScale);
+	alOut(m + alAttack,inst->mAttack);
+	alOut(m + alSus,inst->mSus);
+	alOut(m + alWave,inst->mWave);
+
+	// Most percussive instruments only use one cell
+	if (c != 0xff)
+	{
+		alOut(c + alChar,inst->cChar);
+		alOut(c + alScale,inst->cScale);
+		alOut(c + alAttack,inst->cAttack);
+		alOut(c + alSus,inst->cSus);
+		alOut(c + alWave,inst->cWave);
+	}
+
+	alOut(which + alFeedCon,inst->nConn);	// DEBUG - I think this is right
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_ALStopSound() - Turns off any sound effects playing through the
+//		AdLib card
+//
+///////////////////////////////////////////////////////////////////////////
+#ifdef	_MUSE_
+void
+#else
+static void
+#endif
+SDL_ALStopSound(void)
+{
+asm	pushf
+asm	cli
+
+	(long)alSound = 0;
+	alOut(alFreqH + 0,0);
+
+asm	popf
+}
+
+static void
+SDL_AlSetFXInst(Instrument far *inst)
+{
+	byte		c,m;
+
+	m = modifiers[0];
+	c = carriers[0];
+	alOut(m + alChar,inst->mChar);
+	alOut(m + alScale,inst->mScale);
+	alOut(m + alAttack,inst->mAttack);
+	alOut(m + alSus,inst->mSus);
+	alOut(m + alWave,inst->mWave);
+	alOut(c + alChar,inst->cChar);
+	alOut(c + alScale,inst->cScale);
+	alOut(c + alAttack,inst->cAttack);
+	alOut(c + alSus,inst->cSus);
+	alOut(c + alWave,inst->cWave);
+
+	// Note: Switch commenting on these lines for old MUSE compatibility
+//	alOut(alFeedCon,inst->nConn);
+	alOut(alFeedCon,0);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_ALPlaySound() - Plays the specified sound on the AdLib card
+//
+///////////////////////////////////////////////////////////////////////////
+#ifdef	_MUSE_
+void
+#else
+static void
+#endif
+SDL_ALPlaySound(AdLibSound far *sound)
+{
+	Instrument	far *inst;
+	byte		huge *data;
+
+	SDL_ALStopSound();
+
+asm	pushf
+asm	cli
+
+	alLengthLeft = sound->common.length;
+	data = sound->data;
+	data++;
+	data--;
+	alSound = (byte far *)data;
+	alBlock = ((sound->block & 7) << 2) | 0x20;
+	inst = &sound->inst;
+
+	if (!(inst->mSus | inst->cSus))
+	{
+	asm	popf
+		Quit("SDL_ALPlaySound() - Bad instrument");
+	}
+
+	SDL_AlSetFXInst(&alZeroInst);	// DEBUG
+	SDL_AlSetFXInst(inst);
+
+asm	popf
+}
+
+#if 0
+///////////////////////////////////////////////////////////////////////////
+//
+// 	SDL_ALSoundService() - Plays the next sample out through the AdLib card
+//
+///////////////////////////////////////////////////////////////////////////
+//static void
+void
+SDL_ALSoundService(void)
+{
+	byte	s;
+
+	if (alSound)
+	{
+		s = *alSound++;
+		if (!s)
+			alOut(alFreqH + 0,0);
+		else
+		{
+			alOut(alFreqL + 0,s);
+			alOut(alFreqH + 0,alBlock);
+		}
+
+		if (!(--alLengthLeft))
+		{
+			(long)alSound = 0;
+			alOut(alFreqH + 0,0);
+			SDL_SoundFinished();
+		}
+	}
+}
+#endif
+
+#if 0
+void
+SDL_ALService(void)
+{
+	byte	a,v;
+	word	w;
+
+	if (!sqActive)
+		return;
+
+	while (sqHackLen && (sqHackTime <= alTimeCount))
+	{
+		w = *sqHackPtr++;
+		sqHackTime = alTimeCount + *sqHackPtr++;
+	asm	mov	dx,[w]
+	asm	mov	[a],dl
+	asm	mov	[v],dh
+		alOut(a,v);
+		sqHackLen -= 4;
+	}
+	alTimeCount++;
+	if (!sqHackLen)
+	{
+		sqHackPtr = (word far *)sqHack;
+		sqHackLen = sqHackSeqLen;
+		alTimeCount = sqHackTime = 0;
+	}
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_ShutAL() - Shuts down the AdLib card for sound effects
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_ShutAL(void)
+{
+asm	pushf
+asm	cli
+
+	alOut(alEffects,0);
+	alOut(alFreqH + 0,0);
+	SDL_AlSetFXInst(&alZeroInst);
+	alSound = 0;
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_CleanAL() - Totally shuts down the AdLib card
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_CleanAL(void)
+{
+	int	i;
+
+asm	pushf
+asm	cli
+
+	alOut(alEffects,0);
+	for (i = 1;i < 0xf5;i++)
+		alOut(i,0);
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_StartAL() - Starts up the AdLib card for sound effects
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_StartAL(void)
+{
+	alFXReg = 0;
+	alOut(alEffects,alFXReg);
+	SDL_AlSetFXInst(&alZeroInst);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_DetectAdLib() - Determines if there's an AdLib (or SoundBlaster
+//		emulating an AdLib) present
+//
+///////////////////////////////////////////////////////////////////////////
+static boolean
+SDL_DetectAdLib(void)
+{
+	byte	status1,status2;
+	int		i;
+
+	alOut(4,0x60);	// Reset T1 & T2
+	alOut(4,0x80);	// Reset IRQ
+	status1 = readstat();
+	alOut(2,0xff);	// Set timer 1
+	alOut(4,0x21);	// Start timer 1
+#if 0
+	SDL_Delay(TimerDelay100);
+#else
+asm	mov	dx,0x388
+asm	mov	cx,100
+usecloop:
+asm	in	al,dx
+asm	loop usecloop
+#endif
+
+	status2 = readstat();
+	alOut(4,0x60);
+	alOut(4,0x80);
+
+	if (((status1 & 0xe0) == 0x00) && ((status2 & 0xe0) == 0xc0))
+	{
+		for (i = 1;i <= 0xf5;i++)	// Zero all the registers
+			alOut(i,0);
+
+		alOut(1,0x20);	// Set WSE=1
+		alOut(8,0);		// Set CSM=0 & SEL=0
+
+		return(true);
+	}
+	else
+		return(false);
+}
+
+#if 0
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_t0Service() - My timer 0 ISR which handles the different timings and
+//		dispatches to whatever other routines are appropriate
+//
+///////////////////////////////////////////////////////////////////////////
+static void interrupt
+SDL_t0Service(void)
+{
+static	word	count = 1;
+
+#if 1	// for debugging
+asm	mov	dx,STATUS_REGISTER_1
+asm	in	al,dx
+asm	mov	dx,ATR_INDEX
+asm	mov	al,ATR_OVERSCAN
+asm	out	dx,al
+asm	mov	al,4	// red
+asm	out	dx,al
+#endif
+
+	HackCount++;
+
+	if ((MusicMode == smm_AdLib) || (DigiMode == sds_SoundSource))
+	{
+		SDL_ALService();
+		SDL_SSService();
+//		if (!(++count & 7))
+		if (!(++count % 10))
+		{
+			LocalTime++;
+			TimeCount++;
+			if (SoundUserHook)
+				SoundUserHook();
+		}
+//		if (!(count & 3))
+		if (!(count % 5))
+		{
+			switch (SoundMode)
+			{
+			case sdm_PC:
+				SDL_PCService();
+				break;
+			case sdm_AdLib:
+				SDL_ALSoundService();
+				break;
+			}
+		}
+	}
+	else
+	{
+		if (!(++count & 1))
+		{
+			LocalTime++;
+			TimeCount++;
+			if (SoundUserHook)
+				SoundUserHook();
+		}
+		switch (SoundMode)
+		{
+		case sdm_PC:
+			SDL_PCService();
+			break;
+		case sdm_AdLib:
+			SDL_ALSoundService();
+			break;
+		}
+	}
+
+asm	mov	ax,[WORD PTR TimerCount]
+asm	add	ax,[WORD PTR TimerDivisor]
+asm	mov	[WORD PTR TimerCount],ax
+asm	jnc	myack
+	t0OldService();			// If we overflow a word, time to call old int handler
+asm	jmp	olddone
+myack:;
+	outportb(0x20,0x20);	// Ack the interrupt
+olddone:;
+
+#if 1	// for debugging
+asm	mov	dx,STATUS_REGISTER_1
+asm	in	al,dx
+asm	mov	dx,ATR_INDEX
+asm	mov	al,ATR_OVERSCAN
+asm	out	dx,al
+asm	mov	al,3	// blue
+asm	out	dx,al
+asm	mov	al,0x20	// normal
+asm	out	dx,al
+#endif
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////
+//
+//	SDL_ShutDevice() - turns off whatever device was being used for sound fx
+//
+////////////////////////////////////////////////////////////////////////////
+static void
+SDL_ShutDevice(void)
+{
+	switch (SoundMode)
+	{
+	case sdm_PC:
+		SDL_ShutPC();
+		break;
+	case sdm_AdLib:
+		SDL_ShutAL();
+		break;
+	}
+	SoundMode = sdm_Off;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_CleanDevice() - totally shuts down all sound devices
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_CleanDevice(void)
+{
+	if ((SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib))
+		SDL_CleanAL();
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SDL_StartDevice() - turns on whatever device is to be used for sound fx
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+SDL_StartDevice(void)
+{
+	switch (SoundMode)
+	{
+	case sdm_AdLib:
+		SDL_StartAL();
+		break;
+	}
+	SoundNumber = SoundPriority = 0;
+}
+
+//	Public routines
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_SetSoundMode() - Sets which sound hardware to use for sound effects
+//
+///////////////////////////////////////////////////////////////////////////
+boolean
+SD_SetSoundMode(SDMode mode)
+{
+	boolean	result = false;
+	word	tableoffset;
+
+	SD_StopSound();
+
+#ifndef	_MUSE_
+	if ((mode == sdm_AdLib) && !AdLibPresent)
+		mode = sdm_PC;
+
+	switch (mode)
+	{
+	case sdm_Off:
+		NeedsDigitized = false;
+		result = true;
+		break;
+	case sdm_PC:
+		tableoffset = STARTPCSOUNDS;
+		NeedsDigitized = false;
+		result = true;
+		break;
+	case sdm_AdLib:
+		if (AdLibPresent)
+		{
+			tableoffset = STARTADLIBSOUNDS;
+			NeedsDigitized = false;
+			result = true;
+		}
+		break;
+	}
+#else
+	result = true;
+#endif
+
+	if (result && (mode != SoundMode))
+	{
+		SDL_ShutDevice();
+		SoundMode = mode;
+#ifndef	_MUSE_
+		SoundTable = (word *)(&audiosegs[tableoffset]);
+#endif
+		SDL_StartDevice();
+	}
+
+	SDL_SetTimerSpeed();
+
+	return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_SetMusicMode() - sets the device to use for background music
+//
+///////////////////////////////////////////////////////////////////////////
+boolean
+SD_SetMusicMode(SMMode mode)
+{
+	boolean	result = false;
+
+	SD_FadeOutMusic();
+	while (SD_MusicPlaying())
+		;
+
+	switch (mode)
+	{
+	case smm_Off:
+		NeedsMusic = false;
+		result = true;
+		break;
+	case smm_AdLib:
+		if (AdLibPresent)
+		{
+			NeedsMusic = true;
+			result = true;
+		}
+		break;
+	}
+
+	if (result)
+		MusicMode = mode;
+
+	SDL_SetTimerSpeed();
+
+	return(result);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_Startup() - starts up the Sound Mgr
+//		Detects all additional sound hardware and installs my ISR
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_Startup(void)
+{
+	int	i;
+
+	if (SD_Started)
+		return;
+
+	SDL_SetDS();
+
+	ssIsTandy = false;
+	ssNoCheck = false;
+	alNoCheck = false;
+	sbNoCheck = false;
+	sbNoProCheck = false;
+#ifndef	_MUSE_
+	for (i = 1;i < _argc;i++)
+	{
+		switch (US_CheckParm(_argv[i],ParmStrings))
+		{
+		case 0:						// No AdLib detection
+			alNoCheck = true;
+			break;
+		case 1:						// No SoundBlaster detection
+			sbNoCheck = true;
+			break;
+		case 2:						// No SoundBlaster Pro detection
+			sbNoProCheck = true;
+			break;
+		case 3:
+			ssNoCheck = true;		// No Sound Source detection
+			break;
+		case 4:						// Tandy Sound Source handling
+			ssIsTandy = true;
+			break;
+		case 5:						// Sound Source present at LPT1
+			ssPort = 1;
+			ssNoCheck = SoundSourcePresent = true;
+			break;
+		case 6:                     // Sound Source present at LPT2
+			ssPort = 2;
+			ssNoCheck = SoundSourcePresent = true;
+			break;
+		case 7:                     // Sound Source present at LPT3
+			ssPort = 3;
+			ssNoCheck = SoundSourcePresent = true;
+			break;
+		}
+	}
+#endif
+
+	SoundUserHook = 0;
+
+	t0OldService = getvect(8);	// Get old timer 0 ISR
+
+	LocalTime = TimeCount = alTimeCount = 0;
+
+	SD_SetSoundMode(sdm_Off);
+	SD_SetMusicMode(smm_Off);
+
+	if (!ssNoCheck)
+		SoundSourcePresent = SDL_DetectSoundSource();
+
+	if (!alNoCheck)
+	{
+		AdLibPresent = SDL_DetectAdLib();
+		if (AdLibPresent && !sbNoCheck)
+		{
+			int port = -1;
+			char *env = getenv("BLASTER");
+			if (env)
+			{
+				long temp;
+				while (*env)
+				{
+					while (isspace(*env))
+						env++;
+
+					switch (toupper(*env))
+					{
+					case 'A':
+						temp = strtol(env + 1,&env,16);
+						if
+						(
+							(temp >= 0x210)
+						&&	(temp <= 0x260)
+						&&	(!(temp & 0x00f))
+						)
+							port = (temp - 0x200) >> 4;
+						else
+							Quit("SD_Startup: Unsupported address value in BLASTER");
+						break;
+					case 'I':
+						temp = strtol(env + 1,&env,10);
+						if
+						(
+							(temp >= 0)
+						&&	(temp <= 10)
+						&&	(sbIntVectors[temp] != -1)
+						)
+						{
+							sbInterrupt = temp;
+							sbIntVec = sbIntVectors[sbInterrupt];
+						}
+						else
+							Quit("SD_Startup: Unsupported interrupt value in BLASTER");
+						break;
+					case 'D':
+						temp = strtol(env + 1,&env,10);
+						if ((temp == 0) || (temp == 1) || (temp == 3))
+							SDL_SBSetDMA(temp);
+						else
+							Quit("SD_Startup: Unsupported DMA value in BLASTER");
+						break;
+					default:
+						while (isspace(*env))
+							env++;
+						while (*env && !isspace(*env))
+							env++;
+						break;
+					}
+				}
+			}
+			SoundBlasterPresent = SDL_DetectSoundBlaster(port);
+		}
+	}
+
+	for (i = 0;i < 255;i++)
+		pcSoundLookup[i] = i * 60;
+
+	if (SoundBlasterPresent)
+		SDL_StartSB();
+
+	SDL_SetupDigi();
+
+	SD_Started = true;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_Default() - Sets up the default behaviour for the Sound Mgr whether
+//		the config file was present or not.
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_Default(boolean gotit,SDMode sd,SMMode sm)
+{
+	boolean	gotsd,gotsm;
+
+	gotsd = gotsm = gotit;
+
+	if (gotsd)	// Make sure requested sound hardware is available
+	{
+		switch (sd)
+		{
+		case sdm_AdLib:
+			gotsd = AdLibPresent;
+			break;
+		}
+	}
+	if (!gotsd)
+	{
+		if (AdLibPresent)
+			sd = sdm_AdLib;
+		else
+			sd = sdm_PC;
+	}
+	if (sd != SoundMode)
+		SD_SetSoundMode(sd);
+
+
+	if (gotsm)	// Make sure requested music hardware is available
+	{
+		switch (sm)
+		{
+		case sdm_AdLib:
+			gotsm = AdLibPresent;
+			break;
+		}
+	}
+	if (!gotsm)
+	{
+		if (AdLibPresent)
+			sm = smm_AdLib;
+	}
+	if (sm != MusicMode)
+		SD_SetMusicMode(sm);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_Shutdown() - shuts down the Sound Mgr
+//		Removes sound ISR and turns off whatever sound hardware was active
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_Shutdown(void)
+{
+	if (!SD_Started)
+		return;
+
+	SD_MusicOff();
+	SD_StopSound();
+	SDL_ShutDevice();
+	SDL_CleanDevice();
+
+	if (SoundBlasterPresent)
+		SDL_ShutSB();
+
+	if (SoundSourcePresent)
+		SDL_ShutSS();
+
+	asm	pushf
+	asm	cli
+
+	SDL_SetTimer0(0);
+
+	setvect(8,t0OldService);
+
+	asm	popf
+
+	SD_Started = false;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_SetUserHook() - sets the routine that the Sound Mgr calls every 1/70th
+//		of a second from its timer 0 ISR
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_SetUserHook(void (* hook)(void))
+{
+	SoundUserHook = hook;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_PositionSound() - Sets up a stereo imaging location for the next
+//		sound to be played. Each channel ranges from 0 to 15.
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_PositionSound(int leftvol,int rightvol)
+{
+	LeftPosition = leftvol;
+	RightPosition = rightvol;
+	nextsoundpos = true;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_PlaySound() - plays the specified sound on the appropriate hardware
+//
+///////////////////////////////////////////////////////////////////////////
+boolean
+SD_PlaySound(soundnames sound)
+{
+	boolean		ispos;
+	SoundCommon	far *s;
+	int	lp,rp;
+
+	lp = LeftPosition;
+	rp = RightPosition;
+	LeftPosition = 0;
+	RightPosition = 0;
+
+	ispos = nextsoundpos;
+	nextsoundpos = false;
+
+	if (sound == -1)
+		return(false);
+
+	s = MK_FP(SoundTable[sound],0);
+	if ((SoundMode != sdm_Off) && !s)
+		Quit("SD_PlaySound() - Uncached sound");
+
+	if ((DigiMode != sds_Off) && (DigiMap[sound] != -1))
+	{
+		if ((DigiMode == sds_PC) && (SoundMode == sdm_PC))
+		{
+			if (s->priority < SoundPriority)
+				return(false);
+
+			SDL_PCStopSound();
+
+			SD_PlayDigitized(DigiMap[sound],lp,rp);
+			SoundPositioned = ispos;
+			SoundNumber = sound;
+			SoundPriority = s->priority;
+		}
+		else
+		{
+		asm	pushf
+		asm	cli
+			if (DigiPriority && !DigiNumber)
+			{
+			asm	popf
+				Quit("SD_PlaySound: Priority without a sound");
+			}
+		asm	popf
+
+			if (s->priority < DigiPriority)
+				return(false);
+
+			SD_PlayDigitized(DigiMap[sound],lp,rp);
+			SoundPositioned = ispos;
+			DigiNumber = sound;
+			DigiPriority = s->priority;
+		}
+
+		return(true);
+	}
+
+	if (SoundMode == sdm_Off)
+		return(false);
+	if (!s->length)
+		Quit("SD_PlaySound() - Zero length sound");
+	if (s->priority < SoundPriority)
+		return(false);
+
+	switch (SoundMode)
+	{
+	case sdm_PC:
+		SDL_PCPlaySound((void far *)s);
+		break;
+	case sdm_AdLib:
+		SDL_ALPlaySound((void far *)s);
+		break;
+	}
+
+	SoundNumber = sound;
+	SoundPriority = s->priority;
+
+	return(false);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_SoundPlaying() - returns the sound number that's playing, or 0 if
+//		no sound is playing
+//
+///////////////////////////////////////////////////////////////////////////
+word
+SD_SoundPlaying(void)
+{
+	boolean	result = false;
+
+	switch (SoundMode)
+	{
+	case sdm_PC:
+		result = pcSound? true : false;
+		break;
+	case sdm_AdLib:
+		result = alSound? true : false;
+		break;
+	}
+
+	if (result)
+		return(SoundNumber);
+	else
+		return(false);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_StopSound() - if a sound is playing, stops it
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_StopSound(void)
+{
+	if (DigiPlaying)
+		SD_StopDigitized();
+
+	switch (SoundMode)
+	{
+	case sdm_PC:
+		SDL_PCStopSound();
+		break;
+	case sdm_AdLib:
+		SDL_ALStopSound();
+		break;
+	}
+
+	SoundPositioned = false;
+
+	SDL_SoundFinished();
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_WaitSoundDone() - waits until the current sound is done playing
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_WaitSoundDone(void)
+{
+	while (SD_SoundPlaying())
+		;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_MusicOn() - turns on the sequencer
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_MusicOn(void)
+{
+	sqActive = true;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_MusicOff() - turns off the sequencer and any playing notes
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_MusicOff(void)
+{
+	word	i;
+
+
+	switch (MusicMode)
+	{
+	case smm_AdLib:
+		alFXReg = 0;
+		alOut(alEffects,0);
+		for (i = 0;i < sqMaxTracks;i++)
+			alOut(alFreqH + i + 1,0);
+		break;
+	}
+	sqActive = false;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_StartMusic() - starts playing the music pointed to
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_StartMusic(MusicGroup far *music)
+{
+	SD_MusicOff();
+asm	pushf
+asm	cli
+
+	if (MusicMode == smm_AdLib)
+	{
+		sqHackPtr = sqHack = music->values;
+		sqHackSeqLen = sqHackLen = music->length;
+		sqHackTime = 0;
+		alTimeCount = 0;
+		SD_MusicOn();
+	}
+
+asm	popf
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying()
+//		to see if the fadeout is complete
+//
+///////////////////////////////////////////////////////////////////////////
+void
+SD_FadeOutMusic(void)
+{
+	switch (MusicMode)
+	{
+	case smm_AdLib:
+		// DEBUG - quick hack to turn the music off
+		SD_MusicOff();
+		break;
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	SD_MusicPlaying() - returns true if music is currently playing, false if
+//		not
+//
+///////////////////////////////////////////////////////////////////////////
+boolean
+SD_MusicPlaying(void)
+{
+	boolean	result;
+
+	switch (MusicMode)
+	{
+	case smm_AdLib:
+		result = false;
+		// DEBUG - not written
+		break;
+	default:
+		result = false;
+	}
+
+	return(result);
+}
--- /dev/null
+++ b/WOLFSRC/ID_SD.EQU
@@ -1,0 +1,38 @@
+;
+;	ID_SD.EQU
+;	Id Sound Manager assembly equates
+;
+
+	INCLUDE	'ID_VL.EQU'	; For screen color debugging stuff
+
+;	Modes
+sdm_Off				=	0
+sdm_PC				=	1
+sdm_AdLib			=	2
+
+smm_Off				=	0
+smm_AdLib			=	1
+
+sds_Off				=	0
+sds_SoundSource		=	1
+sds_SoundBlaster	=	2
+
+;	Stuff for the PC speaker
+pcTimer				=	42h
+pcTAccess			=	43h
+pcSpeaker			=	61h
+pcSpkBits			=	3
+
+;	Stuff for the AdLib
+;	Operator registers
+alChar				=	20h
+alScale				=	40h
+alAttack			=	60h
+alSus				=	80h
+alWave				=	0e0h
+;	Channel registers
+alFreqL				=	0a0h
+alFreqH				=	0b0h
+alFeedCon			=	0c0h
+;	Global registers
+alEffects			=	0bdh
--- /dev/null
+++ b/WOLFSRC/ID_SD.H
@@ -1,0 +1,237 @@
+//
+//	ID Engine
+//	ID_SD.h - Sound Manager Header
+//	Version for Wolfenstein
+//	By Jason Blochowiak
+//
+
+#ifndef	__ID_SD__
+#define	__ID_SD__
+
+void	alOut(byte n,byte b);
+
+#ifdef	__DEBUG__
+#define	__DEBUG_SoundMgr__
+#endif
+
+#define	TickBase	70		// 70Hz per tick - used as a base for timer 0
+
+typedef	enum	{
+					sdm_Off,
+					sdm_PC,sdm_AdLib,
+				}	SDMode;
+typedef	enum	{
+					smm_Off,smm_AdLib
+				}	SMMode;
+typedef	enum	{
+					sds_Off,sds_PC,sds_SoundSource,sds_SoundBlaster
+				}	SDSMode;
+typedef	struct
+		{
+			longword	length;
+			word		priority;
+		} SoundCommon;
+
+//	PC Sound stuff
+#define	pcTimer		0x42
+#define	pcTAccess	0x43
+#define	pcSpeaker	0x61
+
+#define	pcSpkBits	3
+
+typedef	struct
+		{
+			SoundCommon	common;
+			byte		data[1];
+		} PCSound;
+
+// 	Registers for the Sound Blaster card - needs to be offset by n0 (0x10,0x20,0x30,0x40,0x50,0x60)
+#define	sbReset		0x206	// W
+#define	sbFMStatus	0x208	// R
+#define	sbFMAddr	0x208	// W
+#define	sbFMData	0x209	// W
+#define	sbReadData	0x20a	// R
+#define	sbWriteCmd	0x20c	// W
+#define	sbWriteData	0x20c	// W
+#define	sbWriteStat	0x20c	// R
+#define	sbDataAvail	0x20e	// R
+
+//	Registers for the Sound Blaster Pro card - needs to be offset by n0 (0x20 or 0x40)
+#define	sbpLFMStatus	0x200	// R
+#define	sbpLFMAddr		0x200	// W
+#define	sbpLFMData		0x201	// W
+#define	sbpRFMStatus	0x202	// R
+#define	sbpRFMAddr		0x202	// W
+#define	sbpRFMData		0x203	// W
+#define	sbpMixerAddr	0x204	// W
+#define	sbpMixerData	0x205	// RW
+#define	sbpCDData		0x210	// R
+#define	sbpCDCommand	0x210	// W
+#define	sbpCDStatus		0x211	// R
+#define	sbpCDReset		0x212	// W
+
+//	SBPro Mixer addresses
+#define	sbpmReset		0x00
+#define	sbpmVoiceVol	0x04
+#define	sbpmMicMix		0x0a
+#define	sbpmFilterADC	0x0c
+#define	sbpmControl		0x0e
+#define	sbpmMasterVol	0x22
+#define	sbpmFMVol		0x26
+#define	sbpmCDVol		0x28
+#define	sbpmLineVol		0x2e
+
+typedef	struct
+		{
+			SoundCommon	common;
+			word		hertz;
+			byte		bits,
+						reference,
+						data[1];
+		} SampledSound;
+
+// 	Registers for the AdLib card
+#define	alFMStatus	0x388	// R
+#define	alFMAddr	0x388	// W
+#define	alFMData	0x389	// W
+
+//	Register addresses
+// Operator stuff
+#define	alChar		0x20
+#define	alScale		0x40
+#define	alAttack	0x60
+#define	alSus		0x80
+#define	alWave		0xe0
+// Channel stuff
+#define	alFreqL		0xa0
+#define	alFreqH		0xb0
+#define	alFeedCon	0xc0
+// Global stuff
+#define	alEffects	0xbd
+
+typedef	struct
+		{
+			byte	mChar,cChar,
+					mScale,cScale,
+					mAttack,cAttack,
+					mSus,cSus,
+					mWave,cWave,
+					nConn,
+
+					// These are only for Muse - these bytes are really unused
+					voice,
+					mode,
+					unused[3];
+		} Instrument;
+
+typedef	struct
+		{
+			SoundCommon	common;
+			Instrument	inst;
+			byte		block,
+						data[1];
+		} AdLibSound;
+
+//
+//	Sequencing stuff
+//
+#define	sqMaxTracks	10
+#define	sqMaxMoods	1	// DEBUG
+
+#define	sev_Null		0	// Does nothing
+#define	sev_NoteOff		1	// Turns a note off
+#define	sev_NoteOn		2	// Turns a note on
+#define	sev_NotePitch	3	// Sets the pitch of a currently playing note
+#define	sev_NewInst		4	// Installs a new instrument
+#define	sev_NewPerc		5	// Installs a new percussive instrument
+#define	sev_PercOn		6	// Turns a percussive note on
+#define	sev_PercOff		7	// Turns a percussive note off
+#define	sev_SeqEnd		-1	// Terminates a sequence
+
+// 	Flags for MusicGroup.flags
+#define	sf_Melodic		0
+#define	sf_Percussive	1
+
+#if 1
+typedef	struct
+		{
+			word	length,
+					values[1];
+		} MusicGroup;
+#else
+typedef	struct
+		{
+			word	flags,
+					count,
+					offsets[1];
+		} MusicGroup;
+#endif
+
+typedef	struct
+		{
+			/* This part needs to be set up by the user */
+			word        mood,far *moods[sqMaxMoods];
+
+			/* The rest is set up by the code */
+			Instrument	inst;
+			boolean		percussive;
+			word		far *seq;
+			longword	nextevent;
+		} ActiveTrack;
+
+#define	sqmode_Normal		0
+#define	sqmode_FadeIn		1
+#define	sqmode_FadeOut		2
+
+#define	sqMaxFade		64	// DEBUG
+
+
+// Global variables
+extern	boolean		AdLibPresent,
+					SoundSourcePresent,
+					SoundBlasterPresent,
+					NeedsMusic,					// For Caching Mgr
+					SoundPositioned;
+extern	SDMode		SoundMode;
+extern	SDSMode		DigiMode;
+extern	SMMode		MusicMode;
+extern	boolean		DigiPlaying;
+extern	int			DigiMap[];
+extern	longword	TimeCount;					// Global time in ticks
+
+// Function prototypes
+extern	void	SD_Startup(void),
+				SD_Shutdown(void),
+				SD_Default(boolean gotit,SDMode sd,SMMode sm),
+
+				SD_PositionSound(int leftvol,int rightvol);
+extern	boolean	SD_PlaySound(soundnames sound);
+extern	void	SD_SetPosition(int leftvol,int rightvol),
+				SD_StopSound(void),
+				SD_WaitSoundDone(void),
+
+				SD_StartMusic(MusicGroup far *music),
+				SD_MusicOn(void),
+				SD_MusicOff(void),
+				SD_FadeOutMusic(void),
+
+				SD_SetUserHook(void (*hook)(void));
+extern	boolean	SD_MusicPlaying(void),
+				SD_SetSoundMode(SDMode mode),
+				SD_SetMusicMode(SMMode mode);
+extern	word	SD_SoundPlaying(void);
+
+extern	void	SD_SetDigiDevice(SDSMode),
+				SD_PlayDigitized(word which,int leftpos,int rightpos),
+				SD_StopDigitized(void),
+				SD_Poll(void);
+
+#ifdef	_MUSE_	// MUSE Goes directly to the lower level routines
+extern	void	SDL_PCPlaySound(PCSound far *sound),
+				SDL_PCStopSound(void),
+				SDL_ALPlaySound(AdLibSound far *sound),
+				SDL_ALStopSound(void);
+#endif
+
+#endif
+
--- /dev/null
+++ b/WOLFSRC/ID_SD_A.ASM
@@ -1,0 +1,526 @@
+;
+;	ID_SD_A.ASM
+;	Id Sound Manager assembly stuff
+
+	.286C
+	IDEAL
+	MODEL	MEDIUM,C
+	JUMPS
+
+	INCLUDE 'ID_SD.EQU'
+
+DEBUG	=	0
+
+	EXTRN	SDL_DigitizedDone:FAR
+	EXTRN	alOut:FAR
+
+;============================================================================
+
+DATASEG
+
+	EXTRN	sqActive:WORD
+	EXTRN	ssSample:DWORD
+	EXTRN	ssLengthLeft:WORD
+	EXTRN	ssControl:WORD
+	EXTRN	ssStatus:WORD
+	EXTRN	ssData:WORD
+	EXTRN	ssOn:BYTE
+	EXTRN	ssOff:BYTE
+
+	EXTRN	pcSound:DWORD
+	EXTRN	pcLengthLeft:WORD
+	EXTRN	pcLastSample:BYTE
+	EXTRN	pcSoundLookup:WORD
+
+	EXTRN	alSound:DWORD
+	EXTRN	alBlock:WORD
+	EXTRN	alLengthLeft:WORD
+	EXTRN	alTimeCount:DWORD
+
+	EXTRN	sqHack:DWORD
+	EXTRN	sqHackPtr:DWORD
+	EXTRN	sqHackLen:WORD
+	EXTRN	sqHackSeqLen:WORD
+	EXTRN	sqHackTime:DWORD
+
+	EXTRN	HackCount:WORD
+	EXTRN	TimeCount:WORD
+	EXTRN	LocalTime:WORD
+
+	EXTRN	TimerCount:WORD
+	EXTRN	TimerDivisor:WORD
+	EXTRN	t0OldService:DWORD
+
+	EXTRN	SoundMode:WORD
+	EXTRN	DigiMode:WORD
+
+	EXTRN	SoundNumber:WORD
+	EXTRN	SoundPriority:WORD
+
+count_time	dw	?
+count_fx	dw	?
+
+pcdtab	db	00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
+		db	00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
+		db	00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
+		db	00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
+		db	00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
+		db	00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
+		db	00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
+		db	00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b,00b
+		db	10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
+		db	10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
+		db	10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
+		db	10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
+		db	10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
+		db	10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
+		db	10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
+		db	10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b,10b
+
+
+;============================================================================
+
+CODESEG
+
+MyDS	dw	?
+
+pcindicate	dw	?
+extreme		dw	?
+
+	PROC	SDL_SetDS
+	PUBLIC	SDL_SetDS
+
+	mov	ax,ds
+	mov	[cs:MyDS],ds
+	ret
+
+	ENDP
+
+;
+;	COMMONSTART
+;	Macro used for common prefix code
+;
+	MACRO	COMMONSTART
+	IF DEBUG
+	push dx
+	push ax
+	mov	dx,STATUS_REGISTER_1
+	in	al,dx
+	mov	dx,ATR_INDEX
+	mov	al,ATR_OVERSCAN
+	out	dx,al
+	mov	al,4	; red
+	out	dx,al
+	ENDIF
+
+	push ds
+	push ax
+
+	mov	ds,[cs:MyDS]
+	inc	[HackCount]
+	ENDM
+
+;
+;	DOFX
+;	Macro used to do the sound effects code
+;
+	MACRO	DOFX
+	les	di,[pcSound]				; PC sound effects
+	mov	ax,es
+	or	ax,di
+	jz	@@nopc						; nil pointer - no PC sound effect going
+
+	mov	bl,[es:di]					; Get the byte
+	inc	[WORD PTR pcSound]			; Increment pointer
+	cmp	[pcLastSample],bl			; Is this sample the same as last?
+	jz	@@pcsame					; Yep - don't do anything
+	mov	[pcLastSample],bl			; No, save it for next time
+
+	or	bl,bl
+	jz	@@pcoff						; If 0, turn sounds off
+	xor	bh,bh
+	shl	bx,1
+	mov	bx,[pcSoundLookup+bx]		; Use byte as index into frequency table
+
+	mov	al,0b6h						; Write to channel 2 (speaker) timer
+	out	pcTAccess,al
+	mov	al,bl
+	out	pcTimer,al					; Low byte
+	mov	al,bh
+	out	pcTimer,al					; High byte
+
+	in	al,pcSpeaker				; Turn the speaker & gate on
+	or	al,3
+	out	pcSpeaker,al
+
+	jmp @@pcsame
+
+@@pcoff:
+	in	al,pcSpeaker  				; Turn the speaker & gate off
+	and	al,0fch						; ~3
+	out	pcSpeaker,al
+
+@@pcsame:
+	dec	[pcLengthLeft]				; Decrement length
+	jnz	@@nopc						; If not 0, we're not done with the sound
+
+	mov	ax,0
+	mov	[WORD PTR pcSound],ax		; Zero the pointer
+	mov	[WORD PTR pcSound + 2],ax
+	mov	[SoundNumber],ax    		; Indicate no sound
+	mov	[SoundPriority],ax			;  with no priority
+
+	in	al,pcSpeaker  				; Turn the speaker off
+	and	al,0fdh						; ~2
+	out	pcSpeaker,al
+@@nopc:
+
+	les	di,[alSound]				; AdLib sound effects
+	mov	ax,es
+	or	ax,di
+	jz	@@noal						; nil pointer - no AdLib effect going
+
+	xor	ah,ah
+	mov	al,[es:di]
+	or	al,al
+	jz	@@aldone
+
+	CALL alOut C,alFreqL,ax
+	mov	ax,[alBlock]
+
+@@aldone:
+	CALL alOut C,alFreqH,ax
+	inc	[WORD PTR alSound]
+	dec	[alLengthLeft]
+	jnz	@@noal
+
+	mov	ax,0
+	mov	[WORD PTR alSound],ax		; Zero the pointer
+	mov	[WORD PTR alSound + 2],ax
+	mov	[SoundNumber],ax    		; Indicate no sound
+	mov	[SoundPriority],ax			;  with no priority
+	CALL alOut C,alFreqH,ax			; Turn off the sound
+@@noal:
+
+	ENDM
+
+;
+;
+;
+	MACRO	TIME
+	cmp	[count_time],2
+	jb	@@notime
+	add	[LocalTime],1
+	adc	[LocalTime+2],0
+	add	[TimeCount],1
+	adc	[TimeCount+2],0
+	mov	[count_time],0
+@@notime:
+	ENDM
+
+;
+;	COMMONEND
+;	Macro used for common suffix code
+;
+	MACRO	COMMONEND
+@@fullexit:
+	pop	es
+	popa
+
+@@nosave:
+	mov	ax,[TimerDivisor]
+	add	[TimerCount],ax
+	jnc	@@myack
+
+	pushf
+	call [t0OldService]
+	jmp	@@out
+
+@@myack:
+	mov	al,20h
+	out	20h,al
+
+@@out:
+	pop	ax
+	pop	ds
+
+	IF DEBUG
+	mov	dx,STATUS_REGISTER_1
+	in	al,dx
+	mov	dx,ATR_INDEX
+	mov	al,ATR_OVERSCAN
+	out	dx,al
+	mov	al,3	; blue
+	out	dx,al
+	mov	al,20h	; normal
+	out	dx,al
+	pop	ax
+	pop	dx
+	ENDIF
+
+	iret
+	ENDM
+
+;
+;	SDL_IndicatePC
+;
+	PROC	SDL_IndicatePC on:WORD
+	PUBLIC	SDL_IndicatePC
+
+	mov	ax,[on]
+	mov	[cs:pcindicate],ax
+	ret
+
+	ENDP
+
+;
+;	SDL_t0ExtremeAsmService
+;	Timer 0 ISR 7000Hz interrupts
+;
+	PROC	SDL_t0ExtremeAsmService
+	PUBLIC	SDL_t0ExtremeAsmService
+
+	push ax
+	mov	al,[BYTE PTR cs:pcindicate]
+	or	al,al
+	jz	@@done
+
+	push ds
+	push es
+	pusha
+
+	mov	ds,[cs:MyDS]
+
+	les	di,[pcSound]
+	mov	ax,es
+	or	ax,di
+	jz	@@donereg					; nil pointer
+
+	mov	bl,[es:di]					; Get the byte
+	inc	[WORD PTR pcSound]			; Increment pointer
+
+	and	bl,11100000b				; Nuke some of the precision (DEBUG - do this in the table)
+
+	xor	bh,bh
+	mov	ah,[pcdtab+bx]				; Translate the byte
+
+	in	al,pcSpeaker
+	and	al,11111100b
+	or	al,ah
+	out	pcSpeaker,al
+
+	dec	[pcLengthLeft]
+	jnz	@@donereg
+
+	mov	[WORD PTR pcSound],0		; We're done with this sample
+	mov	[WORD PTR pcSound+2],0
+
+	in	al,pcSpeaker
+	and	al,11111100b
+	out	pcSpeaker,al
+
+	call SDL_DigitizedDone
+
+@@donereg:
+	popa
+	pop	es
+	pop	ds
+
+@@done:
+	inc	[cs:extreme]
+	cmp	[cs:extreme],10
+	jae	@@tofast
+
+	mov	al,20h
+	out	20h,al
+	pop	ax
+	iret
+
+@@tofast:
+	mov	[cs:extreme],0
+	pop	ax
+
+;	jmp	SDL_t0FastAsmService			; Drops through to SDL_t0FastAsmService
+
+	ENDP
+
+;
+;	SDL_t0FastAsmService
+;	Timer 0 ISR for 700Hz interrupts
+;
+	PROC	SDL_t0FastAsmService
+	PUBLIC	SDL_t0FastAsmService
+
+	COMMONSTART
+
+	inc	[count_fx]						; Time to do PC/AdLib effects & time?
+	cmp	[count_fx],5
+	jae	@@dofull
+
+	mov	ax,[sqActive]					; Is the sequencer active?
+	or	ax,ax
+	jnz	@@dofull
+
+	mov	ax,[WORD PTR ssSample]			; Is there a sample for the Sound Src?
+	or	ax,[WORD PTR ssSample+2]
+	jz	@@nosave
+
+@@dofull:
+	pusha
+	push es
+
+	cmp	[count_fx],5
+	jb	@@nofx
+	mov	[count_fx],0
+	DOFX
+
+	inc	[count_time]
+	TIME
+@@nofx:
+
+	mov	ax,[sqActive]
+	or	ax,ax
+	jz	@@nosq
+
+	mov	ax,[sqHackLen]
+	or	ax,ax
+	jz	@@sqdone
+
+	les	di,[sqHackPtr]
+@@sqloop:
+	mov	ax,[WORD PTR sqHackTime+2]
+	cmp	ax,[WORD PTR alTimeCount+2]
+	ja	@@sqdone
+	mov	ax,[WORD PTR sqHackTime]
+	cmp	ax,[WORD PTR alTimeCount]
+	ja	@@sqdone
+
+	mov	ax,[es:di+2]					; Get time to next event
+	add	ax,[WORD PTR alTimeCount]
+	mov	[WORD PTR sqHackTime],ax
+	mov	ax,[WORD PTR alTimeCount+2]
+	adc	ax,0
+	mov	[WORD PTR sqHackTime+2],ax
+
+	mov	ax,[es:di]						; Get register/value pair
+	xor	bh,bh
+	mov	bl,ah
+	xor	ah,ah
+	CALL alOut C,ax,bx
+
+	add	di,4
+	mov	[WORD PTR sqHackPtr],di
+
+	sub	[sqHackLen],4
+	jnz	@@sqloop
+
+@@sqdone:
+	add	[WORD PTR alTimeCount],1
+	adc	[WORD PTR alTimeCount+2],0
+	mov	ax,[sqHackLen]
+	or	ax,ax
+	jnz	@@nosq
+
+	mov	ax,[WORD PTR sqHack]		; Copy pointer
+	mov	[WORD PTR sqHackPtr],ax
+	mov	ax,[WORD PTR sqHack+2]
+	mov	[WORD PTR sqHackPtr+2],ax
+
+	mov	ax,[sqHackSeqLen]			; Copy length
+	mov	[sqHackLen],ax
+
+	mov	ax,0
+	mov	[WORD PTR alTimeCount],ax	; Reset time counts
+	mov	[WORD PTR alTimeCount+2],ax
+	mov	[WORD PTR sqHackTime],ax
+	mov	[WORD PTR sqHackTime+2],ax
+@@nosq:
+
+	les	di,[ssSample]			; Get pointer to Sound Source sample
+	mov	ax,es
+	or	ax,di
+	jz	@@ssdone				; If nil, skip this
+
+@@ssloop:
+	mov	dx,[ssStatus]			; Check to see if FIFO has any empty slots
+	in	al,dx
+	test al,40h
+	jnz	@@ssdone				; Nope - don't push any more data out
+
+	mov	dx,[ssData]
+	mov	al,[es:di]				; al = *ssSample
+	out	dx,al					; Pump the value out
+
+	mov	dx,[ssControl]			; Pulse printer select
+	mov	al,[ssOff]
+	out	dx,al
+	push ax
+	pop	ax
+	mov	al,[ssOn]
+	out	dx,al
+
+	push ax						; Delay a short while
+	pop	ax
+
+	inc	di
+	mov	[WORD PTR ssSample],di	; ssSample++
+
+	dec	[ssLengthLeft]
+	jnz @@ssloop
+
+	mov	[WORD PTR ssSample],0	; We're done with this sample
+	mov	[WORD PTR ssSample+2],0
+
+	call SDL_DigitizedDone
+@@ssdone:
+
+	COMMONEND
+
+	ENDP
+
+;
+;	SDL_t0SlowAsmService
+;	Timer 0 ISR for 140Hz interrupts
+;
+	PROC	SDL_t0SlowAsmService
+	PUBLIC	SDL_t0SlowAsmService
+
+	IF DEBUG
+	push dx
+	push ax
+	mov	dx,STATUS_REGISTER_1
+	in	al,dx
+	mov	dx,ATR_INDEX
+	mov	al,ATR_OVERSCAN
+	out	dx,al
+	mov	al,4	; red
+	out	dx,al
+	ENDIF
+
+	push ds
+	push ax
+
+	mov	ds,[cs:MyDS]
+
+	inc	[count_time]
+	TIME
+
+	mov	ax,[WORD PTR pcSound]		; Is there a PC sound effect going?
+	or	ax,[WORD PTR pcSound+2]
+	jnz	@@dofull
+
+	mov	ax,[WORD PTR alSound]		; Is there an AdLib sound effect going?
+	or	ax,[WORD PTR alSound+2]
+	jz	@@nosave
+
+@@dofull:
+	pusha
+	push es
+
+	DOFX
+
+	COMMONEND
+
+	ENDP
+
+	END
--- /dev/null
+++ b/WOLFSRC/ID_US.H
@@ -1,0 +1,123 @@
+//
+//	ID Engine
+//	ID_US.h - Header file for the User Manager
+//	v1.0d1
+//	By Jason Blochowiak
+//
+
+#ifndef	__ID_US__
+#define	__ID_US__
+
+#ifdef	__DEBUG__
+#define	__DEBUG_UserMgr__
+#endif
+
+//#define	HELPTEXTLINKED
+
+#define	MaxX	320
+#define	MaxY	200
+
+#define	MaxHelpLines	500
+
+#define	MaxHighName	57
+#define	MaxScores	7
+typedef	struct
+		{
+			char	name[MaxHighName + 1];
+			long	score;
+			word	completed,episode;
+		} HighScore;
+
+#define	MaxGameName		32
+#define	MaxSaveGames	6
+typedef	struct
+		{
+			char	signature[4];
+			word	*oldtest;
+			boolean	present;
+			char	name[MaxGameName + 1];
+		} SaveGame;
+
+#define	MaxString	128	// Maximum input string size
+
+typedef	struct
+		{
+			int	x,y,
+				w,h,
+				px,py;
+		} WindowRec;	// Record used to save & restore screen windows
+
+typedef	enum
+		{
+			gd_Continue,
+			gd_Easy,
+			gd_Normal,
+			gd_Hard
+		} GameDiff;
+
+//	Hack import for TED launch support
+extern	boolean		tedlevel;
+extern	int			tedlevelnum;
+extern	void		TEDDeath(void);
+
+extern	boolean		ingame,		// Set by game code if a game is in progress
+					abortgame,	// Set if a game load failed
+					loadedgame,	// Set if the current game was loaded
+					NoWait,
+					HighScoresDirty;
+extern	char		*abortprogram;	// Set to error msg if program is dying
+extern	GameDiff	restartgame;	// Normally gd_Continue, else starts game
+extern	word		PrintX,PrintY;	// Current printing location in the window
+extern	word		WindowX,WindowY,// Current location of window
+					WindowW,WindowH;// Current size of window
+
+extern	boolean		Button0,Button1,
+					CursorBad;
+extern	int			CursorX,CursorY;
+
+extern	void		(*USL_MeasureString)(char far *,word *,word *),
+					(*USL_DrawString)(char far *);
+
+extern	boolean		(*USL_SaveGame)(int),(*USL_LoadGame)(int);
+extern	void		(*USL_ResetGame)(void);
+extern	SaveGame	Games[MaxSaveGames];
+extern	HighScore	Scores[];
+
+#define	US_HomeWindow()	{PrintX = WindowX; PrintY = WindowY;}
+
+extern	void	US_Startup(void),
+				US_Setup(void),
+				US_Shutdown(void),
+				US_InitRndT(boolean randomize),
+				US_SetLoadSaveHooks(boolean (*load)(int),
+									boolean (*save)(int),
+									void (*reset)(void)),
+				US_TextScreen(void),
+				US_UpdateTextScreen(void),
+				US_FinishTextScreen(void),
+				US_DrawWindow(word x,word y,word w,word h),
+				US_CenterWindow(word,word),
+				US_SaveWindow(WindowRec *win),
+				US_RestoreWindow(WindowRec *win),
+				US_ClearWindow(void),
+				US_SetPrintRoutines(void (*measure)(char far *,word *,word *),
+									void (*print)(char far *)),
+				US_PrintCentered(char far *s),
+				US_CPrint(char far *s),
+				US_CPrintLine(char far *s),
+				US_Print(char far *s),
+				US_PrintUnsigned(longword n),
+				US_PrintSigned(long n),
+				US_StartCursor(void),
+				US_ShutCursor(void),
+				US_CheckHighScore(long score,word other),
+				US_DisplayHighScores(int which);
+extern	boolean	US_UpdateCursor(void),
+				US_LineInput(int x,int y,char *buf,char *def,boolean escok,
+								int maxchars,int maxwidth);
+extern	int		US_CheckParm(char *parm,char **strings),
+				US_RndT(void);
+
+		void	USL_PrintInCenter(char far *s,Rect r);
+		char 	*USL_GiveSaveName(word game);
+#endif
--- /dev/null
+++ b/WOLFSRC/ID_US_1.C
@@ -1,0 +1,755 @@
+//
+//	ID Engine
+//	ID_US_1.c - User Manager - General routines
+//	v1.1d1
+//	By Jason Blochowiak
+//	Hacked up for Catacomb 3D
+//
+
+//
+//	This module handles dealing with user input & feedback
+//
+//	Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,
+//		and Refresh Mgrs, Memory Mgr for background save/restore
+//
+//	Globals:
+//		ingame - Flag set by game indicating if a game is in progress
+//      abortgame - Flag set if the current game should be aborted (if a load
+//			game fails)
+//		loadedgame - Flag set if a game was loaded
+//		abortprogram - Normally nil, this points to a terminal error message
+//			if the program needs to abort
+//		restartgame - Normally set to gd_Continue, this is set to one of the
+//			difficulty levels if a new game should be started
+//		PrintX, PrintY - Where the User Mgr will print (global coords)
+//		WindowX,WindowY,WindowW,WindowH - The dimensions of the current
+//			window
+//
+
+#include "ID_HEADS.H"
+
+#pragma	hdrstop
+
+#pragma	warn	-pia
+
+
+//	Global variables
+		char		*abortprogram;
+		boolean		NoWait;
+		word		PrintX,PrintY;
+		word		WindowX,WindowY,WindowW,WindowH;
+
+//	Internal variables
+#define	ConfigVersion	1
+
+static	char		*ParmStrings[] = {"TEDLEVEL","NOWAIT"},
+					*ParmStrings2[] = {"COMP","NOCOMP"};
+static	boolean		US_Started;
+
+		boolean		Button0,Button1,
+					CursorBad;
+		int			CursorX,CursorY;
+
+		void		(*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,
+					(*USL_DrawString)(char far *) = VWB_DrawPropString;
+
+		SaveGame	Games[MaxSaveGames];
+		HighScore	Scores[MaxScores] =
+					{
+						{"id software-'92",10000,1},
+						{"Adrian Carmack",10000,1},
+						{"John Carmack",10000,1},
+						{"Kevin Cloud",10000,1},
+						{"Tom Hall",10000,1},
+						{"John Romero",10000,1},
+						{"Jay Wilbur",10000,1},
+					};
+
+//	Internal routines
+
+//	Public routines
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed
+//			from DOS.
+//
+///////////////////////////////////////////////////////////////////////////
+#pragma	warn	-par
+#pragma	warn	-rch
+int
+USL_HardError(word errval,int ax,int bp,int si)
+{
+#define IGNORE  0
+#define RETRY   1
+#define	ABORT   2
+extern	void	ShutdownId(void);
+
+static	char		buf[32];
+static	WindowRec	wr;
+		int			di;
+		char		c,*s,*t;
+
+
+	di = _DI;
+
+	if (ax < 0)
+		s = "Device Error";
+	else
+	{
+		if ((di & 0x00ff) == 0)
+			s = "Drive ~ is Write Protected";
+		else
+			s = "Error on Drive ~";
+		for (t = buf;*s;s++,t++)	// Can't use sprintf()
+			if ((*t = *s) == '~')
+				*t = (ax & 0x00ff) + 'A';
+		*t = '\0';
+		s = buf;
+	}
+
+	c = peekb(0x40,0x49);	// Get the current screen mode
+	if ((c < 4) || (c == 7))
+		goto oh_kill_me;
+
+	// DEBUG - handle screen cleanup
+
+	US_SaveWindow(&wr);
+	US_CenterWindow(30,3);
+	US_CPrint(s);
+	US_CPrint("(R)etry or (A)bort?");
+	VW_UpdateScreen();
+	IN_ClearKeysDown();
+
+asm	sti	// Let the keyboard interrupts come through
+
+	while (true)
+	{
+		switch (IN_WaitForASCII())
+		{
+		case key_Escape:
+		case 'a':
+		case 'A':
+			goto oh_kill_me;
+			break;
+		case key_Return:
+		case key_Space:
+		case 'r':
+		case 'R':
+			US_ClearWindow();
+			VW_UpdateScreen();
+			US_RestoreWindow(&wr);
+			return(RETRY);
+			break;
+		}
+	}
+
+oh_kill_me:
+	abortprogram = s;
+	ShutdownId();
+	fprintf(stderr,"Terminal Error: %s\n",s);
+	if (tedlevel)
+		fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");
+
+	return(ABORT);
+#undef	IGNORE
+#undef	RETRY
+#undef	ABORT
+}
+#pragma	warn	+par
+#pragma	warn	+rch
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	US_Startup() - Starts the User Mgr
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_Startup(void)
+{
+	int	i,n;
+
+	if (US_Started)
+		return;
+
+	harderr(USL_HardError);	// Install the fatal error handler
+
+	US_InitRndT(true);		// Initialize the random number generator
+
+	for (i = 1;i < _argc;i++)
+	{
+		switch (US_CheckParm(_argv[i],ParmStrings2))
+		{
+		case 0:
+			compatability = true;
+			break;
+		case 1:
+			compatability = false;
+			break;
+		}
+	}
+
+	// Check for TED launching here
+	for (i = 1;i < _argc;i++)
+	{
+		n = US_CheckParm(_argv[i],ParmStrings);
+		switch(n)
+		{
+		 case 0:
+		   tedlevelnum = atoi(_argv[i + 1]);
+		   if (tedlevelnum >= 0)
+		     tedlevel = true;
+		   break;
+
+		 case 1:
+		   NoWait = true;
+		   break;
+		}
+	}
+
+	US_Started = true;
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	US_Shutdown() - Shuts down the User Mgr
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_Shutdown(void)
+{
+	if (!US_Started)
+		return;
+
+	US_Started = false;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	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;
+
+	while (!isalpha(*parm))	// Skip non-alphas
+		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);
+}
+
+
+//	Window/Printing routines
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	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)(char far *,word *,word *),void (*print)(char far *))
+{
+	USL_MeasureString = measure;
+	USL_DrawString = print;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	US_Print() - Prints a string in the current window. Newlines are
+//		supported.
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_Print(char far *s)
+{
+	char	c,far *se;
+	word	w,h;
+
+	while (*s)
+	{
+		se = s;
+		while ((c = *se) && (c != '\n'))
+			se++;
+		*se = '\0';
+
+		USL_MeasureString(s,&w,&h);
+		px = PrintX;
+		py = PrintY;
+		USL_DrawString(s);
+
+		s = se;
+		if (c)
+		{
+			*se = c;
+			s++;
+
+			PrintX = WindowX;
+			PrintY += h;
+		}
+		else
+			PrintX += w;
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	US_PrintUnsigned() - Prints an unsigned long
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_PrintUnsigned(longword n)
+{
+	char	buffer[32];
+
+	US_Print(ultoa(n,buffer,10));
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	US_PrintSigned() - Prints a signed long
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_PrintSigned(long 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(char far *s,Rect r)
+{
+	word	w,h,
+			rw,rh;
+
+	USL_MeasureString(s,&w,&h);
+	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(char far *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(char far *s)
+{
+	word	w,h;
+
+	USL_MeasureString(s,&w,&h);
+
+	if (w > WindowW)
+		Quit("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(char far *s)
+{
+	char	c,far *se;
+
+	while (*s)
+	{
+		se = s;
+		while ((c = *se) && (c != '\n'))
+			se++;
+		*se = '\0';
+
+		US_CPrintLine(s);
+
+		s = se;
+		if (c)
+		{
+			*se = c;
+			s++;
+		}
+	}
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	US_ClearWindow() - Clears the current window to white and homes the
+//		cursor
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_ClearWindow(void)
+{
+	VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
+	PrintX = WindowX;
+	PrintY = WindowY;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	US_DrawWindow() - Draws a frame and sets the current window parms
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_DrawWindow(word x,word y,word w,word h)
+{
+	word	i,
+			sx,sy,sw,sh;
+
+	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_DrawTile8(sx,sy,0),VWB_DrawTile8(sx,sy + sh,5);
+	for (i = sx + 8;i <= sx + sw - 8;i += 8)
+		VWB_DrawTile8(i,sy,1),VWB_DrawTile8(i,sy + sh,6);
+	VWB_DrawTile8(i,sy,2),VWB_DrawTile8(i,sy + sh,7);
+
+	for (i = sy + 8;i <= sy + sh - 8;i += 8)
+		VWB_DrawTile8(sx,i,3),VWB_DrawTile8(sx + sw,i,4);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	US_CenterWindow() - Generates a window of a given width & height in the
+//		middle of the screen
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_CenterWindow(word w,word h)
+{
+	US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	US_SaveWindow() - Saves the current window parms into a record for
+//		later restoration
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_SaveWindow(WindowRec *win)
+{
+	win->x = WindowX;
+	win->y = WindowY;
+	win->w = WindowW;
+	win->h = WindowH;
+
+	win->px = PrintX;
+	win->py = PrintY;
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	US_RestoreWindow() - Sets the current window parms to those held in the
+//		record
+//
+///////////////////////////////////////////////////////////////////////////
+void
+US_RestoreWindow(WindowRec *win)
+{
+	WindowX = win->x;
+	WindowY = win->y;
+	WindowW = win->w;
+	WindowH = win->h;
+
+	PrintX = win->px;
+	PrintY = win->py;
+}
+
+//	Input routines
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
+//
+///////////////////////////////////////////////////////////////////////////
+static void
+USL_XORICursor(int x,int y,char *s,word cursor)
+{
+	static	boolean	status;		// VGA doesn't XOR...
+	char	buf[MaxString];
+	int		temp;
+	word	w,h;
+
+	strcpy(buf,s);
+	buf[cursor] = '\0';
+	USL_MeasureString(buf,&w,&h);
+
+	px = x + w - 1;
+	py = y;
+	if (status^=1)
+		USL_DrawString("\x80");
+	else
+	{
+		temp = fontcolor;
+		fontcolor = backcolor;
+		USL_DrawString("\x80");
+		fontcolor = temp;
+	}
+
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	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
+//
+///////////////////////////////////////////////////////////////////////////
+boolean
+US_LineInput(int x,int y,char *buf,char *def,boolean escok,
+				int maxchars,int maxwidth)
+{
+	boolean		redraw,
+				cursorvis,cursormoved,
+				done,result;
+	ScanCode	sc;
+	char		c,
+				s[MaxString],olds[MaxString];
+	word		i,
+				cursor,
+				w,h,
+				len,temp;
+	longword	lasttime;
+
+	if (def)
+		strcpy(s,def);
+	else
+		*s = '\0';
+	*olds = '\0';
+	cursor = strlen(s);
+	cursormoved = redraw = true;
+
+	cursorvis = done = false;
+	lasttime = TimeCount;
+	LastASCII = key_None;
+	LastScan = sc_None;
+
+	while (!done)
+	{
+		if (cursorvis)
+			USL_XORICursor(x,y,s,cursor);
+
+	asm	pushf
+	asm	cli
+
+		sc = LastScan;
+		LastScan = sc_None;
+		c = LastASCII;
+		LastASCII = key_None;
+
+	asm	popf
+
+		switch (sc)
+		{
+		case sc_LeftArrow:
+			if (cursor)
+				cursor--;
+			c = key_None;
+			cursormoved = true;
+			break;
+		case sc_RightArrow:
+			if (s[cursor])
+				cursor++;
+			c = key_None;
+			cursormoved = true;
+			break;
+		case sc_Home:
+			cursor = 0;
+			c = key_None;
+			cursormoved = true;
+			break;
+		case sc_End:
+			cursor = strlen(s);
+			c = key_None;
+			cursormoved = true;
+			break;
+
+		case sc_Return:
+			strcpy(buf,s);
+			done = true;
+			result = true;
+			c = key_None;
+			break;
+		case sc_Escape:
+			if (escok)
+			{
+				done = true;
+				result = false;
+			}
+			c = key_None;
+			break;
+
+		case sc_BackSpace:
+			if (cursor)
+			{
+				strcpy(s + cursor - 1,s + cursor);
+				cursor--;
+				redraw = true;
+			}
+			c = key_None;
+			cursormoved = true;
+			break;
+		case sc_Delete:
+			if (s[cursor])
+			{
+				strcpy(s + cursor,s + cursor + 1);
+				redraw = true;
+			}
+			c = key_None;
+			cursormoved = true;
+			break;
+
+		case 0x4c:	// Keypad 5
+		case sc_UpArrow:
+		case sc_DownArrow:
+		case sc_PgUp:
+		case sc_PgDn:
+		case sc_Insert:
+			c = key_None;
+			break;
+		}
+
+		if (c)
+		{
+			len = strlen(s);
+			USL_MeasureString(s,&w,&h);
+
+			if
+			(
+				isprint(c)
+			&&	(len < MaxString - 1)
+			&&	((!maxchars) || (len < maxchars))
+			&&	((!maxwidth) || (w < maxwidth))
+			)
+			{
+				for (i = len + 1;i > cursor;i--)
+					s[i] = s[i - 1];
+				s[cursor++] = c;
+				redraw = true;
+			}
+		}
+
+		if (redraw)
+		{
+			px = x;
+			py = y;
+			temp = fontcolor;
+			fontcolor = backcolor;
+			USL_DrawString(olds);
+			fontcolor = temp;
+			strcpy(olds,s);
+
+			px = x;
+			py = y;
+			USL_DrawString(s);
+
+			redraw = false;
+		}
+
+		if (cursormoved)
+		{
+			cursorvis = false;
+			lasttime = TimeCount - TickBase;
+
+			cursormoved = false;
+		}
+		if (TimeCount - lasttime > TickBase / 2)
+		{
+			lasttime = TimeCount;
+
+			cursorvis ^= true;
+		}
+		if (cursorvis)
+			USL_XORICursor(x,y,s,cursor);
+
+		VW_UpdateScreen();
+	}
+
+	if (cursorvis)
+		USL_XORICursor(x,y,s,cursor);
+	if (!result)
+	{
+		px = x;
+		py = y;
+		USL_DrawString(olds);
+	}
+	VW_UpdateScreen();
+
+	IN_ClearKeysDown();
+	return(result);
+}
--- /dev/null
+++ b/WOLFSRC/ID_US_A.ASM
@@ -1,0 +1,101 @@
+IDEAL
+MODEL	MEDIUM,C
+
+;	Assembly portion of the User Mgr. This is just John Carmack's table
+;		driven pseudo-random number generator, and we put it in the User Mgr
+;		because we couldn't figure out where it should go
+
+
+;============================================================================
+;
+;                           RANDOM ROUTINES
+;
+;============================================================================
+
+	FARDATA
+
+rndindex	dw	?
+
+rndtable db    0,   8, 109, 220, 222, 241, 149, 107,  75, 248, 254, 140,  16,  66
+	db   74,  21, 211,  47,  80, 242, 154,  27, 205, 128, 161,  89,  77,  36
+	db   95, 110,  85,  48, 212, 140, 211, 249,  22,  79, 200,  50,  28, 188
+	db   52, 140, 202, 120,  68, 145,  62,  70, 184, 190,  91, 197, 152, 224
+	db  149, 104,  25, 178, 252, 182, 202, 182, 141, 197,   4,  81, 181, 242
+	db  145,  42,  39, 227, 156, 198, 225, 193, 219,  93, 122, 175, 249,   0
+	db  175, 143,  70, 239,  46, 246, 163,  53, 163, 109, 168, 135,   2, 235
+	db   25,  92,  20, 145, 138,  77,  69, 166,  78, 176, 173, 212, 166, 113
+	db   94, 161,  41,  50, 239,  49, 111, 164,  70,  60,   2,  37, 171,  75
+	db  136, 156,  11,  56,  42, 146, 138, 229,  73, 146,  77,  61,  98, 196
+	db  135, 106,  63, 197, 195,  86,  96, 203, 113, 101, 170, 247, 181, 113
+	db   80, 250, 108,   7, 255, 237, 129, 226,  79, 107, 112, 166, 103, 241
+	db   24, 223, 239, 120, 198,  58,  60,  82, 128,   3, 184,  66, 143, 224
+	db  145, 224,  81, 206, 163,  45,  63,  90, 168, 114,  59,  33, 159,  95
+	db   28, 139, 123,  98, 125, 196,  15,  70, 194, 253,  54,  14, 109, 226
+	db   71,  17, 161,  93, 186,  87, 244, 138,  20,  52, 123, 251,  26,  36
+	db   17,  46,  52, 231, 232,  76,  31, 221,  84,  37, 216, 165, 212, 106
+	db  197, 242,  98,  43,  39, 175, 254, 145, 190,  84, 118, 222, 187, 136
+	db  120, 163, 236, 249
+
+PUBLIC	rndtable
+
+	CODESEG
+
+LastRnd		dw	?
+
+;=================================================
+;
+; void US_InitRndT (boolean randomize)
+; Init table based RND generator
+; if randomize is false, the counter is set to 0
+;
+;=================================================
+
+PROC	US_InitRndT randomize:word
+	uses	si,di
+	public	US_InitRndT
+
+	mov	ax,SEG rndtable
+	mov	es,ax
+
+	mov	ax,[randomize]
+	or	ax,ax
+	jne	@@timeit		;if randomize is true, really random
+
+	mov	dx,0			;set to a definite value
+	jmp	@@setit
+
+@@timeit:
+	mov	ah,2ch
+	int	21h			;GetSystemTime
+	and	dx,0ffh
+
+@@setit:
+	mov	[es:rndindex],dx
+	ret
+
+ENDP
+
+;=================================================
+;
+; int US_RndT (void)
+; Return a random # between 0-255
+; Exit : AX = value
+;
+;=================================================
+PROC	US_RndT
+	public	US_RndT
+
+	mov	ax,SEG rndtable
+	mov	es,ax
+	mov	bx,[es:rndindex]
+	inc	bx
+	and	bx,0ffh
+	mov	[es:rndindex],bx
+	mov	al,[es:rndtable+BX]
+	xor	ah,ah
+	ret
+
+ENDP
+
+END
+
--- /dev/null
+++ b/WOLFSRC/ID_VH.C
@@ -1,0 +1,547 @@
+// ID_VH.C
+
+#include "ID_HEADS.H"
+
+#define	SCREENWIDTH		80
+#define CHARWIDTH		2
+#define TILEWIDTH		4
+#define GRPLANES		4
+#define BYTEPIXELS		4
+
+#define SCREENXMASK		(~3)
+#define SCREENXPLUS		(3)
+#define SCREENXDIV		(4)
+
+#define VIEWWIDTH		80
+
+#define PIXTOBLOCK		4		// 16 pixels to an update block
+
+#define UNCACHEGRCHUNK(chunk)	{MM_FreePtr(&grsegs[chunk]);grneeded[chunk]&=~ca_levelbit;}
+
+byte	update[UPDATEHIGH][UPDATEWIDE];
+
+//==========================================================================
+
+pictabletype	_seg *pictable;
+
+
+int	px,py;
+byte	fontcolor,backcolor;
+int	fontnumber;
+int bufferwidth,bufferheight;
+
+
+//==========================================================================
+
+void	VWL_UpdateScreenBlocks (void);
+
+//==========================================================================
+
+void VW_DrawPropString (char far *string)
+{
+	fontstruct	far	*font;
+	int		width,step,height,i;
+	byte	far *source, far *dest, far *origdest;
+	byte	ch,mask;
+
+	font = (fontstruct far *)grsegs[STARTFONT+fontnumber];
+	height = bufferheight = font->height;
+	dest = origdest = MK_FP(SCREENSEG,bufferofs+ylookup[py]+(px>>2));
+	mask = 1<<(px&3);
+
+
+	while ((ch = *string++)!=0)
+	{
+		width = step = font->width[ch];
+		source = ((byte far *)font)+font->location[ch];
+		while (width--)
+		{
+			VGAMAPMASK(mask);
+
+asm	mov	ah,[BYTE PTR fontcolor]
+asm	mov	bx,[step]
+asm	mov	cx,[height]
+asm	mov	dx,[linewidth]
+asm	lds	si,[source]
+asm	les	di,[dest]
+
+vertloop:
+asm	mov	al,[si]
+asm	or	al,al
+asm	je	next
+asm	mov	[es:di],ah			// draw color
+
+next:
+asm	add	si,bx
+asm	add	di,dx
+asm	loop	vertloop
+asm	mov	ax,ss
+asm	mov	ds,ax
+
+			source++;
+			px++;
+			mask <<= 1;
+			if (mask == 16)
+			{
+				mask = 1;
+				dest++;
+			}
+		}
+	}
+bufferheight = height;
+bufferwidth = ((dest+1)-origdest)*4;
+}
+
+
+void VW_DrawColorPropString (char far *string)
+{
+	fontstruct	far	*font;
+	int		width,step,height,i;
+	byte	far *source, far *dest, far *origdest;
+	byte	ch,mask;
+
+	font = (fontstruct far *)grsegs[STARTFONT+fontnumber];
+	height = bufferheight = font->height;
+	dest = origdest = MK_FP(SCREENSEG,bufferofs+ylookup[py]+(px>>2));
+	mask = 1<<(px&3);
+
+
+	while ((ch = *string++)!=0)
+	{
+		width = step = font->width[ch];
+		source = ((byte far *)font)+font->location[ch];
+		while (width--)
+		{
+			VGAMAPMASK(mask);
+
+asm	mov	ah,[BYTE PTR fontcolor]
+asm	mov	bx,[step]
+asm	mov	cx,[height]
+asm	mov	dx,[linewidth]
+asm	lds	si,[source]
+asm	les	di,[dest]
+
+vertloop:
+asm	mov	al,[si]
+asm	or	al,al
+asm	je	next
+asm	mov	[es:di],ah			// draw color
+
+next:
+asm	add	si,bx
+asm	add	di,dx
+
+asm rcr cx,1				// inc font color
+asm jc  cont
+asm	inc ah
+
+cont:
+asm rcl cx,1
+asm	loop	vertloop
+asm	mov	ax,ss
+asm	mov	ds,ax
+
+			source++;
+			px++;
+			mask <<= 1;
+			if (mask == 16)
+			{
+				mask = 1;
+				dest++;
+			}
+		}
+	}
+bufferheight = height;
+bufferwidth = ((dest+1)-origdest)*4;
+}
+
+
+//==========================================================================
+
+
+/*
+=================
+=
+= VL_MungePic
+=
+=================
+*/
+
+void VL_MungePic (byte far *source, unsigned width, unsigned height)
+{
+	unsigned	x,y,plane,size,pwidth;
+	byte		_seg *temp, far *dest, far *srcline;
+
+	size = width*height;
+
+	if (width&3)
+		MS_Quit ("VL_MungePic: Not divisable by 4!");
+
+//
+// copy the pic to a temp buffer
+//
+	MM_GetPtr (&(memptr)temp,size);
+	_fmemcpy (temp,source,size);
+
+//
+// munge it back into the original buffer
+//
+	dest = source;
+	pwidth = width/4;
+
+	for (plane=0;plane<4;plane++)
+	{
+		srcline = temp;
+		for (y=0;y<height;y++)
+		{
+			for (x=0;x<pwidth;x++)
+				*dest++ = *(srcline+x*4+plane);
+			srcline+=width;
+		}
+	}
+
+	MM_FreePtr (&(memptr)temp);
+}
+
+void VWL_MeasureString (char far *string, word *width, word *height
+	, fontstruct _seg *font)
+{
+	*height = font->height;
+	for (*width = 0;*string;string++)
+		*width += font->width[*((byte far *)string)];	// proportional width
+}
+
+void	VW_MeasurePropString (char far *string, word *width, word *height)
+{
+	VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONT+fontnumber]);
+}
+
+void	VW_MeasureMPropString  (char far *string, word *width, word *height)
+{
+	VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONTM+fontnumber]);
+}
+
+
+
+/*
+=============================================================================
+
+				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;
+}
+
+void VWB_DrawTile8 (int x, int y, int tile)
+{
+	if (VW_MarkUpdateBlock (x,y,x+7,y+7))
+		LatchDrawChar(x,y,tile);
+}
+
+void VWB_DrawTile8M (int x, int y, int tile)
+{
+	if (VW_MarkUpdateBlock (x,y,x+7,y+7))
+		VL_MemToScreen (((byte far *)grsegs[STARTTILE8M])+tile*64,8,8,x,y);
+}
+
+
+void VWB_DrawPic (int x, int y, int chunknum)
+{
+	int	picnum = chunknum - STARTPICS;
+	unsigned width,height;
+
+	x &= ~7;
+
+	width = pictable[picnum].width;
+	height = pictable[picnum].height;
+
+	if (VW_MarkUpdateBlock (x,y,x+width-1,y+height-1))
+		VL_MemToScreen (grsegs[chunknum],width,height,x,y);
+}
+
+
+
+void VWB_DrawPropString	 (char far *string)
+{
+	int x;
+	x=px;
+	VW_DrawPropString (string);
+	VW_MarkUpdateBlock(x,py,px-1,py+bufferheight-1);
+}
+
+
+void VWB_Bar (int x, int y, int width, int height, int color)
+{
+	if (VW_MarkUpdateBlock (x,y,x+width,y+height-1) )
+		VW_Bar (x,y,width,height,color);
+}
+
+void VWB_Plot (int x, int y, int color)
+{
+	if (VW_MarkUpdateBlock (x,y,x,y))
+		VW_Plot(x,y,color);
+}
+
+void VWB_Hlin (int x1, int x2, int y, int color)
+{
+	if (VW_MarkUpdateBlock (x1,y,x2,y))
+		VW_Hlin(x1,x2,y,color);
+}
+
+void VWB_Vlin (int y1, int y2, int x, int color)
+{
+	if (VW_MarkUpdateBlock (x,y1,x,y2))
+		VW_Vlin(y1,y2,x,color);
+}
+
+void VW_UpdateScreen (void)
+{
+	VH_UpdateScreen ();
+}
+
+
+/*
+=============================================================================
+
+						WOLFENSTEIN STUFF
+
+=============================================================================
+*/
+
+/*
+=====================
+=
+= LatchDrawPic
+=
+=====================
+*/
+
+void LatchDrawPic (unsigned x, unsigned y, unsigned picnum)
+{
+	unsigned wide, height, source;
+
+	wide = pictable[picnum-STARTPICS].width;
+	height = pictable[picnum-STARTPICS].height;
+	source = latchpics[2+picnum-LATCHPICS_LUMP_START];
+
+	VL_LatchToScreen (source,wide/4,height,x*8,y);
+}
+
+
+//==========================================================================
+
+/*
+===================
+=
+= LoadLatchMem
+=
+===================
+*/
+
+void LoadLatchMem (void)
+{
+	int	i,j,p,m,width,height,start,end;
+	byte	far *src;
+	unsigned	destoff;
+
+//
+// tile 8s
+//
+	latchpics[0] = freelatch;
+	CA_CacheGrChunk (STARTTILE8);
+	src = (byte _seg *)grsegs[STARTTILE8];
+	destoff = freelatch;
+
+	for (i=0;i<NUMTILE8;i++)
+	{
+		VL_MemToLatch (src,8,8,destoff);
+		src += 64;
+		destoff +=16;
+	}
+	UNCACHEGRCHUNK (STARTTILE8);
+
+#if 0	// ran out of latch space!
+//
+// tile 16s
+//
+	src = (byte _seg *)grsegs[STARTTILE16];
+	latchpics[1] = destoff;
+
+	for (i=0;i<NUMTILE16;i++)
+	{
+		CA_CacheGrChunk (STARTTILE16+i);
+		src = (byte _seg *)grsegs[STARTTILE16+i];
+		VL_MemToLatch (src,16,16,destoff);
+		destoff+=64;
+		if (src)
+			UNCACHEGRCHUNK (STARTTILE16+i);
+	}
+#endif
+
+//
+// pics
+//
+	start = LATCHPICS_LUMP_START;
+	end = LATCHPICS_LUMP_END;
+
+	for (i=start;i<=end;i++)
+	{
+		latchpics[2+i-start] = destoff;
+		CA_CacheGrChunk (i);
+		width = pictable[i-STARTPICS].width;
+		height = pictable[i-STARTPICS].height;
+		VL_MemToLatch (grsegs[i],width,height,destoff);
+		destoff += width/4 *height;
+		UNCACHEGRCHUNK(i);
+	}
+
+	EGAMAPMASK(15);
+}
+
+//==========================================================================
+
+/*
+===================
+=
+= FizzleFade
+=
+= returns true if aborted
+=
+===================
+*/
+
+extern	ControlInfo	c;
+
+boolean FizzleFade (unsigned source, unsigned dest,
+	unsigned width,unsigned height, unsigned frames, boolean abortable)
+{
+	int			pixperframe;
+	unsigned	drawofs,pagedelta;
+	byte 		mask,maskb[8] = {1,2,4,8};
+	unsigned	x,y,p,frame;
+	long		rndval;
+
+	pagedelta = dest-source;
+	rndval = 1;
+	y = 0;
+	pixperframe = 64000/frames;
+
+	IN_StartAck ();
+
+	TimeCount=frame=0;
+	do	// while (1)
+	{
+		if (abortable && IN_CheckAck () )
+			return true;
+
+		asm	mov	es,[screenseg]
+
+		for (p=0;p<pixperframe;p++)
+		{
+			//
+			// seperate random value into x/y pair
+			//
+			asm	mov	ax,[WORD PTR rndval]
+			asm	mov	dx,[WORD PTR rndval+2]
+			asm	mov	bx,ax
+			asm	dec	bl
+			asm	mov	[BYTE PTR y],bl			// low 8 bits - 1 = y xoordinate
+			asm	mov	bx,ax
+			asm	mov	cx,dx
+			asm	mov	[BYTE PTR x],ah			// next 9 bits = x xoordinate
+			asm	mov	[BYTE PTR x+1],dl
+			//
+			// advance to next random element
+			//
+			asm	shr	dx,1
+			asm	rcr	ax,1
+			asm	jnc	noxor
+			asm	xor	dx,0x0001
+			asm	xor	ax,0x2000
+noxor:
+			asm	mov	[WORD PTR rndval],ax
+			asm	mov	[WORD PTR rndval+2],dx
+
+			if (x>width || y>height)
+				continue;
+			drawofs = source+ylookup[y] + (x>>2);
+
+			//
+			// copy one pixel
+			//
+			mask = x&3;
+			VGAREADMAP(mask);
+			mask = maskb[mask];
+			VGAMAPMASK(mask);
+
+			asm	mov	di,[drawofs]
+			asm	mov	al,[es:di]
+			asm add	di,[pagedelta]
+			asm	mov	[es:di],al
+
+			if (rndval == 1)		// entire sequence has been completed
+				return false;
+		}
+		frame++;
+		while (TimeCount<frame)		// don't go too fast
+		;
+	} while (1);
+
+
+}
--- /dev/null
+++ b/WOLFSRC/ID_VH.H
@@ -1,0 +1,134 @@
+// ID_VH.H
+
+
+#define WHITE			15			// graphics mode independant colors
+#define BLACK			0
+#define FIRSTCOLOR		1
+#define SECONDCOLOR		12
+#define F_WHITE			15
+#define F_BLACK			0
+#define F_FIRSTCOLOR	1
+#define F_SECONDCOLOR	12
+
+//===========================================================================
+
+#define MAXSHIFTS	1
+
+typedef struct
+{
+  int	width,
+	height,
+	orgx,orgy,
+	xl,yl,xh,yh,
+	shifts;
+} spritetabletype;
+
+typedef	struct
+{
+	unsigned	sourceoffset[MAXSHIFTS];
+	unsigned	planesize[MAXSHIFTS];
+	unsigned	width[MAXSHIFTS];
+	byte		data[];
+} spritetype;		// the memptr for each sprite points to this
+
+typedef struct
+{
+	int width,height;
+} pictabletype;
+
+
+typedef struct
+{
+	int height;
+	int location[256];
+	char width[256];
+} fontstruct;
+
+
+//===========================================================================
+
+
+extern	pictabletype	_seg *pictable;
+extern	pictabletype	_seg *picmtable;
+extern	spritetabletype _seg *spritetable;
+
+extern	byte	fontcolor;
+extern	int	fontnumber;
+extern	int	px,py;
+
+//
+// Double buffer management routines
+//
+
+void VW_InitDoubleBuffer (void);
+int	 VW_MarkUpdateBlock (int x1, int y1, int x2, int y2);
+void VW_UpdateScreen (void);
+
+//
+// mode independant routines
+// coordinates in pixels, rounded to best screen res
+// regions marked in double buffer
+//
+
+void VWB_DrawTile8 (int x, int y, int tile);
+void VWB_DrawTile8M (int x, int y, int tile);
+void VWB_DrawTile16 (int x, int y, int tile);
+void VWB_DrawTile16M (int x, int y, int tile);
+void VWB_DrawPic (int x, int y, int chunknum);
+void VWB_DrawMPic(int x, int y, int chunknum);
+void VWB_Bar (int x, int y, int width, int height, int color);
+
+void VWB_DrawPropString	 (char far *string);
+void VWB_DrawMPropString (char far *string);
+void VWB_DrawSprite (int x, int y, int chunknum);
+void VWB_Plot (int x, int y, int color);
+void VWB_Hlin (int x1, int x2, int y, int color);
+void VWB_Vlin (int y1, int y2, int x, int color);
+
+
+//
+// wolfenstein EGA compatability stuff
+//
+extern byte far gamepal;
+
+void VH_SetDefaultColors (void);
+
+#define VW_Startup		VL_Startup
+#define VW_Shutdown		VL_Shutdown
+#define VW_SetCRTC		VL_SetCRTC
+#define VW_SetScreen	VL_SetScreen
+#define VW_Bar			VL_Bar
+#define VW_Plot			VL_Plot
+#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_DrawPic		VH_DrawPic
+#define VW_SetSplitScreen	VL_SetSplitScreen
+#define VW_SetLineWidth		VL_SetLineWidth
+#define VW_ColorBorder	VL_ColorBorder
+#define VW_WaitVBL		VL_WaitVBL
+#define VW_FadeIn()		VL_FadeIn(0,255,&gamepal,30);
+#define VW_FadeOut()	VL_FadeOut(0,255,0,0,0,30);
+#define VW_ScreenToScreen	VL_ScreenToScreen
+#define VW_SetDefaultColors	VH_SetDefaultColors
+void	VW_MeasurePropString (char far *string, word *width, word *height);
+#define EGAMAPMASK(x)	VGAMAPMASK(x)
+#define EGAWRITEMODE(x)	VGAWRITEMODE(x)
+
+//#define VW_MemToScreen	VL_MemToLatch
+
+#define MS_Quit			Quit
+
+
+#define LatchDrawChar(x,y,p) VL_LatchToScreen(latchpics[0]+(p)*16,2,8,x,y)
+#define LatchDrawTile(x,y,p) VL_LatchToScreen(latchpics[1]+(p)*64,4,16,x,y)
+
+void LatchDrawPic (unsigned x, unsigned y, unsigned picnum);
+void 	LoadLatchMem (void);
+boolean 	FizzleFade (unsigned source, unsigned dest,
+	unsigned width,unsigned height, unsigned frames,boolean abortable);
+
+
+#define NUMLATCHPICS	100
+extern	unsigned	latchpics[NUMLATCHPICS];
+extern	unsigned freelatch;
+
--- /dev/null
+++ b/WOLFSRC/ID_VH_A.ASM
@@ -1,0 +1,110 @@
+; ID_VL.ASM
+
+	IDEAL
+	MODEL	MEDIUM,C
+
+	INCLUDE	'ID_VL.EQU'
+
+SCREENSEG	=	0a000h
+
+UPDATEWIDE	=	20
+UPDATEHIGH	=	13
+
+	DATASEG
+
+
+EXTRN	bufferofs			:WORD
+EXTRN	displayofs			:WORD
+EXTRN	ylookup				:WORD
+EXTRN	linewidth			:WORD
+EXTRN	blockstarts			:WORD	;offsets from drawofs for each update block
+
+EXTRN	update				:BYTE
+
+	CODESEG
+
+
+;=================
+;
+; VH_UpdateScreen
+;
+;=================
+
+PROC	VH_UpdateScreen
+PUBLIC	VH_UpdateScreen
+USES	si,di
+
+	mov	dx,SC_INDEX
+	mov	ax,SC_MAPMASK+15*256
+	out	dx,ax
+
+	mov dx,GC_INDEX
+	mov al,GC_MODE
+	out dx,al
+
+	inc dx
+	in	al,dx
+	and al,252
+	or	al,1
+	out dx,al
+
+	mov	bx,UPDATEWIDE*UPDATEHIGH-1		; bx is the tile number
+	mov	dx,[linewidth]
+
+;
+; see if the tile needs to be copied
+;
+@@checktile:
+	test	[update+bx],1
+	jnz	@@copytile
+@@next:
+	dec	bx
+	jns	@@checktile
+
+;
+; done
+;
+	mov dx,GC_INDEX+1
+	in	al,dx
+	and al,NOT 3
+	or	al,0
+	out dx,al
+	ret
+
+;
+; copy a tile
+;
+@@copytile:
+	mov	[update+bx],0
+	shl	bx,1
+	mov	si,[blockstarts+bx]
+	shr	bx,1
+	mov	di,si
+	add	si,[bufferofs]
+	add	di,[displayofs]
+
+	mov	ax,SCREENSEG
+	mov	ds,ax
+
+REPT	16
+	mov	al,[si]
+	mov	[di],al
+	mov	al,[si+1]
+	mov	[di+1],al
+	mov	al,[si+2]
+	mov	[di+2],al
+	mov	al,[si+3]
+	mov	[di+3],al
+	add	si,dx
+	add	di,dx
+ENDM
+
+	mov	ax,ss
+	mov	ds,ax
+	jmp	@@next
+
+ENDP
+
+
+	END
+
--- /dev/null
+++ b/WOLFSRC/ID_VL.C
@@ -1,0 +1,1084 @@
+// ID_VL.C
+
+#include <dos.h>
+#include <alloc.h>
+#include <mem.h>
+#include <string.h>
+#include "ID_HEAD.H"
+#include "ID_VL.H"
+#pragma hdrstop
+
+//
+// SC_INDEX is expected to stay at SC_MAPMASK for proper operation
+//
+
+unsigned	bufferofs;
+unsigned	displayofs,pelpan;
+
+unsigned	screenseg=SCREENSEG;		// set to 0xa000 for asm convenience
+
+unsigned	linewidth;
+unsigned	ylookup[MAXSCANLINES];
+
+boolean		screenfaded;
+unsigned	bordercolor;
+
+boolean		fastpalette;				// if true, use outsb to set
+
+byte		far	palette1[256][3],far palette2[256][3];
+
+//===========================================================================
+
+// asm
+
+int	 VL_VideoID (void);
+void VL_SetCRTC (int crtc);
+void VL_SetScreen (int crtc, int pelpan);
+void VL_WaitVBL (int vbls);
+
+//===========================================================================
+
+
+/*
+=======================
+=
+= VL_Startup
+=
+=======================
+*/
+
+#if 0
+void	VL_Startup (void)
+{
+	if ( !MS_CheckParm ("HIDDENCARD") && VL_VideoID () != 5)
+		MS_Quit ("You need a VGA graphics card to run this!");
+
+	asm	cld;				// all string instructions assume forward
+}
+
+#endif
+
+/*
+=======================
+=
+= VL_Startup	// WOLFENSTEIN HACK
+=
+=======================
+*/
+
+static	char *ParmStrings[] = {"HIDDENCARD",""};
+
+void	VL_Startup (void)
+{
+	int i,videocard;
+
+	asm	cld;
+
+	videocard = VL_VideoID ();
+	for (i = 1;i < _argc;i++)
+		if (US_CheckParm(_argv[i],ParmStrings) == 0)
+		{
+			videocard = 5;
+			break;
+		}
+
+	if (videocard != 5)
+Quit ("Improper video card!  If you really have a VGA card that I am not \n"
+	  "detecting, use the -HIDDENCARD command line parameter!");
+
+}
+
+
+
+/*
+=======================
+=
+= VL_Shutdown
+=
+=======================
+*/
+
+void	VL_Shutdown (void)
+{
+	VL_SetTextMode ();
+}
+
+
+/*
+=======================
+=
+= VL_SetVGAPlaneMode
+=
+=======================
+*/
+
+void	VL_SetVGAPlaneMode (void)
+{
+asm	mov	ax,0x13
+asm	int	0x10
+	VL_DePlaneVGA ();
+	VGAMAPMASK(15);
+	VL_SetLineWidth (40);
+}
+
+
+/*
+=======================
+=
+= VL_SetTextMode
+=
+=======================
+*/
+
+void	VL_SetTextMode (void)
+{
+asm	mov	ax,3
+asm	int	0x10
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_ClearVideo
+=
+= Fill the entire video buffer with a given color
+=
+=================
+*/
+
+void VL_ClearVideo (byte color)
+{
+asm	mov	dx,GC_INDEX
+asm	mov	al,GC_MODE
+asm	out	dx,al
+asm	inc	dx
+asm	in	al,dx
+asm	and	al,0xfc				// write mode 0 to store directly to video
+asm	out	dx,al
+
+asm	mov	dx,SC_INDEX
+asm	mov	ax,SC_MAPMASK+15*256
+asm	out	dx,ax				// write through all four planes
+
+asm	mov	ax,SCREENSEG
+asm	mov	es,ax
+asm	mov	al,[color]
+asm	mov	ah,al
+asm	mov	cx,0x8000			// 0x8000 words, clearing 8 video bytes/word
+asm	xor	di,di
+asm	rep	stosw
+}
+
+
+/*
+=============================================================================
+
+			VGA REGISTER MANAGEMENT ROUTINES
+
+=============================================================================
+*/
+
+
+/*
+=================
+=
+= VL_DePlaneVGA
+=
+=================
+*/
+
+void VL_DePlaneVGA (void)
+{
+
+//
+// change CPU addressing to non linear mode
+//
+
+//
+// turn off chain 4 and odd/even
+//
+	outportb (SC_INDEX,SC_MEMMODE);
+	outportb (SC_INDEX+1,(inportb(SC_INDEX+1)&~8)|4);
+
+	outportb (SC_INDEX,SC_MAPMASK);		// leave this set throughought
+
+//
+// turn off odd/even and set write mode 0
+//
+	outportb (GC_INDEX,GC_MODE);
+	outportb (GC_INDEX+1,inportb(GC_INDEX+1)&~0x13);
+
+//
+// turn off chain
+//
+	outportb (GC_INDEX,GC_MISCELLANEOUS);
+	outportb (GC_INDEX+1,inportb(GC_INDEX+1)&~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
+//
+	outportb (CRTC_INDEX,CRTC_UNDERLINE);
+	outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1)&~0x40);
+
+	outportb (CRTC_INDEX,CRTC_MODE);
+	outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1)|0x40);
+}
+
+//===========================================================================
+
+/*
+====================
+=
+= 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
+//
+	outport (CRTC_INDEX,CRTC_OFFSET+width*256);
+
+//
+// set up lookup tables
+//
+	linewidth = width*2;
+
+	offset = 0;
+
+	for (i=0;i<MAXSCANLINES;i++)
+	{
+		ylookup[i]=offset;
+		offset += linewidth;
+	}
+}
+
+/*
+====================
+=
+= VL_SetSplitScreen
+=
+====================
+*/
+
+void VL_SetSplitScreen (int linenum)
+{
+	VL_WaitVBL (1);
+	linenum=linenum*2-1;
+	outportb (CRTC_INDEX,CRTC_LINECOMPARE);
+	outportb (CRTC_INDEX+1,linenum % 256);
+	outportb (CRTC_INDEX,CRTC_OVERFLOW);
+	outportb (CRTC_INDEX+1, 1+16*(linenum/256));
+	outportb (CRTC_INDEX,CRTC_MAXSCANLINE);
+	outportb (CRTC_INDEX+1,inportb(CRTC_INDEX+1) & (255-64));
+}
+
+
+/*
+=============================================================================
+
+						PALETTE OPS
+
+		To avoid snow, do a WaitVBL BEFORE calling these
+
+=============================================================================
+*/
+
+
+/*
+=================
+=
+= VL_FillPalette
+=
+=================
+*/
+
+void VL_FillPalette (int red, int green, int blue)
+{
+	int	i;
+
+	outportb (PEL_WRITE_ADR,0);
+	for (i=0;i<256;i++)
+	{
+		outportb (PEL_DATA,red);
+		outportb (PEL_DATA,green);
+		outportb (PEL_DATA,blue);
+	}
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_SetColor
+=
+=================
+*/
+
+void VL_SetColor	(int color, int red, int green, int blue)
+{
+	outportb (PEL_WRITE_ADR,color);
+	outportb (PEL_DATA,red);
+	outportb (PEL_DATA,green);
+	outportb (PEL_DATA,blue);
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_GetColor
+=
+=================
+*/
+
+void VL_GetColor	(int color, int *red, int *green, int *blue)
+{
+	outportb (PEL_READ_ADR,color);
+	*red = inportb (PEL_DATA);
+	*green = inportb (PEL_DATA);
+	*blue = inportb (PEL_DATA);
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= 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 far *palette)
+{
+	int	i;
+
+//	outportb (PEL_WRITE_ADR,0);
+//	for (i=0;i<768;i++)
+//		outportb(PEL_DATA,*palette++);
+
+	asm	mov	dx,PEL_WRITE_ADR
+	asm	mov	al,0
+	asm	out	dx,al
+	asm	mov	dx,PEL_DATA
+	asm	lds	si,[palette]
+
+	asm	test	[ss:fastpalette],1
+	asm	jz	slowset
+//
+// set palette fast for cards that can take it
+//
+	asm	mov	cx,768
+	asm	rep outsb
+	asm	jmp	done
+
+//
+// set palette slowly for some video cards
+//
+slowset:
+	asm	mov	cx,256
+setloop:
+	asm	lodsb
+	asm	out	dx,al
+	asm	lodsb
+	asm	out	dx,al
+	asm	lodsb
+	asm	out	dx,al
+	asm	loop	setloop
+
+done:
+	asm	mov	ax,ss
+	asm	mov	ds,ax
+
+}
+
+
+//===========================================================================
+
+/*
+=================
+=
+= VL_GetPalette
+=
+= This does not use the port string instructions,
+= due to some incompatabilities
+=
+=================
+*/
+
+void VL_GetPalette (byte far *palette)
+{
+	int	i;
+
+	outportb (PEL_READ_ADR,0);
+	for (i=0;i<768;i++)
+		*palette++ = inportb(PEL_DATA);
+}
+
+
+//===========================================================================
+
+/*
+=================
+=
+= 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	far *origptr, far *newptr;
+
+	VL_WaitVBL(1);
+	VL_GetPalette (&palette1[0][0]);
+	_fmemcpy (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;
+		}
+
+		VL_WaitVBL(1);
+		VL_SetPalette (&palette2[0][0]);
+	}
+
+//
+// final color
+//
+	VL_FillPalette (red,green,blue);
+
+	screenfaded = true;
+}
+
+
+/*
+=================
+=
+= VL_FadeIn
+=
+=================
+*/
+
+void VL_FadeIn (int start, int end, byte far *palette, int steps)
+{
+	int		i,j,delta;
+
+	VL_WaitVBL(1);
+	VL_GetPalette (&palette1[0][0]);
+	_fmemcpy (&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;
+		}
+
+		VL_WaitVBL(1);
+		VL_SetPalette (&palette2[0][0]);
+	}
+
+//
+// final color
+//
+	VL_SetPalette (palette);
+	screenfaded = false;
+}
+
+
+
+/*
+=================
+=
+= 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;
+}
+
+
+
+/*
+=============================================================================
+
+							PIXEL OPS
+
+=============================================================================
+*/
+
+byte	pixmasks[4] = {1,2,4,8};
+byte	leftmasks[4] = {15,14,12,8};
+byte	rightmasks[4] = {1,3,7,15};
+
+
+/*
+=================
+=
+= VL_Plot
+=
+=================
+*/
+
+void VL_Plot (int x, int y, int color)
+{
+	byte mask;
+
+	mask = pixmasks[x&3];
+	VGAMAPMASK(mask);
+	*(byte far *)MK_FP(SCREENSEG,bufferofs+(ylookup[y]+(x>>2))) = color;
+	VGAMAPMASK(15);
+}
+
+
+/*
+=================
+=
+= VL_Hlin
+=
+=================
+*/
+
+void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color)
+{
+	unsigned		xbyte;
+	byte			far *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 = MK_FP(SCREENSEG,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);
+	_fmemset (dest,color,midbytes);
+	dest+=midbytes;
+
+	VGAMAPMASK(rightmask);
+	*dest = color;
+
+	VGAMAPMASK(15);
+}
+
+
+/*
+=================
+=
+= VL_Vlin
+=
+=================
+*/
+
+void VL_Vlin (int x, int y, int height, int color)
+{
+	byte	far *dest,mask;
+
+	mask = pixmasks[x&3];
+	VGAMAPMASK(mask);
+
+	dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2));
+
+	while (height--)
+	{
+		*dest = color;
+		dest += linewidth;
+	}
+
+	VGAMAPMASK(15);
+}
+
+
+/*
+=================
+=
+= VL_Bar
+=
+=================
+*/
+
+void VL_Bar (int x, int y, int width, int height, int color)
+{
+	byte	far *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 = MK_FP(SCREENSEG,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);
+		_fmemset (dest,color,midbytes);
+		dest+=midbytes;
+
+		VGAMAPMASK(rightmask);
+		*dest = color;
+
+		dest+=linedelta;
+	}
+
+	VGAMAPMASK(15);
+}
+
+/*
+============================================================================
+
+							MEMORY OPS
+
+============================================================================
+*/
+
+/*
+=================
+=
+= VL_MemToLatch
+=
+=================
+*/
+
+void VL_MemToLatch (byte far *source, int width, int height, unsigned dest)
+{
+	unsigned	count;
+	byte	plane,mask;
+
+	count = ((width+3)/4)*height;
+	mask = 1;
+	for (plane = 0; plane<4 ; plane++)
+	{
+		VGAMAPMASK(mask);
+		mask <<= 1;
+
+asm	mov	cx,count
+asm mov ax,SCREENSEG
+asm mov es,ax
+asm	mov	di,[dest]
+asm	lds	si,[source]
+asm	rep movsb
+asm mov	ax,ss
+asm	mov	ds,ax
+
+		source+= count;
+	}
+}
+
+
+//===========================================================================
+
+
+/*
+=================
+=
+= VL_MemToScreen
+=
+= Draws a block of data to the screen.
+=
+=================
+*/
+
+void VL_MemToScreen (byte far *source, int width, int height, int x, int y)
+{
+	byte    far *screen,far *dest,mask;
+	int		plane;
+
+	width>>=2;
+	dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2) );
+	mask = 1 << (x&3);
+
+	for (plane = 0; plane<4; plane++)
+	{
+		VGAMAPMASK(mask);
+		mask <<= 1;
+		if (mask == 16)
+			mask = 1;
+
+		screen = dest;
+		for (y=0;y<height;y++,screen+=linewidth,source+=width)
+			_fmemcpy (screen,source,width);
+	}
+}
+
+//==========================================================================
+
+
+/*
+=================
+=
+= VL_MaskedToScreen
+=
+= Masks a block of main memory to the screen.
+=
+=================
+*/
+
+void VL_MaskedToScreen (byte far *source, int width, int height, int x, int y)
+{
+	byte    far *screen,far *dest,mask;
+	byte	far *maskptr;
+	int		plane;
+
+	width>>=2;
+	dest = MK_FP(SCREENSEG,bufferofs+ylookup[y]+(x>>2) );
+//	mask = 1 << (x&3);
+
+//	maskptr = source;
+
+	for (plane = 0; plane<4; plane++)
+	{
+		VGAMAPMASK(mask);
+		mask <<= 1;
+		if (mask == 16)
+			mask = 1;
+
+		screen = dest;
+		for (y=0;y<height;y++,screen+=linewidth,source+=width)
+			_fmemcpy (screen,source,width);
+	}
+}
+
+//==========================================================================
+
+/*
+=================
+=
+= VL_LatchToScreen
+=
+=================
+*/
+
+void VL_LatchToScreen (unsigned source, int width, int height, int x, int y)
+{
+	VGAWRITEMODE(1);
+	VGAMAPMASK(15);
+
+asm	mov	di,[y]				// dest = bufferofs+ylookup[y]+(x>>2)
+asm	shl	di,1
+asm	mov	di,[WORD PTR ylookup+di]
+asm	add	di,[bufferofs]
+asm	mov	ax,[x]
+asm	shr	ax,2
+asm	add	di,ax
+
+asm	mov	si,[source]
+asm	mov	ax,[width]
+asm	mov	bx,[linewidth]
+asm	sub	bx,ax
+asm	mov	dx,[height]
+asm	mov	cx,SCREENSEG
+asm	mov	ds,cx
+asm	mov	es,cx
+
+drawline:
+asm	mov	cx,ax
+asm	rep movsb
+asm	add	di,bx
+asm	dec	dx
+asm	jnz	drawline
+
+asm	mov	ax,ss
+asm	mov	ds,ax
+
+	VGAWRITEMODE(0);
+}
+
+
+//===========================================================================
+
+#if 0
+
+/*
+=================
+=
+= VL_ScreenToScreen
+=
+=================
+*/
+
+void VL_ScreenToScreen (unsigned source, unsigned dest,int width, int height)
+{
+	VGAWRITEMODE(1);
+	VGAMAPMASK(15);
+
+asm	mov	si,[source]
+asm	mov	di,[dest]
+asm	mov	ax,[width]
+asm	mov	bx,[linewidth]
+asm	sub	bx,ax
+asm	mov	dx,[height]
+asm	mov	cx,SCREENSEG
+asm	mov	ds,cx
+asm	mov	es,cx
+
+drawline:
+asm	mov	cx,ax
+asm	rep movsb
+asm	add	si,bx
+asm	add	di,bx
+asm	dec	dx
+asm	jnz	drawline
+
+asm	mov	ax,ss
+asm	mov	ds,ax
+
+	VGAWRITEMODE(0);
+}
+
+
+#endif
+
+/*
+=============================================================================
+
+						STRING OUTPUT ROUTINES
+
+=============================================================================
+*/
+
+
+
+
+/*
+===================
+=
+= VL_DrawTile8String
+=
+===================
+*/
+
+void VL_DrawTile8String (char *str, char far *tile8ptr, int printx, int printy)
+{
+	int		i;
+	unsigned	far *dest,far *screen,far *src;
+
+	dest = MK_FP(SCREENSEG,bufferofs+ylookup[printy]+(printx>>2));
+
+	while (*str)
+	{
+		src = (unsigned far *)(tile8ptr + (*str<<6));
+		// each character is 64 bytes
+
+		VGAMAPMASK(1);
+		screen = dest;
+		for (i=0;i<8;i++,screen+=linewidth)
+			*screen = *src++;
+		VGAMAPMASK(2);
+		screen = dest;
+		for (i=0;i<8;i++,screen+=linewidth)
+			*screen = *src++;
+		VGAMAPMASK(4);
+		screen = dest;
+		for (i=0;i<8;i++,screen+=linewidth)
+			*screen = *src++;
+		VGAMAPMASK(8);
+		screen = dest;
+		for (i=0;i<8;i++,screen+=linewidth)
+			*screen = *src++;
+
+		str++;
+		printx += 8;
+		dest+=2;
+	}
+}
+
+
+
+/*
+===================
+=
+= VL_DrawLatch8String
+=
+===================
+*/
+
+void VL_DrawLatch8String (char *str, unsigned tile8ptr, int printx, int printy)
+{
+	int		i;
+	unsigned	src,dest;
+
+	dest = bufferofs+ylookup[printy]+(printx>>2);
+
+	VGAWRITEMODE(1);
+	VGAMAPMASK(15);
+
+	while (*str)
+	{
+		src = tile8ptr + (*str<<4);		// each character is 16 latch bytes
+
+asm	mov	si,[src]
+asm	mov	di,[dest]
+asm	mov	dx,[linewidth]
+
+asm	mov	ax,SCREENSEG
+asm	mov	ds,ax
+
+asm	lodsw
+asm	mov	[di],ax
+asm	add	di,dx
+asm	lodsw
+asm	mov	[di],ax
+asm	add	di,dx
+asm	lodsw
+asm	mov	[di],ax
+asm	add	di,dx
+asm	lodsw
+asm	mov	[di],ax
+asm	add	di,dx
+asm	lodsw
+asm	mov	[di],ax
+asm	add	di,dx
+asm	lodsw
+asm	mov	[di],ax
+asm	add	di,dx
+asm	lodsw
+asm	mov	[di],ax
+asm	add	di,dx
+asm	lodsw
+asm	mov	[di],ax
+asm	add	di,dx
+
+asm	mov	ax,ss
+asm	mov	ds,ax
+
+		str++;
+		printx += 8;
+		dest+=2;
+	}
+
+	VGAWRITEMODE(0);
+}
+
+
+/*
+===================
+=
+= VL_SizeTile8String
+=
+===================
+*/
+
+void VL_SizeTile8String (char *str, int *width, int *height)
+{
+	*height = 8;
+	*width = 8*strlen(str);
+}
+
+
+
+
+
+
+
+
+
--- /dev/null
+++ b/WOLFSRC/ID_VL.EQU
@@ -1,0 +1,58 @@
+; ID_VL.EQU
+
+SC_INDEX	=	03C4h
+SC_RESET	=	0
+SC_CLOCK	=	1
+SC_MAPMASK	=	2
+SC_CHARMAP	=	3
+SC_MEMMODE	=	4
+
+CRTC_INDEX	=	03D4h
+CRTC_H_TOTAL	=	0
+CRTC_H_DISPEND	=	1
+CRTC_H_BLANK	=	2
+CRTC_H_ENDBLANK	=	3
+CRTC_H_RETRACE	=	4
+CRTC_H_ENDRETRACE =	5
+CRTC_V_TOTAL	=	6
+CRTC_OVERFLOW	=	7
+CRTC_ROWSCAN	=	8
+CRTC_MAXSCANLINE =	9
+CRTC_CURSORSTART =	10
+CRTC_CURSOREND	=	11
+CRTC_STARTHIGH	=	12
+CRTC_STARTLOW	=	13
+CRTC_CURSORHIGH	=	14
+CRTC_CURSORLOW	=	15
+CRTC_V_RETRACE	=	16
+CRTC_V_ENDRETRACE =	17
+CRTC_V_DISPEND	=	18
+CRTC_OFFSET	=	19
+CRTC_UNDERLINE	=	20
+CRTC_V_BLANK	=	21
+CRTC_V_ENDBLANK	=	22
+CRTC_MODE	=	23
+CRTC_LINECOMPARE =	24
+
+
+GC_INDEX	=	03CEh
+GC_SETRESET	=	0
+GC_ENABLESETRESET =	1
+GC_COLORCOMPARE	=	2
+GC_DATAROTATE	=	3
+GC_READMAP	=	4
+GC_MODE		=	5
+GC_MISCELLANEOUS =	6
+GC_COLORDONTCARE =	7
+GC_BITMASK	=	8
+
+ATR_INDEX	=	03c0h
+ATR_MODE	=	16
+ATR_OVERSCAN	=	17
+ATR_COLORPLANEENABLE =	18
+ATR_PELPAN	=	19
+ATR_COLORSELECT	=	20
+
+STATUS_REGISTER_1     =	03dah
+
+
--- /dev/null
+++ b/WOLFSRC/ID_VL.H
@@ -1,0 +1,161 @@
+// ID_VL.H
+
+// wolf compatability
+
+#define MS_Quit	Quit
+
+void Quit (char *error);
+
+//===========================================================================
+
+
+#define SC_INDEX			0x3C4
+#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_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_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
+
+
+//===========================================================================
+
+#define SCREENSEG		0xa000
+
+#define SCREENWIDTH		80			// default screen width in bytes
+#define MAXSCANLINES	200			// size of ylookup table
+
+#define CHARWIDTH		2
+#define TILEWIDTH		4
+
+//===========================================================================
+
+extern	unsigned	bufferofs;			// all drawing is reletive to this
+extern	unsigned	displayofs,pelpan;	// last setscreen coordinates
+
+extern	unsigned	screenseg;			// set to 0xa000 for asm convenience
+
+extern	unsigned	linewidth;
+extern	unsigned	ylookup[MAXSCANLINES];
+
+extern	boolean		screenfaded;
+extern	unsigned	bordercolor;
+
+//===========================================================================
+
+//
+// VGA hardware routines
+//
+
+#define VGAWRITEMODE(x) asm{\
+cli;\
+mov dx,GC_INDEX;\
+mov al,GC_MODE;\
+out dx,al;\
+inc dx;\
+in al,dx;\
+and al,252;\
+or al,x;\
+out dx,al;\
+sti;}
+
+#define VGAMAPMASK(x) asm{cli;mov dx,SC_INDEX;mov al,SC_MAPMASK;mov ah,x;out dx,ax;sti;}
+#define VGAREADMAP(x) asm{cli;mov dx,GC_INDEX;mov al,GC_READMAP;mov ah,x;out dx,ax;sti;}
+
+
+void VL_Startup (void);
+void VL_Shutdown (void);
+
+void VL_SetVGAPlane (void);
+void VL_SetTextMode (void);
+void VL_DePlaneVGA (void);
+void VL_SetVGAPlaneMode (void);
+void VL_ClearVideo (byte color);
+
+void VL_SetLineWidth (unsigned width);
+void VL_SetSplitScreen (int linenum);
+
+void VL_WaitVBL (int vbls);
+void VL_CrtcStart (int crtc);
+void VL_SetScreen (int crtc, int pelpan);
+
+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 far *palette);
+void VL_GetPalette (byte far *palette);
+void VL_FadeOut (int start, int end, int red, int green, int blue, int steps);
+void VL_FadeIn (int start, int end, byte far *palette, int steps);
+void VL_ColorBorder (int color);
+
+void VL_Plot (int x, int y, int color);
+void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color);
+void VL_Vlin (int x, int y, int height, int color);
+void VL_Bar (int x, int y, int width, int height, int color);
+
+void VL_MungePic (byte far *source, unsigned width, unsigned height);
+void VL_DrawPicBare (int x, int y, byte far *pic, int width, int height);
+void VL_MemToLatch (byte far *source, int width, int height, unsigned dest);
+void VL_ScreenToScreen (unsigned source, unsigned dest,int width, int height);
+void VL_MemToScreen (byte far *source, int width, int height, int x, int y);
+void VL_MaskedToScreen (byte far *source, int width, int height, int x, int y);
+
+void VL_DrawTile8String (char *str, char far *tile8ptr, int printx, int printy);
+void VL_DrawLatch8String (char *str, unsigned tile8ptr, int printx, int printy);
+void VL_SizeTile8String (char *str, int *width, int *height);
+void VL_DrawPropString (char *str, unsigned tile8ptr, int printx, int printy);
+void VL_SizePropString (char *str, int *width, int *height, char far *font);
+
+void VL_TestPaletteSet (void);
+
--- /dev/null
+++ b/WOLFSRC/ID_VL_A.ASM
@@ -1,0 +1,742 @@
+; ID_VL.ASM
+
+	IDEAL
+	MODEL	MEDIUM,C
+
+	INCLUDE	'ID_VL.EQU'
+
+SCREENSEG	=	0a000h
+
+	DATASEG
+
+	EXTRN	TimeCount:WORD		; incremented every 70th of a second
+	EXTRN	linewidth:WORD
+
+starttime	dw	?
+
+	CODESEG
+
+;===========================================================================
+
+
+;==============
+;
+; VL_WaitVBL			******** NEW *********
+;
+; Wait for the vertical retrace (returns before the actual vertical sync)
+;
+;==============
+
+PROC	VL_WaitVBL  num:WORD
+PUBLIC	VL_WaitVBL
+@@wait:
+
+	mov	dx,STATUS_REGISTER_1
+
+	mov	cx,[num]
+;
+; wait for a display signal to make sure the raster isn't in the middle
+; of a sync
+;
+@@waitnosync:
+	in	al,dx
+	test	al,8
+	jnz	@@waitnosync
+
+
+@@waitsync:
+	in	al,dx
+	test	al,8
+	jz	@@waitsync
+
+	loop	@@waitnosync
+
+	ret
+
+ENDP
+
+
+;===========================================================================
+
+;==============
+;
+; VL_SetCRTC
+;
+;==============
+
+PROC	VL_SetCRTC  crtc:WORD
+PUBLIC	VL_SetCRTC
+
+;
+; wait for a display signal to make sure the raster isn't in the middle
+; of a sync
+;
+	cli
+
+	mov	dx,STATUS_REGISTER_1
+
+@@waitdisplay:
+	in	al,dx
+	test	al,1	;1 = display is disabled (HBL / VBL)
+	jnz	@@waitdisplay
+
+
+;
+; set CRTC start
+;
+; for some reason, my XT's EGA card doesn't like word outs to the CRTC
+; index...
+;
+	mov	cx,[crtc]
+	mov	dx,CRTC_INDEX
+	mov	al,0ch		;start address high register
+	out	dx,al
+	inc	dx
+	mov	al,ch
+	out	dx,al
+	dec	dx
+	mov	al,0dh		;start address low register
+	out	dx,al
+	mov	al,cl
+	inc	dx
+	out	dx,al
+
+
+	sti
+
+	ret
+
+ENDP
+
+
+
+;===========================================================================
+
+;==============
+;
+; VL_SetScreen
+;
+;==============
+
+PROC	VL_SetScreen  crtc:WORD, pel:WORD
+PUBLIC	VL_SetScreen
+
+
+	mov	cx,[timecount]		; if timecount goes up by two, the retrace
+	add	cx,2				; period was missed (an interrupt covered it)
+
+	mov	dx,STATUS_REGISTER_1
+
+;
+; wait for a display signal to make sure the raster isn't in the middle
+; of a sync
+;
+@@waitdisplay:
+	in	al,dx
+	test	al,1	;1 = display is disabled (HBL / VBL)
+	jnz	@@waitdisplay
+
+
+@@loop:
+	sti
+	jmp	$+2
+	cli
+
+	cmp	[timecount],cx		; will only happen if an interrupt is
+	jae	@@setcrtc			; straddling the entire retrace period
+
+;
+; when several succesive display not enableds occur,
+; the bottom of the screen has been hit
+;
+
+	in	al,dx
+	test	al,8
+	jnz	@@waitdisplay
+	test	al,1
+	jz	@@loop
+
+	in	al,dx
+	test	al,8
+	jnz	@@waitdisplay
+	test	al,1
+	jz	@@loop
+
+	in	al,dx
+	test	al,8
+	jnz	@@waitdisplay
+	test	al,1
+	jz	@@loop
+
+	in	al,dx
+	test	al,8
+	jnz	@@waitdisplay
+	test	al,1
+	jz	@@loop
+
+	in	al,dx
+	test	al,8
+	jnz	@@waitdisplay
+	test	al,1
+	jz	@@loop
+
+
+@@setcrtc:
+
+
+;
+; set CRTC start
+;
+; for some reason, my XT's EGA card doesn't like word outs to the CRTC
+; index...
+;
+	mov	cx,[crtc]
+	mov	dx,CRTC_INDEX
+	mov	al,0ch		;start address high register
+	out	dx,al
+	inc	dx
+	mov	al,ch
+	out	dx,al
+	dec	dx
+	mov	al,0dh		;start address low register
+	out	dx,al
+	mov	al,cl
+	inc	dx
+	out	dx,al
+
+;
+; set horizontal panning
+;
+	mov	dx,ATR_INDEX
+	mov	al,ATR_PELPAN or 20h
+	out	dx,al
+	jmp	$+2
+	mov	al,[BYTE pel]		;pel pan value
+	out	dx,al
+
+	sti
+
+	ret
+
+ENDP
+
+
+;===========================================================================
+
+
+;============================================================================
+;
+; VL_ScreenToScreen
+;
+; Basic block copy routine.  Copies one block of screen memory to another,
+; using write mode 1 (sets it and returns with write mode 0).  bufferofs is
+; NOT accounted for.
+;
+;============================================================================
+
+PROC	VL_ScreenToScreen	source:WORD, dest:WORD, wide:WORD, height:WORD
+PUBLIC	VL_ScreenToScreen
+USES	SI,DI
+
+	pushf
+	cli
+
+	mov	dx,SC_INDEX
+	mov	ax,SC_MAPMASK+15*256
+	out	dx,ax
+	mov	dx,GC_INDEX
+	mov	al,GC_MODE
+	out	dx,al
+	inc	dx
+	in	al,dx
+	and	al,NOT 3
+	or	al,1
+	out	dx,al
+
+	popf
+
+	mov	bx,[linewidth]
+	sub	bx,[wide]
+
+	mov	ax,SCREENSEG
+	mov	es,ax
+	mov	ds,ax
+
+	mov	si,[source]
+	mov	di,[dest]				;start at same place in all planes
+	mov	dx,[height]				;scan lines to draw
+	mov	ax,[wide]
+
+@@lineloop:
+	mov	cx,ax
+	rep	movsb
+	add	si,bx
+	add	di,bx
+
+	dec	dx
+	jnz	@@lineloop
+
+	mov	dx,GC_INDEX+1
+	in	al,dx
+	and	al,NOT 3
+	out	dx,al
+
+	mov	ax,ss
+	mov	ds,ax					;restore turbo's data segment
+
+	ret
+
+ENDP
+
+
+;===========================================================================
+
+
+	MASM
+;���������������������������������������������������������
+;
+; Name:	VL_VideoID
+;
+; Function:	Detects the presence of various video subsystems
+;
+; int VideoID;
+;
+; Subsystem ID values:
+; 	 0  = (none)
+; 	 1  = MDA
+; 	 2  = CGA
+; 	 3  = EGA
+; 	 4  = MCGA
+; 	 5  = VGA
+; 	80h = HGC
+; 	81h = HGC+
+; 	82h = Hercules InColor
+;
+;���������������������������������������������������������
+
+;���������������������������������������������������������
+;
+; Equates
+;
+;���������������������������������������������������������
+VIDstruct	STRUC		; corresponds to C data structure
+
+Video0Type	DB	?	; first subsystem type
+Display0Type	DB	? 	; display attached to first subsystem
+
+Video1Type	DB	?	; second subsystem type
+Display1Type	DB	?	; display attached to second subsystem
+
+VIDstruct	ENDS
+
+
+Device0	EQU	word ptr Video0Type[di]
+Device1	EQU	word ptr Video1Type[di]
+
+
+MDA	EQU	1	; subsystem types
+CGA	EQU	2
+EGA	EQU	3
+MCGA	EQU	4
+VGA	EQU	5
+HGC	EQU	80h
+HGCPlus	EQU	81h
+InColor	EQU	82h
+
+MDADisplay	EQU	1	; display types
+CGADisplay	EQU	2
+EGAColorDisplay	EQU	3
+PS2MonoDisplay	EQU	4
+PS2ColorDisplay	EQU	5
+
+TRUE	EQU	1
+FALSE	EQU	0
+
+;���������������������������������������������������������
+;
+; Program
+;
+;���������������������������������������������������������
+
+Results	VIDstruct <>	;results go here!
+
+EGADisplays	DB	CGADisplay	; 0000b, 0001b	(EGA switch values)
+	DB	EGAColorDisplay	; 0010b, 0011b
+	DB	MDADisplay	; 0100b, 0101b
+	DB	CGADisplay	; 0110b, 0111b
+	DB	EGAColorDisplay	; 1000b, 1001b
+	DB	MDADisplay	; 1010b, 1011b
+
+DCCtable	DB	0,0	; translate table for INT 10h func 1Ah
+	DB	MDA,MDADisplay
+	DB	CGA,CGADisplay
+	DB	0,0
+	DB	EGA,EGAColorDisplay
+	DB	EGA,MDADisplay
+	DB	0,0
+	DB	VGA,PS2MonoDisplay
+	DB	VGA,PS2ColorDisplay
+	DB	0,0
+	DB	MCGA,EGAColorDisplay
+	DB	MCGA,PS2MonoDisplay
+	DB	MCGA,PS2ColorDisplay
+
+TestSequence	DB	TRUE	; this list of flags and addresses
+	DW	FindPS2	;  determines the order in which this
+			;  program looks for the various
+EGAflag	DB	?	;  subsystems
+	DW	FindEGA
+
+CGAflag	DB	?
+	DW	FindCGA
+
+Monoflag	DB	?
+	DW	FindMono
+
+NumberOfTests	EQU	($-TestSequence)/3
+
+
+PUBLIC	VL_VideoID
+VL_VideoID	PROC
+
+	push	bp	; preserve caller registers
+	mov	bp,sp
+	push	ds
+	push	si
+	push	di
+
+	push	cs
+	pop	ds
+	ASSUME	DS:@Code
+
+; initialize the data structure that will contain the results
+
+	lea	di,Results	; DS:DI -> start of data structure
+
+	mov	Device0,0	; zero these variables
+	mov	Device1,0
+
+; look for the various subsystems using the subroutines whose addresses are
+; tabulated in TestSequence; each subroutine sets flags in TestSequence
+; to indicate whether subsequent subroutines need to be called
+
+	mov	byte ptr CGAflag,TRUE
+	mov	byte ptr EGAflag,TRUE
+	mov	byte ptr Monoflag,TRUE
+
+	mov	cx,NumberOfTests
+	mov	si,offset TestSequence
+
+@@L01:	lodsb		; AL := flag
+	test	al,al
+	lodsw		; AX := subroutine address
+	jz	@@L02	; skip subroutine if flag is false
+
+	push	si
+	push	cx
+	call	ax	; call subroutine to detect subsystem
+	pop	cx
+	pop	si
+
+@@L02:	loop	@@L01
+
+; determine which subsystem is active
+
+	call	FindActive
+
+	mov	al,Results.Video0Type
+	mov	ah,0	; was:  Results.Display0Type
+
+	pop	di	; restore caller registers and return
+	pop	si
+	pop	ds
+	mov	sp,bp
+	pop	bp
+	ret
+
+VL_VideoID	ENDP
+
+
+;
+; FindPS2
+;
+; This subroutine uses INT 10H function 1Ah to determine the video BIOS
+; Display Combination Code (DCC) for each video subsystem present.
+;
+
+FindPS2	PROC	near
+
+	mov	ax,1A00h
+	int	10h	; call video BIOS for info
+
+	cmp	al,1Ah
+	jne	@@L13	; exit if function not supported (i.e.,
+			;  no MCGA or VGA in system)
+
+; convert BIOS DCCs into specific subsystems & displays
+
+	mov	cx,bx
+	xor	bh,bh	; BX := DCC for active subsystem
+
+	or	ch,ch
+	jz	@@L11	; jump if only one subsystem present
+
+	mov	bl,ch	; BX := inactive DCC
+	add	bx,bx
+	mov	ax,[bx+offset DCCtable]
+
+	mov	Device1,ax
+
+	mov	bl,cl
+	xor	bh,bh	; BX := active DCC
+
+@@L11:	add	bx,bx
+	mov	ax,[bx+offset DCCtable]
+
+	mov	Device0,ax
+
+; reset flags for subsystems that have been ruled out
+
+	mov	byte ptr CGAflag,FALSE
+	mov	byte ptr EGAflag,FALSE
+	mov	byte ptr Monoflag,FALSE
+
+	lea	bx,Video0Type[di]  ; if the BIOS reported an MDA ...
+	cmp	byte ptr [bx],MDA
+	je	@@L12
+
+	lea	bx,Video1Type[di]
+	cmp	byte ptr [bx],MDA
+	jne	@@L13
+
+@@L12:	mov	word ptr [bx],0    ; ... Hercules can't be ruled out
+	mov	byte ptr Monoflag,TRUE
+
+@@L13:	ret
+
+FindPS2	ENDP
+
+
+;
+; FindEGA
+;
+; Look for an EGA.  This is done by making a call to an EGA BIOS function
+;  which doesn't exist in the default (MDA, CGA) BIOS.
+
+FindEGA	PROC	near	; Caller:	AH = flags
+			; Returns:	AH = flags
+			;		Video0Type and
+			;		 Display0Type updated
+
+	mov	bl,10h	; BL := 10h (return EGA info)
+	mov	ah,12h	; AH := INT 10H function number
+	int	10h	; call EGA BIOS for info
+			; if EGA BIOS is present,
+			;  BL <> 10H
+			;  CL = switch setting
+	cmp	bl,10h
+	je	@@L22	; jump if EGA BIOS not present
+
+	mov	al,cl
+	shr	al,1	; AL := switches/2
+	mov	bx,offset EGADisplays
+	xlat		; determine display type from switches
+	mov	ah,al	; AH := display type
+	mov	al,EGA	; AL := subystem type
+	call	FoundDevice
+
+	cmp	ah,MDADisplay
+	je	@@L21	; jump if EGA has a monochrome display
+
+	mov	CGAflag,FALSE	; no CGA if EGA has color display
+	jmp	short @@L22
+
+@@L21:	mov	Monoflag,FALSE	; EGA has a mono display, so MDA and
+			;  Hercules are ruled out
+@@L22:	ret
+
+FindEGA	ENDP
+
+;
+; FindCGA
+;
+; This is done by looking for the CGA's 6845 CRTC at I/O port 3D4H.
+;
+FindCGA	PROC	near	; Returns:	VIDstruct updated
+
+	mov	dx,3D4h	; DX := CRTC address port
+	call	Find6845
+	jc	@@L31	; jump if not present
+
+	mov	al,CGA
+	mov	ah,CGADisplay
+	call	FoundDevice
+
+@@L31:	ret
+
+FindCGA	ENDP
+
+;
+; FindMono
+;
+; This is done by looking for the MDA's 6845 CRTC at I/O port 3B4H.  If
+; a 6845 is found, the subroutine distinguishes between an MDA
+; and a Hercules adapter by monitoring bit 7 of the CRT Status byte.
+; This bit changes on Hercules adapters but does not change on an MDA.
+;
+; The various Hercules adapters are identified by bits 4 through 6 of
+; the CRT Status value:
+;
+; 000b = HGC
+; 001b = HGC+
+; 101b = InColor card
+;
+
+FindMono	PROC	near	; Returns:	VIDstruct updated
+
+	mov	dx,3B4h	; DX := CRTC address port
+	call	Find6845
+	jc	@@L44	; jump if not present
+
+	mov	dl,0BAh	; DX := 3BAh (status port)
+	in	al,dx
+	and	al,80h
+	mov	ah,al	; AH := bit 7 (vertical sync on HGC)
+
+	mov	cx,8000h	; do this 32768 times
+@@L41:	in	al,dx
+	and	al,80h	; isolate bit 7
+	cmp	ah,al
+	loope	@@L41	; wait for bit 7 to change
+	jne	@@L42	; if bit 7 changed, it's a Hercules
+
+	mov	al,MDA	; if bit 7 didn't change, it's an MDA
+	mov	ah,MDADisplay
+	call	FoundDevice
+	jmp	short @@L44
+
+@@L42:	in	al,dx
+	mov	dl,al	; DL := value from status port
+	and	dl,01110000b	; mask bits 4 thru 6
+
+	mov	ah,MDADisplay	; assume it's a monochrome display
+
+	mov	al,HGCPlus	; look for an HGC+
+	cmp	dl,00010000b
+	je	@@L43	; jump if it's an HGC+
+
+	mov	al,HGC	; look for an InColor card or HGC
+	cmp	dl,01010000b
+	jne	@@L43	; jump if it's not an InColor card
+
+	mov	al,InColor	; it's an InColor card
+	mov	ah,EGAColorDisplay
+
+@@L43:	call	FoundDevice
+
+@@L44:	ret
+
+FindMono	ENDP
+
+;
+; Find6845
+;
+; This routine detects the presence of the CRTC on a MDA, CGA or HGC.
+; The technique is to write and read register 0Fh of the chip (cursor
+; low).  If the same value is read as written, assume the chip is
+; present at the specified port addr.
+;
+
+Find6845	PROC	near	; Caller:  DX = port addr
+			; Returns: cf set if not present
+	mov	al,0Fh
+	out	dx,al	; select 6845 reg 0Fh (Cursor Low)
+	inc	dx
+	in	al,dx	; AL := current Cursor Low value
+	mov	ah,al	; preserve in AH
+	mov	al,66h	; AL := arbitrary value
+	out	dx,al	; try to write to 6845
+
+	mov	cx,100h
+@@L51:	loop	@@L51	; wait for 6845 to respond
+
+	in	al,dx
+	xchg	ah,al	; AH := returned value
+			; AL := original value
+	out	dx,al	; restore original value
+
+	cmp	ah,66h	; test whether 6845 responded
+	je	@@L52	; jump if it did (cf is reset)
+
+	stc		; set carry flag if no 6845 present
+
+@@L52:	ret
+
+Find6845	ENDP
+
+
+;
+; FindActive
+;
+; This subroutine stores the currently active device as Device0.  The
+; current video mode determines which subsystem is active.
+;
+
+FindActive	PROC	near
+
+	cmp	word ptr Device1,0
+	je	@@L63	; exit if only one subsystem
+
+	cmp	Video0Type[di],4	; exit if MCGA or VGA present
+	jge	@@L63	;  (INT 10H function 1AH
+	cmp	Video1Type[di],4	;  already did the work)
+	jge	@@L63
+
+	mov	ah,0Fh
+	int	10h	; AL := current BIOS video mode
+
+	and	al,7
+	cmp	al,7	; jump if monochrome
+	je	@@L61	;  (mode 7 or 0Fh)
+
+	cmp	Display0Type[di],MDADisplay
+	jne	@@L63	; exit if Display0 is color
+	jmp	short @@L62
+
+@@L61:	cmp	Display0Type[di],MDADisplay
+	je	@@L63	; exit if Display0 is monochrome
+
+@@L62:	mov	ax,Device0	; make Device0 currently active
+	xchg	ax,Device1
+	mov	Device0,ax
+
+@@L63:	ret
+
+FindActive	ENDP
+
+
+;
+; FoundDevice
+;
+; This routine updates the list of subsystems.
+;
+
+FoundDevice	PROC	near	; Caller:    AH = display #
+			;	     AL = subsystem #
+			; Destroys:  BX
+	lea	bx,Video0Type[di]
+	cmp	byte ptr [bx],0
+	je	@@L71	; jump if 1st subsystem
+
+	lea	bx,Video1Type[di]	; must be 2nd subsystem
+
+@@L71:	mov	[bx],ax	; update list entry
+	ret
+
+FoundDevice	ENDP
+
+IDEAL
+
+
+
+END
--- /dev/null
+++ b/WOLFSRC/JABHACK.ASM
@@ -1,0 +1,98 @@
+; JABHACK.ASM
+
+.386C
+IDEAL
+MODEL	MEDIUM
+
+EXTRN	LDIV@:far
+
+;============================================================================
+
+DATASEG
+
+EXTRN	_intaddr:word
+
+;============================================================================
+
+CODESEG
+
+;	Hacked up Juan Jimenez's code a bit to just return 386/not 386
+PROC	_CheckIs386
+PUBLIC	_CheckIs386
+
+	pushf			; Save flag registers, we use them here
+	xor	ax,ax		; Clear AX and...
+	push ax			; ...push it onto the stack
+	popf			; Pop 0 into flag registers (all bits to 0),
+	pushf			; attempting to set bits 12-15 of flags to 0's
+	pop	ax			; Recover the save flags
+	and	ax,08000h	; If bits 12-15 of flags are set to
+	cmp	ax,08000h	; zero then it's 8088/86 or 80188/186
+	jz	not386
+
+	mov	ax,07000h	; Try to set flag bits 12-14 to 1's
+	push ax			; Push the test value onto the stack
+	popf			; Pop it into the flag register
+	pushf			; Push it back onto the stack
+	pop	ax			; Pop it into AX for check
+	and	ax,07000h	; if bits 12-14 are cleared then
+	jz	not386		; the chip is an 80286
+
+	mov	ax,1		; We now assume it's a 80386 or better
+	popf
+	retf
+
+not386:
+	xor	ax,ax
+	popf
+	retf
+
+	ENDP
+
+
+PROC	_jabhack2
+PUBLIC	_jabhack2
+
+	jmp	@@skip
+
+@@where:
+	int	060h
+	retf
+
+@@skip:
+	push	es
+
+	mov	ax,seg LDIV@
+	mov	es,ax
+	mov	ax,[WORD PTR @@where]
+	mov	[WORD FAR es:LDIV@],ax
+	mov	ax,[WORD PTR @@where+2]
+	mov	[WORD FAR es:LDIV@+2],ax
+
+	mov	ax,offset @@jabdiv
+	mov	[_intaddr],ax
+	mov	ax,seg @@jabdiv
+	mov	[_intaddr+2],ax
+
+	pop	es
+	retf
+
+@@jabdiv:
+	add	sp,4	;Nuke IRET address, but leave flags
+	push bp
+	mov	bp,sp	;Save BP, and set it equal to stack
+	cli
+
+	mov	eax,[bp+8]
+	cdq
+	idiv [DWORD PTR bp+12]
+	mov	edx,eax
+	shr	edx,16
+
+	pop	bp		;Restore BP
+	popf 		;Restore flags (from INT)
+	retf	8	;Return to original caller
+
+	ENDP
+
+	END
--- /dev/null
+++ b/WOLFSRC/MAPSSDM.H
@@ -1,0 +1,14 @@
+///////////////////////////////////////
+//
+// TED5 Map Header for SDM
+//
+///////////////////////////////////////
+
+//
+// Map Names
+//
+typedef enum {
+		TUNNELS_1_MAP,           // 0
+		TUNNELS_2_MAP,           // 1
+		LASTMAP
+	     } mapnames;
--- /dev/null
+++ b/WOLFSRC/MAPSSOD.H
@@ -1,0 +1,33 @@
+///////////////////////////////////////
+//
+// TED5 Map Header for SOD
+//
+///////////////////////////////////////
+
+//
+// Map Names
+//
+typedef enum {
+		TUNNELS_1_MAP,           // 0
+		TUNNELS_2_MAP,           // 1
+		TUNNELS_3_MAP,           // 2
+		TUNNELS_4_MAP,           // 3
+		TUNNEL_BOSS_MAP,         // 4
+		DUNGEONS_1_MAP,          // 5
+		DUNGEONS_2_MAP,          // 6
+		DUNGEONS_3_MAP,          // 7
+		DUNGEONS_4_MAP,          // 8
+		DUNGEON_BOSS_MAP,        // 9
+		CASTLE_1_MAP,            // 10
+		CASTLE_2_MAP,            // 11
+		CASTLE_3_MAP,            // 12
+		CASTLE_4_MAP,            // 13
+		CASTLE_5_MAP,            // 14
+		CASTLE_BOSS_MAP,         // 15
+		RAMPARTS_MAP,            // 16
+		DEATH_KNIGHT_MAP,        // 17
+		SECRET_1_MAP,            // 18
+		SECRET_2_MAP,            // 19
+		ANGEL_OF_DEATH_MAP,      // 20
+		LASTMAP
+	     } mapnames;
--- /dev/null
+++ b/WOLFSRC/MAPSWL1.H
@@ -1,0 +1,42 @@
+///////////////////////////////////////
+//
+// TED5 Map Header for WL1
+//
+///////////////////////////////////////
+
+//
+// Map Names
+//
+typedef enum {
+		WOLF1_MAP1_MAP,          // 0
+		WOLF1_MAP2_MAP,          // 1
+		WOLF1_MAP3_MAP,          // 2
+		WOLF1_MAP4_MAP,          // 3
+		WOLF1_MAP5_MAP,          // 4
+		WOLF1_MAP6_MAP,          // 5
+		WOLF1_MAP7_MAP,          // 6
+		WOLF1_MAP8_MAP,          // 7
+		WOLF1_BOSS_MAP,          // 8
+		WOLF1_SECRET_MAP,        // 9
+		WOLF2_MAP1_MAP,          // 10
+		WOLF2_MAP2_MAP,          // 11
+		WOLF2_MAP3_MAP,          // 12
+		WOLF2_MAP4_MAP,          // 13
+		WOLF2_MAP5_MAP,          // 14
+		WOLF2_MAP6_MAP,          // 15
+		WOLF2_MAP7_MAP,          // 16
+		WOLF2_MAP8_MAP,          // 17
+		WOLF2_BOSS_MAP,          // 18
+		WOLF2_SECRET_MAP,        // 19
+		WOLF3_MAP1_MAP,          // 20
+		WOLF3_MAP2_MAP,          // 21
+		WOLF3_MAP3_MAP,          // 22
+		WOLF3_MAP4_MAP,          // 23
+		WOLF3_MAP5_MAP,          // 24
+		WOLF3_MAP6_MAP,          // 25
+		WOLF3_MAP7_MAP,          // 26
+		WOLF3_MAP8_MAP,          // 27
+		WOLF3_BOSS_MAP,          // 28
+		WOLF3_SECRET_MAP,        // 29
+		LASTMAP
+	     } mapnames;
--- /dev/null
+++ b/WOLFSRC/MAPSWL6.H
@@ -1,0 +1,73 @@
+///////////////////////////////////////
+//
+// TED5 Map Header for WL6
+//
+///////////////////////////////////////
+
+//
+// Map Names
+//
+typedef enum {
+		WOLF1_MAP1_MAP,          // 0
+		WOLF1_MAP2_MAP,          // 1
+		WOLF1_MAP3_MAP,          // 2
+		WOLF1_MAP4_MAP,          // 3
+		WOLF1_MAP5_MAP,          // 4
+		WOLF1_MAP6_MAP,          // 5
+		WOLF1_MAP7_MAP,          // 6
+		WOLF1_MAP8_MAP,          // 7
+		WOLF1_BOSS_MAP,          // 8
+		WOLF1_SECRET_MAP,        // 9
+		WOLF2_MAP1_MAP,          // 10
+		WOLF2_MAP2_MAP,          // 11
+		WOLF2_MAP3_MAP,          // 12
+		WOLF2_MAP4_MAP,          // 13
+		WOLF2_MAP5_MAP,          // 14
+		WOLF2_MAP6_MAP,          // 15
+		WOLF2_MAP7_MAP,          // 16
+		WOLF2_MAP8_MAP,          // 17
+		WOLF2_BOSS_MAP,          // 18
+		WOLF2_SECRET_MAP,        // 19
+		WOLF3_MAP1_MAP,          // 20
+		WOLF3_MAP2_MAP,          // 21
+		WOLF3_MAP3_MAP,          // 22
+		WOLF3_MAP4_MAP,          // 23
+		WOLF3_MAP5_MAP,          // 24
+		WOLF3_MAP6_MAP,          // 25
+		WOLF3_MAP7_MAP,          // 26
+		WOLF3_MAP8_MAP,          // 27
+		WOLF3_BOSS_MAP,          // 28
+		WOLF3_SECRET_MAP,        // 29
+		WOLF4_MAP_1_MAP,         // 30
+		WOLF4_MAP_2_MAP,         // 31
+		WOLF4_MAP_3_MAP,         // 32
+		WOLF4_MAP_4_MAP,         // 33
+		WOLF4_MAP_5_MAP,         // 34
+		WOLF4_MAP_6_MAP,         // 35
+		WOLF4_MAP_7_MAP,         // 36
+		WOLF4_MAP_8_MAP,         // 37
+		WOLF4_BOSS_MAP,          // 38
+		WOLF4_SECRET_MAP,        // 39
+		WOLF5_MAP_1_MAP,         // 40
+		WOLF5_MAP_2_MAP,         // 41
+		WOLF5_MAP_3_MAP,         // 42
+		WOLF5_MAP_4_MAP,         // 43
+		WOLF5_MAP_5_MAP,         // 44
+		WOLF5_MAP_6_MAP,         // 45
+		WOLF5_MAP_7_MAP,         // 46
+		WOLF5_MAP_8_MAP,         // 47
+		WOLF5_BOSS_MAP,          // 48
+		WOLF5_SECRET_MAP,        // 49
+		WOLF6_MAP_1_MAP,         // 50
+		WOLF6_MAP_2_MAP,         // 51
+		WOLF6_MAP_3_MAP,         // 52
+		WOLF6_MAP_4_MAP,         // 53
+		WOLF6_MAP_5_MAP,         // 54
+		WOLF6_MAP_6_MAP,         // 55
+		WOLF6_MAP_7_MAP,         // 56
+		WOLF6_MAP_8_MAP,         // 57
+		WOLF6_BOSS_MAP,          // 58
+		WOLF6_SECRET_MAP,        // 59
+		MAP4L10PATH_MAP,         // 60
+		LASTMAP
+	     } mapnames;
--- /dev/null
+++ b/WOLFSRC/MAPSWLF.H
@@ -1,0 +1,16 @@
+///////////////////////////////////////
+//
+// TED5 Map Header for WLF
+//
+///////////////////////////////////////
+
+//
+// Map Names
+//
+typedef enum {
+		LEVEL_ONE_MAP,           // 0
+		LEVEL_TWO_MAP,           // 1
+		LEVEL_THREE_MAP,         // 2
+		LEVEL_FOUR_MAP,          // 3
+		LASTMAP
+	     } mapnames;
--- /dev/null
+++ b/WOLFSRC/MUNGE.C
@@ -1,0 +1,48 @@
+
+/*
+=================
+=
+= VL_MungePic
+=
+=================
+*/
+
+void VL_MungePic (unsigned char far *source, unsigned width, unsigned height)
+{
+	unsigned	x,y,plane,size,pwidth;
+	unsigned char	far *temp, far *dest, far *srcline;
+
+	size = width*height;
+
+	if (width&3)
+		errout ("VL_MungePic: Not divisable by 4!\n");
+
+//
+// copy the pic to a temp buffer
+//
+	temp = (unsigned char far *)farmalloc (size);
+	if (!temp)
+		errout ("Non enough memory for munge buffer!\n");
+
+	_fmemcpy (temp,source,size);
+
+//
+// munge it back into the original buffer
+//
+	dest = source;
+	pwidth = width/4;
+
+	for (plane=0;plane<4;plane++)
+	{
+		srcline = temp;
+		for (y=0;y<height;y++)
+		{
+			for (x=0;x<pwidth;x++)
+				*dest++ = *(srcline+x*4+plane);
+			srcline+=width;
+		}
+	}
+
+	free (temp);
+}
+
binary files /dev/null b/WOLFSRC/OBJ/GAMEPAL.OBJ differ
binary files /dev/null b/WOLFSRC/OBJ/SIGNON.OBJ differ
--- /dev/null
+++ b/WOLFSRC/OLDSCALE.C
@@ -1,0 +1,737 @@
+// WL_SCALE.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+
+#define OP_RETF	0xcb
+
+/*
+=============================================================================
+
+						  GLOBALS
+
+=============================================================================
+*/
+
+t_compscale _seg *scaledirectory[MAXSCALEHEIGHT+1];
+long			fullscalefarcall[MAXSCALEHEIGHT+1];
+
+int			maxscale,maxscaleshl2;
+
+/*
+=============================================================================
+
+						  LOCALS
+
+=============================================================================
+*/
+
+t_compscale 	_seg *work;
+unsigned BuildCompScale (int height, memptr *finalspot);
+
+int			stepbytwo;
+
+//===========================================================================
+
+/*
+==============
+=
+= BadScale
+=
+==============
+*/
+
+void far BadScale (void)
+{
+	Quit ("BadScale called!");
+}
+
+
+/*
+==========================
+=
+= SetupScaling
+=
+==========================
+*/
+
+void SetupScaling (int maxscaleheight)
+{
+	int		i,x,y;
+	byte	far *dest;
+
+	maxscaleheight/=2;			// one scaler every two pixels
+
+	maxscale = maxscaleheight-1;
+	maxscaleshl2 = maxscale<<2;
+
+//
+// free up old scalers
+//
+	for (i=1;i<MAXSCALEHEIGHT;i++)
+	{
+		if (scaledirectory[i])
+			MM_FreePtr (&(memptr)scaledirectory[i]);
+		if (i>=stepbytwo)
+			i += 2;
+	}
+	memset (scaledirectory,0,sizeof(scaledirectory));
+
+	MM_SortMem ();
+
+//
+// build the compiled scalers
+//
+	stepbytwo = viewheight/2;	// save space by double stepping
+	MM_GetPtr (&(memptr)work,20000);
+	if (mmerror)
+		return;
+
+	for (i=1;i<=maxscaleheight;i++)
+	{
+		BuildCompScale (i*2,&(memptr)scaledirectory[i]);
+		if (mmerror)
+		{
+			MM_FreePtr (&(memptr)work);
+			return;
+		}
+		if (i>=stepbytwo)
+			i+= 2;
+	}
+	MM_FreePtr (&(memptr)work);
+
+//
+// compact memory and lock down scalers
+//
+	MM_SortMem ();
+	for (i=1;i<=maxscaleheight;i++)
+	{
+		MM_SetLock (&(memptr)scaledirectory[i],true);
+		fullscalefarcall[i] = (unsigned)scaledirectory[i];
+		fullscalefarcall[i] <<=16;
+		fullscalefarcall[i] += scaledirectory[i]->codeofs[0];
+		if (i>=stepbytwo)
+		{
+			scaledirectory[i+1] = scaledirectory[i];
+			fullscalefarcall[i+1] = fullscalefarcall[i];
+			scaledirectory[i+2] = scaledirectory[i];
+			fullscalefarcall[i+2] = fullscalefarcall[i];
+			i+=2;
+		}
+	}
+	scaledirectory[0] = scaledirectory[1];
+	fullscalefarcall[0] = fullscalefarcall[1];
+
+//
+// check for oversize wall drawing
+//
+	for (i=maxscaleheight;i<MAXSCALEHEIGHT;i++)
+		fullscalefarcall[i] = (long)BadScale;
+
+}
+
+//===========================================================================
+
+/*
+========================
+=
+= BuildCompScale
+=
+= Builds a compiled scaler object that will scale a 64 tall object to
+= the given height (centered vertically on the screen)
+=
+= height should be even
+=
+= Call with
+= ---------
+= DS:SI		Source for scale
+= ES:DI		Dest for scale
+=
+= Calling the compiled scaler only destroys AL
+=
+========================
+*/
+
+unsigned BuildCompScale (int height, memptr *finalspot)
+{
+	byte		far *code;
+
+	int			i;
+	long		fix,step;
+	unsigned	src,totalscaled,totalsize;
+	int			startpix,endpix,toppix;
+
+
+	step = ((long)height<<16) / 64;
+	code = &work->code[0];
+	toppix = (viewheight-height)/2;
+	fix = 0;
+
+	for (src=0;src<=64;src++)
+	{
+		startpix = fix>>16;
+		fix += step;
+		endpix = fix>>16;
+
+		if (endpix>startpix)
+			work->width[src] = endpix-startpix;
+		else
+			work->width[src] = 0;
+
+//
+// mark the start of the code
+//
+		work->codeofs[src] = FP_OFF(code);
+
+//
+// compile some code if the source pixel generates any screen pixels
+//
+		startpix+=toppix;
+		endpix+=toppix;
+
+		if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64)
+			continue;
+
+	//
+	// mov al,[si+src]
+	//
+		*code++ = 0x8a;
+		*code++ = 0x44;
+		*code++ = src;
+
+		for (;startpix<endpix;startpix++)
+		{
+			if (startpix >= viewheight)
+				break;						// off the bottom of the view area
+			if (startpix < 0)
+				continue;					// not into the view area
+
+		//
+		// mov [es:di+heightofs],al
+		//
+			*code++ = 0x26;
+			*code++ = 0x88;
+			*code++ = 0x85;
+			*((unsigned far *)code)++ = startpix*SCREENBWIDE;
+		}
+
+	}
+
+//
+// retf
+//
+	*code++ = 0xcb;
+
+	totalsize = FP_OFF(code);
+	MM_GetPtr (finalspot,totalsize);
+	if (mmerror)
+		return 0;
+	_fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize);
+
+	return totalsize;
+}
+
+
+/*
+=======================
+=
+= ScaleLine
+=
+= linescale should have the high word set to the segment of the scaler
+=
+=======================
+*/
+
+extern	int			slinex,slinewidth;
+extern	unsigned	far *linecmds;
+extern	long		linescale;
+extern	unsigned	maskword;
+
+byte	mask1,mask2,mask3;
+
+
+void near ScaleLine (void)
+{
+asm	mov	cx,WORD PTR [linescale+2]
+asm	mov	es,cx						// segment of scaler
+
+asm	mov bp,WORD PTR [linecmds]
+asm	mov	dx,SC_INDEX+1				// to set SC_MAPMASK
+
+asm	mov	bx,[slinex]
+asm	mov	di,bx
+asm	shr	di,2						// X in bytes
+asm	add	di,[bufferofs]
+asm	and	bx,3
+asm	shl	bx,3
+asm	add	bx,[slinewidth]				// bx = (pixel*8+pixwidth)
+asm	mov	al,BYTE [mapmasks3-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ds,WORD PTR [linecmds+2]
+asm	or	al,al
+asm	jz	notthreebyte				// scale across three bytes
+asm	jmp	threebyte
+notthreebyte:
+asm	mov	al,BYTE PTR ss:[mapmasks2-1+bx]	// -1 because pixwidth of 1 is first
+asm	or	al,al
+asm	jnz	twobyte						// scale across two bytes
+
+//
+// one byte scaling
+//
+asm	mov	al,BYTE PTR ss:[mapmasks1-1+bx]	// -1 because pixwidth of 1 is first
+asm	out	dx,al						// set map mask register
+
+scalesingle:
+
+asm	mov	bx,[ds:bp]					// table location of rtl to patch
+asm	or	bx,bx
+asm	jz	linedone					// 0 signals end of segment list
+asm	mov	bx,[es:bx]
+asm	mov	dl,[es:bx]					// save old value
+asm	mov	BYTE PTR es:[bx],OP_RETF	// patch a RETF in
+asm	mov	si,[ds:bp+4]				// table location of entry spot
+asm	mov	ax,[es:si]
+asm	mov	WORD PTR ss:[linescale],ax	// call here to start scaling
+asm	mov	si,[ds:bp+2]				// corrected top of shape for this segment
+asm	add	bp,6						// next segment list
+
+asm	mov	ax,SCREENSEG
+asm	mov	es,ax
+asm	call ss:[linescale]				// scale the segment of pixels
+
+asm	mov	es,cx						// segment of scaler
+asm	mov	BYTE PTR es:[bx],dl			// unpatch the RETF
+asm	jmp	scalesingle					// do the next segment
+
+
+//
+// done
+//
+linedone:
+asm	mov	ax,ss
+asm	mov	ds,ax
+return;
+
+//
+// two byte scaling
+//
+twobyte:
+asm	mov	ss:[mask2],al
+asm	mov	al,BYTE PTR ss:[mapmasks1-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ss:[mask1],al
+
+scaledouble:
+
+asm	mov	bx,[ds:bp]					// table location of rtl to patch
+asm	or	bx,bx
+asm	jz	linedone					// 0 signals end of segment list
+asm	mov	bx,[es:bx]
+asm	mov	cl,[es:bx]					// save old value
+asm	mov	BYTE PTR es:[bx],OP_RETF	// patch a RETF in
+asm	mov	si,[ds:bp+4]				// table location of entry spot
+asm	mov	ax,[es:si]
+asm	mov	WORD PTR ss:[linescale],ax	// call here to start scaling
+asm	mov	si,[ds:bp+2]				// corrected top of shape for this segment
+asm	add	bp,6						// next segment list
+
+asm	mov	ax,SCREENSEG
+asm	mov	es,ax
+asm	mov	al,ss:[mask1]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	inc	di
+asm	mov	al,ss:[mask2]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	dec	di
+
+asm	mov	es,WORD PTR ss:[linescale+2] // segment of scaler
+asm	mov	BYTE PTR es:[bx],cl			// unpatch the RETF
+asm	jmp	scaledouble					// do the next segment
+
+
+//
+// three byte scaling
+//
+threebyte:
+asm	mov	ss:[mask3],al
+asm	mov	al,BYTE PTR ss:[mapmasks2-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ss:[mask2],al
+asm	mov	al,BYTE PTR ss:[mapmasks1-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ss:[mask1],al
+
+scaletriple:
+
+asm	mov	bx,[ds:bp]					// table location of rtl to patch
+asm	or	bx,bx
+asm	jz	linedone					// 0 signals end of segment list
+asm	mov	bx,[es:bx]
+asm	mov	cl,[es:bx]					// save old value
+asm	mov	BYTE PTR es:[bx],OP_RETF	// patch a RETF in
+asm	mov	si,[ds:bp+4]				// table location of entry spot
+asm	mov	ax,[es:si]
+asm	mov	WORD PTR ss:[linescale],ax	// call here to start scaling
+asm	mov	si,[ds:bp+2]				// corrected top of shape for this segment
+asm	add	bp,6						// next segment list
+
+asm	mov	ax,SCREENSEG
+asm	mov	es,ax
+asm	mov	al,ss:[mask1]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	inc	di
+asm	mov	al,ss:[mask2]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	inc	di
+asm	mov	al,ss:[mask3]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	dec	di
+asm	dec	di
+
+asm	mov	es,WORD PTR ss:[linescale+2] // segment of scaler
+asm	mov	BYTE PTR es:[bx],cl			// unpatch the RETF
+asm	jmp	scaletriple					// do the next segment
+
+
+}
+
+
+/*
+=======================
+=
+= ScaleShape
+=
+= Draws a compiled shape at [scale] pixels high
+=
+= each vertical line of the shape has a pointer to segment data:
+= 	end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
+= 	top of virtual line with segment in proper place
+=	start of segment pixel*2, used to jsl into compiled scaler
+=	<repeat>
+=
+= Setup for call
+= --------------
+= GC_MODE			read mode 1, write mode 2
+= GC_COLORDONTCARE  set to 0, so all reads from video memory return 0xff
+= GC_INDEX			pointing at GC_BITMASK
+=
+=======================
+*/
+
+static	long		longtemp;
+
+void ScaleShape (int xcenter, int shapenum, unsigned height)
+{
+	t_compshape	_seg *shape;
+	t_compscale _seg *comptable;
+	unsigned	scale,srcx,stopx,tempx;
+	int			t;
+	unsigned	far *cmdptr;
+	boolean		leftvis,rightvis;
+
+
+	shape = PM_GetSpritePage (shapenum);
+
+	scale = height>>3;						// low three bits are fractional
+	if (!scale || scale>maxscale)
+		return;								// too close or far away
+	comptable = scaledirectory[scale];
+
+	*(((unsigned *)&linescale)+1)=(unsigned)comptable;	// seg of far call
+	*(((unsigned *)&linecmds)+1)=(unsigned)shape;		// seg of shape
+
+//
+// scale to the left (from pixel 31 to shape->leftpix)
+//
+	srcx = 32;
+	slinex = xcenter;
+	stopx = shape->leftpix;
+	cmdptr = &shape->dataofs[31-stopx];
+
+	while ( --srcx >=stopx && slinex>0)
+	{
+		(unsigned)linecmds = *cmdptr--;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		if (slinewidth == 1)
+		{
+			slinex--;
+			if (slinex<viewwidth)
+			{
+				if (wallheight[slinex] >= height)
+					continue;		// obscured by closer wall
+				ScaleLine ();
+			}
+			continue;
+		}
+
+		//
+		// handle multi pixel lines
+		//
+		if (slinex>viewwidth)
+		{
+			slinex -= slinewidth;
+			slinewidth = viewwidth-slinex;
+			if (slinewidth<1)
+				continue;		// still off the right side
+		}
+		else
+		{
+			if (slinewidth>slinex)
+				slinewidth = slinex;
+			slinex -= slinewidth;
+		}
+
+
+		leftvis = (wallheight[slinex] < height);
+		rightvis = (wallheight[slinex+slinewidth-1] < height);
+
+		if (leftvis)
+		{
+			if (rightvis)
+				ScaleLine ();
+			else
+			{
+				while (wallheight[slinex+slinewidth-1] >= height)
+					slinewidth--;
+				ScaleLine ();
+			}
+		}
+		else
+		{
+			if (!rightvis)
+				continue;		// totally obscured
+
+			while (wallheight[slinex] >= height)
+			{
+				slinex++;
+				slinewidth--;
+			}
+			ScaleLine ();
+			break;			// the rest of the shape is gone
+		}
+	}
+
+
+//
+// scale to the right
+//
+	slinex = xcenter;
+	stopx = shape->rightpix;
+	if (shape->leftpix<31)
+	{
+		srcx = 31;
+		cmdptr = &shape->dataofs[32-shape->leftpix];
+	}
+	else
+	{
+		srcx = shape->leftpix-1;
+		cmdptr = &shape->dataofs[0];
+	}
+	slinewidth = 0;
+
+	while ( ++srcx <= stopx && (slinex+=slinewidth)<viewwidth)
+	{
+		(unsigned)linecmds = *cmdptr++;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		if (slinewidth == 1)
+		{
+			if (slinex>=0 && wallheight[slinex] < height)
+			{
+				ScaleLine ();
+			}
+			continue;
+		}
+
+		//
+		// handle multi pixel lines
+		//
+		if (slinex<0)
+		{
+			if (slinewidth <= -slinex)
+				continue;		// still off the left edge
+
+			slinewidth += slinex;
+			slinex = 0;
+		}
+		else
+		{
+			if (slinex + slinewidth > viewwidth)
+				slinewidth = viewwidth-slinex;
+		}
+
+
+		leftvis = (wallheight[slinex] < height);
+		rightvis = (wallheight[slinex+slinewidth-1] < height);
+
+		if (leftvis)
+		{
+			if (rightvis)
+			{
+				ScaleLine ();
+			}
+			else
+			{
+				while (wallheight[slinex+slinewidth-1] >= height)
+					slinewidth--;
+				ScaleLine ();
+				break;			// the rest of the shape is gone
+			}
+		}
+		else
+		{
+			if (rightvis)
+			{
+				while (wallheight[slinex] >= height)
+				{
+					slinex++;
+					slinewidth--;
+				}
+				ScaleLine ();
+			}
+			else
+				continue;		// totally obscured
+		}
+	}
+}
+
+
+
+/*
+=======================
+=
+= SimpleScaleShape
+=
+= NO CLIPPING, height in pixels
+=
+= Draws a compiled shape at [scale] pixels high
+=
+= each vertical line of the shape has a pointer to segment data:
+= 	end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
+= 	top of virtual line with segment in proper place
+=	start of segment pixel*2, used to jsl into compiled scaler
+=	<repeat>
+=
+= Setup for call
+= --------------
+= GC_MODE			read mode 1, write mode 2
+= GC_COLORDONTCARE  set to 0, so all reads from video memory return 0xff
+= GC_INDEX			pointing at GC_BITMASK
+=
+=======================
+*/
+
+void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
+{
+	t_compshape	_seg *shape;
+	t_compscale _seg *comptable;
+	unsigned	scale,srcx,stopx,tempx;
+	int			t;
+	unsigned	far *cmdptr;
+	boolean		leftvis,rightvis;
+
+
+	shape = PM_GetSpritePage (shapenum);
+
+	scale = height>>1;
+	comptable = scaledirectory[scale];
+
+	*(((unsigned *)&linescale)+1)=(unsigned)comptable;	// seg of far call
+	*(((unsigned *)&linecmds)+1)=(unsigned)shape;		// seg of shape
+
+//
+// scale to the left (from pixel 31 to shape->leftpix)
+//
+	srcx = 32;
+	slinex = xcenter;
+	stopx = shape->leftpix;
+	cmdptr = &shape->dataofs[31-stopx];
+
+	while ( --srcx >=stopx )
+	{
+		(unsigned)linecmds = *cmdptr--;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		slinex -= slinewidth;
+		ScaleLine ();
+	}
+
+
+//
+// scale to the right
+//
+	slinex = xcenter;
+	stopx = shape->rightpix;
+	if (shape->leftpix<31)
+	{
+		srcx = 31;
+		cmdptr = &shape->dataofs[32-shape->leftpix];
+	}
+	else
+	{
+		srcx = shape->leftpix-1;
+		cmdptr = &shape->dataofs[0];
+	}
+	slinewidth = 0;
+
+	while ( ++srcx <= stopx )
+	{
+		(unsigned)linecmds = *cmdptr++;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		ScaleLine ();
+		slinex+=slinewidth;
+	}
+}
+
+
+
+
+//
+// bit mask tables for drawing scaled strips up to eight pixels wide
+//
+// down here so the STUPID inline assembler doesn't get confused!
+//
+
+
+byte	mapmasks1[4][8] = {
+{1 ,3 ,7 ,15,15,15,15,15},
+{2 ,6 ,14,14,14,14,14,14},
+{4 ,12,12,12,12,12,12,12},
+{8 ,8 ,8 ,8 ,8 ,8 ,8 ,8} };
+
+byte	mapmasks2[4][8] = {
+{0 ,0 ,0 ,0 ,1 ,3 ,7 ,15},
+{0 ,0 ,0 ,1 ,3 ,7 ,15,15},
+{0 ,0 ,1 ,3 ,7 ,15,15,15},
+{0 ,1 ,3 ,7 ,15,15,15,15} };
+
+byte	mapmasks3[4][8] = {
+{0 ,0 ,0 ,0 ,0 ,0 ,0 ,0},
+{0 ,0 ,0 ,0 ,0 ,0 ,0 ,1},
+{0 ,0 ,0 ,0 ,0 ,0 ,1 ,3},
+{0 ,0 ,0 ,0 ,0 ,1 ,3 ,7} };
+
+
+unsigned	wordmasks[8][8] = {
+{0x0080,0x00c0,0x00e0,0x00f0,0x00f8,0x00fc,0x00fe,0x00ff},
+{0x0040,0x0060,0x0070,0x0078,0x007c,0x007e,0x007f,0x807f},
+{0x0020,0x0030,0x0038,0x003c,0x003e,0x003f,0x803f,0xc03f},
+{0x0010,0x0018,0x001c,0x001e,0x001f,0x801f,0xc01f,0xe01f},
+{0x0008,0x000c,0x000e,0x000f,0x800f,0xc00f,0xe00f,0xf00f},
+{0x0004,0x0006,0x0007,0x8007,0xc007,0xe007,0xf007,0xf807},
+{0x0002,0x0003,0x8003,0xc003,0xe003,0xf003,0xf803,0xfc03},
+{0x0001,0x8001,0xc001,0xe001,0xf001,0xf801,0xfc01,0xfe01} };
+
+int			slinex,slinewidth;
+unsigned	far *linecmds;
+long		linescale;
+unsigned	maskword;
+
--- /dev/null
+++ b/WOLFSRC/PICLIST.H
@@ -1,0 +1,36 @@
+//////////////////////////////////////
+//
+// Graphics .H file for .WL1
+// IGRAB-ed on Sat May 02 02:32:49 1992
+//
+//////////////////////////////////////
+
+typedef enum {
+		// Lump Start
+		H_BJPIC=3,
+		H_CASTLEPIC,                 // 4
+		H_KEYBOARDPIC,               // 5
+		H_JOYPIC,                    // 6
+		H_MOUSEPIC,                  // 7
+		H_BOTHPIC,                   // 8
+		H_GAMEPADPIC,                // 9
+		H_HEALPIC,                   // 10
+		H_TREASUREPIC,               // 11
+		H_GUNPIC,                    // 12
+		H_KEYPIC,                    // 13
+		H_BLAZEPIC,                  // 14
+		H_WEAPON1234PIC,             // 15
+		H_WOLFLOGOPIC,               // 16
+		H_VISAPIC,                   // 17
+		H_MCPIC,                     // 18
+		H_IDLOGOPIC,                 // 19
+		H_FAXPIC,                    // 20
+		H_GALACTIXPIC,               // 21
+		H_FGODMOMPIC,                // 22
+		H_AUSTRALIAPIC,              // 23
+		H_CANADAPIC,                 // 24
+		H_UKPIC,                     // 25
+		H_TOPWINDOWPIC,              // 26
+		H_LEFTWINDOWPIC,             // 27
+		H_RIGHTWINDOWPIC,            // 28
+		H_BOTTOMINFOPIC,             // 29
--- /dev/null
+++ b/WOLFSRC/README/LICENSE.DOC
@@ -1,0 +1,129 @@
+	LIMITED USE SOFTWARE LICENSE AGREEMENT
+
+	This Limited Use Software License Agreement (the "Agreement") 
+is a legal agreement between you, the end-user, and Id Software, Inc. 
+("ID").  By continuing the downloading of this Wolfenstein 3D 
+(the "Trademark") software material, which includes source code 
+(the "Source Code"), artwork data, music and software tools 
+(collectively, the "Software"), you are agreeing to be bound by the 
+terms of this Agreement.  If you do not agree to the terms of this 
+Agreement, promptly destroy the Software you may have downloaded.  
+
+ID SOFTWARE LICENSE
+
+	Grant of License.  ID grants to you the right to use one (1) 
+copy of the Software on a single computer.  You have no ownership or 
+proprietary rights in or to the Software, or the Trademark.  For purposes 
+of this section, "use" means loading the Software into RAM, as well as 
+installation on a hard disk or other storage device.  The Software, 
+together with any archive copy thereof, shall be destroyed when no longer 
+used in accordance with this Agreement, or when the right to use the 
+Software is terminated.  You agree that the Software will not be shipped, 
+transferred or exported into any country in violation of the U.S. 
+Export Administration Act (or any other law governing such matters) and 
+that you will not utilize, in any other manner, the Software in violation 
+of any applicable law.
+
+	Permitted Uses.  For educational purposes only, you, the end-user, 
+may use portions of the Source Code, such as particular routines, to 
+develop your own software, but may not duplicate the Source Code, except 
+as noted in paragraph 4.  The limited right referenced in the preceding 
+sentence is hereinafter referred to as "Educational Use."  By so exercising 
+the Educational Use right you shall not obtain any ownership, copyright,
+proprietary or other interest in or to the Source Code, or any portion of
+the Source Code.  You may dispose of your own software in your sole
+discretion.  With the exception of the Educational Use right, you may not
+otherwise use the Software, or an portion of the Software, which includes
+the Source Code, for commercial gain.
+
+	Prohibited Uses:  Under no circumstances shall you, the end-user, 
+be permitted, allowed or authorized to commercially exploit the Software.
+Neither you nor anyone at your direction shall do any of the following acts
+with regard to the Software, or any portion thereof:
+
+	Rent;
+
+	Sell;
+
+	Lease;
+
+	Offer on a pay-per-play basis;
+
+	Distribute for money or any other consideration; or
+
+	In any other manner and through any medium whatsoever commercially 
+exploit or use for any commercial purpose.
+
+Notwithstanding the foregoing prohibitions, you may commercially exploit the
+software you develop by exercising the Educational Use right, referenced in
+paragraph 2. hereinabove. 
+
+	Copyright.  The Software and all copyrights related thereto 
+(including all characters and other images generated by the Software 
+or depicted in the Software) are owned by ID and is protected by 
+United States copyright laws and international treaty provisions.  
+Id shall retain exclusive ownership and copyright in and to the Software 
+and all portions of the Software and you shall have no ownership or other 
+proprietary interest in such materials. You must treat the Software like 
+any other copyrighted material, except that you may either (a) make one 
+copy of the Software solely for back-up or archival purposes, or (b) 
+transfer the Software to a single hard disk provided you keep the original 
+solely for back-up or archival purposes.  You may not otherwise reproduce, 
+copy or disclose to others, in whole or in any part, the Software.  You 
+may not copy the written materials accompanying the Software.  You agree 
+to use your best efforts to see that any user of the Software licensed 
+hereunder complies with this Agreement.
+
+	NO WARRANTIES.  ID DISCLAIMS ALL WARRANTIES, BOTH EXPRESS IMPLIED,
+INCLUDING BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE WITH RESPECT TO THE SOFTWARE.  THIS LIMITED
+WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS.  YOU MAY HAVE OTHER RIGHTS WHICH
+VARY FROM JURISDICTION TO JURISDICTION.  ID DOES NOT WARRANT THAT THE
+OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED, ERROR FREE OR MEET YOUR
+SPECIFIC REQUIREMENTS.  THE WARRANTY SET FORTH ABOVE IS IN LIEU OF ALL OTHER
+EXPRESS WARRANTIES WHETHER ORAL OR WRITTEN.  THE AGENTS, EMPLOYEES,
+DISTRIBUTORS, AND DEALERS OF ID ARE NOT AUTHORIZED TO MAKE MODIFICATIONS TO
+THIS WARRANTY, OR ADDITIONAL WARRANTIES ON BEHALF OF ID. 
+
+	Exclusive Remedies.  The Software is being offered to you free of any
+charge.  You agree that you have no remedy against ID, its affiliates,
+contractors, suppliers, and agents for loss or damage caused by any defect
+or failure in the Software regardless of the form of action, whether in
+contract, tort, includinegligence, strict liability or otherwise, with
+regard to the Software.  This Agreement shall be construed in accordance
+with and governed by the laws of the State of Texas.  Copyright and other
+proprietary matters will be governed by United States laws and international
+treaties.  IN ANY CASE, ID SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF
+PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT OR OTHER
+SIMILAR DAMAGES ARISING FROM BREACH OF WARRANTY, BREACH OF CONTRACT,
+NEGLIGENCE, OR OTHER LEGAL THEORY EVEN IF ID OR ITS AGENT HAS BEEN ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
+Some jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so the above limitation or exclusion may not apply to
+you.
+
+	General Provisions.  Neither this Agreement nor any part or portion 
+hereof shall be assigned, sublicensed or otherwise transferred by you.  
+Should any provision of this Agreement be held to be void, invalid, 
+unenforceable or illegal by a court, the validity and enforceability of the 
+other provisions shall not be affected thereby.  If any provision is 
+determined to be unenforceable, you agree to a modification of such 
+provision to provide for enforcement of the provision's intent, to the 
+extent permitted by applicable law.  Failure of a party to enforce any 
+provision of this Agreement shall not constitute or be construed as a 
+waiver of such provision or of the right to enforce such provision.  If 
+you fail to comply with any terms of this Agreement, YOUR LICENSE IS 
+AUTOMATICALLY TERMINATED and you agree to the issuance of an injunction 
+against you in favor of Id.  You agree that Id shall not have to post 
+bond or other security to obtain an injunction against you to prohibit 
+you from violating Id's rights.
+
+	YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, THAT YOU 
+UNDERSTAND THIS AGREEMENT, AND UNDERSTAND THAT BY CONTINUING THE 
+DOWNLOADING OF THE SOFTWARE, YOU AGREE TO BE BOUND BY THIS AGREEMENT'S 
+TERMS AND CONDITIONS. YOU FURTHER AGREE THAT, EXCEPT FOR WRITTEN SEPARATE 
+AGREEMENTS BETWEEN ID AND YOU, THIS AGREEMENT IS A COMPLETE AND EXCLUSIVE 
+STATEMENT OF THE RIGHTS AND LIABILITIES OF THE PARTIES.  THIS AGREEMENT 
+SUPERSEDES ALL PRIOR ORAL AGREEMENTS, PROPOSALS OR UNDERSTANDINGS, AND 
+ANY OTHER COMMUNICATIONS BETWEEN ID AND YOU RELATING TO THE SUBJECT MATTER 
+OF THIS AGREEMENT 
--- /dev/null
+++ b/WOLFSRC/README/README.TXT
@@ -1,0 +1,8 @@
+NOTES:
+------
+
+This version will compile under BORLAND C++ 3.0/3.1 and compiled perfectly
+before it was uploaded. 
+
+Please do not send your questions to id Software.
+
--- /dev/null
+++ b/WOLFSRC/README/RELEASE.TXT
@@ -1,0 +1,53 @@
+We are releasing this code for the entertainment of the 
+user community.  We don't guarentee that anything even 
+builds in here.  Projects just seem to rot when you leave 
+them alone for long periods of time.
+
+This is all the source we have relating to the original 
+PC wolfenstein 3D project.  We haven't looked at this 
+stuff in years, and I would probably be horribly embarassed 
+to dig through my old code, so please don't ask any questions 
+about it. The original project was built in borland c++ 3.0.  
+I think some minor changes were required for later versions.
+
+You will need the data from a released version of wolf or spear 
+to use the exe built from this code.  You can just use a 
+shareware version if you are really cheap.
+
+
+Some coding comments in retrospect:
+
+The ray casting refresh architecture is still reasonably 
+appropriate for the game.  A BSP based texture mapper could 
+go faster, but ray casting was a lot simpler to do at the time.
+
+The dynamically compiled scaling routines are now a Bad Thing.  
+On uncached machines (the original target) they are the fastest 
+possible way to scale walls, but on modern processors you just 
+wind up thrashing the code cash and wrecking performance.  
+A simple looping texture mapper would be faster on 486+ machines.
+
+The whole page manager caching scheme is unecessarily complex.
+
+Way too many #ifdefs in the code!
+
+
+Some project ideas with this code:
+
+Add new monsters or weapons.
+
+Add taller walls and vertical motion.   This should only be 
+done if the texture mapper is rewritten.
+
+Convert to a 32 bit compiler.  This would be a fair amount 
+of work, but I would hate to even mess with crusty old 16 
+bit code.  The code would get a LOT smaller.
+
+Make a multi-player game that runs on DOOM sersetup / ipxsetup drivers.
+
+
+Have fun...
+
+John Carmack
+Technical Director
+Id Software
binary files /dev/null b/WOLFSRC/README/~$ICENSE.DOC differ
--- /dev/null
+++ b/WOLFSRC/RULES.ASI
@@ -1,0 +1,692 @@
+;[]-----------------------------------------------------------------[]
+;|      RULES.ASI  --  Rules & Structures for assembler              |
+;|                                                                   |
+;|      Turbo C++ Run Time Library                                   |
+;|                                                                   |
+;|      Copyright (c) 1987, 1991 by Borland International Inc.       |
+;|      All Rights Reserved.                                         |
+;[]-----------------------------------------------------------------[]
+
+;*** First we begin with a few of the major constants of C.
+
+false   equ     0       ; Beware !  For incoming parameters, non-false = true.
+true    equ     1       ; For results, we generate the proper numbers.
+
+lesser  equ    -1       ; Incoming, lesser < 0
+equal   equ     0
+greater equ     1       ; Incoming, greater > 0
+
+	PAGE
+;[]------------------------------------------------------------[]
+;|                                                              |
+;|      Conditional Assembly Directives                         |
+;|                                                              |
+;[]------------------------------------------------------------[]
+
+;memory model aliases, for the convenience of building the library
+
+IFDEF           __s__
+__SMALL__       equ     1
+ENDIF
+
+IFDEF           __c__
+__COMPACT__     equ     1
+ENDIF
+
+IFDEF           __m__
+__MEDIUM__      equ     1
+ENDIF
+
+IFDEF           __l__
+__LARGE__       equ     1
+ENDIF
+
+IFDEF           __h__
+__HUGE__        equ     1
+ENDIF
+
+IFNDEF __TINY__
+    IFNDEF __SMALL__
+	IFNDEF __MEDIUM__
+	    IFNDEF __COMPACT__
+		IFNDEF __LARGE__
+		    IFNDEF __HUGE__
+			%OUT  You must supply a model symbol.
+			.ERR
+		    ENDIF
+		ENDIF
+	    ENDIF
+	ENDIF
+    ENDIF
+ENDIF
+
+;bit masks to extract default pointer types from MMODEL (at run-time)
+FCODE           equ     8000h
+FDATA           equ     4000h
+
+IFDEF   __TINY__                ; Small Code - Small Data
+	LPROG           equ     false
+	LDATA           equ     false
+	MMODEL          equ     0       
+	_DSSTACK_       equ     <>
+ENDIF
+
+IFDEF   __SMALL__               ; Small Code - Small Data
+	LPROG           equ     false
+	LDATA           equ     false
+	MMODEL          equ     1       
+	_DSSTACK_       equ     <>
+ENDIF
+
+IFDEF   __MEDIUM__              ; Large Code - Small Data
+	LPROG           equ     true
+	LDATA           equ     false
+	MMODEL          equ     FCODE+2 
+	_DSSTACK_       equ     <>
+ENDIF
+
+IFDEF   __COMPACT__             ; Small Code - Large Data
+	LPROG           equ     false
+	LDATA           equ     true
+	MMODEL          equ     FDATA+3 
+ENDIF
+
+IFDEF   __LARGE__               ; Large Code - Large Data
+	LPROG           equ     true
+	LDATA           equ     true
+	MMODEL          equ     FCODE+FDATA+4
+ENDIF
+
+IFDEF   __HUGE__                ; Large Code - Large Data
+	LPROG           equ     true
+	LDATA           equ     true
+	MMODEL          equ     FCODE+FDATA+5
+ENDIF
+
+IF      LPROG
+	DIST            equ     FAR
+ELSE
+	DIST            equ     NEAR
+ENDIF
+
+	PAGE
+;[]------------------------------------------------------------[]
+;|                                                              |
+;|      Segment Declarations Macros                             |
+;|                                                              |
+;[]------------------------------------------------------------[]
+
+Code_Seg@       MACRO           ;; Open a Code Segment
+IFDEF __WINDOWS__
+_TEXT   SEGMENT WORD PUBLIC 'CODE'
+ELSE
+_TEXT   SEGMENT BYTE PUBLIC 'CODE'
+ENDIF
+	ASSUME  CS:_TEXT
+		ENDM
+
+Code_EndS@      MACRO           ;; Close a Code Segment
+_TEXT   ENDS
+		ENDM
+
+Data_Seg@       MACRO           ;; Open a Data Segment  (initialized)
+_DATA   SEGMENT WORD PUBLIC 'DATA'
+		ENDM
+
+Data_EndS@      MACRO           ;; Close a Data Segment (initialized)
+_DATA   ENDS
+		ENDM
+
+IFNDEF __HUGE__
+    BSS_Seg@        MACRO       ;; Open a Data Segment  (un-initialized)
+    _BSS    SEGMENT WORD PUBLIC 'BSS'
+	    ENDM
+
+    BSS_EndS@       MACRO       ;; Close a Data Segment (un-initialized)
+    _BSS    ENDS
+		    ENDM
+ENDIF
+
+FarData_Seg@    MACRO           ;; Open a FAR Data Segment
+_FARDATA        SEGMENT PARA PUBLIC 'FAR_DATA'
+		ENDM
+
+FarData_EndS@   MACRO           ;; Close a FAR Data Segment
+_FARDATA        ENDS
+		ENDM
+
+FarBSS_Seg@     MACRO           ;; Open a FAR BSS Segment
+_FARBSS         SEGMENT PARA PUBLIC 'FAR_BSS'
+		ENDM
+
+FarBSS_EndS@    MACRO           ;; Close a FAR BSS Segment
+_FARBSS         ENDS
+		ENDM
+
+Const_Seg@      MACRO           ;; Open a CONST Segment
+_CONST  SEGMENT WORD PUBLIC 'CONST'
+		ENDM
+
+Const_EndS@     MACRO           ;; Close a CONST Segment
+_CONST  ENDS
+		ENDM
+
+Init_Seg@       MACRO           ;; Open a INIT Segment
+_INIT_  SEGMENT WORD PUBLIC 'INITDATA'
+		ENDM
+
+Init_EndS@      MACRO           ;; Close a INIT Segment
+_INIT_  ENDS
+		ENDM
+
+Exit_Seg@       MACRO           ;; Open a EXIT Segment
+_EXIT_  SEGMENT WORD PUBLIC 'EXITDATA'
+		ENDM
+
+Exit_EndS@      MACRO           ;; Close a EXIT Segment
+_EXIT_  ENDS
+		ENDM
+
+CVT_Seg@        MACRO
+_CVTSEG SEGMENT WORD PUBLIC 'DATA'
+		ENDM
+
+CVT_EndS@       MACRO
+_CVTSEG ENDS
+		ENDM
+
+SCN_Seg@        MACRO
+_SCNSEG SEGMENT WORD PUBLIC 'DATA'
+		ENDM
+
+SCN_EndS@       MACRO
+_SCNSEG ENDS
+		ENDM
+
+Header@ MACRO
+Code_Seg@
+Code_EndS@
+Data_Seg@
+Data_EndS@
+BSS_Seg@
+BSS_EndS@
+	ASSUME  CS:_TEXT, DS:DGROUP
+	ENDM
+
+;[]------------------------------------------------------------[]
+;|                                                              |
+;|      Segment Definitions                                     |
+;|                                                              |
+;[]------------------------------------------------------------[]
+
+IFDEF __C0__
+
+IFDEF __WINDOWS__
+_TEXT           SEGMENT WORD PUBLIC 'CODE'
+		ENDS
+ELSE
+_TEXT           SEGMENT BYTE PUBLIC 'CODE'
+		ENDS
+ENDIF
+
+_FARDATA        SEGMENT PARA PUBLIC 'FAR_DATA'
+		ENDS
+
+_FARBSS         SEGMENT PARA PUBLIC 'FAR_BSS'
+		ENDS
+
+IFNDEF __WINDOWS__
+  IFNDEF __TINY__
+  _OVERLAY_       SEGMENT PARA PUBLIC 'OVRINFO'
+		  ENDS
+  _1STUB_         SEGMENT PARA PUBLIC 'STUBSEG'
+		  ENDS
+  ENDIF
+ENDIF
+
+IFDEF __WINDOWS__
+NULL            SEGMENT PARA PUBLIC 'BEGDATA'
+		ENDS
+ENDIF
+
+_DATA           SEGMENT PARA PUBLIC 'DATA'
+		ENDS
+		ENDS
+
+_CONST          SEGMENT WORD PUBLIC 'CONST'
+		ENDS
+
+IFDEF __WINDOWS__
+_FPSEG          SEGMENT WORD PUBLIC 'DATA'
+		ENDS
+ENDIF
+
+_CVTSEG         SEGMENT WORD PUBLIC 'DATA'
+		ENDS
+
+_SCNSEG         SEGMENT WORD PUBLIC 'DATA'
+		ENDS
+
+_INIT_          SEGMENT WORD PUBLIC 'INITDATA'
+InitStart       label byte
+		ENDS
+_INITEND_       SEGMENT BYTE PUBLIC 'INITDATA'
+InitEnd         label byte
+		ENDS
+
+_EXIT_          SEGMENT WORD PUBLIC 'EXITDATA'
+ExitStart       label byte
+		ENDS
+_EXITEND_       SEGMENT BYTE PUBLIC 'EXITDATA'
+ExitEnd         label byte
+		ENDS
+
+IFNDEF __HUGE__
+_BSS          SEGMENT WORD PUBLIC 'BSS'
+BeginBSS      label byte
+	      ENDS
+_BSSEND       SEGMENT BYTE PUBLIC 'BSSEND'
+EndBSS        label byte
+	      ENDS
+ENDIF
+
+
+IFDEF __WINDOWS__
+
+  IFDEF  __HUGE__
+  DGROUP GROUP NULL,_DATA,_CONST,_FPSEG,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_
+  ELSE
+  DGROUP GROUP NULL,_DATA,_CONST,_FPSEG,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
+  ENDIF
+
+ELSE
+
+IFNDEF __NOFLOAT__
+  IF LDATA
+    IFDEF  __HUGE__
+      DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_
+    ELSE
+      DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
+    ENDIF
+  ELSE
+    IFDEF __TINY__
+      DGROUP GROUP _TEXT,_DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
+    ELSE
+      DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
+    ENDIF
+  ENDIF
+ELSE
+  IF LDATA
+    IFDEF __HUGE__
+      DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_
+    ELSE
+      DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_BSS,_BSSEND
+    ENDIF
+  ELSE
+    IFDEF __TINY__
+      DGROUP GROUP _TEXT,_DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
+    ELSE
+      DGROUP GROUP _DATA,_CONST,_CVTSEG,_SCNSEG,_INIT_,_INITEND_,_EXIT_,_EXITEND_,_BSS,_BSSEND
+    ENDIF
+  ENDIF
+ENDIF ; __NOFLOAT__
+
+ENDIF ; __WINDOWS__
+
+ELSE
+
+Code_Seg@
+Code_EndS@
+Data_Seg@
+Data_EndS@
+DGROUP GROUP _DATA
+
+ENDIF ; __C0__
+
+	PAGE
+;[]------------------------------------------------------------[]
+;|                                                              |
+;|      Old Segment Declarations Macros                         |
+;|                                                              |
+;[]------------------------------------------------------------[]
+
+
+CSeg@           MACRO           ;; Open a Code Segment
+IFDEF __WINDOWS__
+_TEXT   SEGMENT WORD PUBLIC 'CODE'
+ELSE
+_TEXT   SEGMENT BYTE PUBLIC 'CODE'
+ENDIF
+	ASSUME  CS:_TEXT
+		ENDM
+
+CSegEnd@        MACRO           ;; Close a Code Segment
+_TEXT   ENDS
+		ENDM
+
+DSeg@           MACRO           ;; Open a Data Segment  (initialized)
+_DATA   SEGMENT WORD PUBLIC 'DATA'
+		ENDM
+
+DSegEnd@        MACRO           ;; Close a Data Segment (initialized)
+_DATA   ENDS
+		ENDM
+
+IFDEF __BSS__
+    IFNDEF __HUGE__
+	BSeg@           MACRO           ;; Open a Data Segment  (un-initialized)
+	_BSS    SEGMENT WORD PUBLIC 'BSS'
+		ENDM
+
+	BSegEnd@        MACRO           ;; Close a Data Segment (un-initialized)
+	_BSS    ENDS
+			ENDM
+    ENDIF
+ENDIF
+
+Header@ MACRO
+IFDEF __WINDOWS__
+_TEXT   SEGMENT WORD PUBLIC 'CODE'
+ELSE
+_TEXT   SEGMENT BYTE PUBLIC 'CODE'
+ENDIF
+_TEXT   ENDS
+_DATA   SEGMENT WORD PUBLIC 'DATA'
+_DATA   ENDS
+IFDEF __BSS__
+    IFNDEF  __HUGE__
+	_BSS    SEGMENT WORD PUBLIC 'BSS'
+	_BSS    ENDS
+    ENDIF
+ENDIF
+
+	ASSUME  CS:_TEXT, DS:DGROUP
+	ENDM
+
+	PAGE
+;[]------------------------------------------------------------[]
+;|                                                              |
+;|      C Naming Convention Macros                              |
+;|                                                              |
+;[]------------------------------------------------------------[]
+
+UNDERSCORE      EQU     1
+
+ExtSym@ MACRO   Sym, sType, sName
+	IFNB    <sName>
+	IFIDN   <sName>, <__PASCAL__>
+NAMING      =       0
+	ELSE
+NAMING      =       UNDERSCORE
+	ENDIF
+	ENDIF
+	IF      NAMING
+	EXTRN   _&Sym : sType
+Sym&@   equ     _&Sym
+	ELSE
+	EXTRN   Sym : sType
+Sym&@   equ     Sym
+	ENDIF
+	ENDM
+
+PubSym@ MACRO   Sym, Definition, sName
+	IFNB    <sName>
+	IFIDN   <sName>, <__PASCAL__>
+NAMING      =       0
+	ELSE
+NAMING      =       UNDERSCORE
+	ENDIF
+	ENDIF
+	IF      NAMING
+	PUBLIC  _&Sym
+_&Sym   Definition
+Sym&@   equ     _&Sym
+	ELSE
+	PUBLIC  Sym
+Sym     Definition
+Sym&@   equ     Sym
+	ENDIF
+	ENDM
+
+Static@ MACRO   Sym, Definition, sName
+	IFNB    <sName>
+	IFIDN   <sName>, <__PASCAL__>
+NAMING      =       0
+	ELSE
+NAMING      =       UNDERSCORE
+	ENDIF
+	ENDIF
+	IF      NAMING
+_&Sym   Definition
+Sym&@   equ     _&Sym
+	ELSE
+Sym     Definition
+Sym&@   equ     Sym
+	ENDIF
+	ENDM
+
+	PAGE
+;[]------------------------------------------------------------[]
+;|                                                              |
+;|      Macros which are Data Size Dependent                    |
+;|                                                              |
+;[]------------------------------------------------------------[]
+
+IF      LDATA
+DPTR_           equ     DWORD PTR
+dPtrSize        equ     4
+LES_            equ     LES
+ES_             equ     ES:
+SS_             equ     SS:
+LDS_            equ     LDS
+
+pushDS_         MACRO
+		PUSH    DS
+		ENDM
+
+popDS_          MACRO
+		POP    DS
+		ENDM
+
+PushPtr         MACRO   dPtrOff, dPtrSeg
+		PUSH    dPtrSeg
+		PUSH    dPtrOff
+		ENDM
+
+
+dPtr@           MACRO   Sym, VALUE, sName       ;; Static Data pointer
+Static@         Sym, <DD        VALUE>, sName
+		ENDM
+
+dPtrPub@        MACRO   Sym, VALUE, sName       ;; Global Data Pointer
+PubSym@         Sym, <DD        VALUE>, sName
+		ENDM
+
+dPtrExt@        MACRO   Sym, sName      ;; External Data Pointer
+ExtSym@         Sym, DWORD, sName
+		ENDM
+ELSE
+DPTR_           equ     WORD PTR
+dPtrSize        equ     2
+LES_            equ     MOV
+ES_             equ     DS:
+SS_             equ     DS:
+LDS_            equ     MOV
+
+pushDS_         MACRO
+		ENDM
+
+popDS_          MACRO
+		ENDM
+
+PushPtr         MACRO   dPtrOff, dPtrSeg
+		PUSH    dPtrOff
+		ENDM
+
+dPtr@           MACRO   Sym, VALUE, sName       ;; Static Data pointer
+Static@         Sym, <DW        VALUE>, sName
+		ENDM
+
+dPtrPub@        MACRO   Sym, VALUE, sName       ;; Global Data Pointer
+PubSym@         Sym, <DW        VALUE>, sName
+		ENDM
+
+dPtrExt@        MACRO   Sym, sName      ;; External Data Pointer
+ExtSym@         Sym, WORD, sName
+		ENDM
+ENDIF
+	PAGE
+;[]------------------------------------------------------------[]
+;|                                                              |
+;|      Macros which are Code Size Dependent                    |
+;|                                                              |
+;[]------------------------------------------------------------[]
+
+IF      LPROG
+CPTR_           equ     DWORD PTR
+cPtrSize        equ     4
+
+Proc@           MACRO   Sym, sName      ;; Open a Static function
+Static@         Sym, <PROC      FAR>, sName
+		ENDM
+
+PubProc@        MACRO   Sym, sName      ;; Open a Public function
+PubSym@         Sym, <PROC      FAR>, sName
+		ENDM
+
+ExtProc@        MACRO   Sym, sName      ;; External Function
+ExtSym@         Sym, FAR, sName
+		ENDM
+
+cPtr@           MACRO   Sym, VALUE, sName       ;; Static Function pointer
+Static@         Sym, <DD        VALUE>, sName
+		ENDM
+
+cPtrPub@        MACRO   Sym, VALUE, sName;; Global Function Pointer
+PubSym@         Sym, <DD        VALUE>, sName
+		ENDM
+
+cPtrExt@        MACRO   Sym, sName      ;; External Function Pointer
+ExtSym@         Sym, DWORD, sName
+		ENDM
+ELSE
+CPTR_           equ     WORD PTR
+cPtrSize        equ     2
+
+Proc@           MACRO   Sym, sName      ;; Open a Static function
+Static@         Sym, <PROC      NEAR>, sName
+		ENDM
+
+PubProc@        MACRO   Sym, sName      ;; Open a Public function
+PubSym@         Sym, <PROC      NEAR>, sName
+		ENDM
+
+ExtProc@        MACRO   Sym, sName      ;; External Function
+ExtSym@         Sym, NEAR, sName
+		ENDM
+
+cPtr@           MACRO   Sym, VALUE, sName       ;; Static Function pointer
+Static@         Sym, <DW        VALUE>, sName
+		ENDM
+
+cPtrPub@        MACRO   Sym, VALUE, sName       ;; Global Function Pointer
+PubSym@         Sym, <DW        VALUE>, sName
+		ENDM
+
+cPtrExt@        MACRO   Sym, sName      ;; External Function Pointer
+ExtSym@         Sym, WORD, sName
+		ENDM
+ENDIF
+
+EndProc@        MACRO   Sym, sName      ;; Close a function
+Static@         Sym, ENDP, sName
+		ENDM
+
+	PAGE
+;[]------------------------------------------------------------[]
+;|                                                              |
+;|      Miscellaneous Definitions                               |
+;|                                                              |
+;[]------------------------------------------------------------[]
+
+;*** Set up some macros for procedure parameters and export/import
+
+nearCall        STRUC
+nearBP          dw      ?
+nearIP          dw      ?
+nearParam       dw      ?
+nearCall        ENDS
+
+farCall         STRUC
+farBP           dw      ?
+farCSIP         dd      ?
+aParam          dw      ?
+farCall         ENDS
+
+;*** Next, we define some convenient structures to access the parts
+;       of larger objects.
+
+_twoBytes       STRUC
+BY0     db      ?
+BY1     db      ?
+_twoBytes       ENDS
+
+_fourWords      STRUC
+W0      dw      ?
+W1      dw      ?
+W2      dw      ?
+W3      dw      ?
+_fourWords      ENDS
+
+_twoDwords      STRUC
+DD0     dd      ?
+DD1     dd      ?
+_twoDwords      ENDS
+
+_aFloat         STRUC
+double          dq      ?
+_aFloat         ENDS
+
+; How to invoke MSDOS.
+
+MSDOS@  MACRO
+	int     21h
+	ENDM
+	PAGE
+
+; The next section concerns the use of registers.  SI and DI are used
+;       for register variables, and must be conserved.
+
+; Registers AX, BX, CX, DX will not be preserved across function calls.
+
+; Firstly, the registers to be conserved through function calls, including
+;       the setup of local variables.
+
+link@   MACRO   _si,_di,_ES,locals
+	push    bp
+	mov     bp, sp
+	IFNB    <locals>
+		lea     sp, locals
+	ENDIF
+	IFNB    <_si>
+		push    si
+	ENDIF
+	IFNB    <_di>
+		push    di
+	ENDIF
+ENDM
+
+unLink@ MACRO   _si,_di,_ES,locals
+	IFNB    <_di>
+		pop     di
+	ENDIF
+	IFNB    <_si>
+		pop     si
+	ENDIF
+	IFNB    <locals>
+		mov     sp, bp
+	ENDIF
+	pop     bp
+ENDM
+
+.LIST
--- /dev/null
+++ b/WOLFSRC/SDMVER.H
@@ -1,0 +1,8 @@
+#define SPEAR
+#define SPEARDEMO
+#define ARTSEXTERN
+#define DEMOSEXTERN
+#define CARMACIZED
+//#define MYPROFILE
+//#define DEBCHECK
+//#define UPLOAD
--- /dev/null
+++ b/WOLFSRC/SHAREMSG.H
@@ -1,0 +1,9 @@
+"This game is shareware.\n"
+"Share it with everyone.\n"
+"Thanks.\n\n"
+"       Id Software\n"
+
+"This game is NOT shareware.\n"
+"Please do not distribute it.\n"
+"Thanks.\n\n"
+"       Id Software\n"
--- /dev/null
+++ b/WOLFSRC/SODVER.H
@@ -1,0 +1,7 @@
+#define SPEAR
+#define ARTSEXTERN
+#define DEMOSEXTERN
+#define CARMACIZED
+//#define MYPROFILE
+//#define DEBCHECK
+//#define UPLOAD
--- /dev/null
+++ b/WOLFSRC/SPANISH.H
@@ -1,0 +1,112 @@
+#define  QUITSUR  	"Estas seguro que quieres\n"\
+					"parar este gran juego?"
+
+#define  CURGAME  	"Ahora estas en\n"\
+					"un juego. Si continuas\n"\
+					"borras el juego viejo. O.K.?"
+
+#define  GAMESVD  "Ya hay un juego\n"\
+				  "guardado en esta posicion.\n"\
+				  "sobre-escribir?"
+
+#define  ENDGAMESTR  "Estas seguro que quieres\n"\
+					 "terminar el juego que\n"\
+					 "estas jugando?  (S  o  N):"
+
+#define   STR_NG    "Juego nuevo"
+#define   STR_SD    "Sonido"
+#define   STR_CL    "Control"
+#define   STR_LG    "Cargar juego"
+#define   STR_SG    "Guardar juego"
+#define   STR_CV    "Cambiar vista"
+#define   STR_VS    "Ver anotacion"
+#define  STR_EG     "Abandonar"
+#define   STR_BD    "Regresar al demo"
+#define  STR_QT     "Parar"
+
+#define  STR_LOADING  "Cargando"
+#define  STR_SAVING   "Guardando"
+
+#define  STR_GAME  "Regresar, jugar"
+#define  STR_DEMO  "Regresar al Demo"
+#define  STR_LGC         "Cargar juego llamado\n\""
+#define  STR_EMPTY       "vacio"
+#define  STR_CALIB       "Calibrar"
+#define  STR_JOYST       "Joystick"
+#define  STR_MOVEJOY 	"Mover joystick a\n"\
+						"arriba izq y\n"\
+						"oprimir boton 0\n"
+#define  STR_MOVEJOY2  	"Mover joystick a\n"\
+						"abajo derecha y\n"\
+						"oprimir boton 1\n"
+#define  STR_ESCEXIT     "ESC para salir"
+#define  STR_NONE  "Ninguno"
+#define   STR_PC         "P.C. bocina"
+#define   STR_ALSB       "AdLib/Sound Blaster"
+#define   STR_DISNEY  "Disney Sound Source"
+#define   STR_SB         "Sound Blaster"
+
+#define   STR_MOUSEEN         "Raton activado"
+#define   STR_JOYEN   "Joystick activado"
+#define   STR_PORT2   "Use joystick puerto 2"
+#define   STR_GAMEPAD         "Gravis Gamepad Activada"
+#define   STR_SENS  "Raton Sensibilidad"
+#define   STR_CUSTOM     "Modificar controles"
+#define   STR_DADDY   "Papi puedo jugar?"
+#define   STR_HURTME   "No me hieras."
+#define   STR_BRINGEM    "�Echamelos!"
+#define   STR_DEATH "La muerte encarnada"
+
+#define   STR_MOUSEADJ  "Raton ajustar sensibilidad"
+#define  STR_SLOW  "Lento"
+#define  STR_FAST   "Rapido"
+
+#define   STR_CRUN  "Corre"
+#define  STR_COPEN       "Abre"
+#define  STR_CFIRE        "Fuego"
+#define  STR_CSTRAFE     "Ametrallar"
+
+#define   STR_LEFT       "Izquierda"
+#define   STR_RIGHT "Derecha"
+#define   STR_FRWD  "Adelante"
+#define   STR_BKWD  "Atras"
+#define   STR_THINK "Pensando"
+
+#define   STR_SIZE1 "Use flechas para ajustar"
+#define   STR_SIZE2 "Enter para aceptar"
+#define   STR_SIZE3 "Esc para cancelar"
+
+#define   STR_YOUWIN     "Tu ganas"
+
+#define   STR_TOTALTIME  "Tiempo total"
+
+#define   STR_RATKILL       "Muertes    %"
+#define   STR_RATSECRET  	"Secreto    %"
+#define   STR_RATTREASURE   "Tesoros    %"
+
+#define   STR_BONUS 	"Bono"
+#define   STR_TIME      "Tiempo"
+#define   STR_PAR       "Par"
+
+#define   STR_RAT2KILL   	"Muertes    %" // ratio = promedio
+#define   STR_RAT2SECRET   	"Secreto    %"
+#define   STR_RAT2TREASURE  "Tesoros    %"
+
+#define   STR_DEFEATED   "Derrotado!"
+
+#define   STR_CHEATER1  "Ahora tienes 100% salud"
+#define   STR_CHEATER2   "99 balas y dos llaves"
+#define   STR_CHEATER3   "Notar que has basicamente"
+#define   STR_CHEATER4   "eliminado tus chances de"
+#define   STR_CHEATER5   "obtener puntos altos"
+
+#define   STR_NOSPACE1   "No hay suficiente espacio"
+#define   STR_NOSPACE2   "en tu disco para guardar juego"
+
+#define   STR_SAVECHT1   "Tu archivo para guardar juego es"
+#define   STR_SAVECHT2   "diremos,\"corrupto\"."
+#define   STR_SAVECHT3   "Pero te dire, sigue y"
+#define  STR_SAVECHT4   "de todos modos juega"
+
+#define   STR_SEEAGAIN      "Veamos eso de nuevo"
+
--- /dev/null
+++ b/WOLFSRC/SPANVER.H
@@ -1,0 +1,8 @@
+//#define SPEAR
+#define SPANISH
+#define ARTSEXTERN
+#define DEMOSEXTERN
+//#define MYPROFILE
+//#define DEBCHECK
+#define CARMACIZED
+//#define UPLOAD
binary files /dev/null b/WOLFSRC/SV.EXE differ
--- /dev/null
+++ b/WOLFSRC/VERSION.H
@@ -1,0 +1,10 @@
+//#define SPEAR
+//#define JAPAN
+#define GOODTIMES
+#define ARTSEXTERN
+#define DEMOSEXTERN
+//#define MYPROFILE
+//#define DEBCHECK
+#define CARMACIZED
+//#define UPLOAD
+
\ No newline at end of file
--- /dev/null
+++ b/WOLFSRC/WHACK_A.ASM
@@ -1,0 +1,100 @@
+; WOLFHACK.ASM
+
+.386C
+IDEAL
+MODEL	MEDIUM,C
+
+
+;============================================================================
+
+DATASEG
+
+EXTRN	mr_rowofs:WORD
+EXTRN	mr_count:WORD
+EXTRN	mr_xstep:WORD
+EXTRN	mr_ystep:WORD
+EXTRN	mr_xfrac:WORD
+EXTRN	mr_yfrac:WORD
+EXTRN	mr_dest:WORD
+
+FARDATA
+
+planepics	db	8192 dup(?)	;	// 4k of ceiling, 4k of floor
+PUBLIC	planepics
+
+
+;============================================================================
+
+CODESEG
+
+;============================
+;
+; MapRow
+;
+;
+;============================
+
+PROC	MapRow
+PUBLIC	MapRow
+	push	esi
+	push	edi
+	push	ebp
+	push 	ds
+
+	mov     bp,[mr_rowofs]
+	mov		cx,[mr_count]
+	mov		dx,[mr_ystep]
+	shl		edx,16
+	mov		dx,[mr_xstep]
+	mov		si,[mr_yfrac]
+	shl		esi,16
+	mov		si,[mr_xfrac]
+	mov		di,[mr_dest]
+	mov		ax,SEG planepics
+	mov		ds,ax
+	mov		ax,0a000h
+	mov		es,ax
+	mov		ax,1111111111110b
+
+; eax		color lookup
+; ebx		scratch offset and pixel values
+; ecx     	loop counter
+; edx		packed x / y step values
+; esi		packed x / y fractional values
+; edi		write pointer
+; ebp		toprow to bottomrow delta
+; es:		screenseg
+; ds:		pictures
+
+; mov	al,[esi]
+; mov	al,[eax]
+; mov	[edi],al
+
+; mov   ax,[_variable+ebx+2]
+
+
+pixelloop:
+	shld	ebx,esi,22				; shift y units in
+	shld	ebx,esi,7				; shift x units in and one extra bit
+	and		bx,63*65*2				; mask off extra top bits and 0 low bit
+	add		esi,edx					; position += step
+	mov		al,[bx]
+	mov		al,[eax]
+	mov     [es:di],al     			; write ceiling pixel
+	mov		al,[bx+1]
+	mov		al,[eax]
+	mov     [es:di+bp],al     		; write floor pixel
+	inc		di
+	loop	pixelloop
+
+	pop		ds
+	pop		ebp
+	pop		edi
+	pop		esi
+
+	retf
+
+ENDP
+
+END
+
--- /dev/null
+++ b/WOLFSRC/WLFJ1VER.H
@@ -1,0 +1,9 @@
+//#define SPEAR
+#define JAPAN
+#define JAPDEMO
+#define UPLOAD
+#define ARTSEXTERN
+#define DEMOSEXTERN
+//#define MYPROFILE
+//#define DEBCHECK
+#define CARMACIZED
--- /dev/null
+++ b/WOLFSRC/WL_ACT1.C
@@ -1,0 +1,900 @@
+// WL_ACT1.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+
+/*
+=============================================================================
+
+							STATICS
+
+=============================================================================
+*/
+
+
+statobj_t	statobjlist[MAXSTATS],*laststatobj;
+
+
+struct
+{
+	int		picnum;
+	stat_t	type;
+} statinfo[] =
+{
+{SPR_STAT_0},					// puddle          spr1v
+{SPR_STAT_1,block},				// Green Barrel    "
+{SPR_STAT_2,block},				// Table/chairs    "
+{SPR_STAT_3,block},				// Floor lamp      "
+{SPR_STAT_4},					// Chandelier      "
+{SPR_STAT_5,block},				// Hanged man      "
+{SPR_STAT_6,bo_alpo},			// Bad food        "
+{SPR_STAT_7,block},				// Red pillar      "
+//
+// NEW PAGE
+//
+{SPR_STAT_8,block},				// Tree            spr2v
+{SPR_STAT_9},					// Skeleton flat   "
+{SPR_STAT_10,block},			// Sink            " (SOD:gibs)
+{SPR_STAT_11,block},			// Potted plant    "
+{SPR_STAT_12,block},			// Urn             "
+{SPR_STAT_13,block},			// Bare table      "
+{SPR_STAT_14},					// Ceiling light   "
+#ifndef SPEAR
+{SPR_STAT_15},					// Kitchen stuff   "
+#else
+{SPR_STAT_15,block},			// Gibs!
+#endif
+//
+// NEW PAGE
+//
+{SPR_STAT_16,block},			// suit of armor   spr3v
+{SPR_STAT_17,block},			// Hanging cage    "
+{SPR_STAT_18,block},			// SkeletoninCage  "
+{SPR_STAT_19},					// Skeleton relax  "
+{SPR_STAT_20,bo_key1},			// Key 1           "
+{SPR_STAT_21,bo_key2},			// Key 2           "
+{SPR_STAT_22,block},			// stuff				(SOD:gibs)
+{SPR_STAT_23},					// stuff
+//
+// NEW PAGE
+//
+{SPR_STAT_24,bo_food}, 			// Good food       spr4v
+{SPR_STAT_25,bo_firstaid},		// First aid       "
+{SPR_STAT_26,bo_clip},			// Clip            "
+{SPR_STAT_27,bo_machinegun},	// Machine gun     "
+{SPR_STAT_28,bo_chaingun},		// Gatling gun     "
+{SPR_STAT_29,bo_cross},			// Cross           "
+{SPR_STAT_30,bo_chalice},		// Chalice         "
+{SPR_STAT_31,bo_bible},			// Bible           "
+//
+// NEW PAGE
+//
+{SPR_STAT_32,bo_crown},			// crown           spr5v
+{SPR_STAT_33,bo_fullheal},		// one up          "
+{SPR_STAT_34,bo_gibs},			// gibs            "
+{SPR_STAT_35,block},			// barrel          "
+{SPR_STAT_36,block},			// well            "
+{SPR_STAT_37,block},			// Empty well      "
+{SPR_STAT_38,bo_gibs},			// Gibs 2          "
+{SPR_STAT_39,block},			// flag				"
+//
+// NEW PAGE
+//
+#ifndef SPEAR
+{SPR_STAT_40,block},			// Call Apogee		spr7v
+#else
+{SPR_STAT_40},					// Red light
+#endif
+//
+// NEW PAGE
+//
+{SPR_STAT_41},					// junk            "
+{SPR_STAT_42},					// junk 		   "
+{SPR_STAT_43},					// junk            "
+#ifndef SPEAR
+{SPR_STAT_44},					// pots            "
+#else
+{SPR_STAT_44,block},			// Gibs!
+#endif
+{SPR_STAT_45,block},			// stove           " (SOD:gibs)
+{SPR_STAT_46,block},			// spears          " (SOD:gibs)
+{SPR_STAT_47},					// vines			"
+//
+// NEW PAGE
+//
+#ifdef SPEAR
+{SPR_STAT_48,block},			// marble pillar
+{SPR_STAT_49,bo_25clip},		// bonus 25 clip
+{SPR_STAT_50,block},			// truck
+{SPR_STAT_51,bo_spear},			// SPEAR OF DESTINY!
+#endif
+
+{SPR_STAT_26,bo_clip2},			// Clip            "
+{-1}							// terminator
+};
+
+/*
+===============
+=
+= InitStaticList
+=
+===============
+*/
+
+void InitStaticList (void)
+{
+	laststatobj = &statobjlist[0];
+}
+
+
+
+/*
+===============
+=
+= SpawnStatic
+=
+===============
+*/
+
+void SpawnStatic (int tilex, int tiley, int type)
+{
+	laststatobj->shapenum = statinfo[type].picnum;
+	laststatobj->tilex = tilex;
+	laststatobj->tiley = tiley;
+	laststatobj->visspot = &spotvis[tilex][tiley];
+
+	switch (statinfo[type].type)
+	{
+	case block:
+		(unsigned)actorat[tilex][tiley] = 1;		// consider it a blocking tile
+	case dressing:
+		laststatobj->flags = 0;
+		break;
+
+	case	bo_cross:
+	case	bo_chalice:
+	case	bo_bible:
+	case	bo_crown:
+	case	bo_fullheal:
+		if (!loadedgame)
+		  gamestate.treasuretotal++;
+
+	case	bo_firstaid:
+	case	bo_key1:
+	case	bo_key2:
+	case	bo_key3:
+	case	bo_key4:
+	case	bo_clip:
+	case	bo_25clip:
+	case	bo_machinegun:
+	case	bo_chaingun:
+	case	bo_food:
+	case	bo_alpo:
+	case	bo_gibs:
+	case	bo_spear:
+		laststatobj->flags = FL_BONUS;
+		laststatobj->itemnumber = statinfo[type].type;
+		break;
+	}
+
+	laststatobj++;
+
+	if (laststatobj == &statobjlist[MAXSTATS])
+		Quit ("Too many static objects!\n");
+}
+
+
+/*
+===============
+=
+= PlaceItemType
+=
+= Called during game play to drop actors' items.  It finds the proper
+= item number based on the item type (bo_???).  If there are no free item
+= spots, nothing is done.
+=
+===============
+*/
+
+void PlaceItemType (int itemtype, int tilex, int tiley)
+{
+	int			type;
+	statobj_t	*spot;
+
+//
+// find the item number
+//
+	for (type=0 ;  ; type++)
+	{
+		if (statinfo[type].picnum == -1)		// end of list
+			Quit ("PlaceItemType: couldn't find type!");
+		if (statinfo[type].type == itemtype)
+			break;
+	}
+
+//
+// find a spot in statobjlist to put it in
+//
+	for (spot=&statobjlist[0] ; ; spot++)
+	{
+		if (spot==laststatobj)
+		{
+			if (spot == &statobjlist[MAXSTATS])
+				return;							// no free spots
+			laststatobj++;						// space at end
+			break;
+		}
+
+		if (spot->shapenum == -1)				// -1 is a free spot
+			break;
+	}
+//
+// place it
+//
+	spot->shapenum = statinfo[type].picnum;
+	spot->tilex = tilex;
+	spot->tiley = tiley;
+	spot->visspot = &spotvis[tilex][tiley];
+	spot->flags = FL_BONUS;
+	spot->itemnumber = statinfo[type].type;
+}
+
+
+
+/*
+=============================================================================
+
+							DOORS
+
+doorobjlist[] holds most of the information for the doors
+
+doorposition[] holds the amount the door is open, ranging from 0 to 0xffff
+	this is directly accessed by AsmRefresh during rendering
+
+The number of doors is limited to 64 because a spot in tilemap holds the
+	door number in the low 6 bits, with the high bit meaning a door center
+	and bit 6 meaning a door side tile
+
+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.
+
+=============================================================================
+*/
+
+#define DOORWIDTH	0x7800
+#define OPENTICS	300
+
+doorobj_t	doorobjlist[MAXDOORS],*lastdoorobj;
+int			doornum;
+
+unsigned	doorposition[MAXDOORS];		// leading edge of door 0=closed
+										// 0xffff = fully open
+
+byte		far areaconnect[NUMAREAS][NUMAREAS];
+
+boolean		areabyplayer[NUMAREAS];
+
+
+/*
+==============
+=
+= ConnectAreas
+=
+= Scans outward from playerarea, marking all connected areas
+=
+==============
+*/
+
+void RecursiveConnect (int areanumber)
+{
+	int	i;
+
+	for (i=0;i<NUMAREAS;i++)
+	{
+		if (areaconnect[areanumber][i] && !areabyplayer[i])
+		{
+			areabyplayer[i] = true;
+			RecursiveConnect (i);
+		}
+	}
+}
+
+
+void ConnectAreas (void)
+{
+	memset (areabyplayer,0,sizeof(areabyplayer));
+	areabyplayer[player->areanumber] = true;
+	RecursiveConnect (player->areanumber);
+}
+
+
+void InitAreas (void)
+{
+	memset (areabyplayer,0,sizeof(areabyplayer));
+	areabyplayer[player->areanumber] = true;
+}
+
+
+
+/*
+===============
+=
+= InitDoorList
+=
+===============
+*/
+
+void InitDoorList (void)
+{
+	memset (areabyplayer,0,sizeof(areabyplayer));
+	_fmemset (areaconnect,0,sizeof(areaconnect));
+
+	lastdoorobj = &doorobjlist[0];
+	doornum = 0;
+}
+
+
+/*
+===============
+=
+= SpawnDoor
+=
+===============
+*/
+
+void SpawnDoor (int tilex, int tiley, boolean vertical, int lock)
+{
+	int	areanumber;
+	unsigned	far *map;
+
+	if (doornum==64)
+		Quit ("64+ doors on level!");
+
+	doorposition[doornum] = 0;		// doors start out fully closed
+	lastdoorobj->tilex = tilex;
+	lastdoorobj->tiley = tiley;
+	lastdoorobj->vertical = vertical;
+	lastdoorobj->lock = lock;
+	lastdoorobj->action = dr_closed;
+
+	(unsigned)actorat[tilex][tiley] = doornum | 0x80;	// consider it a solid wall
+
+//
+// make the door tile a special tile, and mark the adjacent tiles
+// for door sides
+//
+	tilemap[tilex][tiley] = doornum | 0x80;
+	map = mapsegs[0] + farmapylookup[tiley]+tilex;
+	if (vertical)
+	{
+		*map = *(map-1);                        // set area number
+		tilemap[tilex][tiley-1] |= 0x40;
+		tilemap[tilex][tiley+1] |= 0x40;
+	}
+	else
+	{
+		*map = *(map-mapwidth);					// set area number
+		tilemap[tilex-1][tiley] |= 0x40;
+		tilemap[tilex+1][tiley] |= 0x40;
+	}
+
+	doornum++;
+	lastdoorobj++;
+}
+
+//===========================================================================
+
+/*
+=====================
+=
+= 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
+}
+
+
+/*
+=====================
+=
+= CloseDoor
+=
+=====================
+*/
+
+void CloseDoor (int door)
+{
+	int	tilex,tiley,area;
+	objtype *check;
+
+//
+// don't close on anything solid
+//
+	tilex = doorobjlist[door].tilex;
+	tiley = doorobjlist[door].tiley;
+
+	if (actorat[tilex][tiley])
+		return;
+
+	if (player->tilex == tilex && player->tiley == tiley)
+		return;
+
+	if (doorobjlist[door].vertical)
+	{
+		if ( player->tiley == tiley )
+		{
+			if ( ((player->x+MINDIST) >>TILESHIFT) == tilex )
+				return;
+			if ( ((player->x-MINDIST) >>TILESHIFT) == tilex )
+				return;
+		}
+		check = actorat[tilex-1][tiley];
+		if (check && ((check->x+MINDIST) >> TILESHIFT) == tilex )
+			return;
+		check = actorat[tilex+1][tiley];
+		if (check && ((check->x-MINDIST) >> TILESHIFT) == tilex )
+			return;
+	}
+	else if (!doorobjlist[door].vertical)
+	{
+		if (player->tilex == tilex)
+		{
+			if ( ((player->y+MINDIST) >>TILESHIFT) == tiley )
+				return;
+			if ( ((player->y-MINDIST) >>TILESHIFT) == tiley )
+				return;
+		}
+		check = actorat[tilex][tiley-1];
+		if (check && ((check->y+MINDIST) >> TILESHIFT) == tiley )
+			return;
+		check = actorat[tilex][tiley+1];
+		if (check && ((check->y-MINDIST) >> TILESHIFT) == tiley )
+			return;
+	}
+
+
+//
+// play door sound if in a connected area
+//
+	area = *(mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
+			+doorobjlist[door].tilex)-AREATILE;
+	if (areabyplayer[area])
+	{
+		PlaySoundLocTile(CLOSEDOORSND,doorobjlist[door].tilex,doorobjlist[door].tiley);	// JAB
+	}
+
+	doorobjlist[door].action = dr_closing;
+//
+// make the door space solid
+//
+	(unsigned)actorat[tilex][tiley]
+		= door | 0x80;
+}
+
+
+
+/*
+=====================
+=
+= OperateDoor
+=
+= The player wants to change the door's direction
+=
+=====================
+*/
+
+void OperateDoor (int door)
+{
+	int	lock;
+
+	lock = doorobjlist[door].lock;
+	if (lock >= dr_lock1 && lock <= dr_lock4)
+	{
+		if ( ! (gamestate.keys & (1 << (lock-dr_lock1) ) ) )
+		{
+			SD_PlaySound (NOWAYSND);		// locked
+			return;
+		}
+	}
+
+	switch (doorobjlist[door].action)
+	{
+	case dr_closed:
+	case dr_closing:
+		OpenDoor (door);
+		break;
+	case dr_open:
+	case dr_opening:
+		CloseDoor (door);
+		break;
+	}
+}
+
+
+//===========================================================================
+
+/*
+===============
+=
+= DoorOpen
+=
+= Close the door after three seconds
+=
+===============
+*/
+
+void DoorOpen (int door)
+{
+	if ( (doorobjlist[door].ticcount += tics) >= OPENTICS)
+		CloseDoor (door);
+}
+
+
+
+/*
+===============
+=
+= DoorOpening
+=
+===============
+*/
+
+void DoorOpening (int door)
+{
+	int		area1,area2;
+	unsigned	far	*map;
+	long	position;
+
+	position = doorposition[door];
+	if (!position)
+	{
+	//
+	// door is just starting to open, so connect the areas
+	//
+		map = mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
+			+doorobjlist[door].tilex;
+
+		if (doorobjlist[door].vertical)
+		{
+			area1 =	*(map+1);
+			area2 =	*(map-1);
+		}
+		else
+		{
+			area1 =	*(map-mapwidth);
+			area2 =	*(map+mapwidth);
+		}
+		area1 -= AREATILE;
+		area2 -= AREATILE;
+		areaconnect[area1][area2]++;
+		areaconnect[area2][area1]++;
+		ConnectAreas ();
+		if (areabyplayer[area1])
+		{
+			PlaySoundLocTile(OPENDOORSND,doorobjlist[door].tilex,doorobjlist[door].tiley);	// JAB
+		}
+	}
+
+//
+// slide the door by an adaptive amount
+//
+	position += tics<<10;
+	if (position >= 0xffff)
+	{
+	//
+	// door is all the way open
+	//
+		position = 0xffff;
+		doorobjlist[door].ticcount = 0;
+		doorobjlist[door].action = dr_open;
+		actorat[doorobjlist[door].tilex][doorobjlist[door].tiley] = 0;
+	}
+
+	doorposition[door] = position;
+}
+
+
+/*
+===============
+=
+= DoorClosing
+=
+===============
+*/
+
+void DoorClosing (int door)
+{
+	int		area1,area2,move;
+	unsigned	far	*map;
+	long	position;
+	int		tilex,tiley;
+
+	tilex = doorobjlist[door].tilex;
+	tiley = doorobjlist[door].tiley;
+
+	if ( ((unsigned)actorat[tilex][tiley] != (door | 0x80))
+	|| (player->tilex == tilex && player->tiley == tiley) )
+	{			// something got inside the door
+		OpenDoor (door);
+		return;
+	};
+
+	position = doorposition[door];
+
+//
+// slide the door by an adaptive amount
+//
+	position -= tics<<10;
+	if (position <= 0)
+	{
+	//
+	// door is closed all the way, so disconnect the areas
+	//
+		position = 0;
+
+		doorobjlist[door].action = dr_closed;
+
+		map = mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
+			+doorobjlist[door].tilex;
+
+		if (doorobjlist[door].vertical)
+		{
+			area1 =	*(map+1);
+			area2 =	*(map-1);
+		}
+		else
+		{
+			area1 =	*(map-mapwidth);
+			area2 =	*(map+mapwidth);
+		}
+		area1 -= AREATILE;
+		area2 -= AREATILE;
+		areaconnect[area1][area2]--;
+		areaconnect[area2][area1]--;
+
+		ConnectAreas ();
+	}
+
+	doorposition[door] = position;
+}
+
+
+
+
+/*
+=====================
+=
+= MoveDoors
+=
+= Called from PlayLoop
+=
+=====================
+*/
+
+void MoveDoors (void)
+{
+	int		door;
+
+	if (gamestate.victoryflag)		// don't move door during victory sequence
+		return;
+
+	for (door = 0 ; door < doornum ; door++)
+		switch (doorobjlist[door].action)
+		{
+		case dr_open:
+			DoorOpen (door);
+			break;
+
+		case dr_opening:
+			DoorOpening(door);
+			break;
+
+		case dr_closing:
+			DoorClosing(door);
+			break;
+		}
+}
+
+
+/*
+=============================================================================
+
+						PUSHABLE WALLS
+
+=============================================================================
+*/
+
+unsigned	pwallstate;
+unsigned	pwallpos;			// amount a pushable wall has been moved (0-63)
+unsigned	pwallx,pwally;
+int			pwalldir;
+
+/*
+===============
+=
+= PushWall
+=
+===============
+*/
+
+void PushWall (int checkx, int checky, int dir)
+{
+	int		oldtile;
+
+	if (pwallstate)
+	  return;
+
+
+	oldtile = tilemap[checkx][checky];
+	if (!oldtile)
+		return;
+
+	switch (dir)
+	{
+	case di_north:
+		if (actorat[checkx][checky-1])
+		{
+			SD_PlaySound (NOWAYSND);
+			return;
+		}
+		(unsigned)actorat[checkx][checky-1] =
+		tilemap[checkx][checky-1] = oldtile;
+		break;
+
+	case di_east:
+		if (actorat[checkx+1][checky])
+		{
+			SD_PlaySound (NOWAYSND);
+			return;
+		}
+		(unsigned)actorat[checkx+1][checky] =
+		tilemap[checkx+1][checky] = oldtile;
+		break;
+
+	case di_south:
+		if (actorat[checkx][checky+1])
+		{
+			SD_PlaySound (NOWAYSND);
+			return;
+		}
+		(unsigned)actorat[checkx][checky+1] =
+		tilemap[checkx][checky+1] = oldtile;
+		break;
+
+	case di_west:
+		if (actorat[checkx-1][checky])
+		{
+			SD_PlaySound (NOWAYSND);
+			return;
+		}
+		(unsigned)actorat[checkx-1][checky] =
+		tilemap[checkx-1][checky] = oldtile;
+		break;
+	}
+
+	gamestate.secretcount++;
+	pwallx = checkx;
+	pwally = checky;
+	pwalldir = dir;
+	pwallstate = 1;
+	pwallpos = 0;
+	tilemap[pwallx][pwally] |= 0xc0;
+	*(mapsegs[1]+farmapylookup[pwally]+pwallx) = 0;	// remove P tile info
+
+	SD_PlaySound (PUSHWALLSND);
+}
+
+
+
+/*
+=================
+=
+= MovePWalls
+=
+=================
+*/
+
+void MovePWalls (void)
+{
+	int		oldblock,oldtile;
+
+	if (!pwallstate)
+		return;
+
+	oldblock = pwallstate/128;
+
+	pwallstate += tics;
+
+	if (pwallstate/128 != oldblock)
+	{
+	// block crossed into a new block
+		oldtile = tilemap[pwallx][pwally] & 63;
+
+		//
+		// the tile can now be walked into
+		//
+		tilemap[pwallx][pwally] = 0;
+		(unsigned)actorat[pwallx][pwally] = 0;
+		*(mapsegs[0]+farmapylookup[pwally]+pwallx) = player->areanumber+AREATILE;
+
+		//
+		// see if it should be pushed farther
+		//
+		if (pwallstate>256)
+		{
+		//
+		// the block has been pushed two tiles
+		//
+			pwallstate = 0;
+			return;
+		}
+		else
+		{
+			switch (pwalldir)
+			{
+			case di_north:
+				pwally--;
+				if (actorat[pwallx][pwally-1])
+				{
+					pwallstate = 0;
+					return;
+				}
+				(unsigned)actorat[pwallx][pwally-1] =
+				tilemap[pwallx][pwally-1] = oldtile;
+				break;
+
+			case di_east:
+				pwallx++;
+				if (actorat[pwallx+1][pwally])
+				{
+					pwallstate = 0;
+					return;
+				}
+				(unsigned)actorat[pwallx+1][pwally] =
+				tilemap[pwallx+1][pwally] = oldtile;
+				break;
+
+			case di_south:
+				pwally++;
+				if (actorat[pwallx][pwally+1])
+				{
+					pwallstate = 0;
+					return;
+				}
+				(unsigned)actorat[pwallx][pwally+1] =
+				tilemap[pwallx][pwally+1] = oldtile;
+				break;
+
+			case di_west:
+				pwallx--;
+				if (actorat[pwallx-1][pwally])
+				{
+					pwallstate = 0;
+					return;
+				}
+				(unsigned)actorat[pwallx-1][pwally] =
+				tilemap[pwallx-1][pwally] = oldtile;
+				break;
+			}
+
+			tilemap[pwallx][pwally] = oldtile | 0xc0;
+		}
+	}
+
+
+	pwallpos = (pwallstate/2)&63;
+
+}
+
--- /dev/null
+++ b/WOLFSRC/WL_ACT2.C
@@ -1,0 +1,3872 @@
+// WL_ACT2.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+
+/*
+=============================================================================
+
+						 LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+#define PROJECTILESIZE	0xc000l
+
+#define BJRUNSPEED	2048
+#define BJJUMPSPEED	680
+
+
+/*
+=============================================================================
+
+						 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+
+dirtype dirtable[9] = {northwest,north,northeast,west,nodir,east,
+	southwest,south,southeast};
+
+int	starthitpoints[4][NUMENEMIES] =
+	 //
+	 // BABY MODE
+	 //
+	 {
+	 {25,	// guards
+	  50,	// officer
+	  100,	// SS
+	  1,	// dogs
+	  850,	// Hans
+	  850,	// Schabbs
+	  200,	// fake hitler
+	  800,	// mecha hitler
+	  45,	// mutants
+	  25,	// ghosts
+	  25,	// ghosts
+	  25,	// ghosts
+	  25,	// ghosts
+
+	  850,	// Gretel
+	  850,	// Gift
+	  850,	// Fat
+	  5,	// en_spectre,
+	  1450,	// en_angel,
+	  850,	// en_trans,
+	  1050,	// en_uber,
+	  950,	// en_will,
+	  1250	// en_death
+	  },
+	 //
+	 // DON'T HURT ME MODE
+	 //
+	 {25,	// guards
+	  50,	// officer
+	  100,	// SS
+	  1,	// dogs
+	  950,	// Hans
+	  950,	// Schabbs
+	  300,	// fake hitler
+	  950,	// mecha hitler
+	  55,	// mutants
+	  25,	// ghosts
+	  25,	// ghosts
+	  25,	// ghosts
+	  25,	// ghosts
+
+	  950,	// Gretel
+	  950,	// Gift
+	  950,	// Fat
+	  10,	// en_spectre,
+	  1550,	// en_angel,
+	  950,	// en_trans,
+	  1150,	// en_uber,
+	  1050,	// en_will,
+	  1350	// en_death
+	  },
+	 //
+	 // BRING 'EM ON MODE
+	 //
+	 {25,	// guards
+	  50,	// officer
+	  100,	// SS
+	  1,	// dogs
+
+	  1050,	// Hans
+	  1550,	// Schabbs
+	  400,	// fake hitler
+	  1050,	// mecha hitler
+
+	  55,	// mutants
+	  25,	// ghosts
+	  25,	// ghosts
+	  25,	// ghosts
+	  25,	// ghosts
+
+	  1050,	// Gretel
+	  1050,	// Gift
+	  1050,	// Fat
+	  15,	// en_spectre,
+	  1650,	// en_angel,
+	  1050,	// en_trans,
+	  1250,	// en_uber,
+	  1150,	// en_will,
+	  1450	// en_death
+	  },
+	 //
+	 // DEATH INCARNATE MODE
+	 //
+	 {25,	// guards
+	  50,	// officer
+	  100,	// SS
+	  1,	// dogs
+
+	  1200,	// Hans
+	  2400,	// Schabbs
+	  500,	// fake hitler
+	  1200,	// mecha hitler
+
+	  65,	// mutants
+	  25,	// ghosts
+	  25,	// ghosts
+	  25,	// ghosts
+	  25,	// ghosts
+
+	  1200,	// Gretel
+	  1200,	// Gift
+	  1200,	// Fat
+	  25,	// en_spectre,
+	  2000,	// en_angel,
+	  1200,	// en_trans,
+	  1400,	// en_uber,
+	  1300,	// en_will,
+	  1600	// en_death
+	  }}
+	  ;
+
+void	A_StartDeathCam (objtype *ob);
+
+
+void	T_Path (objtype *ob);
+void	T_Shoot (objtype *ob);
+void	T_Bite (objtype *ob);
+void	T_DogChase (objtype *ob);
+void	T_Chase (objtype *ob);
+void	T_Projectile (objtype *ob);
+void	T_Stand (objtype *ob);
+
+void A_DeathScream (objtype *ob);
+
+extern	statetype s_rocket;
+extern	statetype s_smoke1;
+extern	statetype s_smoke2;
+extern	statetype s_smoke3;
+extern	statetype s_smoke4;
+extern	statetype s_boom2;
+extern	statetype s_boom3;
+
+void A_Smoke (objtype *ob);
+
+statetype s_rocket	 	= {true,SPR_ROCKET_1,3,T_Projectile,A_Smoke,&s_rocket};
+statetype s_smoke1	 	= {false,SPR_SMOKE_1,3,NULL,NULL,&s_smoke2};
+statetype s_smoke2	 	= {false,SPR_SMOKE_2,3,NULL,NULL,&s_smoke3};
+statetype s_smoke3	 	= {false,SPR_SMOKE_3,3,NULL,NULL,&s_smoke4};
+statetype s_smoke4	 	= {false,SPR_SMOKE_4,3,NULL,NULL,NULL};
+
+statetype s_boom1	 	= {false,SPR_BOOM_1,6,NULL,NULL,&s_boom2};
+statetype s_boom2	 	= {false,SPR_BOOM_2,6,NULL,NULL,&s_boom3};
+statetype s_boom3	 	= {false,SPR_BOOM_3,6,NULL,NULL,NULL};
+
+#ifdef SPEAR
+
+extern	statetype s_hrocket;
+extern	statetype s_hsmoke1;
+extern	statetype s_hsmoke2;
+extern	statetype s_hsmoke3;
+extern	statetype s_hsmoke4;
+extern	statetype s_hboom2;
+extern	statetype s_hboom3;
+
+void A_Smoke (objtype *ob);
+
+statetype s_hrocket	 	= {true,SPR_HROCKET_1,3,T_Projectile,A_Smoke,&s_hrocket};
+statetype s_hsmoke1	 	= {false,SPR_HSMOKE_1,3,NULL,NULL,&s_hsmoke2};
+statetype s_hsmoke2	 	= {false,SPR_HSMOKE_2,3,NULL,NULL,&s_hsmoke3};
+statetype s_hsmoke3	 	= {false,SPR_HSMOKE_3,3,NULL,NULL,&s_hsmoke4};
+statetype s_hsmoke4	 	= {false,SPR_HSMOKE_4,3,NULL,NULL,NULL};
+
+statetype s_hboom1	 	= {false,SPR_HBOOM_1,6,NULL,NULL,&s_hboom2};
+statetype s_hboom2	 	= {false,SPR_HBOOM_2,6,NULL,NULL,&s_hboom3};
+statetype s_hboom3	 	= {false,SPR_HBOOM_3,6,NULL,NULL,NULL};
+
+#endif
+
+void	T_Schabb (objtype *ob);
+void	T_SchabbThrow (objtype *ob);
+void	T_Fake (objtype *ob);
+void	T_FakeFire (objtype *ob);
+void	T_Ghosts (objtype *ob);
+
+void A_Slurpie (objtype *ob);
+void A_HitlerMorph (objtype *ob);
+void A_MechaSound (objtype *ob);
+
+/*
+=================
+=
+= A_Smoke
+=
+=================
+*/
+
+void A_Smoke (objtype *ob)
+{
+	GetNewActor ();
+#ifdef SPEAR
+	if (ob->obclass == hrocketobj)
+		new->state = &s_hsmoke1;
+	else
+#endif
+		new->state = &s_smoke1;
+	new->ticcount = 6;
+
+	new->tilex = ob->tilex;
+	new->tiley = ob->tiley;
+	new->x = ob->x;
+	new->y = ob->y;
+	new->obclass = inertobj;
+	new->active = true;
+
+	new->flags = FL_NEVERMARK;
+}
+
+
+/*
+===================
+=
+= ProjectileTryMove
+=
+= returns true if move ok
+===================
+*/
+
+#define PROJSIZE	0x2000
+
+boolean ProjectileTryMove (objtype *ob)
+{
+	int			xl,yl,xh,yh,x,y;
+	objtype		*check;
+	long		deltax,deltay;
+
+	xl = (ob->x-PROJSIZE) >>TILESHIFT;
+	yl = (ob->y-PROJSIZE) >>TILESHIFT;
+
+	xh = (ob->x+PROJSIZE) >>TILESHIFT;
+	yh = (ob->y+PROJSIZE) >>TILESHIFT;
+
+//
+// check for solid walls
+//
+	for (y=yl;y<=yh;y++)
+		for (x=xl;x<=xh;x++)
+		{
+			check = actorat[x][y];
+			if (check && check<objlist)
+				return false;
+		}
+
+	return true;
+}
+
+
+
+/*
+=================
+=
+= T_Projectile
+=
+=================
+*/
+
+void T_Projectile (objtype *ob)
+{
+	long	deltax,deltay;
+	int		damage;
+	long	speed;
+
+	speed = (long)ob->speed*tics;
+
+	deltax = FixedByFrac(speed,costable[ob->angle]);
+	deltay = -FixedByFrac(speed,sintable[ob->angle]);
+
+	if (deltax>0x10000l)
+		deltax = 0x10000l;
+	if (deltay>0x10000l)
+		deltay = 0x10000l;
+
+	ob->x += deltax;
+	ob->y += deltay;
+
+	deltax = LABS(ob->x - player->x);
+	deltay = LABS(ob->y - player->y);
+
+	if (!ProjectileTryMove (ob))
+	{
+		if (ob->obclass == rocketobj)
+		{
+			PlaySoundLocActor(MISSILEHITSND,ob);
+			ob->state = &s_boom1;
+		}
+#ifdef SPEAR
+		else if (ob->obclass == hrocketobj)
+		{
+			PlaySoundLocActor(MISSILEHITSND,ob);
+			ob->state = &s_hboom1;
+		}
+#endif
+		else
+			ob->state = NULL;		// mark for removal
+
+		return;
+	}
+
+	if (deltax < PROJECTILESIZE && deltay < PROJECTILESIZE)
+	{	// hit the player
+		switch (ob->obclass)
+		{
+		case needleobj:
+			damage = (US_RndT() >>3) + 20;
+			break;
+		case rocketobj:
+		case hrocketobj:
+		case sparkobj:
+			damage = (US_RndT() >>3) + 30;
+			break;
+		case fireobj:
+			damage = (US_RndT() >>3);
+			break;
+		}
+
+		TakeDamage (damage,ob);
+		ob->state = NULL;		// mark for removal
+		return;
+	}
+
+	ob->tilex = ob->x >> TILESHIFT;
+	ob->tiley = ob->y >> TILESHIFT;
+
+}
+
+
+
+
+/*
+=============================================================================
+
+							GUARD
+
+=============================================================================
+*/
+
+//
+// guards
+//
+
+extern	statetype s_grdstand;
+
+extern	statetype s_grdpath1;
+extern	statetype s_grdpath1s;
+extern	statetype s_grdpath2;
+extern	statetype s_grdpath3;
+extern	statetype s_grdpath3s;
+extern	statetype s_grdpath4;
+
+extern	statetype s_grdpain;
+extern	statetype s_grdpain1;
+
+extern	statetype s_grdgiveup;
+
+extern	statetype s_grdshoot1;
+extern	statetype s_grdshoot2;
+extern	statetype s_grdshoot3;
+extern	statetype s_grdshoot4;
+
+extern	statetype s_grdchase1;
+extern	statetype s_grdchase1s;
+extern	statetype s_grdchase2;
+extern	statetype s_grdchase3;
+extern	statetype s_grdchase3s;
+extern	statetype s_grdchase4;
+
+extern	statetype s_grddie1;
+extern	statetype s_grddie1d;
+extern	statetype s_grddie2;
+extern	statetype s_grddie3;
+extern	statetype s_grddie4;
+
+statetype s_grdstand	= {true,SPR_GRD_S_1,0,T_Stand,NULL,&s_grdstand};
+
+statetype s_grdpath1 	= {true,SPR_GRD_W1_1,20,T_Path,NULL,&s_grdpath1s};
+statetype s_grdpath1s 	= {true,SPR_GRD_W1_1,5,NULL,NULL,&s_grdpath2};
+statetype s_grdpath2 	= {true,SPR_GRD_W2_1,15,T_Path,NULL,&s_grdpath3};
+statetype s_grdpath3 	= {true,SPR_GRD_W3_1,20,T_Path,NULL,&s_grdpath3s};
+statetype s_grdpath3s 	= {true,SPR_GRD_W3_1,5,NULL,NULL,&s_grdpath4};
+statetype s_grdpath4 	= {true,SPR_GRD_W4_1,15,T_Path,NULL,&s_grdpath1};
+
+statetype s_grdpain 	= {2,SPR_GRD_PAIN_1,10,NULL,NULL,&s_grdchase1};
+statetype s_grdpain1 	= {2,SPR_GRD_PAIN_2,10,NULL,NULL,&s_grdchase1};
+
+statetype s_grdshoot1 	= {false,SPR_GRD_SHOOT1,20,NULL,NULL,&s_grdshoot2};
+statetype s_grdshoot2 	= {false,SPR_GRD_SHOOT2,20,NULL,T_Shoot,&s_grdshoot3};
+statetype s_grdshoot3 	= {false,SPR_GRD_SHOOT3,20,NULL,NULL,&s_grdchase1};
+
+statetype s_grdchase1 	= {true,SPR_GRD_W1_1,10,T_Chase,NULL,&s_grdchase1s};
+statetype s_grdchase1s 	= {true,SPR_GRD_W1_1,3,NULL,NULL,&s_grdchase2};
+statetype s_grdchase2 	= {true,SPR_GRD_W2_1,8,T_Chase,NULL,&s_grdchase3};
+statetype s_grdchase3 	= {true,SPR_GRD_W3_1,10,T_Chase,NULL,&s_grdchase3s};
+statetype s_grdchase3s 	= {true,SPR_GRD_W3_1,3,NULL,NULL,&s_grdchase4};
+statetype s_grdchase4 	= {true,SPR_GRD_W4_1,8,T_Chase,NULL,&s_grdchase1};
+
+statetype s_grddie1		= {false,SPR_GRD_DIE_1,15,NULL,A_DeathScream,&s_grddie2};
+statetype s_grddie2		= {false,SPR_GRD_DIE_2,15,NULL,NULL,&s_grddie3};
+statetype s_grddie3		= {false,SPR_GRD_DIE_3,15,NULL,NULL,&s_grddie4};
+statetype s_grddie4		= {false,SPR_GRD_DEAD,0,NULL,NULL,&s_grddie4};
+
+
+#ifndef SPEAR
+//
+// ghosts
+//
+extern	statetype s_blinkychase1;
+extern	statetype s_blinkychase2;
+extern	statetype s_inkychase1;
+extern	statetype s_inkychase2;
+extern	statetype s_pinkychase1;
+extern	statetype s_pinkychase2;
+extern	statetype s_clydechase1;
+extern	statetype s_clydechase2;
+
+statetype s_blinkychase1 	= {false,SPR_BLINKY_W1,10,T_Ghosts,NULL,&s_blinkychase2};
+statetype s_blinkychase2 	= {false,SPR_BLINKY_W2,10,T_Ghosts,NULL,&s_blinkychase1};
+
+statetype s_inkychase1 		= {false,SPR_INKY_W1,10,T_Ghosts,NULL,&s_inkychase2};
+statetype s_inkychase2 		= {false,SPR_INKY_W2,10,T_Ghosts,NULL,&s_inkychase1};
+
+statetype s_pinkychase1 	= {false,SPR_PINKY_W1,10,T_Ghosts,NULL,&s_pinkychase2};
+statetype s_pinkychase2 	= {false,SPR_PINKY_W2,10,T_Ghosts,NULL,&s_pinkychase1};
+
+statetype s_clydechase1 	= {false,SPR_CLYDE_W1,10,T_Ghosts,NULL,&s_clydechase2};
+statetype s_clydechase2 	= {false,SPR_CLYDE_W2,10,T_Ghosts,NULL,&s_clydechase1};
+#endif
+
+//
+// dogs
+//
+
+extern	statetype s_dogpath1;
+extern	statetype s_dogpath1s;
+extern	statetype s_dogpath2;
+extern	statetype s_dogpath3;
+extern	statetype s_dogpath3s;
+extern	statetype s_dogpath4;
+
+extern	statetype s_dogjump1;
+extern	statetype s_dogjump2;
+extern	statetype s_dogjump3;
+extern	statetype s_dogjump4;
+extern	statetype s_dogjump5;
+
+extern	statetype s_dogchase1;
+extern	statetype s_dogchase1s;
+extern	statetype s_dogchase2;
+extern	statetype s_dogchase3;
+extern	statetype s_dogchase3s;
+extern	statetype s_dogchase4;
+
+extern	statetype s_dogdie1;
+extern	statetype s_dogdie1d;
+extern	statetype s_dogdie2;
+extern	statetype s_dogdie3;
+extern	statetype s_dogdead;
+
+statetype s_dogpath1 	= {true,SPR_DOG_W1_1,20,T_Path,NULL,&s_dogpath1s};
+statetype s_dogpath1s 	= {true,SPR_DOG_W1_1,5,NULL,NULL,&s_dogpath2};
+statetype s_dogpath2 	= {true,SPR_DOG_W2_1,15,T_Path,NULL,&s_dogpath3};
+statetype s_dogpath3 	= {true,SPR_DOG_W3_1,20,T_Path,NULL,&s_dogpath3s};
+statetype s_dogpath3s 	= {true,SPR_DOG_W3_1,5,NULL,NULL,&s_dogpath4};
+statetype s_dogpath4 	= {true,SPR_DOG_W4_1,15,T_Path,NULL,&s_dogpath1};
+
+statetype s_dogjump1 	= {false,SPR_DOG_JUMP1,10,NULL,NULL,&s_dogjump2};
+statetype s_dogjump2 	= {false,SPR_DOG_JUMP2,10,NULL,T_Bite,&s_dogjump3};
+statetype s_dogjump3 	= {false,SPR_DOG_JUMP3,10,NULL,NULL,&s_dogjump4};
+statetype s_dogjump4 	= {false,SPR_DOG_JUMP1,10,NULL,NULL,&s_dogjump5};
+statetype s_dogjump5 	= {false,SPR_DOG_W1_1,10,NULL,NULL,&s_dogchase1};
+
+statetype s_dogchase1 	= {true,SPR_DOG_W1_1,10,T_DogChase,NULL,&s_dogchase1s};
+statetype s_dogchase1s 	= {true,SPR_DOG_W1_1,3,NULL,NULL,&s_dogchase2};
+statetype s_dogchase2 	= {true,SPR_DOG_W2_1,8,T_DogChase,NULL,&s_dogchase3};
+statetype s_dogchase3 	= {true,SPR_DOG_W3_1,10,T_DogChase,NULL,&s_dogchase3s};
+statetype s_dogchase3s 	= {true,SPR_DOG_W3_1,3,NULL,NULL,&s_dogchase4};
+statetype s_dogchase4 	= {true,SPR_DOG_W4_1,8,T_DogChase,NULL,&s_dogchase1};
+
+statetype s_dogdie1		= {false,SPR_DOG_DIE_1,15,NULL,A_DeathScream,&s_dogdie2};
+statetype s_dogdie2		= {false,SPR_DOG_DIE_2,15,NULL,NULL,&s_dogdie3};
+statetype s_dogdie3		= {false,SPR_DOG_DIE_3,15,NULL,NULL,&s_dogdead};
+statetype s_dogdead		= {false,SPR_DOG_DEAD,15,NULL,NULL,&s_dogdead};
+
+
+//
+// officers
+//
+
+extern	statetype s_ofcstand;
+
+extern	statetype s_ofcpath1;
+extern	statetype s_ofcpath1s;
+extern	statetype s_ofcpath2;
+extern	statetype s_ofcpath3;
+extern	statetype s_ofcpath3s;
+extern	statetype s_ofcpath4;
+
+extern	statetype s_ofcpain;
+extern	statetype s_ofcpain1;
+
+extern	statetype s_ofcgiveup;
+
+extern	statetype s_ofcshoot1;
+extern	statetype s_ofcshoot2;
+extern	statetype s_ofcshoot3;
+extern	statetype s_ofcshoot4;
+
+extern	statetype s_ofcchase1;
+extern	statetype s_ofcchase1s;
+extern	statetype s_ofcchase2;
+extern	statetype s_ofcchase3;
+extern	statetype s_ofcchase3s;
+extern	statetype s_ofcchase4;
+
+extern	statetype s_ofcdie1;
+extern	statetype s_ofcdie2;
+extern	statetype s_ofcdie3;
+extern	statetype s_ofcdie4;
+extern	statetype s_ofcdie5;
+
+statetype s_ofcstand	= {true,SPR_OFC_S_1,0,T_Stand,NULL,&s_ofcstand};
+
+statetype s_ofcpath1 	= {true,SPR_OFC_W1_1,20,T_Path,NULL,&s_ofcpath1s};
+statetype s_ofcpath1s 	= {true,SPR_OFC_W1_1,5,NULL,NULL,&s_ofcpath2};
+statetype s_ofcpath2 	= {true,SPR_OFC_W2_1,15,T_Path,NULL,&s_ofcpath3};
+statetype s_ofcpath3 	= {true,SPR_OFC_W3_1,20,T_Path,NULL,&s_ofcpath3s};
+statetype s_ofcpath3s 	= {true,SPR_OFC_W3_1,5,NULL,NULL,&s_ofcpath4};
+statetype s_ofcpath4 	= {true,SPR_OFC_W4_1,15,T_Path,NULL,&s_ofcpath1};
+
+statetype s_ofcpain 	= {2,SPR_OFC_PAIN_1,10,NULL,NULL,&s_ofcchase1};
+statetype s_ofcpain1 	= {2,SPR_OFC_PAIN_2,10,NULL,NULL,&s_ofcchase1};
+
+statetype s_ofcshoot1 	= {false,SPR_OFC_SHOOT1,6,NULL,NULL,&s_ofcshoot2};
+statetype s_ofcshoot2 	= {false,SPR_OFC_SHOOT2,20,NULL,T_Shoot,&s_ofcshoot3};
+statetype s_ofcshoot3 	= {false,SPR_OFC_SHOOT3,10,NULL,NULL,&s_ofcchase1};
+
+statetype s_ofcchase1 	= {true,SPR_OFC_W1_1,10,T_Chase,NULL,&s_ofcchase1s};
+statetype s_ofcchase1s 	= {true,SPR_OFC_W1_1,3,NULL,NULL,&s_ofcchase2};
+statetype s_ofcchase2 	= {true,SPR_OFC_W2_1,8,T_Chase,NULL,&s_ofcchase3};
+statetype s_ofcchase3 	= {true,SPR_OFC_W3_1,10,T_Chase,NULL,&s_ofcchase3s};
+statetype s_ofcchase3s 	= {true,SPR_OFC_W3_1,3,NULL,NULL,&s_ofcchase4};
+statetype s_ofcchase4 	= {true,SPR_OFC_W4_1,8,T_Chase,NULL,&s_ofcchase1};
+
+statetype s_ofcdie1		= {false,SPR_OFC_DIE_1,11,NULL,A_DeathScream,&s_ofcdie2};
+statetype s_ofcdie2		= {false,SPR_OFC_DIE_2,11,NULL,NULL,&s_ofcdie3};
+statetype s_ofcdie3		= {false,SPR_OFC_DIE_3,11,NULL,NULL,&s_ofcdie4};
+statetype s_ofcdie4		= {false,SPR_OFC_DIE_4,11,NULL,NULL,&s_ofcdie5};
+statetype s_ofcdie5		= {false,SPR_OFC_DEAD,0,NULL,NULL,&s_ofcdie5};
+
+
+//
+// mutant
+//
+
+extern	statetype s_mutstand;
+
+extern	statetype s_mutpath1;
+extern	statetype s_mutpath1s;
+extern	statetype s_mutpath2;
+extern	statetype s_mutpath3;
+extern	statetype s_mutpath3s;
+extern	statetype s_mutpath4;
+
+extern	statetype s_mutpain;
+extern	statetype s_mutpain1;
+
+extern	statetype s_mutgiveup;
+
+extern	statetype s_mutshoot1;
+extern	statetype s_mutshoot2;
+extern	statetype s_mutshoot3;
+extern	statetype s_mutshoot4;
+
+extern	statetype s_mutchase1;
+extern	statetype s_mutchase1s;
+extern	statetype s_mutchase2;
+extern	statetype s_mutchase3;
+extern	statetype s_mutchase3s;
+extern	statetype s_mutchase4;
+
+extern	statetype s_mutdie1;
+extern	statetype s_mutdie2;
+extern	statetype s_mutdie3;
+extern	statetype s_mutdie4;
+extern	statetype s_mutdie5;
+
+statetype s_mutstand	= {true,SPR_MUT_S_1,0,T_Stand,NULL,&s_mutstand};
+
+statetype s_mutpath1 	= {true,SPR_MUT_W1_1,20,T_Path,NULL,&s_mutpath1s};
+statetype s_mutpath1s 	= {true,SPR_MUT_W1_1,5,NULL,NULL,&s_mutpath2};
+statetype s_mutpath2 	= {true,SPR_MUT_W2_1,15,T_Path,NULL,&s_mutpath3};
+statetype s_mutpath3 	= {true,SPR_MUT_W3_1,20,T_Path,NULL,&s_mutpath3s};
+statetype s_mutpath3s 	= {true,SPR_MUT_W3_1,5,NULL,NULL,&s_mutpath4};
+statetype s_mutpath4 	= {true,SPR_MUT_W4_1,15,T_Path,NULL,&s_mutpath1};
+
+statetype s_mutpain 	= {2,SPR_MUT_PAIN_1,10,NULL,NULL,&s_mutchase1};
+statetype s_mutpain1 	= {2,SPR_MUT_PAIN_2,10,NULL,NULL,&s_mutchase1};
+
+statetype s_mutshoot1 	= {false,SPR_MUT_SHOOT1,6,NULL,T_Shoot,&s_mutshoot2};
+statetype s_mutshoot2 	= {false,SPR_MUT_SHOOT2,20,NULL,NULL,&s_mutshoot3};
+statetype s_mutshoot3 	= {false,SPR_MUT_SHOOT3,10,NULL,T_Shoot,&s_mutshoot4};
+statetype s_mutshoot4 	= {false,SPR_MUT_SHOOT4,20,NULL,NULL,&s_mutchase1};
+
+statetype s_mutchase1 	= {true,SPR_MUT_W1_1,10,T_Chase,NULL,&s_mutchase1s};
+statetype s_mutchase1s 	= {true,SPR_MUT_W1_1,3,NULL,NULL,&s_mutchase2};
+statetype s_mutchase2 	= {true,SPR_MUT_W2_1,8,T_Chase,NULL,&s_mutchase3};
+statetype s_mutchase3 	= {true,SPR_MUT_W3_1,10,T_Chase,NULL,&s_mutchase3s};
+statetype s_mutchase3s 	= {true,SPR_MUT_W3_1,3,NULL,NULL,&s_mutchase4};
+statetype s_mutchase4 	= {true,SPR_MUT_W4_1,8,T_Chase,NULL,&s_mutchase1};
+
+statetype s_mutdie1		= {false,SPR_MUT_DIE_1,7,NULL,A_DeathScream,&s_mutdie2};
+statetype s_mutdie2		= {false,SPR_MUT_DIE_2,7,NULL,NULL,&s_mutdie3};
+statetype s_mutdie3		= {false,SPR_MUT_DIE_3,7,NULL,NULL,&s_mutdie4};
+statetype s_mutdie4		= {false,SPR_MUT_DIE_4,7,NULL,NULL,&s_mutdie5};
+statetype s_mutdie5		= {false,SPR_MUT_DEAD,0,NULL,NULL,&s_mutdie5};
+
+
+//
+// SS
+//
+
+extern	statetype s_ssstand;
+
+extern	statetype s_sspath1;
+extern	statetype s_sspath1s;
+extern	statetype s_sspath2;
+extern	statetype s_sspath3;
+extern	statetype s_sspath3s;
+extern	statetype s_sspath4;
+
+extern	statetype s_sspain;
+extern	statetype s_sspain1;
+
+extern	statetype s_ssshoot1;
+extern	statetype s_ssshoot2;
+extern	statetype s_ssshoot3;
+extern	statetype s_ssshoot4;
+extern	statetype s_ssshoot5;
+extern	statetype s_ssshoot6;
+extern	statetype s_ssshoot7;
+extern	statetype s_ssshoot8;
+extern	statetype s_ssshoot9;
+
+extern	statetype s_sschase1;
+extern	statetype s_sschase1s;
+extern	statetype s_sschase2;
+extern	statetype s_sschase3;
+extern	statetype s_sschase3s;
+extern	statetype s_sschase4;
+
+extern	statetype s_ssdie1;
+extern	statetype s_ssdie2;
+extern	statetype s_ssdie3;
+extern	statetype s_ssdie4;
+
+statetype s_ssstand	= {true,SPR_SS_S_1,0,T_Stand,NULL,&s_ssstand};
+
+statetype s_sspath1 	= {true,SPR_SS_W1_1,20,T_Path,NULL,&s_sspath1s};
+statetype s_sspath1s 	= {true,SPR_SS_W1_1,5,NULL,NULL,&s_sspath2};
+statetype s_sspath2 	= {true,SPR_SS_W2_1,15,T_Path,NULL,&s_sspath3};
+statetype s_sspath3 	= {true,SPR_SS_W3_1,20,T_Path,NULL,&s_sspath3s};
+statetype s_sspath3s 	= {true,SPR_SS_W3_1,5,NULL,NULL,&s_sspath4};
+statetype s_sspath4 	= {true,SPR_SS_W4_1,15,T_Path,NULL,&s_sspath1};
+
+statetype s_sspain 		= {2,SPR_SS_PAIN_1,10,NULL,NULL,&s_sschase1};
+statetype s_sspain1 	= {2,SPR_SS_PAIN_2,10,NULL,NULL,&s_sschase1};
+
+statetype s_ssshoot1 	= {false,SPR_SS_SHOOT1,20,NULL,NULL,&s_ssshoot2};
+statetype s_ssshoot2 	= {false,SPR_SS_SHOOT2,20,NULL,T_Shoot,&s_ssshoot3};
+statetype s_ssshoot3 	= {false,SPR_SS_SHOOT3,10,NULL,NULL,&s_ssshoot4};
+statetype s_ssshoot4 	= {false,SPR_SS_SHOOT2,10,NULL,T_Shoot,&s_ssshoot5};
+statetype s_ssshoot5 	= {false,SPR_SS_SHOOT3,10,NULL,NULL,&s_ssshoot6};
+statetype s_ssshoot6 	= {false,SPR_SS_SHOOT2,10,NULL,T_Shoot,&s_ssshoot7};
+statetype s_ssshoot7  	= {false,SPR_SS_SHOOT3,10,NULL,NULL,&s_ssshoot8};
+statetype s_ssshoot8  	= {false,SPR_SS_SHOOT2,10,NULL,T_Shoot,&s_ssshoot9};
+statetype s_ssshoot9  	= {false,SPR_SS_SHOOT3,10,NULL,NULL,&s_sschase1};
+
+statetype s_sschase1 	= {true,SPR_SS_W1_1,10,T_Chase,NULL,&s_sschase1s};
+statetype s_sschase1s 	= {true,SPR_SS_W1_1,3,NULL,NULL,&s_sschase2};
+statetype s_sschase2 	= {true,SPR_SS_W2_1,8,T_Chase,NULL,&s_sschase3};
+statetype s_sschase3 	= {true,SPR_SS_W3_1,10,T_Chase,NULL,&s_sschase3s};
+statetype s_sschase3s 	= {true,SPR_SS_W3_1,3,NULL,NULL,&s_sschase4};
+statetype s_sschase4 	= {true,SPR_SS_W4_1,8,T_Chase,NULL,&s_sschase1};
+
+statetype s_ssdie1		= {false,SPR_SS_DIE_1,15,NULL,A_DeathScream,&s_ssdie2};
+statetype s_ssdie2		= {false,SPR_SS_DIE_2,15,NULL,NULL,&s_ssdie3};
+statetype s_ssdie3		= {false,SPR_SS_DIE_3,15,NULL,NULL,&s_ssdie4};
+statetype s_ssdie4		= {false,SPR_SS_DEAD,0,NULL,NULL,&s_ssdie4};
+
+
+#ifndef SPEAR
+//
+// hans
+//
+extern	statetype s_bossstand;
+
+extern	statetype s_bosschase1;
+extern	statetype s_bosschase1s;
+extern	statetype s_bosschase2;
+extern	statetype s_bosschase3;
+extern	statetype s_bosschase3s;
+extern	statetype s_bosschase4;
+
+extern	statetype s_bossdie1;
+extern	statetype s_bossdie2;
+extern	statetype s_bossdie3;
+extern	statetype s_bossdie4;
+
+extern	statetype s_bossshoot1;
+extern	statetype s_bossshoot2;
+extern	statetype s_bossshoot3;
+extern	statetype s_bossshoot4;
+extern	statetype s_bossshoot5;
+extern	statetype s_bossshoot6;
+extern	statetype s_bossshoot7;
+extern	statetype s_bossshoot8;
+
+
+statetype s_bossstand	= {false,SPR_BOSS_W1,0,T_Stand,NULL,&s_bossstand};
+
+statetype s_bosschase1 	= {false,SPR_BOSS_W1,10,T_Chase,NULL,&s_bosschase1s};
+statetype s_bosschase1s	= {false,SPR_BOSS_W1,3,NULL,NULL,&s_bosschase2};
+statetype s_bosschase2 	= {false,SPR_BOSS_W2,8,T_Chase,NULL,&s_bosschase3};
+statetype s_bosschase3 	= {false,SPR_BOSS_W3,10,T_Chase,NULL,&s_bosschase3s};
+statetype s_bosschase3s	= {false,SPR_BOSS_W3,3,NULL,NULL,&s_bosschase4};
+statetype s_bosschase4 	= {false,SPR_BOSS_W4,8,T_Chase,NULL,&s_bosschase1};
+
+statetype s_bossdie1	= {false,SPR_BOSS_DIE1,15,NULL,A_DeathScream,&s_bossdie2};
+statetype s_bossdie2	= {false,SPR_BOSS_DIE2,15,NULL,NULL,&s_bossdie3};
+statetype s_bossdie3	= {false,SPR_BOSS_DIE3,15,NULL,NULL,&s_bossdie4};
+statetype s_bossdie4	= {false,SPR_BOSS_DEAD,0,NULL,NULL,&s_bossdie4};
+
+statetype s_bossshoot1 	= {false,SPR_BOSS_SHOOT1,30,NULL,NULL,&s_bossshoot2};
+statetype s_bossshoot2 	= {false,SPR_BOSS_SHOOT2,10,NULL,T_Shoot,&s_bossshoot3};
+statetype s_bossshoot3 	= {false,SPR_BOSS_SHOOT3,10,NULL,T_Shoot,&s_bossshoot4};
+statetype s_bossshoot4 	= {false,SPR_BOSS_SHOOT2,10,NULL,T_Shoot,&s_bossshoot5};
+statetype s_bossshoot5 	= {false,SPR_BOSS_SHOOT3,10,NULL,T_Shoot,&s_bossshoot6};
+statetype s_bossshoot6 	= {false,SPR_BOSS_SHOOT2,10,NULL,T_Shoot,&s_bossshoot7};
+statetype s_bossshoot7 	= {false,SPR_BOSS_SHOOT3,10,NULL,T_Shoot,&s_bossshoot8};
+statetype s_bossshoot8 	= {false,SPR_BOSS_SHOOT1,10,NULL,NULL,&s_bosschase1};
+
+
+//
+// gretel
+//
+extern	statetype s_gretelstand;
+
+extern	statetype s_gretelchase1;
+extern	statetype s_gretelchase1s;
+extern	statetype s_gretelchase2;
+extern	statetype s_gretelchase3;
+extern	statetype s_gretelchase3s;
+extern	statetype s_gretelchase4;
+
+extern	statetype s_greteldie1;
+extern	statetype s_greteldie2;
+extern	statetype s_greteldie3;
+extern	statetype s_greteldie4;
+
+extern	statetype s_gretelshoot1;
+extern	statetype s_gretelshoot2;
+extern	statetype s_gretelshoot3;
+extern	statetype s_gretelshoot4;
+extern	statetype s_gretelshoot5;
+extern	statetype s_gretelshoot6;
+extern	statetype s_gretelshoot7;
+extern	statetype s_gretelshoot8;
+
+
+statetype s_gretelstand	= {false,SPR_GRETEL_W1,0,T_Stand,NULL,&s_gretelstand};
+
+statetype s_gretelchase1 	= {false,SPR_GRETEL_W1,10,T_Chase,NULL,&s_gretelchase1s};
+statetype s_gretelchase1s	= {false,SPR_GRETEL_W1,3,NULL,NULL,&s_gretelchase2};
+statetype s_gretelchase2 	= {false,SPR_GRETEL_W2,8,T_Chase,NULL,&s_gretelchase3};
+statetype s_gretelchase3 	= {false,SPR_GRETEL_W3,10,T_Chase,NULL,&s_gretelchase3s};
+statetype s_gretelchase3s	= {false,SPR_GRETEL_W3,3,NULL,NULL,&s_gretelchase4};
+statetype s_gretelchase4 	= {false,SPR_GRETEL_W4,8,T_Chase,NULL,&s_gretelchase1};
+
+statetype s_greteldie1	= {false,SPR_GRETEL_DIE1,15,NULL,A_DeathScream,&s_greteldie2};
+statetype s_greteldie2	= {false,SPR_GRETEL_DIE2,15,NULL,NULL,&s_greteldie3};
+statetype s_greteldie3	= {false,SPR_GRETEL_DIE3,15,NULL,NULL,&s_greteldie4};
+statetype s_greteldie4	= {false,SPR_GRETEL_DEAD,0,NULL,NULL,&s_greteldie4};
+
+statetype s_gretelshoot1 	= {false,SPR_GRETEL_SHOOT1,30,NULL,NULL,&s_gretelshoot2};
+statetype s_gretelshoot2 	= {false,SPR_GRETEL_SHOOT2,10,NULL,T_Shoot,&s_gretelshoot3};
+statetype s_gretelshoot3 	= {false,SPR_GRETEL_SHOOT3,10,NULL,T_Shoot,&s_gretelshoot4};
+statetype s_gretelshoot4 	= {false,SPR_GRETEL_SHOOT2,10,NULL,T_Shoot,&s_gretelshoot5};
+statetype s_gretelshoot5 	= {false,SPR_GRETEL_SHOOT3,10,NULL,T_Shoot,&s_gretelshoot6};
+statetype s_gretelshoot6 	= {false,SPR_GRETEL_SHOOT2,10,NULL,T_Shoot,&s_gretelshoot7};
+statetype s_gretelshoot7 	= {false,SPR_GRETEL_SHOOT3,10,NULL,T_Shoot,&s_gretelshoot8};
+statetype s_gretelshoot8 	= {false,SPR_GRETEL_SHOOT1,10,NULL,NULL,&s_gretelchase1};
+#endif
+
+
+/*
+===============
+=
+= SpawnStand
+=
+===============
+*/
+
+void SpawnStand (enemy_t which, int tilex, int tiley, int dir)
+{
+	unsigned	far *map,tile;
+
+	switch (which)
+	{
+	case en_guard:
+		SpawnNewObj (tilex,tiley,&s_grdstand);
+		new->speed = SPDPATROL;
+		if (!loadedgame)
+		  gamestate.killtotal++;
+		break;
+
+	case en_officer:
+		SpawnNewObj (tilex,tiley,&s_ofcstand);
+		new->speed = SPDPATROL;
+		if (!loadedgame)
+		  gamestate.killtotal++;
+		break;
+
+	case en_mutant:
+		SpawnNewObj (tilex,tiley,&s_mutstand);
+		new->speed = SPDPATROL;
+		if (!loadedgame)
+		  gamestate.killtotal++;
+		break;
+
+	case en_ss:
+		SpawnNewObj (tilex,tiley,&s_ssstand);
+		new->speed = SPDPATROL;
+		if (!loadedgame)
+		  gamestate.killtotal++;
+		break;
+	}
+
+
+	map = mapsegs[0]+farmapylookup[tiley]+tilex;
+	if (*map == AMBUSHTILE)
+	{
+		tilemap[tilex][tiley] = 0;
+
+		if (*(map+1) >= AREATILE)
+			tile = *(map+1);
+		if (*(map-mapwidth) >= AREATILE)
+			tile = *(map-mapwidth);
+		if (*(map+mapwidth) >= AREATILE)
+			tile = *(map+mapwidth);
+		if ( *(map-1) >= AREATILE)
+			tile = *(map-1);
+
+		*map = tile;
+		new->areanumber = tile-AREATILE;
+
+		new->flags |= FL_AMBUSH;
+	}
+
+	new->obclass = guardobj+which;
+	new->hitpoints = starthitpoints[gamestate.difficulty][which];
+	new->dir = dir*2;
+	new->flags |= FL_SHOOTABLE;
+}
+
+
+
+/*
+===============
+=
+= SpawnDeadGuard
+=
+===============
+*/
+
+void SpawnDeadGuard (int tilex, int tiley)
+{
+	SpawnNewObj (tilex,tiley,&s_grddie4);
+	new->obclass = inertobj;
+}
+
+
+
+#ifndef SPEAR
+/*
+===============
+=
+= SpawnBoss
+=
+===============
+*/
+
+void SpawnBoss (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	SpawnNewObj (tilex,tiley,&s_bossstand);
+	new->speed = SPDPATROL;
+
+	new->obclass = bossobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_boss];
+	new->dir = south;
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+/*
+===============
+=
+= SpawnGretel
+=
+===============
+*/
+
+void SpawnGretel (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	SpawnNewObj (tilex,tiley,&s_gretelstand);
+	new->speed = SPDPATROL;
+
+	new->obclass = gretelobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_gretel];
+	new->dir = north;
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+#endif
+
+/*
+===============
+=
+= SpawnPatrol
+=
+===============
+*/
+
+void SpawnPatrol (enemy_t which, int tilex, int tiley, int dir)
+{
+	switch (which)
+	{
+	case en_guard:
+		SpawnNewObj (tilex,tiley,&s_grdpath1);
+		new->speed = SPDPATROL;
+		if (!loadedgame)
+		  gamestate.killtotal++;
+		break;
+
+	case en_officer:
+		SpawnNewObj (tilex,tiley,&s_ofcpath1);
+		new->speed = SPDPATROL;
+		if (!loadedgame)
+		  gamestate.killtotal++;
+		break;
+
+	case en_ss:
+		SpawnNewObj (tilex,tiley,&s_sspath1);
+		new->speed = SPDPATROL;
+		if (!loadedgame)
+		  gamestate.killtotal++;
+		break;
+
+	case en_mutant:
+		SpawnNewObj (tilex,tiley,&s_mutpath1);
+		new->speed = SPDPATROL;
+		if (!loadedgame)
+		  gamestate.killtotal++;
+		break;
+
+	case en_dog:
+		SpawnNewObj (tilex,tiley,&s_dogpath1);
+		new->speed = SPDDOG;
+		if (!loadedgame)
+		  gamestate.killtotal++;
+		break;
+	}
+
+	new->obclass = guardobj+which;
+	new->dir = dir*2;
+	new->hitpoints = starthitpoints[gamestate.difficulty][which];
+	new->distance = tileglobal;
+	new->flags |= FL_SHOOTABLE;
+	new->active = true;
+
+	actorat[new->tilex][new->tiley] = NULL;		// don't use original spot
+
+	switch (dir)
+	{
+	case 0:
+		new->tilex++;
+		break;
+	case 1:
+		new->tiley--;
+		break;
+	case 2:
+		new->tilex--;
+		break;
+	case 3:
+		new->tiley++;
+		break;
+	}
+
+	actorat[new->tilex][new->tiley] = new;
+}
+
+
+
+/*
+==================
+=
+= A_DeathScream
+=
+==================
+*/
+
+void A_DeathScream (objtype *ob)
+{
+#ifndef UPLOAD
+#ifndef SPEAR
+	if (mapon==9 && !US_RndT())
+#else
+	if ((mapon==18 || mapon==19) && !US_RndT())
+#endif
+	{
+	 switch(ob->obclass)
+	 {
+	  case mutantobj:
+	  case guardobj:
+	  case officerobj:
+	  case ssobj:
+	  case dogobj:
+		PlaySoundLocActor(DEATHSCREAM6SND,ob);
+		return;
+	 }
+	}
+#endif
+
+	switch (ob->obclass)
+	{
+	case mutantobj:
+		PlaySoundLocActor(AHHHGSND,ob);
+		break;
+
+	case guardobj:
+		{
+		 int sounds[9]={ DEATHSCREAM1SND,
+				 DEATHSCREAM2SND,
+				 DEATHSCREAM3SND,
+				 DEATHSCREAM4SND,
+				 DEATHSCREAM5SND,
+				 DEATHSCREAM7SND,
+				 DEATHSCREAM8SND,
+				 DEATHSCREAM9SND
+				 };
+
+		 #ifndef UPLOAD
+		 PlaySoundLocActor(sounds[US_RndT()%8],ob);
+		 #else
+		 PlaySoundLocActor(sounds[US_RndT()%2],ob);
+		 #endif
+		}
+		break;
+	case officerobj:
+		PlaySoundLocActor(NEINSOVASSND,ob);
+		break;
+	case ssobj:
+		PlaySoundLocActor(LEBENSND,ob);	// JAB
+		break;
+	case dogobj:
+		PlaySoundLocActor(DOGDEATHSND,ob);	// JAB
+		break;
+#ifndef SPEAR
+	case bossobj:
+		SD_PlaySound(MUTTISND);				// JAB
+		break;
+	case schabbobj:
+		SD_PlaySound(MEINGOTTSND);
+		break;
+	case fakeobj:
+		SD_PlaySound(HITLERHASND);
+		break;
+	case mechahitlerobj:
+		SD_PlaySound(SCHEISTSND);
+		break;
+	case realhitlerobj:
+		SD_PlaySound(EVASND);
+		break;
+	case gretelobj:
+		SD_PlaySound(MEINSND);
+		break;
+	case giftobj:
+		SD_PlaySound(DONNERSND);
+		break;
+	case fatobj:
+		SD_PlaySound(ROSESND);
+		break;
+#else
+	case spectreobj:
+		SD_PlaySound(GHOSTFADESND);
+		break;
+	case angelobj:
+		SD_PlaySound(ANGELDEATHSND);
+		break;
+	case transobj:
+		SD_PlaySound(TRANSDEATHSND);
+		break;
+	case uberobj:
+		SD_PlaySound(UBERDEATHSND);
+		break;
+	case willobj:
+		SD_PlaySound(WILHELMDEATHSND);
+		break;
+	case deathobj:
+		SD_PlaySound(KNIGHTDEATHSND);
+		break;
+#endif
+	}
+}
+
+
+/*
+=============================================================================
+
+						 SPEAR ACTORS
+
+=============================================================================
+*/
+
+#ifdef SPEAR
+
+void T_Launch (objtype *ob);
+void T_Will (objtype *ob);
+
+extern	statetype s_angelshoot1;
+extern	statetype s_deathshoot1;
+extern	statetype s_spark1;
+
+//
+// trans
+//
+extern	statetype s_transstand;
+
+extern	statetype s_transchase1;
+extern	statetype s_transchase1s;
+extern	statetype s_transchase2;
+extern	statetype s_transchase3;
+extern	statetype s_transchase3s;
+extern	statetype s_transchase4;
+
+extern	statetype s_transdie0;
+extern	statetype s_transdie01;
+extern	statetype s_transdie1;
+extern	statetype s_transdie2;
+extern	statetype s_transdie3;
+extern	statetype s_transdie4;
+
+extern	statetype s_transshoot1;
+extern	statetype s_transshoot2;
+extern	statetype s_transshoot3;
+extern	statetype s_transshoot4;
+extern	statetype s_transshoot5;
+extern	statetype s_transshoot6;
+extern	statetype s_transshoot7;
+extern	statetype s_transshoot8;
+
+
+statetype s_transstand	= {false,SPR_TRANS_W1,0,T_Stand,NULL,&s_transstand};
+
+statetype s_transchase1 	= {false,SPR_TRANS_W1,10,T_Chase,NULL,&s_transchase1s};
+statetype s_transchase1s	= {false,SPR_TRANS_W1,3,NULL,NULL,&s_transchase2};
+statetype s_transchase2 	= {false,SPR_TRANS_W2,8,T_Chase,NULL,&s_transchase3};
+statetype s_transchase3 	= {false,SPR_TRANS_W3,10,T_Chase,NULL,&s_transchase3s};
+statetype s_transchase3s	= {false,SPR_TRANS_W3,3,NULL,NULL,&s_transchase4};
+statetype s_transchase4 	= {false,SPR_TRANS_W4,8,T_Chase,NULL,&s_transchase1};
+
+statetype s_transdie0	= {false,SPR_TRANS_W1,1,NULL,A_DeathScream,&s_transdie01};
+statetype s_transdie01	= {false,SPR_TRANS_W1,1,NULL,NULL,&s_transdie1};
+statetype s_transdie1	= {false,SPR_TRANS_DIE1,15,NULL,NULL,&s_transdie2};
+statetype s_transdie2	= {false,SPR_TRANS_DIE2,15,NULL,NULL,&s_transdie3};
+statetype s_transdie3	= {false,SPR_TRANS_DIE3,15,NULL,NULL,&s_transdie4};
+statetype s_transdie4	= {false,SPR_TRANS_DEAD,0,NULL,NULL,&s_transdie4};
+
+statetype s_transshoot1 	= {false,SPR_TRANS_SHOOT1,30,NULL,NULL,&s_transshoot2};
+statetype s_transshoot2 	= {false,SPR_TRANS_SHOOT2,10,NULL,T_Shoot,&s_transshoot3};
+statetype s_transshoot3 	= {false,SPR_TRANS_SHOOT3,10,NULL,T_Shoot,&s_transshoot4};
+statetype s_transshoot4 	= {false,SPR_TRANS_SHOOT2,10,NULL,T_Shoot,&s_transshoot5};
+statetype s_transshoot5 	= {false,SPR_TRANS_SHOOT3,10,NULL,T_Shoot,&s_transshoot6};
+statetype s_transshoot6 	= {false,SPR_TRANS_SHOOT2,10,NULL,T_Shoot,&s_transshoot7};
+statetype s_transshoot7 	= {false,SPR_TRANS_SHOOT3,10,NULL,T_Shoot,&s_transshoot8};
+statetype s_transshoot8 	= {false,SPR_TRANS_SHOOT1,10,NULL,NULL,&s_transchase1};
+
+
+/*
+===============
+=
+= SpawnTrans
+=
+===============
+*/
+
+void SpawnTrans (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	if (SoundBlasterPresent && DigiMode != sds_Off)
+		s_transdie01.tictime = 105;
+
+	SpawnNewObj (tilex,tiley,&s_transstand);
+	new->obclass = transobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_trans];
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+//
+// uber
+//
+void T_UShoot (objtype *ob);
+
+extern	statetype s_uberstand;
+
+extern	statetype s_uberchase1;
+extern	statetype s_uberchase1s;
+extern	statetype s_uberchase2;
+extern	statetype s_uberchase3;
+extern	statetype s_uberchase3s;
+extern	statetype s_uberchase4;
+
+extern	statetype s_uberdie0;
+extern	statetype s_uberdie01;
+extern	statetype s_uberdie1;
+extern	statetype s_uberdie2;
+extern	statetype s_uberdie3;
+extern	statetype s_uberdie4;
+extern	statetype s_uberdie5;
+
+extern	statetype s_ubershoot1;
+extern	statetype s_ubershoot2;
+extern	statetype s_ubershoot3;
+extern	statetype s_ubershoot4;
+extern	statetype s_ubershoot5;
+extern	statetype s_ubershoot6;
+extern	statetype s_ubershoot7;
+
+
+statetype s_uberstand	= {false,SPR_UBER_W1,0,T_Stand,NULL,&s_uberstand};
+
+statetype s_uberchase1 	= {false,SPR_UBER_W1,10,T_Chase,NULL,&s_uberchase1s};
+statetype s_uberchase1s	= {false,SPR_UBER_W1,3,NULL,NULL,&s_uberchase2};
+statetype s_uberchase2 	= {false,SPR_UBER_W2,8,T_Chase,NULL,&s_uberchase3};
+statetype s_uberchase3 	= {false,SPR_UBER_W3,10,T_Chase,NULL,&s_uberchase3s};
+statetype s_uberchase3s	= {false,SPR_UBER_W3,3,NULL,NULL,&s_uberchase4};
+statetype s_uberchase4 	= {false,SPR_UBER_W4,8,T_Chase,NULL,&s_uberchase1};
+
+statetype s_uberdie0	= {false,SPR_UBER_W1,1,NULL,A_DeathScream,&s_uberdie01};
+statetype s_uberdie01	= {false,SPR_UBER_W1,1,NULL,NULL,&s_uberdie1};
+statetype s_uberdie1	= {false,SPR_UBER_DIE1,15,NULL,NULL,&s_uberdie2};
+statetype s_uberdie2	= {false,SPR_UBER_DIE2,15,NULL,NULL,&s_uberdie3};
+statetype s_uberdie3	= {false,SPR_UBER_DIE3,15,NULL,NULL,&s_uberdie4};
+statetype s_uberdie4	= {false,SPR_UBER_DIE4,15,NULL,NULL,&s_uberdie5};
+statetype s_uberdie5	= {false,SPR_UBER_DEAD,0,NULL,NULL,&s_uberdie5};
+
+statetype s_ubershoot1 	= {false,SPR_UBER_SHOOT1,30,NULL,NULL,&s_ubershoot2};
+statetype s_ubershoot2 	= {false,SPR_UBER_SHOOT2,12,NULL,T_UShoot,&s_ubershoot3};
+statetype s_ubershoot3 	= {false,SPR_UBER_SHOOT3,12,NULL,T_UShoot,&s_ubershoot4};
+statetype s_ubershoot4 	= {false,SPR_UBER_SHOOT4,12,NULL,T_UShoot,&s_ubershoot5};
+statetype s_ubershoot5 	= {false,SPR_UBER_SHOOT3,12,NULL,T_UShoot,&s_ubershoot6};
+statetype s_ubershoot6 	= {false,SPR_UBER_SHOOT2,12,NULL,T_UShoot,&s_ubershoot7};
+statetype s_ubershoot7 	= {false,SPR_UBER_SHOOT1,12,NULL,NULL,&s_uberchase1};
+
+
+/*
+===============
+=
+= SpawnUber
+=
+===============
+*/
+
+void SpawnUber (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	if (SoundBlasterPresent && DigiMode != sds_Off)
+		s_uberdie01.tictime = 70;
+
+	SpawnNewObj (tilex,tiley,&s_uberstand);
+	new->obclass = uberobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_uber];
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+/*
+===============
+=
+= T_UShoot
+=
+===============
+*/
+
+void T_UShoot (objtype *ob)
+{
+	int	dx,dy,dist;
+
+	T_Shoot (ob);
+
+	dx = abs(ob->tilex - player->tilex);
+	dy = abs(ob->tiley - player->tiley);
+	dist = dx>dy ? dx : dy;
+	if (dist <= 1)
+		TakeDamage (10,ob);
+}
+
+
+//
+// will
+//
+extern	statetype s_willstand;
+
+extern	statetype s_willchase1;
+extern	statetype s_willchase1s;
+extern	statetype s_willchase2;
+extern	statetype s_willchase3;
+extern	statetype s_willchase3s;
+extern	statetype s_willchase4;
+
+extern	statetype s_willdie1;
+extern	statetype s_willdie2;
+extern	statetype s_willdie3;
+extern	statetype s_willdie4;
+extern	statetype s_willdie5;
+extern	statetype s_willdie6;
+
+extern	statetype s_willshoot1;
+extern	statetype s_willshoot2;
+extern	statetype s_willshoot3;
+extern	statetype s_willshoot4;
+extern	statetype s_willshoot5;
+extern	statetype s_willshoot6;
+
+
+statetype s_willstand	= {false,SPR_WILL_W1,0,T_Stand,NULL,&s_willstand};
+
+statetype s_willchase1 	= {false,SPR_WILL_W1,10,T_Will,NULL,&s_willchase1s};
+statetype s_willchase1s	= {false,SPR_WILL_W1,3,NULL,NULL,&s_willchase2};
+statetype s_willchase2 	= {false,SPR_WILL_W2,8,T_Will,NULL,&s_willchase3};
+statetype s_willchase3 	= {false,SPR_WILL_W3,10,T_Will,NULL,&s_willchase3s};
+statetype s_willchase3s	= {false,SPR_WILL_W3,3,NULL,NULL,&s_willchase4};
+statetype s_willchase4 	= {false,SPR_WILL_W4,8,T_Will,NULL,&s_willchase1};
+
+statetype s_willdeathcam	= {false,SPR_WILL_W1,1,NULL,NULL,&s_willdie1};
+
+statetype s_willdie1	= {false,SPR_WILL_W1,1,NULL,A_DeathScream,&s_willdie2};
+statetype s_willdie2	= {false,SPR_WILL_W1,10,NULL,NULL,&s_willdie3};
+statetype s_willdie3	= {false,SPR_WILL_DIE1,10,NULL,NULL,&s_willdie4};
+statetype s_willdie4	= {false,SPR_WILL_DIE2,10,NULL,NULL,&s_willdie5};
+statetype s_willdie5	= {false,SPR_WILL_DIE3,10,NULL,NULL,&s_willdie6};
+statetype s_willdie6	= {false,SPR_WILL_DEAD,20,NULL,NULL,&s_willdie6};
+
+statetype s_willshoot1 	= {false,SPR_WILL_SHOOT1,30,NULL,NULL,&s_willshoot2};
+statetype s_willshoot2 	= {false,SPR_WILL_SHOOT2,10,NULL,T_Launch,&s_willshoot3};
+statetype s_willshoot3 	= {false,SPR_WILL_SHOOT3,10,NULL,T_Shoot,&s_willshoot4};
+statetype s_willshoot4 	= {false,SPR_WILL_SHOOT4,10,NULL,T_Shoot,&s_willshoot5};
+statetype s_willshoot5 	= {false,SPR_WILL_SHOOT3,10,NULL,T_Shoot,&s_willshoot6};
+statetype s_willshoot6 	= {false,SPR_WILL_SHOOT4,10,NULL,T_Shoot,&s_willchase1};
+
+
+/*
+===============
+=
+= SpawnWill
+=
+===============
+*/
+
+void SpawnWill (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	if (SoundBlasterPresent && DigiMode != sds_Off)
+		s_willdie2.tictime = 70;
+
+	SpawnNewObj (tilex,tiley,&s_willstand);
+	new->obclass = willobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_will];
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+/*
+================
+=
+= T_Will
+=
+================
+*/
+
+void T_Will (objtype *ob)
+{
+	long move;
+	int	dx,dy,dist;
+	boolean	dodge;
+
+	dodge = false;
+	dx = abs(ob->tilex - player->tilex);
+	dy = abs(ob->tiley - player->tiley);
+	dist = dx>dy ? dx : dy;
+
+	if (CheckLine(ob))						// got a shot at player?
+	{
+		if ( US_RndT() < (tics<<3) )
+		{
+		//
+		// go into attack frame
+		//
+			if (ob->obclass == willobj)
+				NewState (ob,&s_willshoot1);
+			else if (ob->obclass == angelobj)
+				NewState (ob,&s_angelshoot1);
+			else
+				NewState (ob,&s_deathshoot1);
+			return;
+		}
+		dodge = true;
+	}
+
+	if (ob->dir == nodir)
+	{
+		if (dodge)
+			SelectDodgeDir (ob);
+		else
+			SelectChaseDir (ob);
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+	move = ob->speed*tics;
+
+	while (move)
+	{
+		if (ob->distance < 0)
+		{
+		//
+		// waiting for a door to open
+		//
+			OpenDoor (-ob->distance-1);
+			if (doorobjlist[-ob->distance-1].action != dr_open)
+				return;
+			ob->distance = TILEGLOBAL;	// go ahead, the door is now opoen
+		}
+
+		if (move < ob->distance)
+		{
+			MoveObj (ob,move);
+			break;
+		}
+
+		//
+		// reached goal tile, so select another one
+		//
+
+		//
+		// fix position to account for round off during moving
+		//
+		ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+		ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+
+		move -= ob->distance;
+
+		if (dist <4)
+			SelectRunDir (ob);
+		else if (dodge)
+			SelectDodgeDir (ob);
+		else
+			SelectChaseDir (ob);
+
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+}
+
+
+//
+// death
+//
+extern	statetype s_deathstand;
+
+extern	statetype s_deathchase1;
+extern	statetype s_deathchase1s;
+extern	statetype s_deathchase2;
+extern	statetype s_deathchase3;
+extern	statetype s_deathchase3s;
+extern	statetype s_deathchase4;
+
+extern	statetype s_deathdie1;
+extern	statetype s_deathdie2;
+extern	statetype s_deathdie3;
+extern	statetype s_deathdie4;
+extern	statetype s_deathdie5;
+extern	statetype s_deathdie6;
+extern	statetype s_deathdie7;
+extern	statetype s_deathdie8;
+extern	statetype s_deathdie9;
+
+extern	statetype s_deathshoot1;
+extern	statetype s_deathshoot2;
+extern	statetype s_deathshoot3;
+extern	statetype s_deathshoot4;
+extern	statetype s_deathshoot5;
+
+
+statetype s_deathstand	= {false,SPR_DEATH_W1,0,T_Stand,NULL,&s_deathstand};
+
+statetype s_deathchase1 	= {false,SPR_DEATH_W1,10,T_Will,NULL,&s_deathchase1s};
+statetype s_deathchase1s	= {false,SPR_DEATH_W1,3,NULL,NULL,&s_deathchase2};
+statetype s_deathchase2 	= {false,SPR_DEATH_W2,8,T_Will,NULL,&s_deathchase3};
+statetype s_deathchase3 	= {false,SPR_DEATH_W3,10,T_Will,NULL,&s_deathchase3s};
+statetype s_deathchase3s	= {false,SPR_DEATH_W3,3,NULL,NULL,&s_deathchase4};
+statetype s_deathchase4 	= {false,SPR_DEATH_W4,8,T_Will,NULL,&s_deathchase1};
+
+statetype s_deathdeathcam	= {false,SPR_DEATH_W1,1,NULL,NULL,&s_deathdie1};
+
+statetype s_deathdie1	= {false,SPR_DEATH_W1,1,NULL,A_DeathScream,&s_deathdie2};
+statetype s_deathdie2	= {false,SPR_DEATH_W1,10,NULL,NULL,&s_deathdie3};
+statetype s_deathdie3	= {false,SPR_DEATH_DIE1,10,NULL,NULL,&s_deathdie4};
+statetype s_deathdie4	= {false,SPR_DEATH_DIE2,10,NULL,NULL,&s_deathdie5};
+statetype s_deathdie5	= {false,SPR_DEATH_DIE3,10,NULL,NULL,&s_deathdie6};
+statetype s_deathdie6	= {false,SPR_DEATH_DIE4,10,NULL,NULL,&s_deathdie7};
+statetype s_deathdie7	= {false,SPR_DEATH_DIE5,10,NULL,NULL,&s_deathdie8};
+statetype s_deathdie8	= {false,SPR_DEATH_DIE6,10,NULL,NULL,&s_deathdie9};
+statetype s_deathdie9	= {false,SPR_DEATH_DEAD,0,NULL,NULL,&s_deathdie9};
+
+statetype s_deathshoot1 	= {false,SPR_DEATH_SHOOT1,30,NULL,NULL,&s_deathshoot2};
+statetype s_deathshoot2 	= {false,SPR_DEATH_SHOOT2,10,NULL,T_Launch,&s_deathshoot3};
+statetype s_deathshoot3 	= {false,SPR_DEATH_SHOOT4,10,NULL,T_Shoot,&s_deathshoot4};
+statetype s_deathshoot4 	= {false,SPR_DEATH_SHOOT3,10,NULL,T_Launch,&s_deathshoot5};
+statetype s_deathshoot5 	= {false,SPR_DEATH_SHOOT4,10,NULL,T_Shoot,&s_deathchase1};
+
+
+/*
+===============
+=
+= SpawnDeath
+=
+===============
+*/
+
+void SpawnDeath (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	if (SoundBlasterPresent && DigiMode != sds_Off)
+		s_deathdie2.tictime = 105;
+
+	SpawnNewObj (tilex,tiley,&s_deathstand);
+	new->obclass = deathobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_death];
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+/*
+===============
+=
+= T_Launch
+=
+===============
+*/
+
+void T_Launch (objtype *ob)
+{
+	long	deltax,deltay;
+	float	angle;
+	int		iangle;
+
+	deltax = player->x - ob->x;
+	deltay = ob->y - player->y;
+	angle = atan2 (deltay,deltax);
+	if (angle<0)
+		angle = M_PI*2+angle;
+	iangle = angle/(M_PI*2)*ANGLES;
+	if (ob->obclass == deathobj)
+	{
+		T_Shoot (ob);
+		if (ob->state == &s_deathshoot2)
+		{
+			iangle-=4;
+			if (iangle<0)
+				iangle+=ANGLES;
+		}
+		else
+		{
+			iangle+=4;
+			if (iangle>=ANGLES)
+				iangle-=ANGLES;
+		}
+	}
+
+	GetNewActor ();
+	new->state = &s_rocket;
+	new->ticcount = 1;
+
+	new->tilex = ob->tilex;
+	new->tiley = ob->tiley;
+	new->x = ob->x;
+	new->y = ob->y;
+	new->obclass = rocketobj;
+	switch(ob->obclass)
+	{
+	case deathobj:
+		new->state = &s_hrocket;
+		new->obclass = hrocketobj;
+		PlaySoundLocActor (KNIGHTMISSILESND,new);
+		break;
+	case angelobj:
+		new->state = &s_spark1;
+		new->obclass = sparkobj;
+		PlaySoundLocActor (ANGELFIRESND,new);
+		break;
+	default:
+		PlaySoundLocActor (MISSILEFIRESND,new);
+	}
+
+	new->dir = nodir;
+	new->angle = iangle;
+	new->speed = 0x2000l;
+	new->flags = FL_NONMARK;
+	new->active = true;
+}
+
+
+
+//
+// angel
+//
+void A_Relaunch (objtype *ob);
+void A_Victory (objtype *ob);
+void A_StartAttack (objtype *ob);
+void A_Breathing (objtype *ob);
+
+extern	statetype s_angelstand;
+
+extern	statetype s_angelchase1;
+extern	statetype s_angelchase1s;
+extern	statetype s_angelchase2;
+extern	statetype s_angelchase3;
+extern	statetype s_angelchase3s;
+extern	statetype s_angelchase4;
+
+extern	statetype s_angeldie1;
+extern	statetype s_angeldie11;
+extern	statetype s_angeldie2;
+extern	statetype s_angeldie3;
+extern	statetype s_angeldie4;
+extern	statetype s_angeldie5;
+extern	statetype s_angeldie6;
+extern	statetype s_angeldie7;
+extern	statetype s_angeldie8;
+extern	statetype s_angeldie9;
+
+extern	statetype s_angelshoot1;
+extern	statetype s_angelshoot2;
+extern	statetype s_angelshoot3;
+extern	statetype s_angelshoot4;
+extern	statetype s_angelshoot5;
+extern	statetype s_angelshoot6;
+
+extern	statetype s_angeltired;
+extern	statetype s_angeltired2;
+extern	statetype s_angeltired3;
+extern	statetype s_angeltired4;
+extern	statetype s_angeltired5;
+extern	statetype s_angeltired6;
+extern	statetype s_angeltired7;
+
+extern	statetype s_spark1;
+extern	statetype s_spark2;
+extern	statetype s_spark3;
+extern	statetype s_spark4;
+
+
+statetype s_angelstand	= {false,SPR_ANGEL_W1,0,T_Stand,NULL,&s_angelstand};
+
+statetype s_angelchase1 	= {false,SPR_ANGEL_W1,10,T_Will,NULL,&s_angelchase1s};
+statetype s_angelchase1s	= {false,SPR_ANGEL_W1,3,NULL,NULL,&s_angelchase2};
+statetype s_angelchase2 	= {false,SPR_ANGEL_W2,8,T_Will,NULL,&s_angelchase3};
+statetype s_angelchase3 	= {false,SPR_ANGEL_W3,10,T_Will,NULL,&s_angelchase3s};
+statetype s_angelchase3s	= {false,SPR_ANGEL_W3,3,NULL,NULL,&s_angelchase4};
+statetype s_angelchase4 	= {false,SPR_ANGEL_W4,8,T_Will,NULL,&s_angelchase1};
+
+statetype s_angeldie1	= {false,SPR_ANGEL_W1,1,NULL,A_DeathScream,&s_angeldie11};
+statetype s_angeldie11	= {false,SPR_ANGEL_W1,1,NULL,NULL,&s_angeldie2};
+statetype s_angeldie2	= {false,SPR_ANGEL_DIE1,10,NULL,A_Slurpie,&s_angeldie3};
+statetype s_angeldie3	= {false,SPR_ANGEL_DIE2,10,NULL,NULL,&s_angeldie4};
+statetype s_angeldie4	= {false,SPR_ANGEL_DIE3,10,NULL,NULL,&s_angeldie5};
+statetype s_angeldie5	= {false,SPR_ANGEL_DIE4,10,NULL,NULL,&s_angeldie6};
+statetype s_angeldie6	= {false,SPR_ANGEL_DIE5,10,NULL,NULL,&s_angeldie7};
+statetype s_angeldie7	= {false,SPR_ANGEL_DIE6,10,NULL,NULL,&s_angeldie8};
+statetype s_angeldie8	= {false,SPR_ANGEL_DIE7,10,NULL,NULL,&s_angeldie9};
+statetype s_angeldie9	= {false,SPR_ANGEL_DEAD,130,NULL,A_Victory,&s_angeldie9};
+
+statetype s_angelshoot1 	= {false,SPR_ANGEL_SHOOT1,10,NULL,A_StartAttack,&s_angelshoot2};
+statetype s_angelshoot2 	= {false,SPR_ANGEL_SHOOT2,20,NULL,T_Launch,&s_angelshoot3};
+statetype s_angelshoot3 	= {false,SPR_ANGEL_SHOOT1,10,NULL,A_Relaunch,&s_angelshoot2};
+
+statetype s_angeltired 	= {false,SPR_ANGEL_TIRED1,40,NULL,A_Breathing,&s_angeltired2};
+statetype s_angeltired2	= {false,SPR_ANGEL_TIRED2,40,NULL,NULL,&s_angeltired3};
+statetype s_angeltired3	= {false,SPR_ANGEL_TIRED1,40,NULL,A_Breathing,&s_angeltired4};
+statetype s_angeltired4	= {false,SPR_ANGEL_TIRED2,40,NULL,NULL,&s_angeltired5};
+statetype s_angeltired5	= {false,SPR_ANGEL_TIRED1,40,NULL,A_Breathing,&s_angeltired6};
+statetype s_angeltired6	= {false,SPR_ANGEL_TIRED2,40,NULL,NULL,&s_angeltired7};
+statetype s_angeltired7	= {false,SPR_ANGEL_TIRED1,40,NULL,A_Breathing,&s_angelchase1};
+
+statetype s_spark1 	= {false,SPR_SPARK1,6,T_Projectile,NULL,&s_spark2};
+statetype s_spark2 	= {false,SPR_SPARK2,6,T_Projectile,NULL,&s_spark3};
+statetype s_spark3 	= {false,SPR_SPARK3,6,T_Projectile,NULL,&s_spark4};
+statetype s_spark4 	= {false,SPR_SPARK4,6,T_Projectile,NULL,&s_spark1};
+
+
+#pragma argsused
+void A_Slurpie (objtype *ob)
+{
+ SD_PlaySound(SLURPIESND);
+}
+
+#pragma argsused
+void A_Breathing (objtype *ob)
+{
+ SD_PlaySound(ANGELTIREDSND);
+}
+
+/*
+===============
+=
+= SpawnAngel
+=
+===============
+*/
+
+void SpawnAngel (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+
+	if (SoundBlasterPresent && DigiMode != sds_Off)
+		s_angeldie11.tictime = 105;
+
+	SpawnNewObj (tilex,tiley,&s_angelstand);
+	new->obclass = angelobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_angel];
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+/*
+=================
+=
+= A_Victory
+=
+=================
+*/
+
+#pragma argsused
+void A_Victory (objtype *ob)
+{
+	playstate = ex_victorious;
+}
+
+
+/*
+=================
+=
+= A_StartAttack
+=
+=================
+*/
+
+void A_StartAttack (objtype *ob)
+{
+	ob->temp1 = 0;
+}
+
+
+/*
+=================
+=
+= A_Relaunch
+=
+=================
+*/
+
+void A_Relaunch (objtype *ob)
+{
+	if (++ob->temp1 == 3)
+	{
+		NewState (ob,&s_angeltired);
+		return;
+	}
+
+	if (US_RndT()&1)
+	{
+		NewState (ob,&s_angelchase1);
+		return;
+	}
+}
+
+
+
+
+//
+// spectre
+//
+void T_SpectreWait (objtype *ob);
+void A_Dormant (objtype *ob);
+
+extern	statetype s_spectrewait1;
+extern	statetype s_spectrewait2;
+extern	statetype s_spectrewait3;
+extern	statetype s_spectrewait4;
+
+extern	statetype s_spectrechase1;
+extern	statetype s_spectrechase2;
+extern	statetype s_spectrechase3;
+extern	statetype s_spectrechase4;
+
+extern	statetype s_spectredie1;
+extern	statetype s_spectredie2;
+extern	statetype s_spectredie3;
+extern	statetype s_spectredie4;
+
+extern	statetype s_spectrewake;
+
+statetype s_spectrewait1	= {false,SPR_SPECTRE_W1,10,T_Stand,NULL,&s_spectrewait2};
+statetype s_spectrewait2	= {false,SPR_SPECTRE_W2,10,T_Stand,NULL,&s_spectrewait3};
+statetype s_spectrewait3	= {false,SPR_SPECTRE_W3,10,T_Stand,NULL,&s_spectrewait4};
+statetype s_spectrewait4	= {false,SPR_SPECTRE_W4,10,T_Stand,NULL,&s_spectrewait1};
+
+statetype s_spectrechase1	= {false,SPR_SPECTRE_W1,10,T_Ghosts,NULL,&s_spectrechase2};
+statetype s_spectrechase2	= {false,SPR_SPECTRE_W2,10,T_Ghosts,NULL,&s_spectrechase3};
+statetype s_spectrechase3	= {false,SPR_SPECTRE_W3,10,T_Ghosts,NULL,&s_spectrechase4};
+statetype s_spectrechase4	= {false,SPR_SPECTRE_W4,10,T_Ghosts,NULL,&s_spectrechase1};
+
+statetype s_spectredie1	= {false,SPR_SPECTRE_F1,10,NULL,NULL,&s_spectredie2};
+statetype s_spectredie2	= {false,SPR_SPECTRE_F2,10,NULL,NULL,&s_spectredie3};
+statetype s_spectredie3	= {false,SPR_SPECTRE_F3,10,NULL,NULL,&s_spectredie4};
+statetype s_spectredie4	= {false,SPR_SPECTRE_F4,300,NULL,NULL,&s_spectrewake};
+statetype s_spectrewake	= {false,SPR_SPECTRE_F4,10,NULL,A_Dormant,&s_spectrewake};
+
+/*
+===============
+=
+= SpawnSpectre
+=
+===============
+*/
+
+void SpawnSpectre (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	SpawnNewObj (tilex,tiley,&s_spectrewait1);
+	new->obclass = spectreobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_spectre];
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH; // |FL_NEVERMARK|FL_NONMARK;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+/*
+===============
+=
+= A_Dormant
+=
+===============
+*/
+
+void A_Dormant (objtype *ob)
+{
+	long	deltax,deltay;
+	int	xl,xh,yl,yh;
+	int	x,y;
+	unsigned	tile;
+
+	deltax = ob->x - player->x;
+	if (deltax < -MINACTORDIST || deltax > MINACTORDIST)
+		goto moveok;
+	deltay = ob->y - player->y;
+	if (deltay < -MINACTORDIST || deltay > MINACTORDIST)
+		goto moveok;
+
+	return;
+moveok:
+
+	xl = (ob->x-MINDIST) >> TILESHIFT;
+	xh = (ob->x+MINDIST) >> TILESHIFT;
+	yl = (ob->y-MINDIST) >> TILESHIFT;
+	yh = (ob->y+MINDIST) >> TILESHIFT;
+
+	for (y=yl ; y<=yh ; y++)
+		for (x=xl ; x<=xh ; x++)
+		{
+			tile = actorat[x][y];
+			if (!tile)
+				continue;
+			if (tile<256)
+				return;
+			if (((objtype *)tile)->flags&FL_SHOOTABLE)
+				return;
+		}
+
+	ob->flags |= FL_AMBUSH | FL_SHOOTABLE;
+	ob->flags &= ~FL_ATTACKMODE;
+	ob->dir = nodir;
+	NewState (ob,&s_spectrewait1);
+}
+
+
+#endif
+
+/*
+=============================================================================
+
+						 SCHABBS / GIFT / FAT
+
+=============================================================================
+*/
+
+#ifndef SPEAR
+/*
+===============
+=
+= SpawnGhosts
+=
+===============
+*/
+
+void SpawnGhosts (int which, int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	switch(which)
+	{
+	 case en_blinky:
+	   SpawnNewObj (tilex,tiley,&s_blinkychase1);
+	   break;
+	 case en_clyde:
+	   SpawnNewObj (tilex,tiley,&s_clydechase1);
+	   break;
+	 case en_pinky:
+	   SpawnNewObj (tilex,tiley,&s_pinkychase1);
+	   break;
+	 case en_inky:
+	   SpawnNewObj (tilex,tiley,&s_inkychase1);
+	   break;
+	}
+
+	new->obclass = ghostobj;
+	new->speed = SPDDOG;
+
+	new->dir = east;
+	new->flags |= FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+
+void	T_Gift (objtype *ob);
+void	T_GiftThrow (objtype *ob);
+
+void	T_Fat (objtype *ob);
+void	T_FatThrow (objtype *ob);
+
+//
+// schabb
+//
+extern	statetype s_schabbstand;
+
+extern	statetype s_schabbchase1;
+extern	statetype s_schabbchase1s;
+extern	statetype s_schabbchase2;
+extern	statetype s_schabbchase3;
+extern	statetype s_schabbchase3s;
+extern	statetype s_schabbchase4;
+
+extern	statetype s_schabbdie1;
+extern	statetype s_schabbdie2;
+extern	statetype s_schabbdie3;
+extern	statetype s_schabbdie4;
+extern	statetype s_schabbdie5;
+extern	statetype s_schabbdie6;
+
+extern	statetype s_schabbshoot1;
+extern	statetype s_schabbshoot2;
+
+extern	statetype s_needle1;
+extern	statetype s_needle2;
+extern	statetype s_needle3;
+extern	statetype s_needle4;
+
+extern	statetype s_schabbdeathcam;
+
+
+statetype s_schabbstand	= {false,SPR_SCHABB_W1,0,T_Stand,NULL,&s_schabbstand};
+
+statetype s_schabbchase1 	= {false,SPR_SCHABB_W1,10,T_Schabb,NULL,&s_schabbchase1s};
+statetype s_schabbchase1s	= {false,SPR_SCHABB_W1,3,NULL,NULL,&s_schabbchase2};
+statetype s_schabbchase2 	= {false,SPR_SCHABB_W2,8,T_Schabb,NULL,&s_schabbchase3};
+statetype s_schabbchase3 	= {false,SPR_SCHABB_W3,10,T_Schabb,NULL,&s_schabbchase3s};
+statetype s_schabbchase3s	= {false,SPR_SCHABB_W3,3,NULL,NULL,&s_schabbchase4};
+statetype s_schabbchase4 	= {false,SPR_SCHABB_W4,8,T_Schabb,NULL,&s_schabbchase1};
+
+statetype s_schabbdeathcam	= {false,SPR_SCHABB_W1,1,NULL,NULL,&s_schabbdie1};
+
+statetype s_schabbdie1	= {false,SPR_SCHABB_W1,10,NULL,A_DeathScream,&s_schabbdie2};
+statetype s_schabbdie2	= {false,SPR_SCHABB_W1,10,NULL,NULL,&s_schabbdie3};
+statetype s_schabbdie3	= {false,SPR_SCHABB_DIE1,10,NULL,NULL,&s_schabbdie4};
+statetype s_schabbdie4	= {false,SPR_SCHABB_DIE2,10,NULL,NULL,&s_schabbdie5};
+statetype s_schabbdie5	= {false,SPR_SCHABB_DIE3,10,NULL,NULL,&s_schabbdie6};
+statetype s_schabbdie6	= {false,SPR_SCHABB_DEAD,20,NULL,A_StartDeathCam,&s_schabbdie6};
+
+statetype s_schabbshoot1 	= {false,SPR_SCHABB_SHOOT1,30,NULL,NULL,&s_schabbshoot2};
+statetype s_schabbshoot2 	= {false,SPR_SCHABB_SHOOT2,10,NULL,T_SchabbThrow,&s_schabbchase1};
+
+statetype s_needle1 	= {false,SPR_HYPO1,6,T_Projectile,NULL,&s_needle2};
+statetype s_needle2 	= {false,SPR_HYPO2,6,T_Projectile,NULL,&s_needle3};
+statetype s_needle3 	= {false,SPR_HYPO3,6,T_Projectile,NULL,&s_needle4};
+statetype s_needle4 	= {false,SPR_HYPO4,6,T_Projectile,NULL,&s_needle1};
+
+
+//
+// gift
+//
+extern	statetype s_giftstand;
+
+extern	statetype s_giftchase1;
+extern	statetype s_giftchase1s;
+extern	statetype s_giftchase2;
+extern	statetype s_giftchase3;
+extern	statetype s_giftchase3s;
+extern	statetype s_giftchase4;
+
+extern	statetype s_giftdie1;
+extern	statetype s_giftdie2;
+extern	statetype s_giftdie3;
+extern	statetype s_giftdie4;
+extern	statetype s_giftdie5;
+extern	statetype s_giftdie6;
+
+extern	statetype s_giftshoot1;
+extern	statetype s_giftshoot2;
+
+extern	statetype s_needle1;
+extern	statetype s_needle2;
+extern	statetype s_needle3;
+extern	statetype s_needle4;
+
+extern	statetype s_giftdeathcam;
+
+extern	statetype s_boom1;
+extern	statetype s_boom2;
+extern	statetype s_boom3;
+
+
+statetype s_giftstand	= {false,SPR_GIFT_W1,0,T_Stand,NULL,&s_giftstand};
+
+statetype s_giftchase1 	= {false,SPR_GIFT_W1,10,T_Gift,NULL,&s_giftchase1s};
+statetype s_giftchase1s	= {false,SPR_GIFT_W1,3,NULL,NULL,&s_giftchase2};
+statetype s_giftchase2 	= {false,SPR_GIFT_W2,8,T_Gift,NULL,&s_giftchase3};
+statetype s_giftchase3 	= {false,SPR_GIFT_W3,10,T_Gift,NULL,&s_giftchase3s};
+statetype s_giftchase3s	= {false,SPR_GIFT_W3,3,NULL,NULL,&s_giftchase4};
+statetype s_giftchase4 	= {false,SPR_GIFT_W4,8,T_Gift,NULL,&s_giftchase1};
+
+statetype s_giftdeathcam	= {false,SPR_GIFT_W1,1,NULL,NULL,&s_giftdie1};
+
+statetype s_giftdie1	= {false,SPR_GIFT_W1,1,NULL,A_DeathScream,&s_giftdie2};
+statetype s_giftdie2	= {false,SPR_GIFT_W1,10,NULL,NULL,&s_giftdie3};
+statetype s_giftdie3	= {false,SPR_GIFT_DIE1,10,NULL,NULL,&s_giftdie4};
+statetype s_giftdie4	= {false,SPR_GIFT_DIE2,10,NULL,NULL,&s_giftdie5};
+statetype s_giftdie5	= {false,SPR_GIFT_DIE3,10,NULL,NULL,&s_giftdie6};
+statetype s_giftdie6	= {false,SPR_GIFT_DEAD,20,NULL,A_StartDeathCam,&s_giftdie6};
+
+statetype s_giftshoot1 	= {false,SPR_GIFT_SHOOT1,30,NULL,NULL,&s_giftshoot2};
+statetype s_giftshoot2 	= {false,SPR_GIFT_SHOOT2,10,NULL,T_GiftThrow,&s_giftchase1};
+
+
+//
+// fat
+//
+extern	statetype s_fatstand;
+
+extern	statetype s_fatchase1;
+extern	statetype s_fatchase1s;
+extern	statetype s_fatchase2;
+extern	statetype s_fatchase3;
+extern	statetype s_fatchase3s;
+extern	statetype s_fatchase4;
+
+extern	statetype s_fatdie1;
+extern	statetype s_fatdie2;
+extern	statetype s_fatdie3;
+extern	statetype s_fatdie4;
+extern	statetype s_fatdie5;
+extern	statetype s_fatdie6;
+
+extern	statetype s_fatshoot1;
+extern	statetype s_fatshoot2;
+extern	statetype s_fatshoot3;
+extern	statetype s_fatshoot4;
+extern	statetype s_fatshoot5;
+extern	statetype s_fatshoot6;
+
+extern	statetype s_needle1;
+extern	statetype s_needle2;
+extern	statetype s_needle3;
+extern	statetype s_needle4;
+
+extern	statetype s_fatdeathcam;
+
+
+statetype s_fatstand	= {false,SPR_FAT_W1,0,T_Stand,NULL,&s_fatstand};
+
+statetype s_fatchase1 	= {false,SPR_FAT_W1,10,T_Fat,NULL,&s_fatchase1s};
+statetype s_fatchase1s	= {false,SPR_FAT_W1,3,NULL,NULL,&s_fatchase2};
+statetype s_fatchase2 	= {false,SPR_FAT_W2,8,T_Fat,NULL,&s_fatchase3};
+statetype s_fatchase3 	= {false,SPR_FAT_W3,10,T_Fat,NULL,&s_fatchase3s};
+statetype s_fatchase3s	= {false,SPR_FAT_W3,3,NULL,NULL,&s_fatchase4};
+statetype s_fatchase4 	= {false,SPR_FAT_W4,8,T_Fat,NULL,&s_fatchase1};
+
+statetype s_fatdeathcam	= {false,SPR_FAT_W1,1,NULL,NULL,&s_fatdie1};
+
+statetype s_fatdie1	= {false,SPR_FAT_W1,1,NULL,A_DeathScream,&s_fatdie2};
+statetype s_fatdie2	= {false,SPR_FAT_W1,10,NULL,NULL,&s_fatdie3};
+statetype s_fatdie3	= {false,SPR_FAT_DIE1,10,NULL,NULL,&s_fatdie4};
+statetype s_fatdie4	= {false,SPR_FAT_DIE2,10,NULL,NULL,&s_fatdie5};
+statetype s_fatdie5	= {false,SPR_FAT_DIE3,10,NULL,NULL,&s_fatdie6};
+statetype s_fatdie6	= {false,SPR_FAT_DEAD,20,NULL,A_StartDeathCam,&s_fatdie6};
+
+statetype s_fatshoot1 	= {false,SPR_FAT_SHOOT1,30,NULL,NULL,&s_fatshoot2};
+statetype s_fatshoot2 	= {false,SPR_FAT_SHOOT2,10,NULL,T_GiftThrow,&s_fatshoot3};
+statetype s_fatshoot3 	= {false,SPR_FAT_SHOOT3,10,NULL,T_Shoot,&s_fatshoot4};
+statetype s_fatshoot4 	= {false,SPR_FAT_SHOOT4,10,NULL,T_Shoot,&s_fatshoot5};
+statetype s_fatshoot5 	= {false,SPR_FAT_SHOOT3,10,NULL,T_Shoot,&s_fatshoot6};
+statetype s_fatshoot6 	= {false,SPR_FAT_SHOOT4,10,NULL,T_Shoot,&s_fatchase1};
+
+
+/*
+===============
+=
+= SpawnSchabbs
+=
+===============
+*/
+
+void SpawnSchabbs (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	if (DigiMode != sds_Off)
+		s_schabbdie2.tictime = 140;
+	else
+		s_schabbdie2.tictime = 5;
+
+	SpawnNewObj (tilex,tiley,&s_schabbstand);
+	new->speed = SPDPATROL;
+
+	new->obclass = schabbobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_schabbs];
+	new->dir = south;
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+/*
+===============
+=
+= SpawnGift
+=
+===============
+*/
+
+void SpawnGift (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	if (DigiMode != sds_Off)
+	  s_giftdie2.tictime = 140;
+	else
+	  s_giftdie2.tictime = 5;
+
+	SpawnNewObj (tilex,tiley,&s_giftstand);
+	new->speed = SPDPATROL;
+
+	new->obclass = giftobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_gift];
+	new->dir = north;
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+/*
+===============
+=
+= SpawnFat
+=
+===============
+*/
+
+void SpawnFat (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	if (DigiMode != sds_Off)
+	  s_fatdie2.tictime = 140;
+	else
+	  s_fatdie2.tictime = 5;
+
+	SpawnNewObj (tilex,tiley,&s_fatstand);
+	new->speed = SPDPATROL;
+
+	new->obclass = fatobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_fat];
+	new->dir = south;
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+/*
+=================
+=
+= T_SchabbThrow
+=
+=================
+*/
+
+void T_SchabbThrow (objtype *ob)
+{
+	long	deltax,deltay;
+	float	angle;
+	int		iangle;
+
+	deltax = player->x - ob->x;
+	deltay = ob->y - player->y;
+	angle = atan2 (deltay,deltax);
+	if (angle<0)
+		angle = M_PI*2+angle;
+	iangle = angle/(M_PI*2)*ANGLES;
+
+	GetNewActor ();
+	new->state = &s_needle1;
+	new->ticcount = 1;
+
+	new->tilex = ob->tilex;
+	new->tiley = ob->tiley;
+	new->x = ob->x;
+	new->y = ob->y;
+	new->obclass = needleobj;
+	new->dir = nodir;
+	new->angle = iangle;
+	new->speed = 0x2000l;
+
+	new->flags = FL_NONMARK;
+	new->active = true;
+
+	PlaySoundLocActor (SCHABBSTHROWSND,new);
+}
+
+/*
+=================
+=
+= T_GiftThrow
+=
+=================
+*/
+
+void T_GiftThrow (objtype *ob)
+{
+	long	deltax,deltay;
+	float	angle;
+	int		iangle;
+
+	deltax = player->x - ob->x;
+	deltay = ob->y - player->y;
+	angle = atan2 (deltay,deltax);
+	if (angle<0)
+		angle = M_PI*2+angle;
+	iangle = angle/(M_PI*2)*ANGLES;
+
+	GetNewActor ();
+	new->state = &s_rocket;
+	new->ticcount = 1;
+
+	new->tilex = ob->tilex;
+	new->tiley = ob->tiley;
+	new->x = ob->x;
+	new->y = ob->y;
+	new->obclass = rocketobj;
+	new->dir = nodir;
+	new->angle = iangle;
+	new->speed = 0x2000l;
+	new->flags = FL_NONMARK;
+	new->active = true;
+
+	PlaySoundLocActor (MISSILEFIRESND,new);
+}
+
+
+
+/*
+=================
+=
+= T_Schabb
+=
+=================
+*/
+
+void T_Schabb (objtype *ob)
+{
+	long move;
+	int	dx,dy,dist;
+	boolean	dodge;
+
+	dodge = false;
+	dx = abs(ob->tilex - player->tilex);
+	dy = abs(ob->tiley - player->tiley);
+	dist = dx>dy ? dx : dy;
+
+	if (CheckLine(ob))						// got a shot at player?
+	{
+
+		if ( US_RndT() < (tics<<3) )
+		{
+		//
+		// go into attack frame
+		//
+			NewState (ob,&s_schabbshoot1);
+			return;
+		}
+		dodge = true;
+	}
+
+	if (ob->dir == nodir)
+	{
+		if (dodge)
+			SelectDodgeDir (ob);
+		else
+			SelectChaseDir (ob);
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+	move = ob->speed*tics;
+
+	while (move)
+	{
+		if (ob->distance < 0)
+		{
+		//
+		// waiting for a door to open
+		//
+			OpenDoor (-ob->distance-1);
+			if (doorobjlist[-ob->distance-1].action != dr_open)
+				return;
+			ob->distance = TILEGLOBAL;	// go ahead, the door is now opoen
+		}
+
+		if (move < ob->distance)
+		{
+			MoveObj (ob,move);
+			break;
+		}
+
+		//
+		// reached goal tile, so select another one
+		//
+
+		//
+		// fix position to account for round off during moving
+		//
+		ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+		ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+
+		move -= ob->distance;
+
+		if (dist <4)
+			SelectRunDir (ob);
+		else if (dodge)
+			SelectDodgeDir (ob);
+		else
+			SelectChaseDir (ob);
+
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+}
+
+
+
+
+/*
+=================
+=
+= T_Gift
+=
+=================
+*/
+
+void T_Gift (objtype *ob)
+{
+	long move;
+	int	dx,dy,dist;
+	boolean	dodge;
+
+	dodge = false;
+	dx = abs(ob->tilex - player->tilex);
+	dy = abs(ob->tiley - player->tiley);
+	dist = dx>dy ? dx : dy;
+
+	if (CheckLine(ob))						// got a shot at player?
+	{
+
+		if ( US_RndT() < (tics<<3) )
+		{
+		//
+		// go into attack frame
+		//
+			NewState (ob,&s_giftshoot1);
+			return;
+		}
+		dodge = true;
+	}
+
+	if (ob->dir == nodir)
+	{
+		if (dodge)
+			SelectDodgeDir (ob);
+		else
+			SelectChaseDir (ob);
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+	move = ob->speed*tics;
+
+	while (move)
+	{
+		if (ob->distance < 0)
+		{
+		//
+		// waiting for a door to open
+		//
+			OpenDoor (-ob->distance-1);
+			if (doorobjlist[-ob->distance-1].action != dr_open)
+				return;
+			ob->distance = TILEGLOBAL;	// go ahead, the door is now opoen
+		}
+
+		if (move < ob->distance)
+		{
+			MoveObj (ob,move);
+			break;
+		}
+
+		//
+		// reached goal tile, so select another one
+		//
+
+		//
+		// fix position to account for round off during moving
+		//
+		ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+		ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+
+		move -= ob->distance;
+
+		if (dist <4)
+			SelectRunDir (ob);
+		else if (dodge)
+			SelectDodgeDir (ob);
+		else
+			SelectChaseDir (ob);
+
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+}
+
+
+
+
+/*
+=================
+=
+= T_Fat
+=
+=================
+*/
+
+void T_Fat (objtype *ob)
+{
+	long move;
+	int	dx,dy,dist;
+	boolean	dodge;
+
+	dodge = false;
+	dx = abs(ob->tilex - player->tilex);
+	dy = abs(ob->tiley - player->tiley);
+	dist = dx>dy ? dx : dy;
+
+	if (CheckLine(ob))						// got a shot at player?
+	{
+
+		if ( US_RndT() < (tics<<3) )
+		{
+		//
+		// go into attack frame
+		//
+			NewState (ob,&s_fatshoot1);
+			return;
+		}
+		dodge = true;
+	}
+
+	if (ob->dir == nodir)
+	{
+		if (dodge)
+			SelectDodgeDir (ob);
+		else
+			SelectChaseDir (ob);
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+	move = ob->speed*tics;
+
+	while (move)
+	{
+		if (ob->distance < 0)
+		{
+		//
+		// waiting for a door to open
+		//
+			OpenDoor (-ob->distance-1);
+			if (doorobjlist[-ob->distance-1].action != dr_open)
+				return;
+			ob->distance = TILEGLOBAL;	// go ahead, the door is now opoen
+		}
+
+		if (move < ob->distance)
+		{
+			MoveObj (ob,move);
+			break;
+		}
+
+		//
+		// reached goal tile, so select another one
+		//
+
+		//
+		// fix position to account for round off during moving
+		//
+		ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+		ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+
+		move -= ob->distance;
+
+		if (dist <4)
+			SelectRunDir (ob);
+		else if (dodge)
+			SelectDodgeDir (ob);
+		else
+			SelectChaseDir (ob);
+
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+}
+
+
+
+/*
+=============================================================================
+
+							HITLERS
+
+=============================================================================
+*/
+
+
+//
+// fake
+//
+extern	statetype s_fakestand;
+
+extern	statetype s_fakechase1;
+extern	statetype s_fakechase1s;
+extern	statetype s_fakechase2;
+extern	statetype s_fakechase3;
+extern	statetype s_fakechase3s;
+extern	statetype s_fakechase4;
+
+extern	statetype s_fakedie1;
+extern	statetype s_fakedie2;
+extern	statetype s_fakedie3;
+extern	statetype s_fakedie4;
+extern	statetype s_fakedie5;
+extern	statetype s_fakedie6;
+
+extern	statetype s_fakeshoot1;
+extern	statetype s_fakeshoot2;
+extern	statetype s_fakeshoot3;
+extern	statetype s_fakeshoot4;
+extern	statetype s_fakeshoot5;
+extern	statetype s_fakeshoot6;
+extern	statetype s_fakeshoot7;
+extern	statetype s_fakeshoot8;
+extern	statetype s_fakeshoot9;
+
+extern	statetype s_fire1;
+extern	statetype s_fire2;
+
+statetype s_fakestand	= {false,SPR_FAKE_W1,0,T_Stand,NULL,&s_fakestand};
+
+statetype s_fakechase1 	= {false,SPR_FAKE_W1,10,T_Fake,NULL,&s_fakechase1s};
+statetype s_fakechase1s	= {false,SPR_FAKE_W1,3,NULL,NULL,&s_fakechase2};
+statetype s_fakechase2 	= {false,SPR_FAKE_W2,8,T_Fake,NULL,&s_fakechase3};
+statetype s_fakechase3 	= {false,SPR_FAKE_W3,10,T_Fake,NULL,&s_fakechase3s};
+statetype s_fakechase3s	= {false,SPR_FAKE_W3,3,NULL,NULL,&s_fakechase4};
+statetype s_fakechase4 	= {false,SPR_FAKE_W4,8,T_Fake,NULL,&s_fakechase1};
+
+statetype s_fakedie1	= {false,SPR_FAKE_DIE1,10,NULL,A_DeathScream,&s_fakedie2};
+statetype s_fakedie2	= {false,SPR_FAKE_DIE2,10,NULL,NULL,&s_fakedie3};
+statetype s_fakedie3	= {false,SPR_FAKE_DIE3,10,NULL,NULL,&s_fakedie4};
+statetype s_fakedie4	= {false,SPR_FAKE_DIE4,10,NULL,NULL,&s_fakedie5};
+statetype s_fakedie5	= {false,SPR_FAKE_DIE5,10,NULL,NULL,&s_fakedie6};
+statetype s_fakedie6	= {false,SPR_FAKE_DEAD,0,NULL,NULL,&s_fakedie6};
+
+statetype s_fakeshoot1 	= {false,SPR_FAKE_SHOOT,8,NULL,T_FakeFire,&s_fakeshoot2};
+statetype s_fakeshoot2 	= {false,SPR_FAKE_SHOOT,8,NULL,T_FakeFire,&s_fakeshoot3};
+statetype s_fakeshoot3 	= {false,SPR_FAKE_SHOOT,8,NULL,T_FakeFire,&s_fakeshoot4};
+statetype s_fakeshoot4 	= {false,SPR_FAKE_SHOOT,8,NULL,T_FakeFire,&s_fakeshoot5};
+statetype s_fakeshoot5 	= {false,SPR_FAKE_SHOOT,8,NULL,T_FakeFire,&s_fakeshoot6};
+statetype s_fakeshoot6 	= {false,SPR_FAKE_SHOOT,8,NULL,T_FakeFire,&s_fakeshoot7};
+statetype s_fakeshoot7 	= {false,SPR_FAKE_SHOOT,8,NULL,T_FakeFire,&s_fakeshoot8};
+statetype s_fakeshoot8 	= {false,SPR_FAKE_SHOOT,8,NULL,T_FakeFire,&s_fakeshoot9};
+statetype s_fakeshoot9 	= {false,SPR_FAKE_SHOOT,8,NULL,NULL,&s_fakechase1};
+
+statetype s_fire1 	= {false,SPR_FIRE1,6,NULL,T_Projectile,&s_fire2};
+statetype s_fire2 	= {false,SPR_FIRE2,6,NULL,T_Projectile,&s_fire1};
+
+//
+// hitler
+//
+extern	statetype s_mechachase1;
+extern	statetype s_mechachase1s;
+extern	statetype s_mechachase2;
+extern	statetype s_mechachase3;
+extern	statetype s_mechachase3s;
+extern	statetype s_mechachase4;
+
+extern	statetype s_mechadie1;
+extern	statetype s_mechadie2;
+extern	statetype s_mechadie3;
+extern	statetype s_mechadie4;
+
+extern	statetype s_mechashoot1;
+extern	statetype s_mechashoot2;
+extern	statetype s_mechashoot3;
+extern	statetype s_mechashoot4;
+extern	statetype s_mechashoot5;
+extern	statetype s_mechashoot6;
+
+
+extern	statetype s_hitlerchase1;
+extern	statetype s_hitlerchase1s;
+extern	statetype s_hitlerchase2;
+extern	statetype s_hitlerchase3;
+extern	statetype s_hitlerchase3s;
+extern	statetype s_hitlerchase4;
+
+extern	statetype s_hitlerdie1;
+extern	statetype s_hitlerdie2;
+extern	statetype s_hitlerdie3;
+extern	statetype s_hitlerdie4;
+extern	statetype s_hitlerdie5;
+extern	statetype s_hitlerdie6;
+extern	statetype s_hitlerdie7;
+extern	statetype s_hitlerdie8;
+extern	statetype s_hitlerdie9;
+extern	statetype s_hitlerdie10;
+
+extern	statetype s_hitlershoot1;
+extern	statetype s_hitlershoot2;
+extern	statetype s_hitlershoot3;
+extern	statetype s_hitlershoot4;
+extern	statetype s_hitlershoot5;
+extern	statetype s_hitlershoot6;
+
+extern	statetype s_hitlerdeathcam;
+
+statetype s_mechastand	= {false,SPR_MECHA_W1,0,T_Stand,NULL,&s_mechastand};
+
+statetype s_mechachase1 	= {false,SPR_MECHA_W1,10,T_Chase,A_MechaSound,&s_mechachase1s};
+statetype s_mechachase1s	= {false,SPR_MECHA_W1,6,NULL,NULL,&s_mechachase2};
+statetype s_mechachase2 	= {false,SPR_MECHA_W2,8,T_Chase,NULL,&s_mechachase3};
+statetype s_mechachase3 	= {false,SPR_MECHA_W3,10,T_Chase,A_MechaSound,&s_mechachase3s};
+statetype s_mechachase3s	= {false,SPR_MECHA_W3,6,NULL,NULL,&s_mechachase4};
+statetype s_mechachase4 	= {false,SPR_MECHA_W4,8,T_Chase,NULL,&s_mechachase1};
+
+statetype s_mechadie1	= {false,SPR_MECHA_DIE1,10,NULL,A_DeathScream,&s_mechadie2};
+statetype s_mechadie2	= {false,SPR_MECHA_DIE2,10,NULL,NULL,&s_mechadie3};
+statetype s_mechadie3	= {false,SPR_MECHA_DIE3,10,NULL,A_HitlerMorph,&s_mechadie4};
+statetype s_mechadie4	= {false,SPR_MECHA_DEAD,0,NULL,NULL,&s_mechadie4};
+
+statetype s_mechashoot1 	= {false,SPR_MECHA_SHOOT1,30,NULL,NULL,&s_mechashoot2};
+statetype s_mechashoot2 	= {false,SPR_MECHA_SHOOT2,10,NULL,T_Shoot,&s_mechashoot3};
+statetype s_mechashoot3 	= {false,SPR_MECHA_SHOOT3,10,NULL,T_Shoot,&s_mechashoot4};
+statetype s_mechashoot4 	= {false,SPR_MECHA_SHOOT2,10,NULL,T_Shoot,&s_mechashoot5};
+statetype s_mechashoot5 	= {false,SPR_MECHA_SHOOT3,10,NULL,T_Shoot,&s_mechashoot6};
+statetype s_mechashoot6 	= {false,SPR_MECHA_SHOOT2,10,NULL,T_Shoot,&s_mechachase1};
+
+
+statetype s_hitlerchase1 	= {false,SPR_HITLER_W1,6,T_Chase,NULL,&s_hitlerchase1s};
+statetype s_hitlerchase1s	= {false,SPR_HITLER_W1,4,NULL,NULL,&s_hitlerchase2};
+statetype s_hitlerchase2 	= {false,SPR_HITLER_W2,2,T_Chase,NULL,&s_hitlerchase3};
+statetype s_hitlerchase3 	= {false,SPR_HITLER_W3,6,T_Chase,NULL,&s_hitlerchase3s};
+statetype s_hitlerchase3s	= {false,SPR_HITLER_W3,4,NULL,NULL,&s_hitlerchase4};
+statetype s_hitlerchase4 	= {false,SPR_HITLER_W4,2,T_Chase,NULL,&s_hitlerchase1};
+
+statetype s_hitlerdeathcam	= {false,SPR_HITLER_W1,10,NULL,NULL,&s_hitlerdie1};
+
+statetype s_hitlerdie1	= {false,SPR_HITLER_W1,1,NULL,A_DeathScream,&s_hitlerdie2};
+statetype s_hitlerdie2	= {false,SPR_HITLER_W1,10,NULL,NULL,&s_hitlerdie3};
+statetype s_hitlerdie3	= {false,SPR_HITLER_DIE1,10,NULL,A_Slurpie,&s_hitlerdie4};
+statetype s_hitlerdie4	= {false,SPR_HITLER_DIE2,10,NULL,NULL,&s_hitlerdie5};
+statetype s_hitlerdie5	= {false,SPR_HITLER_DIE3,10,NULL,NULL,&s_hitlerdie6};
+statetype s_hitlerdie6	= {false,SPR_HITLER_DIE4,10,NULL,NULL,&s_hitlerdie7};
+statetype s_hitlerdie7	= {false,SPR_HITLER_DIE5,10,NULL,NULL,&s_hitlerdie8};
+statetype s_hitlerdie8	= {false,SPR_HITLER_DIE6,10,NULL,NULL,&s_hitlerdie9};
+statetype s_hitlerdie9	= {false,SPR_HITLER_DIE7,10,NULL,NULL,&s_hitlerdie10};
+statetype s_hitlerdie10	= {false,SPR_HITLER_DEAD,20,NULL,A_StartDeathCam,&s_hitlerdie10};
+
+statetype s_hitlershoot1 	= {false,SPR_HITLER_SHOOT1,30,NULL,NULL,&s_hitlershoot2};
+statetype s_hitlershoot2 	= {false,SPR_HITLER_SHOOT2,10,NULL,T_Shoot,&s_hitlershoot3};
+statetype s_hitlershoot3 	= {false,SPR_HITLER_SHOOT3,10,NULL,T_Shoot,&s_hitlershoot4};
+statetype s_hitlershoot4 	= {false,SPR_HITLER_SHOOT2,10,NULL,T_Shoot,&s_hitlershoot5};
+statetype s_hitlershoot5 	= {false,SPR_HITLER_SHOOT3,10,NULL,T_Shoot,&s_hitlershoot6};
+statetype s_hitlershoot6 	= {false,SPR_HITLER_SHOOT2,10,NULL,T_Shoot,&s_hitlerchase1};
+
+
+
+/*
+===============
+=
+= SpawnFakeHitler
+=
+===============
+*/
+
+void SpawnFakeHitler (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+
+	if (DigiMode != sds_Off)
+	  s_hitlerdie2.tictime = 140;
+	else
+	  s_hitlerdie2.tictime = 5;
+
+	SpawnNewObj (tilex,tiley,&s_fakestand);
+	new->speed = SPDPATROL;
+
+	new->obclass = fakeobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_fake];
+	new->dir = north;
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+/*
+===============
+=
+= SpawnHitler
+=
+===============
+*/
+
+void SpawnHitler (int tilex, int tiley)
+{
+	unsigned	far *map,tile;
+
+	if (DigiMode != sds_Off)
+		s_hitlerdie2.tictime = 140;
+	else
+		s_hitlerdie2.tictime = 5;
+
+
+	SpawnNewObj (tilex,tiley,&s_mechastand);
+	new->speed = SPDPATROL;
+
+	new->obclass = mechahitlerobj;
+	new->hitpoints = starthitpoints[gamestate.difficulty][en_hitler];
+	new->dir = south;
+	new->flags |= FL_SHOOTABLE|FL_AMBUSH;
+	if (!loadedgame)
+	  gamestate.killtotal++;
+}
+
+
+/*
+===============
+=
+= A_HitlerMorph
+=
+===============
+*/
+
+void A_HitlerMorph (objtype *ob)
+{
+	unsigned	far *map,tile,hitpoints[4]={500,700,800,900};
+
+
+	SpawnNewObj (ob->tilex,ob->tiley,&s_hitlerchase1);
+	new->speed = SPDPATROL*5;
+
+	new->x = ob->x;
+	new->y = ob->y;
+
+	new->distance = ob->distance;
+	new->dir = ob->dir;
+	new->flags = ob->flags | FL_SHOOTABLE;
+
+	new->obclass = realhitlerobj;
+	new->hitpoints = hitpoints[gamestate.difficulty];
+}
+
+
+////////////////////////////////////////////////////////
+//
+// A_MechaSound
+// A_Slurpie
+//
+////////////////////////////////////////////////////////
+void A_MechaSound (objtype *ob)
+{
+	if (areabyplayer[ob->areanumber])
+		PlaySoundLocActor (MECHSTEPSND,ob);
+}
+
+
+#pragma argsused
+void A_Slurpie (objtype *ob)
+{
+ SD_PlaySound(SLURPIESND);
+}
+
+/*
+=================
+=
+= T_FakeFire
+=
+=================
+*/
+
+void T_FakeFire (objtype *ob)
+{
+	long	deltax,deltay;
+	float	angle;
+	int		iangle;
+
+	deltax = player->x - ob->x;
+	deltay = ob->y - player->y;
+	angle = atan2 (deltay,deltax);
+	if (angle<0)
+		angle = M_PI*2+angle;
+	iangle = angle/(M_PI*2)*ANGLES;
+
+	GetNewActor ();
+	new->state = &s_fire1;
+	new->ticcount = 1;
+
+	new->tilex = ob->tilex;
+	new->tiley = ob->tiley;
+	new->x = ob->x;
+	new->y = ob->y;
+	new->dir = nodir;
+	new->angle = iangle;
+	new->obclass = fireobj;
+	new->speed = 0x1200l;
+	new->flags = FL_NEVERMARK;
+	new->active = true;
+
+	PlaySoundLocActor (FLAMETHROWERSND,new);
+}
+
+
+
+/*
+=================
+=
+= T_Fake
+=
+=================
+*/
+
+void T_Fake (objtype *ob)
+{
+	long move;
+	int	dx,dy,dist;
+	boolean	dodge;
+
+	if (CheckLine(ob))			// got a shot at player?
+	{
+		if ( US_RndT() < (tics<<1) )
+		{
+		//
+		// go into attack frame
+		//
+			NewState (ob,&s_fakeshoot1);
+			return;
+		}
+	}
+
+	if (ob->dir == nodir)
+	{
+		SelectDodgeDir (ob);
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+	move = ob->speed*tics;
+
+	while (move)
+	{
+		if (move < ob->distance)
+		{
+			MoveObj (ob,move);
+			break;
+		}
+
+		//
+		// reached goal tile, so select another one
+		//
+
+		//
+		// fix position to account for round off during moving
+		//
+		ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+		ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+
+		move -= ob->distance;
+
+		SelectDodgeDir (ob);
+
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+}
+
+#endif
+/*
+============================================================================
+
+							STAND
+
+============================================================================
+*/
+
+
+/*
+===============
+=
+= T_Stand
+=
+===============
+*/
+
+void T_Stand (objtype *ob)
+{
+	SightPlayer (ob);
+}
+
+
+/*
+============================================================================
+
+								CHASE
+
+============================================================================
+*/
+
+/*
+=================
+=
+= T_Chase
+=
+=================
+*/
+
+void T_Chase (objtype *ob)
+{
+	long move;
+	int	dx,dy,dist,chance;
+	boolean	dodge;
+
+	if (gamestate.victoryflag)
+		return;
+
+	dodge = false;
+	if (CheckLine(ob))	// got a shot at player?
+	{
+		dx = abs(ob->tilex - player->tilex);
+		dy = abs(ob->tiley - player->tiley);
+		dist = dx>dy ? dx : dy;
+		if (!dist || (dist==1 && ob->distance<0x4000) )
+			chance = 300;
+		else
+			chance = (tics<<4)/dist;
+
+		if ( US_RndT()<chance)
+		{
+		//
+		// go into attack frame
+		//
+			switch (ob->obclass)
+			{
+			case guardobj:
+				NewState (ob,&s_grdshoot1);
+				break;
+			case officerobj:
+				NewState (ob,&s_ofcshoot1);
+				break;
+			case mutantobj:
+				NewState (ob,&s_mutshoot1);
+				break;
+			case ssobj:
+				NewState (ob,&s_ssshoot1);
+				break;
+#ifndef SPEAR
+			case bossobj:
+				NewState (ob,&s_bossshoot1);
+				break;
+			case gretelobj:
+				NewState (ob,&s_gretelshoot1);
+				break;
+			case mechahitlerobj:
+				NewState (ob,&s_mechashoot1);
+				break;
+			case realhitlerobj:
+				NewState (ob,&s_hitlershoot1);
+				break;
+#else
+			case angelobj:
+				NewState (ob,&s_angelshoot1);
+				break;
+			case transobj:
+				NewState (ob,&s_transshoot1);
+				break;
+			case uberobj:
+				NewState (ob,&s_ubershoot1);
+				break;
+			case willobj:
+				NewState (ob,&s_willshoot1);
+				break;
+			case deathobj:
+				NewState (ob,&s_deathshoot1);
+				break;
+#endif
+			}
+			return;
+		}
+		dodge = true;
+	}
+
+	if (ob->dir == nodir)
+	{
+		if (dodge)
+			SelectDodgeDir (ob);
+		else
+			SelectChaseDir (ob);
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+	move = ob->speed*tics;
+
+	while (move)
+	{
+		if (ob->distance < 0)
+		{
+		//
+		// waiting for a door to open
+		//
+			OpenDoor (-ob->distance-1);
+			if (doorobjlist[-ob->distance-1].action != dr_open)
+				return;
+			ob->distance = TILEGLOBAL;	// go ahead, the door is now opoen
+		}
+
+		if (move < ob->distance)
+		{
+			MoveObj (ob,move);
+			break;
+		}
+
+		//
+		// reached goal tile, so select another one
+		//
+
+		//
+		// fix position to account for round off during moving
+		//
+		ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+		ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+
+		move -= ob->distance;
+
+		if (dodge)
+			SelectDodgeDir (ob);
+		else
+			SelectChaseDir (ob);
+
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+}
+
+
+/*
+=================
+=
+= T_Ghosts
+=
+=================
+*/
+
+void T_Ghosts (objtype *ob)
+{
+	long move;
+
+
+	if (ob->dir == nodir)
+	{
+		SelectChaseDir (ob);
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+	move = ob->speed*tics;
+
+	while (move)
+	{
+		if (move < ob->distance)
+		{
+			MoveObj (ob,move);
+			break;
+		}
+
+		//
+		// reached goal tile, so select another one
+		//
+
+		//
+		// fix position to account for round off during moving
+		//
+		ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+		ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+
+		move -= ob->distance;
+
+		SelectChaseDir (ob);
+
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+}
+
+/*
+=================
+=
+= T_DogChase
+=
+=================
+*/
+
+void T_DogChase (objtype *ob)
+{
+	long 	move;
+	int		dist,chance;
+	long	dx,dy;
+
+
+	if (ob->dir == nodir)
+	{
+		SelectDodgeDir (ob);
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+	move = ob->speed*tics;
+
+	while (move)
+	{
+	//
+	// check for byte range
+	//
+		dx = player->x - ob->x;
+		if (dx<0)
+			dx = -dx;
+		dx -= move;
+		if (dx <= MINACTORDIST)
+		{
+			dy = player->y - ob->y;
+			if (dy<0)
+				dy = -dy;
+			dy -= move;
+			if (dy <= MINACTORDIST)
+			{
+				NewState (ob,&s_dogjump1);
+				return;
+			}
+		}
+
+		if (move < ob->distance)
+		{
+			MoveObj (ob,move);
+			break;
+		}
+
+		//
+		// reached goal tile, so select another one
+		//
+
+		//
+		// fix position to account for round off during moving
+		//
+		ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+		ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+
+		move -= ob->distance;
+
+		SelectDodgeDir (ob);
+
+		if (ob->dir == nodir)
+			return;							// object is blocked in
+	}
+
+}
+
+
+
+/*
+============================================================================
+
+								PATH
+
+============================================================================
+*/
+
+
+/*
+===============
+=
+= SelectPathDir
+=
+===============
+*/
+
+void SelectPathDir (objtype *ob)
+{
+	unsigned spot;
+
+	spot = MAPSPOT(ob->tilex,ob->tiley,1)-ICONARROWS;
+
+	if (spot<8)
+	{
+	// new direction
+		ob->dir = spot;
+	}
+
+	ob->distance = TILEGLOBAL;
+
+	if (!TryWalk (ob))
+		ob->dir = nodir;
+}
+
+
+/*
+===============
+=
+= T_Path
+=
+===============
+*/
+
+void T_Path (objtype *ob)
+{
+	long 	move;
+	long 	deltax,deltay,size;
+
+	if (SightPlayer (ob))
+		return;
+
+	if (ob->dir == nodir)
+	{
+		SelectPathDir (ob);
+		if (ob->dir == nodir)
+			return;					// all movement is blocked
+	}
+
+
+	move = ob->speed*tics;
+
+	while (move)
+	{
+		if (ob->distance < 0)
+		{
+		//
+		// waiting for a door to open
+		//
+			OpenDoor (-ob->distance-1);
+			if (doorobjlist[-ob->distance-1].action != dr_open)
+				return;
+			ob->distance = TILEGLOBAL;	// go ahead, the door is now opoen
+		}
+
+		if (move < ob->distance)
+		{
+			MoveObj (ob,move);
+			break;
+		}
+
+		if (ob->tilex>MAPSIZE || ob->tiley>MAPSIZE)
+		{
+			sprintf (str,"T_Path hit a wall at %u,%u, dir %u"
+			,ob->tilex,ob->tiley,ob->dir);
+			Quit (str);
+		}
+
+
+
+		ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+		ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+		move -= ob->distance;
+
+		SelectPathDir (ob);
+
+		if (ob->dir == nodir)
+			return;					// all movement is blocked
+	}
+}
+
+
+/*
+=============================================================================
+
+								FIGHT
+
+=============================================================================
+*/
+
+
+/*
+===============
+=
+= T_Shoot
+=
+= Try to damage the player, based on skill level and player's speed
+=
+===============
+*/
+
+void T_Shoot (objtype *ob)
+{
+	int	dx,dy,dist;
+	int	hitchance,damage;
+
+	hitchance = 128;
+
+	if (!areabyplayer[ob->areanumber])
+		return;
+
+	if (!CheckLine (ob))			// player is behind a wall
+	  return;
+
+	dx = abs(ob->tilex - player->tilex);
+	dy = abs(ob->tiley - player->tiley);
+	dist = dx>dy ? dx:dy;
+
+	if (ob->obclass == ssobj || ob->obclass == bossobj)
+		dist = dist*2/3;					// ss are better shots
+
+	if (thrustspeed >= RUNSPEED)
+	{
+		if (ob->flags&FL_VISABLE)
+			hitchance = 160-dist*16;		// player can see to dodge
+		else
+			hitchance = 160-dist*8;
+	}
+	else
+	{
+		if (ob->flags&FL_VISABLE)
+			hitchance = 256-dist*16;		// player can see to dodge
+		else
+			hitchance = 256-dist*8;
+	}
+
+// see if the shot was a hit
+
+	if (US_RndT()<hitchance)
+	{
+		if (dist<2)
+			damage = US_RndT()>>2;
+		else if (dist<4)
+			damage = US_RndT()>>3;
+		else
+			damage = US_RndT()>>4;
+
+		TakeDamage (damage,ob);
+	}
+
+	switch(ob->obclass)
+	{
+	 case ssobj:
+	   PlaySoundLocActor(SSFIRESND,ob);
+	   break;
+#ifndef SPEAR
+	 case giftobj:
+	 case fatobj:
+	   PlaySoundLocActor(MISSILEFIRESND,ob);
+	   break;
+	 case mechahitlerobj:
+	 case realhitlerobj:
+	 case bossobj:
+	   PlaySoundLocActor(BOSSFIRESND,ob);
+	   break;
+	 case schabbobj:
+	   PlaySoundLocActor(SCHABBSTHROWSND,ob);
+	   break;
+	 case fakeobj:
+	   PlaySoundLocActor(FLAMETHROWERSND,ob);
+	   break;
+#endif
+	 default:
+	   PlaySoundLocActor(NAZIFIRESND,ob);
+	}
+
+}
+
+
+/*
+===============
+=
+= T_Bite
+=
+===============
+*/
+
+void T_Bite (objtype *ob)
+{
+	long	dx,dy;
+	int	hitchance,damage;
+
+
+	PlaySoundLocActor(DOGATTACKSND,ob);	// JAB
+
+	dx = player->x - ob->x;
+	if (dx<0)
+		dx = -dx;
+	dx -= TILEGLOBAL;
+	if (dx <= MINACTORDIST)
+	{
+		dy = player->y - ob->y;
+		if (dy<0)
+			dy = -dy;
+		dy -= TILEGLOBAL;
+		if (dy <= MINACTORDIST)
+		{
+		   if (US_RndT()<180)
+		   {
+			   TakeDamage (US_RndT()>>4,ob);
+			   return;
+		   }
+		}
+	}
+
+	return;
+}
+
+
+#ifndef SPEAR
+/*
+============================================================================
+
+							BJ VICTORY
+
+============================================================================
+*/
+
+
+//
+// BJ victory
+//
+
+void T_BJRun (objtype *ob);
+void T_BJJump (objtype *ob);
+void T_BJDone (objtype *ob);
+void T_BJYell (objtype *ob);
+
+void T_DeathCam (objtype *ob);
+
+extern	statetype s_bjrun1;
+extern	statetype s_bjrun1s;
+extern	statetype s_bjrun2;
+extern	statetype s_bjrun3;
+extern	statetype s_bjrun3s;
+extern	statetype s_bjrun4;
+
+extern	statetype s_bjjump1;
+extern	statetype s_bjjump2;
+extern	statetype s_bjjump3;
+extern	statetype s_bjjump4;
+
+
+statetype s_bjrun1 	= {false,SPR_BJ_W1,12,T_BJRun,NULL,&s_bjrun1s};
+statetype s_bjrun1s	= {false,SPR_BJ_W1,3, NULL,NULL,&s_bjrun2};
+statetype s_bjrun2 	= {false,SPR_BJ_W2,8,T_BJRun,NULL,&s_bjrun3};
+statetype s_bjrun3 	= {false,SPR_BJ_W3,12,T_BJRun,NULL,&s_bjrun3s};
+statetype s_bjrun3s	= {false,SPR_BJ_W3,3, NULL,NULL,&s_bjrun4};
+statetype s_bjrun4 	= {false,SPR_BJ_W4,8,T_BJRun,NULL,&s_bjrun1};
+
+
+statetype s_bjjump1	= {false,SPR_BJ_JUMP1,14,T_BJJump,NULL,&s_bjjump2};
+statetype s_bjjump2	= {false,SPR_BJ_JUMP2,14,T_BJJump,T_BJYell,&s_bjjump3};
+statetype s_bjjump3	= {false,SPR_BJ_JUMP3,14,T_BJJump,NULL,&s_bjjump4};
+statetype s_bjjump4	= {false,SPR_BJ_JUMP4,300,NULL,T_BJDone,&s_bjjump4};
+
+
+statetype s_deathcam = {false,0,0,NULL,NULL,NULL};
+
+
+/*
+===============
+=
+= SpawnBJVictory
+=
+===============
+*/
+
+void SpawnBJVictory (void)
+{
+	unsigned	far *map,tile;
+
+	SpawnNewObj (player->tilex,player->tiley+1,&s_bjrun1);
+	new->x = player->x;
+	new->y = player->y;
+	new->obclass = bjobj;
+	new->dir = north;
+	new->temp1 = 6;			// tiles to run forward
+}
+
+
+
+/*
+===============
+=
+= T_BJRun
+=
+===============
+*/
+
+void T_BJRun (objtype *ob)
+{
+	long 	move;
+
+	move = BJRUNSPEED*tics;
+
+	while (move)
+	{
+		if (move < ob->distance)
+		{
+			MoveObj (ob,move);
+			break;
+		}
+
+
+		ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+		ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+		move -= ob->distance;
+
+		SelectPathDir (ob);
+
+		if ( !(--ob->temp1) )
+		{
+			NewState (ob,&s_bjjump1);
+			return;
+		}
+	}
+}
+
+
+/*
+===============
+=
+= T_BJJump
+=
+===============
+*/
+
+void T_BJJump (objtype *ob)
+{
+	long 	move;
+
+	move = BJJUMPSPEED*tics;
+	MoveObj (ob,move);
+}
+
+
+/*
+===============
+=
+= T_BJYell
+=
+===============
+*/
+
+void T_BJYell (objtype *ob)
+{
+	PlaySoundLocActor(YEAHSND,ob);	// JAB
+}
+
+
+/*
+===============
+=
+= T_BJDone
+=
+===============
+*/
+
+#pragma argsused
+void T_BJDone (objtype *ob)
+{
+	playstate = ex_victorious;				// exit castle tile
+}
+
+
+
+//===========================================================================
+
+
+/*
+===============
+=
+= CheckPosition
+=
+===============
+*/
+
+boolean	CheckPosition (objtype *ob)
+{
+	int	x,y,xl,yl,xh,yh;
+	objtype *check;
+
+	xl = (ob->x-PLAYERSIZE) >>TILESHIFT;
+	yl = (ob->y-PLAYERSIZE) >>TILESHIFT;
+
+	xh = (ob->x+PLAYERSIZE) >>TILESHIFT;
+	yh = (ob->y+PLAYERSIZE) >>TILESHIFT;
+
+	//
+	// check for solid walls
+	//
+	for (y=yl;y<=yh;y++)
+		for (x=xl;x<=xh;x++)
+		{
+			check = actorat[x][y];
+			if (check && check<objlist)
+				return false;
+		}
+
+	return true;
+}
+
+
+/*
+===============
+=
+= A_StartDeathCam
+=
+===============
+*/
+
+void	A_StartDeathCam (objtype *ob)
+{
+	long	dx,dy;
+	float	fangle;
+	long    xmove,ymove;
+	long	dist;
+	int		temp,i;
+
+	FinishPaletteShifts ();
+
+	VW_WaitVBL (100);
+
+	if (gamestate.victoryflag)
+	{
+		playstate = ex_victorious;				// exit castle tile
+		return;
+	}
+
+	gamestate.victoryflag = true;
+	VW_Bar (0,0,320,200-STATUSLINES,127);
+	FizzleFade(bufferofs,displayofs,320,200-STATUSLINES,70,false);
+
+	PM_UnlockMainMem ();
+	CA_UpLevel ();
+	CacheLump(LEVELEND_LUMP_START,LEVELEND_LUMP_END);
+	#ifdef JAPAN
+	#ifndef JAPDEMO
+	CA_CacheScreen(C_LETSSEEPIC);
+	#endif
+	#else
+	Write(0,7,STR_SEEAGAIN);
+	#endif
+	CA_DownLevel ();
+	PM_CheckMainMem ();
+
+	VW_UpdateScreen ();
+
+	IN_UserInput(300);
+
+//
+// line angle up exactly
+//
+	NewState (player,&s_deathcam);
+
+	player->x = gamestate.killx;
+	player->y = gamestate.killy;
+
+	dx = ob->x - player->x;
+	dy = player->y - ob->y;
+
+	fangle = atan2(dy,dx);			// returns -pi to pi
+	if (fangle<0)
+		fangle = M_PI*2+fangle;
+
+	player->angle = fangle/(M_PI*2)*ANGLES;
+
+//
+// try to position as close as possible without being in a wall
+//
+	dist = 0x14000l;
+	do
+	{
+		xmove = FixedByFrac(dist,costable[player->angle]);
+		ymove = -FixedByFrac(dist,sintable[player->angle]);
+
+		player->x = ob->x - xmove;
+		player->y = ob->y - ymove;
+		dist += 0x1000;
+
+	} while (!CheckPosition (player));
+	plux = player->x >> UNSIGNEDSHIFT;			// scale to fit in unsigned
+	pluy = player->y >> UNSIGNEDSHIFT;
+	player->tilex = player->x >> TILESHIFT;		// scale to tile values
+	player->tiley = player->y >> TILESHIFT;
+
+//
+// go back to the game
+//
+	temp = bufferofs;
+	for (i=0;i<3;i++)
+	{
+		bufferofs = screenloc[i];
+		DrawPlayBorder ();
+	}
+	bufferofs = temp;
+
+	fizzlein = true;
+	switch (ob->obclass)
+	{
+#ifndef SPEAR
+	case schabbobj:
+		NewState (ob,&s_schabbdeathcam);
+		break;
+	case realhitlerobj:
+		NewState (ob,&s_hitlerdeathcam);
+		break;
+	case giftobj:
+		NewState (ob,&s_giftdeathcam);
+		break;
+	case fatobj:
+		NewState (ob,&s_fatdeathcam);
+		break;
+#endif
+	}
+
+}
+
+#endif
--- /dev/null
+++ b/WOLFSRC/WL_AGENT.C
@@ -1,0 +1,1421 @@
+// WL_AGENT.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+
+
+/*
+=============================================================================
+
+						 LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+#define MAXMOUSETURN	10
+
+
+#define MOVESCALE		150l
+#define BACKMOVESCALE	100l
+#define ANGLESCALE		20
+
+/*
+=============================================================================
+
+						 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+
+
+//
+// player state info
+//
+boolean		running;
+long		thrustspeed;
+
+unsigned	plux,pluy;			// player coordinates scaled to unsigned
+
+int			anglefrac;
+int			gotgatgun;	// JR
+
+objtype		*LastAttacker;
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+
+void	T_Player (objtype *ob);
+void	T_Attack (objtype *ob);
+
+statetype s_player = {false,0,0,T_Player,NULL,NULL};
+statetype s_attack = {false,0,0,T_Attack,NULL,NULL};
+
+
+long	playerxmove,playerymove;
+
+struct atkinf
+{
+	char	tics,attack,frame;		// attack is 1 for gun, 2 for knife
+} attackinfo[4][14] =
+
+{
+{ {6,0,1},{6,2,2},{6,0,3},{6,-1,4} },
+{ {6,0,1},{6,1,2},{6,0,3},{6,-1,4} },
+{ {6,0,1},{6,1,2},{6,3,3},{6,-1,4} },
+{ {6,0,1},{6,1,2},{6,4,3},{6,-1,4} },
+};
+
+
+int	strafeangle[9] = {0,90,180,270,45,135,225,315,0};
+
+void DrawWeapon (void);
+void GiveWeapon (int weapon);
+void	GiveAmmo (int ammo);
+
+//===========================================================================
+
+//----------
+
+void Attack (void);
+void Use (void);
+void Search (objtype *ob);
+void SelectWeapon (void);
+void SelectItem (void);
+
+//----------
+
+boolean TryMove (objtype *ob);
+void T_Player (objtype *ob);
+
+void ClipMove (objtype *ob, long xmove, long ymove);
+
+/*
+=============================================================================
+
+						CONTROL STUFF
+
+=============================================================================
+*/
+
+/*
+======================
+=
+= CheckWeaponChange
+=
+= Keys 1-4 change weapons
+=
+======================
+*/
+
+void CheckWeaponChange (void)
+{
+	int	i,buttons;
+
+	if (!gamestate.ammo)		// must use knife with no ammo
+		return;
+
+	for (i=wp_knife ; i<=gamestate.bestweapon ; i++)
+		if (buttonstate[bt_readyknife+i-wp_knife])
+		{
+			gamestate.weapon = gamestate.chosenweapon = i;
+			DrawWeapon ();
+			return;
+		}
+}
+
+
+/*
+=======================
+=
+= ControlMovement
+=
+= Takes controlx,controly, and buttonstate[bt_strafe]
+=
+= Changes the player's angle and position
+=
+= There is an angle hack because when going 70 fps, the roundoff becomes
+= significant
+=
+=======================
+*/
+
+void ControlMovement (objtype *ob)
+{
+	long	oldx,oldy;
+	int		angle,maxxmove;
+	int		angleunits;
+	long	speed;
+
+	thrustspeed = 0;
+
+	oldx = player->x;
+	oldy = player->y;
+
+//
+// side to side move
+//
+	if (buttonstate[bt_strafe])
+	{
+	//
+	// strafing
+	//
+	//
+		if (controlx > 0)
+		{
+			angle = ob->angle - ANGLES/4;
+			if (angle < 0)
+				angle += ANGLES;
+			Thrust (angle,controlx*MOVESCALE);	// move to left
+		}
+		else if (controlx < 0)
+		{
+			angle = ob->angle + ANGLES/4;
+			if (angle >= ANGLES)
+				angle -= ANGLES;
+			Thrust (angle,-controlx*MOVESCALE);	// move to right
+		}
+	}
+	else
+	{
+	//
+	// not strafing
+	//
+		anglefrac += controlx;
+		angleunits = anglefrac/ANGLESCALE;
+		anglefrac -= angleunits*ANGLESCALE;
+		ob->angle -= angleunits;
+
+		if (ob->angle >= ANGLES)
+			ob->angle -= ANGLES;
+		if (ob->angle < 0)
+			ob->angle += ANGLES;
+
+	}
+
+//
+// forward/backwards move
+//
+	if (controly < 0)
+	{
+		Thrust (ob->angle,-controly*MOVESCALE);	// move forwards
+	}
+	else if (controly > 0)
+	{
+		angle = ob->angle + ANGLES/2;
+		if (angle >= ANGLES)
+			angle -= ANGLES;
+		Thrust (angle,controly*BACKMOVESCALE);		// move backwards
+	}
+
+	if (gamestate.victoryflag)		// watching the BJ actor
+		return;
+
+//
+// calculate total move
+//
+	playerxmove = player->x - oldx;
+	playerymove = player->y - oldy;
+}
+
+/*
+=============================================================================
+
+					STATUS WINDOW STUFF
+
+=============================================================================
+*/
+
+
+/*
+==================
+=
+= StatusDrawPic
+=
+==================
+*/
+
+void StatusDrawPic (unsigned x, unsigned y, unsigned picnum)
+{
+	unsigned	temp;
+
+	temp = bufferofs;
+	bufferofs = 0;
+
+	bufferofs = PAGE1START+(200-STATUSLINES)*SCREENWIDTH;
+	LatchDrawPic (x,y,picnum);
+	bufferofs = PAGE2START+(200-STATUSLINES)*SCREENWIDTH;
+	LatchDrawPic (x,y,picnum);
+	bufferofs = PAGE3START+(200-STATUSLINES)*SCREENWIDTH;
+	LatchDrawPic (x,y,picnum);
+
+	bufferofs = temp;
+}
+
+
+/*
+==================
+=
+= DrawFace
+=
+==================
+*/
+
+void DrawFace (void)
+{
+	if (gamestate.health)
+	{
+		#ifdef SPEAR
+		if (godmode)
+			StatusDrawPic (17,4,GODMODEFACE1PIC+gamestate.faceframe);
+		else
+		#endif
+		StatusDrawPic (17,4,FACE1APIC+3*((100-gamestate.health)/16)+gamestate.faceframe);
+	}
+	else
+	{
+#ifndef SPEAR
+	 if (LastAttacker->obclass == needleobj)
+	   StatusDrawPic (17,4,MUTANTBJPIC);
+	 else
+#endif
+	   StatusDrawPic (17,4,FACE8APIC);
+	}
+}
+
+
+/*
+===============
+=
+= UpdateFace
+=
+= Calls draw face if time to change
+=
+===============
+*/
+
+#define FACETICS	70
+
+int	facecount;
+
+void	UpdateFace (void)
+{
+
+	if (SD_SoundPlaying() == GETGATLINGSND)
+	  return;
+
+	facecount += tics;
+	if (facecount > US_RndT())
+	{
+		gamestate.faceframe = (US_RndT()>>6);
+		if (gamestate.faceframe==3)
+			gamestate.faceframe = 1;
+
+		facecount = 0;
+		DrawFace ();
+	}
+}
+
+
+
+/*
+===============
+=
+= LatchNumber
+=
+= right justifies and pads with blanks
+=
+===============
+*/
+
+void	LatchNumber (int x, int y, int width, long number)
+{
+	unsigned	length,c;
+	char	str[20];
+
+	ltoa (number,str,10);
+
+	length = strlen (str);
+
+	while (length<width)
+	{
+		StatusDrawPic (x,y,N_BLANKPIC);
+		x++;
+		width--;
+	}
+
+	c= length <= width ? 0 : length-width;
+
+	while (c<length)
+	{
+		StatusDrawPic (x,y,str[c]-'0'+ N_0PIC);
+		x++;
+		c++;
+	}
+}
+
+
+/*
+===============
+=
+= DrawHealth
+=
+===============
+*/
+
+void	DrawHealth (void)
+{
+	LatchNumber (21,16,3,gamestate.health);
+}
+
+
+/*
+===============
+=
+= TakeDamage
+=
+===============
+*/
+
+void	TakeDamage (int points,objtype *attacker)
+{
+	LastAttacker = attacker;
+
+	if (gamestate.victoryflag)
+		return;
+	if (gamestate.difficulty==gd_baby)
+	  points>>=2;
+
+	if (!godmode)
+		gamestate.health -= points;
+
+	if (gamestate.health<=0)
+	{
+		gamestate.health = 0;
+		playstate = ex_died;
+		killerobj = attacker;
+	}
+
+	StartDamageFlash (points);
+
+	gotgatgun=0;
+
+	DrawHealth ();
+	DrawFace ();
+
+	//
+	// MAKE BJ'S EYES BUG IF MAJOR DAMAGE!
+	//
+	#ifdef SPEAR
+	if (points > 30 && gamestate.health!=0 && !godmode)
+	{
+		StatusDrawPic (17,4,BJOUCHPIC);
+		facecount = 0;
+	}
+	#endif
+
+}
+
+
+/*
+===============
+=
+= HealSelf
+=
+===============
+*/
+
+void	HealSelf (int points)
+{
+	gamestate.health += points;
+	if (gamestate.health>100)
+		gamestate.health = 100;
+
+	DrawHealth ();
+	gotgatgun = 0;	// JR
+	DrawFace ();
+}
+
+
+//===========================================================================
+
+
+/*
+===============
+=
+= DrawLevel
+=
+===============
+*/
+
+void	DrawLevel (void)
+{
+#ifdef SPEAR
+	if (gamestate.mapon == 20)
+		LatchNumber (2,16,2,18);
+	else
+#endif
+	LatchNumber (2,16,2,gamestate.mapon+1);
+}
+
+//===========================================================================
+
+
+/*
+===============
+=
+= DrawLives
+=
+===============
+*/
+
+void	DrawLives (void)
+{
+	LatchNumber (14,16,1,gamestate.lives);
+}
+
+
+/*
+===============
+=
+= GiveExtraMan
+=
+===============
+*/
+
+void	GiveExtraMan (void)
+{
+	if (gamestate.lives<9)
+		gamestate.lives++;
+	DrawLives ();
+	SD_PlaySound (BONUS1UPSND);
+}
+
+//===========================================================================
+
+/*
+===============
+=
+= DrawScore
+=
+===============
+*/
+
+void	DrawScore (void)
+{
+	LatchNumber (6,16,6,gamestate.score);
+}
+
+/*
+===============
+=
+= GivePoints
+=
+===============
+*/
+
+void	GivePoints (long points)
+{
+	gamestate.score += points;
+	while (gamestate.score >= gamestate.nextextra)
+	{
+		gamestate.nextextra += EXTRAPOINTS;
+		GiveExtraMan ();
+	}
+	DrawScore ();
+}
+
+//===========================================================================
+
+/*
+==================
+=
+= DrawWeapon
+=
+==================
+*/
+
+void DrawWeapon (void)
+{
+	StatusDrawPic (32,8,KNIFEPIC+gamestate.weapon);
+}
+
+
+/*
+==================
+=
+= DrawKeys
+=
+==================
+*/
+
+void DrawKeys (void)
+{
+	if (gamestate.keys & 1)
+		StatusDrawPic (30,4,GOLDKEYPIC);
+	else
+		StatusDrawPic (30,4,NOKEYPIC);
+
+	if (gamestate.keys & 2)
+		StatusDrawPic (30,20,SILVERKEYPIC);
+	else
+		StatusDrawPic (30,20,NOKEYPIC);
+}
+
+
+
+/*
+==================
+=
+= GiveWeapon
+=
+==================
+*/
+
+void GiveWeapon (int weapon)
+{
+	GiveAmmo (6);
+
+	if (gamestate.bestweapon<weapon)
+		gamestate.bestweapon = gamestate.weapon
+		= gamestate.chosenweapon = weapon;
+
+	DrawWeapon ();
+}
+
+
+//===========================================================================
+
+/*
+===============
+=
+= DrawAmmo
+=
+===============
+*/
+
+void	DrawAmmo (void)
+{
+	LatchNumber (27,16,2,gamestate.ammo);
+}
+
+
+/*
+===============
+=
+= GiveAmmo
+=
+===============
+*/
+
+void	GiveAmmo (int ammo)
+{
+	if (!gamestate.ammo)				// knife was out
+	{
+		if (!gamestate.attackframe)
+		{
+			gamestate.weapon = gamestate.chosenweapon;
+			DrawWeapon ();
+		}
+	}
+	gamestate.ammo += ammo;
+	if (gamestate.ammo > 99)
+		gamestate.ammo = 99;
+	DrawAmmo ();
+}
+
+//===========================================================================
+
+/*
+==================
+=
+= GiveKey
+=
+==================
+*/
+
+void GiveKey (int key)
+{
+	gamestate.keys |= (1<<key);
+	DrawKeys ();
+}
+
+
+
+/*
+=============================================================================
+
+							MOVEMENT
+
+=============================================================================
+*/
+
+
+/*
+===================
+=
+= GetBonus
+=
+===================
+*/
+void GetBonus (statobj_t *check)
+{
+	switch (check->itemnumber)
+	{
+	case	bo_firstaid:
+		if (gamestate.health == 100)
+			return;
+
+		SD_PlaySound (HEALTH2SND);
+		HealSelf (25);
+		break;
+
+	case	bo_key1:
+	case	bo_key2:
+	case	bo_key3:
+	case	bo_key4:
+		GiveKey (check->itemnumber - bo_key1);
+		SD_PlaySound (GETKEYSND);
+		break;
+
+	case	bo_cross:
+		SD_PlaySound (BONUS1SND);
+		GivePoints (100);
+		gamestate.treasurecount++;
+		break;
+	case	bo_chalice:
+		SD_PlaySound (BONUS2SND);
+		GivePoints (500);
+		gamestate.treasurecount++;
+		break;
+	case	bo_bible:
+		SD_PlaySound (BONUS3SND);
+		GivePoints (1000);
+		gamestate.treasurecount++;
+		break;
+	case	bo_crown:
+		SD_PlaySound (BONUS4SND);
+		GivePoints (5000);
+		gamestate.treasurecount++;
+		break;
+
+	case	bo_clip:
+		if (gamestate.ammo == 99)
+			return;
+
+		SD_PlaySound (GETAMMOSND);
+		GiveAmmo (8);
+		break;
+	case	bo_clip2:
+		if (gamestate.ammo == 99)
+			return;
+
+		SD_PlaySound (GETAMMOSND);
+		GiveAmmo (4);
+		break;
+
+#ifdef SPEAR
+	case	bo_25clip:
+		if (gamestate.ammo == 99)
+		  return;
+
+		SD_PlaySound (GETAMMOBOXSND);
+		GiveAmmo (25);
+		break;
+#endif
+
+	case	bo_machinegun:
+		SD_PlaySound (GETMACHINESND);
+		GiveWeapon (wp_machinegun);
+		break;
+	case	bo_chaingun:
+		SD_PlaySound (GETGATLINGSND);
+		GiveWeapon (wp_chaingun);
+
+		StatusDrawPic (17,4,GOTGATLINGPIC);
+		facecount = 0;
+		gotgatgun = 1;
+		break;
+
+	case	bo_fullheal:
+		SD_PlaySound (BONUS1UPSND);
+		HealSelf (99);
+		GiveAmmo (25);
+		GiveExtraMan ();
+		gamestate.treasurecount++;
+		break;
+
+	case	bo_food:
+		if (gamestate.health == 100)
+			return;
+
+		SD_PlaySound (HEALTH1SND);
+		HealSelf (10);
+		break;
+
+	case	bo_alpo:
+		if (gamestate.health == 100)
+			return;
+
+		SD_PlaySound (HEALTH1SND);
+		HealSelf (4);
+		break;
+
+	case	bo_gibs:
+		if (gamestate.health >10)
+			return;
+
+		SD_PlaySound (SLURPIESND);
+		HealSelf (1);
+		break;
+
+	case	bo_spear:
+		spearflag = true;
+		spearx = player->x;
+		speary = player->y;
+		spearangle = player->angle;
+		playstate = ex_completed;
+	}
+
+	StartBonusFlash ();
+	check->shapenum = -1;			// remove from list
+}
+
+
+/*
+===================
+=
+= TryMove
+=
+= returns true if move ok
+= debug: use pointers to optimize
+===================
+*/
+
+boolean TryMove (objtype *ob)
+{
+	int			xl,yl,xh,yh,x,y;
+	objtype		*check;
+	long		deltax,deltay;
+
+	xl = (ob->x-PLAYERSIZE) >>TILESHIFT;
+	yl = (ob->y-PLAYERSIZE) >>TILESHIFT;
+
+	xh = (ob->x+PLAYERSIZE) >>TILESHIFT;
+	yh = (ob->y+PLAYERSIZE) >>TILESHIFT;
+
+//
+// check for solid walls
+//
+	for (y=yl;y<=yh;y++)
+		for (x=xl;x<=xh;x++)
+		{
+			check = actorat[x][y];
+			if (check && check<objlist)
+				return false;
+		}
+
+//
+// check for actors
+//
+	if (yl>0)
+		yl--;
+	if (yh<MAPSIZE-1)
+		yh++;
+	if (xl>0)
+		xl--;
+	if (xh<MAPSIZE-1)
+		xh++;
+
+	for (y=yl;y<=yh;y++)
+		for (x=xl;x<=xh;x++)
+		{
+			check = actorat[x][y];
+			if (check > objlist
+			&& (check->flags & FL_SHOOTABLE) )
+			{
+				deltax = ob->x - check->x;
+				if (deltax < -MINACTORDIST || deltax > MINACTORDIST)
+					continue;
+				deltay = ob->y - check->y;
+				if (deltay < -MINACTORDIST || deltay > MINACTORDIST)
+					continue;
+
+				return false;
+			}
+		}
+
+	return true;
+}
+
+
+/*
+===================
+=
+= ClipMove
+=
+===================
+*/
+
+void ClipMove (objtype *ob, long xmove, long ymove)
+{
+	long	basex,basey;
+
+	basex = ob->x;
+	basey = ob->y;
+
+	ob->x = basex+xmove;
+	ob->y = basey+ymove;
+	if (TryMove (ob))
+		return;
+
+	if (noclip && ob->x > 2*TILEGLOBAL && ob->y > 2*TILEGLOBAL &&
+	ob->x < (((long)(mapwidth-1))<<TILESHIFT)
+	&& ob->y < (((long)(mapheight-1))<<TILESHIFT) )
+		return;		// walk through walls
+
+	if (!SD_SoundPlaying())
+		SD_PlaySound (HITWALLSND);
+
+	ob->x = basex+xmove;
+	ob->y = basey;
+	if (TryMove (ob))
+		return;
+
+	ob->x = basex;
+	ob->y = basey+ymove;
+	if (TryMove (ob))
+		return;
+
+	ob->x = basex;
+	ob->y = basey;
+}
+
+//==========================================================================
+
+/*
+===================
+=
+= VictoryTile
+=
+===================
+*/
+
+void VictoryTile (void)
+{
+#ifndef SPEAR
+	SpawnBJVictory ();
+#endif
+
+	gamestate.victoryflag = true;
+}
+
+
+/*
+===================
+=
+= Thrust
+=
+===================
+*/
+
+void Thrust (int angle, long speed)
+{
+	long xmove,ymove;
+	long	slowmax;
+	unsigned	offset;
+
+
+	//
+	// ZERO FUNNY COUNTER IF MOVED!
+	//
+	#ifdef SPEAR
+	if (speed)
+		funnyticount = 0;
+	#endif
+
+	thrustspeed += speed;
+//
+// moving bounds speed
+//
+	if (speed >= MINDIST*2)
+		speed = MINDIST*2-1;
+
+	xmove = FixedByFrac(speed,costable[angle]);
+	ymove = -FixedByFrac(speed,sintable[angle]);
+
+	ClipMove(player,xmove,ymove);
+
+	player->tilex = player->x >> TILESHIFT;		// scale to tile values
+	player->tiley = player->y >> TILESHIFT;
+
+	offset = farmapylookup[player->tiley]+player->tilex;
+	player->areanumber = *(mapsegs[0] + offset) -AREATILE;
+
+	if (*(mapsegs[1] + offset) == EXITTILE)
+		VictoryTile ();
+}
+
+
+/*
+=============================================================================
+
+								ACTIONS
+
+=============================================================================
+*/
+
+
+/*
+===============
+=
+= Cmd_Fire
+=
+===============
+*/
+
+void Cmd_Fire (void)
+{
+	buttonheld[bt_attack] = true;
+
+	gamestate.weaponframe = 0;
+
+	player->state = &s_attack;
+
+	gamestate.attackframe = 0;
+	gamestate.attackcount =
+		attackinfo[gamestate.weapon][gamestate.attackframe].tics;
+	gamestate.weaponframe =
+		attackinfo[gamestate.weapon][gamestate.attackframe].frame;
+}
+
+//===========================================================================
+
+/*
+===============
+=
+= Cmd_Use
+=
+===============
+*/
+
+void Cmd_Use (void)
+{
+	objtype 	*check;
+	int			checkx,checky,doornum,dir;
+	boolean		elevatorok;
+
+
+//
+// find which cardinal direction the player is facing
+//
+	if (player->angle < ANGLES/8 || player->angle > 7*ANGLES/8)
+	{
+		checkx = player->tilex + 1;
+		checky = player->tiley;
+		dir = di_east;
+		elevatorok = true;
+	}
+	else if (player->angle < 3*ANGLES/8)
+	{
+		checkx = player->tilex;
+		checky = player->tiley-1;
+		dir = di_north;
+		elevatorok = false;
+	}
+	else if (player->angle < 5*ANGLES/8)
+	{
+		checkx = player->tilex - 1;
+		checky = player->tiley;
+		dir = di_west;
+		elevatorok = true;
+	}
+	else
+	{
+		checkx = player->tilex;
+		checky = player->tiley + 1;
+		dir = di_south;
+		elevatorok = false;
+	}
+
+	doornum = tilemap[checkx][checky];
+	if (*(mapsegs[1]+farmapylookup[checky]+checkx) == PUSHABLETILE)
+	{
+	//
+	// pushable wall
+	//
+
+		PushWall (checkx,checky,dir);
+		return;
+	}
+	if (!buttonheld[bt_use] && doornum == ELEVATORTILE && elevatorok)
+	{
+	//
+	// use elevator
+	//
+		buttonheld[bt_use] = true;
+
+		tilemap[checkx][checky]++;		// flip switch
+		if (*(mapsegs[0]+farmapylookup[player->tiley]+player->tilex) == ALTELEVATORTILE)
+			playstate = ex_secretlevel;
+		else
+			playstate = ex_completed;
+		SD_PlaySound (LEVELDONESND);
+		SD_WaitSoundDone();
+	}
+	else if (!buttonheld[bt_use] && doornum & 0x80)
+	{
+		buttonheld[bt_use] = true;
+		OperateDoor (doornum & ~0x80);
+	}
+	else
+		SD_PlaySound (DONOTHINGSND);
+
+}
+
+/*
+=============================================================================
+
+						   PLAYER CONTROL
+
+=============================================================================
+*/
+
+
+
+/*
+===============
+=
+= SpawnPlayer
+=
+===============
+*/
+
+void SpawnPlayer (int tilex, int tiley, int dir)
+{
+	player->obclass = playerobj;
+	player->active = true;
+	player->tilex = tilex;
+	player->tiley = tiley;
+	player->areanumber =
+		*(mapsegs[0] + farmapylookup[player->tiley]+player->tilex);
+	player->x = ((long)tilex<<TILESHIFT)+TILEGLOBAL/2;
+	player->y = ((long)tiley<<TILESHIFT)+TILEGLOBAL/2;
+	player->state = &s_player;
+	player->angle = (1-dir)*90;
+	if (player->angle<0)
+		player->angle += ANGLES;
+	player->flags = FL_NEVERMARK;
+	Thrust (0,0);				// set some variables
+
+	InitAreas ();
+}
+
+
+//===========================================================================
+
+/*
+===============
+=
+= T_KnifeAttack
+=
+= Update player hands, and try to do damage when the proper frame is reached
+=
+===============
+*/
+
+void	KnifeAttack (objtype *ob)
+{
+	objtype *check,*closest;
+	long	dist;
+
+	SD_PlaySound (ATKKNIFESND);
+// actually fire
+	dist = 0x7fffffff;
+	closest = NULL;
+	for (check=ob->next ; check ; check=check->next)
+		if ( (check->flags & FL_SHOOTABLE)
+		&& (check->flags & FL_VISABLE)
+		&& abs (check->viewx-centerx) < shootdelta
+		)
+		{
+			if (check->transx < dist)
+			{
+				dist = check->transx;
+				closest = check;
+			}
+		}
+
+	if (!closest || dist> 0x18000l)
+	{
+	// missed
+
+		return;
+	}
+
+// hit something
+	DamageActor (closest,US_RndT() >> 4);
+}
+
+
+
+void	GunAttack (objtype *ob)
+{
+	objtype *check,*closest,*oldclosest;
+	int		damage;
+	int		dx,dy,dist;
+	long	viewdist;
+
+	switch (gamestate.weapon)
+	{
+	case wp_pistol:
+		SD_PlaySound (ATKPISTOLSND);
+		break;
+	case wp_machinegun:
+		SD_PlaySound (ATKMACHINEGUNSND);
+		break;
+	case wp_chaingun:
+		SD_PlaySound (ATKGATLINGSND);
+		break;
+	}
+
+	madenoise = true;
+
+//
+// find potential targets
+//
+	viewdist = 0x7fffffffl;
+	closest = NULL;
+
+	while (1)
+	{
+		oldclosest = closest;
+
+		for (check=ob->next ; check ; check=check->next)
+			if ( (check->flags & FL_SHOOTABLE)
+			&& (check->flags & FL_VISABLE)
+			&& abs (check->viewx-centerx) < shootdelta
+			)
+			{
+				if (check->transx < viewdist)
+				{
+					viewdist = check->transx;
+					closest = check;
+				}
+			}
+
+		if (closest == oldclosest)
+			return;						// no more targets, all missed
+
+	//
+	// trace a line from player to enemey
+	//
+		if (CheckLine(closest))
+			break;
+
+	}
+
+//
+// hit something
+//
+	dx = abs(closest->tilex - player->tilex);
+	dy = abs(closest->tiley - player->tiley);
+	dist = dx>dy ? dx:dy;
+
+	if (dist<2)
+		damage = US_RndT() / 4;
+	else if (dist<4)
+		damage = US_RndT() / 6;
+	else
+	{
+		if ( (US_RndT() / 12) < dist)		// missed
+			return;
+		damage = US_RndT() / 6;
+	}
+
+	DamageActor (closest,damage);
+}
+
+//===========================================================================
+
+/*
+===============
+=
+= VictorySpin
+=
+===============
+*/
+
+void VictorySpin (void)
+{
+	long	desty;
+
+	if (player->angle > 270)
+	{
+		player->angle -= tics * 3;
+		if (player->angle < 270)
+			player->angle = 270;
+	}
+	else if (player->angle < 270)
+	{
+		player->angle += tics * 3;
+		if (player->angle > 270)
+			player->angle = 270;
+	}
+
+	desty = (((long)player->tiley-5)<<TILESHIFT)-0x3000;
+
+	if (player->y > desty)
+	{
+		player->y -= tics*4096;
+		if (player->y < desty)
+			player->y = desty;
+	}
+}
+
+
+//===========================================================================
+
+/*
+===============
+=
+= T_Attack
+=
+===============
+*/
+
+void	T_Attack (objtype *ob)
+{
+	struct	atkinf	*cur;
+
+	UpdateFace ();
+
+	if (gamestate.victoryflag)		// watching the BJ actor
+	{
+		VictorySpin ();
+		return;
+	}
+
+	if ( buttonstate[bt_use] && !buttonheld[bt_use] )
+		buttonstate[bt_use] = false;
+
+	if ( buttonstate[bt_attack] && !buttonheld[bt_attack])
+		buttonstate[bt_attack] = false;
+
+	ControlMovement (ob);
+	if (gamestate.victoryflag)		// watching the BJ actor
+		return;
+
+	plux = player->x >> UNSIGNEDSHIFT;			// scale to fit in unsigned
+	pluy = player->y >> UNSIGNEDSHIFT;
+	player->tilex = player->x >> TILESHIFT;		// scale to tile values
+	player->tiley = player->y >> TILESHIFT;
+
+//
+// change frame and fire
+//
+	gamestate.attackcount -= tics;
+	while (gamestate.attackcount <= 0)
+	{
+		cur = &attackinfo[gamestate.weapon][gamestate.attackframe];
+		switch (cur->attack)
+		{
+		case -1:
+			ob->state = &s_player;
+			if (!gamestate.ammo)
+			{
+				gamestate.weapon = wp_knife;
+				DrawWeapon ();
+			}
+			else
+			{
+				if (gamestate.weapon != gamestate.chosenweapon)
+				{
+					gamestate.weapon = gamestate.chosenweapon;
+					DrawWeapon ();
+				}
+			};
+			gamestate.attackframe = gamestate.weaponframe = 0;
+			return;
+
+		case 4:
+			if (!gamestate.ammo)
+				break;
+			if (buttonstate[bt_attack])
+				gamestate.attackframe -= 2;
+		case 1:
+			if (!gamestate.ammo)
+			{	// can only happen with chain gun
+				gamestate.attackframe++;
+				break;
+			}
+			GunAttack (ob);
+			gamestate.ammo--;
+			DrawAmmo ();
+			break;
+
+		case 2:
+			KnifeAttack (ob);
+			break;
+
+		case 3:
+			if (gamestate.ammo && buttonstate[bt_attack])
+				gamestate.attackframe -= 2;
+			break;
+		}
+
+		gamestate.attackcount += cur->tics;
+		gamestate.attackframe++;
+		gamestate.weaponframe =
+			attackinfo[gamestate.weapon][gamestate.attackframe].frame;
+	}
+
+}
+
+
+
+//===========================================================================
+
+/*
+===============
+=
+= T_Player
+=
+===============
+*/
+
+void	T_Player (objtype *ob)
+{
+	if (gamestate.victoryflag)		// watching the BJ actor
+	{
+		VictorySpin ();
+		return;
+	}
+
+	UpdateFace ();
+	CheckWeaponChange ();
+
+	if ( buttonstate[bt_use] )
+		Cmd_Use ();
+
+	if ( buttonstate[bt_attack] && !buttonheld[bt_attack])
+		Cmd_Fire ();
+
+	ControlMovement (ob);
+	if (gamestate.victoryflag)		// watching the BJ actor
+		return;
+
+
+	plux = player->x >> UNSIGNEDSHIFT;			// scale to fit in unsigned
+	pluy = player->y >> UNSIGNEDSHIFT;
+	player->tilex = player->x >> TILESHIFT;		// scale to tile values
+	player->tiley = player->y >> TILESHIFT;
+}
+
+
--- /dev/null
+++ b/WOLFSRC/WL_ASM.ASM
@@ -1,0 +1,67 @@
+; JABHACK.ASM
+
+.386C
+IDEAL
+MODEL	MEDIUM
+
+EXTRN	LDIV@:far
+
+;============================================================================
+
+DATASEG
+
+;============================================================================
+
+CODESEG
+
+;	Hacked up Juan Jimenez's code a bit to just return 386/not 386
+PROC	_CheckIs386
+PUBLIC	_CheckIs386
+
+	pushf			; Save flag registers, we use them here
+	xor	ax,ax		; Clear AX and...
+	push ax			; ...push it onto the stack
+	popf			; Pop 0 into flag registers (all bits to 0),
+	pushf			; attempting to set bits 12-15 of flags to 0's
+	pop	ax			; Recover the save flags
+	and	ax,08000h	; If bits 12-15 of flags are set to
+	cmp	ax,08000h	; zero then it's 8088/86 or 80188/186
+	jz	not386
+
+	mov	ax,07000h	; Try to set flag bits 12-14 to 1's
+	push ax			; Push the test value onto the stack
+	popf			; Pop it into the flag register
+	pushf			; Push it back onto the stack
+	pop	ax			; Pop it into AX for check
+	and	ax,07000h	; if bits 12-14 are cleared then
+	jz	not386		; the chip is an 80286
+
+	mov	ax,1		; We now assume it's a 80386 or better
+	popf
+	retf
+
+not386:
+	xor	ax,ax
+	popf
+	retf
+
+	ENDP
+
+
+PROC	_jabhack2
+PUBLIC	_jabhack2
+
+	push	es
+
+	mov	ax,seg LDIV@
+	mov	es,ax
+	mov	ax,9090h					;Two NOP's
+	mov	[WORD FAR es:LDIV@],ax		;Patch over XOR AX,AX
+	mov	[WORD FAR es:LDIV@+2],ax	;and over JMP SHORT COMMON
+
+	pop	es
+	retf
+
+	ENDP
+
+	END
--- /dev/null
+++ b/WOLFSRC/WL_DEBUG.C
@@ -1,0 +1,722 @@
+// WL_DEBUG.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+#include <BIOS.H>
+
+/*
+=============================================================================
+
+						 LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+#define VIEWTILEX	(viewwidth/16)
+#define VIEWTILEY	(viewheight/16)
+
+/*
+=============================================================================
+
+						 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+
+int DebugKeys (void);
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+
+int	maporgx;
+int	maporgy;
+enum {mapview,tilemapview,actoratview,visview}	viewtype;
+
+void ViewMap (void);
+
+//===========================================================================
+
+/*
+==================
+=
+= DebugMemory
+=
+==================
+*/
+
+void DebugMemory (void)
+{
+	int	i;
+	char    scratch[80],str[10];
+	long	mem;
+	spritetype _seg	*block;
+
+	CenterWindow (16,7);
+
+	US_CPrint ("Memory Usage");
+	US_CPrint ("------------");
+	US_Print ("Total     :");
+	US_PrintUnsigned (mminfo.mainmem/1024);
+	US_Print ("k\nFree      :");
+	US_PrintUnsigned (MM_UnusedMemory()/1024);
+	US_Print ("k\nWith purge:");
+	US_PrintUnsigned (MM_TotalFree()/1024);
+	US_Print ("k\n");
+	VW_UpdateScreen();
+	IN_Ack ();
+}
+
+//===========================================================================
+
+/*
+==================
+=
+= CountObjects
+=
+==================
+*/
+
+void CountObjects (void)
+{
+	int	i,total,count,active,inactive,doors;
+	objtype	*obj;
+
+	CenterWindow (16,7);
+	active = inactive = count = doors = 0;
+
+	US_Print ("Total statics :");
+	total = laststatobj-&statobjlist[0];
+	US_PrintUnsigned (total);
+
+	US_Print ("\nIn use statics:");
+	for (i=0;i<total;i++)
+		if (statobjlist[i].shapenum != -1)
+			count++;
+		else
+			doors++;	//debug
+	US_PrintUnsigned (count);
+
+	US_Print ("\nDoors         :");
+	US_PrintUnsigned (doornum);
+
+	for (obj=player->next;obj;obj=obj->next)
+	{
+		if (obj->active)
+			active++;
+		else
+			inactive++;
+	}
+
+	US_Print ("\nTotal actors  :");
+	US_PrintUnsigned (active+inactive);
+
+	US_Print ("\nActive actors :");
+	US_PrintUnsigned (active);
+
+	VW_UpdateScreen();
+	IN_Ack ();
+}
+
+//===========================================================================
+
+/*
+================
+=
+= PicturePause
+=
+================
+*/
+
+void PicturePause (void)
+{
+	int			i;
+	byte		p;
+	unsigned	x;
+	byte		far	*dest,far *src;
+	memptr		buffer;
+
+	VW_ColorBorder (15);
+	FinishPaletteShifts ();
+
+	LastScan = 0;
+	while (!LastScan)
+	;
+	if (LastScan != sc_Enter)
+	{
+		VW_ColorBorder (0);
+		return;
+	}
+
+	VW_ColorBorder (1);
+	VW_SetScreen (0,0);
+//
+// vga stuff...
+//
+
+	ClearMemory ();
+	CA_SetAllPurge();
+	MM_GetPtr (&buffer,64000);
+	for (p=0;p<4;p++)
+	{
+	   src = MK_FP(0xa000,displayofs);
+	   dest = (byte far *)buffer+p;
+	   VGAREADMAP(p);
+	   for (x=0;x<16000;x++,dest+=4)
+		   *dest = *src++;
+	}
+
+
+#if 0
+	for (p=0;p<4;p++)
+	{
+		src = MK_FP(0xa000,0);
+		dest = (byte far *)buffer+51200+p;
+		VGAREADMAP(p);
+		for (x=0;x<3200;x++,dest+=4)
+			*dest = *src++;
+	}
+#endif
+
+	asm	mov	ax,0x13
+	asm	int	0x10
+
+	dest = MK_FP(0xa000,0);
+	_fmemcpy (dest,buffer,64000);
+
+	VL_SetPalette (&gamepal);
+
+
+	IN_Shutdown ();
+
+	VW_WaitVBL(70);
+	bioskey(0);
+	VW_WaitVBL(70);
+	Quit (NULL);
+}
+
+
+//===========================================================================
+
+
+/*
+================
+=
+= ShapeTest
+=
+================
+*/
+
+#pragma warn -pia
+void ShapeTest (void)
+{
+extern	word	NumDigi;
+extern	word	_seg *DigiList;
+static	char	buf[10];
+
+	boolean			done;
+	ScanCode		scan;
+	int				i,j,k,x;
+	longword		l;
+	memptr			addr;
+	PageListStruct	far *page;
+
+	CenterWindow(20,16);
+	VW_UpdateScreen();
+	for (i = 0,done = false;!done;)
+	{
+		US_ClearWindow();
+//		sound = -1;
+
+		page = &PMPages[i];
+		US_Print(" Page #");
+		US_PrintUnsigned(i);
+		if (i < PMSpriteStart)
+			US_Print(" (Wall)");
+		else if (i < PMSoundStart)
+			US_Print(" (Sprite)");
+		else if (i == ChunksInFile - 1)
+			US_Print(" (Sound Info)");
+		else
+			US_Print(" (Sound)");
+
+		US_Print("\n XMS: ");
+		if (page->xmsPage != -1)
+			US_PrintUnsigned(page->xmsPage);
+		else
+			US_Print("No");
+
+		US_Print("\n Main: ");
+		if (page->mainPage != -1)
+			US_PrintUnsigned(page->mainPage);
+		else if (page->emsPage != -1)
+		{
+			US_Print("EMS ");
+			US_PrintUnsigned(page->emsPage);
+		}
+		else
+			US_Print("No");
+
+		US_Print("\n Last hit: ");
+		US_PrintUnsigned(page->lastHit);
+
+		US_Print("\n Address: ");
+		addr = PM_GetPageAddress(i);
+		sprintf(buf,"0x%04x",(word)addr);
+		US_Print(buf);
+
+		if (addr)
+		{
+			if (i < PMSpriteStart)
+			{
+			//
+			// draw the wall
+			//
+				bufferofs += 32*SCREENWIDTH;
+				postx = 128;
+				postwidth = 1;
+				postsource = ((long)((unsigned)addr))<<16;
+				for (x=0;x<64;x++,postx++,postsource+=64)
+				{
+					wallheight[postx] = 256;
+					FarScalePost ();
+				}
+				bufferofs -= 32*SCREENWIDTH;
+			}
+			else if (i < PMSoundStart)
+			{
+			//
+			// draw the sprite
+			//
+				bufferofs += 32*SCREENWIDTH;
+				SimpleScaleShape (160, i-PMSpriteStart, 64);
+				bufferofs -= 32*SCREENWIDTH;
+			}
+			else if (i == ChunksInFile - 1)
+			{
+				US_Print("\n\n Number of sounds: ");
+				US_PrintUnsigned(NumDigi);
+				for (l = j = k = 0;j < NumDigi;j++)
+				{
+					l += DigiList[(j * 2) + 1];
+					k += (DigiList[(j * 2) + 1] + (PMPageSize - 1)) / PMPageSize;
+				}
+				US_Print("\n Total bytes: ");
+				US_PrintUnsigned(l);
+				US_Print("\n Total pages: ");
+				US_PrintUnsigned(k);
+			}
+			else
+			{
+				byte far *dp = (byte far *)MK_FP(addr,0);
+				for (j = 0;j < NumDigi;j++)
+				{
+					k = (DigiList[(j * 2) + 1] + (PMPageSize - 1)) / PMPageSize;
+					if
+					(
+						(i >= PMSoundStart + DigiList[j * 2])
+					&&	(i < PMSoundStart + DigiList[j * 2] + k)
+					)
+						break;
+				}
+				if (j < NumDigi)
+				{
+//					sound = j;
+					US_Print("\n Sound #");
+					US_PrintUnsigned(j);
+					US_Print("\n Segment #");
+					US_PrintUnsigned(i - PMSoundStart - DigiList[j * 2]);
+				}
+				for (j = 0;j < page->length;j += 32)
+				{
+					byte v = dp[j];
+					int v2 = (unsigned)v;
+					v2 -= 128;
+					v2 /= 4;
+					if (v2 < 0)
+						VWB_Vlin(WindowY + WindowH - 32 + v2,
+								WindowY + WindowH - 32,
+								WindowX + 8 + (j / 32),BLACK);
+					else
+						VWB_Vlin(WindowY + WindowH - 32,
+								WindowY + WindowH - 32 + v2,
+								WindowX + 8 + (j / 32),BLACK);
+				}
+			}
+		}
+
+		VW_UpdateScreen();
+
+		while (!(scan = LastScan))
+			SD_Poll();
+
+		IN_ClearKey(scan);
+		switch (scan)
+		{
+		case sc_LeftArrow:
+			if (i)
+				i--;
+			break;
+		case sc_RightArrow:
+			if (++i >= ChunksInFile)
+				i--;
+			break;
+		case sc_W:	// Walls
+			i = 0;
+			break;
+		case sc_S:	// Sprites
+			i = PMSpriteStart;
+			break;
+		case sc_D:	// Digitized
+			i = PMSoundStart;
+			break;
+		case sc_I:	// Digitized info
+			i = ChunksInFile - 1;
+			break;
+		case sc_L:	// Load all pages
+			for (j = 0;j < ChunksInFile;j++)
+				PM_GetPage(j);
+			break;
+		case sc_P:
+//			if (sound != -1)
+//				SD_PlayDigitized(sound);
+			break;
+		case sc_Escape:
+			done = true;
+			break;
+		case sc_Enter:
+			PM_GetPage(i);
+			break;
+		}
+	}
+	SD_StopDigitized();
+}
+#pragma warn +pia
+
+
+
+//===========================================================================
+
+
+/*
+================
+=
+= DebugKeys
+=
+================
+*/
+
+int DebugKeys (void)
+{
+	boolean esc;
+	int level,i;
+
+	if (Keyboard[sc_B])		// B = border color
+	{
+		CenterWindow(24,3);
+		PrintY+=6;
+		US_Print(" Border color (0-15):");
+		VW_UpdateScreen();
+		esc = !US_LineInput (px,py,str,NULL,true,2,0);
+		if (!esc)
+		{
+			level = atoi (str);
+			if (level>=0 && level<=15)
+				VW_ColorBorder (level);
+		}
+		return 1;
+	}
+
+	if (Keyboard[sc_C])		// C = count objects
+	{
+		CountObjects();
+		return 1;
+	}
+
+	if (Keyboard[sc_E])		// E = quit level
+	{
+		if (tedlevel)
+			Quit (NULL);
+		playstate = ex_completed;
+//		gamestate.mapon++;
+	}
+
+	if (Keyboard[sc_F])		// F = facing spot
+	{
+		CenterWindow (14,4);
+		US_Print ("X:");
+		US_PrintUnsigned (player->x);
+		US_Print ("\nY:");
+		US_PrintUnsigned (player->y);
+		US_Print ("\nA:");
+		US_PrintUnsigned (player->angle);
+		VW_UpdateScreen();
+		IN_Ack();
+		return 1;
+	}
+
+	if (Keyboard[sc_G])		// G = god mode
+	{
+		CenterWindow (12,2);
+		if (godmode)
+		  US_PrintCentered ("God mode OFF");
+		else
+		  US_PrintCentered ("God mode ON");
+		VW_UpdateScreen();
+		IN_Ack();
+		godmode ^= 1;
+		return 1;
+	}
+	if (Keyboard[sc_H])		// H = hurt self
+	{
+		IN_ClearKeysDown ();
+		TakeDamage (16,NULL);
+	}
+	else if (Keyboard[sc_I])			// I = item cheat
+	{
+		CenterWindow (12,3);
+		US_PrintCentered ("Free items!");
+		VW_UpdateScreen();
+		GivePoints (100000);
+		HealSelf (99);
+		if (gamestate.bestweapon<wp_chaingun)
+			GiveWeapon (gamestate.bestweapon+1);
+		gamestate.ammo += 50;
+		if (gamestate.ammo > 99)
+			gamestate.ammo = 99;
+		DrawAmmo ();
+		IN_Ack ();
+		return 1;
+	}
+	else if (Keyboard[sc_M])			// M = memory info
+	{
+		DebugMemory();
+		return 1;
+	}
+#ifdef SPEAR
+	else if (Keyboard[sc_N])			// N = no clip
+	{
+		noclip^=1;
+		CenterWindow (18,3);
+		if (noclip)
+			US_PrintCentered ("No clipping ON");
+		else
+			US_PrintCentered ("No clipping OFF");
+		VW_UpdateScreen();
+		IN_Ack ();
+		return 1;
+	}
+#endif
+#if 0
+	else if (Keyboard[sc_O])			// O = overhead
+	{
+		ViewMap();
+		return 1;
+	}
+#endif
+	else if (Keyboard[sc_P])			// P = pause with no screen disruptioon
+	{
+		PicturePause ();
+		return 1;
+	}
+	else if (Keyboard[sc_Q])			// Q = fast quit
+		Quit (NULL);
+	else if (Keyboard[sc_S])			// S = slow motion
+	{
+		singlestep^=1;
+		CenterWindow (18,3);
+		if (singlestep)
+			US_PrintCentered ("Slow motion ON");
+		else
+			US_PrintCentered ("Slow motion OFF");
+		VW_UpdateScreen();
+		IN_Ack ();
+		return 1;
+	}
+	else if (Keyboard[sc_T])			// T = shape test
+	{
+		ShapeTest ();
+		return 1;
+	}
+	else if (Keyboard[sc_V])			// V = extra VBLs
+	{
+		CenterWindow(30,3);
+		PrintY+=6;
+		US_Print("  Add how many extra VBLs(0-8):");
+		VW_UpdateScreen();
+		esc = !US_LineInput (px,py,str,NULL,true,2,0);
+		if (!esc)
+		{
+			level = atoi (str);
+			if (level>=0 && level<=8)
+				extravbls = level;
+		}
+		return 1;
+	}
+	else if (Keyboard[sc_W])			// W = warp to level
+	{
+		CenterWindow(26,3);
+		PrintY+=6;
+#ifndef SPEAR
+		US_Print("  Warp to which level(1-10):");
+#else
+		US_Print("  Warp to which level(1-21):");
+#endif
+		VW_UpdateScreen();
+		esc = !US_LineInput (px,py,str,NULL,true,2,0);
+		if (!esc)
+		{
+			level = atoi (str);
+#ifndef SPEAR
+			if (level>0 && level<11)
+#else
+			if (level>0 && level<22)
+#endif
+			{
+				gamestate.mapon = level-1;
+				playstate = ex_warped;
+			}
+		}
+		return 1;
+	}
+	else if (Keyboard[sc_X])			// X = item cheat
+	{
+		CenterWindow (12,3);
+		US_PrintCentered ("Extra stuff!");
+		VW_UpdateScreen();
+		// DEBUG: put stuff here
+		IN_Ack ();
+		return 1;
+	}
+
+	return 0;
+}
+
+
+#if 0
+/*
+===================
+=
+= OverheadRefresh
+=
+===================
+*/
+
+void OverheadRefresh (void)
+{
+	unsigned	x,y,endx,endy,sx,sy;
+	unsigned	tile;
+
+
+	endx = maporgx+VIEWTILEX;
+	endy = maporgy+VIEWTILEY;
+
+	for (y=maporgy;y<endy;y++)
+		for (x=maporgx;x<endx;x++)
+		{
+			sx = (x-maporgx)*16;
+			sy = (y-maporgy)*16;
+
+			switch (viewtype)
+			{
+#if 0
+			case mapview:
+				tile = *(mapsegs[0]+farmapylookup[y]+x);
+				break;
+
+			case tilemapview:
+				tile = tilemap[x][y];
+				break;
+
+			case visview:
+				tile = spotvis[x][y];
+				break;
+#endif
+			case actoratview:
+				tile = (unsigned)actorat[x][y];
+				break;
+			}
+
+			if (tile<MAXWALLTILES)
+				LatchDrawTile(sx,sy,tile);
+			else
+			{
+				LatchDrawChar(sx,sy,NUMBERCHARS+((tile&0xf000)>>12));
+				LatchDrawChar(sx+8,sy,NUMBERCHARS+((tile&0x0f00)>>8));
+				LatchDrawChar(sx,sy+8,NUMBERCHARS+((tile&0x00f0)>>4));
+				LatchDrawChar(sx+8,sy+8,NUMBERCHARS+(tile&0x000f));
+			}
+		}
+
+}
+#endif
+
+#if 0
+/*
+===================
+=
+= ViewMap
+=
+===================
+*/
+
+void ViewMap (void)
+{
+	boolean		button0held;
+
+	viewtype = actoratview;
+//	button0held = false;
+
+
+	maporgx = player->tilex - VIEWTILEX/2;
+	if (maporgx<0)
+		maporgx = 0;
+	if (maporgx>MAPSIZE-VIEWTILEX)
+		maporgx=MAPSIZE-VIEWTILEX;
+	maporgy = player->tiley - VIEWTILEY/2;
+	if (maporgy<0)
+		maporgy = 0;
+	if (maporgy>MAPSIZE-VIEWTILEY)
+		maporgy=MAPSIZE-VIEWTILEY;
+
+	do
+	{
+//
+// let user pan around
+//
+		PollControls ();
+		if (controlx < 0 && maporgx>0)
+			maporgx--;
+		if (controlx > 0 && maporgx<mapwidth-VIEWTILEX)
+			maporgx++;
+		if (controly < 0 && maporgy>0)
+			maporgy--;
+		if (controly > 0 && maporgy<mapheight-VIEWTILEY)
+			maporgy++;
+
+#if 0
+		if (c.button0 && !button0held)
+		{
+			button0held = true;
+			viewtype++;
+			if (viewtype>visview)
+				viewtype = mapview;
+		}
+		if (!c.button0)
+			button0held = false;
+#endif
+
+		OverheadRefresh ();
+
+	} while (!Keyboard[sc_Escape]);
+
+	IN_ClearKeysDown ();
+}
+#endif
+
--- /dev/null
+++ b/WOLFSRC/WL_DEF.H
@@ -1,0 +1,1276 @@
+//#define BETA
+#define YEAR	1992
+#define MONTH	9
+#define DAY		30
+
+#include "ID_HEADS.H"
+#include <MATH.H>
+#include <VALUES.H>
+
+#include "WL_MENU.H"
+
+#ifdef SPANISH
+#include "SPANISH.H"
+#else
+#include "FOREIGN.H"
+#endif
+
+#ifdef SPEAR
+#include "F_SPEAR.H"
+#endif
+
+/*
+=============================================================================
+
+							MACROS
+
+=============================================================================
+*/
+
+
+#define COLORBORDER(color)		asm{mov	dx,STATUS_REGISTER_1;in al,dx;\
+	mov dx,ATR_INDEX;mov al,ATR_OVERSCAN;out dx,al;mov al,color;out	dx,al;\
+	mov	al,32;out dx,al};
+
+#define MAPSPOT(x,y,plane)		(*(mapsegs[plane]+farmapylookup[y]+x))
+
+#define SIGN(x) 	((x)>0?1:-1)
+#define ABS(x) 		((int)(x)>0?(x):-(x))
+#define LABS(x) 	((long)(x)>0?(x):-(x))
+
+/*
+=============================================================================
+
+						 GLOBAL CONSTANTS
+
+=============================================================================
+*/
+
+#define MAXACTORS		150				// max number of nazis, etc / map
+#define MAXSTATS		400				// max number of lamps, bonus, etc
+#define MAXDOORS		64				// max number of sliding doors
+#define MAXWALLTILES	64				// max number of wall tiles
+
+//
+// tile constants
+//
+
+#define	ICONARROWS		90
+#define PUSHABLETILE	98
+#define EXITTILE		99				// at end of castle
+#define AREATILE		107				// first of NUMAREAS floor tiles
+#define NUMAREAS		37
+#define ELEVATORTILE	21
+#define AMBUSHTILE		106
+#define	ALTELEVATORTILE	107
+
+#define NUMBERCHARS	9
+
+
+//----------------
+
+#define EXTRAPOINTS		40000
+
+#define PLAYERSPEED		3000
+#define RUNSPEED   		6000
+
+#define	SCREENSEG		0xa000
+
+#define SCREENBWIDE		80
+
+#define HEIGHTRATIO		0.50		// also defined in id_mm.c
+
+#define BORDERCOLOR	3
+#define FLASHCOLOR	5
+#define FLASHTICS	4
+
+
+#define PLAYERSIZE		MINDIST			// player radius
+#define MINACTORDIST	0x10000l		// minimum dist from player center
+										// to any actor center
+
+#define NUMLATCHPICS	100
+
+
+#define PI	3.141592657
+
+#define GLOBAL1		(1l<<16)
+#define TILEGLOBAL  GLOBAL1
+#define PIXGLOBAL	(GLOBAL1/64)
+#define TILESHIFT		16l
+#define UNSIGNEDSHIFT	8
+
+#define ANGLES		360					// must be divisable by 4
+#define ANGLEQUAD	(ANGLES/4)
+#define FINEANGLES	3600
+#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 MINDIST		(0x5800l)
+
+
+#define	MAXSCALEHEIGHT	256				// largest scale on largest view
+
+#define MAXVIEWWIDTH		320
+
+#define MAPSIZE		64					// maps are 64*64 max
+#define NORTH	0
+#define EAST	1
+#define SOUTH	2
+#define WEST	3
+
+
+#define STATUSLINES		40
+
+#define SCREENSIZE		(SCREENBWIDE*208)
+#define PAGE1START		0
+#define PAGE2START		(SCREENSIZE)
+#define PAGE3START		(SCREENSIZE*2u)
+#define	FREESTART		(SCREENSIZE*3u)
+
+
+#define PIXRADIUS		512
+
+#define STARTAMMO		8
+
+
+// object flag values
+
+#define FL_SHOOTABLE	1
+#define FL_BONUS		2
+#define FL_NEVERMARK	4
+#define FL_VISABLE		8
+#define FL_ATTACKMODE	16
+#define FL_FIRSTATTACK	32
+#define FL_AMBUSH		64
+#define FL_NONMARK		128
+
+
+//
+// sprite constants
+//
+
+enum	{
+		SPR_DEMO,
+		SPR_DEATHCAM,
+//
+// static sprites
+//
+		SPR_STAT_0,SPR_STAT_1,SPR_STAT_2,SPR_STAT_3,
+		SPR_STAT_4,SPR_STAT_5,SPR_STAT_6,SPR_STAT_7,
+
+		SPR_STAT_8,SPR_STAT_9,SPR_STAT_10,SPR_STAT_11,
+		SPR_STAT_12,SPR_STAT_13,SPR_STAT_14,SPR_STAT_15,
+
+		SPR_STAT_16,SPR_STAT_17,SPR_STAT_18,SPR_STAT_19,
+		SPR_STAT_20,SPR_STAT_21,SPR_STAT_22,SPR_STAT_23,
+
+		SPR_STAT_24,SPR_STAT_25,SPR_STAT_26,SPR_STAT_27,
+		SPR_STAT_28,SPR_STAT_29,SPR_STAT_30,SPR_STAT_31,
+
+		SPR_STAT_32,SPR_STAT_33,SPR_STAT_34,SPR_STAT_35,
+		SPR_STAT_36,SPR_STAT_37,SPR_STAT_38,SPR_STAT_39,
+
+		SPR_STAT_40,SPR_STAT_41,SPR_STAT_42,SPR_STAT_43,
+		SPR_STAT_44,SPR_STAT_45,SPR_STAT_46,SPR_STAT_47,
+
+#ifdef SPEAR
+		SPR_STAT_48,SPR_STAT_49,SPR_STAT_50,SPR_STAT_51,
+#endif
+
+//
+// guard
+//
+		SPR_GRD_S_1,SPR_GRD_S_2,SPR_GRD_S_3,SPR_GRD_S_4,
+		SPR_GRD_S_5,SPR_GRD_S_6,SPR_GRD_S_7,SPR_GRD_S_8,
+
+		SPR_GRD_W1_1,SPR_GRD_W1_2,SPR_GRD_W1_3,SPR_GRD_W1_4,
+		SPR_GRD_W1_5,SPR_GRD_W1_6,SPR_GRD_W1_7,SPR_GRD_W1_8,
+
+		SPR_GRD_W2_1,SPR_GRD_W2_2,SPR_GRD_W2_3,SPR_GRD_W2_4,
+		SPR_GRD_W2_5,SPR_GRD_W2_6,SPR_GRD_W2_7,SPR_GRD_W2_8,
+
+		SPR_GRD_W3_1,SPR_GRD_W3_2,SPR_GRD_W3_3,SPR_GRD_W3_4,
+		SPR_GRD_W3_5,SPR_GRD_W3_6,SPR_GRD_W3_7,SPR_GRD_W3_8,
+
+		SPR_GRD_W4_1,SPR_GRD_W4_2,SPR_GRD_W4_3,SPR_GRD_W4_4,
+		SPR_GRD_W4_5,SPR_GRD_W4_6,SPR_GRD_W4_7,SPR_GRD_W4_8,
+
+		SPR_GRD_PAIN_1,SPR_GRD_DIE_1,SPR_GRD_DIE_2,SPR_GRD_DIE_3,
+		SPR_GRD_PAIN_2,SPR_GRD_DEAD,
+
+		SPR_GRD_SHOOT1,SPR_GRD_SHOOT2,SPR_GRD_SHOOT3,
+
+//
+// dogs
+//
+		SPR_DOG_W1_1,SPR_DOG_W1_2,SPR_DOG_W1_3,SPR_DOG_W1_4,
+		SPR_DOG_W1_5,SPR_DOG_W1_6,SPR_DOG_W1_7,SPR_DOG_W1_8,
+
+		SPR_DOG_W2_1,SPR_DOG_W2_2,SPR_DOG_W2_3,SPR_DOG_W2_4,
+		SPR_DOG_W2_5,SPR_DOG_W2_6,SPR_DOG_W2_7,SPR_DOG_W2_8,
+
+		SPR_DOG_W3_1,SPR_DOG_W3_2,SPR_DOG_W3_3,SPR_DOG_W3_4,
+		SPR_DOG_W3_5,SPR_DOG_W3_6,SPR_DOG_W3_7,SPR_DOG_W3_8,
+
+		SPR_DOG_W4_1,SPR_DOG_W4_2,SPR_DOG_W4_3,SPR_DOG_W4_4,
+		SPR_DOG_W4_5,SPR_DOG_W4_6,SPR_DOG_W4_7,SPR_DOG_W4_8,
+
+		SPR_DOG_DIE_1,SPR_DOG_DIE_2,SPR_DOG_DIE_3,SPR_DOG_DEAD,
+		SPR_DOG_JUMP1,SPR_DOG_JUMP2,SPR_DOG_JUMP3,
+
+
+
+//
+// ss
+//
+		SPR_SS_S_1,SPR_SS_S_2,SPR_SS_S_3,SPR_SS_S_4,
+		SPR_SS_S_5,SPR_SS_S_6,SPR_SS_S_7,SPR_SS_S_8,
+
+		SPR_SS_W1_1,SPR_SS_W1_2,SPR_SS_W1_3,SPR_SS_W1_4,
+		SPR_SS_W1_5,SPR_SS_W1_6,SPR_SS_W1_7,SPR_SS_W1_8,
+
+		SPR_SS_W2_1,SPR_SS_W2_2,SPR_SS_W2_3,SPR_SS_W2_4,
+		SPR_SS_W2_5,SPR_SS_W2_6,SPR_SS_W2_7,SPR_SS_W2_8,
+
+		SPR_SS_W3_1,SPR_SS_W3_2,SPR_SS_W3_3,SPR_SS_W3_4,
+		SPR_SS_W3_5,SPR_SS_W3_6,SPR_SS_W3_7,SPR_SS_W3_8,
+
+		SPR_SS_W4_1,SPR_SS_W4_2,SPR_SS_W4_3,SPR_SS_W4_4,
+		SPR_SS_W4_5,SPR_SS_W4_6,SPR_SS_W4_7,SPR_SS_W4_8,
+
+		SPR_SS_PAIN_1,SPR_SS_DIE_1,SPR_SS_DIE_2,SPR_SS_DIE_3,
+		SPR_SS_PAIN_2,SPR_SS_DEAD,
+
+		SPR_SS_SHOOT1,SPR_SS_SHOOT2,SPR_SS_SHOOT3,
+
+//
+// mutant
+//
+		SPR_MUT_S_1,SPR_MUT_S_2,SPR_MUT_S_3,SPR_MUT_S_4,
+		SPR_MUT_S_5,SPR_MUT_S_6,SPR_MUT_S_7,SPR_MUT_S_8,
+
+		SPR_MUT_W1_1,SPR_MUT_W1_2,SPR_MUT_W1_3,SPR_MUT_W1_4,
+		SPR_MUT_W1_5,SPR_MUT_W1_6,SPR_MUT_W1_7,SPR_MUT_W1_8,
+
+		SPR_MUT_W2_1,SPR_MUT_W2_2,SPR_MUT_W2_3,SPR_MUT_W2_4,
+		SPR_MUT_W2_5,SPR_MUT_W2_6,SPR_MUT_W2_7,SPR_MUT_W2_8,
+
+		SPR_MUT_W3_1,SPR_MUT_W3_2,SPR_MUT_W3_3,SPR_MUT_W3_4,
+		SPR_MUT_W3_5,SPR_MUT_W3_6,SPR_MUT_W3_7,SPR_MUT_W3_8,
+
+		SPR_MUT_W4_1,SPR_MUT_W4_2,SPR_MUT_W4_3,SPR_MUT_W4_4,
+		SPR_MUT_W4_5,SPR_MUT_W4_6,SPR_MUT_W4_7,SPR_MUT_W4_8,
+
+		SPR_MUT_PAIN_1,SPR_MUT_DIE_1,SPR_MUT_DIE_2,SPR_MUT_DIE_3,
+		SPR_MUT_PAIN_2,SPR_MUT_DIE_4,SPR_MUT_DEAD,
+
+		SPR_MUT_SHOOT1,SPR_MUT_SHOOT2,SPR_MUT_SHOOT3,SPR_MUT_SHOOT4,
+
+//
+// officer
+//
+		SPR_OFC_S_1,SPR_OFC_S_2,SPR_OFC_S_3,SPR_OFC_S_4,
+		SPR_OFC_S_5,SPR_OFC_S_6,SPR_OFC_S_7,SPR_OFC_S_8,
+
+		SPR_OFC_W1_1,SPR_OFC_W1_2,SPR_OFC_W1_3,SPR_OFC_W1_4,
+		SPR_OFC_W1_5,SPR_OFC_W1_6,SPR_OFC_W1_7,SPR_OFC_W1_8,
+
+		SPR_OFC_W2_1,SPR_OFC_W2_2,SPR_OFC_W2_3,SPR_OFC_W2_4,
+		SPR_OFC_W2_5,SPR_OFC_W2_6,SPR_OFC_W2_7,SPR_OFC_W2_8,
+
+		SPR_OFC_W3_1,SPR_OFC_W3_2,SPR_OFC_W3_3,SPR_OFC_W3_4,
+		SPR_OFC_W3_5,SPR_OFC_W3_6,SPR_OFC_W3_7,SPR_OFC_W3_8,
+
+		SPR_OFC_W4_1,SPR_OFC_W4_2,SPR_OFC_W4_3,SPR_OFC_W4_4,
+		SPR_OFC_W4_5,SPR_OFC_W4_6,SPR_OFC_W4_7,SPR_OFC_W4_8,
+
+		SPR_OFC_PAIN_1,SPR_OFC_DIE_1,SPR_OFC_DIE_2,SPR_OFC_DIE_3,
+		SPR_OFC_PAIN_2,SPR_OFC_DIE_4,SPR_OFC_DEAD,
+
+		SPR_OFC_SHOOT1,SPR_OFC_SHOOT2,SPR_OFC_SHOOT3,
+
+#ifndef SPEAR
+//
+// ghosts
+//
+		SPR_BLINKY_W1,SPR_BLINKY_W2,SPR_PINKY_W1,SPR_PINKY_W2,
+		SPR_CLYDE_W1,SPR_CLYDE_W2,SPR_INKY_W1,SPR_INKY_W2,
+
+//
+// hans
+//
+		SPR_BOSS_W1,SPR_BOSS_W2,SPR_BOSS_W3,SPR_BOSS_W4,
+		SPR_BOSS_SHOOT1,SPR_BOSS_SHOOT2,SPR_BOSS_SHOOT3,SPR_BOSS_DEAD,
+
+		SPR_BOSS_DIE1,SPR_BOSS_DIE2,SPR_BOSS_DIE3,
+
+//
+// schabbs
+//
+		SPR_SCHABB_W1,SPR_SCHABB_W2,SPR_SCHABB_W3,SPR_SCHABB_W4,
+		SPR_SCHABB_SHOOT1,SPR_SCHABB_SHOOT2,
+
+		SPR_SCHABB_DIE1,SPR_SCHABB_DIE2,SPR_SCHABB_DIE3,SPR_SCHABB_DEAD,
+		SPR_HYPO1,SPR_HYPO2,SPR_HYPO3,SPR_HYPO4,
+
+//
+// fake
+//
+		SPR_FAKE_W1,SPR_FAKE_W2,SPR_FAKE_W3,SPR_FAKE_W4,
+		SPR_FAKE_SHOOT,SPR_FIRE1,SPR_FIRE2,
+
+		SPR_FAKE_DIE1,SPR_FAKE_DIE2,SPR_FAKE_DIE3,SPR_FAKE_DIE4,
+		SPR_FAKE_DIE5,SPR_FAKE_DEAD,
+
+//
+// hitler
+//
+		SPR_MECHA_W1,SPR_MECHA_W2,SPR_MECHA_W3,SPR_MECHA_W4,
+		SPR_MECHA_SHOOT1,SPR_MECHA_SHOOT2,SPR_MECHA_SHOOT3,SPR_MECHA_DEAD,
+
+		SPR_MECHA_DIE1,SPR_MECHA_DIE2,SPR_MECHA_DIE3,
+
+		SPR_HITLER_W1,SPR_HITLER_W2,SPR_HITLER_W3,SPR_HITLER_W4,
+		SPR_HITLER_SHOOT1,SPR_HITLER_SHOOT2,SPR_HITLER_SHOOT3,SPR_HITLER_DEAD,
+
+		SPR_HITLER_DIE1,SPR_HITLER_DIE2,SPR_HITLER_DIE3,SPR_HITLER_DIE4,
+		SPR_HITLER_DIE5,SPR_HITLER_DIE6,SPR_HITLER_DIE7,
+
+//
+// giftmacher
+//
+		SPR_GIFT_W1,SPR_GIFT_W2,SPR_GIFT_W3,SPR_GIFT_W4,
+		SPR_GIFT_SHOOT1,SPR_GIFT_SHOOT2,
+
+		SPR_GIFT_DIE1,SPR_GIFT_DIE2,SPR_GIFT_DIE3,SPR_GIFT_DEAD,
+#endif
+//
+// Rocket, smoke and small explosion
+//
+		SPR_ROCKET_1,SPR_ROCKET_2,SPR_ROCKET_3,SPR_ROCKET_4,
+		SPR_ROCKET_5,SPR_ROCKET_6,SPR_ROCKET_7,SPR_ROCKET_8,
+
+		SPR_SMOKE_1,SPR_SMOKE_2,SPR_SMOKE_3,SPR_SMOKE_4,
+		SPR_BOOM_1,SPR_BOOM_2,SPR_BOOM_3,
+
+//
+// Angel of Death's DeathSparks(tm)
+//
+#ifdef SPEAR
+		SPR_HROCKET_1,SPR_HROCKET_2,SPR_HROCKET_3,SPR_HROCKET_4,
+		SPR_HROCKET_5,SPR_HROCKET_6,SPR_HROCKET_7,SPR_HROCKET_8,
+
+		SPR_HSMOKE_1,SPR_HSMOKE_2,SPR_HSMOKE_3,SPR_HSMOKE_4,
+		SPR_HBOOM_1,SPR_HBOOM_2,SPR_HBOOM_3,
+
+		SPR_SPARK1,SPR_SPARK2,SPR_SPARK3,SPR_SPARK4,
+#endif
+
+#ifndef SPEAR
+//
+// gretel
+//
+		SPR_GRETEL_W1,SPR_GRETEL_W2,SPR_GRETEL_W3,SPR_GRETEL_W4,
+		SPR_GRETEL_SHOOT1,SPR_GRETEL_SHOOT2,SPR_GRETEL_SHOOT3,SPR_GRETEL_DEAD,
+
+		SPR_GRETEL_DIE1,SPR_GRETEL_DIE2,SPR_GRETEL_DIE3,
+
+//
+// fat face
+//
+		SPR_FAT_W1,SPR_FAT_W2,SPR_FAT_W3,SPR_FAT_W4,
+		SPR_FAT_SHOOT1,SPR_FAT_SHOOT2,SPR_FAT_SHOOT3,SPR_FAT_SHOOT4,
+
+		SPR_FAT_DIE1,SPR_FAT_DIE2,SPR_FAT_DIE3,SPR_FAT_DEAD,
+
+//
+// bj
+//
+		SPR_BJ_W1,SPR_BJ_W2,SPR_BJ_W3,SPR_BJ_W4,
+		SPR_BJ_JUMP1,SPR_BJ_JUMP2,SPR_BJ_JUMP3,SPR_BJ_JUMP4,
+#else
+//
+// THESE ARE FOR 'SPEAR OF DESTINY'
+//
+
+//
+// Trans Grosse
+//
+		SPR_TRANS_W1,SPR_TRANS_W2,SPR_TRANS_W3,SPR_TRANS_W4,
+		SPR_TRANS_SHOOT1,SPR_TRANS_SHOOT2,SPR_TRANS_SHOOT3,SPR_TRANS_DEAD,
+
+		SPR_TRANS_DIE1,SPR_TRANS_DIE2,SPR_TRANS_DIE3,
+
+//
+// Wilhelm
+//
+		SPR_WILL_W1,SPR_WILL_W2,SPR_WILL_W3,SPR_WILL_W4,
+		SPR_WILL_SHOOT1,SPR_WILL_SHOOT2,SPR_WILL_SHOOT3,SPR_WILL_SHOOT4,
+
+		SPR_WILL_DIE1,SPR_WILL_DIE2,SPR_WILL_DIE3,SPR_WILL_DEAD,
+
+//
+// UberMutant
+//
+		SPR_UBER_W1,SPR_UBER_W2,SPR_UBER_W3,SPR_UBER_W4,
+		SPR_UBER_SHOOT1,SPR_UBER_SHOOT2,SPR_UBER_SHOOT3,SPR_UBER_SHOOT4,
+
+		SPR_UBER_DIE1,SPR_UBER_DIE2,SPR_UBER_DIE3,SPR_UBER_DIE4,
+		SPR_UBER_DEAD,
+
+//
+// Death Knight
+//
+		SPR_DEATH_W1,SPR_DEATH_W2,SPR_DEATH_W3,SPR_DEATH_W4,
+		SPR_DEATH_SHOOT1,SPR_DEATH_SHOOT2,SPR_DEATH_SHOOT3,SPR_DEATH_SHOOT4,
+
+		SPR_DEATH_DIE1,SPR_DEATH_DIE2,SPR_DEATH_DIE3,SPR_DEATH_DIE4,
+		SPR_DEATH_DIE5,SPR_DEATH_DIE6,SPR_DEATH_DEAD,
+
+//
+// Ghost
+//
+		SPR_SPECTRE_W1,SPR_SPECTRE_W2,SPR_SPECTRE_W3,SPR_SPECTRE_W4,
+		SPR_SPECTRE_F1,SPR_SPECTRE_F2,SPR_SPECTRE_F3,SPR_SPECTRE_F4,
+
+//
+// Angel of Death
+//
+		SPR_ANGEL_W1,SPR_ANGEL_W2,SPR_ANGEL_W3,SPR_ANGEL_W4,
+		SPR_ANGEL_SHOOT1,SPR_ANGEL_SHOOT2,SPR_ANGEL_TIRED1,SPR_ANGEL_TIRED2,
+
+		SPR_ANGEL_DIE1,SPR_ANGEL_DIE2,SPR_ANGEL_DIE3,SPR_ANGEL_DIE4,
+		SPR_ANGEL_DIE5,SPR_ANGEL_DIE6,SPR_ANGEL_DIE7,SPR_ANGEL_DEAD,
+
+#endif
+
+//
+// player attack frames
+//
+		SPR_KNIFEREADY,SPR_KNIFEATK1,SPR_KNIFEATK2,SPR_KNIFEATK3,
+		SPR_KNIFEATK4,
+
+		SPR_PISTOLREADY,SPR_PISTOLATK1,SPR_PISTOLATK2,SPR_PISTOLATK3,
+		SPR_PISTOLATK4,
+
+		SPR_MACHINEGUNREADY,SPR_MACHINEGUNATK1,SPR_MACHINEGUNATK2,MACHINEGUNATK3,
+		SPR_MACHINEGUNATK4,
+
+		SPR_CHAINREADY,SPR_CHAINATK1,SPR_CHAINATK2,SPR_CHAINATK3,
+		SPR_CHAINATK4,
+
+		};
+
+
+/*
+=============================================================================
+
+						   GLOBAL TYPES
+
+=============================================================================
+*/
+
+typedef long fixed;
+
+typedef enum {
+	di_north,
+	di_east,
+	di_south,
+	di_west
+} controldir_t;
+
+typedef enum {
+	dr_normal,
+	dr_lock1,
+	dr_lock2,
+	dr_lock3,
+	dr_lock4,
+	dr_elevator
+} door_t;
+
+typedef enum {
+	ac_badobject = -1,
+	ac_no,
+	ac_yes,
+	ac_allways
+} activetype;
+
+typedef enum {
+	nothing,
+	playerobj,
+	inertobj,
+	guardobj,
+	officerobj,
+	ssobj,
+	dogobj,
+	bossobj,
+	schabbobj,
+	fakeobj,
+	mechahitlerobj,
+	mutantobj,
+	needleobj,
+	fireobj,
+	bjobj,
+	ghostobj,
+	realhitlerobj,
+	gretelobj,
+	giftobj,
+	fatobj,
+	rocketobj,
+
+	spectreobj,
+	angelobj,
+	transobj,
+	uberobj,
+	willobj,
+	deathobj,
+	hrocketobj,
+	sparkobj
+} classtype;
+
+typedef enum {
+	dressing,
+	block,
+	bo_gibs,
+	bo_alpo,
+	bo_firstaid,
+	bo_key1,
+	bo_key2,
+	bo_key3,
+	bo_key4,
+	bo_cross,
+	bo_chalice,
+	bo_bible,
+	bo_crown,
+	bo_clip,
+	bo_clip2,
+	bo_machinegun,
+	bo_chaingun,
+	bo_food,
+	bo_fullheal,
+	bo_25clip,
+	bo_spear
+} stat_t;
+
+typedef enum {
+	east,
+	northeast,
+	north,
+	northwest,
+	west,
+	southwest,
+	south,
+	southeast,
+	nodir
+} dirtype;
+
+
+#define NUMENEMIES		22
+typedef enum {
+	en_guard,
+	en_officer,
+	en_ss,
+	en_dog,
+	en_boss,
+	en_schabbs,
+	en_fake,
+	en_hitler,
+	en_mutant,
+	en_blinky,
+	en_clyde,
+	en_pinky,
+	en_inky,
+	en_gretel,
+	en_gift,
+	en_fat,
+	en_spectre,
+	en_angel,
+	en_trans,
+	en_uber,
+	en_will,
+	en_death
+} enemy_t;
+
+
+typedef struct	statestruct
+{
+	boolean	rotate;
+	int		shapenum;			// a shapenum of -1 means get from ob->temp1
+	int		tictime;
+	void	(*think) (),(*action) ();
+	struct	statestruct	*next;
+} statetype;
+
+
+//---------------------
+//
+// trivial actor structure
+//
+//---------------------
+
+typedef struct statstruct
+{
+	byte	tilex,tiley;
+	byte	*visspot;
+	int		shapenum;			// if shapenum == -1 the obj has been removed
+	byte	flags;
+	byte	itemnumber;
+} statobj_t;
+
+
+//---------------------
+//
+// door actor structure
+//
+//---------------------
+
+typedef struct doorstruct
+{
+	byte	tilex,tiley;
+	boolean	vertical;
+	byte	lock;
+	enum	{dr_open,dr_closed,dr_opening,dr_closing}	action;
+	int		ticcount;
+} doorobj_t;
+
+
+//--------------------
+//
+// thinking actor structure
+//
+//--------------------
+
+typedef struct objstruct
+{
+	activetype	active;
+	int			ticcount;
+	classtype	obclass;
+	statetype	*state;
+
+	byte		flags;				//	FL_SHOOTABLE, etc
+
+	long		distance;			// if negative, wait for that door to open
+	dirtype		dir;
+
+	fixed 		x,y;
+	unsigned	tilex,tiley;
+	byte		areanumber;
+
+	int	 		viewx;
+	unsigned	viewheight;
+	fixed		transx,transy;		// in global coord
+
+	int 		angle;
+	int			hitpoints;
+	long		speed;
+
+	int			temp1,temp2,temp3;
+	struct		objstruct	*next,*prev;
+} objtype;
+
+
+#define NUMBUTTONS	8
+enum	{
+	bt_nobutton=-1,
+	bt_attack=0,
+	bt_strafe,
+	bt_run,
+	bt_use,
+	bt_readyknife,
+	bt_readypistol,
+	bt_readymachinegun,
+	bt_readychaingun
+};
+
+
+#define NUMWEAPONS	5
+typedef enum	{
+	wp_knife,
+	wp_pistol,
+	wp_machinegun,
+	wp_chaingun
+} weapontype;
+
+
+typedef enum	{
+	gd_baby,
+	gd_easy,
+	gd_medium,
+	gd_hard
+};
+
+//---------------
+//
+// gamestate structure
+//
+//---------------
+
+typedef	struct
+{
+	int			difficulty;
+	int			mapon;
+	long		oldscore,score,nextextra;
+	int			lives;
+	int			health;
+	int			ammo;
+	int			keys;
+	weapontype		bestweapon,weapon,chosenweapon;
+
+	int			faceframe;
+	int			attackframe,attackcount,weaponframe;
+
+	int			episode,secretcount,treasurecount,killcount,
+				secrettotal,treasuretotal,killtotal;
+	long		TimeCount;
+	long		killx,killy;
+	boolean		victoryflag;		// set during victory animations
+} gametype;
+
+
+typedef	enum	{
+	ex_stillplaying,
+	ex_completed,
+	ex_died,
+	ex_warped,
+	ex_resetgame,
+	ex_loadedgame,
+	ex_victorious,
+	ex_abort,
+	ex_demodone,
+	ex_secretlevel
+} exit_t;
+
+
+/*
+=============================================================================
+
+						 WL_MAIN DEFINITIONS
+
+=============================================================================
+*/
+
+extern	boolean		MS_CheckParm (char far *string);
+
+extern	char		str[80],str2[20];
+extern	int			tedlevelnum;
+extern	boolean		tedlevel;
+extern	boolean		nospr;
+extern	boolean		IsA386;
+
+extern	byte far	*scalermemory;
+
+extern	fixed		focallength;
+extern	unsigned	viewangles;
+extern	unsigned	screenofs;
+extern	int		    viewwidth;
+extern	int			viewheight;
+extern	int			centerx;
+extern	int			shootdelta;
+
+extern	int			dirangle[9];
+
+extern	boolean         startgame,loadedgame,virtualreality;
+extern	int		mouseadjustment;
+//
+// math tables
+//
+extern	int			pixelangle[MAXVIEWWIDTH];
+extern	long		far finetangent[FINEANGLES/4];
+extern	fixed 		far sintable[],far *costable;
+
+//
+// derived constants
+//
+extern	fixed 	scale,maxslope;
+extern	long	heightnumerator;
+extern	int		minheightdiv;
+
+extern	char	configname[13];
+
+
+
+void		HelpScreens (void);
+void		OrderingInfo (void);
+void		TEDDeath(void);
+void		Quit (char *error);
+void 		CalcProjection (long focal);
+boolean		SetViewSize (unsigned width, unsigned height);
+void		NewGame (int difficulty,int episode);
+void 		NewViewSize (int width);
+boolean 	LoadTheGame(int file,int x,int y);
+boolean		SaveTheGame(int file,int x,int y);
+void 		ShowViewSize (int width);
+void		ShutdownId (void);
+
+
+/*
+=============================================================================
+
+						 WL_GAME DEFINITIONS
+
+=============================================================================
+*/
+
+
+extern	boolean		ingame,fizzlein;
+extern	unsigned	latchpics[NUMLATCHPICS];
+extern	gametype	gamestate;
+extern	int			doornum;
+
+extern	char		demoname[13];
+
+extern	long		spearx,speary;
+extern	unsigned	spearangle;
+extern	boolean		spearflag;
+
+
+void 	DrawPlayBorder (void);
+void 	ScanInfoPlane (void);
+void	SetupGameLevel (void);
+void 	NormalScreen (void);
+void 	DrawPlayScreen (void);
+void 	FizzleOut (void);
+void 	GameLoop (void);
+void ClearMemory (void);
+void PlayDemo (int demonumber);
+void RecordDemo (void);
+void DrawAllPlayBorder (void);
+void	DrawHighScores(void);
+void DrawAllPlayBorderSides (void);
+
+
+// JAB
+#define	PlaySoundLocTile(s,tx,ty)	PlaySoundLocGlobal(s,(((long)(tx) << TILESHIFT) + (1L << (TILESHIFT - 1))),(((long)ty << TILESHIFT) + (1L << (TILESHIFT - 1))))
+#define	PlaySoundLocActor(s,ob)		PlaySoundLocGlobal(s,(ob)->x,(ob)->y)
+void	PlaySoundLocGlobal(word s,fixed gx,fixed gy);
+void UpdateSoundLoc(void);
+
+
+/*
+=============================================================================
+
+						 WL_PLAY DEFINITIONS
+
+=============================================================================
+*/
+
+#ifdef SPEAR
+extern	long		funnyticount;		// FOR FUNNY BJ FACE
+#endif
+
+extern	exit_t		playstate;
+
+extern	boolean		madenoise;
+
+extern	objtype 	objlist[MAXACTORS],*new,*obj,*player,*lastobj,
+					*objfreelist,*killerobj;
+extern	statobj_t	statobjlist[MAXSTATS],*laststatobj;
+extern	doorobj_t	doorobjlist[MAXDOORS],*lastdoorobj;
+
+extern	unsigned	farmapylookup[MAPSIZE];
+extern	byte		*nearmapylookup[MAPSIZE];
+
+extern	byte		tilemap[MAPSIZE][MAPSIZE];	// wall values only
+extern	byte		spotvis[MAPSIZE][MAPSIZE];
+extern	objtype		*actorat[MAPSIZE][MAPSIZE];
+
+#define UPDATESIZE			(UPDATEWIDE*UPDATEHIGH)
+extern	byte		update[UPDATESIZE];
+
+extern	boolean		singlestep,godmode,noclip;
+extern	int			extravbls;
+
+//
+// control info
+//
+extern	boolean		mouseenabled,joystickenabled,joypadenabled,joystickprogressive;
+extern	int			joystickport;
+extern	int			dirscan[4];
+extern	int			buttonscan[NUMBUTTONS];
+extern	int			buttonmouse[4];
+extern	int			buttonjoy[4];
+
+extern	boolean		buttonheld[NUMBUTTONS];
+
+extern	int			viewsize;
+
+//
+// curent user input
+//
+extern	int			controlx,controly;		// range from -100 to 100
+extern	boolean		buttonstate[NUMBUTTONS];
+
+extern	boolean		demorecord,demoplayback;
+extern	char		far *demoptr, far *lastdemoptr;
+extern	memptr		demobuffer;
+
+
+
+void	InitRedShifts (void);
+void 	FinishPaletteShifts (void);
+
+void	CenterWindow(word w,word h);
+void 	InitActorList (void);
+void 	GetNewActor (void);
+void 	RemoveObj (objtype *gone);
+void 	PollControls (void);
+void 	StopMusic(void);
+void 	StartMusic(void);
+void	PlayLoop (void);
+void StartDamageFlash (int damage);
+void StartBonusFlash (void);
+
+/*
+=============================================================================
+
+							WL_INTER
+
+=============================================================================
+*/
+
+void IntroScreen (void);
+void PreloadGraphics(void);
+void LevelCompleted (void);
+void	CheckHighScore (long score,word other);
+void Victory (void);
+void ClearSplitVWB (void);
+
+
+/*
+=============================================================================
+
+							WL_DEBUG
+
+=============================================================================
+*/
+
+int DebugKeys (void);
+void PicturePause (void);
+
+
+/*
+=============================================================================
+
+						 WL_DRAW DEFINITIONS
+
+=============================================================================
+*/
+
+extern	unsigned screenloc[3];
+extern	unsigned freelatch;
+
+extern	long 	lasttimecount;
+extern	long 	frameon;
+extern	boolean	fizzlein;
+
+extern	unsigned	wallheight[MAXVIEWWIDTH];
+
+extern	fixed	tileglobal;
+extern	fixed	focallength;
+extern	fixed	mindist;
+
+//
+// math tables
+//
+extern	int			pixelangle[MAXVIEWWIDTH];
+extern	long		far finetangent[FINEANGLES/4];
+extern	fixed 		far sintable[],far *costable;
+
+//
+// derived constants
+//
+extern	fixed 	scale;
+extern	long	heightnumerator,mindist;
+
+//
+// refresh variables
+//
+extern	fixed	viewx,viewy;			// the focal point
+extern	int		viewangle;
+extern	fixed	viewsin,viewcos;
+
+extern	long		postsource;
+extern	unsigned	postx;
+extern	unsigned	postwidth;
+
+
+extern	int		horizwall[],vertwall[];
+
+extern	unsigned	pwallpos;
+
+
+fixed	FixedByFrac (fixed a, fixed b);
+void	TransformActor (objtype *ob);
+void	BuildTables (void);
+void	ClearScreen (void);
+int		CalcRotate (objtype *ob);
+void	DrawScaleds (void);
+void	CalcTics (void);
+void	FixOfs (void);
+void	ThreeDRefresh (void);
+void  FarScalePost (void);
+
+/*
+=============================================================================
+
+						 WL_STATE DEFINITIONS
+
+=============================================================================
+*/
+#define TURNTICS	10
+#define SPDPATROL	512
+#define SPDDOG		1500
+
+
+extern	dirtype opposite[9];
+extern	dirtype diagonal[9][9];
+
+
+void	InitHitRect (objtype *ob, unsigned radius);
+void	SpawnNewObj (unsigned tilex, unsigned tiley, statetype *state);
+void	NewState (objtype *ob, statetype *state);
+
+boolean TryWalk (objtype *ob);
+void 	SelectChaseDir (objtype *ob);
+void 	SelectDodgeDir (objtype *ob);
+void	SelectRunDir (objtype *ob);
+void	MoveObj (objtype *ob, long move);
+boolean SightPlayer (objtype *ob);
+
+void	KillActor (objtype *ob);
+void	DamageActor (objtype *ob, unsigned damage);
+
+boolean CheckLine (objtype *ob);
+boolean	CheckSight (objtype *ob);
+
+
+/*
+=============================================================================
+
+						 WL_SCALE DEFINITIONS
+
+=============================================================================
+*/
+
+
+#define COMPSCALECODESTART	(65*4)		// offset to start of code in comp scaler
+
+typedef struct
+{
+	unsigned	codeofs[65];
+	unsigned	width[65];
+	byte		code[];
+}	t_compscale;
+
+typedef struct
+{
+	unsigned	leftpix,rightpix;
+	unsigned	dataofs[64];
+// table data after dataofs[rightpix-leftpix+1]
+}	t_compshape;
+
+
+extern	t_compscale _seg *scaledirectory[MAXSCALEHEIGHT+1];
+extern	long			fullscalefarcall[MAXSCALEHEIGHT+1];
+
+extern	byte		bitmasks1[8][8];
+extern	byte		bitmasks2[8][8];
+extern	unsigned	wordmasks[8][8];
+
+extern	byte		mapmasks1[4][8];
+extern	byte		mapmasks2[4][8];
+extern	byte		mapmasks3[4][8];
+
+extern	int			maxscale,maxscaleshl2;
+
+extern	boolean	insetupscaling;
+
+void SetupScaling (int maxscaleheight);
+void ScaleShape (int xcenter, int shapenum, unsigned height);
+void SimpleScaleShape (int xcenter, int shapenum, unsigned height);
+
+/*
+=============================================================================
+
+						 WL_AGENT DEFINITIONS
+
+=============================================================================
+*/
+
+//
+// player state info
+//
+extern	boolean		running;
+extern	long		thrustspeed;
+extern	unsigned	plux,pluy;		// player coordinates scaled to unsigned
+
+extern	int			anglefrac;
+extern	int			facecount;
+
+void	SpawnPlayer (int tilex, int tiley, int dir);
+void 	DrawFace (void);
+void	DrawHealth (void);
+void	TakeDamage (int points,objtype *attacker);
+void	HealSelf (int points);
+void	DrawLevel (void);
+void	DrawLives (void);
+void	GiveExtraMan (void);
+void	DrawScore (void);
+void	GivePoints (long points);
+void	DrawWeapon (void);
+void	DrawKeys (void);
+void	GiveWeapon (int weapon);
+void	DrawAmmo (void);
+void	GiveAmmo (int ammo);
+void	GiveKey (int key);
+void	GetBonus (statobj_t *check);
+
+void	Thrust (int angle, long speed);
+
+/*
+=============================================================================
+
+						 WL_ACT1 DEFINITIONS
+
+=============================================================================
+*/
+
+extern	doorobj_t	doorobjlist[MAXDOORS],*lastdoorobj;
+extern	int			doornum;
+
+extern	unsigned	doorposition[MAXDOORS],pwallstate;
+
+extern	byte		far areaconnect[NUMAREAS][NUMAREAS];
+
+extern	boolean		areabyplayer[NUMAREAS];
+
+extern unsigned	pwallstate;
+extern unsigned	pwallpos;			// amount a pushable wall has been moved (0-63)
+extern unsigned	pwallx,pwally;
+extern int			pwalldir;
+
+
+void InitDoorList (void);
+void InitStaticList (void);
+void SpawnStatic (int tilex, int tiley, int type);
+void SpawnDoor (int tilex, int tiley, boolean vertical, int lock);
+void MoveDoors (void);
+void MovePWalls (void);
+void OpenDoor (int door);
+void PlaceItemType (int itemtype, int tilex, int tiley);
+void PushWall (int checkx, int checky, int dir);
+void OperateDoor (int door);
+void InitAreas (void);
+
+/*
+=============================================================================
+
+						 WL_ACT2 DEFINITIONS
+
+=============================================================================
+*/
+
+#define s_nakedbody s_static10
+
+extern	statetype s_grddie1;
+extern	statetype s_dogdie1;
+extern	statetype s_ofcdie1;
+extern	statetype s_mutdie1;
+extern	statetype s_ssdie1;
+extern	statetype s_bossdie1;
+extern	statetype s_schabbdie1;
+extern	statetype s_fakedie1;
+extern	statetype s_mechadie1;
+extern	statetype s_hitlerdie1;
+extern	statetype s_greteldie1;
+extern	statetype s_giftdie1;
+extern	statetype s_fatdie1;
+
+extern	statetype s_spectredie1;
+extern	statetype s_angeldie1;
+extern	statetype s_transdie0;
+extern	statetype s_uberdie0;
+extern	statetype s_willdie1;
+extern	statetype s_deathdie1;
+
+
+extern	statetype s_grdchase1;
+extern	statetype s_dogchase1;
+extern	statetype s_ofcchase1;
+extern	statetype s_sschase1;
+extern	statetype s_mutchase1;
+extern	statetype s_bosschase1;
+extern	statetype s_schabbchase1;
+extern	statetype s_fakechase1;
+extern	statetype s_mechachase1;
+extern	statetype s_gretelchase1;
+extern	statetype s_giftchase1;
+extern	statetype s_fatchase1;
+
+extern	statetype s_spectrechase1;
+extern	statetype s_angelchase1;
+extern	statetype s_transchase1;
+extern	statetype s_uberchase1;
+extern	statetype s_willchase1;
+extern	statetype s_deathchase1;
+
+extern	statetype s_blinkychase1;
+extern	statetype s_hitlerchase1;
+
+extern	statetype s_grdpain;
+extern	statetype s_grdpain1;
+extern	statetype s_ofcpain;
+extern	statetype s_ofcpain1;
+extern	statetype s_sspain;
+extern	statetype s_sspain1;
+extern	statetype s_mutpain;
+extern	statetype s_mutpain1;
+
+extern	statetype s_deathcam;
+
+extern	statetype s_schabbdeathcam2;
+extern	statetype s_hitlerdeathcam2;
+extern	statetype s_giftdeathcam2;
+extern	statetype s_fatdeathcam2;
+
+void SpawnStand (enemy_t which, int tilex, int tiley, int dir);
+void SpawnPatrol (enemy_t which, int tilex, int tiley, int dir);
+void KillActor (objtype *ob);
+
+void	US_ControlPanel(byte);
+
+void SpawnDeadGuard (int tilex, int tiley);
+void SpawnBoss (int tilex, int tiley);
+void SpawnGretel (int tilex, int tiley);
+void SpawnTrans (int tilex, int tiley);
+void SpawnUber (int tilex, int tiley);
+void SpawnWill (int tilex, int tiley);
+void SpawnDeath (int tilex, int tiley);
+void SpawnAngel (int tilex, int tiley);
+void SpawnSpectre (int tilex, int tiley);
+void SpawnGhosts (int which, int tilex, int tiley);
+void SpawnSchabbs (int tilex, int tiley);
+void SpawnGift (int tilex, int tiley);
+void SpawnFat (int tilex, int tiley);
+void SpawnFakeHitler (int tilex, int tiley);
+void SpawnHitler (int tilex, int tiley);
+
+/*
+=============================================================================
+
+						 WL_TEXT DEFINITIONS
+
+=============================================================================
+*/
+
+extern	char	helpfilename[],endfilename[];
+
+extern	void	HelpScreens(void);
+extern	void	EndText(void);
--- /dev/null
+++ b/WOLFSRC/WL_DRAW.C
@@ -1,0 +1,1403 @@
+// WL_DRAW.C
+
+#include "WL_DEF.H"
+#include <DOS.H>
+#pragma hdrstop
+
+//#define DEBUGWALLS
+//#define DEBUGTICS
+
+/*
+=============================================================================
+
+						 LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+// the door is the last picture before the sprites
+#define DOORWALL	(PMSpriteStart-8)
+
+#define ACTORSIZE	0x4000
+
+/*
+=============================================================================
+
+						 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+
+#ifdef DEBUGWALLS
+unsigned screenloc[3]= {0,0,0};
+#else
+unsigned screenloc[3]= {PAGE1START,PAGE2START,PAGE3START};
+#endif
+unsigned freelatch = FREESTART;
+
+long 	lasttimecount;
+long 	frameon;
+
+unsigned	wallheight[MAXVIEWWIDTH];
+
+fixed	tileglobal	= TILEGLOBAL;
+fixed	mindist		= MINDIST;
+
+
+//
+// math tables
+//
+int			pixelangle[MAXVIEWWIDTH];
+long		far finetangent[FINEANGLES/4];
+fixed 		far sintable[ANGLES+ANGLES/4],far *costable = sintable+(ANGLES/4);
+
+//
+// refresh variables
+//
+fixed	viewx,viewy;			// the focal point
+int		viewangle;
+fixed	viewsin,viewcos;
+
+
+
+fixed	FixedByFrac (fixed a, fixed b);
+void	TransformActor (objtype *ob);
+void	BuildTables (void);
+void	ClearScreen (void);
+int		CalcRotate (objtype *ob);
+void	DrawScaleds (void);
+void	CalcTics (void);
+void	FixOfs (void);
+void	ThreeDRefresh (void);
+
+
+
+//
+// wall optimization variables
+//
+int		lastside;		// true for vertical
+long	lastintercept;
+int		lasttilehit;
+
+
+//
+// ray tracing variables
+//
+int			focaltx,focalty,viewtx,viewty;
+
+int			midangle,angle;
+unsigned	xpartial,ypartial;
+unsigned	xpartialup,xpartialdown,ypartialup,ypartialdown;
+unsigned	xinttile,yinttile;
+
+unsigned	tilehit;
+unsigned	pixx;
+
+int		xtile,ytile;
+int		xtilestep,ytilestep;
+long	xintercept,yintercept;
+long	xstep,ystep;
+
+int		horizwall[MAXWALLTILES],vertwall[MAXWALLTILES];
+
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+
+void AsmRefresh (void);			// in WL_DR_A.ASM
+
+/*
+============================================================================
+
+			   3 - D  DEFINITIONS
+
+============================================================================
+*/
+
+
+//==========================================================================
+
+
+/*
+========================
+=
+= FixedByFrac
+=
+= multiply a 16/16 bit, 2's complement fixed point number by a 16 bit
+= fraction, passed as a signed magnitude 32 bit number
+=
+========================
+*/
+
+#pragma warn -rvl			// I stick the return value in with ASMs
+
+fixed FixedByFrac (fixed a, fixed b)
+{
+//
+// setup
+//
+asm	mov	si,[WORD PTR b+2]	// sign of result = sign of fraction
+
+asm	mov	ax,[WORD PTR a]
+asm	mov	cx,[WORD PTR a+2]
+
+asm	or	cx,cx
+asm	jns	aok:				// negative?
+asm	neg	cx
+asm	neg	ax
+asm	sbb	cx,0
+asm	xor	si,0x8000			// toggle sign of result
+aok:
+
+//
+// multiply  cx:ax by bx
+//
+asm	mov	bx,[WORD PTR b]
+asm	mul	bx					// fraction*fraction
+asm	mov	di,dx				// di is low word of result
+asm	mov	ax,cx				//
+asm	mul	bx					// units*fraction
+asm add	ax,di
+asm	adc	dx,0
+
+//
+// put result dx:ax in 2's complement
+//
+asm	test	si,0x8000		// is the result negative?
+asm	jz	ansok:
+asm	neg	dx
+asm	neg	ax
+asm	sbb	dx,0
+
+ansok:;
+
+}
+
+#pragma warn +rvl
+
+//==========================================================================
+
+/*
+========================
+=
+= TransformActor
+=
+= Takes paramaters:
+=   gx,gy		: globalx/globaly of point
+=
+= globals:
+=   viewx,viewy		: point of view
+=   viewcos,viewsin	: sin/cos of viewangle
+=   scale		: conversion from global value to screen value
+=
+= sets:
+=   screenx,transx,transy,screenheight: projected edge location and size
+=
+========================
+*/
+
+
+//
+// transform actor
+//
+void TransformActor (objtype *ob)
+{
+	int ratio;
+	fixed gx,gy,gxt,gyt,nx,ny;
+	long	temp;
+
+//
+// translate point to view centered coordinates
+//
+	gx = ob->x-viewx;
+	gy = ob->y-viewy;
+
+//
+// calculate newx
+//
+	gxt = FixedByFrac(gx,viewcos);
+	gyt = FixedByFrac(gy,viewsin);
+	nx = gxt-gyt-ACTORSIZE;		// fudge the shape forward a bit, because
+								// the midpoint could put parts of the shape
+								// into an adjacent wall
+
+//
+// calculate newy
+//
+	gxt = FixedByFrac(gx,viewsin);
+	gyt = FixedByFrac(gy,viewcos);
+	ny = gyt+gxt;
+
+//
+// calculate perspective ratio
+//
+	ob->transx = nx;
+	ob->transy = ny;
+
+	if (nx<mindist)			// too close, don't overflow the divide
+	{
+	  ob->viewheight = 0;
+	  return;
+	}
+
+	ob->viewx = centerx + ny*scale/nx;	// DEBUG: use assembly divide
+
+//
+// calculate height (heightnumerator/(nx>>8))
+//
+	asm	mov	ax,[WORD PTR heightnumerator]
+	asm	mov	dx,[WORD PTR heightnumerator+2]
+	asm	idiv	[WORD PTR nx+1]			// nx>>8
+	asm	mov	[WORD PTR temp],ax
+	asm	mov	[WORD PTR temp+2],dx
+
+	ob->viewheight = temp;
+}
+
+//==========================================================================
+
+/*
+========================
+=
+= TransformTile
+=
+= Takes paramaters:
+=   tx,ty		: tile the object is centered in
+=
+= globals:
+=   viewx,viewy		: point of view
+=   viewcos,viewsin	: sin/cos of viewangle
+=   scale		: conversion from global value to screen value
+=
+= sets:
+=   screenx,transx,transy,screenheight: projected edge location and size
+=
+= Returns true if the tile is withing getting distance
+=
+========================
+*/
+
+boolean TransformTile (int tx, int ty, int *dispx, int *dispheight)
+{
+	int ratio;
+	fixed gx,gy,gxt,gyt,nx,ny;
+	long	temp;
+
+//
+// translate point to view centered coordinates
+//
+	gx = ((long)tx<<TILESHIFT)+0x8000-viewx;
+	gy = ((long)ty<<TILESHIFT)+0x8000-viewy;
+
+//
+// calculate newx
+//
+	gxt = FixedByFrac(gx,viewcos);
+	gyt = FixedByFrac(gy,viewsin);
+	nx = gxt-gyt-0x2000;		// 0x2000 is size of object
+
+//
+// calculate newy
+//
+	gxt = FixedByFrac(gx,viewsin);
+	gyt = FixedByFrac(gy,viewcos);
+	ny = gyt+gxt;
+
+
+//
+// calculate perspective ratio
+//
+	if (nx<mindist)			// too close, don't overflow the divide
+	{
+		*dispheight = 0;
+		return false;
+	}
+
+	*dispx = centerx + ny*scale/nx;	// DEBUG: use assembly divide
+
+//
+// calculate height (heightnumerator/(nx>>8))
+//
+	asm	mov	ax,[WORD PTR heightnumerator]
+	asm	mov	dx,[WORD PTR heightnumerator+2]
+	asm	idiv	[WORD PTR nx+1]			// nx>>8
+	asm	mov	[WORD PTR temp],ax
+	asm	mov	[WORD PTR temp+2],dx
+
+	*dispheight = temp;
+
+//
+// see if it should be grabbed
+//
+	if (nx<TILEGLOBAL && ny>-TILEGLOBAL/2 && ny<TILEGLOBAL/2)
+		return true;
+	else
+		return false;
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= CalcHeight
+=
+= Calculates the height of xintercept,yintercept from viewx,viewy
+=
+====================
+*/
+
+#pragma warn -rvl			// I stick the return value in with ASMs
+
+int	CalcHeight (void)
+{
+	int	transheight;
+	int ratio;
+	fixed gxt,gyt,nx,ny;
+	long	gx,gy;
+
+	gx = xintercept-viewx;
+	gxt = FixedByFrac(gx,viewcos);
+
+	gy = yintercept-viewy;
+	gyt = FixedByFrac(gy,viewsin);
+
+	nx = gxt-gyt;
+
+  //
+  // calculate perspective ratio (heightnumerator/(nx>>8))
+  //
+	if (nx<mindist)
+		nx=mindist;			// don't let divide overflow
+
+	asm	mov	ax,[WORD PTR heightnumerator]
+	asm	mov	dx,[WORD PTR heightnumerator+2]
+	asm	idiv	[WORD PTR nx+1]			// nx>>8
+}
+
+
+//==========================================================================
+
+/*
+===================
+=
+= ScalePost
+=
+===================
+*/
+
+long		postsource;
+unsigned	postx;
+unsigned	postwidth;
+
+void	near ScalePost (void)		// VGA version
+{
+	asm	mov	ax,SCREENSEG
+	asm	mov	es,ax
+
+	asm	mov	bx,[postx]
+	asm	shl	bx,1
+	asm	mov	bp,WORD PTR [wallheight+bx]		// fractional height (low 3 bits frac)
+	asm	and	bp,0xfff8				// bp = heightscaler*4
+	asm	shr	bp,1
+	asm	cmp	bp,[maxscaleshl2]
+	asm	jle	heightok
+	asm	mov	bp,[maxscaleshl2]
+heightok:
+	asm	add	bp,OFFSET fullscalefarcall
+	//
+	// scale a byte wide strip of wall
+	//
+	asm	mov	bx,[postx]
+	asm	mov	di,bx
+	asm	shr	di,2						// X in bytes
+	asm	add	di,[bufferofs]
+
+	asm	and	bx,3
+	asm	shl	bx,3						// bx = pixel*8+pixwidth
+	asm	add	bx,[postwidth]
+
+	asm	mov	al,BYTE PTR [mapmasks1-1+bx]	// -1 because no widths of 0
+	asm	mov	dx,SC_INDEX+1
+	asm	out	dx,al						// set bit mask register
+	asm	lds	si,DWORD PTR [postsource]
+	asm	call DWORD PTR [bp]				// scale the line of pixels
+
+	asm	mov	al,BYTE PTR [ss:mapmasks2-1+bx]   // -1 because no widths of 0
+	asm	or	al,al
+	asm	jz	nomore
+
+	//
+	// draw a second byte for vertical strips that cross two bytes
+	//
+	asm	inc	di
+	asm	out	dx,al						// set bit mask register
+	asm	call DWORD PTR [bp]				// scale the line of pixels
+
+	asm	mov	al,BYTE PTR [ss:mapmasks3-1+bx]	// -1 because no widths of 0
+	asm	or	al,al
+	asm	jz	nomore
+	//
+	// draw a third byte for vertical strips that cross three bytes
+	//
+	asm	inc	di
+	asm	out	dx,al						// set bit mask register
+	asm	call DWORD PTR [bp]				// scale the line of pixels
+
+
+nomore:
+	asm	mov	ax,ss
+	asm	mov	ds,ax
+}
+
+void  FarScalePost (void)				// just so other files can call
+{
+	ScalePost ();
+}
+
+
+/*
+====================
+=
+= HitVertWall
+=
+= tilehit bit 7 is 0, because it's not a door tile
+= if bit 6 is 1 and the adjacent tile is a door tile, use door side pic
+=
+====================
+*/
+
+void HitVertWall (void)
+{
+	int			wallpic;
+	unsigned	texture;
+
+	texture = (yintercept>>4)&0xfc0;
+	if (xtilestep == -1)
+	{
+		texture = 0xfc0-texture;
+		xintercept += TILEGLOBAL;
+	}
+	wallheight[pixx] = CalcHeight();
+
+	if (lastside==1 && lastintercept == xtile && lasttilehit == tilehit)
+	{
+		// in the same wall type as last time, so check for optimized draw
+		if (texture == (unsigned)postsource)
+		{
+		// wide scale
+			postwidth++;
+			wallheight[pixx] = wallheight[pixx-1];
+			return;
+		}
+		else
+		{
+			ScalePost ();
+			(unsigned)postsource = texture;
+			postwidth = 1;
+			postx = pixx;
+		}
+	}
+	else
+	{
+	// new wall
+		if (lastside != -1)				// if not the first scaled post
+			ScalePost ();
+
+		lastside = true;
+		lastintercept = xtile;
+
+		lasttilehit = tilehit;
+		postx = pixx;
+		postwidth = 1;
+
+		if (tilehit & 0x40)
+		{								// check for adjacent doors
+			ytile = yintercept>>TILESHIFT;
+			if ( tilemap[xtile-xtilestep][ytile]&0x80 )
+				wallpic = DOORWALL+3;
+			else
+				wallpic = vertwall[tilehit & ~0x40];
+		}
+		else
+			wallpic = vertwall[tilehit];
+
+		*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic);
+		(unsigned)postsource = texture;
+
+	}
+}
+
+
+/*
+====================
+=
+= HitHorizWall
+=
+= tilehit bit 7 is 0, because it's not a door tile
+= if bit 6 is 1 and the adjacent tile is a door tile, use door side pic
+=
+====================
+*/
+
+void HitHorizWall (void)
+{
+	int			wallpic;
+	unsigned	texture;
+
+	texture = (xintercept>>4)&0xfc0;
+	if (ytilestep == -1)
+		yintercept += TILEGLOBAL;
+	else
+		texture = 0xfc0-texture;
+	wallheight[pixx] = CalcHeight();
+
+	if (lastside==0 && lastintercept == ytile && lasttilehit == tilehit)
+	{
+		// in the same wall type as last time, so check for optimized draw
+		if (texture == (unsigned)postsource)
+		{
+		// wide scale
+			postwidth++;
+			wallheight[pixx] = wallheight[pixx-1];
+			return;
+		}
+		else
+		{
+			ScalePost ();
+			(unsigned)postsource = texture;
+			postwidth = 1;
+			postx = pixx;
+		}
+	}
+	else
+	{
+	// new wall
+		if (lastside != -1)				// if not the first scaled post
+			ScalePost ();
+
+		lastside = 0;
+		lastintercept = ytile;
+
+		lasttilehit = tilehit;
+		postx = pixx;
+		postwidth = 1;
+
+		if (tilehit & 0x40)
+		{								// check for adjacent doors
+			xtile = xintercept>>TILESHIFT;
+			if ( tilemap[xtile][ytile-ytilestep]&0x80 )
+				wallpic = DOORWALL+2;
+			else
+				wallpic = horizwall[tilehit & ~0x40];
+		}
+		else
+			wallpic = horizwall[tilehit];
+
+		*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic);
+		(unsigned)postsource = texture;
+	}
+
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= HitHorizDoor
+=
+====================
+*/
+
+void HitHorizDoor (void)
+{
+	unsigned	texture,doorpage,doornum;
+
+	doornum = tilehit&0x7f;
+	texture = ( (xintercept-doorposition[doornum]) >> 4) &0xfc0;
+
+	wallheight[pixx] = CalcHeight();
+
+	if (lasttilehit == tilehit)
+	{
+	// in the same door as last time, so check for optimized draw
+		if (texture == (unsigned)postsource)
+		{
+		// wide scale
+			postwidth++;
+			wallheight[pixx] = wallheight[pixx-1];
+			return;
+		}
+		else
+		{
+			ScalePost ();
+			(unsigned)postsource = texture;
+			postwidth = 1;
+			postx = pixx;
+		}
+	}
+	else
+	{
+		if (lastside != -1)				// if not the first scaled post
+			ScalePost ();			// draw last post
+	// first pixel in this door
+		lastside = 2;
+		lasttilehit = tilehit;
+		postx = pixx;
+		postwidth = 1;
+
+		switch (doorobjlist[doornum].lock)
+		{
+		case dr_normal:
+			doorpage = DOORWALL;
+			break;
+		case dr_lock1:
+		case dr_lock2:
+		case dr_lock3:
+		case dr_lock4:
+			doorpage = DOORWALL+6;
+			break;
+		case dr_elevator:
+			doorpage = DOORWALL+4;
+			break;
+		}
+
+		*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(doorpage);
+		(unsigned)postsource = texture;
+	}
+}
+
+//==========================================================================
+
+/*
+====================
+=
+= HitVertDoor
+=
+====================
+*/
+
+void HitVertDoor (void)
+{
+	unsigned	texture,doorpage,doornum;
+
+	doornum = tilehit&0x7f;
+	texture = ( (yintercept-doorposition[doornum]) >> 4) &0xfc0;
+
+	wallheight[pixx] = CalcHeight();
+
+	if (lasttilehit == tilehit)
+	{
+	// in the same door as last time, so check for optimized draw
+		if (texture == (unsigned)postsource)
+		{
+		// wide scale
+			postwidth++;
+			wallheight[pixx] = wallheight[pixx-1];
+			return;
+		}
+		else
+		{
+			ScalePost ();
+			(unsigned)postsource = texture;
+			postwidth = 1;
+			postx = pixx;
+		}
+	}
+	else
+	{
+		if (lastside != -1)				// if not the first scaled post
+			ScalePost ();			// draw last post
+	// first pixel in this door
+		lastside = 2;
+		lasttilehit = tilehit;
+		postx = pixx;
+		postwidth = 1;
+
+		switch (doorobjlist[doornum].lock)
+		{
+		case dr_normal:
+			doorpage = DOORWALL;
+			break;
+		case dr_lock1:
+		case dr_lock2:
+		case dr_lock3:
+		case dr_lock4:
+			doorpage = DOORWALL+6;
+			break;
+		case dr_elevator:
+			doorpage = DOORWALL+4;
+			break;
+		}
+
+		*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(doorpage+1);
+		(unsigned)postsource = texture;
+	}
+}
+
+//==========================================================================
+
+
+/*
+====================
+=
+= HitHorizPWall
+=
+= A pushable wall in action has been hit
+=
+====================
+*/
+
+void HitHorizPWall (void)
+{
+	int			wallpic;
+	unsigned	texture,offset;
+
+	texture = (xintercept>>4)&0xfc0;
+	offset = pwallpos<<10;
+	if (ytilestep == -1)
+		yintercept += TILEGLOBAL-offset;
+	else
+	{
+		texture = 0xfc0-texture;
+		yintercept += offset;
+	}
+
+	wallheight[pixx] = CalcHeight();
+
+	if (lasttilehit == tilehit)
+	{
+		// in the same wall type as last time, so check for optimized draw
+		if (texture == (unsigned)postsource)
+		{
+		// wide scale
+			postwidth++;
+			wallheight[pixx] = wallheight[pixx-1];
+			return;
+		}
+		else
+		{
+			ScalePost ();
+			(unsigned)postsource = texture;
+			postwidth = 1;
+			postx = pixx;
+		}
+	}
+	else
+	{
+	// new wall
+		if (lastside != -1)				// if not the first scaled post
+			ScalePost ();
+
+		lasttilehit = tilehit;
+		postx = pixx;
+		postwidth = 1;
+
+		wallpic = horizwall[tilehit&63];
+
+		*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic);
+		(unsigned)postsource = texture;
+	}
+
+}
+
+
+/*
+====================
+=
+= HitVertPWall
+=
+= A pushable wall in action has been hit
+=
+====================
+*/
+
+void HitVertPWall (void)
+{
+	int			wallpic;
+	unsigned	texture,offset;
+
+	texture = (yintercept>>4)&0xfc0;
+	offset = pwallpos<<10;
+	if (xtilestep == -1)
+	{
+		xintercept += TILEGLOBAL-offset;
+		texture = 0xfc0-texture;
+	}
+	else
+		xintercept += offset;
+
+	wallheight[pixx] = CalcHeight();
+
+	if (lasttilehit == tilehit)
+	{
+		// in the same wall type as last time, so check for optimized draw
+		if (texture == (unsigned)postsource)
+		{
+		// wide scale
+			postwidth++;
+			wallheight[pixx] = wallheight[pixx-1];
+			return;
+		}
+		else
+		{
+			ScalePost ();
+			(unsigned)postsource = texture;
+			postwidth = 1;
+			postx = pixx;
+		}
+	}
+	else
+	{
+	// new wall
+		if (lastside != -1)				// if not the first scaled post
+			ScalePost ();
+
+		lasttilehit = tilehit;
+		postx = pixx;
+		postwidth = 1;
+
+		wallpic = vertwall[tilehit&63];
+
+		*( ((unsigned *)&postsource)+1) = (unsigned)PM_GetPage(wallpic);
+		(unsigned)postsource = texture;
+	}
+
+}
+
+//==========================================================================
+
+//==========================================================================
+
+#if 0
+/*
+=====================
+=
+= ClearScreen
+=
+=====================
+*/
+
+void ClearScreen (void)
+{
+ unsigned floor=egaFloor[gamestate.episode*10+mapon],
+	  ceiling=egaCeiling[gamestate.episode*10+mapon];
+
+  //
+  // clear the screen
+  //
+asm	mov	dx,GC_INDEX
+asm	mov	ax,GC_MODE + 256*2		// read mode 0, write mode 2
+asm	out	dx,ax
+asm	mov	ax,GC_BITMASK + 255*256
+asm	out	dx,ax
+
+asm	mov	dx,40
+asm	mov	ax,[viewwidth]
+asm	shr	ax,3
+asm	sub	dx,ax					// dx = 40-viewwidth/8
+
+asm	mov	bx,[viewwidth]
+asm	shr	bx,4					// bl = viewwidth/16
+asm	mov	bh,BYTE PTR [viewheight]
+asm	shr	bh,1					// half height
+
+asm	mov	ax,[ceiling]
+asm	mov	es,[screenseg]
+asm	mov	di,[bufferofs]
+
+toploop:
+asm	mov	cl,bl
+asm	rep	stosw
+asm	add	di,dx
+asm	dec	bh
+asm	jnz	toploop
+
+asm	mov	bh,BYTE PTR [viewheight]
+asm	shr	bh,1					// half height
+asm	mov	ax,[floor]
+
+bottomloop:
+asm	mov	cl,bl
+asm	rep	stosw
+asm	add	di,dx
+asm	dec	bh
+asm	jnz	bottomloop
+
+
+asm	mov	dx,GC_INDEX
+asm	mov	ax,GC_MODE + 256*10		// read mode 1, write mode 2
+asm	out	dx,ax
+asm	mov	al,GC_BITMASK
+asm	out	dx,al
+
+}
+#endif
+//==========================================================================
+
+unsigned vgaCeiling[]=
+{
+#ifndef SPEAR
+ 0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0xbfbf,
+ 0x4e4e,0x4e4e,0x4e4e,0x1d1d,0x8d8d,0x4e4e,0x1d1d,0x2d2d,0x1d1d,0x8d8d,
+ 0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x1d1d,0x2d2d,0xdddd,0x1d1d,0x1d1d,0x9898,
+
+ 0x1d1d,0x9d9d,0x2d2d,0xdddd,0xdddd,0x9d9d,0x2d2d,0x4d4d,0x1d1d,0xdddd,
+ 0x7d7d,0x1d1d,0x2d2d,0x2d2d,0xdddd,0xd7d7,0x1d1d,0x1d1d,0x1d1d,0x2d2d,
+ 0x1d1d,0x1d1d,0x1d1d,0x1d1d,0xdddd,0xdddd,0x7d7d,0xdddd,0xdddd,0xdddd
+#else
+ 0x6f6f,0x4f4f,0x1d1d,0xdede,0xdfdf,0x2e2e,0x7f7f,0x9e9e,0xaeae,0x7f7f,
+ 0x1d1d,0xdede,0xdfdf,0xdede,0xdfdf,0xdede,0xe1e1,0xdcdc,0x2e2e,0x1d1d,0xdcdc
+#endif
+};
+
+/*
+=====================
+=
+= VGAClearScreen
+=
+=====================
+*/
+
+void VGAClearScreen (void)
+{
+ unsigned ceiling=vgaCeiling[gamestate.episode*10+mapon];
+
+  //
+  // clear the screen
+  //
+asm	mov	dx,SC_INDEX
+asm	mov	ax,SC_MAPMASK+15*256	// write through all planes
+asm	out	dx,ax
+
+asm	mov	dx,80
+asm	mov	ax,[viewwidth]
+asm	shr	ax,2
+asm	sub	dx,ax					// dx = 40-viewwidth/2
+
+asm	mov	bx,[viewwidth]
+asm	shr	bx,3					// bl = viewwidth/8
+asm	mov	bh,BYTE PTR [viewheight]
+asm	shr	bh,1					// half height
+
+asm	mov	es,[screenseg]
+asm	mov	di,[bufferofs]
+asm	mov	ax,[ceiling]
+
+toploop:
+asm	mov	cl,bl
+asm	rep	stosw
+asm	add	di,dx
+asm	dec	bh
+asm	jnz	toploop
+
+asm	mov	bh,BYTE PTR [viewheight]
+asm	shr	bh,1					// half height
+asm	mov	ax,0x1919
+
+bottomloop:
+asm	mov	cl,bl
+asm	rep	stosw
+asm	add	di,dx
+asm	dec	bh
+asm	jnz	bottomloop
+}
+
+//==========================================================================
+
+/*
+=====================
+=
+= CalcRotate
+=
+=====================
+*/
+
+int	CalcRotate (objtype *ob)
+{
+	int	angle,viewangle;
+
+	// this isn't exactly correct, as it should vary by a trig value,
+	// but it is close enough with only eight rotations
+
+	viewangle = player->angle + (centerx - ob->viewx)/8;
+
+	if (ob->obclass == rocketobj || ob->obclass == hrocketobj)
+		angle =  (viewangle-180)- ob->angle;
+	else
+		angle =  (viewangle-180)- dirangle[ob->dir];
+
+	angle+=ANGLES/16;
+	while (angle>=ANGLES)
+		angle-=ANGLES;
+	while (angle<0)
+		angle+=ANGLES;
+
+	if (ob->state->rotate == 2)             // 2 rotation pain frame
+		return 4*(angle/(ANGLES/2));        // seperated by 3 (art layout...)
+
+	return angle/(ANGLES/8);
+}
+
+
+/*
+=====================
+=
+= DrawScaleds
+=
+= Draws all objects that are visable
+=
+=====================
+*/
+
+#define MAXVISABLE	50
+
+typedef struct
+{
+	int	viewx,
+		viewheight,
+		shapenum;
+} visobj_t;
+
+visobj_t	vislist[MAXVISABLE],*visptr,*visstep,*farthest;
+
+void DrawScaleds (void)
+{
+	int 		i,j,least,numvisable,height;
+	memptr		shape;
+	byte		*tilespot,*visspot;
+	int			shapenum;
+	unsigned	spotloc;
+
+	statobj_t	*statptr;
+	objtype		*obj;
+
+	visptr = &vislist[0];
+
+//
+// place static objects
+//
+	for (statptr = &statobjlist[0] ; statptr !=laststatobj ; statptr++)
+	{
+		if ((visptr->shapenum = statptr->shapenum) == -1)
+			continue;						// object has been deleted
+
+		if (!*statptr->visspot)
+			continue;						// not visable
+
+		if (TransformTile (statptr->tilex,statptr->tiley
+			,&visptr->viewx,&visptr->viewheight) && statptr->flags & FL_BONUS)
+		{
+			GetBonus (statptr);
+			continue;
+		}
+
+		if (!visptr->viewheight)
+			continue;						// to close to the object
+
+		if (visptr < &vislist[MAXVISABLE-1])	// don't let it overflow
+			visptr++;
+	}
+
+//
+// place active objects
+//
+	for (obj = player->next;obj;obj=obj->next)
+	{
+		if (!(visptr->shapenum = obj->state->shapenum))
+			continue;						// no shape
+
+		spotloc = (obj->tilex<<6)+obj->tiley;	// optimize: keep in struct?
+		visspot = &spotvis[0][0]+spotloc;
+		tilespot = &tilemap[0][0]+spotloc;
+
+		//
+		// could be in any of the nine surrounding tiles
+		//
+		if (*visspot
+		|| ( *(visspot-1) && !*(tilespot-1) )
+		|| ( *(visspot+1) && !*(tilespot+1) )
+		|| ( *(visspot-65) && !*(tilespot-65) )
+		|| ( *(visspot-64) && !*(tilespot-64) )
+		|| ( *(visspot-63) && !*(tilespot-63) )
+		|| ( *(visspot+65) && !*(tilespot+65) )
+		|| ( *(visspot+64) && !*(tilespot+64) )
+		|| ( *(visspot+63) && !*(tilespot+63) ) )
+		{
+			obj->active = true;
+			TransformActor (obj);
+			if (!obj->viewheight)
+				continue;						// too close or far away
+
+			visptr->viewx = obj->viewx;
+			visptr->viewheight = obj->viewheight;
+			if (visptr->shapenum == -1)
+				visptr->shapenum = obj->temp1;	// special shape
+
+			if (obj->state->rotate)
+				visptr->shapenum += CalcRotate (obj);
+
+			if (visptr < &vislist[MAXVISABLE-1])	// don't let it overflow
+				visptr++;
+			obj->flags |= FL_VISABLE;
+		}
+		else
+			obj->flags &= ~FL_VISABLE;
+	}
+
+//
+// draw from back to front
+//
+	numvisable = visptr-&vislist[0];
+
+	if (!numvisable)
+		return;									// no visable objects
+
+	for (i = 0; i<numvisable; i++)
+	{
+		least = 32000;
+		for (visstep=&vislist[0] ; visstep<visptr ; visstep++)
+		{
+			height = visstep->viewheight;
+			if (height < least)
+			{
+				least = height;
+				farthest = visstep;
+			}
+		}
+		//
+		// draw farthest
+		//
+		ScaleShape(farthest->viewx,farthest->shapenum,farthest->viewheight);
+
+		farthest->viewheight = 32000;
+	}
+
+}
+
+//==========================================================================
+
+/*
+==============
+=
+= DrawPlayerWeapon
+=
+= Draw the player's hands
+=
+==============
+*/
+
+int	weaponscale[NUMWEAPONS] = {SPR_KNIFEREADY,SPR_PISTOLREADY
+	,SPR_MACHINEGUNREADY,SPR_CHAINREADY};
+
+void DrawPlayerWeapon (void)
+{
+	int	shapenum;
+
+#ifndef SPEAR
+	if (gamestate.victoryflag)
+	{
+		if (player->state == &s_deathcam && (TimeCount&32) )
+			SimpleScaleShape(viewwidth/2,SPR_DEATHCAM,viewheight+1);
+		return;
+	}
+#endif
+
+	if (gamestate.weapon != -1)
+	{
+		shapenum = weaponscale[gamestate.weapon]+gamestate.weaponframe;
+		SimpleScaleShape(viewwidth/2,shapenum,viewheight+1);
+	}
+
+	if (demorecord || demoplayback)
+		SimpleScaleShape(viewwidth/2,SPR_DEMO,viewheight+1);
+}
+
+
+//==========================================================================
+
+
+/*
+=====================
+=
+= CalcTics
+=
+=====================
+*/
+
+void CalcTics (void)
+{
+	long	newtime,oldtimecount;
+
+//
+// calculate tics since last refresh for adaptive timing
+//
+	if (lasttimecount > TimeCount)
+		TimeCount = lasttimecount;		// if the game was paused a LONG time
+
+	do
+	{
+		newtime = TimeCount;
+		tics = newtime-lasttimecount;
+	} while (!tics);			// make sure at least one tic passes
+
+	lasttimecount = newtime;
+
+#ifdef FILEPROFILE
+		strcpy (scratch,"\tTics:");
+		itoa (tics,str,10);
+		strcat (scratch,str);
+		strcat (scratch,"\n");
+		write (profilehandle,scratch,strlen(scratch));
+#endif
+
+	if (tics>MAXTICS)
+	{
+		TimeCount -= (tics-MAXTICS);
+		tics = MAXTICS;
+	}
+}
+
+
+//==========================================================================
+
+
+/*
+========================
+=
+= FixOfs
+=
+========================
+*/
+
+void	FixOfs (void)
+{
+	VW_ScreenToScreen (displayofs,bufferofs,viewwidth/8,viewheight);
+}
+
+
+//==========================================================================
+
+
+/*
+====================
+=
+= WallRefresh
+=
+====================
+*/
+
+void WallRefresh (void)
+{
+//
+// set up variables for this view
+//
+	viewangle = player->angle;
+	midangle = viewangle*(FINEANGLES/ANGLES);
+	viewsin = sintable[viewangle];
+	viewcos = costable[viewangle];
+	viewx = player->x - FixedByFrac(focallength,viewcos);
+	viewy = player->y + FixedByFrac(focallength,viewsin);
+
+	focaltx = viewx>>TILESHIFT;
+	focalty = viewy>>TILESHIFT;
+
+	viewtx = player->x >> TILESHIFT;
+	viewty = player->y >> TILESHIFT;
+
+	xpartialdown = viewx&(TILEGLOBAL-1);
+	xpartialup = TILEGLOBAL-xpartialdown;
+	ypartialdown = viewy&(TILEGLOBAL-1);
+	ypartialup = TILEGLOBAL-ypartialdown;
+
+	lastside = -1;			// the first pixel is on a new wall
+	AsmRefresh ();
+	ScalePost ();			// no more optimization on last post
+}
+
+//==========================================================================
+
+/*
+========================
+=
+= ThreeDRefresh
+=
+========================
+*/
+
+void	ThreeDRefresh (void)
+{
+	int tracedir;
+
+// this wouldn't need to be done except for my debugger/video wierdness
+	outportb (SC_INDEX,SC_MAPMASK);
+
+//
+// clear out the traced array
+//
+asm	mov	ax,ds
+asm	mov	es,ax
+asm	mov	di,OFFSET spotvis
+asm	xor	ax,ax
+asm	mov	cx,2048							// 64*64 / 2
+asm	rep stosw
+
+	bufferofs += screenofs;
+
+//
+// follow the walls from there to the right, drawwing as we go
+//
+	VGAClearScreen ();
+
+	WallRefresh ();
+
+//
+// draw all the scaled images
+//
+	DrawScaleds();			// draw scaled stuff
+	DrawPlayerWeapon ();	// draw player's hands
+
+//
+// show screen and time last cycle
+//
+	if (fizzlein)
+	{
+		FizzleFade(bufferofs,displayofs+screenofs,viewwidth,viewheight,20,false);
+		fizzlein = false;
+
+		lasttimecount = TimeCount = 0;		// don't make a big tic count
+
+	}
+
+	bufferofs -= screenofs;
+	displayofs = bufferofs;
+
+	asm	cli
+	asm	mov	cx,[displayofs]
+	asm	mov	dx,3d4h		// CRTC address register
+	asm	mov	al,0ch		// start address high register
+	asm	out	dx,al
+	asm	inc	dx
+	asm	mov	al,ch
+	asm	out	dx,al   	// set the high byte
+	asm	sti
+
+	bufferofs += SCREENSIZE;
+	if (bufferofs > PAGE3START)
+		bufferofs = PAGE1START;
+
+	frameon++;
+	PM_NextFrame();
+}
+
+
+//===========================================================================
+
--- /dev/null
+++ b/WOLFSRC/WL_DR_A.ASM
@@ -1,0 +1,739 @@
+	IDEAL
+	MODEL	MEDIUM,C
+	P286
+
+SCREENSEG	=	0a000h
+
+FINEANGLES	=	3600
+DEG90		=	900
+DEG180		=	1800
+DEG270		=	2700
+DEG360		=	3600
+
+OP_JLE		=	07eh
+OP_JGE		=	07dh
+
+EXTRN	finetangent:DWORD	; far array, starts at offset 0
+
+EXTRN	HitHorizWall:FAR
+EXTRN	HitVertWall:FAR
+EXTRN	HitHorizDoor:FAR
+EXTRN	HitVertDoor:FAR
+EXTRN	HitHorizPWall:FAR
+EXTRN	HitVertPWall:FAR
+
+
+DATASEG
+
+EXTRN	viewwidth:WORD
+
+EXTRN	tilemap:BYTE
+EXTRN	spotvis:BYTE
+EXTRN	pixelangle:WORD
+
+
+EXTRN	midangle:WORD
+EXTRN	angle:WORD
+
+EXTRN	focaltx:WORD
+EXTRN	focalty:WORD
+EXTRN	viewtx:WORD
+EXTRN	viewty:WORD
+EXTRN	viewx:DWORD
+EXTRN	viewy:DWORD
+
+EXTRN	xpartialup:WORD
+EXTRN	ypartialup:WORD
+EXTRN	xpartialdown:WORD
+EXTRN	ypartialdown:WORD
+
+EXTRN	tilehit:WORD
+EXTRN	pixx:WORD
+EXTRN	wallheight:WORD			; array of VIEWWIDTH entries
+
+EXTRN	xtile:WORD
+EXTRN	ytile:WORD
+EXTRN	xtilestep:WORD
+EXTRN	ytilestep:WORD
+EXTRN	xintercept:DWORD
+EXTRN	yintercept:DWORD
+EXTRN	xstep:DWORD
+EXTRN	ystep:DWORD
+
+EXTRN	doorposition:WORD		; table of door position values
+
+
+EXTRN	pwallpos:WORD			; amound a pushable wall has been moved
+
+CODESEG
+
+;-------------------
+;
+; xpartialbyystep
+;
+; multiplies long [ystep] (possibly negative), by word [xpartial] (in BX)
+;
+; returns dx:ax
+; trashes bx,cx,di
+;
+;-------------------
+
+PROC xpartialbyystep NEAR
+;
+; setup
+;
+	mov	ax,[WORD ystep]
+	mov	cx,[WORD ystep+2]
+	or	cx,cx               ; is ystep negatice?
+	jns	@@multpos
+;
+; multiply negative cx:ax by bx
+;
+	neg	cx
+	neg	ax
+	sbb	cx,0
+
+	mul	bx					; fraction*fraction
+	mov	di,dx				; di is low word of result
+	mov	ax,cx				;
+	mul	bx					; units*fraction
+	add	ax,di
+	adc	dx,0
+
+	neg	dx
+	neg	ax
+	sbb	dx,0
+	ret
+;
+; multiply positive cx:ax by bx
+;
+EVEN
+@@multpos:
+	mul	bx					; fraction*fraction
+	mov	di,dx				; di is low word of result
+	mov	ax,cx				;
+	mul	bx					; units*fraction
+	add	ax,di
+	adc	dx,0
+
+	ret
+
+ENDP
+
+
+
+;-------------------
+;
+; ypartialbyxstep
+;
+; multiplies long [xstep] (possibly negative), by word [ypartial] (in BP)
+;
+; returns dx:ax
+; trashes cx,di,bp
+;
+;-------------------
+
+PROC ypartialbyxstep NEAR
+;
+; setup
+;
+	mov	ax,[WORD xstep]
+	mov	cx,[WORD xstep+2]
+	or	cx,cx               ; is ystep negatice?
+	jns	@@multpos
+;
+; multiply negative cx:ax by bx
+;
+	neg	cx
+	neg	ax
+	sbb	cx,0
+
+	mul	bp					; fraction*fraction
+	mov	di,dx				; di is low word of result
+	mov	ax,cx				;
+	mul	bp					; units*fraction
+	add	ax,di
+	adc	dx,0
+
+	neg	dx
+	neg	ax
+	sbb	dx,0
+	ret
+;
+; multiply positive cx:ax by bx
+;
+EVEN
+@@multpos:
+	mul	bp					; fraction*fraction
+	mov	di,dx				; di is low word of result
+	mov	ax,cx				;
+	mul	bp					; units*fraction
+	add	ax,di
+	adc	dx,0
+	ret
+
+ENDP
+
+
+;============================
+;
+; AsmRefresh
+;
+;
+;============================
+
+PROC	AsmRefresh
+PUBLIC	AsmRefresh
+
+	push	si
+	push	di
+	push	bp
+
+	mov	[pixx],0
+;---------------------------------------------------------------------------
+;
+; Setup to trace a ray through pixx view pixel
+;
+; CX : angle of the ray through pixx
+; ES : points to segment of finetangent array for this block of code
+;
+; Upon entrance to initialize block
+;
+; BX : xpartial
+; BP : ypartial
+;
+;---------------------------------------------------------------------------
+	EVEN
+pixxloop:
+	mov	ax,SEG finetangent
+	mov	es,ax
+	mov	cx,[midangle]			; center of view area
+	mov	bx,[pixx]
+	shl	bx,1
+	add	cx,[pixelangle+bx]		; delta for this pixel
+	cmp	cx,0
+	jge	not0
+;----------
+;
+; -90 - -1 degree arc
+;
+;----------
+	add	cx,FINEANGLES			; -90 is the same as 270
+	jmp	entry360
+
+not0:
+	cmp	cx,DEG90
+	jge	not90
+;----------
+;
+; 0-89 degree arc
+;
+;----------
+entry90:
+	mov	[xtilestep],1			; xtilestep = 1
+	mov	[ytilestep],-1			; ytilestep = -1
+	mov	[BYTE cs:horizop],OP_JGE	; patch a jge in
+	mov	[BYTE cs:vertop],OP_JLE		; patch a jle in
+	mov	bx,DEG90-1
+	sub	bx,cx
+	shl	bx,2
+	mov	ax,[es:bx]
+	mov	dx,[es:bx+2]
+	mov	[WORD xstep],ax
+	mov	[WORD xstep+2],dx		; xstep = finetangent[DEG90-1-angle]
+	mov	bx,cx
+	shl	bx,2
+	mov	ax,[es:bx]
+	mov	dx,[es:bx+2]
+	neg	dx
+	neg	ax
+	sbb	dx,0
+	mov	[WORD ystep],ax
+	mov	[WORD ystep+2],dx		; ystep = -finetangent[angle]
+
+	mov	bx,[xpartialup]			; xpartial = xpartialup
+	mov	bp,[ypartialdown]		; ypartial = ypartialdown
+	jmp	initvars
+
+not90:
+	cmp	cx,DEG180
+	jge	not180
+;----------
+;
+; 90-179 degree arc
+;
+;----------
+	mov	ax,-1
+	mov	[xtilestep],ax			; xtilestep = -1
+	mov	[ytilestep],ax			; ytilestep = -1
+	mov	[BYTE cs:horizop],OP_JLE	; patch a jle in
+	mov	[BYTE cs:vertop],OP_JLE		; patch a jle in
+
+	mov	bx,cx
+	shl	bx,2
+	mov	ax,[es:bx-DEG90*4]
+	mov	dx,[es:bx+2-DEG90*4]
+	neg	dx
+	neg	ax
+	sbb	dx,0
+	mov	[WORD xstep],ax
+	mov	[WORD xstep+2],dx		; xstep = -finetangent[angle-DEG90]
+	mov	bx,DEG180-1
+	sub	bx,cx
+	shl	bx,2
+	mov	ax,[es:bx]
+	mov	dx,[es:bx+2]
+	neg	dx
+	neg	ax
+	sbb	dx,0
+	mov	[WORD ystep],ax
+	mov	[WORD ystep+2],dx		; ystep = -finetangent[DEG180-1-angle]
+
+	mov	bx,[xpartialdown]		; xpartial = xpartialdown
+	mov	bp,[ypartialdown]		; ypartial = ypartialdown
+	jmp	initvars
+
+not180:
+	cmp	cx,DEG270
+	jge	not270
+;----------
+;
+; 180-269 degree arc
+;
+;----------
+	mov	[xtilestep],-1			; xtilestep = -1
+	mov	[ytilestep],1			; ytilestep = 1
+	mov	[BYTE cs:horizop],OP_JLE	; patch a jle in
+	mov	[BYTE cs:vertop],OP_JGE		; patch a jge in
+
+	mov	bx,DEG270-1
+	sub	bx,cx
+	shl	bx,2
+	mov	ax,[es:bx]
+	mov	dx,[es:bx+2]
+	neg	dx
+	neg	ax
+	sbb	dx,0
+	mov	[WORD xstep],ax
+	mov	[WORD xstep+2],dx		; xstep = -finetangent[DEG270-1-angle]
+	mov	bx,cx
+	shl	bx,2
+	mov	ax,[es:bx-DEG180*4]
+	mov	dx,[es:bx+2-DEG180*4]
+	mov	[WORD ystep],ax
+	mov	[WORD ystep+2],dx		; ystep = finetangent[angle-DEG180]
+
+	mov	bx,[xpartialdown]		; xpartial = xpartialdown
+	mov	bp,[ypartialup]			; ypartial = ypartialup
+	jmp	initvars
+
+
+not270:
+	cmp	cx,DEG360
+	jge	not360
+;----------
+;
+; 270-359 degree arc
+;
+;----------
+entry360:
+	mov	ax,1
+	mov	[xtilestep],ax			; xtilestep = 1
+	mov	[ytilestep],ax			; ytilestep = 1
+	mov	[BYTE cs:horizop],OP_JGE	; patch a jge in
+	mov	[BYTE cs:vertop],OP_JGE		; patch a jge in
+
+	mov	bx,cx
+	shl	bx,2
+	mov	ax,[es:bx-DEG270*4]
+	mov	dx,[es:bx+2-DEG270*4]
+	mov	[WORD xstep],ax
+	mov	[WORD xstep+2],dx		; xstep = finetangent[angle-DEG270]
+	mov	bx,DEG360-1
+	sub	bx,cx
+	shl	bx,2
+	mov	ax,[es:bx]
+	mov	dx,[es:bx+2]
+	mov	[WORD ystep],ax
+	mov	[WORD ystep+2],dx		; ystep = finetangent[DEG360-1-angle]
+
+	mov	bx,[xpartialup]			; xpartial = xpartialup
+	mov	bp,[ypartialup]			; ypartial = ypartialup
+	jmp	initvars
+
+
+not360:
+;----------
+;
+; 360-449 degree arc
+;
+;----------
+	sub	cx,FINEANGLES			; -449 is the same as 89
+	jmp	entry90
+
+;---------------------------------------------------------------------------
+;
+; initialise variables for intersection testing
+;
+;---------------------------------------------------------------------------
+initvars:
+	call	NEAR xpartialbyystep	; xpartial is in BX
+	add	ax,[WORD viewy]
+	adc	dx,[WORD viewy+2]
+	mov	[WORD yintercept],ax
+	mov	[WORD yintercept+2],dx
+
+	mov	si,[focaltx]
+	add	si,[xtilestep]
+	mov	[xtile],si					; xtile = focaltx+xtilestep
+	shl	si,6
+	add	si,dx						; xspot = (xtile<<6) + yinttile
+
+
+	call	NEAR ypartialbyxstep	; ypartial is in BP
+	add	ax,[WORD viewx]
+	adc	dx,[WORD viewx+2]
+	mov	[WORD xintercept],ax
+	mov	cx,dx
+
+	mov	bx,[focalty]
+	add	bx,[ytilestep]
+	mov	bp,bx						; ytile = focalty+ytilestep
+	mov	di,dx
+	shl	di,6
+	add	di,bx						; yspot = (xinttile<<6) + ytile
+
+	mov	bx,[xtile]
+	mov	dx,[WORD yintercept+2]
+	mov	ax,SCREENSEG
+	mov	es,ax						; faster than mov es,[screenseg]
+
+
+;---------------------------------------------------------------------------
+;
+; trace along this angle until we hit a wall
+;
+; CORE LOOP!
+;
+; All variables are killed when a wall is hit
+;
+; AX : scratch
+; BX : xtile
+; CX : high word of xintercept
+; DX : high word of yintercept
+; SI : xspot (yinttile<<6)+xtile (index into tilemap and spotvis)
+; DI : yspot (xinttile<<6)+ytile (index into tilemap and spotvis)
+; BP : ytile
+; ES : screenseg
+;
+;---------------------------------------------------------------------------
+
+;-----------
+;
+; check intersections with vertical walls
+;
+;-----------
+
+	EVEN
+vertcheck:
+	cmp	dx,bp
+vertop:								; 0x7e = jle (ytilestep==-1)
+	jle	horizentry					; 0x7d = jge (ytilestep==1)
+vertentry:
+	test [BYTE tilemap+si],0ffh		; tilehit = *((byte *)tilemap+xspot);
+	jnz	hitvert
+passvert:
+	mov	[BYTE spotvis+si],1			; *((byte *)spotvis+xspot) = true;
+	add	bx,[xtilestep]				; xtile+=xtilestep
+	mov	ax,[WORD ystep]
+	add	[WORD yintercept],ax		; yintercept += ystep
+	adc	dx,[WORD ystep+2]
+	mov	si,bx
+	shl	si,6
+	add	si,dx						; xspot = (xtile<<6)+yinttile
+	jmp	vertcheck
+
+	EVEN
+hitvert:
+	mov	al,[BYTE tilemap+si]		; tilehit = *((byte *)tilemap+xspot);
+	mov	[BYTE tilehit],al
+	or	al,al						; set flags
+	jns	notvertdoor
+	jmp	vertdoor
+notvertdoor:
+	mov	[WORD xintercept],0
+	mov	[WORD xintercept+2],bx
+	mov	[xtile],bx
+	mov	[WORD yintercept+2],dx
+	mov	[ytile],dx
+	call FAR HitVertWall
+	jmp nextpix
+
+
+;-----------
+;
+; check intersections with horizontal walls
+;
+;-----------
+	EVEN
+horizcheck:
+	cmp	cx,bx
+horizop:							; 0x7e = jle (xtilestep==-1)
+	jle	vertentry					; 0x7d = jge (xtilestep==1)
+horizentry:
+	test [BYTE tilemap+di],0ffh		; tilehit = *((byte *)tilemap+yspot);
+	jnz	hithoriz
+passhoriz:
+	mov	[BYTE spotvis+di],1			; *((byte *)spotvis+yspot) = true;
+	add	bp,[ytilestep]				; ytile+=ytilestep
+	mov	ax,[WORD xstep]
+	add	[WORD xintercept],ax		; xintercept += xstep
+	adc	cx,[WORD xstep+2]
+	mov	di,cx
+	shl	di,6
+	add	di,bp						; yspot = (xinttile<<6)+ytile
+	jmp	horizcheck
+
+	EVEN
+hithoriz:
+	mov	al,[BYTE tilemap+di]		; tilehit = *((byte *)tilemap+yspot);
+	mov	[BYTE tilehit],al
+	or	al,al						; set flags
+	js	horizdoor
+	mov	[WORD xintercept+2],cx
+	mov	[xtile],cx
+	mov	[WORD yintercept],0
+	mov	[WORD yintercept+2],bp
+	mov	[ytile],bp
+	call FAR HitHorizWall
+	jmp nextpix
+
+;---------------------------------------------------------------------------
+;
+; next pixel over
+;
+;---------------------------------------------------------------------------
+
+nextpix:
+	mov	ax,[pixx]
+	inc	ax
+	mov	[pixx],ax
+	cmp	ax,[viewwidth]
+	jge	done
+	jmp	pixxloop
+done:
+	pop	bp
+	pop	di
+	pop	si
+	retf
+
+;===========================================================================
+
+;=============
+;
+; hit a special horizontal wall, so find which coordinate a door would be
+; intersected at, and check to see if the door is open past that point
+;
+;=============
+horizdoor:
+	mov	[xtile],bx					; save off live register variables
+	mov	[WORD yintercept+2],dx
+
+	test al,040h      				; both high bits set == pushable wall
+	jnz	horizpushwall
+
+	mov	bx,ax
+	and	bx,7fh						; strip high bit
+	shl	bx,1                        ; index into word width door table
+
+	mov	ax,[WORD xstep]
+	mov	dx,[WORD xstep+2]
+	sar	dx,1
+	rcr ax,1						; half a step gets to door position
+
+	add	ax,[WORD xintercept]		; add half step to current intercept pos
+	adc	dx,cx						; CX hold high word of xintercept
+
+	cmp	cx,dx						; is it still in the same tile?
+	je	hithmid
+;
+; midpoint is outside tile, so it hit the side of the wall before a door
+;
+continuehoriz:
+	mov	bx,[xtile]					; reload register variables
+	mov	dx,[WORD yintercept+2]
+	jmp	passhoriz					; continue tracing
+;
+; the trace hit the door plane at pixel position AX, see if the door is
+; closed that much
+;
+hithmid:
+	cmp	ax,[doorposition+bx]		; position of leading edge of door
+	jb	continuehoriz
+;
+; draw the door
+;
+	mov	[WORD xintercept],ax		; save pixel intercept position
+	mov	[WORD xintercept+2],cx
+
+	mov	[WORD yintercept],8000h		; intercept in middle of tile
+	mov	[WORD yintercept+2],bp
+
+	call	FAR HitHorizDoor
+	jmp	nextpix
+
+;============
+;
+; hit a sliding horizontal wall
+;
+;============
+
+horizpushwall:
+	mov	ax,[WORD xstep+2]			; multiply xstep by pwallmove (0-63)
+	mul	[pwallpos]
+	mov	bx,ax
+	mov	ax,[WORD xstep]
+	mul	[pwallpos]
+	add	dx,bx
+
+	sar	dx,1						; then divide by 64 to accomplish a
+	rcr ax,1						; fixed point multiplication
+	sar	dx,1
+	rcr ax,1
+	sar	dx,1
+	rcr ax,1
+	sar	dx,1
+	rcr ax,1
+	sar	dx,1
+	rcr ax,1
+	sar	dx,1
+	rcr ax,1
+
+	add	ax,[WORD xintercept]		; add partial step to current intercept
+	adc	dx,cx						; CX hold high word of xintercept
+
+	cmp	cx,dx						; is it still in the same tile?
+	jne	continuehoriz				; no, it hit the side
+
+;
+; draw the pushable wall at the new height
+;
+	mov	[WORD xintercept],ax		; save pixel intercept position
+	mov	[WORD xintercept+2],dx
+
+	mov	[WORD yintercept+2],bp
+	mov	[WORD yintercept],0
+
+	call	FAR HitHorizPWall
+	jmp	nextpix
+
+
+
+;===========================================================================
+
+;=============
+;
+; hit a special vertical wall, so find which coordinate a door would be
+; intersected at, and check to see if the door is open past that point
+;
+;=============
+vertdoor:
+	mov	[xtile],bx					; save off live register variables
+	mov	[WORD yintercept+2],dx
+
+	test al,040h      				; both high bits set == pushable wall
+	jnz	vertpushwall
+
+	mov	bx,ax
+	and	bx,7fh						; strip high bit
+	shl	bx,1                        ; index into word width doorposition
+
+	mov	ax,[WORD ystep]
+	mov	dx,[WORD ystep+2]
+	sar	dx,1
+	rcr ax,1						; half a step gets to door position
+
+	add	ax,[WORD yintercept]		; add half step to current intercept pos
+	adc	dx,[WORD yintercept+2]
+
+	cmp	[WORD yintercept+2],dx		; is it still in the same tile?
+	je	hitvmid
+;
+; midpoint is outside tile, so it hit the side of the wall before a door
+;
+continuevert:
+	mov	bx,[xtile]					; reload register variables
+	mov	dx,[WORD yintercept+2]
+	jmp	passvert					; continue tracing
+;
+; the trace hit the door plane at pixel position AX, see if the door is
+; closed that much
+;
+hitvmid:
+	cmp	ax,[doorposition+bx]		; position of leading edge of door
+	jb	continuevert
+;
+; draw the door
+;
+	mov	[WORD yintercept],ax		; save pixel intercept position
+	mov	[WORD xintercept],8000h		; intercept in middle of tile
+	mov	ax,[xtile]
+	mov	[WORD xintercept+2],ax
+
+	call	FAR HitVertDoor
+	jmp	nextpix
+
+;============
+;
+; hit a sliding vertical wall
+;
+;============
+
+vertpushwall:
+	mov	ax,[WORD ystep+2]			; multiply ystep by pwallmove (0-63)
+	mul	[pwallpos]
+	mov	bx,ax
+	mov	ax,[WORD ystep]
+	mul	[pwallpos]
+	add	dx,bx
+
+	sar	dx,1						; then divide by 64 to accomplish a
+	rcr ax,1						; fixed point multiplication
+	sar	dx,1
+	rcr ax,1
+	sar	dx,1
+	rcr ax,1
+	sar	dx,1
+	rcr ax,1
+	sar	dx,1
+	rcr ax,1
+	sar	dx,1
+	rcr ax,1
+
+	add	ax,[WORD yintercept]		; add partial step to current intercept
+	adc	dx,[WORD yintercept+2]
+
+	cmp	[WORD yintercept+2],dx		; is it still in the same tile?
+	jne	continuevert				; no, it hit the side
+
+;
+; draw the pushable wall at the new height
+;
+	mov	[WORD yintercept],ax		; save pixel intercept position
+	mov	[WORD yintercept+2],dx
+
+	mov	bx,[xtile]
+	mov	[WORD xintercept+2],bx
+	mov	[WORD xintercept],0
+
+	call	FAR HitVertPWall
+	jmp	nextpix
+
+
+
+ENDP
+
+
+END
+
+
--- /dev/null
+++ b/WOLFSRC/WL_GAME.C
@@ -1,0 +1,1484 @@
+// WL_GAME.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+
+#ifdef MYPROFILE
+#include <TIME.H>
+#endif
+
+
+/*
+=============================================================================
+
+						 LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+
+/*
+=============================================================================
+
+						 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+boolean		ingame,fizzlein;
+unsigned	latchpics[NUMLATCHPICS];
+gametype	gamestate;
+
+long		spearx,speary;
+unsigned	spearangle;
+boolean		spearflag;
+
+//
+// ELEVATOR BACK MAPS - REMEMBER (-1)!!
+//
+int ElevatorBackTo[]={1,1,7,3,5,3};
+
+void ScanInfoPlane (void);
+void SetupGameLevel (void);
+void DrawPlayScreen (void);
+void LoadLatchMem (void);
+void GameLoop (void);
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+
+
+//===========================================================================
+//===========================================================================
+
+
+/*
+==========================
+=
+= SetSoundLoc - Given the location of an object (in terms of global
+=	coordinates, held in globalsoundx and globalsoundy), munges the values
+=	for an approximate distance from the left and right ear, and puts
+=	those values into leftchannel and rightchannel.
+=
+= JAB
+=
+==========================
+*/
+
+	fixed	globalsoundx,globalsoundy;
+	int		leftchannel,rightchannel;
+#define ATABLEMAX 15
+byte righttable[ATABLEMAX][ATABLEMAX * 2] = {
+{ 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 0, 0, 0, 0, 0, 1, 3, 5, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 4, 0, 0, 0, 0, 0, 2, 4, 6, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 4, 1, 0, 0, 0, 1, 2, 4, 6, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 6, 5, 4, 2, 1, 0, 1, 2, 3, 5, 7, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 5, 4, 3, 2, 2, 3, 3, 5, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 4, 4, 4, 4, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 6, 5, 5, 5, 6, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}
+};
+byte lefttable[ATABLEMAX][ATABLEMAX * 2] = {
+{ 8, 8, 8, 8, 8, 8, 8, 8, 5, 3, 1, 0, 0, 0, 0, 0, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 6, 4, 2, 0, 0, 0, 0, 0, 4, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 6, 4, 2, 1, 0, 0, 0, 1, 4, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 7, 5, 3, 2, 1, 0, 1, 2, 4, 5, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 5, 3, 3, 2, 2, 3, 4, 5, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 5, 4, 4, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 6, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
+{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}
+};
+
+void
+SetSoundLoc(fixed gx,fixed gy)
+{
+	fixed	xt,yt;
+	int		x,y;
+
+//
+// translate point to view centered coordinates
+//
+	gx -= viewx;
+	gy -= viewy;
+
+//
+// calculate newx
+//
+	xt = FixedByFrac(gx,viewcos);
+	yt = FixedByFrac(gy,viewsin);
+	x = (xt - yt) >> TILESHIFT;
+
+//
+// calculate newy
+//
+	xt = FixedByFrac(gx,viewsin);
+	yt = FixedByFrac(gy,viewcos);
+	y = (yt + xt) >> TILESHIFT;
+
+	if (y >= ATABLEMAX)
+		y = ATABLEMAX - 1;
+	else if (y <= -ATABLEMAX)
+		y = -ATABLEMAX;
+	if (x < 0)
+		x = -x;
+	if (x >= ATABLEMAX)
+		x = ATABLEMAX - 1;
+	leftchannel  =  lefttable[x][y + ATABLEMAX];
+	rightchannel = righttable[x][y + ATABLEMAX];
+
+#if 0
+	CenterWindow(8,1);
+	US_PrintSigned(leftchannel);
+	US_Print(",");
+	US_PrintSigned(rightchannel);
+	VW_UpdateScreen();
+#endif
+}
+
+/*
+==========================
+=
+= SetSoundLocGlobal - Sets up globalsoundx & globalsoundy and then calls
+=	UpdateSoundLoc() to transform that into relative channel volumes. Those
+=	values are then passed to the Sound Manager so that they'll be used for
+=	the next sound played (if possible).
+=
+= JAB
+=
+==========================
+*/
+void PlaySoundLocGlobal(word s,fixed gx,fixed gy)
+{
+	SetSoundLoc(gx,gy);
+	SD_PositionSound(leftchannel,rightchannel);
+	if (SD_PlaySound(s))
+	{
+		globalsoundx = gx;
+		globalsoundy = gy;
+	}
+}
+
+void UpdateSoundLoc(void)
+{
+	if (SoundPositioned)
+	{
+		SetSoundLoc(globalsoundx,globalsoundy);
+		SD_SetPosition(leftchannel,rightchannel);
+	}
+}
+
+/*
+**	JAB End
+*/
+
+
+/*
+==========================
+=
+= ClearMemory
+=
+==========================
+*/
+
+void ClearMemory (void)
+{
+	PM_UnlockMainMem();
+	SD_StopDigitized();
+	MM_SortMem ();
+}
+
+
+/*
+==========================
+=
+= ScanInfoPlane
+=
+= Spawn all actors and mark down special places
+=
+==========================
+*/
+
+void ScanInfoPlane (void)
+{
+	unsigned	x,y,i,j;
+	int			tile;
+	unsigned	far	*start;
+
+	start = mapsegs[1];
+	for (y=0;y<mapheight;y++)
+		for (x=0;x<mapwidth;x++)
+		{
+			tile = *start++;
+			if (!tile)
+				continue;
+
+			switch (tile)
+			{
+			case 19:
+			case 20:
+			case 21:
+			case 22:
+				SpawnPlayer(x,y,NORTH+tile-19);
+				break;
+
+			case 23:
+			case 24:
+			case 25:
+			case 26:
+			case 27:
+			case 28:
+			case 29:
+			case 30:
+
+			case 31:
+			case 32:
+			case 33:
+			case 34:
+			case 35:
+			case 36:
+			case 37:
+			case 38:
+
+			case 39:
+			case 40:
+			case 41:
+			case 42:
+			case 43:
+			case 44:
+			case 45:
+			case 46:
+
+			case 47:
+			case 48:
+			case 49:
+			case 50:
+			case 51:
+			case 52:
+			case 53:
+			case 54:
+
+			case 55:
+			case 56:
+			case 57:
+			case 58:
+			case 59:
+			case 60:
+			case 61:
+			case 62:
+
+			case 63:
+			case 64:
+			case 65:
+			case 66:
+			case 67:
+			case 68:
+			case 69:
+			case 70:
+			case 71:
+			case 72:
+			case 73:						// TRUCK AND SPEAR!
+			case 74:
+
+				SpawnStatic(x,y,tile-23);
+				break;
+
+//
+// P wall
+//
+			case 98:
+				if (!loadedgame)
+				  gamestate.secrettotal++;
+				break;
+
+//
+// guard
+//
+			case 180:
+			case 181:
+			case 182:
+			case 183:
+				if (gamestate.difficulty<gd_hard)
+					break;
+				tile -= 36;
+			case 144:
+			case 145:
+			case 146:
+			case 147:
+				if (gamestate.difficulty<gd_medium)
+					break;
+				tile -= 36;
+			case 108:
+			case 109:
+			case 110:
+			case 111:
+				SpawnStand(en_guard,x,y,tile-108);
+				break;
+
+
+			case 184:
+			case 185:
+			case 186:
+			case 187:
+				if (gamestate.difficulty<gd_hard)
+					break;
+				tile -= 36;
+			case 148:
+			case 149:
+			case 150:
+			case 151:
+				if (gamestate.difficulty<gd_medium)
+					break;
+				tile -= 36;
+			case 112:
+			case 113:
+			case 114:
+			case 115:
+				SpawnPatrol(en_guard,x,y,tile-112);
+				break;
+
+			case 124:
+				SpawnDeadGuard (x,y);
+				break;
+//
+// officer
+//
+			case 188:
+			case 189:
+			case 190:
+			case 191:
+				if (gamestate.difficulty<gd_hard)
+					break;
+				tile -= 36;
+			case 152:
+			case 153:
+			case 154:
+			case 155:
+				if (gamestate.difficulty<gd_medium)
+					break;
+				tile -= 36;
+			case 116:
+			case 117:
+			case 118:
+			case 119:
+				SpawnStand(en_officer,x,y,tile-116);
+				break;
+
+
+			case 192:
+			case 193:
+			case 194:
+			case 195:
+				if (gamestate.difficulty<gd_hard)
+					break;
+				tile -= 36;
+			case 156:
+			case 157:
+			case 158:
+			case 159:
+				if (gamestate.difficulty<gd_medium)
+					break;
+				tile -= 36;
+			case 120:
+			case 121:
+			case 122:
+			case 123:
+				SpawnPatrol(en_officer,x,y,tile-120);
+				break;
+
+
+//
+// ss
+//
+			case 198:
+			case 199:
+			case 200:
+			case 201:
+				if (gamestate.difficulty<gd_hard)
+					break;
+				tile -= 36;
+			case 162:
+			case 163:
+			case 164:
+			case 165:
+				if (gamestate.difficulty<gd_medium)
+					break;
+				tile -= 36;
+			case 126:
+			case 127:
+			case 128:
+			case 129:
+				SpawnStand(en_ss,x,y,tile-126);
+				break;
+
+
+			case 202:
+			case 203:
+			case 204:
+			case 205:
+				if (gamestate.difficulty<gd_hard)
+					break;
+				tile -= 36;
+			case 166:
+			case 167:
+			case 168:
+			case 169:
+				if (gamestate.difficulty<gd_medium)
+					break;
+				tile -= 36;
+			case 130:
+			case 131:
+			case 132:
+			case 133:
+				SpawnPatrol(en_ss,x,y,tile-130);
+				break;
+
+//
+// dogs
+//
+			case 206:
+			case 207:
+			case 208:
+			case 209:
+				if (gamestate.difficulty<gd_hard)
+					break;
+				tile -= 36;
+			case 170:
+			case 171:
+			case 172:
+			case 173:
+				if (gamestate.difficulty<gd_medium)
+					break;
+				tile -= 36;
+			case 134:
+			case 135:
+			case 136:
+			case 137:
+				SpawnStand(en_dog,x,y,tile-134);
+				break;
+
+
+			case 210:
+			case 211:
+			case 212:
+			case 213:
+				if (gamestate.difficulty<gd_hard)
+					break;
+				tile -= 36;
+			case 174:
+			case 175:
+			case 176:
+			case 177:
+				if (gamestate.difficulty<gd_medium)
+					break;
+				tile -= 36;
+			case 138:
+			case 139:
+			case 140:
+			case 141:
+				SpawnPatrol(en_dog,x,y,tile-138);
+				break;
+
+//
+// boss
+//
+#ifndef SPEAR
+			case 214:
+				SpawnBoss (x,y);
+				break;
+			case 197:
+				SpawnGretel (x,y);
+				break;
+			case 215:
+				SpawnGift (x,y);
+				break;
+			case 179:
+				SpawnFat (x,y);
+				break;
+			case 196:
+				SpawnSchabbs (x,y);
+				break;
+			case 160:
+				SpawnFakeHitler (x,y);
+				break;
+			case 178:
+				SpawnHitler (x,y);
+				break;
+#else
+			case 106:
+				SpawnSpectre (x,y);
+				break;
+			case 107:
+				SpawnAngel (x,y);
+				break;
+			case 125:
+				SpawnTrans (x,y);
+				break;
+			case 142:
+				SpawnUber (x,y);
+				break;
+			case 143:
+				SpawnWill (x,y);
+				break;
+			case 161:
+				SpawnDeath (x,y);
+				break;
+
+#endif
+
+//
+// mutants
+//
+			case 252:
+			case 253:
+			case 254:
+			case 255:
+				if (gamestate.difficulty<gd_hard)
+					break;
+				tile -= 18;
+			case 234:
+			case 235:
+			case 236:
+			case 237:
+				if (gamestate.difficulty<gd_medium)
+					break;
+				tile -= 18;
+			case 216:
+			case 217:
+			case 218:
+			case 219:
+				SpawnStand(en_mutant,x,y,tile-216);
+				break;
+
+			case 256:
+			case 257:
+			case 258:
+			case 259:
+				if (gamestate.difficulty<gd_hard)
+					break;
+				tile -= 18;
+			case 238:
+			case 239:
+			case 240:
+			case 241:
+				if (gamestate.difficulty<gd_medium)
+					break;
+				tile -= 18;
+			case 220:
+			case 221:
+			case 222:
+			case 223:
+				SpawnPatrol(en_mutant,x,y,tile-220);
+				break;
+
+//
+// ghosts
+//
+#ifndef SPEAR
+			case 224:
+				SpawnGhosts (en_blinky,x,y);
+				break;
+			case 225:
+				SpawnGhosts (en_clyde,x,y);
+				break;
+			case 226:
+				SpawnGhosts (en_pinky,x,y);
+				break;
+			case 227:
+				SpawnGhosts (en_inky,x,y);
+				break;
+#endif
+			}
+
+		}
+}
+
+//==========================================================================
+
+/*
+==================
+=
+= SetupGameLevel
+=
+==================
+*/
+
+void SetupGameLevel (void)
+{
+	int	x,y,i;
+	unsigned	far *map,tile,spot;
+
+
+	if (!loadedgame)
+	{
+	 gamestate.TimeCount=
+	 gamestate.secrettotal=
+	 gamestate.killtotal=
+	 gamestate.treasuretotal=
+	 gamestate.secretcount=
+	 gamestate.killcount=
+	 gamestate.treasurecount=0;
+	}
+
+	if (demoplayback || demorecord)
+		US_InitRndT (false);
+	else
+		US_InitRndT (true);
+
+//
+// load the level
+//
+	CA_CacheMap (gamestate.mapon+10*gamestate.episode);
+	mapon-=gamestate.episode*10;
+
+	mapwidth = mapheaderseg[mapon]->width;
+	mapheight = mapheaderseg[mapon]->height;
+
+	if (mapwidth != 64 || mapheight != 64)
+		Quit ("Map not 64*64!");
+
+
+//
+// copy the wall data to a data segment array
+//
+	memset (tilemap,0,sizeof(tilemap));
+	memset (actorat,0,sizeof(actorat));
+	map = mapsegs[0];
+	for (y=0;y<mapheight;y++)
+		for (x=0;x<mapwidth;x++)
+		{
+			tile = *map++;
+			if (tile<AREATILE)
+			{
+			// solid wall
+				tilemap[x][y] = tile;
+				(unsigned)actorat[x][y] = tile;
+			}
+			else
+			{
+			// area floor
+				tilemap[x][y] = 0;
+				(unsigned)actorat[x][y] = 0;
+			}
+		}
+
+//
+// spawn doors
+//
+	InitActorList ();			// start spawning things with a clean slate
+	InitDoorList ();
+	InitStaticList ();
+
+	map = mapsegs[0];
+	for (y=0;y<mapheight;y++)
+		for (x=0;x<mapwidth;x++)
+		{
+			tile = *map++;
+			if (tile >= 90 && tile <= 101)
+			{
+			// door
+				switch (tile)
+				{
+				case 90:
+				case 92:
+				case 94:
+				case 96:
+				case 98:
+				case 100:
+					SpawnDoor (x,y,1,(tile-90)/2);
+					break;
+				case 91:
+				case 93:
+				case 95:
+				case 97:
+				case 99:
+				case 101:
+					SpawnDoor (x,y,0,(tile-91)/2);
+					break;
+				}
+			}
+		}
+
+//
+// spawn actors
+//
+	ScanInfoPlane ();
+
+//
+// take out the ambush markers
+//
+	map = mapsegs[0];
+	for (y=0;y<mapheight;y++)
+		for (x=0;x<mapwidth;x++)
+		{
+			tile = *map++;
+			if (tile == AMBUSHTILE)
+			{
+				tilemap[x][y] = 0;
+				if ( (unsigned)actorat[x][y] == AMBUSHTILE)
+					actorat[x][y] = NULL;
+
+				if (*map >= AREATILE)
+					tile = *map;
+				if (*(map-1-mapwidth) >= AREATILE)
+					tile = *(map-1-mapwidth);
+				if (*(map-1+mapwidth) >= AREATILE)
+					tile = *(map-1+mapwidth);
+				if ( *(map-2) >= AREATILE)
+					tile = *(map-2);
+
+				*(map-1) = tile;
+			}
+		}
+
+
+
+//
+// have the caching manager load and purge stuff to make sure all marks
+// are in memory
+//
+	CA_LoadAllSounds ();
+
+}
+
+
+//==========================================================================
+
+
+/*
+===================
+=
+= DrawPlayBorderSides
+=
+= To fix window overwrites
+=
+===================
+*/
+
+void DrawPlayBorderSides (void)
+{
+	int	xl,yl;
+
+	xl = 160-viewwidth/2;
+	yl = (200-STATUSLINES-viewheight)/2;
+
+	VWB_Bar (0,0,xl-1,200-STATUSLINES,127);
+	VWB_Bar (xl+viewwidth+1,0,xl-2,200-STATUSLINES,127);
+
+	VWB_Vlin (yl-1,yl+viewheight,xl-1,0);
+	VWB_Vlin (yl-1,yl+viewheight,xl+viewwidth,125);
+}
+
+
+/*
+===================
+=
+= DrawAllPlayBorderSides
+=
+===================
+*/
+
+void DrawAllPlayBorderSides (void)
+{
+	unsigned	i,temp;
+
+	temp = bufferofs;
+	for (i=0;i<3;i++)
+	{
+		bufferofs = screenloc[i];
+		DrawPlayBorderSides ();
+	}
+	bufferofs = temp;
+}
+
+/*
+===================
+=
+= DrawPlayBorder
+=
+===================
+*/
+void DrawAllPlayBorder (void)
+{
+	unsigned	i,temp;
+
+	temp = bufferofs;
+	for (i=0;i<3;i++)
+	{
+		bufferofs = screenloc[i];
+		DrawPlayBorder ();
+	}
+	bufferofs = temp;
+}
+
+/*
+===================
+=
+= DrawPlayBorder
+=
+===================
+*/
+
+void DrawPlayBorder (void)
+{
+	int	xl,yl;
+
+	VWB_Bar (0,0,320,200-STATUSLINES,127);
+
+	xl = 160-viewwidth/2;
+	yl = (200-STATUSLINES-viewheight)/2;
+	VWB_Bar (xl,yl,viewwidth,viewheight,0);
+
+	VWB_Hlin (xl-1,xl+viewwidth,yl-1,0);
+	VWB_Hlin (xl-1,xl+viewwidth,yl+viewheight,125);
+	VWB_Vlin (yl-1,yl+viewheight,xl-1,0);
+	VWB_Vlin (yl-1,yl+viewheight,xl+viewwidth,125);
+	VWB_Plot (xl-1,yl+viewheight,124);
+}
+
+
+
+/*
+===================
+=
+= DrawPlayScreen
+=
+===================
+*/
+
+void DrawPlayScreen (void)
+{
+	int	i,j,p,m;
+	unsigned	temp;
+
+	VW_FadeOut ();
+
+	temp = bufferofs;
+
+	CA_CacheGrChunk (STATUSBARPIC);
+
+	for (i=0;i<3;i++)
+	{
+		bufferofs = screenloc[i];
+		DrawPlayBorder ();
+		VWB_DrawPic (0,200-STATUSLINES,STATUSBARPIC);
+	}
+
+	bufferofs = temp;
+
+	UNCACHEGRCHUNK (STATUSBARPIC);
+
+	DrawFace ();
+	DrawHealth ();
+	DrawLives ();
+	DrawLevel ();
+	DrawAmmo ();
+	DrawKeys ();
+	DrawWeapon ();
+	DrawScore ();
+}
+
+
+
+//==========================================================================
+
+/*
+==================
+=
+= StartDemoRecord
+=
+==================
+*/
+
+#define MAXDEMOSIZE	8192
+
+void StartDemoRecord (int levelnumber)
+{
+	MM_GetPtr (&demobuffer,MAXDEMOSIZE);
+	MM_SetLock (&demobuffer,true);
+	demoptr = (char far *)demobuffer;
+	lastdemoptr = demoptr+MAXDEMOSIZE;
+
+	*demoptr = levelnumber;
+	demoptr += 4;				// leave space for length
+	demorecord = true;
+}
+
+
+/*
+==================
+=
+= FinishDemoRecord
+=
+==================
+*/
+
+char	demoname[13] = "DEMO?.";
+
+void FinishDemoRecord (void)
+{
+	long	length,level;
+
+	demorecord = false;
+
+	length = demoptr - (char far *)demobuffer;
+
+	demoptr = ((char far *)demobuffer)+1;
+	*(unsigned far *)demoptr = length;
+
+	CenterWindow(24,3);
+	PrintY+=6;
+	US_Print(" Demo number (0-9):");
+	VW_UpdateScreen();
+
+	if (US_LineInput (px,py,str,NULL,true,2,0))
+	{
+		level = atoi (str);
+		if (level>=0 && level<=9)
+		{
+			demoname[4] = '0'+level;
+			CA_WriteFile (demoname,(void far *)demobuffer,length);
+		}
+	}
+
+
+	MM_FreePtr (&demobuffer);
+}
+
+//==========================================================================
+
+/*
+==================
+=
+= RecordDemo
+=
+= Fades the screen out, then starts a demo.  Exits with the screen faded
+=
+==================
+*/
+
+void RecordDemo (void)
+{
+	int level,esc;
+
+	CenterWindow(26,3);
+	PrintY+=6;
+	CA_CacheGrChunk(STARTFONT);
+	fontnumber=0;
+	US_Print("  Demo which level(1-10):");
+	VW_UpdateScreen();
+	VW_FadeIn ();
+	esc = !US_LineInput (px,py,str,NULL,true,2,0);
+	if (esc)
+		return;
+
+	level = atoi (str);
+	level--;
+
+	SETFONTCOLOR(0,15);
+	VW_FadeOut ();
+
+#ifndef SPEAR
+	NewGame (gd_hard,level/10);
+	gamestate.mapon = level%10;
+#else
+	NewGame (gd_hard,0);
+	gamestate.mapon = level;
+#endif
+
+	StartDemoRecord (level);
+
+	DrawPlayScreen ();
+	VW_FadeIn ();
+
+	startgame = false;
+	demorecord = true;
+
+	SetupGameLevel ();
+	StartMusic ();
+	PM_CheckMainMem ();
+	fizzlein = true;
+
+	PlayLoop ();
+
+	demoplayback = false;
+
+	StopMusic ();
+	VW_FadeOut ();
+	ClearMemory ();
+
+	FinishDemoRecord ();
+}
+
+//==========================================================================
+
+/*
+==================
+=
+= PlayDemo
+=
+= Fades the screen out, then starts a demo.  Exits with the screen faded
+=
+==================
+*/
+
+void PlayDemo (int demonumber)
+{
+	int length;
+
+#ifdef DEMOSEXTERN
+// debug: load chunk
+#ifndef SPEARDEMO
+	int dems[4]={T_DEMO0,T_DEMO1,T_DEMO2,T_DEMO3};
+#else
+	int dems[1]={T_DEMO0};
+#endif
+
+	CA_CacheGrChunk(dems[demonumber]);
+	demoptr = grsegs[dems[demonumber]];
+	MM_SetLock (&grsegs[dems[demonumber]],true);
+#else
+	demoname[4] = '0'+demonumber;
+	CA_LoadFile (demoname,&demobuffer);
+	MM_SetLock (&demobuffer,true);
+	demoptr = (char far *)demobuffer;
+#endif
+
+	NewGame (1,0);
+	gamestate.mapon = *demoptr++;
+	gamestate.difficulty = gd_hard;
+	length = *((unsigned far *)demoptr)++;
+	demoptr++;
+	lastdemoptr = demoptr-4+length;
+
+	VW_FadeOut ();
+
+	SETFONTCOLOR(0,15);
+	DrawPlayScreen ();
+	VW_FadeIn ();
+
+	startgame = false;
+	demoplayback = true;
+
+	SetupGameLevel ();
+	StartMusic ();
+	PM_CheckMainMem ();
+	fizzlein = true;
+
+	PlayLoop ();
+
+#ifdef DEMOSEXTERN
+	UNCACHEGRCHUNK(dems[demonumber]);
+#else
+	MM_FreePtr (&demobuffer);
+#endif
+
+	demoplayback = false;
+
+	StopMusic ();
+	VW_FadeOut ();
+	ClearMemory ();
+}
+
+//==========================================================================
+
+/*
+==================
+=
+= Died
+=
+==================
+*/
+
+#define DEATHROTATE 2
+
+void Died (void)
+{
+	float	fangle;
+	long	dx,dy;
+	int		iangle,curangle,clockwise,counter,change;
+
+	gamestate.weapon = -1;			// take away weapon
+	SD_PlaySound (PLAYERDEATHSND);
+//
+// swing around to face attacker
+//
+	dx = killerobj->x - player->x;
+	dy = player->y - killerobj->y;
+
+	fangle = atan2(dy,dx);			// returns -pi to pi
+	if (fangle<0)
+		fangle = M_PI*2+fangle;
+
+	iangle = fangle/(M_PI*2)*ANGLES;
+
+	if (player->angle > iangle)
+	{
+		counter = player->angle - iangle;
+		clockwise = ANGLES-player->angle + iangle;
+	}
+	else
+	{
+		clockwise = iangle - player->angle;
+		counter = player->angle + ANGLES-iangle;
+	}
+
+	curangle = player->angle;
+
+	if (clockwise<counter)
+	{
+	//
+	// rotate clockwise
+	//
+		if (curangle>iangle)
+			curangle -= ANGLES;
+		do
+		{
+			change = tics*DEATHROTATE;
+			if (curangle + change > iangle)
+				change = iangle-curangle;
+
+			curangle += change;
+			player->angle += change;
+			if (player->angle >= ANGLES)
+				player->angle -= ANGLES;
+
+			ThreeDRefresh ();
+			CalcTics ();
+		} while (curangle != iangle);
+	}
+	else
+	{
+	//
+	// rotate counterclockwise
+	//
+		if (curangle<iangle)
+			curangle += ANGLES;
+		do
+		{
+			change = -tics*DEATHROTATE;
+			if (curangle + change < iangle)
+				change = iangle-curangle;
+
+			curangle += change;
+			player->angle += change;
+			if (player->angle < 0)
+				player->angle += ANGLES;
+
+			ThreeDRefresh ();
+			CalcTics ();
+		} while (curangle != iangle);
+	}
+
+//
+// fade to red
+//
+	FinishPaletteShifts ();
+
+	bufferofs += screenofs;
+	VW_Bar (0,0,viewwidth,viewheight,4);
+	IN_ClearKeysDown ();
+	FizzleFade(bufferofs,displayofs+screenofs,viewwidth,viewheight,70,false);
+	bufferofs -= screenofs;
+	IN_UserInput(100);
+	SD_WaitSoundDone ();
+
+	if (tedlevel == false)	// SO'S YA DON'T GET KILLED WHILE LAUNCHING!
+	  gamestate.lives--;
+
+	if (gamestate.lives > -1)
+	{
+		gamestate.health = 100;
+		gamestate.weapon = gamestate.bestweapon
+			= gamestate.chosenweapon = wp_pistol;
+		gamestate.ammo = STARTAMMO;
+		gamestate.keys = 0;
+		gamestate.attackframe = gamestate.attackcount =
+		gamestate.weaponframe = 0;
+
+		DrawKeys ();
+		DrawWeapon ();
+		DrawAmmo ();
+		DrawHealth ();
+		DrawFace ();
+		DrawLives ();
+	}
+
+}
+
+//==========================================================================
+
+/*
+===================
+=
+= GameLoop
+=
+===================
+*/
+
+void GameLoop (void)
+{
+	int i,xl,yl,xh,yh;
+	char num[20];
+	boolean	died;
+#ifdef MYPROFILE
+	clock_t start,end;
+#endif
+
+restartgame:
+	ClearMemory ();
+	SETFONTCOLOR(0,15);
+	DrawPlayScreen ();
+	died = false;
+restart:
+	do
+	{
+		if (!loadedgame)
+		  gamestate.score = gamestate.oldscore;
+		DrawScore();
+
+		startgame = false;
+		if (loadedgame)
+			loadedgame = false;
+		else
+			SetupGameLevel ();
+
+#ifdef SPEAR
+		if (gamestate.mapon == 20)	// give them the key allways
+		{
+			gamestate.keys |= 1;
+			DrawKeys ();
+		}
+#endif
+
+		ingame = true;
+		StartMusic ();
+		PM_CheckMainMem ();
+		if (!died)
+			PreloadGraphics ();
+		else
+			died = false;
+
+		fizzlein = true;
+		DrawLevel ();
+
+startplayloop:
+		PlayLoop ();
+
+#ifdef SPEAR
+		if (spearflag)
+		{
+			SD_StopSound();
+			SD_PlaySound(GETSPEARSND);
+			if (DigiMode != sds_Off)
+			{
+				long lasttimecount = TimeCount;
+
+				while(TimeCount < lasttimecount+150)
+				//while(DigiPlaying!=false)
+					SD_Poll();
+			}
+			else
+				SD_WaitSoundDone();
+
+			ClearMemory ();
+			gamestate.oldscore = gamestate.score;
+			gamestate.mapon = 20;
+			SetupGameLevel ();
+			StartMusic ();
+			PM_CheckMainMem ();
+			player->x = spearx;
+			player->y = speary;
+			player->angle = spearangle;
+			spearflag = false;
+			Thrust (0,0);
+			goto startplayloop;
+		}
+#endif
+
+		StopMusic ();
+		ingame = false;
+
+		if (demorecord && playstate != ex_warped)
+			FinishDemoRecord ();
+
+		if (startgame || loadedgame)
+			goto restartgame;
+
+		switch (playstate)
+		{
+		case ex_completed:
+		case ex_secretlevel:
+			gamestate.keys = 0;
+			DrawKeys ();
+			VW_FadeOut ();
+
+			ClearMemory ();
+
+			LevelCompleted ();		// do the intermission
+#ifdef SPEARDEMO
+			if (gamestate.mapon == 1)
+			{
+				died = true;			// don't "get psyched!"
+
+				VW_FadeOut ();
+
+				ClearMemory ();
+
+				CheckHighScore (gamestate.score,gamestate.mapon+1);
+
+				#pragma warn -sus
+				#ifndef JAPAN
+				_fstrcpy(MainMenu[viewscores].string,STR_VS);
+				#endif
+				MainMenu[viewscores].routine = CP_ViewScores;
+				#pragma warn +sus
+
+				return;
+			}
+#endif
+
+#ifdef JAPDEMO
+			if (gamestate.mapon == 3)
+			{
+				died = true;			// don't "get psyched!"
+
+				VW_FadeOut ();
+
+				ClearMemory ();
+
+				CheckHighScore (gamestate.score,gamestate.mapon+1);
+
+				#pragma warn -sus
+				#ifndef JAPAN
+				_fstrcpy(MainMenu[viewscores].string,STR_VS);
+				#endif
+				MainMenu[viewscores].routine = CP_ViewScores;
+				#pragma warn +sus
+
+				return;
+			}
+#endif
+
+			gamestate.oldscore = gamestate.score;
+
+#ifndef SPEAR
+			//
+			// COMING BACK FROM SECRET LEVEL
+			//
+			if (gamestate.mapon == 9)
+				gamestate.mapon = ElevatorBackTo[gamestate.episode];	// back from secret
+			else
+			//
+			// GOING TO SECRET LEVEL
+			//
+			if (playstate == ex_secretlevel)
+				gamestate.mapon = 9;
+#else
+
+#define FROMSECRET1		3
+#define FROMSECRET2		11
+
+			//
+			// GOING TO SECRET LEVEL
+			//
+			if (playstate == ex_secretlevel)
+				switch(gamestate.mapon)
+				{
+				 case FROMSECRET1: gamestate.mapon = 18; break;
+				 case FROMSECRET2: gamestate.mapon = 19; break;
+				}
+			else
+			//
+			// COMING BACK FROM SECRET LEVEL
+			//
+			if (gamestate.mapon == 18 || gamestate.mapon == 19)
+				switch(gamestate.mapon)
+				{
+				 case 18: gamestate.mapon = FROMSECRET1+1; break;
+				 case 19: gamestate.mapon = FROMSECRET2+1; break;
+				}
+#endif
+			else
+			//
+			// GOING TO NEXT LEVEL
+			//
+				gamestate.mapon++;
+
+
+			break;
+
+		case ex_died:
+			Died ();
+			died = true;			// don't "get psyched!"
+
+			if (gamestate.lives > -1)
+				break;				// more lives left
+
+			VW_FadeOut ();
+
+			ClearMemory ();
+
+			CheckHighScore (gamestate.score,gamestate.mapon+1);
+
+			#pragma warn -sus
+			#ifndef JAPAN
+			_fstrcpy(MainMenu[viewscores].string,STR_VS);
+			#endif
+			MainMenu[viewscores].routine = CP_ViewScores;
+			#pragma warn +sus
+
+			return;
+
+		case ex_victorious:
+
+#ifndef SPEAR
+			VW_FadeOut ();
+#else
+			VL_FadeOut (0,255,0,17,17,300);
+#endif
+			ClearMemory ();
+
+			Victory ();
+
+			ClearMemory ();
+
+			CheckHighScore (gamestate.score,gamestate.mapon+1);
+
+			#pragma warn -sus
+			#ifndef JAPAN
+			_fstrcpy(MainMenu[viewscores].string,STR_VS);
+			#endif
+			MainMenu[viewscores].routine = CP_ViewScores;
+			#pragma warn +sus
+
+			return;
+
+		default:
+			ClearMemory ();
+			break;
+		}
+
+	} while (1);
+
+}
+
--- /dev/null
+++ b/WOLFSRC/WL_INTER.C
@@ -1,0 +1,1718 @@
+// WL_INTER.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+
+
+//==========================================================================
+
+/*
+==================
+=
+= CLearSplitVWB
+=
+==================
+*/
+
+void ClearSplitVWB (void)
+{
+	memset (update,0,sizeof(update));
+	WindowX = 0;
+	WindowY = 0;
+	WindowW = 320;
+	WindowH = 160;
+}
+
+
+//==========================================================================
+
+#ifdef SPEAR
+#ifndef SPEARDEMO
+////////////////////////////////////////////////////////
+//
+// End of Spear of Destiny
+//
+////////////////////////////////////////////////////////
+
+void EndScreen (int palette, int screen)
+{
+	CA_CacheScreen (screen);
+	VW_UpdateScreen ();
+	CA_CacheGrChunk (palette);
+	VL_FadeIn(0,255,grsegs[palette],30);
+	UNCACHEGRCHUNK (palette);
+	IN_ClearKeysDown ();
+	IN_Ack ();
+	VW_FadeOut ();
+}
+
+
+void EndSpear(void)
+{
+	EndScreen (END1PALETTE, ENDSCREEN11PIC);
+
+	CA_CacheScreen (ENDSCREEN3PIC);
+	VW_UpdateScreen ();
+	CA_CacheGrChunk (END3PALETTE);
+	VL_FadeIn(0,255,grsegs[END3PALETTE],30);
+	UNCACHEGRCHUNK (END3PALETTE);
+	fontnumber = 0;
+	fontcolor = 0xd0;
+	WindowX = 0;
+	WindowW = 320;
+	PrintX = 0;
+	PrintY = 180;
+	US_CPrint (STR_ENDGAME1"\n");
+	US_CPrint (STR_ENDGAME2);
+	VW_UpdateScreen ();
+	IN_StartAck ();
+	TimeCount = 0;
+	while (!IN_CheckAck () && TimeCount < 700);
+
+	PrintX = 0;
+	PrintY = 180;
+	VWB_Bar(0,180,320,20,0);
+	US_CPrint (STR_ENDGAME3"\n");
+	US_CPrint (STR_ENDGAME4);
+	VW_UpdateScreen ();
+	IN_StartAck ();
+	TimeCount = 0;
+	while (!IN_CheckAck () && TimeCount < 700);
+
+	VW_FadeOut ();
+
+	EndScreen (END4PALETTE, ENDSCREEN4PIC);
+	EndScreen (END5PALETTE, ENDSCREEN5PIC);
+	EndScreen (END6PALETTE, ENDSCREEN6PIC);
+	EndScreen (END7PALETTE, ENDSCREEN7PIC);
+	EndScreen (END8PALETTE, ENDSCREEN8PIC);
+	EndScreen (END9PALETTE, ENDSCREEN9PIC);
+
+	EndScreen (END2PALETTE, ENDSCREEN12PIC);
+
+	MainMenu[savegame].active = 0;
+}
+#endif
+#endif
+
+//==========================================================================
+
+/*
+==================
+=
+= Victory
+=
+==================
+*/
+
+void Victory (void)
+{
+#ifndef SPEARDEMO
+	long	sec;
+	int i,min,kr,sr,tr,x;
+	char tempstr[8];
+
+#define RATIOX	6
+#define RATIOY	14
+#define TIMEX	14
+#define TIMEY	8
+
+
+#ifdef SPEAR
+	StartCPMusic (XTHEEND_MUS);
+
+	CA_CacheGrChunk(BJCOLLAPSE1PIC);
+	CA_CacheGrChunk(BJCOLLAPSE2PIC);
+	CA_CacheGrChunk(BJCOLLAPSE3PIC);
+	CA_CacheGrChunk(BJCOLLAPSE4PIC);
+
+	VWB_Bar(0,0,320,200,VIEWCOLOR);
+	VWB_DrawPic (124,44,BJCOLLAPSE1PIC);
+	VW_UpdateScreen ();
+	VW_FadeIn ();
+	VW_WaitVBL(2*70);
+	VWB_DrawPic (124,44,BJCOLLAPSE2PIC);
+	VW_UpdateScreen ();
+	VW_WaitVBL(105);
+	VWB_DrawPic (124,44,BJCOLLAPSE3PIC);
+	VW_UpdateScreen ();
+	VW_WaitVBL(105);
+	VWB_DrawPic (124,44,BJCOLLAPSE4PIC);
+	VW_UpdateScreen ();
+	VW_WaitVBL(3*70);
+
+	UNCACHEGRCHUNK(BJCOLLAPSE1PIC);
+	UNCACHEGRCHUNK(BJCOLLAPSE2PIC);
+	UNCACHEGRCHUNK(BJCOLLAPSE3PIC);
+	UNCACHEGRCHUNK(BJCOLLAPSE4PIC);
+	VL_FadeOut (0,255,0,17,17,5);
+#endif
+
+	StartCPMusic (URAHERO_MUS);
+	ClearSplitVWB ();
+	CacheLump(LEVELEND_LUMP_START,LEVELEND_LUMP_END);
+	CA_CacheGrChunk(STARTFONT);
+
+#ifndef SPEAR
+	CA_CacheGrChunk(C_TIMECODEPIC);
+#endif
+
+
+	VWB_Bar (0,0,320,200-STATUSLINES,127);
+#ifdef JAPAN
+#ifndef JAPDEMO
+	CA_CacheGrChunk(C_ENDRATIOSPIC);
+	VWB_DrawPic(0,0,C_ENDRATIOSPIC);
+	UNCACHEGRCHUNK(C_ENDRATIOSPIC);
+#endif
+#else
+	Write(18,2,STR_YOUWIN);
+
+	Write(TIMEX,TIMEY-2,STR_TOTALTIME);
+
+	Write(12,RATIOY-2,"averages");
+
+	#ifdef SPANISH
+	Write(RATIOX+2,  RATIOY,      STR_RATKILL);
+	Write(RATIOX+2,  RATIOY+2,  STR_RATSECRET);
+	Write(RATIOX+2,  RATIOY+4,STR_RATTREASURE);
+	#else
+	Write(RATIOX+8,RATIOY,      STR_RATKILL);
+	Write(RATIOX+4,RATIOY+2,  STR_RATSECRET);
+	Write(RATIOX,  RATIOY+4,STR_RATTREASURE);
+	#endif
+
+#endif
+
+#ifndef JAPDEMO
+	VWB_DrawPic (8,4,L_BJWINSPIC);
+#endif
+
+
+#ifndef SPEAR
+	for (kr = sr = tr = sec = i = 0;i < 8;i++)
+#else
+	for (kr = sr = tr = sec = i = 0;i < 20;i++)
+#endif
+	{
+		sec += LevelRatios[i].time;
+		kr += LevelRatios[i].kill;
+		sr += LevelRatios[i].secret;
+		tr += LevelRatios[i].treasure;
+	}
+
+#ifndef SPEAR
+	kr /= 8;
+	sr /= 8;
+	tr /= 8;
+#else
+	kr /= 14;
+	sr /= 14;
+	tr /= 14;
+#endif
+
+	min = sec/60;
+	sec %= 60;
+
+	if (min > 99)
+		min = sec = 99;
+
+	i = TIMEX*8+1;
+	VWB_DrawPic(i,TIMEY*8,L_NUM0PIC+(min/10));
+	i += 2*8;
+	VWB_DrawPic(i,TIMEY*8,L_NUM0PIC+(min%10));
+	i += 2*8;
+	Write(i/8,TIMEY,":");
+	i += 1*8;
+	VWB_DrawPic(i,TIMEY*8,L_NUM0PIC+(sec/10));
+	i += 2*8;
+	VWB_DrawPic(i,TIMEY*8,L_NUM0PIC+(sec%10));
+	VW_UpdateScreen ();
+
+	itoa(kr,tempstr,10);
+	x=RATIOX+24-strlen(tempstr)*2;
+	Write(x,RATIOY,tempstr);
+
+	itoa(sr,tempstr,10);
+	x=RATIOX+24-strlen(tempstr)*2;
+	Write(x,RATIOY+2,tempstr);
+
+	itoa(tr,tempstr,10);
+	x=RATIOX+24-strlen(tempstr)*2;
+	Write(x,RATIOY+4,tempstr);
+
+
+#ifndef SPANISH
+#ifndef UPLOAD
+#ifndef SPEAR
+	//
+	// TOTAL TIME VERIFICATION CODE
+	//
+	if (gamestate.difficulty>=gd_medium)
+	{
+		VWB_DrawPic (30*8,TIMEY*8,C_TIMECODEPIC);
+		fontnumber = 0;
+		fontcolor = READHCOLOR;
+		PrintX = 30*8-3;
+		PrintY = TIMEY*8+8;
+		PrintX+=4;
+		tempstr[0] = (((min/10)^(min%10))^0xa)+'A';
+		tempstr[1] = (((sec/10)^(sec%10))^0xa)+'A';
+		tempstr[2] = (tempstr[0]^tempstr[1])+'A';
+		tempstr[3] = 0;
+		US_Print(tempstr);
+	}
+#endif
+#endif
+#endif
+
+
+	fontnumber = 1;
+
+	VW_UpdateScreen ();
+	VW_FadeIn ();
+
+	IN_Ack();
+
+	#ifndef SPEAR
+	if (Keyboard[sc_P] && MS_CheckParm("goobers"))
+		PicturePause();
+	#endif
+
+	VW_FadeOut ();
+
+#ifndef SPEAR
+	UNCACHEGRCHUNK(C_TIMECODEPIC);
+#endif
+	UnCacheLump(LEVELEND_LUMP_START,LEVELEND_LUMP_END);
+
+#ifndef SPEAR
+	EndText();
+#else
+	EndSpear();
+#endif
+
+#endif // SPEARDEMO
+}
+
+
+//==========================================================================
+
+#ifndef JAPAN
+/*
+==================
+=
+= PG13
+=
+==================
+*/
+
+void PG13 (void)
+{
+	VW_FadeOut();
+	VWB_Bar(0,0,320,200,0x82);			// background
+
+	CA_CacheGrChunk (PG13PIC);
+	VWB_DrawPic (216,110,PG13PIC);
+	VW_UpdateScreen ();
+
+	UNCACHEGRCHUNK (PG13PIC);
+
+	VW_FadeIn();
+	IN_UserInput(TickBase*7);
+
+	VW_FadeOut ();
+}
+#endif
+
+
+//==========================================================================
+
+void Write(int x,int y,char *string)
+{
+ int alpha[]={L_NUM0PIC,L_NUM1PIC,L_NUM2PIC,L_NUM3PIC,L_NUM4PIC,L_NUM5PIC,
+	L_NUM6PIC,L_NUM7PIC,L_NUM8PIC,L_NUM9PIC,L_COLONPIC,0,0,0,0,0,0,L_APIC,L_BPIC,
+	L_CPIC,L_DPIC,L_EPIC,L_FPIC,L_GPIC,L_HPIC,L_IPIC,L_JPIC,L_KPIC,
+	L_LPIC,L_MPIC,L_NPIC,L_OPIC,L_PPIC,L_QPIC,L_RPIC,L_SPIC,L_TPIC,
+	L_UPIC,L_VPIC,L_WPIC,L_XPIC,L_YPIC,L_ZPIC};
+
+ int i,ox,nx,ny;
+ char ch;
+
+
+ ox=nx=x*8;
+ ny=y*8;
+ for (i=0;i<strlen(string);i++)
+   if (string[i]=='\n')
+   {
+	nx=ox;
+	ny+=16;
+   }
+   else
+   {
+	ch=string[i];
+	if (ch>='a')
+	  ch-=('a'-'A');
+	ch-='0';
+
+	switch(string[i])
+	{
+	 case '!':
+	   VWB_DrawPic(nx,ny,L_EXPOINTPIC);
+	   nx+=8;
+	   continue;
+
+	 case '\'':
+	   VWB_DrawPic(nx,ny,L_APOSTROPHEPIC);
+	   nx+=8;
+	   continue;
+
+	 case ' ': break;
+	 case 0x3a:	// ':'
+
+	   VWB_DrawPic(nx,ny,L_COLONPIC);
+	   nx+=8;
+	   continue;
+
+	 case '%':
+	   VWB_DrawPic(nx,ny,L_PERCENTPIC);
+	   break;
+
+	 default:
+	   VWB_DrawPic(nx,ny,alpha[ch]);
+	}
+	nx+=16;
+   }
+}
+
+
+//
+// Breathe Mr. BJ!!!
+//
+void BJ_Breathe(void)
+{
+	static int which=0,max=10;
+	int pics[2]={L_GUYPIC,L_GUY2PIC};
+
+
+	if (TimeCount>max)
+	{
+		which^=1;
+		VWB_DrawPic(0,16,pics[which]);
+		VW_UpdateScreen();
+		TimeCount=0;
+		max=35;
+	}
+}
+
+
+
+/*
+==================
+=
+= LevelCompleted
+=
+= Entered with the screen faded out
+= Still in split screen mode with the status bar
+=
+= Exit with the screen faded out
+=
+==================
+*/
+
+#ifndef SPEAR
+LRstruct LevelRatios[8];
+#else
+LRstruct LevelRatios[20];
+#endif
+
+void LevelCompleted (void)
+{
+	#define VBLWAIT	30
+	#define PAR_AMOUNT	500
+	#define PERCENT100AMT	10000
+	typedef struct {
+			float time;
+			char timestr[6];
+			} times;
+
+	int	x,i,min,sec,ratio,kr,sr,tr;
+	unsigned	temp;
+	char tempstr[10];
+	long bonus,timeleft=0;
+	times parTimes[]=
+	{
+#ifndef SPEAR
+	 //
+	 // Episode One Par Times
+	 //
+	 {1.5,	"01:30"},
+	 {2,	"02:00"},
+	 {2,	"02:00"},
+	 {3.5,	"03:30"},
+	 {3,	"03:00"},
+	 {3,	"03:00"},
+	 {2.5,	"02:30"},
+	 {2.5,	"02:30"},
+	 {0,	"??:??"},	// Boss level
+	 {0,	"??:??"},	// Secret level
+
+	 //
+	 // Episode Two Par Times
+	 //
+	 {1.5,	"01:30"},
+	 {3.5,	"03:30"},
+	 {3,	"03:00"},
+	 {2,	"02:00"},
+	 {4,	"04:00"},
+	 {6,	"06:00"},
+	 {1,	"01:00"},
+	 {3,	"03:00"},
+	 {0,	"??:??"},
+	 {0,	"??:??"},
+
+	 //
+	 // Episode Three Par Times
+	 //
+	 {1.5,	"01:30"},
+	 {1.5,	"01:30"},
+	 {2.5,	"02:30"},
+	 {2.5,	"02:30"},
+	 {3.5,	"03:30"},
+	 {2.5,	"02:30"},
+	 {2,	"02:00"},
+	 {6,	"06:00"},
+	 {0,	"??:??"},
+	 {0,	"??:??"},
+
+	 //
+	 // Episode Four Par Times
+	 //
+	 {2,	"02:00"},
+	 {2,	"02:00"},
+	 {1.5,	"01:30"},
+	 {1,	"01:00"},
+	 {4.5,	"04:30"},
+	 {3.5,	"03:30"},
+	 {2,	"02:00"},
+	 {4.5,	"04:30"},
+	 {0,	"??:??"},
+	 {0,	"??:??"},
+
+	 //
+	 // Episode Five Par Times
+	 //
+	 {2.5,	"02:30"},
+	 {1.5,	"01:30"},
+	 {2.5,	"02:30"},
+	 {2.5,	"02:30"},
+	 {4,	"04:00"},
+	 {3,	"03:00"},
+	 {4.5,	"04:30"},
+	 {3.5,	"03:30"},
+	 {0,	"??:??"},
+	 {0,	"??:??"},
+
+	 //
+	 // Episode Six Par Times
+	 //
+	 {6.5,	"06:30"},
+	 {4,	"04:00"},
+	 {4.5,	"04:30"},
+	 {6,	"06:00"},
+	 {5,	"05:00"},
+	 {5.5,	"05:30"},
+	 {5.5,	"05:30"},
+	 {8.5,	"08:30"},
+	 {0,	"??:??"},
+	 {0,	"??:??"}
+#else
+	 //
+	 // SPEAR OF DESTINY TIMES
+	 //
+	 {1.5,	"01:30"},
+	 {3.5,	"03:30"},
+	 {2.75,	"02:45"},
+	 {3.5,	"03:30"},
+	 {0,	"??:??"},	// Boss 1
+	 {4.5,	"04:30"},
+	 {3.25,	"03:15"},
+	 {2.75,	"02:45"},
+	 {4.75,	"04:45"},
+	 {0,	"??:??"},	// Boss 2
+	 {6.5,	"06:30"},
+	 {4.5,	"04:30"},
+	 {2.75,	"02:45"},
+	 {4.5,	"04:30"},
+	 {6,	"06:00"},
+	 {0,	"??:??"},	// Boss 3
+	 {6,	"06:00"},
+	 {0,	"??:??"},	// Boss 4
+	 {0,	"??:??"},	// Secret level 1
+	 {0,	"??:??"},	// Secret level 2
+#endif
+	};
+
+
+
+	CacheLump(LEVELEND_LUMP_START,LEVELEND_LUMP_END);
+	ClearSplitVWB ();			// set up for double buffering in split screen
+	VWB_Bar (0,0,320,200-STATUSLINES,127);
+	StartCPMusic(ENDLEVEL_MUS);
+
+//
+// do the intermission
+//
+	IN_ClearKeysDown();
+	IN_StartAck();
+
+#ifdef JAPAN
+	CA_CacheGrChunk(C_INTERMISSIONPIC);
+	VWB_DrawPic(0,0,C_INTERMISSIONPIC);
+	UNCACHEGRCHUNK(C_INTERMISSIONPIC);
+#endif
+	VWB_DrawPic(0,16,L_GUYPIC);
+
+#ifndef SPEAR
+	if (mapon<8)
+#else
+	if (mapon != 4 &&
+		mapon != 9 &&
+		mapon != 15 &&
+		mapon < 17)
+#endif
+	{
+#ifndef JAPAN
+	 #ifdef SPANISH
+	 Write(14,2,"piso\ncompletado");
+	 #else
+	 Write(14,2,"floor\ncompleted");
+	 #endif
+
+	 Write(14,7,STR_BONUS"     0");
+	 Write(16,10,STR_TIME);
+	 Write(16,12,STR_PAR);
+
+	 #ifdef SPANISH
+	 Write(11,14,    STR_RAT2KILL);
+	 Write(11,16,  STR_RAT2SECRET);
+	 Write(11,18,STR_RAT2TREASURE);
+	 #else
+	 Write(9,14,    STR_RAT2KILL);
+	 Write(5,16,  STR_RAT2SECRET);
+	 Write(1,18,STR_RAT2TREASURE);
+	 #endif
+
+	 Write(26,2,itoa(gamestate.mapon+1,tempstr,10));
+#endif
+
+	 #ifdef SPANISH
+	 Write(30,12,parTimes[gamestate.episode*10+mapon].timestr);
+	 #else
+	 Write(26,12,parTimes[gamestate.episode*10+mapon].timestr);
+	 #endif
+
+	 //
+	 // PRINT TIME
+	 //
+	 sec=gamestate.TimeCount/70;
+
+	 if (sec > 99*60)		// 99 minutes max
+	   sec = 99*60;
+
+	 if (gamestate.TimeCount<parTimes[gamestate.episode*10+mapon].time*4200)
+		timeleft=(parTimes[gamestate.episode*10+mapon].time*4200)/70-sec;
+
+	 min=sec/60;
+	 sec%=60;
+
+	 #ifdef SPANISH
+	 i=30*8;
+	 #else
+	 i=26*8;
+	 #endif
+	 VWB_DrawPic(i,10*8,L_NUM0PIC+(min/10));
+	 i+=2*8;
+	 VWB_DrawPic(i,10*8,L_NUM0PIC+(min%10));
+	 i+=2*8;
+	 Write(i/8,10,":");
+	 i+=1*8;
+	 VWB_DrawPic(i,10*8,L_NUM0PIC+(sec/10));
+	 i+=2*8;
+	 VWB_DrawPic(i,10*8,L_NUM0PIC+(sec%10));
+
+	 VW_UpdateScreen ();
+	 VW_FadeIn ();
+
+
+	 //
+	 // FIGURE RATIOS OUT BEFOREHAND
+	 //
+	 kr = sr = tr = 0;
+	 if (gamestate.killtotal)
+		kr=(gamestate.killcount*100)/gamestate.killtotal;
+	 if (gamestate.secrettotal)
+		sr=(gamestate.secretcount*100)/gamestate.secrettotal;
+	 if (gamestate.treasuretotal)
+		tr=(gamestate.treasurecount*100)/gamestate.treasuretotal;
+
+
+	 //
+	 // PRINT TIME BONUS
+	 //
+	 bonus=timeleft*PAR_AMOUNT;
+	 if (bonus)
+	 {
+	  for (i=0;i<=timeleft;i++)
+	  {
+	   ltoa((long)i*PAR_AMOUNT,tempstr,10);
+	   x=36-strlen(tempstr)*2;
+	   Write(x,7,tempstr);
+	   if (!(i%(PAR_AMOUNT/10)))
+		 SD_PlaySound(ENDBONUS1SND);
+	   VW_UpdateScreen();
+	   while(SD_SoundPlaying())
+		 BJ_Breathe();
+	   if (IN_CheckAck())
+		 goto done;
+	  }
+
+	  VW_UpdateScreen();
+	  SD_PlaySound(ENDBONUS2SND);
+	  while(SD_SoundPlaying())
+		BJ_Breathe();
+	 }
+
+
+	 #ifdef SPANISH
+	 #define RATIOXX		33
+	 #else
+	 #define RATIOXX		37
+	 #endif
+	 //
+	 // KILL RATIO
+	 //
+	 ratio=kr;
+	 for (i=0;i<=ratio;i++)
+	 {
+	  itoa(i,tempstr,10);
+	  x=RATIOXX-strlen(tempstr)*2;
+	  Write(x,14,tempstr);
+	  if (!(i%10))
+		SD_PlaySound(ENDBONUS1SND);
+	  VW_UpdateScreen ();
+	  while(SD_SoundPlaying())
+		BJ_Breathe();
+
+	  if (IN_CheckAck())
+		goto done;
+	 }
+	 if (ratio==100)
+	 {
+	   VW_WaitVBL(VBLWAIT);
+	   SD_StopSound();
+	   bonus+=PERCENT100AMT;
+	   ltoa(bonus,tempstr,10);
+	   x=(RATIOXX-1)-strlen(tempstr)*2;
+	   Write(x,7,tempstr);
+	   VW_UpdateScreen();
+	   SD_PlaySound(PERCENT100SND);
+	 }
+	 else
+	 if (!ratio)
+	 {
+	   VW_WaitVBL(VBLWAIT);
+	   SD_StopSound();
+	   SD_PlaySound(NOBONUSSND);
+	 }
+	 else
+	 SD_PlaySound(ENDBONUS2SND);
+
+	 VW_UpdateScreen();
+	 while(SD_SoundPlaying())
+	   BJ_Breathe();
+
+
+	 //
+	 // SECRET RATIO
+	 //
+	 ratio=sr;
+	 for (i=0;i<=ratio;i++)
+	 {
+	  itoa(i,tempstr,10);
+	  x=RATIOXX-strlen(tempstr)*2;
+	  Write(x,16,tempstr);
+	  if (!(i%10))
+		SD_PlaySound(ENDBONUS1SND);
+	  VW_UpdateScreen ();
+	  while(SD_SoundPlaying())
+		BJ_Breathe();
+	  BJ_Breathe();
+
+	  if (IN_CheckAck())
+		goto done;
+	 }
+	 if (ratio==100)
+	 {
+	   VW_WaitVBL(VBLWAIT);
+	   SD_StopSound();
+	   bonus+=PERCENT100AMT;
+	   ltoa(bonus,tempstr,10);
+	   x=(RATIOXX-1)-strlen(tempstr)*2;
+	   Write(x,7,tempstr);
+	   VW_UpdateScreen();
+	   SD_PlaySound(PERCENT100SND);
+	 }
+	 else
+	 if (!ratio)
+	 {
+	   VW_WaitVBL(VBLWAIT);
+	   SD_StopSound();
+	   SD_PlaySound(NOBONUSSND);
+	 }
+	 else
+	   SD_PlaySound(ENDBONUS2SND);
+	 VW_UpdateScreen();
+	 while(SD_SoundPlaying())
+	   BJ_Breathe();
+
+
+	 //
+	 // TREASURE RATIO
+	 //
+	 ratio=tr;
+	 for (i=0;i<=ratio;i++)
+	 {
+	  itoa(i,tempstr,10);
+	  x=RATIOXX-strlen(tempstr)*2;
+	  Write(x,18,tempstr);
+	  if (!(i%10))
+		SD_PlaySound(ENDBONUS1SND);
+	  VW_UpdateScreen ();
+	  while(SD_SoundPlaying())
+		BJ_Breathe();
+	  if (IN_CheckAck())
+		goto done;
+	 }
+	 if (ratio==100)
+	 {
+	   VW_WaitVBL(VBLWAIT);
+	   SD_StopSound();
+	   bonus+=PERCENT100AMT;
+	   ltoa(bonus,tempstr,10);
+	   x=(RATIOXX-1)-strlen(tempstr)*2;
+	   Write(x,7,tempstr);
+	   VW_UpdateScreen();
+	   SD_PlaySound(PERCENT100SND);
+	 }
+	 else
+	 if (!ratio)
+	 {
+	   VW_WaitVBL(VBLWAIT);
+	   SD_StopSound();
+	   SD_PlaySound(NOBONUSSND);
+	 }
+	 else
+	 SD_PlaySound(ENDBONUS2SND);
+	 VW_UpdateScreen();
+	 while(SD_SoundPlaying())
+	   BJ_Breathe();
+
+
+	 //
+	 // JUMP STRAIGHT HERE IF KEY PRESSED
+	 //
+	 done:
+
+	 itoa(kr,tempstr,10);
+	 x=RATIOXX-strlen(tempstr)*2;
+	 Write(x,14,tempstr);
+
+	 itoa(sr,tempstr,10);
+	 x=RATIOXX-strlen(tempstr)*2;
+	 Write(x,16,tempstr);
+
+	 itoa(tr,tempstr,10);
+	 x=RATIOXX-strlen(tempstr)*2;
+	 Write(x,18,tempstr);
+
+	 bonus=(long)timeleft*PAR_AMOUNT+
+		   (PERCENT100AMT*(kr==100))+
+		   (PERCENT100AMT*(sr==100))+
+		   (PERCENT100AMT*(tr==100));
+
+	 GivePoints(bonus);
+	 ltoa(bonus,tempstr,10);
+	 x=36-strlen(tempstr)*2;
+	 Write(x,7,tempstr);
+
+	 //
+	 // SAVE RATIO INFORMATION FOR ENDGAME
+	 //
+	 LevelRatios[mapon].kill=kr;
+	 LevelRatios[mapon].secret=sr;
+	 LevelRatios[mapon].treasure=tr;
+	 LevelRatios[mapon].time=min*60+sec;
+	}
+	else
+	{
+#ifdef SPEAR
+#ifndef SPEARDEMO
+	  switch(mapon)
+	  {
+	   case 4: Write(14,4," trans\n"
+						  " grosse\n"
+						  STR_DEFEATED); break;
+	   case 9: Write(14,4,"barnacle\n"
+						  "wilhelm\n"
+						  STR_DEFEATED); break;
+	   case 15: Write(14,4,"ubermutant\n"
+						   STR_DEFEATED); break;
+	   case 17: Write(14,4," death\n"
+						   " knight\n"
+						   STR_DEFEATED); break;
+	   case 18: Write(13,4,"secret tunnel\n"
+						   "    area\n"
+						   "  completed!"); break;
+	   case 19: Write(13,4,"secret castle\n"
+						   "    area\n"
+						   "  completed!"); break;
+	  }
+#endif
+#else
+	  Write(14,4,"secret floor\n completed!");
+#endif
+
+	  Write(10,16,"15000 bonus!");
+
+	  VW_UpdateScreen();
+	  VW_FadeIn();
+
+	  GivePoints(15000);
+	}
+
+
+	DrawScore();
+	VW_UpdateScreen();
+
+	TimeCount=0;
+	IN_StartAck();
+	while(!IN_CheckAck())
+	  BJ_Breathe();
+
+//
+// done
+//
+#ifdef SPEARDEMO
+	if (gamestate.mapon == 1)
+	{
+		SD_PlaySound (BONUS1UPSND);
+
+		CA_CacheGrChunk (STARTFONT+1);
+		Message ("This concludes your demo\n"
+				 "of Spear of Destiny! Now,\n"
+				 "go to your local software\n"
+				 "store and buy it!");
+		UNCACHEGRCHUNK (STARTFONT+1);
+
+		IN_ClearKeysDown();
+		IN_Ack();
+	}
+#endif
+
+#ifdef JAPDEMO
+	if (gamestate.mapon == 3)
+	{
+		SD_PlaySound (BONUS1UPSND);
+
+		CA_CacheGrChunk (STARTFONT+1);
+		Message ("This concludes your demo\n"
+				 "of Wolfenstein 3-D! Now,\n"
+				 "go to your local software\n"
+				 "store and buy it!");
+		UNCACHEGRCHUNK (STARTFONT+1);
+
+		IN_ClearKeysDown();
+		IN_Ack();
+	}
+#endif
+
+	#ifndef SPEAR
+	if (Keyboard[sc_P] && MS_CheckParm("goobers"))
+		PicturePause();
+	#endif
+
+	VW_FadeOut ();
+	temp = bufferofs;
+	for (i=0;i<3;i++)
+	{
+		bufferofs = screenloc[i];
+		DrawPlayBorder ();
+	}
+	bufferofs = temp;
+
+	UnCacheLump(LEVELEND_LUMP_START,LEVELEND_LUMP_END);
+}
+
+
+
+//==========================================================================
+
+
+/*
+=================
+=
+= PreloadGraphics
+=
+= Fill the cache up
+=
+=================
+*/
+
+boolean PreloadUpdate(unsigned current, unsigned total)
+{
+	unsigned w = WindowW - 10;
+
+
+	VWB_Bar(WindowX + 5,WindowY + WindowH - 3,w,2,BLACK);
+	w = ((long)w * current) / total;
+	if (w)
+	{
+	 VWB_Bar(WindowX + 5,WindowY + WindowH - 3,w,2,0x37); //SECONDCOLOR);
+	 VWB_Bar(WindowX + 5,WindowY + WindowH - 3,w-1,1,0x32);
+
+	}
+	VW_UpdateScreen();
+//	if (LastScan == sc_Escape)
+//	{
+//		IN_ClearKeysDown();
+//		return(true);
+//	}
+//	else
+		return(false);
+}
+
+void PreloadGraphics(void)
+{
+	DrawLevel ();
+	ClearSplitVWB ();			// set up for double buffering in split screen
+
+	VWB_Bar (0,0,320,200-STATUSLINES,127);
+
+	LatchDrawPic (20-14,80-3*8,GETPSYCHEDPIC);
+
+	WindowX = 160-14*8;
+	WindowY = 80-3*8;
+	WindowW = 28*8;
+	WindowH = 48;
+	VW_UpdateScreen();
+	VW_FadeIn ();
+
+	PM_Preload (PreloadUpdate);
+	IN_UserInput (70);
+	VW_FadeOut ();
+
+	DrawPlayBorder ();
+	VW_UpdateScreen ();
+}
+
+
+//==========================================================================
+
+/*
+==================
+=
+= DrawHighScores
+=
+==================
+*/
+
+void	DrawHighScores(void)
+{
+	char		buffer[16],*str,buffer1[5];
+	byte		temp,temp1,temp2,temp3;
+	word		i,j,
+				w,h,
+				x,y;
+	HighScore	*s;
+
+
+	MM_SortMem ();
+
+#ifndef SPEAR
+//	CA_CacheGrChunk (C_CODEPIC);
+	CA_CacheGrChunk (HIGHSCORESPIC);
+	CA_CacheGrChunk (STARTFONT);
+	CA_CacheGrChunk (C_LEVELPIC);
+	CA_CacheGrChunk (C_SCOREPIC);
+	CA_CacheGrChunk (C_NAMEPIC);
+
+	ClearMScreen();
+	DrawStripes(10);
+
+	VWB_DrawPic(48,0,HIGHSCORESPIC);
+	UNCACHEGRCHUNK (HIGHSCORESPIC);
+
+	VWB_DrawPic(4*8,68,C_NAMEPIC);
+	VWB_DrawPic(20*8,68,C_LEVELPIC);
+	VWB_DrawPic(28*8,68,C_SCOREPIC);
+#ifndef UPLOAD
+//	VWB_DrawPic(35*8,68,C_CODEPIC);
+#endif
+	fontnumber=0;
+
+#else
+	CacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+	ClearMScreen();
+	DrawStripes(10);
+	UnCacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+
+	CacheLump (HIGHSCORES_LUMP_START,HIGHSCORES_LUMP_END);
+	CA_CacheGrChunk (STARTFONT+1);
+	VWB_DrawPic (0,0,HIGHSCORESPIC);
+
+	fontnumber = 1;
+#endif
+
+
+#ifndef SPEAR
+	SETFONTCOLOR(15,0x29);
+#else
+	SETFONTCOLOR(HIGHLIGHT,0x29);
+#endif
+
+	for (i = 0,s = Scores;i < MaxScores;i++,s++)
+	{
+		PrintY = 76 + (16 * i);
+
+		//
+		// name
+		//
+#ifndef SPEAR
+		PrintX = 4*8;
+#else
+		PrintX = 16;
+#endif
+		US_Print(s->name);
+
+		//
+		// level
+		//
+		ultoa(s->completed,buffer,10);
+#ifndef SPEAR
+		for (str = buffer;*str;str++)
+			*str = *str + (129 - '0');	// Used fixed-width numbers (129...)
+		USL_MeasureString(buffer,&w,&h);
+		PrintX = (22 * 8)-w;
+#else
+		USL_MeasureString(buffer,&w,&h);
+		PrintX = 194 - w;
+#endif
+
+#ifndef UPLOAD
+#ifndef SPEAR
+		PrintX -= 6;
+		itoa(s->episode+1,buffer1,10);
+		US_Print("E");
+		US_Print(buffer1);
+		US_Print("/L");
+#endif
+#endif
+
+#ifdef SPEAR
+		if (s->completed == 21)
+			VWB_DrawPic (PrintX+8,PrintY-1,C_WONSPEARPIC);
+		else
+#endif
+		US_Print(buffer);
+
+		//
+		// score
+		//
+		ultoa(s->score,buffer,10);
+#ifndef SPEAR
+		for (str = buffer;*str;str++)
+			*str = *str + (129 - '0');	// Used fixed-width numbers (129...)
+		USL_MeasureString(buffer,&w,&h);
+		PrintX = (34 * 8) - 8 - w;
+#else
+		USL_MeasureString(buffer,&w,&h);
+		PrintX = 292 - w;
+#endif
+		US_Print(buffer);
+
+		#if 0
+#ifndef UPLOAD
+#ifndef SPEAR
+		//
+		// verification #
+		//
+		if (!i)
+		{
+		 temp=(((s->score >> 28)& 0xf)^
+			  ((s->score >> 24)& 0xf))+'A';
+		 temp1=(((s->score >> 20)& 0xf)^
+			   ((s->score >> 16)& 0xf))+'A';
+		 temp2=(((s->score >> 12)& 0xf)^
+			   ((s->score >> 8)& 0xf))+'A';
+		 temp3=(((s->score >> 4)& 0xf)^
+			   ((s->score >> 0)& 0xf))+'A';
+
+		 SETFONTCOLOR(0x49,0x29);
+		 PrintX = 35*8;
+		 buffer[0]=temp;
+		 buffer[1]=temp1;
+		 buffer[2]=temp2;
+		 buffer[3]=temp3;
+		 buffer[4]=0;
+		 US_Print(buffer);
+		 SETFONTCOLOR(15,0x29);
+		}
+#endif
+#endif
+		#endif
+	}
+
+	VW_UpdateScreen ();
+
+#ifdef SPEAR
+	UnCacheLump (HIGHSCORES_LUMP_START,HIGHSCORES_LUMP_END);
+	fontnumber = 0;
+#endif
+}
+
+//===========================================================================
+
+
+/*
+=======================
+=
+= CheckHighScore
+=
+=======================
+*/
+
+void	CheckHighScore (long score,word other)
+{
+	word		i,j;
+	int			n;
+	HighScore	myscore;
+
+	strcpy(myscore.name,"");
+	myscore.score = score;
+	myscore.episode = gamestate.episode;
+	myscore.completed = other;
+
+	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;
+		}
+	}
+
+#ifdef SPEAR
+	StartCPMusic (XAWARD_MUS);
+#else
+	StartCPMusic (ROSTER_MUS);
+#endif
+	DrawHighScores ();
+
+	VW_FadeIn ();
+
+	if (n != -1)
+	{
+	//
+	// got a high score
+	//
+		PrintY = 76 + (16 * n);
+#ifndef SPEAR
+		PrintX = 4*8;
+		backcolor = BORDCOLOR;
+		fontcolor = 15;
+		US_LineInput(PrintX,PrintY,Scores[n].name,nil,true,MaxHighName,100);
+#else
+		PrintX = 16;
+		fontnumber = 1;
+		VWB_Bar (PrintX-2,PrintY-2,145,15,0x9c);
+		VW_UpdateScreen ();
+		backcolor = 0x9c;
+		fontcolor = 15;
+		US_LineInput(PrintX,PrintY,Scores[n].name,nil,true,MaxHighName,130);
+#endif
+	}
+	else
+	{
+		IN_ClearKeysDown ();
+		IN_UserInput(500);
+	}
+
+}
+
+
+#ifndef UPLOAD
+#ifndef SPEAR
+#ifndef JAPAN
+////////////////////////////////////////////////////////
+//
+// NON-SHAREWARE NOTICE
+//
+////////////////////////////////////////////////////////
+void NonShareware(void)
+{
+	VW_FadeOut();
+
+	ClearMScreen();
+	DrawStripes(10);
+
+	CA_CacheGrChunk(STARTFONT+1);
+	fontnumber = 1;
+
+	SETFONTCOLOR(READHCOLOR,BKGDCOLOR);
+	PrintX=110;
+	PrintY=15;
+
+	#ifdef SPANISH
+	US_Print("Atencion");
+	#else
+	US_Print("Attention");
+	#endif
+
+	SETFONTCOLOR(HIGHLIGHT,BKGDCOLOR);
+	WindowX=PrintX=40;
+	PrintY=60;
+	#ifdef SPANISH
+	US_Print("Este juego NO es gratis y\n");
+	US_Print("NO es Shareware; favor de\n");
+	US_Print("no distribuirlo.\n\n");
+	#else
+	US_Print("This game is NOT shareware.\n");
+	US_Print("Please do not distribute it.\n");
+	US_Print("Thanks.\n\n");
+	#endif
+	US_Print("        Id Software\n");
+
+	VW_UpdateScreen ();
+	VW_FadeIn();
+	IN_Ack();
+}
+#endif
+#endif
+#endif
+
+#ifdef SPEAR
+#ifndef SPEARDEMO
+////////////////////////////////////////////////////////
+//
+// COPY PROTECTION FOR FormGen
+//
+////////////////////////////////////////////////////////
+char 	far CopyProFailedStrs[][100] = {
+			STR_COPY1,
+			STR_COPY2,
+
+			STR_COPY3,
+			STR_COPY4,
+
+			STR_COPY5,
+			STR_COPY6,
+
+			STR_COPY7,
+			STR_COPY8,
+
+			STR_COPY9,
+			"",
+
+			STR_COPY10,
+			STR_COPY11,
+
+			STR_COPY12,
+			"",
+
+			STR_COPY13,
+			"",
+
+			STR_COPY14,
+			""
+			},
+
+		far BackDoorStrs[5][16] = {
+			"a spoon?",
+			"bite me!",
+			"joshua",
+			"pelt",
+#ifdef BETA
+			"beta"
+#else
+			"snoops"
+#endif
+			},
+
+		far GoodBoyStrs[10][40] = {
+			"...is the CORRECT ANSWER!",
+			"",
+
+			"Consider yourself bitten, sir.",
+			"",
+
+			"Greetings Professor Falken, would you",
+			"like to play Spear of Destiny?",
+
+			"Do you have any gold spray paint?",
+			"",
+
+#ifdef BETA
+			"Beta testing approved.",
+#else
+			"I wish I had a 21\" monitor...",
+#endif
+			""
+			},
+
+		far bossstrs[4][24] = {
+			"DEATH KNIGHT",
+			"BARNACLE WILHELM",
+			"UBERMUTANTUBER MUTANT",
+			"TRANS GROSSE"
+			},
+
+		far WordStr[5][20] = {
+			"New Game",
+			"Sound...F4",
+			"Control...F6",
+			"Change View...F5",
+			"Quit...F10"},
+
+		far	WordCorrect[5][2] = {"3","4","4","5","5"},
+
+		far MemberStr[10][40] = {
+			STR_COPY15,
+			"",
+
+			STR_COPY16,
+			"",
+
+			STR_COPY17,
+			STR_COPY18,
+
+			STR_COPY19,
+			STR_COPY20,
+
+			STR_COPY21,
+			STR_COPY22},
+
+		far MemberCorrect[5][24] = {
+			"adrian carmack",
+			"john carmackjohn romero",
+			"tom hall",
+			"jay wilbur",
+			"kevin cloud"},
+
+		far DosMessages[9][80] = {
+			STR_NOPE1,
+			STR_NOPE2,
+			STR_NOPE3,
+			STR_NOPE4,
+			STR_NOPE5,
+			STR_NOPE6,
+			STR_NOPE7,
+			STR_NOPE8,
+			STR_NOPE9},
+
+		far MiscTitle[4][20] = {
+			"BLOOD TEST",
+			"STRAIGHT-LACED",
+			"QUITE SHAPELY",
+			"I AM WHAT I AMMO"
+			},
+
+		far MiscStr[12][40] = {
+			STR_MISC1,
+			STR_MISC2,
+			"",
+
+			STR_MISC3,
+			STR_MISC4,
+			"",
+
+			STR_MISC5,
+			STR_MISC6,
+			"",
+
+			STR_MISC7,
+			STR_MISC8,
+			STR_MISC9
+			},
+
+		far MiscCorrect[4][5] = {"ss","8",STR_STAR,"45"};
+
+
+int  BackDoor(char *s)
+{
+	int i;
+
+
+	strlwr(s);
+
+	for (i=0;i<5;i++)
+		if (!_fstrcmp(s,BackDoorStrs[i]))
+		{
+			SETFONTCOLOR(14,15);
+			fontnumber = 0;
+			PrintY = 175;
+			VWB_DrawPic (0,20*8,COPYPROTBOXPIC);
+			US_CPrint(GoodBoyStrs[i*2]);
+			US_CPrint(GoodBoyStrs[i*2+1]);
+			VW_UpdateScreen();
+			return 1;
+		}
+
+	return 0;
+}
+
+
+void CopyProtection(void)
+{
+#define TYPEBOX_Y		177
+#define TYPEBOX_BKGD	0x9c
+#define PRINTCOLOR		HIGHLIGHT
+
+	int	i,match,whichboss,bossnum,try,whichline,enemypicked[4]={0,0,0,0},
+		bosses[4] = { BOSSPIC1PIC,BOSSPIC2PIC,BOSSPIC3PIC,BOSSPIC4PIC },
+		whichone,whichpicked[4]={0,0,0,0},quiztype,whichmem,
+		memberpicked[5]={0,0,0,0,0},wordpicked[5]={0,0,0,0,0},whichword;
+
+	char	inputbuffer[20],
+			message[80];
+
+	enum
+	{
+		debriefing,
+		checkmanual,
+		staffquiz,
+		miscquiz,
+
+		totaltypes
+	};
+
+
+
+	try = 0;
+	VW_FadeOut();
+	CA_CacheGrChunk(C_BACKDROPPIC);
+	CacheLump(COPYPROT_LUMP_START,COPYPROT_LUMP_END);
+	CA_CacheGrChunk(STARTFONT+1);
+	CA_LoadAllSounds();
+	StartCPMusic(COPYPRO_MUS);
+	US_InitRndT(true);
+
+	while (try<3)
+	{
+		fontnumber = 1;
+		SETFONTCOLOR(PRINTCOLOR-2,15);
+		VWB_DrawPic (0,0,C_BACKDROPPIC);
+		VWB_DrawPic (0,0,COPYPROTTOPPIC);
+		VWB_DrawPic (0,20*8,COPYPROTBOXPIC);
+		WindowX = WindowY = 0;
+		WindowW = 320;
+		WindowH = 200;
+		PrintY = 65;
+
+		quiztype = US_RndT()%totaltypes;
+		switch(quiztype)
+		{
+			//
+			// BOSSES QUIZ
+			//
+			case debriefing:
+				PrintX = 0;
+				US_Print(STR_DEBRIEF);
+				SETFONTCOLOR(PRINTCOLOR,15);
+
+				while (enemypicked[whichboss = US_RndT()&3]);
+				enemypicked[whichboss] = 1;
+				bossnum = bosses[whichboss];
+				VWB_DrawPic(128,60,bossnum);
+				fontnumber = 0;
+				PrintY = 130;
+				US_CPrint(STR_ENEMY1"\n");
+				US_CPrint(STR_ENEMY2"\n\n");
+
+				VW_UpdateScreen();
+				VW_FadeIn();
+
+				PrintX = 100;
+				fontcolor = 15;
+				backcolor = TYPEBOX_BKGD;
+				inputbuffer[0] = 0;
+				PrintY = TYPEBOX_Y;
+				fontnumber = 1;
+				US_LineInput(PrintX,PrintY,inputbuffer,nil,true,20,100);
+
+				match = 0;
+				for (i=0;i<_fstrlen(bossstrs[whichboss]);i++)
+					if (!_fstrnicmp(inputbuffer,bossstrs[whichboss]+i,strlen(inputbuffer)) &&
+						strlen(inputbuffer)>3)
+						match = 1;
+
+				match += BackDoor(inputbuffer);
+				break;
+
+			//
+			// MANUAL CHECK
+			//
+			case checkmanual:
+				while (wordpicked[whichword = US_RndT()%5]);
+				wordpicked[whichword] = 1;
+				US_CPrint(STR_CHECKMAN);
+				SETFONTCOLOR(PRINTCOLOR,15);
+				PrintY += 25;
+				US_CPrint(STR_MAN1);
+				US_CPrint(STR_MAN2);
+				_fstrcpy(message,STR_MAN3" \"");
+				_fstrcat(message,WordStr[whichword]);
+				_fstrcat(message,"\" "STR_MAN4);
+				US_CPrint(message);
+				VW_UpdateScreen();
+				VW_FadeIn();
+
+				PrintX = 146;
+				fontcolor = 15;
+				backcolor = TYPEBOX_BKGD;
+				inputbuffer[0] = 0;
+				PrintY = TYPEBOX_Y;
+				US_LineInput(PrintX,PrintY,inputbuffer,nil,true,6,100);
+
+				strlwr(inputbuffer);
+				match = 1-(_fstrcmp(inputbuffer,WordCorrect[whichword])!=0);
+				match += BackDoor(inputbuffer);
+				break;
+
+			//
+			// STAFF QUIZ
+			//
+			case staffquiz:
+				while (memberpicked[whichmem = US_RndT()%5]);
+				memberpicked[whichmem] = 1;
+				US_CPrint(STR_ID1);
+				SETFONTCOLOR(PRINTCOLOR,15);
+				PrintY += 25;
+				US_CPrint(MemberStr[whichmem*2]);
+				US_CPrint(MemberStr[whichmem*2+1]);
+				VW_UpdateScreen();
+				VW_FadeIn();
+
+				PrintX = 100;
+				fontcolor = 15;
+				backcolor = TYPEBOX_BKGD;
+				inputbuffer[0] = 0;
+				PrintY = TYPEBOX_Y;
+				US_LineInput(PrintX,PrintY,inputbuffer,nil,true,20,120);
+
+				strlwr(inputbuffer);
+				match = 0;
+				for (i=0;i<_fstrlen(MemberCorrect[whichmem]);i++)
+					if (!_fstrnicmp(inputbuffer,MemberCorrect[whichmem]+i,strlen(inputbuffer)) &&
+						strlen(inputbuffer)>2)
+							match = 1;
+				match += BackDoor(inputbuffer);
+				break;
+
+			//
+			// MISCELLANEOUS QUESTIONS
+			//
+			case miscquiz:
+				while (whichpicked[whichone = US_RndT()&3]);
+				whichpicked[whichone] = 1;
+				US_CPrint(MiscTitle[whichone]);
+				SETFONTCOLOR(PRINTCOLOR,15);
+				PrintY += 25;
+				US_CPrint(MiscStr[whichone*3]);
+				US_CPrint(MiscStr[whichone*3+1]);
+				US_CPrint(MiscStr[whichone*3+2]);
+				VW_UpdateScreen();
+				VW_FadeIn();
+
+				PrintX = 146;
+				fontcolor = 15;
+				backcolor = TYPEBOX_BKGD;
+				inputbuffer[0] = 0;
+				PrintY = TYPEBOX_Y;
+				US_LineInput(PrintX,PrintY,inputbuffer,nil,true,6,100);
+
+				strlwr(inputbuffer);
+				match = 1-(_fstrcmp(inputbuffer,MiscCorrect[whichone])!=0);
+				match += BackDoor(inputbuffer);
+				break;
+			}
+
+		//
+		// IF NO MATCH, WE'VE GOT A (MINOR) PROBLEM!
+		//
+
+		if (!match)
+		{
+			whichline = 2*(US_RndT()%9);
+			SETFONTCOLOR(14,15);
+			fontnumber = 0;
+			PrintY = 175;
+			VWB_DrawPic (0,20*8,COPYPROTBOXPIC);
+			US_CPrint(CopyProFailedStrs[whichline]);
+			US_CPrint(CopyProFailedStrs[whichline+1]);
+
+			VW_UpdateScreen();
+			SD_PlaySound(NOWAYSND);
+			IN_UserInput(TickBase*3);
+			VW_FadeOut();
+			try++;
+		}
+		else
+		{
+			int start;
+
+
+			SD_PlaySound(BONUS1UPSND);
+			SD_WaitSoundDone();
+			UNCACHEGRCHUNK (STARTFONT+1);
+			UNCACHEGRCHUNK (C_BACKDROPPIC);
+			UnCacheLump (COPYPROT_LUMP_START,COPYPROT_LUMP_END);
+
+			switch(SoundMode)
+			{
+				case sdm_Off: return;
+				case sdm_PC: start = STARTPCSOUNDS; break;
+				case sdm_AdLib: start = STARTADLIBSOUNDS;
+			}
+
+			for (i=0;i<NUMSOUNDS;i++,start++)
+				MM_FreePtr ((memptr *)&audiosegs[start]);
+			return;
+		}
+	}
+
+	ClearMemory();
+	ShutdownId();
+
+	_fstrcpy(message,DosMessages[US_RndT()%9]);
+
+	_AX = 3;
+	geninterrupt(0x10);
+
+	printf("%s\n",message);
+	exit(1);
+}
+
+#endif // SPEARDEMO
+#endif // SPEAR
+//===========================================================================
--- /dev/null
+++ b/WOLFSRC/WL_MAIN.C
@@ -1,0 +1,1616 @@
+// WL_MAIN.C
+
+#include <conio.h>
+#include "WL_DEF.H"
+#pragma hdrstop
+
+
+/*
+=============================================================================
+
+						   WOLFENSTEIN 3-D
+
+					  An Id Software production
+
+						   by John Carmack
+
+=============================================================================
+*/
+
+/*
+=============================================================================
+
+						 LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+
+#define FOCALLENGTH     (0x5700l)               // in global coordinates
+#define VIEWGLOBAL      0x10000                 // globals visable flush to wall
+
+#define VIEWWIDTH       256                     // size of view window
+#define VIEWHEIGHT      144
+
+/*
+=============================================================================
+
+						 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+char            str[80],str2[20];
+int				tedlevelnum;
+boolean         tedlevel;
+boolean         nospr;
+boolean         IsA386;
+int                     dirangle[9] = {0,ANGLES/8,2*ANGLES/8,3*ANGLES/8,4*ANGLES/8,
+	5*ANGLES/8,6*ANGLES/8,7*ANGLES/8,ANGLES};
+
+//
+// proejection variables
+//
+fixed           focallength;
+unsigned        screenofs;
+int             viewwidth;
+int             viewheight;
+int             centerx;
+int             shootdelta;                     // pixels away from centerx a target can be
+fixed           scale,maxslope;
+long            heightnumerator;
+int                     minheightdiv;
+
+
+void            Quit (char *error);
+
+boolean         startgame,loadedgame,virtualreality;
+int             mouseadjustment;
+
+char	configname[13]="CONFIG.";
+
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+
+/*
+====================
+=
+= ReadConfig
+=
+====================
+*/
+
+void ReadConfig(void)
+{
+	int                     file;
+	SDMode          sd;
+	SMMode          sm;
+	SDSMode         sds;
+
+
+	if ( (file = open(configname,O_BINARY | O_RDONLY)) != -1)
+	{
+	//
+	// valid config file
+	//
+		read(file,Scores,sizeof(HighScore) * MaxScores);
+
+		read(file,&sd,sizeof(sd));
+		read(file,&sm,sizeof(sm));
+		read(file,&sds,sizeof(sds));
+
+		read(file,&mouseenabled,sizeof(mouseenabled));
+		read(file,&joystickenabled,sizeof(joystickenabled));
+		read(file,&joypadenabled,sizeof(joypadenabled));
+		read(file,&joystickprogressive,sizeof(joystickprogressive));
+		read(file,&joystickport,sizeof(joystickport));
+
+		read(file,&dirscan,sizeof(dirscan));
+		read(file,&buttonscan,sizeof(buttonscan));
+		read(file,&buttonmouse,sizeof(buttonmouse));
+		read(file,&buttonjoy,sizeof(buttonjoy));
+
+		read(file,&viewsize,sizeof(viewsize));
+		read(file,&mouseadjustment,sizeof(mouseadjustment));
+
+		close(file);
+
+		if (sd == sdm_AdLib && !AdLibPresent && !SoundBlasterPresent)
+		{
+			sd = sdm_PC;
+			sd = smm_Off;
+		}
+
+		if ((sds == sds_SoundBlaster && !SoundBlasterPresent) ||
+			(sds == sds_SoundSource && !SoundSourcePresent))
+			sds = sds_Off;
+
+		if (!MousePresent)
+			mouseenabled = false;
+		if (!JoysPresent[joystickport])
+			joystickenabled = false;
+
+		MainMenu[6].active=1;
+		MainItems.curpos=0;
+	}
+	else
+	{
+	//
+	// no config file, so select by hardware
+	//
+		if (SoundBlasterPresent || AdLibPresent)
+		{
+			sd = sdm_AdLib;
+			sm = smm_AdLib;
+		}
+		else
+		{
+			sd = sdm_PC;
+			sm = smm_Off;
+		}
+
+		if (SoundBlasterPresent)
+			sds = sds_SoundBlaster;
+		else if (SoundSourcePresent)
+			sds = sds_SoundSource;
+		else
+			sds = sds_Off;
+
+		if (MousePresent)
+			mouseenabled = true;
+
+		joystickenabled = false;
+		joypadenabled = false;
+		joystickport = 0;
+		joystickprogressive = false;
+
+		viewsize = 15;
+		mouseadjustment=5;
+	}
+
+	SD_SetMusicMode (sm);
+	SD_SetSoundMode (sd);
+	SD_SetDigiDevice (sds);
+
+}
+
+
+/*
+====================
+=
+= WriteConfig
+=
+====================
+*/
+
+void WriteConfig(void)
+{
+	int                     file;
+
+	file = open(configname,O_CREAT | O_BINARY | O_WRONLY,
+				S_IREAD | S_IWRITE | S_IFREG);
+
+	if (file != -1)
+	{
+		write(file,Scores,sizeof(HighScore) * MaxScores);
+
+		write(file,&SoundMode,sizeof(SoundMode));
+		write(file,&MusicMode,sizeof(MusicMode));
+		write(file,&DigiMode,sizeof(DigiMode));
+
+		write(file,&mouseenabled,sizeof(mouseenabled));
+		write(file,&joystickenabled,sizeof(joystickenabled));
+		write(file,&joypadenabled,sizeof(joypadenabled));
+		write(file,&joystickprogressive,sizeof(joystickprogressive));
+		write(file,&joystickport,sizeof(joystickport));
+
+		write(file,&dirscan,sizeof(dirscan));
+		write(file,&buttonscan,sizeof(buttonscan));
+		write(file,&buttonmouse,sizeof(buttonmouse));
+		write(file,&buttonjoy,sizeof(buttonjoy));
+
+		write(file,&viewsize,sizeof(viewsize));
+		write(file,&mouseadjustment,sizeof(mouseadjustment));
+
+		close(file);
+	}
+}
+
+
+//===========================================================================
+
+
+/*
+========================
+=
+= Patch386
+=
+= Patch ldiv to use 32 bit instructions
+=
+========================
+*/
+
+char    *JHParmStrings[] = {"no386",nil};
+void Patch386 (void)
+{
+extern void far jabhack2(void);
+extern int far  CheckIs386(void);
+
+	int     i;
+
+	for (i = 1;i < _argc;i++)
+		if (US_CheckParm(_argv[i],JHParmStrings) == 0)
+		{
+			IsA386 = false;
+			return;
+		}
+
+	if (CheckIs386())
+	{
+		IsA386 = true;
+		jabhack2();
+	}
+	else
+		IsA386 = false;
+}
+
+//===========================================================================
+
+/*
+=====================
+=
+= NewGame
+=
+= Set up new game to start from the beginning
+=
+=====================
+*/
+
+void NewGame (int difficulty,int episode)
+{
+	memset (&gamestate,0,sizeof(gamestate));
+	gamestate.difficulty = difficulty;
+	gamestate.weapon = gamestate.bestweapon
+		= gamestate.chosenweapon = wp_pistol;
+	gamestate.health = 100;
+	gamestate.ammo = STARTAMMO;
+	gamestate.lives = 3;
+	gamestate.nextextra = EXTRAPOINTS;
+	gamestate.episode=episode;
+
+	startgame = true;
+}
+
+//===========================================================================
+
+void DiskFlopAnim(int x,int y)
+{
+ static char which=0;
+ if (!x && !y)
+   return;
+ VWB_DrawPic(x,y,C_DISKLOADING1PIC+which);
+ VW_UpdateScreen();
+ which^=1;
+}
+
+
+long DoChecksum(byte far *source,unsigned size,long checksum)
+{
+ unsigned i;
+
+ for (i=0;i<size-1;i++)
+   checksum += source[i]^source[i+1];
+
+ return checksum;
+}
+
+
+/*
+==================
+=
+= SaveTheGame
+=
+==================
+*/
+
+boolean SaveTheGame(int file,int x,int y)
+{
+	struct diskfree_t dfree;
+	long avail,size,checksum;
+	objtype *ob,nullobj;
+
+
+	if (_dos_getdiskfree(0,&dfree))
+	  Quit("Error in _dos_getdiskfree call");
+
+	avail = (long)dfree.avail_clusters *
+			dfree.bytes_per_sector *
+			dfree.sectors_per_cluster;
+
+	size = 0;
+	for (ob = player; ob ; ob=ob->next)
+	  size += sizeof(*ob);
+	size += sizeof(nullobj);
+
+	size += sizeof(gamestate) +
+			sizeof(LRstruct)*8 +
+			sizeof(tilemap) +
+			sizeof(actorat) +
+			sizeof(laststatobj) +
+			sizeof(statobjlist) +
+			sizeof(doorposition) +
+			sizeof(pwallstate) +
+			sizeof(pwallx) +
+			sizeof(pwally) +
+			sizeof(pwalldir) +
+			sizeof(pwallpos);
+
+	if (avail < size)
+	{
+	 Message(STR_NOSPACE1"\n"
+			 STR_NOSPACE2);
+	 return false;
+	}
+
+	checksum = 0;
+
+
+	DiskFlopAnim(x,y);
+	CA_FarWrite (file,(void far *)&gamestate,sizeof(gamestate));
+	checksum = DoChecksum((byte far *)&gamestate,sizeof(gamestate),checksum);
+
+	DiskFlopAnim(x,y);
+#ifdef SPEAR
+	CA_FarWrite (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*20);
+	checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*20,checksum);
+#else
+	CA_FarWrite (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*8);
+	checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*8,checksum);
+#endif
+
+	DiskFlopAnim(x,y);
+	CA_FarWrite (file,(void far *)tilemap,sizeof(tilemap));
+	checksum = DoChecksum((byte far *)tilemap,sizeof(tilemap),checksum);
+	DiskFlopAnim(x,y);
+	CA_FarWrite (file,(void far *)actorat,sizeof(actorat));
+	checksum = DoChecksum((byte far *)actorat,sizeof(actorat),checksum);
+
+	CA_FarWrite (file,(void far *)areaconnect,sizeof(areaconnect));
+	CA_FarWrite (file,(void far *)areabyplayer,sizeof(areabyplayer));
+
+	for (ob = player ; ob ; ob=ob->next)
+	{
+	 DiskFlopAnim(x,y);
+	 CA_FarWrite (file,(void far *)ob,sizeof(*ob));
+	}
+	nullobj.active = ac_badobject;          // end of file marker
+	DiskFlopAnim(x,y);
+	CA_FarWrite (file,(void far *)&nullobj,sizeof(nullobj));
+
+
+
+	DiskFlopAnim(x,y);
+	CA_FarWrite (file,(void far *)&laststatobj,sizeof(laststatobj));
+	checksum = DoChecksum((byte far *)&laststatobj,sizeof(laststatobj),checksum);
+	DiskFlopAnim(x,y);
+	CA_FarWrite (file,(void far *)statobjlist,sizeof(statobjlist));
+	checksum = DoChecksum((byte far *)statobjlist,sizeof(statobjlist),checksum);
+
+	DiskFlopAnim(x,y);
+	CA_FarWrite (file,(void far *)doorposition,sizeof(doorposition));
+	checksum = DoChecksum((byte far *)doorposition,sizeof(doorposition),checksum);
+	DiskFlopAnim(x,y);
+	CA_FarWrite (file,(void far *)doorobjlist,sizeof(doorobjlist));
+	checksum = DoChecksum((byte far *)doorobjlist,sizeof(doorobjlist),checksum);
+
+	DiskFlopAnim(x,y);
+	CA_FarWrite (file,(void far *)&pwallstate,sizeof(pwallstate));
+	checksum = DoChecksum((byte far *)&pwallstate,sizeof(pwallstate),checksum);
+	CA_FarWrite (file,(void far *)&pwallx,sizeof(pwallx));
+	checksum = DoChecksum((byte far *)&pwallx,sizeof(pwallx),checksum);
+	CA_FarWrite (file,(void far *)&pwally,sizeof(pwally));
+	checksum = DoChecksum((byte far *)&pwally,sizeof(pwally),checksum);
+	CA_FarWrite (file,(void far *)&pwalldir,sizeof(pwalldir));
+	checksum = DoChecksum((byte far *)&pwalldir,sizeof(pwalldir),checksum);
+	CA_FarWrite (file,(void far *)&pwallpos,sizeof(pwallpos));
+	checksum = DoChecksum((byte far *)&pwallpos,sizeof(pwallpos),checksum);
+
+	//
+	// WRITE OUT CHECKSUM
+	//
+	CA_FarWrite (file,(void far *)&checksum,sizeof(checksum));
+
+	return(true);
+}
+
+//===========================================================================
+
+/*
+==================
+=
+= LoadTheGame
+=
+==================
+*/
+
+boolean LoadTheGame(int file,int x,int y)
+{
+	long checksum,oldchecksum;
+	objtype *ob,nullobj;
+
+
+	checksum = 0;
+
+	DiskFlopAnim(x,y);
+	CA_FarRead (file,(void far *)&gamestate,sizeof(gamestate));
+	checksum = DoChecksum((byte far *)&gamestate,sizeof(gamestate),checksum);
+
+	DiskFlopAnim(x,y);
+#ifdef SPEAR
+	CA_FarRead (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*20);
+	checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*20,checksum);
+#else
+	CA_FarRead (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*8);
+	checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*8,checksum);
+#endif
+
+	DiskFlopAnim(x,y);
+	SetupGameLevel ();
+
+	DiskFlopAnim(x,y);
+	CA_FarRead (file,(void far *)tilemap,sizeof(tilemap));
+	checksum = DoChecksum((byte far *)tilemap,sizeof(tilemap),checksum);
+	DiskFlopAnim(x,y);
+	CA_FarRead (file,(void far *)actorat,sizeof(actorat));
+	checksum = DoChecksum((byte far *)actorat,sizeof(actorat),checksum);
+
+	CA_FarRead (file,(void far *)areaconnect,sizeof(areaconnect));
+	CA_FarRead (file,(void far *)areabyplayer,sizeof(areabyplayer));
+
+
+
+	InitActorList ();
+	DiskFlopAnim(x,y);
+	CA_FarRead (file,(void far *)player,sizeof(*player));
+
+	while (1)
+	{
+	 DiskFlopAnim(x,y);
+		CA_FarRead (file,(void far *)&nullobj,sizeof(nullobj));
+		if (nullobj.active == ac_badobject)
+			break;
+		GetNewActor ();
+	 // don't copy over the links
+		memcpy (new,&nullobj,sizeof(nullobj)-4);
+	}
+
+
+
+	DiskFlopAnim(x,y);
+	CA_FarRead (file,(void far *)&laststatobj,sizeof(laststatobj));
+	checksum = DoChecksum((byte far *)&laststatobj,sizeof(laststatobj),checksum);
+	DiskFlopAnim(x,y);
+	CA_FarRead (file,(void far *)statobjlist,sizeof(statobjlist));
+	checksum = DoChecksum((byte far *)statobjlist,sizeof(statobjlist),checksum);
+
+	DiskFlopAnim(x,y);
+	CA_FarRead (file,(void far *)doorposition,sizeof(doorposition));
+	checksum = DoChecksum((byte far *)doorposition,sizeof(doorposition),checksum);
+	DiskFlopAnim(x,y);
+	CA_FarRead (file,(void far *)doorobjlist,sizeof(doorobjlist));
+	checksum = DoChecksum((byte far *)doorobjlist,sizeof(doorobjlist),checksum);
+
+	DiskFlopAnim(x,y);
+	CA_FarRead (file,(void far *)&pwallstate,sizeof(pwallstate));
+	checksum = DoChecksum((byte far *)&pwallstate,sizeof(pwallstate),checksum);
+	CA_FarRead (file,(void far *)&pwallx,sizeof(pwallx));
+	checksum = DoChecksum((byte far *)&pwallx,sizeof(pwallx),checksum);
+	CA_FarRead (file,(void far *)&pwally,sizeof(pwally));
+	checksum = DoChecksum((byte far *)&pwally,sizeof(pwally),checksum);
+	CA_FarRead (file,(void far *)&pwalldir,sizeof(pwalldir));
+	checksum = DoChecksum((byte far *)&pwalldir,sizeof(pwalldir),checksum);
+	CA_FarRead (file,(void far *)&pwallpos,sizeof(pwallpos));
+	checksum = DoChecksum((byte far *)&pwallpos,sizeof(pwallpos),checksum);
+
+	CA_FarRead (file,(void far *)&oldchecksum,sizeof(oldchecksum));
+
+	if (oldchecksum != checksum)
+	{
+	 Message(STR_SAVECHT1"\n"
+			 STR_SAVECHT2"\n"
+			 STR_SAVECHT3"\n"
+			 STR_SAVECHT4);
+
+	 IN_ClearKeysDown();
+	 IN_Ack();
+
+	 gamestate.score = 0;
+	 gamestate.lives = 1;
+	 gamestate.weapon =
+	   gamestate.chosenweapon =
+	   gamestate.bestweapon = wp_pistol;
+	 gamestate.ammo = 8;
+	}
+
+	return true;
+}
+
+//===========================================================================
+
+/*
+==========================
+=
+= ShutdownId
+=
+= Shuts down all ID_?? managers
+=
+==========================
+*/
+
+void ShutdownId (void)
+{
+	US_Shutdown ();
+	SD_Shutdown ();
+	PM_Shutdown ();
+	IN_Shutdown ();
+	VW_Shutdown ();
+	CA_Shutdown ();
+	MM_Shutdown ();
+}
+
+
+//===========================================================================
+
+/*
+==================
+=
+= BuildTables
+=
+= Calculates:
+=
+= scale                 projection constant
+= sintable/costable     overlapping fractional tables
+=
+==================
+*/
+
+const   float   radtoint = (float)FINEANGLES/2/PI;
+
+void BuildTables (void)
+{
+  int           i;
+  float         angle,anglestep;
+  double        tang;
+  fixed         value;
+
+
+//
+// calculate fine tangents
+//
+
+	for (i=0;i<FINEANGLES/8;i++)
+	{
+		tang = tan( (i+0.5)/radtoint);
+		finetangent[i] = tang*TILEGLOBAL;
+		finetangent[FINEANGLES/4-1-i] = 1/tang*TILEGLOBAL;
+	}
+
+//
+// costable overlays sintable with a quarter phase shift
+// ANGLES is assumed to be divisable by four
+//
+// The low word of the value is the fraction, the high bit is the sign bit,
+// bits 16-30 should be 0
+//
+
+  angle = 0;
+  anglestep = PI/2/ANGLEQUAD;
+  for (i=0;i<=ANGLEQUAD;i++)
+  {
+	value=GLOBAL1*sin(angle);
+	sintable[i]=
+	  sintable[i+ANGLES]=
+	  sintable[ANGLES/2-i] = value;
+	sintable[ANGLES-i]=
+	  sintable[ANGLES/2+i] = value | 0x80000000l;
+	angle += anglestep;
+  }
+
+}
+
+//===========================================================================
+
+
+/*
+====================
+=
+= CalcProjection
+=
+= Uses focallength
+=
+====================
+*/
+
+void CalcProjection (long focal)
+{
+	int             i;
+	long            intang;
+	float   angle;
+	double  tang;
+	double  planedist;
+	double  globinhalf;
+	int             halfview;
+	double  halfangle,facedist;
+
+
+	focallength = focal;
+	facedist = focal+MINDIST;
+	halfview = viewwidth/2;                                 // half view in pixels
+
+//
+// calculate scale value for vertical height calculations
+// and sprite x calculations
+//
+	scale = halfview*facedist/(VIEWGLOBAL/2);
+
+//
+// divide heightnumerator by a posts distance to get the posts height for
+// the heightbuffer.  The pixel height is height>>2
+//
+	heightnumerator = (TILEGLOBAL*scale)>>6;
+	minheightdiv = heightnumerator/0x7fff +1;
+
+//
+// calculate the angle offset from view angle of each pixel's ray
+//
+
+	for (i=0;i<halfview;i++)
+	{
+	// start 1/2 pixel over, so viewangle bisects two middle pixels
+		tang = (long)i*VIEWGLOBAL/viewwidth/facedist;
+		angle = atan(tang);
+		intang = angle*radtoint;
+		pixelangle[halfview-1-i] = intang;
+		pixelangle[halfview+i] = -intang;
+	}
+
+//
+// if a point's abs(y/x) is greater than maxslope, the point is outside
+// the view area
+//
+	maxslope = finetangent[pixelangle[0]];
+	maxslope >>= 8;
+}
+
+
+
+//===========================================================================
+
+/*
+===================
+=
+= SetupWalls
+=
+= Map tile values to scaled pics
+=
+===================
+*/
+
+void SetupWalls (void)
+{
+	int     i;
+
+	for (i=1;i<MAXWALLTILES;i++)
+	{
+		horizwall[i]=(i-1)*2;
+		vertwall[i]=(i-1)*2+1;
+	}
+}
+
+//===========================================================================
+
+/*
+==========================
+=
+= SignonScreen
+=
+==========================
+*/
+
+void SignonScreen (void)                        // VGA version
+{
+	unsigned        segstart,seglength;
+
+	VL_SetVGAPlaneMode ();
+	VL_TestPaletteSet ();
+	VL_SetPalette (&gamepal);
+
+	if (!virtualreality)
+	{
+		VW_SetScreen(0x8000,0);
+		VL_MungePic (&introscn,320,200);
+		VL_MemToScreen (&introscn,320,200,0,0);
+		VW_SetScreen(0,0);
+	}
+
+//
+// reclaim the memory from the linked in signon screen
+//
+	segstart = FP_SEG(&introscn);
+	seglength = 64000/16;
+	if (FP_OFF(&introscn))
+	{
+		segstart++;
+		seglength--;
+	}
+	MML_UseSpace (segstart,seglength);
+}
+
+
+/*
+==========================
+=
+= FinishSignon
+=
+==========================
+*/
+
+void FinishSignon (void)
+{
+
+#ifndef SPEAR
+	VW_Bar (0,189,300,11,peekb(0xa000,0));
+	WindowX = 0;
+	WindowW = 320;
+	PrintY = 190;
+
+	#ifndef JAPAN
+	SETFONTCOLOR(14,4);
+
+	#ifdef SPANISH
+	US_CPrint ("Oprima una tecla");
+	#else
+	US_CPrint ("Press a key");
+	#endif
+
+	#endif
+
+	if (!NoWait)
+		IN_Ack ();
+
+	#ifndef JAPAN
+	VW_Bar (0,189,300,11,peekb(0xa000,0));
+
+	PrintY = 190;
+	SETFONTCOLOR(10,4);
+
+	#ifdef SPANISH
+	US_CPrint ("pensando...");
+	#else
+	US_CPrint ("Working...");
+	#endif
+
+	#endif
+
+	SETFONTCOLOR(0,15);
+#else
+	if (!NoWait)
+		VW_WaitVBL(3*70);
+#endif
+}
+
+//===========================================================================
+
+/*
+=================
+=
+= MS_CheckParm
+=
+=================
+*/
+
+boolean MS_CheckParm (char far *check)
+{
+	int             i;
+	char    *parm;
+
+	for (i = 1;i<_argc;i++)
+	{
+		parm = _argv[i];
+
+		while ( !isalpha(*parm) )       // skip - / \ etc.. in front of parm
+			if (!*parm++)
+				break;                          // hit end of string without an alphanum
+
+		if ( !_fstricmp(check,parm) )
+			return true;
+	}
+
+	return false;
+}
+
+//===========================================================================
+
+/*
+=====================
+=
+= InitDigiMap
+=
+=====================
+*/
+
+static  int     wolfdigimap[] =
+		{
+			// These first sounds are in the upload version
+#ifndef SPEAR
+			HALTSND,                0,
+			DOGBARKSND,             1,
+			CLOSEDOORSND,           2,
+			OPENDOORSND,            3,
+			ATKMACHINEGUNSND,       4,
+			ATKPISTOLSND,           5,
+			ATKGATLINGSND,          6,
+			SCHUTZADSND,            7,
+			GUTENTAGSND,            8,
+			MUTTISND,               9,
+			BOSSFIRESND,            10,
+			SSFIRESND,              11,
+			DEATHSCREAM1SND,        12,
+			DEATHSCREAM2SND,        13,
+			DEATHSCREAM3SND,        13,
+			TAKEDAMAGESND,          14,
+			PUSHWALLSND,            15,
+
+			LEBENSND,               20,
+			NAZIFIRESND,            21,
+			SLURPIESND,             22,
+
+			YEAHSND,				32,
+
+#ifndef UPLOAD
+			// These are in all other episodes
+			DOGDEATHSND,            16,
+			AHHHGSND,               17,
+			DIESND,                 18,
+			EVASND,                 19,
+
+			TOT_HUNDSND,            23,
+			MEINGOTTSND,            24,
+			SCHABBSHASND,           25,
+			HITLERHASND,            26,
+			SPIONSND,               27,
+			NEINSOVASSND,           28,
+			DOGATTACKSND,           29,
+			LEVELDONESND,           30,
+			MECHSTEPSND,			31,
+
+			SCHEISTSND,				33,
+			DEATHSCREAM4SND,		34,		// AIIEEE
+			DEATHSCREAM5SND,		35,		// DEE-DEE
+			DONNERSND,				36,		// EPISODE 4 BOSS DIE
+			EINESND,				37,		// EPISODE 4 BOSS SIGHTING
+			ERLAUBENSND,			38,		// EPISODE 6 BOSS SIGHTING
+			DEATHSCREAM6SND,		39,		// FART
+			DEATHSCREAM7SND,		40,		// GASP
+			DEATHSCREAM8SND,		41,		// GUH-BOY!
+			DEATHSCREAM9SND,		42,		// AH GEEZ!
+			KEINSND,				43,		// EPISODE 5 BOSS SIGHTING
+			MEINSND,				44,		// EPISODE 6 BOSS DIE
+			ROSESND,				45,		// EPISODE 5 BOSS DIE
+
+#endif
+#else
+//
+// SPEAR OF DESTINY DIGISOUNDS
+//
+			HALTSND,                0,
+			CLOSEDOORSND,           2,
+			OPENDOORSND,            3,
+			ATKMACHINEGUNSND,       4,
+			ATKPISTOLSND,           5,
+			ATKGATLINGSND,          6,
+			SCHUTZADSND,            7,
+			BOSSFIRESND,            8,
+			SSFIRESND,              9,
+			DEATHSCREAM1SND,        10,
+			DEATHSCREAM2SND,        11,
+			TAKEDAMAGESND,          12,
+			PUSHWALLSND,            13,
+			AHHHGSND,               15,
+			LEBENSND,               16,
+			NAZIFIRESND,            17,
+			SLURPIESND,             18,
+			LEVELDONESND,           22,
+			DEATHSCREAM4SND,		23,		// AIIEEE
+			DEATHSCREAM3SND,        23,		// DOUBLY-MAPPED!!!
+			DEATHSCREAM5SND,		24,		// DEE-DEE
+			DEATHSCREAM6SND,		25,		// FART
+			DEATHSCREAM7SND,		26,		// GASP
+			DEATHSCREAM8SND,		27,		// GUH-BOY!
+			DEATHSCREAM9SND,		28,		// AH GEEZ!
+			GETGATLINGSND,			38,		// Got Gat replacement
+
+#ifndef SPEARDEMO
+			DOGBARKSND,             1,
+			DOGDEATHSND,            14,
+			SPIONSND,               19,
+			NEINSOVASSND,           20,
+			DOGATTACKSND,           21,
+			TRANSSIGHTSND,			29,		// Trans Sight
+			TRANSDEATHSND,			30,		// Trans Death
+			WILHELMSIGHTSND,		31,		// Wilhelm Sight
+			WILHELMDEATHSND,		32,		// Wilhelm Death
+			UBERDEATHSND,			33,		// Uber Death
+			KNIGHTSIGHTSND,			34,		// Death Knight Sight
+			KNIGHTDEATHSND,			35,		// Death Knight Death
+			ANGELSIGHTSND,			36,		// Angel Sight
+			ANGELDEATHSND,			37,		// Angel Death
+			GETSPEARSND,			39,		// Got Spear replacement
+#endif
+#endif
+			LASTSOUND
+		};
+
+
+void InitDigiMap (void)
+{
+	int                     *map;
+
+	for (map = wolfdigimap;*map != LASTSOUND;map += 2)
+		DigiMap[map[0]] = map[1];
+
+
+}
+
+
+#ifndef SPEAR
+CP_iteminfo	MusicItems={CTL_X,CTL_Y,6,0,32};
+CP_itemtype far MusicMenu[]=
+	{
+		{1,"Get Them!",0},
+		{1,"Searching",0},
+		{1,"P.O.W.",0},
+		{1,"Suspense",0},
+		{1,"War March",0},
+		{1,"Around The Corner!",0},
+
+		{1,"Nazi Anthem",0},
+		{1,"Lurking...",0},
+		{1,"Going After Hitler",0},
+		{1,"Pounding Headache",0},
+		{1,"Into the Dungeons",0},
+		{1,"Ultimate Conquest",0},
+
+		{1,"Kill the S.O.B.",0},
+		{1,"The Nazi Rap",0},
+		{1,"Twelfth Hour",0},
+		{1,"Zero Hour",0},
+		{1,"Ultimate Conquest",0},
+		{1,"Wolfpack",0}
+	};
+#else
+CP_iteminfo MusicItems={CTL_X,CTL_Y-20,9,0,32};
+CP_itemtype far MusicMenu[]=
+   {
+		{1,"Funky Colonel Bill",0},
+		{1,"Death To The Nazis",0},
+		{1,"Tiptoeing Around",0},
+		{1,"Is This THE END?",0},
+		{1,"Evil Incarnate",0},
+		{1,"Jazzin' Them Nazis",0},
+		{1,"Puttin' It To The Enemy",0},
+		{1,"The SS Gonna Get You",0},
+		{1,"Towering Above",0}
+	};
+#endif
+
+#ifndef SPEARDEMO
+void DoJukebox(void)
+{
+	int which,lastsong=-1;
+	unsigned start,songs[]=
+		{
+#ifndef SPEAR
+			GETTHEM_MUS,
+			SEARCHN_MUS,
+			POW_MUS,
+			SUSPENSE_MUS,
+			WARMARCH_MUS,
+			CORNER_MUS,
+
+			NAZI_OMI_MUS,
+			PREGNANT_MUS,
+			GOINGAFT_MUS,
+			HEADACHE_MUS,
+			DUNGEON_MUS,
+			ULTIMATE_MUS,
+
+			INTROCW3_MUS,
+			NAZI_RAP_MUS,
+			TWELFTH_MUS,
+			ZEROHOUR_MUS,
+			ULTIMATE_MUS,
+			PACMAN_MUS
+#else
+			XFUNKIE_MUS,             // 0
+			XDEATH_MUS,              // 2
+			XTIPTOE_MUS,             // 4
+			XTHEEND_MUS,             // 7
+			XEVIL_MUS,               // 17
+			XJAZNAZI_MUS,            // 18
+			XPUTIT_MUS,              // 21
+			XGETYOU_MUS,             // 22
+			XTOWER2_MUS              // 23
+#endif
+		};
+	struct dostime_t time;
+
+
+
+	IN_ClearKeysDown();
+	if (!AdLibPresent && !SoundBlasterPresent)
+		return;
+
+
+	MenuFadeOut();
+
+#ifndef SPEAR
+#ifndef UPLOAD
+	_dos_gettime(&time);
+	start = (time.hsecond%3)*6;
+#else
+	start = 0;
+#endif
+#else
+	start = 0;
+#endif
+
+
+	CA_CacheGrChunk (STARTFONT+1);
+#ifdef SPEAR
+	CacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+#else
+	CacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END);
+#endif
+	CA_LoadAllSounds ();
+
+	fontnumber=1;
+	ClearMScreen ();
+	VWB_DrawPic(112,184,C_MOUSELBACKPIC);
+	DrawStripes (10);
+	SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR);
+
+#ifndef SPEAR
+	DrawWindow (CTL_X-2,CTL_Y-6,280,13*7,BKGDCOLOR);
+#else
+	DrawWindow (CTL_X-2,CTL_Y-26,280,13*10,BKGDCOLOR);
+#endif
+
+	DrawMenu (&MusicItems,&MusicMenu[start]);
+
+	SETFONTCOLOR (READHCOLOR,BKGDCOLOR);
+	PrintY=15;
+	WindowX = 0;
+	WindowY = 320;
+	US_CPrint ("Robert's Jukebox");
+
+	SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR);
+	VW_UpdateScreen();
+	MenuFadeIn();
+
+	do
+	{
+		which = HandleMenu(&MusicItems,&MusicMenu[start],NULL);
+		if (which>=0)
+		{
+			if (lastsong >= 0)
+				MusicMenu[start+lastsong].active = 1;
+
+			StartCPMusic(songs[start + which]);
+			MusicMenu[start+which].active = 2;
+			DrawMenu (&MusicItems,&MusicMenu[start]);
+			VW_UpdateScreen();
+			lastsong = which;
+		}
+	} while(which>=0);
+
+	MenuFadeOut();
+	IN_ClearKeysDown();
+#ifdef SPEAR
+	UnCacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+#else
+	UnCacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END);
+#endif
+}
+#endif
+
+
+/*
+==========================
+=
+= InitGame
+=
+= Load a few things right away
+=
+==========================
+*/
+
+void InitGame (void)
+{
+	int                     i,x,y;
+	unsigned        *blockstart;
+
+	if (MS_CheckParm ("virtual"))
+		virtualreality = true;
+	else
+		virtualreality = false;
+
+	MM_Startup ();                  // so the signon screen can be freed
+
+	SignonScreen ();
+
+	VW_Startup ();
+	IN_Startup ();
+	PM_Startup ();
+	PM_UnlockMainMem ();
+	SD_Startup ();
+	CA_Startup ();
+	US_Startup ();
+
+
+#ifndef SPEAR
+	if (mminfo.mainmem < 235000L)
+#else
+	if (mminfo.mainmem < 257000L && !MS_CheckParm("debugmode"))
+#endif
+	{
+		memptr screen;
+
+		CA_CacheGrChunk (ERRORSCREEN);
+		screen = grsegs[ERRORSCREEN];
+		ShutdownId();
+		movedata ((unsigned)screen,7+7*160,0xb800,0,17*160);
+		gotoxy (1,23);
+		exit(1);
+	}
+
+
+//
+// build some tables
+//
+	InitDigiMap ();
+
+	for (i=0;i<MAPSIZE;i++)
+	{
+		nearmapylookup[i] = &tilemap[0][0]+MAPSIZE*i;
+		farmapylookup[i] = i*64;
+	}
+
+	for (i=0;i<PORTTILESHIGH;i++)
+		uwidthtable[i] = UPDATEWIDE*i;
+
+	blockstart = &blockstarts[0];
+	for (y=0;y<UPDATEHIGH;y++)
+		for (x=0;x<UPDATEWIDE;x++)
+			*blockstart++ = SCREENWIDTH*16*y+x*TILEWIDTH;
+
+	updateptr = &update[0];
+
+	bufferofs = 0;
+	displayofs = 0;
+	ReadConfig ();
+
+
+//
+// HOLDING DOWN 'M' KEY?
+//
+#ifndef SPEARDEMO
+	if (Keyboard[sc_M])
+	  DoJukebox();
+	else
+#endif
+//
+// draw intro screen stuff
+//
+	if (!virtualreality)
+		IntroScreen ();
+
+//
+// load in and lock down some basic chunks
+//
+
+	CA_CacheGrChunk(STARTFONT);
+	MM_SetLock (&grsegs[STARTFONT],true);
+
+	LoadLatchMem ();
+	BuildTables ();          // trig tables
+	SetupWalls ();
+
+#if 0
+{
+int temp,i;
+temp = viewsize;
+	profilehandle = open("SCALERS.TXT", O_CREAT | O_WRONLY | O_TEXT);
+for (i=1;i<20;i++)
+	NewViewSize(i);
+viewsize = temp;
+close(profilehandle);
+}
+#endif
+
+	NewViewSize (viewsize);
+
+
+//
+// initialize variables
+//
+	InitRedShifts ();
+	if (!virtualreality)
+		FinishSignon();
+
+	displayofs = PAGE1START;
+	bufferofs = PAGE2START;
+
+	if (virtualreality)
+	{
+		NoWait = true;
+		geninterrupt(0x60);
+	}
+}
+
+//===========================================================================
+
+/*
+==========================
+=
+= SetViewSize
+=
+==========================
+*/
+
+boolean SetViewSize (unsigned width, unsigned height)
+{
+	viewwidth = width&~15;                  // must be divisable by 16
+	viewheight = height&~1;                 // must be even
+	centerx = viewwidth/2-1;
+	shootdelta = viewwidth/10;
+	screenofs = ((200-STATUSLINES-viewheight)/2*SCREENWIDTH+(320-viewwidth)/8);
+
+//
+// calculate trace angles and projection constants
+//
+	CalcProjection (FOCALLENGTH);
+
+//
+// build all needed compiled scalers
+//
+//	MM_BombOnError (false);
+	SetupScaling (viewwidth*1.5);
+#if 0
+	MM_BombOnError (true);
+	if (mmerror)
+	{
+		Quit ("Can't build scalers!");
+		mmerror = false;
+		return false;
+	}
+#endif
+	return true;
+}
+
+
+void ShowViewSize (int width)
+{
+	int     oldwidth,oldheight;
+
+	oldwidth = viewwidth;
+	oldheight = viewheight;
+
+	viewwidth = width*16;
+	viewheight = width*16*HEIGHTRATIO;
+	DrawPlayBorder ();
+
+	viewheight = oldheight;
+	viewwidth = oldwidth;
+}
+
+
+void NewViewSize (int width)
+{
+	CA_UpLevel ();
+	MM_SortMem ();
+	viewsize = width;
+	SetViewSize (width*16,width*16*HEIGHTRATIO);
+	CA_DownLevel ();
+}
+
+
+
+//===========================================================================
+
+/*
+==========================
+=
+= Quit
+=
+==========================
+*/
+
+void Quit (char *error)
+{
+	unsigned        finscreen;
+	memptr	screen;
+
+	if (virtualreality)
+		geninterrupt(0x61);
+
+	ClearMemory ();
+	if (!*error)
+	{
+	 #ifndef JAPAN
+	 CA_CacheGrChunk (ORDERSCREEN);
+	 screen = grsegs[ORDERSCREEN];
+	 #endif
+	 WriteConfig ();
+	}
+	else
+	{
+	 CA_CacheGrChunk (ERRORSCREEN);
+	 screen = grsegs[ERRORSCREEN];
+	}
+
+	ShutdownId ();
+
+	if (error && *error)
+	{
+	  movedata ((unsigned)screen,7,0xb800,0,7*160);
+	  gotoxy (10,4);
+	  puts(error);
+	  gotoxy (1,8);
+	  exit(1);
+	}
+	else
+	if (!error || !(*error))
+	{
+		clrscr();
+		#ifndef JAPAN
+		movedata ((unsigned)screen,7,0xb800,0,4000);
+		gotoxy(1,24);
+		#endif
+//asm	mov	bh,0
+//asm	mov	dh,23	// row
+//asm	mov	dl,0	// collumn
+//asm	mov ah,2
+//asm	int	0x10
+	}
+
+	exit(0);
+}
+
+//===========================================================================
+
+
+
+/*
+=====================
+=
+= DemoLoop
+=
+=====================
+*/
+
+static  char *ParmStrings[] = {"baby","easy","normal","hard",""};
+
+void    DemoLoop (void)
+{
+	static int LastDemo;
+	int     i,level;
+	long nsize;
+	memptr	nullblock;
+
+//
+// check for launch from ted
+//
+	if (tedlevel)
+	{
+		NoWait = true;
+		NewGame(1,0);
+
+		for (i = 1;i < _argc;i++)
+		{
+			if ( (level = US_CheckParm(_argv[i],ParmStrings)) != -1)
+			{
+			 gamestate.difficulty=level;
+			 break;
+			}
+		}
+
+#ifndef SPEAR
+		gamestate.episode = tedlevelnum/10;
+		gamestate.mapon = tedlevelnum%10;
+#else
+		gamestate.episode = 0;
+		gamestate.mapon = tedlevelnum;
+#endif
+		GameLoop();
+		Quit (NULL);
+	}
+
+
+//
+// main game cycle
+//
+
+
+//	nsize = (long)40*1024;
+//	MM_GetPtr(&nullblock,nsize);
+
+#ifndef DEMOTEST
+
+	#ifndef UPLOAD
+
+		#ifndef GOODTIMES
+		#ifndef SPEAR
+		#ifndef JAPAN
+		if (!NoWait)
+			NonShareware();
+		#endif
+		#else
+
+			#ifndef GOODTIMES
+			#ifndef SPEARDEMO
+			CopyProtection();
+			#endif
+			#endif
+
+		#endif
+		#endif
+	#endif
+
+	StartCPMusic(INTROSONG);
+
+#ifndef JAPAN
+	if (!NoWait)
+		PG13 ();
+#endif
+
+#endif
+
+	while (1)
+	{
+		while (!NoWait)
+		{
+//
+// title page
+//
+			MM_SortMem ();
+#ifndef DEMOTEST
+
+#ifdef SPEAR
+			CA_CacheGrChunk (TITLEPALETTE);
+
+			CA_CacheGrChunk (TITLE1PIC);
+			VWB_DrawPic (0,0,TITLE1PIC);
+			UNCACHEGRCHUNK (TITLE1PIC);
+
+			CA_CacheGrChunk (TITLE2PIC);
+			VWB_DrawPic (0,80,TITLE2PIC);
+			UNCACHEGRCHUNK (TITLE2PIC);
+			VW_UpdateScreen ();
+			VL_FadeIn(0,255,grsegs[TITLEPALETTE],30);
+
+			UNCACHEGRCHUNK (TITLEPALETTE);
+#else
+			CA_CacheScreen (TITLEPIC);
+			VW_UpdateScreen ();
+			VW_FadeIn();
+#endif
+			if (IN_UserInput(TickBase*15))
+				break;
+			VW_FadeOut();
+//
+// credits page
+//
+			CA_CacheScreen (CREDITSPIC);
+			VW_UpdateScreen();
+			VW_FadeIn ();
+			if (IN_UserInput(TickBase*10))
+				break;
+			VW_FadeOut ();
+//
+// high scores
+//
+			DrawHighScores ();
+			VW_UpdateScreen ();
+			VW_FadeIn ();
+
+			if (IN_UserInput(TickBase*10))
+				break;
+#endif
+//
+// demo
+//
+
+			#ifndef SPEARDEMO
+			PlayDemo (LastDemo++%4);
+			#else
+			PlayDemo (0);
+			#endif
+
+			if (playstate == ex_abort)
+				break;
+			StartCPMusic(INTROSONG);
+		}
+
+		VW_FadeOut ();
+
+#ifndef SPEAR
+		if (Keyboard[sc_Tab] && MS_CheckParm("goobers"))
+#else
+		if (Keyboard[sc_Tab] && MS_CheckParm("debugmode"))
+#endif
+			RecordDemo ();
+		else
+			US_ControlPanel (0);
+
+		if (startgame || loadedgame)
+		{
+			GameLoop ();
+			VW_FadeOut();
+			StartCPMusic(INTROSONG);
+		}
+	}
+}
+
+
+//===========================================================================
+
+
+/*
+==========================
+=
+= main
+=
+==========================
+*/
+
+char    *nosprtxt[] = {"nospr",nil};
+
+void main (void)
+{
+	int     i;
+
+
+#ifdef BETA
+	//
+	// THIS IS FOR BETA ONLY!
+	//
+	struct dosdate_t d;
+
+	_dos_getdate(&d);
+	if (d.year > YEAR ||
+		(d.month >= MONTH && d.day >= DAY))
+	{
+	 printf("Sorry, BETA-TESTING is over. Thanks for you help.\n");
+	 exit(1);
+	}
+#endif
+
+	CheckForEpisodes();
+
+	Patch386 ();
+
+	InitGame ();
+
+	DemoLoop();
+
+	Quit("Demo loop exited???");
+}
+
--- /dev/null
+++ b/WOLFSRC/WL_MENU.C
@@ -1,0 +1,3986 @@
+////////////////////////////////////////////////////////////////////
+//
+// WL_MENU.C
+// by John Romero (C) 1992 Id Software, Inc.
+//
+////////////////////////////////////////////////////////////////////
+#include "wl_def.h"
+#pragma hdrstop
+
+//
+// PRIVATE PROTOTYPES
+//
+void CP_ReadThis(void);
+
+#ifdef SPEAR
+#define STARTITEM	newgame
+
+#else
+#ifdef GOODTIMES
+#define STARTITEM	newgame
+
+#else
+#define STARTITEM	readthis
+#endif
+#endif
+
+char far endStrings[9][80]=
+{
+#ifndef SPEAR
+	{"Dost thou wish to\nleave with such hasty\nabandon?"},
+	{"Chickening out...\nalready?"},
+	{"Press N for more carnage.\nPress Y to be a weenie."},
+	{"So, you think you can\nquit this easily, huh?"},
+	{"Press N to save the world.\nPress Y to abandon it in\nits hour of need."},
+	{"Press N if you are brave.\nPress Y to cower in shame."},
+	{"Heroes, press N.\nWimps, press Y."},
+	{"You are at an intersection.\nA sign says, 'Press Y to quit.'\n>"},
+	{"For guns and glory, press N.\nFor work and worry, press Y."}
+#else
+	ENDSTR1,
+	ENDSTR2,
+	ENDSTR3,
+	ENDSTR4,
+	ENDSTR5,
+	ENDSTR6,
+	ENDSTR7,
+	ENDSTR8,
+	ENDSTR9
+#endif
+};
+
+CP_iteminfo
+	MainItems={MENU_X,MENU_Y,10,STARTITEM,24},
+	SndItems={SM_X,SM_Y1,12,0,52},
+	LSItems={LSM_X,LSM_Y,10,0,24},
+	CtlItems={CTL_X,CTL_Y,6,-1,56},
+	CusItems={8,CST_Y+13*2,9,-1,0},
+	NewEitems={NE_X,NE_Y,11,0,88},
+	NewItems={NM_X,NM_Y,4,2,24};
+
+#pragma warn -sus
+CP_itemtype far
+MainMenu[]=
+{
+#ifdef JAPAN
+	{1,"",CP_NewGame},
+	{1,"",CP_Sound},
+	{1,"",CP_Control},
+	{1,"",CP_LoadGame},
+	{0,"",CP_SaveGame},
+	{1,"",CP_ChangeView},
+	{2,"",CP_ReadThis},
+	{1,"",CP_ViewScores},
+	{1,"",0},
+	{1,"",0}
+#else
+
+	{1,STR_NG,CP_NewGame},
+	{1,STR_SD,CP_Sound},
+	{1,STR_CL,CP_Control},
+	{1,STR_LG,CP_LoadGame},
+	{0,STR_SG,CP_SaveGame},
+	{1,STR_CV,CP_ChangeView},
+
+#ifndef GOODTIMES
+#ifndef SPEAR
+
+	#ifdef SPANISH
+	{2,"Ve esto!",CP_ReadThis},
+	#else
+	{2,"Read This!",CP_ReadThis},
+	#endif
+
+#endif
+#endif
+
+	{1,STR_VS,CP_ViewScores},
+	{1,STR_BD,0},
+	{1,STR_QT,0}
+#endif
+},
+
+far SndMenu[]=
+{
+#ifdef JAPAN
+	{1,"",0},
+	{1,"",0},
+	{1,"",0},
+	{0,"",0},
+	{0,"",0},
+	{1,"",0},
+	{1,"",0},
+	{1,"",0},
+	{0,"",0},
+	{0,"",0},
+	{1,"",0},
+	{1,"",0},
+#else
+	{1,STR_NONE,0},
+	{1,STR_PC,0},
+	{1,STR_ALSB,0},
+	{0,"",0},
+	{0,"",0},
+	{1,STR_NONE,0},
+	{1,STR_DISNEY,0},
+	{1,STR_SB,0},
+	{0,"",0},
+	{0,"",0},
+	{1,STR_NONE,0},
+	{1,STR_ALSB,0}
+#endif
+},
+
+far CtlMenu[]=
+{
+#ifdef JAPAN
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",MouseSensitivity},
+	{1,"",CustomControls}
+#else
+	{0,STR_MOUSEEN,0},
+	{0,STR_JOYEN,0},
+	{0,STR_PORT2,0},
+	{0,STR_GAMEPAD,0},
+	{0,STR_SENS,MouseSensitivity},
+	{1,STR_CUSTOM,CustomControls}
+#endif
+},
+
+#pragma warn +sus
+
+#ifndef SPEAR
+far NewEmenu[]=
+{
+#ifdef JAPAN
+#ifdef JAPDEMO
+	{1,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+	{0,"",0},
+#else
+	{1,"",0},
+	{0,"",0},
+	{1,"",0},
+	{0,"",0},
+	{1,"",0},
+	{0,"",0},
+	{1,"",0},
+	{0,"",0},
+	{1,"",0},
+	{0,"",0},
+	{1,"",0},
+	{0,"",0}
+#endif
+#else
+	#ifdef SPANISH
+	{1,"Episodio 1\n"
+	   "Fuga desde Wolfenstein",0},
+	{0,"",0},
+	{3,"Episodio 2\n"
+		   "Operacion Eisenfaust",0},
+	{0,"",0},
+	{3,"Episodio 3\n"
+		   "Muere, Fuhrer, Muere!",0},
+	{0,"",0},
+	{3,"Episodio 4\n"
+		  "Un Negro Secreto",0},
+	{0,"",0},
+	{3,"Episodio 5\n"
+		  "Huellas del Loco",0},
+	{0,"",0},
+	{3,"Episodio 6\n"
+		  "Confrontacion",0}
+	#else
+	{1,"Episode 1\n"
+	   "Escape from Wolfenstein",0},
+	{0,"",0},
+	{3,"Episode 2\n"
+		   "Operation: Eisenfaust",0},
+	{0,"",0},
+	{3,"Episode 3\n"
+		   "Die, Fuhrer, Die!",0},
+	{0,"",0},
+	{3,"Episode 4\n"
+		  "A Dark Secret",0},
+	{0,"",0},
+	{3,"Episode 5\n"
+		  "Trail of the Madman",0},
+	{0,"",0},
+	{3,"Episode 6\n"
+		  "Confrontation",0}
+	#endif
+#endif
+},
+#endif
+
+
+far NewMenu[]=
+{
+#ifdef JAPAN
+	{1,"",0},
+	{1,"",0},
+	{1,"",0},
+	{1,"",0}
+#else
+	{1,STR_DADDY,0},
+	{1,STR_HURTME,0},
+	{1,STR_BRINGEM,0},
+	{1,STR_DEATH,0}
+#endif
+},
+
+far LSMenu[]=
+{
+	{1,"",0},
+	{1,"",0},
+	{1,"",0},
+	{1,"",0},
+	{1,"",0},
+	{1,"",0},
+	{1,"",0},
+	{1,"",0},
+	{1,"",0},
+	{1,"",0}
+},
+
+far CusMenu[]=
+{
+	{1,"",0},
+	{0,"",0},
+	{0,"",0},
+	{1,"",0},
+	{0,"",0},
+	{0,"",0},
+	{1,"",0},
+	{0,"",0},
+	{1,"",0}
+}
+;
+
+
+int color_hlite[]={
+   DEACTIVE,
+   HIGHLIGHT,
+   READHCOLOR,
+   0x67
+   },
+
+   color_norml[]={
+   DEACTIVE,
+   TEXTCOLOR,
+   READCOLOR,
+   0x6b
+   };
+
+int EpisodeSelect[6]={1};
+
+
+int SaveGamesAvail[10],StartGame,SoundStatus=1,pickquick;
+char SaveGameNames[10][32],SaveName[13]="SAVEGAM?.";
+
+
+////////////////////////////////////////////////////////////////////
+//
+// INPUT MANAGER SCANCODE TABLES
+//
+////////////////////////////////////////////////////////////////////
+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","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
+	"?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
+	"?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"
+					},	// DEBUG - consolidate these
+					far ExtScanCodes[] =	// Scan codes with >1 char names
+					{
+	1,0xe,0xf,0x1d,0x2a,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,
+	0x3f,0x40,0x41,0x42,0x43,0x44,0x57,0x59,0x46,0x1c,0x36,
+	0x37,0x38,0x47,0x49,0x4f,0x51,0x52,0x53,0x45,0x48,
+	0x50,0x4b,0x4d,0x00
+					},
+					*ExtScanNames[] =	// Names corresponding to ExtScanCodes
+					{
+	"Esc","BkSp","Tab","Ctrl","LShft","Space","CapsLk","F1","F2","F3","F4",
+	"F5","F6","F7","F8","F9","F10","F11","F12","ScrlLk","Enter","RShft",
+	"PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up",
+	"Down","Left","Right",""
+					};
+
+
+////////////////////////////////////////////////////////////////////
+//
+// Wolfenstein Control Panel!  Ta Da!
+//
+////////////////////////////////////////////////////////////////////
+void US_ControlPanel(byte scancode)
+{
+	int which,i,start;
+
+
+	if (ingame)
+		if (CP_CheckQuick(scancode))
+			return;
+
+	StartCPMusic(MENUSONG);
+	SetupControlPanel();
+
+	//
+	// F-KEYS FROM WITHIN GAME
+	//
+	switch(scancode)
+	{
+		case sc_F1:
+			#ifdef SPEAR
+			BossKey();
+			#else
+			#ifdef GOODTIMES
+			BossKey();
+			#else
+			HelpScreens();
+			#endif
+			#endif
+			goto finishup;
+
+		case sc_F2:
+			CP_SaveGame(0);
+			goto finishup;
+
+		case sc_F3:
+			CP_LoadGame(0);
+			goto finishup;
+
+		case sc_F4:
+			CP_Sound();
+			goto finishup;
+
+		case sc_F5:
+			CP_ChangeView();
+			goto finishup;
+
+		case sc_F6:
+			CP_Control();
+			goto finishup;
+
+		finishup:
+			CleanupControlPanel();
+			#ifdef SPEAR
+			UnCacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+			#endif
+			return;
+	}
+
+#ifdef SPEAR
+	CacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+#endif
+
+	DrawMainMenu();
+	MenuFadeIn();
+	StartGame=0;
+
+	//
+	// MAIN MENU LOOP
+	//
+	do
+	{
+		which=HandleMenu(&MainItems,&MainMenu[0],NULL);
+
+		#ifdef SPEAR
+		#ifndef SPEARDEMO
+		//
+		// EASTER EGG FOR SPEAR OF DESTINY!
+		//
+		if (Keyboard[sc_I] && Keyboard[sc_D])
+		{
+			VW_FadeOut();
+			StartCPMusic (XJAZNAZI_MUS);
+			UnCacheLump(OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+			UnCacheLump(BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+			MM_SortMem ();
+			ClearMemory ();
+
+
+			CA_CacheGrChunk (IDGUYS1PIC);
+			VWB_DrawPic(0,0,IDGUYS1PIC);
+			UNCACHEGRCHUNK(IDGUYS1PIC);
+
+			CA_CacheGrChunk (IDGUYS2PIC);
+			VWB_DrawPic(0,80,IDGUYS2PIC);
+			UNCACHEGRCHUNK(IDGUYS2PIC);
+
+			VW_UpdateScreen();
+
+			CA_CacheGrChunk (IDGUYSPALETTE);
+			VL_FadeIn(0,255,grsegs[IDGUYSPALETTE],30);
+			UNCACHEGRCHUNK(IDGUYSPALETTE);
+
+			while (Keyboard[sc_I] || Keyboard[sc_D]);
+			IN_ClearKeysDown();
+			IN_Ack();
+
+			VW_FadeOut();
+
+			CacheLump(BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+			CacheLump(OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+			DrawMainMenu();
+			StartCPMusic (MENUSONG);
+			MenuFadeIn();
+		}
+		#endif
+		#endif
+
+		switch(which)
+		{
+			case viewscores:
+				if (MainMenu[viewscores].routine == NULL)
+					if (CP_EndGame())
+						StartGame=1;
+
+				DrawMainMenu();
+				MenuFadeIn();
+				break;
+
+			case backtodemo:
+				#ifdef SPEAR
+				if (!ingame)
+				{
+					//
+					// DEALLOCATE ALL SOUNDS!
+					//
+					switch (SoundMode)
+					{
+						case sdm_PC:
+							start = STARTPCSOUNDS;
+							break;
+						case sdm_AdLib:
+							start = STARTADLIBSOUNDS;
+							break;
+					}
+
+					if (SoundMode != sdm_Off)
+						for (i=0;i<NUMSOUNDS;i++,start++)
+							if (audiosegs[start])
+								MM_SetPurge (&(memptr)audiosegs[start],3);		// make purgable
+				}
+				#endif
+
+				MM_SortMem();
+				StartGame=1;
+				if (!ingame)
+					StartCPMusic(INTROSONG);
+				VL_FadeOut(0,255,0,0,0,10);
+				break;
+
+			case -1:
+			case quit:
+				CP_Quit();
+				break;
+
+			default:
+				if (!StartGame)
+				{
+					DrawMainMenu();
+					MenuFadeIn();
+				}
+		}
+
+	//
+	// "EXIT OPTIONS" OR "NEW GAME" EXITS
+	//
+	} while(!StartGame);
+
+	//
+	// DEALLOCATE EVERYTHING
+	//
+	CleanupControlPanel();
+
+	//
+	// CHANGE MAINMENU ITEM
+	//
+	if (startgame || loadedgame)
+	{
+		#pragma warn -sus
+		MainMenu[viewscores].routine = NULL;
+		#ifndef JAPAN
+		_fstrcpy(MainMenu[viewscores].string,STR_EG);
+		#endif
+		#pragma warn +sus
+	}
+
+	// RETURN/START GAME EXECUTION
+
+#ifdef SPEAR
+	UnCacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+	MM_SortMem ();
+#endif
+}
+
+
+////////////////////////
+//
+// DRAW MAIN MENU SCREEN
+//
+void DrawMainMenu(void)
+{
+#ifdef JAPAN
+	CA_CacheScreen(S_OPTIONSPIC);
+#else
+	ClearMScreen();
+
+	VWB_DrawPic(112,184,C_MOUSELBACKPIC);
+	DrawStripes(10);
+	VWB_DrawPic(84,0,C_OPTIONSPIC);
+
+	#ifdef SPANISH
+	DrawWindow(MENU_X-8,MENU_Y-3,MENU_W+8,MENU_H,BKGDCOLOR);
+	#else
+	DrawWindow(MENU_X-8,MENU_Y-3,MENU_W,MENU_H,BKGDCOLOR);
+	#endif
+#endif
+
+	//
+	// CHANGE "GAME" AND "DEMO"
+	//
+	if (ingame)
+	{
+		#ifndef JAPAN
+
+		#ifdef SPANISH
+		_fstrcpy(&MainMenu[backtodemo].string,STR_GAME);
+		#else
+		_fstrcpy(&MainMenu[backtodemo].string[8],STR_GAME);
+		#endif
+
+		#else
+		CA_CacheGrChunk(C_MRETGAMEPIC);
+		VWB_DrawPic(12*8,20*8,C_MRETGAMEPIC);
+		UNCACHEGRCHUNK(C_MRETGAMEPIC);
+		CA_CacheGrChunk(C_MENDGAMEPIC);
+		VWB_DrawPic(12*8,18*8,C_MENDGAMEPIC);
+		UNCACHEGRCHUNK(C_MENDGAMEPIC);
+		#endif
+		MainMenu[backtodemo].active=2;
+	}
+	else
+	{
+		#ifndef JAPAN
+		#ifdef SPANISH
+		_fstrcpy(&MainMenu[backtodemo].string,STR_BD);
+		#else
+		_fstrcpy(&MainMenu[backtodemo].string[8],STR_DEMO);
+		#endif
+		#else
+		CA_CacheGrChunk(C_MRETDEMOPIC);
+		VWB_DrawPic(12*8,20*8,C_MRETDEMOPIC);
+		UNCACHEGRCHUNK(C_MRETDEMOPIC);
+		CA_CacheGrChunk(C_MSCORESPIC);
+		VWB_DrawPic(12*8,18*8,C_MSCORESPIC);
+		UNCACHEGRCHUNK(C_MSCORESPIC);
+		#endif
+		MainMenu[backtodemo].active=1;
+	}
+
+	DrawMenu(&MainItems,&MainMenu[0]);
+	VW_UpdateScreen();
+}
+
+#ifndef GOODTIMES
+#ifndef SPEAR
+////////////////////////////////////////////////////////////////////
+//
+// READ THIS!
+//
+////////////////////////////////////////////////////////////////////
+void CP_ReadThis(void)
+{
+	StartCPMusic(CORNER_MUS);
+	HelpScreens();
+	StartCPMusic(MENUSONG);
+}
+#endif
+#endif
+
+#ifndef SPEAR
+#ifndef GOODTIMES
+#else
+////////////////////////////////////////////////////////////////////
+//
+// BOSS KEY
+//
+////////////////////////////////////////////////////////////////////
+void BossKey(void)
+{
+	SD_MusicOff();
+	_AX = 3;
+	geninterrupt(0x10);
+	printf("C>");
+	while (!Keyboard[sc_Escape])
+	IN_ClearKeysDown();
+
+	SD_MusicOn();
+	VL_SetVGAPlaneMode ();
+	VL_TestPaletteSet ();
+	VL_SetPalette (&gamepal);
+	LoadLatchMem();
+}
+#endif
+#endif
+
+////////////////////////////////////////////////////////////////////
+//
+// CHECK QUICK-KEYS & QUIT (WHILE IN A GAME)
+//
+////////////////////////////////////////////////////////////////////
+int CP_CheckQuick(unsigned scancode)
+{
+	switch(scancode)
+	{
+		//
+		// END GAME
+		//
+		case sc_F7:
+			CA_CacheGrChunk(STARTFONT+1);
+
+			WindowH=160;
+			#ifdef JAPAN
+			if (GetYorN(7,8,C_JAPQUITPIC))
+			#else
+			if (Confirm(ENDGAMESTR))
+			#endif
+			{
+				playstate = ex_died;
+				pickquick = gamestate.lives = 0;
+			}
+
+			DrawAllPlayBorder();
+			WindowH=200;
+			fontnumber=0;
+			MainMenu[savegame].active = 0;
+			return 1;
+
+		//
+		// QUICKSAVE
+		//
+		case sc_F8:
+			if (SaveGamesAvail[LSItems.curpos] && pickquick)
+			{
+				CA_CacheGrChunk(STARTFONT+1);
+				fontnumber = 1;
+				Message(STR_SAVING"...");
+				CP_SaveGame(1);
+				fontnumber=0;
+			}
+			else
+			{
+				#ifndef SPEAR
+				CA_CacheGrChunk(STARTFONT+1);
+				CA_CacheGrChunk(C_CURSOR1PIC);
+				CA_CacheGrChunk(C_CURSOR2PIC);
+				CA_CacheGrChunk(C_DISKLOADING1PIC);
+				CA_CacheGrChunk(C_DISKLOADING2PIC);
+				CA_CacheGrChunk(C_SAVEGAMEPIC);
+				CA_CacheGrChunk(C_MOUSELBACKPIC);
+				#else
+				CacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+				CA_CacheGrChunk(C_CURSOR1PIC);
+				#endif
+
+				VW_FadeOut ();
+
+				StartCPMusic(MENUSONG);
+				pickquick=CP_SaveGame(0);
+
+				SETFONTCOLOR(0,15);
+				IN_ClearKeysDown();
+				DrawPlayScreen ();
+
+				if (!startgame && !loadedgame)
+				{
+					VW_FadeIn ();
+					StartMusic ();
+				}
+
+				if (loadedgame)
+					playstate = ex_abort;
+				lasttimecount = TimeCount;
+
+				if (MousePresent)
+					Mouse(MDelta);	// Clear accumulated mouse movement
+
+				PM_CheckMainMem ();
+
+				#ifndef SPEAR
+				UNCACHEGRCHUNK(C_CURSOR1PIC);
+				UNCACHEGRCHUNK(C_CURSOR2PIC);
+				UNCACHEGRCHUNK(C_DISKLOADING1PIC);
+				UNCACHEGRCHUNK(C_DISKLOADING2PIC);
+				UNCACHEGRCHUNK(C_SAVEGAMEPIC);
+				UNCACHEGRCHUNK(C_MOUSELBACKPIC);
+				#else
+				UnCacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+				#endif
+			}
+			return 1;
+
+		//
+		// QUICKLOAD
+		//
+		case sc_F9:
+			if (SaveGamesAvail[LSItems.curpos] && pickquick)
+			{
+				char string[100]=STR_LGC;
+
+
+				CA_CacheGrChunk(STARTFONT+1);
+				fontnumber = 1;
+
+				strcat(string,SaveGameNames[LSItems.curpos]);
+				strcat(string,"\"?");
+
+				if (Confirm(string))
+					CP_LoadGame(1);
+
+				DrawAllPlayBorder();
+				fontnumber=0;
+			}
+			else
+			{
+				#ifndef SPEAR
+				CA_CacheGrChunk(STARTFONT+1);
+				CA_CacheGrChunk(C_CURSOR1PIC);
+				CA_CacheGrChunk(C_CURSOR2PIC);
+				CA_CacheGrChunk(C_DISKLOADING1PIC);
+				CA_CacheGrChunk(C_DISKLOADING2PIC);
+				CA_CacheGrChunk(C_LOADGAMEPIC);
+				CA_CacheGrChunk(C_MOUSELBACKPIC);
+				#else
+				CA_CacheGrChunk(C_CURSOR1PIC);
+				CacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+				#endif
+
+				VW_FadeOut ();
+
+				StartCPMusic(MENUSONG);
+				pickquick=CP_LoadGame(0);
+
+				SETFONTCOLOR(0,15);
+				IN_ClearKeysDown();
+				DrawPlayScreen ();
+
+				if (!startgame && !loadedgame)
+				{
+					VW_FadeIn ();
+					StartMusic ();
+				}
+
+				if (loadedgame)
+					playstate = ex_abort;
+
+				lasttimecount = TimeCount;
+
+				if (MousePresent)
+					Mouse(MDelta);	// Clear accumulated mouse movement
+				PM_CheckMainMem ();
+
+				#ifndef SPEAR
+				UNCACHEGRCHUNK(C_CURSOR1PIC);
+				UNCACHEGRCHUNK(C_CURSOR2PIC);
+				UNCACHEGRCHUNK(C_DISKLOADING1PIC);
+				UNCACHEGRCHUNK(C_DISKLOADING2PIC);
+				UNCACHEGRCHUNK(C_LOADGAMEPIC);
+				UNCACHEGRCHUNK(C_MOUSELBACKPIC);
+				#else
+				UnCacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+				#endif
+			}
+			return 1;
+
+		//
+		// QUIT
+		//
+		case sc_F10:
+			CA_CacheGrChunk(STARTFONT+1);
+
+			WindowX=WindowY=0;
+			WindowW=320;
+			WindowH=160;
+			#ifdef JAPAN
+			if (GetYorN(7,8,C_QUITMSGPIC))
+			#else
+				#ifdef SPANISH
+			if (Confirm(ENDGAMESTR))
+				#else
+			if (Confirm(endStrings[US_RndT()&0x7+(US_RndT()&1)]))
+				#endif
+			#endif
+			{
+				int i;
+
+
+				VW_UpdateScreen();
+				SD_MusicOff();
+				SD_StopSound();
+				MenuFadeOut();
+
+				//
+				// SHUT-UP THE ADLIB
+				//
+				for (i=1;i<=0xf5;i++)
+					alOut(i,0);
+				Quit(NULL);
+			}
+
+			DrawAllPlayBorder();
+			WindowH=200;
+			fontnumber=0;
+			return 1;
+		}
+
+	return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// END THE CURRENT GAME
+//
+////////////////////////////////////////////////////////////////////
+int CP_EndGame(void)
+{
+#ifdef JAPAN
+	if (!GetYorN(7,8,C_JAPQUITPIC))
+#else
+	if (!Confirm(ENDGAMESTR))
+#endif
+		return 0;
+
+	pickquick = gamestate.lives = 0;
+	playstate = ex_died;
+
+	#pragma warn -sus
+	MainMenu[savegame].active = 0;
+	MainMenu[viewscores].routine=CP_ViewScores;
+	#ifndef JAPAN
+	_fstrcpy(MainMenu[viewscores].string,STR_VS);
+	#endif
+	#pragma warn +sus
+
+	return 1;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// VIEW THE HIGH SCORES
+//
+////////////////////////////////////////////////////////////////////
+void CP_ViewScores(void)
+{
+	fontnumber=0;
+
+#ifdef SPEAR
+	UnCacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+	StartCPMusic (XAWARD_MUS);
+#else
+	StartCPMusic (ROSTER_MUS);
+#endif
+
+	DrawHighScores ();
+	VW_UpdateScreen ();
+	MenuFadeIn();
+	fontnumber=1;
+
+	IN_Ack();
+
+	StartCPMusic(MENUSONG);
+	MenuFadeOut();
+
+#ifdef SPEAR
+	CacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+	CacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+#endif
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// START A NEW GAME
+//
+////////////////////////////////////////////////////////////////////
+void CP_NewGame(void)
+{
+	int which,episode;
+
+#ifdef SPEAR
+	UnCacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+#endif
+
+
+#ifndef SPEAR
+firstpart:
+
+	DrawNewEpisode();
+	do
+	{
+		which=HandleMenu(&NewEitems,&NewEmenu[0],NULL);
+		switch(which)
+		{
+			case -1:
+				MenuFadeOut();
+				return;
+
+			default:
+				if (!EpisodeSelect[which/2])
+				{
+					SD_PlaySound (NOWAYSND);
+					Message("Please select \"Read This!\"\n"
+							"from the Options menu to\n"
+							"find out how to order this\n"
+							"episode from Apogee.");
+					IN_ClearKeysDown();
+					IN_Ack();
+					DrawNewEpisode();
+					which = 0;
+				}
+				else
+				{
+					episode = which/2;
+					which = 1;
+				}
+				break;
+		}
+
+	} while (!which);
+
+	ShootSnd();
+
+	//
+	// ALREADY IN A GAME?
+	//
+	if (ingame)
+		#ifdef JAPAN
+		if (!GetYorN(7,8,C_JAPNEWGAMEPIC))
+		#else
+		if (!Confirm(CURGAME))
+		#endif
+		{
+			MenuFadeOut();
+			return;
+		}
+
+	MenuFadeOut();
+
+#else
+	episode = 0;
+
+	//
+	// ALREADY IN A GAME?
+	//
+	CacheLump (NEWGAME_LUMP_START,NEWGAME_LUMP_END);
+	DrawNewGame();
+	if (ingame)
+		if (!Confirm(CURGAME))
+		{
+			MenuFadeOut();
+			UnCacheLump (NEWGAME_LUMP_START,NEWGAME_LUMP_END);
+			CacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+			return;
+		}
+
+#endif
+
+	DrawNewGame();
+	which=HandleMenu(&NewItems,&NewMenu[0],DrawNewGameDiff);
+	if (which<0)
+	{
+		MenuFadeOut();
+		#ifndef SPEAR
+		goto firstpart;
+		#else
+		UnCacheLump (NEWGAME_LUMP_START,NEWGAME_LUMP_END);
+		CacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+		return;
+		#endif
+	}
+
+	ShootSnd();
+	NewGame(which,episode);
+	StartGame=1;
+	MenuFadeOut();
+
+	//
+	// CHANGE "READ THIS!" TO NORMAL COLOR
+	//
+	#ifndef SPEAR
+	#ifndef GOODTIMES
+	MainMenu[readthis].active=1;
+	#endif
+	#endif
+
+	pickquick = 0;
+
+#ifdef SPEAR
+	UnCacheLump (NEWGAME_LUMP_START,NEWGAME_LUMP_END);
+	CacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+#endif
+}
+
+
+#ifndef SPEAR
+/////////////////////
+//
+// DRAW NEW EPISODE MENU
+//
+void DrawNewEpisode(void)
+{
+	int i;
+
+#ifdef JAPAN
+	CA_CacheScreen(S_EPISODEPIC);
+#else
+	ClearMScreen();
+	VWB_DrawPic(112,184,C_MOUSELBACKPIC);
+
+	DrawWindow(NE_X-4,NE_Y-4,NE_W+8,NE_H+8,BKGDCOLOR);
+	SETFONTCOLOR(READHCOLOR,BKGDCOLOR);
+	PrintY=2;
+	WindowX=0;
+	#ifdef SPANISH
+	US_CPrint("Cual episodio jugar?");
+	#else
+	US_CPrint("Which episode to play?");
+	#endif
+#endif
+
+	SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+	DrawMenu(&NewEitems,&NewEmenu[0]);
+
+	for (i=0;i<6;i++)
+		VWB_DrawPic(NE_X+32,NE_Y+i*26,C_EPISODE1PIC+i);
+
+	VW_UpdateScreen();
+	MenuFadeIn();
+	WaitKeyUp();
+}
+#endif
+
+/////////////////////
+//
+// DRAW NEW GAME MENU
+//
+void DrawNewGame(void)
+{
+#ifdef JAPAN
+	CA_CacheScreen(S_SKILLPIC);
+#else
+	ClearMScreen();
+	VWB_DrawPic(112,184,C_MOUSELBACKPIC);
+
+	SETFONTCOLOR(READHCOLOR,BKGDCOLOR);
+	PrintX=NM_X+20;
+	PrintY=NM_Y-32;
+
+#ifndef SPEAR
+	#ifdef SPANISH
+	US_Print("Eres macho?");
+	#else
+	US_Print("How tough are you?");
+	#endif
+#else
+	VWB_DrawPic (PrintX,PrintY,C_HOWTOUGHPIC);
+#endif
+
+	DrawWindow(NM_X-5,NM_Y-10,NM_W,NM_H,BKGDCOLOR);
+#endif
+
+	DrawMenu(&NewItems,&NewMenu[0]);
+	DrawNewGameDiff(NewItems.curpos);
+	VW_UpdateScreen();
+	MenuFadeIn();
+	WaitKeyUp();
+}
+
+
+////////////////////////
+//
+// DRAW NEW GAME GRAPHIC
+//
+void DrawNewGameDiff(int w)
+{
+	VWB_DrawPic(NM_X+185,NM_Y+7,w+C_BABYMODEPIC);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// HANDLE SOUND MENU
+//
+////////////////////////////////////////////////////////////////////
+void CP_Sound(void)
+{
+	int which,i;
+
+
+#ifdef SPEAR
+	UnCacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+	CacheLump (SOUND_LUMP_START,SOUND_LUMP_END);
+#endif
+
+	DrawSoundMenu();
+	MenuFadeIn();
+	WaitKeyUp();
+
+	do
+	{
+		which=HandleMenu(&SndItems,&SndMenu[0],NULL);
+		//
+		// HANDLE MENU CHOICES
+		//
+		switch(which)
+		{
+			//
+			// SOUND EFFECTS
+			//
+			case 0:
+				if (SoundMode!=sdm_Off)
+				{
+					SD_WaitSoundDone();
+					SD_SetSoundMode(sdm_Off);
+					DrawSoundMenu();
+				}
+				break;
+			case 1:
+				if (SoundMode!=sdm_PC)
+				{
+					SD_WaitSoundDone();
+					SD_SetSoundMode(sdm_PC);
+					CA_LoadAllSounds();
+					DrawSoundMenu();
+					ShootSnd();
+				}
+				break;
+			case 2:
+				if (SoundMode!=sdm_AdLib)
+				{
+					SD_WaitSoundDone();
+					SD_SetSoundMode(sdm_AdLib);
+					CA_LoadAllSounds();
+					DrawSoundMenu();
+					ShootSnd();
+				}
+				break;
+
+			//
+			// DIGITIZED SOUND
+			//
+			case 5:
+				if (DigiMode!=sds_Off)
+				{
+					SD_SetDigiDevice(sds_Off);
+					DrawSoundMenu();
+				}
+				break;
+			case 6:
+				if (DigiMode!=sds_SoundSource)
+				{
+					SD_SetDigiDevice(sds_SoundSource);
+					DrawSoundMenu();
+					ShootSnd();
+				}
+				break;
+			case 7:
+				if (DigiMode!=sds_SoundBlaster)
+				{
+					SD_SetDigiDevice(sds_SoundBlaster);
+					DrawSoundMenu();
+					ShootSnd();
+				}
+				break;
+
+			//
+			// MUSIC
+			//
+			case 10:
+				if (MusicMode!=smm_Off)
+				{
+					SD_SetMusicMode(smm_Off);
+					DrawSoundMenu();
+					ShootSnd();
+				}
+				break;
+			case 11:
+				if (MusicMode!=smm_AdLib)
+				{
+					SD_SetMusicMode(smm_AdLib);
+					DrawSoundMenu();
+					ShootSnd();
+					StartCPMusic(MENUSONG);
+				}
+				break;
+		}
+	} while(which>=0);
+
+	MenuFadeOut();
+
+#ifdef SPEAR
+	UnCacheLump (SOUND_LUMP_START,SOUND_LUMP_END);
+	CacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+#endif
+}
+
+
+//////////////////////
+//
+// DRAW THE SOUND MENU
+//
+void DrawSoundMenu(void)
+{
+	int i,on;
+
+
+#ifdef JAPAN
+	CA_CacheScreen(S_SOUNDPIC);
+#else
+	//
+	// DRAW SOUND MENU
+	//
+	ClearMScreen();
+	VWB_DrawPic(112,184,C_MOUSELBACKPIC);
+
+	DrawWindow(SM_X-8,SM_Y1-3,SM_W,SM_H1,BKGDCOLOR);
+	DrawWindow(SM_X-8,SM_Y2-3,SM_W,SM_H2,BKGDCOLOR);
+	DrawWindow(SM_X-8,SM_Y3-3,SM_W,SM_H3,BKGDCOLOR);
+#endif
+
+	//
+	// IF NO ADLIB, NON-CHOOSENESS!
+	//
+	if (!AdLibPresent && !SoundBlasterPresent)
+	{
+		SndMenu[2].active=SndMenu[10].active=SndMenu[11].active=0;
+	}
+
+	if (!SoundSourcePresent)
+		SndMenu[6].active=0;
+
+	if (!SoundBlasterPresent)
+		SndMenu[7].active=0;
+
+	if (!SoundSourcePresent && !SoundBlasterPresent)
+		SndMenu[5].active=0;
+
+	DrawMenu(&SndItems,&SndMenu[0]);
+#ifndef JAPAN
+	VWB_DrawPic(100,SM_Y1-20,C_FXTITLEPIC);
+	VWB_DrawPic(100,SM_Y2-20,C_DIGITITLEPIC);
+	VWB_DrawPic(100,SM_Y3-20,C_MUSICTITLEPIC);
+#endif
+
+	for (i=0;i<SndItems.amount;i++)
+#ifdef JAPAN
+		if (i!=3 && i!=4 && i!=8 && i!=9)
+#else
+		if (SndMenu[i].string[0])
+#endif
+		{
+			//
+			// DRAW SELECTED/NOT SELECTED GRAPHIC BUTTONS
+			//
+			on=0;
+			switch(i)
+			{
+				//
+				// SOUND EFFECTS
+				//
+				case 0: if (SoundMode==sdm_Off) on=1; break;
+				case 1: if (SoundMode==sdm_PC) on=1; break;
+				case 2: if (SoundMode==sdm_AdLib) on=1; break;
+
+				//
+				// DIGITIZED SOUND
+				//
+				case 5: if (DigiMode==sds_Off) on=1; break;
+				case 6: if (DigiMode==sds_SoundSource) on=1; break;
+				case 7: if (DigiMode==sds_SoundBlaster) on=1; break;
+
+				//
+				// MUSIC
+				//
+				case 10: if (MusicMode==smm_Off) on=1; break;
+				case 11: if (MusicMode==smm_AdLib) on=1; break;
+			}
+
+			if (on)
+				VWB_DrawPic(SM_X+24,SM_Y1+i*13+2,C_SELECTEDPIC);
+			else
+				VWB_DrawPic(SM_X+24,SM_Y1+i*13+2,C_NOTSELECTEDPIC);
+		}
+
+	DrawMenuGun(&SndItems);
+	VW_UpdateScreen();
+}
+
+
+//
+// DRAW LOAD/SAVE IN PROGRESS
+//
+void DrawLSAction(int which)
+{
+	#define LSA_X	96
+	#define LSA_Y	80
+	#define LSA_W	130
+	#define LSA_H	42
+
+	DrawWindow(LSA_X,LSA_Y,LSA_W,LSA_H,TEXTCOLOR);
+	DrawOutline(LSA_X,LSA_Y,LSA_W,LSA_H,0,HIGHLIGHT);
+	VWB_DrawPic(LSA_X+8,LSA_Y+5,C_DISKLOADING1PIC);
+
+	fontnumber=1;
+	SETFONTCOLOR(0,TEXTCOLOR);
+	PrintX=LSA_X+46;
+	PrintY=LSA_Y+13;
+
+	if (!which)
+		US_Print(STR_LOADING"...");
+	else
+		US_Print(STR_SAVING"...");
+
+	VW_UpdateScreen();
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// LOAD SAVED GAMES
+//
+////////////////////////////////////////////////////////////////////
+int CP_LoadGame(int quick)
+{
+	int handle,which,exit=0;
+	char name[13];
+
+
+	strcpy(name,SaveName);
+
+	//
+	// QUICKLOAD?
+	//
+	if (quick)
+	{
+		which=LSItems.curpos;
+
+		if (SaveGamesAvail[which])
+		{
+			name[7]=which+'0';
+			handle=open(name,O_BINARY);
+			lseek(handle,32,SEEK_SET);
+			loadedgame=true;
+			LoadTheGame(handle,0,0);
+			loadedgame=false;
+			close(handle);
+
+			DrawFace ();
+			DrawHealth ();
+			DrawLives ();
+			DrawLevel ();
+			DrawAmmo ();
+			DrawKeys ();
+			DrawWeapon ();
+			DrawScore ();
+			return 1;
+		}
+	}
+
+
+#ifdef SPEAR
+	UnCacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+	CacheLump (LOADSAVE_LUMP_START,LOADSAVE_LUMP_END);
+#endif
+
+	DrawLoadSaveScreen(0);
+
+	do
+	{
+		which=HandleMenu(&LSItems,&LSMenu[0],TrackWhichGame);
+		if (which>=0 && SaveGamesAvail[which])
+		{
+			ShootSnd();
+			name[7]=which+'0';
+
+			handle=open(name,O_BINARY);
+			lseek(handle,32,SEEK_SET);
+
+			DrawLSAction(0);
+			loadedgame=true;
+
+			LoadTheGame(handle,LSA_X+8,LSA_Y+5);
+			close(handle);
+
+			StartGame=1;
+			ShootSnd();
+			//
+			// CHANGE "READ THIS!" TO NORMAL COLOR
+			//
+
+			#ifndef SPEAR
+			#ifndef GOODTIMES
+			MainMenu[readthis].active=1;
+			#endif
+			#endif
+
+			exit=1;
+			break;
+		}
+
+	} while(which>=0);
+
+	MenuFadeOut();
+
+#ifdef SPEAR
+	UnCacheLump (LOADSAVE_LUMP_START,LOADSAVE_LUMP_END);
+	CacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+#endif
+
+	return exit;
+}
+
+
+///////////////////////////////////
+//
+// HIGHLIGHT CURRENT SELECTED ENTRY
+//
+void TrackWhichGame(int w)
+{
+	static int lastgameon=0;
+
+	PrintLSEntry(lastgameon,TEXTCOLOR);
+	PrintLSEntry(w,HIGHLIGHT);
+
+	lastgameon=w;
+}
+
+
+////////////////////////////
+//
+// DRAW THE LOAD/SAVE SCREEN
+//
+void DrawLoadSaveScreen(int loadsave)
+{
+	#define DISKX	100
+	#define DISKY	0
+
+	int i;
+
+
+	ClearMScreen();
+	fontnumber=1;
+	VWB_DrawPic(112,184,C_MOUSELBACKPIC);
+	DrawWindow(LSM_X-10,LSM_Y-5,LSM_W,LSM_H,BKGDCOLOR);
+	DrawStripes(10);
+
+	if (!loadsave)
+		VWB_DrawPic(60,0,C_LOADGAMEPIC);
+	else
+		VWB_DrawPic(60,0,C_SAVEGAMEPIC);
+
+	for (i=0;i<10;i++)
+		PrintLSEntry(i,TEXTCOLOR);
+
+	DrawMenu(&LSItems,&LSMenu[0]);
+	VW_UpdateScreen();
+	MenuFadeIn();
+	WaitKeyUp();
+}
+
+
+///////////////////////////////////////////
+//
+// PRINT LOAD/SAVE GAME ENTRY W/BOX OUTLINE
+//
+void PrintLSEntry(int w,int color)
+{
+	SETFONTCOLOR(color,BKGDCOLOR);
+	DrawOutline(LSM_X+LSItems.indent,LSM_Y+w*13,LSM_W-LSItems.indent-15,11,color,color);
+	PrintX=LSM_X+LSItems.indent+2;
+	PrintY=LSM_Y+w*13+1;
+	fontnumber=0;
+
+	if (SaveGamesAvail[w])
+		US_Print(SaveGameNames[w]);
+	else
+		US_Print("      - "STR_EMPTY" -");
+
+	fontnumber=1;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// SAVE CURRENT GAME
+//
+////////////////////////////////////////////////////////////////////
+int CP_SaveGame(int quick)
+{
+	int handle,which,exit=0;
+	unsigned nwritten;
+	char name[13],input[32];
+
+
+	strcpy(name,SaveName);
+
+	//
+	// QUICKSAVE?
+	//
+	if (quick)
+	{
+		which=LSItems.curpos;
+
+		if (SaveGamesAvail[which])
+		{
+			name[7]=which+'0';
+			unlink(name);
+			handle=creat(name,S_IREAD|S_IWRITE);
+
+			strcpy(input,&SaveGameNames[which][0]);
+
+			_dos_write(handle,(void far *)input,32,&nwritten);
+			lseek(handle,32,SEEK_SET);
+			SaveTheGame(handle,0,0);
+			close(handle);
+
+			return 1;
+		}
+	}
+
+
+#ifdef SPEAR
+	UnCacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+	CacheLump (LOADSAVE_LUMP_START,LOADSAVE_LUMP_END);
+#endif
+
+	DrawLoadSaveScreen(1);
+
+	do
+	{
+		which=HandleMenu(&LSItems,&LSMenu[0],TrackWhichGame);
+		if (which>=0)
+		{
+			//
+			// OVERWRITE EXISTING SAVEGAME?
+			//
+			if (SaveGamesAvail[which])
+				#ifdef JAPAN
+				if (!GetYorN(7,8,C_JAPSAVEOVERPIC))
+				#else
+				if (!Confirm(GAMESVD))
+				#endif
+				{
+					DrawLoadSaveScreen(1);
+					continue;
+				}
+				else
+				{
+					DrawLoadSaveScreen(1);
+					PrintLSEntry(which,HIGHLIGHT);
+					VW_UpdateScreen();
+				}
+
+			ShootSnd();
+
+			strcpy(input,&SaveGameNames[which][0]);
+			name[7]=which+'0';
+
+			fontnumber=0;
+			if (!SaveGamesAvail[which])
+				VWB_Bar(LSM_X+LSItems.indent+1,LSM_Y+which*13+1,LSM_W-LSItems.indent-16,10,BKGDCOLOR);
+			VW_UpdateScreen();
+
+			if (US_LineInput(LSM_X+LSItems.indent+2,LSM_Y+which*13+1,input,input,true,31,LSM_W-LSItems.indent-30))
+			{
+				SaveGamesAvail[which]=1;
+				strcpy(&SaveGameNames[which][0],input);
+
+				unlink(name);
+				handle=creat(name,S_IREAD|S_IWRITE);
+				_dos_write(handle,(void far *)input,32,&nwritten);
+				lseek(handle,32,SEEK_SET);
+
+				DrawLSAction(1);
+				SaveTheGame(handle,LSA_X+8,LSA_Y+5);
+
+				close(handle);
+
+				ShootSnd();
+				exit=1;
+			}
+			else
+			{
+				VWB_Bar(LSM_X+LSItems.indent+1,LSM_Y+which*13+1,LSM_W-LSItems.indent-16,10,BKGDCOLOR);
+				PrintLSEntry(which,HIGHLIGHT);
+				VW_UpdateScreen();
+				SD_PlaySound(ESCPRESSEDSND);
+				continue;
+			}
+
+			fontnumber=1;
+			break;
+		}
+
+	} while(which>=0);
+
+	MenuFadeOut();
+
+#ifdef SPEAR
+	UnCacheLump (LOADSAVE_LUMP_START,LOADSAVE_LUMP_END);
+	CacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+#endif
+
+	return exit;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// CALIBRATE JOYSTICK
+//
+////////////////////////////////////////////////////////////////////
+int CalibrateJoystick(void)
+{
+	#define CALX	85
+	#define CALY	40
+	#define CALW	158
+	#define CALH	140
+
+	unsigned xmin,ymin,xmax,ymax,jb;
+
+
+
+	#ifdef JAPAN
+	VWB_DrawPic(CALX,CALY,C_JOY0PIC);
+	#else
+	DrawWindow(CALX-5,CALY-5,CALW,CALH,TEXTCOLOR);
+	DrawOutline(CALX-5,CALY-5,CALW,CALH,0,HIGHLIGHT);
+	SETFONTCOLOR(0,TEXTCOLOR);
+
+	WindowX = PrintX = CALX;
+	WindowW = CALW;
+	WindowH = CALH;
+	WindowY = PrintY = CALY;
+	US_Print("    "STR_CALIB"\n    "STR_JOYST"\n");
+	VWB_DrawPic(CALX+40,CALY+30,C_JOY1PIC);
+	PrintY = CALY+80;
+	US_Print(STR_MOVEJOY);
+	SETFONTCOLOR(BKGDCOLOR,TEXTCOLOR);
+	US_Print("   "STR_ESCEXIT);
+	#endif
+	VW_UpdateScreen();
+
+	do
+	{
+		jb=IN_JoyButtons();
+		if (Keyboard[sc_Escape])
+			return 0;
+		#ifndef SPEAR
+		if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("goobers"))
+			PicturePause();
+		#endif
+
+	} while(!(jb&1));
+
+	SD_PlaySound(SHOOTSND);
+	IN_GetJoyAbs(joystickport,&xmin,&ymin);
+
+
+	#ifdef JAPAN
+	VWB_DrawPic(CALX,CALY,C_JOY1PIC);
+	#else
+	DrawWindow(CALX-5,CALY-5,CALW,CALH,TEXTCOLOR);
+	DrawOutline(CALX-5,CALY-5,CALW,CALH,0,HIGHLIGHT);
+	SETFONTCOLOR(0,TEXTCOLOR);
+
+	PrintX = CALX;
+	PrintY = CALY;
+	US_Print("    "STR_CALIB"\n    "STR_JOYST"\n");
+	VWB_DrawPic(CALX+40,CALY+30,C_JOY2PIC);
+	PrintY = CALY+80;
+	US_Print(STR_MOVEJOY2);
+	SETFONTCOLOR(BKGDCOLOR,TEXTCOLOR);
+	US_Print("   "STR_ESCEXIT);
+	#endif
+	VW_UpdateScreen();
+
+	do
+	{
+		jb=IN_JoyButtons();
+		if (Keyboard[sc_Escape])
+			return 0;
+		#ifndef SPEAR
+		if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("goobers"))
+			PicturePause();
+		#endif
+	} while(!(jb&2));
+
+	IN_GetJoyAbs(joystickport,&xmax,&ymax);
+	SD_PlaySound(SHOOTSND);
+
+	while (IN_JoyButtons());
+
+	//
+	// ASSIGN ACTUAL VALUES HERE
+	//
+	if ((xmin != xmax) && (ymin != ymax))
+		IN_SetupJoy(joystickport,xmin,xmax,ymin,ymax);
+	else
+		return 0;
+
+	return 1;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// DEFINE CONTROLS
+//
+////////////////////////////////////////////////////////////////////
+void CP_Control(void)
+{
+	#define CTL_SPC	70
+	enum {MOUSEENABLE,JOYENABLE,USEPORT2,PADENABLE,MOUSESENS,CUSTOMIZE};
+	int i,which;
+
+
+#ifdef SPEAR
+	UnCacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+	CacheLump (CONTROL_LUMP_START,CONTROL_LUMP_END);
+#endif
+
+	DrawCtlScreen();
+	MenuFadeIn();
+	WaitKeyUp();
+
+	do
+	{
+		which=HandleMenu(&CtlItems,&CtlMenu[0],NULL);
+		switch(which)
+		{
+			case MOUSEENABLE:
+				mouseenabled^=1;
+				_CX=_DX=CENTER;
+				Mouse(4);
+				DrawCtlScreen();
+				CusItems.curpos=-1;
+				ShootSnd();
+				break;
+
+			case JOYENABLE:
+				joystickenabled^=1;
+				if (joystickenabled)
+					if (!CalibrateJoystick())
+						joystickenabled = 0;
+				DrawCtlScreen();
+				CusItems.curpos=-1;
+				ShootSnd();
+				break;
+
+			case USEPORT2:
+				joystickport^=1;
+				DrawCtlScreen();
+				ShootSnd();
+				break;
+
+			case PADENABLE:
+				joypadenabled^=1;
+				DrawCtlScreen();
+				ShootSnd();
+				break;
+
+			case MOUSESENS:
+			case CUSTOMIZE:
+				DrawCtlScreen();
+				MenuFadeIn();
+				WaitKeyUp();
+				break;
+		}
+	} while(which>=0);
+
+	MenuFadeOut();
+
+#ifdef SPEAR
+	UnCacheLump (CONTROL_LUMP_START,CONTROL_LUMP_END);
+	CacheLump (OPTIONS_LUMP_START,OPTIONS_LUMP_END);
+#endif
+}
+
+
+////////////////////////////////
+//
+// DRAW MOUSE SENSITIVITY SCREEN
+//
+void DrawMouseSens(void)
+{
+#ifdef JAPAN
+	CA_CacheScreen(S_MOUSESENSPIC);
+#else
+	ClearMScreen();
+	VWB_DrawPic(112,184,C_MOUSELBACKPIC);
+	#ifdef SPANISH
+	DrawWindow(10,80,300,43,BKGDCOLOR);
+	#else
+	DrawWindow(10,80,300,30,BKGDCOLOR);
+	#endif
+
+	WindowX=0;
+	WindowW=320;
+	PrintY=82;
+	SETFONTCOLOR(READCOLOR,BKGDCOLOR);
+	US_CPrint(STR_MOUSEADJ);
+
+	SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+	#ifdef SPANISH
+	PrintX=14;
+	PrintY=95+13;
+	US_Print(STR_SLOW);
+	PrintX=252;
+	US_Print(STR_FAST);
+	#else
+	PrintX=14;
+	PrintY=95;
+	US_Print(STR_SLOW);
+	PrintX=269;
+	US_Print(STR_FAST);
+	#endif
+#endif
+
+	VWB_Bar(60,97,200,10,TEXTCOLOR);
+	DrawOutline(60,97,200,10,0,HIGHLIGHT);
+	DrawOutline(60+20*mouseadjustment,97,20,10,0,READCOLOR);
+	VWB_Bar(61+20*mouseadjustment,98,19,9,READHCOLOR);
+
+	VW_UpdateScreen();
+	MenuFadeIn();
+}
+
+
+///////////////////////////
+//
+// ADJUST MOUSE SENSITIVITY
+//
+void MouseSensitivity(void)
+{
+	ControlInfo ci;
+	int exit=0,oldMA;
+
+
+	oldMA=mouseadjustment;
+	DrawMouseSens();
+	do
+	{
+		ReadAnyControl(&ci);
+		switch(ci.dir)
+		{
+			case dir_North:
+			case dir_West:
+				if (mouseadjustment)
+				{
+					mouseadjustment--;
+					VWB_Bar(60,97,200,10,TEXTCOLOR);
+					DrawOutline(60,97,200,10,0,HIGHLIGHT);
+					DrawOutline(60+20*mouseadjustment,97,20,10,0,READCOLOR);
+					VWB_Bar(61+20*mouseadjustment,98,19,9,READHCOLOR);
+					VW_UpdateScreen();
+					SD_PlaySound(MOVEGUN1SND);
+					while(Keyboard[sc_LeftArrow]);
+					WaitKeyUp();
+				}
+				break;
+
+			case dir_South:
+			case dir_East:
+				if (mouseadjustment<9)
+				{
+					mouseadjustment++;
+					VWB_Bar(60,97,200,10,TEXTCOLOR);
+					DrawOutline(60,97,200,10,0,HIGHLIGHT);
+					DrawOutline(60+20*mouseadjustment,97,20,10,0,READCOLOR);
+					VWB_Bar(61+20*mouseadjustment,98,19,9,READHCOLOR);
+					VW_UpdateScreen();
+					SD_PlaySound(MOVEGUN1SND);
+					while(Keyboard[sc_RightArrow]);
+					WaitKeyUp();
+				}
+				break;
+		}
+
+		#ifndef SPEAR
+		if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("goobers"))
+		#else
+		if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("debugmode"))
+		#endif
+			PicturePause();
+
+		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)
+	{
+		mouseadjustment=oldMA;
+		SD_PlaySound(ESCPRESSEDSND);
+	}
+	else
+		SD_PlaySound(SHOOTSND);
+
+	WaitKeyUp();
+	MenuFadeOut();
+}
+
+
+///////////////////////////
+//
+// DRAW CONTROL MENU SCREEN
+//
+void DrawCtlScreen(void)
+{
+ int i,x,y;
+
+
+#ifdef JAPAN
+	CA_CacheScreen(S_CONTROLPIC);
+#else
+ ClearMScreen();
+ DrawStripes(10);
+ VWB_DrawPic(80,0,C_CONTROLPIC);
+ VWB_DrawPic(112,184,C_MOUSELBACKPIC);
+ DrawWindow(CTL_X-8,CTL_Y-5,CTL_W,CTL_H,BKGDCOLOR);
+#endif
+ WindowX=0;
+ WindowW=320;
+ SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+
+ if (JoysPresent[0])
+   CtlMenu[1].active=
+   CtlMenu[2].active=
+   CtlMenu[3].active=1;
+
+ CtlMenu[2].active=CtlMenu[3].active=joystickenabled;
+
+ if (MousePresent)
+ {
+  CtlMenu[4].active=
+  CtlMenu[0].active=1;
+ }
+
+ CtlMenu[4].active=mouseenabled;
+
+
+ DrawMenu(&CtlItems,&CtlMenu[0]);
+
+
+ x=CTL_X+CtlItems.indent-24;
+ y=CTL_Y+3;
+ if (mouseenabled)
+   VWB_DrawPic(x,y,C_SELECTEDPIC);
+ else
+   VWB_DrawPic(x,y,C_NOTSELECTEDPIC);
+
+ y=CTL_Y+16;
+ if (joystickenabled)
+   VWB_DrawPic(x,y,C_SELECTEDPIC);
+ else
+   VWB_DrawPic(x,y,C_NOTSELECTEDPIC);
+
+ y=CTL_Y+29;
+ if (joystickport)
+   VWB_DrawPic(x,y,C_SELECTEDPIC);
+ else
+   VWB_DrawPic(x,y,C_NOTSELECTEDPIC);
+
+ y=CTL_Y+42;
+ if (joypadenabled)
+   VWB_DrawPic(x,y,C_SELECTEDPIC);
+ else
+   VWB_DrawPic(x,y,C_NOTSELECTEDPIC);
+
+ //
+ // PICK FIRST AVAILABLE SPOT
+ //
+ if (CtlItems.curpos<0 || !CtlMenu[CtlItems.curpos].active)
+   for (i=0;i<6;i++)
+	 if (CtlMenu[i].active)
+	 {
+	  CtlItems.curpos=i;
+	  break;
+	 }
+
+ DrawMenuGun(&CtlItems);
+ VW_UpdateScreen();
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// CUSTOMIZE CONTROLS
+//
+////////////////////////////////////////////////////////////////////
+enum {FIRE,STRAFE,RUN,OPEN};
+char mbarray[4][3]={"b0","b1","b2","b3"},
+	   order[4]={RUN,OPEN,FIRE,STRAFE};
+
+
+void CustomControls(void)
+{
+ int which;
+
+
+ DrawCustomScreen();
+ do
+ {
+  which=HandleMenu(&CusItems,&CusMenu[0],FixupCustom);
+  switch(which)
+  {
+   case 0:
+	 DefineMouseBtns();
+	 DrawCustMouse(1);
+	 break;
+   case 3:
+	 DefineJoyBtns();
+	 DrawCustJoy(0);
+	 break;
+   case 6:
+	 DefineKeyBtns();
+	 DrawCustKeybd(0);
+	 break;
+   case 8:
+	 DefineKeyMove();
+	 DrawCustKeys(0);
+  }
+ } while(which>=0);
+
+
+
+ MenuFadeOut();
+}
+
+
+////////////////////////
+//
+// DEFINE THE MOUSE BUTTONS
+//
+void DefineMouseBtns(void)
+{
+ CustomCtrls mouseallowed={0,1,1,1};
+ EnterCtrlData(2,&mouseallowed,DrawCustMouse,PrintCustMouse,MOUSE);
+}
+
+
+////////////////////////
+//
+// DEFINE THE JOYSTICK BUTTONS
+//
+void DefineJoyBtns(void)
+{
+ CustomCtrls joyallowed={1,1,1,1};
+ EnterCtrlData(5,&joyallowed,DrawCustJoy,PrintCustJoy,JOYSTICK);
+}
+
+
+////////////////////////
+//
+// DEFINE THE KEYBOARD BUTTONS
+//
+void DefineKeyBtns(void)
+{
+ CustomCtrls keyallowed={1,1,1,1};
+ EnterCtrlData(8,&keyallowed,DrawCustKeybd,PrintCustKeybd,KEYBOARDBTNS);
+}
+
+
+////////////////////////
+//
+// DEFINE THE KEYBOARD BUTTONS
+//
+void DefineKeyMove(void)
+{
+	CustomCtrls keyallowed={1,1,1,1};
+	EnterCtrlData(10,&keyallowed,DrawCustKeys,PrintCustKeys,KEYBOARDMOVE);
+}
+
+
+////////////////////////
+//
+// ENTER CONTROL DATA FOR ANY TYPE OF CONTROL
+//
+enum {FWRD,RIGHT,BKWD,LEFT};
+int moveorder[4]={LEFT,RIGHT,FWRD,BKWD};
+
+void EnterCtrlData(int index,CustomCtrls *cust,void (*DrawRtn)(int),void (*PrintRtn)(int),int type)
+{
+ int j,exit,tick,redraw,which,x,picked;
+ ControlInfo ci;
+
+
+ ShootSnd();
+ PrintY=CST_Y+13*index;
+ IN_ClearKeysDown();
+ exit=0;
+ redraw=1;
+ //
+ // FIND FIRST SPOT IN ALLOWED ARRAY
+ //
+ for (j=0;j<4;j++)
+   if (cust->allowed[j])
+   {
+	which=j;
+	break;
+   }
+
+ do
+ {
+  if (redraw)
+  {
+   x=CST_START+CST_SPC*which;
+   DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
+
+   DrawRtn(1);
+   DrawWindow(x-2,PrintY,CST_SPC,11,TEXTCOLOR);
+   DrawOutline(x-2,PrintY,CST_SPC,11,0,HIGHLIGHT);
+   SETFONTCOLOR(0,TEXTCOLOR);
+   PrintRtn(which);
+   PrintX=x;
+   SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+   VW_UpdateScreen();
+   WaitKeyUp();
+   redraw=0;
+  }
+
+  ReadAnyControl(&ci);
+
+  if (type==MOUSE || type==JOYSTICK)
+	if (IN_KeyDown(sc_Enter)||IN_KeyDown(sc_Control)||IN_KeyDown(sc_Alt))
+	{
+	 IN_ClearKeysDown();
+	 ci.button0=ci.button1=false;
+	}
+
+  //
+  // CHANGE BUTTON VALUE?
+  //
+  if ((ci.button0|ci.button1|ci.button2|ci.button3)||
+	  ((type==KEYBOARDBTNS||type==KEYBOARDMOVE) && LastScan==sc_Enter))
+  {
+   tick=TimeCount=picked=0;
+   SETFONTCOLOR(0,TEXTCOLOR);
+
+   do
+   {
+	int button,result=0;
+
+
+	if (type==KEYBOARDBTNS||type==KEYBOARDMOVE)
+	  IN_ClearKeysDown();
+
+	//
+	// FLASH CURSOR
+	//
+	if (TimeCount>10)
+	{
+	 switch(tick)
+	 {
+	  case 0:
+	VWB_Bar(x,PrintY+1,CST_SPC-2,10,TEXTCOLOR);
+	break;
+	  case 1:
+	PrintX=x;
+	US_Print("?");
+	SD_PlaySound(HITWALLSND);
+	 }
+	 tick^=1;
+	 TimeCount=0;
+	 VW_UpdateScreen();
+	}
+
+	//
+	// WHICH TYPE OF INPUT DO WE PROCESS?
+	//
+	switch(type)
+	{
+	 case MOUSE:
+	   Mouse(3);
+	   button=_BX;
+	   switch(button)
+	   {
+	case 1: result=1; break;
+	case 2: result=2; break;
+	case 4: result=3; break;
+	   }
+
+	   if (result)
+	   {
+	int z;
+
+
+	for (z=0;z<4;z++)
+	  if (order[which]==buttonmouse[z])
+	  {
+	   buttonmouse[z]=bt_nobutton;
+	   break;
+	  }
+
+	buttonmouse[result-1]=order[which];
+	picked=1;
+	SD_PlaySound(SHOOTDOORSND);
+	   }
+	   break;
+
+	 case JOYSTICK:
+	   if (ci.button0) result=1;
+	   else
+	   if (ci.button1) result=2;
+	   else
+	   if (ci.button2) result=3;
+	   else
+	   if (ci.button3) result=4;
+
+	   if (result)
+	   {
+	int z;
+
+
+	for (z=0;z<4;z++)
+	  if (order[which]==buttonjoy[z])
+	  {
+	   buttonjoy[z]=bt_nobutton;
+	   break;
+	  }
+
+	buttonjoy[result-1]=order[which];
+	picked=1;
+	SD_PlaySound(SHOOTDOORSND);
+	   }
+	   break;
+
+	 case KEYBOARDBTNS:
+	   if (LastScan)
+	   {
+	buttonscan[order[which]]=LastScan;
+	picked=1;
+	ShootSnd();
+	IN_ClearKeysDown();
+	   }
+	   break;
+
+	 case KEYBOARDMOVE:
+	   if (LastScan)
+	   {
+	dirscan[moveorder[which]]=LastScan;
+	picked=1;
+	ShootSnd();
+	IN_ClearKeysDown();
+	   }
+	   break;
+	}
+
+	//
+	// EXIT INPUT?
+	//
+	if (IN_KeyDown(sc_Escape))
+	{
+	 picked=1;
+	 continue;
+	}
+
+   } while(!picked);
+
+   SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+   redraw=1;
+   WaitKeyUp();
+   continue;
+  }
+
+  if (ci.button1 || IN_KeyDown(sc_Escape))
+	exit=1;
+
+  //
+  // MOVE TO ANOTHER SPOT?
+  //
+  switch(ci.dir)
+  {
+   case dir_West:
+	 do
+	 {
+	  which--;
+	  if (which<0)
+	which=3;
+	 } while(!cust->allowed[which]);
+	 redraw=1;
+	 SD_PlaySound(MOVEGUN1SND);
+	 while(ReadAnyControl(&ci),ci.dir!=dir_None);
+	 IN_ClearKeysDown();
+	 break;
+
+   case dir_East:
+	 do
+	 {
+	  which++;
+	  if (which>3)
+	which=0;
+	 } while(!cust->allowed[which]);
+	 redraw=1;
+	 SD_PlaySound(MOVEGUN1SND);
+	 while(ReadAnyControl(&ci),ci.dir!=dir_None);
+	 IN_ClearKeysDown();
+	 break;
+   case dir_North:
+   case dir_South:
+	 exit=1;
+  }
+ } while(!exit);
+
+ SD_PlaySound(ESCPRESSEDSND);
+ WaitKeyUp();
+ DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
+}
+
+
+////////////////////////
+//
+// FIXUP GUN CURSOR OVERDRAW SHIT
+//
+void FixupCustom(int w)
+{
+	static int lastwhich=-1;
+	int y=CST_Y+26+w*13;
+
+
+	VWB_Hlin(7,32,y-1,DEACTIVE);
+	VWB_Hlin(7,32,y+12,BORD2COLOR);
+#ifndef SPEAR
+	VWB_Hlin(7,32,y-2,BORDCOLOR);
+	VWB_Hlin(7,32,y+13,BORDCOLOR);
+#else
+	VWB_Hlin(7,32,y-2,BORD2COLOR);
+	VWB_Hlin(7,32,y+13,BORD2COLOR);
+#endif
+
+	switch(w)
+	{
+		case 0: DrawCustMouse(1); break;
+		case 3: DrawCustJoy(1); break;
+		case 6: DrawCustKeybd(1); break;
+		case 8: DrawCustKeys(1);
+	}
+
+
+	if (lastwhich>=0)
+	{
+		y=CST_Y+26+lastwhich*13;
+		VWB_Hlin(7,32,y-1,DEACTIVE);
+		VWB_Hlin(7,32,y+12,BORD2COLOR);
+#ifndef SPEAR
+		VWB_Hlin(7,32,y-2,BORDCOLOR);
+		VWB_Hlin(7,32,y+13,BORDCOLOR);
+#else
+		VWB_Hlin(7,32,y-2,BORD2COLOR);
+		VWB_Hlin(7,32,y+13,BORD2COLOR);
+#endif
+
+		if (lastwhich!=w)
+			switch(lastwhich)
+			{
+				case 0: DrawCustMouse(0); break;
+				case 3: DrawCustJoy(0); break;
+				case 6: DrawCustKeybd(0); break;
+				case 8: DrawCustKeys(0);
+			}
+	}
+
+	lastwhich=w;
+}
+
+
+////////////////////////
+//
+// DRAW CUSTOMIZE SCREEN
+//
+void DrawCustomScreen(void)
+{
+	int i;
+
+
+#ifdef JAPAN
+	CA_CacheScreen(S_CUSTOMPIC);
+	fontnumber=1;
+
+	PrintX=CST_START;
+	PrintY = CST_Y+26;
+	DrawCustMouse(0);
+
+	PrintX=CST_START;
+	US_Print("\n\n\n");
+	DrawCustJoy(0);
+
+	PrintX=CST_START;
+	US_Print("\n\n\n");
+	DrawCustKeybd(0);
+
+	PrintX=CST_START;
+	US_Print("\n\n\n");
+	DrawCustKeys(0);
+#else
+	ClearMScreen();
+	WindowX=0;
+	WindowW=320;
+	VWB_DrawPic(112,184,C_MOUSELBACKPIC);
+	DrawStripes(10);
+	VWB_DrawPic(80,0,C_CUSTOMIZEPIC);
+
+	//
+	// MOUSE
+	//
+	SETFONTCOLOR(READCOLOR,BKGDCOLOR);
+	WindowX=0;
+	WindowW=320;
+
+#ifndef SPEAR
+	PrintY=CST_Y;
+	US_CPrint("Mouse\n");
+#else
+	PrintY = CST_Y+13;
+	VWB_DrawPic (128,48,C_MOUSEPIC);
+#endif
+
+	SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+	#ifdef SPANISH
+	PrintX=CST_START-16;
+	US_Print(STR_CRUN);
+	PrintX=CST_START-16+CST_SPC*1;
+	US_Print(STR_COPEN);
+	PrintX=CST_START-16+CST_SPC*2;
+	US_Print(STR_CFIRE);
+	PrintX=CST_START-16+CST_SPC*3;
+	US_Print(STR_CSTRAFE"\n");
+	#else
+	PrintX=CST_START;
+	US_Print(STR_CRUN);
+	PrintX=CST_START+CST_SPC*1;
+	US_Print(STR_COPEN);
+	PrintX=CST_START+CST_SPC*2;
+	US_Print(STR_CFIRE);
+	PrintX=CST_START+CST_SPC*3;
+	US_Print(STR_CSTRAFE"\n");
+	#endif
+
+	DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
+	DrawCustMouse(0);
+	US_Print("\n");
+
+
+	//
+	// JOYSTICK/PAD
+	//
+#ifndef SPEAR
+	SETFONTCOLOR(READCOLOR,BKGDCOLOR);
+	US_CPrint("Joystick/Gravis GamePad\n");
+#else
+	PrintY += 13;
+	VWB_DrawPic (40,88,C_JOYSTICKPIC);
+#endif
+
+#ifdef SPEAR
+	VWB_DrawPic (112,120,C_KEYBOARDPIC);
+#endif
+
+	SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+	#ifdef SPANISH
+	PrintX=CST_START-16;
+	US_Print(STR_CRUN);
+	PrintX=CST_START-16+CST_SPC*1;
+	US_Print(STR_COPEN);
+	PrintX=CST_START-16+CST_SPC*2;
+	US_Print(STR_CFIRE);
+	PrintX=CST_START-16+CST_SPC*3;
+	US_Print(STR_CSTRAFE"\n");
+	#else
+	PrintX=CST_START;
+	US_Print(STR_CRUN);
+	PrintX=CST_START+CST_SPC*1;
+	US_Print(STR_COPEN);
+	PrintX=CST_START+CST_SPC*2;
+	US_Print(STR_CFIRE);
+	PrintX=CST_START+CST_SPC*3;
+	US_Print(STR_CSTRAFE"\n");
+	#endif
+	DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
+	DrawCustJoy(0);
+	US_Print("\n");
+
+
+	//
+	// KEYBOARD
+	//
+#ifndef SPEAR
+	SETFONTCOLOR(READCOLOR,BKGDCOLOR);
+	US_CPrint("Keyboard\n");
+#else
+	PrintY += 13;
+#endif
+	SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+	#ifdef SPANISH
+	PrintX=CST_START-16;
+	US_Print(STR_CRUN);
+	PrintX=CST_START-16+CST_SPC*1;
+	US_Print(STR_COPEN);
+	PrintX=CST_START-16+CST_SPC*2;
+	US_Print(STR_CFIRE);
+	PrintX=CST_START-16+CST_SPC*3;
+	US_Print(STR_CSTRAFE"\n");
+	#else
+	PrintX=CST_START;
+	US_Print(STR_CRUN);
+	PrintX=CST_START+CST_SPC*1;
+	US_Print(STR_COPEN);
+	PrintX=CST_START+CST_SPC*2;
+	US_Print(STR_CFIRE);
+	PrintX=CST_START+CST_SPC*3;
+	US_Print(STR_CSTRAFE"\n");
+	#endif
+	DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
+	DrawCustKeybd(0);
+	US_Print("\n");
+
+
+	//
+	// KEYBOARD MOVE KEYS
+	//
+	SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+	#ifdef SPANISH
+	PrintX=4;
+	US_Print(STR_LEFT);
+	US_Print("/");
+	US_Print(STR_RIGHT);
+	US_Print("/");
+	US_Print(STR_FRWD);
+	US_Print("/");
+	US_Print(STR_BKWD"\n");
+	#else
+	PrintX=CST_START;
+	US_Print(STR_LEFT);
+	PrintX=CST_START+CST_SPC*1;
+	US_Print(STR_RIGHT);
+	PrintX=CST_START+CST_SPC*2;
+	US_Print(STR_FRWD);
+	PrintX=CST_START+CST_SPC*3;
+	US_Print(STR_BKWD"\n");
+	#endif
+	DrawWindow(5,PrintY-1,310,13,BKGDCOLOR);
+	DrawCustKeys(0);
+#endif
+	//
+	// PICK STARTING POINT IN MENU
+	//
+	if (CusItems.curpos<0)
+		for (i=0;i<CusItems.amount;i++)
+			if (CusMenu[i].active)
+			{
+				CusItems.curpos=i;
+				break;
+			}
+
+
+	VW_UpdateScreen();
+	MenuFadeIn();
+}
+
+
+void PrintCustMouse(int i)
+{
+	int j;
+
+	for (j=0;j<4;j++)
+		if (order[i]==buttonmouse[j])
+		{
+			PrintX=CST_START+CST_SPC*i;
+			US_Print(mbarray[j]);
+			break;
+		}
+}
+
+void DrawCustMouse(int hilight)
+{
+	int i,color;
+
+
+	color=TEXTCOLOR;
+	if (hilight)
+		color=HIGHLIGHT;
+	SETFONTCOLOR(color,BKGDCOLOR);
+
+	if (!mouseenabled)
+	{
+		SETFONTCOLOR(DEACTIVE,BKGDCOLOR);
+		CusMenu[0].active=0;
+	}
+	else
+		CusMenu[0].active=1;
+
+	PrintY=CST_Y+13*2;
+	for (i=0;i<4;i++)
+		PrintCustMouse(i);
+}
+
+void PrintCustJoy(int i)
+{
+	int j;
+
+	for (j=0;j<4;j++)
+		if (order[i]==buttonjoy[j])
+		{
+			PrintX=CST_START+CST_SPC*i;
+			US_Print(mbarray[j]);
+			break;
+		}
+}
+
+void DrawCustJoy(int hilight)
+{
+	int i,color;
+
+
+	color=TEXTCOLOR;
+	if (hilight)
+		color=HIGHLIGHT;
+	SETFONTCOLOR(color,BKGDCOLOR);
+
+	if (!joystickenabled)
+	{
+		SETFONTCOLOR(DEACTIVE,BKGDCOLOR);
+		CusMenu[3].active=0;
+	}
+	else
+		CusMenu[3].active=1;
+
+	PrintY=CST_Y+13*5;
+	for (i=0;i<4;i++)
+		PrintCustJoy(i);
+}
+
+
+void PrintCustKeybd(int i)
+{
+	PrintX=CST_START+CST_SPC*i;
+	US_Print(IN_GetScanName(buttonscan[order[i]]));
+}
+
+void DrawCustKeybd(int hilight)
+{
+	int i,color;
+
+
+	color=TEXTCOLOR;
+	if (hilight)
+		color=HIGHLIGHT;
+	SETFONTCOLOR(color,BKGDCOLOR);
+
+	PrintY=CST_Y+13*8;
+	for (i=0;i<4;i++)
+		PrintCustKeybd(i);
+}
+
+void PrintCustKeys(int i)
+{
+	PrintX=CST_START+CST_SPC*i;
+	US_Print(IN_GetScanName(dirscan[moveorder[i]]));
+}
+
+void DrawCustKeys(int hilight)
+{
+	int i,color;
+
+
+	color=TEXTCOLOR;
+	if (hilight)
+		color=HIGHLIGHT;
+	SETFONTCOLOR(color,BKGDCOLOR);
+
+	PrintY=CST_Y+13*10;
+	for (i=0;i<4;i++)
+		PrintCustKeys(i);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// CHANGE SCREEN VIEWING SIZE
+//
+////////////////////////////////////////////////////////////////////
+void CP_ChangeView(void)
+{
+	int exit=0,oldview,newview;
+	ControlInfo ci;
+
+
+	WindowX=WindowY=0;
+	WindowW=320;
+	WindowH=200;
+	newview=oldview=viewwidth/16;
+	DrawChangeView(oldview);
+
+	do
+	{
+		CheckPause();
+		ReadAnyControl(&ci);
+		switch(ci.dir)
+		{
+		case dir_South:
+		case dir_West:
+			newview--;
+			if (newview<4)
+				newview=4;
+			ShowViewSize(newview);
+			VW_UpdateScreen();
+			SD_PlaySound(HITWALLSND);
+			TicDelay(10);
+			break;
+
+		case dir_North:
+		case dir_East:
+			newview++;
+			if (newview>19)
+				newview=19;
+			ShowViewSize(newview);
+			VW_UpdateScreen();
+			SD_PlaySound(HITWALLSND);
+			TicDelay(10);
+			break;
+		}
+
+		#ifndef SPEAR
+		if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("goobers"))
+		#else
+		if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("debugmode"))
+		#endif
+			PicturePause();
+
+		if (ci.button0 || Keyboard[sc_Enter])
+			exit=1;
+		else
+		if (ci.button1 || Keyboard[sc_Escape])
+		{
+			viewwidth=oldview*16;
+			SD_PlaySound(ESCPRESSEDSND);
+			MenuFadeOut();
+			return;
+		}
+
+	} while(!exit);
+
+
+	if (oldview!=newview)
+	{
+		SD_PlaySound (SHOOTSND);
+		Message(STR_THINK"...");
+		NewViewSize(newview);
+	}
+
+	ShootSnd();
+	MenuFadeOut();
+}
+
+
+/////////////////////////////
+//
+// DRAW THE CHANGEVIEW SCREEN
+//
+void DrawChangeView(int view)
+{
+#ifdef JAPAN
+	CA_CacheScreen(S_CHANGEPIC);
+
+	ShowViewSize(view);
+#else
+	VWB_Bar(0,160,320,40,VIEWCOLOR);
+	ShowViewSize(view);
+
+	PrintY=161;
+	WindowX=0;
+	WindowY=320;
+	SETFONTCOLOR(HIGHLIGHT,BKGDCOLOR);
+
+	US_CPrint(STR_SIZE1"\n");
+	US_CPrint(STR_SIZE2"\n");
+	US_CPrint(STR_SIZE3);
+#endif
+	VW_UpdateScreen();
+
+	MenuFadeIn();
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// QUIT THIS INFERNAL GAME!
+//
+////////////////////////////////////////////////////////////////////
+void CP_Quit(void)
+{
+	int i;
+
+
+	#ifdef JAPAN
+	if (GetYorN(7,11,C_QUITMSGPIC))
+	#else
+
+	#ifdef SPANISH
+	if (Confirm(ENDGAMESTR))
+	#else
+	if (Confirm(endStrings[US_RndT()&0x7+(US_RndT()&1)]))
+	#endif
+
+	#endif
+	{
+		VW_UpdateScreen();
+		SD_MusicOff();
+		SD_StopSound();
+		MenuFadeOut();
+		//
+		// SHUT-UP THE ADLIB
+		//
+		for (i=1;i<=0xf5;i++)
+			alOut(i,0);
+		Quit(NULL);
+	}
+
+	DrawMainMenu();
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// HANDLE INTRO SCREEN (SYSTEM CONFIG)
+//
+////////////////////////////////////////////////////////////////////
+void IntroScreen(void)
+{
+#ifdef SPEAR
+
+#define MAINCOLOR	0x4f
+#define EMSCOLOR	0x4f
+#define XMSCOLOR	0x4f
+
+#else
+
+#define MAINCOLOR	0x6c
+#define EMSCOLOR	0x6c
+#define XMSCOLOR	0x6c
+
+#endif
+#define FILLCOLOR	14
+
+	long memory,emshere,xmshere;
+	int i,num,ems[10]={100,200,300,400,500,600,700,800,900,1000},
+		xms[10]={100,200,300,400,500,600,700,800,900,1000},
+		main[10]={32,64,96,128,160,192,224,256,288,320};
+
+
+	//
+	// DRAW MAIN MEMORY
+	//
+	memory=(1023l+mminfo.nearheap+mminfo.farheap)/1024l;
+	for (i=0;i<10;i++)
+		if (memory>=main[i])
+			VWB_Bar(49,163-8*i,6,5,MAINCOLOR-i);
+
+
+	//
+	// DRAW EMS MEMORY
+	//
+	if (EMSPresent)
+	{
+		emshere=4l*EMSPagesAvail;
+		for (i=0;i<10;i++)
+			if (emshere>=ems[i])
+				VWB_Bar(89,163-8*i,6,5,EMSCOLOR-i);
+	}
+
+	//
+	// DRAW XMS MEMORY
+	//
+	if (XMSPresent)
+	{
+		xmshere=4l*XMSPagesAvail;
+		for (i=0;i<10;i++)
+			if (xmshere>=xms[i])
+				VWB_Bar(129,163-8*i,6,5,XMSCOLOR-i);
+	}
+
+	//
+	// FILL BOXES
+	//
+	if (MousePresent)
+		VWB_Bar(164,82,12,2,FILLCOLOR);
+
+	if (JoysPresent[0] || JoysPresent[1])
+		VWB_Bar(164,105,12,2,FILLCOLOR);
+
+	if (AdLibPresent && !SoundBlasterPresent)
+		VWB_Bar(164,128,12,2,FILLCOLOR);
+
+	if (SoundBlasterPresent)
+		VWB_Bar(164,151,12,2,FILLCOLOR);
+
+	if (SoundSourcePresent)
+		VWB_Bar(164,174,12,2,FILLCOLOR);
+}
+
+
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+//
+// SUPPORT ROUTINES
+//
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////
+//
+// Clear Menu screens to dark red
+//
+////////////////////////////////////////////////////////////////////
+void ClearMScreen(void)
+{
+#ifndef SPEAR
+	VWB_Bar(0,0,320,200,BORDCOLOR);
+#else
+	VWB_DrawPic(0,0,C_BACKDROPPIC);
+#endif
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// Un/Cache a LUMP of graphics
+//
+////////////////////////////////////////////////////////////////////
+void CacheLump(int lumpstart,int lumpend)
+{
+ int i;
+
+ for (i=lumpstart;i<=lumpend;i++)
+   CA_CacheGrChunk(i);
+}
+
+
+void UnCacheLump(int lumpstart,int lumpend)
+{
+ int i;
+
+ for (i=lumpstart;i<=lumpend;i++)
+	if (grsegs[i])
+		UNCACHEGRCHUNK(i);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// Draw a window for a menu
+//
+////////////////////////////////////////////////////////////////////
+void DrawWindow(int x,int y,int w,int h,int wcolor)
+{
+	VWB_Bar(x,y,w,h,wcolor);
+	DrawOutline(x,y,w,h,BORD2COLOR,DEACTIVE);
+}
+
+
+void DrawOutline(int x,int y,int w,int h,int color1,int color2)
+{
+	VWB_Hlin(x,x+w,y,color2);
+	VWB_Vlin(y,y+h,x,color2);
+	VWB_Hlin(x,x+w,y+h,color1);
+	VWB_Vlin(y,y+h,x+w,color1);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// Setup Control Panel stuff - graphics, etc.
+//
+////////////////////////////////////////////////////////////////////
+void SetupControlPanel(void)
+{
+	struct ffblk f;
+	char name[13];
+	int which,i;
+
+
+	//
+	// CACHE GRAPHICS & SOUNDS
+	//
+	CA_CacheGrChunk(STARTFONT+1);
+#ifndef SPEAR
+	CacheLump(CONTROLS_LUMP_START,CONTROLS_LUMP_END);
+#else
+	CacheLump(BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+#endif
+
+	SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+	fontnumber=1;
+	WindowH=200;
+
+	if (!ingame)
+		CA_LoadAllSounds();
+	else
+		MainMenu[savegame].active=1;
+
+	//
+	// SEE WHICH SAVE GAME FILES ARE AVAILABLE & READ STRING IN
+	//
+	strcpy(name,SaveName);
+	if (!findfirst(name,&f,0))
+		do
+		{
+			which=f.ff_name[7]-'0';
+			if (which<10)
+			{
+				int handle;
+				char temp[32];
+
+				SaveGamesAvail[which]=1;
+				handle=open(f.ff_name,O_BINARY);
+				read(handle,temp,32);
+				close(handle);
+				strcpy(&SaveGameNames[which][0],temp);
+			}
+		} while(!findnext(&f));
+
+	//
+	// CENTER MOUSE
+	//
+	_CX=_DX=CENTER;
+	Mouse(4);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// Clean up all the Control Panel stuff
+//
+////////////////////////////////////////////////////////////////////
+void CleanupControlPanel(void)
+{
+#ifndef SPEAR
+	UnCacheLump(CONTROLS_LUMP_START,CONTROLS_LUMP_END);
+#else
+	UnCacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);
+#endif
+
+	fontnumber = 0;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// Handle moving gun around a menu
+//
+////////////////////////////////////////////////////////////////////
+int HandleMenu(CP_iteminfo *item_i,CP_itemtype far *items,void (*routine)(int w))
+{
+	char key;
+	static int redrawitem=1,lastitem=-1;
+	int i,x,y,basey,exit,which,shape,timer;
+	ControlInfo ci;
+
+
+	which=item_i->curpos;
+	x=item_i->x&-8;
+	basey=item_i->y-2;
+	y=basey+which*13;
+
+	VWB_DrawPic(x,y,C_CURSOR1PIC);
+	SetTextColor(items+which,1);
+	if (redrawitem)
+	{
+		PrintX=item_i->x+item_i->indent;
+		PrintY=item_i->y+which*13;
+		US_Print((items+which)->string);
+	}
+	//
+	// CALL CUSTOM ROUTINE IF IT IS NEEDED
+	//
+	if (routine)
+		routine(which);
+	VW_UpdateScreen();
+
+	shape=C_CURSOR1PIC;
+	timer=8;
+	exit=0;
+	TimeCount=0;
+	IN_ClearKeysDown();
+
+
+	do
+	{
+		//
+		// CHANGE GUN SHAPE
+		//
+		if (TimeCount>timer)
+		{
+			TimeCount=0;
+			if (shape==C_CURSOR1PIC)
+			{
+				shape=C_CURSOR2PIC;
+				timer=8;
+			}
+			else
+			{
+				shape=C_CURSOR1PIC;
+				timer=70;
+			}
+			VWB_DrawPic(x,y,shape);
+			if (routine)
+				routine(which);
+			VW_UpdateScreen();
+		}
+
+		CheckPause();
+
+		//
+		// SEE IF ANY KEYS ARE PRESSED FOR INITIAL CHAR FINDING
+		//
+		key=LastASCII;
+		if (key)
+		{
+			int ok=0;
+
+			//
+			// CHECK FOR SCREEN CAPTURE
+			//
+			#ifndef SPEAR
+			if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("goobers"))
+			#else
+			if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("debugmode"))
+			#endif
+				PicturePause();
+
+
+			if (key>='a')
+				key-='a'-'A';
+
+			for (i=which+1;i<item_i->amount;i++)
+				if ((items+i)->active && (items+i)->string[0]==key)
+				{
+					EraseGun(item_i,items,x,y,which);
+					which=i;
+					DrawGun(item_i,items,x,&y,which,basey,routine);
+					ok=1;
+					IN_ClearKeysDown();
+					break;
+				}
+
+			//
+			// DIDN'T FIND A MATCH FIRST TIME THRU. CHECK AGAIN.
+			//
+			if (!ok)
+			{
+				for (i=0;i<which;i++)
+					if ((items+i)->active && (items+i)->string[0]==key)
+					{
+						EraseGun(item_i,items,x,y,which);
+						which=i;
+						DrawGun(item_i,items,x,&y,which,basey,routine);
+						IN_ClearKeysDown();
+						break;
+					}
+			}
+		}
+
+		//
+		// GET INPUT
+		//
+		ReadAnyControl(&ci);
+		switch(ci.dir)
+		{
+			////////////////////////////////////////////////
+			//
+			// MOVE UP
+			//
+			case dir_North:
+
+			EraseGun(item_i,items,x,y,which);
+
+			//
+			// ANIMATE HALF-STEP
+			//
+			if (which && (items+which-1)->active)
+			{
+				y-=6;
+				DrawHalfStep(x,y);
+			}
+
+			//
+			// MOVE TO NEXT AVAILABLE SPOT
+			//
+			do
+			{
+				if (!which)
+					which=item_i->amount-1;
+				else
+					which--;
+			} while(!(items+which)->active);
+
+			DrawGun(item_i,items,x,&y,which,basey,routine);
+			//
+			// WAIT FOR BUTTON-UP OR DELAY NEXT MOVE
+			//
+			TicDelay(20);
+			break;
+
+			////////////////////////////////////////////////
+			//
+			// MOVE DOWN
+			//
+			case dir_South:
+
+			EraseGun(item_i,items,x,y,which);
+			//
+			// ANIMATE HALF-STEP
+			//
+			if (which!=item_i->amount-1 && (items+which+1)->active)
+			{
+				y+=6;
+				DrawHalfStep(x,y);
+			}
+
+			do
+			{
+				if (which==item_i->amount-1)
+					which=0;
+				else
+					which++;
+			} while(!(items+which)->active);
+
+			DrawGun(item_i,items,x,&y,which,basey,routine);
+
+			//
+			// WAIT FOR BUTTON-UP OR DELAY NEXT MOVE
+			//
+			TicDelay(20);
+			break;
+		}
+
+		if (ci.button0 ||
+			Keyboard[sc_Space] ||
+			Keyboard[sc_Enter])
+				exit=1;
+
+		if (ci.button1 ||
+			Keyboard[sc_Escape])
+				exit=2;
+
+	} while(!exit);
+
+
+	IN_ClearKeysDown();
+
+	//
+	// ERASE EVERYTHING
+	//
+	if (lastitem!=which)
+	{
+		VWB_Bar(x-1,y,25,16,BKGDCOLOR);
+		PrintX=item_i->x+item_i->indent;
+		PrintY=item_i->y+which*13;
+		US_Print((items+which)->string);
+		redrawitem=1;
+	}
+	else
+		redrawitem=0;
+
+	if (routine)
+		routine(which);
+	VW_UpdateScreen();
+
+	item_i->curpos=which;
+
+	lastitem=which;
+	switch(exit)
+	{
+		case 1:
+			//
+			// CALL THE ROUTINE
+			//
+			if ((items+which)->routine!=NULL)
+			{
+				ShootSnd();
+				MenuFadeOut();
+				(items+which)->routine(0);
+			}
+			return which;
+
+		case 2:
+			SD_PlaySound(ESCPRESSEDSND);
+			return -1;
+	}
+
+	return 0; // JUST TO SHUT UP THE ERROR MESSAGES!
+}
+
+
+//
+// ERASE GUN & DE-HIGHLIGHT STRING
+//
+void EraseGun(CP_iteminfo *item_i,CP_itemtype far *items,int x,int y,int which)
+{
+	VWB_Bar(x-1,y,25,16,BKGDCOLOR);
+	SetTextColor(items+which,0);
+
+	PrintX=item_i->x+item_i->indent;
+	PrintY=item_i->y+which*13;
+	US_Print((items+which)->string);
+	VW_UpdateScreen();
+}
+
+
+//
+// DRAW HALF STEP OF GUN TO NEXT POSITION
+//
+void DrawHalfStep(int x,int y)
+{
+	VWB_DrawPic(x,y,C_CURSOR1PIC);
+	VW_UpdateScreen();
+	SD_PlaySound(MOVEGUN1SND);
+	TimeCount=0;
+	while(TimeCount<8);
+}
+
+
+//
+// DRAW GUN AT NEW POSITION
+//
+void DrawGun(CP_iteminfo *item_i,CP_itemtype far *items,int x,int *y,int which,int basey,void (*routine)(int w))
+{
+	VWB_Bar(x-1,*y,25,16,BKGDCOLOR);
+	*y=basey+which*13;
+	VWB_DrawPic(x,*y,C_CURSOR1PIC);
+	SetTextColor(items+which,1);
+
+	PrintX=item_i->x+item_i->indent;
+	PrintY=item_i->y+which*13;
+	US_Print((items+which)->string);
+
+	//
+	// CALL CUSTOM ROUTINE IF IT IS NEEDED
+	//
+	if (routine)
+		routine(which);
+	VW_UpdateScreen();
+	SD_PlaySound(MOVEGUN2SND);
+}
+
+////////////////////////////////////////////////////////////////////
+//
+// DELAY FOR AN AMOUNT OF TICS OR UNTIL CONTROLS ARE INACTIVE
+//
+////////////////////////////////////////////////////////////////////
+void TicDelay(int count)
+{
+	ControlInfo ci;
+
+
+	TimeCount=0;
+	do
+	{
+		ReadAnyControl(&ci);
+	} while(TimeCount<count && ci.dir!=dir_None);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// Draw a menu
+//
+////////////////////////////////////////////////////////////////////
+void DrawMenu(CP_iteminfo *item_i,CP_itemtype far *items)
+{
+	int i,which=item_i->curpos;
+
+
+	WindowX=PrintX=item_i->x+item_i->indent;
+	WindowY=PrintY=item_i->y;
+	WindowW=320;
+	WindowH=200;
+
+	for (i=0;i<item_i->amount;i++)
+	{
+		SetTextColor(items+i,which==i);
+
+		PrintY=item_i->y+i*13;
+		if ((items+i)->active)
+			US_Print((items+i)->string);
+		else
+		{
+			SETFONTCOLOR(DEACTIVE,BKGDCOLOR);
+			US_Print((items+i)->string);
+			SETFONTCOLOR(TEXTCOLOR,BKGDCOLOR);
+		}
+
+		US_Print("\n");
+	}
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// SET TEXT COLOR (HIGHLIGHT OR NO)
+//
+////////////////////////////////////////////////////////////////////
+void SetTextColor(CP_itemtype far *items,int hlight)
+{
+	if (hlight)
+		{SETFONTCOLOR(color_hlite[items->active],BKGDCOLOR);}
+	else
+		{SETFONTCOLOR(color_norml[items->active],BKGDCOLOR);}
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// WAIT FOR CTRLKEY-UP OR BUTTON-UP
+//
+////////////////////////////////////////////////////////////////////
+void WaitKeyUp(void)
+{
+	ControlInfo ci;
+	while(ReadAnyControl(&ci),	ci.button0|
+								ci.button1|
+								ci.button2|
+								ci.button3|
+								Keyboard[sc_Space]|
+								Keyboard[sc_Enter]|
+								Keyboard[sc_Escape]);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// READ KEYBOARD, JOYSTICK AND MOUSE FOR INPUT
+//
+////////////////////////////////////////////////////////////////////
+void ReadAnyControl(ControlInfo *ci)
+{
+	int mouseactive=0;
+
+
+	IN_ReadControl(0,ci);
+
+	if (mouseenabled)
+	{
+		int mousey,mousex;
+
+
+		// READ MOUSE MOTION COUNTERS
+		// RETURN DIRECTION
+		// HOME MOUSE
+		// CHECK MOUSE BUTTONS
+
+		Mouse(3);
+		mousex=_CX;
+		mousey=_DX;
+
+		if (mousey<CENTER-SENSITIVE)
+		{
+			ci->dir=dir_North;
+			_CX=_DX=CENTER;
+			Mouse(4);
+			mouseactive=1;
+		}
+		else
+		if (mousey>CENTER+SENSITIVE)
+		{
+			ci->dir=dir_South;
+			_CX=_DX=CENTER;
+			Mouse(4);
+			mouseactive=1;
+		}
+
+		if (mousex<CENTER-SENSITIVE)
+		{
+			ci->dir=dir_West;
+			_CX=_DX=CENTER;
+			Mouse(4);
+			mouseactive=1;
+		}
+		else
+		if (mousex>CENTER+SENSITIVE)
+		{
+			ci->dir=dir_East;
+			_CX=_DX=CENTER;
+			Mouse(4);
+			mouseactive=1;
+		}
+
+		if (IN_MouseButtons())
+		{
+			ci->button0=IN_MouseButtons()&1;
+			ci->button1=IN_MouseButtons()&2;
+			ci->button2=IN_MouseButtons()&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;
+		}
+	}
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// DRAW DIALOG AND CONFIRM YES OR NO TO QUESTION
+//
+////////////////////////////////////////////////////////////////////
+int Confirm(char far *string)
+{
+	int xit=0,i,x,y,tick=0,time,whichsnd[2]={ESCPRESSEDSND,SHOOTSND};
+
+
+	Message(string);
+	IN_ClearKeysDown();
+
+	//
+	// BLINK CURSOR
+	//
+	x=PrintX;
+	y=PrintY;
+	TimeCount=0;
+
+	do
+	{
+		if (TimeCount>=10)
+		{
+			switch(tick)
+			{
+				case 0:
+					VWB_Bar(x,y,8,13,TEXTCOLOR);
+					break;
+				case 1:
+					PrintX=x;
+					PrintY=y;
+					US_Print("_");
+			}
+			VW_UpdateScreen();
+			tick^=1;
+			TimeCount=0;
+		}
+
+		#ifndef SPEAR
+		if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("goobers"))
+			PicturePause();
+		#endif
+
+	#ifdef SPANISH
+	} while(!Keyboard[sc_S] && !Keyboard[sc_N] && !Keyboard[sc_Escape]);
+	#else
+	} while(!Keyboard[sc_Y] && !Keyboard[sc_N] && !Keyboard[sc_Escape]);
+	#endif
+
+	#ifdef SPANISH
+	if (Keyboard[sc_S])
+	{
+		xit=1;
+		ShootSnd();
+	}
+
+	while(Keyboard[sc_S] || Keyboard[sc_N] || Keyboard[sc_Escape]);
+
+	#else
+
+	if (Keyboard[sc_Y])
+	{
+		xit=1;
+		ShootSnd();
+	}
+
+	while(Keyboard[sc_Y] || Keyboard[sc_N] || Keyboard[sc_Escape]);
+	#endif
+
+	IN_ClearKeysDown();
+	SD_PlaySound(whichsnd[xit]);
+	return xit;
+}
+
+#ifdef JAPAN
+////////////////////////////////////////////////////////////////////
+//
+// DRAW MESSAGE & GET Y OR N
+//
+////////////////////////////////////////////////////////////////////
+int GetYorN(int x,int y,int pic)
+{
+	int xit=0,whichsnd[2]={ESCPRESSEDSND,SHOOTSND};
+
+
+	CA_CacheGrChunk(pic);
+	VWB_DrawPic(x * 8,y * 8,pic);
+	UNCACHEGRCHUNK(pic);
+	VW_UpdateScreen();
+	IN_ClearKeysDown();
+
+	do
+	{
+		#ifndef SPEAR
+		if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("goobers"))
+			PicturePause();
+		#endif
+
+	#ifdef SPANISH
+	} while(!Keyboard[sc_S] && !Keyboard[sc_N] && !Keyboard[sc_Escape]);
+	#else
+	} while(!Keyboard[sc_Y] && !Keyboard[sc_N] && !Keyboard[sc_Escape]);
+	#endif
+
+	#ifdef SPANISH
+	if (Keyboard[sc_S])
+	{
+		xit=1;
+		ShootSnd();
+	}
+
+	while(Keyboard[sc_S] || Keyboard[sc_N] || Keyboard[sc_Escape]);
+
+	#else
+
+	if (Keyboard[sc_Y])
+	{
+		xit=1;
+		ShootSnd();
+	}
+
+	while(Keyboard[sc_Y] || Keyboard[sc_N] || Keyboard[sc_Escape]);
+	#endif
+
+	IN_ClearKeysDown();
+	SD_PlaySound(whichsnd[xit]);
+	return xit;
+}
+#endif
+
+
+////////////////////////////////////////////////////////////////////
+//
+// PRINT A MESSAGE IN A WINDOW
+//
+////////////////////////////////////////////////////////////////////
+void Message(char far *string)
+{
+	int h=0,w=0,mw=0,i,x,y,time;
+	fontstruct _seg *font;
+
+
+	CA_CacheGrChunk (STARTFONT+1);
+	fontnumber=1;
+	font=grsegs[STARTFONT+fontnumber];
+	h=font->height;
+	for (i=0;i<_fstrlen(string);i++)
+		if (string[i]=='\n')
+		{
+			if (w>mw)
+				mw=w;
+			w=0;
+			h+=font->height;
+		}
+		else
+			w+=font->width[string[i]];
+
+	if (w+10>mw)
+		mw=w+10;
+
+	PrintY=(WindowH/2)-h/2;
+	PrintX=WindowX=160-mw/2;
+
+	DrawWindow(WindowX-5,PrintY-5,mw+10,h+10,TEXTCOLOR);
+	DrawOutline(WindowX-5,PrintY-5,mw+10,h+10,0,HIGHLIGHT);
+	SETFONTCOLOR(0,TEXTCOLOR);
+	US_Print(string);
+	VW_UpdateScreen();
+}
+
+
+////////////////////////////////////////////////////////////////////
+//
+// THIS MAY BE FIXED A LITTLE LATER...
+//
+////////////////////////////////////////////////////////////////////
+static	int	lastmusic;
+
+void StartCPMusic(int song)
+{
+	musicnames	chunk;
+
+	if (audiosegs[STARTMUSIC + lastmusic])	// JDC
+		MM_FreePtr ((memptr *)&audiosegs[STARTMUSIC + lastmusic]);
+	lastmusic = song;
+
+	SD_MusicOff();
+	chunk =	song;
+
+	MM_BombOnError (false);
+	CA_CacheAudioChunk(STARTMUSIC + chunk);
+	MM_BombOnError (true);
+	if (mmerror)
+		mmerror = false;
+	else
+	{
+		MM_SetLock(&((memptr)audiosegs[STARTMUSIC + chunk]),true);
+		SD_StartMusic((MusicGroup far *)audiosegs[STARTMUSIC + chunk]);
+	}
+}
+
+void FreeMusic (void)
+{
+	if (audiosegs[STARTMUSIC + lastmusic])	// JDC
+		MM_FreePtr ((memptr *)&audiosegs[STARTMUSIC + lastmusic]);
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	IN_GetScanName() - Returns a string containing the name of the
+//		specified scan code
+//
+///////////////////////////////////////////////////////////////////////////
+byte *
+IN_GetScanName(ScanCode scan)
+{
+	byte		**p;
+	ScanCode	far *s;
+
+	for (s = ExtScanCodes,p = ExtScanNames;*s;p++,s++)
+		if (*s == scan)
+			return(*p);
+
+	return(ScanNames[scan]);
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// CHECK FOR PAUSE KEY (FOR MUSIC ONLY)
+//
+///////////////////////////////////////////////////////////////////////////
+void CheckPause(void)
+{
+	if (Paused)
+	{
+		switch(SoundStatus)
+		{
+			case 0: SD_MusicOn(); break;
+			case 1: SD_MusicOff(); break;
+		}
+
+		SoundStatus^=1;
+		VW_WaitVBL(3);
+		IN_ClearKeysDown();
+		Paused=false;
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// DRAW GUN CURSOR AT CORRECT POSITION IN MENU
+//
+///////////////////////////////////////////////////////////////////////////
+void DrawMenuGun(CP_iteminfo *iteminfo)
+{
+	int x,y;
+
+
+	x=iteminfo->x;
+	y=iteminfo->y+iteminfo->curpos*13-2;
+	VWB_DrawPic(x,y,C_CURSOR1PIC);
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// DRAW SCREEN TITLE STRIPES
+//
+///////////////////////////////////////////////////////////////////////////
+void DrawStripes(int y)
+{
+#ifndef SPEAR
+	VWB_Bar(0,y,320,24,0);
+	VWB_Hlin(0,319,y+22,STRIPE);
+#else
+	VWB_Bar(0,y,320,22,0);
+	VWB_Hlin(0,319,y+23,0);
+#endif
+}
+
+void ShootSnd(void)
+{
+	SD_PlaySound(SHOOTSND);
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// CHECK FOR EPISODES
+//
+///////////////////////////////////////////////////////////////////////////
+void CheckForEpisodes(void)
+{
+	struct ffblk f;
+
+//
+// JAPANESE VERSION
+//
+#ifdef JAPAN
+#ifdef JAPDEMO
+	if (!findfirst("*.WJ1",&f,FA_ARCH))
+	{
+		strcpy(extension,"WJ1");
+#else
+	if (!findfirst("*.WJ6",&f,FA_ARCH))
+	{
+		strcpy(extension,"WJ6");
+#endif
+		strcat(configname,extension);
+		strcat(SaveName,extension);
+		strcat(PageFileName,extension);
+		strcat(audioname,extension);
+		strcat(demoname,extension);
+		EpisodeSelect[1] =
+		EpisodeSelect[2] =
+		EpisodeSelect[3] =
+		EpisodeSelect[4] =
+		EpisodeSelect[5] = 1;
+	}
+	else
+		Quit("NO JAPANESE WOLFENSTEIN 3-D DATA FILES to be found!");
+#else
+
+//
+// ENGLISH
+//
+#ifndef UPLOAD
+#ifndef SPEAR
+	if (!findfirst("*.WL6",&f,FA_ARCH))
+	{
+		strcpy(extension,"WL6");
+		NewEmenu[2].active =
+		NewEmenu[4].active =
+		NewEmenu[6].active =
+		NewEmenu[8].active =
+		NewEmenu[10].active =
+		EpisodeSelect[1] =
+		EpisodeSelect[2] =
+		EpisodeSelect[3] =
+		EpisodeSelect[4] =
+		EpisodeSelect[5] = 1;
+	}
+	else
+	if (!findfirst("*.WL3",&f,FA_ARCH))
+	{
+		strcpy(extension,"WL3");
+		NewEmenu[2].active =
+		NewEmenu[4].active =
+		EpisodeSelect[1] =
+		EpisodeSelect[2] = 1;
+	}
+	else
+#endif
+#endif
+
+
+
+#ifdef SPEAR
+#ifndef SPEARDEMO
+	if (!findfirst("*.SOD",&f,FA_ARCH))
+	{
+		strcpy(extension,"SOD");
+	}
+	else
+		Quit("NO SPEAR OF DESTINY DATA FILES TO BE FOUND!");
+#else
+	if (!findfirst("*.SDM",&f,FA_ARCH))
+	{
+		strcpy(extension,"SDM");
+	}
+	else
+		Quit("NO SPEAR OF DESTINY DEMO DATA FILES TO BE FOUND!");
+#endif
+
+#else
+	if (!findfirst("*.WL1",&f,FA_ARCH))
+	{
+		strcpy(extension,"WL1");
+	}
+	else
+		Quit("NO WOLFENSTEIN 3-D DATA FILES to be found!");
+#endif
+
+	strcat(configname,extension);
+	strcat(SaveName,extension);
+	strcat(PageFileName,extension);
+	strcat(audioname,extension);
+	strcat(demoname,extension);
+#ifndef SPEAR
+#ifndef GOODTIMES
+	strcat(helpfilename,extension);
+#endif
+	strcat(endfilename,extension);
+#endif
+#endif
+}
--- /dev/null
+++ b/WOLFSRC/WL_MENU.H
@@ -1,0 +1,231 @@
+//
+// WL_MENU.H
+//
+#ifdef SPEAR
+
+#define BORDCOLOR	0x99
+#define BORD2COLOR	0x93
+#define DEACTIVE	0x9b
+#define BKGDCOLOR	0x9d
+//#define STRIPE		0x9c
+
+#define MenuFadeOut()	VL_FadeOut(0,255,0,0,51,10)
+
+#else
+
+#define BORDCOLOR	0x29
+#define BORD2COLOR	0x23
+#define DEACTIVE	0x2b
+#define BKGDCOLOR	0x2d
+#define STRIPE		0x2c
+
+#define MenuFadeOut()	VL_FadeOut(0,255,43,0,0,10)
+
+#endif
+
+#define READCOLOR	0x4a
+#define READHCOLOR	0x47
+#define VIEWCOLOR	0x7f
+#define TEXTCOLOR	0x17
+#define HIGHLIGHT	0x13
+#define MenuFadeIn()	VL_FadeIn(0,255,&gamepal,10)
+
+
+#define MENUSONG	WONDERIN_MUS
+
+#ifndef SPEAR
+#define INTROSONG	NAZI_NOR_MUS
+#else
+#define INTROSONG	XTOWER2_MUS
+#endif
+
+#define SENSITIVE	60
+#define CENTER		SENSITIVE*2
+
+#define MENU_X	76
+#define MENU_Y	55
+#define MENU_W	178
+#ifndef SPEAR
+#define MENU_H	13*10+6
+#else
+#define MENU_H	13*9+6
+#endif
+
+#define SM_X	48
+#define SM_W	250
+
+#define SM_Y1	20
+#define SM_H1	4*13-7
+#define SM_Y2	SM_Y1+5*13
+#define SM_H2	4*13-7
+#define SM_Y3	SM_Y2+5*13
+#define SM_H3	3*13-7
+
+#define CTL_X	24
+#define CTL_Y	70
+#define CTL_W	284
+#define CTL_H	13*7-7
+
+#define LSM_X	85
+#define LSM_Y	55
+#define LSM_W	175
+#define LSM_H	10*13+10
+
+#define NM_X	50
+#define NM_Y	100
+#define NM_W	225
+#define NM_H	13*4+15
+
+#define NE_X	10
+#define NE_Y	23
+#define NE_W	320-NE_X*2
+#define NE_H	200-NE_Y*2
+
+#define CST_X		20
+#define CST_Y		48
+#define CST_START	60
+#define CST_SPC	60
+
+
+//
+// TYPEDEFS
+//
+typedef struct {
+		int x,y,amount,curpos,indent;
+		} CP_iteminfo;
+
+typedef struct {
+		int active;
+		char string[36];
+		void (* routine)(int temp1);
+		} CP_itemtype;
+
+typedef struct {
+		int allowed[4];
+		} CustomCtrls;
+
+extern CP_itemtype far MainMenu[],far NewEMenu[];
+extern CP_iteminfo MainItems;
+
+//
+// FUNCTION PROTOTYPES
+//
+void SetupControlPanel(void);
+void CleanupControlPanel(void);
+
+void DrawMenu(CP_iteminfo *item_i,CP_itemtype far *items);
+int  HandleMenu(CP_iteminfo *item_i,
+		CP_itemtype far *items,
+		void (*routine)(int w));
+void ClearMScreen(void);
+void DrawWindow(int x,int y,int w,int h,int wcolor);
+void DrawOutline(int x,int y,int w,int h,int color1,int color2);
+void WaitKeyUp(void);
+void ReadAnyControl(ControlInfo *ci);
+void TicDelay(int count);
+void CacheLump(int lumpstart,int lumpend);
+void UnCacheLump(int lumpstart,int lumpend);
+void StartCPMusic(int song);
+int  Confirm(char far *string);
+void Message(char far *string);
+void CheckPause(void);
+void ShootSnd(void);
+void CheckSecretMissions(void);
+void BossKey(void);
+
+void DrawGun(CP_iteminfo *item_i,CP_itemtype far *items,int x,int *y,int which,int basey,void (*routine)(int w));
+void DrawHalfStep(int x,int y);
+void EraseGun(CP_iteminfo *item_i,CP_itemtype far *items,int x,int y,int which);
+void SetTextColor(CP_itemtype far *items,int hlight);
+void DrawMenuGun(CP_iteminfo *iteminfo);
+void DrawStripes(int y);
+
+void DefineMouseBtns(void);
+void DefineJoyBtns(void);
+void DefineKeyBtns(void);
+void DefineKeyMove(void);
+void EnterCtrlData(int index,CustomCtrls *cust,void (*DrawRtn)(int),void (*PrintRtn)(int),int type);
+
+void DrawMainMenu(void);
+void DrawSoundMenu(void);
+void DrawLoadSaveScreen(int loadsave);
+void DrawNewEpisode(void);
+void DrawNewGame(void);
+void DrawChangeView(int view);
+void DrawMouseSens(void);
+void DrawCtlScreen(void);
+void DrawCustomScreen(void);
+void DrawLSAction(int which);
+void DrawCustMouse(int hilight);
+void DrawCustJoy(int hilight);
+void DrawCustKeybd(int hilight);
+void DrawCustKeys(int hilight);
+void PrintCustMouse(int i);
+void PrintCustJoy(int i);
+void PrintCustKeybd(int i);
+void PrintCustKeys(int i);
+
+void PrintLSEntry(int w,int color);
+void TrackWhichGame(int w);
+void DrawNewGameDiff(int w);
+void FixupCustom(int w);
+
+void CP_NewGame(void);
+void CP_Sound(void);
+int  CP_LoadGame(int quick);
+int  CP_SaveGame(int quick);
+void CP_Control(void);
+void CP_ChangeView(void);
+void CP_ExitOptions(void);
+void CP_Quit(void);
+void CP_ViewScores(void);
+int  CP_EndGame(void);
+int  CP_CheckQuick(unsigned scancode);
+void CustomControls(void);
+void MouseSensitivity(void);
+
+void CheckForEpisodes(void);
+
+//
+// VARIABLES
+//
+extern int SaveGamesAvail[10],StartGame,SoundStatus;
+extern char SaveGameNames[10][32],SaveName[13];
+
+enum {MOUSE,JOYSTICK,KEYBOARDBTNS,KEYBOARDMOVE};	// FOR INPUT TYPES
+
+enum
+{
+	newgame,
+	soundmenu,
+	control,
+	loadgame,
+	savegame,
+	changeview,
+
+#ifndef GOODTIMES
+#ifndef SPEAR
+	readthis,
+#endif
+#endif
+
+	viewscores,
+	backtodemo,
+	quit
+} menuitems;
+
+//
+// WL_INTER
+//
+typedef struct {
+		int kill,secret,treasure;
+		long time;
+		} LRstruct;
+
+extern LRstruct LevelRatios[];
+
+void Write (int x,int y,char *string);
+void NonShareware(void);
+int GetYorN(int x,int y,int pic);
+
+
--- /dev/null
+++ b/WOLFSRC/WL_PLAY.C
@@ -1,0 +1,1472 @@
+// WL_PLAY.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+
+
+/*
+=============================================================================
+
+						 LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+#define sc_Question	0x35
+
+/*
+=============================================================================
+
+						 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+boolean		madenoise;					// true when shooting or screaming
+
+exit_t		playstate;
+
+int			DebugOk;
+
+objtype 	objlist[MAXACTORS],*new,*obj,*player,*lastobj,
+			*objfreelist,*killerobj;
+
+unsigned	farmapylookup[MAPSIZE];
+byte		*nearmapylookup[MAPSIZE];
+
+boolean		singlestep,godmode,noclip;
+int			extravbls;
+
+byte		tilemap[MAPSIZE][MAPSIZE];	// wall values only
+byte		spotvis[MAPSIZE][MAPSIZE];
+objtype		*actorat[MAPSIZE][MAPSIZE];
+
+//
+// replacing refresh manager
+//
+unsigned	mapwidth,mapheight,tics;
+boolean		compatability;
+byte		*updateptr;
+unsigned	mapwidthtable[64];
+unsigned	uwidthtable[UPDATEHIGH];
+unsigned	blockstarts[UPDATEWIDE*UPDATEHIGH];
+byte		update[UPDATESIZE];
+
+//
+// control info
+//
+boolean		mouseenabled,joystickenabled,joypadenabled,joystickprogressive;
+int			joystickport;
+int			dirscan[4] = {sc_UpArrow,sc_RightArrow,sc_DownArrow,sc_LeftArrow};
+int			buttonscan[NUMBUTTONS] =
+			{sc_Control,sc_Alt,sc_RShift,sc_Space,sc_1,sc_2,sc_3,sc_4};
+int			buttonmouse[4]={bt_attack,bt_strafe,bt_use,bt_nobutton};
+int			buttonjoy[4]={bt_attack,bt_strafe,bt_use,bt_run};
+
+int			viewsize;
+
+boolean		buttonheld[NUMBUTTONS];
+
+boolean		demorecord,demoplayback;
+char		far *demoptr, far *lastdemoptr;
+memptr		demobuffer;
+
+//
+// curent user input
+//
+int			controlx,controly;		// range from -100 to 100 per tic
+boolean		buttonstate[NUMBUTTONS];
+
+
+
+//===========================================================================
+
+
+void	CenterWindow(word w,word h);
+void 	InitObjList (void);
+void 	RemoveObj (objtype *gone);
+void 	PollControls (void);
+void 	StopMusic(void);
+void 	StartMusic(void);
+void	PlayLoop (void);
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+
+objtype dummyobj;
+
+//
+// LIST OF SONGS FOR EACH VERSION
+//
+int songs[]=
+{
+#ifndef SPEAR
+ //
+ // Episode One
+ //
+ GETTHEM_MUS,
+ SEARCHN_MUS,
+ POW_MUS,
+ SUSPENSE_MUS,
+ GETTHEM_MUS,
+ SEARCHN_MUS,
+ POW_MUS,
+ SUSPENSE_MUS,
+
+ WARMARCH_MUS,	// Boss level
+ CORNER_MUS,	// Secret level
+
+ //
+ // Episode Two
+ //
+ NAZI_OMI_MUS,
+ PREGNANT_MUS,
+ GOINGAFT_MUS,
+ HEADACHE_MUS,
+ NAZI_OMI_MUS,
+ PREGNANT_MUS,
+ HEADACHE_MUS,
+ GOINGAFT_MUS,
+
+ WARMARCH_MUS,	// Boss level
+ DUNGEON_MUS,	// Secret level
+
+ //
+ // Episode Three
+ //
+ INTROCW3_MUS,
+ NAZI_RAP_MUS,
+ TWELFTH_MUS,
+ ZEROHOUR_MUS,
+ INTROCW3_MUS,
+ NAZI_RAP_MUS,
+ TWELFTH_MUS,
+ ZEROHOUR_MUS,
+
+ ULTIMATE_MUS,	// Boss level
+ PACMAN_MUS,	// Secret level
+
+ //
+ // Episode Four
+ //
+ GETTHEM_MUS,
+ SEARCHN_MUS,
+ POW_MUS,
+ SUSPENSE_MUS,
+ GETTHEM_MUS,
+ SEARCHN_MUS,
+ POW_MUS,
+ SUSPENSE_MUS,
+
+ WARMARCH_MUS,	// Boss level
+ CORNER_MUS,	// Secret level
+
+ //
+ // Episode Five
+ //
+ NAZI_OMI_MUS,
+ PREGNANT_MUS,
+ GOINGAFT_MUS,
+ HEADACHE_MUS,
+ NAZI_OMI_MUS,
+ PREGNANT_MUS,
+ HEADACHE_MUS,
+ GOINGAFT_MUS,
+
+ WARMARCH_MUS,	// Boss level
+ DUNGEON_MUS,	// Secret level
+
+ //
+ // Episode Six
+ //
+ INTROCW3_MUS,
+ NAZI_RAP_MUS,
+ TWELFTH_MUS,
+ ZEROHOUR_MUS,
+ INTROCW3_MUS,
+ NAZI_RAP_MUS,
+ TWELFTH_MUS,
+ ZEROHOUR_MUS,
+
+ ULTIMATE_MUS,	// Boss level
+ FUNKYOU_MUS		// Secret level
+#else
+
+ //////////////////////////////////////////////////////////////
+ //
+ // SPEAR OF DESTINY TRACKS
+ //
+ //////////////////////////////////////////////////////////////
+ XTIPTOE_MUS,
+ XFUNKIE_MUS,
+ XDEATH_MUS,
+ XGETYOU_MUS,		// DON'T KNOW
+ ULTIMATE_MUS,	// Trans Gr�sse
+
+ DUNGEON_MUS,
+ GOINGAFT_MUS,
+ POW_MUS,
+ TWELFTH_MUS,
+ ULTIMATE_MUS,	// Barnacle Wilhelm BOSS
+
+ NAZI_OMI_MUS,
+ GETTHEM_MUS,
+ SUSPENSE_MUS,
+ SEARCHN_MUS,
+ ZEROHOUR_MUS,
+ ULTIMATE_MUS,	// Super Mutant BOSS
+
+ XPUTIT_MUS,
+ ULTIMATE_MUS,	// Death Knight BOSS
+
+ XJAZNAZI_MUS,	// Secret level
+ XFUNKIE_MUS,	// Secret level (DON'T KNOW)
+
+ XEVIL_MUS		// Angel of Death BOSS
+
+#endif
+};
+
+
+/*
+=============================================================================
+
+						  USER CONTROL
+
+=============================================================================
+*/
+
+
+#define BASEMOVE		35
+#define RUNMOVE			70
+#define BASETURN		35
+#define RUNTURN			70
+
+#define JOYSCALE		2
+
+/*
+===================
+=
+= PollKeyboardButtons
+=
+===================
+*/
+
+void PollKeyboardButtons (void)
+{
+	int		i;
+
+	for (i=0;i<NUMBUTTONS;i++)
+		if (Keyboard[buttonscan[i]])
+			buttonstate[i] = true;
+}
+
+
+/*
+===================
+=
+= PollMouseButtons
+=
+===================
+*/
+
+void PollMouseButtons (void)
+{
+	int	buttons;
+
+	buttons = IN_MouseButtons ();
+
+	if (buttons&1)
+		buttonstate[buttonmouse[0]] = true;
+	if (buttons&2)
+		buttonstate[buttonmouse[1]] = true;
+	if (buttons&4)
+		buttonstate[buttonmouse[2]] = true;
+}
+
+
+
+/*
+===================
+=
+= PollJoystickButtons
+=
+===================
+*/
+
+void PollJoystickButtons (void)
+{
+	int	buttons;
+
+	buttons = IN_JoyButtons ();
+
+	if (joystickport && !joypadenabled)
+	{
+		if (buttons&4)
+			buttonstate[buttonjoy[0]] = true;
+		if (buttons&8)
+			buttonstate[buttonjoy[1]] = true;
+	}
+	else
+	{
+		if (buttons&1)
+			buttonstate[buttonjoy[0]] = true;
+		if (buttons&2)
+			buttonstate[buttonjoy[1]] = true;
+		if (joypadenabled)
+		{
+			if (buttons&4)
+				buttonstate[buttonjoy[2]] = true;
+			if (buttons&8)
+				buttonstate[buttonjoy[3]] = true;
+		}
+	}
+}
+
+
+/*
+===================
+=
+= PollKeyboardMove
+=
+===================
+*/
+
+void PollKeyboardMove (void)
+{
+	if (buttonstate[bt_run])
+	{
+		if (Keyboard[dirscan[di_north]])
+			controly -= RUNMOVE*tics;
+		if (Keyboard[dirscan[di_south]])
+			controly += RUNMOVE*tics;
+		if (Keyboard[dirscan[di_west]])
+			controlx -= RUNMOVE*tics;
+		if (Keyboard[dirscan[di_east]])
+			controlx += RUNMOVE*tics;
+	}
+	else
+	{
+		if (Keyboard[dirscan[di_north]])
+			controly -= BASEMOVE*tics;
+		if (Keyboard[dirscan[di_south]])
+			controly += BASEMOVE*tics;
+		if (Keyboard[dirscan[di_west]])
+			controlx -= BASEMOVE*tics;
+		if (Keyboard[dirscan[di_east]])
+			controlx += BASEMOVE*tics;
+	}
+}
+
+
+/*
+===================
+=
+= PollMouseMove
+=
+===================
+*/
+
+void PollMouseMove (void)
+{
+	int	mousexmove,mouseymove;
+
+	Mouse(MDelta);
+	mousexmove = _CX;
+	mouseymove = _DX;
+
+	controlx += mousexmove*10/(13-mouseadjustment);
+	controly += mouseymove*20/(13-mouseadjustment);
+}
+
+
+
+/*
+===================
+=
+= PollJoystickMove
+=
+===================
+*/
+
+void PollJoystickMove (void)
+{
+	int	joyx,joyy;
+
+	INL_GetJoyDelta(joystickport,&joyx,&joyy);
+
+	if (joystickprogressive)
+	{
+		if (joyx > 64)
+			controlx += (joyx-64)*JOYSCALE*tics;
+		else if (joyx < -64)
+			controlx -= (-joyx-64)*JOYSCALE*tics;
+		if (joyy > 64)
+			controlx += (joyy-64)*JOYSCALE*tics;
+		else if (joyy < -64)
+			controly -= (-joyy-64)*JOYSCALE*tics;
+	}
+	else if (buttonstate[bt_run])
+	{
+		if (joyx > 64)
+			controlx += RUNMOVE*tics;
+		else if (joyx < -64)
+			controlx -= RUNMOVE*tics;
+		if (joyy > 64)
+			controly += RUNMOVE*tics;
+		else if (joyy < -64)
+			controly -= RUNMOVE*tics;
+	}
+	else
+	{
+		if (joyx > 64)
+			controlx += BASEMOVE*tics;
+		else if (joyx < -64)
+			controlx -= BASEMOVE*tics;
+		if (joyy > 64)
+			controly += BASEMOVE*tics;
+		else if (joyy < -64)
+			controly -= BASEMOVE*tics;
+	}
+}
+
+
+/*
+===================
+=
+= PollControls
+=
+= Gets user or demo input, call once each frame
+=
+= controlx		set between -100 and 100 per tic
+= controly
+= buttonheld[]	the state of the buttons LAST frame
+= buttonstate[]	the state of the buttons THIS frame
+=
+===================
+*/
+
+void PollControls (void)
+{
+	int		max,min,i;
+	byte	buttonbits;
+
+//
+// get timing info for last frame
+//
+	if (demoplayback)
+	{
+		while (TimeCount<lasttimecount+DEMOTICS)
+		;
+		TimeCount = lasttimecount + DEMOTICS;
+		lasttimecount += DEMOTICS;
+		tics = DEMOTICS;
+	}
+	else if (demorecord)			// demo recording and playback needs
+	{								// to be constant
+//
+// take DEMOTICS or more tics, and modify Timecount to reflect time taken
+//
+		while (TimeCount<lasttimecount+DEMOTICS)
+		;
+		TimeCount = lasttimecount + DEMOTICS;
+		lasttimecount += DEMOTICS;
+		tics = DEMOTICS;
+	}
+	else
+		CalcTics ();
+
+	controlx = 0;
+	controly = 0;
+	memcpy (buttonheld,buttonstate,sizeof(buttonstate));
+	memset (buttonstate,0,sizeof(buttonstate));
+
+	if (demoplayback)
+	{
+	//
+	// read commands from demo buffer
+	//
+		buttonbits = *demoptr++;
+		for (i=0;i<NUMBUTTONS;i++)
+		{
+			buttonstate[i] = buttonbits&1;
+			buttonbits >>= 1;
+		}
+
+		controlx = *demoptr++;
+		controly = *demoptr++;
+
+		if (demoptr == lastdemoptr)
+			playstate = ex_completed;		// demo is done
+
+		controlx *= (int)tics;
+		controly *= (int)tics;
+
+		return;
+	}
+
+
+//
+// get button states
+//
+	PollKeyboardButtons ();
+
+	if (mouseenabled)
+		PollMouseButtons ();
+
+	if (joystickenabled)
+		PollJoystickButtons ();
+
+//
+// get movements
+//
+	PollKeyboardMove ();
+
+	if (mouseenabled)
+		PollMouseMove ();
+
+	if (joystickenabled)
+		PollJoystickMove ();
+
+//
+// bound movement to a maximum
+//
+	max = 100*tics;
+	min = -max;
+	if (controlx > max)
+		controlx = max;
+	else if (controlx < min)
+		controlx = min;
+
+	if (controly > max)
+		controly = max;
+	else if (controly < min)
+		controly = min;
+
+	if (demorecord)
+	{
+	//
+	// save info out to demo buffer
+	//
+		controlx /= (int)tics;
+		controly /= (int)tics;
+
+		buttonbits = 0;
+
+		for (i=NUMBUTTONS-1;i>=0;i--)
+		{
+			buttonbits <<= 1;
+			if (buttonstate[i])
+				buttonbits |= 1;
+		}
+
+		*demoptr++ = buttonbits;
+		*demoptr++ = controlx;
+		*demoptr++ = controly;
+
+		if (demoptr >= lastdemoptr)
+			Quit ("Demo buffer overflowed!");
+
+		controlx *= (int)tics;
+		controly *= (int)tics;
+	}
+}
+
+
+
+//==========================================================================
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+//	CenterWindow() - Generates a window of a given width & height in the
+//		middle of the screen
+//
+///////////////////////////////////////////////////////////////////////////
+
+#define MAXX	320
+#define MAXY	160
+
+void	CenterWindow(word w,word h)
+{
+	FixOfs ();
+	US_DrawWindow(((MAXX / 8) - w) / 2,((MAXY / 8) - h) / 2,w,h);
+}
+
+//===========================================================================
+
+
+/*
+=====================
+=
+= CheckKeys
+=
+=====================
+*/
+
+void CheckKeys (void)
+{
+	int		i;
+	byte	scan;
+	unsigned	temp;
+
+
+	if (screenfaded || demoplayback)	// don't do anything with a faded screen
+		return;
+
+	scan = LastScan;
+
+
+	#ifdef SPEAR
+	//
+	// SECRET CHEAT CODE: TAB-G-F10
+	//
+	if (Keyboard[sc_Tab] &&
+		Keyboard[sc_G] &&
+		Keyboard[sc_F10])
+	{
+		WindowH = 160;
+		if (godmode)
+		{
+			Message ("God mode OFF");
+			SD_PlaySound (NOBONUSSND);
+		}
+		else
+		{
+			Message ("God mode ON");
+			SD_PlaySound (ENDBONUS2SND);
+		}
+
+		IN_Ack();
+		godmode ^= 1;
+		DrawAllPlayBorderSides ();
+		IN_ClearKeysDown();
+		return;
+	}
+	#endif
+
+
+	//
+	// SECRET CHEAT CODE: 'MLI'
+	//
+	if (Keyboard[sc_M] &&
+		Keyboard[sc_L] &&
+		Keyboard[sc_I])
+	{
+		gamestate.health = 100;
+		gamestate.ammo = 99;
+		gamestate.keys = 3;
+		gamestate.score = 0;
+		gamestate.TimeCount += 42000L;
+		GiveWeapon (wp_chaingun);
+
+		DrawWeapon();
+		DrawHealth();
+		DrawKeys();
+		DrawAmmo();
+		DrawScore();
+
+		ClearMemory ();
+		CA_CacheGrChunk (STARTFONT+1);
+		ClearSplitVWB ();
+		VW_ScreenToScreen (displayofs,bufferofs,80,160);
+
+		Message(STR_CHEATER1"\n"
+				STR_CHEATER2"\n\n"
+				STR_CHEATER3"\n"
+				STR_CHEATER4"\n"
+				STR_CHEATER5);
+
+		UNCACHEGRCHUNK(STARTFONT+1);
+		PM_CheckMainMem ();
+		IN_ClearKeysDown();
+		IN_Ack();
+
+		DrawAllPlayBorder ();
+	}
+
+	//
+	// OPEN UP DEBUG KEYS
+	//
+#ifndef SPEAR
+	if (Keyboard[sc_BackSpace] &&
+		Keyboard[sc_LShift] &&
+		Keyboard[sc_Alt] &&
+		MS_CheckParm("goobers"))
+#else
+	if (Keyboard[sc_BackSpace] &&
+		Keyboard[sc_LShift] &&
+		Keyboard[sc_Alt] &&
+		MS_CheckParm("debugmode"))
+#endif
+	{
+	 ClearMemory ();
+	 CA_CacheGrChunk (STARTFONT+1);
+	 ClearSplitVWB ();
+	 VW_ScreenToScreen (displayofs,bufferofs,80,160);
+
+	 Message("Debugging keys are\nnow available!");
+	 UNCACHEGRCHUNK(STARTFONT+1);
+	 PM_CheckMainMem ();
+	 IN_ClearKeysDown();
+	 IN_Ack();
+
+	 DrawAllPlayBorderSides ();
+	 DebugOk=1;
+	}
+
+	//
+	// TRYING THE KEEN CHEAT CODE!
+	//
+	if (Keyboard[sc_B] &&
+		Keyboard[sc_A] &&
+		Keyboard[sc_T])
+	{
+	 ClearMemory ();
+	 CA_CacheGrChunk (STARTFONT+1);
+	 ClearSplitVWB ();
+	 VW_ScreenToScreen (displayofs,bufferofs,80,160);
+
+	 Message("Commander Keen is also\n"
+			 "available from Apogee, but\n"
+			 "then, you already know\n"
+			 "that - right, Cheatmeister?!");
+
+	 UNCACHEGRCHUNK(STARTFONT+1);
+	 PM_CheckMainMem ();
+	 IN_ClearKeysDown();
+	 IN_Ack();
+
+	 DrawAllPlayBorder ();
+	}
+
+//
+// pause key weirdness can't be checked as a scan code
+//
+	if (Paused)
+	{
+		bufferofs = displayofs;
+		LatchDrawPic (20-4,80-2*8,PAUSEDPIC);
+		SD_MusicOff();
+		IN_Ack();
+		IN_ClearKeysDown ();
+		SD_MusicOn();
+		Paused = false;
+		if (MousePresent)
+			Mouse(MDelta);	// Clear accumulated mouse movement
+		return;
+	}
+
+
+//
+// F1-F7/ESC to enter control panel
+//
+	if (
+#ifndef DEBCHECK
+		scan == sc_F10 ||
+#endif
+		scan == sc_F9 ||
+		scan == sc_F7 ||
+		scan == sc_F8)			// pop up quit dialog
+	{
+		ClearMemory ();
+		ClearSplitVWB ();
+		VW_ScreenToScreen (displayofs,bufferofs,80,160);
+		US_ControlPanel(scan);
+
+		 DrawAllPlayBorderSides ();
+
+		if (scan == sc_F9)
+		  StartMusic ();
+
+		PM_CheckMainMem ();
+		SETFONTCOLOR(0,15);
+		IN_ClearKeysDown();
+		return;
+	}
+
+	if ( (scan >= sc_F1 && scan <= sc_F9) || scan == sc_Escape)
+	{
+		StopMusic ();
+		ClearMemory ();
+		VW_FadeOut ();
+
+		US_ControlPanel(scan);
+
+		SETFONTCOLOR(0,15);
+		IN_ClearKeysDown();
+		DrawPlayScreen ();
+		if (!startgame && !loadedgame)
+		{
+			VW_FadeIn ();
+			StartMusic ();
+		}
+		if (loadedgame)
+			playstate = ex_abort;
+		lasttimecount = TimeCount;
+		if (MousePresent)
+			Mouse(MDelta);	// Clear accumulated mouse movement
+		PM_CheckMainMem ();
+		return;
+	}
+
+//
+// TAB-? debug keys
+//
+	if (Keyboard[sc_Tab] && DebugOk)
+	{
+		CA_CacheGrChunk (STARTFONT);
+		fontnumber=0;
+		SETFONTCOLOR(0,15);
+		DebugKeys();
+		if (MousePresent)
+			Mouse(MDelta);	// Clear accumulated mouse movement
+		lasttimecount = TimeCount;
+		return;
+	}
+
+}
+
+
+//===========================================================================
+
+/*
+#############################################################################
+
+				  The objlist data structure
+
+#############################################################################
+
+objlist containt structures for every actor currently playing.  The structure
+is accessed as a linked list starting at *player, ending when ob->next ==
+NULL.  GetNewObj inserts a new object at the end of the list, meaning that
+if an actor spawn another actor, the new one WILL get to think and react the
+same frame.  RemoveObj unlinks the given object and returns it to the free
+list, but does not damage the objects ->next pointer, so if the current object
+removes itself, a linked list following loop can still safely get to the
+next element.
+
+<backwardly linked free list>
+
+#############################################################################
+*/
+
+
+/*
+=========================
+=
+= InitActorList
+=
+= Call to clear out the actor object lists returning them all to the free
+= list.  Allocates a special spot for the player.
+=
+=========================
+*/
+
+int	objcount;
+
+void InitActorList (void)
+{
+	int	i;
+
+//
+// init the actor lists
+//
+	for (i=0;i<MAXACTORS;i++)
+	{
+		objlist[i].prev = &objlist[i+1];
+		objlist[i].next = NULL;
+	}
+
+	objlist[MAXACTORS-1].prev = NULL;
+
+	objfreelist = &objlist[0];
+	lastobj = NULL;
+
+	objcount = 0;
+
+//
+// give the player the first free spots
+//
+	GetNewActor ();
+	player = new;
+
+}
+
+//===========================================================================
+
+/*
+=========================
+=
+= 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)
+{
+	if (!objfreelist)
+		Quit ("GetNewActor: No free spots in objlist!");
+
+	new = objfreelist;
+	objfreelist = new->prev;
+	memset (new,0,sizeof(*new));
+
+	if (lastobj)
+		lastobj->next = new;
+	new->prev = lastobj;	// new->next is allready NULL from memset
+
+	new->active = false;
+	lastobj = new;
+
+	objcount++;
+}
+
+//===========================================================================
+
+/*
+=========================
+=
+= RemoveObj
+=
+= Add the given object back into the free list, and unlink it from it's
+= neighbors
+=
+=========================
+*/
+
+void RemoveObj (objtype *gone)
+{
+	objtype **spotat;
+
+	if (gone == player)
+		Quit ("RemoveObj: Tried to remove the player!");
+
+	gone->state = NULL;
+
+//
+// fix the next object's back link
+//
+	if (gone == lastobj)
+		lastobj = (objtype *)gone->prev;
+	else
+		gone->next->prev = gone->prev;
+
+//
+// fix the previous object's forward link
+//
+	gone->prev->next = gone->next;
+
+//
+// add it back in to the free list
+//
+	gone->prev = objfreelist;
+	objfreelist = gone;
+
+	objcount--;
+}
+
+/*
+=============================================================================
+
+						MUSIC STUFF
+
+=============================================================================
+*/
+
+
+/*
+=================
+=
+= StopMusic
+=
+=================
+*/
+
+void StopMusic(void)
+{
+	int	i;
+
+	SD_MusicOff();
+	for (i = 0;i < LASTMUSIC;i++)
+		if (audiosegs[STARTMUSIC + i])
+		{
+			MM_SetPurge(&((memptr)audiosegs[STARTMUSIC + i]),3);
+			MM_SetLock(&((memptr)audiosegs[STARTMUSIC + i]),false);
+		}
+}
+
+//==========================================================================
+
+
+/*
+=================
+=
+= StartMusic
+=
+=================
+*/
+
+void StartMusic(void)
+{
+	musicnames	chunk;
+
+	SD_MusicOff();
+	chunk = songs[gamestate.mapon+gamestate.episode*10];
+
+//	if ((chunk == -1) || (MusicMode != smm_AdLib))
+//DEBUG control panel		return;
+
+	MM_BombOnError (false);
+	CA_CacheAudioChunk(STARTMUSIC + chunk);
+	MM_BombOnError (true);
+	if (mmerror)
+		mmerror = false;
+	else
+	{
+		MM_SetLock(&((memptr)audiosegs[STARTMUSIC + chunk]),true);
+		SD_StartMusic((MusicGroup far *)audiosegs[STARTMUSIC + chunk]);
+	}
+}
+
+
+/*
+=============================================================================
+
+					PALETTE SHIFTING STUFF
+
+=============================================================================
+*/
+
+#define NUMREDSHIFTS	6
+#define REDSTEPS		8
+
+#define NUMWHITESHIFTS	3
+#define WHITESTEPS		20
+#define WHITETICS		6
+
+
+byte	far redshifts[NUMREDSHIFTS][768];
+byte	far whiteshifts[NUMREDSHIFTS][768];
+
+int		damagecount,bonuscount;
+boolean	palshifted;
+
+extern 	byte	far	gamepal;
+
+/*
+=====================
+=
+= InitRedShifts
+=
+=====================
+*/
+
+void InitRedShifts (void)
+{
+	byte	far *workptr, far *baseptr;
+	int		i,j,delta;
+
+
+//
+// fade through intermediate frames
+//
+	for (i=1;i<=NUMREDSHIFTS;i++)
+	{
+		workptr = (byte far *)&redshifts[i-1][0];
+		baseptr = &gamepal;
+
+		for (j=0;j<=255;j++)
+		{
+			delta = 64-*baseptr;
+			*workptr++ = *baseptr++ + delta * i / REDSTEPS;
+			delta = -*baseptr;
+			*workptr++ = *baseptr++ + delta * i / REDSTEPS;
+			delta = -*baseptr;
+			*workptr++ = *baseptr++ + delta * i / REDSTEPS;
+		}
+	}
+
+	for (i=1;i<=NUMWHITESHIFTS;i++)
+	{
+		workptr = (byte far *)&whiteshifts[i-1][0];
+		baseptr = &gamepal;
+
+		for (j=0;j<=255;j++)
+		{
+			delta = 64-*baseptr;
+			*workptr++ = *baseptr++ + delta * i / WHITESTEPS;
+			delta = 62-*baseptr;
+			*workptr++ = *baseptr++ + delta * i / WHITESTEPS;
+			delta = 0-*baseptr;
+			*workptr++ = *baseptr++ + delta * i / WHITESTEPS;
+		}
+	}
+}
+
+
+/*
+=====================
+=
+= ClearPaletteShifts
+=
+=====================
+*/
+
+void ClearPaletteShifts (void)
+{
+	bonuscount = damagecount = 0;
+}
+
+
+/*
+=====================
+=
+= StartBonusFlash
+=
+=====================
+*/
+
+void StartBonusFlash (void)
+{
+	bonuscount = NUMWHITESHIFTS*WHITETICS;		// white shift palette
+}
+
+
+/*
+=====================
+=
+= StartDamageFlash
+=
+=====================
+*/
+
+void StartDamageFlash (int damage)
+{
+	damagecount += damage;
+}
+
+
+/*
+=====================
+=
+= UpdatePaletteShifts
+=
+=====================
+*/
+
+void UpdatePaletteShifts (void)
+{
+	int	red,white;
+
+	if (bonuscount)
+	{
+		white = bonuscount/WHITETICS +1;
+		if (white>NUMWHITESHIFTS)
+			white = NUMWHITESHIFTS;
+		bonuscount -= tics;
+		if (bonuscount < 0)
+			bonuscount = 0;
+	}
+	else
+		white = 0;
+
+
+	if (damagecount)
+	{
+		red = damagecount/10 +1;
+		if (red>NUMREDSHIFTS)
+			red = NUMREDSHIFTS;
+
+		damagecount -= tics;
+		if (damagecount < 0)
+			damagecount = 0;
+	}
+	else
+		red = 0;
+
+	if (red)
+	{
+		VW_WaitVBL(1);
+		VL_SetPalette (redshifts[red-1]);
+		palshifted = true;
+	}
+	else if (white)
+	{
+		VW_WaitVBL(1);
+		VL_SetPalette (whiteshifts[white-1]);
+		palshifted = true;
+	}
+	else if (palshifted)
+	{
+		VW_WaitVBL(1);
+		VL_SetPalette (&gamepal);		// back to normal
+		palshifted = false;
+	}
+}
+
+
+/*
+=====================
+=
+= FinishPaletteShifts
+=
+= Resets palette to normal if needed
+=
+=====================
+*/
+
+void FinishPaletteShifts (void)
+{
+	if (palshifted)
+	{
+		palshifted = 0;
+		VW_WaitVBL(1);
+		VL_SetPalette (&gamepal);
+	}
+}
+
+
+/*
+=============================================================================
+
+						CORE PLAYLOOP
+
+=============================================================================
+*/
+
+
+/*
+=====================
+=
+= DoActor
+=
+=====================
+*/
+
+void DoActor (objtype *ob)
+{
+	void (*think)(objtype *);
+
+	if (!ob->active && !areabyplayer[ob->areanumber])
+		return;
+
+	if (!(ob->flags&(FL_NONMARK|FL_NEVERMARK)) )
+		actorat[ob->tilex][ob->tiley] = NULL;
+
+//
+// non transitional object
+//
+
+	if (!ob->ticcount)
+	{
+		think =	ob->state->think;
+		if (think)
+		{
+			think (ob);
+			if (!ob->state)
+			{
+				RemoveObj (ob);
+				return;
+			}
+		}
+
+		if (ob->flags&FL_NEVERMARK)
+			return;
+
+		if ( (ob->flags&FL_NONMARK) && actorat[ob->tilex][ob->tiley])
+			return;
+
+		actorat[ob->tilex][ob->tiley] = ob;
+		return;
+	}
+
+//
+// transitional object
+//
+	ob->ticcount-=tics;
+	while ( ob->ticcount <= 0)
+	{
+		think = ob->state->action;			// end of state action
+		if (think)
+		{
+			think (ob);
+			if (!ob->state)
+			{
+				RemoveObj (ob);
+				return;
+			}
+		}
+
+		ob->state = ob->state->next;
+
+		if (!ob->state)
+		{
+			RemoveObj (ob);
+			return;
+		}
+
+		if (!ob->state->tictime)
+		{
+			ob->ticcount = 0;
+			goto think;
+		}
+
+		ob->ticcount += ob->state->tictime;
+	}
+
+think:
+	//
+	// think
+	//
+	think =	ob->state->think;
+	if (think)
+	{
+		think (ob);
+		if (!ob->state)
+		{
+			RemoveObj (ob);
+			return;
+		}
+	}
+
+	if (ob->flags&FL_NEVERMARK)
+		return;
+
+	if ( (ob->flags&FL_NONMARK) && actorat[ob->tilex][ob->tiley])
+		return;
+
+	actorat[ob->tilex][ob->tiley] = ob;
+}
+
+//==========================================================================
+
+
+/*
+===================
+=
+= PlayLoop
+=
+===================
+*/
+long funnyticount;
+
+
+void PlayLoop (void)
+{
+	int		give;
+	int	helmetangle;
+
+	playstate = TimeCount = lasttimecount = 0;
+	frameon = 0;
+	running = false;
+	anglefrac = 0;
+	facecount = 0;
+	funnyticount = 0;
+	memset (buttonstate,0,sizeof(buttonstate));
+	ClearPaletteShifts ();
+
+	if (MousePresent)
+		Mouse(MDelta);	// Clear accumulated mouse movement
+
+	if (demoplayback)
+		IN_StartAck ();
+
+	do
+	{
+		if (virtualreality)
+		{
+			helmetangle = peek (0x40,0xf0);
+			player->angle += helmetangle;
+			if (player->angle >= ANGLES)
+				player->angle -= ANGLES;
+		}
+
+
+		PollControls();
+
+//
+// actor thinking
+//
+		madenoise = false;
+
+		MoveDoors ();
+		MovePWalls ();
+
+		for (obj = player;obj;obj = obj->next)
+			DoActor (obj);
+
+		UpdatePaletteShifts ();
+
+		ThreeDRefresh ();
+
+		//
+		// MAKE FUNNY FACE IF BJ DOESN'T MOVE FOR AWHILE
+		//
+		#ifdef SPEAR
+		funnyticount += tics;
+		if (funnyticount > 30l*70)
+		{
+			funnyticount = 0;
+			StatusDrawPic (17,4,BJWAITING1PIC+(US_RndT()&1));
+			facecount = 0;
+		}
+		#endif
+
+		gamestate.TimeCount+=tics;
+
+		SD_Poll ();
+		UpdateSoundLoc();	// JAB
+
+		if (screenfaded)
+			VW_FadeIn ();
+
+		CheckKeys();
+
+//
+// debug aids
+//
+		if (singlestep)
+		{
+			VW_WaitVBL(14);
+			lasttimecount = TimeCount;
+		}
+		if (extravbls)
+			VW_WaitVBL(extravbls);
+
+		if (demoplayback)
+		{
+			if (IN_CheckAck ())
+			{
+				IN_ClearKeysDown ();
+				playstate = ex_abort;
+			}
+		}
+
+
+		if (virtualreality)
+		{
+			player->angle -= helmetangle;
+			if (player->angle < 0)
+				player->angle += ANGLES;
+		}
+
+	}while (!playstate && !startgame);
+
+	if (playstate != ex_died)
+		FinishPaletteShifts ();
+}
+
--- /dev/null
+++ b/WOLFSRC/WL_SCALE.C
@@ -1,0 +1,733 @@
+// WL_SCALE.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+
+#define OP_RETF	0xcb
+
+/*
+=============================================================================
+
+						  GLOBALS
+
+=============================================================================
+*/
+
+t_compscale _seg *scaledirectory[MAXSCALEHEIGHT+1];
+long			fullscalefarcall[MAXSCALEHEIGHT+1];
+
+int			maxscale,maxscaleshl2;
+
+boolean	insetupscaling;
+
+/*
+=============================================================================
+
+						  LOCALS
+
+=============================================================================
+*/
+
+t_compscale 	_seg *work;
+unsigned BuildCompScale (int height, memptr *finalspot);
+
+int			stepbytwo;
+
+//===========================================================================
+
+/*
+==============
+=
+= BadScale
+=
+==============
+*/
+
+void far BadScale (void)
+{
+	Quit ("BadScale called!");
+}
+
+
+/*
+==========================
+=
+= SetupScaling
+=
+==========================
+*/
+
+void SetupScaling (int maxscaleheight)
+{
+	int		i,x,y;
+	byte	far *dest;
+
+	insetupscaling = true;
+
+	maxscaleheight/=2;			// one scaler every two pixels
+
+	maxscale = maxscaleheight-1;
+	maxscaleshl2 = maxscale<<2;
+
+//
+// free up old scalers
+//
+	for (i=1;i<MAXSCALEHEIGHT;i++)
+	{
+		if (scaledirectory[i])
+			MM_FreePtr (&(memptr)scaledirectory[i]);
+		if (i>=stepbytwo)
+			i += 2;
+	}
+	memset (scaledirectory,0,sizeof(scaledirectory));
+
+	MM_SortMem ();
+
+//
+// build the compiled scalers
+//
+	stepbytwo = viewheight/2;	// save space by double stepping
+	MM_GetPtr (&(memptr)work,20000);
+
+	for (i=1;i<=maxscaleheight;i++)
+	{
+		BuildCompScale (i*2,&(memptr)scaledirectory[i]);
+		if (i>=stepbytwo)
+			i+= 2;
+	}
+	MM_FreePtr (&(memptr)work);
+
+//
+// compact memory and lock down scalers
+//
+	MM_SortMem ();
+	for (i=1;i<=maxscaleheight;i++)
+	{
+		MM_SetLock (&(memptr)scaledirectory[i],true);
+		fullscalefarcall[i] = (unsigned)scaledirectory[i];
+		fullscalefarcall[i] <<=16;
+		fullscalefarcall[i] += scaledirectory[i]->codeofs[0];
+		if (i>=stepbytwo)
+		{
+			scaledirectory[i+1] = scaledirectory[i];
+			fullscalefarcall[i+1] = fullscalefarcall[i];
+			scaledirectory[i+2] = scaledirectory[i];
+			fullscalefarcall[i+2] = fullscalefarcall[i];
+			i+=2;
+		}
+	}
+	scaledirectory[0] = scaledirectory[1];
+	fullscalefarcall[0] = fullscalefarcall[1];
+
+//
+// check for oversize wall drawing
+//
+	for (i=maxscaleheight;i<MAXSCALEHEIGHT;i++)
+		fullscalefarcall[i] = (long)BadScale;
+
+	insetupscaling = false;
+}
+
+//===========================================================================
+
+/*
+========================
+=
+= BuildCompScale
+=
+= Builds a compiled scaler object that will scale a 64 tall object to
+= the given height (centered vertically on the screen)
+=
+= height should be even
+=
+= Call with
+= ---------
+= DS:SI		Source for scale
+= ES:DI		Dest for scale
+=
+= Calling the compiled scaler only destroys AL
+=
+========================
+*/
+
+unsigned BuildCompScale (int height, memptr *finalspot)
+{
+	byte		far *code;
+
+	int			i;
+	long		fix,step;
+	unsigned	src,totalscaled,totalsize;
+	int			startpix,endpix,toppix;
+
+
+	step = ((long)height<<16) / 64;
+	code = &work->code[0];
+	toppix = (viewheight-height)/2;
+	fix = 0;
+
+	for (src=0;src<=64;src++)
+	{
+		startpix = fix>>16;
+		fix += step;
+		endpix = fix>>16;
+
+		if (endpix>startpix)
+			work->width[src] = endpix-startpix;
+		else
+			work->width[src] = 0;
+
+//
+// mark the start of the code
+//
+		work->codeofs[src] = FP_OFF(code);
+
+//
+// compile some code if the source pixel generates any screen pixels
+//
+		startpix+=toppix;
+		endpix+=toppix;
+
+		if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64)
+			continue;
+
+	//
+	// mov al,[si+src]
+	//
+		*code++ = 0x8a;
+		*code++ = 0x44;
+		*code++ = src;
+
+		for (;startpix<endpix;startpix++)
+		{
+			if (startpix >= viewheight)
+				break;						// off the bottom of the view area
+			if (startpix < 0)
+				continue;					// not into the view area
+
+		//
+		// mov [es:di+heightofs],al
+		//
+			*code++ = 0x26;
+			*code++ = 0x88;
+			*code++ = 0x85;
+			*((unsigned far *)code)++ = startpix*SCREENBWIDE;
+		}
+
+	}
+
+//
+// retf
+//
+	*code++ = 0xcb;
+
+	totalsize = FP_OFF(code);
+	MM_GetPtr (finalspot,totalsize);
+	_fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize);
+
+	return totalsize;
+}
+
+
+/*
+=======================
+=
+= ScaleLine
+=
+= linescale should have the high word set to the segment of the scaler
+=
+=======================
+*/
+
+extern	int			slinex,slinewidth;
+extern	unsigned	far *linecmds;
+extern	long		linescale;
+extern	unsigned	maskword;
+
+byte	mask1,mask2,mask3;
+
+
+void near ScaleLine (void)
+{
+asm	mov	cx,WORD PTR [linescale+2]
+asm	mov	es,cx						// segment of scaler
+
+asm	mov bp,WORD PTR [linecmds]
+asm	mov	dx,SC_INDEX+1				// to set SC_MAPMASK
+
+asm	mov	bx,[slinex]
+asm	mov	di,bx
+asm	shr	di,2						// X in bytes
+asm	add	di,[bufferofs]
+asm	and	bx,3
+asm	shl	bx,3
+asm	add	bx,[slinewidth]				// bx = (pixel*8+pixwidth)
+asm	mov	al,BYTE [mapmasks3-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ds,WORD PTR [linecmds+2]
+asm	or	al,al
+asm	jz	notthreebyte				// scale across three bytes
+asm	jmp	threebyte
+notthreebyte:
+asm	mov	al,BYTE PTR ss:[mapmasks2-1+bx]	// -1 because pixwidth of 1 is first
+asm	or	al,al
+asm	jnz	twobyte						// scale across two bytes
+
+//
+// one byte scaling
+//
+asm	mov	al,BYTE PTR ss:[mapmasks1-1+bx]	// -1 because pixwidth of 1 is first
+asm	out	dx,al						// set map mask register
+
+scalesingle:
+
+asm	mov	bx,[ds:bp]					// table location of rtl to patch
+asm	or	bx,bx
+asm	jz	linedone					// 0 signals end of segment list
+asm	mov	bx,[es:bx]
+asm	mov	dl,[es:bx]					// save old value
+asm	mov	BYTE PTR es:[bx],OP_RETF	// patch a RETF in
+asm	mov	si,[ds:bp+4]				// table location of entry spot
+asm	mov	ax,[es:si]
+asm	mov	WORD PTR ss:[linescale],ax	// call here to start scaling
+asm	mov	si,[ds:bp+2]				// corrected top of shape for this segment
+asm	add	bp,6						// next segment list
+
+asm	mov	ax,SCREENSEG
+asm	mov	es,ax
+asm	call ss:[linescale]				// scale the segment of pixels
+
+asm	mov	es,cx						// segment of scaler
+asm	mov	BYTE PTR es:[bx],dl			// unpatch the RETF
+asm	jmp	scalesingle					// do the next segment
+
+
+//
+// done
+//
+linedone:
+asm	mov	ax,ss
+asm	mov	ds,ax
+return;
+
+//
+// two byte scaling
+//
+twobyte:
+asm	mov	ss:[mask2],al
+asm	mov	al,BYTE PTR ss:[mapmasks1-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ss:[mask1],al
+
+scaledouble:
+
+asm	mov	bx,[ds:bp]					// table location of rtl to patch
+asm	or	bx,bx
+asm	jz	linedone					// 0 signals end of segment list
+asm	mov	bx,[es:bx]
+asm	mov	cl,[es:bx]					// save old value
+asm	mov	BYTE PTR es:[bx],OP_RETF	// patch a RETF in
+asm	mov	si,[ds:bp+4]				// table location of entry spot
+asm	mov	ax,[es:si]
+asm	mov	WORD PTR ss:[linescale],ax	// call here to start scaling
+asm	mov	si,[ds:bp+2]				// corrected top of shape for this segment
+asm	add	bp,6						// next segment list
+
+asm	mov	ax,SCREENSEG
+asm	mov	es,ax
+asm	mov	al,ss:[mask1]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	inc	di
+asm	mov	al,ss:[mask2]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	dec	di
+
+asm	mov	es,WORD PTR ss:[linescale+2] // segment of scaler
+asm	mov	BYTE PTR es:[bx],cl			// unpatch the RETF
+asm	jmp	scaledouble					// do the next segment
+
+
+//
+// three byte scaling
+//
+threebyte:
+asm	mov	ss:[mask3],al
+asm	mov	al,BYTE PTR ss:[mapmasks2-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ss:[mask2],al
+asm	mov	al,BYTE PTR ss:[mapmasks1-1+bx]	// -1 because pixwidth of 1 is first
+asm	mov	ss:[mask1],al
+
+scaletriple:
+
+asm	mov	bx,[ds:bp]					// table location of rtl to patch
+asm	or	bx,bx
+asm	jz	linedone					// 0 signals end of segment list
+asm	mov	bx,[es:bx]
+asm	mov	cl,[es:bx]					// save old value
+asm	mov	BYTE PTR es:[bx],OP_RETF	// patch a RETF in
+asm	mov	si,[ds:bp+4]				// table location of entry spot
+asm	mov	ax,[es:si]
+asm	mov	WORD PTR ss:[linescale],ax	// call here to start scaling
+asm	mov	si,[ds:bp+2]				// corrected top of shape for this segment
+asm	add	bp,6						// next segment list
+
+asm	mov	ax,SCREENSEG
+asm	mov	es,ax
+asm	mov	al,ss:[mask1]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	inc	di
+asm	mov	al,ss:[mask2]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	inc	di
+asm	mov	al,ss:[mask3]
+asm	out	dx,al						// set map mask register
+asm	call ss:[linescale]				// scale the segment of pixels
+asm	dec	di
+asm	dec	di
+
+asm	mov	es,WORD PTR ss:[linescale+2] // segment of scaler
+asm	mov	BYTE PTR es:[bx],cl			// unpatch the RETF
+asm	jmp	scaletriple					// do the next segment
+
+
+}
+
+
+/*
+=======================
+=
+= ScaleShape
+=
+= Draws a compiled shape at [scale] pixels high
+=
+= each vertical line of the shape has a pointer to segment data:
+= 	end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
+= 	top of virtual line with segment in proper place
+=	start of segment pixel*2, used to jsl into compiled scaler
+=	<repeat>
+=
+= Setup for call
+= --------------
+= GC_MODE			read mode 1, write mode 2
+= GC_COLORDONTCARE  set to 0, so all reads from video memory return 0xff
+= GC_INDEX			pointing at GC_BITMASK
+=
+=======================
+*/
+
+static	long		longtemp;
+
+void ScaleShape (int xcenter, int shapenum, unsigned height)
+{
+	t_compshape	_seg *shape;
+	t_compscale _seg *comptable;
+	unsigned	scale,srcx,stopx,tempx;
+	int			t;
+	unsigned	far *cmdptr;
+	boolean		leftvis,rightvis;
+
+
+	shape = PM_GetSpritePage (shapenum);
+
+	scale = height>>3;						// low three bits are fractional
+	if (!scale || scale>maxscale)
+		return;								// too close or far away
+	comptable = scaledirectory[scale];
+
+	*(((unsigned *)&linescale)+1)=(unsigned)comptable;	// seg of far call
+	*(((unsigned *)&linecmds)+1)=(unsigned)shape;		// seg of shape
+
+//
+// scale to the left (from pixel 31 to shape->leftpix)
+//
+	srcx = 32;
+	slinex = xcenter;
+	stopx = shape->leftpix;
+	cmdptr = &shape->dataofs[31-stopx];
+
+	while ( --srcx >=stopx && slinex>0)
+	{
+		(unsigned)linecmds = *cmdptr--;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		if (slinewidth == 1)
+		{
+			slinex--;
+			if (slinex<viewwidth)
+			{
+				if (wallheight[slinex] >= height)
+					continue;		// obscured by closer wall
+				ScaleLine ();
+			}
+			continue;
+		}
+
+		//
+		// handle multi pixel lines
+		//
+		if (slinex>viewwidth)
+		{
+			slinex -= slinewidth;
+			slinewidth = viewwidth-slinex;
+			if (slinewidth<1)
+				continue;		// still off the right side
+		}
+		else
+		{
+			if (slinewidth>slinex)
+				slinewidth = slinex;
+			slinex -= slinewidth;
+		}
+
+
+		leftvis = (wallheight[slinex] < height);
+		rightvis = (wallheight[slinex+slinewidth-1] < height);
+
+		if (leftvis)
+		{
+			if (rightvis)
+				ScaleLine ();
+			else
+			{
+				while (wallheight[slinex+slinewidth-1] >= height)
+					slinewidth--;
+				ScaleLine ();
+			}
+		}
+		else
+		{
+			if (!rightvis)
+				continue;		// totally obscured
+
+			while (wallheight[slinex] >= height)
+			{
+				slinex++;
+				slinewidth--;
+			}
+			ScaleLine ();
+			break;			// the rest of the shape is gone
+		}
+	}
+
+
+//
+// scale to the right
+//
+	slinex = xcenter;
+	stopx = shape->rightpix;
+	if (shape->leftpix<31)
+	{
+		srcx = 31;
+		cmdptr = &shape->dataofs[32-shape->leftpix];
+	}
+	else
+	{
+		srcx = shape->leftpix-1;
+		cmdptr = &shape->dataofs[0];
+	}
+	slinewidth = 0;
+
+	while ( ++srcx <= stopx && (slinex+=slinewidth)<viewwidth)
+	{
+		(unsigned)linecmds = *cmdptr++;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		if (slinewidth == 1)
+		{
+			if (slinex>=0 && wallheight[slinex] < height)
+			{
+				ScaleLine ();
+			}
+			continue;
+		}
+
+		//
+		// handle multi pixel lines
+		//
+		if (slinex<0)
+		{
+			if (slinewidth <= -slinex)
+				continue;		// still off the left edge
+
+			slinewidth += slinex;
+			slinex = 0;
+		}
+		else
+		{
+			if (slinex + slinewidth > viewwidth)
+				slinewidth = viewwidth-slinex;
+		}
+
+
+		leftvis = (wallheight[slinex] < height);
+		rightvis = (wallheight[slinex+slinewidth-1] < height);
+
+		if (leftvis)
+		{
+			if (rightvis)
+			{
+				ScaleLine ();
+			}
+			else
+			{
+				while (wallheight[slinex+slinewidth-1] >= height)
+					slinewidth--;
+				ScaleLine ();
+				break;			// the rest of the shape is gone
+			}
+		}
+		else
+		{
+			if (rightvis)
+			{
+				while (wallheight[slinex] >= height)
+				{
+					slinex++;
+					slinewidth--;
+				}
+				ScaleLine ();
+			}
+			else
+				continue;		// totally obscured
+		}
+	}
+}
+
+
+
+/*
+=======================
+=
+= SimpleScaleShape
+=
+= NO CLIPPING, height in pixels
+=
+= Draws a compiled shape at [scale] pixels high
+=
+= each vertical line of the shape has a pointer to segment data:
+= 	end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
+= 	top of virtual line with segment in proper place
+=	start of segment pixel*2, used to jsl into compiled scaler
+=	<repeat>
+=
+= Setup for call
+= --------------
+= GC_MODE			read mode 1, write mode 2
+= GC_COLORDONTCARE  set to 0, so all reads from video memory return 0xff
+= GC_INDEX			pointing at GC_BITMASK
+=
+=======================
+*/
+
+void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
+{
+	t_compshape	_seg *shape;
+	t_compscale _seg *comptable;
+	unsigned	scale,srcx,stopx,tempx;
+	int			t;
+	unsigned	far *cmdptr;
+	boolean		leftvis,rightvis;
+
+
+	shape = PM_GetSpritePage (shapenum);
+
+	scale = height>>1;
+	comptable = scaledirectory[scale];
+
+	*(((unsigned *)&linescale)+1)=(unsigned)comptable;	// seg of far call
+	*(((unsigned *)&linecmds)+1)=(unsigned)shape;		// seg of shape
+
+//
+// scale to the left (from pixel 31 to shape->leftpix)
+//
+	srcx = 32;
+	slinex = xcenter;
+	stopx = shape->leftpix;
+	cmdptr = &shape->dataofs[31-stopx];
+
+	while ( --srcx >=stopx )
+	{
+		(unsigned)linecmds = *cmdptr--;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		slinex -= slinewidth;
+		ScaleLine ();
+	}
+
+
+//
+// scale to the right
+//
+	slinex = xcenter;
+	stopx = shape->rightpix;
+	if (shape->leftpix<31)
+	{
+		srcx = 31;
+		cmdptr = &shape->dataofs[32-shape->leftpix];
+	}
+	else
+	{
+		srcx = shape->leftpix-1;
+		cmdptr = &shape->dataofs[0];
+	}
+	slinewidth = 0;
+
+	while ( ++srcx <= stopx )
+	{
+		(unsigned)linecmds = *cmdptr++;
+		if ( !(slinewidth = comptable->width[srcx]) )
+			continue;
+
+		ScaleLine ();
+		slinex+=slinewidth;
+	}
+}
+
+
+
+
+//
+// bit mask tables for drawing scaled strips up to eight pixels wide
+//
+// down here so the STUPID inline assembler doesn't get confused!
+//
+
+
+byte	mapmasks1[4][8] = {
+{1 ,3 ,7 ,15,15,15,15,15},
+{2 ,6 ,14,14,14,14,14,14},
+{4 ,12,12,12,12,12,12,12},
+{8 ,8 ,8 ,8 ,8 ,8 ,8 ,8} };
+
+byte	mapmasks2[4][8] = {
+{0 ,0 ,0 ,0 ,1 ,3 ,7 ,15},
+{0 ,0 ,0 ,1 ,3 ,7 ,15,15},
+{0 ,0 ,1 ,3 ,7 ,15,15,15},
+{0 ,1 ,3 ,7 ,15,15,15,15} };
+
+byte	mapmasks3[4][8] = {
+{0 ,0 ,0 ,0 ,0 ,0 ,0 ,0},
+{0 ,0 ,0 ,0 ,0 ,0 ,0 ,1},
+{0 ,0 ,0 ,0 ,0 ,0 ,1 ,3},
+{0 ,0 ,0 ,0 ,0 ,1 ,3 ,7} };
+
+
+unsigned	wordmasks[8][8] = {
+{0x0080,0x00c0,0x00e0,0x00f0,0x00f8,0x00fc,0x00fe,0x00ff},
+{0x0040,0x0060,0x0070,0x0078,0x007c,0x007e,0x007f,0x807f},
+{0x0020,0x0030,0x0038,0x003c,0x003e,0x003f,0x803f,0xc03f},
+{0x0010,0x0018,0x001c,0x001e,0x001f,0x801f,0xc01f,0xe01f},
+{0x0008,0x000c,0x000e,0x000f,0x800f,0xc00f,0xe00f,0xf00f},
+{0x0004,0x0006,0x0007,0x8007,0xc007,0xe007,0xf007,0xf807},
+{0x0002,0x0003,0x8003,0xc003,0xe003,0xf003,0xf803,0xfc03},
+{0x0001,0x8001,0xc001,0xe001,0xf001,0xf801,0xfc01,0xfe01} };
+
+int			slinex,slinewidth;
+unsigned	far *linecmds;
+long		linescale;
+unsigned	maskword;
+
--- /dev/null
+++ b/WOLFSRC/WL_STATE.C
@@ -1,0 +1,1480 @@
+// WL_STATE.C
+
+#include "WL_DEF.H"
+#pragma hdrstop
+
+/*
+=============================================================================
+
+						 LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+
+/*
+=============================================================================
+
+						 GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+
+dirtype opposite[9] =
+	{west,southwest,south,southeast,east,northeast,north,northwest,nodir};
+
+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}
+};
+
+
+
+void	SpawnNewObj (unsigned tilex, unsigned tiley, statetype *state);
+void	NewState (objtype *ob, statetype *state);
+
+boolean TryWalk (objtype *ob);
+void	MoveObj (objtype *ob, long move);
+
+void	KillActor (objtype *ob);
+void	DamageActor (objtype *ob, unsigned damage);
+
+boolean CheckLine (objtype *ob);
+void FirstSighting (objtype *ob);
+boolean	CheckSight (objtype *ob);
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+
+
+//===========================================================================
+
+
+/*
+===================
+=
+= SpawnNewObj
+=
+= Spaws a new actor at the given TILE coordinates, with the given state, and
+= the given size in GLOBAL units.
+=
+= new			= a pointer to an initialized new actor
+=
+===================
+*/
+
+void SpawnNewObj (unsigned tilex, unsigned tiley, statetype *state)
+{
+	GetNewActor ();
+	new->state = state;
+	if (state->tictime)
+		new->ticcount = US_RndT () % state->tictime;
+	else
+		new->ticcount = 0;
+
+	new->tilex = tilex;
+	new->tiley = tiley;
+	new->x = ((long)tilex<<TILESHIFT)+TILEGLOBAL/2;
+	new->y = ((long)tiley<<TILESHIFT)+TILEGLOBAL/2;
+	new->dir = nodir;
+
+	actorat[tilex][tiley] = new;
+	new->areanumber =
+		*(mapsegs[0] + farmapylookup[new->tiley]+new->tilex) - AREATILE;
+}
+
+
+
+/*
+===================
+=
+= NewState
+=
+= Changes ob to a new state, setting ticcount to the max for that state
+=
+===================
+*/
+
+void NewState (objtype *ob, statetype *state)
+{
+	ob->state = state;
+	ob->ticcount = state->tictime;
+}
+
+
+
+/*
+=============================================================================
+
+				ENEMY TILE WORLD MOVEMENT CODE
+
+=============================================================================
+*/
+
+
+/*
+==================================
+=
+= TryWalk
+=
+= Attempts to move ob in its current (ob->dir) direction.
+=
+= If blocked by either a wall or an actor returns FALSE
+=
+= If move is either clear or blocked only by a door, returns TRUE and sets
+=
+= ob->tilex			= new destination
+= ob->tiley
+= ob->areanumber    = the floor tile number (0-(NUMAREAS-1)) of destination
+= ob->distance  	= TILEGLOBAl, or -doornumber if a door is blocking the way
+=
+= If a door is in the way, an OpenDoor call is made to start it opening.
+= The actor code should wait until
+= 	doorobjlist[-ob->distance].action = dr_open, meaning the door has been
+=	fully opened
+=
+==================================
+*/
+
+#define CHECKDIAG(x,y)								\
+{                                                   \
+	temp=(unsigned)actorat[x][y];                   \
+	if (temp)                                       \
+	{                                               \
+		if (temp<256)                               \
+			return false;                           \
+		if (((objtype *)temp)->flags&FL_SHOOTABLE)  \
+			return false;                           \
+	}                                               \
+}
+
+#define CHECKSIDE(x,y)								\
+{                                                   \
+	temp=(unsigned)actorat[x][y];                   \
+	if (temp)                                       \
+	{                                               \
+		if (temp<128)                               \
+			return false;                           \
+		if (temp<256)                               \
+			doornum = temp&63;                      \
+		else if (((objtype *)temp)->flags&FL_SHOOTABLE)\
+			return false;                           \
+	}                                               \
+}
+
+
+boolean TryWalk (objtype *ob)
+{
+	int			doornum;
+	unsigned	temp;
+
+	doornum = -1;
+
+	if (ob->obclass == inertobj)
+	{
+		switch (ob->dir)
+		{
+		case north:
+			ob->tiley--;
+			break;
+
+		case northeast:
+			ob->tilex++;
+			ob->tiley--;
+			break;
+
+		case east:
+			ob->tilex++;
+			break;
+
+		case southeast:
+			ob->tilex++;
+			ob->tiley++;
+			break;
+
+		case south:
+			ob->tiley++;
+			break;
+
+		case southwest:
+			ob->tilex--;
+			ob->tiley++;
+			break;
+
+		case west:
+			ob->tilex--;
+			break;
+
+		case northwest:
+			ob->tilex--;
+			ob->tiley--;
+			break;
+		}
+	}
+	else
+		switch (ob->dir)
+		{
+		case north:
+			if (ob->obclass == dogobj || ob->obclass == fakeobj)
+			{
+				CHECKDIAG(ob->tilex,ob->tiley-1);
+			}
+			else
+			{
+				CHECKSIDE(ob->tilex,ob->tiley-1);
+			}
+			ob->tiley--;
+			break;
+
+		case northeast:
+			CHECKDIAG(ob->tilex+1,ob->tiley-1);
+			CHECKDIAG(ob->tilex+1,ob->tiley);
+			CHECKDIAG(ob->tilex,ob->tiley-1);
+			ob->tilex++;
+			ob->tiley--;
+			break;
+
+		case east:
+			if (ob->obclass == dogobj || ob->obclass == fakeobj)
+			{
+				CHECKDIAG(ob->tilex+1,ob->tiley);
+			}
+			else
+			{
+				CHECKSIDE(ob->tilex+1,ob->tiley);
+			}
+			ob->tilex++;
+			break;
+
+		case southeast:
+			CHECKDIAG(ob->tilex+1,ob->tiley+1);
+			CHECKDIAG(ob->tilex+1,ob->tiley);
+			CHECKDIAG(ob->tilex,ob->tiley+1);
+			ob->tilex++;
+			ob->tiley++;
+			break;
+
+		case south:
+			if (ob->obclass == dogobj || ob->obclass == fakeobj)
+			{
+				CHECKDIAG(ob->tilex,ob->tiley+1);
+			}
+			else
+			{
+				CHECKSIDE(ob->tilex,ob->tiley+1);
+			}
+			ob->tiley++;
+			break;
+
+		case southwest:
+			CHECKDIAG(ob->tilex-1,ob->tiley+1);
+			CHECKDIAG(ob->tilex-1,ob->tiley);
+			CHECKDIAG(ob->tilex,ob->tiley+1);
+			ob->tilex--;
+			ob->tiley++;
+			break;
+
+		case west:
+			if (ob->obclass == dogobj || ob->obclass == fakeobj)
+			{
+				CHECKDIAG(ob->tilex-1,ob->tiley);
+			}
+			else
+			{
+				CHECKSIDE(ob->tilex-1,ob->tiley);
+			}
+			ob->tilex--;
+			break;
+
+		case northwest:
+			CHECKDIAG(ob->tilex-1,ob->tiley-1);
+			CHECKDIAG(ob->tilex-1,ob->tiley);
+			CHECKDIAG(ob->tilex,ob->tiley-1);
+			ob->tilex--;
+			ob->tiley--;
+			break;
+
+		case nodir:
+			return false;
+
+		default:
+			Quit ("Walk: Bad dir");
+		}
+
+	if (doornum != -1)
+	{
+		OpenDoor (doornum);
+		ob->distance = -doornum-1;
+		return true;
+	}
+
+
+	ob->areanumber =
+		*(mapsegs[0] + farmapylookup[ob->tiley]+ob->tilex) - AREATILE;
+
+	ob->distance = TILEGLOBAL;
+	return true;
+}
+
+
+
+/*
+==================================
+=
+= SelectDodgeDir
+=
+= Attempts to choose and initiate a movement for ob that sends it towards
+= the player while dodging
+=
+= If there is no possible move (ob is totally surrounded)
+=
+= ob->dir			=	nodir
+=
+= Otherwise
+=
+= ob->dir			= new direction to follow
+= ob->distance		= TILEGLOBAL or -doornumber
+= ob->tilex			= new destination
+= ob->tiley
+= ob->areanumber    = the floor tile number (0-(NUMAREAS-1)) of destination
+=
+==================================
+*/
+
+void SelectDodgeDir (objtype *ob)
+{
+	int 		deltax,deltay,i;
+	unsigned	absdx,absdy;
+	dirtype 	dirtry[5];
+	dirtype 	turnaround,tdir;
+
+	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];
+
+	deltax = player->tilex - ob->tilex;
+	deltay = player->tiley - ob->tiley;
+
+//
+// arange 5 direction choices in order of preference
+// the four cardinal directions plus the diagonal straight towards
+// the player
+//
+
+	if (deltax>0)
+	{
+		dirtry[1]= east;
+		dirtry[3]= west;
+	}
+	else
+	{
+		dirtry[1]= west;
+		dirtry[3]= east;
+	}
+
+	if (deltay>0)
+	{
+		dirtry[2]= south;
+		dirtry[4]= north;
+	}
+	else
+	{
+		dirtry[2]= north;
+		dirtry[4]= south;
+	}
+
+//
+// randomize a bit for dodging
+//
+	absdx = abs(deltax);
+	absdy = abs(deltay);
+
+	if (absdx > absdy)
+	{
+		tdir = dirtry[1];
+		dirtry[1] = dirtry[2];
+		dirtry[2] = tdir;
+		tdir = dirtry[3];
+		dirtry[3] = dirtry[4];
+		dirtry[4] = tdir;
+	}
+
+	if (US_RndT() < 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] ];
+
+//
+// try the directions util one works
+//
+	for (i=0;i<5;i++)
+	{
+		if ( dirtry[i] == nodir || dirtry[i] == turnaround)
+			continue;
+
+		ob->dir = dirtry[i];
+		if (TryWalk(ob))
+			return;
+	}
+
+//
+// turn around only as a last resort
+//
+	if (turnaround != nodir)
+	{
+		ob->dir = turnaround;
+
+		if (TryWalk(ob))
+			return;
+	}
+
+	ob->dir = nodir;
+}
+
+
+/*
+============================
+=
+= SelectChaseDir
+=
+= As SelectDodgeDir, but doesn't try to dodge
+=
+============================
+*/
+
+void SelectChaseDir (objtype *ob)
+{
+	int deltax,deltay,i;
+	dirtype d[3];
+	dirtype tdir, olddir, turnaround;
+
+
+	olddir=ob->dir;
+	turnaround=opposite[olddir];
+
+	deltax=player->tilex - ob->tilex;
+	deltay=player->tiley - ob->tiley;
+
+	d[1]=nodir;
+	d[2]=nodir;
+
+	if (deltax>0)
+		d[1]= east;
+	else if (deltax<0)
+		d[1]= west;
+	if (deltay>0)
+		d[2]=south;
+	else if (deltay<0)
+		d[2]=north;
+
+	if (abs(deltay)>abs(deltax))
+	{
+		tdir=d[1];
+		d[1]=d[2];
+		d[2]=tdir;
+	}
+
+	if (d[1]==turnaround)
+		d[1]=nodir;
+	if (d[2]==turnaround)
+		d[2]=nodir;
+
+
+	if (d[1]!=nodir)
+	{
+		ob->dir=d[1];
+		if (TryWalk(ob))
+			return;     /*either moved forward or attacked*/
+	}
+
+	if (d[2]!=nodir)
+	{
+		ob->dir=d[2];
+		if (TryWalk(ob))
+			return;
+	}
+
+/* there is no direct path to the player, so pick another direction */
+
+	if (olddir!=nodir)
+	{
+		ob->dir=olddir;
+		if (TryWalk(ob))
+			return;
+	}
+
+	if (US_RndT()>128) 	/*randomly determine direction of search*/
+	{
+		for (tdir=north;tdir<=west;tdir++)
+		{
+			if (tdir!=turnaround)
+			{
+				ob->dir=tdir;
+				if ( TryWalk(ob) )
+					return;
+			}
+		}
+	}
+	else
+	{
+		for (tdir=west;tdir>=north;tdir--)
+		{
+			if (tdir!=turnaround)
+			{
+			  ob->dir=tdir;
+			  if ( TryWalk(ob) )
+				return;
+			}
+		}
+	}
+
+	if (turnaround !=  nodir)
+	{
+		ob->dir=turnaround;
+		if (ob->dir != nodir)
+		{
+			if ( TryWalk(ob) )
+				return;
+		}
+	}
+
+	ob->dir = nodir;		// can't move
+}
+
+
+/*
+============================
+=
+= SelectRunDir
+=
+= Run Away from player
+=
+============================
+*/
+
+void SelectRunDir (objtype *ob)
+{
+	int deltax,deltay,i;
+	dirtype d[3];
+	dirtype tdir, olddir, turnaround;
+
+
+	deltax=player->tilex - ob->tilex;
+	deltay=player->tiley - ob->tiley;
+
+	if (deltax<0)
+		d[1]= east;
+	else
+		d[1]= west;
+	if (deltay<0)
+		d[2]=south;
+	else
+		d[2]=north;
+
+	if (abs(deltay)>abs(deltax))
+	{
+		tdir=d[1];
+		d[1]=d[2];
+		d[2]=tdir;
+	}
+
+	ob->dir=d[1];
+	if (TryWalk(ob))
+		return;     /*either moved forward or attacked*/
+
+	ob->dir=d[2];
+	if (TryWalk(ob))
+		return;
+
+/* there is no direct path to the player, so pick another direction */
+
+	if (US_RndT()>128) 	/*randomly determine direction of search*/
+	{
+		for (tdir=north;tdir<=west;tdir++)
+		{
+			ob->dir=tdir;
+			if ( TryWalk(ob) )
+				return;
+		}
+	}
+	else
+	{
+		for (tdir=west;tdir>=north;tdir--)
+		{
+			ob->dir=tdir;
+			if ( TryWalk(ob) )
+			  return;
+		}
+	}
+
+	ob->dir = nodir;		// can't move
+}
+
+
+/*
+=================
+=
+= MoveObj
+=
+= Moves ob be move global units in ob->dir direction
+= Actors are not allowed to move inside the player
+= Does NOT check to see if the move is tile map valid
+=
+= ob->x			= adjusted for new position
+= ob->y
+=
+=================
+*/
+
+void MoveObj (objtype *ob, long move)
+{
+	long	deltax,deltay;
+
+	switch (ob->dir)
+	{
+	case north:
+		ob->y -= move;
+		break;
+	case northeast:
+		ob->x += move;
+		ob->y -= move;
+		break;
+	case east:
+		ob->x += move;
+		break;
+	case southeast:
+		ob->x += move;
+		ob->y += move;
+		break;
+	case south:
+		ob->y += move;
+		break;
+	case southwest:
+		ob->x -= move;
+		ob->y += move;
+		break;
+	case west:
+		ob->x -= move;
+		break;
+	case northwest:
+		ob->x -= move;
+		ob->y -= move;
+		break;
+
+	case nodir:
+		return;
+
+	default:
+		Quit ("MoveObj: bad dir!");
+	}
+
+//
+// check to make sure it's not on top of player
+//
+	if (areabyplayer[ob->areanumber])
+	{
+		deltax = ob->x - player->x;
+		if (deltax < -MINACTORDIST || deltax > MINACTORDIST)
+			goto moveok;
+		deltay = ob->y - player->y;
+		if (deltay < -MINACTORDIST || deltay > MINACTORDIST)
+			goto moveok;
+
+		if (ob->obclass == ghostobj || ob->obclass == spectreobj)
+			TakeDamage (tics*2,ob);
+
+	//
+	// back up
+	//
+		switch (ob->dir)
+		{
+		case north:
+			ob->y += move;
+			break;
+		case northeast:
+			ob->x -= move;
+			ob->y += move;
+			break;
+		case east:
+			ob->x -= move;
+			break;
+		case southeast:
+			ob->x -= move;
+			ob->y -= move;
+			break;
+		case south:
+			ob->y -= move;
+			break;
+		case southwest:
+			ob->x += move;
+			ob->y -= move;
+			break;
+		case west:
+			ob->x += move;
+			break;
+		case northwest:
+			ob->x += move;
+			ob->y += move;
+			break;
+
+		case nodir:
+			return;
+		}
+		return;
+	}
+moveok:
+	ob->distance -=move;
+}
+
+/*
+=============================================================================
+
+							STUFF
+
+=============================================================================
+*/
+
+/*
+===============
+=
+= DropItem
+=
+= Tries to drop a bonus item somewhere in the tiles surrounding the
+= given tilex/tiley
+=
+===============
+*/
+
+void DropItem (stat_t itemtype, int tilex, int tiley)
+{
+	int	x,y,xl,xh,yl,yh;
+
+//
+// find a free spot to put it in
+//
+	if (!actorat[tilex][tiley])
+	{
+		PlaceItemType (itemtype, tilex,tiley);
+		return;
+	}
+
+	xl = tilex-1;
+	xh = tilex+1;
+	yl = tiley-1;
+	yh = tiley+1;
+
+	for (x=xl ; x<= xh ; x++)
+		for (y=yl ; y<= yh ; y++)
+			if (!actorat[x][y])
+			{
+				PlaceItemType (itemtype, x,y);
+				return;
+			}
+}
+
+
+
+/*
+===============
+=
+= KillActor
+=
+===============
+*/
+
+void KillActor (objtype *ob)
+{
+	int	tilex,tiley;
+
+	tilex = ob->tilex = ob->x >> TILESHIFT;		// drop item on center
+	tiley = ob->tiley = ob->y >> TILESHIFT;
+
+	switch (ob->obclass)
+	{
+	case guardobj:
+		GivePoints (100);
+		NewState (ob,&s_grddie1);
+		PlaceItemType (bo_clip2,tilex,tiley);
+		break;
+
+	case officerobj:
+		GivePoints (400);
+		NewState (ob,&s_ofcdie1);
+		PlaceItemType (bo_clip2,tilex,tiley);
+		break;
+
+	case mutantobj:
+		GivePoints (700);
+		NewState (ob,&s_mutdie1);
+		PlaceItemType (bo_clip2,tilex,tiley);
+		break;
+
+	case ssobj:
+		GivePoints (500);
+		NewState (ob,&s_ssdie1);
+		if (gamestate.bestweapon < wp_machinegun)
+			PlaceItemType (bo_machinegun,tilex,tiley);
+		else
+			PlaceItemType (bo_clip2,tilex,tiley);
+		break;
+
+	case dogobj:
+		GivePoints (200);
+		NewState (ob,&s_dogdie1);
+		break;
+
+#ifndef SPEAR
+	case bossobj:
+		GivePoints (5000);
+		NewState (ob,&s_bossdie1);
+		PlaceItemType (bo_key1,tilex,tiley);
+		break;
+
+	case gretelobj:
+		GivePoints (5000);
+		NewState (ob,&s_greteldie1);
+		PlaceItemType (bo_key1,tilex,tiley);
+		break;
+
+	case giftobj:
+		GivePoints (5000);
+		gamestate.killx = player->x;
+		gamestate.killy = player->y;
+		NewState (ob,&s_giftdie1);
+		break;
+
+	case fatobj:
+		GivePoints (5000);
+		gamestate.killx = player->x;
+		gamestate.killy = player->y;
+		NewState (ob,&s_fatdie1);
+		break;
+
+	case schabbobj:
+		GivePoints (5000);
+		gamestate.killx = player->x;
+		gamestate.killy = player->y;
+		NewState (ob,&s_schabbdie1);
+		A_DeathScream(ob);
+		break;
+	case fakeobj:
+		GivePoints (2000);
+		NewState (ob,&s_fakedie1);
+		break;
+
+	case mechahitlerobj:
+		GivePoints (5000);
+		NewState (ob,&s_mechadie1);
+		break;
+	case realhitlerobj:
+		GivePoints (5000);
+		gamestate.killx = player->x;
+		gamestate.killy = player->y;
+		NewState (ob,&s_hitlerdie1);
+		A_DeathScream(ob);
+		break;
+#else
+	case spectreobj:
+		GivePoints (200);
+		NewState (ob,&s_spectredie1);
+		break;
+
+	case angelobj:
+		GivePoints (5000);
+		NewState (ob,&s_angeldie1);
+		break;
+
+	case transobj:
+		GivePoints (5000);
+		NewState (ob,&s_transdie0);
+		PlaceItemType (bo_key1,tilex,tiley);
+		break;
+
+	case uberobj:
+		GivePoints (5000);
+		NewState (ob,&s_uberdie0);
+		PlaceItemType (bo_key1,tilex,tiley);
+		break;
+
+	case willobj:
+		GivePoints (5000);
+		NewState (ob,&s_willdie1);
+		PlaceItemType (bo_key1,tilex,tiley);
+		break;
+
+	case deathobj:
+		GivePoints (5000);
+		NewState (ob,&s_deathdie1);
+		PlaceItemType (bo_key1,tilex,tiley);
+		break;
+#endif
+	}
+
+	gamestate.killcount++;
+	ob->flags &= ~FL_SHOOTABLE;
+	actorat[ob->tilex][ob->tiley] = NULL;
+	ob->flags |= FL_NONMARK;
+}
+
+
+
+/*
+===================
+=
+= DamageActor
+=
+= Called when the player succesfully hits an enemy.
+=
+= Does damage points to enemy ob, either putting it into a stun frame or
+= killing it.
+=
+===================
+*/
+
+void DamageActor (objtype *ob, unsigned damage)
+{
+	madenoise = true;
+
+//
+// do double damage if shooting a non attack mode actor
+//
+	if ( !(ob->flags & FL_ATTACKMODE) )
+		damage <<= 1;
+
+	ob->hitpoints -= damage;
+
+	if (ob->hitpoints<=0)
+		KillActor (ob);
+	else
+	{
+		if (! (ob->flags & FL_ATTACKMODE) )
+			FirstSighting (ob);		// put into combat mode
+
+		switch (ob->obclass)		// dogs only have one hit point
+		{
+		case guardobj:
+			if (ob->hitpoints&1)
+				NewState (ob,&s_grdpain);
+			else
+				NewState (ob,&s_grdpain1);
+			break;
+
+		case officerobj:
+			if (ob->hitpoints&1)
+				NewState (ob,&s_ofcpain);
+			else
+				NewState (ob,&s_ofcpain1);
+			break;
+
+		case mutantobj:
+			if (ob->hitpoints&1)
+				NewState (ob,&s_mutpain);
+			else
+				NewState (ob,&s_mutpain1);
+			break;
+
+		case ssobj:
+			if (ob->hitpoints&1)
+				NewState (ob,&s_sspain);
+			else
+				NewState (ob,&s_sspain1);
+
+			break;
+
+		}
+	}
+}
+
+/*
+=============================================================================
+
+							CHECKSIGHT
+
+=============================================================================
+*/
+
+
+/*
+=====================
+=
+= CheckLine
+=
+= Returns true if a straight line between the player and ob is unobstructed
+=
+=====================
+*/
+
+boolean CheckLine (objtype *ob)
+{
+	int	x1,y1,xt1,yt1,x2,y2,xt2,yt2;
+	int	x,y;
+	int	xdist,ydist,xstep,ystep;
+	int	temp;
+	int	partial,delta;
+	long	ltemp;
+	int	xfrac,yfrac,deltafrac;
+	unsigned	value,intercept;
+
+	x1 = ob->x >> UNSIGNEDSHIFT;		// 1/256 tile precision
+	y1 = ob->y >> UNSIGNEDSHIFT;
+	xt1 = x1 >> 8;
+	yt1 = y1 >> 8;
+
+	x2 = plux;
+	y2 = pluy;
+	xt2 = player->tilex;
+	yt2 = player->tiley;
+
+
+	xdist = abs(xt2-xt1);
+
+	if (xdist > 0)
+	{
+		if (xt2 > xt1)
+		{
+			partial = 256-(x1&0xff);
+			xstep = 1;
+		}
+		else
+		{
+			partial = x1&0xff;
+			xstep = -1;
+		}
+
+		deltafrac = abs(x2-x1);
+		delta = y2-y1;
+		ltemp = ((long)delta<<8)/deltafrac;
+		if (ltemp > 0x7fffl)
+			ystep = 0x7fff;
+		else if (ltemp < -0x7fffl)
+			ystep = -0x7fff;
+		else
+			ystep = ltemp;
+		yfrac = y1 + (((long)ystep*partial) >>8);
+
+		x = xt1+xstep;
+		xt2 += xstep;
+		do
+		{
+			y = yfrac>>8;
+			yfrac += ystep;
+
+			value = (unsigned)tilemap[x][y];
+			x += xstep;
+
+			if (!value)
+				continue;
+
+			if (value<128 || value>256)
+				return false;
+
+			//
+			// see if the door is open enough
+			//
+			value &= ~0x80;
+			intercept = yfrac-ystep/2;
+
+			if (intercept>doorposition[value])
+				return false;
+
+		} while (x != xt2);
+	}
+
+	ydist = abs(yt2-yt1);
+
+	if (ydist > 0)
+	{
+		if (yt2 > yt1)
+		{
+			partial = 256-(y1&0xff);
+			ystep = 1;
+		}
+		else
+		{
+			partial = y1&0xff;
+			ystep = -1;
+		}
+
+		deltafrac = abs(y2-y1);
+		delta = x2-x1;
+		ltemp = ((long)delta<<8)/deltafrac;
+		if (ltemp > 0x7fffl)
+			xstep = 0x7fff;
+		else if (ltemp < -0x7fffl)
+			xstep = -0x7fff;
+		else
+			xstep = ltemp;
+		xfrac = x1 + (((long)xstep*partial) >>8);
+
+		y = yt1 + ystep;
+		yt2 += ystep;
+		do
+		{
+			x = xfrac>>8;
+			xfrac += xstep;
+
+			value = (unsigned)tilemap[x][y];
+			y += ystep;
+
+			if (!value)
+				continue;
+
+			if (value<128 || value>256)
+				return false;
+
+			//
+			// see if the door is open enough
+			//
+			value &= ~0x80;
+			intercept = xfrac-xstep/2;
+
+			if (intercept>doorposition[value])
+				return false;
+		} while (y != yt2);
+	}
+
+	return true;
+}
+
+
+
+/*
+================
+=
+= 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
+=
+================
+*/
+
+#define MINSIGHT	0x18000l
+
+boolean CheckSight (objtype *ob)
+{
+	long		deltax,deltay;
+
+//
+// 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
+//
+	deltax = player->x - ob->x;
+	deltay = player->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;
+	}
+
+//
+// trace a line to check for blocking tiles (corners)
+//
+	return CheckLine (ob);
+
+}
+
+
+
+/*
+===============
+=
+= FirstSighting
+=
+= Puts an actor into attack mode and possibly reverses the direction
+= if the player is behind it
+=
+===============
+*/
+
+void FirstSighting (objtype *ob)
+{
+//
+// react to the player
+//
+	switch (ob->obclass)
+	{
+	case guardobj:
+		PlaySoundLocActor(HALTSND,ob);
+		NewState (ob,&s_grdchase1);
+		ob->speed *= 3;			// go faster when chasing player
+		break;
+
+	case officerobj:
+		PlaySoundLocActor(SPIONSND,ob);
+		NewState (ob,&s_ofcchase1);
+		ob->speed *= 5;			// go faster when chasing player
+		break;
+
+	case mutantobj:
+		NewState (ob,&s_mutchase1);
+		ob->speed *= 3;			// go faster when chasing player
+		break;
+
+	case ssobj:
+		PlaySoundLocActor(SCHUTZADSND,ob);
+		NewState (ob,&s_sschase1);
+		ob->speed *= 4;			// go faster when chasing player
+		break;
+
+	case dogobj:
+		PlaySoundLocActor(DOGBARKSND,ob);
+		NewState (ob,&s_dogchase1);
+		ob->speed *= 2;			// go faster when chasing player
+		break;
+
+#ifndef SPEAR
+	case bossobj:
+		SD_PlaySound(GUTENTAGSND);
+		NewState (ob,&s_bosschase1);
+		ob->speed = SPDPATROL*3;	// go faster when chasing player
+		break;
+
+	case gretelobj:
+		SD_PlaySound(KEINSND);
+		NewState (ob,&s_gretelchase1);
+		ob->speed *= 3;			// go faster when chasing player
+		break;
+
+	case giftobj:
+		SD_PlaySound(EINESND);
+		NewState (ob,&s_giftchase1);
+		ob->speed *= 3;			// go faster when chasing player
+		break;
+
+	case fatobj:
+		SD_PlaySound(ERLAUBENSND);
+		NewState (ob,&s_fatchase1);
+		ob->speed *= 3;			// go faster when chasing player
+		break;
+
+	case schabbobj:
+		SD_PlaySound(SCHABBSHASND);
+		NewState (ob,&s_schabbchase1);
+		ob->speed *= 3;			// go faster when chasing player
+		break;
+
+	case fakeobj:
+		SD_PlaySound(TOT_HUNDSND);
+		NewState (ob,&s_fakechase1);
+		ob->speed *= 3;			// go faster when chasing player
+		break;
+
+	case mechahitlerobj:
+		SD_PlaySound(DIESND);
+		NewState (ob,&s_mechachase1);
+		ob->speed *= 3;			// go faster when chasing player
+		break;
+
+	case realhitlerobj:
+		SD_PlaySound(DIESND);
+		NewState (ob,&s_hitlerchase1);
+		ob->speed *= 5;			// go faster when chasing player
+		break;
+
+	case ghostobj:
+		NewState (ob,&s_blinkychase1);
+		ob->speed *= 2;			// go faster when chasing player
+		break;
+#else
+
+	case spectreobj:
+		SD_PlaySound(GHOSTSIGHTSND);
+		NewState (ob,&s_spectrechase1);
+		ob->speed = 800;			// go faster when chasing player
+		break;
+
+	case angelobj:
+		SD_PlaySound(ANGELSIGHTSND);
+		NewState (ob,&s_angelchase1);
+		ob->speed = 1536;			// go faster when chasing player
+		break;
+
+	case transobj:
+		SD_PlaySound(TRANSSIGHTSND);
+		NewState (ob,&s_transchase1);
+		ob->speed = 1536;			// go faster when chasing player
+		break;
+
+	case uberobj:
+		NewState (ob,&s_uberchase1);
+		ob->speed = 3000;			// go faster when chasing player
+		break;
+
+	case willobj:
+		SD_PlaySound(WILHELMSIGHTSND);
+		NewState (ob,&s_willchase1);
+		ob->speed = 2048;			// go faster when chasing player
+		break;
+
+	case deathobj:
+		SD_PlaySound(KNIGHTSIGHTSND);
+		NewState (ob,&s_deathchase1);
+		ob->speed = 2048;			// go faster when chasing player
+		break;
+
+#endif
+	}
+
+	if (ob->distance < 0)
+		ob->distance = 0;	// ignore the door opening command
+
+	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)
+		Quit ("An actor in ATTACKMODE called SightPlayer!");
+
+	if (ob->temp2)
+	{
+	//
+	// count down reaction time
+	//
+		ob->temp2 -= tics;
+		if (ob->temp2 > 0)
+			return false;
+		ob->temp2 = 0;					// time to react
+	}
+	else
+	{
+		if (!areabyplayer[ob->areanumber])
+			return false;
+
+		if (ob->flags & FL_AMBUSH)
+		{
+			if (!CheckSight (ob))
+				return false;
+			ob->flags &= ~FL_AMBUSH;
+		}
+		else
+		{
+			if (!madenoise && !CheckSight (ob))
+				return false;
+		}
+
+
+		switch (ob->obclass)
+		{
+		case guardobj:
+			ob->temp2 = 1+US_RndT()/4;
+			break;
+		case officerobj:
+			ob->temp2 = 2;
+			break;
+		case mutantobj:
+			ob->temp2 = 1+US_RndT()/6;
+			break;
+		case ssobj:
+			ob->temp2 = 1+US_RndT()/6;
+			break;
+		case dogobj:
+			ob->temp2 = 1+US_RndT()/8;
+			break;
+
+		case bossobj:
+		case schabbobj:
+		case fakeobj:
+		case mechahitlerobj:
+		case realhitlerobj:
+		case gretelobj:
+		case giftobj:
+		case fatobj:
+		case spectreobj:
+		case angelobj:
+		case transobj:
+		case uberobj:
+		case willobj:
+		case deathobj:
+			ob->temp2 = 1;
+			break;
+		}
+		return false;
+	}
+
+	FirstSighting (ob);
+
+	return true;
+}
+
+
--- /dev/null
+++ b/WOLFSRC/WL_TEXT.C
@@ -1,0 +1,859 @@
+// WL_TEXT.C
+
+#include "WL_DEF.H"
+#pragma	hdrstop
+
+/*
+=============================================================================
+
+TEXT FORMATTING COMMANDS
+------------------------
+^C<hex digit>  			Change text color
+^E[enter]				End of layout (all pages)
+^G<y>,<x>,<pic>[enter]	Draw a graphic and push margins
+^P[enter]				start new page, must be the first chars in a layout
+^L<x>,<y>[ENTER]		Locate to a specific spot, x in pixels, y in lines
+
+=============================================================================
+*/
+
+/*
+=============================================================================
+
+						 LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+#define BACKCOLOR		0x11
+
+
+#define WORDLIMIT		80
+#define FONTHEIGHT		10
+#define	TOPMARGIN		16
+#define BOTTOMMARGIN	32
+#define LEFTMARGIN		16
+#define RIGHTMARGIN		16
+#define PICMARGIN		8
+#define TEXTROWS		((200-TOPMARGIN-BOTTOMMARGIN)/FONTHEIGHT)
+#define	SPACEWIDTH		7
+#define SCREENPIXWIDTH	320
+#define SCREENMID		(SCREENPIXWIDTH/2)
+
+/*
+=============================================================================
+
+						 LOCAL VARIABLES
+
+=============================================================================
+*/
+
+int			pagenum,numpages;
+
+unsigned	leftmargin[TEXTROWS],rightmargin[TEXTROWS];
+char		far *text;
+unsigned	rowon;
+
+int			picx,picy,picnum,picdelay;
+boolean		layoutdone;
+
+//===========================================================================
+
+#ifndef JAPAN
+/*
+=====================
+=
+= RipToEOL
+=
+=====================
+*/
+
+void RipToEOL (void)
+{
+	while (*text++ != '\n')		// scan to end of line
+	;
+}
+
+
+/*
+=====================
+=
+= ParseNumber
+=
+=====================
+*/
+
+int	ParseNumber (void)
+{
+	char	ch;
+	char	num[80],*numptr;
+
+//
+// scan until a number is found
+//
+	ch = *text;
+	while (ch < '0' || ch >'9')
+		ch = *++text;
+
+//
+// copy the number out
+//
+	numptr = num;
+	do
+	{
+		*numptr++ = ch;
+		ch = *++text;
+	} while (ch >= '0' && ch <= '9');
+	*numptr = 0;
+
+	return atoi (num);
+}
+
+
+
+/*
+=====================
+=
+= ParsePicCommand
+=
+= Call with text pointing just after a ^P
+= Upon exit text points to the start of next line
+=
+=====================
+*/
+
+void	ParsePicCommand (void)
+{
+	picy=ParseNumber();
+	picx=ParseNumber();
+	picnum=ParseNumber();
+	RipToEOL ();
+}
+
+
+void	ParseTimedCommand (void)
+{
+	picy=ParseNumber();
+	picx=ParseNumber();
+	picnum=ParseNumber();
+	picdelay=ParseNumber();
+	RipToEOL ();
+}
+
+
+/*
+=====================
+=
+= TimedPicCommand
+=
+= Call with text pointing just after a ^P
+= Upon exit text points to the start of next line
+=
+=====================
+*/
+
+void	TimedPicCommand (void)
+{
+	ParseTimedCommand ();
+
+//
+// update the screen, and wait for time delay
+//
+	VW_UpdateScreen ();
+
+//
+// wait for time
+//
+	TimeCount = 0;
+	while (TimeCount < picdelay)
+	;
+
+//
+// draw pic
+//
+	VWB_DrawPic (picx&~7,picy,picnum);
+}
+
+
+/*
+=====================
+=
+= HandleCommand
+=
+=====================
+*/
+
+void HandleCommand (void)
+{
+	int	i,margin,top,bottom;
+	int	picwidth,picheight,picmid;
+
+	switch (toupper(*++text))
+	{
+	case 'B':
+		picy=ParseNumber();
+		picx=ParseNumber();
+		picwidth=ParseNumber();
+		picheight=ParseNumber();
+		VWB_Bar(picx,picy,picwidth,picheight,BACKCOLOR);
+		RipToEOL();
+		break;
+	case ';':		// comment
+		RipToEOL();
+		break;
+	case 'P':		// ^P is start of next page, ^E is end of file
+	case 'E':
+		layoutdone = true;
+		text--;    	// back up to the '^'
+		break;
+
+	case 'C':		// ^c<hex digit> changes text color
+		i = toupper(*++text);
+		if (i>='0' && i<='9')
+			fontcolor = i-'0';
+		else if (i>='A' && i<='F')
+			fontcolor = i-'A'+10;
+
+		fontcolor *= 16;
+		i = toupper(*++text);
+		if (i>='0' && i<='9')
+			fontcolor += i-'0';
+		else if (i>='A' && i<='F')
+			fontcolor += i-'A'+10;
+		text++;
+		break;
+
+	case '>':
+		px = 160;
+		text++;
+		break;
+
+	case 'L':
+		py=ParseNumber();
+		rowon = (py-TOPMARGIN)/FONTHEIGHT;
+		py = TOPMARGIN+rowon*FONTHEIGHT;
+		px=ParseNumber();
+		while (*text++ != '\n')		// scan to end of line
+		;
+		break;
+
+	case 'T':		// ^Tyyy,xxx,ppp,ttt waits ttt tics, then draws pic
+		TimedPicCommand ();
+		break;
+
+	case 'G':		// ^Gyyy,xxx,ppp draws graphic
+		ParsePicCommand ();
+		VWB_DrawPic (picx&~7,picy,picnum);
+		picwidth = pictable[picnum-STARTPICS].width;
+		picheight = pictable[picnum-STARTPICS].height;
+		//
+		// adjust margins
+		//
+		picmid = picx + picwidth/2;
+		if (picmid > SCREENMID)
+			margin = picx-PICMARGIN;			// new right margin
+		else
+			margin = picx+picwidth+PICMARGIN;	// new left margin
+
+		top = (picy-TOPMARGIN)/FONTHEIGHT;
+		if (top<0)
+			top = 0;
+		bottom = (picy+picheight-TOPMARGIN)/FONTHEIGHT;
+		if (bottom>=TEXTROWS)
+			bottom = TEXTROWS-1;
+
+		for (i=top;i<=bottom;i++)
+			if (picmid > SCREENMID)
+				rightmargin[i] = margin;
+			else
+				leftmargin[i] = margin;
+
+		//
+		// adjust this line if needed
+		//
+		if (px < leftmargin[rowon])
+			px = leftmargin[rowon];
+		break;
+	}
+}
+
+
+/*
+=====================
+=
+= NewLine
+=
+=====================
+*/
+
+void NewLine (void)
+{
+	char	ch;
+
+	if (++rowon == TEXTROWS)
+	{
+	//
+	// overflowed the page, so skip until next page break
+	//
+		layoutdone = true;
+		do
+		{
+			if (*text == '^')
+			{
+				ch = toupper(*(text+1));
+				if (ch == 'E' || ch == 'P')
+				{
+					layoutdone = true;
+					return;
+				}
+			}
+			text++;
+
+		} while (1);
+
+	}
+	px = leftmargin[rowon];
+	py+= FONTHEIGHT;
+}
+
+
+
+/*
+=====================
+=
+= HandleCtrls
+=
+=====================
+*/
+
+void HandleCtrls (void)
+{
+	char	ch;
+
+	ch = *text++;			// get the character and advance
+
+	if (ch == '\n')
+	{
+		NewLine ();
+		return;
+	}
+
+}
+
+
+/*
+=====================
+=
+= HandleWord
+=
+=====================
+*/
+
+void HandleWord (void)
+{
+	char		word[WORDLIMIT];
+	int			i,wordindex;
+	unsigned	wwidth,wheight,newpos;
+
+
+	//
+	// copy the next word into [word]
+	//
+	word[0] = *text++;
+	wordindex = 1;
+	while (*text>32)
+	{
+		word[wordindex] = *text++;
+		if (++wordindex == WORDLIMIT)
+			Quit ("PageLayout: Word limit exceeded");
+	}
+	word[wordindex] = 0;		// stick a null at end for C
+
+	//
+	// see if it fits on this line
+	//
+	VW_MeasurePropString (word,&wwidth,&wheight);
+
+	while (px+wwidth > rightmargin[rowon])
+	{
+		NewLine ();
+		if (layoutdone)
+			return;		// overflowed page
+	}
+
+	//
+	// print it
+	//
+	newpos = px+wwidth;
+	VWB_DrawPropString (word);
+	px = newpos;
+
+	//
+	// suck up any extra spaces
+	//
+	while (*text == ' ')
+	{
+		px += SPACEWIDTH;
+		text++;
+	}
+}
+
+/*
+=====================
+=
+= PageLayout
+=
+= Clears the screen, draws the pics on the page, and word wraps the text.
+= Returns a pointer to the terminating command
+=
+=====================
+*/
+
+void PageLayout (boolean shownumber)
+{
+	int		i,oldfontcolor;
+	char	ch;
+
+	oldfontcolor = fontcolor;
+
+	fontcolor = 0;
+
+//
+// clear the screen
+//
+	VWB_Bar (0,0,320,200,BACKCOLOR);
+	VWB_DrawPic (0,0,H_TOPWINDOWPIC);
+	VWB_DrawPic (0,8,H_LEFTWINDOWPIC);
+	VWB_DrawPic (312,8,H_RIGHTWINDOWPIC);
+	VWB_DrawPic (8,176,H_BOTTOMINFOPIC);
+
+
+	for (i=0;i<TEXTROWS;i++)
+	{
+		leftmargin[i] = LEFTMARGIN;
+		rightmargin[i] = SCREENPIXWIDTH-RIGHTMARGIN;
+	}
+
+	px = LEFTMARGIN;
+	py = TOPMARGIN;
+	rowon = 0;
+	layoutdone = false;
+
+//
+// make sure we are starting layout text (^P first command)
+//
+	while (*text <= 32)
+		text++;
+
+	if (*text != '^' || toupper(*++text) != 'P')
+		Quit ("PageLayout: Text not headed with ^P");
+
+	while (*text++ != '\n')
+	;
+
+
+//
+// process text stream
+//
+	do
+	{
+		ch = *text;
+
+		if (ch == '^')
+			HandleCommand ();
+		else
+		if (ch == 9)
+		{
+		 px = (px+8)&0xf8;
+		 text++;
+		}
+		else if (ch <= 32)
+			HandleCtrls ();
+		else
+			HandleWord ();
+
+	} while (!layoutdone);
+
+	pagenum++;
+
+	if (shownumber)
+	{
+		#ifdef SPANISH
+		strcpy (str,"Hoja ");
+		itoa (pagenum,str2,10);
+		strcat (str,str2);
+		strcat (str," de ");
+		py = 183;
+		px = 208;
+		#else
+		strcpy (str,"pg ");
+		itoa (pagenum,str2,10);
+		strcat (str,str2);
+		strcat (str," of ");
+		py = 183;
+		px = 213;
+		#endif
+		itoa (numpages,str2,10);
+		strcat (str,str2);
+		fontcolor = 0x4f; 			   //12^BACKCOLOR;
+
+		VWB_DrawPropString (str);
+	}
+
+	fontcolor = oldfontcolor;
+}
+
+//===========================================================================
+
+/*
+=====================
+=
+= BackPage
+=
+= Scans for a previous ^P
+=
+=====================
+*/
+
+void BackPage (void)
+{
+	pagenum--;
+	do
+	{
+		text--;
+		if (*text == '^' && toupper(*(text+1)) == 'P')
+			return;
+	} while (1);
+}
+
+
+//===========================================================================
+
+
+/*
+=====================
+=
+= CacheLayoutGraphics
+=
+= Scans an entire layout file (until a ^E) marking all graphics used, and
+= counting pages, then caches the graphics in
+=
+=====================
+*/
+void CacheLayoutGraphics (void)
+{
+	char	far *bombpoint, far *textstart;
+	char	ch;
+
+	textstart = text;
+	bombpoint = text+30000;
+	numpages = pagenum = 0;
+
+	do
+	{
+		if (*text == '^')
+		{
+			ch = toupper(*++text);
+			if (ch == 'P')		// start of a page
+				numpages++;
+			if (ch == 'E')		// end of file, so load graphics and return
+			{
+				CA_MarkGrChunk(H_TOPWINDOWPIC);
+				CA_MarkGrChunk(H_LEFTWINDOWPIC);
+				CA_MarkGrChunk(H_RIGHTWINDOWPIC);
+				CA_MarkGrChunk(H_BOTTOMINFOPIC);
+				CA_CacheMarks ();
+				text = textstart;
+				return;
+			}
+			if (ch == 'G')		// draw graphic command, so mark graphics
+			{
+				ParsePicCommand ();
+				CA_MarkGrChunk (picnum);
+			}
+			if (ch == 'T')		// timed draw graphic command, so mark graphics
+			{
+				ParseTimedCommand ();
+				CA_MarkGrChunk (picnum);
+			}
+		}
+		else
+			text++;
+
+	} while (text<bombpoint);
+
+	Quit ("CacheLayoutGraphics: No ^E to terminate file!");
+}
+#endif
+
+
+/*
+=====================
+=
+= ShowArticle
+=
+=====================
+*/
+
+#ifdef JAPAN
+void ShowArticle (int which)
+#else
+void ShowArticle (char far *article)
+#endif
+{
+	#ifdef JAPAN
+	int		snames[10] = {	H_HELP1PIC,
+							H_HELP2PIC,
+							H_HELP3PIC,
+							H_HELP4PIC,
+							H_HELP5PIC,
+							H_HELP6PIC,
+							H_HELP7PIC,
+							H_HELP8PIC,
+							H_HELP9PIC,
+							H_HELP10PIC};
+	int		enames[14] = {
+							0,0,
+							#ifndef JAPDEMO
+							C_ENDGAME1APIC,
+							C_ENDGAME1BPIC,
+							C_ENDGAME2APIC,
+							C_ENDGAME2BPIC,
+							C_ENDGAME3APIC,
+							C_ENDGAME3BPIC,
+							C_ENDGAME4APIC,
+							C_ENDGAME4BPIC,
+							C_ENDGAME5APIC,
+							C_ENDGAME5BPIC,
+							C_ENDGAME6APIC,
+							C_ENDGAME6BPIC
+							#endif
+							};
+	#endif
+	unsigned	oldfontnumber;
+	unsigned	temp;
+	boolean 	newpage,firstpage;
+
+	#ifdef JAPAN
+	pagenum = 1;
+	if (!which)
+		numpages = 10;
+	else
+		numpages = 2;
+
+	#else
+
+	text = article;
+	oldfontnumber = fontnumber;
+	fontnumber = 0;
+	CA_MarkGrChunk(STARTFONT);
+	VWB_Bar (0,0,320,200,BACKCOLOR);
+	CacheLayoutGraphics ();
+	#endif
+
+	newpage = true;
+	firstpage = true;
+
+	do
+	{
+		if (newpage)
+		{
+			newpage = false;
+			#ifdef JAPAN
+			if (!which)
+				CA_CacheScreen(snames[pagenum - 1]);
+			else
+				CA_CacheScreen(enames[which*2 + pagenum - 1]);
+			#else
+			PageLayout (true);
+			#endif
+			VW_UpdateScreen ();
+			if (firstpage)
+			{
+				VL_FadeIn(0,255,&gamepal,10);
+				// VW_FadeIn ()
+				firstpage = false;
+			}
+		}
+
+		LastScan = 0;
+		while (!LastScan)
+		;
+
+		switch (LastScan)
+		{
+		case sc_UpArrow:
+		case sc_PgUp:
+		case sc_LeftArrow:
+			if (pagenum>1)
+			{
+				#ifndef JAPAN
+				BackPage ();
+				BackPage ();
+				#else
+				pagenum--;
+				#endif
+				newpage = true;
+			}
+			break;
+
+		case sc_Enter:
+		case sc_DownArrow:
+		case sc_PgDn:
+		case sc_RightArrow:		// the text allready points at next page
+			if (pagenum<numpages)
+			{
+				newpage = true;
+				#ifdef JAPAN
+				pagenum++;
+				#endif
+			}
+			break;
+		}
+
+		#ifndef SPEAR
+		if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("goobers"))
+			PicturePause();
+		#endif
+
+	} while (LastScan != sc_Escape);
+
+	IN_ClearKeysDown ();
+	fontnumber = oldfontnumber;
+}
+
+
+//===========================================================================
+
+#ifndef JAPAN
+#ifdef ARTSEXTERN
+int 	endextern = T_ENDART1;
+#ifndef SPEAR
+int		helpextern = T_HELPART;
+#endif
+#endif
+char helpfilename[13] = "HELPART.",
+	 endfilename[13] = "ENDART1.";
+#endif
+
+/*
+=================
+=
+= HelpScreens
+=
+=================
+*/
+#ifndef SPEAR
+void HelpScreens (void)
+{
+	int			artnum;
+	char far 	*text;
+	memptr		layout;
+
+
+	CA_UpLevel ();
+	MM_SortMem ();
+#ifdef JAPAN
+	ShowArticle (0);
+	VW_FadeOut();
+	FreeMusic ();
+	CA_DownLevel ();
+	MM_SortMem ();
+#else
+
+
+
+
+#ifdef ARTSEXTERN
+	artnum = helpextern;
+	CA_CacheGrChunk (artnum);
+	text = (char _seg *)grsegs[artnum];
+	MM_SetLock (&grsegs[artnum], true);
+#else
+	CA_LoadFile (helpfilename,&layout);
+	text = (char _seg *)layout;
+	MM_SetLock (&layout, true);
+#endif
+
+	ShowArticle (text);
+
+#ifdef ARTSEXTERN
+	MM_FreePtr (&grsegs[artnum]);
+#else
+	MM_FreePtr (&layout);
+#endif
+
+
+
+	VW_FadeOut();
+
+	FreeMusic ();
+	CA_DownLevel ();
+	MM_SortMem ();
+#endif
+}
+#endif
+
+//
+// END ARTICLES
+//
+void EndText (void)
+{
+	int			artnum;
+	char far 	*text;
+	memptr		layout;
+
+
+	ClearMemory ();
+
+	CA_UpLevel ();
+	MM_SortMem ();
+#ifdef JAPAN
+	ShowArticle(gamestate.episode + 1);
+
+	VW_FadeOut();
+
+	SETFONTCOLOR(0,15);
+	IN_ClearKeysDown();
+	if (MousePresent)
+		Mouse(MDelta);	// Clear accumulated mouse movement
+
+	FreeMusic ();
+	CA_DownLevel ();
+	MM_SortMem ();
+#else
+
+
+
+#ifdef ARTSEXTERN
+	artnum = endextern+gamestate.episode;
+	CA_CacheGrChunk (artnum);
+	text = (char _seg *)grsegs[artnum];
+	MM_SetLock (&grsegs[artnum], true);
+#else
+	endfilename[6] = '1'+gamestate.episode;
+	CA_LoadFile (endfilename,&layout);
+	text = (char _seg *)layout;
+	MM_SetLock (&layout, true);
+#endif
+
+	ShowArticle (text);
+
+#ifdef ARTSEXTERN
+	MM_FreePtr (&grsegs[artnum]);
+#else
+	MM_FreePtr (&layout);
+#endif
+
+
+	VW_FadeOut();
+	SETFONTCOLOR(0,15);
+	IN_ClearKeysDown();
+	if (MousePresent)
+		Mouse(MDelta);	// Clear accumulated mouse movement
+
+	FreeMusic ();
+	CA_DownLevel ();
+	MM_SortMem ();
+#endif
+}
binary files /dev/null b/WOLFSRC/WOLF.DSW differ
binary files /dev/null b/WOLFSRC/WOLF.EXE differ
binary files /dev/null b/WOLFSRC/WOLF.IDE differ
binary files /dev/null b/WOLFSRC/WOLF.OBR differ
binary files /dev/null b/WOLFSRC/WOLF.~DE differ
--- /dev/null
+++ b/WOLFSRC/WOLF1VER.H
@@ -1,0 +1,7 @@
+//#define SPEAR
+#define ARTSEXTERN
+#define DEMOSEXTERN
+//#define MYPROFILE
+//#define DEBCHECK
+#define CARMACIZED
+#define UPLOAD
binary files /dev/null b/WOLFSRC/WOLF3D.DSK differ
binary files /dev/null b/WOLFSRC/WOLF3D.EXE differ
--- /dev/null
+++ b/WOLFSRC/WOLF3D.MAP
@@ -1,0 +1,3660 @@
+
+ Start  Stop   Length Name               Class
+
+ 00000H 044BBH 044BCH _TEXT              CODE
+ 044BCH 044BCH 00000H H_LDIV_TEXT        CODE
+ 044BCH 04855H 0039AH WOLFHACK_TEXT      CODE
+ 04858H 048BCH 00065H WHACK_A_TEXT       CODE
+ 048C0H 048FAH 0003BH WL_ASM_TEXT        CODE
+ 048FBH 060ABH 017B1H WL_MAIN_TEXT       CODE
+ 060ACH 06A53H 009A8H WL_TEXT_TEXT       CODE
+ 06A54H 0A853H 03E00H WL_MENU_TEXT       CODE
+ 0A854H 0BC65H 01412H WL_INTER_TEXT      CODE
+ 0BC66H 0CFC6H 01361H WL_GAME_TEXT       CODE
+ 0CFC7H 0E0DCH 01116H WL_PLAY_TEXT       CODE
+ 0E0DDH 0EBCEH 00AF2H WL_DEBUG_TEXT      CODE
+ 0EBCFH 0FB85H 00FB7H WL_DRAW_TEXT       CODE
+ 0FB86H 0FFD9H 00454H WL_DR_A_TEXT       CODE
+ 0FFDAH 1087BH 008A2H WL_SCALE_TEXT      CODE
+ 1087CH 12014H 01799H WL_STATE_TEXT      CODE
+ 12015H 1320EH 011FAH WL_AGENT_TEXT      CODE
+ 1320FH 13ECBH 00CBDH WL_ACT1_TEXT       CODE
+ 13ECCH 160F7H 0222CH WL_ACT2_TEXT       CODE
+ 160F8H 177B0H 016B9H ID_CA_TEXT         CODE
+ 177B1H 182DFH 00B2FH ID_IN_TEXT         CODE
+ 182E0H 19126H 00E47H ID_MM_TEXT         CODE
+ 19127H 1A286H 01160H ID_PM_TEXT         CODE
+ 1A287H 1BB15H 0188FH ID_SD_TEXT         CODE
+ 1BB16H 1BF07H 003F2H ID_SD_A_TEXT       CODE
+ 1BF08H 1CAADH 00BA6H ID_US_1_TEXT       CODE
+ 1CAAEH 1CAF2H 00045H ID_US_A_TEXT       CODE
+ 1CAF3H 1D61FH 00B2DH ID_VL_TEXT         CODE
+ 1D620H 1DF01H 008E2H ID_VH_TEXT         CODE
+ 1DF02H 1E195H 00294H ID_VL_A_TEXT       CODE
+ 1E196H 1E38BH 001F6H ID_VH_A_TEXT       CODE
+ 1E390H 20B06H 02777H EMU_PROG           CODE
+ 20B10H 210D7H 005C8H E87_PROG           CODE
+ 210E0H 210E0H 00000H _FARDATA           FAR_DATA
+ 210E0H 230DFH 02000H FAR_DATA           FAR_DATA
+ 230E0H 231E1H 00102H FAR_DATA           FAR_DATA
+ 231F0H 234E3H 002F4H WL_MAIN5_DATA      FAR_DATA
+ 234F0H 237BFH 002D0H WL_MENU5_DATA      FAR_DATA
+ 237C0H 23939H 0017AH WL_MENU6_DATA      FAR_DATA
+ 23940H 23B37H 001F8H WL_MENU7_DATA      FAR_DATA
+ 23B40H 23C3BH 000FCH WL_MENU8_DATA      FAR_DATA
+ 23C40H 23E0DH 001CEH WL_MENU9_DATA      FAR_DATA
+ 23E10H 23EB7H 000A8H WL_MENU10_DATA     FAR_DATA
+ 23EC0H 24063H 001A4H WL_MENU11_DATA     FAR_DATA
+ 24070H 241E9H 0017AH WL_MENU12_DATA     FAR_DATA
+ 241F0H 24213H 00024H WL_MENU13_DATA     FAR_DATA
+ 24220H 33C1FH 0FA00H SignonSeg          FAR_DATA
+ 33C20H 33C9FH 00080H ID_IN5_DATA        FAR_DATA
+ 33CA0H 33D1FH 00080H ID_IN6_DATA        FAR_DATA
+ 33D20H 33D9FH 00080H ID_IN7_DATA        FAR_DATA
+ 33DA0H 33DA0H 00000H _FARBSS            FAR_BSS
+ 33DA0H 342F8H 00559H _COMDEF_AA_        FAR_BSS
+ 34300H 34A07H 00708H _COMDEF_AB_        FAR_BSS
+ 34A10H 3581FH 00E10H _COMDEF_AC_        FAR_BSS
+ 35820H 358B4H 00095H _COMDEF_AD_        FAR_BSS
+ 358C0H 36ABFH 01200H _COMDEF_AE_        FAR_BSS
+ 36AC0H 37CBFH 01200H _COMDEF_AF_        FAR_BSS
+ 37CC0H 39D8FH 020D0H _COMDEF_AG_        FAR_BSS
+ 39D90H 3A08FH 00300H _COMDEF_AH_        FAR_BSS
+ 3A090H 3A38FH 00300H _COMDEF_AI_        FAR_BSS
+ 3A390H 3A390H 00000H _OVERLAY_          OVRINFO
+ 3A390H 3A390H 00000H _1STUB_            STUBSEG
+ 3A390H 3EAC9H 0473AH _DATA              DATA
+ 3EACAH 3EACDH 00004H _CVTSEG            DATA
+ 3EACEH 3EAD9H 0000CH _SCNSEG            DATA
+ 3EADAH 3EADAH 00000H _CONST             CONST
+ 3EADAH 3EAF7H 0001EH _INIT_             INITDATA
+ 3EAF8H 3EAF8H 00000H _INITEND_          INITDATA
+ 3EAF8H 3EAFDH 00006H _EXIT_             EXITDATA
+ 3EAFEH 3EAFEH 00000H _EXITEND_          EXITDATA
+ 3EAFEH 3ED73H 00276H _BSS               BSS
+ 3ED74H 4933EH 0A5CBH _COMDEF_           BSS
+ 4933FH 4933FH 00000H _BSSEND            BSSEND
+ 49340H 493BFH 00080H _STACK             STACK
+
+
+Detailed map of segments
+
+ 0000:0000 02B2 C=CODE   S=_TEXT          G=(none)  M=C0.ASM     ACBP=28
+ 0000:02B2 00DE C=CODE   S=_TEXT          G=(none)  M=H_LDIV.ASM ACBP=28
+ 0000:0390 0258 C=CODE   S=_TEXT          G=(none)  M=FPINIT     ACBP=28
+ 0000:05E8 0000 C=CODE   S=_TEXT          G=(none)  M=E87TRAP    ACBP=28
+ 0000:05E8 0000 C=CODE   S=_TEXT          G=(none)  M=PROTFLAG   ACBP=28
+ 0000:05E8 0000 C=CODE   S=_TEXT          G=(none)  M=DEFLT87    ACBP=28
+ 0000:05E8 000D C=CODE   S=_TEXT          G=(none)  M=ATAN       ACBP=28
+ 0000:05F5 0000 C=CODE   S=_TEXT          G=(none)  M=HUGEVAL    ACBP=28
+ 0000:05F5 009A C=CODE   S=_TEXT          G=(none)  M=LDTRUNC    ACBP=28
+ 0000:068F 0000 C=CODE   S=_TEXT          G=(none)  M=MATHWHY    ACBP=28
+ 0000:068F 01B5 C=CODE   S=_TEXT          G=(none)  M=REALCVT    ACBP=28
+ 0000:0844 0361 C=CODE   S=_TEXT          G=(none)  M=SCANTOD    ACBP=28
+ 0000:0BA5 0205 C=CODE   S=_TEXT          G=(none)  M=XCVT       ACBP=28
+ 0000:0DAA 00A4 C=CODE   S=_TEXT          G=(none)  M=FPERR      ACBP=28
+ 0000:0E4E 00C9 C=CODE   S=_TEXT          G=(none)  M=_POW10     ACBP=28
+ 0000:0F17 000B C=CODE   S=_TEXT          G=(none)  M=POW10D     ACBP=28
+ 0000:0F22 0026 C=CODE   S=_TEXT          G=(none)  M=MATHERR    ACBP=28
+ 0000:0F48 004D C=CODE   S=_TEXT          G=(none)  M=SIN        ACBP=28
+ 0000:0F95 0050 C=CODE   S=_TEXT          G=(none)  M=TAN        ACBP=28
+ 0000:0FE5 0090 C=CODE   S=_TEXT          G=(none)  M=_MATHERR   ACBP=28
+ 0000:1075 00BB C=CODE   S=_TEXT          G=(none)  M=ATAN2      ACBP=28
+ 0000:1130 002C C=CODE   S=_TEXT          G=(none)  M=FFTOL      ACBP=28
+ 0000:115C 002D C=CODE   S=_TEXT          G=(none)  M=ATEXIT     ACBP=28
+ 0000:1189 0000 C=CODE   S=_TEXT          G=(none)  M=CTYPE      ACBP=28
+ 0000:1189 0038 C=CODE   S=_TEXT          G=(none)  M=DOSFATTR   ACBP=28
+ 0000:11C1 0032 C=CODE   S=_TEXT          G=(none)  M=DOSGDATE   ACBP=28
+ 0000:11F3 0023 C=CODE   S=_TEXT          G=(none)  M=DOSWRITE   ACBP=28
+ 0000:1216 0093 C=CODE   S=_TEXT          G=(none)  M=EXIT       ACBP=28
+ 0000:12A9 0000 C=CODE   S=_TEXT          G=(none)  M=FILES      ACBP=28
+ 0000:12A9 0000 C=CODE   S=_TEXT          G=(none)  M=FILES2     ACBP=28
+ 0000:12A9 0000 C=CODE   S=_TEXT          G=(none)  M=FMODE      ACBP=28
+ 0000:12A9 0000 C=CODE   S=_TEXT          G=(none)  M=FPSTKLEN   ACBP=28
+ 0000:12A9 0017 C=CODE   S=_TEXT          G=(none)  M=F_LXMUL    ACBP=28
+ 0000:12C0 0021 C=CODE   S=_TEXT          G=(none)  M=F_PCMP     ACBP=28
+ 0000:12E1 001C C=CODE   S=_TEXT          G=(none)  M=F_SCOPY    ACBP=28
+ 0000:12FD 0020 C=CODE   S=_TEXT          G=(none)  M=GETVECT    ACBP=28
+ 0000:131D 0000 C=CODE   S=_TEXT          G=(none)  M=HEAPLEN    ACBP=28
+ 0000:131D 0021 C=CODE   S=_TEXT          G=(none)  M=H_LLSH     ACBP=28
+ 0000:133E 0020 C=CODE   S=_TEXT          G=(none)  M=H_LRSH     ACBP=28
+ 0000:135E 0021 C=CODE   S=_TEXT          G=(none)  M=H_LURSH    ACBP=28
+ 0000:137F 0088 C=CODE   S=_TEXT          G=(none)  M=H_PADA     ACBP=28
+ 0000:1407 0060 C=CODE   S=_TEXT          G=(none)  M=H_PADD     ACBP=28
+ 0000:1467 0028 C=CODE   S=_TEXT          G=(none)  M=H_PSBP     ACBP=28
+ 0000:148F 0027 C=CODE   S=_TEXT          G=(none)  M=H_SPUSH    ACBP=28
+ 0000:14B6 004B C=CODE   S=_TEXT          G=(none)  M=IOERROR    ACBP=28
+ 0000:1501 0011 C=CODE   S=_TEXT          G=(none)  M=ISATTY     ACBP=28
+ 0000:1512 009A C=CODE   S=_TEXT          G=(none)  M=LONGTOA    ACBP=28
+ 0000:15AC 0029 C=CODE   S=_TEXT          G=(none)  M=LSEEK      ACBP=28
+ 0000:15D5 0082 C=CODE   S=_TEXT          G=(none)  M=MKNAME     ACBP=28
+ 0000:1657 0021 C=CODE   S=_TEXT          G=(none)  M=N_PCMP     ACBP=28
+ 0000:1678 0032 C=CODE   S=_TEXT          G=(none)  M=OUTPORT    ACBP=28
+ 0000:16AA 002D C=CODE   S=_TEXT          G=(none)  M=READA      ACBP=28
+ 0000:16D7 01AA C=CODE   S=_TEXT          G=(none)  M=SCANTOL    ACBP=28
+ 0000:1881 00A5 C=CODE   S=_TEXT          G=(none)  M=SETUPIO    ACBP=28
+ 0000:1926 0000 C=CODE   S=_TEXT          G=(none)  M=SIGDATA    ACBP=28
+ 0000:1926 0000 C=CODE   S=_TEXT          G=(none)  M=STKLEN     ACBP=28
+ 0000:1926 0018 C=CODE   S=_TEXT          G=(none)  M=TELL       ACBP=28
+ 0000:193E 002C C=CODE   S=_TEXT          G=(none)  M=TOLOWER    ACBP=28
+ 0000:196A 002C C=CODE   S=_TEXT          G=(none)  M=TOUPPER    ACBP=28
+ 0000:1996 0016 C=CODE   S=_TEXT          G=(none)  M=UNLINK     ACBP=28
+ 0000:19AC 04C6 C=CODE   S=_TEXT          G=(none)  M=VPRINTER   ACBP=28
+ 0000:1E72 009F C=CODE   S=_TEXT          G=(none)  M=VRAM       ACBP=28
+ 0000:1F11 001A C=CODE   S=_TEXT          G=(none)  M=XCLOSE     ACBP=28
+ 0000:1F2B 0029 C=CODE   S=_TEXT          G=(none)  M=_STPCPY    ACBP=28
+ 0000:1F54 0025 C=CODE   S=_TEXT          G=(none)  M=BIOSKEY    ACBP=28
+ 0000:1F79 006F C=CODE   S=_TEXT          G=(none)  M=BRK        ACBP=28
+ 0000:1FE8 0029 C=CODE   S=_TEXT          G=(none)  M=CLRSCR     ACBP=28
+ 0000:2011 0010 C=CODE   S=_TEXT          G=(none)  M=CORELEFT   ACBP=28
+ 0000:2021 01B3 C=CODE   S=_TEXT          G=(none)  M=CRTINIT    ACBP=28
+ 0000:21D4 001F C=CODE   S=_TEXT          G=(none)  M=CVTFAK     ACBP=28
+ 0000:21F3 0421 C=CODE   S=_TEXT          G=(none)  M=FARHEAP    ACBP=28
+ 0000:2614 0143 C=CODE   S=_TEXT          G=(none)  M=FBRK       ACBP=28
+ 0000:2757 0050 C=CODE   S=_TEXT          G=(none)  M=FCORELFT   ACBP=28
+ 0000:27A7 0049 C=CODE   S=_TEXT          G=(none)  M=GOTOXY     ACBP=28
+ 0000:27F0 0095 C=CODE   S=_TEXT          G=(none)  M=GPTEXT     ACBP=28
+ 0000:2885 002E C=CODE   S=_TEXT          G=(none)  M=HARD       ACBP=28
+ 0000:28B3 0126 C=CODE   S=_TEXT          G=(none)  M=HARDERR    ACBP=28
+ 0000:29D9 0027 C=CODE   S=_TEXT          G=(none)  M=IOCTL      ACBP=28
+ 0000:2A00 009D C=CODE   S=_TEXT          G=(none)  M=MOVETEXT   ACBP=28
+ 0000:2A9D 027B C=CODE   S=_TEXT          G=(none)  M=NEARHEAP   ACBP=28
+ 0000:2D18 0004 C=CODE   S=_TEXT          G=(none)  M=REALCVT    ACBP=28
+ 0000:2D1C 01AB C=CODE   S=_TEXT          G=(none)  M=SCREEN     ACBP=28
+ 0000:2EC7 0188 C=CODE   S=_TEXT          G=(none)  M=SCROLL     ACBP=28
+ 0000:304F 0115 C=CODE   S=_TEXT          G=(none)  M=SETARGV    ACBP=28
+ 0000:3164 001C C=CODE   S=_TEXT          G=(none)  M=SETBLOCK   ACBP=28
+ 0000:3180 005D C=CODE   S=_TEXT          G=(none)  M=SETENVP    ACBP=28
+ 0000:31DD 002C C=CODE   S=_TEXT          G=(none)  M=WHEREXY    ACBP=28
+ 0000:3209 007D C=CODE   S=_TEXT          G=(none)  M=ATOL       ACBP=28
+ 0000:3286 0010 C=CODE   S=_TEXT          G=(none)  M=BDOS       ACBP=28
+ 0000:3296 001B C=CODE   S=_TEXT          G=(none)  M=CHMODA     ACBP=28
+ 0000:32B1 0028 C=CODE   S=_TEXT          G=(none)  M=CLOSE      ACBP=28
+ 0000:32D9 001E C=CODE   S=_TEXT          G=(none)  M=CLOSEA     ACBP=28
+ 0000:32F7 008B C=CODE   S=_TEXT          G=(none)  M=CREAT      ACBP=28
+ 0000:3382 007D C=CODE   S=_TEXT          G=(none)  M=FCLOSE     ACBP=28
+ 0000:33FF 0081 C=CODE   S=_TEXT          G=(none)  M=FFLUSH     ACBP=28
+ 0000:3480 0060 C=CODE   S=_TEXT          G=(none)  M=FINDFIRS   ACBP=28
+ 0000:34E0 0041 C=CODE   S=_TEXT          G=(none)  M=FLENGTH    ACBP=28
+ 0000:3521 003A C=CODE   S=_TEXT          G=(none)  M=FLUSHALL   ACBP=28
+ 0000:355B 01A0 C=CODE   S=_TEXT          G=(none)  M=FOPEN      ACBP=28
+ 0000:36FB 0016 C=CODE   S=_TEXT          G=(none)  M=FPRINTF    ACBP=28
+ 0000:3711 0112 C=CODE   S=_TEXT          G=(none)  M=FSEEK      ACBP=28
+ 0000:3823 005F C=CODE   S=_TEXT          G=(none)  M=GETENV     ACBP=28
+ 0000:3882 0067 C=CODE   S=_TEXT          G=(none)  M=LTOA1      ACBP=28
+ 0000:38E9 001F C=CODE   S=_TEXT          G=(none)  M=MEMCPY     ACBP=28
+ 0000:3908 0022 C=CODE   S=_TEXT          G=(none)  M=MOVEDATA   ACBP=28
+ 0000:392A 0183 C=CODE   S=_TEXT          G=(none)  M=OPEN       ACBP=28
+ 0000:3AAD 004D C=CODE   S=_TEXT          G=(none)  M=OPENA      ACBP=28
+ 0000:3AFA 0017 C=CODE   S=_TEXT          G=(none)  M=PRINTF     ACBP=28
+ 0000:3B11 0302 C=CODE   S=_TEXT          G=(none)  M=PUTC       ACBP=28
+ 0000:3E13 004B C=CODE   S=_TEXT          G=(none)  M=PUTS       ACBP=28
+ 0000:3E5E 00CE C=CODE   S=_TEXT          G=(none)  M=READ       ACBP=28
+ 0000:3F2C 0003 C=CODE   S=_TEXT          G=(none)  M=READU      ACBP=28
+ 0000:3F2F 00D6 C=CODE   S=_TEXT          G=(none)  M=SETVBUF    ACBP=28
+ 0000:4005 0061 C=CODE   S=_TEXT          G=(none)  M=SPRINTF    ACBP=28
+ 0000:4066 0039 C=CODE   S=_TEXT          G=(none)  M=STRCAT     ACBP=28
+ 0000:409F 0022 C=CODE   S=_TEXT          G=(none)  M=STRCPY     ACBP=28
+ 0000:40C1 001A C=CODE   S=_TEXT          G=(none)  M=STRLEN     ACBP=28
+ 0000:40DB 00FF C=CODE   S=_TEXT          G=(none)  M=STRTOL     ACBP=28
+ 0000:41DA 010C C=CODE   S=_TEXT          G=(none)  M=WRITE      ACBP=28
+ 0000:42E6 003A C=CODE   S=_TEXT          G=(none)  M=WRITEA     ACBP=28
+ 0000:4320 0003 C=CODE   S=_TEXT          G=(none)  M=WRITEU     ACBP=28
+ 0000:4323 0028 C=CODE   S=_TEXT          G=(none)  M=XFCLOSE    ACBP=28
+ 0000:434B 0023 C=CODE   S=_TEXT          G=(none)  M=XFFLUSH    ACBP=28
+ 0000:436E 0028 C=CODE   S=_TEXT          G=(none)  M=FMEMCMP    ACBP=28
+ 0000:4396 0024 C=CODE   S=_TEXT          G=(none)  M=FMEMCPY    ACBP=28
+ 0000:43BA 0043 C=CODE   S=_TEXT          G=(none)  M=FMEMSET    ACBP=28
+ 0000:43FD 0029 C=CODE   S=_TEXT          G=(none)  M=FSTRCPY    ACBP=28
+ 0000:4426 0041 C=CODE   S=_TEXT          G=(none)  M=FSTRICMP   ACBP=28
+ 0000:4467 001F C=CODE   S=_TEXT          G=(none)  M=FSTRLEN    ACBP=28
+ 0000:4486 0036 C=CODE   S=_TEXT          G=(none)  M=DOSDFREE   ACBP=28
+ 044B:000C 0000 C=CODE   S=H_LDIV_TEXT    G=(none)  M=H_LDIV.ASM ACBP=48
+ 044B:000C 039A C=CODE   S=WOLFHACK_TEXT  G=(none)  M=WOLFHACK.C ACBP=28
+ 0485:0008 0065 C=CODE   S=WHACK_A_TEXT   G=(none)  M=WHACK_A.ASM ACBP=A8
+ 048C:0000 003B C=CODE   S=WL_ASM_TEXT    G=(none)  M=WL_ASM.ASM ACBP=A8
+ 048F:000B 17B1 C=CODE   S=WL_MAIN_TEXT   G=(none)  M=WL_MAIN.C  ACBP=28
+ 060A:000C 09A8 C=CODE   S=WL_TEXT_TEXT   G=(none)  M=WL_TEXT.C  ACBP=28
+ 06A5:0004 3E00 C=CODE   S=WL_MENU_TEXT   G=(none)  M=WL_MENU.C  ACBP=28
+ 0A85:0004 1412 C=CODE   S=WL_INTER_TEXT  G=(none)  M=WL_INTER.C ACBP=28
+ 0BC6:0006 1361 C=CODE   S=WL_GAME_TEXT   G=(none)  M=WL_GAME.C  ACBP=28
+ 0CFC:0007 1116 C=CODE   S=WL_PLAY_TEXT   G=(none)  M=WL_PLAY.C  ACBP=28
+ 0E0D:000D 0AF2 C=CODE   S=WL_DEBUG_TEXT  G=(none)  M=WL_DEBUG.C ACBP=28
+ 0EBC:000F 0FB7 C=CODE   S=WL_DRAW_TEXT   G=(none)  M=WL_DRAW.C  ACBP=28
+ 0FB8:0006 0454 C=CODE   S=WL_DR_A_TEXT   G=(none)  M=WL_DR_A.ASM ACBP=48
+ 0FFD:000A 08A2 C=CODE   S=WL_SCALE_TEXT  G=(none)  M=WL_SCALE.C ACBP=28
+ 1087:000C 1799 C=CODE   S=WL_STATE_TEXT  G=(none)  M=WL_STATE.C ACBP=28
+ 1201:0005 11FA C=CODE   S=WL_AGENT_TEXT  G=(none)  M=WL_AGENT.C ACBP=28
+ 1320:000F 0CBD C=CODE   S=WL_ACT1_TEXT   G=(none)  M=WL_ACT1.C  ACBP=28
+ 13EC:000C 222C C=CODE   S=WL_ACT2_TEXT   G=(none)  M=WL_ACT2.C  ACBP=28
+ 160F:0008 16B9 C=CODE   S=ID_CA_TEXT     G=(none)  M=ID_CA.C    ACBP=28
+ 177B:0001 0B2F C=CODE   S=ID_IN_TEXT     G=(none)  M=ID_IN.C    ACBP=28
+ 182E:0000 0E47 C=CODE   S=ID_MM_TEXT     G=(none)  M=ID_MM.C    ACBP=28
+ 1912:0007 1160 C=CODE   S=ID_PM_TEXT     G=(none)  M=ID_PM.C    ACBP=28
+ 1A28:0007 188F C=CODE   S=ID_SD_TEXT     G=(none)  M=ID_SD.C    ACBP=28
+ 1BB1:0006 03F2 C=CODE   S=ID_SD_A_TEXT   G=(none)  M=ID_SD_A.ASM ACBP=48
+ 1BF0:0008 0BA6 C=CODE   S=ID_US_1_TEXT   G=(none)  M=ID_US_1.C  ACBP=28
+ 1CAA:000E 0045 C=CODE   S=ID_US_A_TEXT   G=(none)  M=ID_US_A.ASM ACBP=48
+ 1CAF:0003 0B2D C=CODE   S=ID_VL_TEXT     G=(none)  M=ID_VL.C    ACBP=28
+ 1D62:0000 08E2 C=CODE   S=ID_VH_TEXT     G=(none)  M=ID_VH.C    ACBP=28
+ 1DF0:0002 0294 C=CODE   S=ID_VL_A_TEXT   G=(none)  M=ID_VL_A.ASM ACBP=48
+ 1E19:0006 01F6 C=CODE   S=ID_VH_A_TEXT   G=(none)  M=ID_VH_A.ASM ACBP=48
+ 1E39:0000 0000 C=CODE   S=EMU_PROG       G=(none)  M=FPINIT     ACBP=68
+ 1E39:0000 2777 C=CODE   S=EMU_PROG       G=(none)  M=EMU086     ACBP=68
+ 20B1:0000 0000 C=CODE   S=E87_PROG       G=(none)  M=FPINIT     ACBP=68
+ 20B1:0000 03E3 C=CODE   S=E87_PROG       G=(none)  M=EMU087     ACBP=68
+ 20B1:03F0 01D8 C=CODE   S=E87_PROG       G=(none)  M=E87TRAP    ACBP=68
+ 210E:0000 0000 C=FAR_DATA S=_FARDATA       G=(none)  M=C0.ASM     ACBP=68
+ 210E:0000 2000 C=FAR_DATA S=FAR_DATA       G=(none)  M=WHACK_A.ASM ACBP=60
+ 230E:0000 0102 C=FAR_DATA S=FAR_DATA       G=(none)  M=ID_US_A.ASM ACBP=60
+ 231F:0000 02F4 C=FAR_DATA S=WL_MAIN5_DATA  G=(none)  M=WL_MAIN.C  ACBP=68
+ 234F:0000 02D0 C=FAR_DATA S=WL_MENU5_DATA  G=(none)  M=WL_MENU.C  ACBP=68
+ 237C:0000 017A C=FAR_DATA S=WL_MENU6_DATA  G=(none)  M=WL_MENU.C  ACBP=68
+ 2394:0000 01F8 C=FAR_DATA S=WL_MENU7_DATA  G=(none)  M=WL_MENU.C  ACBP=68
+ 23B4:0000 00FC C=FAR_DATA S=WL_MENU8_DATA  G=(none)  M=WL_MENU.C  ACBP=68
+ 23C4:0000 01CE C=FAR_DATA S=WL_MENU9_DATA  G=(none)  M=WL_MENU.C  ACBP=68
+ 23E1:0000 00A8 C=FAR_DATA S=WL_MENU10_DATA G=(none)  M=WL_MENU.C  ACBP=68
+ 23EC:0000 01A4 C=FAR_DATA S=WL_MENU11_DATA G=(none)  M=WL_MENU.C  ACBP=68
+ 2407:0000 017A C=FAR_DATA S=WL_MENU12_DATA G=(none)  M=WL_MENU.C  ACBP=68
+ 241F:0000 0024 C=FAR_DATA S=WL_MENU13_DATA G=(none)  M=WL_MENU.C  ACBP=68
+ 2422:0000 FA00 C=FAR_DATA S=SignonSeg      G=(none)  M=SIGNON.BIN   ACBP=60
+ 33C2:0000 0080 C=FAR_DATA S=ID_IN5_DATA    G=(none)  M=ID_IN.C    ACBP=68
+ 33CA:0000 0080 C=FAR_DATA S=ID_IN6_DATA    G=(none)  M=ID_IN.C    ACBP=68
+ 33D2:0000 0080 C=FAR_DATA S=ID_IN7_DATA    G=(none)  M=ID_IN.C    ACBP=68
+ 33DA:0000 0000 C=FAR_BSS S=_FARBSS        G=(none)  M=C0.ASM     ACBP=68
+ 33DA:0000 0559 C=FAR_BSS S=_COMDEF_AA_    G=(none)  M=WL_ACT1.C  ACBP=60
+ 3430:0000 0708 C=FAR_BSS S=_COMDEF_AB_    G=(none)  M=WL_DRAW.C  ACBP=60
+ 34A1:0000 0E10 C=FAR_BSS S=_COMDEF_AC_    G=(none)  M=WL_DRAW.C  ACBP=60
+ 3582:0000 0095 C=FAR_BSS S=_COMDEF_AD_    G=(none)  M=ID_CA.C    ACBP=60
+ 358C:0000 1200 C=FAR_BSS S=_COMDEF_AE_    G=(none)  M=WL_PLAY.C  ACBP=60
+ 36AC:0000 1200 C=FAR_BSS S=_COMDEF_AF_    G=(none)  M=WL_PLAY.C  ACBP=60
+ 37CC:0000 20D0 C=FAR_BSS S=_COMDEF_AG_    G=(none)  M=ID_MM.C    ACBP=60
+ 39D9:0000 0300 C=FAR_BSS S=_COMDEF_AH_    G=(none)  M=ID_VL.C    ACBP=60
+ 3A09:0000 0300 C=FAR_BSS S=_COMDEF_AI_    G=(none)  M=ID_VL.C    ACBP=60
+ 3A39:0000 0000 C=OVRINFO S=_OVERLAY_      G=(none)  M=C0.ASM     ACBP=68
+ 3A39:0000 0000 C=STUBSEG S=_1STUB_        G=(none)  M=C0.ASM     ACBP=68
+ 3A39:0000 00D9 C=DATA   S=_DATA          G=DGROUP  M=C0.ASM     ACBP=68
+ 3A39:00DA 0000 C=DATA   S=_DATA          G=DGROUP  M=H_LDIV.ASM ACBP=48
+ 3A39:00DA 0002 C=DATA   S=_DATA          G=DGROUP  M=WOLFHACK.C ACBP=48
+ 3A39:00DC 0000 C=DATA   S=_DATA          G=DGROUP  M=WHACK_A.ASM ACBP=A8
+ 3A39:00DC 0000 C=DATA   S=_DATA          G=DGROUP  M=WL_ASM.ASM ACBP=A8
+ 3A39:00DC 0254 C=DATA   S=_DATA          G=DGROUP  M=WL_MAIN.C  ACBP=48
+ 3A39:0330 00A1 C=DATA   S=_DATA          G=DGROUP  M=WL_TEXT.C  ACBP=48
+ 3A39:03D2 06B4 C=DATA   S=_DATA          G=DGROUP  M=WL_MENU.C  ACBP=48
+ 3A39:0A86 03ED C=DATA   S=_DATA          G=DGROUP  M=WL_INTER.C ACBP=48
+ 3A39:0E74 03FC C=DATA   S=_DATA          G=DGROUP  M=WL_GAME.C  ACBP=48
+ 3A39:1270 0216 C=DATA   S=_DATA          G=DGROUP  M=WL_PLAY.C  ACBP=48
+ 3A39:1486 01FE C=DATA   S=_DATA          G=DGROUP  M=WL_DEBUG.C ACBP=48
+ 3A39:1684 0096 C=DATA   S=_DATA          G=DGROUP  M=WL_DRAW.C  ACBP=48
+ 3A39:171A 0000 C=DATA   S=_DATA          G=DGROUP  M=WL_DR_A.ASM ACBP=48
+ 3A39:171A 00F1 C=DATA   S=_DATA          G=DGROUP  M=WL_SCALE.C ACBP=48
+ 3A39:180C 00FF C=DATA   S=_DATA          G=DGROUP  M=WL_STATE.C ACBP=48
+ 3A39:190C 0112 C=DATA   S=_DATA          G=DGROUP  M=WL_AGENT.C ACBP=48
+ 3A39:1A1E 0119 C=DATA   S=_DATA          G=DGROUP  M=WL_ACT1.C  ACBP=48
+ 3A39:1B38 1412 C=DATA   S=_DATA          G=DGROUP  M=WL_ACT2.C  ACBP=48
+ 3A39:2F4A 0300 C=DATA   S=_DATA          G=DGROUP  M=GAMEPAL.BIN  ACBP=48
+ 3A39:324A 0109 C=DATA   S=_DATA          G=DGROUP  M=ID_CA.C    ACBP=48
+ 3A39:3354 005F C=DATA   S=_DATA          G=DGROUP  M=ID_IN.C    ACBP=48
+ 3A39:33B4 015B C=DATA   S=_DATA          G=DGROUP  M=ID_MM.C    ACBP=48
+ 3A39:3510 0490 C=DATA   S=_DATA          G=DGROUP  M=ID_PM.C    ACBP=48
+ 3A39:39A0 0265 C=DATA   S=_DATA          G=DGROUP  M=ID_SD.C    ACBP=48
+ 3A39:3C06 0104 C=DATA   S=_DATA          G=DGROUP  M=ID_SD_A.ASM ACBP=48
+ 3A39:3D0A 02B9 C=DATA   S=_DATA          G=DGROUP  M=ID_US_1.C  ACBP=48
+ 3A39:3FC4 0000 C=DATA   S=_DATA          G=DGROUP  M=ID_US_A.ASM ACBP=48
+ 3A39:3FC4 0097 C=DATA   S=_DATA          G=DGROUP  M=ID_VL.C    ACBP=48
+ 3A39:405C 0029 C=DATA   S=_DATA          G=DGROUP  M=ID_VH.C    ACBP=48
+ 3A39:4086 0002 C=DATA   S=_DATA          G=DGROUP  M=ID_VL_A.ASM ACBP=48
+ 3A39:4088 0000 C=DATA   S=_DATA          G=DGROUP  M=ID_VH_A.ASM ACBP=48
+ 3A39:4090 0002 C=DATA   S=_DATA          G=DGROUP  M=FPINIT     ACBP=68
+ 3A39:40A0 0000 C=DATA   S=_DATA          G=DGROUP  M=E87TRAP    ACBP=68
+ 3A39:40A0 0003 C=DATA   S=_DATA          G=DGROUP  M=PROTFLAG   ACBP=48
+ 3A39:40A4 0002 C=DATA   S=_DATA          G=DGROUP  M=DEFLT87    ACBP=48
+ 3A39:40A6 0000 C=DATA   S=_DATA          G=DGROUP  M=ATAN       ACBP=48
+ 3A39:40A6 0024 C=DATA   S=_DATA          G=DGROUP  M=HUGEVAL    ACBP=48
+ 3A39:40CA 0000 C=DATA   S=_DATA          G=DGROUP  M=LDTRUNC    ACBP=48
+ 3A39:40CA 0037 C=DATA   S=_DATA          G=DGROUP  M=MATHWHY    ACBP=48
+ 3A39:4102 0000 C=DATA   S=_DATA          G=DGROUP  M=REALCVT    ACBP=48
+ 3A39:4102 0018 C=DATA   S=_DATA          G=DGROUP  M=SCANTOD    ACBP=48
+ 3A39:411A 0000 C=DATA   S=_DATA          G=DGROUP  M=XCVT       ACBP=48
+ 3A39:411A 008C C=DATA   S=_DATA          G=DGROUP  M=FPERR      ACBP=48
+ 3A39:41A6 0080 C=DATA   S=_DATA          G=DGROUP  M=_POW10     ACBP=48
+ 3A39:4226 0000 C=DATA   S=_DATA          G=DGROUP  M=POW10D     ACBP=48
+ 3A39:4226 0000 C=DATA   S=_DATA          G=DGROUP  M=MATHERR    ACBP=48
+ 3A39:4226 000C C=DATA   S=_DATA          G=DGROUP  M=SIN        ACBP=48
+ 3A39:4232 000C C=DATA   S=_DATA          G=DGROUP  M=TAN        ACBP=48
+ 3A39:423E 000E C=DATA   S=_DATA          G=DGROUP  M=_MATHERR   ACBP=48
+ 3A39:424C 0018 C=DATA   S=_DATA          G=DGROUP  M=ATAN2      ACBP=48
+ 3A39:4270 0110 C=DATA   S=_DATA          G=DGROUP  M=EMUVARS    ACBP=68
+ 3A39:4380 0000 C=DATA   S=_DATA          G=DGROUP  M=FFTOL      ACBP=48
+ 3A39:4380 0002 C=DATA   S=_DATA          G=DGROUP  M=ATEXIT     ACBP=48
+ 3A39:4382 0101 C=DATA   S=_DATA          G=DGROUP  M=CTYPE      ACBP=48
+ 3A39:4484 0000 C=DATA   S=_DATA          G=DGROUP  M=DOSFATTR   ACBP=48
+ 3A39:4484 0000 C=DATA   S=_DATA          G=DGROUP  M=DOSGDATE   ACBP=48
+ 3A39:4484 0000 C=DATA   S=_DATA          G=DGROUP  M=DOSWRITE   ACBP=48
+ 3A39:4484 000C C=DATA   S=_DATA          G=DGROUP  M=EXIT       ACBP=48
+ 3A39:4490 0140 C=DATA   S=_DATA          G=DGROUP  M=FILES      ACBP=48
+ 3A39:45D0 002A C=DATA   S=_DATA          G=DGROUP  M=FILES2     ACBP=48
+ 3A39:45FA 0004 C=DATA   S=_DATA          G=DGROUP  M=FMODE      ACBP=48
+ 3A39:45FE 0002 C=DATA   S=_DATA          G=DGROUP  M=FPSTKLEN   ACBP=48
+ 3A39:4600 0000 C=DATA   S=_DATA          G=DGROUP  M=F_LXMUL    ACBP=48
+ 3A39:4600 0000 C=DATA   S=_DATA          G=DGROUP  M=F_PCMP     ACBP=48
+ 3A39:4600 0000 C=DATA   S=_DATA          G=DGROUP  M=F_SCOPY    ACBP=48
+ 3A39:4600 0000 C=DATA   S=_DATA          G=DGROUP  M=GETVECT    ACBP=48
+ 3A39:4600 0002 C=DATA   S=_DATA          G=DGROUP  M=HEAPLEN    ACBP=48
+ 3A39:4602 0000 C=DATA   S=_DATA          G=DGROUP  M=H_LLSH     ACBP=48
+ 3A39:4602 0000 C=DATA   S=_DATA          G=DGROUP  M=H_LRSH     ACBP=48
+ 3A39:4602 0000 C=DATA   S=_DATA          G=DGROUP  M=H_LURSH    ACBP=48
+ 3A39:4602 0000 C=DATA   S=_DATA          G=DGROUP  M=H_PADA     ACBP=48
+ 3A39:4602 0000 C=DATA   S=_DATA          G=DGROUP  M=H_PADD     ACBP=48
+ 3A39:4602 0000 C=DATA   S=_DATA          G=DGROUP  M=H_PSBP     ACBP=48
+ 3A39:4602 0000 C=DATA   S=_DATA          G=DGROUP  M=H_SPUSH    ACBP=48
+ 3A39:4602 005B C=DATA   S=_DATA          G=DGROUP  M=IOERROR    ACBP=48
+ 3A39:465E 0000 C=DATA   S=_DATA          G=DGROUP  M=ISATTY     ACBP=48
+ 3A39:465E 0000 C=DATA   S=_DATA          G=DGROUP  M=LONGTOA    ACBP=48
+ 3A39:465E 0000 C=DATA   S=_DATA          G=DGROUP  M=LSEEK      ACBP=48
+ 3A39:465E 0009 C=DATA   S=_DATA          G=DGROUP  M=MKNAME     ACBP=48
+ 3A39:4668 0000 C=DATA   S=_DATA          G=DGROUP  M=N_PCMP     ACBP=48
+ 3A39:4668 0000 C=DATA   S=_DATA          G=DGROUP  M=OUTPORT    ACBP=48
+ 3A39:4668 0000 C=DATA   S=_DATA          G=DGROUP  M=READA      ACBP=48
+ 3A39:4668 0000 C=DATA   S=_DATA          G=DGROUP  M=SCANTOL    ACBP=48
+ 3A39:4668 0000 C=DATA   S=_DATA          G=DGROUP  M=SETUPIO    ACBP=48
+ 3A39:4668 0000 C=DATA   S=_DATA          G=DGROUP  M=SIGDATA    ACBP=48
+ 3A39:4668 0002 C=DATA   S=_DATA          G=DGROUP  M=STKLEN     ACBP=48
+ 3A39:466A 0000 C=DATA   S=_DATA          G=DGROUP  M=TELL       ACBP=48
+ 3A39:466A 0000 C=DATA   S=_DATA          G=DGROUP  M=TOLOWER    ACBP=48
+ 3A39:466A 0000 C=DATA   S=_DATA          G=DGROUP  M=TOUPPER    ACBP=48
+ 3A39:466A 0000 C=DATA   S=_DATA          G=DGROUP  M=UNLINK     ACBP=48
+ 3A39:466A 0067 C=DATA   S=_DATA          G=DGROUP  M=VPRINTER   ACBP=48
+ 3A39:46D2 0000 C=DATA   S=_DATA          G=DGROUP  M=VRAM       ACBP=48
+ 3A39:46D2 0000 C=DATA   S=_DATA          G=DGROUP  M=XCLOSE     ACBP=48
+ 3A39:46D2 0000 C=DATA   S=_DATA          G=DGROUP  M=_STPCPY    ACBP=48
+ 3A39:46D2 0000 C=DATA   S=_DATA          G=DGROUP  M=BIOSKEY    ACBP=48
+ 3A39:46D2 0000 C=DATA   S=_DATA          G=DGROUP  M=BRK        ACBP=48
+ 3A39:46D2 0000 C=DATA   S=_DATA          G=DGROUP  M=CLRSCR     ACBP=48
+ 3A39:46D2 0000 C=DATA   S=_DATA          G=DGROUP  M=CORELEFT   ACBP=48
+ 3A39:46D2 0018 C=DATA   S=_DATA          G=DGROUP  M=CRTINIT    ACBP=48
+ 3A39:46EA 0031 C=DATA   S=_DATA          G=DGROUP  M=CVTFAK     ACBP=48
+ 3A39:471C 0000 C=DATA   S=_DATA          G=DGROUP  M=FARHEAP    ACBP=48
+ 3A39:471C 0002 C=DATA   S=_DATA          G=DGROUP  M=FBRK       ACBP=48
+ 3A39:471E 0000 C=DATA   S=_DATA          G=DGROUP  M=FCORELFT   ACBP=48
+ 3A39:471E 0000 C=DATA   S=_DATA          G=DGROUP  M=GOTOXY     ACBP=48
+ 3A39:471E 0000 C=DATA   S=_DATA          G=DGROUP  M=GPTEXT     ACBP=48
+ 3A39:471E 0000 C=DATA   S=_DATA          G=DGROUP  M=HARD       ACBP=48
+ 3A39:471E 0000 C=DATA   S=_DATA          G=DGROUP  M=HARDERR    ACBP=48
+ 3A39:471E 0000 C=DATA   S=_DATA          G=DGROUP  M=IOCTL      ACBP=48
+ 3A39:471E 0000 C=DATA   S=_DATA          G=DGROUP  M=MOVETEXT   ACBP=48
+ 3A39:471E 0006 C=DATA   S=_DATA          G=DGROUP  M=NEARHEAP   ACBP=48
+ 3A39:4724 0000 C=DATA   S=_DATA          G=DGROUP  M=REALCVT    ACBP=48
+ 3A39:4724 0000 C=DATA   S=_DATA          G=DGROUP  M=SCREEN     ACBP=48
+ 3A39:4724 0000 C=DATA   S=_DATA          G=DGROUP  M=SCROLL     ACBP=48
+ 3A39:4724 000E C=DATA   S=_DATA          G=DGROUP  M=SETARGV    ACBP=48
+ 3A39:4732 0000 C=DATA   S=_DATA          G=DGROUP  M=SETBLOCK   ACBP=48
+ 3A39:4732 0002 C=DATA   S=_DATA          G=DGROUP  M=SETENVP    ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=WHEREXY    ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=ATOL       ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=BDOS       ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=CHMODA     ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=CLOSE      ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=CLOSEA     ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=CREAT      ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=FCLOSE     ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=FFLUSH     ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=FINDFIRS   ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=FLENGTH    ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=FLUSHALL   ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=FOPEN      ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=FPRINTF    ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=FSEEK      ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=GETENV     ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=LTOA1      ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=MEMCPY     ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=MOVEDATA   ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=OPEN       ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=OPENA      ACBP=48
+ 3A39:4734 0000 C=DATA   S=_DATA          G=DGROUP  M=PRINTF     ACBP=48
+ 3A39:4734 0001 C=DATA   S=_DATA          G=DGROUP  M=PUTC       ACBP=48
+ 3A39:4736 0000 C=DATA   S=_DATA          G=DGROUP  M=PUTS       ACBP=48
+ 3A39:4736 0000 C=DATA   S=_DATA          G=DGROUP  M=READ       ACBP=48
+ 3A39:4736 0000 C=DATA   S=_DATA          G=DGROUP  M=READU      ACBP=48
+ 3A39:4736 0004 C=DATA   S=_DATA          G=DGROUP  M=SETVBUF    ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=SPRINTF    ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=STRCAT     ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=STRCPY     ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=STRLEN     ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=STRTOL     ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=WRITE      ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=WRITEA     ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=WRITEU     ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=XFCLOSE    ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=XFFLUSH    ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=FMEMCMP    ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=FMEMCPY    ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=FMEMSET    ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=FSTRCPY    ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=FSTRICMP   ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=FSTRLEN    ACBP=48
+ 3A39:473A 0000 C=DATA   S=_DATA          G=DGROUP  M=DOSDFREE   ACBP=48
+ 3A39:473A 0000 C=DATA   S=_CVTSEG        G=DGROUP  M=C0.ASM     ACBP=48
+ 3A39:473A 0002 C=DATA   S=_CVTSEG        G=DGROUP  M=REALCVT    ACBP=48
+ 3A39:473C 0002 C=DATA   S=_CVTSEG        G=DGROUP  M=CVTFAK     ACBP=48
+ 3A39:473E 0000 C=DATA   S=_CVTSEG        G=DGROUP  M=REALCVT    ACBP=48
+ 3A39:473E 0000 C=DATA   S=_SCNSEG        G=DGROUP  M=C0.ASM     ACBP=48
+ 3A39:473E 0006 C=DATA   S=_SCNSEG        G=DGROUP  M=SCANTOD    ACBP=48
+ 3A39:4744 0006 C=DATA   S=_SCNSEG        G=DGROUP  M=CVTFAK     ACBP=48
+ 3A39:474A 0000 C=CONST  S=_CONST         G=DGROUP  M=C0.ASM     ACBP=48
+ 3A39:474A 0000 C=INITDATA S=_INIT_         G=DGROUP  M=C0.ASM     ACBP=48
+ 3A39:474A 0006 C=INITDATA S=_INIT_         G=DGROUP  M=FPINIT     ACBP=48
+ 3A39:4750 0006 C=INITDATA S=_INIT_         G=DGROUP  M=SETUPIO    ACBP=48
+ 3A39:4756 0006 C=INITDATA S=_INIT_         G=DGROUP  M=CRTINIT    ACBP=48
+ 3A39:475C 0006 C=INITDATA S=_INIT_         G=DGROUP  M=SETARGV    ACBP=48
+ 3A39:4762 0006 C=INITDATA S=_INIT_         G=DGROUP  M=SETENVP    ACBP=48
+ 3A39:4768 0000 C=INITDATA S=_INITEND_      G=DGROUP  M=C0.ASM     ACBP=28
+ 3A39:4768 0000 C=EXITDATA S=_EXIT_         G=DGROUP  M=C0.ASM     ACBP=48
+ 3A39:4768 0006 C=EXITDATA S=_EXIT_         G=DGROUP  M=FPINIT     ACBP=48
+ 3A39:476E 0000 C=EXITDATA S=_EXITEND_      G=DGROUP  M=C0.ASM     ACBP=28
+ 3A39:476E 0000 C=BSS    S=_BSS           G=DGROUP  M=C0.ASM     ACBP=48
+ 3A39:476E 0000 C=BSS    S=_BSS           G=DGROUP  M=WOLFHACK.C ACBP=48
+ 3A39:476E 0002 C=BSS    S=_BSS           G=DGROUP  M=WL_MAIN.C  ACBP=48
+ 3A39:4770 0000 C=BSS    S=_BSS           G=DGROUP  M=WL_TEXT.C  ACBP=48
+ 3A39:4770 0002 C=BSS    S=_BSS           G=DGROUP  M=WL_MENU.C  ACBP=48
+ 3A39:4772 0000 C=BSS    S=_BSS           G=DGROUP  M=WL_INTER.C ACBP=48
+ 3A39:4772 0000 C=BSS    S=_BSS           G=DGROUP  M=WL_GAME.C  ACBP=48
+ 3A39:4772 0000 C=BSS    S=_BSS           G=DGROUP  M=WL_PLAY.C  ACBP=48
+ 3A39:4772 000A C=BSS    S=_BSS           G=DGROUP  M=WL_DEBUG.C ACBP=48
+ 3A39:477C 0000 C=BSS    S=_BSS           G=DGROUP  M=WL_DRAW.C  ACBP=48
+ 3A39:477C 0004 C=BSS    S=_BSS           G=DGROUP  M=WL_SCALE.C ACBP=48
+ 3A39:4780 0000 C=BSS    S=_BSS           G=DGROUP  M=WL_STATE.C ACBP=48
+ 3A39:4780 0000 C=BSS    S=_BSS           G=DGROUP  M=WL_AGENT.C ACBP=48
+ 3A39:4780 0000 C=BSS    S=_BSS           G=DGROUP  M=WL_ACT1.C  ACBP=48
+ 3A39:4780 0000 C=BSS    S=_BSS           G=DGROUP  M=WL_ACT2.C  ACBP=48
+ 3A39:4780 0000 C=BSS    S=_BSS           G=DGROUP  M=ID_CA.C    ACBP=48
+ 3A39:4780 0014 C=BSS    S=_BSS           G=DGROUP  M=ID_IN.C    ACBP=48
+ 3A39:4794 0000 C=BSS    S=_BSS           G=DGROUP  M=ID_MM.C    ACBP=48
+ 3A39:4794 0000 C=BSS    S=_BSS           G=DGROUP  M=ID_PM.C    ACBP=48
+ 3A39:4794 0180 C=BSS    S=_BSS           G=DGROUP  M=ID_SD.C    ACBP=48
+ 3A39:4914 0030 C=BSS    S=_BSS           G=DGROUP  M=ID_US_1.C  ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=ID_VL.C    ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=ID_VH.C    ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=ATAN       ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=LDTRUNC    ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=REALCVT    ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=SCANTOD    ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=XCVT       ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=_POW10     ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=SIN        ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=TAN        ACBP=48
+ 3A39:4944 0000 C=BSS    S=_BSS           G=DGROUP  M=ATAN2      ACBP=48
+ 3A39:4944 0080 C=BSS    S=_BSS           G=DGROUP  M=ATEXIT     ACBP=48
+ 3A39:49C4 0000 C=BSS    S=_BSS           G=DGROUP  M=DOSFATTR   ACBP=48
+ 3A39:49C4 0000 C=BSS    S=_BSS           G=DGROUP  M=DOSWRITE   ACBP=48
+ 3A39:49C4 0000 C=BSS    S=_BSS           G=DGROUP  M=GETVECT    ACBP=48
+ 3A39:49C4 0000 C=BSS    S=_BSS           G=DGROUP  M=IOERROR    ACBP=48
+ 3A39:49C4 0000 C=BSS    S=_BSS           G=DGROUP  M=ISATTY     ACBP=48
+ 3A39:49C4 0000 C=BSS    S=_BSS           G=DGROUP  M=LONGTOA    ACBP=48
+ 3A39:49C4 0000 C=BSS    S=_BSS           G=DGROUP  M=LSEEK      ACBP=48
+ 3A39:49C4 000D C=BSS    S=_BSS           G=DGROUP  M=MKNAME     ACBP=48
+ 3A39:49D2 0000 C=BSS    S=_BSS           G=DGROUP  M=OUTPORT    ACBP=48
+ 3A39:49D2 0000 C=BSS    S=_BSS           G=DGROUP  M=READA      ACBP=48
+ 3A39:49D2 0000 C=BSS    S=_BSS           G=DGROUP  M=SCANTOL    ACBP=48
+ 3A39:49D2 0000 C=BSS    S=_BSS           G=DGROUP  M=SETUPIO    ACBP=48
+ 3A39:49D2 0004 C=BSS    S=_BSS           G=DGROUP  M=SIGDATA    ACBP=48
+ 3A39:49D6 0000 C=BSS    S=_BSS           G=DGROUP  M=UNLINK     ACBP=48
+ 3A39:49D6 0000 C=BSS    S=_BSS           G=DGROUP  M=VPRINTER   ACBP=48
+ 3A39:49D6 0000 C=BSS    S=_BSS           G=DGROUP  M=VRAM       ACBP=48
+ 3A39:49D6 0000 C=BSS    S=_BSS           G=DGROUP  M=BIOSKEY    ACBP=48
+ 3A39:49D6 0000 C=BSS    S=_BSS           G=DGROUP  M=BRK        ACBP=48
+ 3A39:49D6 0000 C=BSS    S=_BSS           G=DGROUP  M=CORELEFT   ACBP=48
+ 3A39:49D6 0000 C=BSS    S=_BSS           G=DGROUP  M=CRTINIT    ACBP=48
+ 3A39:49D6 000C C=BSS    S=_BSS           G=DGROUP  M=HARDERR    ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=IOCTL      ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=SETBLOCK   ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=ATOL       ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=BDOS       ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=CHMODA     ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=CLOSEA     ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=CREAT      ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=FINDFIRS   ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=FLENGTH    ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=GETENV     ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=MEMCPY     ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=MOVEDATA   ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=OPEN       ACBP=48
+ 3A39:49E2 0000 C=BSS    S=_BSS           G=DGROUP  M=OPENA      ACBP=48
+ 3A39:49E2 0001 C=BSS    S=_BSS           G=DGROUP  M=PUTC       ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=READ       ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=STRCAT     ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=STRCPY     ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=STRLEN     ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=WRITEA     ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=FMEMCMP    ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=FMEMCPY    ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=FMEMSET    ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=FSTRCPY    ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=FSTRICMP   ACBP=48
+ 3A39:49E4 0000 C=BSS    S=_BSS           G=DGROUP  M=FSTRLEN    ACBP=48
+ 3A39:49E4 A5CB C=BSS    S=_COMDEF_       G=DGROUP  M=WOLFHACK.C ACBP=48
+ 3A39:EFAF 0000 C=BSSEND S=_BSSEND        G=DGROUP  M=C0.ASM     ACBP=28
+ 4934:0000 0080 C=STACK  S=_STACK         G=(none)  M=C0.ASM     ACBP=74
+
+  Address         Publics by Name
+
+ 3A39:0000 idle  DATASEG@
+ 0000:02AE idle  DGROUP@
+ 1E39:2152       e086_Entry
+ 1E39:26E0       e086_Shortcut
+ 20B1:0306       e087_Entry
+ 20B1:03C6       e087_Shortcut
+ 20B1:0430       e087_Trap
+ 0000:FE32 idle  FIARQQ
+ 0000:0E32 idle  FICRQQ
+ 0000:5C32  Abs  FIDRQQ
+ 0000:1632  Abs  FIERQQ
+ 0000:0632 idle  FISRQQ
+ 0000:A23D  Abs  FIWRQQ
+ 0000:4000 idle  FJARQQ
+ 0000:C000 idle  FJCRQQ
+ 0000:8000 idle  FJSRQQ
+ 0000:1130 idle  FTOL@
+ 0000:1130       F_FTOL@
+ 0000:02B5       F_LDIV@
+ 0000:02DC       F_LMOD@
+ 0000:02D4 idle  F_LUDIV@
+ 0000:02E4 idle  F_LUMOD@
+ 0000:1320       F_LXLSH@
+ 0000:12A9       F_LXMUL@
+ 0000:1341       F_LXRSH@
+ 0000:1361       F_LXURSH@
+ 0000:1382       F_PADA@
+ 0000:140A       F_PADD@
+ 0000:12C0       F_PCMP@
+ 0000:13C6       F_PSBA@
+ 0000:146A       F_PSBP@
+ 0000:1439 idle  F_PSUB@
+ 0000:12E1       F_SCOPY@
+ 0000:1495       F_SPUSH@
+ 0000:02B5       LDIV@
+ 0000:02DC idle  LMOD@
+ 0000:02D4 idle  LUDIV@
+ 0000:02E4 idle  LUMOD@
+ 0000:1320 idle  LXLSH@
+ 0000:12A9 idle  LXMUL@
+ 0000:1341 idle  LXRSH@
+ 0000:1361 idle  LXURSH@
+ 0000:02B2 idle  N_LDIV@
+ 0000:02D9 idle  N_LMOD@
+ 0000:02D1 idle  N_LUDIV@
+ 0000:02E1 idle  N_LUMOD@
+ 0000:131D       N_LXLSH@
+ 0000:133E idle  N_LXRSH@
+ 0000:135E idle  N_LXURSH@
+ 0000:137F idle  N_PADA@
+ 0000:1407       N_PADD@
+ 0000:1657       N_PCMP@
+ 0000:13C3 idle  N_PSBA@
+ 0000:1467       N_PSBP@
+ 0000:1436 idle  N_PSUB@
+ 0000:148F idle  N_SPUSH@
+ 0000:1382 idle  PADA@
+ 0000:140A idle  PADD@
+ 0000:12C0 idle  PCMP@
+ 0000:13C6 idle  PSBA@
+ 0000:146A idle  PSBP@
+ 0000:1439 idle  PSUB@
+ 0000:12E1 idle  SCOPY@
+ 0000:1495 idle  SPUSH@
+ 0000:0296       _abort
+ 3A39:EE11       _abortprogram
+ 3A39:55BA       _actorat
+ 3A39:9C43       _AdLibPresent
+ 3A39:3293 idle  _afilename
+ 3A39:E8B0       _aftersort
+ 3A39:3289 idle  _aheadname
+ 3A39:EAB2       _alBlock
+ 3A39:EAAE       _alLengthLeft
+ 3A39:EAB8       _alNoCheck
+ 1A28:0D03       _alOut
+ 3A39:EAB4       _alSound
+ 3A39:EAAA       _alTimeCount
+ 3A39:EA9A       _alZeroInst
+ 3A39:D9C6       _angle
+ 3A39:A4E2       _anglefrac
+ 3A39:52DC       _areabyplayer
+ 33DA:0000       _areaconnect
+ 0FB8:0072       _AsmRefresh
+ 0000:05E8       _atan
+ 0000:1075       _atan2
+ 0000:115C idle  _atexit
+ 0000:3279 idle  _atoi
+ 0000:3209       _atol
+ 3A39:192C idle  _attackinfo
+ 3A39:E01D       _audiohandle
+ 3A39:E023       _audiohuffman
+ 3A39:324A       _audioname
+ 3A39:A054       _audiosegs
+ 3A39:E81B       _audiostarts
+ 13EC:072D       _A_DeathScream
+ 13EC:1220 idle  _A_HitlerMorph
+ 13EC:12A8 idle  _A_MechaSound
+ 13EC:12D8 idle  _A_Slurpie
+ 13EC:000C idle  _A_Smoke
+ 13EC:1F4F idle  _A_StartDeathCam
+ 3A39:9956       _backcolor
+ 060A:0660 idle  _BackPage
+ 0FFD:000A idle  _BadScale
+ 3A39:4C52       _basedist
+ 0000:3286       _bdos
+ 3A39:E8B4       _beforesort
+ 0000:1F54       _bioskey
+ 0A85:056F idle  _BJ_Breathe
+ 3A39:9957       _blockstarts
+ 3A39:E896       _bombonerror
+ 3A39:A41C       _bonuscount
+ 3A39:EE15       _bordercolor
+ 06A5:025E idle  _BossKey
+ 0000:1FCC idle  _brk
+ 3A39:E828       _btnstate
+ 3A39:EFAB       _bufferheight
+ 3A39:52D4       _bufferofs
+ 3A39:E826       _bufferseg
+ 3A39:EFAD       _bufferwidth
+ 0FFD:01DB idle  _BuildCompScale
+ 048F:0BFA idle  _BuildTables
+ 3A39:EE0F       _Button0
+ 3A39:EE0D       _Button1
+ 3A39:A4FE       _buttonheld
+ 3A39:1290       _buttonjoy
+ 3A39:1288       _buttonmouse
+ 3A39:1278       _buttonscan
+ 3A39:A4EA       _buttonstate
+ 060A:068A idle  _CacheLayoutGraphics
+ 06A5:2D10       _CacheLump
+ 0EBC:02F9 idle  _CalcHeight
+ 048F:0D49 idle  _CalcProjection
+ 0EBC:0A73 idle  _CalcRotate
+ 0EBC:0D9E       _CalcTics
+ 06A5:148E idle  _CalibrateJoystick
+ 160F:046B idle  _CAL_CarmackExpand
+ 160F:0E22 idle  _CAL_ExpandGrChunk
+ 160F:0088 idle  _CAL_GetGrChunkLength
+ 160F:0300 idle  _CAL_HuffExpand
+ 160F:02B5 idle  _CAL_OptimizeNodes
+ 160F:0B75 idle  _CAL_SetupAudioFile
+ 160F:078E idle  _CAL_SetupGrFile
+ 160F:09C0 idle  _CAL_SetupMapFile
+ 160F:0CF9       _CA_CacheAudioChunk
+ 160F:0EF4       _CA_CacheGrChunk
+ 160F:111A       _CA_CacheMap
+ 160F:135D       _CA_CacheMarks
+ 160F:1031       _CA_CacheScreen
+ 160F:165E idle  _CA_CannotOpen
+ 160F:12ED idle  _CA_ClearAllMarks
+ 160F:12CC idle  _CA_ClearMarks
+ 160F:0077 idle  _CA_CloseDebug
+ 160F:12A6       _CA_DownLevel
+ 160F:00E4       _CA_FarRead
+ 160F:012F       _CA_FarWrite
+ 3A39:9EE9       _ca_levelbit
+ 3A39:E823       _ca_levelnum
+ 160F:0DA1       _CA_LoadAllSounds
+ 160F:023B idle  _CA_LoadFile
+ 160F:0056 idle  _CA_OpenDebug
+ 160F:017A idle  _CA_ReadFile
+ 160F:058F idle  _CA_RLEWCompress
+ 160F:06D7 idle  _CA_RLEWexpand
+ 160F:1336       _CA_SetAllPurge
+ 160F:130F idle  _CA_SetGrPurge
+ 160F:0CD0       _CA_Shutdown
+ 160F:0CAF       _CA_Startup
+ 160F:1269       _CA_UpLevel
+ 160F:01E5       _CA_WriteFile
+ 0CFC:05E6       _CenterWindow
+ 3A39:9896       _centerx
+ 06A5:3C30       _CheckForEpisodes
+ 0A85:120F       _CheckHighScore
+ 048C:0000       _CheckIs386
+ 0CFC:0614 idle  _CheckKeys
+ 1087:0FED       _CheckLine
+ 06A5:3B7D idle  _CheckPause
+ 13EC:1EB7 idle  _CheckPosition
+ 1087:1291 idle  _CheckSight
+ 1201:0005 idle  _CheckWeaponChange
+ 3A39:E019       _chunkcomplen
+ 3A39:E015       _chunkexplen
+ 3A39:D866       _ChunksInFile
+ 06A5:2F07 idle  _CleanupControlPanel
+ 0BC6:017B       _ClearMemory
+ 06A5:2CF7       _ClearMScreen
+ 0CFC:0CBC idle  _ClearPaletteShifts
+ 0A85:0004       _ClearSplitVWB
+ 1201:091D idle  _ClipMove
+ 0000:32B1       _close
+ 1320:0369 idle  _CloseDoor
+ 0000:1FE8       _clrscr
+ 1201:0B37 idle  _Cmd_Fire
+ 1201:0B89 idle  _Cmd_Use
+ 3A39:0418 idle  _color_hlite
+ 3A39:0420 idle  _color_norml
+ 3A39:D846       _compatability
+ 3A39:00EE       _configname
+ 06A5:3839 idle  _Confirm
+ 1320:01B7 idle  _ConnectAreas
+ 1201:0039 idle  _ControlMovement
+ 3A39:E844       _Controls
+ 3A39:A4FC       _controlx
+ 3A39:A4FA       _controly
+ 0000:2011       _coreleft
+ 3A39:1694       _costable
+ 0E0D:00C2 idle  _CountObjects
+ 06A5:288C idle  _CP_ChangeView
+ 06A5:02A8 idle  _CP_CheckQuick
+ 06A5:16A9 idle  _CP_Control
+ 06A5:079D idle  _CP_EndGame
+ 06A5:0EDA idle  _CP_LoadGame
+ 06A5:0851 idle  _CP_NewGame
+ 06A5:2A7D idle  _CP_Quit
+ 06A5:11BB idle  _CP_SaveGame
+ 06A5:0ADF idle  _CP_Sound
+ 06A5:07F3       _CP_ViewScores
+ 0000:3310       _creat
+ 3A39:03F0 idle  _CtlItems
+ 23B4:0000 idle  _CtlMenu
+ 3A39:EE0B       _CursorBad
+ 3A39:EE09       _CursorX
+ 3A39:EE07       _CursorY
+ 3A39:03FA idle  _CusItems
+ 2407:0000 idle  _CusMenu
+ 06A5:1C5A idle  _CustomControls
+ 1087:0EF2       _DamageActor
+ 3A39:A41E       _damagecount
+ 3A39:E81F       _debughandle
+ 0E0D:076C       _DebugKeys
+ 0E0D:000D idle  _DebugMemory
+ 3A39:A4DE       _DebugOk
+ 06A5:1D37 idle  _DefineJoyBtns
+ 06A5:1D73 idle  _DefineKeyBtns
+ 06A5:1DAF idle  _DefineKeyMove
+ 06A5:1CFB idle  _DefineMouseBtns
+ 3A39:E842       _DemoBuffer
+ 3A39:A2AC       _demobuffer
+ 048F:159A idle  _DemoLoop
+ 3A39:335E idle  _DemoMode
+ 3A39:1204       _demoname
+ 3A39:E840       _DemoOffset
+ 3A39:A2B6       _demoplayback
+ 3A39:A2B2       _demoptr
+ 3A39:A2B8       _demorecord
+ 3A39:E83E       _DemoSize
+ 3A39:181E idle  _diagonal
+ 0BC6:0F34 idle  _Died
+ 3A39:ECD5       _DigiLastEnd
+ 3A39:ECD7       _DigiLastStart
+ 3A39:ECDB       _DigiLeft
+ 3A39:D84A       _DigiList
+ 3A39:9B8B       _DigiMap
+ 3A39:9C3B       _DigiMode
+ 3A39:ECEF       _DigiNumber
+ 3A39:ECD9       _DigiPage
+ 3A39:ED07       _DigiPlaying
+ 3A39:ECEB       _DigiPriority
+ 3A39:00DC       _dirangle
+ 3A39:46E1       _directvideo
+ 3A39:1270       _dirscan
+ 3A39:1B38 idle  _dirtable
+ 048F:03BA idle  _DiskFlopAnim
+ 3A39:9D4E       _displayofs
+ 0CFC:0E00 idle  _DoActor
+ 048F:03E9 idle  _DoChecksum
+ 048F:1041 idle  _DoJukebox
+ 1320:07B9 idle  _DoorClosing
+ 3A39:D85C       _doornum
+ 3A39:86BA       _doorobjlist
+ 1320:0631 idle  _DoorOpen
+ 1320:065F idle  _DoorOpening
+ 3A39:5328       _doorposition
+ 0BC6:09E5       _DrawAllPlayBorder
+ 0BC6:09BA       _DrawAllPlayBorderSides
+ 1201:04F5       _DrawAmmo
+ 06A5:29FF idle  _DrawChangeView
+ 06A5:1A9B idle  _DrawCtlScreen
+ 06A5:275E idle  _DrawCustJoy
+ 06A5:27F2 idle  _DrawCustKeybd
+ 06A5:285A idle  _DrawCustKeys
+ 06A5:26B7 idle  _DrawCustMouse
+ 06A5:23A7 idle  _DrawCustomScreen
+ 1201:01FF       _DrawFace
+ 06A5:34BE idle  _DrawGun
+ 06A5:347E idle  _DrawHalfStep
+ 1201:032A       _DrawHealth
+ 0A85:1041       _DrawHighScores
+ 1201:047F       _DrawKeys
+ 1201:03C2       _DrawLevel
+ 1201:03DB       _DrawLives
+ 06A5:1089 idle  _DrawLoadSaveScreen
+ 06A5:0E5E idle  _DrawLSAction
+ 06A5:01BE idle  _DrawMainMenu
+ 06A5:35AC       _DrawMenu
+ 06A5:3BBD idle  _DrawMenuGun
+ 06A5:17AE idle  _DrawMouseSens
+ 06A5:098F idle  _DrawNewEpisode
+ 06A5:0A3C idle  _DrawNewGame
+ 06A5:0AC6 idle  _DrawNewGameDiff
+ 06A5:2DA4 idle  _DrawOutline
+ 044B:027E idle  _DrawPlanes
+ 0BC6:0A11       _DrawPlayBorder
+ 0BC6:0930 idle  _DrawPlayBorderSides
+ 0EBC:0D02 idle  _DrawPlayerWeapon
+ 0BC6:0ADB       _DrawPlayScreen
+ 0EBC:0AEF idle  _DrawScaleds
+ 1201:0411       _DrawScore
+ 06A5:0C70 idle  _DrawSoundMenu
+ 044B:0034 idle  _DrawSpans
+ 06A5:3BF0       _DrawStripes
+ 1201:0468       _DrawWeapon
+ 06A5:2D6E       _DrawWindow
+ 1087:0B99 idle  _DropItem
+ 3A39:A422       _dummyobj
+ 3A39:0E74 idle  _ElevatorBackTo
+ 3A39:352A idle  _EMMDriverName
+ 3A39:E8F2       _EMSAvail
+ 3A39:E8F0       _EMSHandle
+ 3A39:E8D4       _EMSList
+ 3A39:E8EE       _EMSPageFrame
+ 3A39:A294       _EMSPagesAvail
+ 3A39:E8C2       _EMSPagesUsed
+ 3A39:E8EC       _EMSPhysicalPage
+ 3A39:A298       _EMSPresent
+ 3A39:0330 idle  _endextern
+ 3A39:0341       _endfilename
+ 234F:0000 idle  _endStrings
+ 060A:090C       _EndText
+ 06A5:1DEB idle  _EnterCtrlData
+ 3A39:4732       _environ
+ 3A39:0428 idle  _EpisodeSelect
+ 06A5:3407 idle  _EraseGun
+ 3A39:00C3       _errno
+ 0000:126E       _exit
+ 3A39:A04F       _extension
+ 3A39:A50E       _extravbls
+ 3A39:A4E0       _facecount
+ 0000:2757       _farcoreleft
+ 0000:2333       _farfree
+ 3A39:E8AA       _farheap
+ 0000:243D       _farmalloc
+ 3A39:863A       _farmapylookup
+ 0000:259A idle  _farrealloc
+ 0EBC:040A       _FarScalePost
+ 3A39:D868       _farthest
+ 3A39:EE13       _fastpalette
+ 0000:3382       _fclose
+ 0000:33FF       _fflush
+ 0000:34E0       _filelength
+ 0000:3480       _findfirst
+ 0000:34B3       _findnext
+ 34A1:0000       _finetangent
+ 0BC6:0BC7 idle  _FinishDemoRecord
+ 0CFC:0DD6       _FinishPaletteShifts
+ 048F:0F21 idle  _FinishSignon
+ 1087:138E idle  _FirstSighting
+ 0EBC:000F       _FixedByFrac
+ 044B:000C idle  _FixedMul
+ 0EBC:0E01       _FixOfs
+ 06A5:2237 idle  _FixupCustom
+ 1D62:07A1       _FizzleFade
+ 3A39:A2C8       _fizzlein
+ 0000:3521       _flushall
+ 3A39:989A       _focallength
+ 3A39:D9D0       _focaltx
+ 3A39:D9CE       _focalty
+ 3A39:9D4D       _fontcolor
+ 3A39:9D4B       _fontnumber
+ 0000:36DC       _fopen
+ 0000:36FB       _fprintf
+ 0000:3B2A       _fputc
+ 0000:3C5E idle  _fputchar
+ 3A39:A4E6       _frameon
+ 0000:2A9D       _free
+ 3A39:168A       _freelatch
+ 06A5:3B16       _FreeMusic
+ 0000:376E       _fseek
+ 0000:37D6 idle  _ftell
+ 3A39:D9DC       _fullscalefarcall
+ 3A39:A416       _funnyticount
+ 0BC6:1162       _GameLoop
+ 3A39:2F4A       _gamepal
+ 3A39:ED0B       _Games
+ 3A39:95C2       _gamestate
+ 3A39:326B idle  _gdictname
+ 1201:0557       _GetBonus
+ 0000:3823       _getenv
+ 0CFC:09F4       _GetNewActor
+ 0000:27F0       _gettext
+ 0000:12FD       _getvect
+ 3A39:3261 idle  _gfilename
+ 3A39:3257 idle  _gheadname
+ 1201:050D idle  _GiveAmmo
+ 1201:03F3 idle  _GiveExtraMan
+ 1201:0542 idle  _GiveKey
+ 1201:042B       _GivePoints
+ 1201:04CC       _GiveWeapon
+ 3A39:A2A8       _globalsoundx
+ 3A39:A2A4       _globalsoundy
+ 3A39:A512       _godmode
+ 3A39:E00B       _gotgatgun
+ 0000:27A7       _gotoxy
+ 160F:0008 idle  _GRFILEPOS
+ 3A39:E021       _grhandle
+ 3A39:E41F       _grhuffman
+ 3582:0000       _grneeded
+ 3A39:9D50       _grsegs
+ 3A39:E81D       _grstarts
+ 1201:0DFF idle  _GunAttack
+ 3A39:ED01       _HackCount
+ 3A39:00DA idle  _halfheight
+ 060A:00F7 idle  _HandleCommand
+ 060A:03A7 idle  _HandleCtrls
+ 06A5:2F1D       _HandleMenu
+ 060A:03C7 idle  _HandleWord
+ 0000:2885       _harderr
+ 0000:2897 idle  _hardresume
+ 0000:28A5 idle  _hardretn
+ 1201:039B       _HealSelf
+ 3A39:9606       _heightnumerator
+ 3A39:0332 idle  _helpextern
+ 3A39:0334 idle  _helpfilename
+ 060A:0885 idle  _HelpScreens
+ 0EBC:0653       _HitHorizDoor
+ 0EBC:0857       _HitHorizPWall
+ 0EBC:0531       _HitHorizWall
+ 0EBC:0753       _HitVertDoor
+ 0EBC:0931       _HitVertPWall
+ 0EBC:0412       _HitVertWall
+ 3A39:542A       _horizwall
+ 3A39:A04A       _ingame
+ 0CFC:09B0       _InitActorList
+ 1320:01F0       _InitAreas
+ 048F:1020 idle  _InitDigiMap
+ 1320:0218       _InitDoorList
+ 048F:122A idle  _InitGame
+ 0CFC:0B4C       _InitRedShifts
+ 1320:000F       _InitStaticList
+ 177B:01DA       _INL_GetJoyDelta
+ 3A39:DDF7       _insetupscaling
+ 06A5:2B04       _IntroScreen
+ 177B:0AB2       _IN_Ack
+ 177B:0A59       _IN_CheckAck
+ 177B:068B       _IN_ClearKeysDown
+ 177B:060E idle  _IN_Default
+ 177B:0141       _IN_GetJoyAbs
+ 177B:0336 idle  _IN_GetJoyButtonsDB
+ 06A5:3B39 idle  _IN_GetScanName
+ 177B:0B1B       _IN_JoyButtons
+ 177B:0B04       _IN_MouseButtons
+ 177B:06AA       _IN_ReadControl
+ 177B:09C2 idle  _IN_SetControlType
+ 177B:0679 idle  _IN_SetKeyHook
+ 177B:048B       _IN_SetupJoy
+ 177B:064D       _IN_Shutdown
+ 177B:0A0A       _IN_StartAck
+ 177B:0572       _IN_Startup
+ 177B:0AC3       _IN_UserInput
+ 177B:09EF       _IN_WaitForASCII
+ 177B:09D3 idle  _IN_WaitForKey
+ 0000:29D9       _ioctl
+ 3A39:989E       _IsA386
+ 0000:1501       _isatty
+ 0000:3882       _itoa
+ 048C:0028       _jabhack2
+ 3A39:00FC idle  _JHParmStrings
+ 3A39:E84C       _JoyDefs
+ 3A39:54B0       _joypadenabled
+ 3A39:E83C       _JoyPadPresent
+ 3A39:9C45       _JoysPresent
+ 3A39:54B2       _joystickenabled
+ 3A39:54AC       _joystickport
+ 3A39:54AE       _joystickprogressive
+ 3A39:3354 idle  _KbdDefs
+ 3A39:9C4B       _Keyboard
+ 1087:0C2C idle  _KillActor
+ 3A39:A2BA       _killerobj
+ 1201:0D6B idle  _KnifeAttack
+ 3A39:A04C       _LastASCII
+ 3A39:E009       _LastAttacker
+ 3A39:A2AE       _lastdemoptr
+ 3A39:E011       _lastdoorobj
+ 3A39:D9D4       _lastintercept
+ 3A39:B518       _lastobj
+ 3A39:9EE2       _LastScan
+ 3A39:D9D8       _lastside
+ 3A39:893A       _laststatobj
+ 3A39:D9D2       _lasttilehit
+ 3A39:9EEC       _lasttimecount
+ 1D62:062F       _LatchDrawPic
+ 1201:02A1 idle  _LatchNumber
+ 3A39:A2D2       _latchpics
+ 3A39:9E8E       _layoutdone
+ 3A39:A2A2       _leftchannel
+ 3A39:9EBC       _leftmargin
+ 3A39:3FCE idle  _leftmasks
+ 3A39:ECE9       _LeftPosition
+ 3A39:1042 idle  _lefttable
+ 0A85:05D1       _LevelCompleted
+ 3A39:9906       _LevelRatios
+ 3A39:DDEB       _linecmds
+ 3A39:DDE7       _linescale
+ 3A39:EFA7       _linewidth
+ 3A39:9B85       _loadedgame
+ 1D62:0687       _LoadLatchMem
+ 048F:0803       _LoadTheGame
+ 3A39:ECDF       _LocalTime
+ 0000:15AC       _lseek
+ 3A39:03E6 idle  _LSItems
+ 23EC:0000 idle  _LSMenu
+ 0000:38C4       _ltoa
+ 3A39:D844       _madenoise
+ 048F:179C       _main
+ 3A39:03D2       _MainItems
+ 3A39:E9BE       _MainMemPages
+ 3A39:E8F6       _MainMemUsed
+ 237C:0000       _MainMenu
+ 3A39:E8F4       _MainPagesAvail
+ 3A39:E8C0       _MainPagesUsed
+ 3A39:EA86       _MainPresent
+ 0000:2B6C       _malloc
+ 3A39:E01F       _maphandle
+ 3A39:A39A       _mapheaderseg
+ 3A39:A2CC       _mapheight
+ 3A39:171A       _mapmasks1
+ 3A39:173A       _mapmasks2
+ 3A39:175A       _mapmasks3
+ 3A39:A29E       _mapon
+ 3A39:D852       _maporgx
+ 3A39:D850       _maporgy
+ 0485:0008       _MapRow
+ 3A39:A412       _mapsegs
+ 3A39:A2CE       _mapwidth
+ 3A39:A45E       _mapwidthtable
+ 3A39:DDE4       _mask1
+ 3A39:DDE3       _mask2
+ 3A39:DDE2       _mask3
+ 3A39:DDE5       _maskword
+ 0000:0F22       _matherr
+ 3A39:DDF9       _maxscale
+ 3A39:D9DA       _maxscaleshl2
+ 3A39:960A       _maxslope
+ 3A39:05F2 idle  _mbarray
+ 0000:38E9       _memcpy
+ 3A39:52D2       _menuitems
+ 06A5:3960       _Message
+ 3A39:327F idle  _mfilename
+ 3A39:3275 idle  _mheadname
+ 3A39:D9C8       _midangle
+ 3A39:1690 idle  _mindist
+ 3A39:9604       _minheightdiv
+ 3A39:49FA       _mirrorofs
+ 37CC:0000       _mmblocks
+ 3A39:A29C       _mmerror
+ 3A39:E8A0       _mmfree
+ 3A39:E8A4       _mmhead
+ 3A39:9E7A       _mminfo
+ 182E:0000 idle  _MML_CheckForXMS
+ 182E:0239 idle  _MML_ClearBlock
+ 182E:001B idle  _MML_SetupXMS
+ 182E:0087 idle  _MML_ShutdownXMS
+ 182E:00B6       _MML_UseSpace
+ 3A39:E898       _mmnew
+ 3A39:E89C       _mmrover
+ 3A39:E8AE       _mmstarted
+ 182E:0E3C       _MM_BombOnError
+ 182E:0C31 idle  _MM_DumpData
+ 182E:0767       _MM_FreePtr
+ 182E:04B3       _MM_GetPtr
+ 182E:08A9       _MM_SetLock
+ 182E:082B       _MM_SetPurge
+ 182E:0AE0 idle  _MM_ShowMemory
+ 182E:048B       _MM_Shutdown
+ 182E:092B       _MM_SortMem
+ 182E:029A       _MM_Startup
+ 182E:0DC0       _MM_TotalFree
+ 182E:0D5B       _MM_UnusedMemory
+ 3A39:988E       _mouseadjustment
+ 3A39:E838       _MouseDownCount
+ 3A39:54B4       _mouseenabled
+ 3A39:9C49       _MousePresent
+ 06A5:18B2 idle  _MouseSensitivity
+ 0000:3908       _movedata
+ 1320:08E8       _MoveDoors
+ 1087:0967       _MoveObj
+ 3A39:0622 idle  _moveorder
+ 1320:0AC9       _MovePWalls
+ 0000:2A00       _movetext
+ 3A39:49EE       _mr_count
+ 3A39:49E4       _mr_dest
+ 3A39:49F0       _mr_rowofs
+ 3A39:49E8       _mr_xfrac
+ 3A39:49EC       _mr_xstep
+ 3A39:49E6       _mr_yfrac
+ 3A39:49EA       _mr_ystep
+ 048F:0FBA       _MS_CheckParm
+ 3A39:01C4 idle  _MusicItems
+ 231F:0000 idle  _MusicMenu
+ 3A39:9C39       _MusicMode
+ 3A39:E8A8       _nearheap
+ 3A39:85BA       _nearmapylookup
+ 3A39:ED03       _NeedsDigitized
+ 3A39:ED09       _NeedsMusic
+ 3A39:95BE       _new
+ 3A39:0404 idle  _NewEitems
+ 23C4:0000 idle  _NewEmenu
+ 048F:0369       _NewGame
+ 3A39:040E idle  _NewItems
+ 060A:034C idle  _NewLine
+ 23E1:0000 idle  _NewMenu
+ 1087:00BA       _NewState
+ 048F:148B       _NewViewSize
+ 3A39:ECFB       _nextsoundpos
+ 3A39:A510       _noclip
+ 0A85:1353 idle  _NonShareware
+ 3A39:98A0       _nospr
+ 3A39:01FC idle  _nosprtxt
+ 3A39:9B83       _NoWait
+ 3A39:D84C       _NumDigi
+ 3A39:9EDA       _numpages
+ 3A39:E890       _numUMBs
+ 3A39:B51A       _obj
+ 3A39:A420       _objcount
+ 3A39:B516       _objfreelist
+ 3A39:B51C       _objlist
+ 3A39:E013       _oldsoundmode
+ 0000:3955       _open
+ 1320:0340       _OpenDoor
+ 1320:05BD       _OperateDoor
+ 3A39:180C idle  _opposite
+ 3A39:05FE idle  _order
+ 0000:169C idle  _outp
+ 0000:1678       _outport
+ 0000:1684 idle  _outportb
+ 0000:1690 idle  _outpw
+ 3A39:3520 idle  _PageFile
+ 3A39:3512       _PageFileName
+ 060A:0475 idle  _PageLayout
+ 3A39:9EDC       _pagenum
+ 3A09:0000       _palette1
+ 39D9:0000       _palette2
+ 3A39:A41A       _palshifted
+ 060A:001F idle  _ParseNumber
+ 060A:0071 idle  _ParsePicCommand
+ 060A:008F idle  _ParseTimedCommand
+ 048F:030D idle  _Patch386
+ 3A39:A04D       _Paused
+ 3A39:ECC0       _pcLastSample
+ 3A39:ECB8       _pcLengthLeft
+ 3A39:49F2       _pcos
+ 3A39:ECBC       _pcSound
+ 3A39:EABA       _pcSoundLookup
+ 3A39:EFA9       _pelpan
+ 0A85:03CC       _PG13
+ 3A39:9E90       _picdelay
+ 3A39:9EEA       _pickquick
+ 3A39:9E92       _picnum
+ 3A39:9EE7       _pictable
+ 0E0D:01B3       _PicturePause
+ 3A39:9E96       _picx
+ 3A39:9E94       _picy
+ 3A39:960E       _pixelangle
+ 3A39:3FCA idle  _pixmasks
+ 3A39:D9B2       _pixx
+ 1320:00E1       _PlaceItemType
+ 210E:0000       _planepics
+ 3A39:4AC2       _planeylookup
+ 0BC6:0DD1       _PlayDemo
+ 3A39:95BC       _player
+ 3A39:E005       _playerxmove
+ 3A39:E001       _playerymove
+ 0CFC:0F8C       _PlayLoop
+ 0BC6:00F7       _PlaySoundLocGlobal
+ 3A39:95C0       _playstate
+ 3A39:DFFF       _plux
+ 3A39:DFFD       _pluy
+ 3A39:E8BA       _PMFrameCount
+ 1912:06B1 idle  _PML_ClosePageFile
+ 1912:0A96 idle  _PML_GetAPageBuffer
+ 1912:06E8 idle  _PML_GetEMSAddress
+ 1912:0BA0 idle  _PML_GetPageFromXMS
+ 1912:0812 idle  _PML_GiveLRUPage
+ 1912:08B0 idle  _PML_GiveLRUXMSPage
+ 1912:0C21 idle  _PML_LoadPage
+ 1912:0007 idle  _PML_MapEMS
+ 1912:04E8 idle  _PML_OpenPageFile
+ 1912:0920 idle  _PML_PutPageInXMS
+ 1912:046E idle  _PML_ReadFromFile
+ 1912:0155 idle  _PML_ShutdownEMS
+ 1912:0447 idle  _PML_ShutdownMainMem
+ 1912:0293 idle  _PML_ShutdownXMS
+ 1912:0029 idle  _PML_StartupEMS
+ 1912:03D0 idle  _PML_StartupMainMem
+ 1912:0178 idle  _PML_StartupXMS
+ 1912:09C9 idle  _PML_TransferPageSpace
+ 1912:01EA idle  _PML_XMSCopy
+ 3A39:E8BE       _PMNumBlocks
+ 3A39:D85E       _PMPages
+ 3A39:E8C8       _PMPanicMode
+ 3A39:E8B8       _PMSegPages
+ 3A39:D862       _PMSoundStart
+ 3A39:D864       _PMSpriteStart
+ 3A39:E8CA       _PMStarted
+ 3A39:E8C6       _PMThrashing
+ 1912:02DF       _PM_CheckMainMem
+ 1912:0C71       _PM_GetPage
+ 1912:07BF       _PM_GetPageAddress
+ 1912:0FBA       _PM_NextFrame
+ 1912:0D60       _PM_Preload
+ 1912:1034 idle  _PM_Reset
+ 1912:02B8       _PM_SetMainMemPurge
+ 1912:0D31       _PM_SetPageLock
+ 1912:114B       _PM_Shutdown
+ 1912:10A0       _PM_Startup
+ 0CFC:03B9 idle  _PollControls
+ 0CFC:006F idle  _PollJoystickButtons
+ 0CFC:0248 idle  _PollJoystickMove
+ 0CFC:0007 idle  _PollKeyboardButtons
+ 0CFC:0100 idle  _PollKeyboardMove
+ 0CFC:002B idle  _PollMouseButtons
+ 0CFC:020C idle  _PollMouseMove
+ 3A39:D858       _postsource
+ 3A39:D854       _postwidth
+ 3A39:D856       _postx
+ 0000:0F17       _pow10
+ 0A85:0FA5       _PreloadGraphics
+ 0A85:0F10 idle  _PreloadUpdate
+ 06A5:2714 idle  _PrintCustJoy
+ 06A5:27BB idle  _PrintCustKeybd
+ 06A5:2824 idle  _PrintCustKeys
+ 06A5:266D idle  _PrintCustMouse
+ 0000:3AFA       _printf
+ 06A5:112F idle  _PrintLSEntry
+ 3A39:A048       _PrintX
+ 3A39:9B81       _PrintY
+ 3A39:E821       _profilehandle
+ 13EC:005A idle  _ProjectileTryMove
+ 3A39:49F6       _psin
+ 1320:093B       _PushWall
+ 0000:3E13       _puts
+ 0000:2844       _puttext
+ 3A39:52D6       _pwalldir
+ 3A39:53A8       _pwallpos
+ 3A39:5326       _pwallstate
+ 3A39:52DA       _pwallx
+ 3A39:52D8       _pwally
+ 3A39:9EE5       _px
+ 3A39:9EE3       _py
+ 048F:14CF       _Quit
+ 3A39:0102 idle  _radtoint
+ 0000:3F2C       _read
+ 06A5:36DC idle  _ReadAnyControl
+ 048F:000B idle  _ReadConfig
+ 0000:2CC5 idle  _realloc
+ 0BC6:0C9A       _RecordDemo
+ 1320:016B idle  _RecursiveConnect
+ 36AC:0000       _redshifts
+ 0CFC:0A55 idle  _RemoveObj
+ 3A39:A2A0       _rightchannel
+ 3A39:9E9E       _rightmargin
+ 3A39:3FD2 idle  _rightmasks
+ 3A39:ECE7       _RightPosition
+ 3A39:0E80 idle  _righttable
+ 060A:000C idle  _RipToEOL
+ 230E:0002 idle  _rndtable
+ 3A39:9E98       _rowon
+ 3A39:A4E4       _running
+ 3A39:9EF0       _SaveGameNames
+ 3A39:A032       _SaveGamesAvail
+ 3A39:0436 idle  _SaveName
+ 048F:042E       _SaveTheGame
+ 3A39:ED05       _SBProPresent
+ 0000:1FD8 idle  _sbrk
+ 3A39:52CA       _scale
+ 3A39:DDFB       _scaledirectory
+ 0FFD:032F idle  _ScaleLine
+ 0EBC:0397 idle  _ScalePost
+ 0FFD:0479       _ScaleShape
+ 0BC6:0194 idle  _ScanInfoPlane
+ 3A39:3D1A       _Scores
+ 3A39:D848       _screenfaded
+ 3A39:1684       _screenloc
+ 3A39:9898       _screenofs
+ 3A39:3FC4       _screenseg
+ 1A28:0B5F       _SDL_DigitizedDone
+ 1BB1:0014       _SDL_IndicatePC
+ 1A28:08B0 idle  _SDL_LoadDigiSegment
+ 1A28:08E1 idle  _SDL_PlayDigiSegment
+ 1A28:0501 idle  _SDL_SBSetDMA
+ 1BB1:000C       _SDL_SetDS
+ 1A28:0C2D idle  _SDL_SetupDigi
+ 1BB1:0021       _SDL_t0ExtremeAsmService
+ 1BB1:009B       _SDL_t0FastAsmService
+ 1BB1:02CD       _SDL_t0SlowAsmService
+ 1A28:14B4 idle  _SD_Default
+ 1A28:1870 idle  _SD_FadeOutMusic
+ 1A28:17DA       _SD_MusicOff
+ 1A28:17CF       _SD_MusicOn
+ 1A28:1881 idle  _SD_MusicPlaying
+ 1A28:0A9F idle  _SD_PlayDigitized
+ 1A28:15A4       _SD_PlaySound
+ 1A28:09CC       _SD_Poll
+ 1A28:158D       _SD_PositionSound
+ 1A28:0BC9       _SD_SetDigiDevice
+ 1A28:1129       _SD_SetMusicMode
+ 1A28:0A58       _SD_SetPosition
+ 1A28:109B       _SD_SetSoundMode
+ 1A28:157B idle  _SD_SetUserHook
+ 1A28:1523       _SD_Shutdown
+ 1A28:1744       _SD_SoundPlaying
+ 1A28:181E       _SD_StartMusic
+ 1A28:117B       _SD_Startup
+ 1A28:092B       _SD_StopDigitized
+ 1A28:178B       _SD_StopSound
+ 1A28:17C2       _SD_WaitSoundDone
+ 1087:0747       _SelectChaseDir
+ 1087:0619       _SelectDodgeDir
+ 13EC:1951 idle  _SelectPathDir
+ 1087:089F       _SelectRunDir
+ 0000:3164       _setblock
+ 044B:0179 idle  _SetPlaneViewSize
+ 0BC6:0006 idle  _SetSoundLoc
+ 06A5:3677 idle  _SetTextColor
+ 06A5:2E09 idle  _SetupControlPanel
+ 0BC6:0683       _SetupGameLevel
+ 0FFD:001A       _SetupScaling
+ 048F:0E7C idle  _SetupWalls
+ 0000:3F2F       _setvbuf
+ 0000:130C       _setvect
+ 048F:13BC       _SetViewSize
+ 0E0D:02C5 idle  _ShapeTest
+ 3A39:9894       _shootdelta
+ 06A5:3C21 idle  _ShootSnd
+ 060A:0771 idle  _ShowArticle
+ 048F:1442       _ShowViewSize
+ 048F:0BD2       _ShutdownId
+ 1087:167A       _SightPlayer
+ 2422:0000       _signon
+ 048F:0E9F idle  _SignonScreen
+ 0FFD:078D       _SimpleScaleShape
+ 0000:0F48       _sin
+ 3A39:A514       _singlestep
+ 3430:0000       _sintable
+ 3A39:DDEF       _slinewidth
+ 3A39:DDF1       _slinex
+ 3A39:03DC idle  _SndItems
+ 2394:0000 idle  _SndMenu
+ 3A39:1298 idle  _songs
+ 3A39:9C3F       _SoundBlasterPresent
+ 3A39:9C3D       _SoundMode
+ 3A39:ECF1       _SoundNumber
+ 3A39:A2D0       _SoundPositioned
+ 3A39:ECED       _SoundPriority
+ 3A39:9C41       _SoundSourcePresent
+ 3A39:0434 idle  _SoundStatus
+ 3A39:ECFF       _SoundTable
+ 3A39:4F72       _spanstart
+ 13EC:1D7E       _SpawnBJVictory
+ 13EC:04D9       _SpawnBoss
+ 13EC:04BA       _SpawnDeadGuard
+ 1320:024B       _SpawnDoor
+ 13EC:1152       _SpawnFakeHitler
+ 13EC:0A19       _SpawnFat
+ 13EC:08C5       _SpawnGhosts
+ 13EC:09B2       _SpawnGift
+ 13EC:052B       _SpawnGretel
+ 13EC:11B9       _SpawnHitler
+ 1087:000C       _SpawnNewObj
+ 13EC:057D       _SpawnPatrol
+ 1201:0CCC       _SpawnPlayer
+ 13EC:094B       _SpawnSchabbs
+ 13EC:0312       _SpawnStand
+ 1320:001A       _SpawnStatic
+ 3A39:A2BE       _spearangle
+ 3A39:A2BC       _spearflag
+ 3A39:A2C4       _spearx
+ 3A39:A2C0       _speary
+ 3A39:A516       _spotvis
+ 0000:402D       _sprintf
+ 3A39:EA98       _sqActive
+ 3A39:EA94       _sqHack
+ 3A39:EA8E       _sqHackLen
+ 3A39:EA90       _sqHackPtr
+ 3A39:EA8C       _sqHackSeqLen
+ 3A39:EA88       _sqHackTime
+ 3A39:ECD1       _ssActive
+ 3A39:ECCF       _ssControl
+ 3A39:ECCB       _ssData
+ 3A39:ECFD       _ssIsTandy
+ 3A39:ECC1       _ssLengthLeft
+ 3A39:ECD3       _ssNoCheck
+ 3A39:ECC9       _ssOff
+ 3A39:ECCA       _ssOn
+ 3A39:39A0 idle  _ssPort
+ 3A39:ECC5       _ssSample
+ 3A39:ECCD       _ssStatus
+ 0CFC:0CC9       _StartBonusFlash
+ 06A5:3A8F       _StartCPMusic
+ 0CFC:0CD4       _StartDamageFlash
+ 0BC6:0B76 idle  _StartDemoRecord
+ 3A39:A030       _StartGame
+ 3A39:9892       _startgame
+ 3A39:1B4A idle  _starthitpoints
+ 0CFC:0AD6       _StartMusic
+ 3A39:1A1E idle  _statinfo
+ 3A39:893C       _statobjlist
+ 1201:01A8 idle  _StatusDrawPic
+ 3A39:DDF3       _stepbytwo
+ 3A39:4DE2       _stepscale
+ 0CFC:0AA3       _StopMusic
+ 3A39:98B6       _str
+ 3A39:98A2       _str2
+ 3A39:1A0C idle  _strafeangle
+ 0000:4066       _strcat
+ 0000:409F       _strcpy
+ 0000:40C1       _strlen
+ 0000:4105       _strtol
+ 3A39:191C idle  _s_attack
+ 3A39:2EB4 idle  _s_bjjump1
+ 3A39:2EC4 idle  _s_bjjump2
+ 3A39:2ED4 idle  _s_bjjump3
+ 3A39:2EE4 idle  _s_bjjump4
+ 3A39:2E54 idle  _s_bjrun1
+ 3A39:2E64 idle  _s_bjrun1s
+ 3A39:2E74 idle  _s_bjrun2
+ 3A39:2E84 idle  _s_bjrun3
+ 3A39:2E94 idle  _s_bjrun3s
+ 3A39:2EA4 idle  _s_bjrun4
+ 3A39:1DDA       _s_blinkychase1
+ 3A39:1DEA idle  _s_blinkychase2
+ 3A39:1C4A idle  _s_boom1
+ 3A39:1C5A idle  _s_boom2
+ 3A39:1C6A idle  _s_boom3
+ 3A39:246A       _s_bosschase1
+ 3A39:247A idle  _s_bosschase1s
+ 3A39:248A idle  _s_bosschase2
+ 3A39:249A idle  _s_bosschase3
+ 3A39:24AA idle  _s_bosschase3s
+ 3A39:24BA idle  _s_bosschase4
+ 3A39:24CA       _s_bossdie1
+ 3A39:24DA idle  _s_bossdie2
+ 3A39:24EA idle  _s_bossdie3
+ 3A39:24FA idle  _s_bossdie4
+ 3A39:250A idle  _s_bossshoot1
+ 3A39:251A idle  _s_bossshoot2
+ 3A39:252A idle  _s_bossshoot3
+ 3A39:253A idle  _s_bossshoot4
+ 3A39:254A idle  _s_bossshoot5
+ 3A39:255A idle  _s_bossshoot6
+ 3A39:256A idle  _s_bossshoot7
+ 3A39:257A idle  _s_bossshoot8
+ 3A39:245A idle  _s_bossstand
+ 3A39:1E3A idle  _s_clydechase1
+ 3A39:1E4A idle  _s_clydechase2
+ 3A39:2EF4       _s_deathcam
+ 3A39:1F0A       _s_dogchase1
+ 3A39:1F1A idle  _s_dogchase1s
+ 3A39:1F2A idle  _s_dogchase2
+ 3A39:1F3A idle  _s_dogchase3
+ 3A39:1F4A idle  _s_dogchase3s
+ 3A39:1F5A idle  _s_dogchase4
+ 3A39:1F9A idle  _s_dogdead
+ 3A39:1F6A       _s_dogdie1
+ 3A39:1F7A idle  _s_dogdie2
+ 3A39:1F8A idle  _s_dogdie3
+ 3A39:1EBA idle  _s_dogjump1
+ 3A39:1ECA idle  _s_dogjump2
+ 3A39:1EDA idle  _s_dogjump3
+ 3A39:1EEA idle  _s_dogjump4
+ 3A39:1EFA idle  _s_dogjump5
+ 3A39:1E5A idle  _s_dogpath1
+ 3A39:1E6A idle  _s_dogpath1s
+ 3A39:1E7A idle  _s_dogpath2
+ 3A39:1E8A idle  _s_dogpath3
+ 3A39:1E9A idle  _s_dogpath3s
+ 3A39:1EAA idle  _s_dogpath4
+ 3A39:2A5C       _s_fakechase1
+ 3A39:2A6C idle  _s_fakechase1s
+ 3A39:2A7C idle  _s_fakechase2
+ 3A39:2A8C idle  _s_fakechase3
+ 3A39:2A9C idle  _s_fakechase3s
+ 3A39:2AAC idle  _s_fakechase4
+ 3A39:2ABC       _s_fakedie1
+ 3A39:2ACC idle  _s_fakedie2
+ 3A39:2ADC idle  _s_fakedie3
+ 3A39:2AEC idle  _s_fakedie4
+ 3A39:2AFC idle  _s_fakedie5
+ 3A39:2B0C idle  _s_fakedie6
+ 3A39:2B1C idle  _s_fakeshoot1
+ 3A39:2B2C idle  _s_fakeshoot2
+ 3A39:2B3C idle  _s_fakeshoot3
+ 3A39:2B4C idle  _s_fakeshoot4
+ 3A39:2B5C idle  _s_fakeshoot5
+ 3A39:2B6C idle  _s_fakeshoot6
+ 3A39:2B7C idle  _s_fakeshoot7
+ 3A39:2B8C idle  _s_fakeshoot8
+ 3A39:2B9C idle  _s_fakeshoot9
+ 3A39:2A4C idle  _s_fakestand
+ 3A39:291C       _s_fatchase1
+ 3A39:292C idle  _s_fatchase1s
+ 3A39:293C idle  _s_fatchase2
+ 3A39:294C idle  _s_fatchase3
+ 3A39:295C idle  _s_fatchase3s
+ 3A39:296C idle  _s_fatchase4
+ 3A39:297C idle  _s_fatdeathcam
+ 3A39:298C       _s_fatdie1
+ 3A39:299C idle  _s_fatdie2
+ 3A39:29AC idle  _s_fatdie3
+ 3A39:29BC idle  _s_fatdie4
+ 3A39:29CC idle  _s_fatdie5
+ 3A39:29DC idle  _s_fatdie6
+ 3A39:29EC idle  _s_fatshoot1
+ 3A39:29FC idle  _s_fatshoot2
+ 3A39:2A0C idle  _s_fatshoot3
+ 3A39:2A1C idle  _s_fatshoot4
+ 3A39:2A2C idle  _s_fatshoot5
+ 3A39:2A3C idle  _s_fatshoot6
+ 3A39:290C idle  _s_fatstand
+ 3A39:2BAC idle  _s_fire1
+ 3A39:2BBC idle  _s_fire2
+ 3A39:281C       _s_giftchase1
+ 3A39:282C idle  _s_giftchase1s
+ 3A39:283C idle  _s_giftchase2
+ 3A39:284C idle  _s_giftchase3
+ 3A39:285C idle  _s_giftchase3s
+ 3A39:286C idle  _s_giftchase4
+ 3A39:287C idle  _s_giftdeathcam
+ 3A39:288C       _s_giftdie1
+ 3A39:289C idle  _s_giftdie2
+ 3A39:28AC idle  _s_giftdie3
+ 3A39:28BC idle  _s_giftdie4
+ 3A39:28CC idle  _s_giftdie5
+ 3A39:28DC idle  _s_giftdie6
+ 3A39:28EC idle  _s_giftshoot1
+ 3A39:28FC idle  _s_giftshoot2
+ 3A39:280C idle  _s_giftstand
+ 3A39:1D3A       _s_grdchase1
+ 3A39:1D4A idle  _s_grdchase1s
+ 3A39:1D5A idle  _s_grdchase2
+ 3A39:1D6A idle  _s_grdchase3
+ 3A39:1D7A idle  _s_grdchase3s
+ 3A39:1D8A idle  _s_grdchase4
+ 3A39:1D9A       _s_grddie1
+ 3A39:1DAA idle  _s_grddie2
+ 3A39:1DBA idle  _s_grddie3
+ 3A39:1DCA idle  _s_grddie4
+ 3A39:1CEA       _s_grdpain
+ 3A39:1CFA       _s_grdpain1
+ 3A39:1C8A idle  _s_grdpath1
+ 3A39:1C9A idle  _s_grdpath1s
+ 3A39:1CAA idle  _s_grdpath2
+ 3A39:1CBA idle  _s_grdpath3
+ 3A39:1CCA idle  _s_grdpath3s
+ 3A39:1CDA idle  _s_grdpath4
+ 3A39:1D0A idle  _s_grdshoot1
+ 3A39:1D1A idle  _s_grdshoot2
+ 3A39:1D2A idle  _s_grdshoot3
+ 3A39:1C7A idle  _s_grdstand
+ 3A39:259A       _s_gretelchase1
+ 3A39:25AA idle  _s_gretelchase1s
+ 3A39:25BA idle  _s_gretelchase2
+ 3A39:25CA idle  _s_gretelchase3
+ 3A39:25DA idle  _s_gretelchase3s
+ 3A39:25EA idle  _s_gretelchase4
+ 3A39:25FA       _s_greteldie1
+ 3A39:260A idle  _s_greteldie2
+ 3A39:261A idle  _s_greteldie3
+ 3A39:262A idle  _s_greteldie4
+ 3A39:263A idle  _s_gretelshoot1
+ 3A39:264A idle  _s_gretelshoot2
+ 3A39:265A idle  _s_gretelshoot3
+ 3A39:266A idle  _s_gretelshoot4
+ 3A39:267A idle  _s_gretelshoot5
+ 3A39:268A idle  _s_gretelshoot6
+ 3A39:269A idle  _s_gretelshoot7
+ 3A39:26AA idle  _s_gretelshoot8
+ 3A39:258A idle  _s_gretelstand
+ 3A39:2CDC       _s_hitlerchase1
+ 3A39:2CEC idle  _s_hitlerchase1s
+ 3A39:2CFC idle  _s_hitlerchase2
+ 3A39:2D0C idle  _s_hitlerchase3
+ 3A39:2D1C idle  _s_hitlerchase3s
+ 3A39:2D2C idle  _s_hitlerchase4
+ 3A39:2D3C idle  _s_hitlerdeathcam
+ 3A39:2D4C       _s_hitlerdie1
+ 3A39:2DDC idle  _s_hitlerdie10
+ 3A39:2D5C idle  _s_hitlerdie2
+ 3A39:2D6C idle  _s_hitlerdie3
+ 3A39:2D7C idle  _s_hitlerdie4
+ 3A39:2D8C idle  _s_hitlerdie5
+ 3A39:2D9C idle  _s_hitlerdie6
+ 3A39:2DAC idle  _s_hitlerdie7
+ 3A39:2DBC idle  _s_hitlerdie8
+ 3A39:2DCC idle  _s_hitlerdie9
+ 3A39:2DEC idle  _s_hitlershoot1
+ 3A39:2DFC idle  _s_hitlershoot2
+ 3A39:2E0C idle  _s_hitlershoot3
+ 3A39:2E1C idle  _s_hitlershoot4
+ 3A39:2E2C idle  _s_hitlershoot5
+ 3A39:2E3C idle  _s_hitlershoot6
+ 3A39:1DFA idle  _s_inkychase1
+ 3A39:1E0A idle  _s_inkychase2
+ 3A39:2BDC       _s_mechachase1
+ 3A39:2BEC idle  _s_mechachase1s
+ 3A39:2BFC idle  _s_mechachase2
+ 3A39:2C0C idle  _s_mechachase3
+ 3A39:2C1C idle  _s_mechachase3s
+ 3A39:2C2C idle  _s_mechachase4
+ 3A39:2C3C       _s_mechadie1
+ 3A39:2C4C idle  _s_mechadie2
+ 3A39:2C5C idle  _s_mechadie3
+ 3A39:2C6C idle  _s_mechadie4
+ 3A39:2C7C idle  _s_mechashoot1
+ 3A39:2C8C idle  _s_mechashoot2
+ 3A39:2C9C idle  _s_mechashoot3
+ 3A39:2CAC idle  _s_mechashoot4
+ 3A39:2CBC idle  _s_mechashoot5
+ 3A39:2CCC idle  _s_mechashoot6
+ 3A39:2BCC idle  _s_mechastand
+ 3A39:21EA       _s_mutchase1
+ 3A39:21FA idle  _s_mutchase1s
+ 3A39:220A idle  _s_mutchase2
+ 3A39:221A idle  _s_mutchase3
+ 3A39:222A idle  _s_mutchase3s
+ 3A39:223A idle  _s_mutchase4
+ 3A39:224A       _s_mutdie1
+ 3A39:225A idle  _s_mutdie2
+ 3A39:226A idle  _s_mutdie3
+ 3A39:227A idle  _s_mutdie4
+ 3A39:228A idle  _s_mutdie5
+ 3A39:218A       _s_mutpain
+ 3A39:219A       _s_mutpain1
+ 3A39:212A idle  _s_mutpath1
+ 3A39:213A idle  _s_mutpath1s
+ 3A39:214A idle  _s_mutpath2
+ 3A39:215A idle  _s_mutpath3
+ 3A39:216A idle  _s_mutpath3s
+ 3A39:217A idle  _s_mutpath4
+ 3A39:21AA idle  _s_mutshoot1
+ 3A39:21BA idle  _s_mutshoot2
+ 3A39:21CA idle  _s_mutshoot3
+ 3A39:21DA idle  _s_mutshoot4
+ 3A39:211A idle  _s_mutstand
+ 3A39:27CC idle  _s_needle1
+ 3A39:27DC idle  _s_needle2
+ 3A39:27EC idle  _s_needle3
+ 3A39:27FC idle  _s_needle4
+ 3A39:206A       _s_ofcchase1
+ 3A39:207A idle  _s_ofcchase1s
+ 3A39:208A idle  _s_ofcchase2
+ 3A39:209A idle  _s_ofcchase3
+ 3A39:20AA idle  _s_ofcchase3s
+ 3A39:20BA idle  _s_ofcchase4
+ 3A39:20CA       _s_ofcdie1
+ 3A39:20DA idle  _s_ofcdie2
+ 3A39:20EA idle  _s_ofcdie3
+ 3A39:20FA idle  _s_ofcdie4
+ 3A39:210A idle  _s_ofcdie5
+ 3A39:201A       _s_ofcpain
+ 3A39:202A       _s_ofcpain1
+ 3A39:1FBA idle  _s_ofcpath1
+ 3A39:1FCA idle  _s_ofcpath1s
+ 3A39:1FDA idle  _s_ofcpath2
+ 3A39:1FEA idle  _s_ofcpath3
+ 3A39:1FFA idle  _s_ofcpath3s
+ 3A39:200A idle  _s_ofcpath4
+ 3A39:203A idle  _s_ofcshoot1
+ 3A39:204A idle  _s_ofcshoot2
+ 3A39:205A idle  _s_ofcshoot3
+ 3A39:1FAA idle  _s_ofcstand
+ 3A39:1E1A idle  _s_pinkychase1
+ 3A39:1E2A idle  _s_pinkychase2
+ 3A39:190C idle  _s_player
+ 3A39:1BFA idle  _s_rocket
+ 3A39:26DC       _s_schabbchase1
+ 3A39:26EC idle  _s_schabbchase1s
+ 3A39:26FC idle  _s_schabbchase2
+ 3A39:270C idle  _s_schabbchase3
+ 3A39:271C idle  _s_schabbchase3s
+ 3A39:272C idle  _s_schabbchase4
+ 3A39:273C idle  _s_schabbdeathcam
+ 3A39:274C       _s_schabbdie1
+ 3A39:275C idle  _s_schabbdie2
+ 3A39:276C idle  _s_schabbdie3
+ 3A39:277C idle  _s_schabbdie4
+ 3A39:278C idle  _s_schabbdie5
+ 3A39:279C idle  _s_schabbdie6
+ 3A39:27AC idle  _s_schabbshoot1
+ 3A39:27BC idle  _s_schabbshoot2
+ 3A39:26CC idle  _s_schabbstand
+ 3A39:1C0A idle  _s_smoke1
+ 3A39:1C1A idle  _s_smoke2
+ 3A39:1C2A idle  _s_smoke3
+ 3A39:1C3A idle  _s_smoke4
+ 3A39:23BA       _s_sschase1
+ 3A39:23CA idle  _s_sschase1s
+ 3A39:23DA idle  _s_sschase2
+ 3A39:23EA idle  _s_sschase3
+ 3A39:23FA idle  _s_sschase3s
+ 3A39:240A idle  _s_sschase4
+ 3A39:241A       _s_ssdie1
+ 3A39:242A idle  _s_ssdie2
+ 3A39:243A idle  _s_ssdie3
+ 3A39:244A idle  _s_ssdie4
+ 3A39:230A       _s_sspain
+ 3A39:231A       _s_sspain1
+ 3A39:22AA idle  _s_sspath1
+ 3A39:22BA idle  _s_sspath1s
+ 3A39:22CA idle  _s_sspath2
+ 3A39:22DA idle  _s_sspath3
+ 3A39:22EA idle  _s_sspath3s
+ 3A39:22FA idle  _s_sspath4
+ 3A39:232A idle  _s_ssshoot1
+ 3A39:233A idle  _s_ssshoot2
+ 3A39:234A idle  _s_ssshoot3
+ 3A39:235A idle  _s_ssshoot4
+ 3A39:236A idle  _s_ssshoot5
+ 3A39:237A idle  _s_ssshoot6
+ 3A39:238A idle  _s_ssshoot7
+ 3A39:239A idle  _s_ssshoot8
+ 3A39:23AA idle  _s_ssshoot9
+ 3A39:229A idle  _s_ssstand
+ 3A39:ECE3       _t0OldService
+ 1201:0342       _TakeDamage
+ 0000:0F95       _tan
+ 3A39:9B89       _tedlevel
+ 3A39:9B87       _tedlevelnum
+ 0000:1926       _tell
+ 3A39:9E9A       _text
+ 0EBC:0F15       _ThreeDRefresh
+ 1201:0A51 idle  _Thrust
+ 3A39:E00D       _thrustspeed
+ 06A5:3570 idle  _TicDelay
+ 3A39:A2CA       _tics
+ 3A39:168C       _tileglobal
+ 3A39:D9B4       _tilehit
+ 3A39:75BA       _tilemap
+ 3A39:9EDE       _TimeCount
+ 060A:00B4 idle  _TimedPicCommand
+ 3A39:ECF3       _TimerCount
+ 3A39:ECF7       _TimerDivisor
+ 3A39:ECDD       _TimerRate
+ 3A39:E824       _tinf
+ 0000:193E       _tolower
+ 0000:196A       _toupper
+ 06A5:1062 idle  _TrackWhichGame
+ 0EBC:004D idle  _TransformActor
+ 0EBC:018B idle  _TransformTile
+ 1201:0794 idle  _TryMove
+ 1087:00D2       _TryWalk
+ 1201:0FEB idle  _T_Attack
+ 13EC:1CA5 idle  _T_Bite
+ 13EC:1EAC idle  _T_BJDone
+ 13EC:1E66 idle  _T_BJJump
+ 13EC:1DD1 idle  _T_BJRun
+ 13EC:1E8C idle  _T_BJYell
+ 13EC:14EC idle  _T_Chase
+ 13EC:17EF idle  _T_DogChase
+ 13EC:1404 idle  _T_Fake
+ 13EC:12E7 idle  _T_FakeFire
+ 13EC:0FCA idle  _T_Fat
+ 13EC:1743 idle  _T_Ghosts
+ 13EC:0E42 idle  _T_Gift
+ 13EC:0B9D idle  _T_GiftThrow
+ 13EC:199D idle  _T_Path
+ 1201:117D idle  _T_Player
+ 13EC:00F3 idle  _T_Projectile
+ 13EC:0CBA idle  _T_Schabb
+ 13EC:0A80 idle  _T_SchabbThrow
+ 13EC:1ACC idle  _T_Shoot
+ 13EC:14DC idle  _T_Stand
+ 0000:38AA       _ultoa
+ 3A39:E87C       _UMBbase
+ 06A5:2D2F       _UnCacheLump
+ 0000:1996       _unlink
+ 3A39:54B6       _update
+ 1201:025B idle  _UpdateFace
+ 0CFC:0CE0 idle  _UpdatePaletteShifts
+ 3A39:9B79       _updateptr
+ 0BC6:0148       _UpdateSoundLoc
+ 3A39:3D16 idle  _USL_DrawString
+ 1BF0:0008 idle  _USL_HardError
+ 3A39:3D12       _USL_MeasureString
+ 1BF0:03C2 idle  _USL_PrintInCenter
+ 1BF0:0669 idle  _US_CenterWindow
+ 1BF0:020F       _US_CheckParm
+ 1BF0:0528       _US_ClearWindow
+ 06A5:0004       _US_ControlPanel
+ 1BF0:04BF       _US_CPrint
+ 1BF0:0462 idle  _US_CPrintLine
+ 1BF0:0553       _US_DrawWindow
+ 1CAA:0010       _US_InitRndT
+ 1BF0:0782       _US_LineInput
+ 1BF0:02D4       _US_Print
+ 1BF0:0420       _US_PrintCentered
+ 1BF0:039D idle  _US_PrintSigned
+ 1BF0:0378       _US_PrintUnsigned
+ 1BF0:06BA idle  _US_RestoreWindow
+ 1CAA:0038       _US_RndT
+ 1BF0:068D idle  _US_SaveWindow
+ 1BF0:02B5 idle  _US_SetPrintRoutines
+ 1BF0:01FD       _US_Shutdown
+ 1BF0:0131       _US_Startup
+ 3A39:9B5F       _uwidthtable
+ 3A39:53AA       _vertwall
+ 3A39:1698 idle  _vgaCeiling
+ 0EBC:0A0B idle  _VGAClearScreen
+ 1E19:0006       _VH_UpdateScreen
+ 0A85:0031       _Victory
+ 1201:0F2E idle  _VictorySpin
+ 1201:0A41 idle  _VictoryTile
+ 3A39:DDE0       _viewangle
+ 3A39:503A       _viewcos
+ 3A39:52CE       _viewheight
+ 3A39:503E       _viewsin
+ 3A39:54AA       _viewsize
+ 3A39:D9CC       _viewtx
+ 3A39:D9CA       _viewty
+ 3A39:D84E       _viewtype
+ 3A39:52D0       _viewwidth
+ 3A39:5046       _viewx
+ 3A39:5042       _viewy
+ 3A39:9890       _virtualreality
+ 3A39:D86E       _vislist
+ 3A39:D86C       _visptr
+ 3A39:D86A       _visstep
+ 1CAF:0646       _VL_Bar
+ 1CAF:0092 idle  _VL_ClearVideo
+ 1CAF:04A5       _VL_ColorBorder
+ 1CAF:00BC idle  _VL_DePlaneVGA
+ 1CAF:0A5B idle  _VL_DrawLatch8String
+ 1CAF:092E idle  _VL_DrawTile8String
+ 1CAF:0374       _VL_FadeIn
+ 1CAF:0256       _VL_FadeOut
+ 1CAF:0198 idle  _VL_FillPalette
+ 1CAF:01D8 idle  _VL_GetColor
+ 1CAF:0235 idle  _VL_GetPalette
+ 1CAF:0504       _VL_Hlin
+ 1CAF:08C5       _VL_LatchToScreen
+ 1CAF:0837 idle  _VL_MaskedToScreen
+ 1CAF:0749       _VL_MemToLatch
+ 1CAF:079C       _VL_MemToScreen
+ 1D62:022E       _VL_MungePic
+ 1CAF:04B9       _VL_Plot
+ 1DF0:00AA       _VL_ScreenToScreen
+ 1CAF:01BD idle  _VL_SetColor
+ 1DF0:0019 idle  _VL_SetCRTC
+ 1CAF:0113 idle  _VL_SetLineWidth
+ 1CAF:0203       _VL_SetPalette
+ 1DF0:003D       _VL_SetScreen
+ 1CAF:014C idle  _VL_SetSplitScreen
+ 1CAF:0088 idle  _VL_SetTextMode
+ 1CAF:0065       _VL_SetVGAPlaneMode
+ 1CAF:005B       _VL_Shutdown
+ 1CAF:0B07 idle  _VL_SizeTile8String
+ 1CAF:0003       _VL_Startup
+ 1CAF:044A       _VL_TestPaletteSet
+ 1DF0:012A       _VL_VideoID
+ 1CAF:05DF       _VL_Vlin
+ 1DF0:0002       _VL_WaitVBL
+ 0000:404A idle  _vsprintf
+ 1D62:0556       _VWB_Bar
+ 1D62:04B3       _VWB_DrawPic
+ 1D62:051F       _VWB_DrawPropString
+ 1D62:042B       _VWB_DrawTile8
+ 1D62:046E idle  _VWB_DrawTile8M
+ 1D62:05BD       _VWB_Hlin
+ 1D62:0592       _VWB_Plot
+ 1D62:05F1       _VWB_Vlin
+ 1D62:02EC idle  _VWL_MeasureString
+ 1D62:0113 idle  _VW_DrawColorPropString
+ 1D62:0000 idle  _VW_DrawPropString
+ 1D62:0370       _VW_MarkUpdateBlock
+ 1D62:034E idle  _VW_MeasureMPropString
+ 1D62:032C       _VW_MeasurePropString
+ 1D62:0625       _VW_UpdateScreen
+ 06A5:36AC idle  _WaitKeyUp
+ 3A39:504A       _wallheight
+ 0EBC:0E24 idle  _WallRefresh
+ 3A39:1710 idle  _weaponscale
+ 0000:31E7 idle  _wherex
+ 0000:31F6 idle  _wherey
+ 358C:0000       _whiteshifts
+ 3A39:A046       _WindowH
+ 3A39:9B7B       _WindowW
+ 3A39:9B7F       _WindowX
+ 3A39:9B7D       _WindowY
+ 3A39:177A idle  _wordmasks
+ 3A39:DDF5       _work
+ 0000:4320       _write
+ 0A85:046A       _Write
+ 048F:020F idle  _WriteConfig
+ 3A39:D9A6       _xintercept
+ 3A39:D9B8       _xinttile
+ 3A39:E892       _XMSaddr
+ 3A39:E8D2       _XMSAvail
+ 3A39:E8CC       _XMSDriver
+ 3A39:E8D0       _XMSHandle
+ 3A39:A296       _XMSPagesAvail
+ 3A39:E8C4       _XMSPagesUsed
+ 3A39:A29A       _XMSPresent
+ 3A39:3510 idle  _XMSProtectPage
+ 3A39:D9C4       _xpartial
+ 3A39:D9BE       _xpartialdown
+ 3A39:D9C0       _xpartialup
+ 3A39:D99E       _xstep
+ 3A39:D9B0       _xtile
+ 3A39:D9AC       _xtilestep
+ 3A39:D9A2       _yintercept
+ 3A39:D9B6       _yinttile
+ 3A39:EE17       _ylookup
+ 3A39:D9C2       _ypartial
+ 3A39:D9BA       _ypartialdown
+ 3A39:D9BC       _ypartialup
+ 3A39:D99A       _ystep
+ 3A39:D9AE       _ytile
+ 3A39:D9AA       _ytilestep
+ 3A39:4090       __8087
+ 0000:1000 idle  __AHINCR
+ 0000:000C idle  __AHSHIFT
+ 3A39:4724       __argc
+ 3A39:4726       __argv
+ 3A39:4380       __atexitcnt
+ 3A39:4944       __atexittbl
+ 0000:268A       __brk
+ 3A39:00D1       __brklvl
+ 3A39:00B3       __C0argc
+ 3A39:00B5       __C0argv
+ 0000:20DD idle  __c0crtinit
+ 3A39:00B7       __C0environ
+ 0000:128F idle  __cexit
+ 0000:0189       __checknull
+ 0000:3296       __chmod
+ 0000:0176       __cleanup
+ 0000:32D9       __close
+ 0000:20FA idle  __crtinit
+ 3A39:4382       __ctype
+ 0000:0000  Abs  __cvtfak
+ 0000:129D idle  __c_exit
+ 3A39:40A4       __default87
+ 3A39:4602       __doserrno
+ 0000:14EF       __DOSERROR
+ 3A39:4604 idle  __dosErrorToSV
+ 0000:11C1 idle  __dos_getdate
+ 0000:4486       __dos_getdiskfree
+ 0000:1189       __dos_getfileattr
+ 0000:11DA       __dos_gettime
+ 0000:11A6 idle  __dos_setfileattr
+ 0000:11F3       __dos_write
+ 3A39:4270       __emu
+ 3A39:00B9       __envLng
+ 3A39:00BB       __envseg
+ 3A39:00BD       __envSize
+ 0000:127D       __exit
+ 3A39:4484       __exitbuf
+ 3A39:4488       __exitfopen
+ 3A39:448C       __exitopen
+ 3A39:471E idle  __first
+ 0000:8087 idle  __floatconvert
+ 0000:436E       __fmemcmp
+ 0000:4396       __fmemcpy
+ 0000:43DE       __fmemset
+ 3A39:45FA       __fmode
+ 0000:0DAA       __fperror
+ 3A39:45FE       __fpstklen
+ 0000:05E4       __fpuint
+ 0000:3B11 idle  __fputc
+ 0000:3C70       __FPUTN
+ 0000:43BA idle  __fsetmem
+ 0000:43FD       __fstrcpy
+ 0000:4426       __fstricmp
+ 0000:4467       __fstrlen
+ 0000:36B1 idle  __GETFP
+ 0000:2933 idle  __harderr
+ 0000:295F       __hardresume
+ 0000:297A       __hardretn
+ 3A39:00CD       __heapbase
+ 3A39:4600       __heaplen
+ 3A39:00D5       __heaptop
+ 3A39:40AA       __huge_dble
+ 3A39:40A6 idle  __huge_flt
+ 3A39:40B2 idle  __huge_ldble
+ 3A39:40BC idle  __indefinite
+ 3A39:00A3 idle  __Int0Vector
+ 3A39:00A7 idle  __Int4Vector
+ 3A39:00AB idle  __Int5Vector
+ 3A39:00AF idle  __Int6Vector
+ 0000:14B6       __IOERROR
+ 3A39:4720 idle  __last
+ 3A39:40A1       __LDT
+ 0000:05F5       __LDTRUNC
+ 0000:1512       __LONGTOA
+ 0000:0FE5       __matherr
+ 3A39:40CA       __mathwhy
+ 0000:15D5       __MKNAME
+ 0000:02B0 idle  __MMODEL
+ 3A39:45D0       __nfile
+ 3A39:45FC       __notUmask
+ 0000:3AAD       __open
+ 3A39:45D2       __openfd
+ 0000:3615 idle  __OPENFP
+ 3A39:00C1       __osmajor
+ 3A39:00C2 idle  __osminor
+ 3A39:00C1 idle  __osversion
+ 0000:0E4E       __POW10
+ 3A39:40A0       __protected
+ 3A39:00BF       __psp
+ 0000:16AA       __read
+ 0000:2D18       __REALCVT
+ 3A39:473A       __RealCvtVector
+ 0000:020A       __restorezero
+ 3A39:4722 idle  __rover
+ 0000:26C9       __sbrk
+ 3A39:473E idle  __ScanTodVector
+ 0000:1702       __scantol
+ 0000:2E48       __SCREENIO
+ 0000:2EE9       __SCROLL
+ 0000:0000 idle  __setargv__
+ 0000:0000 idle  __setenvp__
+ 0000:1881       __setupio
+ 3A39:00C5 idle  __StartTime
+ 3A39:4668       __stklen
+ 0000:1F2B       __stpcpy
+ 3A39:4490       __streams
+ 0000:01B4       __terminate
+ 3A39:40C0 idle  __tiny_ldble
+ 0000:1614 idle  __TMPNAM
+ 0000:0000 idle  __turboCrt
+ 0000:0000  Abs  __turboCvt
+ 0000:8087  Abs  __turboFloat
+ 0000:158F       __UTOA
+ 0000:2E84       __VALIDATEXY
+ 3A39:00C1       __version
+ 3A39:46D2       __video
+ 0000:2059       __VideoInt
+ 0000:19C4       __VPRINTER
+ 0000:1E72       __VPTR
+ 0000:1E97       __VRAM
+ 0000:31DD       __wherexy
+ 0000:42E6       __write
+ 0000:1F11       __xclose
+ 0000:0BA5       __XCVT
+ 0000:4323       __xfclose
+ 0000:434B       __xfflush
+ 0000:1F79       ___brk
+ 3A39:00CB       ___brklvl
+ 0000:21F3 idle  ___first
+ 0000:04FD idle  ___fpreset
+ 0000:2907       ___harderr
+ 3A39:00C9 idle  ___heapbase
+ 0000:21F5 idle  ___last
+ 0000:3E5E       ___read
+ 0000:21F7 idle  ___rover
+ 0000:1F9B       ___sbrk
+ 3A39:49D2       ___SignalPtr
+ 0000:41DA       ___write
+
+  Address         Publics by Value
+
+ 0000:0000  Abs  __turboCvt
+ 0000:0000 idle  __turboCrt
+ 0000:0000  Abs  __cvtfak
+ 0000:0000 idle  __setargv__
+ 0000:0000 idle  __setenvp__
+ 0000:000C idle  __AHSHIFT
+ 0000:0632 idle  FISRQQ
+ 0000:0E32 idle  FICRQQ
+ 0000:1000 idle  __AHINCR
+ 0000:1632  Abs  FIERQQ
+ 0000:4000 idle  FJARQQ
+ 0000:5C32  Abs  FIDRQQ
+ 0000:8000 idle  FJSRQQ
+ 0000:8087  Abs  __turboFloat
+ 0000:8087 idle  __floatconvert
+ 0000:A23D  Abs  FIWRQQ
+ 0000:C000 idle  FJCRQQ
+ 0000:FE32 idle  FIARQQ
+ 0000:0176       __cleanup
+ 0000:0189       __checknull
+ 0000:01B4       __terminate
+ 0000:020A       __restorezero
+ 0000:0296       _abort
+ 0000:02AE idle  DGROUP@
+ 0000:02B0 idle  __MMODEL
+ 0000:02B2 idle  N_LDIV@
+ 0000:02B5       LDIV@
+ 0000:02B5       F_LDIV@
+ 0000:02D1 idle  N_LUDIV@
+ 0000:02D4 idle  F_LUDIV@
+ 0000:02D4 idle  LUDIV@
+ 0000:02D9 idle  N_LMOD@
+ 0000:02DC       F_LMOD@
+ 0000:02DC idle  LMOD@
+ 0000:02E1 idle  N_LUMOD@
+ 0000:02E4 idle  LUMOD@
+ 0000:02E4 idle  F_LUMOD@
+ 0000:04FD idle  ___fpreset
+ 0000:05E4       __fpuint
+ 0000:05E8       _atan
+ 0000:05F5       __LDTRUNC
+ 0000:0BA5       __XCVT
+ 0000:0DAA       __fperror
+ 0000:0E4E       __POW10
+ 0000:0F17       _pow10
+ 0000:0F22       _matherr
+ 0000:0F48       _sin
+ 0000:0F95       _tan
+ 0000:0FE5       __matherr
+ 0000:1075       _atan2
+ 0000:1130       F_FTOL@
+ 0000:1130 idle  FTOL@
+ 0000:115C idle  _atexit
+ 0000:1189       __dos_getfileattr
+ 0000:11A6 idle  __dos_setfileattr
+ 0000:11C1 idle  __dos_getdate
+ 0000:11DA       __dos_gettime
+ 0000:11F3       __dos_write
+ 0000:126E       _exit
+ 0000:127D       __exit
+ 0000:128F idle  __cexit
+ 0000:129D idle  __c_exit
+ 0000:12A9       F_LXMUL@
+ 0000:12A9 idle  LXMUL@
+ 0000:12C0       F_PCMP@
+ 0000:12C0 idle  PCMP@
+ 0000:12E1       F_SCOPY@
+ 0000:12E1 idle  SCOPY@
+ 0000:12FD       _getvect
+ 0000:130C       _setvect
+ 0000:131D       N_LXLSH@
+ 0000:1320       F_LXLSH@
+ 0000:1320 idle  LXLSH@
+ 0000:133E idle  N_LXRSH@
+ 0000:1341       F_LXRSH@
+ 0000:1341 idle  LXRSH@
+ 0000:135E idle  N_LXURSH@
+ 0000:1361       F_LXURSH@
+ 0000:1361 idle  LXURSH@
+ 0000:137F idle  N_PADA@
+ 0000:1382       F_PADA@
+ 0000:1382 idle  PADA@
+ 0000:13C3 idle  N_PSBA@
+ 0000:13C6       F_PSBA@
+ 0000:13C6 idle  PSBA@
+ 0000:1407       N_PADD@
+ 0000:140A       F_PADD@
+ 0000:140A idle  PADD@
+ 0000:1436 idle  N_PSUB@
+ 0000:1439 idle  F_PSUB@
+ 0000:1439 idle  PSUB@
+ 0000:1467       N_PSBP@
+ 0000:146A       F_PSBP@
+ 0000:146A idle  PSBP@
+ 0000:148F idle  N_SPUSH@
+ 0000:1495       F_SPUSH@
+ 0000:1495 idle  SPUSH@
+ 0000:14B6       __IOERROR
+ 0000:14EF       __DOSERROR
+ 0000:1501       _isatty
+ 0000:1512       __LONGTOA
+ 0000:158F       __UTOA
+ 0000:15AC       _lseek
+ 0000:15D5       __MKNAME
+ 0000:1614 idle  __TMPNAM
+ 0000:1657       N_PCMP@
+ 0000:1678       _outport
+ 0000:1684 idle  _outportb
+ 0000:1690 idle  _outpw
+ 0000:169C idle  _outp
+ 0000:16AA       __read
+ 0000:1702       __scantol
+ 0000:1881       __setupio
+ 0000:1926       _tell
+ 0000:193E       _tolower
+ 0000:196A       _toupper
+ 0000:1996       _unlink
+ 0000:19C4       __VPRINTER
+ 0000:1E72       __VPTR
+ 0000:1E97       __VRAM
+ 0000:1F11       __xclose
+ 0000:1F2B       __stpcpy
+ 0000:1F54       _bioskey
+ 0000:1F79       ___brk
+ 0000:1F9B       ___sbrk
+ 0000:1FCC idle  _brk
+ 0000:1FD8 idle  _sbrk
+ 0000:1FE8       _clrscr
+ 0000:2011       _coreleft
+ 0000:2059       __VideoInt
+ 0000:20DD idle  __c0crtinit
+ 0000:20FA idle  __crtinit
+ 0000:21F3 idle  ___first
+ 0000:21F5 idle  ___last
+ 0000:21F7 idle  ___rover
+ 0000:2333       _farfree
+ 0000:243D       _farmalloc
+ 0000:259A idle  _farrealloc
+ 0000:268A       __brk
+ 0000:26C9       __sbrk
+ 0000:2757       _farcoreleft
+ 0000:27A7       _gotoxy
+ 0000:27F0       _gettext
+ 0000:2844       _puttext
+ 0000:2885       _harderr
+ 0000:2897 idle  _hardresume
+ 0000:28A5 idle  _hardretn
+ 0000:2907       ___harderr
+ 0000:2933 idle  __harderr
+ 0000:295F       __hardresume
+ 0000:297A       __hardretn
+ 0000:29D9       _ioctl
+ 0000:2A00       _movetext
+ 0000:2A9D       _free
+ 0000:2B6C       _malloc
+ 0000:2CC5 idle  _realloc
+ 0000:2D18       __REALCVT
+ 0000:2E48       __SCREENIO
+ 0000:2E84       __VALIDATEXY
+ 0000:2EE9       __SCROLL
+ 0000:3164       _setblock
+ 0000:31DD       __wherexy
+ 0000:31E7 idle  _wherex
+ 0000:31F6 idle  _wherey
+ 0000:3209       _atol
+ 0000:3279 idle  _atoi
+ 0000:3286       _bdos
+ 0000:3296       __chmod
+ 0000:32B1       _close
+ 0000:32D9       __close
+ 0000:3310       _creat
+ 0000:3382       _fclose
+ 0000:33FF       _fflush
+ 0000:3480       _findfirst
+ 0000:34B3       _findnext
+ 0000:34E0       _filelength
+ 0000:3521       _flushall
+ 0000:3615 idle  __OPENFP
+ 0000:36B1 idle  __GETFP
+ 0000:36DC       _fopen
+ 0000:36FB       _fprintf
+ 0000:376E       _fseek
+ 0000:37D6 idle  _ftell
+ 0000:3823       _getenv
+ 0000:3882       _itoa
+ 0000:38AA       _ultoa
+ 0000:38C4       _ltoa
+ 0000:38E9       _memcpy
+ 0000:3908       _movedata
+ 0000:3955       _open
+ 0000:3AAD       __open
+ 0000:3AFA       _printf
+ 0000:3B11 idle  __fputc
+ 0000:3B2A       _fputc
+ 0000:3C5E idle  _fputchar
+ 0000:3C70       __FPUTN
+ 0000:3E13       _puts
+ 0000:3E5E       ___read
+ 0000:3F2C       _read
+ 0000:3F2F       _setvbuf
+ 0000:402D       _sprintf
+ 0000:404A idle  _vsprintf
+ 0000:4066       _strcat
+ 0000:409F       _strcpy
+ 0000:40C1       _strlen
+ 0000:4105       _strtol
+ 0000:41DA       ___write
+ 0000:42E6       __write
+ 0000:4320       _write
+ 0000:4323       __xfclose
+ 0000:434B       __xfflush
+ 0000:436E       __fmemcmp
+ 0000:4396       __fmemcpy
+ 0000:43BA idle  __fsetmem
+ 0000:43DE       __fmemset
+ 0000:43FD       __fstrcpy
+ 0000:4426       __fstricmp
+ 0000:4467       __fstrlen
+ 0000:4486       __dos_getdiskfree
+ 044B:000C idle  _FixedMul
+ 044B:0034 idle  _DrawSpans
+ 044B:0179 idle  _SetPlaneViewSize
+ 044B:027E idle  _DrawPlanes
+ 0485:0008       _MapRow
+ 048C:0000       _CheckIs386
+ 048C:0028       _jabhack2
+ 048F:000B idle  _ReadConfig
+ 048F:020F idle  _WriteConfig
+ 048F:030D idle  _Patch386
+ 048F:0369       _NewGame
+ 048F:03BA idle  _DiskFlopAnim
+ 048F:03E9 idle  _DoChecksum
+ 048F:042E       _SaveTheGame
+ 048F:0803       _LoadTheGame
+ 048F:0BD2       _ShutdownId
+ 048F:0BFA idle  _BuildTables
+ 048F:0D49 idle  _CalcProjection
+ 048F:0E7C idle  _SetupWalls
+ 048F:0E9F idle  _SignonScreen
+ 048F:0F21 idle  _FinishSignon
+ 048F:0FBA       _MS_CheckParm
+ 048F:1020 idle  _InitDigiMap
+ 048F:1041 idle  _DoJukebox
+ 048F:122A idle  _InitGame
+ 048F:13BC       _SetViewSize
+ 048F:1442       _ShowViewSize
+ 048F:148B       _NewViewSize
+ 048F:14CF       _Quit
+ 048F:159A idle  _DemoLoop
+ 048F:179C       _main
+ 060A:000C idle  _RipToEOL
+ 060A:001F idle  _ParseNumber
+ 060A:0071 idle  _ParsePicCommand
+ 060A:008F idle  _ParseTimedCommand
+ 060A:00B4 idle  _TimedPicCommand
+ 060A:00F7 idle  _HandleCommand
+ 060A:034C idle  _NewLine
+ 060A:03A7 idle  _HandleCtrls
+ 060A:03C7 idle  _HandleWord
+ 060A:0475 idle  _PageLayout
+ 060A:0660 idle  _BackPage
+ 060A:068A idle  _CacheLayoutGraphics
+ 060A:0771 idle  _ShowArticle
+ 060A:0885 idle  _HelpScreens
+ 060A:090C       _EndText
+ 06A5:0004       _US_ControlPanel
+ 06A5:01BE idle  _DrawMainMenu
+ 06A5:025E idle  _BossKey
+ 06A5:02A8 idle  _CP_CheckQuick
+ 06A5:079D idle  _CP_EndGame
+ 06A5:07F3       _CP_ViewScores
+ 06A5:0851 idle  _CP_NewGame
+ 06A5:098F idle  _DrawNewEpisode
+ 06A5:0A3C idle  _DrawNewGame
+ 06A5:0AC6 idle  _DrawNewGameDiff
+ 06A5:0ADF idle  _CP_Sound
+ 06A5:0C70 idle  _DrawSoundMenu
+ 06A5:0E5E idle  _DrawLSAction
+ 06A5:0EDA idle  _CP_LoadGame
+ 06A5:1062 idle  _TrackWhichGame
+ 06A5:1089 idle  _DrawLoadSaveScreen
+ 06A5:112F idle  _PrintLSEntry
+ 06A5:11BB idle  _CP_SaveGame
+ 06A5:148E idle  _CalibrateJoystick
+ 06A5:16A9 idle  _CP_Control
+ 06A5:17AE idle  _DrawMouseSens
+ 06A5:18B2 idle  _MouseSensitivity
+ 06A5:1A9B idle  _DrawCtlScreen
+ 06A5:1C5A idle  _CustomControls
+ 06A5:1CFB idle  _DefineMouseBtns
+ 06A5:1D37 idle  _DefineJoyBtns
+ 06A5:1D73 idle  _DefineKeyBtns
+ 06A5:1DAF idle  _DefineKeyMove
+ 06A5:1DEB idle  _EnterCtrlData
+ 06A5:2237 idle  _FixupCustom
+ 06A5:23A7 idle  _DrawCustomScreen
+ 06A5:266D idle  _PrintCustMouse
+ 06A5:26B7 idle  _DrawCustMouse
+ 06A5:2714 idle  _PrintCustJoy
+ 06A5:275E idle  _DrawCustJoy
+ 06A5:27BB idle  _PrintCustKeybd
+ 06A5:27F2 idle  _DrawCustKeybd
+ 06A5:2824 idle  _PrintCustKeys
+ 06A5:285A idle  _DrawCustKeys
+ 06A5:288C idle  _CP_ChangeView
+ 06A5:29FF idle  _DrawChangeView
+ 06A5:2A7D idle  _CP_Quit
+ 06A5:2B04       _IntroScreen
+ 06A5:2CF7       _ClearMScreen
+ 06A5:2D10       _CacheLump
+ 06A5:2D2F       _UnCacheLump
+ 06A5:2D6E       _DrawWindow
+ 06A5:2DA4 idle  _DrawOutline
+ 06A5:2E09 idle  _SetupControlPanel
+ 06A5:2F07 idle  _CleanupControlPanel
+ 06A5:2F1D       _HandleMenu
+ 06A5:3407 idle  _EraseGun
+ 06A5:347E idle  _DrawHalfStep
+ 06A5:34BE idle  _DrawGun
+ 06A5:3570 idle  _TicDelay
+ 06A5:35AC       _DrawMenu
+ 06A5:3677 idle  _SetTextColor
+ 06A5:36AC idle  _WaitKeyUp
+ 06A5:36DC idle  _ReadAnyControl
+ 06A5:3839 idle  _Confirm
+ 06A5:3960       _Message
+ 06A5:3A8F       _StartCPMusic
+ 06A5:3B16       _FreeMusic
+ 06A5:3B39 idle  _IN_GetScanName
+ 06A5:3B7D idle  _CheckPause
+ 06A5:3BBD idle  _DrawMenuGun
+ 06A5:3BF0       _DrawStripes
+ 06A5:3C21 idle  _ShootSnd
+ 06A5:3C30       _CheckForEpisodes
+ 0A85:0004       _ClearSplitVWB
+ 0A85:0031       _Victory
+ 0A85:03CC       _PG13
+ 0A85:046A       _Write
+ 0A85:056F idle  _BJ_Breathe
+ 0A85:05D1       _LevelCompleted
+ 0A85:0F10 idle  _PreloadUpdate
+ 0A85:0FA5       _PreloadGraphics
+ 0A85:1041       _DrawHighScores
+ 0A85:120F       _CheckHighScore
+ 0A85:1353 idle  _NonShareware
+ 0BC6:0006 idle  _SetSoundLoc
+ 0BC6:00F7       _PlaySoundLocGlobal
+ 0BC6:0148       _UpdateSoundLoc
+ 0BC6:017B       _ClearMemory
+ 0BC6:0194 idle  _ScanInfoPlane
+ 0BC6:0683       _SetupGameLevel
+ 0BC6:0930 idle  _DrawPlayBorderSides
+ 0BC6:09BA       _DrawAllPlayBorderSides
+ 0BC6:09E5       _DrawAllPlayBorder
+ 0BC6:0A11       _DrawPlayBorder
+ 0BC6:0ADB       _DrawPlayScreen
+ 0BC6:0B76 idle  _StartDemoRecord
+ 0BC6:0BC7 idle  _FinishDemoRecord
+ 0BC6:0C9A       _RecordDemo
+ 0BC6:0DD1       _PlayDemo
+ 0BC6:0F34 idle  _Died
+ 0BC6:1162       _GameLoop
+ 0CFC:0007 idle  _PollKeyboardButtons
+ 0CFC:002B idle  _PollMouseButtons
+ 0CFC:006F idle  _PollJoystickButtons
+ 0CFC:0100 idle  _PollKeyboardMove
+ 0CFC:020C idle  _PollMouseMove
+ 0CFC:0248 idle  _PollJoystickMove
+ 0CFC:03B9 idle  _PollControls
+ 0CFC:05E6       _CenterWindow
+ 0CFC:0614 idle  _CheckKeys
+ 0CFC:09B0       _InitActorList
+ 0CFC:09F4       _GetNewActor
+ 0CFC:0A55 idle  _RemoveObj
+ 0CFC:0AA3       _StopMusic
+ 0CFC:0AD6       _StartMusic
+ 0CFC:0B4C       _InitRedShifts
+ 0CFC:0CBC idle  _ClearPaletteShifts
+ 0CFC:0CC9       _StartBonusFlash
+ 0CFC:0CD4       _StartDamageFlash
+ 0CFC:0CE0 idle  _UpdatePaletteShifts
+ 0CFC:0DD6       _FinishPaletteShifts
+ 0CFC:0E00 idle  _DoActor
+ 0CFC:0F8C       _PlayLoop
+ 0E0D:000D idle  _DebugMemory
+ 0E0D:00C2 idle  _CountObjects
+ 0E0D:01B3       _PicturePause
+ 0E0D:02C5 idle  _ShapeTest
+ 0E0D:076C       _DebugKeys
+ 0EBC:000F       _FixedByFrac
+ 0EBC:004D idle  _TransformActor
+ 0EBC:018B idle  _TransformTile
+ 0EBC:02F9 idle  _CalcHeight
+ 0EBC:0397 idle  _ScalePost
+ 0EBC:040A       _FarScalePost
+ 0EBC:0412       _HitVertWall
+ 0EBC:0531       _HitHorizWall
+ 0EBC:0653       _HitHorizDoor
+ 0EBC:0753       _HitVertDoor
+ 0EBC:0857       _HitHorizPWall
+ 0EBC:0931       _HitVertPWall
+ 0EBC:0A0B idle  _VGAClearScreen
+ 0EBC:0A73 idle  _CalcRotate
+ 0EBC:0AEF idle  _DrawScaleds
+ 0EBC:0D02 idle  _DrawPlayerWeapon
+ 0EBC:0D9E       _CalcTics
+ 0EBC:0E01       _FixOfs
+ 0EBC:0E24 idle  _WallRefresh
+ 0EBC:0F15       _ThreeDRefresh
+ 0FB8:0072       _AsmRefresh
+ 0FFD:000A idle  _BadScale
+ 0FFD:001A       _SetupScaling
+ 0FFD:01DB idle  _BuildCompScale
+ 0FFD:032F idle  _ScaleLine
+ 0FFD:0479       _ScaleShape
+ 0FFD:078D       _SimpleScaleShape
+ 1087:000C       _SpawnNewObj
+ 1087:00BA       _NewState
+ 1087:00D2       _TryWalk
+ 1087:0619       _SelectDodgeDir
+ 1087:0747       _SelectChaseDir
+ 1087:089F       _SelectRunDir
+ 1087:0967       _MoveObj
+ 1087:0B99 idle  _DropItem
+ 1087:0C2C idle  _KillActor
+ 1087:0EF2       _DamageActor
+ 1087:0FED       _CheckLine
+ 1087:1291 idle  _CheckSight
+ 1087:138E idle  _FirstSighting
+ 1087:167A       _SightPlayer
+ 1201:0005 idle  _CheckWeaponChange
+ 1201:0039 idle  _ControlMovement
+ 1201:01A8 idle  _StatusDrawPic
+ 1201:01FF       _DrawFace
+ 1201:025B idle  _UpdateFace
+ 1201:02A1 idle  _LatchNumber
+ 1201:032A       _DrawHealth
+ 1201:0342       _TakeDamage
+ 1201:039B       _HealSelf
+ 1201:03C2       _DrawLevel
+ 1201:03DB       _DrawLives
+ 1201:03F3 idle  _GiveExtraMan
+ 1201:0411       _DrawScore
+ 1201:042B       _GivePoints
+ 1201:0468       _DrawWeapon
+ 1201:047F       _DrawKeys
+ 1201:04CC       _GiveWeapon
+ 1201:04F5       _DrawAmmo
+ 1201:050D idle  _GiveAmmo
+ 1201:0542 idle  _GiveKey
+ 1201:0557       _GetBonus
+ 1201:0794 idle  _TryMove
+ 1201:091D idle  _ClipMove
+ 1201:0A41 idle  _VictoryTile
+ 1201:0A51 idle  _Thrust
+ 1201:0B37 idle  _Cmd_Fire
+ 1201:0B89 idle  _Cmd_Use
+ 1201:0CCC       _SpawnPlayer
+ 1201:0D6B idle  _KnifeAttack
+ 1201:0DFF idle  _GunAttack
+ 1201:0F2E idle  _VictorySpin
+ 1201:0FEB idle  _T_Attack
+ 1201:117D idle  _T_Player
+ 1320:000F       _InitStaticList
+ 1320:001A       _SpawnStatic
+ 1320:00E1       _PlaceItemType
+ 1320:016B idle  _RecursiveConnect
+ 1320:01B7 idle  _ConnectAreas
+ 1320:01F0       _InitAreas
+ 1320:0218       _InitDoorList
+ 1320:024B       _SpawnDoor
+ 1320:0340       _OpenDoor
+ 1320:0369 idle  _CloseDoor
+ 1320:05BD       _OperateDoor
+ 1320:0631 idle  _DoorOpen
+ 1320:065F idle  _DoorOpening
+ 1320:07B9 idle  _DoorClosing
+ 1320:08E8       _MoveDoors
+ 1320:093B       _PushWall
+ 1320:0AC9       _MovePWalls
+ 13EC:000C idle  _A_Smoke
+ 13EC:005A idle  _ProjectileTryMove
+ 13EC:00F3 idle  _T_Projectile
+ 13EC:0312       _SpawnStand
+ 13EC:04BA       _SpawnDeadGuard
+ 13EC:04D9       _SpawnBoss
+ 13EC:052B       _SpawnGretel
+ 13EC:057D       _SpawnPatrol
+ 13EC:072D       _A_DeathScream
+ 13EC:08C5       _SpawnGhosts
+ 13EC:094B       _SpawnSchabbs
+ 13EC:09B2       _SpawnGift
+ 13EC:0A19       _SpawnFat
+ 13EC:0A80 idle  _T_SchabbThrow
+ 13EC:0B9D idle  _T_GiftThrow
+ 13EC:0CBA idle  _T_Schabb
+ 13EC:0E42 idle  _T_Gift
+ 13EC:0FCA idle  _T_Fat
+ 13EC:1152       _SpawnFakeHitler
+ 13EC:11B9       _SpawnHitler
+ 13EC:1220 idle  _A_HitlerMorph
+ 13EC:12A8 idle  _A_MechaSound
+ 13EC:12D8 idle  _A_Slurpie
+ 13EC:12E7 idle  _T_FakeFire
+ 13EC:1404 idle  _T_Fake
+ 13EC:14DC idle  _T_Stand
+ 13EC:14EC idle  _T_Chase
+ 13EC:1743 idle  _T_Ghosts
+ 13EC:17EF idle  _T_DogChase
+ 13EC:1951 idle  _SelectPathDir
+ 13EC:199D idle  _T_Path
+ 13EC:1ACC idle  _T_Shoot
+ 13EC:1CA5 idle  _T_Bite
+ 13EC:1D7E       _SpawnBJVictory
+ 13EC:1DD1 idle  _T_BJRun
+ 13EC:1E66 idle  _T_BJJump
+ 13EC:1E8C idle  _T_BJYell
+ 13EC:1EAC idle  _T_BJDone
+ 13EC:1EB7 idle  _CheckPosition
+ 13EC:1F4F idle  _A_StartDeathCam
+ 160F:0008 idle  _GRFILEPOS
+ 160F:0056 idle  _CA_OpenDebug
+ 160F:0077 idle  _CA_CloseDebug
+ 160F:0088 idle  _CAL_GetGrChunkLength
+ 160F:00E4       _CA_FarRead
+ 160F:012F       _CA_FarWrite
+ 160F:017A idle  _CA_ReadFile
+ 160F:01E5       _CA_WriteFile
+ 160F:023B idle  _CA_LoadFile
+ 160F:02B5 idle  _CAL_OptimizeNodes
+ 160F:0300 idle  _CAL_HuffExpand
+ 160F:046B idle  _CAL_CarmackExpand
+ 160F:058F idle  _CA_RLEWCompress
+ 160F:06D7 idle  _CA_RLEWexpand
+ 160F:078E idle  _CAL_SetupGrFile
+ 160F:09C0 idle  _CAL_SetupMapFile
+ 160F:0B75 idle  _CAL_SetupAudioFile
+ 160F:0CAF       _CA_Startup
+ 160F:0CD0       _CA_Shutdown
+ 160F:0CF9       _CA_CacheAudioChunk
+ 160F:0DA1       _CA_LoadAllSounds
+ 160F:0E22 idle  _CAL_ExpandGrChunk
+ 160F:0EF4       _CA_CacheGrChunk
+ 160F:1031       _CA_CacheScreen
+ 160F:111A       _CA_CacheMap
+ 160F:1269       _CA_UpLevel
+ 160F:12A6       _CA_DownLevel
+ 160F:12CC idle  _CA_ClearMarks
+ 160F:12ED idle  _CA_ClearAllMarks
+ 160F:130F idle  _CA_SetGrPurge
+ 160F:1336       _CA_SetAllPurge
+ 160F:135D       _CA_CacheMarks
+ 160F:165E idle  _CA_CannotOpen
+ 177B:0141       _IN_GetJoyAbs
+ 177B:01DA       _INL_GetJoyDelta
+ 177B:0336 idle  _IN_GetJoyButtonsDB
+ 177B:048B       _IN_SetupJoy
+ 177B:0572       _IN_Startup
+ 177B:060E idle  _IN_Default
+ 177B:064D       _IN_Shutdown
+ 177B:0679 idle  _IN_SetKeyHook
+ 177B:068B       _IN_ClearKeysDown
+ 177B:06AA       _IN_ReadControl
+ 177B:09C2 idle  _IN_SetControlType
+ 177B:09D3 idle  _IN_WaitForKey
+ 177B:09EF       _IN_WaitForASCII
+ 177B:0A0A       _IN_StartAck
+ 177B:0A59       _IN_CheckAck
+ 177B:0AB2       _IN_Ack
+ 177B:0AC3       _IN_UserInput
+ 177B:0B04       _IN_MouseButtons
+ 177B:0B1B       _IN_JoyButtons
+ 182E:0000 idle  _MML_CheckForXMS
+ 182E:001B idle  _MML_SetupXMS
+ 182E:0087 idle  _MML_ShutdownXMS
+ 182E:00B6       _MML_UseSpace
+ 182E:0239 idle  _MML_ClearBlock
+ 182E:029A       _MM_Startup
+ 182E:048B       _MM_Shutdown
+ 182E:04B3       _MM_GetPtr
+ 182E:0767       _MM_FreePtr
+ 182E:082B       _MM_SetPurge
+ 182E:08A9       _MM_SetLock
+ 182E:092B       _MM_SortMem
+ 182E:0AE0 idle  _MM_ShowMemory
+ 182E:0C31 idle  _MM_DumpData
+ 182E:0D5B       _MM_UnusedMemory
+ 182E:0DC0       _MM_TotalFree
+ 182E:0E3C       _MM_BombOnError
+ 1912:0007 idle  _PML_MapEMS
+ 1912:0029 idle  _PML_StartupEMS
+ 1912:0155 idle  _PML_ShutdownEMS
+ 1912:0178 idle  _PML_StartupXMS
+ 1912:01EA idle  _PML_XMSCopy
+ 1912:0293 idle  _PML_ShutdownXMS
+ 1912:02B8       _PM_SetMainMemPurge
+ 1912:02DF       _PM_CheckMainMem
+ 1912:03D0 idle  _PML_StartupMainMem
+ 1912:0447 idle  _PML_ShutdownMainMem
+ 1912:046E idle  _PML_ReadFromFile
+ 1912:04E8 idle  _PML_OpenPageFile
+ 1912:06B1 idle  _PML_ClosePageFile
+ 1912:06E8 idle  _PML_GetEMSAddress
+ 1912:07BF       _PM_GetPageAddress
+ 1912:0812 idle  _PML_GiveLRUPage
+ 1912:08B0 idle  _PML_GiveLRUXMSPage
+ 1912:0920 idle  _PML_PutPageInXMS
+ 1912:09C9 idle  _PML_TransferPageSpace
+ 1912:0A96 idle  _PML_GetAPageBuffer
+ 1912:0BA0 idle  _PML_GetPageFromXMS
+ 1912:0C21 idle  _PML_LoadPage
+ 1912:0C71       _PM_GetPage
+ 1912:0D31       _PM_SetPageLock
+ 1912:0D60       _PM_Preload
+ 1912:0FBA       _PM_NextFrame
+ 1912:1034 idle  _PM_Reset
+ 1912:10A0       _PM_Startup
+ 1912:114B       _PM_Shutdown
+ 1A28:0501 idle  _SDL_SBSetDMA
+ 1A28:08B0 idle  _SDL_LoadDigiSegment
+ 1A28:08E1 idle  _SDL_PlayDigiSegment
+ 1A28:092B       _SD_StopDigitized
+ 1A28:09CC       _SD_Poll
+ 1A28:0A58       _SD_SetPosition
+ 1A28:0A9F idle  _SD_PlayDigitized
+ 1A28:0B5F       _SDL_DigitizedDone
+ 1A28:0BC9       _SD_SetDigiDevice
+ 1A28:0C2D idle  _SDL_SetupDigi
+ 1A28:0D03       _alOut
+ 1A28:109B       _SD_SetSoundMode
+ 1A28:1129       _SD_SetMusicMode
+ 1A28:117B       _SD_Startup
+ 1A28:14B4 idle  _SD_Default
+ 1A28:1523       _SD_Shutdown
+ 1A28:157B idle  _SD_SetUserHook
+ 1A28:158D       _SD_PositionSound
+ 1A28:15A4       _SD_PlaySound
+ 1A28:1744       _SD_SoundPlaying
+ 1A28:178B       _SD_StopSound
+ 1A28:17C2       _SD_WaitSoundDone
+ 1A28:17CF       _SD_MusicOn
+ 1A28:17DA       _SD_MusicOff
+ 1A28:181E       _SD_StartMusic
+ 1A28:1870 idle  _SD_FadeOutMusic
+ 1A28:1881 idle  _SD_MusicPlaying
+ 1BB1:000C       _SDL_SetDS
+ 1BB1:0014       _SDL_IndicatePC
+ 1BB1:0021       _SDL_t0ExtremeAsmService
+ 1BB1:009B       _SDL_t0FastAsmService
+ 1BB1:02CD       _SDL_t0SlowAsmService
+ 1BF0:0008 idle  _USL_HardError
+ 1BF0:0131       _US_Startup
+ 1BF0:01FD       _US_Shutdown
+ 1BF0:020F       _US_CheckParm
+ 1BF0:02B5 idle  _US_SetPrintRoutines
+ 1BF0:02D4       _US_Print
+ 1BF0:0378       _US_PrintUnsigned
+ 1BF0:039D idle  _US_PrintSigned
+ 1BF0:03C2 idle  _USL_PrintInCenter
+ 1BF0:0420       _US_PrintCentered
+ 1BF0:0462 idle  _US_CPrintLine
+ 1BF0:04BF       _US_CPrint
+ 1BF0:0528       _US_ClearWindow
+ 1BF0:0553       _US_DrawWindow
+ 1BF0:0669 idle  _US_CenterWindow
+ 1BF0:068D idle  _US_SaveWindow
+ 1BF0:06BA idle  _US_RestoreWindow
+ 1BF0:0782       _US_LineInput
+ 1CAA:0010       _US_InitRndT
+ 1CAA:0038       _US_RndT
+ 1CAF:0003       _VL_Startup
+ 1CAF:005B       _VL_Shutdown
+ 1CAF:0065       _VL_SetVGAPlaneMode
+ 1CAF:0088 idle  _VL_SetTextMode
+ 1CAF:0092 idle  _VL_ClearVideo
+ 1CAF:00BC idle  _VL_DePlaneVGA
+ 1CAF:0113 idle  _VL_SetLineWidth
+ 1CAF:014C idle  _VL_SetSplitScreen
+ 1CAF:0198 idle  _VL_FillPalette
+ 1CAF:01BD idle  _VL_SetColor
+ 1CAF:01D8 idle  _VL_GetColor
+ 1CAF:0203       _VL_SetPalette
+ 1CAF:0235 idle  _VL_GetPalette
+ 1CAF:0256       _VL_FadeOut
+ 1CAF:0374       _VL_FadeIn
+ 1CAF:044A       _VL_TestPaletteSet
+ 1CAF:04A5       _VL_ColorBorder
+ 1CAF:04B9       _VL_Plot
+ 1CAF:0504       _VL_Hlin
+ 1CAF:05DF       _VL_Vlin
+ 1CAF:0646       _VL_Bar
+ 1CAF:0749       _VL_MemToLatch
+ 1CAF:079C       _VL_MemToScreen
+ 1CAF:0837 idle  _VL_MaskedToScreen
+ 1CAF:08C5       _VL_LatchToScreen
+ 1CAF:092E idle  _VL_DrawTile8String
+ 1CAF:0A5B idle  _VL_DrawLatch8String
+ 1CAF:0B07 idle  _VL_SizeTile8String
+ 1D62:0000 idle  _VW_DrawPropString
+ 1D62:0113 idle  _VW_DrawColorPropString
+ 1D62:022E       _VL_MungePic
+ 1D62:02EC idle  _VWL_MeasureString
+ 1D62:032C       _VW_MeasurePropString
+ 1D62:034E idle  _VW_MeasureMPropString
+ 1D62:0370       _VW_MarkUpdateBlock
+ 1D62:042B       _VWB_DrawTile8
+ 1D62:046E idle  _VWB_DrawTile8M
+ 1D62:04B3       _VWB_DrawPic
+ 1D62:051F       _VWB_DrawPropString
+ 1D62:0556       _VWB_Bar
+ 1D62:0592       _VWB_Plot
+ 1D62:05BD       _VWB_Hlin
+ 1D62:05F1       _VWB_Vlin
+ 1D62:0625       _VW_UpdateScreen
+ 1D62:062F       _LatchDrawPic
+ 1D62:0687       _LoadLatchMem
+ 1D62:07A1       _FizzleFade
+ 1DF0:0002       _VL_WaitVBL
+ 1DF0:0019 idle  _VL_SetCRTC
+ 1DF0:003D       _VL_SetScreen
+ 1DF0:00AA       _VL_ScreenToScreen
+ 1DF0:012A       _VL_VideoID
+ 1E19:0006       _VH_UpdateScreen
+ 1E39:2152       e086_Entry
+ 1E39:26E0       e086_Shortcut
+ 20B1:0306       e087_Entry
+ 20B1:03C6       e087_Shortcut
+ 20B1:0430       e087_Trap
+ 210E:0000       _planepics
+ 230E:0002 idle  _rndtable
+ 231F:0000 idle  _MusicMenu
+ 234F:0000 idle  _endStrings
+ 237C:0000       _MainMenu
+ 2394:0000 idle  _SndMenu
+ 23B4:0000 idle  _CtlMenu
+ 23C4:0000 idle  _NewEmenu
+ 23E1:0000 idle  _NewMenu
+ 23EC:0000 idle  _LSMenu
+ 2407:0000 idle  _CusMenu
+ 2422:0000       _signon
+ 33DA:0000       _areaconnect
+ 3430:0000       _sintable
+ 34A1:0000       _finetangent
+ 3582:0000       _grneeded
+ 358C:0000       _whiteshifts
+ 36AC:0000       _redshifts
+ 37CC:0000       _mmblocks
+ 39D9:0000       _palette2
+ 3A09:0000       _palette1
+ 3A39:0000 idle  DATASEG@
+ 3A39:00A3 idle  __Int0Vector
+ 3A39:00A7 idle  __Int4Vector
+ 3A39:00AB idle  __Int5Vector
+ 3A39:00AF idle  __Int6Vector
+ 3A39:00B3       __C0argc
+ 3A39:00B5       __C0argv
+ 3A39:00B7       __C0environ
+ 3A39:00B9       __envLng
+ 3A39:00BB       __envseg
+ 3A39:00BD       __envSize
+ 3A39:00BF       __psp
+ 3A39:00C1 idle  __osversion
+ 3A39:00C1       __osmajor
+ 3A39:00C1       __version
+ 3A39:00C2 idle  __osminor
+ 3A39:00C3       _errno
+ 3A39:00C5 idle  __StartTime
+ 3A39:00C9 idle  ___heapbase
+ 3A39:00CB       ___brklvl
+ 3A39:00CD       __heapbase
+ 3A39:00D1       __brklvl
+ 3A39:00D5       __heaptop
+ 3A39:00DA idle  _halfheight
+ 3A39:00DC       _dirangle
+ 3A39:00EE       _configname
+ 3A39:00FC idle  _JHParmStrings
+ 3A39:0102 idle  _radtoint
+ 3A39:01C4 idle  _MusicItems
+ 3A39:01FC idle  _nosprtxt
+ 3A39:0330 idle  _endextern
+ 3A39:0332 idle  _helpextern
+ 3A39:0334 idle  _helpfilename
+ 3A39:0341       _endfilename
+ 3A39:03D2       _MainItems
+ 3A39:03DC idle  _SndItems
+ 3A39:03E6 idle  _LSItems
+ 3A39:03F0 idle  _CtlItems
+ 3A39:03FA idle  _CusItems
+ 3A39:0404 idle  _NewEitems
+ 3A39:040E idle  _NewItems
+ 3A39:0418 idle  _color_hlite
+ 3A39:0420 idle  _color_norml
+ 3A39:0428 idle  _EpisodeSelect
+ 3A39:0434 idle  _SoundStatus
+ 3A39:0436 idle  _SaveName
+ 3A39:05F2 idle  _mbarray
+ 3A39:05FE idle  _order
+ 3A39:0622 idle  _moveorder
+ 3A39:0E74 idle  _ElevatorBackTo
+ 3A39:0E80 idle  _righttable
+ 3A39:1042 idle  _lefttable
+ 3A39:1204       _demoname
+ 3A39:1270       _dirscan
+ 3A39:1278       _buttonscan
+ 3A39:1288       _buttonmouse
+ 3A39:1290       _buttonjoy
+ 3A39:1298 idle  _songs
+ 3A39:1684       _screenloc
+ 3A39:168A       _freelatch
+ 3A39:168C       _tileglobal
+ 3A39:1690 idle  _mindist
+ 3A39:1694       _costable
+ 3A39:1698 idle  _vgaCeiling
+ 3A39:1710 idle  _weaponscale
+ 3A39:171A       _mapmasks1
+ 3A39:173A       _mapmasks2
+ 3A39:175A       _mapmasks3
+ 3A39:177A idle  _wordmasks
+ 3A39:180C idle  _opposite
+ 3A39:181E idle  _diagonal
+ 3A39:190C idle  _s_player
+ 3A39:191C idle  _s_attack
+ 3A39:192C idle  _attackinfo
+ 3A39:1A0C idle  _strafeangle
+ 3A39:1A1E idle  _statinfo
+ 3A39:1B38 idle  _dirtable
+ 3A39:1B4A idle  _starthitpoints
+ 3A39:1BFA idle  _s_rocket
+ 3A39:1C0A idle  _s_smoke1
+ 3A39:1C1A idle  _s_smoke2
+ 3A39:1C2A idle  _s_smoke3
+ 3A39:1C3A idle  _s_smoke4
+ 3A39:1C4A idle  _s_boom1
+ 3A39:1C5A idle  _s_boom2
+ 3A39:1C6A idle  _s_boom3
+ 3A39:1C7A idle  _s_grdstand
+ 3A39:1C8A idle  _s_grdpath1
+ 3A39:1C9A idle  _s_grdpath1s
+ 3A39:1CAA idle  _s_grdpath2
+ 3A39:1CBA idle  _s_grdpath3
+ 3A39:1CCA idle  _s_grdpath3s
+ 3A39:1CDA idle  _s_grdpath4
+ 3A39:1CEA       _s_grdpain
+ 3A39:1CFA       _s_grdpain1
+ 3A39:1D0A idle  _s_grdshoot1
+ 3A39:1D1A idle  _s_grdshoot2
+ 3A39:1D2A idle  _s_grdshoot3
+ 3A39:1D3A       _s_grdchase1
+ 3A39:1D4A idle  _s_grdchase1s
+ 3A39:1D5A idle  _s_grdchase2
+ 3A39:1D6A idle  _s_grdchase3
+ 3A39:1D7A idle  _s_grdchase3s
+ 3A39:1D8A idle  _s_grdchase4
+ 3A39:1D9A       _s_grddie1
+ 3A39:1DAA idle  _s_grddie2
+ 3A39:1DBA idle  _s_grddie3
+ 3A39:1DCA idle  _s_grddie4
+ 3A39:1DDA       _s_blinkychase1
+ 3A39:1DEA idle  _s_blinkychase2
+ 3A39:1DFA idle  _s_inkychase1
+ 3A39:1E0A idle  _s_inkychase2
+ 3A39:1E1A idle  _s_pinkychase1
+ 3A39:1E2A idle  _s_pinkychase2
+ 3A39:1E3A idle  _s_clydechase1
+ 3A39:1E4A idle  _s_clydechase2
+ 3A39:1E5A idle  _s_dogpath1
+ 3A39:1E6A idle  _s_dogpath1s
+ 3A39:1E7A idle  _s_dogpath2
+ 3A39:1E8A idle  _s_dogpath3
+ 3A39:1E9A idle  _s_dogpath3s
+ 3A39:1EAA idle  _s_dogpath4
+ 3A39:1EBA idle  _s_dogjump1
+ 3A39:1ECA idle  _s_dogjump2
+ 3A39:1EDA idle  _s_dogjump3
+ 3A39:1EEA idle  _s_dogjump4
+ 3A39:1EFA idle  _s_dogjump5
+ 3A39:1F0A       _s_dogchase1
+ 3A39:1F1A idle  _s_dogchase1s
+ 3A39:1F2A idle  _s_dogchase2
+ 3A39:1F3A idle  _s_dogchase3
+ 3A39:1F4A idle  _s_dogchase3s
+ 3A39:1F5A idle  _s_dogchase4
+ 3A39:1F6A       _s_dogdie1
+ 3A39:1F7A idle  _s_dogdie2
+ 3A39:1F8A idle  _s_dogdie3
+ 3A39:1F9A idle  _s_dogdead
+ 3A39:1FAA idle  _s_ofcstand
+ 3A39:1FBA idle  _s_ofcpath1
+ 3A39:1FCA idle  _s_ofcpath1s
+ 3A39:1FDA idle  _s_ofcpath2
+ 3A39:1FEA idle  _s_ofcpath3
+ 3A39:1FFA idle  _s_ofcpath3s
+ 3A39:200A idle  _s_ofcpath4
+ 3A39:201A       _s_ofcpain
+ 3A39:202A       _s_ofcpain1
+ 3A39:203A idle  _s_ofcshoot1
+ 3A39:204A idle  _s_ofcshoot2
+ 3A39:205A idle  _s_ofcshoot3
+ 3A39:206A       _s_ofcchase1
+ 3A39:207A idle  _s_ofcchase1s
+ 3A39:208A idle  _s_ofcchase2
+ 3A39:209A idle  _s_ofcchase3
+ 3A39:20AA idle  _s_ofcchase3s
+ 3A39:20BA idle  _s_ofcchase4
+ 3A39:20CA       _s_ofcdie1
+ 3A39:20DA idle  _s_ofcdie2
+ 3A39:20EA idle  _s_ofcdie3
+ 3A39:20FA idle  _s_ofcdie4
+ 3A39:210A idle  _s_ofcdie5
+ 3A39:211A idle  _s_mutstand
+ 3A39:212A idle  _s_mutpath1
+ 3A39:213A idle  _s_mutpath1s
+ 3A39:214A idle  _s_mutpath2
+ 3A39:215A idle  _s_mutpath3
+ 3A39:216A idle  _s_mutpath3s
+ 3A39:217A idle  _s_mutpath4
+ 3A39:218A       _s_mutpain
+ 3A39:219A       _s_mutpain1
+ 3A39:21AA idle  _s_mutshoot1
+ 3A39:21BA idle  _s_mutshoot2
+ 3A39:21CA idle  _s_mutshoot3
+ 3A39:21DA idle  _s_mutshoot4
+ 3A39:21EA       _s_mutchase1
+ 3A39:21FA idle  _s_mutchase1s
+ 3A39:220A idle  _s_mutchase2
+ 3A39:221A idle  _s_mutchase3
+ 3A39:222A idle  _s_mutchase3s
+ 3A39:223A idle  _s_mutchase4
+ 3A39:224A       _s_mutdie1
+ 3A39:225A idle  _s_mutdie2
+ 3A39:226A idle  _s_mutdie3
+ 3A39:227A idle  _s_mutdie4
+ 3A39:228A idle  _s_mutdie5
+ 3A39:229A idle  _s_ssstand
+ 3A39:22AA idle  _s_sspath1
+ 3A39:22BA idle  _s_sspath1s
+ 3A39:22CA idle  _s_sspath2
+ 3A39:22DA idle  _s_sspath3
+ 3A39:22EA idle  _s_sspath3s
+ 3A39:22FA idle  _s_sspath4
+ 3A39:230A       _s_sspain
+ 3A39:231A       _s_sspain1
+ 3A39:232A idle  _s_ssshoot1
+ 3A39:233A idle  _s_ssshoot2
+ 3A39:234A idle  _s_ssshoot3
+ 3A39:235A idle  _s_ssshoot4
+ 3A39:236A idle  _s_ssshoot5
+ 3A39:237A idle  _s_ssshoot6
+ 3A39:238A idle  _s_ssshoot7
+ 3A39:239A idle  _s_ssshoot8
+ 3A39:23AA idle  _s_ssshoot9
+ 3A39:23BA       _s_sschase1
+ 3A39:23CA idle  _s_sschase1s
+ 3A39:23DA idle  _s_sschase2
+ 3A39:23EA idle  _s_sschase3
+ 3A39:23FA idle  _s_sschase3s
+ 3A39:240A idle  _s_sschase4
+ 3A39:241A       _s_ssdie1
+ 3A39:242A idle  _s_ssdie2
+ 3A39:243A idle  _s_ssdie3
+ 3A39:244A idle  _s_ssdie4
+ 3A39:245A idle  _s_bossstand
+ 3A39:246A       _s_bosschase1
+ 3A39:247A idle  _s_bosschase1s
+ 3A39:248A idle  _s_bosschase2
+ 3A39:249A idle  _s_bosschase3
+ 3A39:24AA idle  _s_bosschase3s
+ 3A39:24BA idle  _s_bosschase4
+ 3A39:24CA       _s_bossdie1
+ 3A39:24DA idle  _s_bossdie2
+ 3A39:24EA idle  _s_bossdie3
+ 3A39:24FA idle  _s_bossdie4
+ 3A39:250A idle  _s_bossshoot1
+ 3A39:251A idle  _s_bossshoot2
+ 3A39:252A idle  _s_bossshoot3
+ 3A39:253A idle  _s_bossshoot4
+ 3A39:254A idle  _s_bossshoot5
+ 3A39:255A idle  _s_bossshoot6
+ 3A39:256A idle  _s_bossshoot7
+ 3A39:257A idle  _s_bossshoot8
+ 3A39:258A idle  _s_gretelstand
+ 3A39:259A       _s_gretelchase1
+ 3A39:25AA idle  _s_gretelchase1s
+ 3A39:25BA idle  _s_gretelchase2
+ 3A39:25CA idle  _s_gretelchase3
+ 3A39:25DA idle  _s_gretelchase3s
+ 3A39:25EA idle  _s_gretelchase4
+ 3A39:25FA       _s_greteldie1
+ 3A39:260A idle  _s_greteldie2
+ 3A39:261A idle  _s_greteldie3
+ 3A39:262A idle  _s_greteldie4
+ 3A39:263A idle  _s_gretelshoot1
+ 3A39:264A idle  _s_gretelshoot2
+ 3A39:265A idle  _s_gretelshoot3
+ 3A39:266A idle  _s_gretelshoot4
+ 3A39:267A idle  _s_gretelshoot5
+ 3A39:268A idle  _s_gretelshoot6
+ 3A39:269A idle  _s_gretelshoot7
+ 3A39:26AA idle  _s_gretelshoot8
+ 3A39:26CC idle  _s_schabbstand
+ 3A39:26DC       _s_schabbchase1
+ 3A39:26EC idle  _s_schabbchase1s
+ 3A39:26FC idle  _s_schabbchase2
+ 3A39:270C idle  _s_schabbchase3
+ 3A39:271C idle  _s_schabbchase3s
+ 3A39:272C idle  _s_schabbchase4
+ 3A39:273C idle  _s_schabbdeathcam
+ 3A39:274C       _s_schabbdie1
+ 3A39:275C idle  _s_schabbdie2
+ 3A39:276C idle  _s_schabbdie3
+ 3A39:277C idle  _s_schabbdie4
+ 3A39:278C idle  _s_schabbdie5
+ 3A39:279C idle  _s_schabbdie6
+ 3A39:27AC idle  _s_schabbshoot1
+ 3A39:27BC idle  _s_schabbshoot2
+ 3A39:27CC idle  _s_needle1
+ 3A39:27DC idle  _s_needle2
+ 3A39:27EC idle  _s_needle3
+ 3A39:27FC idle  _s_needle4
+ 3A39:280C idle  _s_giftstand
+ 3A39:281C       _s_giftchase1
+ 3A39:282C idle  _s_giftchase1s
+ 3A39:283C idle  _s_giftchase2
+ 3A39:284C idle  _s_giftchase3
+ 3A39:285C idle  _s_giftchase3s
+ 3A39:286C idle  _s_giftchase4
+ 3A39:287C idle  _s_giftdeathcam
+ 3A39:288C       _s_giftdie1
+ 3A39:289C idle  _s_giftdie2
+ 3A39:28AC idle  _s_giftdie3
+ 3A39:28BC idle  _s_giftdie4
+ 3A39:28CC idle  _s_giftdie5
+ 3A39:28DC idle  _s_giftdie6
+ 3A39:28EC idle  _s_giftshoot1
+ 3A39:28FC idle  _s_giftshoot2
+ 3A39:290C idle  _s_fatstand
+ 3A39:291C       _s_fatchase1
+ 3A39:292C idle  _s_fatchase1s
+ 3A39:293C idle  _s_fatchase2
+ 3A39:294C idle  _s_fatchase3
+ 3A39:295C idle  _s_fatchase3s
+ 3A39:296C idle  _s_fatchase4
+ 3A39:297C idle  _s_fatdeathcam
+ 3A39:298C       _s_fatdie1
+ 3A39:299C idle  _s_fatdie2
+ 3A39:29AC idle  _s_fatdie3
+ 3A39:29BC idle  _s_fatdie4
+ 3A39:29CC idle  _s_fatdie5
+ 3A39:29DC idle  _s_fatdie6
+ 3A39:29EC idle  _s_fatshoot1
+ 3A39:29FC idle  _s_fatshoot2
+ 3A39:2A0C idle  _s_fatshoot3
+ 3A39:2A1C idle  _s_fatshoot4
+ 3A39:2A2C idle  _s_fatshoot5
+ 3A39:2A3C idle  _s_fatshoot6
+ 3A39:2A4C idle  _s_fakestand
+ 3A39:2A5C       _s_fakechase1
+ 3A39:2A6C idle  _s_fakechase1s
+ 3A39:2A7C idle  _s_fakechase2
+ 3A39:2A8C idle  _s_fakechase3
+ 3A39:2A9C idle  _s_fakechase3s
+ 3A39:2AAC idle  _s_fakechase4
+ 3A39:2ABC       _s_fakedie1
+ 3A39:2ACC idle  _s_fakedie2
+ 3A39:2ADC idle  _s_fakedie3
+ 3A39:2AEC idle  _s_fakedie4
+ 3A39:2AFC idle  _s_fakedie5
+ 3A39:2B0C idle  _s_fakedie6
+ 3A39:2B1C idle  _s_fakeshoot1
+ 3A39:2B2C idle  _s_fakeshoot2
+ 3A39:2B3C idle  _s_fakeshoot3
+ 3A39:2B4C idle  _s_fakeshoot4
+ 3A39:2B5C idle  _s_fakeshoot5
+ 3A39:2B6C idle  _s_fakeshoot6
+ 3A39:2B7C idle  _s_fakeshoot7
+ 3A39:2B8C idle  _s_fakeshoot8
+ 3A39:2B9C idle  _s_fakeshoot9
+ 3A39:2BAC idle  _s_fire1
+ 3A39:2BBC idle  _s_fire2
+ 3A39:2BCC idle  _s_mechastand
+ 3A39:2BDC       _s_mechachase1
+ 3A39:2BEC idle  _s_mechachase1s
+ 3A39:2BFC idle  _s_mechachase2
+ 3A39:2C0C idle  _s_mechachase3
+ 3A39:2C1C idle  _s_mechachase3s
+ 3A39:2C2C idle  _s_mechachase4
+ 3A39:2C3C       _s_mechadie1
+ 3A39:2C4C idle  _s_mechadie2
+ 3A39:2C5C idle  _s_mechadie3
+ 3A39:2C6C idle  _s_mechadie4
+ 3A39:2C7C idle  _s_mechashoot1
+ 3A39:2C8C idle  _s_mechashoot2
+ 3A39:2C9C idle  _s_mechashoot3
+ 3A39:2CAC idle  _s_mechashoot4
+ 3A39:2CBC idle  _s_mechashoot5
+ 3A39:2CCC idle  _s_mechashoot6
+ 3A39:2CDC       _s_hitlerchase1
+ 3A39:2CEC idle  _s_hitlerchase1s
+ 3A39:2CFC idle  _s_hitlerchase2
+ 3A39:2D0C idle  _s_hitlerchase3
+ 3A39:2D1C idle  _s_hitlerchase3s
+ 3A39:2D2C idle  _s_hitlerchase4
+ 3A39:2D3C idle  _s_hitlerdeathcam
+ 3A39:2D4C       _s_hitlerdie1
+ 3A39:2D5C idle  _s_hitlerdie2
+ 3A39:2D6C idle  _s_hitlerdie3
+ 3A39:2D7C idle  _s_hitlerdie4
+ 3A39:2D8C idle  _s_hitlerdie5
+ 3A39:2D9C idle  _s_hitlerdie6
+ 3A39:2DAC idle  _s_hitlerdie7
+ 3A39:2DBC idle  _s_hitlerdie8
+ 3A39:2DCC idle  _s_hitlerdie9
+ 3A39:2DDC idle  _s_hitlerdie10
+ 3A39:2DEC idle  _s_hitlershoot1
+ 3A39:2DFC idle  _s_hitlershoot2
+ 3A39:2E0C idle  _s_hitlershoot3
+ 3A39:2E1C idle  _s_hitlershoot4
+ 3A39:2E2C idle  _s_hitlershoot5
+ 3A39:2E3C idle  _s_hitlershoot6
+ 3A39:2E54 idle  _s_bjrun1
+ 3A39:2E64 idle  _s_bjrun1s
+ 3A39:2E74 idle  _s_bjrun2
+ 3A39:2E84 idle  _s_bjrun3
+ 3A39:2E94 idle  _s_bjrun3s
+ 3A39:2EA4 idle  _s_bjrun4
+ 3A39:2EB4 idle  _s_bjjump1
+ 3A39:2EC4 idle  _s_bjjump2
+ 3A39:2ED4 idle  _s_bjjump3
+ 3A39:2EE4 idle  _s_bjjump4
+ 3A39:2EF4       _s_deathcam
+ 3A39:2F4A       _gamepal
+ 3A39:324A       _audioname
+ 3A39:3257 idle  _gheadname
+ 3A39:3261 idle  _gfilename
+ 3A39:326B idle  _gdictname
+ 3A39:3275 idle  _mheadname
+ 3A39:327F idle  _mfilename
+ 3A39:3289 idle  _aheadname
+ 3A39:3293 idle  _afilename
+ 3A39:3354 idle  _KbdDefs
+ 3A39:335E idle  _DemoMode
+ 3A39:3510 idle  _XMSProtectPage
+ 3A39:3512       _PageFileName
+ 3A39:3520 idle  _PageFile
+ 3A39:352A idle  _EMMDriverName
+ 3A39:39A0 idle  _ssPort
+ 3A39:3D12       _USL_MeasureString
+ 3A39:3D16 idle  _USL_DrawString
+ 3A39:3D1A       _Scores
+ 3A39:3FC4       _screenseg
+ 3A39:3FCA idle  _pixmasks
+ 3A39:3FCE idle  _leftmasks
+ 3A39:3FD2 idle  _rightmasks
+ 3A39:4090       __8087
+ 3A39:40A0       __protected
+ 3A39:40A1       __LDT
+ 3A39:40A4       __default87
+ 3A39:40A6 idle  __huge_flt
+ 3A39:40AA       __huge_dble
+ 3A39:40B2 idle  __huge_ldble
+ 3A39:40BC idle  __indefinite
+ 3A39:40C0 idle  __tiny_ldble
+ 3A39:40CA       __mathwhy
+ 3A39:4270       __emu
+ 3A39:4380       __atexitcnt
+ 3A39:4382       __ctype
+ 3A39:4484       __exitbuf
+ 3A39:4488       __exitfopen
+ 3A39:448C       __exitopen
+ 3A39:4490       __streams
+ 3A39:45D0       __nfile
+ 3A39:45D2       __openfd
+ 3A39:45FA       __fmode
+ 3A39:45FC       __notUmask
+ 3A39:45FE       __fpstklen
+ 3A39:4600       __heaplen
+ 3A39:4602       __doserrno
+ 3A39:4604 idle  __dosErrorToSV
+ 3A39:4668       __stklen
+ 3A39:46D2       __video
+ 3A39:46E1       _directvideo
+ 3A39:471E idle  __first
+ 3A39:4720 idle  __last
+ 3A39:4722 idle  __rover
+ 3A39:4724       __argc
+ 3A39:4726       __argv
+ 3A39:4732       _environ
+ 3A39:473A       __RealCvtVector
+ 3A39:473E idle  __ScanTodVector
+ 3A39:4944       __atexittbl
+ 3A39:49D2       ___SignalPtr
+ 3A39:49E4       _mr_dest
+ 3A39:49E6       _mr_yfrac
+ 3A39:49E8       _mr_xfrac
+ 3A39:49EA       _mr_ystep
+ 3A39:49EC       _mr_xstep
+ 3A39:49EE       _mr_count
+ 3A39:49F0       _mr_rowofs
+ 3A39:49F2       _pcos
+ 3A39:49F6       _psin
+ 3A39:49FA       _mirrorofs
+ 3A39:4AC2       _planeylookup
+ 3A39:4C52       _basedist
+ 3A39:4DE2       _stepscale
+ 3A39:4F72       _spanstart
+ 3A39:503A       _viewcos
+ 3A39:503E       _viewsin
+ 3A39:5042       _viewy
+ 3A39:5046       _viewx
+ 3A39:504A       _wallheight
+ 3A39:52CA       _scale
+ 3A39:52CE       _viewheight
+ 3A39:52D0       _viewwidth
+ 3A39:52D2       _menuitems
+ 3A39:52D4       _bufferofs
+ 3A39:52D6       _pwalldir
+ 3A39:52D8       _pwally
+ 3A39:52DA       _pwallx
+ 3A39:52DC       _areabyplayer
+ 3A39:5326       _pwallstate
+ 3A39:5328       _doorposition
+ 3A39:53A8       _pwallpos
+ 3A39:53AA       _vertwall
+ 3A39:542A       _horizwall
+ 3A39:54AA       _viewsize
+ 3A39:54AC       _joystickport
+ 3A39:54AE       _joystickprogressive
+ 3A39:54B0       _joypadenabled
+ 3A39:54B2       _joystickenabled
+ 3A39:54B4       _mouseenabled
+ 3A39:54B6       _update
+ 3A39:55BA       _actorat
+ 3A39:75BA       _tilemap
+ 3A39:85BA       _nearmapylookup
+ 3A39:863A       _farmapylookup
+ 3A39:86BA       _doorobjlist
+ 3A39:893A       _laststatobj
+ 3A39:893C       _statobjlist
+ 3A39:95BC       _player
+ 3A39:95BE       _new
+ 3A39:95C0       _playstate
+ 3A39:95C2       _gamestate
+ 3A39:9604       _minheightdiv
+ 3A39:9606       _heightnumerator
+ 3A39:960A       _maxslope
+ 3A39:960E       _pixelangle
+ 3A39:988E       _mouseadjustment
+ 3A39:9890       _virtualreality
+ 3A39:9892       _startgame
+ 3A39:9894       _shootdelta
+ 3A39:9896       _centerx
+ 3A39:9898       _screenofs
+ 3A39:989A       _focallength
+ 3A39:989E       _IsA386
+ 3A39:98A0       _nospr
+ 3A39:98A2       _str2
+ 3A39:98B6       _str
+ 3A39:9906       _LevelRatios
+ 3A39:9956       _backcolor
+ 3A39:9957       _blockstarts
+ 3A39:9B5F       _uwidthtable
+ 3A39:9B79       _updateptr
+ 3A39:9B7B       _WindowW
+ 3A39:9B7D       _WindowY
+ 3A39:9B7F       _WindowX
+ 3A39:9B81       _PrintY
+ 3A39:9B83       _NoWait
+ 3A39:9B85       _loadedgame
+ 3A39:9B87       _tedlevelnum
+ 3A39:9B89       _tedlevel
+ 3A39:9B8B       _DigiMap
+ 3A39:9C39       _MusicMode
+ 3A39:9C3B       _DigiMode
+ 3A39:9C3D       _SoundMode
+ 3A39:9C3F       _SoundBlasterPresent
+ 3A39:9C41       _SoundSourcePresent
+ 3A39:9C43       _AdLibPresent
+ 3A39:9C45       _JoysPresent
+ 3A39:9C49       _MousePresent
+ 3A39:9C4B       _Keyboard
+ 3A39:9D4B       _fontnumber
+ 3A39:9D4D       _fontcolor
+ 3A39:9D4E       _displayofs
+ 3A39:9D50       _grsegs
+ 3A39:9E7A       _mminfo
+ 3A39:9E8E       _layoutdone
+ 3A39:9E90       _picdelay
+ 3A39:9E92       _picnum
+ 3A39:9E94       _picy
+ 3A39:9E96       _picx
+ 3A39:9E98       _rowon
+ 3A39:9E9A       _text
+ 3A39:9E9E       _rightmargin
+ 3A39:9EBC       _leftmargin
+ 3A39:9EDA       _numpages
+ 3A39:9EDC       _pagenum
+ 3A39:9EDE       _TimeCount
+ 3A39:9EE2       _LastScan
+ 3A39:9EE3       _py
+ 3A39:9EE5       _px
+ 3A39:9EE7       _pictable
+ 3A39:9EE9       _ca_levelbit
+ 3A39:9EEA       _pickquick
+ 3A39:9EEC       _lasttimecount
+ 3A39:9EF0       _SaveGameNames
+ 3A39:A030       _StartGame
+ 3A39:A032       _SaveGamesAvail
+ 3A39:A046       _WindowH
+ 3A39:A048       _PrintX
+ 3A39:A04A       _ingame
+ 3A39:A04C       _LastASCII
+ 3A39:A04D       _Paused
+ 3A39:A04F       _extension
+ 3A39:A054       _audiosegs
+ 3A39:A294       _EMSPagesAvail
+ 3A39:A296       _XMSPagesAvail
+ 3A39:A298       _EMSPresent
+ 3A39:A29A       _XMSPresent
+ 3A39:A29C       _mmerror
+ 3A39:A29E       _mapon
+ 3A39:A2A0       _rightchannel
+ 3A39:A2A2       _leftchannel
+ 3A39:A2A4       _globalsoundy
+ 3A39:A2A8       _globalsoundx
+ 3A39:A2AC       _demobuffer
+ 3A39:A2AE       _lastdemoptr
+ 3A39:A2B2       _demoptr
+ 3A39:A2B6       _demoplayback
+ 3A39:A2B8       _demorecord
+ 3A39:A2BA       _killerobj
+ 3A39:A2BC       _spearflag
+ 3A39:A2BE       _spearangle
+ 3A39:A2C0       _speary
+ 3A39:A2C4       _spearx
+ 3A39:A2C8       _fizzlein
+ 3A39:A2CA       _tics
+ 3A39:A2CC       _mapheight
+ 3A39:A2CE       _mapwidth
+ 3A39:A2D0       _SoundPositioned
+ 3A39:A2D2       _latchpics
+ 3A39:A39A       _mapheaderseg
+ 3A39:A412       _mapsegs
+ 3A39:A416       _funnyticount
+ 3A39:A41A       _palshifted
+ 3A39:A41C       _bonuscount
+ 3A39:A41E       _damagecount
+ 3A39:A420       _objcount
+ 3A39:A422       _dummyobj
+ 3A39:A45E       _mapwidthtable
+ 3A39:A4DE       _DebugOk
+ 3A39:A4E0       _facecount
+ 3A39:A4E2       _anglefrac
+ 3A39:A4E4       _running
+ 3A39:A4E6       _frameon
+ 3A39:A4EA       _buttonstate
+ 3A39:A4FA       _controly
+ 3A39:A4FC       _controlx
+ 3A39:A4FE       _buttonheld
+ 3A39:A50E       _extravbls
+ 3A39:A510       _noclip
+ 3A39:A512       _godmode
+ 3A39:A514       _singlestep
+ 3A39:A516       _spotvis
+ 3A39:B516       _objfreelist
+ 3A39:B518       _lastobj
+ 3A39:B51A       _obj
+ 3A39:B51C       _objlist
+ 3A39:D844       _madenoise
+ 3A39:D846       _compatability
+ 3A39:D848       _screenfaded
+ 3A39:D84A       _DigiList
+ 3A39:D84C       _NumDigi
+ 3A39:D84E       _viewtype
+ 3A39:D850       _maporgy
+ 3A39:D852       _maporgx
+ 3A39:D854       _postwidth
+ 3A39:D856       _postx
+ 3A39:D858       _postsource
+ 3A39:D85C       _doornum
+ 3A39:D85E       _PMPages
+ 3A39:D862       _PMSoundStart
+ 3A39:D864       _PMSpriteStart
+ 3A39:D866       _ChunksInFile
+ 3A39:D868       _farthest
+ 3A39:D86A       _visstep
+ 3A39:D86C       _visptr
+ 3A39:D86E       _vislist
+ 3A39:D99A       _ystep
+ 3A39:D99E       _xstep
+ 3A39:D9A2       _yintercept
+ 3A39:D9A6       _xintercept
+ 3A39:D9AA       _ytilestep
+ 3A39:D9AC       _xtilestep
+ 3A39:D9AE       _ytile
+ 3A39:D9B0       _xtile
+ 3A39:D9B2       _pixx
+ 3A39:D9B4       _tilehit
+ 3A39:D9B6       _yinttile
+ 3A39:D9B8       _xinttile
+ 3A39:D9BA       _ypartialdown
+ 3A39:D9BC       _ypartialup
+ 3A39:D9BE       _xpartialdown
+ 3A39:D9C0       _xpartialup
+ 3A39:D9C2       _ypartial
+ 3A39:D9C4       _xpartial
+ 3A39:D9C6       _angle
+ 3A39:D9C8       _midangle
+ 3A39:D9CA       _viewty
+ 3A39:D9CC       _viewtx
+ 3A39:D9CE       _focalty
+ 3A39:D9D0       _focaltx
+ 3A39:D9D2       _lasttilehit
+ 3A39:D9D4       _lastintercept
+ 3A39:D9D8       _lastside
+ 3A39:D9DA       _maxscaleshl2
+ 3A39:D9DC       _fullscalefarcall
+ 3A39:DDE0       _viewangle
+ 3A39:DDE2       _mask3
+ 3A39:DDE3       _mask2
+ 3A39:DDE4       _mask1
+ 3A39:DDE5       _maskword
+ 3A39:DDE7       _linescale
+ 3A39:DDEB       _linecmds
+ 3A39:DDEF       _slinewidth
+ 3A39:DDF1       _slinex
+ 3A39:DDF3       _stepbytwo
+ 3A39:DDF5       _work
+ 3A39:DDF7       _insetupscaling
+ 3A39:DDF9       _maxscale
+ 3A39:DDFB       _scaledirectory
+ 3A39:DFFD       _pluy
+ 3A39:DFFF       _plux
+ 3A39:E001       _playerymove
+ 3A39:E005       _playerxmove
+ 3A39:E009       _LastAttacker
+ 3A39:E00B       _gotgatgun
+ 3A39:E00D       _thrustspeed
+ 3A39:E011       _lastdoorobj
+ 3A39:E013       _oldsoundmode
+ 3A39:E015       _chunkexplen
+ 3A39:E019       _chunkcomplen
+ 3A39:E01D       _audiohandle
+ 3A39:E01F       _maphandle
+ 3A39:E021       _grhandle
+ 3A39:E023       _audiohuffman
+ 3A39:E41F       _grhuffman
+ 3A39:E81B       _audiostarts
+ 3A39:E81D       _grstarts
+ 3A39:E81F       _debughandle
+ 3A39:E821       _profilehandle
+ 3A39:E823       _ca_levelnum
+ 3A39:E824       _tinf
+ 3A39:E826       _bufferseg
+ 3A39:E828       _btnstate
+ 3A39:E838       _MouseDownCount
+ 3A39:E83C       _JoyPadPresent
+ 3A39:E83E       _DemoSize
+ 3A39:E840       _DemoOffset
+ 3A39:E842       _DemoBuffer
+ 3A39:E844       _Controls
+ 3A39:E84C       _JoyDefs
+ 3A39:E87C       _UMBbase
+ 3A39:E890       _numUMBs
+ 3A39:E892       _XMSaddr
+ 3A39:E896       _bombonerror
+ 3A39:E898       _mmnew
+ 3A39:E89C       _mmrover
+ 3A39:E8A0       _mmfree
+ 3A39:E8A4       _mmhead
+ 3A39:E8A8       _nearheap
+ 3A39:E8AA       _farheap
+ 3A39:E8AE       _mmstarted
+ 3A39:E8B0       _aftersort
+ 3A39:E8B4       _beforesort
+ 3A39:E8B8       _PMSegPages
+ 3A39:E8BA       _PMFrameCount
+ 3A39:E8BE       _PMNumBlocks
+ 3A39:E8C0       _MainPagesUsed
+ 3A39:E8C2       _EMSPagesUsed
+ 3A39:E8C4       _XMSPagesUsed
+ 3A39:E8C6       _PMThrashing
+ 3A39:E8C8       _PMPanicMode
+ 3A39:E8CA       _PMStarted
+ 3A39:E8CC       _XMSDriver
+ 3A39:E8D0       _XMSHandle
+ 3A39:E8D2       _XMSAvail
+ 3A39:E8D4       _EMSList
+ 3A39:E8EC       _EMSPhysicalPage
+ 3A39:E8EE       _EMSPageFrame
+ 3A39:E8F0       _EMSHandle
+ 3A39:E8F2       _EMSAvail
+ 3A39:E8F4       _MainPagesAvail
+ 3A39:E8F6       _MainMemUsed
+ 3A39:E9BE       _MainMemPages
+ 3A39:EA86       _MainPresent
+ 3A39:EA88       _sqHackTime
+ 3A39:EA8C       _sqHackSeqLen
+ 3A39:EA8E       _sqHackLen
+ 3A39:EA90       _sqHackPtr
+ 3A39:EA94       _sqHack
+ 3A39:EA98       _sqActive
+ 3A39:EA9A       _alZeroInst
+ 3A39:EAAA       _alTimeCount
+ 3A39:EAAE       _alLengthLeft
+ 3A39:EAB2       _alBlock
+ 3A39:EAB4       _alSound
+ 3A39:EAB8       _alNoCheck
+ 3A39:EABA       _pcSoundLookup
+ 3A39:ECB8       _pcLengthLeft
+ 3A39:ECBC       _pcSound
+ 3A39:ECC0       _pcLastSample
+ 3A39:ECC1       _ssLengthLeft
+ 3A39:ECC5       _ssSample
+ 3A39:ECC9       _ssOff
+ 3A39:ECCA       _ssOn
+ 3A39:ECCB       _ssData
+ 3A39:ECCD       _ssStatus
+ 3A39:ECCF       _ssControl
+ 3A39:ECD1       _ssActive
+ 3A39:ECD3       _ssNoCheck
+ 3A39:ECD5       _DigiLastEnd
+ 3A39:ECD7       _DigiLastStart
+ 3A39:ECD9       _DigiPage
+ 3A39:ECDB       _DigiLeft
+ 3A39:ECDD       _TimerRate
+ 3A39:ECDF       _LocalTime
+ 3A39:ECE3       _t0OldService
+ 3A39:ECE7       _RightPosition
+ 3A39:ECE9       _LeftPosition
+ 3A39:ECEB       _DigiPriority
+ 3A39:ECED       _SoundPriority
+ 3A39:ECEF       _DigiNumber
+ 3A39:ECF1       _SoundNumber
+ 3A39:ECF3       _TimerCount
+ 3A39:ECF7       _TimerDivisor
+ 3A39:ECFB       _nextsoundpos
+ 3A39:ECFD       _ssIsTandy
+ 3A39:ECFF       _SoundTable
+ 3A39:ED01       _HackCount
+ 3A39:ED03       _NeedsDigitized
+ 3A39:ED05       _SBProPresent
+ 3A39:ED07       _DigiPlaying
+ 3A39:ED09       _NeedsMusic
+ 3A39:ED0B       _Games
+ 3A39:EE07       _CursorY
+ 3A39:EE09       _CursorX
+ 3A39:EE0B       _CursorBad
+ 3A39:EE0D       _Button1
+ 3A39:EE0F       _Button0
+ 3A39:EE11       _abortprogram
+ 3A39:EE13       _fastpalette
+ 3A39:EE15       _bordercolor
+ 3A39:EE17       _ylookup
+ 3A39:EFA7       _linewidth
+ 3A39:EFA9       _pelpan
+ 3A39:EFAB       _bufferheight
+ 3A39:EFAD       _bufferwidth
+
+Program entry point at 0000:0000
+
binary files /dev/null b/WOLFSRC/WOLF3D.PRJ differ
--- /dev/null
+++ b/WOLFSRC/WOLFGTV.H
@@ -1,0 +1,10 @@
+//#define SPEAR
+//#define JAPAN
+#define GOODTIMES
+#define ARTSEXTERN
+#define DEMOSEXTERN
+//#define MYPROFILE
+//#define DEBCHECK
+#define CARMACIZED
+//#define UPLOAD
+
\ No newline at end of file
--- /dev/null
+++ b/WOLFSRC/WOLFHACK.C
@@ -1,0 +1,186 @@
+// WOLFHACK.C
+
+#include "WL_DEF.H"
+
+#define	MAXVIEWHEIGHT	200
+
+int		spanstart[MAXVIEWHEIGHT/2];
+
+fixed	stepscale[MAXVIEWHEIGHT/2];
+fixed	basedist[MAXVIEWHEIGHT/2];
+
+extern	char	far	planepics[8192];	// 4k of ceiling, 4k of floor
+
+int		halfheight = 0;
+
+byte	far *planeylookup[MAXVIEWHEIGHT/2];
+unsigned	mirrorofs[MAXVIEWHEIGHT/2];
+
+fixed	psin, pcos;
+
+fixed FixedMul (fixed a, fixed b)
+{
+	return (a>>8)*(b>>8);
+}
+
+
+int		mr_rowofs;
+int		mr_count;
+int		mr_xstep;
+int		mr_ystep;
+int		mr_xfrac;
+int		mr_yfrac;
+int		mr_dest;
+
+
+/*
+==============
+=
+= DrawSpans
+=
+= Height ranges from 0 (infinity) to viewheight/2 (nearest)
+==============
+*/
+
+void DrawSpans (int x1, int x2, int height)
+{
+	fixed		length;
+	int			ofs;
+	int			prestep;
+	fixed		startxfrac, startyfrac;
+
+	int			x, startx, count, plane, startplane;
+	byte		far	*toprow, far *dest;
+
+	toprow = planeylookup[height]+bufferofs;
+	mr_rowofs = mirrorofs[height];
+
+	mr_xstep = (psin<<1)/height;
+	mr_ystep = (pcos<<1)/height;
+
+	length = basedist[height];
+	startxfrac = (viewx + FixedMul(length,pcos));
+	startyfrac = (viewy - FixedMul(length,psin));
+
+// draw two spans simultaniously
+
+	plane = startplane = x1&3;
+	prestep = viewwidth/2 - x1;
+	do
+	{
+		outportb (SC_INDEX+1,1<<plane);
+		mr_xfrac = startxfrac - (mr_xstep>>2)*prestep;
+		mr_yfrac = startyfrac - (mr_ystep>>2)*prestep;
+
+		startx = x1>>2;
+		mr_dest = (unsigned)toprow + startx;
+		mr_count = ((x2-plane)>>2) - startx + 1;
+		x1++;
+		prestep--;
+		if (mr_count)
+			MapRow ();
+		plane = (plane+1)&3;
+	} while (plane != startplane);
+
+}
+
+
+
+
+/*
+===================
+=
+= SetPlaneViewSize
+=
+===================
+*/
+
+void SetPlaneViewSize (void)
+{
+	int		x,y;
+	byte 	far *dest, far *src;
+
+	halfheight = viewheight>>1;
+
+
+	for (y=0 ; y<halfheight ; y++)
+	{
+		planeylookup[y] = (byte far *)0xa0000000l + (halfheight-1-y)*SCREENBWIDE;;
+		mirrorofs[y] = (y*2+1)*SCREENBWIDE;
+
+		stepscale[y] = y*GLOBAL1/32;
+		if (y>0)
+			basedist[y] = GLOBAL1/2*scale/y;
+	}
+
+	src = PM_GetPage(0);
+	dest = planepics;
+	for (x=0 ; x<4096 ; x++)
+	{
+		*dest = *src++;
+		dest += 2;
+	}
+	src = PM_GetPage(1);
+	dest = planepics+1;
+	for (x=0 ; x<4096 ; x++)
+	{
+		*dest = *src++;
+		dest += 2;
+	}
+
+}
+
+
+/*
+===================
+=
+= DrawPlanes
+=
+===================
+*/
+
+void DrawPlanes (void)
+{
+	int		height, lastheight;
+	int		x;
+
+	if (viewheight>>1 != halfheight)
+		SetPlaneViewSize ();		// screen size has changed
+
+
+	psin = viewsin;
+	if (psin < 0)
+		psin = -(psin&0xffff);
+	pcos = viewcos;
+	if (pcos < 0)
+		pcos = -(pcos&0xffff);
+
+//
+// loop over all columns
+//
+	lastheight = halfheight;
+
+	for (x=0 ; x<viewwidth ; x++)
+	{
+		height = wallheight[x]>>3;
+		if (height < lastheight)
+		{	// more starts
+			do
+			{
+				spanstart[--lastheight] = x;
+			} while (lastheight > height);
+		}
+		else if (height > lastheight)
+		{	// draw spans
+			if (height > halfheight)
+				height = halfheight;
+			for ( ; lastheight < height ; lastheight++)
+				DrawSpans (spanstart[lastheight], x-1, lastheight);
+		}
+	}
+
+	height = halfheight;
+	for ( ; lastheight < height ; lastheight++)
+		DrawSpans (spanstart[lastheight], x-1, lastheight);
+}
+
--- /dev/null
+++ b/WOLFSRC/WOLFJVER.H
@@ -1,0 +1,8 @@
+//#define SPEAR
+#define JAPAN
+#define ARTSEXTERN
+#define DEMOSEXTERN
+//#define MYPROFILE
+//#define DEBCHECK
+#define CARMACIZED
+//#define UPLOAD
--- /dev/null
+++ b/WOLFSRC/WOLFVER.H
@@ -1,0 +1,7 @@
+//#define SPEAR
+#define ARTSEXTERN
+#define DEMOSEXTERN
+//#define MYPROFILE
+//#define DEBCHECK
+#define CARMACIZED
+//#define UPLOAD