From c8940ef65f3e3c92a124fed00395d703d6e890be Mon Sep 17 00:00:00 2001 From: archive Date: Fri, 21 Jul 1995 00:00:00 +0000 Subject: [PATCH] as released 1995-07-21 --- AUDIOSDM.H | 142 ++ AUDIOSOD.H | 142 ++ AUDIOWL1.H | 133 ++ AUDIOWL6.H | 151 ++ BUDIOSOD.H | 142 ++ BUDIOWL6.H | 151 ++ C0.ASM | 841 ++++++++++ CONTIGSC.C | 733 ++++++++ DETECT.C | 87 + FOREIGN.H | 110 ++ F_SPEAR.H | 87 + GFXE_SOD.EQU | 47 + GFXE_SOD.H | 53 + GFXE_WL1.EQU | 201 +++ GFXE_WL1.H | 211 +++ GFXE_WL6.EQU | 47 + GFXE_WL6.H | 53 + GFXV_SDM.EQU | 208 +++ GFXV_SDM.H | 224 +++ GFXV_SOD.EQU | 259 +++ GFXV_SOD.H | 280 ++++ GFXV_WL1.EQU | 199 +++ GFXV_WL1.H | 209 +++ GFXV_WL6.EQU | 206 +++ GFXV_WL6.H | 216 +++ GO.BAT | 5 + GOODSTUF.TXT | 56 + H_LDIV.ASM | 227 +++ ID_CA.C | 1768 ++++++++++++++++++++ ID_CA.H | 101 ++ ID_HEAD.H | 34 + ID_HEADS.H | 123 ++ ID_IN.C | 990 +++++++++++ ID_IN.H | 202 +++ ID_MM.C | 953 +++++++++++ ID_MM.H | 96 ++ ID_PM.C | 1199 +++++++++++++ ID_PM.H | 83 + ID_SD.C | 2367 ++++++++++++++++++++++++++ ID_SD.EQU | 38 + ID_SD.H | 237 +++ ID_SD_A.ASM | 526 ++++++ ID_US.H | 123 ++ ID_US_1.C | 755 +++++++++ ID_US_A.ASM | 101 ++ ID_VH.C | 547 ++++++ ID_VH.H | 134 ++ ID_VH_A.ASM | 110 ++ ID_VL.C | 1084 ++++++++++++ ID_VL.EQU | 58 + ID_VL.H | 161 ++ ID_VL_A.ASM | 742 +++++++++ JABHACK.ASM | 98 ++ MAPSSDM.H | 14 + MAPSSOD.H | 33 + MAPSWL1.H | 42 + MAPSWL6.H | 73 + MAPSWLF.H | 16 + MUNGE.C | 48 + OBJ/GAMEPAL.OBJ | Bin 0 -> 893 bytes OBJ/SIGNON.OBJ | Bin 0 -> 64561 bytes OLDSCALE.C | 737 ++++++++ PICLIST.H | 36 + README/LICENSE.DOC | 129 ++ README/README.TXT | 8 + README/RELEASE.TXT | 53 + RULES.ASI | 692 ++++++++ SDMVER.H | 8 + SHAREMSG.H | 9 + SODVER.H | 7 + SPANISH.H | 112 ++ SPANVER.H | 8 + SV.EXE | Bin 0 -> 6746 bytes VERSION.H | 10 + WHACK_A.ASM | 100 ++ WLFJ1VER.H | 9 + WL_ACT1.C | 900 ++++++++++ WL_ACT2.C | 3872 ++++++++++++++++++++++++++++++++++++++++++ WL_AGENT.C | 1421 ++++++++++++++++ WL_ASM.ASM | 67 + WL_DEBUG.C | 722 ++++++++ WL_DEF.H | 1276 ++++++++++++++ WL_DRAW.C | 1403 ++++++++++++++++ WL_DR_A.ASM | 739 ++++++++ WL_GAME.C | 1484 +++++++++++++++++ WL_INTER.C | 1718 +++++++++++++++++++ WL_MAIN.C | 1616 ++++++++++++++++++ WL_MENU.C | 3986 ++++++++++++++++++++++++++++++++++++++++++++ WL_MENU.H | 231 +++ WL_PLAY.C | 1472 ++++++++++++++++ WL_SCALE.C | 733 ++++++++ WL_STATE.C | 1480 ++++++++++++++++ WL_TEXT.C | 859 ++++++++++ WOLF.DSW | Bin 0 -> 805 bytes WOLF.EXE | Bin 0 -> 50148 bytes WOLF.IDE | Bin 0 -> 30962 bytes WOLF.OBR | Bin 0 -> 467 bytes WOLF.~DE | Bin 0 -> 28360 bytes WOLF1VER.H | 7 + WOLF3D.DSK | Bin 0 -> 1196 bytes WOLF3D.EXE | Bin 0 -> 494951 bytes WOLF3D.MAP | 3660 ++++++++++++++++++++++++++++++++++++++++ WOLF3D.PRJ | Bin 0 -> 14828 bytes WOLFGTV.H | 10 + WOLFHACK.C | 186 +++ WOLFJVER.H | 8 + WOLFVER.H | 7 + 107 files changed, 48051 insertions(+) create mode 100644 AUDIOSDM.H create mode 100644 AUDIOSOD.H create mode 100644 AUDIOWL1.H create mode 100644 AUDIOWL6.H create mode 100644 BUDIOSOD.H create mode 100644 BUDIOWL6.H create mode 100644 C0.ASM create mode 100644 CONTIGSC.C create mode 100644 DETECT.C create mode 100644 FOREIGN.H create mode 100644 F_SPEAR.H create mode 100644 GFXE_SOD.EQU create mode 100644 GFXE_SOD.H create mode 100644 GFXE_WL1.EQU create mode 100644 GFXE_WL1.H create mode 100644 GFXE_WL6.EQU create mode 100644 GFXE_WL6.H create mode 100644 GFXV_SDM.EQU create mode 100644 GFXV_SDM.H create mode 100644 GFXV_SOD.EQU create mode 100644 GFXV_SOD.H create mode 100644 GFXV_WL1.EQU create mode 100644 GFXV_WL1.H create mode 100644 GFXV_WL6.EQU create mode 100644 GFXV_WL6.H create mode 100644 GO.BAT create mode 100644 GOODSTUF.TXT create mode 100644 H_LDIV.ASM create mode 100644 ID_CA.C create mode 100644 ID_CA.H create mode 100644 ID_HEAD.H create mode 100644 ID_HEADS.H create mode 100644 ID_IN.C create mode 100644 ID_IN.H create mode 100644 ID_MM.C create mode 100644 ID_MM.H create mode 100644 ID_PM.C create mode 100644 ID_PM.H create mode 100644 ID_SD.C create mode 100644 ID_SD.EQU create mode 100644 ID_SD.H create mode 100644 ID_SD_A.ASM create mode 100644 ID_US.H create mode 100644 ID_US_1.C create mode 100644 ID_US_A.ASM create mode 100644 ID_VH.C create mode 100644 ID_VH.H create mode 100644 ID_VH_A.ASM create mode 100644 ID_VL.C create mode 100644 ID_VL.EQU create mode 100644 ID_VL.H create mode 100644 ID_VL_A.ASM create mode 100644 JABHACK.ASM create mode 100644 MAPSSDM.H create mode 100644 MAPSSOD.H create mode 100644 MAPSWL1.H create mode 100644 MAPSWL6.H create mode 100644 MAPSWLF.H create mode 100644 MUNGE.C create mode 100644 OBJ/GAMEPAL.OBJ create mode 100644 OBJ/SIGNON.OBJ create mode 100644 OLDSCALE.C create mode 100644 PICLIST.H create mode 100644 README/LICENSE.DOC create mode 100644 README/README.TXT create mode 100644 README/RELEASE.TXT create mode 100644 RULES.ASI create mode 100644 SDMVER.H create mode 100644 SHAREMSG.H create mode 100644 SODVER.H create mode 100644 SPANISH.H create mode 100644 SPANVER.H create mode 100644 SV.EXE create mode 100644 VERSION.H create mode 100644 WHACK_A.ASM create mode 100644 WLFJ1VER.H create mode 100644 WL_ACT1.C create mode 100644 WL_ACT2.C create mode 100644 WL_AGENT.C create mode 100644 WL_ASM.ASM create mode 100644 WL_DEBUG.C create mode 100644 WL_DEF.H create mode 100644 WL_DRAW.C create mode 100644 WL_DR_A.ASM create mode 100644 WL_GAME.C create mode 100644 WL_INTER.C create mode 100644 WL_MAIN.C create mode 100644 WL_MENU.C create mode 100644 WL_MENU.H create mode 100644 WL_PLAY.C create mode 100644 WL_SCALE.C create mode 100644 WL_STATE.C create mode 100644 WL_TEXT.C create mode 100644 WOLF.DSW create mode 100644 WOLF.EXE create mode 100644 WOLF.IDE create mode 100644 WOLF.OBR create mode 100644 WOLF.~DE create mode 100644 WOLF1VER.H create mode 100644 WOLF3D.DSK create mode 100644 WOLF3D.EXE create mode 100644 WOLF3D.MAP create mode 100644 WOLF3D.PRJ create mode 100644 WOLFGTV.H create mode 100644 WOLFHACK.C create mode 100644 WOLFJVER.H create mode 100644 WOLFVER.H diff --git a/AUDIOSDM.H b/AUDIOSDM.H new file mode 100644 index 0000000..1154646 --- /dev/null +++ b/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/AUDIOSOD.H b/AUDIOSOD.H new file mode 100644 index 0000000..543e2c1 --- /dev/null +++ b/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/AUDIOWL1.H b/AUDIOWL1.H new file mode 100644 index 0000000..7ce44c0 --- /dev/null +++ b/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/AUDIOWL6.H b/AUDIOWL6.H new file mode 100644 index 0000000..3cb747b --- /dev/null +++ b/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/BUDIOSOD.H b/BUDIOSOD.H new file mode 100644 index 0000000..543e2c1 --- /dev/null +++ b/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/BUDIOWL6.H b/BUDIOWL6.H new file mode 100644 index 0000000..9cd66ca --- /dev/null +++ b/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/C0.ASM b/C0.ASM new file mode 100644 index 0000000..a53fa68 --- /dev/null +++ b/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/SDMVER.H b/SDMVER.H new file mode 100644 index 0000000..e5f4872 --- /dev/null +++ b/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/SHAREMSG.H b/SHAREMSG.H new file mode 100644 index 0000000..39c2797 --- /dev/null +++ b/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/SODVER.H b/SODVER.H new file mode 100644 index 0000000..b964b80 --- /dev/null +++ b/SODVER.H @@ -0,0 +1,7 @@ +#define SPEAR +#define ARTSEXTERN +#define DEMOSEXTERN +#define CARMACIZED +//#define MYPROFILE +//#define DEBCHECK +//#define UPLOAD diff --git a/SPANISH.H b/SPANISH.H new file mode 100644 index 0000000..361ca49 --- /dev/null +++ b/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/SPANVER.H b/SPANVER.H new file mode 100644 index 0000000..b0f3f62 --- /dev/null +++ b/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/SV.EXE b/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/VERSION.H b/VERSION.H new file mode 100644 index 0000000..05abb0e --- /dev/null +++ b/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/WHACK_A.ASM b/WHACK_A.ASM new file mode 100644 index 0000000..30b4f9a --- /dev/null +++ b/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/WLFJ1VER.H b/WLFJ1VER.H new file mode 100644 index 0000000..13e1340 --- /dev/null +++ b/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/WL_ACT1.C b/WL_ACT1.C new file mode 100644 index 0000000..10d84e4 --- /dev/null +++ b/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/WL_ACT2.C b/WL_ACT2.C new file mode 100644 index 0000000..d9d99a0 --- /dev/null +++ b/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/WL_AGENT.C b/WL_AGENT.C new file mode 100644 index 0000000..631478d --- /dev/null +++ b/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/WL_ASM.ASM b/WL_ASM.ASM new file mode 100644 index 0000000..ded7ba1 --- /dev/null +++ b/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/WL_DEBUG.C b/WL_DEBUG.C new file mode 100644 index 0000000..dd4674b --- /dev/null +++ b/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/WL_DEF.H b/WL_DEF.H new file mode 100644 index 0000000..d1bc080 --- /dev/null +++ b/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/WL_DRAW.C b/WL_DRAW.C new file mode 100644 index 0000000..68c59ae --- /dev/null +++ b/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/WL_DR_A.ASM b/WL_DR_A.ASM new file mode 100644 index 0000000..db1df24 --- /dev/null +++ b/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/WL_GAME.C b/WL_GAME.C new file mode 100644 index 0000000..9f63d9f --- /dev/null +++ b/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/WL_INTER.C b/WL_INTER.C new file mode 100644 index 0000000..c74cc9e --- /dev/null +++ b/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/WL_MENU.C b/WL_MENU.C new file mode 100644 index 0000000..7d1521c --- /dev/null +++ b/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/WL_MENU.H b/WL_MENU.H new file mode 100644 index 0000000..8ea7192 --- /dev/null +++ b/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/WL_PLAY.C b/WL_PLAY.C new file mode 100644 index 0000000..6a49dbc --- /dev/null +++ b/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/WL_SCALE.C b/WL_SCALE.C new file mode 100644 index 0000000..e9a9f92 --- /dev/null +++ b/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/WL_STATE.C b/WL_STATE.C new file mode 100644 index 0000000..ad534ba --- /dev/null +++ b/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/WL_TEXT.C b/WL_TEXT.C new file mode 100644 index 0000000..1df86b8 --- /dev/null +++ b/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/WOLF.EXE b/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/WOLF.OBR b/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 zlkESu=JTuSuKInyzv`;$>guZMGt2r1dfWOsGWAoYWY!GyU)|Y0m}%GW zoTyEjWJHdj5_U;^th;j8*etPoNRuzlE>=Gei}DNBN6CbgTF@* zeiL#C@-4`tkZ(gCgM0__IOMyKCm>Hko`QT2@-*c8kY^x2fEh{tJIKF6K7{-p@)6|UARj~i9r6j}KOm)ft5wt98e-nLyftw!z!KP_$64i5BeTe@SgzoBzmXJ3cQF;(su zU+*;2(z&&NXJ@85sCq!IeTm#zzV0N|ZR_pLT;c0qnd$5A=-i&^8tC7eX_FJT9(h-) zOY>UVw{6pF;oYjvkuq;Ly>6NFE><^+xXxXjisRj_F3Gfx-d;`PU9WCB>%ZNYRW2uc z19fbtwe4+Qxw4l~C!B5Dw_46B={+W?I9{1yv1=O_^!^Rjb#vGDFB2gBmw~ld2joYxPdFZrIbRLtkTR zdyKi%y$<%k>Y^;ar7g?Xy5+~7SzXMa{MD!HE7c^()()~Z4P!^Cr$7H;jNJ;gQiE!2-J52D(A9BmO_S^m%P`=)5F)R zFx9O)1~&I+8ag-c*s`T_!0Z*ih4O^)_0Bc9YMK7NO#6<3fzH0c%wXHVmd-){9-Asp zCLcRW@-nSAlpVJ`_ykiIM>%hnt72Krktds`Ma-FI+SUnM`Um?r_4f32W~#C)nj0s0 z4e+S&Rmqc3F)>q$zJK7F?cM#`{QI>=o|LK+G3CZ>Mp}({%GLhLRR8noaackcW#qp`EPSUmy4rm&m*6M73u)|B^Q(T?ky88PR$EUkGrmd)7 z-E7k`^3?a!5@y+o)>TW_7}GA-n2`}dFuh^L((LNx#$4f+0Y?k!$i1qud7b61l2L@8 zR$|t+wybDg-nw*Iw$Wr=evUHK;rVUq*R`x&-C|6=q*uuZ#7{3VOY7?!vyClFTcNbT z%>zd$>e!bxt!{3e@7{|Xxu_$*txIF3xb``!QHODZ(GEh(ha(9l;?4Ol4+f2KzHSn5FHXBVTnGhnl5p zo0{iyusL(4>D$8k&d4ZPbxP582RnD2KM(PCY?YBwv!=8Cc5K_)GqcWk<2jC~)$#u8 z+`40zVmZ=QN9@+N!S3sN8Dsk|j>6T+SXUBlJLKqGUBr~h7r{tt zH|m16I{3hKZSn0#T~McO3!bm84&RQ{1#Pvp56)6se0x$C(wV6`@^Vi7kw)#4JdsG+H*&5K{+oigo4qK1f;@hXXpiX<6ufw-fbzV8Q z_xBCXT)H~jv;oiV))mXw*4Ne}iPu&mZ@9i*+PLpIEuCGR7=fXi z6unCCEttCOD;oM6FkT^px|4pUH0u9{e?kdFF<&$xIzPHTIuJb&eJuJ?^xf#E(Q&c5 zSWB!g_CV~#STsI9K0m%bJ`g_;e=Pn|{MYeBQFYPgqMM7pR#cvtoM=jPCH5p9N<5!< zGZ9TrPIe{lOFof&H<@s1os~|Pv&VVJdER-$`JFQ|H7nJe8c5xjI-Ghf^}E!_;#tLe ziVqdPTwGhSvgGQL10{z`qNUBH1Eu$sK3)21>2FGl%WBJ7%6680t?X#oyJd;;$>q)E z1LY5tKVSZKd9WKDSdVNK>Bd{?ey_QG0b=vCu-_O>`Ol( z<-j?y;}aarqC^mH%&{!f)x8n1X;F#$7SbYMIF_}#HZ3M;Pa-XbG5oPCb(>-~EiP$) zjkF@O25Hn?Vy^0rU}RK;W6mdGgy&$wj?Qt+&d9S_o?CoE@V^8;X?lSdzG&t>W2TxU z((F7C8~KMwbwpd3Ja6>_n8k}TD>2h2t{uqgQRy2Pr{`bW{EPkn^ zR*3%$Vo*YI{9`#jLylh%&G9&nnJ47k_exGy7Sr}(?X-vQs4o5a6E z{Jj#tS^VAN-zEO_;@>X*HSmqOTaLdd{yy=q5WgF~F`aVUCH@xizbx_Xa(s{Y_lkd? z`1gzdfcRe#zeD^h#os9Y4dP!1-U9d|6}-=66SH{UnJ(|67y6X zG10FI&mQH+cZ5&vHC?-Tz^;@>a+SKwn38z@Yvm+%_i5dTg1X>&r3|6crqqWN|B#j!sVY?EC7 zpd8;Q{EUa%^m$mO?*u947cYH|BWJv21akK5dC%%5+m3sWA2PH!Q24 zvjJ0M*>w$#W_qMVqd3d=`-+r|=xWIy$Z1ZjAlH0={)u_hAAUmdp6hhx;5`3kp4;z*T_6vRfZ{JjQ=z- z#`g2J(c7{(4LU#1;Tx5gk10d>4Dh^i%Xd0-Ud`bforf=Dm@+buKddwflV0l?NdH9+ z*O)w9Qw>wjGP5IN&8AHajmy?8Uo>mMrcJFaOY0jEUb?iUnM5{^W1;&uIlSY-ybk6Y z@Ek8SHihGdspd>*+3~|^7%x1PdUBOoQ`rr{*=sltHgfBt1~IlS zcoe*bpZ%>JD^5Z@*BtR?rRC`Ko6)gnvplytlcB>kNzCwiI@`=j=?fH0W@)C8)DKq*DtW&ZyY7Am!~0dTqhxXF7DaUK-Td5z?6f9j>Pa zb#{hyWq0uSpu-szt5a3Hq}VvSLOQdd!xpdM?e{-Od zTYu*x#?~K?hO56i#B&zL@=i@=lg7EhZCOkA}lE4#6~e7#_1$Ax@ z=`=%!vsXc#J3>0Ep~Km$pw68koi)(m>{U=_Ur6T?=y3KbsPl!8P78E6dll5VE2Og) zI-I=<>fG(=*ml$k9qzmEpP%ax!?ssxcvNbZ0MFeS_uSktj_udJzpqCcUBuaM9>*Jc z0_O|5x$j~Q<^y`oKExi!yZgbS<3&zlPU4=#k%URIf7q2gm^_|*KRL#k=X5ytI7gi0 z&WBDqRg-E+ZAk4)J(4<-I+6MyRav~d_+arf#V3kS6=zBsO1ew-mpoPSddbHnm8DBc zHLAq708QjI%mX=uDMy$fwX5nFN6gkI@Cbu}J)Qw?aIpav10c~Swmmyt{b0$(Vh$Cn1Fq|9}sI#0!;G9*E zb9R7p`Y@blC?P`2nE>aUf}H0|D(7qnp5QY0*M6oO!@zPT!C9A=b1qWmL2f1BUY1D} zkKlaH@p7J)v4!Py!1F3+J)}Ghk=a;q4_8MS;k2G@8!2#J0Bu`GH$>PrYC>(J z7&;3)9i`BET!@rKkS$CYLAw)O6>^JnswJ>vDSIs?NL!qj^FpL7f#BB7%Qg0%Cst_r!uIWr}wkoIHko{qFl9_L1LC+yA% z*&Pj?Hc!VT_3Um&N;?G!yx!?v8IoI^Gh0Cjt=%(_*5h$LCU)n_&MrpUavlSnYdjsL zcpiNScX#z7Wh+D$<>Y!Nx+>%r=bSHrZHLzGSfurNoaJd=?**nGF^sf!$3bVCr(>y% z=p2FFYmqVl=|FT%tg$P zVfSW)w?MeSh?n3%|3GeW&U^{R1nT!Jq;+_lO=5Sk=|l`8t=;j^>GE_e70MMc+>g5j zVK?M#Cgj*9w>W2!1mgmB&qmsA;rs*Ib3*Jc3AL*XboO{Umddtg?moK>DSILJFah|UrKg!Wp_LE7zkIqyKqosfGAa4rpS+BP!*oclb^@^aQ)Q|MYILgy||M=6-+ zzrwZLjc`9i?t5vgszGjX&N7WcXzf-Z?Ta4gYh|>1QONGO(D^T(j#6k@-Gh{SAxkyE z3&}0c!Dc7VS-aIpyU*jiPwcLg9e9ki<$NA=zU1jBL3oe$eN33CsSL?2&RJnY@hxW! z(!M+_=g&}v7+jmLK!h`Z4RT%_h_}}=37ijloXv7At7P9eBdy)Z(D|yTqZF^eCf(N% zd>ta~ALo3YT1ReiPS%ZKU^%BC?VxC~{cAEgxnG@}5B(8NnG$q?mUAjNzcDN)+ZZ|j z;*W5y){G#ut$lMBXpn6&e2f{?H|4e^wW^t zOvouia*K1?Z79CAI|pgs7rUp}$BNxf`G$d!yxz;q`OtaB(@_fj&fy10ISd(E&g356 zS=)6;f7auD*a5-QNV{A(IX-ID z*uE0sMhNXj&?oxidvc3&5aS)85Ql0?vK6`ofF#^dn-00zBm48 z{8W5R(IDn1-Y;5`=tw-5cq=g@*_wPb`ARb5G&m1B?_*}71G5rurA%>a@uS7BU@l^? z0FMY1Gv}{J%-m*u_OnFuLuJVI2*U(+Dzry)V5;G{AJ@_E?K=Rs;9lOU5JQy{i3F^bvf zV2+2mmWs0F9`v2ja>j849p@%2hF6(ppbPo5g; zRHiZw#{+b}9o|*JFQEdMVGeEHco*_(B)1O=>N)4gnU*!@cPxf?ZSX6l0LZa#?wU8g zD_acja(=y(TW&8$`G!4F2>2fIX#B~nfB&#o2!7QRv}51))DGtYtR40u{Mt!p5Q3O< z<%HMsPV~tv=awvny-x5es37LNz==U$rWp28{?}3L(L6<`&a=YxU;6 z!(RNQJa!rdqu1kO*y{(sf)O?AIhRN{)DE8#!LMV2n3g;kK2?HW%>*%a7H6m(K85_R zY52tQP)=(eJA7*SU)k`<=wsI9!SE>;{QAa2pg&lj2g9dg@T;64=F&VEK1F|-r+zNW zgW*&6L>|oN@?iLs4t~`W%$pr?3@vLu)!)ox=ZZXbI0^`U{S&maArFS5hPU$AxiSxi zqYVEGA&y8qOU}kT7>-K*$+N?ekB1rdpwhgFoiNKHJ0p)p-j0lnHbrlUK7l>Jqhl*$ zH^-iios5l(H^=wH4`bi&_@b7gJBpq!`c2V<#QMZtiKB_%C90E`Cl4fFOn#J{>}+)I zb6#>jacWbWQ)_xKVnRDAGF_N2jf-uL_r{sI*;1^89m{f8t1%q=&BxfU2)pr%F}}m< z8-zQhxO<7aj<{3kbO?9la0d-{d01Ct(j8H;k}xlrBLORQu(A&}xbrrRaSyHB4=V|i z!5?F}r-pkixR-)^CAb%YdmXs1h5H$}UxE7(xZi;L3AkT?Yx`Wg=h{5i-nq8UwR5hG zbM2dJ+gyX?8Y|aOxkk!0P_A)u4U=n>T!U0sV_w*7SKN~3Xz{}0J(9pusxiOB&f_G` ze}NUZgz0`fX&R9Kq=+#e;f;aHQPJUein<1?jP{!4M7)0nzF6KoxrT}Fv_;eM5oM9e z7e@@OTqs&t+jNd)SyI0H7QVmhGx2+ktcjLlG)v2tuL#E!KYt0FY2K1J-jF($WeJB} z{8r^7LivcG_1fsd^#?0h~Vl#d9C&sUB!<*UGPrsPM%d;`1%Rnex$6I(;k~ z91$w7j;}I?h>`fifG@{Uvj!{1yD;uOZb~C#A{!#zk;fy?MNZ+9wQTgV=)vft(f6Yt zM;FE}itUd*h#B7ZVpHSu;y1v%jxkM_Og^XIQl3oUUW)@U4|U#-ALS zo8^dmG{%yS;eIfVDXptCPqp(KJZ#p(xW6udVmeXdpq(<@i9G@(%~5|CSsb$Wwdk)_ zs=Z>d$M*8~@(b$Ct2{V<4%2AnE zZ{<>sWKz_q_11nx$bNN&El1j~@a%K8ma~YQQRa>`?jTbpErWE3iRpSJ{5~Nu?3_Pm z+LcMmWCY$ZHx5%K%aErLcRgnMKb<)r-V^w6+oRe1f{tgUjT)g!5>$i!nV#fEv9*xx}1f&JR4u; zIC39zCY`hD+>OI~hPy?$yF*v1_$zgqk4%C4J0tgZc)gCR8vge~l}1bNoC5dvIdXrq zzIlI#?``gY3ipFtRSjSLgaTJTL9U(_xb_fc3%3=`^TZJ24bi#9yf;{$6FtU!! z%2HLrj2`YQ)<$TV1E+YGAl#&MR=wohSF4=24OQq^b$Ezmw(uld4AA zpCZGpMw#>~CKc#4CP}X`+!ZK#asl*Y56ycac>Ri=QUE>WkD{j*Ku`Un=xGJe)BY&B zwg9?T(CmkFtzOGqYj1j}-VeF8$MGS5Z;<0d+tL-OB{ri#|2ISWKdu6XQ8NpmW(taH zl#0?^&I+Nr++1=Dg*zR8>@yUlIh-9rF`f4wQL_bQcbGE1(x|ODAyjq1)*L|vpLlBP z{17T=>wH1kUFX)8_BD0r2bK+U-&P}sb@;WXB3XkB_l4vL=6G(%_Q^7P2l6`SifyiB zTIWAE=7nmW=`0=A{5+|7)*r{miqsOiAY|`Qz}^L7kG-Ozw1oH`5`2GQy4D8PCh*4< zQ$=YBEeQ24isCqUf%Gn1Jq?%8%z%B(^}>+-u0XCAihVMvea-cv0;ROby+3lFrfP3- z$X<28-eR%G-aTyZ!UFa#6nlC%D^l$(2_a9G+E&2&Tp~yvQ7BTcacKz2bZrSshqbB5 zWd%kI%VfmB{+7Kq`&_zI=mC~X55W4?63o|&Ulg+4 z6|jAg*yadAbF8*k6eyt;!`8cA>&g(aI?&cu3Q|X`VVf6+kWAOMcJZ(_HMiLUuV7W^sd=)*-YtBmS|v}-LgTIG0(oivlk=iiwz>e@>i;y`8nf5z z9_E?Sfh$`hvs^3}?owj^uKV)1Bji83H_w)-@B42OmlUYwOQe?bjh9;rAX^F|*M{x^ z=1cF|wQ>&(cdxe=K(*#Ytt*hrbp>;|zJR^;dF@?V0Cj0z)MW)wm*qu$t^n$Dc~O@a zKwX{}bwvTx6?st`3ZORRMO|3{b!A@E#sa8~Lr~hgYznoHLvHWFXYr?2mXm1;u^)S{jP#3ZV`KP+fxJj{7ibO9<5! zKy48e_sc6vOQSo4V!HN5-Gbt%M^T!?o)D@!V5>(^!I6&Ix;lgk+PYd$d@_b@T@yl` zO!;Maji7=vIJyea8*16V#vUMje)met=E@6yi$?7!a%;%m<$?8ttzwUR8x*DM7kwer zX#BqoEk~>=;LqQwRB6;!e+V_wB)zqgenHtCFSO>PwuMkwh4oO|1ZDTN>ia|)b3H?&t`kt_z{Y2W(v@DDK+`qjrT*cLYjfm!P;iBaFH} zgjyD;k|5LJb5^Hw(({waB$~O9=I80CkI??2d|D)b0@K zWYW*!Zb8|76S=5cL#Ugh{<`O_g0j0Ka#4H2sFZJOkD%-xh+NcdA=Ks0E%MzAOa3-N z*_{r#sJ$W79Vs8RS5S68LoVv}5bA+qA9cH+?5>4e)Eyzz#!?@3hoJ1RUeEPBkQio4%c2*hu z?u#+6&B2dXri^)UvB3&~F*O$&?5;KDJ%mTGmGsa`=;Qn?g#0RfG(OGcc^2UTgl{5b z{3v`n3l*~wA=B@7&);^#npO6f6z)RE^cN5k_lbKx1E0w8Qvq#IUVW%XJRiamtP&zo+1y3M9H zx#3N2__Q0o=Z51^NX$p88{XxHFSy}HZaB5w+UY__{ey1!nj1PDHh!@i4!YrEZupKH zj>gYl5TA9!J#P4%8~(-(tI$ZPcexwh>%N?Wl-bBiIbit$ zZ|{-Z8UWbDwr{NV!&$RQ2X8rxg6(I6gE|N6y3foh$z1hlaI}@@Kks ziary45ssfUQ}kz0jr*}ynxg+RMqmhHaI>^bKU7+wKcQQtuSXsxV<-&pX;6O8+6A!UPP&Wy31{H>kp=Sckc|0ZsZ<`U*UO-(vz=EW{O! z_z@@Z9qO?e>#+`ta3=~txhrXa zefSuE$2vTX1-JzxaYbjA?U=7M%X>9u`7gK&;b@Y~@@M!1&KS+|VI08wSc``-0r4>7 z2iYwD3x&7~T~KN;%V`*fI=xxmjgRmKUcyww;r$S^yak)_Jf6WL$U!3F&BtA9;@(YJd8Q;>o&_j;}{NOEB=P(P=v);fIna^M!Cro7aqi1 z%)mH|fe~%y&9WEu*nxNPCfs-&*+@h`^oAJ?A>;vUf)fv58iwNr^o9aw*=!%lIo+L&39HibYt6$8aC+KpGBNH_QJMg z?#DeCk0FS`yInTRucAM?Ap%#p=F|8J8N@C zA{AW`4kLcu+w zj70Q6<3Pe;FaC*_@fXa14L74dWSmdnp5b}S#aIkOFI*nVHQ)d~!*-NnBUa#96yOiI zANL{$8R(5J_;Cp3B+Bp)xG@vi7>WVtg)4)}M>vORIC&#^8E@lmG$oQB@FlA75sEPd zHbg^$XE^c2rzpZy+>U+-!MS0Z z;*Op85Lp8 zdO|g`AHKr@?7^p4iU)Bo?#68xk7V3{I5dYWGuPt){)u<75ies7GLVED5e7Xjo0ge> z#z%M$%g`U)5CIc35nOlpGV^(SiE_M+f8Yh!F%?rV8b+MAE;AoSHFn|+yaEN!q7YBu ze$2(Ouw~|bco;XKo%E~3HoT61U=0+w@B|)48u}v!SE81g+t7s5sK>wX2A05qM=>9h zk&c^jA#$1d42~cK=elt3@haBfS^OD~;0AQXG1BBql;b^Y!a5Ygg{ScZ9>i=+!|fQ0 zTQCB>5Dp_EyOPJztgEv8fO_o5XV`|<@FE^UGR!!tt+Kp>#dsX!p}{##m1Q*)xM0Ts z^uXVwD$5ewja%@kvC2}04{-xd%T<;d?80C4Rh9xggqgSNWoxy*M<9zI_$NkTXfyjlzr!Bvz!p3N1J;E2LZ8C#aU=R89A>nce4&jvg6-IXm$3%V!j8v~iX_~G zVHgMtWN6SH?hCyf<_rB9UR2|AY{x&a4$JX49>z@c3iX9X;oAsbXdQNA6H2fY4m^&z z7>VKV>%y$fIE{nYferX8its4r;ckq>Q1pNWUTv85TYQC2@gd&At5}ECSdM4V9U;)e zrwOw*;S{RzIo`#aSdX?!79XUwF zjTnILFqp!u^~NykZoG#VP=dvnk9&}YS7ojVi*YAf4Pn;9s6jdYfLXW`<8f9`+TasB zgNYb}c=SORTr`JS&*MiN#d}x>C!WNENXJk_!i>uyq&L1qHMZk*D42n1NX8)aLKlSK z3fK7~j$tn`mZ#F~O#;h$LN!;10NPpp0LV%R6v$B_na=qJ_}qLWh=OJ(72 zY0JXfai6X%{2fU8vhaH_PDF>4~${W0c9%7;)}4xsAn)2 z6EFrnVZdeL`2nV2B79NA8!M5G6OoNk2at(meAlHhssOiOIC|r7L}Sz%Jcg;r#1M2t z2=qM~qw2diM*R&A%z%uJ=*FlrJdQhXBL+f?=5CEqCvgxJ_y8NR29LmkAG$V1?ZI-) z!z7GEUqqp!7jegKl;I7m!}*xTsHgB4Zi5ELdNxMA0|jHyPMp6+KluBy4}QQ297P>= zV<$euTUdqrF&mp>8>5zC8jM)mhjhaun1}M-jZus7dt~88bVGE1(grR48l%qOpD4jo z=m{+v;~Jy3<0*{no17AfL$S#zA7Blh!8}aG1dK#~L_&+^KFKL3@jBKZAM-E)@i^H# zIi&(0U=5yu46QJL?fsKe4&noBL@p+vKO)iGkNDu9cn0$@6(i9fhvGOsHewC(k&8$) zb1f%Pfe%oCd6cD6Su0VK3gq3^XMsr+kY8_!mCGJ6M55xEHtK77RuY znBW_-{eE#c9}@O#X_V01+YD$U{13o#RuFa#fmunseE zGipu52WjY!o;VgB9(@1`20=olH9Y#eF!sgo&;n8Ps1Zyx1;rKd=V`3#9$88t{ ze`I)c3yz=+EAbSjVhk>J36I`}O>iI*GB!qpM?a5eFc@Xg;n5lRxf^l99z2HqT}gM{ z)7{_2CcJ=Z>FMrozy%AEj8Aue-N3T`>F$qUI>zIbkf*!1=@NT1;1eiV3{{)h;|#vT z7g&pQO=6GJ#>5_XBN@Z+FMVQ%LlS!=Aq=Zbe77d{ z*b$c4V;XM5aLfr!>~RNf#US)S1TN|#d!E3%C_y1=w2?ixp%{_S;R#J-&l^EArDuy2 z*|QG2&>xC1vgh}5WY0sWz+0G$93-O;{%wft`8nQ%g89fpI&MTP!qBGYSU8BCcpYo7 z1oz?=^u#4gWY6a?1EZmsITi-u`;f?b#B$6-UtG`(jyWg|j@f~?QH1+2R~{U*#4tE!0p?>Sx}efL zIEGQsm~A10V-A^EMmkLR!8$nRWhiI}9USu=D)By^#%xT(6r|u>)ZmzU6vK`O(I4%R zgJbq%2L9D$aLjY~DVn&!fJeFwjv3N*aLkj^wq6ftw)L{(74*_>>-8R9)$xf#_)yo> zs|3Z`re2TXUz(;~(~yPn7=#Gu(I7ST`WV~r4(^hhdfkel=!q+are2Mx#~!3(g`RMD z!P3<0Ib>l|NK>yrp~qOtPee;wdM87pf4}!>-TS>a&jAyV2 zf5Lps(7fM!2&PK!_a26DL>k}k{gL7Q-p_OF6?hf}_ycm#8_{^p#3xQ^=k<9MGcg4} z8t3&njxyxqPnd=ToRsJF`39fkZ&-o^^oGYUuTLr5h{hKEygm;=GR^CASSLxxa2DBm zNirBDDH?GYh9ta?yKhL2Ey+kuDaNz-bg(4F4w0nENEszbEu$rA*RB6?>ePQ%{x=2w zn*#q$f&Zq!e^cQ9#}wF+oRa8{eotFEqNbmcsFjr1VN%JFO}nHO^5>E}cBkY{{6_M; zs(EEpdCuQonelf^`Jc_(ZmzNE=8oCUuaaWcy$e@HOg__5qIpDM6OQS@VS&wUs7H=d3sI1 zxphCbmmE}n>=;#^SR%it{ru6)?eCvY_|kV_i)-A0NnHyvo#S>%y8QHoM(4N+DK>vh znP$dLtyI%5e`x80O6-A2e2Xi+ZKp=8>Yl#o8|gLoV zEmf6olw+yK?E~VSx2pCYfh}@;%7YrOKK_;mH4EkV;s-TKovTvz9!~wn-b*<`K#^Fg zY&XWMbG1hAws>_qA6qI*(*rl8a(gTnmMbNe#J;EXG^k}dNu=AC;gY0v=2`C=^@TU_ z9;I=*(u;gmh zD-GM@r0Jv7Q7yG6Y7f>Ps{JPQN`9Bss~4J9uTH&?Z(O}P;XNTSddcFVOiUQ}7oRQ^cnzqKBS$`&OMveB% zoU-JUmq+Ng#pTO0&WdBMWkpH7XM4zuFJp73mz7RP+Eh5fP%b5Ha!%N=Aw6l+Qxn#& zPfyyoaKef&M(!;+Tz2#5?H1|t)jD!jpB0m|u4;Yy$qQu;k$pOs%d}S)+_9&1E95h} zz&UoRY6)dWe2F|vN>C{owo0OG=o_D6u*bwN9ec|dM^n6VkJi~f*74&+=b7V9f1X1# zaqb*$!u@yWrT)t?&~kK%T+?Ns);{&zbZr$M%iS@C&b$>g4;vZYJ_B4OF_m-ol zs^!(`l5}|7>h$ehrIUWex;lO7_qT>Gy?m?A(NkNlIEz3pi;H1P1aT0+PB43+k91g^KXlDbY<<-eymN7W$lT0)+Wc6 z-8^W!S=y7^R?{#2WJlS!L3?t2HT}x8gRFgbd_$sj9?;%(!!GIB6JvE<9p*BJ*tnOC zHDgXC5y1&`B&y{#e3TsB@LIat)+QpMTcmeow`preKia0)+LHRo`4dK!zoh&yTRfuT zCI(`!-}&&ZN^aNMleM+AXP36COY9G(9w-EmunYC9hr_hYPIeDiO1-bNg4MWjex~OVkk#|5HwHJg@p_?Otbc?Xpx zWVs6cl3kmg{&rcm?d=9xQ+mgsbI;}6_Gr#y&v$iPS@Z}o zw3ItE>8bTge&^~KyyRXoc6ix{#J4G->>*o6Y?s`EV zZA+!oVQeXKP1HC}u2r+mi|$WLup85cJ8tsZI{dcFV%1&OcXJlDYaG$e!po99A}z}< zr)Ap>Ub*34ng*SgSV(D!_K|7H3lq{t3KsfLAJ*Or;3*7+V?W#l2Z&Ew8J+mNri z)X0T52REE^+s*|-G`ek#Qv=`5x@~8J-`IwA=`sz?SK7s(Z$tF|@ym+%OCxGZYio0LjdM`VF+XQZUt zm9SrTxhC~dk5X+Zw|8HxZLJp-`Fi~fi^@q-E_-z~DPK4XJ9vmF50pac=8Kv>N}*Mm z)9mi!U3~q5#P!Wj%XZBB^{Q!UHpiWT0~l*Y%kp^dPCm5by`{enHY{ztWALw6_2gjP zuI*_Z?_J8C=J5@G4&I)IJbxgQixQ_MxxO=(n`uWB=#@g5tlZLCO?^IyvL%PBZ*eu6 zS$U==S>BRPr9wG)tY)ldZF@~}Z|_a5)h3>J5v*oRnzuiV>0j>>IsW=C_qErI?p-tX z+SxnH>xkUx)I5@tI>;=^D`@tTTxIGKWsW{x3F(*ZkMF0c_441TMD>lsmgANmEM7}Z z+F^sYdrjJR25*=60h3H)DdF_-&OuEzX-9{TI$HaEZJknRa`&kj{Xw~4%(qE@y6}YNLxox{#d?PqH8@o-gS9!fo}U?$w!)8 z*h0}jS~a9ndFbC0bVpB^qRu&vI+M zu42*Vv5``tt}Ieg>JuuICVT&@+2slCjIm^1nM0HREGu*5n0?amCS>&&>?DNP-Ib|j(M~yw0<=QQ~bK7Y} zs0Ho6Tcfh-XFAsAE5ATr87D4IfD2#+i7q`cG)s zEKwP<+SBkizKNUrnNb?hRC}iOOwH)Oygt6x6Z~(1q2^|5)p&>2`-fT&3%6MJv2B5= zW=!J2@e~)G-@pCE_cOov-t>#_?Z5c0pKyI&>o30d5Z_yD2B)3#j(dIloY@sxk=Sa1 z>`7Du4_~fQAiL7^4lCDGlYDR2nz4Zfg)7ZKBrlFCpA!fr+E-;wO9s#^NuRi&OJ`f| zu-}_lGp=#9cd*F5$#VRJ;FI1a%7C#eZE{Xo;)I+sL!gIqkL21N@gEM>HFz-N;SNz| za=fN%#~b;7A1~$F@eJ3F=W6UNiY}RUj=SKrVl%mIXDq5CP|)jYk_{ABRL!o!P${@h zR_27(BpX@X#C2KuY!k6PE$(@vpE}zyLOCX~%ieTqlCp7}GMFLWjCbuex%@i2!R6OG z3}v+MbY=adO_dVIX$xfL&c>)!v2`8T#Ce>jnrcsp)Uzknp0H<)J)tg`>FPMK;MSUy zpGAYU#n#Pf?@}|`+hPk7cPXVoR2#dzPtZ_3VZSw>$RGCp97tXY2ybn}g40wc-s7EX z#w6Z8A+V>YV!U67BU`QpKIh%o`88S2y_%B2+p^MT%_*D1by2=^(L4NCZ;dGEX$#kk zEw-u7Y&BH0bZb%zTbA2Y@l~<4D7kGs4S{C%IOoJTQi1koZza|_Q9NQKzLG1ui)>l$ z7c;U{**S4kc_47<#F6D}VZb3onPYN?k1F@lIGv*F+_+W4MkU+Cc71Tuh~OrXJxhny z^jn^xU*2`OUE{u88_bb`4a3+lZ29e)<#z4zyLG`0v8CzC9F7&bCzr$Z73Z_MjlqK+ z)z028qR!4HON*nwH$t^KCti)b`f5g&i;I#R4J1m^c{TPg8GPAwoOJ*UmMbr`7%9tJvy!Ox>UR z!kT5}c5UmaQ-~r%~4-mc&%@+?@e?{M;Fs8>bG`9MKF~Iu^1anmD&4eS*JNK zM=Xd?>g!I_ooqSm+!ayhwbbo*Hbkr$RbF@UdVnK!p1Ss6fK!&rK!BI(+J3$L?60?v zI#}n~Z?wuK6>H;_>Dp-&z?Lr-hqfMQtu<&QSFPmD(A6){FRhRwiof5cKX`g%Ialee z^Xlq~_i%}`;@!r0_jK+5e2h;L#4*lZKSsj;>llHP*R|HVDmCKdH|i=oPu{@Ef6!hk z_5_oeQ;SpnCU|Xv2rkZZnczQ;JepAVn;oVrmy6GFuTCEPNq4~cHRFbLKOSt<9cP#; zp)RJec+a{ubNA0m_}=O@%rYi?FHf5utN2{irWJK1l_f`BxOVSe=sUMFd+IGMi@Le| zGYWN|O_$tBT3hj7^tN?MlQ*pOn9Dz4Nkg@)wb52hs+4H5UM<(j*ZN$~C#q6)bxoO+ z!P8LFZ_Oa56nttM`_sdusHBrQ$K>i5xNwHELz_R1o|%$u<;uGRI$4$~!|=@3!!%?L zODhYGoeF<0;b7~9=UOi;?`k_0;{91H@s+aj(#q^(RQvz-Wf$v*nHT8wDPEn{rr&b% z{8niT9a(d*k`MH!f=>g_4IPP`t^EIYIi82r*%f;6^bpV5Q%m1CI7z)yI-!{8h^Lq_ zEm0_Fy@njmY5z-sOAt>l#RZR|?z7!l9L;i&VrY)dt5qs;a(N_2gyiMrcuLf=dA7jv ztf6^%fg}k$rLIP8XLX^^B|@&TR22*(P?T#VjX~i=FRMz^N}E5h?}Uy#Y6Sb&N>%VW z^wR(KSc;Z{D9vo9^MUB{z1U_tclG;k*N;3M+#;^Nwdmj^2FzqpWqKn^Z~b)=P+)$4 zW%mAQPVb2P{?3k&f=Fk_(1ix4*XY$by*G$8mXyN_j2RhiA4^{Ctjoa>1zGf7Rr-NG z(OYfTNUF_ut$VuYp!(Mej6p(ag@ySG1oz#`5G}?J_!{Me%cMPTk?U zJaA#6^RhO7NZJU;A1O~9_lw{ouLniLi%$89C*f7o3GE z!}Xmbrh(p@PxRsNZl!S(LXXKh@kmjuYW#cov4#1_(VfQUK+n9L%mWa zX>(fTH5roD9;k1%t74*XTG}M#%ud+4DLs~uI{%!uwR(iPvnu# zYDv^ooOywd)mL+?t6e-D+_;$Hic)$nVhlrX4-pH7IEJ^xm;WiOsWa>e^%r4F$MZ~F zuj)fPX74Yq@@S>vimxJ`J;9e}Pv}?Q&^7&rEh2VH8()w_|L~m1zKuEjVbs@ao4#FD zN0v9g*IJu3w=!wDA=97T=(us(T~p8ot)K3!2_x!;b_V^@TgT*`4iQ zo_&eoQJv6sNB06?yjZNhMBmO6J6&hPx!>GW%e=D-JQ1pHD%WW+U-Br#J z(eQw}G}|v}i0S!;JoRIf*Zi>=5g#^ak5t(%Ny~FPMjc$9+a8RiH{xTn7(QcdaK%fR zneGCai;9r!h9spMi-r1?g*&-ZVHD>fuEG|{VQhHF&&l*tbEX$pugfX6wdYLpq+E_R zD!DC|gNt>HC^cLWXW~#R3wO}7Oj5^8oammT=fH7{oh2#V1B=l{&)=_XP1zD{oauS~ zN>Y_UjO9thy<=tej)coaUvj|I+9g`0w&7KYgI$ZJNZn{7@fvwL$!%b0v!UYp_P|LT zVM)qZ5iHhdQN5O=-C{w%qTEvLFvJ=^f7s@^=SpgJOMy*xy_d~ zrD)$NBjLyTPG06~WWwS2cdkBrI?o8-$tKIu!VqOY=ZGOl!%W5uX}tt*u)}gK?Y+j% zlrPJXhT0l+wsY}r1JNOS88b8EtC`T$(2FOWu@B$YL7snih|%LVXJKQ`Vx8xU4x_8^ zEE!Q0bUMX$E?Cu@q%ASe#~hD&H72ZAOs^Te=JvY3*WQ?wz5dwiv0e*${n+dI-eY=C z?|rCGWUTmaM@)GPrPcZ)Hp@x%rTpeO z!JY)eLKK&5dA47k(v(hhV4BX-`koAfDAhU|K!K8eWO?y?xhC2k-eQwA_AcUy73pRQ zEKD+@4z#;e9ww=ZGnjVrnANVt8!gizI)k zX1h_YiQpZt_gGrG|TZ&w7vkza-8p(63%IXxA&0>plT)mBx1m5(=2hLDvs3LTFU_(Ka z_()$6Dn5+YS|1ya2KGz0>$mpwT7vto|BK`=-*`B%!D#PWCN=FitL98CJ7vr9Jntu) zgnB*}A6Hv28@~+(Wrehr*0)r)>A0<0{>~;zTcwS4wv7jEJWP6Z<5#xzhsEdDw%L_C z&f2`X9p`P^4N~U|_3bxEJ1*Kv(`))QY&s!c2VebPVruk-e)cgXM@nL~l4~6Q2%O!R zxFYsaKkqFo>Jw9CHg?-!k`gyv>K996%Ck|tlfT^0J0MYE$HZy^ND?2Hf*-BoLj;&A z0uR%>cI)Z8#g@ogiM|*oT_JO@z&R7+1E+JuZ;+%}a=b=n<1XESl8Vmt^lhys$!q3A z^gBFvNyZiB@j8NuH=rV-no4#J?#NTGi)Bk?{3fkL2@uOGu%0EdES1FSIj1beuiy(8 z*2;_7O5!UbTA8?^wI6kNzZG?_w3i%665*3pua zSix1&?_&NyI2UxOpTpqU<|m%vY9IkbIgk_hMoQ#(?$ePJ^qlQocSJ}D2gDQ=_RpE> z$rKxA@zcPI^6_sjX1J$WC)3^izZo* zY~rM35amc9m5*MH04YHdFbjjCXfw#tZqdor&Z_KNQX$7qQ;4~5^5=RwsUWD-9h0S6Fqab2Mxj~8$0mVnXw=Qr_tH;0)pnj%Ey2Ml- z5&I;iL)TVPt^AzO6z@(VFN!phb3`tr6H}+Fy_%Vs=i(;IdJTM-B;^95iB~w3awu>c zg5h=b)5J5=#)xh39D&3Q6*E@mm^#yzJkZfEanqH4OqECxX>Px@GqKYHiJfvau{oq- zm88_Y`Bvsl)o~hcKTnqG?d{p?_jaF}WA#iF*WwMG#@9p<7t;D#%8Cq5JKvU&^tt4! zx^QDZDNzx9L3@jXJqjWJ8@zAC)V++QS!x zFEQ{m6_|FYs;G+dlxXIU)k;b>L*07Ml}0yjR%|}yS`_@AaOLQ~!*hJJ&w(Tn$Wbf*|o5NWi5tFW?fY^~%u*Lgb8 zc*&0t@2Y$e1t!;{z6jSGKaFl*6Af=w$rUHPI+Wa~EzUMMcd1%yosCgSy~=Zg4>A=`dq09);^jx*TtQLfN zo|Z{WQKb(j!zEOw)8z8T#4=H0damb=mZ>yz{GMLi6o2grjm>IHEeI|Ao(vFZG>Ilc zaJ-1uw(M<_#qJ#4+mlj`83SUQ=0&tXI02)eew0Z#t%0HO~X=vmt((Olt>!NpId zUoPzvOF5$d$|R{scqPhq5GlH?@Fa6TMoXRSP22*m_=xnY=N9HLQ%JlhvhdN%W_A5n^i4yJSNCVIb|OX&M6xhcm;5* zfks|u(@G4kZ8}2O`aoFCZ^M3YEiB_`JT}Df>e(_fzU*uz=1v!tL)qPdqqmzx6S6?w za3aglLsCvCo*7QxEei(HbjqiL5mnID>7zmE^mVtJoxTC0(=o&mx|K$yS9WGcYm};4 zc{AtCo!!@X_3%orxio`ewZI5jC}Rms)-lmmRw}%*c(YJ;HgGXa1rlR@Cf+-W`$dkJ z?)jsh{5*jBA4oQFPnBG&?!Z)~I-yF*jo_Q-Hi87Q%rxbYyUEIFQCIvss2n_p-1rB*v?uH_4&by2z3%x>{p1UO_Q@e>(EQ~7O z6r0KSP5m>cd5SL1s#L>M#lAh*SJA(zafIuPZoP7=uEXunD#tkfNJ%UyhBq}dGBie| zRoCRcSF0RXmdH$Ww7SRj&r}xb-44Bbkz83V_s^s;p(ORsw6xeGltr@pUfDfc?_MIi z7wRkBvHdgMbM@}Ia%JFhGEAiGRDMvBpESs?jx|XObfOzOE;f@{I|_j*+ryN)WaEMu zWv-lh#Bs?pUzFa(yg~BxW>}AhG)if5Rhg2E^1^D^-xanESKa+v6ou;TfhV-C!>vfn}q4kynj;aOBY6$aNyzpLG} zK)1srrS8iQU1(qzugOzHH`a59s#JQziSazY*Er4US#f1l`79pP{c3zlX0TkNCaU!) zdjoye9A($2gR@#M6xWwZ#nDG>|CCzK7S|3vu$)r%6eX|dLI%d^#RDa};7ZrjZuXFm zrBbcur)GCIe?V0GYJomDr;nOnB%(>Y8tHuFQJi?lwk^&pyUB6d z38}gI!b^ePDIu0Nu9rGvXxBB|tO-QYp=%hbaTZdB=of^v(@5c0Oo#?G9b}?0qV$f}wu7hxksQ#ci(L=FULD z&Eim=vFfjO3?BaaLD+Gf*sdT%2q2L^O%4A4+R(l{`3el{^%~GU+7U zIl`TknCTujBGV^k1%Kw0MxKs;Cw;}9qC;zyr0tT;Mn(%x%oTmHSuk8+jIMlVxeC zT)n!%U7M%dMe`Lwx2YCjQ3{7Uf9kWLohh;!SgYU;s^~bW1)pV>Z+N z6@Dmj7kA>sJ4 zya5cp$qY8JvdyIvMdKy#7DV@)Xs{Sh1~=vMkHIn~7ZMoqZT{Zd<@&p$sic&yv&~pK zj+T#T_FR3jMAgYrc71>KD5Yr(D-u8}R&V+Kdf8oQ8Zgc`iH1sRwNnZVb%__B)UCYq zT2+TlDoam7#(e0Bg2c`xNz&edsH`8)p={|jg zm^kBp@!%x!x-<|KQTWTBscQ0KtK&h}Vg@hbTw|rh7BRATuO!}a-PJltD}FqnI>gxH znU*}~V!gB|tay?>@FJ|i&tPOVuSKQmN%W}2NN&|6z3N&VO7SmR1u6qep6^BZv+0Mt z>PbAPzdkurfsAbIqVYaNB!Yvy_YsFhLpU*QMzc~)lO=hQ*>RgV__d`JWs=D~$?P5J z9idE;b%u1MX~^iD;L4n;e76zG{!`%kI`q!)(ovqvYW+?-|5d&ZGKl(M6hoBfp+X~x8UV+Eo!_E>SK&3QS2Mn5kD`Z_P$Y4l&7$E?-M2@Y*> zsOzN9wNG?1otn>e5}SDyx=%{?_7Q=^SEo08L;IvbQn}@TQt=iOo^`G-)2rp;K;B)R zF<>Hz;_fac8#1Nes8k0l^UetXdMZ@7~Uq>_wB^!u)w^ zbJ8J%0V|m)NapgzVO1G=wK{|B$VFrpX9P3p^T)&_0mIVU$pnFywFLO}yIPT)uh0z= zP2>=Hn=c1LP93KCxH6m#{rxl8W z(=rSdm**7kp@R=wmP^$*A~;~7CD-$m`qB`asb{Wv>HXTder6d@X;mFVS+Z6nz)2 z^scR%;QW_w1JPhj;BJW_i_V!bIl(P7n6GWj8OsETs{`nP-4lX=a;Gz&Cot|o5mVdX zyRdnI<~2I!*Ggd@vwOHTCDcO&rq~i@o6uV!jF>JKh-bE*DkD%K1*(jNN3RZC&Cw@( zk#JB9uy@|(>z!(IYn4>)Fm*nNG#f;Y2s8k zA=NQ}k#3vTZdRGxwmdHlax%N$Gcvfz-tZbDb%EGyV%S9lUvwY4ir}A}7t!;HDlKm5zoj@%#4N}X(Bq#k$j>FUv$}3URmmluT)@3~YWz6#+30B%nJpac6 zw^{Tg)X-eo)`7~^K+;^Vr%kNhcruF_QH#@5gEHH!PBJey25U)OgI?ntcQVV&2n`=$ z^d2q*(*DIZQHkpseh_c=8cs_M-%9MUnz#3Sa3R4e@zl~gw9FO|_5bbEz4l=JAJ}y- zwQFm=yYqbOPi9>|<#RNje|1V{;FJT!es+hq#QTJ(hk3PHFJ?|jCVMv~as`G8uGY`5 zAEq1$9K_L&_)xgTh?`b+bLO=w{8O1bH8e#rZZ$Bu=VLUU1K~M7yC?q<7{2cH!^VbK!wU!gMt)zA|v394ueg z;FY{f8_r0IL1&W}_2Jn3giloyCdqDt*D7-Vt`?ERx`vqyD~mdWf|#{`?cfN3ow!}R z{hefP*dYCHF&XfG$7FJ6OcvbVaM|yj8^{*pydzY@;;zA5Cvqw2rC)9=mAnzxl8@9& zxe`o09(`IfooQF)6$Jy)yn3nMi3(e!o33FU!Gf)p;3VBZCB@u9@hpxJHPt#Tr9*Du zVezE;Q>%lOR&Q~0#WY1i9QScf^VRtQtn9r1!Gh2xr^>Y0&4Cts`k{t*#VwoP4(9Iv)!RQ1r1fyG@|?SZXIyuPOc99G z(p5Y!+F1!5F9sWQ4L7QRUQ)0EPqtef45*s5OXQ`hx`f{$@@Q{mB=43?ezU&RzdplZ zs+Mobq@5S#8kfY%(53#>84kHxPGTjsuf2f}183kH#NW*X>$8 zKbxPYGG0UrLL6a{_+^a7p=T3qp=*_2pk~wuCWGC~QT{E;YE7EbTl_>N(0mEB3rQGO zlo`@VR+(fCHk=k64%Uyq-6%$@?h9_qoi2VN#Etr9r0BLbzqit%^3$Wh*VbC*7qzxl zQFUlv%j&Fj*IbL47(^^IDXpD5w$^f>3%{tirw4xwMWyEp9PYW+1Gmk+T9WIP-m0EL zCD05E^u3t@JE!xfDm)LN!SB2~5}7{OQWujjBz`;2d)xUa^svTx z>+oxB45ckN!sgH6=UAkPIq<8F%jr2~N7MOn>DR8^*5D6wc*`R#;eDxph)woRW=Siu zNZ>cHX)I|RN#eIUi^2lG){z(~An(wkV@$kHFc?iL;||HmQzu_hV_}a%Kevn>?v>T{@q?@`DXOUVZ)+h)3?QBx>5u>Y>Zk>Otfsez(uVaCKw4 zBZ8~T6&v2+J*C{RKCokOKC-)jVN0`UlH95CP|j&rZSBRz<+dwnW{18?AI3YYE6eq^ zmCrt@Du)sdENyqvyG&@x4KyTXi^DP6S7nb3G*G!T@2!FN1AgzQmH&KF4b1X+L+qT; zq*PhT3kKwhg}}~n*LJqDv%Ql2bQK9zVwO^HVs&R5GkA$)vf$j|zNNt*L3B=^4$ry% z&_~P=?Syr;v-dZA?B^|wN~c34;DR2(j-OGKiIbZ0=yqfV64t|zaqe_pHjCb2($0;$&uju_RcWV2|!bpk;&o{KJl*?*!8DEwulGl?FE`G!AF2W6|!V!>)7hq%WHBv zx#FdL@CljjV^-BKo~_swszF?FY+^FCF)bHMjFYZI@zW00fODTKu z<&<3uwZr04zRNeJ9A3y=>$sFk`?m>9|M*2@$;&pALr?u-{_UeGS_M3R#kq26QcXWm z_nXS1#LtGjQSLc@cUO0Y-hI1x14$>8H^!YUxL_2wnO+_r#k;zx;vaXgnL8KrX1)AY zq;z#gf7i|j!K@tHbxNxg?VhZ>STR`_{nb={!s^a#6oWEKQG3>=rYxn3c~cwOvXtnS zEPf4tAZO~!AJLcH)Y!S@B3qh&wdHJ9=TYyzU3qcp?K}kTT%VeBF-uKqX7as%s+B25 zBH?3i%TcVh9NpfiBW~tKXSbKlJQb&M?$sIRGi(sRdevfjy<|_8yd5AwP{<=F*cuYz#Z+$+Hm&jii={! znJnd-UF}+hiGLNFPG?acB-onSgYm#k=dv=hUE|L23f1tkNm@qJtT{b!!sb+4ljG&N zbG`_+y?ITs;onnh+cq6xcyg4O)GMYMUu@4xO*$eieq_TD>9&Nb9XY%esb02wvb5g4 ztYWhGJ=7dVB_Ea^jw5Ar9+m>B>Hh2KJKW1o-eGAe>>o&QCHh}eH|(3bE&Sy;?&Z{+ z&QN#X?p`+acK-Q^rM8y!O!vH~WkTK&Y0+Aa^927qpldgCdE1#|%&-^lmH2lWc-=ng z;O;qXOjQ#|GY@P2U;AnP$NjD)0u@Cd5mMzNJaATiaB!z`(!cymFCpc#Sc)*D!1-BuS@kWj?50^U~*nj z{++3)g5M1DFpmqbK5-irF#6!rD%sIQF?UkQ$< z)54{sI({7SmEd?G>T6ZRm(lTNL@7qc$~Af^cICG>QGdYn3mRQOOmBM)h^bU?EB-)g z88Zwhi0H!HMFs9~&*aeoL>JtFcObEwOMsPHHEUST}uHv~b^F4R~?UnDk#KWfEg ztYRve>S{G_V$Y52`D^xkvt%H`SFVY}HKJD;2g94_EOu9AU8?#TP(DavuY6atJF2Q3 z#_I4KFoU}e+KY%wx;6*0ZbSVv2OKkAvn%1RsZn3~QC~Cx!YOG2guiG4guiG4guiG4 zXkUB+XkUB+XkUB+guiG4XkUB+guiG4s9*X7&`28FL5n7l=g~zK;~c#h((Izpjmkh+ z8pU$JEh4eiT(?GG*Ey+`Hs8@j<$qBitw|yx11ZuVC}Z(S=X^LVP@U2pEw#Bjt?@NS z-?>IO^DCen-j-UdNbiwa@1a`n;o4U7C$*1Zv_7p(!1G|Oi0A%V8rOZbg|Fd+^7@eG zWmLd%84!6uB!G~g2`v5*^@3pyBxQ>4pQro|b~`aX${5)7tjZG%28P=(LPPFBNO;X8 z9N3mP2M6;?8|0GkklP{492cK`6K>B2Te4)g2s4XjO|=J?9)qY0=!yD%U(7Ivmux+B zbkT*2!KEz8VKxE_EKkM!!akh)0XEFsgAC=s2HiU^_n?Y^xb59;+gYX&08<%QGeKg)y-hxq(*!;-*$T0u=2Qkd)G5*R>v5l@(8@5F>yU= zo~G|Z%3^e7w)omftPdycEUTlXwp6(R_NT$$4K3*mEjh&l>AXUa+YYNGr?hMhYPMpl z!@Ra{HWp~{{a62NPw;FGA=T<=cJ;}phFW}O{WIRAWz0gx`Ta7oQ0NnfGdcywx8fX! zavktBt@R4sywmD9JWmf`fE}szX&;F-BF%J&ifLImus>_HZ3=;A!$J0jmJV_fn~L?M zTJ#Dv+Gur5b4SE7h_XP7?`5Rv1JPoh%~6$XbxiM@PYt#BzSTeD5G|u%b&S2gPlb*u z7HaWj_0M<&r!e~Ks6wNff7&l23$^(EfmD5(x}IlrB1LxJ3VEQ#w<(+rAVtbUVX&*S ziv@z8+c#xftdwoQh`-%8<)^Vyeu|Vg^-Z}URy#L9ekUO+r3piNDmp;5GR}ZK`%IC1t&ejhh=i2&dL@I!gq(!xi-&HfRrP4p6x`LkQpK%;zR3x}C z(~26xi&9rlzq0gIW$j!%J$sd8JWY_M_`g~CwlE?A3K?xA8Hgl%zU zKO7S%GA#3}2m#IlhUD&`o79P9oby=5zK`?qf3msB`0?aCqk-FJ`Sjx%N-Ydd;?@r1 zCoubB>x5aFZAN9%AVJvbnG6wo_k1H1=wQ(1<0(s`BjqJ0D82;oCR|;mr%phrG*}%< zhrKQHSSDh4UAPR7z|wz z`!Toe^N(+_9Rui2d^|%ZSrDlOf%*79W$p<;dnbpd8+U*2hx6pj51}~pTQj5PxHA)0 zd(Eq{Lxq-w@)A~afB2)$9O(dPc zcFb+(ZJDwJ*14EHn=TIEPcX(lh_lcb-wXpcH`{tJ#zq4hW4^VzT2_OK)P!lUGh1E(=*q8xK$N`Note1$w+V7)@@h}wYPB25tG$V(K@nj%A3GaN0Id;R zx6}S!rOXhzu11*SeZf&^a9leYc#$#@#_-V-Y!X6L_-in*55YtV*YY)AJ9=w9L|!1P zS!SGd7cl6zg^5E^AX_HvE}mU42y2R+Nsj9cjz3UVo0*EiZD83t!q9)RuF%kGu3ooY z*kiuub;};JeXYsr*lkpHz?T4PuCxwUO17H6ra-NbM75CpdLdLa%D1l_7)IzJIKys` z`31PK+)39JabZxt#Sg-s4Rm_Cl+>7Xay0{MIXW{MO)1B;Y%993cXvosDNQ$=WK1u$kcg0MhtoVXH_~y{%?JZh_&! z9;Z<`3->FCb&hu?Dyb6~;;(q%f~D1b*Xy`+ox6U$*_q~O5}Z$KHy|YJg0E#{BG3&X z&`oeoa6af5YH$`hGnJ=UDUjxB9uFcNroLn3sA9)%gR&7Go^gYsTtzGwjV;}z`Dj;Q zw5^W6Mhy%vo!z;diF~f|4wk_S1ZE2Lxqn4h!yPsvnH=2{MAa`J3cXodkTs}z>fLMghG396Q5lvSuDB1Q)i$!&*9bB_{F+s3K)C=N0?ScQ6nKWQ_=Kq&9c5?q@N27=Aq@RQ0503CJt1zrWKZYB#Ra7*i8JMUeZYnh7fONVwfs#BR zf-b&h4S~9pz>c;eJBS20p@KLG&hpc#SQ!pKkZ3P94V4fMbr>^G3Q{lzO>WtB)I@Ef zzo18>fB*_;;sv0M${@H623Y{Fz&VgoEr^&NX65_vgQVoZIglIBk@v7Nv_`09;7mhs zF|3Ev-C219IkfExC2(jNKmLyL6Sz*s{)atou;T@NYRLtU)LDF~U-}0|%s08xupt@2&?A$DROzY91To$=bfA{F4g0(NsjQ1-&BI|O&wfH+H) z8{vG4CMyw_oYt5donyF3c^7CaT8ceF?AR$dt!&E&@)EJ-JHK^Bg#pRb3v(@rS&}j{ z72eV>*P^IGZuC4=6f!?mwADn@ex7mwzN674sbFVqd|5^xAb|2IhGNz#6?`8HKhx^4 zh`7)I&!^tTD+)YH`>|muCV_3yQo+l>R6y>19uVEg0Ui?^I`I8JRcC-QY5IC>EZ_56 ze3b!<@8m_t2vju`o3D{!0K2V9UC6A|!GwIG>$Hj#6x%5{yJm<#iQ?3cs=%c3uByP) zW&W3zY`!=XS;)Hzi5}1reG+2B(`r6iM|uxw=7-*C_C{y|b;W_hv{uq}&6&<6;rzvuOxM@@LSOc~(tPhFN$(_#d!!OIy; z<)l(MNop{aMMY3^TFqb7)eG8}#g`cL9f1yCC+$k`yb^91p*R)B+-`)4t$KUq9w{`iT-;$1)lzlqLf5s~V6lZKSLoAFoT)<||)$kogD^@L?1Tk{=c*+No#V0(G4t!3IizP2GQumS+|VvdMd9 z6br5-$6QhQW5&;5K*FdtFl*VL_srUW)k?Z-!D3+E8^D_r*_FqiWbs`Sk_uMV39drk zJkJ+(Kq{e4H+4l_-QuG-l6j7iYyp759YEv#10;YJjwsYkqw3bIvM&K$07^OqlW>^L zo56JtvTKNQ5WiK?zOJn!r<4E&4n{#+#CT6|Ofl%6100(KXM*;b+ugc+TV1Nq zy1cG#k^y5b1+A`AG}RFXn9_3%+d0rFXahvHu@VN1Fkr*=Fp`W-Y$LAcJk$u8{d~ z9kcN%c5D@PyuD`o%c3y7yaW8domtrNUN=EaknhTXLq6fbe?&;fuOI3u@tquB`At-@*el ze)n1(Z?93*;jgg;vBA(nqBUVTTt{1v|VyodBMfCH>$Tb4S#!{hUU?Ho+07rQW`hp-R`=j>A9P0GCS%(N=Seq z4E86U|4HC~1_;VS@TAE}XWrN9Kx(P`;3H%%a%IA}>Uk7EyOmZ5ND+uDagDI}=EjKQ zlgXph<=c88`*~N$u}+^YI##OFby#JdyIw~>>DmbfZ$xViLabF`@f{2j!e$VF5a#4| z6BhTYUJZqU4BL>H_eI#IHy^7L>W|ft4r$pr_A=uxp=|WBK{G}OWjD^41DjqmAf%G+ zzj4MrkV~hze$|ZofRgyLq=LhBhRR_;^Y3R^H5!dh%b)2jF1W{fWi#6 zIzAAU=7F@q5DpWk{LTRH^##Z3h`==`#4dz{r{ASb5)xw#qv>+qO=1ZDwd)QS9x7%) zB4)M|+V~(#6~A7r-GMauo?j65u17u&AEJOuOk_*R#6_Or`3w=&wk0%!Q2fZYOcKRB zU#)0@h&$V8E2KzFkI|MAwX~Fex z(KLMHZ`%ZxM8#<0mKHK}<}CxF(v1EbCn-KI8icg|k?j3h3%#c!v@Fq|j6cK2`s46t zQYIemi4T2*KT|<(iGiiJnkRvzMf~wqYW@b1Dgc+V|6?oU+f49 z%0(u=0DF~_4fzp2Xr34*8;XRv!UMu0;Riw)sZpco8*}!lKj5kD$(1Kizv(NTm<B5P?kZH?iTb zjSrLFTFtildH}MT#_++L`EFrpHSer7LbuI(u-1FBPWfWMo+L{6K8`E4L#iS$8z7&g z(ivszDHynvcHD$jktY?LtP{#^h^&R^d0^R7EhF+!i<4Hs4`{OUB0H8C!pWUU+ERBW z>u*E#w_*C*)%shS{uc8hMoaQfsMp9A*}tH#X++2REPCayAYt%Hhq;Qooojf^>#*`^ zB2jhd@`v?;8>ZknibL~AowpN*$*DRfL8NUSe*=}wvFLS0-3jYE>bmzgKX)@|fLZ1w z!QqGU;&d1LMgi-=`u>u6kDR~;}`rC3>1NOKhiJeBQxAAu>_~+6dqWNcS4>C#L(&OgWrn-9TaMNA>7 zHO5G+4E{@~^x>|d-jVumL7ct8c^bld#v$TgOrM#ty{lW52_ zrris;Xe$oD^=5XWoQbzO{up(lV0U9%Dc_`=L(st&F@uc}!i1(YWy z1X$@z;b5|X9o@Ux(QP890-LfKAA#gGhsDfHG$sA&4$HkDn(P=0b-{5?v(gA=F)9U5 zgZA7F1P*qDutp)|JqS4aTPIN^}5+;)~gB1CtOMq z9Io3Oe;1q&I47Whj%(4ENZ4jl`$Bmc1n1GjGP!J9d^rqkU^BqBUa|8DhhM+ab9kbZ z7h&=|U2ajKQ2@w*V*P3`otA%Ba#p8-Soms3Ol; z1F1J6fdL7Q3p{~AOTc)5NM$4>;n$O3Zkdvj>SdFf)Yv!aUkGQFCc%7+RFKcAeTm2z zsvs=l-WL2g*YaO8mbtLYg~RJ8ybh$7G2z*heQK*5cSJ@;-f=5)q97RD#tm9!*jO7fIsPtvxe zcJ|htl%C8;HSkq{;{GG6&&0vBnBWNDis~d3`(PHvK?|D4f_A7uSxDvhxxm7HMPZzS zJDPKFuWou}RPI4+h3?FK2DzpAl~KS>yp0BWmH?h48=Z_aY_r7W4?!eNtp{ZT73ZlS z)*Kac5Q!tF$`8nyk`p`==VRIea;7?GMtlu&JQop}+YQNG91@uj-#sdVzX_kNtQ`=B z$82~RC@PzFOTWhuTbqT?xl(M~{&{?Q-9_&YVR%Xzk!9j*iemzGzPUO16_g^NgI@3}pXNsb39q3T$Th^6rs+$>=R`#L*R1gG|$Xmd(IMYp&Ua!2(*DX zvx=3Ckfeb;N2~dHa6l>0u80Y=^#iL0a*a<_lwS!M3~9=E5s$ypqlF&-GU2g|9u9g8 z!UID@&}BIO-%zxXj-l_SI!>|8>I7|8-v;PNhmSGlpJs~l{L=CmB5%9?O505QwRyx} zQyY(w&>OEeTfa;DbGSAD4BA5+KW|B>_NzUrffYO?Mr<8cxtYQx-xVTJ?@8|Nu}ob5uf#$;f1Xi1NSik%~!0OH=_etAlf z=ec;2zOtb4BK(@NzO}Bn2{bFp5pH7`(3cq-l2H1(Q2fWCa*1ywd5E{{GIu_@%V{t6H5Yff)vAXEcJM+KNML2nCA>m<~hEW~U zyUoA{+kWRTu_16%mW5%@xAl|_4J{#=;{Xxe2_mwIAd=|k@Wmd%iRrX`cZiqTpO1p# z3`~AAI~=>{aJ-e~4Yn*`@^QfAYXyc?H4KsRHkTNhe=Nu!!qE1|xk&kQvDGY?LPV#v zjPd_K%6qE>)+V8{R%XF^xro(?Gn_Qokl^uf+GC?ZibR76uP>$=4~+ItlJYjOfLkeG z=V<>({K>s!tH+OInDlM2k5Iy-&t?uDGIPkhA&=t6>Af=t_d6Xy*t^~U9E*;`wS&=Z zO%PBM`<%zbKJR2FmesL#K>r&e%_R$)OAli%y`|3;3QvJB;qUbjpmd4gtvbJh(^eHw zU?`myh&J4XHY7Xm#E2w1Go0V?tX$KaL8sz$b{tM%u|>`S$o5@5ZbqLiH0D67cwL4a zeEOAZa4uj<1nG!Er4}HUQ0?lKE|@XgS^VPm(s1xXA>JZ(3^ar+E7x2><5y-}uJKQ^ z*spDToVM0swG_9D^Jrhe)g3Z!7Aw~b0Mb+qcHS8zjS3!wmgaP-j zRAl>kTAx)wdmg8SNCmf})z+rXqhQyM-4iPz!`r->-4ja$x+jho5G!ZCRnkA2lf#Eb zVw=%Skgv>gUXR#x2j&2jam&)27AI^8^oZI~4Hv@@Fw;Xrn;Tf|jz&-hu@!Cp{{cpsm_ZG;nR!U+BBc*5y!xz-U+ zLhp_M?TT;E*zk=xVd))gSMC^r@F&5D#h+^uQH=jayuFGY9e;k$0*ElRF;x3avad0s+sXGY~6&hn06d95sO7RxJAjiblX^MSFfUOEuStFYGQ;f(Y$ z4mM599Dkie7!o6;GWlW%0g#9>)NQ3(VJ$&E4a{wq5rW31@>4L1!jRNG&C~f_4v+y$ zOmXBHJk{&w6g#PtS3&R=+>p>h8Z&IRNzUn^yy|t3g@6_X?a~2o$v6q1U({gajlgc~ zp@qazBiWxh_2K2K;qYG#$ql_^J3(b;5LaHROvB8?)8GQ}16vhsT+j23YbzFf3hQMq z%mDk~Oj(9MWt%U_b~4F!3ihun(~M=nQPV`o6I^2?$$}Ah8v-RCxpl1@LV(^QB%F`%jk7?D`5|}1wZvh~mH#BSP*uq=)KzAg z0n1dW{&X}H8#c7~d$?+Tj|d7%4;_feA5qu|ruk2`jFBpR`~!6jW&X!t696?re;OxA z87u?zn6&C&5m5cA{?)IFsD4eK>Q_cr@4t^mN+`RN$(|Imh7#XkfqTV|DJ7;x!BuQv z;7XLG%wj2-{Kqe@g&{Ndil^0tgLy)Z*^49$L(_c-6DH&51~2f(gFAkYF8K80kIXPY z`C(x<$2$~`W?pmcT0Ns*Xqe3<#WN%bR7eWr`A^oOR5XOQz2xgFgk<~F$PaAHf z)zSWc*(RsnrsB)B>Gc0)n?8-#;1sh>d^@5sp;7vtPWjeG32RX0v{49+Qm+nY3ZYRl zBx-5;jnV?W_GttWsX&1J=xl}p=4S@QimRI9M~4wX!Nd_kiYmVh+fYRbY1hd8U^|YT z=lQXd;TjEPFcqV~L2s3J!Bga}xYKdPS_^5JK;(8N>@lXf_Gx_5<{{XIVS806!WuvyvI*sb2S^OEr^d(KmuKzPjC0>VHS*ScJ)`cD5?c5$j(K~bW0>J0>7l7hf@LGa zmuagbf%bd_Xfwo2W!^mm+=(kQ5ySduu(I>qGH&WP`v3Q_^dIMnbD482DJ9n4(Df(aWesx{-2e@ zvG}%qs$S+w?4{sed;$Tn>&@?EZ~-v{>_k9eWWYuQl;{DtB?=}_ImG4uqfX4MtV=gn z)m68IM6d!?D}-DvJ-7R%%8f87^d#87U0&EIUYlPmrGeS#FJL8obRyeNuYL$IIT!sU_(kVHlms&Uuc;a7v=W5K*ZJcQY-)_oEV!`7vnV5)VFumjHu0 zQ7I4weK=OQyAWlB27_16#KyB3b91Z=GSL|sH1cJ?aaI!TL$S*z1> zfD9TGzYaz_On(n6)g&UDxVU{c2_R&>0d?K=EIFb`X#mSkUr_v zN~BW{*h|AQbEII6ZJlJ!X~}Cy2eEUw^emT`j%VU6I9hcnS}?CF_go1#(g`ltC*T+C zDORc`6N8a#hA*nIonI5TAD&wl7Mh zqUtQlPe3?iwUA)D5~lxa^MQ5uYU(cM{;B)ZwM^((UTT)($Mle!E_kXVgAi~W$yvQH zk3vdj0cR2nvh-@?J5niNlr->)#r+s(@^ljq%nG`{4qz>LkYtwQ#i9h9+FC)SMpAGF zu_Pj=)Bp!C(gRd6>%;>C_} z24*?!3eHFuy|<4HxQX+fGaG!upy2uS_}Y1jCo{J$)F zO{(k?Tn-R^>H+Krdf5O?&2yT|N^mtwb;2tuEM@o3(HZ>TY~{9^9cJKwU?gJs!?I8Rb&PV| zOW_&Q3EPL=M8}IKI^I40Z%4sEF3QeMDjHjM14iOI2{92p*zt&jTIgX&-onEUZFFH= z6DGSUAi|6aT_!41wLX(g#c-c>(;$)C*%W}-EStpHY!l<8Ah|@_#P}*^>HBPAY}Zl` z9VaZQF=H>0HX*|lvZ$Sk5m(O>&TynIVR2XF$!JlVeREW+Wm_tvPs#Q)?5u-P*UdO! zBerP76SpI>Q;%W>g*&Acp!X^=N1txVwu~fOCY*l3ne9Sw?Nqr{lSVAnkJ&U5h>GkP z36xtP;({YnDAUT%~ znDDK-Ut}0Vh$QNOL4@U=Le`0IH^D|nrP%STZjGuE-X}7dSIdzHj@PUhN^0orTJg|F z;n1vzP}YCk^%$(KL95w@Y3oX|ole4$W&Xo!NoEQE?|BVqM4JjP<|`M{&UV~x-Xsb= zS!M$J4NHB!z^LYKSie6cU6@{x(K&pdm z>cRfN)Qz0|oM}?R*LC9JyU1Sv=b2>s$Af2*;zU8cr5c*-&vc_0OlHhhtD{J#W3gRD z>W<=;Tmc3m6}WJ}7$g<^7ydvx794E=+X?k_gqLxP$5@-)xbaiM^E}~cp3u(@3nsP& zb{n&Mq-rYQcCUj8E*Qvs4=I}JMxwY})K&wy1@ek{&_wN7Y3s@Mz!)18cgcP--9T=E z;oIygIAqAouk5W9-Icw$AvKu+jvF#48U|btB)4VPtS}naz*jf?IH+6d(t^#!3H&jLypTrgr9T+I z332$djQxQH{4**)@AAo}B3T4)Pi>(}rc@6Ewq$8uS%+)D>}@P0IIVMDQY z#d7C8UBonTu%xG3m_{!4qc}scavo-zuq{AzT@9BCUPBR}n&XdvtCXtfONFV%j_7_7 z`u)NNlw}>t6n6NH>+(%d?*=A&jol3P&&bhibhpor^QV&y`zb@is59>WFl@bKH&g=GE<0zjwGp0N_mq_21xN6nFTo` zn{TaVWYQcZFt>3sj2H#w*__?Mj$o;Ud>XJjNl-iRc$G{VS8xsm(T6rg?ecj&V3-Mk zgn{bI)*i4ixqSv&5n-+ou3YGDAUjQ1v!caq6F(d50} zZbg*`G3Z;mR5((E09t8W^BnU#dmXcqQZG^O&V<+uz>0rm5H^olc)3*UVJ4|V@ zlXmw_+P!0@7(40NzDdujdsOL;w@Xyh-_ODHcbME4HXTSRbKI;q6RUR))hsbte18Z* zoHR!>d56`fSrr?jzbylO5fhH6lG==OOiuw(C=Gk-aa<_Oj@wgUo`W=7KVhH6DIge; z%J_Ti^IIt(^HA*D?DNqSVCF>p{7?4z!xU#4Q;b?epJjm>mQA|J()mM7Q-Y(lcJV z*-JONGMxk#apfm(BP0tE4mnIA%;YdE@;_Q>X?hfwYanCTc#&}XkAVLNwlcG4aTCD# zEOh=zTcdD3qsK`t6XrP!b%7m3IVx}%LPw67LnD-N1EJt>E|0ol9$Rk>FEuh}L;`AD zp9E|JcES--C+I1vMG)vrL@bUwh%K|#D&(|LBB$kkRGveX^IVYNyrO)mlf z+|)8T(KPb~Tc=ZiX*MctOgvXp)j!ZA%sIF#6`uVVzZ-c;jNovKoz4aN+Fam#%F(8Skxd1MP^X=?Q7YaGU??qy83j~$(x4eZi`fSCE*4A27D!bjlC{taWIhZ|K6`PSNbOiB)C{f) ze5YKjYB^ffvY)4cO`REIgtGgWCC|tb%9hNy1`;s-`7^GA;LVI_LfKgV9Zrzv0uf6h z!GFIKV;>z<=)Asf&;;i#kwO09H7#(@_>#R*Y>{E;GBOS;lohY=cx#*N^~F)t1#RV!l^zE2soC*r3QQ~ED~WyGl>#C~Dp&9@JG`{5 zqFYpp|9{BebH{=EB5TJEriYlw^&q+Du+XQ zg`z#aT4q&DG}kq-mzP$*a8Yb2MqNlEu@VHQ4bqmi@ZMCb?%2K6mA#XP;HG55A5Tv$ z97xr=?T6jABd~>hI7XSvQ6}UT+djTI9@Zj{qXhd-Vn+YZ+)8H1s8+YZB) z5s2>Ry-)g8~(1}3xgin~LEP7O*()cM5Yk}kDXFH4A1I|x)KdOabnWwY1`7w}A z)}F&R3+`gUC-vYi1b0gXr&;hRJ@_<&&&qR;!A^7T!KSkY=7Ga)KLHEWNwyQXdTjx3 z*k8#9oD4(5GY68X&N<*`YBwAHgqJFPk*kayPovrKhDJma?AeRb~Up2EE{n@-0koAmL(%M+DUo47y`DWtN7PCFI+VE)_d|zzqZf z&ru7Z{1e0ZfgxbyLern*O}A_FG*&~$XbrWXp`Sw`hZ@R8>kBIgZy zg2XU%bPy+nTMpcbgXrmh2Slj=(Jt6}{W=ge1auI=t7{-Uo(BvJO!EH%n8s1N{zt&{ z`FXwdGA*@#dnTm;OiIt!gXt&XioziJweY_-lg!kn{}B-F>d`@@&FKiFv;S@owaAv8 zLo>8&5jf{%veCqw6PfMo6)kBRh(VOC?Gap;)a$T)KKLziE_mPlU_V?s z>TK*N_reqIxu0WY->2k2Ul>$2t%Lv8T7Rq?jrFJpCyqA|@Y>w3;!cF+ifa)~M_h|= zJ~06x5oebB70X)p^5nJt+Z-oSaM!|FKavV@gxIwV{iiQJ=&_Cy;EQXfX>De@&Ma*t zKEv=0+G0QI)~4y1e;a}JkhjRw+m~m`ChsTQrZXrq)xnxf*O%amA}kV-R`0@gIqxUy zq)w8cG1@&9>qMv$P7oQz3qE~yE|8N5obnO!BV|_oNU2T`$&hH-Oy@05WASCO-$b;i zIhRSnKmrXzhB`APaVW!d#X{8_KNXx)U?k-RSUd*Y>GnPex1Wl2Q}F!Bx}$j7>L&@8 z9uLR!iH_8P$|EUc0-ZeS*e;9AGvnB-G!?BUmrZ02+xdWgsR$DRvh}dB`rCEd8#jut zTfv7(5WzV~y9+x^v2P&{2+r%Avq6^940&cdXM?_=e~!iHQT;P~FC0khg>jHU2VH&m z3~fdIlaOQU2HjMeIH#U%IDumM_QEjQYIXcQMXLlE;Z#7qLs}il z7VVvtsD1FJgj~}@u4(^XTM`VsEm6fuw$r$!^hm9Q8eA^Mfb|1D%gKr#eBdf-HhsFLYX~ z*I~}78ruXdb}_gE_g?J z&8o6<^*WLP9;PRhG7{2pFA0UDOG74?K=$+KR{7&BJU79{9M;oQ03X zVYcK@-gLlY8n8;nyB#QOgXm=fr+9_(px%;KfH)FmQuMe05#Mk-w)f`Pd#(Z*M(zqH zja7_RMXX}TDUoRJO}7Qtl5OpQ<#Agr0%SNY{BxPO^`9ZK;w;f5k-0Bj=Co~n)p_?VuIM#dZhA1ODKU$D1fvDg7+k?#Dwef0XNk@yVq5ONHQ zTLeu08o}4}r&nL-5 zpH{4^OVs3A=_dt%sa*xrXY`T70BGviPakg$-~fD=K87XokGJXLE;Z(t^f7M`k9mzg z-cdh(1~xN?;`4%ZGL4U~(f=&o0rRn}AqiT${omz@js9;%q`ily9j&HS8|}}-#2BEw zmq3-8{bTW!sDBN|SCamfjIU(v3l@j=HQ;a>e-ZwE_R`zni?q8QH}GG#;s566HvK!l z0mlBRCmZ?iQ6vBT!pML7jQsaw3nzqcJ7wm$j*kL1LT$o4+sZ9Kr_&;fl{%V z`!f*wAPZ%C2@mB>d6PF|9bBWHkE$EUHSabKrguQlgZKfw9l=Mg?KC6*^-8;f>bdoz zpf+t6Jht^3rGV4*IJ7BQ@6SrNI$b6L0i}^{ePXeQ6K*B2h<4Auh66`)Ao++u089In zhp;y!XHt>DCl;Hs<%lv zLrf0rQ?u1EE={|K@@oUAB6Kl=cZN{jad@fu0$v_8BUWYikkba$IS;t*gz^*3xcp`p z#29;o#S`dj*>&t|z|xU5PzRsXkdVeXu#jhi7>>h~rhLKuU=svXL({4>ABInK4v%VK zSlobL^sSB=eOerw0(Hr5oNK#kXCc-QDN6$ZZl+B*p<;}xP$2xC%fs>B9KL$M$kGMVy<;@9+5bzrEKtGy}N5en2@bzAe90Ol;a7e2*ZWqtp?BL2AEfA5bZ&! zrB|KIF}o55H*ELy#=OgGAbXpEY{$8nAnV_Hb!LSlMm9z2?!YU@*Ms@a(;A3V!ErSo zt__8N>}n!_*5(GeC`~R+m95)qb4pXMDoO+KgajmuGUd_?8Sy!#8CMl$a@q<+6L70_ z+q*!s1OrladiptW7sS(06psjF_uKo&a1ydaGw znZZBv@HyG?NE+ixLbe61o4Ra#$BTdQr%|~47knVRdKZHK$U>Hm z&p%LcD>R}^)twFle84swIEIbACBL=Ogyf%!rzx4CbbR%)@eV_IT=fs}M;SbD8+^8; zY_sH_bA9A5$Uj$Ms@}u1pF5-#P!U~#v~0Xk5m#N*H~)vqrzyS3o;7O>@O0=jX{QZ4 zV^z1ODrtsTzWgZi%za%nuUP}i1PH;Ncp{Wi3FD{)GSR9MaG2>{=G6`!Un~cKVIHgv zRYIWTliJ6aPh&VVhFfFJr*W&ftrlDIPVb3Y@8`ANW3>?`JefsLX62I|1Z3({B@fXi z&=oncA3dK7PAM+jE{o@Vu%Y+VdiU14Ge4|lv~fPa`GuUB7bOQn7T>35Tg`XEQeb$x zL$xDbSwHakM4}3)+XXW&N_z&|Ehqe`85NM|Be02wlbmyT|j^xD`9BU2poV#gQ3OH}o7CzA&V1c zrqj>Q{*Fu|v=K=0Yd=mSG1t2wXl!m>ezFmrCeKo-t}j%oKS_+k-r)XoEo9b3w!VP$ ztt%+uxfUY}sfh@I!55@?Q4e9HBTdqKKQ|NwHzY6x<;p(S!c(u(Q=e-|5Xv5cVPEy_-L)bSM=|sYEuwh;(>xzGG}}lQBQwxQ z;>UqT*;*DmnzZC7dP%J4UY5HT(TlZcRJKY8m*3k+1@tz;+I-&zjJkXSwCGDTfJet@ zKpE?u7OmCJ5K=R9$^#t)CJGc}!Yf--gd8iZ+btwfHG>&_fs7E@&s%%0GGH(V8a3U9 zn3@0uzlN!=3ScjVl|zA};;gO;otyX}&RebHek)>kR#5D@wy1ald~YN42Uy?u68jAB>aUsO;Lfkx5JpaoHl)hK&AzC(}TvKVrx=n6a88as=2=QHQD4iXVr| zil~fw%JM`5IIwMCe#gni+?}9F;Qd#;9F zZ~k?|;v`3Ex<&!IRIk}&Aw7o51jS(4W+}BdWe7Q~Agq9Mld}hZmHXq!@NYu+<}MY? zX`>^!M&x59c2tQlRt2qC=D!(x*t<9qUuD`UutHbxEPMM62A)upR`aK|kTC{2BI3Ch zND1Z|p4H~=+SEn~riPFJYY*wlBU8zJtjSRl`vwdpBf7RQOpNiBnAa1j;BnUQ8g$_o?5zrKWS{L> zt7AiYgkbFV|Bcpc`Ub6OW^SO4(4kxKE7boZsbB^EIHiJT@aNHgqxOT}pmuUX#g#t_ zftrFY<9J?x9C)h6#OJPN-hxaT2O#;#;(8yX-d2{3=gcxQ zp0ix{amRC)978Bw7h{B(3t)wSK_$4zhTjcFHgaJMl{JA?l)sn?zir6?Jc-#_OZKex z8aS|G2_Hw+(x<>Hbx?&GUI(Lu_)%=P`C126bO4cQ(?TeU;v51aR}(h~%L4E#yz*o` zjK&m%z2il@zTyf=K-BicE!g5-Zr{?nykraT=RMP_gJVaze68kLZM4!dw~W}*Y95NH zR&y4%VYGOF;Mrd5-B!yHIS{imw~(LIDH;0Sk-5dYy;innZjpbTesJGhHh~eO(SwB6+U!J2(@vY47%Xw=WVM+6%XrGw2}s4e%{b6 zt^|4ZG^B^;+u76PZ%;uX^6V+{x2K_8Pv#c)>}l@2%q<~HRwHk&oz1@O3ma&&%yf!i zG;!DPj*V1^GM7>=7V zq!Kpfk%plyFm)QJ?|0si8}cvNy|4#liJJE}3tI~zdnvzru9GWK)EqGGC*m*;09y~! z)zT84Ym?jld#Q@5Lm{DZc{Qvuh_K>fUM6-t6k@GC3+Z+kRI!~!YhS#%Z)<-NtF;+K zV7_!~w-#vK`kI8fe^t95GaYL(+F2d~U7WRA#MgXHcpW!gYom7rP-h%*t>zJpXYPvp;tHs-+vm+?1X2Z1U& z9J@Rnwa|8rOx>!de(~lQsilJ9Xc2kBQH$rQ50S;{ZkyD!R29@bFOeh6%ZCm(?8dm# zYi=LGRRX0Qhv(6)=zE5m+Y>emzg&(;`Jth^j>pTl4~Idtw$>HR^Re|*7zNi8@z!**RG8K^hNb21%sr?&I#khhxy8G) zw$<#zIJTNku;=IOd5k@evgc6t%*2yn+17X!&xVUspt9lfgyV8?Oqx+DSOp@>)lG$D zbXv~q!u=O?vZYaUGDt3;X*JKrsiOE2z|{L75lp>pwcg=d{DVVz!?(a<6_go_vUNC) zjVTDmyu-orxy84$;gM}mX41g;t{=v=~#o= zN!Nitz*P)e98erd)yVr$63Pgh7yEg{dwqt+lOVPU2!Jnw5m8ge)H)!9`D2lAYm?Qn zF*=>{V9Lays*q-6vgSU?cE(QjzMhP6LLz0QV3i@V<+)IoAVoj9$Ljb<&*hoso-p0b zj~y)BwUJHutDXvW77N|54puQpnht$`97#~-n1z7yuW;dx%5+N4PVrmV zU8l&8LIQHx6p#lyt&WR&Ch*B1g%#Nf%U}(zPYHYMG zXl_6`1xLS{20IBhMfHObYG<&Ugoz`md2p9aLm42EN{t1!#}*QR8Q3GSlss@Oqj+9Opmn5)`e|io7>*)UU(K3Gh)L%zu>X9XW;4T zIz8H-mtXK*7Is58>{`#FwmJE&bMGOOc3{hen?=2?;>v*hup#1Od}3T$C7@vQOdPk4hU_nwlM2Y6-90C3=y-0hV{wr(p^!!cgkHR>!n4f(fX&Dtc6T+1`T}qSds`K@@RByz*~ojK zt<}5$+bWQGs~wnW>xw&z1%r}k+GeqZkWxZyp_KVRn;-=X%l}$Ek&5UzYhdsm#Y=QT zVl>D6SX(jf#L7$Y7h!kNtS0=(zy|>b>1&Y3bnDHB1aaQoZCc0J#sDeAJt}jQj5>qJ zW)$T2^O5YC@pAi0^PO$ka=g4B>d2BkAjE|R?(!u=Y7+D}JH#eTki59NZSkj8$1n6s zpo2&Xxca{L8$Bj^%jg(wa4+eCu|R@D?m<@NB>51p5@yX(Y40 z`{Pd{h+Vwm{VdmQR>zKTC3_+U8m`*I5nvfYum(LMz@gBbcqb(2)plYiY@OhBbv!4m zv~|e~PiNN*A(E8*esxEcu+=2UyGV%Q{iF{nCX%4U)+|CMWf-Oq_e(7a^EBc5ED*?x z#a+6jg#Y@lOO3?yG`R{0d}K*`vS=PpU1|ceV=-6s^2f2`vnKOc9W@F9pI>p?;qQ|L zht?G!+6&VV>55}ppS)|vNEmBcHhjhqp==(sP(iSNa>gJSdh@$xj1bBm_dhk`E_kx% z`l&fHvW2o-|ARB`fprRh3DDBwd;Rwm$*uY3MQw{`-|L@=OUn!y>)(Hij1}*{Q7%~2 zcCUXtN%Jgfd*)iZ@}p$7DljO>(dAFYP6K;214^|BkXY%Eef|QZNXHJ>Hf~1gcrpf? z|IhlMv7HNB^rhJRj6W{#hluIONX|F{$}Li0;IaY5+CC2x5HQ?Z@SnJfL&x*aJ?i%l z@eND)ZrtagWTD-MIUP|dcnPsC(kan)QmezSw~bD=(9$$)7uqDUIy(ErW`>q#gkw)f z#mYtFBc>|rDLcm1mi-KM&qT+QwYsH(G$20MSi1)+Stf>6&@L%vYG2_Zq`b8C2DP03 zhjKC)Mg%yfDzm`)13uD`49QlI?aICn`0G_b!aKS&NPg7+R8x*|KB}x^xsmk{@h$_P;axgS9y8>vnC4eA5%z1`|}1^=F^4aO7rrgK_7%{m;Q zw73xl$3_|JVR*!u7KR1kh=9dadV2{LDE_!sAUJ5?s%2_28C*%GM!-oStcsA)=`?)r$U8wFBs-W0@?zsCe?)T3f zH}pscg>!p^sjG zHV@A?znr-&wHzFlRhiEuw9d{F$RQXk+lH2$lINb37y9JPz4JUD&SR>?KwHTkhn%^3 z4NlAwtH-=r&P-T+uJTK07(>rk#&dR-hP90#b84_GKqIi0iB?q&7KA>4v?WAFT@IcT zNwhyUJkxnp40s;BBs~9yyPjTLG(30nC|+D_crv)9sc=hdHIbkKodZ_}xxujjXMzQ5 z!?FqGkmfoiJOg(hCqv~Um&I3C`h=<_ndI;T1I0g|iN~6t>U0Z(Fz)Ty&@N}b(H@5H zX-Kt%C*|pR7M~v^4D>ljXh?cJKxJ&&=y)K!#&%Cb`)^Ik%ydB*vvVMM7~I$%at&(QIWT7rzRYj53sUBWcGyGM48OE* z!Th=#7_3y#)^2d!=h@T_>k*%}yNdG7pR~JXdJeYdn>V++rsShNt`Q;Nz?A1M627>z zIGi1KZl4%(BN0cFJ#V#p?QIC9a&h_eod|-Z)DHF@DsZC$?cT4t-o&XUeWBTf?Pu8V{OvO1gS;z50kB%+oj_>(3)4@ zyx$KR_hzytkN0^R^5T7uJZ}O#$&$H&;L_M`@W-p5g6pq~;T}>) z1OVvQ-yA^4E?x#e?_DGSfgXkA=c6okf?gdsG( zBsPRdnzs}KGiI59y`Pz*Q(=~~V(k4mEh1+Y{H6AW0i;cpX>6)oeaWdpE7|v#-oBuq zU~RIz1FL>*?M9*h41u5l6Ko*utL;Aph7XmkxTV=l=)5SN&|K-O1b?RbBDKQyw*GF? zFpknYL+U-FjgtJF>pgn|J=@T( z_RBxOV0{BU+dw`0@%eAovm@s()3aUYFWa*>@4sBnN;Q@lnXcis0oUMw3O4T+n~Vd$ zYAzDpYZ*drK-RqIRZI*5|x-4?b*3EP`-*wc8EgN4G=u6$bAs72(+f!}Z zr@Q@&1Dt4*?J6XW&s)}7|z%CY$TU9Yr4VcLSuC1!TnaK(*WC4S! zDq!9EyHxG16yPdtH5mkmiVi)C?n>oZLfIYiY%A+UygWP0U1S6YCFBC`e-q%zh5{}g zks*Zy%qg9r$P@*ds=E^s{HChM63#JdFgp8r5OAOHR2%2h$z%=oL68{ERm^`!sAx4i zF>XyywdDh@&s-y0oo#Zd5yHO-@`oO0o7VxNnX}D|S4yz>Z?e_V7FucyEj5L1QJyt1 z@)(7+78!*KxKJqnRiw0waW(8-(il}QGoPJ^wk(4YthzB-LW&@im3j6-C&p>el}w5? zdK(=#5VJ1JfoUuzOqx1GG@pP{dXQy-CPDu^Oe}~rxF9uOHjEd|{K+t-ort2b*{A|s zB-OPz6DF7;zqQ1o2C57qG&2VxUEU9&8ulSd{Hiark)ky$37fk`fXX)cV4<@XHWal{{A*CwP}W#{EB}er#8-cs{BUYc z+f^UBEx0gRZAhuAZR?4@6Hc5dKb#@9r6VzJlGa(p&6i?Kl*K~RK;QDStiz?)?=~4b zUu;{sb4TX-8+X1#Ds`%aHw=OWEIuFPf`0?4vF#V7g7*RSDIl$6Tu!>11fc241O6VD z!&BLOs?;}Be!O#E56G6euQz`pZc6T)^@6YS0weU!tj5kNJV!RV@fVskCmIb>CK!T{ zPD&dFfeVk)E?Zt}Px|25tJVAZx#My`-gWM{*h&|5eno$GRaEG^o;u{JkIMB0%k@Q{ zT#=#g+Dqp{@dqg8swNM{UbfI&ApBqanPs(fUZ{w#-j!8)! zJ2gBMqJ|rUh$hux`8YnSgRdolTy(Z`jTolc-iqkV^7ke83F_|U@(Khi4RQ0TfHi2d)n9%#iPtX(DRzsK;>&27%tycuT2yhDU28&JLSd!D0F=g2ZJLpM5DuUx&Tn8bDtRm zD3=m>id>(W=XlT4Uhh5B4nZRS7}8#nc3k)j7Ws&m6nEh>-As0V-kHzJMTlwHs)K@| z{Le_G%9j}oXMV+OOW-KvimTo;pMfKqHP`X4&ou5U6+codlm3#q+3~QzY6=&ezrz@NFf(_u`;sDud0Q*R~&11zj_okM5YWyq@=3dD^4KQ=j{Y2 z^as*Tw}m_xKl5Jr%ySI$G12&UHI_GC?S6}V2&m1)fvxe0 zK#@(=fy1A6e7Z;wHhDw+BvcHoF+5Ltqpm&EilXpjzM$$85knWOeYFfVh>pe`j8bU`34+OzHVE<{$o2_H#k3!8J6FeDIJ5 zmAucZld{@2ieDVd^!@Zv`1og!emn{SJ>vc^(-&u2(PygY%X`aHnK)Qgo@ak+)!H9Q z)%{C6-zU|#j`(`jNqI+n0e`A@_OomB5k&nfVyf7AZ>?R#3NB1MP&Jzu%hZc)(4T&) zK9O-XjJey3mgc=x)qyBjinE`ZgeS!X3NL;TS>e-_9BCnXk40N}E+yv+tVYDTh09a@ zhMtEn!6pGf?LEgfw#oB@#~^Z(Gd@3dzC`ZSvHJDjnYc0Ivty9EnR>Qq5;^Zp5Y0`V z*qbkx2nio}uE><9;nEQhIG8V2z);+r)BNc%JQ}4xiwrC0C>fukF{lRy4{DOToNa$Q z#;VELb{v^mO*ns0Q}V@XYCL|dmsMAo)A%>_ab?a%vFBLkhUDPOIorCa*4&9>RsYyO zRy|tk)>?`*MPxXMA0@UrtF28BbefzNo%hC~l;3YVX<|NPJ~ie!zC4Co(U0IvhHoPX zW}ADku)@us9m7(^?WUsErpAPPv%DzssWb6_XGY=&p145Ox#0D3e;usUgYhsSQ0%9Ut9d>TEIAjPEIr(hz<#uQ;SQ?|a+%MM2?&c42uDE?aX1hQ z0&!P`Y30)Z;%UOJ=|W}}lzB%3HRw>mzMQm;pbSX*uLEY#f2V+jc0DS{uHnPorgmTz zcsh%K-l>AVFADTWRnSjkeZuj6AQtE?LZD`(XD4!@%WE$IIM0CbJB2f*=hrk720Z&Q zT&VL+#H$IfG<#TI`mFo|P`{KxT^t!3>b+-48i*_z7lZr$vy!t92uOu`<#;Rt1A2;H zs+7#}NU#nl6pz{v(ARKU4vQ)&p9OS`4jN49;O_ zlJ-S+ge?Sg#H@BCuz6So4lP~{VikyHt6q{&@F95h8b}y{WgisND@l5UuwE>R=P%Dx zLB503Vk1<|@j$FURuNKaU~Ojc6{gF6{g%xKb72?MIP26h&HVHhOQD@3u>4w6e`xM0HM0uIc6K$d@Jt*U5+Q3_YfkXahfeQu>}96kYwDC= zZdn68W*5@;mqayr!CptQ zf34ih(orkQ0Onr}ZGs5a(L!iH$E=a_tGF;k#%k~zKqS5AB?G#9D__x5nmMW>qiY<-23?=CTOR+^}q_f0+$3qh(f*4E)ai zZsP&Ntp>$hXa3Ce&!!KIKaWc=2!>(d3d7}w48tTtvVqZ$(0K)S17tJZlL)OsivZd3 z$8cT6t`FARCP7Pt$p(ujWv!kh7p7+wq|2R&N2(ES6pRgwc3=#P2wVLiSSWI7;s^9) zK*ZaSk$o93(z7VY?Z3=!&jJ}UBEP0S;V_4b(BX=T4r6J^NlaYT`_PK8cv4B5k>&Z7ng=1+aFVGu_DA%w>NIXy-k2g?M2~dKhI0a?_;6qv%@!S#;k5F0|(g6;h zA}CA}nC{FwRBe;1DaIEd=Boy62~Z7ssREp=&anD|7GPFw@l3#X-t$l3tee8)Qut8} zjeQF9PaXOvcnGW>V&fg+pMJ|fd4H&Zyn4nS%-@8(>OoJkuZqC7LCtbYp`@6rPXwp! z!PG}*_`aH9&Pqu!t~~*F*aUk_WPzPM+fd0(YMxPWrI3geGb|R00GJ9p4Q}*KaQoUY zo3H%)`b6$#bk6Fu$pwy{pJMvR>!@LM%D945o*4X5bXxFx(Qk&;Y2ykU z!IfGXdt1ui=B!ScT#%~fxFR|Yf*;lj&!M)G=zdGbIrRmj%$BY3Lrs~*)`?_Z?X#)FA!E~N|(Sz9G=f|c;cQ@1t5U}RBiM~IV?scj(X+L zh)Se+(O;wIWmMv*SG_Ggea>p@tuLct{4I;KrMZB9W85u>98O1j=Q~hR88OvmgcP(uKuLX zIaDhY=2eHQU(=Bs6j4}w($ru2mQ4cZw9J8rbZYi)vlKK*XHzg^Yq&4kLv{$p9?(=> z-3^z(W~~snop7`pc0mDH?R`(C5yHtQ4SL4crz2y=7#YuzW3t^wJ>xAik@1Vu=hyfy zWrW*i)os2z{W4^HgEEqut#R!*)`Mid2ipy!y7UXGV85VOP&y42$W%ek|D;bF#_OM6 zr@H?|??jwl>B>2>L$NWk)kHEdoFz(*Som8{%w9gUVI_D^PB7Orwg}yQ%hnSg_R2vzx5_mZg@~=smXew!hlaldehn zGHH>0wS9-}cXs~su)QQ{ebU|}5;4+o;)1KCf=+`_UqI%VDT3DsFI5HeK!g;`ld9$k zHHkQp63G}3dJcM~1Q(>_#b%_+ck%Teh08xkK2tCcsswiT$*CxO7w%WhDC{1lw-xG} zmL+{U5_7dIbLlN>RF?V~NOWjf8tBb3DvR|}B%bb58%n3QzpHO6lgpBKC3osSo01t$ zxs0Ett5fBIlou^bA(3|PYKL5qroR(u(KcjZLZ=b-Fw~@c3|gk?9DWb*sRM1(52BAL z5cg+6T+K6V87mS9G_95nSn{!P!kW zh+=(hi#qC=dI}X zJ`ZPY5Sgj~3XyUx0AvGz`XD8&24y*-0f_o9fW)pCArR3RQTsp^ECUI;1f;>N60$A4 z7?A85kmB|LL=zc^?4-9#Ad1@q0GZ_K6R-gs6F6bAL^_VM!c;*JG&uV>bXcfF1i*rZ zHI{_D-%x!#7D5##F9xFHSx$uB8WThnectC)&O|-;utP`DAaMwlfm4pFBEaWf*6Nfg z1@O1W45S%?%vzl`r2x8BoU#aqtF9+7j6ican@AF zzT&l9L{F$CA}qwpI~bK#J05w2DrXH8qd}A8v%a8Gp(dMjr9t>)sY!5uIh~R~%}mmB zRV7hDkV1SA*rerT$c?)0(Iu#@KLi9I-*%OJ*L(!iG6_89*6OQ#1@n7W8)Hh|sFy4yl(Q?QWL!+i zbffzu;hd*p^2F9YXo#sjTd%!^P|=++CCxFl?~W}wM=xoehLY1`O2XC5f286%k&oz6 zL+Q1e4@P(CWyswh#Q6OMSApj&m@kMu_Zmu9={Xu^A;%%gaRCS|Fq9VQxu?!X?rj&z zjcC2MM{>_WZqG$>zlWPaJ@<#1$nCsH?&pNkd_DJFbCG+}g>wggQhJS^`NJ$^4xYT= zAcHHSGtWcj)|kvOGasDcK1$2#S20;)CPAvQ2{o`ikgBXgxz%4_BhW*>02Q>WaO4Tk zk3T;C#Q&OtvD9VaJrril|4PEgl6gbOL~y4|I-9#Yjp7}3iG z3z=Jjf`#;6P5b8VgZ_erFt&XWM|KQ%!at&-C7y}s_3pFSTHxn+G9(sz;3+I0CimWP z__{Ubt9FP_tSn~x+&hu6e7M%aZTu2n!NTATXcWBPbv&KByP)*TM<+OV0#o{8CBelm zgwiT?9PM688=f!=fHQ95%!!L8-a7Fv^=Hn+`_vyTy)5oGQ-D55XPA z52XB&?Lzexa@AbP|7@ZHKc0TKfn08}NPSNWdZfN$H2l93U?Us+AuF@?L00C@It6Y) z&2^_(sWY8pmaAmtu0gd1v3q+{_x4wryApXn^Mf}BX>)FyTUW&$jQ#+Bq$=hsw16J- zhv6gSQgTFge&uigf^JRX)w7({^UWS% zn83f>&%Yo{EPr3c-?2hiyfrday|$@qyNUd^bZuwL80wMR*Un^*Z9`%++R5+QWFlv9 zU2q16-*Aj!58TVmTcnVK(UcU&=p@3z*bx~f5{U3*bQDMULB!zloYwNmrT0T802^Z; zv{^-`0v?xrDEpNEtu$xvB{D9Y1$KT2JZO1({Y@vIiOYr#F)Q~tD@WXE*$EX?P48|3 zVFdF$9FX?F0~n^2Yg@WRXdCzlGHh;dqVN_lo^2b3)g=r-z2-TNcQHf&x+aDEtkT{`xiO`V z8PPF#hCYa%^NuwgVI4Lg9U<2Kpr?~-)P%KWMLedr_mTZ!eq7s0A6rPC4k5{wU46V}KX_?!bzlU#Z)R!@dKkVapENu~Gj*Eo8mJW$k5F1@cb zjq>yX*`YM@u-8xcE1@xcJ6#FrCUl&5B6X#{ z0NUwSK)woll~fR0pL0LB569D5c))8yUrJ|curHl#4_EAfP}1Lj9x1P&zB>W55K4Q2$tLD7_-; z!q+j*Ra&%LTRR+iq70X zscuO{B1t$$2^|0t&}xTH7-S0iIxYR4J@65ocm%XUDrgU6o?|e00tyB?aA)WZz#;GN zs6g=HF+ZcP8`l_whRPW9d7$H z-UPD+i0CHD*Wl*ZRu`W7M~$JZ^VbSYK6hMd#}z&$t|B_4!_^P?m-_%59^!N{z49hPh61h9ctx-+aGv97DsC zkR8#lH}cM3q}yIKC+<;bn9(_TZD26zl&`)d1kc{arz4Rgm;{W=$sI{u<3J!v)mEWu zycayMMc7e>OFIzrey2tGUvfvp^Z?c$nG_M7VyHy|ztJTW)8ORB3(CtdUVs-LsQpFf zQ`N)a)(6sPI5fdAPDbSloEq8#3o!w(6Xj+GzCzq3LaYpB5~dCEZ;RH^CsXkx60eY2 zh^h;+n{+{VTH1C5ius-wXd+4BqxOqoIE90UFP!F7++Qe8o$MEJZU{K(TCRiEWA+iK zdeXgM{rY*6pMit-F+R-4hZCFFNyw}asVcaYm;PjdS&{}@W!G98A*xsPlUC}NWXPGD9QUp(_iahTf37q zK4dbWRkdQ$w#)5w5r6^TkL!@zS2g4%(7iB%ppfy58T8D(*!dH@cf#5SYWL>f03Y)D z!l;k+ceIub0IzD7-1c$?6E<^QR1%jl zvzEqqZKO@*S!~4kUZE=`Wc_%0RcA;o;k@}zYm;w65rg| zm3YHBb&{ur;cXvjcoT4AB0~BPt_Ccu2P=s9L3F)16^Fbk{BBlY$VX`o9QIn;Ii3a^ zuL$yOI=+dy@;tt&=ctY{Wk>fWhBV{mO_uv$$@$C@X6%jA?q~c0_DAFV%diJIp^iv4 z9|GZmNxfU}IdXRXdLOR(diiwVtm#2u4Vr~SDW7HmDL?%Zm#OwZ zZLc;9-bMfT46swjFD~+3?_-ZHFn5GKE3B$fMMk=uvB(GO&9 z*pBiXzn-2holUD;#)MlhvtvNLMkaToL?8z0r zh4B)4VyVkt6)7v8@S75Gp zS~lR9bwdGeRxAVzry2iY{3-xHfd58BeDxNNegICr5W)}QA)2!DQs&YzL zysY9(2}=UkSVz^|!#eTR1;@?iJ5g=#W#eC$=zJrLPab5LJaYH~xf=>QaJeDzP-))oH8UKx9RUg%qBkxZ5Q=aDbPHuwZSRI31hcvGzR9R$a!K)BN$dBz^XQT%<`*hlCnGX?4Xd&kn`%&;{{rXq&OqA^qZ6$=n zQdKXYJCzFSYlKv)oaD9S)}-SIG*BeoJ-gA8si%!mo0MJ<%lomrw(sU0z0(_?cL*8Z zFfhyz!$FSD^Bkgb5#;^Uy!>yA*5HC|rhN3`6_<}Hhwf@*VA22&FeK5Q9!Cb83XJZTP zrb5$bBx<2iEtxS44_D)lD3LS087!qM9%8g~NtkTv;Evfd3;eK7Ko+f%+oE1d$7?rI z`VxUxz`g5Cgez!Iu!(tJ+YuUp%T(1m`1%{7CB^)q9Fm~abg49KuF0r>y|#@Q*mt^q z3UQRzUaH5OX2^qn>8d$PK=P)MxFhxYyYT|nU8ybp} z+QzQm+_LUvob=k>mUd&=dy?4p26rg03&a5@LsHK}@ZwFl*3{N= zG+XZ6*q#|)4>Z)q67{57A{(9^<_3^7S=XM|v#8mE)hxDaR090ksaK?o7_+M0HrX|9 z0gF$llwHrp4h2-)u}4Pj2mHYM0#OJ8uNE3q^-sOJ?j-?}4Q`Qp>SpkRE-FB%Q|hDv z3dlz4(lAQ>V;q|xPAV-O=oJ8)4$|7m!#NE9)wIi2PV%OK$|U7Y^6s5YH&s;i=$YaJ zngjVx$*@2Jg2>_5stO(Gu&2Pc4-@k~#76<)Cu{xd&*MtWW96uMOpcz%YcYwK%F$D{ z0ke4C)c%a-@uQ*h!9{-L>89nT>_H&uyqvo_*Ip;bfrVgP&N$+796{2YnL>*Ee&E%>b=1r&`;r zd{STsOL%@4T&9oSnXH!f4YjY3ItZJ=_xR@DwWep6nxYn8x! z7Ow$K@OLmobYkKlJi3bL3ADmR9K%N3B&=GAKJR3YE-) zAXX7sx0XQbin@i^i(k>Lf%Cf6Pu&XMtYDU@^sT;Vx>vjlY7X08 z0s^M&$Edh z3NC;lD^$|jPQ;rkhL~dPM0qM~4sCU3qonQ~wZe^ghpYe2gL798S09L$LL;6zVg8KQ zw`CuY*IXqpo6j{?5Y`iOwruYCGSmU3qJNYO_3pXgh|UwDMrVu>qB03ms;XH8iESAB zmW&B-Bp9k#I#iXAK1}I247ilouqI{PGH9HU7~HTXZQL@4jMp_xAi*`e6Zck4sxc=X zsX%h7yo`S-Oqo)gitC6`DSC&P5Eyl>LD*AL5ho?@=!(z^|5BJXrPx6g#ir;Lk$4!V zUoscTd*{PID9t-f@jBq%O!1~F-V}s!R*!Z_8g79x;DLj9AftT9KS?L+5w7U9xBN$R zI@UbIHM{nf-w!Ln#c6_PE}S&mNRXB!c;*MMT|5Q;iphs_YA{Q^@;1e#fm9p}PSM{p z*n6V(j*n2A9@MnZ_4WZvrWnoDqIJT6nK00?1XhQutN(_dJI|Tjk4%MrfK4C)8Ws@Q zRFWQ3;d}wY4+JAKB*^UY)VGTjX`FP;ywfPqb%_Rxqw zBE~erk0?Hh-u@FJgvE|JLeP{{V|=I#E@%pk*kw_KAcb*H(P#+9*hPJ3!t962M9}C+ zWi{6zvO86SbwvqSuR!DV&f$3vsWzasD=kYviN}E+C;QVvb5r}KmU+bXxkTVkX6t&!Z+_EBEV{;9`Tc;bW!)c!=?f?mI6V>$5gn zKv;-erF8-%^D3=%7`%!CnqI04SqAuxg1dg!SJXHzrp5=NYBY{nBhV1=BdGycW!MOP z#24FPzSyS3yX&Vyr8Z`CTK9PXE>q8MaO4bZ>e(u|Tc%w!Z)9Q4ym&rsVa}a#@qF6C zyfb6$d>_U|!4Dz3^qD927?Z2Rp6IgJ`ET0jkR6XZe1$e&v6U799W3%aOpTnG7)OQR zk%=;_oWmHf@wj_v-J}#wBA1 zx(j`zYN@n5X8BG$|0#>-Ki{DXesv20TL%+pIV@$DiJZ>DiJnz7CPie^${nt3p)nXz$Gq?tKt zGjph!IbYGt_?TwgQO#UnG<-`%gln3X0=uhWgrF9coyBVBmoP3ws^~*h_FgGuc{8_! zMP=vV+G9V&Mr9vBz;*mnqq6r>RQ6sTm3`pN>qPUFh{`_jCPih(YYtu)+HF^|sO+E$ zqv_%|F83E2fswu*U2MY|A{PqIeq3*A%So6HLb;akno>z25_lMeQcKjHi{P98r+_m& z<(mK}?Hd4R&1m3o(HN(ezvewA=#%LC&shwKA~yQAwr*2idwGich0BW@S{Ql9u5?j3 zB9gAPTfCQ&m4GL)xM8x$Zciz=M`1jBWZw}%3$)F790gI@@ZBP64m*crkMsdUU6Bs#4 zq!R9Pb+MXnS*j15!ZO^1YWMKV96pfztfD!tk;zWdH8QWopnh%PgG#^nDB+dOIg*Iz zcBUS>>txrU*n*6m`ae4lq1pd`9xlAv{x8nMoc})$-*6suGT;i847dUZ=WTPp;^0Jx z+9+J+z6vB+@CRu-B&n|V;Q2m zV=YO@!Yazh%Bi0YjQuOs)lJpgLq@s(KXsD6ko65t(kKeUoTO8&LMqAQ&LcCH>9A5U zI9;t)i_s_JH2q{e+|3TgsaY|IfSq}%`e~>hfpCa0_7RA1rT-nrS4{gJ7=qH_LMV?4r0A(3O5i%(dA3jxFO&^Cwy(CCJM3KQl@~kR4sQQvYn!u(2nPF z>NA~Zj$Q(#PnLm;vFEskCOd}#eM8MZvFlu+@;;7>NiiU6P1+PtrsOAR0Pbbf3I~L8 zR0vi30lh-Xpj9|9**S>JhMGxK;eb$?;%>=^S!aL^UedgTe=-f0C!X}%VWt@%0x{k1se&nDh$ zBjM$%CT7()B;~_WvueHgo?zgNq?Ogod+%! zSe_)FM}6f-g)_W1hkP&D*lXL65xTWg;H^ndFd@OJel*L6T&uL(4JKlYlg`rd;^U&^ z^;2U=rR%lhp8yl{MQ5?k`;vFTGP=y-yfQkOao(3j(X|ODr~F`Q#?0EEHf&%E$}A0cg}Zdk`t;bUZ0LwLI985&+g7*fhQFrTb= zw5g)y*EF(8hT|f>&YFa$WjHSKv1@&P*~~ARRjUXFJ?+Gf7Rh$Q77ZfVZZ492kEE+y zBpdtTtv44pcvEoiy)T8yTcbs?-BhUiYl&p3-y}~Z2P}SPKv=@}(HK|vCzXmo#=3C5!}}Rb^^iufRUnQgw!$KvO{~0$ zU4KlU>ApTznCZSgmgaX?#R}QnRk6Yz;o})oW=8*?yNHXz#4E~DYpi|7n2UhUk=mkV~jc3f;?FX3Dy)pn;18x0N;p>kt_IV`b1 zDMHP|#C+NN${&P7F8HC6tA{pXJC>l(VEsJji-yPE^d{uU6Ayh-W-U+3L9n4ipOnY3 zFP1@%+4oNHqs$Ex3Q;)M?|tWtGYy7olMg+3y8gk_wIeAWJBtK$3bmrX;2(nbN)Ou& zQVAq=B?B)SqT74nvHjjSG!!(ejU>Myg;UDnAOGvpjeos*@I`~#T&LQcq|nFq8#lIJ ztx%=qdz2L^KW^b+9aOQD4a(AXxU(Wv?=z>N7{)v%XpANHAz(o~Vb4i;(;q^dEmHS_ z^<>aeclO@}@AnWI0B*Sw2fb71GYf8a2$t65`JEzS3>a_j*}+QECz(D$?G{dJ;o7W| z_D{)3)?2|erY#-M3dOT98Yn1ttiV?Kd$6qT>~n(mKE0vz3pEs69@Rrwgvu@(B1%&@ zhOg61VpNwQb29ZLD;iMtv^K3s?N@ypF&x z=^TZDf$b)F1>E}%Hk4w-&;_7?F9ZvY9dQB?F~*KF#D<|lN<|9ro1TwghG^7Q9cD~( zj&>z>B6cOV1$HH@`mqv8G(q}+{DITkr?G4+8?*PmqA2~pKXW+iOEt^m zB_kU-QhS*Py%uXJi? zbf<=JLPr75+&rU8%Ae7N7|AO9Qq@kS7~P+4)u2O0&Xz#Yg7egWXduN0K}bSs7L!FPOv*XtBkUX2E&FZ6U;F(-=mc)!Mo zk!|c1GdOz0gW5ElIDf^QpcONnyz-1eowzU4SBHAM=Um2T$%9~{(X(`-bp&00B~Cc~ z8#aKkdp0n-X9MT=ta(}&kxZBj*0rA|qHFLO-P+K+QM@dWDKCRb#RPuLki@vgQnifk z#mnFlwKUVE%}A-irA5;sun#L0Lm*QlR4DQ)3u&&VVXprD3k-%46rij61@F_XsoODY z!t}AKWAwdayZ0k~(zI>v`x=u5Y%n%xzWLsH2;AhDlQ!kNNt?naZ4Vp)M^73$^NasV zpU2o*jQ)+30DiqawWY&CR4{l3l zw7M?A>be;YhE;<~9({X!7evL2$qPX|c_9#k@!5kxQ)@AKtKgj`y0RopY9@)LraQC| z6iV=5@066{vhJqEn^DKyG3x-?A0$a^A5~9rFV)3=WGTF@J`X zUr|byb7TtWL*|4fvQi?9E<;XNkQDmkzzLwY}mY>E(wY)Zumd*FF&A3Li; z1=4vd1s&8rb(q1IO9*g*kOCS-?yAkdG!PFvcrjZOzqA%@Ay=BfS1xUzv6J$Vt=>-$ zW%g_h1FLgUL*u0Z7PT8z^m^$-^O3`TX#ljyFF5XZWe+y?Y#lsQzaKjryL$TLf`IUx zn}n)Uyc+i=jLrS%HBn~!qmBpvld%c)w;TI%&tGR&HE`;p-D(GUB%gujsa1k zQuGQaT17dJA;7d}0#%X(8de*BaC~7fWsI5?C;S}%F1r&Ih#wn`6nGi(S)U8S*nrP< zLdBa$$7lrk?=i|HN4W+f91@cw1sgp40+E5U!7c8HP(z3;*GO{;cIzr546@WM{WrM4 zjos3RDJ9D}JO!m)A?D|M1cC5Ou9M@PcqOKlTx`QEw%Fjc)>WSr$dmG|a0(HST_^IK zBlz;6;I-trhLL^*inPaNS2vufp$q$1`XKtyg7o1m>@)|koeR?Zk9xjupt)Q-M-CtU zw9a3&B}l8xS*JX*)iWW2${%|Qa6KU{7QCNOc260mG=sX#`D3Tt0nuSn%&3CMau(ip zk)@A<>VWfe^=G*Tr@$_IZ_Ru!c^o%aX2M^%?CQ;O4Nt*c$le+UOHZi;UrgzIhVU zi)#&!ru4&9vM8JJw<}*U38%L|;Y92a^|qOsD7xeJRU&R^*8C}V(Z*xUrAW)YLa2U! z%Y8y%lUDmlO?}%=ND|1t z{MOCzbNn-*@n?nGHWt>mZR_5;?PvH4iBg}I0XoF_wS{mAwd)9ZDyhes3%Y8*T;z?D za-J-N!^dB57QFCd`7#U$rtf-P%TqhNwCu{-;X5nmO8HNs_@%Y&(}Nki+9TiZD@(2& zexwox)b!m{+umh8;xTV<+}23lhx4@h!bI`$Lh^ZoSFc&gs4r}pF6@}z3xVde_&dMz z-EY4QG8qRKNZV@5u0-L@Y@f|HL6>$K;h-EzBu@;hk`k!cOj(tCTf=+Au!! zEl=u(*QWo?@X?09;&0IKvG7;#$-7bEJH06U&M9BTu&;XPo{}waUV^<&UPiD8hkS4k zqjrqh?a?rvaE{>k3KwCY-UjJ35GS-x&kPF zkCbOaZIb@##UXh@VW`hU7v@bPL?#s_NRjP#Q`c76@zK`i#|nLpM+;T3(PWVDQ=Ksp zGiI*e|ISIN+a&dydBfh< zWxv{%A4?G|fLM>;IEIIfr3nq^AUh;f>ex`&yspswlZkHluuEvLk%U}zYP)NRfKAgh zQJB>?+=A!!%;t$eMH>p0oOOkx^5UjBdoSgF3;rdLQ+B)onua==c*u)S2M&@rxAum& z`AhcRH?wg;!4{BuuLKt}(TgPu{^t-X+AY-bXwd~JnER{(%c#^e%x+cz(M{2L5w^pg zRR9@HOsYdA3V_&HxS;43;XUd$Th`lh8?;QA(EAVq2?gZ+S?wl2oF>U_CiZ|GV1uV5 z+!i1R7KG$kxRv5U@<@Kl0aqg^Ku_Rm;Oc5B&5FLc8KV}pS*DSPJz`WmX+X`@<13Ts zu=jw!7^xnwhC{%TML;KTJkButi>Y3KN-4A*--nFW^{-zBtQc84QvS~gKjFLq<-shU z4FWk}G$MZZWrgJn+-2EvMrNUMbwjeTZwgpxu%7Y6dL{%pPe^gX$XXgFIF%@S3ry2F z);o+!3I`3FL|SfiifdE6K*98|*2?frLk|-MwC?o_p39*u=`~3&2hGlN&iR$gvx^ z{_3uT*45dKu55lJN*E4chbV${(>tIj!BzDI=F#7170|aF=AM~O%2DMY`cJPfNQf?n z+v7o2jv@h>qQ8K9p~@z(*guiVuxbVf zh>Ttvw+mgueuIM;Ee19wo5YU#r=jRi13?G4@|GH$YdFY2gQ}0Xkr?(Z1AZ9vLE{?d z<1(C*1HNS-J4a^0e<#keky&6$mjQW<%rfJ_Ob-@3h`9KI$#}_tsbrAc4Y{*@%Tj15 z7`#8OcaH4sGS|BX!|i*!jn?*h*Fd=4+KxpRy#^OK6>k!-t5P1H8DlK@C6sW?h@Tw^;M>4>xegi5X*#zGuo-&jsJyZ1%4i}&_*JznJz}L5>*6aZ0z33 zmOrq@0NYh4tP%yr#@ib4?HPRfg6%c!lM6D8|2eW}c0k>E7VJFi?k|L$0u=aUsP|#l zdlHaz5J`zct+NAX{J=fg}-|8KtSRMX538}kohjo zc3O4-v_V|ARdQ_D3hmV=12nN=-}JfxOSBI+%?a~v-4 zs0DznkkZQnDqfdDxXuIH(DZCTc5Da2B1I*YR^ds_TLV7F=0NZgG)Uf~C3GB;2BWh>V>i1XNV^&dTotz$YmEk-;ziK7g}9 ze471!7OU1TZfC!@1>U&UFE-*CGPwhCTbvEfl3L!l7UZFSy;XSQ+DzYi1Yd2lIqSaM zH{JUY*aaKVDsnJ?XOu?}kkx`e8eoCKCo5kGR~2T>&jRq<0eFHkCL4ebh(gH=ShVTzj*q;Rjhn4I7)E3p@_LMb4pF$wEsCG>qpUre{f5sDm!6nI5=G z)r;na`#?U!5u9@YOBxj$kvA9%V`DE%{F-W zqK3tnQDbJGgE#{pfY%DvZpFJF9ejF=K~Gdm$H5;InM6)#J0;@|-6jK--RYeATcY;y3q=-tka=YxBkHd!Ck%h980j`%3yE zrF$Xi%ak?D)^{FegW^b^j@f!;5(`p;z$5rTY~+hzBfT$Z+lS+7!tD|CVd3b*J0%u@ z#|$zGnQ6F$It`zFU`3R0o@)Sq&x8>g*aYl3CoJVZ4RrFLlz--!;4PB!pI>dQzFF-A zr1*%lC(VC;wXx~>)i}5yb9*xn{}$R)7cwsaMLfNzVfXl-0heKuQ5*#o>Gm8r=XNZN zmPPr+&CuG^4=iwkvBy=+bg;vS)=ut9(R)SgZu#mnj7sUIKu1)Bn&`et?@tt<{-NVZ zMaYbw)K_Vw&y}L*mVHqxU)|(#y3hCCBh#KZSSNv~j{h`sV*L~kiaU?D9H5uIlL||tzBp?)~;256En-*`@?@!G^ z5fW%;Z*eI^+r9ka7)&B~RC9woadvvsPC(m zGu%R7sQ~3ESA&Hq?ON*|?h}&hI`Gerf7N)Y`~X64>=`i7(HT)GBOTy6>K+l8Wi+(~ zT`JnI7a-2~I>rtThGQ2{(+)uLKN%!<1lUBRlDtBP`61|KGov83Y;3M#76ELyX~h;O zQ;&kY#=`atL;*K$PaH&hdlIxHgjF!@v8gaZtP$5>O)5xk=RjqmdxO4q7zhiE%Nb4v zi=GJ+=l!oPF_4%CXSyoC=`WT$Oo$;0m1W%Ot!gmGky(JHG#PKMhF8q=Ci1E*nTdr~ z&#jsJ?tzei^cGhPNNoljczNwr*VM#i<|bFnFJ-+#4zxz4vf}0U;3GCnTKM2W`wmce@T007DfL@P)?@0`1sRl$hxV-o`q3j|hK%S7k#RZm?z!JoJ|g zl+UEM{;DakZ7J!iNQ+)K9NZ-X7Z{uO1u{8gHiU|231L6Jfy^%!1&uFWp(bF4&Hs5@ z(Df@h<>ldJ&R$=E-HRTV2FQYfG^G5Y`yC9u4BFAPV_XnE#0|29)fsxb2 zO%HY=#l})_C5zzfb!|ee^p24CPR*57=DfD@Ini0-geBO8yeQGKOBh{Ex~I+kft@$W zXoDK|&i4Tz(XAQ8N4Ji1Jhrv<-GCoKuA~mJE*uJYPZMC^-u;;jguD`m%# zz|I8v=yM#xSBfx0)dVLr9SO8`S#^$`+CZ-wwy6`C#&~WVi-}GvHn~sl5row`_&8J` zxLz_V4Cx@WF<@PT5Gxcx(A0DYym}wrES!E1!pH=dGq^a0v5pz%zWF}R&p%4hum%du6@#zw=2(%RZXck2`q zQq}8W`UdMxdLd{~2aVe>DSzEbawh))ID@8pJ7q@+E_6uZkeB~pXZh8HLgZo_^jtjY z6#q!t)7m3=lVv3P3vG-K1n&pUtD#gXQ1&+IZ~la2*Ng!qeSneHp4P!Y@Sh+hz_q;h zJ7?hK&=W6Rc22Pm1kOMnMK58+z8A+`Sn%coL0@ktl{8#PfR%#WMN?Yj7r&5}LJA*@ zmuyD(4-AwVwCw1`h!KO7ln1JQ&htVpjO$ztpCAGQ3Xsl+Rs^F#-&i}kp$5MJPNTa0 z=qgnR!;5fhkN5pZTQSv3`2zv#+C=v!`ZV~(b+GNyrE3uWwDts3X+9EQv>4AuN1+|4 zt37HqV4Os!1(TkTqahclW+ysrNSduD(Iq!5d#p;%^lLPwyF8bTPHZb7rkIR~k4a7@ zS>EG9vIAEgY*{^^=Ta9!stZcL?$m2^)1~RxNcq#Rp?DdO>Um3z?gu+rU8>SF5*`?x zaDPk!5KD7wpd}R&3EU&Ocj=m!&{)EYdU4;hE6{vzCq(!NC()#42eqZ-?84M&F(*(J zOkOmx0%{}iwYD;Vqqz0~l>%U*2m3pH03=;@4zV*e`+&aKDM(zN9gF?aeImQg{o01%_N4!6=nimVFGiMB1-3MEFx*$_+skO#;Nz{LRMS@Mi=UX_StC zHpXmp>s86ov#drRV91BvsUkqaSRHO^2e_ZwR(=I4o5P@n$`!Fa06V+L8b1p|c)F8d zHT7%|n)ag9K%o4=>?6Pdba+o>hjtR3*4}t|Sh5*{2{+RDHT*!;aXxR>>-6==;(fIC zXf<*^3~;$x&%y?b{U`1X1Sj7P=xl?e)rhTsJ8ie~3cB=yoTQ4HR!E+*2QM&swk|!Z zXsl8V7W{G_7B`MWgeiH6wZr7b>>@tVT^VVkB24{Lmlci{EGSSl?~@gTUqlT`WCL*D z4lGRc_aaq}u?=YXaG=v-<-slK%(4eev{3nm0v4_i^K!7s6Wzbo`vdS?MXn0u{W!cU z^K$O*EYogT;Sqo@V7^H*<#@2wMu2*+Ub+~?k5JcG@#{wAR}p}?JK(kEIa&hHvJyK2 zRAw3pckuU*bQKKq#prgLfP;}4t26~yL3X)KqjXsJ@9)GN(lNaQF(pCiqLf7=K_@$@j#}@>UW?WGlJKylsZxov>vc+!PSC^l)}lW58b}Y#Jh^%T%?^xXi?5M$f5Cc%xCg0sKL;pQux1&()Sb;B_rvZFJ)5U0FfF zM~N&cAvXtf8}4mn{5olfvaL(4Nq$=proE|9DdZhqtazZP487IQ2xCCjLKkFU$3GO@ z^Yw;$-V(k>S26U!d3{ue7mcI)5vT!}nYFJXWff7wg#0$WQ4*8a)tI3Wndp8fCYA3M zzN!akv&^T>LizPwgk(a?|4Q1|96W=u;9qIC?L-OqCQYIY<8f#@`3>J<#q*w$2G{6XG z0CeuCDmI4Jpp^eQx@PLxg!+kdBMZ)OL_KM3zI*01=cy;zNV03ETb`8Qcq~QmQ&4#s z!5=7+Ac}*gs#Mi(4;(v97?MH`rk!FN22bDV^#d`}Am7*`~f$n}renPmidAQ{!VMk6cH00`E>y=+?3s?~Q@XHWx zTI=%9gr29kcp_c_=`*2c#USu7z4kk>S21-r94C#$iK;ZN z88@zZn+;xvlpp^YLdds%dkRMWB7Tj`5Q0}r`MH}79y{eRM)K??j)Ud-l@Ls7eVpz! z+3TCeyqsep&s5HN!1=MN^al*^&(x?7Uo|SpxOrI07j70jEBzw=2u&TiaW?F1$cMww zU;GbTD1WizP;bi&X!CY9?#$gOv_O}~zCZV!?w_`MEISNGx~!c+8x&EIcBE_Y(9BNc z1)#R5%K-W@+@PEk(t%>z0ye7MX_=)YLvn3$itK1-7;nT-Hl8Gg!$MgiaE|maB0H6g zK&;Od+Xu%xhp;%xCRS2hj&abJ$UedqxCt9W-TmP~gH$pkY#wg>W3J5%&%eF6aNdF6 ziNcPXdmCRy?}4+55J2HhT#gOE1{relVTAvrYu!708(%^Od=2Aq7t7m^w?WF=kGv$p z*Yl!sG}6n#g&W~_RA3G6Nb8Nfpmfw*Ock=DBe$;I2DAF!E&M|q*7gyonVhdoZRVNn z#!&Ww>#)u29}4+hS;R0;pMVpXgN{&6POBV zCDv+qIjz+Z{0`2c2udJiURuxwL0g9~y`Zq6QhppZSnjT5A?r0rKk=tc-e3RPWyz$4 zb-1=Wndx3_9_A1?LunULe`u!S5D-#PS2b8SEZydgT>eRfGInpv22)7;Pfy0u+hBU- z0U^|VF8c$7zGgLH8lS86Oyw_DW9a(ly+ku1EThmU15?zWflr!9Beu3U|B zLSV@Kxx~1>k=y)wF3@VO014C@y&@&&_1uVla{uz?zUA)O>F#P+TH}L?tj5?`hkHAm zN?Bxg?N}1ExoCF$A|@9HqVZFHBn&nw?nO_rnf`O zo8QF0gP{)b^^jT0KNo`Bv_m`)vIpbnkBxN%UEs%|+AIC&%O11`ey+r*-f=V}wVUB- zBTwwwTG{Ir^Ppm12|FYXn7OY^2LKL+cGQkB%I>PX>q6bbqI*qp0CW zHs;R^2W_cAO}aXXl1M{|AN}NIs>ITi$1c)Yut5g}8=MX_BHXcx=;T2{XQiMGflEpuql@ zP#Ngg_d}$w_80U>#Yp++oo9)ZkM4PM>*y^7Y^snF6q`N>fevXFZ=Qn@Nc4rGh+A=P zH2pQCh<^A5cQh| zPqk6-N5>!smMZH>9IToog_CQ*4OS&fN^*@AZ}8=%B!ff#m5wS2EKr+IAg=dXKpfZW z>b_yq&4P)5OZ*Qs;0fpD+(z8_ZoRZ-bG;5|-AoqtFqRc>=>#j@{MQh@!=o9!d=SED zn*rMoLUEwV0@$#B4Z(er<1e8xpe6T3VDlK~13^&719S4Rx&X5+NH@>P83j{>4Odqm z2jV3WApU>~L<5oHy%QK0MuU;BopF5aShckiq*WBP!ssNmVG23G8Q-6`*|QoFoO58< zJBYQogrGW8%D({y2vel|rO-%@Yc&eNWKg#dB~yaeglAlcPUU1bR^ZaJzMQoO&8EGNf zgNYBz=9OY$kNm5Qc*yu*C&4iU7@rL$9QwVStho_)&AnT0(P*5D{AF+_r0^09pZ(%a z{02yNV2wUU3sFDj8iTp8Tx;ycZ-yG{lrIUr<JRu0pniuKH;_cAJ%lH9cdJ+G!`qQ0?; zNQVY=@lr}Eok3r7)UTWf=h?!%5{js+Rgz54gHEN(>qH*`&n{u{UK|!&@W6ULf}Z0p zpL#w5!>uob>Ymc+BsO}75+Omt^zNre5aar#Othk!h0d~ENbUduAk4+OAs0?UBQBbW z$tTRRJIn@4MPWUKgs!lL=~O6icg)$!lhDr=2_FGt-9#7*)Q;Q%x`xS6QW>HPUgZ}} zIETpN*DOc~Xh&-AAm~ucV@GmvBpLF_OY(9SZ}v>I2l5mjo9&XLLO**DUAZnEzY5~Pq?}>uy3EcjDF~`M0qqkf0;3md4@SQUI4zI@D;={BkN(J&~+GGtj5Mq82R3-ZO4*R`}Ar>>EFhJ}_nYRHSj2QTFWubyPAE8&5{yD5 z0i-wR82Hg6& zjd=~1UI%J~1hoiA1pNhEgBf}rHDK$J|AY8vCNjE+7AGkZ|S=CU=U4<@Q3fbG@ z0?PlcuoyKy)HBUcnnGs=R>G2^hPb6vtq4|!i*1CeJaVBioMJ3nKmxg%dF=IGW96kl zS5T@?5(MugE^Ubu!qO21%2Z29+|UPoX}2{`V=;UFE|gj?*3Px6c<4&j%pCS+t(*ZD zsign$My}$SfEJtg=du))1BDT}J1^2k-G$pobdGo?QPr$sg9mzNcpeXll*yX}u@O+f z-^hVXFyH;KUSaU+2tXs?3^hjO*ZvZghAL%rz)Fo*qnW&wdJHQ zO=`a$*H?AJ`|`Z~j6(4M2mGeb9(d}EUrfbHrSn<%c-*JsPK`S=P8k=UIw^HdDiPw) z&bP=FhVrqUIHmBU|bJ%ZY7y+V><{sj`nm+{-aTc3XMHCbv z3rtT>2sv}pTiR26=M3Hc?FPQL==t)Gv)h`2o zrO&NKV8aat$YlvM68ZgjL1khJIUx$|M!GmP=ZT+%%GGAtoEB*{_s?>^4=@kb< zKvc9;*yyz3v)Z(qxNf}_y^+WWnxb^9#|2ekGOqjJ`p6ti(x`=5a7nBHtjqK_3V>TX^BUmj`n%zZYVbJX=XBUtf8NiLo8kI zn;oZz`sg_Q*%zF(j5#K`>7JL{_Ce7PC|_MQ#-?1V=6|#ICh$#F>EHNGa+`#-bj9v1 zX`7@=N=Mnov20cdpis+JbcAY0i=b@NCg9Q~7_~G3Msx<1D$AgwvM8uH6_jZyP;qU* zg@Qt5O$nA#uz|KT|L=2dlBT6B&Tr=Z|K9h*O?&UTXMLXUdCob{Irl7vG(qQZ={SD) zEW}rA!F~(aF9hl#%K9Z_7~i3D8jGFV4W}s%IyN1g(bh7QY1Cp5cdKvstb*$Nucz0& zh{p>|H$&fQ+39sl5Y)_Cti|lUk=@th4sFXR=u9q>z{~?qMyA_hz&;?gkM;||Dk)q` z4x}xKm2zKv1~bY<+B!K68Krp##OPletd+iZg~tc)%AWR&Hn{Ll{?B`Jiu7WUj1lnp3La($E>> z6a~HDbF=cK^1g3?odOix7n{Wrb4o?OIHmF-=+_PLDTsi#wXd9pCJ;a-*PxT6!6teL z6Eet$1ob|8dqc1=&Q0cn@aiJ-_SniZ`rGin7zWHDRKnQbi4n!s+fHx(=;U4I>XRAf znv)sFbNwVIbM3Mh1d16m;qY65389~y!I%mL7Er+8ijkOI!#+IC@R&%k9oLwB09Y{0 zSu@vgD?B9Yl^-#?v&o{Ia`iO!4D|J~DuSXZnco`&Wv#M;%L6s${!i1TCM(Ih=` zMq~>8`3z^09$p1g{VFgk1+xMuG#h2@GQgvs4Bxwky>NQ1`Eq_`35u3@_cX}Jr&-GgkuXXY<30O@nZDBI{VgmC&- zoiSjXnno{$VMr!5vfQ=R zxre0xPe{%+p+Zf=PJt{dhW;kUg7qEzaQg@crgL!ypB+KN?UEg-!|_qH&sg-$`8yZu zF4_B-d8j^%WkZS$K4#se#WH-)ZZ!_!45whdN5<{wGgjF4W6fC9beE0AmwD)_W)21! za9zaB95@z@c`r;05I-h)EEeWE9~6w(Y?#!v{3>?l(BUvgkeMBWu+k!ZI;?Hw* z7>kM92`V!WSDocx3-o?o?>A}XFhS{uPc(Y0OW<U46VQ;aBVHShaRh`MP7P+zz2|z|gj^Wf#7E zQZ$f2L<63%EeCL0TT;Gm%o=>c6-gJBW9uH>MUiyO8X7<$1zpncsC#1rWh`|;>RpMh zT+g~t@+^Pb5E>P74drz6w9Dfu%*&H!za%%AjDAef*V4Au*jpk{iydUJLWy=*>%eX_ z*$NtTJ+TVJX|Wv)Ed0o#8=vmcByfblYm0Dig;^qf8m4xQaip_-f&L4 z$(up&U6GNPeb||it}HXGWeH*Z)?nQl=isNyor8<;UsAp@+lO|NR0tUkIMyvHcZnZu zWW_#vSTYrs1%BASrCzeGq#ScP@GL5~RMGS4a?2ii>ehJ2VA(kamO$0gc5l@w3G?cM z%{?G<MpYkkVz9O zBJf4rYRjrf;V{U-4eeQ>OJSMi6zT>j#K3F}>IcXk>Ic){5o1OAfY_N;!=16Lk|3_vjDMXbf^@9O ze)aF;U-xoEEe8u1FpJJ8MQButQN^Y#-SH3+=yyE=@xAl;hn(D==j%H-3ghK}Y*}U# zS~w(&;yR#`W~`vF3OkAjYoOUKDr}dPhA|Qvc+lU1eLb+hi*54oY^Xxv6GD!F4Qc7`f0iK3p4q~T|7s6Rc=azmr(`B$!C zvS{cSGL8{pj0evVqM`R-^;5$TQNQun#YRNG6E-4R<7>itQ@zBQ*|Y~6bFhh6 z4Iv^T&XUuFsp~oQtQvLdyxgJU>zX*OGr-ZFKuy9-llnl4Ekgk0`qdSoin%#uDE4zN;(&rzGL>kh=rQu4%RIUPplX*BNAY)>48=36nO?R+ek7?nJUOE0w@dfaW5{JZ7M!p zQZR$gAE9OCr_*(T1^1bXgV|dn&VMMl8@3~`WNXaQ6%RQjJIi!Ov0YKlQL~KRad3p> zAR4>Oqs~k$@oi4mH7z`f?4i_H7MXPys4WzDWwYe;G_>L_Ev|B56UqgMtj8fYLa{OH zY$zE^chq;Fuy&E_9?wMZj@8X9D}HPMnkIPZW0>0FDgdU_I(D)pZ3O`Q(NS`5wR1d5 zcha{qKYXE&sWo9iP?rK@TF{P@;d&}3Z(u}A&XiL&wN=vaUVG0TpC*rN;%h`Vnmc*# zRC1v`Q02hABmbn=L3u?l`aRo=Vw(;KYLnjS49Q|S1o9f6(QVLfq1=}Yh~xpd>C-H?Xe_SyZ{AOn2Si8 z7X`BBa_Y9PC7XR3GtQ{m8`()Z0cR_?HOngTMR4)1k2&LQ^revbq`3ITZM!9BR1QBF z@G5Q;LT~#9mS@)Ar7)d?A2;RE4&SJDQtg)<*B=oJbG+f&8)>*^3&K3wtzw3-R>&Z-tI~*Sv zwsWFa9c>el;(aVV8SG$DSxg_JSE|Wjx({a6@ZG8*Q>!vW0{Y%kBlz z!47FiBPPPiKISCn=h}Tg=0qDC>38%Zol_!&K%_+3UIf9gpHxtEajp_4Da7!ZyZ2}* z4(vo@X0JPD(zsJ4DOxi*iSRzN?hmkae|{d&lJ3BFl$|ubWUa>xO>D9WY3p?dX*=Fl zt#yAO^)*v!FQ5TLcG}MY>LO$-wEHbP9gVL#oaX)FT3WKOIE#nhIDcQN6vO4m$Qlu3Rk+$zvyA8OUQCbvDALsGMyhrPcUn?*B#gvi8iP;AN&X! zmZjD)x8qeuu|MHcQTGSb3ya}6T9>{+Ui`TiQ7*0yUj|Y1L4hSv__{FX(%-g+?1?MS zO40#)D|+2wsiO%0f_d3Y8h)u^(&Wzk#PU`tma-c0l)N+40hdso{B*N4|HvK>5g5iWdRmE zN~$_AyG@EjF)LczWZKh#1N|(hPwDtvobH5d^Wce->S1 zH+84GQs))G;~iB+rzdn?uqK$+9eKcA;Bq$4XeDr6iBQ+w4Z%B|;XO#xmbyBHkAxEz zZ93-Cg!4VR%c2iFR9`;ZRy*S|CLXgE%~I@-8u$DgRI#FbiFDGAYGWIp@9rYG4);cv zF|f)B#QZ6n@Kwj+l}oLZOBcGmrG%0?u&cQaHa}q62fD>GA=1OXors|!lyFfE6$p$G#J+Vlxf*T8$51comQ|Hioqt1gG2G)O~nZ(N3%lX-!(ggLW9j^%={}=^=u!5967D9Z7IvS;F1{;s6r*<-UnyE zUOEhpc5}hK`PE_r63Y^lRoBc{6JyE1j1Ixu!&DQ>4Kf(p)oO=Ui! zA8z1A8Hoi#3ZhPIsiRTDH@#D38Oxdg%2iUAYA~RJ&)DAmXEx+g);R%^P6dg*=XEes zI`MUsaMquoN)jL4Hk`#?l50<_B7S3!t@36VgkxijvTQWrO;}xT_CK-8Q)F!oi}B^J zfd&UoA|}ZJjk#1TeueebFlMcm#w zVbVR8NfY$Yx}f^9eCE>mFbM`rG_hOh0FZ&vo#ymnzk=W4o9%+;bZbEv4l2}`F>w$o zF#6sXaq?+Kx;4K6k%)B7BHe}2@SbmlYKQ(CpTC(A;@Sbhm9bPPFsTE>>Hg3m*J5p% z4{d5|$5s#|ARl7qc8g0?MbHtk5}gfd8|q!PrBFB zn~y~vA6V=IGDumVCD7Ply~>GkT2v@lyGzwMS)-5L!4*-*6vScbOh=zW*K7zVVf+B6 z-Ph#oO=nIJU%q>bTqe_{K82ExL)h_69=qc9-i282*N!bkv1EJgljV}q2g{+>Vev_o z7RxaEV3*Fj=?g+IR$5@#jTh+vYq3MJpcR0&7dN=RCb6zLYbh}J=_BK^EPLoq^Qn`- zoE#c%)YR<9-v_ybW$ z&7te|{e5OBxAKBNZDb=}n*->DI>9o`96F$7Dg+EwN(**1TRD~qg#rr32vbcU)?bY& zte=^)%Dw9eJ2`0^&Q02>QA$f`r1b&ZEA@JFH@{50rqVYFOHLylF6E{PT)K7Ub_wP#HM)ta5Kd@o z*@s?}65UkV?Zu>P;^{~$^jI$z|HY*pLDTbYjY5~|nzCYNP8&g=p?=1R6qLJkzH2L; zEf2m<(ysHEJb?M>3;Zz=hies1gV1%XRA2|Z0hQQXwgwA;Fj?X7DmE?}xbl8DKoo@y z!S{Z#OuB10Y0w?{l7_dCz)4HCt*pA^i^Vx-%Bst(i)S=0&OU2BZ9PyRThuJ#260L@ z+-^fVihYR|&bH{z;E?f!k63cfAn)-30sTjuBUE)-OyjHQb2O?X=zubPg*VSY9}?fy zKjfBTC>YhQ8B4R^MnhiA4eAm4`;y{T&0-%@F;--w9y}>>&%OdyINYS+ey3B1Y1*f; zr6J~qEc_L%d%QCpb43=OZisNJZQBk?(6K)Aw%pK$o4)Pn1t!U@us`#*$j}By8rSk` z%rNh6ynA!+Msrn0W1CQ&`va^hvD;^xoooFAtP1*3YzVCXg$&1FI8KIxFdQO-6^4Ce z_zZ@6$-D4p~Zh5q9%8*Y$V0Ua*)=g>M9i8Mj0c zw=~8$T%?yToi4@`M;T!UYL;U42Z0|3e-&tK3)CykRkgP59o!G*`ppvCdz`UdL`&lk z4K0mB9M#A}+c+*?wpsk4*tQJsA4+UPxcoo7zwM05Xs*XVE1q}M|9r{NYqRJ>k?nCT z=%mGqN9TVi+Puiv8mRZ(Y&5oJ8Tif5Am})*dUF5x0S?P# z)!9>f%I5775h=PYr5{a31ou4IBIKwa*Z5%07kgmKp;Y~I>Z?|}r9(0p!y3afUuT^M zOhoX(5fF<LEGNwcK&rpx~Z45&ypq(PPAxYDDXU%2YlA!8;#H2aBX zUwG~94<}|@CQFScOMLtIP8R!4<_$_yn^PaQs6;LrQ5a~M%G|dK+9xt`c&~kMZVP1Cp~N-n(V1tMYhEn zoL<&`{>@7d+BcX-DlmQq9Z@vm1^ZA-G5>U9}Vc{*)#FlY92*J@STSVBQls@V#ozY4f8#<&? zb5(zYq7+;4727ghK2$WK=x-Ev(Wdn3B6A2U>Y^42QVkCUXG;zo{K4h}AV4?M(#{)*v?2j53w28EQ)HHF_I6ev< z!pXw1&tY}!cht7zbo?4p6LKWvn~)!NV6te7VUW4m{GGYM{EfNI{G+)ZAHNx0I4LW$ zsGeZ0+@ovb?6*2I+iPcZSZl5Ot=5ozPd4Gj9Z`Xg^&pbQav0zcPmjuCRXc#)@Y06m z8(!RinH(F;y0-NX=AfG0Ddo0eoE%>5vaNwE0b7NN($H372ZhgGwePMFjX+>?W~=Qp z-}|umK*&kk3zr|vZ(39&N9^JDL)pkemV34*F6ZPQSX2o6lHCYrd&k$lcdOj?u*&|? z)e{) zR*V>m)IN4%(;n;`trt57Vi*OJ$Z5kKgV;IfWy=}c9rzm6$9LZozV}*B3h-F>Sx;h? zW`S?WfsoHaY6~RRgQJPmSQj2EHrxj+2#Kj$r{x=qqeT~B)MH-)&ayzEzCott z`J@7nTzCzSeIZ3=}w!E&B*kIL%yw)|V{K3jR)hw;dEbLOQNnDsZk8geDb zy;ZQSwA;4I?T4YM`RdLX9&DH_VVSvf#sym9kRxw5k5-^q(&qt#+%j6er~^6oJZ0Z2 zFjf}-o$|0kyN7H(BJ*1)e-lv*C$Kz(8oEb!k+YOYEerW$uP(RTE4K7aZ_R%SwjyoL znW)UhsHUjag2%L#uWI*1{oq)DlWtoaGnxrQY`pE5(c;O4MtTvDVA*sA?~a@nBeo-v z5W0X1_AeJkq%UaB55>-nB4hSNPFs8?DyK0jvngspbK#7JFR^;d(wU4Fi3`bSKZ|NM z9YH2gGTH-CpPLSI?42cZAnKs0juWh2F8bK=z2jhdHl>37P#6KlXF_rsLo%B}7Bm;l zB4(7#BNX11yzB^JWKgPy8lGvld~W$+1%{-gS}O^@UoB4%-(Fdox<_J+Ux<>r*odnu7gjG_MGV%9t8PoR~FUY;7x$ z-9_CsYn`dJqabF|1kiWD(tOE!*wK=i-n1ZCCuy=CwpcCI_Qp$S0uR{3bm>h6q80Z) zu-wt2-6uImsD$hc`MzDdclid^4!yKtGlz<|niG%65J~R53%p=`lhC~Tcv@yON$8;# z$+d;@qA>e}(e|PD7PeYv;9NeT>C2CLvN3(K6xzwD^l|*c-udfZr93SUeTy4R9$cT>hM$MlyD*h!y(QY>ucZdvP$AN^4 zY39G}mCHl_oWa`7>QZaz7cZI424XS#1~LoAHKkU;@bbSzl@PMM+C$n(`zlKpy-Ys< zkWY%K;6~97m{XYAb&Ky5vF{Y#aKaufNAI!~BclO_{pTLS z@)Xt}>CK6WwCW1Zr+aXs{~&mUy=9slpwLNU0j5GM)a~_liNU937p5DED~;dMR!*cH zSr6Q0sxB_>zo^a06@^)k);820vL1xechvm7`8>*_=`3F@5Z?=`%iB@N$;$0c&i<{y zm=Bu5m!hBr?1#K#?hp@US)8qHu^zR4uRSC_tWPs`IQ1%%z4%h?K`3smIRFPkDQn=W6mc$6ZidOHf-LCfd9pJ694dvWb)NoDZ9C%(ML?%0locGt41sg{u< zOQFOv&c{4i2JSwR#5XAh8h8vo1o`mPe4!mPf-Ony!Mhe!cSwpez?H0MtmfdMBWGJyJ1QVf|dY z*HUMxBE4N^Ux9HuU@%$wu@46*zgs*8hhr%5%w)3A->G_l4v8k(ZWzmB1iYA`fg4=kRdKnW`w zB_$aeFD~m{4T-hl3!asV)z9b&nl1&F%tuRHS**8AlWHsR<%74{tq0N9_1#-6M@imq ztvz~?b)^-D6$iKY#rqdz7%%x@sOA!<4;7C?-O1}?jF)=p!ySjv#^=Y`1KtRWgNC4L!|G60yHhGf-~9`5GI_2tQS9t?U^=YVA7#aH5o(#WepEI zG3ijiSw#uQG=~@t8uGDqura^GfHN(Hwi5VF&9uG_uX6K zk7S~e=&4YWUscQqihe#>*K7w=kU~KvG3|L?{&l8A=DK2?+g8C4LOGBXJfMcIs0kWHK*~S^Ql?^X*Xv7rJifJODi7++< zE(}yuD{5YPQM(Ul6rVT#9B?cq8>{p8@7!Ox|D@&XgwF<4B{UEC-gl4Uh@#GXIj1xC zhf?l`xN`qi%6+ZlP`;mCy+suNnWD~>^=N0F3}GNE7PWFl1Fd6{G|X}`D;awK2TTW@ z?wr?@O%Yd5$!5(6>NkvdP;L4tu-sP|QlbHV@mMGx3+avA0gMK?1`iJWiq0iyvR$nR|rw=dlyO87=m<>M^*nBzh&h17*uLmHm2z08mec6X?IFTE z2ory|quipb!{aL<_8_$8I?PDGM=HK7M_RT(-msb5aXXiAZot>pM*2ApoA$^|9Wn!s z-8JK2W{Vj5LdU&@Qbp9_bh~4llQaG-+ke{9IywPobz?p4pAqx0kO4b8Q3xj#Vi`F+ zq#YpOk;y(Be@Gh{74 z+5>Qyc7{x+E0G!}%D8+-f$Wl%<}tAHJq7hG>UE0_vtBW05R*!z7z9~Bz4l6doT;O! zq&N1Au10hJxptpvPoS>E&piZYJz_s+J@qeSgKGqf5XljjW%5|-h0#7Xl7i6_g(Zix zWQx&7T9J%va3aJ(ox>0ZBK}(2V$q4a+mlZ=&f)fHJ%&*-kAL1#?}`93KQaEnBJ;9g zV>2O6&rpCA{xLvMmcx~0ipv)8WyR7xIt9LS$=NLMYF2f|N;mtp%#il;<5ox(@V10Y zmX3~0Y4HNT=IPto7XV z(x&B`UflHZrj4uxEp=#}LqvukPlPmf7~-%8qc0|Cc*1aEh-38H!i<-NAwTM6qO&DK zn@pNLc=ozJTF#G;wqt-{;`s!M(fnMl9T)cn|&UDNyMGil#3$Qkk-R-F<<}q z(rQemAp3wV_c+}2N)9~jN48{do8`ckLfG*wJ+xwIXqIhghZA}Oy1DD@tdCo5OCZs6GbI{_9qH+2fT;DCCy{{UPP=1>$n_C*y| z7LffX9ee&9EqLdqIYXxlMiF;l`yB!guu%9h9+-cZ*Hf3Fw0-)<_fI!IGVKFW;I=+D zx?O*3&{~%}J&Y8=YpsuLem_Qb603?mX7c~*_Ir3;_H!G_2Cu;!K?*@qv84JE7KalICGdeH`fMI~_Gi(;fzupbQG!RKaT&cr0qNTJ0Czusx z*cP8-unongFmjsrf?dYzXzGZ;$2Nzv=V5b{d(zCSah7&Y$D(R+xTOuD#T1$}!l_F~ zU07F`k!8EjMhPiT+v0wuA&2ocSEd|dnG$Y`#{{yDMKy=R5PH|IrS3da+g#%k7?Fks zXj}TLsZd^DBEzV}_FwJsl!R%NTw=>=Lza#UtH=z?vW;Vd8e1D&A*)GHJ1-%}xDjOY zjv(Mn4EmnCXFkxqbqO}K}>34w1J=cC|zzE4eX3h1PC>c1y6uy=e13}K=53&l~LVWC^tDPi>G>h?--3< zsp~_-=)zy2OM04mrfjzpAg=xzdKT-URRfp6h>GBdEZe{~l>02izS0dU27A0Z6-x5Dh@zU}aF{lEJ zO3r!u8aB;&dp{cFcMStQ`D^yni4!JeSuWU~=60k;+Gd<*{fJ%JS=qK1PGQ2&QY`Uw z_h4)vpI>UgY}Ki@4JR<)1(V0yZI7QKNeUN6cLYt^VdGgWwj>s12z$w1s`mrBLr!77 z4`%Xo*!o`)5W-totm{mzPqT9rFqmo^dV=m>+iY#kmRQL2Xt~%{coBJbdt}8Oky*AU zE>U?w2|9ezIg*Xlx#-z~h3{LSMQq`h)!5_rM7tR~A+_=Pba76*@tACJ zPP^4!5CnfKT>gmK=Z;e^jlPPsOP=zvy@mDR*d5=T(_U+@wcCflTBHv`asJb}QU}FN zVJ5i3*veYb%d_lZVa276m$S2`+P*o(0vnHsFt{exOZw+H7f)BPL{3zLJ&@|^8rlvu zv9Zk&MYmJOBy9^e{25ayvmHEVIkH8xm3w}kVuCHY?SA7Wk->k0t-i@Q9#faHZTpVh zzj(HSc&@f!AVy)^({$hBkqQid+D~^);F~6Ud{>*9P4>X9HY=NKv(6cdFsvG38O26g zapv)eB0pRFWtPNN-Y!PZ`I%nmCRsYRaJIEg#>*nZF=PQ(Y5%d}SZ}+(Cq{d8#lGI2 zH)7gZOI7AC$0;t$8Fb0Bh-W{pBy(t`v)Ev(ZG!MP2j^!PH3b>xjp&8)7KiQkzy3v< zpOIy0x7~IQd@U{XLltkUJ9?k>V!`wp{<%kLMv4z#su{@-IA1eT%5Swl0GbVf=m#c@ zl=_b3eMgFYc|$DJX3n6obU=~cDF^+a{@7Xj6x6#9owa8oBv%PXk?l>n9lY7LoVEXf zW;r5qx-pZKGmgM&<2@r4oTUS$$`;Z_3`HNO`?#ZQ0F{RpC}IqrsGc-o;ue0Z0-Z*4 z%|2VpiT4BIe-Q6%IkByYi{HQhv}EVU3eNGf=~#fI`j7WNASh-U^T=LmBUf9Ap34>< zZ}R>1`)uDS{uP+$IQ7y}y%d{RN~(juw;aT)<#Wd=$!Eden;ONo<*HdzW>g!+U&n;p-Zu=$ZK z{EICZ5d2oL@3^A=MfTWbKDpuk`vgYYX~Z`gooO1&)bnVK3vcf?ge&Y@GGI}w?_un+ zuU*t}$K&|{3lkPy8onT3wlK=n*0d0tO{VgEU`e3)6e-k}X6-(Ell@Wq+|j#Il&Fyd~@a$5G|Nybr5e1U1P4Rd}A z^g;Np^#BH6`fER<52w|exsQ8s=hxd$Ly8Ken_smzy%YCA+^2Chan`s4aV>F2;!4%+ z>e-sPnlfK=;8MSf{-yED;$MmXTm0(yRq=1d|0CXQAK-g5@T6~gK;MLj1Y<&DLQ+Bp zOotN&;65!OO7(t1lIouc{whdhh_vAqpM|OxoMC@1!@O(B5mlw$e~59(5BZoGz%7(m ziu-6bK3}hr*~bj&W#~J2&BBZ&)y88N2QQ0#D&yACK2n*cX5{6v<1jYd>(d~TzLC+^ zo;6|Oq*yf7Qp=gaWoduU*tH-y^Lk4``$i~ znZz)q2%ZuoI`R<>zj)k2(PGZWvdWe!k$!+Z4BnS~zrxrmGKgMYR!L6e5NW(zi79Na zaxJ@+Sm%7Zc)OH~uS4n^l@+&h@w=@ytL<;(Cxxj}XZ@(+art@qLnV#0?Vw4$OF2vJ z$1iKrod5Vl`A?4Ndr&4MNCP{m=<(e_+tN~nDjS~N-m)f5oY0VWm_3r}O?&)sQbI%e zsh60=*u%o}$DcoyatRGYT}I39Ktp89Zn{#pHcCmCJV`asU*u%2f6pE zc#YY8tE`dgGyFK0mv5C7aW?6Gcs2F6v^ z5uOO%xc+_@%&sKB29y!S$Md&a|hU z&~BLHT$`Vo%cXKD&fiqXVXff#htzrMeEeQje5asiRquVh zkM+LL+s8lDKhZy5{cglRB5w`Tgg?f7<*Tjo=}|uNeD&``LITM@HCffvs!@kz-f4_H zgT~iI4e_Gtm1?Vclll{No%)P=dtWa8r!;dZr+(#SD)4VUt#;*In)79)nq~c2j+n4? z2m<|QNf9L-R!pVgg2h(YrHHmOsSE+ogv01UvFgO z&8d<8Bg0TiMFrnWfik6Ri7n319&sEJa;29I!^D+Kv41UIRL@f#%|@39+Gl*UZl_`$Jv& zxx{#`M6ugkAOCaz`j%aCz1UCrY?VI1&-nNG8Szy^l!o4Y(eA2B@Jfc2$I%P=aL`wA zgUez!XAE8|+V|Fj>O)9R#sxbnK=cE9q& zb)Gj&sxGhlxjgL<#$?Lt_LkRO+$xSgQ~Qf2zNf64CGopzkK5w~ z*PbyR7xh2EtPm`k1v}0X#$L@M^u8`S(@;4e2=(Z%WOsQ!Z-};!)8GB{7{=tGGzDiL z#6l8F_7vi-&Q^ZF>fuQLbAdqO`2s&;T)}|}>IBvtw1hpB~?X#rk+8YY)(e0)wZ6a3j0^F1*7T-m3Dt%JM@9wy3znIouG8 ziF6pr_a&+hH z%jbqSIA-+9?KH08St6jJjGPW5Z;{UjLX{jvRNkVyd?z5TYhrX%+5bq-I^-1G>Mk2I zF9(#@&4sbuIOFnpW;~MJ!Lq2H-7iz76aB6TtaCdGdJ&u|z`3{lh)(cK-Ut#YONOyI ziK$SBphCsEb*R2fJ=L4%FM7G#Kv zdQoONbz=K;v;=$ja^pzR8)XZ`_RK@aU^`f-hVVc=#NqK*6t=-=Tn1xk39nSK*%KBf zlgf7+B0xyQp)>DNSIS6CYi$F=eKZHkc-tgr-<0@l!d~!K!@p2&f8|TNtv@%I zyMxn;R*C*9dQ}uA?j`OmZp+G+LP~ZmkZVx4$X{78ApN~@zw8-w(K(MZ8%+PS3|OBSE00}T5gapsa|x9Yg$&VY4I@{M58s9 znCIK=)cfi(*<6qsA7|L2ZpGU^7>j!bVG^=r!y9ktY&d2_ShhxC4tz~A9=pA~?QOAs3RZF0K83(Ij$)kN zYE!*7#Hg1K`Kz8+y)s0uA6PeRO-8xVe@zCWOIwq%t59KTyA{=prq0K%Sk!haZ%~wL ze)6$B#cjWIxSX0U`vCh`vnD^I<=gmr?DextQT`JpcjzeGRKw-S!ScG)i!S8y`TOp>@0%~M1`po=?FDURp-*H~Jdtt9 zegtJj2x!)<%~(|+F-WTQKKbIO<<+c|G**`%8nz;%{7Bl0jJ2yWEVagyMrPChB(_ys zmCpqvv_pUaG2A9%ib;ru+(h6e0yh!3iNH++ZX$3Kftv{2 zMBpX@Hxamrz)b{hB5)Idn+V)Q;3fh$5x9xKO$2Tt@P9J`@;N^qKKHlB@448qBrxOd zTlW7ht9fPASH`vXk5@f7cgn5bF4=!6^xn_&duTs}-!vEzZ=uhjo-X2kpL zAASDO(%t-otv9D{*k$P z)3^WlbI#i2{%3ES_l9nWSiRw%#jp9^p7Nsk#Ml?d5B<}w(#MAHuFihwi$CYBcWnK0 zR_kn;^Or?O?|pp!KOQ|7e&p;Ed+r!A(I~0N_)Gor`UzjJ>o@$5Z|A4St$r}t^7NmI zb_M8mULNc}=jiC5wbQpvyY8;TZgierIeBK@oVczISGX56_%6_t7idx>|_1th9U6rn(jq zc6ICehByrc^Yi8wb@=e4|&COSiCjzc?>|!J0?#!QOnEMDZrMzoi{@lF$tFR{G zGIO7rrMz>l9_)9Cqx*}98)wLW9Gs`6U56{+IS>Anch1n~2i5jS?Oex4FkDn}aTKAJagZb8pcV#VT=+4@;?a`nXd+&>%g3iMa? zdC#obvss*zkXad5XG_EpkPNAbx%00Q9kYhdg?Y1Q=w~X&%rjhtYazUd`(s}Iyz6>{ z=ikE7)OoXK%+GyTShadBLcQEZ&MVLZg?R?$!dV3~mHK&#*?GAO^6&;W3Jed=RL;yT z&_Aij{ZsDTN9N7N49{y{cg>vj@Z))NDOcwi^bi+C?(BSI?~~UJ*>k*E`FRBe%1q^q zdHKpY^YZhQ59j93&3!a4O(D4450aIC%2Vbl7v>?^ysPJ<5dWlksmdq8tsdq0ab|ir zcdp{khFOHdtO8|TZo#bCPo^qo8fM-Q#cujQMFHVPLb`BX{_ID(5a>criBx9IRm{>C zD1mssa^4K(+`PO;ylHmFH){qXE*BjCDIXDciSFTf3sJac%~cl6%$;*>md8NO@(NOw z^93B!6jNu-neTbO-#h7^GoYL8{lJch%GE1#=Yj;3@`AjF^|R*9O;g;dESU8uh{}Bu z2_$;u55b$3s2J8QE_&4=UmrEhEkJCKC?B0YFCW-@XeCF0`8acgq0{lIgriQ&Tc{ij zSb9jzV>LnkrWAEA)juA)o()G7rcO9`K8R5jSA^{LEJ(A z1JB>W(a2c^bMu~53WVaG|8UPxxMc7DI4=SmzlEdUj{Nv}hJrlhsJXd+nw@v;(slQ| zCkymwF0Su+3SxZB?R);be7zEfTlaX4MrDa=oXS-eO5!!h5a^r)|TSq1YR$y45@7*+6a?)*IEjQn|Xl+-pO zDSh6oxjm$FZ7Yc<&i;yf=jY|;QgwTWa@4GXyty-SLEN>2_vqRg=K#gXS$U~SondBv zUVf?)FIQ0)dyL21vNO(sXbVQ>qT-&E_i%pRzeArp-p)7&DJJLV&YDe)CN;9-b03+L z``fXkcst`9tU%3<{F$p~n7R}7dZO+}J2zH2e|9cfrjfaiTvd}1aUOW=ve=qgl%8|%FASUGxccc#)I&AoeJ2UPYIrV;B^x)s$K6>oESS3AbOx8W) zyMUd1^ZFklz{jiN;uGTHd9^w|9@{W!;??nSYFNbM5wBL^4JK6rpOl=GoS;!_;`xLG zjVeK{PDtPr)O?aUK^3n~N=l;F_yjc^cmznm6K|S?w2JXlJA6+qw<2q{obo^XLru#Z?(008j704r6T zS_6I%98cI&vKkfsc-X3VHKoskOF#p}VTUy10XtCOlak^PLs9}!osa-yJo1F+K^@Tt zPF2LOiY}f)fCzAk2q|&+K?H;XF|GzC07$7+#^YZ@K*CW2ZgE%PC6Nb0h#I&Olz7u5 z;73A&*n~TrK`=q4Qj-VB2T%h|cz_Th3a_9G{t#y}vI%*vi6aaFjVcau5eGqlV5s7e zcgRnkVF!UBAti4lJIGHp*d-hwU&uP-5B?z##2ByUH7FL8`2q>xK|qL{5sqaqMVFWq zuL5B3MNyHg5cLqUBv?WM5iLT1YzQ0Sg^(neyhcUIktCp8Bqb6PkWV*yl!2g~z^8aX z2G0W)WG3YckwO4Mz#tbW1Mw>0OJqarAzXvVm}ac=@JvFWf<!4Le?-bgg7H&Py#0Kmq29|1)8kzL{OwhG*CH3 z0im$SC}ae&rs9b=phA2k@sK|x2vF3h^pJzN5fdbv40jbsqli(30bm|CDxW}?iZ6Z; zMW9PXoz(-HM2JI@Dggxpq=8_vh8v_G(ZUHLK;{D3Knr6I5wn14fYnN>qBF2&qBlsiuX9193nAgm@Mo$cI;uOTYn9 z&;gX$g*d3mhG2jo_(I&M9+LP(*aM%sWAM4>D&Fwk-lGq}_c6Jn3JAW=~PJE#w+Api;>N9Gc? zLS9j04W)ysA*xoW5Fv3Q4X-F{kW+xlkS6jdN}i{Bm{Ov`2|FsHDxd`jNZR28Jo7*e z#1kWUC;t#!$Q@nC1&|L4$TvKaLP4D24v|vB6KZcF0_lPo$P<)VkWK0+Dx9Q50Lz*Q zctr7qD?+Id9YF{nd18|qE3zh81HK3Xz|;VeTp=K!NJT;e{z!oVXSl#Wcp!y{XaUry zs+GuO${(OjLQP^%BqA>4GUYLZm?aEq8UF~1G!o*KsyJc;RIz*j;YgVYJ2)j;lauk_ zfj3}8DW&|SY6Kn;Ucd@6%OhixkuA(C$cJ7D;3!wXff8IMKum!rA0LM-gJM7lB>^m6 zXg)wOv_;ZqKps_<2nhNq&k#H13;m-eK;mEy?J$I#q6e2kuL67nV`L^_1@aJ$3gkeZ zP+d~aA{#(D{IClU_gy397q>WrJgbm?1FZbUWPbNg+u_JWeErrG*ft_Qh}&Q z!vn%V6x4w5q-3N(#fa(&Bn=y$qyt7unl+46JrG$S7-5MLs$gINx?sWD$3zun8%RW@ zs8$k7P~ng)vQ4NbsTxCRreXmq!7)e$2~1ci7SI$A%utr#j6~oBBS1p36dSRK8x;^p zGaUFt4U|Pdh)~2g0#U^Dmq1M6NkT<}!L%$Wt4fqgD(cWakpNO>9Wn$X2_cC^1|l)M zlM^x#Y_kFeKBx#YG!j7r2^M_df+m6*kdi}&sZ}6S1zD#03KS9brTEYvtuSSYWlbwhmA#t}=P42dEdq>d7bLJko^F;Jm~MstBI zK`lzf0U!Y(s@ZX|mK9usU))qk36ckS!4I7*@J62C6L7J{Gzm&P#1Y9**#SckKSELs z$SC89ZN#dg3K#K^I8cG2=y?FaN(OpApn{x`IV*78P1lMQueh#P*|pMjm9y(Lc2NO9 zVkr9Yk=MTD*Sn%`?25VO6?;P$0j+j3*TYlbxAX4iy!$g=3FUxt81exK6R7S`uUNf$ z^=P{AyzZ5PN)d$!s!D=qFW@f2WB)5(Qc=p2Ub!xF*Y%Ks{x4!;RRaW+N=Z`EjpE1f zO+nuS4JwtV|BLX`Qa$`1z%MNc6(1E_ltOB6s3Evv{8;X2Q%QqBU8W}a3zx@0-lApU z|0|`A5yeQ?9t6DH1Lzh^yRo%xxCNy01OC-=3*(VELg_L zBD`YxZyOnjERh?)Z^-SVM&171)r)bD#NG&gnyaje_Gtx>*QOu;gUHK_0Mp z4>@u!Cd6H-2%fKnACzl#5_o(Uow=*S=Uw}E@^DrBMvoqQ1%jQyIEG*UFkD;!-Tk;o zdeGH{+3;|eg&ZzDlq;_&-NyK?F;GL_EmH)aJaU9CH&9C9)pJK<)p=b5KMXY{r2@Y9 z5;fO??>FNI1joB2Pk45cBj6|N6Becw@EgnlAHpb%RY4w~kzt{sLG;FlhK2(4>$e_* zLPNXc04M8gMLp3ngGNJ%y3V8?e5esVuQDr}L0fccTfXqmeTOOgY& zaE5b05DO9>!ir|Uek@%Xy@U%b6|=xCmeLCq-u##`Sg;TryfW*m`0e=g(@zXOC{(PQmAwSWT@&H$vhVU27_dDF>jGU0mN}^ zD6^0=2i)Y)cwhyn{BRF|RwD}zKr`y63Wovif=7gmjDQC`<051MsN;Az13&WANk$C$ zcGU_>7@=a)MQSNMz3Pjr;YaW>#9Z+0*zq61Z}n;yfTZ?$u1>;Thbe{k8H|&`h*aPR zY=X%M^1(V?0k?5|WqtaDauI!8S2*t%N=8|LAG3)LXOFlr_UO|`?tc0SK?3B0|6raR z!USiR?gVP0$=3DChmwg!3l|o=(<65k{9N$8yU82AcXzO>JCI)7cN(uEe}GH?kOWW= zMObwPb00<(jw~h~`jC?hSmEMTga%`{PXyN|BqW@R2$9P}LZ~?U;lVB$S%icO=0Ws; zg`Ye;8m4GD&+KsvU;#sTk3~p`mv%#OxIqezBqNI-w6NHbp8M(Yux=9`W0;efxHl-giF*j9soPu7ztS`JeT7f#k3-Q+xO zLBNj!hDPJwiC<6vE?ER0LI&^z{FGz`V_(uM9M-UIE*u(9+k^kdqc9t$-~(Lcdzn`2xDas?#@f)GWPAXVy2$( z`()e4+jqQ2O)joYp8(7a*HU1*#VEX9z5HGqKlibEh{dBNM1yU-#topTLm3BT5yL7+ zR{*jAzbQdn0C`}n%gK^mP+KUrJ{(gSVZvYyS;WXVDvNTjRMFPM23M?50kQ!ej!P0O zh4CJjnI1jhxABwh>o<5rZNn$)KiTMc6C|$d-7B_E<9`6Zh<^S0{f@(}AKiY(Y5J2f zIF{}qTt6+xdifDrEp$aLoIO$?g27~xb95&p@YHHCI71#}TnN2!DdfQX1#r=@0NP~D zt^nvuF~KRgT>772ok}(^M!TMZZIAfTfqfg_b78cB-mVFsckSn2$0kFqaY4nAJ{o}VfYFG8HvUtDTzulStQ9hx-$um zAd`%X#66PQ1YB&WFo;Ytj+~Jw?o4JmnFgT(=qsB?dWpOgvVkf<4?I2BmGZaoop;{x zAhrQ7?`-ri+M~e}m$zXhy!PCFc(uRo=)3}Y;U_255)-w;gBnCK1%%_99Us8qa~dkR zSb(ZlBTy_JYJx8|l1y@r?kIt>fG{%2xM-cysnC^IXURUB*`u5vzyNmAznBRW;+Tz!<{9PTtPW{gfpLY!2_~Gj*E>3uW zn{YA(52m{;7Be$&4d4QBr<#i1WC7vmA<&?ajNQ?QBqT6X2p0|8V0k2YO9%)FkC%rt ze_R9}s1?bT30&BqL4)KWxDE0i(583T2oEnBd#L}OU$SJ0OX4=bxMax&51&07Iy1w| zbXEMW)Bo_IP0ofMH5_|TWfbWiiyR!z#SCV=4B$fXggnIvtPL6zD`zI*&Z!0KNLfrY znIZ*inB;DM9NEiVcO()%aNs~c{0|%`lxKk_W+B}Cyh!9Y;4k7dRPE&>+e zoIG~G02%DKm`J>%6i2)KAqpk=kaM_0Q=vPfKD594^1`pL+YZl83d#SK_&sYfnKr!p z-h1z^f9@I6GbU4MS9q^{>jcfq)Ez%TS9agK4j*{uKqqw(^5~e@zIg8&6YXLpMh+Wj zW=JOn3LB|%TqIZ`bfd#%@@RbbhEpsJJqdS&X3(<`%$r;o$3u)UFfn_IJtEv)TqAD9 z1?A5RKIl2&(MY+6>q`6ppXvGa8#k0bN9dWJy`K0n?zJhYsoIp3RBbB$>AEId@4m|e1DR&z6<+S$mbmTvX_J$a zuEg)TXP$ZH+2@{n_E|ihzX9=EtxeS?x#RRauYup#@tNI(*b@pu;bp$AQBI0@ngV~$}A11*3HvCdB6^zz< zVa3gFz>nGrF6BR4_gxFP?ry0xt+XfnR&OjVEd_8J+uN_(_yRv|BA*PIqj}0a&Gf@O zKc4Wz^a8q#qmBscjNpc!%Lq%jFsIep6du!@X&D-I#r|)(w8^}R?-4)nMOSH2(G7^- z>Xa17A7+|j{SlV#K#|AP$0Xo4`X0o=5F^k8?+Uaxrre(IjfuYlL%k3TLLu5(XKq4JAm15}7rXht!KoYjBh2|9)!#o&dX zV0PW%1pKht0gFNtJmt49WZ^0o!Qg_Z2hQDqkSAiF&=UUp(!4IghMbtS+nM>J7vaYO zTrGJP32rHge1hug<+tSV$BVCnoZy_Af`uq(KQW0OwHRheVev z3iw@ZT7ZWm;*deWcy;s3o^EU5Ng)Ue;hzLfuwe$bSh_q2P`d6epUittH%21lMjh{k zLpS4`Idi(%T;)|uliV@qnax~BA;iReK8fV-hA(YmJeJLAFn?DG{5mJs^+dXWfPl%> z-2dzLj6`S+y!wWDyt>C!E!tnU+5v4SnhvS~)xQltXrfRYX#(^OwI8hR`mcj@y#yeC zNi@Cce|n{+VEs9|0;D(7qAFUb@f+n2^QY13U_G_>(C+o<|Nq-PMT^xf|5NY~9{s>% zv>iYYjR0Gpij^Yq{ZdlcK#Vp8V=@?&p}&+=*x>^V-C$2n%rZ3@i*2xK1mV@po<7pB zFE*qb2`{impj5;_13YZ7reA75jQZdODNtNA{6j9}1AocnonGk)pSbAmF;QT=6P1XT z99VD`p*A&Hc%!IjNQnqdL6k%Vkw9Ugbzy&jeu6v2B>c!P{=pvX$eO*7e@c#7kQMo- zm((W|5v?lzwb;YlY=BAAta<{=AF!uOb(Jv$Z$+1CkeSo z0tg~7N!}zwCNtw4gdj(}6;WK*YZ26SSJ&moDqg6_D(kh%vb(zLdLSs?im2?WtBYv< zpKo>d`}Vx^P6#nb_P^apzx`Cz(^XG>>#3@zuAXKcH&zt##>MM`mBZtTj*%2Wa`UDF zl}y8&kl?6t13}>{p%6i_NIoZ|UYVy8%|T40)DTA0q=fn3z?pag^+FKR+&Gt3pCfUN zExf1y?p7S}$Z_H!k;MU2PI8rkD+&eU$x$*6Lb=m;GM_n`sDW@@Jx9k`ucAw#g6eP} z$NXq1>0qd;oMuJkIE4q?nB7u7tZ1F5Qc++-avVno!Wr5iCO*E-JZf;QC}?GADj->i zgJMw*9u0$Z3W}KwC>mvQM=UyHr_)(F@Q00xFz|5RiBJw(h+k~_kMXY~XPOA%UHS)T z%mOtph(k2am)8mL7%UKzWcT!*4sYlf3>PQzI8NqHXvv&YOiGLa3%>O^N*m#DH8}O) zgex*J>J@b4jc;K108yh8&Vmg=8JyH3l|&F%J>Qqmw+!It3l9wUkh;FsqgvbuO$36O@=@*)0x*D@ z<7w_I1mr5G96R&?$rXhvkPfuyOrK6tQ`m}D9-d+#L1jW^=up8&F9M*0LFb3`Sq0@> z2VCVomeANRXt12-^@PL*qLejt+^y~Qogp`&T5#Bu!9N}D%=}l!(XY!RR^6Byq zt3X8&bhH%l$d(R2qd_^2p^{M@O6Ee(R1T`EG_Jyj_rXvVk&A91QZUZ4;uXTFmQ)uw zBY+bIELExTXLm(C^M7Qx258U%PSxs*SHLO_(#c&)kGen}pol?-@liC2noLsL)xd$R zKHR}cYaY~o2zh{=8X}2H#&pO~AgU=;#h1$0aCW^0W|EpiF~N@Qi2;Dfh)u2mvB4b* zM*yO59{6$M9F$eZT-H&I950X~=?>+Lu7XdHZ`dg*0#z=^2a#DAkTH)cM6JttRA$vJ^iYYaIU;q*0+3E{ z@*{yzCZ2er%hYu0E-Y$BeV@2g5HzC1j zJmQuH@PqhjXYi1C%8s}j>r}~v05b3$0o626AYTp(UU6~?Ji=Vv^wgfI4^@O(xzXDw zFD#_Ud(uOq$PvB!+z02ZfzpAj7YXKVz8WFhM$JeQ^+w-a0zaAs2`_WnfuO#N+|zg~ z&yvuSrlLwvB&{zb=!F1hz9K{A1S{%FZ6ni$g&d;GmAR+22`Q%6W;a1lHdTRJ2fm1&?T|5*5NdRp# z9O_(!0-E5I)Ez=s0RWkhBQ3rrK*BB@;fN7`A`Bs%)5x5kk|Y*2Fe(c^q`>>?Af)T$ z*;h1V+9RJ*NL6Z#4w;F*hY2FENdUzm=PoU=0Be0t86Xr45gTo!Zi9uJV3n~$q>PuT zR4O9$5~)3KA~O_(njW$$of8lQAr1gKH~@gO^o0iJ+vov>@>Ji{3_tAB28Xl!M36C( zrmxTo0$HgzEY$l__jrY-k4^%9)lnBtE27*x0fp$ zA|)1bL?_FTs;H_@l~J|lW$KEnP~<{gffEHnWh12pIdTLHwLGa%WSKBGBH)8cj5FYC zCh-vJ;8Z=ODA-(nDGWYmCOBw4iN`exWFIfyS6tF&k8%}st~exQJ@2U~0%%n#`cQ=4 zRs`x)z*E_A@S|+{>_e>w0w@!`0bln)DC(u}>l2DO&9%7i6;ZkHlLo4Gs}fTS(G1|l zuiisN;h+u@On;2%Xq=Em*VHL`Dtxt?NKOBrqpV1iA|NZ2A%#mu=-^!TWwq*4CGI8Z zmA*d&M#?EIk<$ouihRqEk5D*xluDCSl#3*YN8gRW1fknh?hyzU24@bx=A7_QE=U$J zVZ^EOBMpkoMZ+ulvI*9LR0W5S)%=xOHAk=6Op>~b; zP=1vs5>i4c7pK>%0^|)ebD&Q_K@pDb;o>GbeCs43a&Q3`3Z@zbXQ%(w2A}-h(aH|~;zVFr8IJb!z1?3nyo#mmpaG^A$td>mQ*C1_- zM4<+(2usW=O~s^g5m+ROh=fB+9E2vciOQ-hNy$79^+7j0Fe3qKo|-+vXb168qo*dN z-k;+!2on~lBmWd9X)3Gen<&ay#wLx2a;>xlX3iswU;NQmWuXZlp%#>>lMJ*~>@wqc zPhZvIQl15*JY8X-H{@1{Q(+_r7hE&;q%OQwA>HP87AJb#Nn+ zN5!GJq|&Q#5u8fPr3NnKP%2F-9;7On93;jMF!zjyGDre1rll|2nha@8Ho!M!3~Ir8WTOK zH8!9Yc#|CZ%AAw3#6Jq&l@irS?Fd6n5UwX%h(Y}N0TwtVmR4zXQJ)cs4+l1*C?G?G z_(}!2cwY)d1TweWo5B@eCaXQlSQ(*kdbuJX3FM?%=lhdVry9Cl&l3pnBDgw$Iu$DV zK(;j6@FXHdtUi_$fs_CR=}Wf^Z>9BW36wcS#Cv2gM>0Yas{}W*ft*YxpS-8{sl-Gf zp%k6Qq{vShOH(OkwJF&bki788=Kp@d0JCVSL6kY>g z-&2svO`*ajrUV@WoKg|G2ryC>#O~2GNdJ(4gq!Fc!A|<&F(7bx zp^eM&o-zZA8(%SZf_T9P8zn9dGN**3(pW!4=uCe zSFec#m5~hise7e#$(lzB%6v|FpfGX{1=$~zq6&|yDzlhGffWvw3^Ku|S|Zg@&E+3C zA!RXwd_D2HUJAewH-|C_f5jfyc_i6Hu7gY7E(bJwB*`0OL6RY>v;bO9E`nWR4sG&C zssdK%E2D~%caeiyO7Eh7TunKT#)O6&9im~P4%ITApjAZim|mXa%wH5ghi>GEM5Q9* zD7WA_zodOYqEhpKrTN(th`%FsOcy79hF@Cvm^Y86O1%}j(1b>*(W3%9d(s|j%&L?* z5A&TF8QS@05x--VXcRu0T#7n}rqVEpl)bWG!EmVm^e)-)wK*yd^;Na)xtC}Z41Be8 zbSKnbHGEjbG(D2`IxgPPPe=@RE4~6xkvH;o%z;C{VLZVLVc76!i&4lQ{HP95L)XxF z(&E=D@YKmte;H%sF!k!Bf6A#cQoM(|156^n=;@#;yz5*p7I_75hfjy-aIcUhNK$45 zZMe*2+Lk%>N5hZrYPgi#GyKR#OH1H8!q0^VVxExSRytIAFFILfTh%Ahw@BI|ZgC8Y zv=T4J6Zsc}bI`gU#~+0AX3?u$G#ZIgvNXu9pLX^4%*BhBRJ%*ZjdYI5uTw)KNTP>> z$9WVyUAXfvPzB-scw#B5V2D}I_dBtSWN%jK?k5y&Ir zrv9o`kyU{WqIvQ80JXTamV=xKTfF8)_)QD2(Jun%cXZ0hc%pum%5=dB#K6)_pH_Wp z)c%d0!64I0zsM71K9I`!M*@NhZtjrZy%+NeqAR=-#MGi8HkwD*fr*D1Bm9=s)(_t< z)7V(V&nei`p%!2oNp?b>ONCyJspPsQY-@%f7=uCk7t5H-d*lwDN<6@1_%re^2l}hV_A^zk0h2dS%vbU zcznN|nNdw4sI`f(k)|kLkvn(>o<+aNJ^blJb8koQN8yDKc@(3OcfhZiM&?u4PRQ~w zMuG5K+AunPEmT`!R}MdUx+^4H;wS2-+6_mjxC~6SutN*zd2#&048=29n&}V&2X(*~ zfZ}8f@Cfk_{9|73oe;IaJNR|;DOwBE0w@N)@M~>oEY&}GhnO7&KPLwW7C4>9iTSDa z>OG&iQs!T11=STJF8Dpi7ZZ&P>fJ&yQ#N(=s;HQ%rPndxC*raBwk`}EPPBQ1kWH_@3&QLi~c|MWxEMcDl10}RhYnl$olVbir^T8}8p?geu z*4Cf2_${VMW@elTYwea{j#*>&lKSh^oNr8San1I&|JgpL$(%4xO_0B5eUFw#W+da$;MWb-dnNaKG(&i7^ zGA+zGw`QhDl^tZ72WOniLI)F7ERry>OQMK@g!K)Y=Ahwo`o~TKmJ~+d7eNz2;?N59 z>KWk@Xzp-;qe$cNY45dkj>R3oq5<@B3^W-WftEt}10G;XxQB;pxLHPFGYrNT*>)If z?uJkza`0$&Nfiw~ezgG7#8Qb$Cs-)qB^KWB7Pg!P(ju7bcNxWQFy!7Pa;?n?u{mt8 zj9=|$!wgtgh^l9-s9zOk58M+YHxUi%r1)?883(x?Hoh{mEkqRDE zz$sYoQEoh~m`Hyh^p7wWlvEmUD}ZpZky+5wz*Pnuka#S7qtfh`fR&ja7)X;uS<&W) z9k>WX+)PP=A*wD-)(X6$Lx2|TxgkXrNC|%G2VA39e5%fdxYUadLdrjmhY$VJ1`sMR zo4)`-H3jj>g9m(C#CP~<)?AjqPGPxfsg+NL0aR|s3QP`Rws;98{g6R9U_-r_Hlb}5 zU{Xw#mrxFt`$oUp>%E&i4+Sjf#%dp!LoPAKEF;O!O69NFpxnY zRm;VDyhWjij@ke)Mcz$Fz6}(}+xl>z5RwK2py52dnBi>;>*p z{L0qO;r3q;eObm~_TMq`u|pHBPz9R9R^di^w3GCrN}#RknVVc=0EB*N|53iXjO@QT z#gZw{7`GE6_*^$MoIQ%q*?(;Hbq$l+aG5EkC0b1LIi>>RMm;?9r#j7|a|dOljXDs- z4V5g)Z_xj`Yzzk^bR8F;&j*m07uQyL^$6uGs^=KEF!@%H^RQ|>=I^!7ls2_?1bzWx z!_nabrg8fvh)#@!5z6TJxgt0!ABV@7$z|dhz_Pp= z0zA{JmG%xn>8zVL@xeZ33cIwnNFc62uIN#)Ut;H!lxdQS5Tjh7e4e)racxqTZ6GwF}TWD3#3K*`i-8F=6LM7Ag?Ye z$RNJx5s#0fziu|Np22{I0K#vy^~)emiRQ#B{sy2Z5nW=7Jwh^+A_xv*dPcw1XdFWr zW`NvZN@9$}6hevpqR6?!Gzv+D{jZzX3(|}+hWzpg`5KFI9hJ|Gr&%&*0zo5n4VxN0 z;Wyg)Wt8@C{35K1p-@M`&*57X@mQ&9?0n6F(f(=d%k~2xEWuB4IXqnQ{3!ngT;lz2 z5HuW~2)}2c{LAe_Tc$rtc*?Uj=>kg3Sw z-a0a^DHeTiIKQTm23z!FvGIpY43!9+weCVIfDPoao6B|2YbHlD^ z@sekm#Y?=7WBHQ5MIXD4dHqty1NdqOtqpVIIR;F*5#x^#vEh$G{~NRGq^EF|Fpjhn zkILuP16tWoj4{Or0_t<9pn5gRnNEc+8517|0P8CP9v^L};nP+ zE!AZlNPd{UN0V9mU@1AL34C|li}oICmjrmvBOXQX^j#@w@k&bw@SsuD0L|QMt%xN$ zMr)*tg%5T)?Q=&S*6utOpoo(t!czSUU@7D}(yNj4R}Q{W@Qd4jPs`Uz#@*^63rXZx za~wMHroAQ_mmoFUW_?yC*=UZ$cUDH;U;W&McBCzkmHygMVus}A!V5y%Vt+|xmY46JTZ8%TuF zhVa(uW)cYuRZ7zE$JNDUFjx zS6+@r56G$fVpIMhC@s?Qc&RR@BNA%UFpBxmpWX*?qLLk;_xZtCX>_tkK6g%@wgvF1 zzUuQz^v|i>$e+2f_1cl4MW4C;G1`Bzb>dd?7M>zSK=o+P*7e7(UkYGnJvZqaYBa`t zqwd)7DS0N>EMwP|aD>%3 zKCc%>JG_FI;cLa7qH?*~LrosBB0XHZ=g`GQ9WL63h9(`cRx?vq+WrX^MAQ#=_$b(a zCG&qH8AsZGF1isB#`(}ciPf0HumZ&qD}v7H$kK>yE13$W1>{+%$u&(NQw9(ctBXo*5IV!{_ zj^DEYAnQk5vU9MlslBrQM#ImQCMbrIjkN2A0~g_UJbbi&d;%3SS07xY0o45cXzQ0k zsGw)VCE)py?iw@Qtq%GydQLKMe?IQyhMytY50M+!ezKcbJr@Ah_UlG$Ed8*ivQbKgE>|85;> z2#O>1FDN<*3N+!PjQyt&u>`--W2F7(*pAA#lv1QvnLuFJ#4!J8>z6J`CFbsUja4}g z_y6Ndwj_pX&EU8pGy8Wjo!t~dY5k2PbngZLL5BTrZ2zuHKV~Ez}lxjf2ouupu2`sG1rNN&c(Gvd$Kim)}Zs3bi?T5 zDE3Q;M+8fxf5YcRkyZa=kK^K7n&Tty%rj9pn0m^&^KWHGz+?i%!ru_Ruw^J9DUQH# z!r^OKf|bt{4mwEthq20O+cNz}DB&H~c=Dbf zTtef*1Q?^GCcbp-F=@#Zb(!`rEaKQB!Y^k3MTM+qpb~nFwEv!-Z>gF-=HUfmUCujs z@moyG=jI?8|MCF|jWxZI?Vl88#1*&KMg+z@j+rkupSV<;I{C65oiL|9awqTk-^Hk& zCu58KcS@63fV;}2II zT{8?)VeKqy|G9Q8;s_bb*?&*Rx0G+G=+v7mdgj~NQ(TXjIsIK?&Cz4q&}eJqjzc_J z0C5%%PJJ+ewuoxa%36;3r3P|`nz+eWH!tQEY?+%!YX~Mpe}x(yVk8?JC*to9@o8BF zvQ)=96aTT|HB9puYtZD8qLS89i7o(S{=SwaWIo?CV*j}CaJa=={et~hV%LrA7ef1G zSUVYyNs;T0^DSjA63Yt6)E<+2eHckct#|+zS)+qt35UG9B}u`QBUEc39K+D3EVc3u zrr?7uDJ%pR+16s3plhDPAI;(~M7a=sSeAgfSaB?|=nLk7H(zsQ0U0BTIP|~X%VDih zDM&EjaN{E_X>opruTwIE?~Uj`T=rZY4f3krLVjcYuj?0%!G3vqKE`ia14nMkTt~5*%_wj3e#mr{`M=8~~zrMGEBUB1fukfPlLm`8oUto@7gPPs+&OZPCY`TrRZt zNFYcpp)kT(gxCA^wZx=_9_g^MuFv7K+D3&$1No01kf8SZSUusg1Qfrkt+d4aV~>GQ zg)9=v|It7C@?p4m&VGA%O_! zR6n(7t32XGBLylbWAGku3Df{>x46lhG?XZ<5LLkthd>U15Ny%8xOd^>>BsPh2N zc?v0jCPJboVI|F*OmXlM1wqZ%s;T5F#V=C4;!{wKwCm&>fakCd*pG`($5K?Vw0ml( znUQ?9u0MMH(gR;1iRP*pb>yrRKjAX+I_7Bk1*sI&REX=dpbVGziRe^i<&WtM8}us6Zw|b-)R4^geY;kG+N*}qtxG6x8NiQ z`_-8JCvUi7j3Pt6*g4^&@&)sMt|eA8jSA*+N5@aa#pMzYse)5w83edeRj^X$5~<5k zfmgw^7+mmzG2o9A97-wAT`HuNVW=bv5lK~h01@+fDQgz_j={df2A@GVux zNOh1wis9gTv}eA4DQT2x2ZE#I3ITMaa~8Z}EW<(rMI zQEH2ehL;0a%HkIXE@CW)-_!Bwv#c`oX#}zUg7u?kzJ4iSBB31>=#|q31%%Fkl5eSB z7&813XKPuCDM$E#%_HVdYN`FrH`fu!<$WlgMSpJM> zF$efNU(&zP)-Q{BbvcsL-2pJpkDs`o%ZdDSmB+6bX#kvFiTLAT)dEjb8nui+81wO0 zt48jBcIo{|e;EI2?cAev!6XRk?=v}n>2Pr3&DPQ#^)~!aww?~ zm?GuCDLMm6o~3?a$nZyyztFE*){6v1@0jRfih~}nJbq4)06Ry9{c6enKY|omd_?{9 zuy!)e5V8;B1HU=^wPxBrO%mkX_jjMk`Ac#aT*Dy={UZE|EJZ3rG4SBG2&UOgVWMA8IT5#SR1g8o;B6oMW^a~tmbR@o7- zA`2vvNM$G|b0NoK2-1&uafWX>iNaV4o{l+uDdKanxwpWtKBpeHmcL97lFVwA+kYCQ z80FK+$xj*ll!B6WcSIf!-%@6fG-;}NOw8z$cm0j^OPMSPs+mJdS`%2K>0ba%gx^T} zPl$z~kP&{z!?#p5LIX=iM#yv$ufJ&m5!f`DjR6RJSPbRy3pF-EXf*rJDW5|!(8lB9 z13wP92s$hR8s(Gs{ACWcqlISjnk5wQWBZ>QZ8}Xl>d!HM*Y8-r6BD=pF#A*)Gz4~M zgV@RzyH29@OVo~wc1A}nq=KB`8b$w(isp$8tY%b+CBTAOFa(w!B4bW7l`3Ycx9ST2 zDSy7X>E;TV%ajR$xBGLnS`<>In)L@*RlSrw4YDvT{ag-nSKECc$TMX{6gq1trFWl# zU^&HO6t4L^R+|*7rV03{860Zs_+!loNcE+W@%Yot^dFji=8aMG&vie*6jsY}_FvdQ zh8*D|Zr2r1j#uz9eAROrkX#uiTR9Kh>iCnp4WQGYKgi0ENgvq^WG4ge3cm~spdNOZ z&eQWrVd_41nc#6HL8Gcw4fa)QeN!83NI*rUw17o_LR3>0T!2#_guyuTC5_rk?TkCY)9Qf)c?lpKZk9AAzTq-*#8cjCj_#i@>MsW7WbF=wK&y!gpm!t(69*W7jr{!{ znf!dYaJ2qIninAHo@MNk0ww}4g6Meos*zo*WikmMkQ(%G>kq9G5@d|};xa*Q1OU}Z z0P@4hW*K7qjeF@2yAT+{u%U($$pM^pIOg=-!<;f9Zf7Q%~#+}13#3eSa zmFh(-4$I@_t9A{V>S~}OCjh8tCkh%z$;hVwnrIv7(d(!ve+8u=9fZ^dH96s7NJk~zsA(!*97u76X+%+C}q{p!EF3z39`7!(}i7wd>CeE(>C z)mZXqAamoGQ%vAXqGxmc(%~YLs}yYKR}3A2-%`#kH0BzpC{37?+B?Sxqy)bJt|-^S zFTk)Am=LTYV<|)Ab}&c95WW?K1yB81H4HkyljY^P?@vC<>zBfA7=B1n&TqJ&tp7GN zHq>DT^8E-dOr=u$MY(l|g%9D!H9Q`z9(| zSWyf3^hWVwqZ4CFP{Y!ur$b`eol^Z1A~AIdz%0fQQ6Z)ge)28{a{zP*cUTOid`rMj zrZQF__UzHWA4|5}H98PMFuzC?{079)Uvr_6PAW5@hseUEiC%s1gb}f-N^q6p=WtLK zxr6^@feC>tFgn-^DHVwVLl|KhK0Zsx00ZORWAp(1EUaIKaExAShoLL!%i&io?W4(K z|1)DAH>MeN|3(pkXPrX-H1?$~$Ovq7-+w;A>z6?uz$8@35tKZ*!pATwcvrvG7|=}c zGC{c$M?iw$1vrk*La4673!($}@XS|J zWBI@stsea_yPf!7_WNtY-+IfWl_osX=VcMu^4j|^3PQ$P|Y1fZv zXoMNxlkwZCHjI}ku?bF*p5TL)Ejvlktz$R*@w`IA}9xw#cWH^li zlM^`xvNDJ<>6mn9;$5k^)dj6RvwoukRA?I=2D9bJ!V?u_mR##!9`o@W&SIvLeU&7} zx&@3L#x?RX#h{6L**dg97_(U4>K4fdYejs7LcPi&C(}Ib-I&FCpY~XltI~6)nok&@re~-@#1C?ofSx=WKj(Nx+Ze&mb_%< zNn`*AQ)a;dg%z$jECe|lMtHKSKw*#;>uLPD%|$c2#SK}d2$-gHt>NHu9W1Av*@ zWO|8DVyF};UX>{n<9(F|GU3vncGWx1)+7p|A!VTgRD4?qJaITEbvz;H(0GA2VCDO# zIgSS*TmwZ$F=0UqMHQW*7XsuHE|T-vAWdH=ZzlcmVTlKv`O+}wUL`6Lff|4lu0<`R z#T}cVm8v%y7Qy5_gIN$xduiE1#4KO9BSE-xt`UwImqU0628l%L#-Y`9+%6C z^d52aB~?MrAM}g~m2D|5*%|qSYeqV1_&tSga z?;IHD+S_v=-!nL_YIWB&UAyyszQ4b>e_U0^&Ys@>1D&w;_wMcQJmABApsS~Iu&cLc zT-Em8{{BPr{K0))0|kcu{0oP=`tt*Rr+?;It$uI6zcW9`Tl2?N9b4Al|BLtkVgzT4 zxy-!MeAs-)jJIdoeRkEB&1=`Mn;-F|L~J^D!s=6bHW_Oso0OSk(q@M7%yg46V@=j9 zHWg->sWfMrG3IPjWzNBOmZ>&V%{X%!_e3+^%r_IvS!Rl9GpCw!2|1rXM^r_~5_5`K zN{p?gh(wWrMv@t!si_dB`YgBB0SC4e(xnZM{4B+ffYz{)VCb`JKJjnrpiH z2ZuVldFB50ot--mnSAHKArO$Jnth%9yUpHSy)%H{KwrOEoj=g)clY-8`T1+Rkg&bI z-P~$!Hs`O|xV2;3jzEppY+en$C~$1;+?(IniR6QAK9cPAySol_0ok>?^7-BQ-6kHs zBY*9n19V@$lQ92a*Wff#YN#dVqJm$bD@Tr;g??;6SB@Mpa8E;TjCme9z8j56@$Ou7 zWu4i}a~gd6(W2sI&GwFq*R1Q<)E?xzFWZ;x&kkm<$zGeiE_;3U#_ZwjOR_J^z9Rc7 zLi(~dXK%^AF8liI8?tZAzB&8W>}}cGvv1G7Gy5*W{yO`f?0d6!X79?rFMD_PgV_&f z@5z45z15e!H+x_9liB;TpU!?Z`}yn_vJYe*3_}#_=>PtOuvcWige?E&B>2ivct?-r z*h9XWeJK0w?Dw)i&i*|6tL*Qxf5_SjucD%&s$yKl#EQukQ!8dvoKaC*(NwXZVrj+M z73~$PE7n(Rs@PU>am8g7Yb&m*$X8rl@xtuJ-p<{w^0-=;-(6K(#QeljI~SUri_Fe5 z&CbOpl~%#pqyBR&=){pDyUiEOJo|e4EBn0EeJMZvvho?h&Z7-pKr4JIZQf+FW?+|Dxqo|~+0nVvtQzd^ zHXFC^+cRjktI?uj^$l#?Z`Lj{YtJ-m7n`+9%-W@9ZL3+k%&a}jtX)pfLThFeojk-Lu%|)}de{lOQ)6qR>&hI^tH(U2!)JHhgd++KVv%Y75mZO`l@&K=`?mgIJ zHs(otoBC9-xgvIri&=G^>7Zp*Q#UXa5(hhb2CJyxc{m66<^8?1rsAmTgh9<9&0D+Q zc&Ylx%}s5FCN^yFYTM1lUHOClcG}eZfZ5tj`$jXH@6PWU^lP`#%=kO#b8Bj=_VoAC zClmRWK6S|hKArdwtxDCNE>flW^7r)~R4YRpMn|unx+>q-HPA~J@80d`>)o5r&sQVw zORil*{r%Vh-G}Hzsydy_^RXm)2D^HOkdDT!ySpmiFL`>qcZcCy_P3i$Xx8@mQQV}c z9JYh2l2<>Y*vWmnQSAsb>btAO&mZU;Jmj|o{Sys+XLmoDq@QpJR1MG>?e;qdLrbG~ zpi7yZUlqK*<(ho|!G7BHb|a5fo!wnK`#T5oE_g%lp@G4!UHhxdre1oqt3#(C8tUr< zl5UDL=$KsRvvX*0ke+H`mEu~neU-3Nr%`B@M?}-z%U?G114GMoaPfE+Rhf?6R}T#g z`kQ)(z-)WIN5WszHF(Hu=S{P=b6^nB2&*#NhI-7FzI=~aiveY}5B7KN!8gjm0{V_? z=(^P@Z|&S&WiH4c+SyBIS7p}rAKXnfIVc*%=!rVci%78(i{RjZvN6zg9nr1XykpHa zIXidl%J&W85oB^#XU{H_{Yuk3|B{WZ?su{KU1Te-mjuv*}?Pv_Jxbu7B5tcD;A#Fws1Ig)ry6SgU}VCTxgN<^@e-5 zNMU@mw_y$Fil|~5SCxs+6w*DsV&Re?jr&(DYz?TxlCLD)V$4OVm`0KE%gA?CL4sna zDM)aCA>CrkF{;29d!v9~QPS5d9}btR3aJ&}D2B#jE@0&sWIlR64i~UmQ7D;W%vTlD zEyP?*?Mup~ldl*{@!k6i7`$`E!leQBcZ+gw6sgLNg=YnR#h4>X&Gx~ro*FaQJIGjP zu#3KcCZ``GaKP-R#Z$XdZwB(a`mtvnJxBxPT6*VdD>M&#Ff;qBcJ&_U!}P^a+}YbR zG@w`fg~spe><^-&dFtwwXCcyWGo=w%x=@0-GT9NYM!}g(wp<`7De`PZnHNi? z`2T}DlMcoRWLQ^8ma?A4q{etb@W@bCe4gMM@oq&X?TSx@Ffz0vFMjk(3V*1XPa>g;p1yLCx(>yjGd zyU}pZ&;bU>e&fQH<(Qs+;Cay5aNYT9^4*P#S{5xN#7u8lz2kQ^r>!vN!>i&(>G{~| zTe0D1VfnYxr>AHGJX!*^3TZbQ)lps^!c5jsr{-Xa;R( zFJpKNtbv-Us?EK$hlBetKh;mT_jYy;bZJ86P*q+N1I&kEpAy>d@1n`v#q3w_o+@Tv zu$uQ`#O`Cn;19@{FAncl=XVb6-K%hBJFs|ZP$gF9HJx4EojbeXT-AHv0J0$e1^IlB zW^FpV2YRat9B~7F9$96uu`k~<&q)~>(EEuKZ)9%?Ow@V)DyAt059Dd;^Zo5LW?g=8 zbN*n*uEE}ZH!0yJiw6372M08b)VuTQZa8bqHl|Rn$#2r_VqhIH~f&X zpYN|RoAByC+u1hpy(l^w2N~+3fI}ZNTr)O)o$(tlq1>8yZtv5W!BMhZ z{q;S2dJC>5Q{_Kz)AlysZ0?2J)Y;Voy=K#PrUU(r*zA-kQ$sj9cJG$K554f(`h`ob zHC0tUBSuv&=6(hgwF0aBK*XJg2J>-upKJ^lzTHVt2j}+uUd_cyS|)9!0K0m-86;9! z7cHeuK9Bresyw!tb-la&0~*Y2S&Q*paBOBs0Knw$z(9=~Xuu_Fz~8cYxRcj><-v^; zQMW^kb{Kg07q8qnKze7n#^I9A{yr6Wnf76g;~p5KqSa8dG3H-lKBG2(LA}{$7cQAK z;`-F5HoI%qtk=GF^X6HzT3SRE*;-m2c|@+azIE2DJMNI{kw^60v}x9?M;^K12E8HQ zuYFBi!TSLv&Kqvf?<0@A)4to@Y2S|^HeE46S1LQ+U0!u?Ma{g#7Ek!#8N3m_sPNdO z{*B9~!$-woH#_o#`K@`%{J|VyM01ttGuJZTaih7(+;kYtpp87ojdt1(x8FaJS-F|a z6VEoY56`}T_M?@|?Tu%~W5VGH_fL3q!V?~CVTGwUTycNJqZLn7{8nvf`f&RG^rPt~ z(!WhVg#mQf-fthZPuSnur|chAcJAIzV-!sBs)=*$u;M^U*8*44;#NWj&x-IFxQf3~ zIJVqT|3%@MQMjV`M++|>JJoW3n@?Vtg6?;Nb=TPJ3_NN~2h+!@-fERPcI@a_b-|`B ztJj1RZ2or5$!rZ9Ay+WQ+;EDW6q4@o(+QC~3l`Z_3Y^m>dn7PN?mhcQyq7-C z^t@;Go?%Yy!>p9Fux9cdb2b{Qo>TLGT1Chx_qZ!~R^mH`XBD?*j;nc&;~vjFfqNo; zr*Kb#p3FUkTWc&+iDeqGOvim1?ip~MPV6&zdlqk=!JD&*nTF5Q5OXat*AYt&N$PoL z4tE20BW|tNG;_}-9?ccBaBDt#0e%a)7eUWNBF%8`=YtbsqnBnR!;Ij1 z8oV8c`tohGm_yyWdm09rRM+$yel@0b$y|T8>p5r$os~mfk&Pl;DoG_njw;BHX3wqJ zmfn{Bg7MQW_yqstvn`!5cV@PwXL$Fdzw1T3_oVMh&$IWWmlb&Bb5FX;jL+VazR{cE zt<6NdGraNH*V`Fhk#`2+GrS3=KRd(wu6Lt%XMy)_@2WAsvUhtOg?R7w^zStDrHZ?~ zYco?aE3($~(-{5IJU+Ra`^nRdxh`y+$dZ{c)0h{<+|9VJkGb1$-w<=_of~a1fD?Tg z;Wx$HSK~e$bE}Ox6TXM1JU&_c*Uhxd?@TdwoEErmb8gv%!F4C@m1sy5elP9~G5!af zyU70#?rkytn`frb?&4Zv+pLtiVwl^|{!WRKGc#rx(;2!SobmYNX52et;cc@dZq?AS=6;g!+L*hU@Vc0L2JT$Uy#aT9 z%-wc|HM?TvbG369%jY`W`{U(ml5K;Qgq+Jcc`K zi}mYC=PvSB`Ly1)$bawbl$lC-M%UGT%FGz%HfC0=K5y`iIfM9hslHr>d-gDX$y=;1 z*OA_T(~3sd&A9&%)BoFWXL&!WKX*EJk^f%Y<87>dk=`_`z9^_K58<93y5;v6?$cuK zCvl%1b63%((_|E`sv2uPfh)p$2JX+q@NRSNB7Pfi|5FU_%W(gDjQ?uqF7jW8`A6*aNemvwC{tw~)SuFf9()&yd|0kWhh-X!; zptk#$xgl@@rHSQnA+}Gj$am;-)?w>@N z;dwLh-^??@|2Eujh~as!a~JV^0QYS%JRidSt{DGg&Ryhx68D`k{yS?^=7TZ3@2yLj zdxp7<`B)6kwmM@z9=e712Hf|?_%CzeLH$wq)g|HAm4x415`J4r_?;!;_tpuIV*Pl) zxzhy%AHscGynJxKE5`q%a~Juma>Aon{`ZpJhrmad+Nov5_50B{ZR#k zm)woESbmo|cTwK!oV%F*&A6Ll_4zj3&GGv0+(rI-anFtMUyXYq?Uyde`w;F$p<8~B z;XX6weiHWrepyNQ)g|HA;hq=9rz9o+ zi(`1*O!$lA`FHME{&Bw~mj4HEzcj}GkaHLLAH)5!82@d!Ume4%Y7TWShR+P#uZg*v zala~tm)tLp;k5zxD`NOuhWnK<_thog*Oi3dToQg;N%)<(UmnIMyl$(X#c1L*_6clY zKY-T!bS;h{_#kgA=8b!+0}JSJ=Pn}h6z(M;5`|Yc7_&6SKhwF3{PS?P#`qt0@f9K2 zNVw9|B@Mhh=9XVK?&Yx@T#vgg=Dr2@*)jL+xX%fD)Gf0gpDg#X7~=QgJ}cxuT=n>5 z$#X6}vMhR~_b}n-#oUkMZjZU2!o4Eqeh~M*7=G1_a#xv^6{b8vToM-;vh z_ti1}%bmN(-;H~JjDIHXeYS|-Eit$7yWP2q7RX(=dt&(9hr2iCeh_zG%>6L#7sl|D zyE}&8Q@9U={CA9feDX}(x5V?`BzKj0U_zLG=Pu^w9Ne!ZKT-Hb+^>uAU+&yRer6BN ztug+YxNnK)KjwD%ckWpJalbK^zx!~%Ddv6<_nTwxhjG6po`2l0kLMrvpN0I&e|57l zZwTFL@n+)w^O$>HN%%P>;mS`(48M(pcksR!j*z;YyNJj2xL1Nl6n+ctRWbhCox8|? z7w*+D{>yQnAIc}Z9>l#qbUXdWy&>j)9QOq=_fxnx#@y9RBy1|Gqmg?J>FN5>q{k=E zD{-Gw;@()|zP!ZUUE;pJ#C=PN`}UYyGAO@msjs?J$L}M2UCezK?#(g$A9U`Z$9*sI zKknSY`-?MKOHk-WJoxTX1g=`K5oiP&Ryi6hx_sv|HCf6swg_Mk?>2y`Yb#yckW_%H}1|bKVJur>v8W4 z-HPNE+`D4#+i~xXx$nZAkGb!|y(i{=5cl4g`(fNy#p^%r7sT*>3ilNuzwoYR^6bi( zdnWF9_`H(vb4tP=p7$#o>VJ zt4b`>_?`Yi?NnwFtbS-7|24x5$!?GU_Uzd+XU;tBw9|NP(xgeOJ&YYY zmPLnl%maFSj1(+cO>=72lQx%bpRp6u1}keMHI^ykiNq6^ zrhQ_2dnG%r_`iI)S-hB4!bqT*X6jS~nzo>Q;=K0C=62K2Zt9ks*^ABTEoNGSU|8T_ z@Y|||pDEN?fMh8k0Ix|uoEOq~dS+p_kvmbAAnYG1mbeet~Z zMNRDs8rtXQ+UNQ0O*7jYrk_(kt*vhAvf5LZ_*2fDJ$b zhOpz<88LbCm1{fu-4@o}z4-yn&=0T?v$ucH zZ(VW$OUj+Q2mC{MR-6OQOSDMKto>10*}=XB0k+TAOBeNR)CPt&|DrxNT(MH?X8QeQ zE=KL*4TD9-85Y9ODS3L?g6W$Y8vI#jtvi1`>r7kOf(X<`>n4?~7i3s3NSkXH-?Uig zF0`kV#{q5P47MF;HGF61uKmUH0&dSm$!-MJ8sc1q@O z6SB4#yMrPUV)aERjTGac^0#{EK;P=l!Ok|e9Ea;St~82#HCkrx^Be1T)$eNZ&!rh> zXKx`EpACB2i-FD^Idbv#OFE>G!FA-w;-zg%SJ39J*|h0-TnklZwD>%Vplzir*e}CE ze_OC);6P_zpEhaiVOvI?jp2lE-#0Y48|86K!GRlXnh+OWj)koQI(^mVUzhJ^LrJhj zV0cLIA`4NwU>p{&+jlTLUc6vYnGE%5F9N7a0Sae$l#j4vT~w-HYuOsU7NKE`o%Jdc ze3@kI-Lq#PKUgModp^HEp8MfZ%M}mR_GRs~2ok=i$7v@!2V5y?uY)_};*uH8y2YjM z>i_8RZOr%VrBA1fhb4-J1AJj426V9M7b~-MYzEo5?IMZR=0i};I{SC+izl^pXi&lH zdmR28&*3RnC+v=XY9m{T#1U51^}Dsfl5Ok#dFuPFytZtN#(M#KNTnaD1?-&>5Tmhf z%MT5RwWqhIg^lOz(qSja(Oz)HS1N-lJ&CMz`=6+V=!e_`9ok;RVWv=(OW0h6XG4j! z$<u{R#mWvB|KtCM6Mx1hBkkF&o%7P4`2Yj7Y^mw17Fxx)UCra zojR7*&z>LUyhd-UJ%SEe9sL5*f}tKE8o}i@+eBDh$zd`@71ZN_^UhthZ-~vT>wBb{ zim(u_at@p3g2og>*MvvDoH|Gv&SS)0mP~Ao(ebjLy-v=-P7bH_x%Sxs+1u}$g_QZj z@^o8e+xWK0ZPVILZ=22Dx+C_bsq`yf%9a`S6ku6b&}vmM7kh-OidFL?N5*jn?juLo z7&*3j+~g^zvH`YoOx46wCQTM2&nc(&^m6iz!)`nI;i#s_0W$!s0|Se=&*WZgwy&n~ zS_zP=H+3{N`7Lav2nxb&JzCjKXUSe80^KgQ9!>+eHb@vYKekKCI8_BSPqhjYX5PpWQ$6|1~*v3gYT9{{cMKWyQ z@b4vE-8+Z+pV|AdT&!8Wam~eRHgYQIl8*HZD7I|c3hf@N!Dv_BceayR-LDOxH)`K( zFo@XN&qm%|I+Rhcy+R(-xUDHa$i7utuEvh0os34>&5q!tdv_3Bn_oXrqeuV)Oim!3ff)WU7T{Tx*89pv zh65RU+gnuE6}<%}KU_U<7i=XK#7z(r&HNYat!h zO*g62I&$O}H@OEtf4Iq*`?=k9*qX1dcx1(QSNwFvuUGtT#p*4aI@Ysgb^YdbX3NEE zwyoW`_w&^C#7!?YtsO5h=XSi*tnGN2+1BxL z^Zbrin0&`8%}pJvgCW3b&ceIHa67-9@e_PXLHdI(AYZ#Neupt%Sjk?g)n>)awPx#Q z)|uSk`onLYeu01ACpVhIk1jj(nT}O&|4855_x|1I?&w!!n&!pvak^f)&@uRCoSL7%@?TX=7v7Ze6r?^X}luECFVY<7bearEu z!u{tQ@2QiRwhV7$#-xe@y?(VZRViEWcqeYMUvS@zdliS+qw9X$D^p(NG+)B~f9qnW z?NurMdGAcU^J#Lv;>eK)1D46D6sM<9j47vPCLfuaIVBY}vhJD540Ga`aHKB94;M{y zDwUa_7u>Kyes#gm7_&NqbYqaQrH`0yTEO z6Q)h5gs7M@wct6fKuwug#kTy)swq>lQznfaKV`}(Q>v#-iNZ@WZCzL2aiQVd21DWj z4lM8S+kD#Pcw@`p<3J~8SJdCpk1^UFr&hQ8HO_h8o&8G9>dNM^wPU|gqkm@NFQtg7 z7c;?XCO+cp_d*>so_JVWkthCLhTr5$5J(V65J(V65J(V65J(V65J(V65J(V65J(V6 z5J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V6 z5J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V6 z5J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V6 z5J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V6 z5J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V6 z5J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(V65J(Vs4iNa=wu$Mk z7a8;Av2UuJTzStar)GVmxWM~ri*IK0@BUADPAcnu6;`~~&Hnj?DV$xYAXFjN%rw`? znSyw=h&059MR*WZ;?F?5Swz-UnfHmPfVf*krCDq~C}Ir6M?_Rb#8`+g%cmORDNpkKNc~K``03-bH95m zKc{iuIgXzh+?&Vqb2|653H;3Dt`#xM{EInX#2MzF&6`Bb=Kg^Q-+V4JG!df4d?35< z6o^`GN7O-FE}tCtt3}jvzemIz?tc)`U?$jyL^PU7sb7j{GGlDdB#34txgi@81Xw<6|qJ7R&^RB^w27IHgck-4<;JMuY`+YyURcg64Jv&8JLsGbb5lzWzl zR`ctuFJc+DBhG?2Pd>|uxkE%7wWTQ5gWN3u?gZ< z`D`{1SG-BY7H&sug}6sP7jpkX#5Qg#P1(*pNyHBBTSZ)CDl6_1aWVIQh`5A%%2a-y zCx?hjO>^b7A}-^8nTY3ezh1=U+_#H(0r#CEuHa5d2d_l$UMwBFihGW9u+#jy;ye*M zO;^R$B6gWGvu_r$oBOjO^4$Gr@Uw^eEh6@EpCV=4$30g>m-%6Ohls1W4~f{%{WcNZ z+z*O4!2NX*J!Xpiv4~#tFWFOkh(7L1MZA#v5fS~|Pl_1e{$&k6gWSIsF~t2F5!aXp zvx}wg2hBfa&y~Jk%YB>l{Sf!f()a7QzbN8G=AW~dG(cQ$CfmOeaRc`gB5vef-N?^P z=2sOj7jc;TEh1jb{caI2;jU=n=cU|>MZAprN)a#TzD~p|xW6IdmE6=MV_s#xl)Xd5 ztIfY=yH%xb=Kh?j)N8n>xA1cd_xY+)ujPK3h}UudM8vJ!yBG2EdhSO={2BL;M7)9f zzeW7H`9;N;Ga=r{eMrQcxL+aS&ALUr#f+)=fQYwpe?!Dym|^U(CKl#M`)! zh`8NkQiqp7++n=bheW*HEX+PC;vL*IOZj;x_o=P?{3Z7XM7+y`WMhq%jB zR9qzD?{up@c%K=YdQ!yuxld8Ua5s0eh!1dIaSlHp00)PxYs;h@eUE6;Qj{@_nCY}rUT;dxgQeoN$wx6 zI@Ia^L_4uW#DlaPhb+WD)0W(rg7_C2gG%#qkM3s| zuiWC9FF`bl__E2_vF289`oEbvJ0S(}@219%OGA9c%(Y!2{=@k8UJ+k4v+Ykre9bi4 z`5wgAO_NPmLVUx_vHvy};vrLSpA_*;(_+_;gLv4SVXq$#@rapa-yz~#W~Qx~0P$_J z(B3QJQFFTWCqjJ3oMt;jeAi63&66O$XXe@aCPRGRG}x6>Abwz)?Q2B*&@8h5D&j|G zn!W8*h##9%?d{Vbeqy?9wW-QZf6VN+vqk*WTy0+{;&IbuZx!(~v(J85#LvxM`x_Cz zFnjFAG{h4oZ~sQbf12I)A4U9^*=2`3h+mqW_NpwzuS}=CS;Vi+RrZAy5dUrZ?8_@5 zeq#>U>M;<%HMx{$-kqKPKW2UElNRDhb5ZJw6vXdLbLzb!o-%V&cT_<9-pot=Qp6w3 z;?#we5J$|~)U9J6j9rsDrwYQ_rK!)0NZB(}-xiU!=coFrAw0Vxb;Wpyj9rv^NJQ4Q zrglz*sIco&uNF~hm!%e*0x`xeOnpK`m7Sh?-4uwic0uZIr$SWQRjKz)gBWKUQy-iT zG2X6By=?}>1lyFlY$n7+yE*kc5vSNqsb#YuCfSXt0TGk!1*!Lom|{1iek$TryCk)& z7GkRHNc~M6#58+$>cAX`>9#%fQ4y!vw$zjch#B_0)De&#>?7q};5og&;Qa6ZLZnviXUPPPSl6peK+4ka8%{dU~*oM?X5$DX&ntq=BaB7i=cKgB9gK3Br_TJRh9z=)zK&m$bvC`g?`m%^s_U_cg2@tF8M^o<> zvBrKZ)iDubt^G)9!X$`w_T#DTlOfKxZRxD}{MhO1ZAbbyA~x6+>GLhb1$J%vMItuZ z4e2+E*ksqIUz&y3Y?r4Oj)B->SElb3vDL0h|3Jir_JZ^&RS?_k`RQ+p*ly2CUo#eB zhh3KbM-dm<)#=-+AuhIS(qA42afxkBFPQ-GJi9Kv^Aw0n?Z?v<=BeuGm)Vb{=Zbi~ z{b;&Z#O3y$w6PE`updcRry#DdA5Nby;!1me`r~PctL$gfKg>XM+7G3tWFdCi&!q1j z1F_3~I{hmVyX`-uFRFsb+fSwcO2i)f$@Eu6?6sdyZyXD;&wem{Uo}LR{Y3hUBCfXg zrN1I#zx_b^Q4!ttbLp>+gE(OCPMh%%J@)U@w@iTOwP$$a%((H>`|K?5(;{AIXL}#A z5dC(h_qi0rfc3rZ3W!15?@ciGjh{YbU+8TTagDv&dyR!SXuG`sNkLp|_jzwgLmaaE zy($mlI=k1KB;rMOkGCiTalOrZ+p`ci*xlat3Wyu+F7J{`h@0$AZ_yZt!}cm~Y!$?d zZJ#$F;w84%`-O;?+AF-&IEa_o9`EfUUTzO~c09x@>s?94W zPJg|9)Vo*2pV@DF|0d!M_7U&2EX1GNZ+Yt~Al_&n_TEtm@h1CCZ|@k0H`}jxe=!!~ zE%qDUylRNI+OK>6H6G$G?AN@XO@O$~e%1T4Nf2+d|KYuEGQ{onA@91W5O>(7Ovczr z)8B3zGs{K1!!~5zYa!lgJ2FQ^{H2|fd43AwUA8{+mm>bkuE;c}A^zI7XI6@Mw>>ZO zHWBZ!=Vm@F;&1FZnQw}CuRS~SOA&u-+cKwk5O><;nYkkVpFJzHPsCkzS>`4Ye`i}W z4~lr7U7Go|i1*tinQeYHKsE7V$B=GV@?H#K&z-X8$;dd##^2BH|Nvc4qzri2Lk<%uhx9 zyDf_a_3=#L+n=;=K@elT3X1|5_w7n+tQ4yc9*Jqv(@mc$d z%=8q*=j=-}7l`=0J)BvQhWJN2l<5-j1$#s0?=uizw1b&N3>K$9U0h$n$y_Gl%l2oPUyArQYqOKm z5dUtEWbXAKzGDB7`G$!9u)ojD%|LwBn(PfCzGi=#X{mttx_v71xk`v{*xzL?7z6Q; zeKPYw5#O}`lR2#l;$i#a%wZ9a*l%a<7z^<&`;*MQ)ezsdk7ibmhj`R}EAzkvi0|0n zX11LI@m>3y%*RE1&welCPlEWq{ch&HB7R`MpZU6oAKD*gek9^Y_D30S3dE1?<==lra}DF{vz`W5s%wPG8di(@iY5hnL9-M-2P|g!5I+0uuo*(Jrm*y z`}NF?vmpM{KAicoi2t(R%;+OUtnOj8s%0862OT@43*D@a!@!$5BnJu#+eq-CR zm1e@!>A$txvlol_AGc58Nlh4{VQlD$sEAMB>=4@4ZX zo3m%9AWZ74EPc_`={B`2Ytj&@)Y;kn9z;5|F?(wU!b@F{{aO|xlWNVrt^y*PTAICo z3`9k0Np@%~L}hA2_WjimV^Zt0UlQ^E(RLT`Ruqljz;|YMXZM_YxqXRChe!!XN=bJK z(k%udAgOeBcOxOvEg}LcARUT`f(Q}}{rh|l&-YI6%SK8NFj@>X32q+a)c@^dZkF2O7>UBi3B-F6*7U; za=0300cqrT)!7Ep%CRa!0qNv8Rh>vL$EY4e202=dA~MQRY8jD9j#S$NKxR2ueNSYO zL)3NR1=&vpgFsfxNHHIY;Ppzu*o%9Od}VU?PA zNgh$dh}`l=wSmYZzgI;hkXN2jGl`ewX>0|6vsLv8kzf9zS~)-gc~a$cfr9dcT1pg> zKdYPpps+lyP6vTk=vCi*A6`9HT$^oj%7$?RBs>x_)4N+Z2IT->#4H@a|C2GnDXKE05 zO(t{Zg#oo>xRWs)s4X)(oru?E7U$(;KpmOYX+hMLFF2bbfqL>qr$7`?UuJja5e;NE zr)o6NP0{BiR|X1C3=T=M2$AzVGA=08M2#=K#@64t5#@f#&i9XD-n~c6FME z0dL6e&R(LW?C87{4!kKxI%YE9E!oSN6$QL4dpg;pfp_Exrx(#m4s+JW0j=e5Cv!Z| zM)q-f5pCsAXAJSK9O5h_+Q}YHxfDQqImj7BbdUp`?ZkVszw<58QTB6=6P@G$CtXUQ zv+V11B)Z7n&H$pT+~tHDYf~HDfH>lP03U#+Ha-Am5#51<66hiCIj(Udb;_R7bzc@h zFX^~Xh~Dyn6Dff{Qn;TIedQD92+>bIcDkEDfBDFnLky7jo$bUxX}B3IV37RNX-N#0 ze>qP0F#dvfG##Co8yb6XRticQ`RYmUkx-6J6#LlAzyV15;J89w;nM|7I(Xvz-*bI$^+4`M!$}A=9Q@Cc9yCfaP+Cn_B`aWLNhJu~PPQbD6*@*~P6vtd@h_j>H-{ z(9LN9Yvlm91F=r_cRwLMk$v6tHn3jybL$bG%0BKyVuS4MenEUDd$~7>jdGCtf&xC5 zJ={FRCfVH`Mr@WJxbq!giyY}n<3?KJ3m_HoB~XI+3Rp&L1#$>ro1Ek-BUL(MyToU{ z8H=Pdz6MTb1$F?+T#JwLfnCHdAg=}Nmd)_FO+-dxk96_PM?_|0uS^j5{6Dj?Pi8`@ znwgFLvK7!fvvELX1SV%T4$2I``pm{RGCi;(v+=D=2b{@l9Fl2)E1B_)M;gG%VjPzE zeC<9k$r&$0L&$X7P%FJSy2!x1vSfbpYjhq!?SjiWlv=z_*EjTMFP^~e$&9S#&W zj_Z)0iWom@1d8Gd6BbycsBseId_?>LEGA9?%Zby#YT}Fx;uAXHEbuAuEASa{4)~ln z4{Rnb0ACQl0bdcn1KWs;s8r)pDC9CiwlnGqLcS)h0y~Loz+U1yu%Ebr_8cT`0^bq0 zfFFq4c#nOYxFhq36T}}fx41^!m6^n2;+~8!qyX;A-Np{$flMwQ6AzI+uL(Q?@)3{a zd!hjGM0UWtYT!>fS{x?+0!|QyIa*vG1aO0pz(c|WEDNxJ2*Nf~%anvN6J!R$F;mHG zglk$x0U}^#m4%3)nOxqofiN>({z-(JaWazvl9?sVt`R_lS;Fj3M4H9SGEqR3SPciY&spIqflTIED;<&9 zykdo?0|8`vGnXBn0K8~+x6={X%)9n0se$a~9lHvV!yIcrBys}5G(avO zfp`hXLF5LC5_y0sL|&i~@iNes$OrT!@&hA@0>Dh7Ah3)m1Z*M-1N(?qfa63F;1W?3 zct{ijf@y)`Kmt($$U(dc6eUUmRftkRBce3WmM8=CB+3FKiE_Y9qCBvSr~qstDgyh6 zO2BcVGH{8g0z4$D0>N}ZH6Veg4&)$e07Z$KKo#OOpb=3EXiL-vdJ?Y#BZ)e|OrkEZ zjHm}}BI*PChz7uMq9JgJXaqbY8Uw-fKocN=XbR*YngKZNel*N5<`Gx#86-pF$~y83G=t)chMiP^OnZy)e88H>uL`(zr5z~R=#0=mP zF%x)5%mRX$f!RO;F$c&&d?4){$BCuDC1M%ykXQ}`vj8iA1Y#wSgIEO=B~}Afh&4bXVlB{?SO@eZJ^@A&>w%fX zr@%5|1F(ts4A@6(1dbD*1DA+Rz(Zm)5PSjH0wfS$06B;+fuh7$Kow#u(1_Ruv?aC! zJ&CV@k;D#QCb1J(M(hGM5xaqX#2(-{u@|^R>;oPW`+;Cq-~f<790YO@-vC94Z-FYr zA)pcQ9nh9I4D=+v2SyS{fSJS(z%t@T-~e$HI6)i(t`I)~kBQ?z_=~{LKpNr%kc&78 z6eoTGsu8DvCd6r=9dQQeO`HWr6TbqpiF3dT;ykd0xBwg=egjSrzXMl@i@;;z5)hsZ zxD2Ert^m1+t3Yw$8c>b64m2Td0PTpIKyTs}Fq*gx%qH#tD~LaUEyP{m0C5jELEHzf z5D$RI#6uuFJMaidLp%m@5l?{P#GgPl;xC{HVOVGnA%Nb51V$4kFq^P|6@(3JArx?c zaDWqp3tS-rz+)l^gy#UlfHXunkc&tL6el8pYD6T^gopy#5z#u!~(O4IA8@4 z4{RZl0|$r{zzHHHaD_+(JSGx=@SH$uAPtcQ$VH?DiWBL8YD9XV36TM4M`Q$g6PbX~ zL}p+%kp);myZ~$=vH}N)7l9K*HsA`89e7OS0K#(tIe|1pE+7~25>TAT4OAoY08NOz zKs(}Ppf`~Z7)|5{W)lT~6+}T`3sDF-KokZ}5U&7Nh$6saq9_pl5>O0CLlg&c5hZ}) z#H&Cxq9o9SC*u~Q5V=j)B}zX^?`Fl1KJv?@hUyKXsntNeOEk0Ut8PSdtDfpdw6N-`5yTr-9W{w) zX?0L_@&j*L6I3(eEz2^Z3IcCiIh+{c9fV{cT3P9w97Jn;sWYz#(8h{zV@d#Rt#CIv z@vaqc6Nq+5v!f)?-pb?dBRW{Q-EWBZte4!wL`Mt1aVZ6K0_G8&f%!xiU?I^JSVVLK zmJ#m*>xd74Ekt)YQFfj;tNDKxZ6ZoNp@h349iH!=tFoZ~AIA9SY5Y?I(iIBs@DBui%Uu78S zDgtAG48&L<6EO}Qo`o21<#e+W6A+b;n1}+45|e;eiOGm6R~eWB944kB>Kri*xIjz? zekb^C+$CZraD|u!Tq9-!H;6fwGHwwc0(XhIRwd&hG0&=OY_9^$x2hVos{sqFYR1{> zz(@FQvU5#fA#xRc4fq&%l~{x?^U4s5feOSDYm8NeSc)|JY6Hu#$=?vmfkVU!YrB1z zSc!%mAyy&kM`ATXjuC5sR}q_lHN<9M9kB&iPke!Wa0BtBwbI^H7x>CrZExxZY_A*K=;dtU(U?On{QIm=9fT_e`Khr|!S zJmN>Ij95S%wYJ(Dh-21psb&B_VcY8w$5Bpw;%BR=+k6&q!m8``AWkBx7x4?whd2fF zBTfSYh%?qPXAp7L8fOn7enkt15$6y!f;ewAc195wtTIlK*}!keUX1u1C_!Ab@;W7n zOF(JjGEkPdVs%sHiK|uG>gW z$0{tw5`Q4qc;YTFk+=s;Chh}Mi3ccWI`PmdB4!egtYYFr;;~g+Y$2W?@p0l$-~{m( za{WRWwriXvgl!qW5)wF1nD!g)Z-j+37YQ3tmk4Dm;|k%}JH-vcMO5B-K)~KD@)1Eh zXjCA=fJ#KT{e`STB(tSajfk+DsOm(dokrCpqU@$l9U>aJCNBVDfT={ReNIg$;((b% zJTRL`j@myYQULRal)wTa6`Hz`NC1`)sqN0@3L=f&#au=fLwM~6|)d{2?Zu6a@%#y1R@VMCk>GoNJqR3WFYd{HOx#ze!HdFj3|JpUxv>6h)ecL^0qoQQTJcpF|0SM0^aqitJHDNg#$OWq)tR z5vA?Mc5Hu#Mb%A$? zdUippHBldEOEdu55e@CaRtKUHzTltv6VMp=kZ1xdAesV;h-N5o8PObAL9_r?5pMu% zh?c-Q;!R*Z@fNUwcpKPAyaQ|^S^-;#*1(rU8(=HZ7T8X_3+y1;0lSFyz#gIlu#b2T zI6!m+z9BjRhltMTsKZ1Tblnl6D?*MD-GJl7`}Qd71n~hvPM-w2bKM|%0KXDFfpbJJ zlzg7(jRJoo`q%@k%S2yfzfSZ6ZW8^0+r$8Sp!Eka&|abL5rYu*fEa9#wjL2fQ1X*g zz);{XVi>9rr-9*sO^m<}8z4p^dl)eaQOStWb_+Y27-Pq(SYj-q;)!uUDq=ixr6nc+ z>4}LzMq-j3uQC&p?c^%`Ibe#NTBZISmWow$4sjS3o z`#qJ7n1lKA3h^P1WwUao8sJ+Bbz&_$Q((EUG1`ZM@fNzPDsOvl87vOv1 z6rz40P6J1YGr&*8S>R{lSKuUZ4md@eNA1577tn{l5%~3wagq2PX)Y5NfvdzNyP|WQ zxQvjS#1-H+aTT~nTtj;v5!Zny#0|TS^A~XwX~b3F7NShzHeeHX0EhSk2oQJeQ%)Fh z5AAWT0r!Cb@c>7VFybMQjCce@5|8b@PBifZ2bWmlPgELD`~{>S3>7pMUk3!Rl#t3Y zmJ=qhlE8VZ{?Eot_n<;>Lcn*gUQ__!x0-ek$cL95MnnMN050${>|_i{4n#1d6cDM_ zs(iSf#*Si0e;^tdM#O{=t7h9J79b>!X|@9KK)yeLd@7Z}3l5C@Koz0@@R%qFO)kZ2TY#4puVevgbDrgKYcAw*x(_d4(eL+YU9-9%l4=&StdAw>5^ zePApb-w09qy1xb}XAVOe0v{7kUkTV)@md>98~^L+CMvg)hapW>9-|V`Oy$MZ6+mQheCXGM@R>zsTe|~5d4rH2wBbD zvvLTj6))b=bBtH$0GU(?4=*ZSeS?r3s@*$U^i33K0E)SBU{YJz^lxm>2}KBL)M#h#|lLVkj`07=g739}XG8kpLHpzu`xX z!pf%8j0X4{ir^SPCmyTH8(03qhf3oRa)THT+#)6b*^t<+#L(F$-1jKQ$ZU zt}#c|_V6L*p$?gg>8CL-lxDtSw&uuZpw2 z0(8%B1$58*@T1r*It{x;ry+RdoW&?!CueQrb_whS+p%5T`ry~tEPf=7^d#}yDrHkYG-y{ENJ=Je?YHty|I1-a3Wz?M^#_14MZWV(CH5TlS?_wyM*Z=jF=h)NvOv&gP{_192cXMnOShe*tB8RZyq4x6Jx*o^X_ zkP5_kB(6xXe<~3d0KIfyR!i_V_P8sG*Gd9cl|DQh>KbO04!N!tc(|b!dAO;%c(|o{ zdbq7Rdbp!Hc<@(%Kh!2K!V@df_b@kFb&)Tvxag&|j5;qw?^7S^^*_F7-&T&i${^#t*PNZ>3`US<{??LhqH+9jQlv9V#fIi18z_6CPQca$H+ zLqJ33V)jM^(=;a5Vv}`tA54R{4u-W3QB6aMdEnC7{bp!<63RZt=`8f3w;myS2w0A8 z#-|8r&g_0-zb>K$qc#9HY)r_{09`U$_y(i=kd27aD^il|Et!T z-ga)F-qJ%rXGZyz`pxhg<~P-Eyg!2M7Ov2G9&-J&zC(dI6lMbZryD~Ey*aGw{ZPmU z#9@T!C{BRxp{O27qLO6iK|mMSD@ht=?;VQbV)=K;es-d7k|^ft7s}N?NmP&zmI)lYl;+Qi;93hxy zD6{{Bj~Mis)p0=2gr5ODrYBIcoC+Myjf$`m~V4{R?yb zju8Ex=pvv;hb2#7$=uQOndc=yj~BZ|@1E=^J#ZYRiA;PI$4Y&u_3QF$_uF#?<+SGh zbs1<&urA$)ELjf|Oa7O}v*byv%P-ka>}O|zlbMDgPYPpZZ{8h2+Hm0 zg*a|^5B|BI>(25*9xGF#fjkL(;DtO<3p_mYY*61U%uoUMLof03oEH9yPGDV*aNDBN z^jQq)zAMXF*r^S-jV#9#s=qK69rY(>Zab-GIA_8lLG%;wqu+Re@y;sRromEKm<_b+?0D$PxTI zJEHV*;a5?^eNXCK-1SZbu{kwS&M(AkZf80839{Eh!%nlD+Q2!YoZChIPMpOVnqF7A zrFvcEmg?n{TdFttbwF=vWkA=(ZPzViQYsUOEPbyf>uqHJoFVT3n+Q%e zJ#Bn2&E`;=ElJX}LX>W*kMsCwNN=+LnP+RH(FO8TkuR9NO(<7ecZ<~XX9}Wp8b*D| zH17gm5$%AjM0;Qx(E->_ya#+ubVS$b3E2tIwRd(SybkZ;ej#@-&1Ln_8{8}Ev4^Yb ziHB?IvWJ`MriWYVu7}&|nuj~;iU)tP-Bq@Ug8$&g>lu=@Sa+>$g(Z|V_Mfs6L6b)c)r2)T8P2*TIh^$ z_nSX(yGCLI^>XT>Gk;_V&+By8)kTyZWp?jTMm2PQHuYXGRh=;PZZ!?i*=JyJIL0(j zLL)c|*?(flXiSOY#2EL4sSm7U-IHE9<51wwj2iETd%G2nASW0y0oipkILap(!e;zJ zaFU!NCc597x`mV6GiGNVySW0KW>jlLogpr(KfI2*qV9XRsvdZ_rVeBD&sSbO% zrGD~oTYc-{jymY!=@Fdl{^CVVaZh=8tWsF0oaZ(_dm&HMZ4b{J-0!_K&o`!C9^k z9vzl*mi@fQeHp*`#SXg|(1)!h7(u-sfR`#FLw)Qx8gb>q1? zy7Al`-FR+}Zu~MFzs@t)a}a}$pSp#-*?UFR@^Dqv_Ha#Q@^D>M_i#hy z_i$5X^KeV$@o-zc;NgzS?BVHsXO3#@MLkgkJUnv;$?m0jz8%DCDn9x5nu zuc^*P_kAlj?_Nc`MSSjd$9@590*VtqxrukU+Ke>48L|bKMSKCwC%y#k5MKdx1h5rY zLu>;!5ZeJMfv)vC>;#$+yMSiIZs2WV4=|9}3ydfB0jr4pz#8HJu#Pwgd`^4= z{78HY{6!oBB2C~sAeJ}`6eGR|DiBA2w}>BrwZxCWN#ZE*J8=xKE#L&^kKU;{fAIDK zpLB&nPP)DEYile8oOL?QFNo4R<0;@zCO!?|#2jCHVbU6SbB3>{6W@cJ4ehYMhIZI< zZeL69uq;q8@qbj2c+St+t1CSpYQ_b(pCy_2H^3x*cL!K{DY%GA^-^#N(8sUKfWX|zcFM>gu=h=y_VhDQkz#8T(@>cbz&{zB`u8mRQNz&YP*IUULau3kw68GH=mY!M$kP~w!tU+7*vY5h)k6q@so0lgKBN|hvW6sEeKb&;VtZv;N~x>p1e zPv_o7Q+0NU5ZwuU|CPXU_#Q1a!E>!NgrA)Srez4LNJsb$V~8$?Y0`(HG7y8%;YqiG zxiW^LGKCWB{xJhV?^B3_*mp8B%0dgX5H_IS$SXjflQ{TQpZ?B;=lm})jf<$PL;%pg zJqQ9XG9(PphyHLt&kb&AHb!wvvlGb>rDsb7pg-}51oWD~AI#_p5QPvu0ippt?lFMw zO#ZsYpP4yWpx;0LJa9Raq+#M*Plde1kSl7Rw^v?O`#oG!t3BLQi#^;@>pjF`xb-f4 zTdnhON3HSj^qTO@rC^Dd>v@)for&$i(bH>>!~H9_w>js%>6a57m4_ibUE!}Ety~yE z-I*@|iSzlq^)jP!VI6%!LHMmulngwu`1=T*=Cu%X?S7ieDw(ZUfGaA} z!&MdK;hMVO?bJ8aJr6h46%V)6Z4bBAMGtq>ZyugrH=d~bUeq%ekgHyr=UG5r4LsC| zot=p-#0k0ALM$m>3mty({fwck#opjh)+U(v^-ze;#o^Wy0Jj71CP4W>S-Vasab1E@ z^$0&P3)I=80o~93nS&ovA5nU>spnL{Z`g54^Ymof(-|BnrPo{sVx&u=~S z1mMqc^||psPk>%YHu-sT@f+s9JLnVCop7ak`^*#*i#|?QlRm?JwH52 zIZ1kTM3N}KVLmuadUR@Gm_{-&$7>Y9@fuBVyv7hoN*>D)znmmdB}we}m=CV=vzdmgx~`q8`W%LERsWFi&*yn8n9C3z3+53l zXMPB}_On=R^qXs*0P9cwd1kKPLG#R9zfI=1oO%WL=WSoW0xzr2yo22pwb{c}wZ+3V zHQd8>^@)d@YOIIX1JgX*Qd2zKR--)JQ6oI~2j2&3j~C*9Yxc~8?>H~<^BsJ>7UJOR zwGhW#uZ2!tbg%BHspwuk`FXvA?s-Oi#BG0wKGbQ5g$&`h()xfnP2pz2JY@4%a5{|- zKgv(+W5>Ve@}vC3?E;opMf-q>YEc(24ACuQT_3YOeiRcgO47o10rg+mnQQTX-^t(P(6J%lVz64en8*wMdm>x3x%3pZA(e`q&N1@Oil8@L0| zTiQ9`8n^i&VHYIUQ?x7A1bw>F4bc1P`+y#}4*=aQ-2uJh`{np0`*r!X`|aU}28qoG z4>cp)YetVixL12mKv&ue&~@<*?+R|%ZGyxvP3+^q3lNtqX3PtIT8j9`G{qxVYZ)Re@3TEFD%C65UnO&E| z+I5Hjb2(oy*Raq!#>9G^ACByLo#*t^1@gi)zhSz-Y0CPy7WxHpU;dI+ustWZGqQhv zAx5As{aNlvKo1jJs0VHoper2>=t{=`x;HokdXkJqo4;bo-1e=6|CW4|lepG3aHEy} zJ)0jgE`S3w{!@=stOx&ivC>K9g>-c@d6>hS=`is#4<)>s{5iiXIUD-rLtZRR+t}s_ z_~pZPVsfB~>d&uHrmJS&k~;%n(Lv&CreV|$q6gLuJ?EzcntOZPR6rj}reP=2x%hFY zp7Z>GRQK3)RH|q14B!ceU?!l;nFZ({)%e-{0{tpFy3M@0Isr-RniFWDc6u#LTt!)_ zE|~@HVia@jCj4?{2f~ek++@Gf{aBIqFpVGL<3p6Qmr-+peFU@X&0(7T44D^b>8%@n zE;j5yk^<)=v0f?{0QxBW5ujJCg}~F>b&%OVM$|XNpXm8-lN88YhZw?gz9amS{kr`2 za8SG<_|N`1oTNZMG1r#w8MO#=L+4ry=w4kCc+(q#r3lf(?SoNAn2XteAeIH*_R{!R z9%$udUlH2z=LFiTADMWk^QO0MtPHgA4qK}Lz3cG=SkEY)0P7jWd8iw=2aut{39qISo4TK6IVN{=fte{^Ib=6`+Zi_<2qyzX;4x!swM^`j)_K zm7EWM*&LXqaub^ZGgUO70`qxbhU!CX3`|$+iO&Ml)M;WvV5&;Z2gH0Dn4&Te>jRTj z7@rjLNnny{N$d_RLVLF7H+JDEf`+j#zp*p05ICIQ*c$jqwaAY>?jn}7&cv62xoRl) z!LI`I)ktC+hH@;i9T-P^jWHch>;NX}kkB-~iVoKk(gzpe6C46wgsaDt7vZvlg4aWf z`3>aKGwNnwv3ExF$XV>oa3(&PB)cEQ0)Jr?)0`qss^wnxDY&{^&qLOJno(aPMAtsR zUFuE#Tc}HaV|W|2pJAFifIi&(fxX}?LsFv|`lxpoiS>EQJwPAq?myL3zvQRudV0H< z_*YhO7j-3V*h!VR?M!nnNt)^I3U9yg>q?UNJQMqA9-w4>(42<;xxlC$z;6W481?4x zEJYtrxutr$o^EPi43myZas>IEJmfl2BdMBsE=LvicW)m zzDhhs$+{U&LRI|vRImC4{)JrEboS8PV90fb7{L|ZnEDXGC7fbBtbgvo-*X?UU0%o> zJS0h{d7{>Mc;-&M!b{`t)H1l*3t6D+MqN+err=t@Yld@ComK0(erN_ew!iOo9+;Cs6y}NO!G%5@!e3GdxT%tRGeYyz1)-s;=TD4hlLK z-%>qbniS|my(XjtbmLP6ao7sA`4Qn~_X|uw8eJe8rnCDYsY65Hcil})W1S`qay<@} z{DffQKfNjv`#DMCze0%({QlbVtMDsLivmR`ice{=(ji2z8|gzWT#7FN^x-%|FtMrQ z&||z}#$p;PlnZxs^xC7dC#g$k=LF!bDlCpW_E~S-@pv0=M){q9{n{&sx8l(o_%8*r z8DUJ5F?iwcJ`7Kii~aMj+5aO~vLw0u#xr{aqxL&DR3yQuDB|g%WK?vLs7%4z-pqW0 zKGZ7`+pHJ8%$O~DB4q($nCk^VcT`p&mLa?vMbFH7fbO3cQH7pkoKbO1!?_wy_;oQP zIYazWW=M)q;*>--Y?m%MJD^L>0qBzb1ubXrK4++*Cc76sOlqn(q1A_@%e*gc8W5x7|c|o@uP|b z6GQwoB{58T)|CQurTpc&e&fTCv}_pD@QF!Q=};OD6CbAZcSw?`4527Kg2^g_4b&z3 zD2tFxj4B7{y8KH0hWSnP;Yayrx#fd-oy;u9kMa}y@S`dO^Lf4DV=U&XZrC`tkdru9 zgLqW6E->*R#V9|`3!$j21UunH;^{tQ*JTSuWe-6Q3Zry~Z^NO@FIm_ADh4+P6Ei9& z;U{JlI(x-nVXr-vutXVvDg;Y-Y1q$tDPWYI*nSk-qq7q_s(Prv8liEo7%b(LQ!_NN z_d9u=yxw+|a$fdO#!JJfe4&v1#92h>4SX$F&Kp6_!vc(Ar3H!2stk5V>`hx#DZG~g zmIm^A1=d0z7Gj#(0Pmt^`B6;#N+^2~Vp*WPm&?cNp`ok;=+5-vM^y+`^m5fj8r@O# z0Nv)tPGzsh>ZA6etb&P)5!}+^M1x=zFS`#$m0;9|!ByUZHaA$+!@S_D9_9y&c~}tq z+`~t~{2mqt3wU^-3VV2n{z0$sM6r|ye_frU3V9*VTq^T=X+B2dbve(oX7&iKz|$)6 z_`>eN- ztp#)pe&kFb-U}{pit-VV9fI?ncm=c%&U4-&+66y!&Jphh=Qzp%+6HGkjfghESxzgW zb#SJ0lxP*4;rvOwgPX+U;1eX@4o-7w5N`#iI=zWEgHxQTM9bi0r!=1q`9^S(^9Io( zIMJyc0W=RzaO_B+S#Z2loM;*x=X4^P1jjm4h{nM&PDMUbvQcof^DfaaILaAFTvXef z1x0XhnT%a#JuwmZl$Zc)AjSiq5#xZ3#Mt1M&gaCK;1|vp#OUA_XB#mJ({C3s64*nG z0QM2XgPWZL#6W!ga+VknT<=^a`UgL8?hyTg>zoHfPwcRh`Odc&FqP;XT)Oiz`he)?^2;e3_N{lgDHnFoE6|4@_1O8&i{jOt`UH;`b?T!-`LOT2ZRaNID*VJv za1yBdr=fe;(VyY_Ax-cGGcoG>P*h^b$AKeWd;D@Lpr3VJ6#;!DVl(ssn$6G~=qG+U zJ41AKKaG!Pl;fv)#s)IGevi*)=()kqTlC!Uf8<;#)aJ^7ZgUl&EJvp*ka)fkG|DlA zxylnPrvkx}D-x`$QV6;VM(I8zDu<$~5Y@td^u~**`cz0YhEzxGy78PgiH%R3*!($x zE}50;4rdj*@%%Y~Zu2DfsMC}0@%_a7HG*!KU!Y$_jj&@*DbDAbnEd+d&es5amz7$G z(jS=23GBrVi@j-*`>*ZciM0Lzke_1dFS&RMsy_f^Q}yS5Y^we^g0<^6hWr#=e_~cU z?6`9p7bfBHz&|@J*mzD_{hsl4?C*atWWRIF(KCFad(4|QbW4@XV8(V_q8n z+(rg(c_GhuV^}XN%KeQ`H@>K1++YceSA(!2|taWi_p`LQMw!^*5&XPRf!Et zgdgQ6_Oo{iOTe;+Y1|n|EGGf)T@dn5v&s{n7vC_YOImS^)$FSb(z?Y z>WVh&y@}1xdlMU`o57~)X7mkxYJC#fb;;dOg5uu^>^O%9yi_EUiF-XxW_W_$cT z^s8W{Z5Z{xTRU%Y^e?r)8>(GzG8>k3BC*HxtmC&!x}SacQQR&)>-_B899>|a(7xOk z&?WZ^OY1Fh4cs)|z)e-@T-}+c0Nsbv0Nsb&PusDDOx&LEv$Mbs4DqWVbQO%!?dgY| zNH^ZEi^Hu;=EcQ&ZZPUSujItUes;gWQ7UnLJ_95z&@Y)$yu}gvIl=8jJoA{Fk;VMe zmr55^Rd*L3kT=Sy_V>irCot1-)Vs)Ccwks{SD(pDQ`KF40<#0q=PeuyeNJ)~E2QpB z4wK#o@8KQ3-gduaADqVjOI4ts^`Q8x7MrRk(jaVw9(QhqZt7X5w%5YJ7`V>tL;eh@ z3o$-4UOe6H$`GCa^Oj5a-ZQa4zY1O=tt-9f)WPpnabz5&UiS{QX8=7n{B8HasP|bQ z6MsN3d-qUC;#NE}yH|3kuIH^ZX)a!Ws_WwQr#dPobU5~J4nHIe4_srzhGMGg!R2+V zdT@CiYfnb;s?}ZuuUgepoqJ_(hHyXaL-+;yRrrJ8*5>&?lH?Hb7JY{sBafrAOZ9Di_`M(6TF zc+mWpb^htvnSDs8ilM~QhZ4U)|775w%NZ6bXE@;}CiJ*7m+o-?j{W{H5hIw(k7DAH zp>lL~zZ|w%m&2jd1IJO;14oQvEnfF6mu5(nX z8|GKxSNin&<2TiBy#M*L>(=xR0V|!B9_FYH9-gSW9-eswspqBf-?csC&DylEVXkf5 zNNY?7!iX6_6fqOX5JDAV7D8$gvw@++9N;wZAv%GBE9X9ic?e;H6ju0Oz4x z2ylwZsbOPuWv5les)#8O}xu?&eH0>*L-%Adpvz!JbpARVy^$VjXP zvJh*47l}_$P7Y!%w&HbS9nhTkENq0^kywwA@x-UV24Vy76|o6vwh|i=a)J09xJ+z8 z)D>bgLLL#@5b~J#0wEC+_!7uKd<7IGwgM%H9Z38tu^k~*iLZhB#2!R7Aa)|87qJT% zK61hE$(lZcPey+cdk%;8|zcsH|=DjgmSG~UfYe1ni8#J6FSaPS3EV7JPq z${8Z@f4%T`JCzo1xP^WVS0cCo`-O?W`C5(m70Se~afE)Y$KR{*w~fE~`W)$lPF740 zp?kC;D@U?juee0_!k&#^#8EDS=wenxzzV1yBgzxnzDe~%Bw;S^u! zSB`)PI$Vbyz6#;*^AU}WlrUc@u#7a13^!82e7zDTg1<$^83{07 zZz29kq%u;&e04zl_9(|l1M@Wif4>)<%t#CKH38`dN9Qrp!F(OS-y5QZksjvj5Yl7U zGcv&ZFS#1mw_HL`^)db(rgp8Ykb0FW)ul%2PgJpf&ME8+b*rUoqiaB{^->K=$U~=Mq{Y)0&a($%@~76;W-Z1@Z^T;cxb~7JbB@!Q3to-s&CxJV*>8rrvHB!EpW@Nmc~8Y1phwn zTmKhsBX5chMnH7L9cQ}YW;5N5DACi16Mc+SVgPQyG6XkR8HQzSl#xM<+!=VN~5q?jTQZiw(D?uD=o_d56*w>j8ploz{=3Sy5@QS8Ib3HIZ51P6_3;v1v7IAqii zhm9uUdt4Fz1FrZ!j*God8ZE?WT+n^iXeoZh<=5wN<@F__jkto#tZy3cirYpz@dvIg zeu#^R9~<Uq&Y(MQ34&u6RsFH{pu+MY#AtM2H>&TPtEjFA*<#ixi@dNG1A;1kqol z6$3;%F;HX>gG44VSY#1HMOHCPWEaClE-^yn7NbO7F+t=P6GcHWNfZ{7MKLi&loV4% zX)#Td71KopF+)@mGeuP~N7NK^MJ+K;)D!bXL$N?K5i3M*pBTWk<_#76Ol*eoph zg|Ou|q2vw`Eq9Apxktpw{UTl-6v^dxBBlI6q>{%(f;=u#%U?uVc~+#8=S6z?o5&z9 zi%jym$SiM(Eb@+cLEabH>hwxvU~n$*MA~tR~aT8Zv{dDKpB~WENRVW|OsL4p~>`l=V?!1C-WK=9i6R zLD@tWlAUE?*+mwUU1bT`O_r4J%hK`#)Y2U_^pq84FO=RJCHFyzeNkFJl++(34UmoH zK-p9dl5fbt@=ZBJwvt0-8#zq2lOtpYIZ}3%qfq*2lspEdjYTQrP|5_9FcG;XA=eb- zn2MCska7l6%|)tta=e_6*ae7PjMyb|rd%fH$mIxGDLl{oCnbjBw#y|G?q zGCq}=jn8Bu<8xWq*d&V>TO=M}DT^7~WpQJdEMe@GC5?l!l<|!$Z+s^!7>8v=<9k`f zI3lYWM`aD;Ct1@tE?+Z#mapUKa&?STvc7RfHZac0hQ_b5iE&Q8jmL|sDSLz!65%>G8WIlzcAM;LMD zNF%v9%1AIr8)?ijMmlq>kHmBjaWz&s9<_x2V zxxy%Ft~839tMLf4HAX3Otx?8YXOuHPF)EnrjY{UHMm2MT@tXOWQQQ0+PdD3SG%z7;DC3eNKTRaZ0SSFJYZ6jJ5R@ zteJS|E>_#VcofrgthmdKlDKbcS*)Jr3@IvNwXB2{vNBe^szz~94XavptX?&Y2BIcz zfAN~pNYuhARU0eR>sW>A;wt=>xL&@MF+jA%^9I}DV%YY$=IuRPYt<1KYjnZ|5?%3V z!EX3X+WSUU*&V-Q>VYQ=_A<)I-bNkS$7m+|;gi|^#(Q!Q-b9bZo7+joP&wI{Ag38q z4acwS=${-obIFB1dI@J7xzSsBaOBU6qxZ{3X7t*N zc;Hx0^jsc1LM%TX|5XTm_zM143=h95frko}!cnO_j!ISV6rmb;fKV+QonFWP>fs30 z(5QX@uibV?2AM364=s@idj@I8Md$ya4A1DR5j(iL<;^II~N@ z*<5Oz!QqjNIGQFyYoc)u5r?B{ypaj1Gb42tq<#UZUPNp*gl0!*E`+{hWW{#8h?ZtU zJF}ymxiH?j(c+hl;@FB;5mFK%jc|t75@%hl&;xA{))o)2dKWEikM?!IQyJgGQM@CL z*qv}2{w}zkcvsvux|^{FPc-=v=K$x79ykK`!aW1~;3(SA7p+JpJF4?kf$V3d#tjjHk+d_!^wA5(va&#(^T(~Ivh$Br0t<&VZndDPe} zk6{h^32V*I#(8A8v%#>n)iSrFJL5wj|i%Di0F~dwN=9=lmax;TiYi1OmnJus^wdIzsoVz<>+9JJbtqgDrT&U#P$ zVRaG__WL5W{ej43_Y~#rUZS?$TfAlW5q<5xVifN1FvlJsKC=gk{q|sS0yjiBi(4RE zw?_zDjTAvON~BQZM0Pb^6jBpJMKw{hP?JP^HCgmiQ^gE5O)OH=#YQzl99A>MDK$&n zRC7cap1F|HnJcn8^F$eEzIfePAlf+}i9XIkG1d84EOr)&tv=E^!@LD@bmTn-3}kQ2h9@rspm!s6tDu;g-aSPJ<` zSW5YMSOQ+D<<78la(`HQ`AyhM@^Dxl`9oM@W^X2HuAcRi@Yi0BX7y{kxyjCNMUA) zlxFEj)2tY2nbjj5^YzGZvuR|s*(Nf^>=+quc8g45PK-=xPLE7$E{M!zu8MpS_eITb zZi;-x+#XrfJQP{N{5i6?c|Nj~c_*^8=|+_^6QatSX`;598KQQXFGTG&b42YkOGMo> zOGiC0D@Q#tYec27YD8tUnnz`_-ipd7%P!*`upjd7`UZ1*2P6SH-i@wrjf`$+jg4+(O^$A2t%z=FZHsPZ9gA*m-HdKw-HmQ(J&1k_Kf-w1ijQey zCB(dIWsT`!<%sEP<%{WOm5v!;RgM{C)r=Wp)rlEqHHaB*HH{fzwTu~QwTc;Kb&45n zy&p5i>J>A=>K`-Rnh-O?njJIKS`ahKS`;(e+7dIz+7q+TIvlge`Y~pSbv$ON^=r%u z>vqga>we5?OU16S0K`ox~L2E<;l#>D<+O^p5Bnh|@+niG53`Y86QwKVp+ zwI=q4wITMFwK4WjYfG$QZ;uuB{#a=ri8bvrv6g)`HekoaMcNtSQrRWq66{iOY3(v` z8SScZne19|S?v08FWAlFvfAC_ve|v&vfG2=a@Zr{Ub08U<*}#4<+W$Vy=>2o%V&QS zm*3tUSHM0HSH}J}uA+T3u9E#rTowCtTvhvgTn+n5Tuu94TrK-iTy6WWxVpB8uV;tH zH?*VT8{2X5P3^St&FsAK&F$jxE$s5~Z`ifsTiT7|-?E#=zhk$KZ*8}aZ)5k5?`)5b z?_y7lA7syrA7jsrA7?L$A8)USpJ;y;KiU2|eyaU*{51Pi{A~Mj{2cpU`~q7f|HxL! zciNH3_t>eD@3k{0|H00g{5Lyq^55;E$uHU^lV7&$B)@96PJYwwll+!FEctDFbn-j) z|KaJJgCtv`tzWq_^B|9^s!?s*J#CC_+qP}nwr$(CdB?WxdHcOD;){thabvn~SN+j- za<8?2Yn_FjU->4_pZvJzFMh`JH^1olmp}ECq;H;@WVj5;-F1Nnxa?At%T3Dba!Hk4 z-cl`>uhhilFLiPSNZnn5(im5WG{cogn&T=a&3BcMmbgkuD_muyHLh~f23L7$m#a9= zLnUz*DveV|HJmHz;VjVrXP^2wFEqvJumwKtvL((st#GnwjsMyfCx~|Vr!P(k{c%DV zfD^$$oErw&M%o6W@*jq(e*~)ik@%3HQMLv6oUG;O39Q4fY{EwZZNW$WY_~14?Z$sS zfKP2XgI~Fe&wBoXlg2mOepK;?P=OytwS5HJ9*^QoaSYYE|%-I734pxc(`fXL2hBD_%_ZBcQChi*Y=*=v;9J~ z{STEkg~v7(p4bd{jv1C0HZORI%>FAR-e23&;VqJ1ACT<&Xe$F>kYxFaGwU~7Yxs_{ z>Tg_6{K02q|NY;`Vv}V6WIa%_7Z^DRoE!#;Tn3rk0F~SVK^}lco`XT&f|L9NHzIIO zaKjm(49)=M@%*oi=YB()NLu6B-<#$kLum>bP1A99$idkmmn@)p$x>R9ET?73T3Vj$ zrWMIST8SK`Rq<*-j?-4;9BoZ*({|(mZBO3O4&)ncLx6Q6I_pmCtT%~deMl_pN%FA4 zq&OQwO0l7&IvYdkv$3QJ8%0{M@uU-*L%Onsq%T`chO!l86kAE=u~lRZTTOPcHRL2) zPj0Y{IS*}=i_lHE1ih8ZFi?2~LzRy(M)?F26&szV5IRc%x=f*T znZQg|e>E=+QS;FlH9t*J3(&%9 z30hSxO&h5dX(zQ39j;cU6V)nonp&04RjboQY7M$vtx4CY2oI}e2r^tmwpAjgtuhI+ zRV5+#NsYtFKN&xz#nH>*K|!_zEEo-LrS^ zb^$DQ5j@ys2xV6w2FvRc*?*AAZbCVB3tF(-Fo@lOIqWWMV~^khdjZ$kD|p4;!f*Bt zB>n+({t-g>XUO1RpalO0mH2n4&i_CI{uf&Df6#^7Xg^Nq2o7`-r*sZi=`ya--CUQ|?Yba}TOYUeuJlsfXlCeIaa#OlMZcaDIE$J4y72PAZrHABp^qky* z-j%!1w{lndLGDXGAu|6}9!h`9BdDZ|q?$5{+Lh5XTp3GamGLx5nLx9ZX|%jDk5*Jx z(Q3+CT3cC1J1HA!cV!bDqim%UlvV*QycH^~&?pF5F1Ij*nRM}5YDF^5o zHc)M>l}cC#RcAw0CmXH$u<>dzR-=TlnQ9nYp@y?PY6Lr`MzS+%EW4y8vb$;$d#>hT zKhzZVS50HyA|0c$87xI)V)`&Y%N0d1u~rnbcg0y{QG(SKC0S!pp0yNJSyxemjSw~2 zOi_z16}8zaQHSjpb=eWogdG#j*h$fx-4X5CJ<*dr61~`S(VP7d_{0EhF!R<%vKVbN zOV!4(ENv_+tW88Ddoru4O<}dPsjP`MjkVOKvv%5S)=its259rxP;EXNuPtCxw1sS@ zwvsK>Rec7%P^j{JRdE8I)@V=QyVEa6{qAhTw$^jaM*qUeB<2Tf>bHFueIV!-r2W z0{J{6h_5n&`8FehA2K5OIU|bSG~)SFBY}T3lKF2V54V}A++k+$WHXcJnpwP{nV;7) zi}8kLao)u&!AF{<_;j;0pKF%k%gwTUty!LLHY@O*W+i^ytimswRrw9GF28Bk=MT-s z{F&K;n^r6Cvf6Nes~wNA+VebC2VU6f$SYZ$cnzyFZ)$bnt*vgni`AX?w0iJcvM`z4=(H51(Z9<#PVNJ5=d}!<61R?9z9KQ~K+0mo%q`AEw&bkkWtdgLr9y>k|kK0Av^Kb*xS%dMp3 zaw{eIyOoxr-O5On-O5Qd+$u=p+$u^l-6~7#-Kt2t-Kt7w+^R|U-D*hh+-geS-D*qR zy{=@s*OT1b>q}nljU*rU#!?aYCQ=3Wrczb+W>S6kmQq9aR#J2Kwo*&?_EIPJZqjh~ z?$Rjt{?a)2vC>rcanefn@zQ?xiPA~;Nzx_v$*lE23sDcWO!l;E*Y%J5hua+7dj6EC>zAaseoLn7kL2dE$sR5u`?x?3c2POn z#pFa6ms4Gmob8h3{4OCEbZK%imoArf8FB@eU9RME$kkm=xsJB!ja^=H3zxUt z*X1J*a{1vEAdhr~$@5&X@;XOu@+PnP z@=mWt@@}uj@qm@GV|^rdwX}3GrT*=mAyO5HN3mX zjl8?cExmio9liU?y}kR%{k{9kle`DW%e@E6N4*Eh54;DfJ`3dzK8xh8K8xj1 zKC9%}KAYtEKAYtwK3n8dKD*?XK6~WPK6~X~KKt=HD0}-J zmh<=?m9u=0;dN53=zB)4?|WWu=X*i!>U&A<<9kIO=X*__<$GP8>w809;(Jrx z?0Z|@?|Vl+>3d(k;rmd2?E6T5=KENF>-$vxAUijBgUisHkKKa*IzWX;& zq=1Hs7SKqs2Q*XM0-7sc0WFolfL2OyKzk)Fpreu!&`Bu}&_$^h&{e4y&`s$c&|R4n z&_kIM&{J6)&`Vhv&|BFY&_~%3&{x?TFhJQKFi1HaFj%=BFjRRRFiiOnFh=JbgB{6V{k`*{z$rm_7DHS+ZDIYjrsUNsVX&bm$863D&85+1u86CJ>nI5=OSs1uV zSsJ)n*%-J{*%r7(IT5&3IUBf5IUl$~c^J4;c@elvc^|k}`4V_Y`5Smx5kW^4Gw7J& z6?9Sw3p%Cb2|BH$1zk`I1zl3g2VGI>1YJ{F2HjA)1l>{k2HjOg2HjW220c)w2R&96 z2R%_X20c}_1iexY1iev?2fbBp1-(=52EA7v1$|Lo27OaL1btUn@DD`}{;BA}pgMw? z>J`jY-(UqVp@sx&YFx0cCI%a7YOr0+2zIDNf<4ue!Mcik9^;vL= z`XV?@eH)yiehbc2NeI@shGeULAqCZpkRodSkm73TkP>R`kWy;NUPr>c8Gr>Unyr>j>(=ctcD=c;c) z=c%7U7pgx(7peb3SEyRpX4NBXi|QM;RgDbWrpAYDSF^%)sQJTos-?qrsTITas&&Km zshz|2t9`?csUyRVtCPbns`JBct1H9qsO!V-s=LGPsRzUEt7pR=sF%YYs`tVksZYY5 zs2{?fs&e=<)e-(y^$&liMuvY{9j=O{;g;AK?jv@G`-+3%e&TGnzqlM8Ant_+iYMVg;zM|__!b^2XhfLsj))ea z5iuerB37hD#ESwE38F|u9#J78MO2MQ6|EvNMB9iQ(KRAh42;MphDPKUlOhU;r4fb1 z=7=I7g1Uqi6|qEN0bv6A}WaM5f#OQh)Uv3L>2KaqMG;>QC*P88iGdF z6pqN+!acIS@QZ99q9PlKxX8vLE3%0w6WL7Eifke3MYa`?Wo}_7Kw|dx=Gny~T>iK4Mj5U$G-{fY=>5NF0hBEY3#`5$__0iI0(^ z#n;F&;z#6I@h@_mfT#&Vi<&4LQImvQ)MODHHC2Q~O&2jyGekzzOi?3hwx|`gK-7y` zC>lmB63wF)i&jxfMdzqxqG!}{(K~8|7#X!ejEUMLrbKNM)1tPEc~LvWlBk_xRn#uA zBWj;G7`0y>g)Cut^>ZJG{bxJ_=X`x4-7iRPYVMSjQ z?$MWoEBdksioPPkqpym@=xZV?`X*j?MfK?WqE7S!(K7mxXczrN^p1WihD1LTUG#ggIr@Xx8~st7jQ%1nMSm67qrZvQ(SOCiXs$twq!p*4(g)0)M&YrSLqw7xM>+TfUYZDUM=wk;-6+Z~gn9f(QQ zuEwNkw`0<^&oNor-Humx3)0hkG4ADueK-QpLROIre8?_{Y8ST|42~uzX_^N6CJvo=&p-IZ`~u& zNB2z((ft!+^zg)3JvK2;Pf3i|a}yKw(uqlW&BSEAb7G3#D=}3cnwX|fP0ZFeBj6nM^u(l^dPY($Jzr8?y>L<^y+l%Dy3!_y?0V4eLzxYeOOXg zeOyvEeSK07{cuuG{Z>*h{Z3ME{a;caohA3x)#SmtTk=rdJ9(HMk~~6BPadh4OCF_H zNFJ?sN*<$kPoAO=OrENbO`faIPhO;NPhO&*OJ1s9N?xmfOkSsdP2QmYOx~#fO5Us+ zdA93`d3NYoc@F5gd5-8+@*LAU{*FC(n6(L7ofx!aSGs&3UftSM%J^ z@8!9L*B!j>>Ywu5*T3g^fY(Evr##k0$}`<9<+bjW@>UN>d8enQyw~%me9+6MeAHW| ze9}9le9=3leA9cReAfr0{LqJ|{L;sy{Lv?+{MDzWFk@+oWb96njRPr)aWzF4FH;QT zeTr%POmP?_)oIXFFGEiCF`TKsMpUZ5Q7ARQD3uy$)JhF9x~2vjy;38MeyP#Mz|ZOiYR06r>c+~n`o@~HhQ{`^CdS^hrpAf1 zX2!*|=En83md2g5*2e3!wuX}4&Tyo+H+<4N8S&|zjg0gzMv3(9My2$gM(6Z_M)&l= zMz8cC#(?x;# z`7=%$MKVqqB{NPNte z#%0_xW@p?s7G&Hv7H2#$wq!gtPGmeY&SktXu4cS6Ze_eS?q|F)o@Tr=-ekNtK4p9~ zzGr+gNah!VXMQzA<~PHc`NQze{AmPd{xYI7{}}O^HZv_#F|#s-SuoQuYiF8f%S<=3 zU8cL)DbvI3k?Cy?$@Dd+WCoZEGXu@dnZf4P%n);DW~jM8Gu%9#8DU(5#j7*ld^c#O#&x#_XH(&K!{Q!5p6R$()+=*_@N}&0LuC-CUOQ!`zVb z)7+Z#+uWVQti3s^bv#E{XL2;_UXE_P$#J*d=eVqIIbN2U>u&|*23oae%9&S0oMK8f!3Sc z!PdLnVb;&w;Z}6s5muGFBdz{Gnon+baIgtBtLng@`*&Yw1ems%qaUs9s zh1^aX+6$GA6pf`yb%vA^y)ayBopZ0w~i1$ShH;Ek;^?#Wuid)$eA zz>LdBWVU`G`}YSKzrVKA@DF)D8@UFA+{PW*L)?))!yOqxW+oPynRF_XY-*C?)K1D$ z2dPBeNORncwLykvFtRfvkeQiF1Cf;pK~5%$oWPyf8JbDX(=75BcVj^{gJ*jLgh7 z)`;vtZe}lQLJlA|bC|UxuaKMh!CI5w$j$skZbrwa^jN$raUeSri0n)VvNK`G&g4O6 zCY28$<&c+Y%}0>-d^G9G$B_|y0-41plKFfR*}*51y?hEe$)}O?d@Z@icafWX4|&XE z;4x2tuRIYzN&*S@Q9e>Sgh?3?E#-p*sUYM^Wucf<0jfw9p^;PxI!HC4pHvIRNVQ>> zR1a22P2jlH3SLTW;IGscxZEBDmcx{lJ3%M8GxU>tz;L-2jFNl961fj7m;1tg>_9ps z_lN890Jtd+#NE>%_#zJhLm3KAWi&)8V<3+*7P6FaxOW;46_g3kK$(d9r|HmLnE_*! zSuj=x#bv5KwS3yB_JCss) zKm~OdR8eY*sLCdqv{Dbt)7Id>M6LXo`y&2 z8Th821xuU*e{mi{#07{Gmmoo0fmCr7@`-CuSX_s)0*O&^3u=lx&_LXVCgKsa6_25_ zcnaOcGZ-eG!#wc<)`*v|L%f1R;tiY>ui>nC3)jSZxG6rtYw-m>im%A?d;_9=2ci9d z0PQEFYrmj~_8UrSf1tAV52|W}*4BVF)hKPHG1^6wXg5u!12mNm*AzNhv*;AfPG@OO zI!|+>Yc+RzRP&&hHBWj^bI})?H+`>p(a)L>{iFF)OAn+TdJqlNgK3x^LgV#NT2K$8 zHT7`XT#uk_^hnxGkET8JSlUmIqa*ZqI#y4h)Ab}eQ%|Og^%S~F&qLSgIdr?8OHb%| z>3uyveXAFs|MY^?WfZ32MiH8B6s6^i;Ksuu+ztH_FjRMtSl}5rE>d6X63wl2mipQ*e33-UhSXqx>y%|^~Azg=Pl?RHku?vAXF2diQCWR2`D*2eC|y4ii$ z0J|?6YWHX3?E!4AJ&0{b9_T3YKv$3ldSuT))+ZNPpL~ouiZIntf?3G>yWO%N#KhFP{;&zjnZnv15+im8BJWiI|3zipIoI=Rqlz02iD!ct; z)!crw)^2}T2e*H$7qU1*ki!{;9L^NvaAqNgv%pQ~YupUJ&CTTd-Q4+6HxGW%&6D48 z^WrbueE1hPU;fk0k6Xy-xVv{mX0<1>s=bh2?T`HF06eb-A|o;k`H5>v$#1vhfL{tWJ)jK#`q4NV~=ce@a)2z z05ZwXY3g=r1pV!N_8aKo(;Z zvKZs#^{@e1jIHuU*d=eq^KuKElD8tWu^rFL9q?G*4R7Vc@J~JhZpdbMAe#}bT!9Sb zKgdyTBCl}^swsD%t8y0xDfeNx@&M1whj?Z_#xwH?EK;7rQso(JSDwRR$9p#?pssDt)46(${Jh{ix>9FKRCRiF}75@>5fkqz+M*dI}_uLq6xhvTGEH2HT@>q(m$d-m9>skXq~8~b*64wHyW$; zpvhV!y|YG9;Gw%%XF50oi5aG(6#!1bd!FQ?$K}2L;7ucPQODh>v!pM z{T|hfht%D8M1zedG{ksHK}a_naQjy-toMW%KiGPV1WsXc(#Ay&X~m=$##VWk{LS$W4XR>g6g)pVR< z^&Hn&BgcK#%<+J=ay(>R9FJHJ$1~Q;@th5GykO%UuaLWa&1N~?u!W9yY^CD|TkH7A zHamXdx%?Z?ANXy-j4uJ_pThD`#%ox$3r)8*Y1fh}(Xi>UM}1 zcRR{UxgF!>+)nd~ZXB5_m1s6W44X!LY&wauxkxNNTRs6#%?wn0dGSH{`WMvUl ziA7Nr7Q;MZaXd9kk-x}z*+_LlNljvqT9_}ajTyo^$XeCKY+yZ71CxNQNCQkFHX-9k zQ_Sx*BWp1gxQn#F#9vEH`L)8dUTgB5v?T)1M;-bQC-fyQz^o#kkNz-_q{ARQZ^w}m zFo~3dDWnmei!EU~X%92VaF|KP!Yr~BW|P%OZykoY{KgfRelU!oIk*EAa9kT@b|mAdLG%0uO*ZJP*P=tpfcNGTZcsNwy5m1Xq zK|LN1O;KNV;7QP%=YhUF6$bD$7{t?IIM0H~JR9cm99YBi!Y-Z<4)X$Vju(U*yf8fE zRpBYG4j*_8)TcGUE;R#p)R#U|2h^pLAyt}+*L0{P&43!xOsFT#f+o^z)TeWxw=@ri zO7oGwTma*xg)l{0gk^+FV4k!T7E8-ut+X6ANh?veuElFTT$VP#8)+kQn4936v;}@k zyMf62@H&R)_Hjs-Pe6`*5(>ztk-ape?np97nDVwvWlYOrO`HuPCFu3*-bI&XvI#aD^5B`aifbA54s#V%QeVZ zZbQy;x8h6pD*p765`e5$AhKG)^n(&g|0rQp#xq-2Bd7z<>_B8NQ}N8sQsZa=HJ%nz z6KEAR5t*$dWVVuNQ#FG&$8)@^noaxTSw0lc^6|)PPQmkhHu9Pakk?$N7RIYJ-Jo`& zThuN%8+4`n)gJVm+KXOMd()e0UwU61M4zgI=__?8{h&^#pVgW4yE=>hQ|C}2=2E+u zM}5Qs8Z8#mB(aEQizPT0ETtvHa#~KTpq0dST2<_(b;KUpNbI9+#bMe>9HBkLF*-n; zrX$4#I!RolGsI;&M_i!`#51~ByrRp+Yr00fq3gvvx<$OF`^86kS^T5d1Z6h`L;g!; zpM*g6OJka*GY`#Rewv+yYYvv7xv`R3I+kYUXH~Rdx~7dcF@d)-Deq*;yqhU_ zf79S|OcQx9cfQed@x7)OKV$mvE2b~MW%~06W&nR-hVVCL82@TU@ZV-6XI2bXtT^tl z;<=}l#JwyJ9&BasNGp@4TiHCHmBWi#d3k9oAFpf`;?=F9yslM(cehF+8&-plvFh@P zRz1GLs?WDr4frmrAwOU>;>WDU{F2p#-?y6a$5wOx%4*5qBZKx0`Lo~1o>6;8ZrD3< zcY9~LNASOZ!;eQpzBsFgx2APv>T&E9M%y+4^9E!5E~XXW(hQl=Q)8clJeZb|gNGaU$j;Cm|6% z1u5vMsA;F$u9KOzyGTqw$M%9(WS;E{S&Z4pB{m83vKlPI9PSER5UjMt!YW%{SdH0+ zHMUZ)+twEL*gC*I>;T)3*FoEGID+}xW42jv+_nU>li}2JvJj31JqAXLdYuoumYF zC*_$psmgHjV7{aw^CQifKk3KXKo1QAww~{5QgV%G+EAK$XXUl4zf7RL&lR+ zERkGgN#p@bChu4ZvGY{)bJIyS&mhHkCaJ=+NCTct+VQ-kBhN>A@&cGqC`hL9qIi`c zn>jiVybL+Y%aTjH9J$LYkl(x#k)_JSE>*#dLRI1;RU=_ibrL1j#H%)D70@q`8j-0| zQ!+`M~l{v=5rKr-clq=Y=2l#)k~^71HBQ65cd$>T_4c|2($&&O=#64G8?M!Lz%$slQQkv-$a}FmW*-sC zA!5hur3e=7Qv=|Z8Uzp3V0fyA!Yef#KB^J$ zSB(TJqR?lK26qty=^_rYMLZN22~a^KK^2h)z2#K&meZh($bgO_2l|R!7$ovy9yC9! z5CvhYCTt?S%jJH#hA-lg1e!mm`h)Vx$fndOkaU}BJ3Z) z9903#Q5CXnz`N5%yfbaZJJKagtKY(W_iapWJwS))c+0dM?Z1W|A$Ep8|jJ(i=G5XADsC66OJt+5_Wb3Vpm5LHiATxE$E}2 zM<4AaHi&Ta(gM&+%YqD21@e++ke~EIU#%Y$CPUCqTaA9&Iw(apL20rT%8(uCt?h=& zBp)31^@2j0v6;eE^o>lnaBMqxYS za0oTS2`0li)C^ZpGu%ea@Q4}kgIU126WmcZ1aJ?C;a;d0A|RQ^LK=@loe&S@apzPU zbwMN41szZmOyHR?4K=|m)CB8M3vA-~VJqr^ou~))^Wt!Vmw@xU6kOt^Q6H3rN4y-o z;N{^RuLxgwW%$FZ0F$bMuT&i(rCN|K)qw(1T___pfC{*qs*Jj!w$u?dLTB{vy23=M z2kx(W!vd)fERp)cPH7i8-xNa7!A4Ijymn(;A06uJQ0*nh0N| zDd3KIDqr;S{L#ycL@zHIy}T6k@>0;t%P%j1!sy>sM&GVB`gTpww;L?)go*MVm?iJW zY}NtXg&jnFa1{2U#yEf);|OYuQ>ZJhpsu(jUx2%)D;}e+cqw0o_wrTviu%GG{XJjw z^!$~3xFdUjdf_2zg(rADg+l1%6+`V%UHJ|5lt0i>`3pUif6yQESd&pd%u*z}SW)Ok z)DXK+I~-6fdIa^uf0)m@joRTJYKKRt9bTYj_=uX}hZ018qhXv}a;QOluUSf0*PE6~lD z;o627uAOQ%x)*a?ht<0Dj9QOgRvXZ3YD4r68=-gDgg#fBp*CnvnP`Qc;VG(#Gt`N* zeYChl<8Z!D6jxCrT%#%CI!zZhXqLE1bHpv0U)-jJ#2s2p+(X@PpOz61Xa(_@Ru)fC zJ3OV;Q4`b@&uMM(lGa6S&=9pjW7GxBP#3fiA80Go25rPA+D?3?9R#*$3z_voeJ~#N z!EB+kWx`}zg`MpZ7TYJBm?LqpQ^K8{6CUiEaIwe2i@g>}?48JApG5)oQxszVFrQ+g zPVh#Z;EfugfK~=IMS0AVRKh$-WmZ?K$y#f*Sy!zdb{^Jele7kGhSrqL(c0qGp2g`M zSd!im^B-MUKD{d|u6JW)Q7=?Ry-*YNLPNa|=0W`IAj=o`rLNHJtl9n0|Z~&i%*DKz_~)=2vn4zmN0(Gcz1@ zKm_W5NYnw*oTCoVtXOVGE#QW;zX#6z-Z<|ET7^*$p!0xpe}q+xM_I*rEYAM%Rym$( zRp6OcRi0~A;{~kRya;N6(x?SmqYmhZv;SbLDIbNi{{*WAYJ`@2D$f5itk!%M=1^u^ zZ81yIj?cp^%6!bBEWjMfGR&c@v$~>==*IV94&|^_757fnu+6SI&geDp{H%jrDRq&i zsD~s)10*OK;yKy~=k~_f(AET7RGK1N(Hzgw7PzBoiTx<8@GNbIttlOlwdjb=FP*UU zr8Ca=U9dr=D>kTf$L5qVc&3iU>3Vp4iK_P)%(_LrI1{4xt$ zUuNUGnS<|S9!~!A@trKdsed89gQfTmmg75Ef&D5g@zq!1E3ZbnV-3FgT72a__{w|n zmG|K*AHY{Whiu0MY*@R9XZ0oAq+PZRwOzp^^;O)UUBh>A9VZ3cZ((A32A=1$@jRc8 zr}#oV&zIwQz825(&9*nTowm35li%S_eUC)Q2i&=R#15BFxO4k#JC8~0i%5uE!A;wB z>`l96`+-04rwxqoI|OvSb_ zi#YI)lelB@(i{H{z~-?a;)xw&E)q_>a6<4#Z_o#)17DI%{4kS=-Xwlk4$cpG@jLUA zV9aKQkfJ1vl*Ip|EVhzW#F?TBi9sJR3EjnHbQ1HRgP20vU^7`Kl8*C82DY7LqQ96$ z`jTvHHp{_2v0O3~f8q#|59gBnWIQQ=ZDs|rL#zKtHk! zwv?5{*`*5hg;gaxNj0(uJovPot-K7Cp@i=xJU>PxB_ho;G|Z4@g7um^8wq zX=CyN{ms|tZ@$NO_X)ktZ|H6QLT~dQ=}Z8yn+<(U6@5(|eNCK7F=;vgJ?ZYK5AGrNk*2Vpw1NYq9VS{k!XeyC9wt5E28Tgk1*LaAv!YGuuP50UqPr z_JnMQXJjWl$KB-%atL0MqwtEHgxBOOCT7pWTXG5Bkt^^Cxu4JECVU}x;48TY-!KRN zojidbW5j_0Pv-O;7@}gkcL1o4TUfo4iPj0qG=?=(tpaZQ6U1)Xa zMr&ZkwkGtVwV)5J4gF{x7(nY{=C&RTq4i-HZ2%)^Ll{LHVFtGejH69q5^WAsXba5a zwuKqA9n7X3U_R{#i)m+ANxQ&0IuJI}L73AWf_v7Xu$vBty>tX-c1OY?IvS49F>suY zh0}B#oTU@sJe`R9*U505PQfhiOx(lHf(I1y!*n4$r;Fece6Xe!FFNpcMrJOUhro7z?ba@e|7)@*+B?qhcFL(827eE zaBq7QqS-NsWyc|&oy2_bDcs+lfedyQa@Zxv%PvC!b`^?XcDMw)4rMSuTnY2T)mZ{| zSta2;IvMZDxp+@5h`OdQ-iM3gzZ66LQX22G|F2K0H1=uL#ye_5yrZ_pJ8DmC(&~qO zRip6UJ`3;b^YMT znvl-e4bcVDds#nD51e`9*Am{9n)H7WyPlv2*GdS&ClCGJMA93VcfC zD(ov;jU7_h?FOi;V7;vfY_wH`Z8rR@*_xqe(h@zBHt3ZMz}~4*=$A}Ek7O-&PHl!u z*mrl?b`Y*019#PS6+M)DaL4u)?qT=beH*0@Y;N?CEt)>I#iB2gh@MC){cX#nf3ZjI zA9lzQ+}{H!N-45&jFduOq#XJpm8gt+dZg+ACM|{fsWf?rofS`LIr5yACogFQ@|IRa{Zt8cQ)TjnRzdAlmHedDP&3uQ zs@s}`BcG=rlP8eLGm*)2LnhCKeO7+RCTckd} zM;h__$PGR~pXmwqVLT;c`E%^PcuCgqS7ZbBUL3*Rixd0{Im>?`FZdn%F#eF&{4e%# zNgyN{_c99ZWCVmr8tN_`@?-Z!LCKD~%L&ybPiQN-pqJzWV!fhZLVz86amvh@1-%_=w18?7qmB3qd})F!o=RfTD6) zPy@E|dGgI%ErXAzQdt9tH=o8{?Qf0?x=I;i^0q z`!2@8PvkOWWfGXk8#s3Xsq#Dk4HSnHN3q6q9cz3CT-F$WNj!_Ti zs|I*aX^2x@BfJ`;U)vGyC7o?Y@hd0(Z}QrT6W1=Bh4$baw9ob&C#Rq2oHPUMX|a7*fi{WHGE)dr9o=$8+?>WEPn(21 zZ3^;8>B!M$A%|2NIi%|3ooy&iSom9GJ4U{skNXuL!Trq^fgLkd;D@a`{Iu0VmbNZ( zv@L;>>A=ZVkp6$K44#oB6F>jWsDa&cCUUb5{QSG&XWoVEjyHD6`QT^HA3ciz{QLxB z=SvXoB!fwB7DD>5a59iZ;$AWqd*b4ebxlClH5q?*^N<9dLhA5TGK#0+?_)ZdfPUyC zo=ax%{A4lupeuPHvV|8W2YGS)-7JAuDe@FO(f8Pix&ZX`wO zLDHmNq@dKBl$HjQ$`W?ZNW-wZWjJXljUtVu(WHem4m;!~kdD|X*G-y4dP`GDUuhZ{ zB+VhirMYCHG@s0t7Lvu%BJ7u2Ox8$C$a-lh*(5E)uDO+Dx3roZmDZ3G(pqv(T1PHQ z=xs_H$W3W8xg%j4th9^#k@gZ*-bYOND2b4dlQ{V#$s?a7`Q&q?uzZUYmmiW!@*`41 zenOhaPf0uZIq4$5AU)+*q@Vm6ebhH(r2LkQmEVy`@_X#9`#|Q(AIU=bGg&5oMPKzB z*(-l1hvi@7nEacZlmC#*@?UaGCU9S-@Kk2-T2`>?`3fr z?jiU45V_yC$o+ms?)RIx2~@icl6D82+FkI{?t`!P03x+V5TiXte)kFFYR@3Q_8dxU zFQJ_F3TkPup@H_{e^@#PD7&(?YoDdt{WBEO(TvyH7cSHf%Dx4&i5oZ-?P?H_R%`dep_c41>b9c z@3ov4nIDXAnDZ)25570M^9ESoTdayR1-$Pa)*Os)SLZ`8zmHiG_}*#G7i_Nc6&=YnrF1jg7>Y!v!Uy+5V+qG;C{>4)xaTD=k?L?*A)GJt-$~G z_#gY*h>t+8-z2*UpN?L?nRW}lz-|o=xDDTAx8*zRcKi~!;QMw5{se6BXK=wkzy<%d zyP^B9JCAbr;H6n1F#MH|GJ|8FA@EJ!`G zmbm7%MY7i|9(q0Ejn^xfFCZje5c>FnMW`=CWcP)OT)qfV#1|>b`=Uf6Uux0RmqxVr zr4_w=>BKl+jF{-lh#tO7Vwo?q*yGD8_W81j6Ta-?vM+~t?#nG+`tpd+zP#d}589Q# zpa}R2iB$f=BA>q{zE+})zm2HsZ;SrD{-Upcpcw2=ME~AkG1)&t%=9OT#r~0ErGJ!I z=O2wOzHwrkf4n&6pD0fICyR^zDdM(&s(9d^CZ70bif8^=;-`O}_~&0J?7$)s6<8ut z1(u5Rf#o75utMYutP%wRt3~<1T2V2uPSg$T6ZHf8MU%imd`Cpfz%kJ=a9ngj=f1#g zMTHXNLeE|RYET&1>NHS9*bU(}F1r*+9I+64MS z3u3UAV8B|DDAtTbvo_$QaW7##;VJbZ#n=$|O2fcNk3bLKNc8!R!nyNx1{Q|!FJ8wvJ(T19$9d(HgG$1;`H|h+| ztQ*ZBy3?$p2hAgT(n6vaEhdK25@I+lEk@9Ikwj~VIq3PC2i9yM?Ijk`fno_AESAzS zVi}z(*3cPZEnOkj(M@6_-6}TG{bDmcCAQFWVjI0Ew$oc;2RO5x^rhHM--tc*o7hX4 zw2#Wt0laSxf;l@xqol*gL>ymS%%(k1vy zcWEo>9_=FC$Ghht9UwiTNzxPa06qnO_6%OrbGll3g?G?vxSy&!zA5gY=7jl77>l(qH;Vf=VSjm`i5NEprwuODs&5Svpx^S!JDN zmkpLzHd#5@Vl`wZt0%iz6WPOBV%v5*IhswC)3dp92K0$#WQXKT?6RDVJ(9Dt_i|1~ zlw6D{xtXaHL}yqbmR%{#aw$d78&;GRR?x|(6lZ0W5-d(Bg&wiethZ8@jaJH`JFGmu zifpD5$5tzq*>R-`OI8xtXQd|d!{Z5trxOl8Cq4X}oN62Ng0*GwV8xoL9pM#q#@7w3 zSa)_(?a3~yz1U-LWADL?{Z{+K`xyWxY!FMQ4Q4sCA*_fto)y<7feV|;%4^eD74Ty5 z+6MSJTUZ-yD_F4YYzR29mD(<_<9pa^uwvi9iv86NFiStgQt5|THvI_8rQcwA^_#4K zp2CXh@Qd_&tcrdg?DzwG55bE+!iT$n{vNFOPc}*a4OaXQTdn^^e(E3Fs5|%;ouJ!` z@q;=?x0e9_CGk_b%+KfwdcHKCtn2(Xc(Qxo$sXz!e*&KDneOIq!IXW}z5I(F;NSEh zbbdwfXd@CnPc(d|IQ0dHnDe1kcVA2Jj9IddqO zurd6FIhOx2C&K5M!DVYU54Gm-wAMVH-kQ&|TMKzkYY{JOEycHrm$X*%O4fSt=Noyv zwTaiUw&L5)ds#dAC~Fs=X6@tits{Jyb(C+m&fq)Ck67pUMe72;ZC&IKtV{g8b(w#$ zu5s?X0S5gRk8-B)jLv5~*7*ty`Ws%<`Ic98zT>r=A9zFOC*H>SnfG;m;e(yuITEmZ zsq;7A?)<|~IREmSPKS8mG{Jq@;*-+@?#n0sI{kvWg3%Ec0`4nJgt)>*23Mqrbw!~c zEE?TlsYP*D8d1ZQ7M)<}M0Zyv(a#ktM!K?s@ya2#x^jwLuH53FD~~wt$}3L03W&3= zLgJdMFgn4CiF>Z%;+d-ySg+Dxy~>EsuCn5ntGsa76@_fa3Ei%YuCOZLzN&)ziWlK_ zbrEUTKyO%W5o6a8dF=+Gklj#}v>S=Cc4K^*MN_+(Xm58B1MF^Mklh0vVm-weyN?)W z_Z5@u{$iRvK+Lrh#X@_KSZ@zOuh>wr*G>{g?2+PzJxaW?M~koa81cvM5C3W)I{6c! zkz)S@Jg4;Vobtl$$&ZXwAviw&c}@-CIdy{T(+lT)ANWgyaJ~=2`92os`&^vtb8)UO zLK1kDV<&!e0`AZS_&ArKjb4V+a|Qb7Er$!bga=vQV4T~LIJeV4lSqdq&Fs)43WM-2 zLEbpZk+=WTChC#*j#ltw+L0JI8kyj&WFa%bdd!6YwSy{toSq92Yg6h!q@;J*gz7*5^<&vA-UL4Xd%N$ zVVv2;a9)=J3sMVbc4M$0E!iUIBdef`u13abEi}&!&^I?j%iKzi;@m!mbNda>Ya4oA z6tuiD(DG{VgV09~qX+jWIE>?DHb03D+%x1Zc#b#VIXvP5n6Vq^&rim8lQe^#*Gb$Z zQ^iBFR6N4>7>w9Q68~vy1(iZA-+D3f^*6R%&tG=bv)%W1M zKH&REx2s?1F7+F7!{3n`{z-4DzwrI0U(|od4ilzolzBAH0-C@lfniWtZcS%pH3MfE z&TY+!&xI_M2cMVq(0r_q=4S)602{0Yu_P@R8L1F9LknYDv~adhi(#j^!UO+?O(EYwvHpM?^9#!AZ#e84dV5_UR&5Ze9+HHY!3<20m2g|OIl`cdhLcl{ z2)q!YF+oy6)r=*d;KKZc+Udi5D1_P29zJbf__V|Dqsf>Nb1@@U!k^s=fA$Y41%I;) zNdO;Ko0f-fSpoB)8tH|5{UF@s=i^>~5HsUEZAva;ZrsJa{yyf$E6j^mv@JYDWs<9{r&4krrMOkfDiPd4%Sp!y=HDs+=Bi4g8X8l=nHiWfc6Ie?& z4}W$kYsXfz_G}01z>cww>@4fXF0$_ICF{vPvEJ+t>%%~#FpKwN5xhT(-{z{pV-Vo#1s5s6li4!bAoMf%UDb`+` zW}U?u)=Qja{lpE1E^Rhm+-3{J9ky27WxK^ac2qoKXT)QcES{iO_bGcLUb0W(6>~_h znI*kJx9$gY>waVzq)#l5^qCcwzO$0j4^~zB$r?((SPSVNYa?Nus6=>wiSii|<4YyZ zS4t9JD=GYlr1MLX!ILG6-;$hI)N1oblAFJjy!^G~N*i8RX~!EV?RhJuBX6s8;@y=lyqD6I4_3PKVM-4^ zUKxY$w0ulCFP~Q~$@i7Z@*Cx<{7$(h|5k3uf0bleS8vItnj(j&ck$hmQ>zc;Eb2o! zhx$m)qdt}kt54+O>Qbemx>BjEu2O2KYm^4+I;EMqUg@rGREDUVlq7YtGFRQAEK;{B z%hYYkT6Md!Q9Yz=R*xy$)Z@xt^`vrCJ*}Kp&nPMCIpu|VUU{otP?&a6QM5~npOQrn>R_Ez4>Iyxhx=+ufUeGhErjbQWZN#cMjBIK- zBfDD3$f4FWa;f!<+-egekJ`$}t9CQ;sfk8@b(m2=9c2_$Cm4m)Sw>-Xo>5d?WE4|( z7;)-uBSAf8R8vnI)zuWEhWgy7rG7E$s?=JoFHy3QP=9xw;1=gl$dWpk|h*c`8ZH7Bannxrb$ zWYuF$QG=~%Y8q>Xn#Jm(=CtOhMXZ%-32VJt$=aYMSR2)5)+V*HwM89ZZC6KId(_$1 zUUj*(UtMh-Qa4yf)NR&Lb&qviJ#L*)FIZ>PWb1TxI6PCGU2 znp4+qISuWV)6~8@otkjDHMc9ErE&#nv91s;hbvsm>x$G0yP~v`u2foOS8A=6E4|j( zl}YRC%BGEUW!Gl7a%x*#d9;15eA)$9e(kQSr1sENO8e|8qe*r-&25+0g6s-fYP+Hq zV^`90*;TZ{c8pfiuBKJCH9f&b*P89p>)UR6b`JfLol}2k=holbdGs%KUR`tN)1B`8y2o8W z4{;aNBiv>5D0ewMqr0MB&>g48xhv~+-Bt9K?s&bcJ3$}luBH!j*U-nhYwDBSwe)4~ z#`;QkQ+M8Da`V)5#{h7O;{=wZ}mpudYV9!9kmM2l~;2EU% z_YBb|dxq*WJj3*bo)P*oPm;dIGg9B=8Kv*@jMh(i#^~ogWA&?^ar#Zqc>R%Qg8s}i zNq^;;tP}5ioqLz+PVaI(%)3U<L)>My;2^w(ZyeDiYSuNUU6 zPc~$qY6N_mk-?`MxqXIF+-Dkfd`_dG&o&0}^JO+(`LY<_d|8cOzHEl~CVs^*1xt`C<-mBOdSHUl zATY&f8JJ-t24)$P0<(>Ufu+XMz%pZdV1;oqu*$d^SYzA?Ofwz@HW;r0yNq{%gT~Lm zVZ#x0#887y81A6+M&_UkMv0({M%AE8Mzf&HMyH^w#(n&frf*q2NCJh;na!2KSm(9 z5K_#)6M z`>+G%kg(I{vapNhhOo=#v9K#YjAi*Yi4*RYi)RD>tJ{m>sWZKbvit&bs@ZPMRjwo)`i>PTei)doC zjA&uCk7#N2k7#9$j_7KQjp%Moj_6^nju>pMjTmZeh!|#Vi|j+kX#igs)yfq8%_<)K z-KrM-)2bi+%W4<>+e(c7V@-+vYt4^l&SlZuxh7h2u8)?TTcTCxp=jNCBHD1Ci*`Bh zMcd9-(b%LF?REZ&_B;PY2b_AUV5c)xh%+=*1ioSD7aIjO_WyK+SZE4)p(&JtrcfC? zYjv=wHQ^W3fjiI~dO{Cq3BBMI^o4>j0+iKAun!Z^C$<85!cI^U55S>51~vN3k&G9^ zEpQPj4zzp0H@M@Fp(|+c1WafPPG}1@mdqoB&I@|5{S{Ru$)=QU1%5&@D_POihfz7Wq5biLEDOq`Zj16+euxv1AfF#(h%B27i3L(A!{-KS(BmYdKrbB`UG|! z{b(1#Y+WKt*kxqtu7LZv3LoM+GA}ofc}a#Jkpgb(Hav+t&^zuT`*IKb)_vq(9)aO{ z3~%BI7_R4FxLzQC_Yxe}8|)H#i!97Lav9#lRR)feeTIMW1x(jBa)*6KCgugS>04#Q~}JdJP;o)f-CG<=OT96Tq_fL$apG&9c#A0!i)!^|`X&w{-qu{00Q3idD? z&5xd$g77>F!}BQ0^U~t*JxcO|v@|aS4zVzNlcHb|i_t3Rory>9Of_DTR_CQ?O?V=; zc{y4izDPs(B2D0jG~-oh3l8p+H-Wd(lJ?-O=^);Qj^!Qb9Nv*G2S+KOS%`(Bah=p&F9lk{_*#}P}h!v27SwT636_!I; zQ8|nilOtIPIf|8puTfe~#mdO(;CrNJ72$7Gl4DpEcpUNYII78+;e}*jwd7bY2Yiv7tht;E-bilNTF%4T%6YMiB_Hc3=VzVe0<5cCkad>}VK+-r)>kgZ2FS%( zqFe$yT1v8Ea%naKyIe-f<=AMs0UM8fEYsyKY@ghXy~JLYm)Og~lwQoK^kxxCAC_Jj z06!&>6;}qa*2)kzO&N-B7+bH5Ko(~tJBR%&*Of`g=1)PsW-2SBPGcq2Iq2M(%NnWk zSZj4Y>#r_AmS!O`_KVnFbv-+%?t*8so4r%_vM_BQzWvaV4#FQfgv`rf)(H9dZrXX) zU%P;8{3W&>*_rLg&Rj$;=C<|_ojQ-$CuCxX{tVv8a~7<>U|IBcEKdIbFXSU@pnqmv zbc$Sx!3V&@!0nS?LN5Lie2kayFuuaWz~VaYHT*mSyo>BcDqh=2!-pGb@ufrdBr`mU zf_#Hf0=r2{^6f?`_!VW~SCr*PjdIAlSK#N7iN9zx;#Z8u@GY9~S4LC*&FIK~Am75w zKHP%$5M>VLsm&ogzd4L2m?L>ha}@6n?_nr%?(>mXS@gf``XRp8JdE7>QGO6vl_Ta! ze5d#Y^EAI)xpf16#Vvd(T($1-AnPuVu-@=g)<>S%`o;4h$6f?E z_6pWtUKLsP`pB|3wTS45JbQQKSq34`GQyI?WaQcBBhS9xf?{I%#Ytpa&=4vZOPM0RBXvMbw>T|eZk zh-^umxaO=R9wEo_!x=BQtD11Ts*7k>4Uxsw0y|4OVP8pSQ63rfIAql;A*bHR)kAbc zRz1npTg-Cx!CsQS$eZ^UCtU+XvTLZgjlB8~*Kqg@BSgTSDnjgqB9*;NWUyC=EcPnw zBv~!0*lR^&d%b9FZxDU$jbfC&MNGH1ik0>@vEAM&4%r7qvVBNAwGWGz_7U;JJ}N9X zwkNrdi)`+TqLBNNsOY{TTDTvIHtwhBpLvG-H`rFm zW5>xnDcHL}iuBHxqP&Zw9NxuJ8Shf5ws*PI!Mg(AYH6N#jkM0YSvu<7f^VC2&%0B4 z;@yS)C3_?Vdq(`eefaiEWqb#v>b{LqE#DETvG1tV-FHly;yW%a@STv>_|8c?edn>K zz!Dg2z3jyO0qb-`;i!2PQk z?qBWT<@Ce-YY6UMCDCL#?qn-*CtD3aX)W$#>yZrF2v2Dcv4Hz zL9`6_y5*z~?tuev2ONYu;8@%NC*cmb7e1 zJK#p{f|I|GT=4_siXW0-WQjxhYZ3vTB#M6pFaHg_xZmMv{UG)EPjun_A|pAcV~`o1 z4#s2&GQ-QjnXCj~vKqPJZQxA~b2mMM``RV2CO2?ryMsI16CR+SaA*62JDZHIAzh?L zCs7Pdi!5E5aG$A)`%F9?B@*a(WQAv= zTWCAFh4zTLbf2h44~s_htY{1-q$zzMnt=&vfjn_bFd!YNC3OY|(i2}VS_HY_V(9*> zh`ewmbpFLlBXQpu1+Q#0I*7*5_Q(o%Mpn3|G=ug*FHwJKHXVijp)t~ObP=t^MwlaVpLMH|W~@YZglPw)=}TV<0%UHU$%IL!r5j;;2xu}3+O4jg^r>p=qP%HobdEj;y+gRusiD~Q7>O^6wO3QKZpa#sMAmp5vc}WVO|%Gk<8|mI+N$PZ zhtWfH3_V1b&^L5NEz54I<14P`B~;m81w085g@617omq&Aw3 z(Z;e#+Bh~{o5<#AlhG$Mg{{}7v(4H}woRMOc4>3jA@md-(bm9=!|Ml3$}Mdp?pT}H zGi@_-=vx@o4=@e}MFxLj=||CBc!CA=lel+XVWHqrBJ^aI4opf6n3T-=Z5FE!b~wP< zF}#9R^q3lW30rtayWqCFF`fN*6$fLshr)4>#!OFxUWRm->lrcAW5MBN!@D{sW_w=D z_WXEP7sLcFg6+4(@U||2`Tk!wLpjX%3TTX}g!x_-^SvQ>ybg|oczYiL4R8#(&x`n# zui;m^fs^DWPLEso)l%@Q+`-@J4Nizp_$xmn$N39q!EYozf8Z@nk-TI`Tyng21tzDA zY^92%qedG4{~10VGkhlA%d0TIcVm9P!2JG%`K^J+3j>drfd>DN$;(YMqQ@bY6s0-P zcbW@b4#;29yretL29Le~GJ^%lOuUb0W9}}(++B%zyN=c&TQF;PVb&hQti6O;dkwSp z8*Pc5x2-V$T7$J~gZbAM@7i{xIctwD(yr(s?FMhY2bj8^WF_l`w`*_kbA9j*?Tfc( zBIey7aC3u^3mSqMHJL8dWn1J~XD#hnHaUwN&sli>caht9D_&t&?P~&Wjf6?> zNoMH-DJ*>?&84@bv-Ft^lD?4f(l0Vu`i<`|Stk7>nAea z4$y!cgc%b|E6U-tvK&Pl$kDW!oE4dyoaisjMF+@v=y*9VorztwE0NdPD(9!i^plQ3R$wf$0<&o*bqUR>E`?XW939`Q z;MK3jx0WV=^REfczb5$p*6KFeLEVmymYwkJche+z{ZrBNy#PM{di4a|gl_M>==MIX zo~Iww3zVYUTLIIrgXs?f(;taG?`Z8VO{d+XdA0krkoExifZMbby1grEPte8kl(s>y zcPI3C4@RH&IBhRFzTeYT+DEzreclJr=Y14?-lx&$eH;G&eR%%Q;rYMSO!gU`KLP7+ zf%OkYFLwlZ|7h_3nZf&K1@B){4`r3X{5J&i-vP{j4?PmS-ciU1M6)A$YIKy^jG~*{ zL^pRTbaSUSGNQLT5B&L}EFXCPQsDiogZHm(lw!@m`gZ{9-^Zu`U%nEXY*ayScRbr= zB(P&f4R#J0fV)O*WB}^2k48QA$7sNa*^n`_5wpPhyTST8MM{i8SMBIu8gM%K5Kbi#UX$pQc4L_QT3AqsS zc`>HsQq1Nx&^WhXHt)d1JcYmVH8f66rXim-9s1)8M<|);2q&{0(PXY8Em?qj@Ipr+ zvKaT@WsWLjIk@Jvjv8dWqc%FH8=-T$3EAvuLAHQ_+UjUWwmW))jqVNFp&vQv7>pcP z5^`Xp$yvu(+`A{@-aUm}c1!~WF$;|JJTTHrkOy0iyZCBoq#JM#-;R6uZfK(ip^F}c zCVG-Qah%7!{37_Pd$^lF!QK2hIO>`HG=3a^VW8LXrKXIx^h` z=}ArGx-F7OozNm(=-08qM`t5bFt4X$UeCk4UIdPM1!nddu+-aWS@i8x1WOTz&df^W zB-pGJ%;|fW&CkG6e8AmT!aO!vNAyc~CgH3L*s5M6FJ^Hu%;M6lABktkPGTN6!aQyY z=Bgzdj@;P@y(}I`}5^=4>Hez7==aZ6qz&xFe^auk$H?LZ0)t==^$z zedX_oEIuKp`I)2^U$DdBJLdimQc?UQ4Z&%(1EPRN|V~ci@oOBp6n2RMF-P8f_TETQH*seWNDEcnL>3OhS zDN+=DirwSS!F0Ws@?rmY0o*kUVeS{f{)S@Uwu+;>x(tm3!<7cR#$)A*=(edu%gdE< z79`-lSq=Bin&`l+g$~R*bRu}JRdPMLUan8KgX`J@hU z8_0$wW3R(KdI~((4e(qk>N9k2J*R)vm+0DhMI$h~W3;#E+xkFDYoD>p0i8P9cjUl+ zVSmFP%=W)@xaMFJHG;lL19w7;Ed{H!9<0_eFj|+vXx#;)^&O1XFYs9$v)aO(4$)JA z!%EE}^>i$wo*r{O1Nh?@Rzc6m67)>a+cKlCIty#9XT=_e>};r>12aA+da84=xq311 zStY?Amtkx5vY7eh*;Ty)OV%r5e?uI52cGMvUK#rvsxUw1c$iU*MPPPE8;w~eqX{cy zG-cI{X6UN!z`B6Z>H|hA(HO`^8-vhUJ(#U9h9Cnr6dADL?1nJ{xv!Dzw=s$db1ZY3 zvsor{4$ERLXW326XLA)RVyjU;ad}PI~Ppp*ngjKbEu$tB{*2wz923UXDXzL%FVlnhqOZ=oIqpMm)PqhwK z*x>&xlPgXOtgw?uIBg!|bn}u?;A(=t>Za(b zZq5^2Es^_b!<)Ir?2xeu>`e zcdjJ<0ln8>(RuwHo!5WRbuHVIxNc8I25buV*;9F_J)K9|GmrtB#q-;9u=8OaFK*B0 zW$mTBqP?6~wpZ{3dlj!~W4nyKo;R^K@D}z~oS{2#e(uEkVK+G6J?N*|i+96*yc-VS z+&qMn^$6YqCvZ+)#5s8xdF3lOAFra>;08{}+c**L;>5cL*7rV6w+C?Vp5S|iT+ef; zNH6dfc#Rju8~iH&b-jGV-{}*6=4bqjuV{Lc;k@ZMT@0Kq7L*?slE!Yl4m?nCe0Tx) zNf2HP8KK?ez^kDM35UWGfj2`2QWn}wB@#>OkgV|AvXP$nD~3UzNrE;rf#ijzlOGIl zA#|n`hF(*I93n-@X?SWE;i+8**Y_B{+Bf{&C@oD~@YYhpSIa>wfCH|GH$@yNk29ze z&Y)Vf3VNO6NoSe>2DmQtn1;|{8slBj6xp6;=oV>?{XwnBOK3Ddq04AEpDdhB9@Z5* z5E4mhoI^1N{4IbeU6 zp|{|_b7(EP3f7@}ay`1;HbPt3gbueY=%3sQePufd!5I{avnL!pa1_p;7@R-3aQ@`Q z`IC>IM)$xOQh=W&1^GF2RG!CKb%7M&7fDfm8E=#;q$0nH4ub0>9_Lg7&Zz1*pK9Z5 zYJszI%;hNjb3nhN%L8XX}`N1kT} zG@V({bY?@#nTs=a9{LOxf`?uN9(pl7j;`qw=$bwQ&F4Hcp9|1@E<*FUB&|liXD#{; z*3s+IdiY=)XtFe!-jp_jo8FK9gM;)LbfD+ZfnGod`U(w*$tNg>?ju3-QK9*`&<7VJ zU&Xn6ou-#>&@9k@azX#e2mPlo^q*4DekwxusS4evHZ-2P@+-XAUegvbS`FoIIJ1A@ z-S&rem;chi@ZaXZe_H_mZ6W-(#mEyaMV4rVtgth)&BzmNL!M~6>|#6M z&+UXiw+G(bUU+l+WIx+42iO7la|hwg9fmh|Tn=X^f%*X@+c4CstYM!s3;#EJ5kcswq8KZKWq`10Svr ze7L^KaMoXet^?0)kTRMLR>rb%$~ZPb8P6ucgPQ^mZmM#LO;@h4S;|#(=3QrVlw`I- zxye>3x7ZrxHe09Mfp7PSZB#zMyZgw_C=Q;Y5PnzT{DC6zmx{{&DjL^SgPW?!LsTaZ zQ(Zhpb>s8#OlmOCs)q1vY8cP1hV#5?1TU;c@{(#4FRw=PDrzcTOHIuisAw8d)A4R< z3{O%s@-b>=K2FWTC#lE*smKATIq~J@Gu1qNnVOgHQ}gj7YJPr7EyT~NMfe4^7{8+y z=bzLP{F_>m|5ZzIu9e|_tsGCImFGFN3Ov77kr&k}@iJOv9;e0g1TBHr)N1hBS}op8 zYlyEAPt=<5(OPppS!;m~yjJ+y@&#HazDn!Lw`kq?4y`-ir}g9~wch-i)`w%`D*veU z=ijw~=+jQ*QTkw>Lm$HP>BD#teK;?xk3jcb5>L=a@!I-mUSA)FUTy4k&?oUW`egKK zPvHagseG6|gOAW>@p1ZWK1H9yXX*3!3VlAhwiohE`XatdU(65aOZg#vIkH!)kiA;R zFX|ilb$v6xrEfv@YCC_f@8s|FUGOUR@L&1??l2A_Z*`Pw#&K>LC%Dfz#eb}S`8drE0;}$x*Q+QG1Hm_>j;WdoAysdGM4>Il}i}jF?H6HVc##6r9c*eIH z&yl}+!5P|7g7B|BUbOFMo2${KaMS4|?_fa^3s~Khq(c=*4rHRM;jHZj%eF zITBt|5V?-V^qsVJ!68X%`BEK0c3Yb|%K{J~uWM&tI%^aeLnNt)sJBZ?DCsE4mEJ~YQ zMH#c3NHBYdhGtLE$m}DUm;*#BbD-#8CW>z6AdzGa7IV!ZVv{*k95;uF6mz(EZ;lYc zN)jQ~NRibVD@s}8L{)2+NU-LM+SWo*-&!OZSW84hYpLjDEfWK+7=d5+&uC-p=vo?vB)@Jd=+A64Xn_$l0=n4FbzVLrSbrMN)QpxXRQYt5xvN$Cv zzf+b9IGs`f%f*b$6zd`a07~Bb^zf zDbDQDG-n=Zjx(>c+?h|>?94Ciau$$|Ig3aaokgW9&f?N_X9?+sv$S;6Sw_0=EGxZo zmY2RcD@vLxPO@E?5(s0*(X`JhUG|BY{-(zW(>#a1$^ua6J$aMeKt51i)eC~mAS@$5h zntO=c+&xSl;2tiIa3{$V+#}`b?$Po*_gHy_dz`%9JwZO~o+ux4Pm-^=XUO;5)8&Wm zS@Ku+T-ocHCui|2#6EU%3`#d&jMB%KL+R(s zr401tR>t^>DC2y^l!?CL%5+}|Wv;KJve;KqS?Y^dHuw^hZN6&C9$$6kkguk4!dFW< zk{H&s&kn=9G;EtJCkR!T{K8>Otjty16LPHF6K zuQc~}P&)cME1msalrH|RN>_h(WstvzGT7fs8SC$(jPv(ZX8Zdq3;hF>ZT^AEE`Or3 z&p$*t;UBJ?_m5Dn`ID3s|48MTf0XjkKU(?cAFGJK1jQSes6+=QE2#rhlx%_N_+}`% z0<)ANf!Rv2z!IfYV3|@jutF&xSgq6!tWnwq)+y}+>y?3lP53q|Ljqfsq`)?1RA8Sn zCU8I*A2_H?3mjHv1&%2z1ILxMfs@Mmz$s;O;4HrL%Fe(AWIppXF^|T9A)2>iWyF)eY0mZZ@RMK7`75b1xpf;D00mzaL zBxgw?y#B%D3K@cTh)Jj8-8qA}=}dHQ&H^JaheTmtP-;3KeCGo2or}QgF?0)!T2cXX$M1Jis-m^!b%^oE~(YrZ}oOqfh2sOSfwD|r|;*+4oPk|ag56Rb_UY5zc-C(zs_Xzn0G@Vj@mBO{sb$U;`(cjG$z4%~>}X`Au8X)Cn$?f9Lu z%Q1-Tc8nl<9V5v;$9QtsF_Rp1pq<^Z16uoGqzkX&cTNgA*B+sh%$1UyjQ3x1$ES)auiJj;7Rse^vzl zd?*|i=_phF}V^oHEf#?g7t@b4DOk8Vc%yT#IywyZF^7)zr=q&zxADxfbU0nBbq@Vd3& zZ#F_dNOSbhw*Xh$5*}x3bR)Kb2HqA~=4ZJV3h5leU29U<^ zJ)82;*mFD zSHk~XMRc(S{^wc}A{L;ha05vvc9INYH_0USKnvdsEqot|7sp67ahkM(H`+;@g(iNE zB*Gs}f=&c zy&_$u*JKQQ&~Xy_?WONzmIQr6`Ux-eH(4Y7fgcKu177HE=_&!$3R1$Bv*w-9*^$#1Zd>dXtG>`K7gM70($yaxi&i5>Z6Xf0af9XM!+YHghv{s zG^6RzmzGIsfh=?@uo`W!^RYdhs&s&6-jU8zI?+W+XZWXG;h%Ox2U~Z#Pw7Dq!B0J| z^rokjKImcVi+#!c=nZ86y4VIH2c3v6wn6Y!htePLSktP*X-0Jf&8jBBQyoR~z-KK4 zpS8F;o|aK3V1M#tXzWwrtxiM#+H~4ook{zsv*-Z$utU_jbQpTrrlE&zC3@J_p@(e~ zyxHyOUE2vib}zixz3L|D@0)3|x|P0xe*Z?@OGCAN*rB|i#%TxOqaOKR=UO}MIQCkc zz`o>@G!eaP!_m7oSvx~#YUj|scAlO<2irOA5_TnDMF-n;`UGC>OL(<^;L}ocuZ8I7 z$Vcy5CjBAJu0N(_^t$L2DgI-!3oW*~hV`+GfWgMBHm}Uh*kqh2qKDdehbv_oxduV+M|Z|2PtpaSZ-@Jp9Lr=x3M=?r%D1jag{s zo&$$+E+*zYuz&MGZ!848u?TMEQm`T`px&+o*|!FNv<`o?5mR+DxRGu6GdsYI>;ea} z7aN2QfbTozI0wS-G8Ew}AV88aZ*M~Vz3X@jb@v;{k3X2coIG=A@DgowNP58Zg%C<& zq4MS?5|mnn6d)>;TAh@K<{JmSw;EL62GD#PL-TD3X0JO5!wDRY6E*@TY9yJ4pE(oy z?tJ{rrTCdR8Nuxp0kc;Oj9wfVy~@yhtB@0YfqpclcZT*4W88J*Qv;eB2M$9ElE$_?@Y=j&H`ll;ON>jYC5hO9(1G7<&ZefXVE zG0UH0hQ9!#@|kpJ-${S=gN$H5p(p=FKkgsw6rtFQ`+qxeQ;>J~g0t4rKckZGvE)1kj9J#q*!=y1x2{-#XG7i30nQx@#B#Vv&A2ZvXXuHl8~I$oG=;60>;973b5NM}qp`FIc=b@qA!H&PX=$3tt z`Td2)%U{8{e8c?yLEFebp_l%qy`Y=+g>E`P#$FBdFb#ozIvo0G675= zp>v^uu7(D>?*D6`*O5<1fe!i7ypNwaRlm_e=w9nJfK5s(%d<5{Z%?(mq$m&RqW73?~hn@=u->y-<6Fd8MVQ1eSO+a&$u!BS9 z2Q`Hs#*U67*wJweJN!;yPsd5k#9j`IpT(YzbJ*8$0ed$su$ z`AzKXNWspI+gdQctA+CWS{Q$*MPQFdBy`Lu{zCi4-e{?@%OeeEdR8v$*|}TK!Towp zo>|WTJ})cowAsK}X9s(i1JgY(CVxIm>w=&^3S;&b!OSg+XNWWaL;zrIgTJY*O8H~#{GALBM;r=z-)AsraK%}=}t!@ zid_?Qzax3PR%ddcyVUUpD+#i6jP zjtuO&BQr}zU-?Z(97}OjW_KL%?5?9D`+w}c2b>he7Cu_l-80?O6L&Vj=EUX*8`&ji zk({ICAc}yJgNulO2uKtp2`Whh1r!C5pd<+@2&kwa5+o@}P*8YZbyv^KE~0WT{@=Ur zz24tepZccy)TvXas!mr|S6?Unu!s2&@pm#>yiLZ5cgPfxVqb9qd*g}pby321nBZfJ zGWtse-&eKZ`>Iy#y<>y#YsdR$4(uE5!h2?Z^c&HQ=WzabuPhLI@&sXjyfV}(h2Z;1 zp;+S_j%RRDSkoL$6Qo$I3n_*8T=C1hO zTQ{0!9t^*CI4v-bpbg9;X>;?_@PCWxv*t70nKEz0-o=|}jQkBN4DN)!2DF%C7#-R--!!JvLUzUpbk4*S}S$JQyJnmDo@vJ--dtW|;`_+fx2Qr_n zG5o+L*yp<~?p@pA-HP_OvIFj4J7V4KBj^!2;p)z~x(n9dc13IL1`gfPEA&9??G0bA z4|<1@=p9DElPpFrFb>?uqZgO}&k(a4@Z=g}{a91www& z9V5~EjN*6C&%on*7Cp{$c(-E$dYu>WZpUQ)&h3kMl0OaacudD?wi)P&X2BPHiR^_$ z`ykN)NOTZ>-jc$`b&WiG?Y0rr)aH?aO-B|OYk@K;yU=I}mS zQp~~NjgdBV9c@eBq3!VINC&J!=t$qkd%>IFd2WWsxrO$m+h}k45#DF{nD(LD>0@*U z?F(=93A_Q^51#6i@Ko_82OW&Jfrrv#bU0?0M$!|Qc{+)ir&E}9I*nPUA2Hi>4zo<> z;S*oP4AW0|=LP$IW7cUlR_M*A*YSSKuaNjRNP82K{tiiT|4MH|IwHJ_8L18Md^f|( z-GUjYZ8Q)wL1l#<@OXE_cGmR1s!uvf$W8js>!5b|ndg&{(&FjUAFh6@!1?93{>AXFA62~~y3LN#HE zP+fRYs3A-hY6;VXI>HR0t}s)mFT5l)5M~Pvg_niK!aSjgFkfgcEEHM_i-cCfYN568 z79?E*N!LQcb&&2INVQ(*ExZSbHVBUkcoRqX0MdLYJSl7z1`Ast!8SjaFmcyn9W*Sz#kVIkPkS%LChc@BHsYuABpi~E0_PQSc`m&e1m{r z7Auim98Z@HiF?cz%mNTnAblc!!EsUfR6GK`g#foIJ9Q<1KA?Go1hq!UA!|8=`f=0R z2wwm&VYZVH!B&T!fXwWuXRkniFv}zgbQ61ur@SK^vFvAzO@tIXA~l)?3mwmpb0|w3 z=*5nwJ$STpjz-5LjC0N+7dZb7&K~3)#ZXOUTTCibUf0rvZD2NfzKo6LKWrBZT_#av&C`$|5Wr zdI#+uqXs_J#df43%2*FTBeAss zlci!5DFn_Wc~fK-r5`)RRisEZ!6P7KzqpiC3fu>ljC zWf^G%ybTb4%Odg!=OdAqX(!Bi|KnQ22m=F2TLqC3J@WL7%;xGL**-V@R5GLuR_ znkbdwsS5Ct2x+Mlc;uX7d6V=4|31KHpp3>*q&}~ak0Y$2jw8L1h8;W9vgA?FPk`R7 zvK~V}j;TXvAK?8F{Xu=o!@r;H5Wa*gU=ELvA+~+^qKE!dN5=^A1n7alJ3EGwejNYW zF`o8Ey$=R{!cmN`C+q3ExDv=<@EHocw<`*DrsES_OUN+b!+}q7EhZyCvm?Xr1u_cs zNYDj-&yZrCexu((tooAi9s~M7zdauNoE#7;j7PqsfzJ#G@ZigXekGG|?HJ&123XD>@eh%Az<&Yof$`PJdXBG;??B!IpI3lyjBi6W zay%g6A@TvzF9sf#P@R0p@s0@{$Y!K}4S1J?He?&eHzwqfk3cU0zAYh>e9ZAH3FXOl zq-R!rJt3X!;&@zQF4+xw1@Pp=O!5iG+a{JLdysx5@Q#VBx7Uvs61&m;=qpwsIwP?? z?&$P#-ANin4uXCQxRA^&P(MZ{k0W0IUxVnF+K@sv{_8O7|dN1hR*-J?#c(S8kP7%pM`u(7X<&-BCIG>d{dq|EV zVa+zipqwqFfa8O6b4VfR11x=Rd4&40GB=Y{0?#iHU6Tu6lJoy2w*#$-^oN0;$!$uj zfIb5HcJAw>8p_M)b$O#nZJxd$KY`X!%xv!^QY}9cUt-tg>{O6J8v_3Zc&~y4+MMH4 zDvl#9!1Fucvnm!N)Q_OTSdBQ2uxw!zX=U&)tVvoU-xI)V6js#IuwZ0iRgFH0u(%M< zS$O(Qg%wD9q(2ROXJHa~gyWYAvq&er7$XYtVy)Pl3igU?CZZnTc zCOTQM;C`5p0n#5ViFQ0;>Ox*Zn(K%SG_~g_A)lM7SYB2fxL+pZYf~=v`{eDyIg_kF z`kTN5oUF&wkJp{7=OMVCCS)1+30b_FYd?Jxc6A$cJ=YGpj`MN4Ytna7U(D$bb{Bcd z+svO?JK8jmmi}AF9-iKeJNkV{&w744IY$oia@~N}aTqjn`EKGa#5n5G3L43(qdv_v zU^1NQ?Og>vit6o){Wt^feSHOcX5Pp=YVzoF3|3u#3)}&GB35D>j500HlkXv$3wVxY ztO1h^mK5>>GIayrYGK~8ew?zTl9Rv#fM2kbGhpJUenL)xPZ01Rm9=R7II7MiXOO-O z@Du6`@*^th0D7uhoDPn^%^ z_OA42=#AY09ksVXs2|zRbm0o@Dh5cAGu~6)E`C?&Ov9Nu_i7&e35=5dz>|Rwz+8{#!0sB1PDLo6MKJc9)j@=7 z@eWP{l(!}D4R}Ip{IFeEDz&hvSRn&@78Xj)kr%Vl{-!wE6!NqMEt|dL{$uiV>{ca^ z_Q0QzU&M}8dc8X_Cou|iN8kbIDT{fz8erAeXp2HR0dEDXm|&5#tS4fgY?8%_HC+U6 zva(%mn?(P&nKSZM9R-BKi-4|yI1j@{o7 z>PMC-hAssD7?2zjYpwdx%zTY3f<5;I($36A2ad}($ZNp+F$VoYQ>w+ggh%*#2}7Ok|SwZ)q?q6 z+{?(pG?U{tc(4^f&j22bx$0b1&vyf6c=AEd0=^w`R#ZXYI6%so3Xy&`qTiAbQ)P~q zHDgB#@P8S2oH>@(<#-*rHLa)07`xE+Bo zpqpe0=vBZ+2VK>4!vYg#Ctm~p7H|vZBVXs~3-Ii53Cg<$culm{H+Z?0(N<&?%DWEu zyR@E%&mF4!JnsU>%&`Y=C)C#H_ked4Y7p!suEiG#6Ue*J^9JB6g;AdL$zmCe{s4HI z7)Um8{Ztp*kjT?8Jeq#V>o?pI zM~|Z3zX6_L3DFaSe>K&m>2b| zw6Al(Wk&)+{YZCiB5e4(03_SFo(Oy>JntM!v4JR_bYrf-iLbtJd?e;o%%Cp;FZT1! z$2#GKvEvGGH|`iBt$KeIf+u$|psxW>z*?l zcnpe_spm-n&$p_W1ij<&5%8K~Ia0{+-ePlnxzvPNdh}P~!$LKVZ!+~E)gdRF3f^w& zN@{XE%bZSXfrjf#@-Zh_o8ym|+tNDV!_44Ob0hjN$KRJTXalQEY`{O3;~=em{HQd8 zABOpV;1`vKqy^Voq2)Q+8f9?-uV)$JNxxgYMcYFjH}Fr@U+7@YpRKwZ0-DWk`D2E5 zD9794dFC*yLV|#Ihd=xb$FGt|VGQJCv$(f$)p)Kqw>Xo&V8#4D@F;N{orb*Fu|bL? zGeCzSx=9KnvpD{h)RfEy9Rd6ssS$aZ<0+=5WFF`!;OVAD1be(|d`6mP(Z!%+fKN7! zrAxRxX>vEZ40IguJh?4h3c4KVSLDiMIoHW{WfWNnIsy281uH*zUiB?K$=jflfH$;s zBWpRn2KYOmQ-Hq%d_Bj@sy)g3pwobdsols%E<>>zPCtN7GJrp?`qQl(pKlGP+kj^Q z$5(6VPL6M|jiFNzQ?;2K=ZS-=^XC8Fx6nfO6FUe%b9$FLPW9_>x=!|60JE0sF``j(-#2BENvH z1N>Nkom}Vmg@AnF25h??@EZYX!flS%2wq9t)n?xD_zZu+$ znr*syH!1rtkEh2^(QOm*oj;3I**gq23GaQujQJ$ViH zt4{+zW?rqOWx-^*ys#QPM+2WFCnMC4EtYra8eBUD$S%v9o<4SBj;eX)W); zSKD;`j|0BOru#*V(`Pn)-fRN!gSL3`J}>WYwq;}k_)G*Y+86L#*?r1rvI)9kvpvi0 zLvg>?j?KGz(T=yuroRN!|U<>?-dXSvSeo?Ir=ffu@tA#YvO z5WhzB3*3{>1Rmp8$0L7lcO@;Kmw-R+*2h@}EOEzc_#EKN-LV?Yg1zo&@-2AI1^$^k z+=E|q$7u9?;FsKy9^C1lpwSC~`}=$OsSk;RJez>WNj*utU2jJdrDBp|SIB1Iv+!)O0#9!>VFm(a+zLF<)PUr1 zyo8Vq=bPv-pvw zpg#w`-Qw`@IcNzZ&B6a5@UJZ1dzqgtp`-=yL%@Hrc<*IYwGn9v{0MNT`jCfD8x?OQ z0RIYjN42>JU!&^%>QUhDs1DK^Y1r|RT8*@UJl_J}trmLHOIH0J=NNF=>b=JawFZ)Q zxb}PC5mvV+J>k#de*i9OD>3w+Lb1+m4EUb{9*q?(#xV{n6UG8R1AGd+>~Wyk@h%xd zC)my8ETUVr85RAC0--aRf_%>duOfKc(aXYR`XX%RBJf25yHn7QiIVPP{|tPxRF2H# z{MSnBgxPkLTn4^TT8R+;Kf)X49^@tPzY5wU*CUI$etOCulUHFszX0ziZzM}NpA`6S z%Yfeio})ZP-r)Fh!sRb=SjisHY?i)? zLm}UCIb{+mT+a7|1ac9yKkzMrSDs_SW%3jF z1Oh)Jc;`Yt69iVEfR2;f6FX>j zY{ohV2hzs@-;T8qE{?mE1;o!`BJse(mFap$2;WlrksybJRnzE8mEI(Tr;oBMC!r3J zBm+;eEFckFhTWEZBno^|fgiDKCgnIjOI2wCWJ?GBn)*9Q=lCnwp*9ogGl8$L4kkGq zkG3@?dC0ds<8P}?3VFW$ZCgksq{#+8)b<`J0-ghUwrwzM2nLBG%br21fzAV-Z%-sO z__dwvZH1Z+8z}(Z%idH^jPx6v!$@PKDFnXB>D7O>>oL*jQ6qb*Or3wnpxCG7#w-0G}#M zBZGMQSaBs8g1T!2JV{(ahI9N=u^|}=yb185Vs)$=(^-W}Pm$3`(+qf&)Sryu_*AJM zc@}sJ;IpOPNu$9|l}@h5@L0sa!_^OllD zW+UH$z&9ufX|}^;7245Q;5oMaWDU<(v{xqUK#v1%wtL6@YW66N{{-MQ?cwBI&cCz$ zGFcDVCIatiKTkGrys2X?*$8|R@YaquwQE^ma_ar(6yS<8+k+Q5bI6Cdb}I1d&I}LU z->KK*bl^`pqdoXc=NhsZ{AU86>s;x<>$vpvF9ClD>m-e%k4vx9Il%k6ynf3wE`6?e zF7UCgAhM0iKi4&xd<6dUfiH25Av-vp2MkDDe}d zSqyrc`yIL)_^Y75alc6SfhRlG1w27MLp{EZ=;nZKhL|Kau(d`n1s)&Rf*j)c4i9vb z!=RS~9~I~%M|gcr3JfM+fqnz{i-7^;C{O=d;4AbS@P8Bd>cE+LX9CVOgX@s*k!CgU zI>9wP`A!Vh>*a0WlY_nWvMpF|r)z<45B9dxPlNS2(szI#2-cs|F=k(Lp6h`h53Yx=bTazWvJRealARPnPley`#$nl9Nck3HY;R+@z`#1deF*&o!L- zHFHUMp}A9+W1o;h`#2>n4c2(jC!8wThD%(yThc%TS=cjTs8b*x1J9*94Hzqxb$@jS z%R+FH;Yh;{r?7;KbjoBG@L)WZ+BA1&JoT-}@SPiYbvS<$7yo z3Zic~E#w>EJxu~#$K~m5jwA1a{toy6+{?Vj`A;&Zk@rC#2R_3bkFi`Y*9PDlL7xD= z75E37{~7aKvIYE40>5OQMs`ED?07~Fmp*d_%&Ai|6aoRz7P`D_D)AJBiiEi@XJ>{-RKx#DTs8To%%? z{#%znM~EizkcWb8z7RnYU1p7cOCf@$yKF=R-WfYoROI}h!kc)NT_`{B5#oL=Eejr! z+L2n|iRFT%fz+DR=KNpB^Q=0c*(3fpBnPR>%k{ogpVS9WHub#?_SuN@m*8(Sb6N1* z9_`5V8EMb)W2T;@6J%p1amj?aHJ5&0U)wCwJ}wo{+}Qo~uVf%kUk^U>P{`@eaJfDy z=IQ6jbJ1U0NFeYP@+2~u<9W(tG97p@@LEbSnaA<%@ShifE(`n^54 zA)$yCSt98gj<-`+l6N6zIPf0oBJu$*uWU^sn?XkccUvRKZmu892GLI-e>89fZ#jLz zaeurSe+YOi@KEfSdW`c)7d|8>Tvk#Jc&_j+xybXqAXFunK_>veiMsxUr%%P4%&(x6 zfM=kuxW(~?z;A<20p0{Sw*An`)lb|=Onx?!hUgG+E%Eb%!Qe=dYLEcX8NhR;d=kv@ zzEUj`0y+!$P(0HN=lELbF%sp6`G4SBrH&-tPq(*7Qyxk16G#s5a;7Yjhm9Umu%!^G(km60j~=yTe@q%OZeSHUVs$3uVq5qOr}Uytjf0GZ45KwGEvPovdmHm z^Wie$3V9uGyO7H5uqs+X+(O3UDXBZ)C%ge;L0ly}@C2r_zeHm|Q}ma=V+J+IFP^4? zrg*o)j*Sejs7Gu|`&S*R{jq-P5_V)_%cO&jkF8Jfk%$NY731~dOBhDa& zydTtEs16!4o@971-bk@7#X7Y>#DhpW9)Q+MzDIWFEN_cF#EGXI|8xOPN-8n zXP~u-guk^k7WHYuv-k+qof*$@O@fSC`%QFG1+}G^J~dfTOGnhVsfyYeZ~Kl~Q7b(h zUum^b#f3MOQ44MS_E874AMgJtbwcYe29%*LXnR>;uHXkPe;0fUUW=Q2RW=MW!2aZy zkXu3kw0SAKy$}d3J{&awD>H-0htbt&Ftm0j=5vfLWyoi7&tr8&S<*IfHgpq0t|X>l z1PUeL$$`*C7%89p6b*+KmZV%l*(1oT)NqVekz{RJoMx{qfbGHL1yX$H&Yh9RQ$^-o{uHu)G706LE|i{35JA&=SKt)RBXB1J3 zV{$_~r?K;YS)K&srzx73C(RSr%TvJ<*UOXViRXsQt1aFj@f>^#Q7wN*kMM~m|i0N z%N~A%J^Io45B0=-<(cQ<_c)2z$?WrW^ct)l1@s~;ALER^@M|{gtYGyP$LiCl2R$8p z98?uSpIN&8b=+G|xc(vbmLAS+F!r%?Id0#@jIWU%IAh3u*UkohuQSp?el5LmhJH%K z(SvL42=+IZ@hyh;tMPYXZ4csAy>cw%<=4_9oo2tq?5&=NGt3EDT|)2cJ$hV1B7S6g z+^F%l;jJEDeQ!g$d&&QIIG)B<#}msE{C)&KT|Zj;aXIvM1Ua>GW1>TAXSiX~&d}oq z^y(-KW-)!`y8K_rRZ?!F-Lr9&<#SWhFP7dC&bif=+QWP_57#5KWn5j&PIBbx5uY>{g$pzBb`=?s2I zk0X!UgSVcH-%FqMaitMFXr||i|MY)zm!MFbEm5Mh+9M@sIYQ_3VZQRuD zX#{(-3;Hki=wFXNtXuvBp`GU(e?SR?o2KPCUQKERJ!a z2TLEv%BSZ$)swFtpYDn4e6;-^An&YF_(0BAYft!H;(p6qmX9FfEfVB|Tr~M%9c)h_ z1nhv{*%$iJ^HX>`TTJ!*6un=7pUbXiml*Z*pw8fH_%X)0gg@ge=kt*BUipHLrf-zD zI(tjc_qw<4x^58HpK%a%USH)YjOrKFqA2@6Fp{FrYnt?ln3AEEMfPXOT|CBtK0@ZUay#;`Rn|Q^v3uzBRkUeRHsYa*Ez|skKw!+Sy2NoQF}oorLtS z@$)h~1!M93JpMb6V=2Fee}+;p{@OTOT0g-5f&Pqg7-z3NmFB0%jdaHO@6!MOzyGx! zAC!LXT_3Om&8~Dg7BhRQi=BVi8RMFMA4>H&?9jN+*6g<>w^MDrLOa9wxR+gr`7iDF z)&l9r><_qc-9S9`Vg383EL}yO&gcg)Zt!;JnU}eD`SpBCv@h+x+0dt+&ll8p9Jy4g zf4%1EU&r!xGJ(kld9Rna?v^Lrz2!0T)z4$~eghIgP8RH#X)?VQdon`Hy7^{N#IEXKmYV&<&tae1>WC#4sXz1NH zUJh}6+`KI4^L^F1y972XBSqU;#`&WJHEd+#qWB1ZeK!jd`6-9(hatelPu(PVbFFzFppW^y2@F z@4fQ-r}!qOSD$u%n#HleH$l|xAd%@M9=q}}9R7#b?hx1dWt`E^r}6avsXdMZH~2DPfN*U~j&5y9#kVeREN7 z7kf&iKY-u$cG22ne|o&FC+^Gdi&Ff*^<0nl3bp#_?70r|7JKdOZaw4ohwzr0C;fxb zpV!a$ll}#E)PmKUarT+#9>Q?Q+kl;sU>G}BHT(}3R)6@!k!}=wGa7z+iFxnDSnSp8 ztFPanpMP2|y?+r)TpuYK*S9Ev$9izxufKcV_ilavxg7V>zj0q@oW1;*eja4KfuB#m zFhJ9@KvwW}es}(VUJkE(59)Wwh5pHFPY;T3X+FqD^DBJLuut#(mu_c!d3$FoTwr(X zz&Kb3cHkSYkGP)x0B`TTN~C`Rzw7Pvu&3SW@h?4bUw-|OzGOQx+WB{^zs5Y;uoC>A zL3)%!^SAZucs~vQ$d~W4NT=)JKi4nvDQ0$GTAzCPuZa5drST=&sSWENeC3$pkwbe9 zQyr_9OZ@(hUY^EG<-XUw@44=vM{lL&_)p^~7mf$T_b8XoI2+@han{O>`H5{j9mhTM z3!##3AOEy{8T0Hhl0H7|DxuFGpf_JVo;akfou45`1xdGqAW6rK`N>=f_6xr@ob6tbid~s>em;IYv#-AyzoPI~5W61jR~rWq zuU0Bv!#6HT{JA4<-{7ycbIp!fy}L*~mcFWY+^O#yN4f@*{#-S>gr1U6ZYHk{E70_D zB(22n_4x06{#JWl;;Xj?_+8g;l1Hz4ydB%EL-?!b0mv8a-P?{4N56S@yEN+WFVCLm z4hFx{^8B408rK==yndu^H~;y12i<-~di0_5D|w&L5_;5ep_UPY8 zckgnGuQU;Ca~D!vMF$N{@u$K*jj;63|ZhcCeE?ZVS9l(sL;|AHU8jPdc-8*03? zo#S^XY&%c4ik+c|o$OqdxAzj)>+Kj{Z1(97e=Jpw3x<5K5Iw(T9{qr?#CFUnF%I7) zmyzB$mzMip_}`~P{)@3Ho0Sj!jiz7itk>IVUT?pYD4)wzvfcs^*VA9%c7ol@eDslz z-*vmVGdz_zhpgM z^yI7K-f`AQhx}px7nxp+Gweb!A&&Y##q9!L$1Y_Th~xg^bP0VmM0s>OXtOB=T!&vCYs49@vj zH&aUA4?5rfo}X?{HBGu7GTLKjzIHj@Q(s2E_>f8WpPnyKudgGW?{&)&*ZDU#>HgCW zlWzY_b-P7-*W=ASao_9r;d#;0e!)4rg-@3xDhwbf2Xf|rStl2 zMt;T_`NBR|X?8@&ICh3TzIB&90*Ae=<@PwPgr26LocJC6>G%?MHyyZFv(&Ck%hXWH#=n z^xxTg9q4By#jN)`pO`fqZ$bFl&pwa6sd|4-wf3pa2csON&tTUNA0*ouk-Wq({;Pm>=NTwS7wKqc-xMh(J!`VXWZ@b>wNkN-R_5R z`G@O#@tp@<&XH#QZ1}zRy55+#HqM598}Yxp-dk@*JN&0-Uws8YUnQ@*m%R7F4Y`do zmkauU{&3$slI!UekDl~?ZLz0*kq-6Rhv~c6d!K7OH!|iC!7x#O--^6ZGhCcLs3_W|x=bKORUHUW9-+e|t=nuDg z`a@k0A9?cAi4_lGs>->SKcGN z(Z3kyzvFZ7-=PoK#}A(N;;YvR(5tQwg*{Y7{pHAd{4DPW3T5B)H9Ylwu|)q+%Y$Dk zWiLj3+xY#@HD2D6`Wg12_YY^8eW1VkmE{Y0>$3g?_W>6fj`JmcUFrJZeD3Nu?$(E1 z&-L|smQ1{yMmo;dQ~!qEjegb2?b_%sjOz@!PILK;xbeFouW>H@yOHjno=cbaB-4-f ziegE-GWZ$!8D|6k=V$OY{2KJ%R<1YRUeNz&_5wf2IQ!a56OVmWkfDEE-;AA6zb#q) zQU)1*nD2FMJl7faQ^>A^eRg2iiR?PvPAfAUcJr8rpD&;O;Nu&A%44U-dXL)N9F+mg@VnpZN~eENd`j~*;s$@?Y~c5MHm*0$rLH&Z5IX?;wcTib zM^)_7&)P*4z8=Kd1=>deJ7YY3oA;NiSRD5&TKh20=&!W6cGla^dXF9H{mA=_FZ_@% z+4WjKfwT4#&d5i*zQkGQvxVD^Mo7?|>Pkws-pOuPhe!g~{aXt8%NaOz9{lV#t-^2Yzvt2Rd z(Bn=|+`y3@`rpm#VfTM&hsOIt-gyi?Uqc?FpEUGUa-9cNy!RiF3-7NR>5XzHC^|oH zyrlk(`>rrgIrZ}0-42cN|G(|5mp6>-$`Em+o1&kn!Mg` z7|){{DSEu*eYuQ!LO$ppO5Z!r5Rnt32qaIuO*2^x2>-lzJa={KQp5Omz zy@2_j*ooG!&gA)H{;4n9eGug{?56a2Kq(yt0V;#)_IVw{UZ7{wqG=J_=od+StX@)k#UevL9K z>{T{k(ToCt(adv29HSUN!geFluZ{Oyo5=WSxg{}*B`Z$BT!KcCG=noqXOzHx&M^2D zXL`8&KTUdUIRr_Un4y%VY}b=zW)T}FY5PIoi__!{wv)+9?8j96CW?hGMzeCk^&wQo zJ~4uf#3Ht5Db_v{ZDQNBnel6}j9-Z&_hqwPP??I&KXE@a05%{)IhX{)ostY*4tW?B zu(3R5v%twV40W-Y1Tjdm4DTz2NsuaI z3z{?;&Q?0x<}^db&NZ1bwzJ8SF>sfcv3+3$8Lm{ejLmCuWOP2cY%tGb9#B5J{V0%e z16EPS)|7>8v@4QBNpU4P40}GwPhn*ilb|XKs>y>emdZm|VFr*bV2&?tLZ0H9Oy*il z`r3@D!=$gvq-WoZCJ!;`>oe&ehV;b^nDh;q;Eh<&m<3G`Yyr%^goRTx7Bpu;3j|xh zgVh3}E*7+8Qndo5wFLBaO!{t2`tD5kJ#a;FPp11Vth#%#B)!?MkFuZ-3m#+G<1FaQ zf+twePhNu^pII<~1y3^UDHaT5!5|iFX8Z;-Y6uI4vS1hshO=M<3q~^bqge1X3yPtL zE!COyqnY&2utJYvg?^SvKbBqb91F&=;3!O4*U){ntvO7p*(?~(xJ+Qd^9XcS3X4vZ zKf%|(l2 z3m%kW^XR=5dtdtdo~dpk0^N#LWe|2qV}XqYb{2S5>`?GoA}0&b1<@^Nv%Y$9VUQwz zEO0ZE^;ghu1Rx-REE>e9UY~fDEnq>7(VD)9FDJq;MZWXV#{ua#HOuT@acuVv%gw%Ftz z{aUVqt|w1Hzm~5+M+FM{wTcR?sE|2jMa*NV#N3+73i`Dw3i`FG@VbhtDWU%d+W7`% zjtB;@;6a(=pa*4+-eK|22F+4KWvF_ioPK5$wVAm|lL0d_gc=jh_U#8kdB-U5)F)zu;<|!)L|hbHe|WtATH? z__`YS97c5+8|Q>VYr3m(Uk=8~zy#*y()@JA7b<+x&toi+a~Q zP)QQWAO+uX_#R_21|pBJnQNexshlXYZDR1+DyFLSlfyJg0VIbVXO_r|0!c_ zA(k-KRw9hG4ZiCEt^HSi@&BiW$_XNx5P|_Lcu-BKg?R6-{yv+~K2L-Alr@OY|D-{D z^=~wYJ*+|O`QK^~2TL}HL##m@VGZK*|E@vIV*cMu)>Xa4JjU6|F=(7oFSB4Se%0ON zd2k(z=QAI30rNH&GU^q0o5hQmx9NKWh`rUdapwQ@4IuVn?=K@5z=8*5?FS!}wg0uR zr^vCAF*uaN_Um$jbobzZO}-!eq)D`dwh%4-PYn*(HQm>f!Di{zW$cU|3a$NDgM+UX zXY)KtSuvlNLepRpY=JlKYy2%`h~_(U(onC}d(WKQr}N$vpR|+_3}C^7vhgJ80rlu! z&-{{t2VCEq$4ca+@|?5<^YU0R$L=|=u;8jPLE7>xQ{8(p^hT!tU{1zcQ7vU~_H{(M=#}!o9FbnkVi62r!Gp5c+NKBOh@`XeXuCYj zq_^MyV?&lAPw*K3L}vVx{>1oa{u{B|1IO6QquURGUK1ljDHe0es8aGU%h;D z=ApD;9!g8rkGEnTN^52jZJ3ABmU$@cn1|Ayc_s@A0>bc)QCDx3&*En;Dxz}=LeeTuEWiMmDj|KZ# z@F@#EW5MSvIKYB~Eck*2hgfi!1xFBU!NV@Bw`9ik6$`#*7Iu_b*f%Wr7G_rb9Wygk zX>Z0eNCY+(*jeCx(C1Kk<9lf=aL9ek`sB)kdGe^T$9q;59AlP!oCV*r-~I^m&0lGw)?g zL(5sPf(37|U?mIQWWg#HtY*PmEO?s*Ygn+B1$9`kPA!u4LTj1VR|{p_jp2tvwTi5p zXekwoXgK;xop)HF-$kLxdRFN7RMhnQtmGS1bc`ESl>Gx0sW-8VK2%{Bo0*=ssOT8C zGPQ40(J_96@5+;pRdkHoRdkFy*eB)9GaS1 z4oyvsM^jT1V4Z3rA>XMJ%;jLN?-;r0V<5e8B1|h$xHLu^SO;irfR$6$hGwTibib`=>SIb1JeU~*;CVtie8DB6&gMbRLvWpp}KT8*2MO_B6pitc) z>+RRu8NH23EOLwm9jpjCBG8jOVm&02P6%|%_FPfASMF^6Ud9)SPspT}`lXD=T|dbB z!?3^T8LrCc84#4}879e)^3NV{dwT)C_@S|aUcQNnesmxmN=MU)^d&l<9-=qsP4E;2Nl=AEp-?Ci zstcWjCxxekVZtckIbo_WQ&=Ia6xIqmgrmZ@!b#zVKtz-15JSXxFT5nnfn{0F12G|DL zhT2Bhp0UlcEw*LZbL{!{B6}@+J$n=T4*OC2aeINI$Whf%%~9Ji#4*BA>=@&i?wIA6 z=UC`i?AYosJN=!3&PZppGtSx1Ineo@bAxl6bG!2s=V#8N&Qs27PQ~SP`MUyKA+9i2 zl&hR8*_GqUcU5v#bJcV8aSe3!@tf>7!*8YEZ+^rb?@o4?cUN=Qb2oC2b5C$jbsuma zc7N?Y<38uU=)UUy)qT_bhnx7D{jL5kf46_2e~5p$e}sRmf1-bqf4YBt|0e#e{X6*2 z@t^Pimj8SHANX(cuNqK2pnkxFfQbP!1NH`d8gL}wyMW^X7XoOYE3iypcwmRX&VjuG zUkIEP_;TRFz$Jkj0yhPI6nHf7`@oZdrvlFhI)h?^Qi6H~tqHmj6c8K{oETg)xLI)9 z;BLWvf(Hc84xSghFn9w#HR;4h|03~Tdj{6zS0Ob?9nyldC6AE4q(44sG>J?h)5sdK zj;tqp$zk#(`HuWTZs4YAFGI+-q- zu9+O>Ky#=$)0|^IZ2s1qBsZ74$lc|~7u{-6rhver;*tTox1ZLM!@VI5>Gwl1>1Vg11Rk@YL|#J11&h3&HKSDR$F+Jo&8_Hys_p9N>f-9{dd@Y$HOaNdb<}m%b>4N|b;I?$E7dQ{VJpKnh3yUdEbLU+k72jMXn0O|UU;SO{^3uC z4-J1ae0BIc;b+6ohhGg3j3^Tk84(*1ACVA|8c`u)bHwKnM;ppbk?V>wHca82JJu3Re z=$X+kMbC|19K9@hMf7{o+oO*}e-r&(^oi)R(LY7shz^U1iph(q67y2boR|eMugAO{ zvnghG%)yv%V~S#{#@32`IJR|cx7dEM!(vCpJ`=k%_Kn!&_|*7}_?-Bv@wMaY#Xl6^ zIR4T2$Kwaa4~`!eKRSMF{POsf@o&bjjb9(XG5+KDo$*KFe~!NuFD6(MYzck|0SRFV z5ed-=i3zC*jT4$BG*4)o&@rJ)LZ5`b38NBbB`i)@k+3FVZNhsA8xyuA{G4zl;d;WI z1R>EsF*GqOF*-3WF*&hyV%x-yi9Hh^O&p#$Ch^(C35hQx&Pd#vcp&jm;@64aC!R?> zm*_|eND59WNUEAtC#h9Z`=l;Oy_5PTJ(V;(X=&1`q_s&0k}f1&O1hIIBo9v>nLH-> z?c{Hg&m~_>zLtDDSxAvmY$?4{2BnNjDNY%iGACtT%EFXaQ(jA1p7K`8$0?tue3f!E z<#@`qlp85GQ*Ni+Ns&^msgbFvsoANysfDSHQ=6r>Ol_OmF11r?&(vY5qf^JH&P`pM zx;%AL>c^>HrXEYZntCJkW~w92l~yJ#JS{#gAuS~>BP}njAgxAP-L%eW-O{?JJ(|`x zZD`snX|JWNPBW!j(*4qFq(7A2GJSgbqV%)rzom;Aa)z1_nh~B+E@N26TN&?VY|c2D z@l(d7jO!UnW@kGrMK>$sC?pocUblN%2D<&%~D>rLs)`+Z;S);QiWxbd+BWqsP!mN#1`?HQ`{gibj>w4DBtXo<3 z@1sqz=fUoHP@`P=1971Rp;6(TAOs4%2LafNXe zW>uI|VL^pgE4*G|V})}SE>)n}Vz!*^&K{OMDtmPH%Ivk-?___F{bBa*?B+Qgavsa+ zmoqHqxtwV^b93hByqdE-XJyX%oD(@0a<1k4mUAm7BsVR$X>P~d&bi%ld*wcvJ2-b( zZgK9c+!eVibJyg4o%>DhncUmC_Ppr4guH^hDtXQF+U7l$H!$zjyf^dK1!A`7`oo<-eT2Fn>}0JNbL^kL91vznK3= zzEEH(a213UL>HtKlrJbKs9Mmzpi@Dwf|m;x7Az}xv*4|Q4+{cotRJgP7V&SF28-)=?(M54Z=|!1E`9%$irWCzaw5RBJ(a%LUi%4bm zS?+X<$OYsYxlV#;SsFom!vFn1r~|Kgj5uE0CGHhJ6?;jK!p~SJt%R4l36H2hlJ-iU zO9$a~d@CKpsCpLT>TSu-6lcmdH8eFbH8=G!Jz*MXnr50|dKsU6{@nDnskYf9t8xQ* zfLx&Y3Z3993|3|;bCe6pb>$C*T2xDrCD;;UiL<0yDp{&o9m zY_V*&?6IV)*=i%TjoL}=rarC?R^L;%VSL@E9#&7QXVeSo6}5%6oi?(Lvre?mur9D3 zv!1nHvR=d3YO$&CoC7hcj2d}*+dAhu7du~fE^}7VykUHj-Y?59&oAGvlHVqb zh#&jy_PgqL!|xA2v)k%+x`W*{-L>7V+-=+)-CfxdNBL2? zpZv7^ygW;uBQKB_%CF1ITZZSN#^~y)e7s{8)3FWl%lX6A5q5KLfG+E3RrzOCWY00s?YuRAg zYT0S|#B$Jb*z%3#gyodwg5`?k7t0-spem|E^;3h?BkEE0geqHAYmBv=HO2ZQtZ%4w zyLG2^pS7y3wXLnKldXrXm#wdDl5Mu_|03+I!=t>O|L=9zI0SD?p)C|CQlms65Niaf zrJH0E7Lshbn_%^RX{ozVcW9}*(o&%x>hA9D?$7JYx$oVjzdxQ{SJ^r4b7tN%=gtLz z%L4_-XwRdgO%CrC-V1%}-SFSxKx9N@d}Kmoa%7)KMWi{h2nnn!vLw5m*0Sra)c zvMzE(WPKzMjYNy12SwYXUD4Iiqob!qFOOauy&?KgbZhj9=*!WsWanA)JhJmj@LP+;RAbHYAg+w{Vg%1@}wnYImU7V zy3d7{%lU)9cUT@`C%$NT!}1<~KKBR9KL7!CYtTB>x{GypcH<)JQtN8#sn!dvH=r#) zg$DGc^*5`}7O>?Zt_zicGV8{-R=9>o9&Cy zozv(&C$WpJMvK13{s4N% zdtUIAct?77_s;fKqXQi5?e_M02fY`1FZ15$z1e#^J7|k{tM?i2_uikpzp-n4zDd44 zd`-Sq-vPdM_}5C`QN9y=m-(*rZSY<1yUBOE?+JL>i*U0ye8bpHHU3(Ei+`cN&A-zB zwf`Hq*zbY>I0M1J*uZ7%rHz4`0yhWl4%{DjFz~;?rbpBz3T{AKvN z@UP*&!uCihh{0ZwIgx$Y$49VtFNxe4*%Wy^@?7Ng$VccBzeWCzIHI9wVRT3|Xo*-h zTOPJNfks_y9fnrDy>&-4>j~)A9q4`uYY$k_P1f7kS{;yhGz=PR7oIkHRcuJ2txx_)#0?fTc{ zaJ#qzgYF{t5chERcJA@+N$x4`neH-oxqGgA9-MAJcZYikI%pCt^a1y?@U^$yAHdmu zaR085Ku^R|jAnh7XT9fk&t|ySo1SmEJtuo-aa%Te+q_-gq<6XZNbhmpvp|k+<<5M{ z`zCzrOSsk^zWKgJUyIzG*ZA)7J>c8QUVF*+r|)kN>H;2l4;3V2G#p_Ec)~6qB9kps zEz>MBkP!AlYcB^KsfJ6`@u%AN05dDM&Oj=9w^B{o+DYqD?RtJhHr86{O&ze7nLsruwG)cK2bw@Rj?jeRF-atY|ab zWFf1%zwba_%-7-T@-6W#_4WAreEq((Z?*3n--W*QzB_#Pvf>Jjc*6G#{N*ELrEh&d z`Tq5VKqdC@&lW`DK!3YG?qB8~^q=6r%D>TnhyOnRWB#Z7ulnEie+K{g-T$xO7l;H( z1ET}G1ZD-A1B(MO!6^<8{9j;g;KaZg$W>Pdt_|E8xG(Tn;F-XSfwuy`2mT2B6R-t6 z!EkVRa9pq=I4?LDJPZzW5$MI`!5f1&gI+u;$i)}Ie}mSLBQz$oJ$Qw}D2E72xm|c{ zcwBhr@C3Nd|AkM7+nf_#7rp>V?4s}`;Y-7pg>MYs9)2Y3<5nwSCy!*m&X?P)(-OBV zvs{WiwaM~;+t01z+lyU3`@7GTXJb z8$g%tvb}5jfW7;v$VI={cDCpC#>w z*q0+A9SZk3(tZrL+X>)$r`ylAud`nW9(|eY^^HhPH^P~2x8H5wWT1VIi|nm-`y1@` z59}Y?KeK-Uru8j5{b%<2AMA6B!|Cv_&qGL8#URY1K$pjINA8TIHN`OA}#}AG??$GgagU)fbIopxv z4*^A7<2=E6lJipMRnGNr!<(IVI5#;rJ0IngJdKS1w(~vbXU?yx&#h+o9kZWx>rFOzj6HmKeTes4&|mD;~wkYnbR}fy@z|2yUJYy0=dY2 zFc@UFdl{VY1otW2#h-yfy1^a`JR?2RJx!iY&r-0)(>)h>F7{l5^L?>pyk$=~)SayK z7Rxip%x_yhvwUg!5vkc?^;*N$67-uLxmTtmv+QN9L~hyFy3pEdO~b*Cv>uD}ayf|q z4c5EZ6^~dSx4y@Y_{#bNl1#`}fGj=AHdd?>N}g#!ita$FIT9)QBy1Ds$u7Ca_Mq)? z+q1TpL3n?#{bu{e=CJ$hqmY|-u}@*Q)Z1G?CJ(lEu`dSM6KBBjF1BB3zZMR+gwf>6pbD&J+ICgC@4pakOJC^3RoyYaKT^?!a>JJm}`zjt?DQ zJAQv`ALN9;jbfE{VSOsxbKFhtV`Np%L>j-?eYtzR`(F2B z?q}RD!t>s9e*#u)1tT8jndq4bI$RER+63QQ4Cm_rK}~yBB8i{qIoETc=Tgr`&jX$< zo+m(5U-rC#B>o48>Im;R?*#8&=z-a4nM6nZ9+ti;=F@BVFCef3 z=D_P@Eid*9JF(v+faU3H6~fJ{9@_IVlhhg@+*}O%Cr7-a9-u+z?(6?hL2G ztHNvHTo;8mVsUv8y!Ey4*Wus72S(ypRE~_?8o51kU*zG)*2oi)=OeF0-ibJ)(deY; z^ypsE^5_9b{oT^oBx4dSw%(lFE-jR97 z=AD>#3YM4)^RCOgIq#jk_pru%o%e0tFL{6E{gda!5);fX5If8mY%sg#PtKo_zgK>F zer5hV^w8G)h1g@-^Oxi=&F{}2%s(7N_niE7`B&y|%>O8V1h$#O3hpd;t-w{dTVZ?Q z>DXSrC@e0TSv0F?c2RXvV^K@d!lKnhM;EOvI`PWW*)d z3{Jz6c&Y7jY>6+}-mra%Eb=Fkh|})22kfK8mN)^MUO77M0(kksNRG?wDR}q!!m+Qn z-)i4%f0*<7y2v5QzV{1qhZS2x)KTCVFWh$){B}Rb0giTLjwSHe!_ireL2EhRu^!oD z6SC%0ASfSVvH8LAv*S01-x);iEJhX?hwWxB=WJ)Wv&z}(T!`k<;p|5$IRd%lJm>As z=dfP*kVhuECcEai>RtO{%Q+nGs^yU%<;>RF&pOY|o?AV4b3!+J9`n58c@JIr zE6(UooYH?h|9Tu=kJk@wGsHXGyQ4SdU4`s|5yL$z$DJz z-hr~fa&Vh9f%5{FAYnWZ*ov<6N}wiKA6yb#7F-@Y16#<&;5YXM?+-o{d{#7@H_&W8 z2!0;?6RE--@`b{og3ypqDU!w1(B7ej(Be>AC>~l7IwrIxbVBI7&;_AOLRW`wMcYw! zk@rL2g?u#}F%J~9z)eIGQQgTjgM(c$C5H-&Er-x+=({1P^k&(VE;4F3~$MS@~6 z9UU1LnJBi>y%!lkZzT=cfDB zVnZj7U^^RP9cdklZax`2Zy6_IC9?Th)^*nP+;1DX;cnxOyU+SHHp-u@g|-sgFm$N- zwpQexZrkgegx$odU1?t^cU1xzW&_g6-S$WAPa|`GZTGR$w+F+iW{0olHaZrW`U1yo zj(fR>-f?{I2srbdW3fP1fdih6&a}z71^M6u=MP8*4wu&zaSh|%8OIKu>1x3u+2&e` zHgz|5&bzK*$k1JAL49c6cew9yKkEJ!-N(bdzlUcpPnG8=&nf8NuX{f7eCGL@o%jp# z^S^@J_&{!=-cs)l+#QpUr)PNgh*GKO!Lh_ zem=yv2^8^J?2O z?1yxD9r(!I;3H3iki3r6@s8yK%O{pkK}x-RhgA2d^GP_%k4|M3-P={+in|i7M_7?3T+d@4{t!*}M_1TA0SoagB!GFy0EkDt=bz_6ZpwQQH2Af=H}gK`#{NF9 zH~+AFYk{L6TrjL)=Yl;8$_knbdJ0w)tSUI7;EaOjxP#v+c(>pSJR^QB_@}^DSX{V! z;ogP&6jotvZ7ggmTwHii;nKq8g{unJ6rNOgVc~U!_Z2>gpTw7ie-`?S!bJr|LyJb? zDY0A89^BrGiVi9|xTve>RPODIiZ)=0y|L&aJSc3%es1c*;!(xh7grS57q@UzA6a~2 z@yW$!6kk>RVeyy6-xmK-Y$?er*`;J|$-I)rl8%zWk`*O~mz-a6Vaeqsx0gItvbE%y zl6OizFZr_MyAu15@*#CY_8qc#$m$`74>^0t`9m%qa?OythdeOk*&&|~`F6R?C|G@zljC+ zm*Kw+|9g0NMD2+EM|6zn8qqW2#1SWtICI3t5!a8nX~Z2P?i%s%2+zpq$bymEjT}F6 z*OAk(~Dkbyw6?p83@le;zRX|{WrAUztDQE4!gr|*c6H!L&URcq+_(`zB@T~ zf%EN(*0dY??+i5HJ<);pK?|;MR5|9N2iH0p9Q%SHw}1#O;{G}aJ4A;g?&wBJ8w63l z8BY1K;}>wiD7V-U=XTD$od=5kyV`lI^JM2~NMSEJzvCwJyGFRSbM5R(xmLJN!;|K0 z*GAWi=(q2>c6Luh`q~X%xrcjCJZkoF&j#bGK)0<1>6?!otO2yI89jF)Ty%f;fk!j?Lp}_Zs(c?&Gn2oQl3>_k=w+f*n;(A;1*=4SCO7R41OB?3}2G(fLL)$Gb_q=h z&4jbg3pIug2(_aH4d8EfTVT6{4er< z&i5BY3WgMnEErWVpj67=H0+)Ej`iAv0d?Jf%L$EFG4jx|)4&Q_n*@xHWa>Hx$RIrij z;Td<@HVG#Gob7YG-o6JL`PUY-N9_gnF=$-lkT|DI^1Dd#KBx18@dKg0s`mGc+pZ_YnJdH-=bz^y`J4;twj%gLVNnt@el zwrjqt4n1p;>mXMb+E$Nixoef{FtGoVIQJVk^>-j6McgCY+Y6>Y%Uz2%+5Vj4)ncz) z@4gi;x~JT4;qv<<7D^8%c%)~0@Zjl!2-ka7g9o1nj&%h{)(xJU(72R+X)CD6v!0JV zdxGoti1d0qn$@}9%RxRK#-)zv~dA>UItX7cW zgTO<2d`J3@_nqWB!*?!-$mPDP1QWRtROAk90T1~eLH>OM4)Uq+5R2dDclh1@kiS@b z)<*az`fJ7fwB|q$&IBf1=W_h{4KFM{(jc6 zmbKhhXIRd*T)^JF+;WxW8YJfH@u|F%J^T@uS1~u#Zro5+);ji~wq@VTKHF-Y#=hDI zoAp7qF7Vi6u^+CpU4UGyq~aGr*_4I)du-IhkcQQ6IMs0uxc+S*VsD^_6vMqournsJ zH+Exp>@7NVzw;8-{~hNy&Rtynu0vf%VROFNb+v0VYxu6~Q`cv%?_9sS{=r|N9=_ZG z2HEdk=f1|h1$^rjY{=uh zJA0?%$)FIddi0Pc?*i`<>@%xD_%FpP@_w)1SK=FsK0F^?_-NlHzH5D(!Kj{qm%r!x zOpy5z{?Yzj{JZ-1^3Q^+*ZbGwE%*Tbg5To@91KiAE13x<)e-0ooEf+n&15}1{?@?l zfqU>Ad?)Y;a`F$@0IfmA>GOgG!70H#gO$NW!Tp0B!GYjacstw=dbJfB;77r);PIo7 zl4s&MyboT2Zj1Vp10`TEJA$oF65CG`-m!}<2V1%={gxvwC$g>=v6{D`?TGKTe8-eE+VHB5izd1pIpa{_JtyNcdlp`^=fiU@Me5iHhq)i_vK9Y@kKrp{Sbw(u zjko6n@m$ywOJ5E9V3BP<{63W}c@PeBDCp}^cz~W}JIi)1{i4egHaIi60n<*aFR(N;^pp2(C`+d zghhBj9OXV1&(!CoYL zyI&rJR&?koD8o7f4vir_f4QTui)?gHa-|1W4rz%{AbuI z7*1(qWMph)7c{)xB6~zqk(J_saY^K|$Tgs}n+BHS1<7Ua=$z<$G`|C*@u(Zy6v`#G)k$#4x!mgWE&E!QT6zT6Jlb-)y`2}9|CqT-af&O10WK6D-!z>e9dn{E`Nmm z|1>^dZ(?z>Ixt^2hH~Ey=f2$yX?iB|^d3mmdvO+KAyv=j6+=DJbQ99_B2Glgu>v&c z7_1Ygfe5X0T!h!yRdD3H9FKx{KI?c1{NZD~#l8X~`URgctJBHtUF4jBt$j9r8g1Oz zCu4cN*tx;EksEu9^GojLeDTyCi}kgW`!@krv`scif9?Vx!4mIvM>uOE-8+J5R3ei%a>n+9{;IPyz9Idd9TKE{6?K6oK~@P=Sl85`J%8*EzO zxWLJQ(*u`sduui$wA1Qb=$`qzYe{dFVAw;6#hjZ94F- zUl!@Z=5v@}M#q90of0`Ca(?7Oe7tUr+!MJ!@&Ioic&?ZijKnibaK%tMHduZR`kE3XNq1fdK0_T4_KX?#h&6|ab9sj@pi?Nif8jK zXijlWac%Lw#S4lTi4AH=aZmAJ@#^BkijUyE!CGD%oK$>j@j1ok^J?hw;`PPX@cQ7^ z;?2bm7jG$ky7<}R7m8miexvw3aInt=1q+r$N{UK`m5eAEU9v;T*peMfCYJP;^p*6N zq)V2U99nW@$4v3_SWcyhATQvbq{y z9)??*mATr37k7P=T7dM}#Q z8>MH$<`Y47JV>Y){GCwbo`N>UFI4dc1+}F!c3Ttgo@+>Sd*ymz6-~wupEJ53`NL zJ9s;M8h9Fk4T2{NV0{y9laL^$f%(lwf>3@A3y`?aK<|3QHVqwpPkdaOkr(>y1NOsM zXXTIeCiWmduhOF8c`_BN&^)Z44UYZA{&_LhhpX``xyx~n<6*}$NC7V(2fWHYcpbav z?~cEa11wIf)8=$I!@SLkIXii?mT)e`>tq!={Nc_cv3wpQFW8R9|Kt?x6=&eXa0xbx zE5sLNgYz0R`v;s4;nn$=^MAv*2O>3kQo?l1Ivi%ab>9JX9Lh~;T_ z*IuICm$}Ma)#&%PA(7wZx(Dy$O|A#f2cH$$;SJYY_<6nSdXGK$G4jI~uCMW5`PTKP z>o4(PQPPAH4~bIr|514LZSURzG*Pvi)j*Ma8h??*@-KYH!H0RGc? zzCyA24CSni$G5Ew`OZfk zQGTt{wEIEdH`^YyJ%NwwGvFYv zAlH9}Pvsv7naWFl99r(Kyd|wi&+X%+uEfvmYWsEKO{sjUALZOW!?}IM{uWaHXV`Ot z;w4!u$eMbgyd(PVbWX6+a926b#LMV5$3vXbQs+qL4#?>XIHia3p7cy4_3OpHyOp!{ zHNIbeIfJgzoUd`N39emTyQA-}1tYr!nfxi_@!woykgSgt-=S04?`ONu!<+v?cD?c< zx)vMa-{LPB#Y>?S&ORC+g&jm{-UXR?3cd={@hI90ZMU2=p!oa%y6#FO=fm+RIudWN zGje3+OFWl*u0nFYfm3l0od01?#dDm5H<6$D!hpq5W^Lg;yUXGTV-Mle0+zr&mc(n-kfl6f32CM4!h+hsh7cUv4q*fu0)3?P;eV{PiM3{YVqE`h34V6&a?&w`u< z9>KIB_55fb!}kNov({nfGZHkqyW=N5B|*$%!Ad?DfmdH3T*OBs=%F`U3_;TC;a?zV zbW6B|Pf0+G<2AMr8zb-XT?z7>82wWdUI1=M^5^dYK|Oi-qlE~}FX-f}6D~{O9K-7-y=S47G>Bc4? z7i>}%$5mK{q|`}Pl|;>l@~TMkylekK&&C4wkraOb_dZFw&t1dnFq{iuS3>Lr{wc-p zLI{$~&v|0RkSFD7hoJR8u^mec&a8ZXgU?2su51-5Pcpa*vkFlW-i{e#r0Qv_#C#d~ zL&r?VrAjps*gaaQ=WtS1LD4trlHcrU@6#`ib<7PAsFCz z9*9cJVZ)w*U=l1m#uVa6UR+9^XGgxo7d+_m_9KUnmdv9^+z3HT{)qb^sHbqmPJA?h zn&*!hznw}7>@(&F2$FUgThG@$sCflXBqeEZ?8y)$Juvo32uj&^4DTp;M({XN@(kN? zDg=4rJEkDWvvJ2eg$O*n{kr4z>UaS{4lA_OtJPgp_>(>r6r-ViLo@(Js7o>ddh(=pdi z_*uu?G~sU{9QRLritm$9{Gy3(YhveJf0!zbo-ygj$x=_4H-OSs-fl4nYJP0Do@o;E zI1d6PX7#l5bt46tI)0iC2C;7Oie_l)c%jZOuil(v4d z%;O4z(i@7<2wIR(U=FDoMOX7Crz7ZuJxhm~Dti|hzNj86!LvqR)6V(7+CVMP$L zI(iZx!cnF8)`Ad+TE5f7agGa^1coyO=Ql~3$g6#6>l>%jrRoWMujDz^`T@R+bbo&I z?I|`2$6Ei1OdV}4_g@V`TMPZS>6qUFXY0wF80>asP|rMDI}69rD*}CzBn9kB(geqV^aoe!bM-v`=BRe-dTdP))U(0$urBqa z`+oXN%)RdQ()qwb%kk1^;9Tp^vNr<)+jz?rI1obEQXpj+{{(!eax8X+mO?nE77ytzpJ>n(r3fv8#9?l#%Ifdb1B zatZ>)@)ubd#l!f6OXe+>t&-$OSeG-I6o1?Dqn_UN_&ZBm&8~Cx^v-vk3_9@t5iud*44+<}h#-_?b!yYyd=4#T~N)tM#Ux5xANYM}@zKo@e*McK+h2 zgfzNSbh$oOCr569InczJku92C^hb(GV!hIleITf?IC?w;t=poN5)=3>e2OM6%v%mi zp^0o)&BOdaF8**`|_x*PoUGMSEz{#re&F9r&kLuU1rz>YGRj+28wLQv{7j0@8Ga{NUl z=B*H(mukq*h2CPqnW#sEAm*FUXp)H8m#4zgdP8UoG1Rk=Cv!qv66q2C9QZLj3W6bz zM*o-Ax5t1cZS9D5A(``W)RB6=v>dGG@NnXtwJ~+;h}{z@t~^^f<3>~bt43we-&(6l1}pcPtWsO&=JY=sQYc% zw2ogq)AW9hc@Jiusky>?CIow<+IzUne4xgAv?MtK!f8oTzLB#19=ALX!RlOR`2vEe zyW8>}1g)PZ1exQwF-fEUSokwVs^;N1`$)_v5u1rQ)_FX`;S+ktJLf_$nI}2tKrozB zom(NuGsArMu;2BR;Z<`Z+7wFxx!GD+D5}$!JOE=yWf_kE-Y=7MIqQ`<@Ut;lC%u_jqDS55olyL$EgvC_Ds- zn&M@AyGYuaR#>KE#tA`%zZTdzXb|?{F*9^HCS(Kz3 zOP?-PNsh66!9-$)mX3v>t)LL}@YSJD5d(44u%*L=cyo9oawao&=7{qkU>7@#oS>!C zpGWKkL7zV!5rCi`&&X;B+A0{SlGq6kk9dYsbalUx`D0X4APVv&HJ^riiWFamW-ED) z#jQ+Y{<2PxRdy^!p_Qa+(XD9WL6lg@vx)bC($>2UzLKoEai`p{^l&4FeM!39aTEmI z7xNhe(G13WOG(xPzjYQfSD;^>wodHNG1ANFbniXWdHrvZ+6pidT`)p|)Rq-E^ zSnfBSn`welL!4hi(8GTGWTc1Fcq%ExZTP`Rp6zjFk&cbVJ|)B;#wAG_#+!SIX$e%Z zrqujzU?c>4HG*+Sx^X@p5t2EM%YzV41ZT3!O!&{%Hu?jxnb%uVPXo>XQaorc(lh^~ zZIdQGvxoF3_Ql{S_0)rLOQY{OFJlzyFoI4?k`t4mB)PFJO3k}sj+dB`ysnT&hw~sx zk{SfvH2c~aCuzyE5IdYA0xx;%A?Wj~*zP1LfH7Vg_4+#@=!VNb z4uV;|+_y~TCvcUoM+nFD{t?3c0viqK0ta*;kMn|aQp)*=wZ`mOQ=_O&d6p!gc> z-Lgz27`P?RYrJ!m&cBJ%rz9=loq=S28V3t^ob}VF!q!6dwhgFU7C*eNGHDzvai%UroYu{!v0Wj>Ba^ zlGb3el-al@vV*FcJ#-C(Trr>6KQO`M9|NNOHtaWi8i-Gx0zV)nOw4?*!6 zAovn9OEec^u5cct5A}!64%w@LgRr;D{KNp%Wx_kLzN=D!Zk|9($C9q2$;=$4aD0;_ zWtR~`nP#MkV*C`P8#6FPNzzdK6@+N!d8LeWJ?N)2aS5)4lJuU*^gaasl-;78bgjb_-B1!wYW9)}{D_fl6}B z;#)1MX2I#H~B)fY4#y{$ZPHDtEJTA=OY?2 zy%9VqrS+*ea7gE;I~sM&az4i*F{}7Cf@J=mOdVU|0f&tlqpJ_$ydlL8avrB+Vz@_3 z%mvO{bj-y(5|)@P*!QH=R_8}L=67d_p76hTf-0Tg9lM{(OU1foHCM!-vYvB{zAfqgby_GUToB@%BVE+ zKe(5rt*xUc9_t(ISJaYt$Fjb`o*w9dc&azi7aNE}r{d{>WGcQoo=RHUV(rP)fTeOy zQ$uUxY!d708Y-)5E%j}+l{E`yTlBxxMu^x}i6%l5#t#XU!-8o1>X6DV(Z-J|CE>QV zwyu7<5g(w%uKvM9A4F^*)<>|mvZblDz5;4d#ex<|kEc?}6jWow!pV~?ZT-m=>Zdn0 zu!Iy#TRK5GT{sh`Dw{%gs#_Xr>6ZLU3-Of+)nsQf-PRo+=t?kG0|TmR6+?Ia6GNU( zJ!eLVfkdyGK^0n&N~qa1YBYX2%wHYPfEU%Z(gEYAx~;LIj%n8aR<|`*G&C-rZ83gS zmzKvn=pa22f(cwy+dNn1RTD;7B{Z1{LKtC{(3(lnlo?as)>u|qrYh6F`d?z3%XO^$ z>X77>1tk~1`d^i|wOneDUmcPf7!~z4m#fjqzx8d+jjg(i24VcPwbe9KH8nLfF_D!G z%?6oBvl6R_s%@yB)6!4|)ha(d>3Dn@p}P6?Wpz~$Ep?4h>`*<6ZOOrbezk{9qFqxf z^bZA6@mME6>5f?6KvEqBrgyME!R8-`tHVKLaz&h7FpwPV?^ncNUr(Y>HM*d&siwZA zN_BNXV~hMW(RN$g%8s67T5W~&Kz~O+{ccYr)63#&0B!9lRkSTFzw(bJJ9<*-4r=e< z@b$#I)J9y8=!_?8)b4NVnADLPNc746%u;P#iBwu8xAnyIZz{Q5b+Id!>Pp4w0Yq=C zrzhDVBxBXI(F@%&d9samCkK)%=_tF6^FZDGg9foAmgtrc`2){sVr-$TC|t|@eQ@L zaw^&xr<&Xqocy>NgeHt%!ZBH4{!OqX98>akEa^?M{^o)iza8{|v3D84uCAWJ^b*2} zzD{Gx71<{fq_{#)ysvveWl;H;V=8WFtg5eWgqTy+qJF!Q{c)xV&IUj0g3vp+OYbtK zJKne4(v}!V#@Jy!@}vLljrYnPQj-P0Az9aC{FwDAPC1~KIp>Gfp##;8tu6JkkZQoj zhS%F(v6A*ddXqM*S)QTN1E~%*3F=qvVSX8={OW^ZGCA|t;CXE;&1r)&Ca$eZjiR@o z_JvaQsTmj`+K3|{aYk#T4x|!B5wmHNHFqY`%k++^POOY~)(tY@m8sZ@=Kfe8V{DEO zH1@>$;tLY-70rp&Y*UpeQKZ(z`kRuR{|a>h)}*J-oNj4b8f#w?>sU6$($)k!s7Us8 zCAuwb3l$SL1C6nPjwO=0KE7g3Ol|&3x>4Pe>@Vv}FpA2g)X2G@2eIYxmL+kWtu`6! z%mkX33=VWASM=4e>B79&3Yt_oODZD4J@KE(VbwBsz>t%m&MzYD|Ni?4fST{rFltmMK;91 zvVnaE6|<>~_a9JlJC>_4)=l<`7@~}h zo|B68FG+N$8Dn5&a7^SK>WKIB>&YXfs;{#}&TT6bm+TuzC3_m#E5;70W0ZCAzCjvD zrqlBk%dTkD6U>At?n00%^jt#Agemq()daJ9gB?epsy~rVcB;Li!^XzR1}YO>96w4n zCkNHU$u?G`?u820HkTQDf^2Ft=}KBsOu<5iyChqwN>zK$+$xQV+0-^yF-$!Ym1y)m z){|&YA-~K^u1YgedT7Rs=zi2C2h;K9xH?i9GBJ=?o={h@>RH7=kJ(biAYx;$QJeym zaX4gLij@zj8gvAW~DKsB_G3r4XiMK=r%AaXD-!W6dMwW>xW`fVfisnJ`gDiuq|=L~Xq zRaJ9iJzdQMam5`7Npwr1qcYwTGv-DYq9JukDiD4+-V0+1H6^W-Qv9*3Z&hZWKyV|% zdFtZnw4BH0fmmvwqOoo;o!~mEhG!XMO?}&(_&_s)R=u!KVV8|D_L%OBYB|%-X1IU9 zI#itGwF2# z)W(;`d*C?zJ>0j7qabT>WLo>RAa4Y-Y(!=((Y>VEJmKojm}^E@+UnuTT(a>M{4c8` zr?^&$TUkWP1z_quViKjsDlcVpXTr#MJb4CFPznmRcQE>9d|8RcAS@FrI2g zG-Lu)|H^uL{{Q3uTRs~$_o6JDV)spP2Fu*&YbG~Fr>Gb`JWW+5)J#fG<)Uaz_VlRp zlSE7`M|e!C)2|{mGsulGSQaaYAy{+8&^kPx+|ILHCoApTaaZL9-_$HIJ=xG z*p)r;#-ysPnzNP-&E?R=Qv*su;f75N%uS{etG5kRCKdBAGG+pju`!cVRbqq|%qi0+ z+7NV9Kbn#QqGPL_F0FSmU=>g^!%D|v{YqL=S>a=(G0=uCepLfaaim1G7A;F)LzS6e zS-LkvmvdvPQ5h#r(TP5UKM~Fpt1welCM}>yj7&3y5{j8@6Vo4C(Z}YJ{lqW(KtTa5 zsa14|TecZ(p<|#j+1VYhOfWw>%vF-k4L1$;Nvhi9Qd4Cr*Q*U={eMQ8Btm$QtkF~nCKtR1OO z(%V_nwMsfRr9qWtE~=)|h+1OH;<}eg4vY0LTI3y-BZsfmCYCF1Hiw_8l>@0*ox*xl z9^tz>p)rXlW30Wo>MD!g-l}MBY+0{jQYtn}ky8%798y^j%|R-968)MoE)abR*fZSq zOh|91nnQIipjy>!g`TmZ&z!^geTlAk*}wqO7}XELriR0TXS!68GSajnVvX% zUr#WDH&h%saB3PEu)5r3@RbM`a|XFLjIffy4RTJ38yiler#_~{cGVOm2DqIWxzf5+ zeRGz;tjto)9ZO>E?Ph2W+}p@itu)&fxSL96rIn=B!hY!*$OLqn8LfV$kTg=wu70!BXurdSr~I zg%#;GVl~4+A6+6Gf;okh;!0FfM7e;E(y{V+8L5c)d9W49FmIj+nks6sz+8%|Oez^u zcmfl)+U=uT{9BW8_NvVs%v&ms$$7t-?CZ* zA)yHONRxnWniefvN~_pveFK$gi-u32wclW*(3JoS*^u0&b+Obk zJzNRWcs7Rd%}F&5rbLUT_wfOevtgr|O!-(}UvfaR2QA7Yh?S|sRZ}l3O%Odo0aTe} zL$IqvI44f#lUzEWc9ohp63`7}U|u@j07%RdaP7ItB&?NuG6co&)j%aiZ5iXnG7A_% z%{M8elozxH;r`iRS#w2AjV_`(Ql^-HBU3aeIO3zGK}SqclB7y_fmXB$v?9R*sToQM5iLkyJ*o*QTAu7}Z|JMi zHkU>Q$3Co5168zeiou+)(c%AQkfEyr5EV%U21@DNiD{JHYdEIY7!h$Yw?^zXZEhQ9 z)U-{caFZ?T;re=tm(^)Ukl#xl*(i50V&K$R8i$HHG$Vug}T*hMvy74*oj%anL)a!b^+z} z;?reAv6ZxX^m^0)1z?iWr0r}_#^UMnnVr^L$+DJHUu7Lu7Zp;CDu}T;-fakoL@HtE zKao_J>{oFEaB6jhLlVl2NBYzNAEPQwD=1KPLv_#4JPB6EI^&Ej8zEFqOTu9)IfH6SYWg}8;P&yx z3LPGpq(o|Dd6b^!cq%)01Cy#T8vVbq&DgtgV_TcKU6IL*GY@Q<*(r+7Oqs${73b4H zv`S);75>-+U<-Q1;UQ9DvQ%qd8f;r_4>Jw@#0ayiRPmZVt<-0;=&(_!LNaN!M|C0F zfZP@)6hM;F7IK2yLItENY&0jGlc5aZIWejc;~pTp61kfIlcispSdd|XfKkwyxlsXd z_c>*(nnFbtBCO*S%9aUBkHzXI$(3=*PBAmL>cPT9rxN#caRI+f(SRse8F01$6J{0z z!y^$Ek`1WU$;l|}C0oweb5e(*YuKjLpkM_Ps!;YCqNGL*N=dk}N6DZh%ylA+=BXO)u1%tIMd4`s~#LKAv4kQJFFHCq#?;~8>^!kRU39q;SZs{^~y*S|96fFJ8*EEbwj zwi&K3(x7xyZL^VQFs%v2nv@CzxEt#*^=`Caqg7?#KzZ#Jl%zY=7ms%;p0r{K+E>~@ z3RCe;lkDvk`!xOP*XM3ZhMH`_oL$yjHAnf_)btHZT7Zf#PAvp>%MDD+4NT7jDkjBJ z-R#jeA+RGuU{6k@RQKDUYSj@@L^^H|+A!MIpJr0ql4;xq(xUG{_r{h=a!;nT~hq92gEx`mK15g1bs+Sos%oJK%XA3H$9ycdg z8Ud~vZ3O9UkEK$|_9C#pc8M^^s-F0Ad=*m4)Y-zMrxc!N>^Uw<4WEvv^ zz6}~=&!KyjDbGw;s#LIavag$-q=h4(Zs0k9jNhYhJbYc4vu?v^foB-@cILPPU`3y| z<=wH0cmlT0URogtEbXcl?2YyJ!oAazvn0FRjGanu#wIzG7el`i0V&m)h;=gr<}9tw zH?Xdv@c3ci%4tLWCa{bU3pm(?y-T(Wy+N)}(G1+^8F8rr4q(557N*-$C_w6}!h=h} zQuNHA=$Jv#FN4}mQSHfOuVhn%P~gig2EVZ5leOU1H4F1lU5UICP+ym!7Qu_ zOwG+C4N4|;SsG;%eP*R;h3IS(Fl&_*vsxggv>q8%>44dYgv>$`*rrgXGm>QXrZbVL z4bm(PX_kf5Q^g)wwo11sQXs!j!+8RNM*SjC%#6`h-Zni?(nvpviN%zj9cS(gON%5-3x zd}iI|%u|~=^O`ivb_#NqZcBD`WOgESW;RS(YBvJX34@k;OgcA{^gt5yPBciF80hRy zGy`U>*_}vAc0Muzvytq4m`P?|a^}NKGJ9jr2l3{7Xwoc8Y))QTmfpdE%+x?2zk63{rZdX&H?sr8a}i$sxT^(RzL~CDTJ285U;H zMs?Y_G2)F%B;M?wDvNs-+*#K%BZr=uL+`HX?5w8KIg@GxjE40r<`mFO!N_Fv!ko`^ z+MG_IjPaY3*^Yf8GlwdW?Lamp^OOlnCo&G|OclguD%hq=nJHH# zWI{7#veTYP%e0f7`b?TkekLT-p9#qVbc^&r<@E?cBW3vPEJlZrz4X7-}16MbMnh1<%DILa>9D2GAWp%OzA;w zmG<`RMCFEM+&K|4ww$o^FE{+(0@7iff%{@$Nr$rAaEPQ$bLujooa)V~%cSMjl!)tN zY1X0-ri8N7s!L|4RcS>%TAI+Lw5CZJhbHwDEAI+(g1QN0rzabdv1WpL+0Cp{VJ6Lx zZOp_>6S-5OGMf`((3vXD$uQ!x<&B9j;`QoNPj(ViN_GmmV%bqaX9txD$e7HKv~LDv zM47-g`J_K2cj#;9!> zh>;;McVY3&9lRMbMr8zzwv3R`m>JqOtI;@MQD)3SXR64KTH_%FqzTD9pY1`H*93fMu@PkZ9?k;@j^dV7%wAm|jWzL<1vXhq+lqt!Evt=c> z%wINDABk*OMj%0R3e7;a9&-}Slx!Ipww8jVvugIT<+2kdB_;Tuva$%-RGBlBH|*!x zq2`8VtT_?VSWZ|*n;ZUb0cl@n$UQbjjIoO{p`7Z?Nywz-)?}QbOj^!3C?{*5Nt3nD zgkgp;}nD0_LA)RiN_d?3- z@gKNXMJdqKgnv!1P>rDoveutiX}}u_p)p7SZVb9@CLky9SikO?0u0roHva9@MsP`8 zGT0sGG0A|!(G=M!FsG(_i~z8V^05{K1;D0nRhyZj-np$<0>;x8?;Ye{tU(CF0 z2E?C8UZBa#521|5DMBa30Z2hDIMpztZGdtL+mZJsU8=uby<)%s=o)BM!%|WG>49bP zJVby$P4U9U#0w$Cegs0ifb5yf%heMn0dQC+BanI3WISpz-ZTNj3dG6Jas~LA=q7gE zo{Hr-BN~t?zIc5t$<9nzkA9$Cfs*o)BGx0u^4=6vu5c}gRbAp23AHjq;T5mkq*Yvo z>QH`{5{Ji7Qth{XP%-|MSBAX_Wfs@b3Z`DwgX4m7aZuo>#?Vwv23Cf;)W_YZ-li?* zp^DU_2&qaDETH;X32KHfqY0N9rB#XnlAT2L#z!v2-fqrzC38j+A z!)fKf#$%i0s(!2seF{rtJDGVh5rS1_LW72Hc1$g=^4e0^B#0vDFOCurnOT;%ZrNZb z14ydpi^Pm_H-f1^7J6Yq_! zO!Eqek#YJ#P&GO!qlk4b#fOkZkwwPeCDy})0~WIcRGu18tw5@qvs3%dbdWioVrev2 zk@f3J0qCa$crHqo95&10Ko0(A=9&V+FE5#MtF zZCqLDm%LC?v@so=M77Q`v)w#mQZRTgYpjrD6|Wv>DMvW0Ost8*=AmSK{OSC(Eg%z0(der4bE6r+C&5=!IrliZ3#}XV@y})ygP_GFQlV__5L} zHCdT}HaVo#?qEK0Ld=XZb7+>PRw>PK=}pSU-Iidz)XvxWQ^r$v@$;Tl~% zF)SBpMVht*MboCl(OQ=nLDg#Fo~!l;56cXD6{NvzWt*CAA&QlW^@O!D3vf)-{*vN) z3cCjT`c_e;UOYr1u@0)T?ds`(5#K3p-9~_Jo6&>4y{lvtW*>~bB7Xi247v+9G9$AL zOkZZmdwpW7A=n#NYhW0NG^fYxrrc>6y+JX4odHvt-VCYO@^Q5!1NO}{lkx4EGPjKxu;5yOUpldvVY5#$Iq*2z9ru1=cO=xdlz zzk2d1hX_|p<+qxy=~F_ZnpzA?A}=sTJzxmgf&A)086txrFW?9SQ|pNLbAVUo(5$~X zWh=9!#FA0Pr~|)}&MO-6-O{G2(g~^}O>v3xz%kaNUXzl;2q|#`pVpidGo(_?T-iK` z0LFcl=rkxj!CLrGQz*BOS{Y3cqj`|gHxeQ;N6k#R3q=y@-i%(5Rkcm{c znXcb#94T_DDv?%iaMcfLrTS6!LfTXAL)yZq$c|q12!uK3&emd&&~!|#OZ%#U6>xG& zav&0YY2_lO3d;#F`$Se%A2N}MjSQ~8XHfr3HCiTE)r(iV8CaED{B0{V&*J87#Ou)H^h)0{-dIC5bg4((S_>zMp_TxZ^MRaBP4xE4;MFR`cw3)Ji!#?9 z=e1K@)12~ncjo+8E0$;st+5U!Bc3_*NcjgyE}Q_V%)I+_$h`V=sIiVm1HAc?9j16o zAKoY;-O!d=3RM9`w3;d8Tw|GuHLhnG(2P#Cv}6?yE$AuSwwb1-rxG#?lhY`i>1<9I zXCB=>?FQ3p3|X?8tCv1xE|;bDsmWL#>%DMW61gtM)l0GPp~hMvxhvt^U=+c3ohC8c-egrw3`0#! z*^(l_N|G6nW{q7dbS1B{+1~0%tQ<(I8Rq^|W2{NHu+_|}TeSa%T6CjyJq#k z%K=TYr&|pfkxF*9WEFXyMaXBYQZlvJBo>(jkLuJ5I`#MyMy`oTthxG}5PYbc zL#NIxpGPrW5J^E;G9>hjN|(dp`*G{hzAcJLnZlT6S;j5U#w*D7Bv=5Nz9yA&-PW;u z0I*e|4!COp9<;S-8VI3Z=(4%Zb8D(wEY&s5P5bW4PlftvYb%>uQ(w_UxJshumFd(< z9g@68Lwp57sir_S{31muC7E&ybxx_Sx<-muOqy8MTxY46WT~$zYbtM)pBnwsSf)N7 zqvCnNQfsM}bpEYqCPSG{RY8?lzIYPbVY*{$PvT!Po{u)}F z7B)0hHd`tyC-J||SZPExw3gRa@wBJ9wxO)WqUvi|+*oDdb2bf4H7$!ReAK6@wqc?C z&aIg<*V0^NnLT@M*@CJmd@W=4?5g?&wG9o8P?Zf8bIa=IsO0jp%9{F`7O47cWPL+R zT}@>@b*O}9KJYYO{kD`fNm%`=hKQo_s`^T(mWIZL>XtIq!`ZVd8tNE#m2`s8+^UNC z(o2%+s}`v`D3r}^&W=hoCQ9|OzRIGyrkhoiYN=|G8KWo_Q(iTvroOzn*+M}5lr_(< zs-#fGe0p8AsIjcRk_lDitIK!-rK+f?YHn_*uB)nRXyO#KRn%6M)wecURJU7Os-(XR zTBWG2*SD%K)wJ=+pt_oRK44>!9xbx$SJl+Om$Pb`YZ~e;Y92?<}~Nhb!GG9J5UYHOqZeQohNbF0c4%WYwl=^N>T8MpVFl zE_{V%_Gk<#o$9a%_PL6`-P8jcHd^RXU(>NPgGf{;@ufH3tMr>5JOxD#mwyniRP&IAgvO|S*Ii4-PjF;q(``~TWH+wR11Wee*k<)yo4&bM}e z1Wp5Hu<0c8B@4()XA(#Tk`CNof1kZe2D5H@E zTpv9s>W=|Xo>;mj$}W)HJK@@x1>Avy26=MaB8?F0kTl{KCfNAQtwmdug428*>SdzAHSXu709zgUkRY!zxW*T(M(u-S7D29uKYLUR>-w<8sh>{e} zpixunLHQH_WZI*LDfU_VnAZzb6otHQyedh2l2*Vy_)2&`2$>umxb=R#Jm23UVyH(l zQP3SN32XP^S89@Ra+*~tYH3g@%~V_%L1-=456!pB{hX(NC8 zpdMAbvhZFFB56AbfY6so62>D`aaXiVZX|Fj<%=677SuRs8SL^I;bciIqCTk+O{(M) zQn%2Yh~6_l^SL#zmzkd|7E}_1wN9G->5>}>+!rjc@o}4k>n}rc)WX>K)ylJm5AAYI zMJ3w=zL1?|LwRLz@P^d!#K%)!W*|;D$j>yL11sM$@F>m7;0n%hizG;bPX7UVp0Em8 z6AC3-YaBg&W#s)q-*&6yMek4`a_hAUaB@^4-y)^qMIuUOa;3Hshbhz9cb?mAhX07G zqRcCu{iEZ9zMK{zzwH}TXFx_q zmu;xXe+YT<0S1G0PgzrO%+1aI?N!HHAqWJxbzi`oZE& z0OIfJJ9r|x(2tx-u$5*C9|vT;T}2Q&(z!wk+%_fB7jmIUA!dMsNpD_Wm3JG!8pcqo zL{-QK5F%xn42E;3MAmr?N;+%UOE`UCf*{97ZCGL+F$3t*sk98Y0T(iqPa*xsQ!O}@ z;KF5sd4abQ*CCEt<@~Lt=^3W6X47>5i>U%hJSl|Cj4=##d7~ ztRK?x0!PItkM2ad46XXAD00H8gNizDnopKT)QOzx1SRFKW%i)5P1148cxybihPgjp zZ=MvPB0;c)DRdtc-^Q~B?*v_uV+&>upmn*XoT1v?GEFgMVZb5)g>*`poyoyYHEpZ- zwlCRYzn?&v=8VSx_BjQrK$=Lv9ZDA5PAQu$Q5@^oc15u*TIA5n!qy6uzIeP zYVYHu*0!W0WF|%5di0m)OGQ`2D3kt~r7b9C!p~p>#glJzpksWXJAX`JcZ4~8@Y-No zg)N(84L4-$VlwKDiQFlV2BmX2hG$nl=gG^a5Awqdpl8ETio#p!iiN{b z3`X(jYLt)k8j7%HNdHl4^s31??gG0EreHQHNgY9Tcw*;v1Om|8k6&}H;POjtU%Gfl zxV?iM_it7!3WZqzis+|Iy*>w8J%izC>Xg4?E+V!2~p9 z0$5QFOi%WF{@WR}<8j%#JauMR{N1}jFWqO# zLC+aNQ9G@QJ}5wt!XvtI<7!e79JY!R-+NZ|UFotMwmZZWcIJFC{B~VVOan;t0R`YH zJi|rV8(tLWwKJn}=VFNV>dd5%QVg!(jJr23M$QO7=zNK_)uYFRGe8^sFd3_;K*Kh=VMtk!8u&k=Cp9WFbP^Nm_2xa+3%|I(^2h zA%3!kZ*QcJXa`&S-IXaA2@o@A!n1-1%$i?Lc>`qkS!v%1!0%Z5Po@*{Chz@XoA>d! zjMFgT3xYyN2Sp`pg%2>zw}e1zBii;kZIETM1A}l@>`cgXd{Gy|Gvu20TykJ=4XPmO z%%47Fx};N~k3B{L&U(8+ptMEJ5)7h-xvh2dU~ML|dPWxo;Y1e==EOV9=*XubEKtFq zY=45E!=GNZoBU4W9I#G&JBI>b?-8**sq8X-DGfui6jeky*f&zmGx}9@kejzVXOoM# zyGiM->;akc{XF5voo`>6C7#~qnP-0W*%B4gkVX{CWKo5VN8k#^rIreYcrP;$++KAo zD{^m!(pl{YQ4ZJW!c<=u&x9S(s8UNAH3Z4vc?;20H8fq58&KX~)=u>x* zE!QF58dpangs%yRw`%HcHIRk6cvFB^67jtjS_GUpu6srQ?E0EFaFnih`77svGy+Eg zxHtlltjE{?0W>b_I3EA$%*h}5-02tRl?b5xUVt8grPTrYi30gj;+BZmUI}WeQOOJ(^j~Imm|0RmiNd0FVmA1Jj$8nGi)X zovY&Rh})o=R3Cf~5$s@7ozR2TaPU~mCKE3Gu+;a}a*DK#970y#&QE7+_>GQSuD2iN zqXa(te5*@%fn>mz)MFmB{gF05c)J^?1lKk^7slO&cG# zIC^jR-}1)?svG{dV#-rtI1ZH~?ZD6xEdA!;kvLJLu>TjO7Oba;_Rt7qh$>DIRh*vY z^pn#03Q)iVFqa~~P&Rv%Lu{PH`$2^KQgZ5M4m2DUHyRG~{R)&@%M*R_xoN;2 zK$?f*g7qHrU@}0scN}il8sV)D>|o&I< zF&>f3A4f1ACBk@I$hC^iN0C4tr2*53;xk3?9Z@rEfKNn3X5pY1gN7D zeR-o4P)A9Iazw($@i&7olp{h=j#5E6N)6?tUYkg6Jh)Rq+6I6vP{vEX6q5*SR59a| zoG{`Hdz5@u1Ra=Dz;PG^-bw`goXWX^p#&RLNl+?7TGp-5^*GK6iRJXi4>XiS*!_<; z9M+^EWoHpNf|AvhDp7jxE=mPf2@H_XNh z0fHeeafEAfspTkzu~W#N|I$g*8iZZuP9&xg_)b%C;Ghb-ss~wG;fsWQD@}$dJG2t^ z@U>4<;_LpuvbJS9wg2sI+qe^y&$r~{-R|q5yL#C6HhFM|tG-L1u6NW`cURU;;Iq#flyLO@C3pPm$&<)7 zPxEUo*KJPbx-pOMxS7C9@S1zaDNsOx^Fhkz&RIL(>5$9O9E|Tvg;3B|xv!ZXHIAvf zoa2D;k_-mHZ3Y9Q7O9C76H+zr9grl9Sudx6g(PU`c45yb%QAX@1%flJYhX9QW)A5n z{vh9CU1UP9f_CLw&=woD=r$aXwuKPUa!v$vvYp^)B}A<0k3|SY{?vwp1`as9PUtA+ zkSG>3lV%pD*qH!BfS)A@5prWGmN3dsIU1zb?A^ru9*iZUCs^v{muIAHDInkm_9zvC z8{8TRnBU{X3>}J-ZW=X2p;*|Rj8t5e#Lej-J|}(SWeF_$yn0uIx(QHK0x^d1atM)M zo3NFf{KWy)LiL33XsDei5f$dTmj_%b*%6oS`tpT)L+gCX4qZF#$PQ42eo!jdK0$Eo z>X&o*f#soc_tu=txqR-GU@jC<9N)m616`N1Ml z%+a3^3)#%|;|dH2V`|z@qKp@__`Ky*Qh&{%yjS7dSK*Ecd}cZEeT`6oy!cMA7;m5XA@Rx)6UX+dBcP++y`P}g>Wfkq*R$4_ z`WGmhBLRw8=g@%4E0o&uATP##kZlu9c>Wd^xZUMNKkY8fv@XkJ(bqd%`6*ScAeQyp z`ITMYobOj?2K)266oZ~ljat8+8nu3HDxVM6wz$9*_65;jH_kz(MOABQ&ElvcTDNOR zjYUIOzqM3V?#sSuUw9U6_`;wM?${VF_qU8Hqby7Ei(Ya0+3)uvaAZUrbPwY+>?(4< z_k*9D5Q59z#4>i3JA(hctw)rBA>|U+IZEq)6``z>=C=MfEVNrVC6;*5Cnp3gy&7|~ zSC-`C{iBRwuXBPencA1_iq^AN_SWxZYk)o$ne#!=l+%$e?<*(5(-7}~*%0Pj-97Yq zW7abyGu6PX~ejlbgpzMioO2ObHxI{l7vO4;9xAt(1rYNm67DY1*;!6|aHbjTIkCA<4(6-9|aXxP9B%L_8($ByH<|}oUTrn7wB7K#c z;)mbrt}8POknY-9Ih<53G_@~te`x1m5Ia>1aJ=H-)t=#V;Zw>m@@K{Pn@G9(?HX+| z`*x2fBh_-1Pof$$O7yUFxr;mF7I4Aw(NR>dD%5a%!IT?J>bfU_^)RXbF5I7@+wFQ5 z+C5k5d@oex0(-%*E_|lnIm1d2*L9c#kplJ4dps8OSy@#LeL(dm<59F(m-S6|GW7ih z9cI0(-AG=SUEh&8>vzUMS0fw{eH&_5C0$a6(JE?rK`L|JXPtRP$5I>M2;HXLlEm^t|5dR_|?FH}yrwNRt{)lyb_b)Oe9s@tc z+^|2q{g1R?EEjipC*KJZvGA4Q-%JDlY6)VpfvU@M?&YF$`GtP{I%<{Y=T0jI8Ddx> zKz#jL^bM>kk1V3ZzKMacCRJ(Rbbz7hn{+C?$n$V)tt`4PkofD zf#33bo>-RRg8E3$|9=YQR(Vj!$PsH-fL5k(vrDtr1kB0C${Z!3{ON=J&>jh}fBvvp z$h?i$kUc9|F&3c|| z3snV)@s+}d6&BzM$Q*@RZ7Gtlv3dG6GtWBik`K;l?CW`eLJUWo`#YAtIr>YU62 zDi`gP2EX@XfbpI6NB9Uus9HFP7$=e&A`lxgL*uS5S41mOR>Y)2A&?mR!e7JwL?O4k zNP@eGjo}wH8}N(gXd6=n9*=(ar`l0}y174HD`-N{gt+U{l)t{j?c>R>pbKq^S7(_& zY*q3AG8$r3l(%wutEHk|%xuoe_z&(3Lft{&dA9>W^=Ry0TO!>S>3gr;DUa+UpPjBF z$VdxTJ3gD)#c;`$f}j-9&+V6{|P57i9dBs>}VGs&$!5*j6x3;r@PsE5Ciq zF_^bnv4Z%-pq2}BXULtY!A5YAS~dX4h6?9K0YyhDnID< zsB-SaXHNJ*W-VHRT~qt?*g4u)?vrbLa_vv2F8Sp1y05aIUEy;y@#W7?pH=w9g1PYg?UdV6`w0eTgu-HmPvNBmMkr9yNZYxQ$hc>Bt02 G_kRH}1)ekj literal 0 HcmV?d00001 diff --git a/WOLF3D.MAP b/WOLF3D.MAP new file mode 100644 index 0000000..a1b3b62 --- /dev/null +++ b/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/WOLF3D.PRJ b/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/WOLFGTV.H b/WOLFGTV.H new file mode 100644 index 0000000..05abb0e --- /dev/null +++ b/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/WOLFHACK.C b/WOLFHACK.C new file mode 100644 index 0000000..343d3b9 --- /dev/null +++ b/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/WOLFJVER.H b/WOLFJVER.H new file mode 100644 index 0000000..c5510ba --- /dev/null +++ b/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/WOLFVER.H b/WOLFVER.H new file mode 100644 index 0000000..1208b35 --- /dev/null +++ b/WOLFVER.H @@ -0,0 +1,7 @@ +//#define SPEAR +#define ARTSEXTERN +#define DEMOSEXTERN +//#define MYPROFILE +//#define DEBCHECK +#define CARMACIZED +//#define UPLOAD