From 536a10d99e813477932125484fc0ad55dbebb536 Mon Sep 17 00:00:00 2001 From: Hans Kokx Date: Thu, 19 Mar 2026 23:32:44 +0100 Subject: [PATCH] Added original source code Signed-off-by: Hans Kokx --- WOLFSRC/AUDIOSDM.H | 142 ++ WOLFSRC/AUDIOSOD.H | 142 ++ WOLFSRC/AUDIOWL1.H | 133 ++ WOLFSRC/AUDIOWL6.H | 151 ++ WOLFSRC/BUDIOSOD.H | 142 ++ WOLFSRC/BUDIOWL6.H | 151 ++ WOLFSRC/C0.ASM | 841 ++++++++ WOLFSRC/CONTIGSC.C | 733 +++++++ WOLFSRC/DETECT.C | 87 + WOLFSRC/FOREIGN.H | 110 + WOLFSRC/F_SPEAR.H | 87 + WOLFSRC/GFXE_SOD.EQU | 47 + WOLFSRC/GFXE_SOD.H | 53 + WOLFSRC/GFXE_WL1.EQU | 201 ++ WOLFSRC/GFXE_WL1.H | 211 ++ WOLFSRC/GFXE_WL6.EQU | 47 + WOLFSRC/GFXE_WL6.H | 53 + WOLFSRC/GFXV_SDM.EQU | 208 ++ WOLFSRC/GFXV_SDM.H | 224 ++ WOLFSRC/GFXV_SOD.EQU | 259 +++ WOLFSRC/GFXV_SOD.H | 280 +++ WOLFSRC/GFXV_WL1.EQU | 199 ++ WOLFSRC/GFXV_WL1.H | 209 ++ WOLFSRC/GFXV_WL6.EQU | 206 ++ WOLFSRC/GFXV_WL6.H | 216 ++ WOLFSRC/GO.BAT | 5 + WOLFSRC/GOODSTUF.TXT | 56 + WOLFSRC/H_LDIV.ASM | 227 ++ WOLFSRC/ID_CA.C | 1768 ++++++++++++++++ WOLFSRC/ID_CA.H | 101 + WOLFSRC/ID_HEAD.H | 34 + WOLFSRC/ID_HEADS.H | 123 ++ WOLFSRC/ID_IN.C | 990 +++++++++ WOLFSRC/ID_IN.H | 202 ++ WOLFSRC/ID_MM.C | 953 +++++++++ WOLFSRC/ID_MM.H | 96 + WOLFSRC/ID_PM.C | 1199 +++++++++++ WOLFSRC/ID_PM.H | 83 + WOLFSRC/ID_SD.C | 2367 +++++++++++++++++++++ WOLFSRC/ID_SD.EQU | 38 + WOLFSRC/ID_SD.H | 237 +++ WOLFSRC/ID_SD_A.ASM | 526 +++++ WOLFSRC/ID_US.H | 123 ++ WOLFSRC/ID_US_1.C | 755 +++++++ WOLFSRC/ID_US_A.ASM | 101 + WOLFSRC/ID_VH.C | 547 +++++ WOLFSRC/ID_VH.H | 134 ++ WOLFSRC/ID_VH_A.ASM | 110 + WOLFSRC/ID_VL.C | 1084 ++++++++++ WOLFSRC/ID_VL.EQU | 58 + WOLFSRC/ID_VL.H | 161 ++ WOLFSRC/ID_VL_A.ASM | 742 +++++++ WOLFSRC/JABHACK.ASM | 98 + WOLFSRC/MAPSSDM.H | 14 + WOLFSRC/MAPSSOD.H | 33 + WOLFSRC/MAPSWL1.H | 42 + WOLFSRC/MAPSWL6.H | 73 + WOLFSRC/MAPSWLF.H | 16 + WOLFSRC/MUNGE.C | 48 + WOLFSRC/OBJ/GAMEPAL.OBJ | Bin 0 -> 893 bytes WOLFSRC/OBJ/SIGNON.OBJ | Bin 0 -> 64561 bytes WOLFSRC/OLDSCALE.C | 737 +++++++ WOLFSRC/PICLIST.H | 36 + WOLFSRC/README/LICENSE.DOC | 129 ++ WOLFSRC/README/README.TXT | 8 + WOLFSRC/README/RELEASE.TXT | 53 + WOLFSRC/README/~$ICENSE.DOC | Bin 0 -> 162 bytes WOLFSRC/RULES.ASI | 692 ++++++ WOLFSRC/SDMVER.H | 8 + WOLFSRC/SHAREMSG.H | 9 + WOLFSRC/SODVER.H | 7 + WOLFSRC/SPANISH.H | 112 + WOLFSRC/SPANVER.H | 8 + WOLFSRC/SV.EXE | Bin 0 -> 6746 bytes WOLFSRC/VERSION.H | 10 + WOLFSRC/WHACK_A.ASM | 100 + WOLFSRC/WLFJ1VER.H | 9 + WOLFSRC/WL_ACT1.C | 900 ++++++++ WOLFSRC/WL_ACT2.C | 3872 ++++++++++++++++++++++++++++++++++ WOLFSRC/WL_AGENT.C | 1421 +++++++++++++ WOLFSRC/WL_ASM.ASM | 67 + WOLFSRC/WL_DEBUG.C | 722 +++++++ WOLFSRC/WL_DEF.H | 1276 +++++++++++ WOLFSRC/WL_DRAW.C | 1403 ++++++++++++ WOLFSRC/WL_DR_A.ASM | 739 +++++++ WOLFSRC/WL_GAME.C | 1484 +++++++++++++ WOLFSRC/WL_INTER.C | 1718 +++++++++++++++ WOLFSRC/WL_MAIN.C | 1616 ++++++++++++++ WOLFSRC/WL_MENU.C | 3986 +++++++++++++++++++++++++++++++++++ WOLFSRC/WL_MENU.H | 231 ++ WOLFSRC/WL_PLAY.C | 1472 +++++++++++++ WOLFSRC/WL_SCALE.C | 733 +++++++ WOLFSRC/WL_STATE.C | 1480 +++++++++++++ WOLFSRC/WL_TEXT.C | 859 ++++++++ WOLFSRC/WOLF.DSW | Bin 0 -> 805 bytes WOLFSRC/WOLF.EXE | Bin 0 -> 50148 bytes WOLFSRC/WOLF.IDE | Bin 0 -> 30962 bytes WOLFSRC/WOLF.OBR | Bin 0 -> 467 bytes WOLFSRC/WOLF.~DE | Bin 0 -> 28360 bytes WOLFSRC/WOLF1VER.H | 7 + WOLFSRC/WOLF3D.DSK | Bin 0 -> 1196 bytes WOLFSRC/WOLF3D.EXE | Bin 0 -> 494951 bytes WOLFSRC/WOLF3D.MAP | 3660 ++++++++++++++++++++++++++++++++ WOLFSRC/WOLF3D.PRJ | Bin 0 -> 14828 bytes WOLFSRC/WOLFGTV.H | 10 + WOLFSRC/WOLFHACK.C | 186 ++ WOLFSRC/WOLFJVER.H | 8 + WOLFSRC/WOLFVER.H | 7 + 108 files changed, 48051 insertions(+) create mode 100644 WOLFSRC/AUDIOSDM.H create mode 100644 WOLFSRC/AUDIOSOD.H create mode 100644 WOLFSRC/AUDIOWL1.H create mode 100644 WOLFSRC/AUDIOWL6.H create mode 100644 WOLFSRC/BUDIOSOD.H create mode 100644 WOLFSRC/BUDIOWL6.H create mode 100644 WOLFSRC/C0.ASM create mode 100644 WOLFSRC/CONTIGSC.C create mode 100644 WOLFSRC/DETECT.C create mode 100644 WOLFSRC/FOREIGN.H create mode 100644 WOLFSRC/F_SPEAR.H create mode 100644 WOLFSRC/GFXE_SOD.EQU create mode 100644 WOLFSRC/GFXE_SOD.H create mode 100644 WOLFSRC/GFXE_WL1.EQU create mode 100644 WOLFSRC/GFXE_WL1.H create mode 100644 WOLFSRC/GFXE_WL6.EQU create mode 100644 WOLFSRC/GFXE_WL6.H create mode 100644 WOLFSRC/GFXV_SDM.EQU create mode 100644 WOLFSRC/GFXV_SDM.H create mode 100644 WOLFSRC/GFXV_SOD.EQU create mode 100644 WOLFSRC/GFXV_SOD.H create mode 100644 WOLFSRC/GFXV_WL1.EQU create mode 100644 WOLFSRC/GFXV_WL1.H create mode 100644 WOLFSRC/GFXV_WL6.EQU create mode 100644 WOLFSRC/GFXV_WL6.H create mode 100644 WOLFSRC/GO.BAT create mode 100644 WOLFSRC/GOODSTUF.TXT create mode 100644 WOLFSRC/H_LDIV.ASM create mode 100644 WOLFSRC/ID_CA.C create mode 100644 WOLFSRC/ID_CA.H create mode 100644 WOLFSRC/ID_HEAD.H create mode 100644 WOLFSRC/ID_HEADS.H create mode 100644 WOLFSRC/ID_IN.C create mode 100644 WOLFSRC/ID_IN.H create mode 100644 WOLFSRC/ID_MM.C create mode 100644 WOLFSRC/ID_MM.H create mode 100644 WOLFSRC/ID_PM.C create mode 100644 WOLFSRC/ID_PM.H create mode 100644 WOLFSRC/ID_SD.C create mode 100644 WOLFSRC/ID_SD.EQU create mode 100644 WOLFSRC/ID_SD.H create mode 100644 WOLFSRC/ID_SD_A.ASM create mode 100644 WOLFSRC/ID_US.H create mode 100644 WOLFSRC/ID_US_1.C create mode 100644 WOLFSRC/ID_US_A.ASM create mode 100644 WOLFSRC/ID_VH.C create mode 100644 WOLFSRC/ID_VH.H create mode 100644 WOLFSRC/ID_VH_A.ASM create mode 100644 WOLFSRC/ID_VL.C create mode 100644 WOLFSRC/ID_VL.EQU create mode 100644 WOLFSRC/ID_VL.H create mode 100644 WOLFSRC/ID_VL_A.ASM create mode 100644 WOLFSRC/JABHACK.ASM create mode 100644 WOLFSRC/MAPSSDM.H create mode 100644 WOLFSRC/MAPSSOD.H create mode 100644 WOLFSRC/MAPSWL1.H create mode 100644 WOLFSRC/MAPSWL6.H create mode 100644 WOLFSRC/MAPSWLF.H create mode 100644 WOLFSRC/MUNGE.C create mode 100644 WOLFSRC/OBJ/GAMEPAL.OBJ create mode 100644 WOLFSRC/OBJ/SIGNON.OBJ create mode 100644 WOLFSRC/OLDSCALE.C create mode 100644 WOLFSRC/PICLIST.H create mode 100644 WOLFSRC/README/LICENSE.DOC create mode 100644 WOLFSRC/README/README.TXT create mode 100644 WOLFSRC/README/RELEASE.TXT create mode 100644 WOLFSRC/README/~$ICENSE.DOC create mode 100644 WOLFSRC/RULES.ASI create mode 100644 WOLFSRC/SDMVER.H create mode 100644 WOLFSRC/SHAREMSG.H create mode 100644 WOLFSRC/SODVER.H create mode 100644 WOLFSRC/SPANISH.H create mode 100644 WOLFSRC/SPANVER.H create mode 100644 WOLFSRC/SV.EXE create mode 100644 WOLFSRC/VERSION.H create mode 100644 WOLFSRC/WHACK_A.ASM create mode 100644 WOLFSRC/WLFJ1VER.H create mode 100644 WOLFSRC/WL_ACT1.C create mode 100644 WOLFSRC/WL_ACT2.C create mode 100644 WOLFSRC/WL_AGENT.C create mode 100644 WOLFSRC/WL_ASM.ASM create mode 100644 WOLFSRC/WL_DEBUG.C create mode 100644 WOLFSRC/WL_DEF.H create mode 100644 WOLFSRC/WL_DRAW.C create mode 100644 WOLFSRC/WL_DR_A.ASM create mode 100644 WOLFSRC/WL_GAME.C create mode 100644 WOLFSRC/WL_INTER.C create mode 100644 WOLFSRC/WL_MAIN.C create mode 100644 WOLFSRC/WL_MENU.C create mode 100644 WOLFSRC/WL_MENU.H create mode 100644 WOLFSRC/WL_PLAY.C create mode 100644 WOLFSRC/WL_SCALE.C create mode 100644 WOLFSRC/WL_STATE.C create mode 100644 WOLFSRC/WL_TEXT.C create mode 100644 WOLFSRC/WOLF.DSW create mode 100644 WOLFSRC/WOLF.EXE create mode 100644 WOLFSRC/WOLF.IDE create mode 100644 WOLFSRC/WOLF.OBR create mode 100644 WOLFSRC/WOLF.~DE create mode 100644 WOLFSRC/WOLF1VER.H create mode 100644 WOLFSRC/WOLF3D.DSK create mode 100644 WOLFSRC/WOLF3D.EXE create mode 100644 WOLFSRC/WOLF3D.MAP create mode 100644 WOLFSRC/WOLF3D.PRJ create mode 100644 WOLFSRC/WOLFGTV.H create mode 100644 WOLFSRC/WOLFHACK.C create mode 100644 WOLFSRC/WOLFJVER.H create mode 100644 WOLFSRC/WOLFVER.H diff --git a/WOLFSRC/AUDIOSDM.H b/WOLFSRC/AUDIOSDM.H new file mode 100644 index 0000000..ca94f62 --- /dev/null +++ b/WOLFSRC/AUDIOSDM.H @@ -0,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! +// +///////////////////////////////////////////////// diff --git a/WOLFSRC/AUDIOSOD.H b/WOLFSRC/AUDIOSOD.H new file mode 100644 index 0000000..8442242 --- /dev/null +++ b/WOLFSRC/AUDIOSOD.H @@ -0,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! +// +///////////////////////////////////////////////// diff --git a/WOLFSRC/AUDIOWL1.H b/WOLFSRC/AUDIOWL1.H new file mode 100644 index 0000000..a1363df --- /dev/null +++ b/WOLFSRC/AUDIOWL1.H @@ -0,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! +// +///////////////////////////////////////////////// diff --git a/WOLFSRC/AUDIOWL6.H b/WOLFSRC/AUDIOWL6.H new file mode 100644 index 0000000..2e76ed3 --- /dev/null +++ b/WOLFSRC/AUDIOWL6.H @@ -0,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! +// +///////////////////////////////////////////////// diff --git a/WOLFSRC/BUDIOSOD.H b/WOLFSRC/BUDIOSOD.H new file mode 100644 index 0000000..8442242 --- /dev/null +++ b/WOLFSRC/BUDIOSOD.H @@ -0,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! +// +///////////////////////////////////////////////// diff --git a/WOLFSRC/BUDIOWL6.H b/WOLFSRC/BUDIOWL6.H new file mode 100644 index 0000000..f2f11ec --- /dev/null +++ b/WOLFSRC/BUDIOWL6.H @@ -0,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! +// +///////////////////////////////////////////////// diff --git a/WOLFSRC/C0.ASM b/WOLFSRC/C0.ASM new file mode 100644 index 0000000..0284256 --- /dev/null +++ b/WOLFSRC/C0.ASM @@ -0,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@, , __PASCAL__ + +IFDEF __BOSS__ +PubSym@ CSalias@,, __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
, __CDECL__ +PubSym@ _Int4Vector
, __CDECL__ +PubSym@ _Int5Vector
, __CDECL__ +PubSym@ _Int6Vector
, __CDECL__ +; +; Miscellaneous variables +; +PubSym@ _C0argc, , __CDECL__ +dPtrPub@ _C0argv, 0, __CDECL__ +dPtrPub@ _C0environ, 0, __CDECL__ +PubSym@ _envLng, , __CDECL__ +PubSym@ _envseg, , __CDECL__ +PubSym@ _envSize, , __CDECL__ +PubSym@ _psp, , __CDECL__ +PubSym@ _version,
, __CDECL__ +PubSym@ _brklvl,
, __CDECL__ +PubSym@ _heaptop,
, __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,
, sName + ENDM + +dPtrPub@ MACRO Sym, VALUE, sName ;; Global Data Pointer +PubSym@ Sym,
, 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, , sName + ENDM + +dPtrPub@ MACRO Sym, VALUE, sName ;; Global Data Pointer +PubSym@ Sym, , 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, , sName + ENDM + +PubProc@ MACRO Sym, sName ;; Open a Public function +PubSym@ Sym, , sName + ENDM + +ExtProc@ MACRO Sym, sName ;; External Function +ExtSym@ Sym, FAR, sName + ENDM + +cPtr@ MACRO Sym, VALUE, sName ;; Static Function pointer +Static@ Sym,
, sName + ENDM + +cPtrPub@ MACRO Sym, VALUE, sName;; Global Function Pointer +PubSym@ Sym,
, 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, , sName + ENDM + +PubProc@ MACRO Sym, sName ;; Open a Public function +PubSym@ Sym, , sName + ENDM + +ExtProc@ MACRO Sym, sName ;; External Function +ExtSym@ Sym, NEAR, sName + ENDM + +cPtr@ MACRO Sym, VALUE, sName ;; Static Function pointer +Static@ Sym, , sName + ENDM + +cPtrPub@ MACRO Sym, VALUE, sName ;; Global Function Pointer +PubSym@ Sym, , 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 + 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 + mov sp, bp + ENDIF + pop bp +ENDM + +.LIST diff --git a/WOLFSRC/SDMVER.H b/WOLFSRC/SDMVER.H new file mode 100644 index 0000000..ed4948f --- /dev/null +++ b/WOLFSRC/SDMVER.H @@ -0,0 +1,8 @@ +#define SPEAR +#define SPEARDEMO +#define ARTSEXTERN +#define DEMOSEXTERN +#define CARMACIZED +//#define MYPROFILE +//#define DEBCHECK +//#define UPLOAD diff --git a/WOLFSRC/SHAREMSG.H b/WOLFSRC/SHAREMSG.H new file mode 100644 index 0000000..8e4d588 --- /dev/null +++ b/WOLFSRC/SHAREMSG.H @@ -0,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" diff --git a/WOLFSRC/SODVER.H b/WOLFSRC/SODVER.H new file mode 100644 index 0000000..e5f9448 --- /dev/null +++ b/WOLFSRC/SODVER.H @@ -0,0 +1,7 @@ +#define SPEAR +#define ARTSEXTERN +#define DEMOSEXTERN +#define CARMACIZED +//#define MYPROFILE +//#define DEBCHECK +//#define UPLOAD diff --git a/WOLFSRC/SPANISH.H b/WOLFSRC/SPANISH.H new file mode 100644 index 0000000..126fc20 --- /dev/null +++ b/WOLFSRC/SPANISH.H @@ -0,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" + diff --git a/WOLFSRC/SPANVER.H b/WOLFSRC/SPANVER.H new file mode 100644 index 0000000..0cb07a5 --- /dev/null +++ b/WOLFSRC/SPANVER.H @@ -0,0 +1,8 @@ +//#define SPEAR +#define SPANISH +#define ARTSEXTERN +#define DEMOSEXTERN +//#define MYPROFILE +//#define DEBCHECK +#define CARMACIZED +//#define UPLOAD diff --git a/WOLFSRC/SV.EXE b/WOLFSRC/SV.EXE new file mode 100644 index 0000000000000000000000000000000000000000..72d3ff022660dc7c8740c9a819fd7559621977cf GIT binary patch literal 6746 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 literal 0 HcmV?d00001 diff --git a/WOLFSRC/VERSION.H b/WOLFSRC/VERSION.H new file mode 100644 index 0000000..c425da6 --- /dev/null +++ b/WOLFSRC/VERSION.H @@ -0,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 diff --git a/WOLFSRC/WHACK_A.ASM b/WOLFSRC/WHACK_A.ASM new file mode 100644 index 0000000..fdd8432 --- /dev/null +++ b/WOLFSRC/WHACK_A.ASM @@ -0,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 + diff --git a/WOLFSRC/WLFJ1VER.H b/WOLFSRC/WLFJ1VER.H new file mode 100644 index 0000000..e6e2a8e --- /dev/null +++ b/WOLFSRC/WLFJ1VER.H @@ -0,0 +1,9 @@ +//#define SPEAR +#define JAPAN +#define JAPDEMO +#define UPLOAD +#define ARTSEXTERN +#define DEMOSEXTERN +//#define MYPROFILE +//#define DEBCHECK +#define CARMACIZED diff --git a/WOLFSRC/WL_ACT1.C b/WOLFSRC/WL_ACT1.C new file mode 100644 index 0000000..911b18d --- /dev/null +++ b/WOLFSRC/WL_ACT1.C @@ -0,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;iareanumber] = 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; + +} + diff --git a/WOLFSRC/WL_ACT2.C b/WOLFSRC/WL_ACT2.C new file mode 100644 index 0000000..96fe848 --- /dev/null +++ b/WOLFSRC/WL_ACT2.C @@ -0,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 && checkspeed*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<y = ((long)ob->tiley<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<y = ((long)ob->tiley<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<y = ((long)ob->tiley<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<y = ((long)ob->tiley<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<y = ((long)ob->tiley<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()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<y = ((long)ob->tiley<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<y = ((long)ob->tiley<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<y = ((long)ob->tiley<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<y = ((long)ob->tiley<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()>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<y = ((long)ob->tiley<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 && checkx = 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 diff --git a/WOLFSRC/WL_AGENT.C b/WOLFSRC/WL_AGENT.C new file mode 100644 index 0000000..e5d8777 --- /dev/null +++ b/WOLFSRC/WL_AGENT.C @@ -0,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>=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 99) + gamestate.ammo = 99; + DrawAmmo (); +} + +//=========================================================================== + +/* +================== += += GiveKey += +================== +*/ + +void GiveKey (int key) +{ + gamestate.keys |= (1<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 && check0) + yl--; + if (yh0) + xl--; + if (xh 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))<y < (((long)(mapheight-1))<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<y = ((long)tiley<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)<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; +} + + diff --git a/WOLFSRC/WL_ASM.ASM b/WOLFSRC/WL_ASM.ASM new file mode 100644 index 0000000..baa8655 --- /dev/null +++ b/WOLFSRC/WL_ASM.ASM @@ -0,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 diff --git a/WOLFSRC/WL_DEBUG.C b/WOLFSRC/WL_DEBUG.C new file mode 100644 index 0000000..4949081 --- /dev/null +++ b/WOLFSRC/WL_DEBUG.C @@ -0,0 +1,722 @@ +// WL_DEBUG.C + +#include "WL_DEF.H" +#pragma hdrstop +#include + +/* +============================================================================= + + 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;inext;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 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>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 && maporgx0) + maporgy--; + if (controly > 0 && maporgyvisview) + viewtype = mapview; + } + if (!c.button0) + button0held = false; +#endif + + OverheadRefresh (); + + } while (!Keyboard[sc_Escape]); + + IN_ClearKeysDown (); +} +#endif + diff --git a/WOLFSRC/WL_DEF.H b/WOLFSRC/WL_DEF.H new file mode 100644 index 0000000..345e11e --- /dev/null +++ b/WOLFSRC/WL_DEF.H @@ -0,0 +1,1276 @@ +//#define BETA +#define YEAR 1992 +#define MONTH 9 +#define DAY 30 + +#include "ID_HEADS.H" +#include +#include + +#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); diff --git a/WOLFSRC/WL_DRAW.C b/WOLFSRC/WL_DRAW.C new file mode 100644 index 0000000..658ad24 --- /dev/null +++ b/WOLFSRC/WL_DRAW.C @@ -0,0 +1,1403 @@ +// WL_DRAW.C + +#include "WL_DEF.H" +#include +#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 (nxviewheight = 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<>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/2 && ny>8)) + // + if (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; iviewheight; + 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(); +} + + +//=========================================================================== + diff --git a/WOLFSRC/WL_DR_A.ASM b/WOLFSRC/WL_DR_A.ASM new file mode 100644 index 0000000..e7c3731 --- /dev/null +++ b/WOLFSRC/WL_DR_A.ASM @@ -0,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 + + diff --git a/WOLFSRC/WL_GAME.C b/WOLFSRC/WL_GAME.C new file mode 100644 index 0000000..437793f --- /dev/null +++ b/WOLFSRC/WL_GAME.C @@ -0,0 +1,1484 @@ +// WL_GAME.C + +#include "WL_DEF.H" +#pragma hdrstop + +#ifdef MYPROFILE +#include +#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;ywidth; + 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= 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= 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 (clockwiseiangle) + 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 (curangleangle += 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); + +} + diff --git a/WOLFSRC/WL_INTER.C b/WOLFSRC/WL_INTER.C new file mode 100644 index 0000000..41b5eae --- /dev/null +++ b/WOLFSRC/WL_INTER.C @@ -0,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='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.TimeCountname); + + // + // 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 +#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;inext) + 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>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>= 8; +} + + + +//=========================================================================== + +/* +=================== += += SetupWalls += += Map tile values to scaled pics += +=================== +*/ + +void SetupWalls (void) +{ + int i; + + for (i=1;i=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 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???"); +} + diff --git a/WOLFSRC/WL_MENU.C b/WOLFSRC/WL_MENU.C new file mode 100644 index 0000000..4e18c49 --- /dev/null +++ b/WOLFSRC/WL_MENU.C @@ -0,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"); + 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=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;i19) + 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;iamount;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;iactive && (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(TimeCountcurpos; + + + WindowX=PrintX=item_i->x+item_i->indent; + WindowY=PrintY=item_i->y; + WindowW=320; + WindowH=200; + + for (i=0;iamount;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 (mouseydir=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 (mousexdir=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 +} diff --git a/WOLFSRC/WL_MENU.H b/WOLFSRC/WL_MENU.H new file mode 100644 index 0000000..4838ffe --- /dev/null +++ b/WOLFSRC/WL_MENU.H @@ -0,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); + + diff --git a/WOLFSRC/WL_PLAY.C b/WOLFSRC/WL_PLAY.C new file mode 100644 index 0000000..ff3a82c --- /dev/null +++ b/WOLFSRC/WL_PLAY.C @@ -0,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 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>= 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. + + + +############################################################################# +*/ + + +/* +========================= += += 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;iprev; + 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 (); +} + diff --git a/WOLFSRC/WL_SCALE.C b/WOLFSRC/WL_SCALE.C new file mode 100644 index 0000000..5b4a415 --- /dev/null +++ b/WOLFSRC/WL_SCALE.C @@ -0,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=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;icode[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= 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 += += += 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= 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)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 += += += 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; + diff --git a/WOLFSRC/WL_STATE.C b/WOLFSRC/WL_STATE.C new file mode 100644 index 0000000..223e5ef --- /dev/null +++ b/WOLFSRC/WL_STATE.C @@ -0,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<y = ((long)tiley<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; +} + + diff --git a/WOLFSRC/WL_TEXT.C b/WOLFSRC/WL_TEXT.C new file mode 100644 index 0000000..9ed3ec1 --- /dev/null +++ b/WOLFSRC/WL_TEXT.C @@ -0,0 +1,859 @@ +// WL_TEXT.C + +#include "WL_DEF.H" +#pragma hdrstop + +/* +============================================================================= + +TEXT FORMATTING COMMANDS +------------------------ +^C Change text color +^E[enter] End of layout (all pages) +^G,,[enter] Draw a graphic and push margins +^P[enter] start new page, must be the first chars in a layout +^L,[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 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;i1) + { + #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&pu)hwz`~Hu1f+m~nS&jU zVSErhlR=Pyk%5VU6UZ*l&q>qEOi5+DYYa{j2@)_Gq{Z1PCfGkT z$k{a}+~3CyOz8PKdV{2B1Q>x%WB_6iNg4P9)(#>$7`6%op!>zy-!H_|J=j^#nM`ZG zGKzqLUy^}Ak3m69NAaa1jOGBE2$9*#m>|q4|3n@}gJS3bSdR{a4uc`{R3;b=as)E_ zFOwe=Fbr53SkU5tVt0dVf|zc^AOK`j9@d6nb08!K!#V*rQ0y@=a5yrifGndq`2U}Q F0RSjNLT~^8 literal 0 HcmV?d00001 diff --git a/WOLFSRC/WOLF.EXE b/WOLFSRC/WOLF.EXE new file mode 100644 index 0000000000000000000000000000000000000000..17d4b8eafa4f78e8b9741a77baf1118c5e911e0a GIT binary patch literal 50148 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 RJBoVVZ_B|wEhH)P{{RI5maYH* literal 0 HcmV?d00001 diff --git a/WOLFSRC/WOLF.OBR b/WOLFSRC/WOLF.OBR new file mode 100644 index 0000000000000000000000000000000000000000..d51eda791f38af94fa3c32e2693aa06180bfceeb GIT binary patch literal 467 zcmZ=N$}cZYEm8OzGjwq-kxRFVDb7eN&r6Rf&Mz%WPK_xj&PdJ4i7ANBP0Y;GOJ+EO0@AG*&S2L7 zRj3HGRu_nkpcv!;D0e^@( TgOrg7Kq2~os0?m-Xg)6E|yI*Cl$t-(U5wyHC%Y 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 G_kRH}1)ekj literal 0 HcmV?d00001 diff --git a/WOLFSRC/WOLF3D.MAP b/WOLFSRC/WOLF3D.MAP new file mode 100644 index 0000000..96a71f4 --- /dev/null +++ b/WOLFSRC/WOLF3D.MAP @@ -0,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 + diff --git a/WOLFSRC/WOLF3D.PRJ b/WOLFSRC/WOLF3D.PRJ new file mode 100644 index 0000000000000000000000000000000000000000..28966378dc2cc581cbec51e7192353ff7675e22f GIT binary patch literal 14828 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 literal 0 HcmV?d00001 diff --git a/WOLFSRC/WOLFGTV.H b/WOLFSRC/WOLFGTV.H new file mode 100644 index 0000000..c425da6 --- /dev/null +++ b/WOLFSRC/WOLFGTV.H @@ -0,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 diff --git a/WOLFSRC/WOLFHACK.C b/WOLFSRC/WOLFHACK.C new file mode 100644 index 0000000..def2333 --- /dev/null +++ b/WOLFSRC/WOLFHACK.C @@ -0,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<>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 ; y0) + 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>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); +} + diff --git a/WOLFSRC/WOLFJVER.H b/WOLFSRC/WOLFJVER.H new file mode 100644 index 0000000..234d4c5 --- /dev/null +++ b/WOLFSRC/WOLFJVER.H @@ -0,0 +1,8 @@ +//#define SPEAR +#define JAPAN +#define ARTSEXTERN +#define DEMOSEXTERN +//#define MYPROFILE +//#define DEBCHECK +#define CARMACIZED +//#define UPLOAD diff --git a/WOLFSRC/WOLFVER.H b/WOLFSRC/WOLFVER.H new file mode 100644 index 0000000..d14c7c4 --- /dev/null +++ b/WOLFSRC/WOLFVER.H @@ -0,0 +1,7 @@ +//#define SPEAR +#define ARTSEXTERN +#define DEMOSEXTERN +//#define MYPROFILE +//#define DEBCHECK +#define CARMACIZED +//#define UPLOAD