aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Mandel <richard@tech-transfer.com>2014-06-09 04:09:32 -0400
committerRichard Mandel <richard@tech-transfer.com>2014-06-09 04:17:22 -0400
commita1df695bba1b45905a1d3ade9b88c2bcabcbddb2 (patch)
treed4f1f15228ebddb4a12b1fe916bffb2db38917f8
parentdd5f4acfebb86681f4e2aeb1004b6ce3b67ce067 (diff)
downloadcatacombarmageddon-master.tar.gz
catacombarmageddon-master.tar.bz2
catacombarmageddon-master.zip
Catacomb Armageddon open source release.HEADmaster
-rw-r--r--ARMADICT.OBJbin1151 -> 1151 bytes
-rw-r--r--ARMAHEAD.OBJbin549 -> 561 bytes
-rw-r--r--ARMEDICT.OBJbin1149 -> 1149 bytes
-rw-r--r--ARMEHEAD.OBJbin2023 -> 2119 bytes
-rw-r--r--ARMGAME.PRJbin11547 -> 12826 bytes
-rw-r--r--ARMMHEAD.OBJbin962 -> 962 bytes
-rw-r--r--AUDIOARM.H17
-rw-r--r--C5_ACT1.C1789
-rw-r--r--C5_ACT2.C827
-rw-r--r--C5_ACT3.C1218
-rw-r--r--C5_ACT4.C414
-rw-r--r--C5_ASM.ASM2
-rw-r--r--C5_DEBUG.C177
-rw-r--r--C5_DRAW.C1147
-rw-r--r--C5_GAME.C847
-rw-r--r--C5_MAIN.C269
-rw-r--r--C5_PLAY.C230
-rw-r--r--C5_SCALE.C5
-rw-r--r--C5_SCA_A.ASM2
-rw-r--r--C5_STATE.C109
-rw-r--r--C5_TRACE.C7
-rw-r--r--C5_WIZ.C304
-rw-r--r--DEF.H229
-rw-r--r--GELIB.C1378
-rw-r--r--GELIB.H111
-rw-r--r--GFXE_ARM.EQU1083
-rw-r--r--GFXE_ARM.H1204
-rw-r--r--ID_ASM.EQU2
-rw-r--r--ID_CA.C23
-rw-r--r--ID_CA.H8
-rw-r--r--ID_HEADS.H13
-rw-r--r--ID_IN.C2
-rw-r--r--ID_IN.H2
-rw-r--r--ID_MM.C18
-rw-r--r--ID_MM.H2
-rw-r--r--ID_RF.C3
-rw-r--r--ID_RF.H2
-rw-r--r--ID_RF_A.ASM2
-rw-r--r--ID_SD.C2
-rw-r--r--ID_SD.H2
-rw-r--r--ID_STRS.H2
-rw-r--r--ID_US.C2
-rw-r--r--ID_US.H2
-rw-r--r--ID_US_1.C4
-rw-r--r--ID_US_2.C2
-rw-r--r--ID_US_A.ASM2
-rw-r--r--ID_VW.C33
-rw-r--r--ID_VW.H5
-rw-r--r--ID_VW_A.ASM2
-rw-r--r--ID_VW_AC.ASM2
-rw-r--r--ID_VW_AE.ASM152
-rw-r--r--JABHACK.ASM2
-rw-r--r--JAMPAK.C1113
-rw-r--r--JAMPAK.H118
-rw-r--r--JAM_IO.C121
-rw-r--r--JAM_IO.H107
-rw-r--r--LZHUF.C1069
-rw-r--r--LZHUFF.H35
-rw-r--r--LZW.C608
-rw-r--r--LZW.H40
-rw-r--r--MAPSARM.H42
-rw-r--r--README.md14
-rw-r--r--SL_FILE.H109
-rw-r--r--SOFT.C479
-rw-r--r--SOFT.H25
65 files changed, 10893 insertions, 4647 deletions
diff --git a/ARMADICT.OBJ b/ARMADICT.OBJ
index b0e8792..3dff988 100644
--- a/ARMADICT.OBJ
+++ b/ARMADICT.OBJ
Binary files differ
diff --git a/ARMAHEAD.OBJ b/ARMAHEAD.OBJ
index 9feed1a..2fcd49d 100644
--- a/ARMAHEAD.OBJ
+++ b/ARMAHEAD.OBJ
Binary files differ
diff --git a/ARMEDICT.OBJ b/ARMEDICT.OBJ
index 2b16875..33ee378 100644
--- a/ARMEDICT.OBJ
+++ b/ARMEDICT.OBJ
Binary files differ
diff --git a/ARMEHEAD.OBJ b/ARMEHEAD.OBJ
index be2b224..b818f4b 100644
--- a/ARMEHEAD.OBJ
+++ b/ARMEHEAD.OBJ
Binary files differ
diff --git a/ARMGAME.PRJ b/ARMGAME.PRJ
index d5e9a95..bea242c 100644
--- a/ARMGAME.PRJ
+++ b/ARMGAME.PRJ
Binary files differ
diff --git a/ARMMHEAD.OBJ b/ARMMHEAD.OBJ
index e227b29..e8dbe9f 100644
--- a/ARMMHEAD.OBJ
+++ b/ARMMHEAD.OBJ
Binary files differ
diff --git a/AUDIOARM.H b/AUDIOARM.H
index 2187679..46b813c 100644
--- a/AUDIOARM.H
+++ b/AUDIOARM.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -18,13 +18,13 @@
/////////////////////////////////////////////////
//
-// MUSE Header for .ABS
-// Created Thu Apr 16 14:56:19 1992
+// MUSE Header for .ARM
+// Created Mon Jun 08 16:14:17 1992
//
/////////////////////////////////////////////////
-#define NUMSOUNDS 34
-#define NUMSNDCHUNKS 103
+#define NUMSOUNDS 35
+#define NUMSNDCHUNKS 106
//
// Sound names & indexes
@@ -64,6 +64,7 @@ typedef enum {
FREEZETIMESND, // 31
TIMERETURNSND, // 32
TICKSND, // 33
+ BODY_EXPLODESND, // 34
LASTSOUND
} soundnames;
@@ -71,9 +72,9 @@ typedef enum {
// Base offsets
//
#define STARTPCSOUNDS 0
-#define STARTADLIBSOUNDS 34
-#define STARTDIGISOUNDS 68
-#define STARTMUSIC 102
+#define STARTADLIBSOUNDS 35
+#define STARTDIGISOUNDS 70
+#define STARTMUSIC 105
//
// Music names & indexes
diff --git a/C5_ACT1.C b/C5_ACT1.C
index 4749b1b..dcd65e3 100644
--- a/C5_ACT1.C
+++ b/C5_ACT1.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -28,16 +28,19 @@
=============================================================================
*/
-void SpawnSkeleton(int tilex, int tiley);
-
+#if 0
#define MSHOTDAMAGE 2
#define MSHOTSPEED 10000
#define ESHOTDAMAGE 1
#define ESHOTSPEED 5000
+#define SSHOTDAMAGE 3
+#define SSHOTSPEED 6500
+
#define RANDOM_ATTACK 20
+#endif
/*
=============================================================================
@@ -55,7 +58,6 @@ short zombie_base_delay;
short other_x[] = {0,39,39,0},
other_y[] = {0,0,27,27};
-
/*
=============================================================================
@@ -69,7 +71,6 @@ dirtype dirtable[9] = {northwest,north,northeast,west,nodir,east,
southwest,south,southeast};
-
/*
=============================================================================
@@ -92,12 +93,12 @@ statetype s_nukebonus2 = {NUKE2OBJPIC,8,NULL,&s_nukebonus3};
statetype s_nukebonus3 = {NUKE3OBJPIC,8,NULL,&s_nukebonus};
statetype s_potionbonus = {POTIONOBJPIC,0,NULL,&s_potionbonus};
-statetype s_rkey2bonus = {RKEY2PIC,0,NULL,&s_rkey2bonus};
+//statetype s_rkey2bonus = {RKEY2PIC,0,NULL,&s_rkey2bonus};
statetype s_rkeybonus = {RKEYOBJPIC,0,NULL,&s_rkeybonus};
statetype s_ykeybonus = {YKEYOBJPIC,0,NULL,&s_ykeybonus};
statetype s_gkeybonus = {GKEYOBJPIC,0,NULL,&s_gkeybonus};
statetype s_bkeybonus = {BKEYOBJPIC,0,NULL,&s_bkeybonus};
-statetype s_scrollbonus = {SCROLLOBJPIC,0,NULL,&s_scrollbonus};
+//////////////////////////statetype s_scrollbonus = {SCROLLOBJPIC,0,NULL,&s_scrollbonus};
statetype s_chestbonus = {CHESTOBJPIC,0,NULL,&s_chestbonus};
//statetype s_goalbonus = {NEMESISPIC,0,NULL,&s_goalbonus};
@@ -135,7 +136,7 @@ statetype s_bonus_die = {0,8,NULL,NULL};
void SpawnBonus (int tilex, int tiley, int number)
{
- extern unsigned gnd_colors[];
+ extern unsigned gcolor;
statetype *state;
@@ -157,12 +158,13 @@ void SpawnBonus (int tilex, int tiley, int number)
case B_PGEM: state = &s_pgem1bonus; break;
case B_CHEST:
- if (gnd_colors[gamestate.mapon] == 0x0101)
+ if (gcolor == 0x0101)
state = &s_waterchestbonus1;
else
state = &s_chestbonus;
break;
+#if 0
case B_SCROLL1:
case B_SCROLL2:
case B_SCROLL3:
@@ -171,8 +173,9 @@ void SpawnBonus (int tilex, int tiley, int number)
case B_SCROLL6:
case B_SCROLL7:
case B_SCROLL8: state = &s_scrollbonus; break;
+#endif
- case B_RKEY2: state = &s_rkey2bonus; break;
+// case B_RKEY2: state = &s_rkey2bonus; break;
default:
Quit("SpawnBonus(): INVALID BONUS");
@@ -218,7 +221,7 @@ void SpawnTombstone (int tilex, int tiley, int shape)
SpawnNewObj (tilex,tiley,state,TILEGLOBAL/2);
// new->tileobject = true;
- new->obclass = solidobj;
+ new->obclass = realsolidobj;
new->flags |= of_shootable;
}
@@ -277,6 +280,7 @@ statetype s_walldie4 = {0,-1,T_WallDie,&s_walldie5};
statetype s_walldie5 = {0,20,NULL,&s_walldie6};
statetype s_walldie6 = {0,-1,T_WallDie,NULL};
+
/*
================
=
@@ -285,10 +289,9 @@ statetype s_walldie6 = {0,-1,T_WallDie,NULL};
================
*/
- extern unsigned gnd_colors[];
-
void ExplodeWall (int tilex, int tiley)
{
+ extern unsigned gcolor;
unsigned tilenum;
DSpawnNewObj (tilex,tiley,&s_walldie1,0);
@@ -296,7 +299,7 @@ void ExplodeWall (int tilex, int tiley)
return;
new->obclass = inertobj;
new->active = always;
- if (gnd_colors[gamestate.mapon] == 0x0101)
+ if (gcolor == 0x0101)
tilenum = WATEREXP;
else
tilenum = WALLEXP;
@@ -316,12 +319,13 @@ void ExplodeWall (int tilex, int tiley)
void T_WallDie (objtype *ob)
{
+ extern unsigned gcolor;
unsigned tile,other,spot,x,y;
if (++ob->temp1 == 3)
tile = 0;
else
- if (gnd_colors[gamestate.mapon] == 0x0101)
+ if (gcolor == 0x0101)
tile = WATEREXP-1 + ob->temp1;
else
tile = WALLEXP-1 + ob->temp1;
@@ -369,8 +373,8 @@ statetype s_obj_gate2 = {OBJ_WARP2PIC,10,T_Gate,&s_obj_gate3};
statetype s_obj_gate3 = {OBJ_WARP3PIC,10,T_Gate,&s_obj_gate4};
statetype s_obj_gate4 = {OBJ_WARP4PIC,10,T_Gate,&s_obj_gate1};
-statetype s_pit = {PITOBJPIC,6,T_Gate,&s_pit};
-
+extern statetype s_anthill;
+statetype s_anthill = {ANT_HILLPIC, 20, T_Gate, &s_anthill};
//---------------------------------------------------------------------------
// SpawnWarp()
@@ -384,7 +388,7 @@ void SpawnWarp (int tilex, int tiley, int type)
if (type)
SpawnNewObj (tilex,tiley,&s_obj_gate1,TILEGLOBAL/3);
else
- SpawnNewObj (tilex,tiley,&s_pit,TILEGLOBAL/3);
+ SpawnNewObj (tilex,tiley,&s_anthill,TILEGLOBAL/3);
new->obclass = gateobj;
new->temp1 = type;
}
@@ -465,167 +469,227 @@ void T_Gate (objtype *ob)
/*
=============================================================================
- TROLLS
+ FAT DEMON
=============================================================================
*/
-void T_Troll (objtype *ob);
-
-extern statetype s_trollpause;
-
-extern statetype s_troll1;
-extern statetype s_troll2;
-extern statetype s_troll3;
-extern statetype s_troll4;
+#define FATCLOUDDAMAGE 2
-extern statetype s_trollattack1;
-extern statetype s_trollattack2;
-extern statetype s_trollattack3;
+void T_FatDemon (objtype *ob);
+void T_CheckCnt(objtype *ob);
+void ExplodeSound(objtype *ob);
-extern statetype s_trollouch;
+extern statetype s_fatdemon_pause;
+extern statetype s_fatdemon_walk1;
+extern statetype s_fatdemon_walk2;
+extern statetype s_fatdemon_walk3;
+extern statetype s_fatdemon_walk4;
+extern statetype s_fatdemon_attack1;
+extern statetype s_fatdemon_attack2;
+extern statetype s_fatdemon_blowup2;
+extern statetype s_fatdemon_blowup3;
+extern statetype s_fatdemon_blowup4;
+extern statetype s_fatdemon_blowup5;
+extern statetype s_fatdemon_blowup6;
+extern statetype s_fatdemon_blowup7;
+extern statetype s_fatdemon_explode;
+extern statetype s_fatdemon_feet;
-extern statetype s_trolldie1;
-extern statetype s_trolldie2;
-extern statetype s_trolldie3;
+statetype s_fatdemon_pause = {FATDEMON_WALK1PIC,40,NULL,&s_fatdemon_walk2};
+statetype s_fatdemon_walk1 = {FATDEMON_WALK1PIC,13,T_FatDemon,&s_fatdemon_walk2};
+statetype s_fatdemon_walk2 = {FATDEMON_WALK2PIC,13,T_FatDemon,&s_fatdemon_walk3};
+statetype s_fatdemon_walk3 = {FATDEMON_WALK3PIC,13,T_FatDemon,&s_fatdemon_walk4};
+statetype s_fatdemon_walk4 = {FATDEMON_WALK4PIC,13,T_FatDemon,&s_fatdemon_walk1};
-statetype s_trollpause = {TROLL1PIC,40,NULL,&s_troll2};
+statetype s_fatdemon_attack1 = {FATDEMON_ATTACK1PIC,20,NULL,&s_fatdemon_attack2};
+statetype s_fatdemon_attack2 = {FATDEMON_ATTACK2PIC,20,T_DoDamage,&s_fatdemon_pause};
-statetype s_troll1 = {TROLL1PIC,13,T_Troll,&s_troll2};
-statetype s_troll2 = {TROLL2PIC,13,T_Troll,&s_troll3};
-statetype s_troll3 = {TROLL3PIC,13,T_Troll,&s_troll4};
-statetype s_troll4 = {TROLL4PIC,13,T_Troll,&s_troll1};
+statetype s_fatdemon_ouch = {FATDEMON_OUCHPIC,14,NULL,&s_fatdemon_walk1};
-statetype s_trollattack1 = {TROLLATTACK1PIC,15,NULL,&s_trollattack2};
-statetype s_trollattack2 = {TROLLATTACK2PIC,15,NULL,&s_trollattack3};
-statetype s_trollattack3 = {TROLLATTACK3PIC,30,T_DoDamage,&s_trollpause};
+statetype s_fatdemon_blowup1 = {FATDEMON_BLOWUP1PIC,25,NULL,&s_fatdemon_blowup2};
+statetype s_fatdemon_blowup2 = {FATDEMON_BLOWUP2PIC,25,NULL,&s_fatdemon_blowup3};
+statetype s_fatdemon_blowup3 = {FATDEMON_BLOWUP1PIC,15,NULL,&s_fatdemon_blowup4};
+statetype s_fatdemon_blowup4 = {FATDEMON_BLOWUP2PIC,15,NULL,&s_fatdemon_blowup5};
+statetype s_fatdemon_blowup5 = {FATDEMON_BLOWUP1PIC,6,NULL,&s_fatdemon_blowup6};
+statetype s_fatdemon_blowup6 = {FATDEMON_BLOWUP2PIC,6,T_CheckCnt,&s_fatdemon_blowup5};
+statetype s_fatdemon_blowup7 = {FATDEMON_BLOWUP3PIC,30,NULL,&s_fatdemon_explode};
-statetype s_trollouch = {TROLLOUCHPIC,14,T_Troll,&s_troll1};
-statetype s_trolldie1 = {TROLLDIE1PIC,18,NULL,&s_trolldie2};
-statetype s_trolldie2 = {TROLLDIE2PIC,18,NULL,&s_trolldie3};
-statetype s_trolldie3 = {TROLLDIE3PIC,0,NULL,&s_trolldie3};
+statetype s_fatdemon_explode = {FATDEMON_EXPLODEPIC,40,ExplodeSound,&s_fatdemon_feet};
+statetype s_fatdemon_feet = {FATDEMON_FEETPIC,30,NULL,&s_fatdemon_feet};
+#define cnt ob->temp1
+#define cloud_delay ob->temp2
/*
===============
=
-= SpawnTroll
+= SpawnFatDemon
=
===============
*/
-void SpawnTroll (int tilex, int tiley)
+void SpawnFatDemon (int tilex, int tiley)
{
- SpawnNewObj(tilex,tiley,&s_troll1,35*PIXRADIUS);
+ SpawnNewObj(tilex,tiley,&s_fatdemon_walk1,35*PIXRADIUS);
new->speed = 2500;
- new->obclass = trollobj;
+ new->obclass = fatdemonobj;
new->flags |= of_shootable;
- new->hitpoints = EasyHitPoints(14);
+ new->hitpoints = EasyHitPoints(10);
+ new->temp1 = 25; //used to "shake" the fat dude??????
}
/*
===============
=
-= T_Troll
+= T_FatDemon
=
===============
*/
-void T_Troll (objtype *ob)
+void T_FatDemon (objtype *ob)
{
if (Chase(ob,true) || (random(1000)<RANDOM_ATTACK))
{
- ob->state = &s_trollattack1;
+ ob->state = &s_fatdemon_attack1;
ob->ticcount = ob->state->tictime;
return;
}
}
-void T_WetMan(objtype *ob);
+/*
+===============
+=
+= T_DecCnt
+=
+===============
+*/
+
+void T_CheckCnt (objtype *ob)
+{
+ ob->temp1--;
+ if (!ob->temp1)
+ {
+ ob->state = &s_fatdemon_blowup7;
+ ob->ticcount = ob->state->tictime;
+ }
+}
+
+/*
+===============
+=
+= ExplodeSound
+=
+===============
+*/
+void ExplodeSound(objtype *ob)
+{
+ if (ob->temp1 != 666) // Has this think been called already?
+ {
+ SD_PlaySound(BODY_EXPLODESND);
+ ob->temp1 = 666; // Has now!
+ }
+}
+
+
+/*
+=============================================================================
+
+ WATER DRAGON
+
+=============================================================================
+*/
+
+extern statetype s_dragon_shot1;
+extern statetype s_dragon_shot2;
+
+void T_Dragon(objtype *ob);
+void T_DragonShoot(objtype *ob);
-//statetype s_wet_pause = {WET_WALK1PIC,25,NULL,&s_wet_walk1};
-statetype s_wet_bubbles1 = {WET_BUBBLE1PIC,13,T_WetMan,&s_wet_bubbles2};
-statetype s_wet_bubbles2 = {WET_BUBBLE2PIC,15,T_WetMan,&s_wet_bubbles1};
-statetype s_wet_bubbles3 = {0,18,T_WetMan,&s_wet_bubbles1};
+statetype s_wet_bubbles1 = {DRAGON_BUBBLES1PIC,13,T_Dragon,&s_wet_bubbles2};
+statetype s_wet_bubbles2 = {DRAGON_BUBBLES2PIC,15,T_Dragon,&s_wet_bubbles1};
+statetype s_wet_bubbles3 = {0,35,T_Dragon,&s_wet_bubbles1};
-statetype s_wet_peek = {WET_EYESPIC,45,NULL,&s_wet_bubbles1};
+statetype s_wet_peek = {DRAGON_EYESPIC,45,NULL,&s_wet_bubbles1};
-//statetype s_wet_rise1 = {WET_BUBBLE1PIC,14,NULL,&s_wet_rise2};
-statetype s_wet_rise1 = {WET_BUBBLE2PIC,15,NULL,&s_wet_rise3};
-statetype s_wet_rise3 = {WET_EYESPIC,20,NULL,&s_wet_rise4};
-statetype s_wet_rise4 = {WET_RISE1PIC,20,NULL,&s_wet_rise5};
-statetype s_wet_rise5 = {WET_RISE2PIC,20,NULL,&s_wet_walk1};
+statetype s_wet_rise1 = {DRAGON_BUBBLES2PIC,15,NULL,&s_wet_rise3};
+statetype s_wet_rise3 = {DRAGON_EYESPIC,20,NULL,&s_wet_rise4};
+statetype s_wet_rise4 = {DRAGON_RISE1PIC,20,NULL,&s_wet_rise5};
+statetype s_wet_rise5 = {DRAGON_RISE2PIC,20,NULL,&s_wet_walk1};
-statetype s_wet_sink1 = {WET_RISE2PIC,20,NULL,&s_wet_sink2};
-statetype s_wet_sink2 = {WET_RISE1PIC,20,NULL,&s_wet_sink3};
-statetype s_wet_sink3 = {WET_EYESPIC,20,NULL,&s_wet_bubbles1};
+statetype s_wet_sink1 = {DRAGON_RISE2PIC,20,NULL,&s_wet_sink2};
+statetype s_wet_sink2 = {DRAGON_RISE1PIC,20,NULL,&s_wet_sink3};
+statetype s_wet_sink3 = {DRAGON_EYESPIC,20,NULL,&s_wet_bubbles1};
-statetype s_wet_walk1 = {WET_WALK1PIC,12,T_WetMan,&s_wet_walk2};
-statetype s_wet_walk2 = {WET_WALK2PIC,12,T_WetMan,&s_wet_walk3};
-statetype s_wet_walk3 = {WET_WALK3PIC,12,T_WetMan,&s_wet_walk4};
-statetype s_wet_walk4 = {WET_WALK4PIC,12,T_WetMan,&s_wet_walk1};
+statetype s_wet_walk1 = {DRAGON_WALK1PIC,12,T_Dragon,&s_wet_walk2};
+statetype s_wet_walk2 = {DRAGON_WALK2PIC,12,T_Dragon,&s_wet_walk3};
+statetype s_wet_walk3 = {DRAGON_WALK3PIC,12,T_Dragon,&s_wet_walk4};
+statetype s_wet_walk4 = {DRAGON_WALK4PIC,12,T_Dragon,&s_wet_walk1};
+statetype s_wet_attack1 = {DRAGON_ATTACK1PIC,10,NULL,&s_wet_attack2};
+statetype s_wet_attack2 = {DRAGON_ATTACK2PIC,10,NULL,&s_wet_attack3};
+statetype s_wet_attack3 = {DRAGON_ATTACK2PIC,10,NULL,&s_wet_attack4};
+statetype s_wet_attack4 = {DRAGON_ATTACK3PIC,10,T_DragonShoot,&s_wet_walk1};
-statetype s_wet_attack1 = {WET_ATTACK1PIC,10,NULL,&s_wet_attack2};
-statetype s_wet_attack2 = {WET_ATTACK2PIC,10,NULL,&s_wet_attack3};
-statetype s_wet_attack3 = {WET_ATTACK2PIC,10,NULL,&s_wet_attack4};
-statetype s_wet_attack4 = {WET_ATTACK3PIC,10,T_DoDamage,&s_wet_walk1};
+statetype s_wet_ouch = {DRAGON_OUCHPIC,10,T_Dragon,&s_wet_walk1};
-statetype s_wet_ouch = {WET_OUCHPIC,10,NULL,&s_wet_walk1};
+statetype s_wet_die1 = {DRAGON_DEATH1PIC,27,NULL,&s_wet_die2};
+statetype s_wet_die2 = {DRAGON_DEATH2PIC,29,NULL,&s_wet_die3};
+statetype s_wet_die3 = {DRAGON_DEATH3PIC,44,NULL,&s_wet_die4};
+statetype s_wet_die4 = {DRAGON_BUBBLES2PIC,26,NULL,&s_wet_die5};
+statetype s_wet_die5 = {DRAGON_BUBBLES1PIC,23,NULL,NULL};
-statetype s_wet_die1 = {WET_DIE1PIC,27,NULL,&s_wet_die2};
-statetype s_wet_die2 = {WET_DIE2PIC,29,NULL,&s_wet_die3};
-statetype s_wet_die3 = {WET_DIE3PIC,44,NULL,&s_wet_die4};
-statetype s_wet_die4 = {WET_BUBBLE2PIC,26,NULL,&s_wet_die5};
-statetype s_wet_die5 = {WET_BUBBLE1PIC,23,NULL,NULL};
+statetype s_dragon_shot1 = {PSHOT1PIC,8,&T_ShootPlayer,&s_dragon_shot2};
+statetype s_dragon_shot2 = {PSHOT2PIC,8,&T_ShootPlayer,&s_dragon_shot1};
-typedef enum {wt_BUBBLES,wt_WALK} WetManTypes;
+typedef enum {wt_BUBBLES,wt_WALK,wt_CORNER1,wt_CORNER2,wt_CORNER3,wt_CORNER4} DragonTypes;
-#define WT_TIMEREMAIN (ob->temp1)
-#define WT_STAGE (ob->temp2)
+#define WD_TIMEREMAIN (ob->temp1)
+#define WD_STAGE (ob->temp2)
+#define WATER_DRAGON_LEAVE 0x04
/*
===============
=
-= SpawnWetMan
+= SpawnDragon
=
===============
*/
-void SpawnWetMan(int tilex, int tiley)
+void SpawnDragon(int tilex, int tiley)
{
objtype *ob;
SpawnNewObj(tilex,tiley,&s_wet_bubbles1,PIXRADIUS*35);
ob=new;
- WT_STAGE = wt_BUBBLES;
- WT_TIMEREMAIN = 60*4+random(60*3);
+ WD_STAGE = wt_BUBBLES;
+ WD_TIMEREMAIN = 80;
new->obclass = wetobj;
new->speed = 1000;
new->flags &= ~of_shootable;
- new->hitpoints = EasyHitPoints(18);
+ new->hitpoints = EasyHitPoints(20);
}
/*
===============
=
-= T_WetMan
+= T_Dragon
=
===============
*/
-void T_WetMan(objtype *ob)
+void T_Dragon(objtype *ob)
{
- switch (WT_STAGE)
+ switch (WD_STAGE)
{
case wt_BUBBLES:
ob->flags &= ~of_shootable;
@@ -634,8 +698,8 @@ void T_WetMan(objtype *ob)
// RISE & GOTO WALK STAGE
//
- WT_STAGE = wt_WALK;
- WT_TIMEREMAIN = 60*5+random(60*5);
+ WD_STAGE = wt_WALK;
+ WD_TIMEREMAIN = 60*8+random(60*5);
ob->state = &s_wet_rise1;
ob->speed = 2200;
ob->ticcount = ob->state->tictime;
@@ -644,13 +708,13 @@ void T_WetMan(objtype *ob)
{
// DEC COUNTER - And check for WALK
//
- if ((WT_TIMEREMAIN-=realtics) < 0)
+ if ((WD_TIMEREMAIN-=realtics) < 0)
{
// RISE & GOTO WALK STAGE
//
- WT_STAGE = wt_WALK;
- WT_TIMEREMAIN = 60+random(60*2);
+ WD_STAGE = wt_WALK;
+ WD_TIMEREMAIN = 60*8+random(60*5);
ob->state = &s_wet_rise1;
ob->speed = 2200;
ob->ticcount = ob->state->tictime;
@@ -670,22 +734,34 @@ void T_WetMan(objtype *ob)
case wt_WALK:
ob->flags |= of_shootable;
- if (Chase(ob,true) || (random(1000)<RANDOM_ATTACK))
+
+ if (Chase(ob,true) || (CheckHandAttack(ob)))
+
{
- ob->state = &s_wet_attack1;
- ob->ticcount = ob->state->tictime;
+ ob->flags |= WATER_DRAGON_LEAVE;
+ WD_STAGE = random(wt_CORNER3) + 2;
+ WD_TIMEREMAIN = 60*2+(random(6)*60);
+ ob->state = &s_wet_bubbles1;
+ ob->ticcount = ob->state->tictime;
}
else
+ if (AngleNearPlayer(ob) != -1)
+ {
+ ob->state = &s_wet_attack1;
+ ob->ticcount = ob->state->tictime;
+ }
+
+ else
{
// DEC COUNTER - And check for SINK
//
- if ((WT_TIMEREMAIN-=realtics) < 0)
+ if ((WD_TIMEREMAIN-=realtics) < 0)
{
// SINK & GOTO BUBBLE STAGE
//
- WT_STAGE = wt_BUBBLES;
- WT_TIMEREMAIN = 60*4+random(60*3);
+ WD_STAGE = wt_BUBBLES;
+ WD_TIMEREMAIN = 60*2+random(60*2);
ob->state = &s_wet_sink1;
ob->speed = 1200;
ob->ticcount = ob->state->tictime;
@@ -694,1504 +770,51 @@ void T_WetMan(objtype *ob)
}
break;
- }
-}
-
-/*
-=============================================================================
-
- ZOMBIE
-
-=============================================================================
-*/
-
-extern statetype s_zombie_rise1;
-extern statetype s_zombie_rise2;
-extern statetype s_zombie_rise3;
-extern statetype s_zombie_rise4;
-
-extern statetype s_zombie_alive1;
-extern statetype s_zombie_alive2;
-extern statetype s_zombie_alive3;
-
-//extern statetype s_zombie_attack1;
-
-extern statetype s_zombie_death1;
-extern statetype s_zombie_death2;
-extern statetype s_zombie_death3;
-
-void T_Zombie (objtype *ob);
-void T_ZombieRisen(objtype *obj);
-
-statetype s_zombie_risen = {ZOMB_WALK3PIC,1,T_ZombieRisen,&s_zombie_alive1};
-
-statetype s_zombie_pause = {ZOMB_WALK1PIC,20,NULL,&s_zombie_alive1};
-
-statetype s_zombie_inground = {0,13,T_Zombie,&s_zombie_inground};
-
-statetype s_zombie_rise1 = {ZOMB_APPEAR1PIC,24,NULL,&s_zombie_rise2};
-statetype s_zombie_rise2 = {ZOMB_APPEAR2PIC,24,NULL,&s_zombie_rise3};
-statetype s_zombie_rise3 = {ZOMB_APPEAR3PIC,24,NULL,&s_zombie_rise4};
-statetype s_zombie_rise4 = {ZOMB_APPEAR4PIC,24,NULL,&s_zombie_risen};
-
-statetype s_zombie_alive1 = {ZOMB_WALK1PIC,13,T_Zombie,&s_zombie_alive2};
-statetype s_zombie_alive2 = {ZOMB_WALK2PIC,13,T_Zombie,&s_zombie_alive3};
-statetype s_zombie_alive3 = {ZOMB_WALK3PIC,13,T_Zombie,&s_zombie_alive1};
-
-statetype s_zombie_death1 = {ZOMB_DIE1PIC,16,NULL,&s_zombie_death2};
-statetype s_zombie_death2 = {ZOMB_DIE2PIC,16,NULL,&s_zombie_death3};
-statetype s_zombie_death3 = {ZOMB_DIE3PIC,16,NULL,&s_zombie_death3};
-
-statetype s_zombie_attack = {ZOMB_ATTACKPIC,15,T_DoDamage,&s_zombie_pause};
-//statetype s_zombie_attack1 = {ZOMB_ATTACKPIC,15,NULL,&s_zombie_pause};
-
-statetype s_zombie_ouch = {ZOMB_OUCHPIC,15,NULL,&s_zombie_alive1};
-
-
-
-
-enum zombie_modes {zm_wait_for_dark,zm_wait_to_rise,zm_active};
-
-#define zombie_mode ob->temp1
-#define zombie_delay ob->temp2
-
-
-//--------------------------------------------------------------------------
-// SpawnZombie()
-//--------------------------------------------------------------------------
-void SpawnZombie (int tilex, int tiley)
-{
- objtype *ob;
- short current_zombie_delay;
- unsigned tile;
-
- SpawnNewObj(tilex,tiley,&s_zombie_inground,35*PIXRADIUS);
- ob = new;
- zombie_mode = zm_wait_for_dark;
-
- tile = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);
- if (tile)
- zombie_delay = (tile>>8)*30;
- else
- {
- current_zombie_delay = (2*60)+random(4*60);
- zombie_delay = zombie_base_delay+current_zombie_delay;
- zombie_base_delay += current_zombie_delay;
- if (zombie_base_delay > 8*60)
- zombie_base_delay = 0;
- }
-
- new->speed = 2500;
- new->obclass = zombieobj;
- new->hitpoints = EasyHitPoints(5);
- new->active = yes;
- new->flags &= ~of_shootable;
-}
-
-//--------------------------------------------------------------------------
-// T_Zombie()
-//--------------------------------------------------------------------------
-void T_Zombie (objtype *ob)
-{
- switch (zombie_mode)
- {
- case zm_wait_for_dark:
- if (gamestate.mapon == 0)
- {
- if (BGFLAGS & BGF_NIGHT)
- zombie_mode = zm_wait_to_rise;
- }
- else
- zombie_mode = zm_wait_to_rise;
- break;
-
- case zm_wait_to_rise:
- if (zombie_delay < 0)
+ case wt_CORNER1:
+ case wt_CORNER2:
+ case wt_CORNER3:
+ case wt_CORNER4:
+ ob->flags &= ~of_shootable;
+ if ((WD_TIMEREMAIN -= realtics) < 0)
{
- if ((ob->tilex == player->tilex) && (ob->tiley == player->tiley))
- break;
-
- ob->active = always;
- ob->state = &s_zombie_rise1;
- ob->ticcount = ob->state->tictime; // JIM Added
- zombie_mode = zm_active;
+ WD_STAGE = wt_BUBBLES;
+ ob->flags &= ~WATER_DRAGON_LEAVE;
}
else
- zombie_delay -= tics;
-
- break;
-
- case zm_active:
- if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
{
- ob->state = &s_zombie_attack;
- ob->ticcount = ob->state->tictime;
- return;
- }
- break;
- }
-}
-
-//--------------------------------------------------------------------------
-// T_ZombieRisen()
-//--------------------------------------------------------------------------
-void T_ZombieRisen(objtype *obj)
-{
- obj->flags |= of_shootable;
-}
-
-
-
-/*
-=============================================================================
-
- SPOOKS
-
-=============================================================================
-*/
-
-void T_Spook(objtype *ob);
-
-statetype s_spook_wait = {0,10,T_Spook,&s_spook_wait};
-
-statetype s_spook0 = {SPOOK_INOUTPIC,7,NULL,&s_spook0_1};
-statetype s_spook0_1 = {0,7,NULL,&s_spook0_2};
-statetype s_spook0_2 = {SPOOK_INOUTPIC,7,NULL,&s_spook1};
-
-statetype s_spook1 = {SPOOK1PIC,10,NULL,&s_spook2};
-statetype s_spook2 = {SPOOK2PIC,10,T_Spook,&s_spook3};
-statetype s_spook3 = {SPOOK3PIC,10,T_Spook,&s_spook4};
-statetype s_spook4 = {SPOOK4PIC,10,T_Spook,&s_spook5};
-statetype s_spook5 = {SPOOK3PIC,10,T_Spook,&s_spook6};
-statetype s_spook6 = {SPOOK2PIC,10,T_Spook,&s_spook1};
-
-statetype s_spook_attack1 = {SPOOK_ATTACKPIC,35,NULL,&s_spook_attack3};
-statetype s_spook_attack3 = {SPOOK3PIC,20,T_DoDamage,&s_spook1};
-
-statetype s_spook_pause = {SPOOK1PIC,20,NULL,&s_spook1};
-
-statetype s_spookouch = {SPOOKHITPIC,5,NULL,&s_spook1};
-
-statetype s_spookdie = {SPOOK_INOUTPIC,9,NULL,&s_spookdie1};
-statetype s_spookdie1 = {SPOOK4PIC,9,NULL,&s_spookdie2};
-statetype s_spookdie2 = {SPOOK_INOUTPIC,9,NULL,&s_spookdie3};
-statetype s_spookdie3 = {SPOOK4PIC,9,NULL,&s_spookdie4};
-statetype s_spookdie4 = {SPOOK_INOUTPIC,9,NULL,&s_spookdie5};
-statetype s_spookdie5 = {0,11,NULL,NULL};
-
-#define spook_mode ob->temp1
-#define spook_delay ob->temp2
-
-/*
-===============
-=
-= SpawnSpook
-=
-===============
-*/
-void SpawnSpook(int tilex, int tiley)
-{
- objtype *ob;
- unsigned tile;
- SpawnNewObj(tilex,tiley,&s_spook_wait,PIXRADIUS*35);
- ob = new;
-
- tile = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);
- if (tile)
- spook_delay = (tile>>8)*30;
- else
- spook_delay = 2*60+random(5*60);
-
- spook_mode = zm_wait_for_dark;
-
- new->active = yes;
- new->obclass = spookobj;
- new->speed = 1900;
- new->flags &= ~of_shootable;
- new->hitpoints = EasyHitPoints(5);
-}
+ fixed tempx,tempy;
+ unsigned temp_tilex,temp_tiley;
+ tempx = player->x;
+ tempy = player->y;
+ temp_tilex = player->tilex;
+ temp_tiley = player->tiley;
-/*
-===============
-=
-= T_Spook
-=
-===============
-*/
-void T_Spook(objtype *ob)
-{
- switch (zombie_mode)
- {
- case zm_wait_for_dark:
- if (!gamestate.mapon)
- {
- if (BGFLAGS & BGF_NIGHT)
- spook_mode = zm_wait_to_rise;
- }
- else
- spook_mode = zm_wait_to_rise;
- break;
+ player->x = ((long)other_x[WD_STAGE-2]<<TILESHIFT)+TILEGLOBAL/2;
+ player->y = ((long)other_y[WD_STAGE-2]<<TILESHIFT)+TILEGLOBAL/2;
+ player->tilex = other_x[WD_STAGE-2];
+ player->tiley = other_y[WD_STAGE-2];
- case zm_wait_to_rise:
- spook_delay -= tics;
- if (spook_delay < 0)
- {
- if ((ob->tilex == player->tilex) && (ob->tiley == player->tiley))
- break;
- ob->active = always;
- ob->flags |= of_shootable;
- ob->state = &s_spook0;
- ob->ticcount = ob->state->tictime;
- spook_mode = zm_active;
- }
- else
- spook_delay -= tics;
- break;
+ Chase(ob,true);
- case zm_active:
- if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
- {
- ob->state = &s_spook_attack1;
- ob->ticcount = ob->state->tictime;
- return;
+ player->x = tempx;
+ player->y = tempy;
+ player->tilex = temp_tilex;
+ player->tiley = temp_tiley;
}
- break;
- }
-}
-
-
-/*
-=============================================================================
-
- SKELETON IN WALL
-
-=============================================================================
-*/
-
-void T_WallSkeleton(objtype *ob);
-
-extern statetype s_skel_1;
-
-statetype s_wallskel = {0,40,T_WallSkeleton,&s_wallskel};
-statetype s_wallskel2 = {0,1,NULL,NULL};
-
-
-enum wskel_modes {ws_wall1,ws_wall2,ws_wall3,ws_exit};
-
-#define wskel_mode ob->temp1
-#define wskel_delay ob->temp2
-#define wskel_base ob->angle
-#define wskel_wallx ob->hitpoints
-#define wskel_wally ob->speed
-
-/*
-===============
-=
-= SpawnWallSkeleton
-=
-===============
-*/
-void SpawnWallSkeleton(int tilex, int tiley)
-{
- char xofs[] = {0,0,-1,+1};
- char yofs[] = {-1,+1,0,0};
-
- objtype *ob;
- int wallx=tilex,wally=tiley,wallbase,wallmode,loop;
- unsigned tile,current_delay;
-
- for (loop=0; loop<4; loop++)
- {
- tile = *(mapsegs[0]+farmapylookup[tiley+yofs[loop]]+tilex+xofs[loop]);
- switch (tile)
- {
- case WALL_SKELETON_CODE:
- case WALL_SKELETON_CODE+1:
- case WALL_SKELETON_CODE+2:
- wallmode = ws_wall1+(tile-WALL_SKELETON_CODE);
- wallbase = WALL_SKELETON_CODE;
- goto foundtile;
- break;
-
- case 41:
- case 43:
- wallmode = ws_wall1+(tile-41);
- wallbase = 41;
- goto foundtile;
- break;
-
- case 42:
- case 44:
- wallmode = ws_wall1+(tile-42);
- wallbase = 42;
- goto foundtile;
break;
- }
- }
-
- return;
-foundtile:;
-
- wallx += xofs[loop];
- wally += yofs[loop];
-
- SpawnNewObj(tilex,tiley,&s_wallskel,PIXRADIUS*35);
- ob = new;
- new->obclass = wallskelobj;
- new->speed = 1900;
- new->flags &= ~of_shootable;
- new->hitpoints = EasyHitPoints(5);
-
-// new->tilex = wallx;
-// new->tiley = wally;
- wskel_wallx = wallx;
- wskel_wally = wally;
- wskel_base = wallbase;
- new->active = no;
-
- wskel_mode = wallmode;
-
- tile = *(mapsegs[2]+farmapylookup[wally]+wallx);
- if (tile)
- wskel_delay = (tile>>8)*30;
- else
- {
- current_delay = (2*60)+random(4*60);
- wskel_delay = zombie_base_delay+current_delay;
- zombie_base_delay += current_delay;
- if (zombie_base_delay > 8*60)
- zombie_base_delay = 0;
- }
-}
-
-/*
-===============
-=
-= T_WallSkeleton
-=
-===============
-*/
-void T_WallSkeleton(objtype *ob)
-{
- int x=wskel_wallx,y=wskel_wally;
-
- wskel_delay -= realtics;
- if (wskel_delay > 0)
- return;
-
- switch (wskel_mode)
- {
- case ws_wall2:
- if ((wskel_base == 41) || (wskel_base == 42))
- wskel_mode++;
- case ws_wall1:
- case ws_wall3:
- (unsigned)actorat[x][y]
- = tilemap[x][y]
- = *(mapsegs[0]+farmapylookup[y]+x)
- = wskel_base+(wskel_mode-ws_wall1);
-
- wskel_mode++;
- wskel_delay = (120);
- ob->active = always;
- break;
-
- case ws_exit:
-// wskel_delay = 0;
-// if (objectcount >= MAXACTORS-3)
-// break;
-
- (unsigned)actorat[x][y]
- = tilemap[x][y]
- = *(mapsegs[0]+farmapylookup[y]+x)
- = wskel_base;
- ob->tilex = ob->x >> TILESHIFT;
- ob->tiley = ob->y >> TILESHIFT;
-
- ob->obclass = skeletonobj;
- ob->speed = 2036;
- ob->flags |= of_shootable;
- ob->hitpoints = EasyHitPoints(12);
- ob->state = &s_skel_1;
- ob->ticcount = ob->state->tictime;
-
-// SpawnSkeleton(ob->tilex,ob->tiley);
-// ob->state = NULL;
- break;
- }
-}
-
-
-/*
-=============================================================================
-
- SKELETONS
-
-=============================================================================
-*/
-
-void T_Skeleton(objtype *ob);
-
-
-
-
-statetype s_skel_pause = {SKELETON_1PIC,40,NULL,&s_skel_2};
-
-statetype s_skel_1 = {SKELETON_1PIC,10,T_Skeleton,&s_skel_2};
-statetype s_skel_2 = {SKELETON_2PIC,10,T_Skeleton,&s_skel_3};
-statetype s_skel_3 = {SKELETON_3PIC,10,T_Skeleton,&s_skel_4};
-statetype s_skel_4 = {SKELETON_4PIC,10,T_Skeleton,&s_skel_1};
-
-statetype s_skel_attack1 = {SKELETON_ATTACK_1PIC,12,NULL,&s_skel_attack2};
-statetype s_skel_attack2 = {SKELETON_ATTACK_2PIC,12,NULL,&s_skel_attack3};
-statetype s_skel_attack3 = {SKELETON_ATTACK_3PIC,12,T_DoDamage,&s_skel_pause};
-
-statetype s_skel_ouch = {SKELETON_OUCHPIC,8,NULL,&s_skel_1};
-
-statetype s_skel_die1 = {SKELETON_OUCHPIC,18,NULL,&s_skel_die2};
-statetype s_skel_die2 = {SKELETON_DEATH_1PIC,18,NULL,&s_skel_die3};
-statetype s_skel_die3 = {SKELETON_DEATH_2PIC,18,NULL,&s_skel_die3};
-
-/*
-===============
-=
-= SpawnSkeleton
-=
-===============
-*/
-void SpawnSkeleton(int tilex, int tiley)
-{
- SpawnNewObj(tilex,tiley,&s_skel_1,PIXRADIUS*35);
- new->obclass = skeletonobj;
- new->speed = 2036;
- new->flags |= of_shootable;
- new->hitpoints = EasyHitPoints(12);
-}
-
-
-/*
-===============
-=
-= T_Skeleton
-=
-===============
-*/
-
-void T_Skeleton(objtype *ob)
-{
- if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
- {
- ob->state = &s_skel_attack1;
- ob->ticcount = ob->state->tictime;
- return;
- }
-}
-
-/*
-=============================================================================
-
- EYE
-
-=============================================================================
-*/
-
-void T_Eye(objtype *ob);
-boolean T_EyeShoot (objtype *ob, boolean eyeshot);
-
-
-
-
-statetype s_eye_pause = {EYE_WALK1PIC,40,NULL,&s_eye_2};
-
-statetype s_eye_1 = {EYE_WALK1PIC,20,T_Eye,&s_eye_2};
-statetype s_eye_2 = {EYE_WALK2PIC,20,T_Eye,&s_eye_3};
-statetype s_eye_3 = {EYE_WALK3PIC,20,T_Eye,&s_eye_4};
-statetype s_eye_4 = {EYE_WALK2PIC,20,T_Eye,&s_eye_1};
-
-statetype s_eye_ouch = {EYE_OUCH1PIC,8,NULL,&s_eye_ouch2};
-statetype s_eye_ouch2 = {EYE_OUCH2PIC,8,NULL,&s_eye_1};
-
-statetype s_eye_die1 = {EYE_DEATH1PIC,22,NULL,&s_eye_die2};
-statetype s_eye_die2 = {EYE_DEATH2PIC,22,NULL,&s_eye_die3};
-statetype s_eye_die3 = {EYE_DEATH2PIC,22,NULL,NULL};
-
-extern statetype s_eshot2;
-
-statetype s_eshot1 = {EYE_SHOT1PIC,8,&T_ShootPlayer,&s_eshot2};
-statetype s_eshot2 = {EYE_SHOT2PIC,8,&T_ShootPlayer,&s_eshot1};
-
-enum eye_modes {em_other1,em_player1,em_other2,em_player2,em_other3,em_player3,em_other4,em_player4};
-
-#define eye_mode ob->temp1
-#define eye_delay ob->temp2
-
-//-------------------------------------------------------------------------
-// SpawnEye()
-//-------------------------------------------------------------------------
-void SpawnEye(int tilex, int tiley)
-{
- objtype *ob;
-
- SpawnNewObj(tilex,tiley,&s_eye_1,PIXRADIUS*35);
- ob = new;
- new->obclass = eyeobj;
- new->speed = 1200;
- new->flags |= of_shootable;
- new->hitpoints = EasyHitPoints(14);
- eye_mode = em_other1;
-}
-
-
-//-------------------------------------------------------------------------
-// T_Eye()
-//-------------------------------------------------------------------------
-void T_Eye(objtype *ob)
-{
- fixed tempx,tempy;
- unsigned temp_tilex,temp_tiley;
-
- eye_delay -= realtics;
- if (eye_delay < 0)
- {
- eye_mode = random(em_player4);
- eye_delay = (10*60);
- }
-
- tempx = player->x;
- tempy = player->y;
- temp_tilex = player->tilex;
- temp_tiley = player->tiley;
-
-
- switch (eye_mode)
- {
- case em_other1:
- case em_other2:
- case em_other3:
- case em_other4:
- player->x = ((long)other_x[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;
- player->y = ((long)other_y[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;
- player->tilex = other_x[eye_mode];
- player->tiley = other_y[eye_mode];
- break;
- }
-
- if (Chase(ob,true))
- eye_delay = 0;
-
- player->x = tempx;
- player->y = tempy;
- player->tilex = temp_tilex;
- player->tiley = temp_tiley;
-
- if (!random(2))
- ShootPlayer(ob,eshotobj,ESHOTSPEED,&s_eshot1);
-}
-
-/*
-=============================================================================
-
- ORCS
-
-=============================================================================
-*/
-
-void T_Orc (objtype *ob);
-
-extern statetype s_orcpause;
-
-extern statetype s_orc1;
-extern statetype s_orc2;
-extern statetype s_orc3;
-extern statetype s_orc4;
-
-extern statetype s_orcattack1;
-extern statetype s_orcattack2;
-extern statetype s_orcattack3;
-
-extern statetype s_orcouch;
-
-extern statetype s_orcdie1;
-extern statetype s_orcdie2;
-extern statetype s_orcdie3;
-
-
-
-statetype s_orcpause = {ORC1PIC,40,NULL,&s_orc2};
-
-statetype s_orc1 = {ORC1PIC,20,T_Orc,&s_orc2};
-statetype s_orc2 = {ORC2PIC,20,T_Orc,&s_orc3};
-statetype s_orc3 = {ORC3PIC,20,T_Orc,&s_orc4};
-statetype s_orc4 = {ORC4PIC,20,T_Orc,&s_orc1};
-
-statetype s_orcattack1 = {ORCATTACK1PIC,20,NULL,&s_orcattack2};
-statetype s_orcattack2 = {ORCATTACK2PIC,20,NULL,&s_orcattack3};
-statetype s_orcattack3 = {ORCATTACK2PIC,30,T_DoDamage,&s_orcpause};
-
-statetype s_orcouch = {ORCOUCHPIC,15,NULL,&s_orc1};
-
-statetype s_orcdie1 = {ORCDIE1PIC,18,NULL,&s_orcdie2};
-statetype s_orcdie2 = {ORCDIE2PIC,18,NULL,&s_orcdie3};
-statetype s_orcdie3 = {ORCDIE3PIC,0,NULL,&s_orcdie3};
-
-
-/*
-===============
-=
-= SpawnOrc
-=
-===============
-*/
-
-void SpawnOrc (int tilex, int tiley)
-{
- SpawnNewObj(tilex,tiley,&s_orc1,PIXRADIUS*35);
- new->obclass = orcobj;
- new->speed = 1536;
- new->flags |= of_shootable;
- new->hitpoints = EasyHitPoints(6);
-}
-
-
-/*
-===============
-=
-= T_Orc
-=
-===============
-*/
-
-void T_Orc (objtype *ob)
-{
- if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
- {
- ob->state = &s_orcattack1;
- ob->ticcount = ob->state->tictime;
- return;
- }
-}
-
-
-/*
-=============================================================================
-
- DEMON
-
-=============================================================================
-*/
-
-void T_Demon (objtype *ob);
-
-
-extern statetype s_demonpause;
-
-extern statetype s_demon1;
-extern statetype s_demon2;
-extern statetype s_demon3;
-extern statetype s_demon4;
-
-extern statetype s_demonattack1;
-extern statetype s_demonattack2;
-extern statetype s_demonattack3;
-
-extern statetype s_demonouch;
-
-extern statetype s_demondie1;
-extern statetype s_demondie2;
-extern statetype s_demondie3;
-
-
-statetype s_demonpause = {DEMON1PIC,40,NULL,&s_demon2};
-
-statetype s_demon1 = {DEMON1PIC,20,T_Demon,&s_demon2};
-statetype s_demon2 = {DEMON2PIC,20,T_Demon,&s_demon3};
-statetype s_demon3 = {DEMON3PIC,20,T_Demon,&s_demon4};
-statetype s_demon4 = {DEMON4PIC,20,T_Demon,&s_demon1};
-
-statetype s_demonattack1 = {DEMONATTACK1PIC,20,NULL,&s_demonattack2};
-statetype s_demonattack2 = {DEMONATTACK2PIC,20,NULL,&s_demonattack3};
-statetype s_demonattack3 = {DEMONATTACK3PIC,30,T_DoDamage,&s_demonpause};
-
-statetype s_demonouch = {DEMONOUCHPIC,15,T_Demon,&s_demon1};
-
-statetype s_demondie1 = {DEMONDIE1PIC,40,NULL,&s_demondie2};
-statetype s_demondie2 = {DEMONDIE2PIC,30,NULL,&s_demondie3};
-statetype s_demondie3 = {DEMONDIE3PIC,0,NULL,&s_demondie3};
-
-
-
-/*
-===============
-=
-= SpawnDemon
-=
-===============
-*/
-
-void SpawnDemon (int tilex, int tiley)
-{
- SpawnNewObj(tilex,tiley,&s_demon1,PIXRADIUS*35);
- new->obclass = demonobj;
- new->speed = 2048;
- new->flags |= of_shootable;
- new->hitpoints = EasyHitPoints(50);
-}
-
-
-/*
-===============
-=
-= T_Demon
-=
-===============
-*/
-
-void T_Demon (objtype *ob)
-{
- if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
- {
- ob->state = &s_demonattack1;
- ob->ticcount = ob->state->tictime;
- return;
- }
-}
-
-
-/*
-=============================================================================
-
- MAGE
-
-=============================================================================
-*/
-
-
-void T_Mage (objtype *ob);
-void T_MageShoot (objtype *ob);
-
-extern statetype s_magepause;
-
-extern statetype s_mage1;
-extern statetype s_mage2;
-
-extern statetype s_mageattack1;
-extern statetype s_mageattack2;
-extern statetype s_mageattack3;
-
-extern statetype s_mageouch;
-
-extern statetype s_magedie1;
-extern statetype s_magedie2;
-
-
-statetype s_magepause = {MAGE1PIC,10,NULL,&s_mage2};
-
-statetype s_mage1 = {MAGE1PIC,20,T_Mage,&s_mage2};
-statetype s_mage2 = {MAGE2PIC,20,T_Mage,&s_mage1};
-
-//statetype s_mageattack1 = {MAGEATTACKPIC,20,NULL,&s_mageattack2};
-//statetype s_mageattack2 = {MAGEATTACKPIC,-1,T_MageShoot,&s_mageattack3};
-statetype s_mageattack3 = {MAGEATTACKPIC,30,NULL,&s_magepause};
-
-statetype s_mageouch = {MAGEOUCHPIC,10,NULL,&s_mage1};
-
-statetype s_magedie1 = {MAGEDIE1PIC,20,NULL,&s_magedie2};
-statetype s_magedie2 = {MAGEDIE2PIC,0,NULL,&s_magedie2};
-
-
-statetype s_mshot1 = {PSHOT1PIC,8,&T_ShootPlayer,&s_mshot2};
-statetype s_mshot2 = {PSHOT2PIC,8,&T_ShootPlayer,&s_mshot1};
-
-/*
-===============
-=
-= SpawnMage
-=
-===============
-*/
-
-void SpawnMage (int tilex, int tiley)
-{
- SpawnNewObj(tilex,tiley,&s_mage1,PIXRADIUS*35);
- new->obclass = mageobj;
- new->speed = 3072;
- new->flags |= of_shootable;
- new->hitpoints = EasyHitPoints(5);
-}
-
-
-/*
-===============
-=
-= T_Mage
-=
-===============
-*/
-
-void T_Mage (objtype *ob)
-{
- fixed tempx,tempy;
- unsigned temp_tilex,temp_tiley;
-
- eye_delay -= realtics;
- if (eye_delay < 0)
- {
- eye_mode = random(em_player4);
- eye_delay = (10*60);
- }
-
- tempx = player->x;
- tempy = player->y;
- temp_tilex = player->tilex;
- temp_tiley = player->tiley;
-
-
- switch (eye_mode)
- {
- case em_other1:
- case em_other2:
- case em_other3:
- case em_other4:
- player->x = ((long)other_x[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;
- player->y = ((long)other_y[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;
- player->tilex = other_x[eye_mode];
- player->tiley = other_y[eye_mode];
- break;
- }
-
- if (Chase(ob,true))
- eye_delay = 0;
-
- player->x = tempx;
- player->y = tempy;
- player->tilex = temp_tilex;
- player->tiley = temp_tiley;
-
- if (!random(10))
- if (ShootPlayer(ob,mshotobj,MSHOTSPEED,&s_mshot1))
- {
- ob->state = &s_mageattack3;
- ob->ticcount = ob->state->tictime;
- }
-}
-
-/*
-=============================================================================
-
- RED DEMON
-
-=============================================================================
-*/
-
-void T_RedDemon (objtype *ob);
-
-extern statetype s_red_demonpause;
-
-extern statetype s_red_demon1;
-extern statetype s_red_demon2;
-extern statetype s_red_demon3;
-extern statetype s_red_demon4;
-
-extern statetype s_red_demonattack1;
-extern statetype s_red_demonattack2;
-extern statetype s_red_demonattack3;
-
-extern statetype s_red_demonouch;
-
-extern statetype s_red_demondie1;
-extern statetype s_red_demondie2;
-extern statetype s_red_demondie3;
-
-statetype s_red_demonpause = {RED_DEMON1PIC,40,NULL,&s_red_demon2};
-
-statetype s_red_demon1 = {RED_DEMON1PIC,20,T_RedDemon,&s_red_demon2};
-statetype s_red_demon2 = {RED_DEMON2PIC,20,T_RedDemon,&s_red_demon3};
-statetype s_red_demon3 = {RED_DEMON3PIC,20,T_RedDemon,&s_red_demon4};
-statetype s_red_demon4 = {RED_DEMON4PIC,20,T_RedDemon,&s_red_demon1};
-
-statetype s_red_demonattack1 = {RED_DEMONATTACK1PIC,20,NULL,&s_red_demonattack2};
-statetype s_red_demonattack2 = {RED_DEMONATTACK2PIC,20,NULL,&s_red_demonattack3};
-statetype s_red_demonattack3 = {RED_DEMONATTACK3PIC,30,T_DoDamage,&s_red_demon2};
-
-statetype s_red_demonouch = {RED_DEMONOUCHPIC,15,T_RedDemon,&s_red_demon1};
-
-statetype s_red_demondie1 = {RED_DEMONDIE1PIC,40,NULL,&s_red_demondie2};
-statetype s_red_demondie2 = {RED_DEMONDIE2PIC,30,NULL,&s_red_demondie3};
-statetype s_red_demondie3 = {RED_DEMONDIE3PIC,0,NULL,&s_red_demondie3};
-
-
-
-/*
-===============
-=
-= SpawnRedDemon
-=
-===============
-*/
-
-void SpawnRedDemon (int tilex, int tiley)
-{
- SpawnNewObj(tilex,tiley,&s_red_demon1,PIXRADIUS*35);
- new->obclass = reddemonobj;
- new->speed = 2048;
- new->flags |= of_shootable;
- new->hitpoints = EasyHitPoints(50);
-}
-
-
-/*
-===============
-=
-= T_RedDemon
-=
-===============
-*/
-
-void T_RedDemon (objtype *ob)
-{
- if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
- {
- ob->state = &s_red_demonattack1;
- ob->ticcount = ob->state->tictime;
- return;
}
}
-
-/*
-=============================================================================
-
- GRELMINAR
-
-=============================================================================
-*/
-
-
-void T_Grelminar (objtype *ob);
-void T_GrelminarShoot (objtype *ob);
-void T_Grelm_DropKey(objtype *ob);
-
-extern statetype s_grelpause;
-
-extern statetype s_grel1;
-extern statetype s_grel2;
-
-extern statetype s_grelattack1;
-extern statetype s_grelattack2;
-extern statetype s_grelattack3;
-
-extern statetype s_grelouch;
-
-extern statetype s_greldie1;
-extern statetype s_greldie2;
-extern statetype s_greldie3;
-extern statetype s_greldie4;
-extern statetype s_greldie5;
-extern statetype s_greldie5a;
-extern statetype s_greldie6;
-
-
-statetype s_grelpause = {GREL1PIC,50,NULL,&s_grel2};
-
-statetype s_grel1 = {GREL1PIC,20,T_Grelminar,&s_grel2};
-statetype s_grel2 = {GREL2PIC,20,T_Grelminar,&s_grel1};
-
-//statetype s_grelattack1 = {GRELATTACKPIC,20,NULL,&s_grelattack2};
-//statetype s_grelattack2 = {GRELATTACKPIC,-1,T_GrelminarShoot,&s_grelattack3};
-statetype s_grelattack3 = {GRELATTACKPIC,30,NULL,&s_grelpause};
-
-statetype s_grelouch = {GRELHITPIC,6,NULL,&s_grel1};
-
-statetype s_greldie1 = {GRELDIE1PIC,22,NULL,&s_greldie2};
-statetype s_greldie2 = {GRELDIE2PIC,22,NULL,&s_greldie3};
-statetype s_greldie3 = {GRELDIE3PIC,22,NULL,&s_greldie4};
-statetype s_greldie4 = {GRELDIE4PIC,22,NULL,&s_greldie5};
-statetype s_greldie5 = {GRELDIE5PIC,22,NULL,&s_greldie5a};
-statetype s_greldie5a = {GRELDIE5PIC,1,T_Grelm_DropKey,&s_greldie6};
-statetype s_greldie6 = {GRELDIE6PIC,0,NULL,&s_greldie6};
-
-
-extern statetype s_gshot1;
-
-statetype s_gshot1 = {SKULL_SHOTPIC,8,T_ShootPlayer,&s_gshot1};
-
-/*
-===============
-=
-= SpawnGrelminar
-=
-===============
-*/
-
-void SpawnGrelminar (int tilex, int tiley)
-{
- SpawnNewObj(tilex,tiley,&s_grel1,PIXRADIUS*35);
- new->obclass = grelmobj;
- new->speed = 2048;
- new->flags |= of_shootable;
- new->hitpoints = EasyHitPoints(100);
-}
-
-
/*
===============
=
-= T_Grelminar
+= T_DragonShoot
=
===============
*/
-
-void T_Grelminar (objtype *ob)
+void T_DragonShoot (objtype *ob)
{
- Chase (ob,false);
-
- if (!random(10))
- if (ShootPlayer(ob,gshotobj,10000,&s_gshot1))
- {
- ob->state = &s_grelattack3;
- }
-}
-
-
-//=================================
-//
-// T_Grelm_DropKey
-//
-//=================================
-void T_Grelm_DropKey(objtype *ob)
-{
- if (ob->temp1)
- return;
-
- SpawnBonus(ob->tilex,ob->tiley,B_RKEY);
- SD_PlaySound(GRELM_DEADSND);
- ob->temp1 = true;
+ ShootPlayer(ob,dshotobj,10000,&s_dragon_shot1);
}
-
-/*
-=============================================================================
-
- BAT
-
-=============================================================================
-*/
-
-void T_Bat (objtype *ob);
-void T_BatPast (objtype *ob);
-
-extern statetype s_bat1;
-extern statetype s_bat2;
-extern statetype s_bat3;
-extern statetype s_bat4;
-
-extern statetype s_batdie1;
-extern statetype s_batdie2;
-
-
-statetype s_bat1 = {BAT1PIC,6,T_Bat,&s_bat2};
-statetype s_bat2 = {BAT2PIC,6,T_Bat,&s_bat3};
-statetype s_bat3 = {BAT3PIC,6,T_Bat,&s_bat4};
-statetype s_bat4 = {BAT4PIC,6,T_Bat,&s_bat1};
-
-statetype s_batpast = {BAT4PIC,80,T_BatPast,&s_bat1};
-
-statetype s_batdie1 = {BATDIE1PIC,18,NULL,&s_batdie2};
-statetype s_batdie2 = {BATDIE2PIC,18,NULL,NULL};
-
-
-/*
-===============
-=
-= SpawnBat
-=
-===============
-*/
-
-void SpawnBat (int tilex, int tiley)
-{
- SpawnNewObj(tilex,tiley,&s_bat1,PIXRADIUS*35);
- new->obclass =batobj;
- new->flags |= of_shootable;
-
- new->hitpoints = 1;
- new->speed = 2000;
-}
-
-
-/*
-==================================
-=
-= BatChaseThink
-=
-==================================
-*/
-
-void BatChaseThink (objtype *obj)
-{
- int deltax,deltay;
-
- deltax=player->tilex - obj->tilex;
- deltay=player->tiley - obj->tiley;
-
- if (deltax>0)
- deltax = 2;
- else if (deltax<0)
- deltax = 0;
- else deltax = 1;
-
- if (deltay>0)
- deltay = 2;
- else if (deltay<0)
- deltay = 0;
- else deltay = 1;
-
- obj->dir = dirtable[deltay*3+deltax];
- if (Walk(obj))
- return;
-
- obj->dir = dirtable[3+deltax];
- if (Walk(obj))
- return;
-
- obj->dir = dirtable[deltay*3+1];
- if (Walk(obj))
- return;
-
- obj->dir = nodir;
-}
-
-
-void BatRunThink (objtype *obj)
-{
- int deltax,deltay;
-
- deltax=player->tilex - obj->tilex;
- deltay=player->tiley - obj->tiley;
-
- if (deltax>=0)
- deltax = 0;
- else
- deltax = 2;
-
- if (deltay>=0)
- deltay = 0;
- else
- deltay = 2;
-
- obj->dir = dirtable[deltay*3+deltax];
- if (Walk(obj))
- return;
-
- obj->dir = dirtable[3+deltax];
- if (Walk(obj))
- return;
-
- obj->dir = dirtable[deltay*3+1];
- Walk(obj);
-}
-
-
-
-/*
-===============
-=
-= T_Bat
-=
-===============
-*/
-
-void T_Bat (objtype *ob)
-{
- long move;
- long deltax,deltay,size;
-
- move = ob->speed*tics;
- size = (long)ob->size + player->size + move;
-
-
- do
- {
- deltax = ob->x - player->x;
- deltay = ob->y - player->y;
-
- if (deltax <= size && deltax >= -size
- && deltay <= size && deltay >= -size && !ob->temp1)
- {
- TakeDamage (4);
- ob->temp1 = 2;
- }
-
- if (move < ob->distance)
- {
- MoveObj (ob,move);
- break;
- }
-
- actorat[ob->tilex][ob->tiley] = 0; // pick up marker from goal
- if (ob->dir == nodir)
- ob->dir = north;
-
- ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
- ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
- move -= ob->distance;
-
- if (ob->temp1)
- {
- Walk (ob); // go straight
- if (!--ob->temp1)
- {
- ob->state = &s_batpast;
- ob->ticcount = ob->state->tictime;
- }
- }
- else
- BatChaseThink (ob); // head towards player
-
- actorat[ob->tilex][ob->tiley] = ob; // set down a new goal marker
- } while (0); // just once
- CalcBounds (ob);
-}
-
-
-/*
-===============
-=
-= T_BatPast
-=
-===============
-*/
-
-void T_BatPast (objtype *ob)
-{
- long move;
- long deltax,deltay,size;
-
- move = ob->speed*tics;
-
- do
- {
- if (move < ob->distance)
- {
- MoveObj (ob,move);
- break;
- }
- actorat[ob->tilex][ob->tiley] = 0; // pick up marker from goal
-
- ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
- ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
- move -= ob->distance;
-
- BatRunThink (ob);
-
- actorat[ob->tilex][ob->tiley] = ob; // set down a new goal marker
- } while (0); //(move)
- CalcBounds (ob);
-}
-
-
-//--------------------------------------------------------------------------
-// ShootPlayer()
-//--------------------------------------------------------------------------
-boolean ShootPlayer(objtype *ob, short obclass, short speed, statetype *state)
-{
- int angle = AngleNearPlayer(ob);
-
- if (angle == -1)
- return(false);
-
- DSpawnNewObjFrac (ob->x,ob->y,state,PIXRADIUS*35);
- new->speed = speed;
- new->obclass = obclass;
- new->active = always;
- new->angle = angle;
-
- return(true);
-}
-
-//--------------------------------------------------------------------------
-// T_ShootPlayer()
-//--------------------------------------------------------------------------
-void T_ShootPlayer(objtype *ob)
-{
- objtype *check;
- long xmove,ymove,speed;
-
- speed = ob->speed*tics;
-
- xmove = FixedByFrac(speed,costable[ob->angle]);
- ymove = -FixedByFrac(speed,sintable[ob->angle]);
-
- if (ShotClipMove(ob,xmove,ymove))
- {
- ob->state = &s_pshot_exp1;
- ob->ticcount = ob->state->tictime;
- return;
- }
-
- ob->tilex = ob->x >> TILESHIFT;
- ob->tiley = ob->y >> TILESHIFT;
-
-// check for collision with wall
-//
- if (tilemap[ob->tilex][ob->tiley])
- {
- SD_PlaySound (SHOOTWALLSND);
- ob->state = &s_pshot_exp1;
- ob->ticcount = s_pshot_exp1.tictime;
- return;
- }
-
-//
-//
- if ( ob->xl <= player->xh
- && ob->xh >= player->xl
- && ob->yl <= player->yh
- && ob->yh >= player->yl)
- {
- switch (ob->obclass)
- {
- case eshotobj:
- TakeDamage (ESHOTDAMAGE);
- break;
-
- case mshotobj:
- TakeDamage (MSHOTDAMAGE);
- break;
-
- case gshotobj:
- TakeDamage (25);
- break;
- }
- ob->state = NULL;
- return;
- }
-
-// check for collision
-//
- for (check = player->next; check; check=check->next)
- if ((ob->flags & of_shootable) && ob->obclass != mageobj
- && ob->xl <= check->xh
- && ob->xh >= check->xl
- && ob->yl <= check->yh
- && ob->yh >= check->yl)
- {
- switch (ob->obclass)
- {
- case eshotobj:
- ShootActor (check,ESHOTDAMAGE);
- break;
-
- case mshotobj:
- ShootActor (check,MSHOTDAMAGE);
- break;
-
- case gshotobj:
- ShootActor (check,25);
- break;
-
- case pshotobj:
- ShootActor (check,25);
- break;
- }
- ob->state = &s_pshot_exp1;
- ob->ticcount = s_pshot_exp1.tictime;
- return;
- }
-}
-
-//-------------------------------------------------------------------------
-// AngleNearPlayer()
-//-------------------------------------------------------------------------
-int AngleNearPlayer(objtype *ob)
-{
- int angle=-1;
- int xdiff = ob->tilex-player->tilex;
- int ydiff = ob->tiley-player->tiley;
-
- if (ob->tiley == player->tiley)
- {
- if (ob->tilex < player->tilex)
- angle = 0;
- else
- angle = 180;
- }
- else
- if (ob->tilex == player->tilex)
- {
- if (ob->tiley < player->tiley)
- angle = 270;
- else
- angle = 90;
- }
- else
- if (xdiff == ydiff)
- if (ob->tilex < player->tilex)
- {
- if (ob->tiley < player->tiley)
- angle = 315;
- else
- angle = 45;
- }
- else
- {
- if (ob->tiley < player->tiley)
- angle = 225;
- else
- angle = 135;
- }
-
- return(angle);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// EasyHitPoints
-//
-// Checks to see if the player has selected the easy mode for playing.
-// If so then the normal hit points are cut in half.
-// This is when the object is spawned.
-//
-// Parms
-// NrmHitPts - the normal hit points
-//
-// Returns
-// Half of NrmHitPts
-//
-/////////////////////////////////////////////////////////////////////////////
-
-int EasyHitPoints(int NrmHitPts)
-{
- if (EASYMODEON) // Wimpy, Wimpy, Wimpy!!!!!
- {
- return(NrmHitPts/4);
- }
- else
- return(NrmHitPts);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// EasyDoDamage
-//
-// Checks to see if the player has selected the easy mode for playing.
-// If so then the normal amount of damage is cut in half.
-// This is called each time a monster does damage.
-//
-// Parms
-// Damage - the normal damage taken
-//
-// Returns
-// Half of Damage
-//
-/////////////////////////////////////////////////////////////////////////////
-
-int EasyDoDamage(int Damage)
-{
- if (EASYMODEON) // Wimpy, Wimpy, Wimpy!!!!!
- return(Damage/2);
- else
- return(Damage);
-}
-
diff --git a/C5_ACT2.C b/C5_ACT2.C
new file mode 100644
index 0000000..fd8633a
--- /dev/null
+++ b/C5_ACT2.C
@@ -0,0 +1,827 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+// C3_PLAY.C
+
+#include "DEF.H"
+#pragma hdrstop
+
+/*
+=============================================================================
+
+ LOCAL CONSTANTS
+
+=============================================================================
+*/
+void SpawnSkeleton(int tilex, int tiley);
+
+#if 0
+#define MSHOTDAMAGE 2
+#define MSHOTSPEED 10000
+
+#define ESHOTDAMAGE 1
+#define ESHOTSPEED 5000
+
+#define SSHOTDAMAGE 3
+#define SSHOTSPEED 6500
+
+#define RANDOM_ATTACK 20
+#endif
+
+/*
+=============================================================================
+
+ GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+boolean ShootPlayer (objtype *ob, short obclass, short speed, statetype *state);
+void T_ShootPlayer(objtype *ob);
+
+/*
+=============================================================================
+
+ LOCAL VARIABLES
+
+=============================================================================
+*/
+
+
+
+/*
+=============================================================================
+
+ SKELETON IN WALL
+
+=============================================================================
+*/
+
+void T_WallSkeleton(objtype *ob);
+
+statetype s_wallskel = {0,40,T_WallSkeleton,&s_wallskel};
+statetype s_wallskel2 = {0,1,NULL,NULL};
+
+
+enum wskel_modes {ws_wall1,ws_wall2,ws_wall3,ws_exit};
+//enum wskel_modes {ws_wall1,ws_exit};
+
+#define wskel_mode ob->temp1
+#define wskel_delay ob->temp2
+#define wskel_base ob->angle
+#define wskel_wallx ob->hitpoints
+#define wskel_wally ob->speed
+
+/*
+===============
+=
+= SpawnWallSkeleton
+=
+===============
+*/
+void SpawnWallSkeleton(int tilex, int tiley)
+{
+ char xofs[] = {0,0,-1,+1};
+ char yofs[] = {-1,+1,0,0};
+
+ objtype *ob;
+ int wallx=tilex,wally=tiley,wallbase,wallmode,loop;
+ unsigned tile,current_delay;
+
+ for (loop=0; loop<4; loop++)
+ {
+ tile = *(mapsegs[0]+farmapylookup[tiley+yofs[loop]]+tilex+xofs[loop]);
+ switch (tile)
+ {
+// case WALL_SKELETON_CODE:
+// case WALL_SKELETON_CODE+1:
+// case WALL_SKELETON_CODE+2:
+// wallmode = ws_wall1+(tile-WALL_SKELETON_CODE);
+// wallbase = WALL_SKELETON_CODE;
+// goto foundtile;
+// break;
+
+ case 66:
+ case 68:
+// case 21:
+ wallmode = ws_wall1+(tile-66);
+ wallbase = 66;
+ goto foundtile;
+// break;
+
+ case 67:
+ case 69:
+ wallmode = ws_wall1+(tile-67);
+ wallbase = 67;
+ goto foundtile;
+// break;
+ }
+ }
+
+ return;
+foundtile:;
+
+ wallx += xofs[loop];
+ wally += yofs[loop];
+
+ SpawnNewObj(tilex,tiley,&s_wallskel,PIXRADIUS*35);
+ ob = new;
+ new->obclass = wallskelobj;
+ new->speed = 1900;
+ new->flags &= ~of_shootable;
+ new->hitpoints = 12;
+
+// new->tilex = wallx;
+// new->tiley = wally;
+ wskel_wallx = wallx;
+ wskel_wally = wally;
+ wskel_base = wallbase;
+ new->active = no;
+
+ wskel_mode = wallmode;
+
+ tile = *(mapsegs[2]+farmapylookup[wally]+wallx);
+ if (tile)
+ wskel_delay = (tile>>8)*30;
+ else
+ {
+ current_delay = (2*60)+random(4*60);
+ wskel_delay = zombie_base_delay+current_delay;
+ zombie_base_delay += current_delay;
+ if (zombie_base_delay > 8*60)
+ zombie_base_delay = 0;
+ }
+}
+
+/*
+===============
+=
+= T_WallSkeleton
+=
+===============
+*/
+void T_WallSkeleton(objtype *ob)
+{
+ int x=wskel_wallx,y=wskel_wally;
+
+ wskel_delay -= realtics;
+ if (wskel_delay > 0)
+ return;
+
+ switch (wskel_mode)
+ {
+ case ws_wall2:
+ if ((wskel_base == 66) || (wskel_base == 67))
+ wskel_mode++;
+ case ws_wall1:
+ case ws_wall3:
+ (unsigned)actorat[x][y]
+ = tilemap[x][y]
+ = *(mapsegs[0]+farmapylookup[y]+x)
+ = wskel_base+(wskel_mode-ws_wall1);
+
+ wskel_mode++;
+ wskel_delay = (120);
+ ob->active = always;
+ break;
+
+ case ws_exit:
+ (unsigned)actorat[x][y]
+ = tilemap[x][y]
+ = *(mapsegs[0]+farmapylookup[y]+x)
+ = 21;
+// = wskel_base;
+ ob->tilex = ob->x >> TILESHIFT;
+ ob->tiley = ob->y >> TILESHIFT;
+
+ ob->obclass = skeletonobj;
+ ob->speed = 2036;
+ ob->flags |= of_shootable;
+ ob->hitpoints = 12;
+ ob->state = &s_skel_1;
+ ob->ticcount = ob->state->tictime;
+ break;
+ }
+}
+
+
+/*
+=============================================================================
+
+ SKELETONS
+
+=============================================================================
+*/
+
+void T_Skeleton(objtype *ob);
+
+
+
+
+statetype s_skel_pause = {SKELETON_1PIC,40,NULL,&s_skel_2};
+
+statetype s_skel_1 = {SKELETON_1PIC,10,T_Skeleton,&s_skel_2};
+statetype s_skel_2 = {SKELETON_2PIC,10,T_Skeleton,&s_skel_3};
+statetype s_skel_3 = {SKELETON_3PIC,10,T_Skeleton,&s_skel_4};
+statetype s_skel_4 = {SKELETON_4PIC,10,T_Skeleton,&s_skel_1};
+
+statetype s_skel_attack1 = {SKELETON_ATTACK_1PIC,12,NULL,&s_skel_attack2};
+statetype s_skel_attack2 = {SKELETON_ATTACK_2PIC,12,NULL,&s_skel_attack3};
+statetype s_skel_attack3 = {SKELETON_ATTACK_3PIC,12,T_DoDamage,&s_skel_pause};
+
+statetype s_skel_ouch = {SKELETON_OUCHPIC,8,NULL,&s_skel_1};
+
+statetype s_skel_die1 = {SKELETON_OUCHPIC,18,NULL,&s_skel_die2};
+statetype s_skel_die2 = {SKELETON_DEATH_1PIC,18,NULL,&s_skel_die3};
+statetype s_skel_die3 = {SKELETON_DEATH_2PIC,18,NULL,&s_skel_die3};
+
+/*
+===============
+=
+= SpawnSkeleton
+=
+===============
+*/
+void SpawnSkeleton(int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_skel_1,PIXRADIUS*35);
+ new->obclass = skeletonobj;
+ new->speed = 2036;
+ new->flags |= of_shootable;
+ new->hitpoints = EasyHitPoints(12);
+}
+
+
+/*
+===============
+=
+= T_Skeleton
+=
+===============
+*/
+
+void T_Skeleton(objtype *ob)
+{
+ if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
+ {
+ ob->state = &s_skel_attack1;
+ ob->ticcount = ob->state->tictime;
+ return;
+ }
+}
+
+/*
+=============================================================================
+
+ EYE
+
+=============================================================================
+*/
+
+void T_EyeMage (objtype *ob);
+boolean T_EyeShoot (objtype *ob, boolean eyeshot);
+void T_EyeShootPlayer (objtype *ob);
+
+extern statetype s_eye_shootplayer_1;
+extern statetype s_eye_shootplayer_2;
+
+statetype s_eye_pause = {EYE_WALK1PIC,40,NULL,&s_eye_2};
+
+statetype s_eye_1 = {EYE_WALK1PIC,20,T_EyeMage,&s_eye_2};
+statetype s_eye_2 = {EYE_WALK2PIC,20,T_EyeMage,&s_eye_3};
+statetype s_eye_3 = {EYE_WALK3PIC,20,T_EyeMage,&s_eye_4};
+statetype s_eye_4 = {EYE_WALK2PIC,20,T_EyeMage,&s_eye_1};
+statetype s_eye_shootplayer_1 = {EYE_SCOWLPIC,1,T_EyeShootPlayer,&s_eye_shootplayer_2};
+statetype s_eye_shootplayer_2 = {EYE_SCOWLPIC,20,NULL,&s_eye_1};
+
+statetype s_eye_ouch = {EYE_OUCH1PIC,8,NULL,&s_eye_ouch2};
+statetype s_eye_ouch2 = {EYE_OUCH2PIC,8,NULL,&s_eye_1};
+
+statetype s_eye_die1 = {EYE_DEATH1PIC,22,NULL,&s_eye_die2};
+statetype s_eye_die2 = {EYE_DEATH2PIC,22,NULL,&s_eye_die3};
+statetype s_eye_die3 = {EYE_DEATH2PIC,22,NULL,NULL};
+
+extern statetype s_eshot2;
+
+statetype s_eshot1 = {EYE_SHOT1PIC,8,&T_ShootPlayer,&s_eshot2};
+statetype s_eshot2 = {EYE_SHOT2PIC,8,&T_ShootPlayer,&s_eshot1};
+
+#define eye_mode ob->temp1
+#define eye_delay ob->temp2
+
+
+//-------------------------------------------------------------------------
+// SpawnEye()
+//-------------------------------------------------------------------------
+void SpawnEye(int tilex, int tiley)
+{
+ objtype *ob;
+
+ SpawnNewObj(tilex,tiley,&s_eye_1,PIXRADIUS*35);
+ ob = new;
+ new->obclass = eyeobj;
+ new->speed = 1200;
+ new->flags |= of_shootable;
+ new->hitpoints = EasyHitPoints(15);
+ eye_mode = em_other1;
+}
+
+
+//---------------------------------------------------------------------------
+// T_EyeShootPlayer
+//---------------------------------------------------------------------------
+void T_EyeShootPlayer (objtype *ob)
+{
+ ShootPlayer(ob,eshotobj,ESHOTSPEED,&s_eshot1);
+}
+
+
+/*
+=============================================================================
+
+ SUCCUBUS
+
+=============================================================================
+*/
+
+void T_Succubus (objtype *ob);
+void T_SuccubusShot (objtype *ob);
+
+extern statetype s_succubus_pause;
+extern statetype s_succubus_walk1;
+extern statetype s_succubus_walk2;
+extern statetype s_succubus_walk3;
+extern statetype s_succubus_walk4;
+extern statetype s_succubus_shot1;
+extern statetype s_succubus_attack1;
+extern statetype s_succubus_attack2;
+extern statetype s_succubus_attack3;
+extern statetype s_succubus_death1;
+extern statetype s_succubus_death2;
+
+statetype s_succubus_pause = {SUCCUBUS_WALK2PIC,10,NULL,&s_succubus_walk3};
+
+statetype s_succubus_walk1 = {SUCCUBUS_WALK1PIC,10,T_EyeMage,&s_succubus_walk2};
+statetype s_succubus_walk2 = {SUCCUBUS_WALK2PIC,10,T_EyeMage,&s_succubus_walk3};
+statetype s_succubus_walk3 = {SUCCUBUS_WALK3PIC,10,T_EyeMage,&s_succubus_walk4};
+statetype s_succubus_walk4 = {SUCCUBUS_WALK4PIC,10,T_EyeMage,&s_succubus_walk1};
+
+statetype s_succubus_attack1 = {SUCCUBUS_ATTACK1PIC,15,NULL,&s_succubus_attack2};
+statetype s_succubus_attack2 = {SUCCUBUS_ATTACK1PIC,-1,T_SuccubusShot,&s_succubus_attack3};
+statetype s_succubus_attack3 = {SUCCUBUS_ATTACK2PIC,15,NULL,&s_succubus_pause};
+
+statetype s_succubus_ouch = {SUCCUBUS_OUCHPIC,15,NULL,&s_succubus_walk1};
+
+statetype s_succubus_death1 = {SUCCUBUS_DEATH1PIC,55,NULL,&s_succubus_death2};
+statetype s_succubus_death2 = {SUCCUBUS_DEATH2PIC,20,NULL,&s_succubus_death2};
+
+statetype s_succubus_shot1 = {SUCCUBUS_SHOT1PIC,12,&T_ShootPlayer,&s_succubus_shot1};
+
+/*
+===============
+=
+= SpawnSuccubus
+=
+===============
+*/
+
+void SpawnSuccubus (int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_succubus_walk1,PIXRADIUS*30);
+ new->obclass = succubusobj;
+ new->speed = 2500;
+ new->flags |= of_shootable;
+ new->hitpoints = EasyHitPoints(12);
+}
+
+/*
+===============
+=
+= T_SuccubusShot
+=
+===============
+*/
+
+void T_SuccubusShot (objtype *ob)
+{
+ ShootPlayer(ob,sshotobj,ob->temp1 ? MSHOTSPEED : SSHOTSPEED,&s_succubus_shot1);
+// ob->state = &s_succubus_attack3;
+// ob->ticcount = ob->temp1 ? 7 : ob->state->tictime;
+}
+
+
+/*
+=============================================================================
+
+ MAGE
+
+=============================================================================
+*/
+
+
+void T_MageShoot (objtype *ob);
+
+extern statetype s_magepause;
+
+extern statetype s_mage1;
+extern statetype s_mage2;
+
+extern statetype s_mageattack1;
+extern statetype s_mageattack2;
+extern statetype s_mageattack3;
+
+extern statetype s_mageouch;
+
+extern statetype s_magedie1;
+extern statetype s_magedie2;
+
+
+statetype s_magepause = {MAGE1PIC,10,NULL,&s_mage2};
+
+statetype s_mage1 = {MAGE1PIC,20,T_EyeMage,&s_mage2};
+statetype s_mage2 = {MAGE2PIC,20,T_EyeMage,&s_mage1};
+
+//statetype s_mageattack1 = {MAGEATTACKPIC,20,NULL,&s_mageattack2};
+//statetype s_mageattack2 = {MAGEATTACKPIC,-1,T_MageShoot,&s_mageattack3};
+statetype s_mageattack3 = {MAGEATTACKPIC,30,NULL,&s_magepause};
+
+statetype s_mageouch = {MAGEOUCHPIC,10,NULL,&s_mage1};
+
+statetype s_magedie1 = {MAGEDIE1PIC,20,NULL,&s_magedie2};
+statetype s_magedie2 = {MAGEDIE2PIC,0,NULL,&s_magedie2};
+
+
+statetype s_mshot1 = {PSHOT1PIC,8,&T_ShootPlayer,&s_mshot2};
+statetype s_mshot2 = {PSHOT2PIC,8,&T_ShootPlayer,&s_mshot1};
+
+/*
+===============
+=
+= SpawnMage
+=
+===============
+*/
+
+void SpawnMage (int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_mage1,PIXRADIUS*35);
+ new->obclass = mageobj;
+ new->speed = 3072;
+ new->flags |= of_shootable;
+ new->hitpoints = EasyHitPoints(12);
+}
+
+
+/*
+===============
+=
+= T_EyeMage
+=
+= **********
+= ***NOTE*** This routine controls the thinks for the Eye, Mage, and Succubus.
+= **********
+=
+===============
+*/
+
+void T_EyeMage (objtype *ob)
+{
+ fixed tempx,tempy;
+ unsigned temp_tilex,temp_tiley;
+ int angle;
+
+ eye_delay -= realtics;
+ if (eye_delay < 0)
+ {
+ eye_mode = random(em_dummy);
+ eye_delay = (10*60);
+ }
+
+ tempx = player->x;
+ tempy = player->y;
+ temp_tilex = player->tilex;
+ temp_tiley = player->tiley;
+
+
+ switch (eye_mode)
+ {
+ case em_other1:
+ case em_other2:
+ case em_other3:
+ case em_other4:
+ player->x = ((long)other_x[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;
+ player->y = ((long)other_y[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;
+ player->tilex = other_x[eye_mode];
+ player->tiley = other_y[eye_mode];
+ break;
+ }
+
+ if (Chase(ob,true))
+ eye_delay = 0;
+
+ player->x = tempx;
+ player->y = tempy;
+ player->tilex = temp_tilex;
+ player->tiley = temp_tiley;
+
+
+ if (ob->obclass == mageobj) // do the mage shot
+ {
+ if (!random(10))
+ if (ShootPlayer(ob,mshotobj,MSHOTSPEED,&s_mshot1))
+ {
+ ob->state = &s_mageattack3;
+ ob->ticcount = ob->state->tictime;
+ }
+ }
+ else
+ if (ob->obclass == succubusobj) // do the succubus shot
+ {
+ angle = AngleNearPlayer(ob); // make sure angle is correct
+ // - see AngleNearPlayer
+ if (!random(5) && (angle != -1)) // if correct angle and random # attack
+ {
+ ob->state = &s_succubus_attack1; // change state to attack
+ ob->ticcount = ob->state->tictime; // init ticcount - otherwise
+ } // object may get hung in a
+ } // endless state
+
+ else
+ {
+ angle = AngleNearPlayer(ob); // do the eye shot
+
+ if (!random(2) && (angle != -1))
+ {
+ ob->state = &s_eye_shootplayer_1;
+ ob->ticcount = ob->state->tictime;
+ }
+ }
+
+}
+
+
+/*
+=============================================================================
+
+ BUNNY
+
+=============================================================================
+*/
+
+void T_HarmlessBunnyWalk(objtype *ob);
+void T_Bunny(objtype *ob);
+
+extern statetype s_bunny_left1;
+extern statetype s_bunny_left2;
+extern statetype s_bunny_left3;
+extern statetype s_bunny_right1;
+extern statetype s_bunny_right2;
+extern statetype s_bunny_right3;
+extern statetype s_bunny_meta1;
+extern statetype s_bunny_meta2;
+extern statetype s_bunny_walk1;
+extern statetype s_bunny_walk2;
+extern statetype s_bunny_attack1;
+extern statetype s_bunny_attack2;
+extern statetype s_bunny_pause;
+extern statetype s_bunny_death1;
+extern statetype s_bunny_death2;
+extern statetype s_bunny_death3;
+
+statetype s_bunny_left1 = {BUNNY_LEFT1PIC, 55, NULL, &s_bunny_left2};
+statetype s_bunny_left2 = {BUNNY_LEFT1PIC, 10, T_HarmlessBunnyWalk, &s_bunny_left1};
+statetype s_bunny_left3 = {BUNNY_LEFT2PIC, 30, NULL, &s_bunny_left1};
+
+statetype s_bunny_right1 = {BUNNY_RIGHT1PIC, 55, NULL, &s_bunny_right2};
+statetype s_bunny_right2 = {BUNNY_RIGHT1PIC, 10, T_HarmlessBunnyWalk, &s_bunny_right1};
+statetype s_bunny_right3 = {BUNNY_RIGHT2PIC, 30, NULL, &s_bunny_right1};
+
+statetype s_bunny_meta1 = {BUNNY_META1PIC, 30, NULL, &s_bunny_meta2};
+statetype s_bunny_meta2 = {BUNNY_META2PIC, 30, NULL, &s_bunny_walk1};
+
+statetype s_bunny_walk1 = {BUNNY_WALK1PIC, 25, T_Bunny, &s_bunny_walk2};
+statetype s_bunny_walk2 = {BUNNY_WALK2PIC, 25, T_Bunny, &s_bunny_walk1};
+
+statetype s_bunny_attack1 = {BUNNY_WALK1PIC, 25, NULL, &s_bunny_attack2};
+statetype s_bunny_attack2 = {BUNNY_WALK2PIC, 25, T_DoDamage, &s_bunny_walk1};
+
+statetype s_bunny_ouch = {BUNNY_OUCHPIC, 30, NULL, &s_bunny_pause};
+statetype s_bunny_pause = {BUNNY_WALK1PIC, 50, T_Bunny, &s_bunny_walk2};
+
+statetype s_bunny_death1 = {BUNNY_OUCHPIC, 40, NULL, &s_bunny_death2};
+statetype s_bunny_death2 = {BUNNY_DEATH1PIC, 50, NULL, &s_bunny_death3};
+statetype s_bunny_death3 = {BUNNY_DEATH2PIC, 20, NULL, &s_bunny_death3};
+
+
+#define bunny_dir_hop ob->temp1
+#define bunny_delay ob->temp2
+#define LEFTSIDE 0x8 // 1=left 0=right --side showing
+
+/*
+===============
+=
+= SpawnBunny
+=
+===============
+*/
+
+void SpawnBunny (int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_bunny_left1,PIXRADIUS*35);
+ new->obclass = hbunnyobj;
+ new->speed = 1947;
+ new->temp1 = (random(3))+2;
+ new->temp2 = random(30);
+ new->flags &= ~of_shootable;
+ new->flags |= LEFTSIDE; //left side showing}
+}
+
+/*
+===============
+=
+= T_HarmlessBunnyWalk
+=
+===============
+*/
+
+
+void T_HarmlessBunnyWalk(objtype *ob)
+{
+ int valid_dir[8][2] = {{6,5}, {7,6}, {4,7}, {5,4}, {3,2}, {0,3}, {1,0}, {2,1}};
+ long move;
+ dirtype player_dir;
+ fixed old_x, old_y;
+ unsigned old_tilex, old_tiley;
+ long old_distance;
+
+
+ ob->temp2 -= realtics;
+ if (ob->temp2 <= 0)
+ {
+ if (CheckHandAttack(ob))
+ {
+ ob->temp2 = -1;
+ return;
+ }
+
+ actorat[ob->tilex][ob->tiley] = 0;
+ ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+ ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+ ob->distance = TILEGLOBAL;
+ ob->state = &s_bunny_meta1;
+ ob->ticcount = ob->state->tictime;
+ ob->obclass = bunnyobj;
+ ob->flags |= of_shootable;
+ ob->hitpoints = EasyHitPoints(10);
+ ob->dir = nodir;
+ ChaseThink(ob,true); // JTR - testing..
+ return;
+ }
+
+ // The direction of the player isn't updated so it must be
+ // calculated. This is done so the correct side (left/right)
+ // of the bunny will be showed.
+
+ if ((player->angle > 337) || (player->angle <= 22))
+ player_dir = east;
+ else
+ if (player->angle <= 67)
+ player_dir = northeast;
+ else
+ if (player->angle <= 112)
+ player_dir = north;
+ else
+ if (player->angle <= 157)
+ player_dir = northwest;
+ else
+ if (player->angle <= 202)
+ player_dir = west;
+ else
+ if (player->angle <= 247)
+ player_dir = southwest;
+ else
+ if (player->angle <= 292)
+ player_dir = south;
+ else
+ if (player->angle <= 337)
+ player_dir = southeast;
+ if (ob->temp1)
+ ob->temp1--;
+ else
+ ob->temp1 = (random(3))+2;
+ if (ob->flags & LEFTSIDE)
+ {
+ if (ob->temp1)
+ {
+ if (valid_dir[player_dir][0] != ob->dir)
+ {
+ ob->dir = valid_dir[player_dir][0];
+ }
+ }
+ else
+ {
+ ob->state = &s_bunny_right1;
+ ob->ticcount = ob->state->tictime;
+ ob->flags &= ~LEFTSIDE;
+ ob->dir = valid_dir[player_dir][1];
+ return;
+ }
+ }
+ else
+ {
+ if (ob->temp1)
+ {
+ if (valid_dir[player_dir][1] != ob->dir)
+ {
+ ob->dir = valid_dir[player_dir][1];
+ }
+ }
+ else
+ {
+ ob->state = &s_bunny_left1;
+ ob->ticcount = ob->state->tictime;
+ ob->flags |= LEFTSIDE;
+ ob->dir = valid_dir[player_dir][2];
+ return;
+ }
+ }
+
+ move = ob->speed*tics;
+
+ do
+ {
+ old_distance = ob->distance;
+ old_x = ob->x;
+ old_y = ob->y;
+ old_tilex = ob->tilex;
+ old_tiley = ob->tiley;
+
+ MoveObj (ob, move);
+
+ ob->tilex = ob->x >> TILESHIFT;
+ ob->tiley = ob->y >> TILESHIFT;
+
+ if (ob->tilex == old_tilex && ob->tiley == old_tiley)
+ {
+ break;
+ }
+ else
+ if (actorat[ob->tilex][ob->tiley] == 0)
+ {
+ actorat[old_tilex][old_tiley] = 0;
+ actorat[ob->tilex][ob->tiley] = ob;
+ ob->distance = TILEGLOBAL;
+ }
+ else
+ {
+ ob->distance = old_distance;
+ ob->x = old_x;
+ ob->y = old_y;
+ ob->tilex = old_tilex;
+ ob->tiley = old_tiley;
+ return;
+ }
+
+ } while (0);
+
+ CalcBounds (ob);
+
+ if (ob->flags & LEFTSIDE)
+ ob->state = &s_bunny_left3;
+ else
+ ob->state = &s_bunny_right3;
+ ob->ticcount = ob->state->tictime;
+}
+
+/*
+===============
+=
+= T_Bunny
+=
+===============
+*/
+
+void T_Bunny(objtype *ob)
+{
+ if (Chase (ob, true) || (random(1000)<RANDOM_ATTACK))
+ {
+ ob->state = &s_bunny_attack1;
+ ob->ticcount = ob->state->tictime;
+ return;
+ }
+}
diff --git a/C5_ACT3.C b/C5_ACT3.C
new file mode 100644
index 0000000..79378d4
--- /dev/null
+++ b/C5_ACT3.C
@@ -0,0 +1,1218 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+// C3_PLAY.C
+
+#include "DEF.H"
+#pragma hdrstop
+
+/*
+=============================================================================
+
+ LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+#if 0
+#define MSHOTDAMAGE 2
+#define MSHOTSPEED 10000
+
+#define ESHOTDAMAGE 1
+#define ESHOTSPEED 5000
+
+#define SSHOTDAMAGE 3
+#define SSHOTSPEED 6500
+
+#define RANDOM_ATTACK 20
+#endif
+
+/*
+=============================================================================
+
+ GLOBAL VARIABLES
+
+=============================================================================
+*/
+
+boolean ShootPlayer (objtype *ob, short obclass, short speed, statetype *state);
+void T_ShootPlayer(objtype *ob);
+
+/*
+=============================================================================
+
+ LOCAL VARIABLES
+
+=============================================================================
+*/
+
+/*
+=============================================================================
+
+ RED DEMON
+
+=============================================================================
+*/
+
+void T_RedDemon (objtype *ob);
+void T_RedDemonCheckCnt (objtype *ob);
+
+extern statetype s_red_demonpause;
+
+extern statetype s_red_demon1;
+extern statetype s_red_demon2;
+extern statetype s_red_demon3;
+extern statetype s_red_demon4;
+
+extern statetype s_red_demonattack1;
+extern statetype s_red_demonattack2;
+extern statetype s_red_demonattack3;
+
+extern statetype s_red_demonouch;
+
+extern statetype s_red_demondie1;
+extern statetype s_red_demondie2;
+extern statetype s_red_demondie3;
+extern statetype s_red_demondie4;
+
+statetype s_red_demonpause = {RED_DEMON1PIC,30,NULL,&s_red_demon2};
+
+statetype s_red_demon1 = {RED_DEMON1PIC,20,T_RedDemon,&s_red_demon2};
+statetype s_red_demon2 = {RED_DEMON2PIC,20,T_RedDemon,&s_red_demon3};
+statetype s_red_demon3 = {RED_DEMON3PIC,20,T_RedDemon,&s_red_demon4};
+statetype s_red_demon4 = {RED_DEMON4PIC,20,T_RedDemon,&s_red_demon1};
+
+statetype s_red_demonattack1 = {RED_DEMONATTACK1PIC,20,NULL,&s_red_demonattack2};
+statetype s_red_demonattack2 = {RED_DEMONATTACK2PIC,20,NULL,&s_red_demonattack3};
+statetype s_red_demonattack3 = {RED_DEMONATTACK3PIC,30,T_DoDamage,&s_red_demon2};
+
+statetype s_red_demonouch = {RED_DEMONOUCHPIC,30,NULL,&s_red_demon1};
+
+statetype s_red_demondie1 = {RED_DEMONOUCHPIC,9,NULL,&s_red_demondie2};
+statetype s_red_demondie2 = {RED_DEMONDIE1PIC,9,T_RedDemonCheckCnt,&s_red_demondie1};
+statetype s_red_demondie3 = {RED_DEMONDIE2PIC,20,NULL,&s_red_demondie4};
+statetype s_red_demondie4 = {RED_DEMONDIE3PIC,10,NULL,&s_red_demondie4};
+
+
+/*
+===============
+=
+= SpawnRedDemon
+=
+===============
+*/
+
+void SpawnRedDemon (int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_red_demon1,PIXRADIUS*35);
+ new->obclass = reddemonobj;
+ new->speed = 2048;
+ new->flags |= of_shootable;
+ new->hitpoints = EasyHitPoints(50);
+ new->temp1 = 25;
+}
+
+
+/*
+===============
+=
+= T_RedDemon
+=
+===============
+*/
+
+void T_RedDemon (objtype *ob)
+{
+ if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
+ {
+ ob->state = &s_red_demonattack1;
+ ob->ticcount = ob->state->tictime;
+ return;
+ }
+}
+
+/*
+===============
+=
+= T_RedDemonCheckCnt
+=
+===============
+*/
+
+void T_RedDemonCheckCnt (objtype *ob)
+{
+ ob->temp1--;
+ if (!ob->temp1)
+ {
+ ob->state = &s_red_demondie3;
+ ob->ticcount = ob->state->tictime;
+ }
+}
+
+
+/*
+=============================================================================
+
+ GRELMINAR
+
+=============================================================================
+*/
+
+
+void T_Grelminar (objtype *ob);
+void T_GrelminarShoot (objtype *ob);
+void T_Grelm_DropKey(objtype *ob);
+
+extern statetype s_grelpause;
+
+extern statetype s_grel1;
+extern statetype s_grel2;
+
+extern statetype s_grelattack1;
+extern statetype s_grelattack2;
+extern statetype s_grelattack3;
+
+extern statetype s_grelouch;
+
+extern statetype s_greldie1;
+extern statetype s_greldie2;
+extern statetype s_greldie3;
+extern statetype s_greldie4;
+extern statetype s_greldie5;
+extern statetype s_greldie5a;
+extern statetype s_greldie6;
+
+
+statetype s_grelpause = {GREL1PIC,50,NULL,&s_grel2};
+
+statetype s_grel1 = {GREL1PIC,20,T_Grelminar,&s_grel2};
+statetype s_grel2 = {GREL2PIC,20,T_Grelminar,&s_grel1};
+
+//statetype s_grelattack1 = {GRELATTACKPIC,20,NULL,&s_grelattack2};
+//statetype s_grelattack2 = {GRELATTACKPIC,-1,T_GrelminarShoot,&s_grelattack3};
+statetype s_grelattack3 = {GRELATTACKPIC,30,NULL,&s_grelpause};
+
+statetype s_grelouch = {GRELHITPIC,6,NULL,&s_grel1};
+
+statetype s_greldie1 = {GRELDIE1PIC,22,NULL,&s_greldie2};
+statetype s_greldie2 = {GRELDIE2PIC,22,NULL,&s_greldie3};
+statetype s_greldie3 = {GRELDIE3PIC,22,NULL,&s_greldie4};
+statetype s_greldie4 = {GRELDIE4PIC,22,NULL,&s_greldie5};
+statetype s_greldie5 = {GRELDIE5PIC,22,NULL,&s_greldie5a};
+statetype s_greldie5a = {GRELDIE5PIC,1,T_Grelm_DropKey,&s_greldie6};
+statetype s_greldie6 = {GRELDIE6PIC,0,NULL,&s_greldie6};
+
+
+extern statetype s_gshot1;
+
+statetype s_gshot1 = {SKULL_SHOTPIC,8,T_ShootPlayer,&s_gshot1};
+
+/*
+===============
+=
+= SpawnGrelminar
+=
+===============
+*/
+
+void SpawnGrelminar (int tilex, int tiley)
+{
+ unsigned Grel_Hard;
+ unsigned DropKey;
+
+ SpawnNewObj(tilex,tiley,&s_grel1,PIXRADIUS*35);
+ new->obclass = grelmobj;
+ new->speed = 2048;
+ new->flags |= of_shootable;
+
+ //
+ // if Grelminar is to drop a key the info-plane byte to the right
+ // should have a 1 in the highbyte, else he will not drop the key.
+ //
+ DropKey = *(mapsegs[2]+farmapylookup[tiley]+tilex+1);
+ if (DropKey)
+ new->temp1 = DropKey>>8;
+ else
+ new->temp1 = 0;
+
+ //
+ // The info-plane byte below Grelminar will determine how powerful
+ // Grelminar is. If nothing is there, he is the most powerful.
+ // -- affected are the hit points and the shot damage.
+ // The hit points are controlled here, the shot damage is controlled
+ // within the spawning of the shot. See ShootPlayer for more info.
+ //
+ Grel_Hard = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);
+ if (Grel_Hard)
+ {
+ new->temp2 = Grel_Hard>>8;
+ new->hitpoints = EasyHitPoints((new->temp2 * 10));
+ }
+ else
+ new->hitpoints = EasyHitPoints(100);
+}
+
+
+/*
+===============
+=
+= T_Grelminar
+=
+===============
+*/
+
+void T_Grelminar (objtype *ob)
+{
+ Chase (ob,false);
+
+ if (!random(10))
+ if (ShootPlayer(ob,gshotobj,ob->temp2,&s_gshot1))
+ {
+ ob->state = &s_grelattack3;
+ ob->ticcount = ob->state->tictime;
+ }
+ if (CheckHandAttack(ob))
+ TakeDamage (ob->temp2*3);
+
+}
+
+
+//=================================
+//
+// T_Grelm_DropKey
+//
+//=================================
+void T_Grelm_DropKey(objtype *ob)
+{
+ if (!(ob->temp1))
+ {
+ ob->state = NULL;
+ return;
+ }
+
+ SpawnBonus(ob->tilex,ob->tiley,B_RKEY);
+ SD_PlaySound(GRELM_DEADSND);
+ ob->temp1 = false;
+}
+
+/*
+=============================================================================
+
+ BAT
+
+=============================================================================
+*/
+
+void T_Bat (objtype *ob);
+void T_BatPast (objtype *ob);
+
+extern statetype s_bat1;
+extern statetype s_bat2;
+extern statetype s_bat3;
+extern statetype s_bat4;
+
+extern statetype s_batdie1;
+extern statetype s_batdie2;
+
+
+statetype s_bat1 = {BAT1PIC,6,T_Bat,&s_bat2};
+statetype s_bat2 = {BAT2PIC,6,T_Bat,&s_bat3};
+statetype s_bat3 = {BAT3PIC,6,T_Bat,&s_bat4};
+statetype s_bat4 = {BAT4PIC,6,T_Bat,&s_bat1};
+
+statetype s_batpast = {BAT4PIC,80,T_BatPast,&s_bat1};
+
+statetype s_batdie1 = {BATDIE1PIC,18,NULL,&s_batdie2};
+statetype s_batdie2 = {BATDIE2PIC,18,NULL,NULL};
+
+
+/*
+===============
+=
+= SpawnBat
+=
+===============
+*/
+
+void SpawnBat (int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_bat1,PIXRADIUS*35);
+ new->obclass = batobj;
+ new->flags |= of_shootable;
+
+ new->hitpoints = 1;
+ new->speed = 2000;
+}
+
+
+/*
+==================================
+=
+= BatChaseThink
+=
+==================================
+*/
+
+void BatChaseThink (objtype *obj)
+{
+ int deltax,deltay;
+
+ deltax=player->tilex - obj->tilex;
+ deltay=player->tiley - obj->tiley;
+
+ if (deltax>0)
+ deltax = 2;
+ else if (deltax<0)
+ deltax = 0;
+ else deltax = 1;
+
+ if (deltay>0)
+ deltay = 2;
+ else if (deltay<0)
+ deltay = 0;
+ else deltay = 1;
+
+ obj->dir = dirtable[deltay*3+deltax];
+ if (Walk(obj))
+ return;
+
+ obj->dir = dirtable[3+deltax];
+ if (Walk(obj))
+ return;
+
+ obj->dir = dirtable[deltay*3+1];
+ if (Walk(obj))
+ return;
+
+ obj->dir = nodir;
+}
+
+
+void BatRunThink (objtype *obj)
+{
+ int deltax,deltay;
+
+ deltax=player->tilex - obj->tilex;
+ deltay=player->tiley - obj->tiley;
+
+ if (deltax>=0)
+ deltax = 0;
+ else
+ deltax = 2;
+
+ if (deltay>=0)
+ deltay = 0;
+ else
+ deltay = 2;
+
+ obj->dir = dirtable[deltay*3+deltax];
+ if (Walk(obj))
+ return;
+
+ obj->dir = dirtable[3+deltax];
+ if (Walk(obj))
+ return;
+
+ obj->dir = dirtable[deltay*3+1];
+ Walk(obj);
+}
+
+
+
+/*
+===============
+=
+= T_Bat
+=
+===============
+*/
+
+void T_Bat (objtype *ob)
+{
+ long move;
+ long deltax,deltay,size;
+
+ move = ob->speed*tics;
+ size = (long)ob->size + player->size + move;
+
+
+ do
+ {
+ deltax = ob->x - player->x;
+ deltay = ob->y - player->y;
+
+ if (deltax <= size && deltax >= -size
+ && deltay <= size && deltay >= -size && !ob->temp1)
+ {
+ TakeDamage (4);
+ ob->temp1 = 2;
+ }
+
+ if (move < ob->distance)
+ {
+ MoveObj (ob,move);
+ break;
+ }
+
+ actorat[ob->tilex][ob->tiley] = 0; // pick up marker from goal
+ if (ob->dir == nodir)
+ ob->dir = north;
+
+ ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+ ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+ move -= ob->distance;
+
+ if (ob->temp1)
+ {
+ Walk (ob); // go straight
+ if (!--ob->temp1)
+ {
+ ob->state = &s_batpast;
+ ob->ticcount = ob->state->tictime;
+ }
+ }
+ else
+ BatChaseThink (ob); // head towards player
+
+ actorat[ob->tilex][ob->tiley] = ob; // set down a new goal marker
+ } while (0); // just once
+ CalcBounds (ob);
+}
+
+
+/*
+===============
+=
+= T_BatPast
+=
+===============
+*/
+
+void T_BatPast (objtype *ob)
+{
+ long move;
+ long deltax,deltay,size;
+
+ move = ob->speed*tics;
+
+ do
+ {
+ if (move < ob->distance)
+ {
+ MoveObj (ob,move);
+ break;
+ }
+ actorat[ob->tilex][ob->tiley] = 0; // pick up marker from goal
+
+ ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;
+ ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;
+ move -= ob->distance;
+
+ BatRunThink (ob);
+
+ actorat[ob->tilex][ob->tiley] = ob; // set down a new goal marker
+ } while (0); //(move)
+ CalcBounds (ob);
+}
+
+
+void T_ChaseThink(objtype *obj);
+void T_AwakeThink(objtype *obj);
+
+
+
+/*
+=============================================================================
+
+ GODESS
+
+=============================================================================
+*/
+
+void T_Godess (objtype *ob);
+
+
+extern statetype s_godesspause;
+
+extern statetype s_godess_statue1;
+extern statetype s_godess_statue2;
+
+extern statetype s_godess1;
+extern statetype s_godess2;
+extern statetype s_godess3;
+
+extern statetype s_godessattack1;
+extern statetype s_godessattack2;
+extern statetype s_godessattack3;
+
+extern statetype s_godessouch;
+
+extern statetype s_godessdie1;
+extern statetype s_godessdie2;
+extern statetype s_godessdie3;
+
+
+statetype s_godesspause = {GODESS_WALK1PIC,25,NULL,&s_godess2};
+
+statetype s_godess_statue1 = {GODESS_STATUEPIC,20,T_ChaseThink,&s_godess_statue1};
+statetype s_godess_statue2 = {GODESS_STATUEPIC,1,T_AwakeThink,&s_godess1};
+
+statetype s_godess1 = {GODESS_WALK1PIC,20,T_ChaseThink,&s_godess2};
+statetype s_godess2 = {GODESS_WALK2PIC,20,T_ChaseThink,&s_godess3};
+statetype s_godess3 = {GODESS_WALK3PIC,20,T_ChaseThink,&s_godess1};
+
+statetype s_godessattack1 = {GODESS_ATTACK1PIC,10,NULL,&s_godessattack2};//20
+statetype s_godessattack2 = {GODESS_ATTACK2PIC,8,NULL,&s_godessattack3};//20
+statetype s_godessattack3 = {GODESS_ATTACK3PIC,10,T_DoDamage,&s_godesspause};//30
+
+statetype s_godessouch = {GODESS_OUCHPIC,10,NULL,&s_godess1};
+
+statetype s_godessdie1 = {GODESS_DEATH1PIC,65,NULL,&s_godessdie2};
+statetype s_godessdie2 = {GODESS_DEATH2PIC,30,NULL,&s_godessdie2};
+
+
+
+/*
+===============
+=
+= SpawnGodess
+=
+===============
+*/
+
+void SpawnGodess (int tilex, int tiley)
+{
+ objtype *ob;
+ short current_zombie_delay;
+ unsigned tile;
+
+ SpawnNewObj(tilex,tiley,&s_godess_statue1,PIXRADIUS*35);
+ ob = new;
+ zombie_mode = zm_wait_for_dark;
+
+ tile = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);
+ if (tile)
+ zombie_delay = (tile>>8)*30;
+ else
+ {
+ current_zombie_delay = (2*60)+random(4*60);
+ zombie_delay = zombie_base_delay+current_zombie_delay;
+ zombie_base_delay += current_zombie_delay;
+ if (zombie_base_delay > 8*60)
+ zombie_base_delay = 0;
+ }
+
+ new->obclass = realsolidobj;//godessobj;
+ new->speed = 3000;
+ new->flags |= of_shootable;
+ new->flags &= ~of_tree;
+// new->hitpoints = EasyHitPoints(10);
+}
+
+
+
+
+/*
+=============================================================================
+
+ ANT
+
+=============================================================================
+*/
+
+void T_Ant(objtype *ob);
+
+statetype s_ant_wait = {ANT_EGG1PIC,10,T_ChaseThink,&s_ant_wait};
+
+statetype s_ant_egg = {ANT_EGG2PIC,45,T_AwakeThink,&s_ant_walk1};
+
+statetype s_ant_walk1 = {ANT_WALK1PIC,20,T_ChaseThink,&s_ant_walk2};
+statetype s_ant_walk2 = {ANT_WALK2PIC,20,T_ChaseThink,&s_ant_walk3};
+statetype s_ant_walk3 = {ANT_WALK3PIC,20,T_ChaseThink,&s_ant_walk1};
+
+statetype s_ant_attack1 = {ANT_ATTACKPIC,20,NULL,&s_ant_pause};
+
+statetype s_ant_pause = {ANT_WALK2PIC,15,T_DoDamage,&s_ant_walk1};
+
+statetype s_ant_ouch = {ANT_WALK1PIC,15,NULL,&s_ant_walk1};
+
+statetype s_ant_die1 = {ANT_DEATH1PIC,40,NULL,&s_ant_die2};
+statetype s_ant_die2 = {ANT_DEATH2PIC,10,NULL,&s_ant_die3};
+statetype s_ant_die3 = {ANT_DEATH3PIC,10,NULL,&s_ant_die2};
+
+#define ant_mode ob->temp1
+#define ant_delay ob->temp2
+
+/*
+===============
+=
+= SpawnAnt
+=
+===============
+*/
+void SpawnAnt(int tilex, int tiley)
+{
+ objtype *ob;
+ unsigned tile;
+ SpawnNewObj(tilex,tiley,&s_ant_wait,PIXRADIUS*35);
+ ob = new;
+
+ tile = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);
+ if (tile)
+ ant_delay = (tile>>8)*30;
+ else
+ ant_delay = 2*60+random(5*60);
+
+ ant_mode = zm_wait_for_dark;
+
+ new->obclass = antobj;
+ new->speed = 1900;
+ new->flags &= ~of_shootable;
+ new->hitpoints = EasyHitPoints(15);
+}
+
+
+
+/*
+=============================================================================
+
+ ZOMBIE
+
+=============================================================================
+*/
+
+extern statetype s_zombie_rise1;
+extern statetype s_zombie_rise2;
+extern statetype s_zombie_rise3;
+extern statetype s_zombie_rise4;
+
+extern statetype s_zombie_alive1;
+extern statetype s_zombie_alive2;
+extern statetype s_zombie_alive3;
+
+//extern statetype s_zombie_attack1;
+
+extern statetype s_zombie_death1;
+extern statetype s_zombie_death2;
+extern statetype s_zombie_death3;
+
+void T_Zombie (objtype *ob);
+void T_ZombieRisen(objtype *obj);
+
+statetype s_zombie_risen = {ZOMB_WALK3PIC,1,T_AwakeThink,&s_zombie_alive1};
+
+statetype s_zombie_pause = {ZOMB_WALK1PIC,20,NULL,&s_zombie_alive1};
+
+statetype s_zombie_inground = {0,13,T_ChaseThink,&s_zombie_inground};
+
+statetype s_zombie_rise1 = {ZOMB_APPEAR1PIC,24,NULL,&s_zombie_rise2};
+statetype s_zombie_rise2 = {ZOMB_APPEAR2PIC,24,NULL,&s_zombie_rise3};
+statetype s_zombie_rise3 = {ZOMB_APPEAR3PIC,24,NULL,&s_zombie_rise4};
+statetype s_zombie_rise4 = {ZOMB_APPEAR4PIC,24,NULL,&s_zombie_risen};
+
+statetype s_zombie_alive1 = {ZOMB_WALK1PIC,13,T_ChaseThink,&s_zombie_alive2};
+statetype s_zombie_alive2 = {ZOMB_WALK2PIC,13,T_ChaseThink,&s_zombie_alive3};
+statetype s_zombie_alive3 = {ZOMB_WALK3PIC,13,T_ChaseThink,&s_zombie_alive1};
+
+statetype s_zombie_death1 = {ZOMB_DIE1PIC,16,NULL,&s_zombie_death2};
+statetype s_zombie_death2 = {ZOMB_DIE2PIC,16,NULL,&s_zombie_death3};
+statetype s_zombie_death3 = {ZOMB_DIE3PIC,16,NULL,&s_zombie_death3};
+
+statetype s_zombie_attack = {ZOMB_ATTACKPIC,15,T_DoDamage,&s_zombie_pause};
+//statetype s_zombie_attack1 = {ZOMB_ATTACKPIC,15,NULL,&s_zombie_pause};
+
+statetype s_zombie_ouch = {ZOMB_OUCHPIC,15,NULL,&s_zombie_alive1};
+
+
+//--------------------------------------------------------------------------
+// SpawnZombie()
+//--------------------------------------------------------------------------
+void SpawnZombie (int tilex, int tiley)
+{
+ objtype *ob;
+ short current_zombie_delay;
+ unsigned tile;
+
+ SpawnNewObj(tilex,tiley,&s_zombie_inground,35*PIXRADIUS);
+ ob = new;
+ zombie_mode = zm_wait_for_dark;
+
+ tile = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);
+ if (tile)
+ zombie_delay = (tile>>8)*30;
+ else
+ {
+ current_zombie_delay = (2*60)+random(4*60);
+ zombie_delay = zombie_base_delay+current_zombie_delay;
+ zombie_base_delay += current_zombie_delay;
+ if (zombie_base_delay > 8*60)
+ zombie_base_delay = 0;
+ }
+
+ new->speed = 2500;
+ new->obclass = zombieobj;
+ new->hitpoints = EasyHitPoints(8);
+ new->active = yes;
+ new->flags &= ~of_shootable;
+}
+
+
+/*
+=============================================================================
+
+ TREE
+
+=============================================================================
+*/
+
+extern statetype s_tree_pause;
+extern statetype s_tree_idle;
+extern statetype s_tree_awakening1;
+extern statetype s_tree_awakening2;
+extern statetype s_tree_walk1;
+extern statetype s_tree_walk2;
+extern statetype s_tree_walk3;
+extern statetype s_tree_death1;
+extern statetype s_tree_death2;
+extern statetype s_tree_death3;
+extern statetype s_tree_death4;
+extern statetype s_tree_death5;
+extern statetype s_tree_attack1;
+extern statetype s_tree_attack2;
+extern statetype s_tree_attack3;
+extern statetype s_tree_ouch;
+
+void T_Tree (objtype *ob);
+void T_DeathThink(objtype *ob);
+
+statetype s_tree_pause = {TREE_WALK1PIC,25,NULL,&s_tree_walk2};
+
+statetype s_tree_idle = {TREE_IDLEPIC,13,T_ChaseThink,&s_tree_idle};
+
+statetype s_tree_awakening1 = {TREE_AWAKENINGPIC,1,T_AwakeThink,&s_tree_awakening2};
+statetype s_tree_awakening2 = {TREE_AWAKENINGPIC,50,NULL,&s_tree_walk1};
+
+statetype s_tree_walk1 = {TREE_WALK1PIC,13,T_ChaseThink,&s_tree_walk2};
+statetype s_tree_walk2 = {TREE_WALK2PIC,13,T_ChaseThink,&s_tree_walk1};
+
+statetype s_tree_death1 = {TREE_DEATH1PIC,45,NULL,&s_tree_death2};
+statetype s_tree_death2 = {TREE_DEATH2PIC,25,NULL,&s_tree_death3};
+statetype s_tree_death3 = {TREE_DEATH1PIC,15,T_DeathThink,&s_tree_death4};
+statetype s_tree_death4 = {TREE_DEATH2PIC,15,T_DeathThink,&s_tree_death5};
+statetype s_tree_death5 = {TREE_DEATH3PIC,15,T_DeathThink,&s_tree_death3};
+
+statetype s_tree_attack1 = {TREE_ATTACK1PIC,15,T_DoDamage,&s_tree_attack2};
+statetype s_tree_attack2 = {TREE_ATTACK2PIC,15,T_DoDamage,&s_tree_attack3};
+statetype s_tree_attack3 = {TREE_ATTACK3PIC,15,T_DoDamage,&s_tree_pause};
+
+statetype s_tree_ouch = {TREE_AWAKENINGPIC,15,NULL,&s_tree_walk1};
+
+
+#define zombie_mode ob->temp1
+#define zombie_delay ob->temp2
+
+
+//--------------------------------------------------------------------------
+// SpawnTree()
+//--------------------------------------------------------------------------
+void SpawnTree(int tilex, int tiley)
+{
+ objtype *ob;
+ short current_zombie_delay;
+ unsigned tile;
+
+ SpawnNewObj(tilex,tiley,&s_tree_idle,35*PIXRADIUS);
+ ob = new;
+ zombie_mode = zm_wait_for_dark;
+
+ tile = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);
+ if (tile)
+ zombie_delay = (tile>>8)*30;
+ else
+ {
+ current_zombie_delay = (2*60)+random(4*60);
+ zombie_delay = zombie_base_delay+current_zombie_delay;
+ zombie_base_delay += current_zombie_delay;
+ if (zombie_base_delay > 8*60)
+ zombie_base_delay = 0;
+ }
+
+ new->speed = 2500;
+ new->obclass = realsolidobj;
+// new->hitpoints = EasyHitPoints(12);
+ new->active = yes;
+ new->flags |= of_shootable;
+ new->flags |= of_tree;
+}
+
+//--------------------------------------------------------------------------
+// T_DeathThink()
+//--------------------------------------------------------------------------
+void T_DeathThink(objtype *ob)
+{
+ char num;
+
+ if ((ob->ticcount - realtics) <= 0)
+ {
+ num = random(2);
+ switch (ob->temp1)
+ {
+ case 3:
+ if (num)
+ ob->state = &s_tree_death4;
+ else
+ ob->state = &s_tree_death5;
+ ob->temp1++;
+ break;
+
+ case 4:
+ if (num)
+ ob->state = &s_tree_death3;
+ else
+ ob->state = &s_tree_death5;
+ ob->temp1++;
+ break;
+
+ case 5:
+ if (num)
+ ob->state = &s_tree_death3;
+ else
+ ob->state = &s_tree_death4;
+ ob->temp1 = 3;
+ break;
+ }
+ ob->ticcount = ob->state->tictime;
+ }
+
+
+
+ if (CheckHandAttack(ob))
+ TakeDamage (1);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//
+// GENERAL THINK ROUTINES USED BY THE ZOMBIE, TREE, ANT, AND GODESS
+// ----trying to cut down on the code size----
+//
+//////////////////////////////////////////////////////////////////////////
+
+
+//--------------------------------------------------------------------------
+// T_ChaseThink()
+//--------------------------------------------------------------------------
+void T_ChaseThink(objtype *ob)
+{
+ switch (zombie_mode)
+ {
+ case zm_wait_for_dark:
+#if 0
+ if (gamestate.mapon == 0)
+ {
+ if (BGFLAGS & BGF_NIGHT)
+ zombie_mode = zm_wait_to_rise;
+ }
+ else
+#endif
+ zombie_mode = zm_wait_to_rise;
+ break;
+
+ case zm_wait_to_rise:
+ if (zombie_delay < 0)
+ {
+ if ((ob->tilex == player->tilex) && (ob->tiley == player->tiley))
+ break;
+ if (CheckHandAttack(ob))
+ break;
+
+ ob->active = always;
+ switch (ob->obclass)
+ {
+ case zombieobj:
+ ob->state = &s_zombie_rise1;
+ break;
+
+ case antobj:
+ ob->state = &s_ant_egg;
+ break;
+
+ case realsolidobj: //tree and godess
+ if (ob->flags & of_tree)
+ ob->state = &s_tree_awakening1;
+ else
+ ob->state = &s_godess_statue2;
+ break;
+ }
+ ob->ticcount = ob->state->tictime;
+ zombie_mode = zm_active;
+ }
+ else
+ zombie_delay -= tics;
+
+ break;
+
+ case zm_active:
+ if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
+ {
+ switch (ob->obclass)
+ {
+ case zombieobj:
+ ob->state = &s_zombie_attack;
+ break;
+
+ case antobj:
+ ob->state = &s_ant_attack1;
+ break;
+
+ case treeobj:
+ ob->state = &s_tree_attack1;
+ break;
+
+ case godessobj:
+ ob->state = &s_godessattack1;
+ break;
+ }
+ ob->ticcount = ob->state->tictime;
+ return;
+ }
+ break;
+ }
+}
+
+//--------------------------------------------------------------------------
+// T_AwakeThink()
+//--------------------------------------------------------------------------
+void T_AwakeThink(objtype *obj)
+{
+ if (obj->obclass == realsolidobj)
+ {
+ if (obj->flags & of_tree)
+ obj->obclass = treeobj;
+ else
+ obj->obclass = godessobj;
+ obj->hitpoints = EasyHitPoints(12);
+ }
+ else
+ obj->flags |= of_shootable;
+}
+
+
+
+
+
+//--------------------------------------------------------------------------
+// ShootPlayer()
+//--------------------------------------------------------------------------
+boolean ShootPlayer(objtype *ob, short obclass, short speed, statetype *state)
+{
+ int angle = AngleNearPlayer(ob);
+
+ if (angle == -1)
+ return(false);
+
+ DSpawnNewObjFrac (ob->x,ob->y,state,PIXRADIUS*35);
+ new->obclass = obclass;
+ new->active = always;
+ new->angle = angle;
+
+ //
+ // If the shot is Grelminar's, then determine the power of the shot.
+ // The shot speed is hard-wired as 10000. But the shot power is
+ // determined by speed. Speed now contains "Grelminar's level of
+ // hardness" and this is multiplied by 3 to get the shot power.
+ //
+ if (obclass == gshotobj)
+ {
+ new->speed = 10000;
+ new->temp1 = speed*3;
+ }
+ else
+ new->speed = speed;
+
+
+ return(true);
+}
+
+//--------------------------------------------------------------------------
+// T_ShootPlayer()
+//--------------------------------------------------------------------------
+void T_ShootPlayer(objtype *ob)
+{
+ objtype *check;
+ long xmove,ymove,speed;
+
+ speed = ob->speed*tics;
+
+ xmove = FixedByFrac(speed,costable[ob->angle]);
+ ymove = -FixedByFrac(speed,sintable[ob->angle]);
+
+ if (ShotClipMove(ob,xmove,ymove))
+ {
+ ob->state = &s_pshot_exp1;
+ ob->ticcount = ob->state->tictime;
+ return;
+ }
+
+ ob->tilex = ob->x >> TILESHIFT;
+ ob->tiley = ob->y >> TILESHIFT;
+
+
+// check for collision with wall
+//
+ if (tilemap[ob->tilex][ob->tiley])
+ {
+ SD_PlaySound (SHOOTWALLSND);
+ ob->state = &s_pshot_exp1;
+ ob->ticcount = s_pshot_exp1.tictime;
+ return;
+ }
+
+
+
+// check for collision with player
+//
+ if ( ob->xl <= player->xh
+ && ob->xh >= player->xl
+ && ob->yl <= player->yh
+ && ob->yh >= player->yl)
+ {
+ switch (ob->obclass)
+ {
+ case eshotobj:
+ TakeDamage (ESHOTDAMAGE);
+ break;
+
+ case mshotobj:
+ TakeDamage (MSHOTDAMAGE);
+ break;
+
+ case gshotobj:
+ TakeDamage (ob->temp1); // the damage of Grelminar's shot -
+ break; // see Grelminar's spawning
+
+ case sshotobj:
+ TakeDamage(SSHOTDAMAGE);
+ break;
+
+ case dshotobj:
+ TakeDamage(7);
+ break;
+ }
+ ob->state = NULL;
+ return;
+ }
+
+// check for collision with other solid and realsolid objects.
+// Great terminology!! -- solid objects really aren't solid
+// -- realsolid objects ARE solid
+// if ((actorat[ob->tilex][ob->tiley]) && (actorat[ob->tilex][ob->tiley]->obclass != ob->obclass))
+ if (((actorat[ob->tilex][ob->tiley]->obclass == realsolidobj) ||
+ (actorat[ob->tilex][ob->tiley]->obclass == solidobj)) &&
+ (actorat[ob->tilex][ob->tiley]->flags & of_shootable))
+ {
+ ob->state = &s_pshot_exp1;
+ ob->ticcount = s_pshot_exp1.tictime;
+ return;
+ }
+
+
+// check for collision with player
+//
+ for (check = player->next; check; check=check->next)
+ if ((ob->flags & of_shootable) && ob->obclass != mageobj
+ && ob->xl <= check->xh
+ && ob->xh >= check->xl
+ && ob->yl <= check->yh
+ && ob->yh >= check->yl)
+ {
+ switch (ob->obclass)
+ {
+ case eshotobj:
+ ShootActor (check,ESHOTDAMAGE);
+ break;
+
+ case mshotobj:
+ ShootActor (check,MSHOTDAMAGE);
+ break;
+
+ case gshotobj:
+ ShootActor (check,25); //NOLAN--check on me!!!!!!!
+ break;
+
+ case pshotobj:
+ ShootActor (check,25);
+ break;
+
+ case sshotobj:
+ ShootActor(check, SSHOTDAMAGE);
+ break;
+
+ case dshotobj:
+ ShootActor(check, 7);
+ break;
+ }
+ ob->state = &s_pshot_exp1;
+ ob->ticcount = s_pshot_exp1.tictime;
+ return;
+ }
+}
+
+//-------------------------------------------------------------------------
+// AngleNearPlayer()
+//-------------------------------------------------------------------------
+int AngleNearPlayer(objtype *ob)
+{
+ int angle=-1;
+ int xdiff = ob->tilex-player->tilex;
+ int ydiff = ob->tiley-player->tiley;
+
+ if (ob->tiley == player->tiley)
+ {
+ if (ob->tilex < player->tilex)
+ angle = 0;
+ else
+ angle = 180;
+ }
+ else
+ if (ob->tilex == player->tilex)
+ {
+ if (ob->tiley < player->tiley)
+ angle = 270;
+ else
+ angle = 90;
+ }
+ else
+ if (xdiff == ydiff)
+ if (ob->tilex < player->tilex)
+ {
+ if (ob->tiley < player->tiley)
+ angle = 315;
+ else
+ angle = 45;
+ }
+ else
+ {
+ if (ob->tiley < player->tiley)
+ angle = 225;
+ else
+ angle = 135;
+ }
+
+ return(angle);
+}
diff --git a/C5_ACT4.C b/C5_ACT4.C
new file mode 100644
index 0000000..676e0b7
--- /dev/null
+++ b/C5_ACT4.C
@@ -0,0 +1,414 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+// C4_PLAY.C
+
+#include "DEF.H"
+#pragma hdrstop
+
+/*
+=============================================================================
+
+ LOCAL CONSTANTS
+
+=============================================================================
+*/
+
+
+
+//-------------------------------------------------------------------------
+//
+// ARCH OBJECTS
+//
+//-------------------------------------------------------------------------
+
+
+
+//-------------------------------------------------------------------------
+// ARCH
+//-------------------------------------------------------------------------
+
+void SpawnArch(int tilex, int tiley, int num);
+
+extern statetype s_arch_1;
+extern statetype s_arch_2;
+extern statetype s_arch_3;
+extern statetype s_arch_4;
+extern statetype s_arch_5;
+extern statetype s_arch_6;
+extern statetype s_arch_7;
+extern statetype s_arch_8;
+extern statetype s_arch_9;
+extern statetype s_arch_10;
+extern statetype s_arch_11;
+extern statetype s_arch_12;
+extern statetype s_arch_13;
+
+statetype s_arch_1 = {ARCH1PIC, 20, NULL, &s_arch_1};
+statetype s_arch_2 = {ARCH2PIC, 20, NULL, &s_arch_2};
+statetype s_arch_3 = {ARCH3PIC, 20, NULL, &s_arch_3};
+statetype s_arch_4 = {ARCH4PIC, 20, NULL, &s_arch_4};
+statetype s_arch_5 = {ARCH5PIC, 20, NULL, &s_arch_5};
+statetype s_arch_6 = {ARCH6PIC, 20, NULL, &s_arch_6};
+statetype s_arch_7 = {ARCH7PIC, 20, NULL, &s_arch_7};
+statetype s_arch_8 = {ARCH8PIC, 20, NULL, &s_arch_8};
+statetype s_arch_9 = {ARCH9PIC, 20, NULL, &s_arch_9};
+statetype s_arch_10 = {ARCH10PIC, 20, NULL, &s_arch_10};
+statetype s_arch_11 = {ARCH11PIC, 20, NULL, &s_arch_11};
+statetype s_arch_12 = {ARCH12PIC, 20, NULL, &s_arch_12};
+statetype s_arch_13 = {ARCH13PIC, 20, NULL, &s_arch_13};
+
+void SpawnArch (int tilex, int tiley, int num)
+{
+ statetype *objstate;
+
+
+ switch (num)
+ {
+ case 1:
+ objstate = &s_arch_1;
+ break;
+ case 2:
+ objstate = &s_arch_2;
+ break;
+ case 3:
+ objstate = &s_arch_3;
+ break;
+ case 4:
+ objstate = &s_arch_4;
+ break;
+ case 5:
+ objstate = &s_arch_5;
+ break;
+ case 6:
+ objstate = &s_arch_6;
+ break;
+ case 7:
+ objstate = &s_arch_7;
+ break;
+ case 8:
+ objstate = &s_arch_8;
+ break;
+ case 9:
+ objstate = &s_arch_9;
+ break;
+ case 10:
+ objstate = &s_arch_10;
+ break;
+ case 11:
+ objstate = &s_arch_11;
+ break;
+ case 12:
+ objstate = &s_arch_12;
+ break;
+ case 13:
+ objstate = &s_arch_13;
+ break;
+ }
+ ASpawnNewObj(tilex,tiley,objstate,PIXRADIUS*35);
+ new->obclass = solidobj;
+ new->flags &= ~of_shootable;
+}
+
+
+//-------------------------------------------------------------------------
+//
+// MISC OBJECTS
+//
+//-------------------------------------------------------------------------
+
+
+//-------------------------------------------------------------------------
+// COLUMN, SULPHUR GAS HOLE, FIRE POT, FOUNTAIN
+//-------------------------------------------------------------------------
+
+
+void SpawnMiscObjects(int tilex, int tiley, int num);
+
+extern statetype s_column;
+extern statetype s_sulphur_gas_1;
+extern statetype s_sulphur_gas_2;
+extern statetype s_sulphur_gas_3;
+extern statetype s_fire_pot_1;
+extern statetype s_fire_pot_2;
+extern statetype s_fountain;
+
+statetype s_column = {COLUMNPIC, 20, NULL, &s_column};
+statetype s_sulphur_gas_1 = {SULPHUR_GAS_1PIC, 20, NULL, &s_sulphur_gas_2};
+statetype s_sulphur_gas_2 = {SULPHUR_GAS_2PIC, 20, NULL, &s_sulphur_gas_3};
+statetype s_sulphur_gas_3 = {SULPHUR_GAS_3PIC, 20, NULL, &s_sulphur_gas_1};
+statetype s_fire_pot_1 = {FIRE_POT_1PIC, 20, NULL, &s_fire_pot_2};
+statetype s_fire_pot_2 = {FIRE_POT_2PIC, 20, NULL, &s_fire_pot_1};
+statetype s_fountain = {WFOUNTAINPIC, 20, NULL, &s_fountain};
+
+
+void SpawnMiscObjects(int tilex, int tiley, int num)
+{
+ statetype *objstate;
+
+ switch (num)
+ {
+ case 1:
+ objstate = &s_column;
+ break;
+
+ case 2:
+ objstate = &s_sulphur_gas_1;
+ break;
+
+ case 3:
+ objstate = &s_fire_pot_1;
+ break;
+
+ case 4:
+ objstate = &s_fountain;
+ break;
+ }
+
+ SpawnNewObj(tilex,tiley,objstate,PIXRADIUS*35);
+ new->obclass = realsolidobj;
+ if (num == 2)
+ new->flags &= ~of_shootable;
+ else
+ new->flags |= of_shootable;
+}
+
+
+
+
+
+
+#if 0
+void SpawnColumn(int tilex, int tiley);
+
+extern statetype s_column;
+statetype s_column = {COLUMNPIC, 20, NULL, &s_column};
+
+void SpawnColumn(int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_column,PIXRADIUS*35);
+ new->obclass = realsolidobj;
+ new->flags |= of_shootable;
+}
+
+
+//-------------------------------------------------------------------------
+// SULPHUR GAS
+//-------------------------------------------------------------------------
+
+void SpawnSulphurGas(int tilex, int tiley);
+
+extern statetype s_sulphur_gas_1;
+extern statetype s_sulphur_gas_2;
+extern statetype s_sulphur_gas_3;
+
+statetype s_sulphur_gas_1 = {SULPHUR_GAS_1PIC, 20, NULL, &s_sulphur_gas_2};
+statetype s_sulphur_gas_2 = {SULPHUR_GAS_2PIC, 20, NULL, &s_sulphur_gas_3};
+statetype s_sulphur_gas_3 = {SULPHUR_GAS_3PIC, 20, NULL, &s_sulphur_gas_1};
+
+void SpawnSulphurGas(int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_sulphur_gas_1,PIXRADIUS*35);
+ new->obclass = realsolidobj;
+ new->flags &= ~of_shootable;
+}
+
+
+//-------------------------------------------------------------------------
+// FIRE POT
+//-------------------------------------------------------------------------
+
+void SpawnFirePot(int tilex, int tiley);
+
+extern statetype s_fire_pot_1;
+extern statetype s_fire_pot_2;
+
+statetype s_fire_pot_1 = {FIRE_POT_1PIC, 20, NULL, &s_fire_pot_2};
+statetype s_fire_pot_2 = {FIRE_POT_2PIC, 20, NULL, &s_fire_pot_1};
+
+void SpawnFirePot(int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_fire_pot_1,PIXRADIUS*35);
+ new->obclass = realsolidobj;
+ new->flags |= of_shootable;
+
+}
+
+//------------------------------------------------------------------------
+// FOUNTAIN
+//------------------------------------------------------------------------
+
+void SpawnFountain(int tilex, int tiley);
+
+extern statetype s_fountain;
+statetype s_fountain = {WFOUNTAINPIC, 20, NULL, &s_fountain};
+
+void SpawnFountain(int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_fountain,PIXRADIUS*35);
+ new->obclass = realsolidobj;
+ new->flags |= of_shootable;
+}
+
+#endif
+
+
+//------------------------------------------------------------------------
+// FORCE FIELD
+//------------------------------------------------------------------------
+
+void SpawnForceField(int tilex, int tiley);
+void T_ForceField(objtype *ob);
+void T_ForceFieldRemove(objtype *ob);
+
+extern statetype s_force_field_1;
+extern statetype s_force_field_2;
+extern statetype s_force_field_3;
+extern statetype s_force_field_4;
+extern statetype s_force_field_die1;
+
+statetype s_force_field_1 = {FORCE_FIELD_1PIC, 10, T_ForceField, &s_force_field_2};
+statetype s_force_field_2 = {FORCE_FIELD_2PIC, 10, T_ForceField, &s_force_field_3};
+statetype s_force_field_3 = {FORCE_FIELD_3PIC, 10, T_ForceField, &s_force_field_4};
+statetype s_force_field_4 = {FORCE_FIELD_4PIC, 10, T_ForceField, &s_force_field_1};
+
+statetype s_force_field_die = {0,0,T_ForceFieldRemove,&s_force_field_die1};
+statetype s_force_field_die1 = {0,0,NULL,NULL};
+
+void SpawnForceField(int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_force_field_1,PIXRADIUS*35);
+ new->obclass = solidobj;
+ new->hitpoints = EasyHitPoints(20);
+ new->flags |= of_forcefield; //sets bit 7 :: makes it nonsolid, but also detectable
+ // without adding another object type!
+ new->flags |= of_shootable;
+}
+
+void T_ForceField(objtype *ob)
+{
+ long move,deltax,deltay,size;
+
+ size = (long)ob->size + player->size;
+
+ deltax = ob->x - player->x;
+ deltay = ob->y - player->y;
+
+ if (deltax <= size && deltax >= -size
+ && deltay <= size && deltay >= -size)
+ TakeDamage (20);
+
+}
+
+void T_ForceFieldRemove(objtype *ob)
+{
+ actorat[ob->tilex][ob->tiley] = 0;
+}
+
+
+//------------------------------------------------------------------------
+// SKELETON HANGING FROM CEILING
+//------------------------------------------------------------------------
+
+void SpawnSkeletonHanging(int tilex, int tiley);
+void T_SkelHangThink(objtype *ob);
+
+extern statetype s_skeleton_hanging;
+statetype s_skeleton_hanging = {SKEL_HANGPIC, 20, T_SkelHangThink, &s_skeleton_hanging};
+
+void SpawnSkeletonHanging(int tilex, int tiley)
+{
+ unsigned tile;
+
+ SpawnNewObj(tilex,tiley,&s_skeleton_hanging,PIXRADIUS*35);
+ new->obclass = solidobj;
+
+ tile = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);
+ if (tile)
+ new->temp1 = (tile>>8)*30;
+ else
+ new->temp1 = (3*60)+random(4*60);
+
+ new->flags |= of_shootable;
+}
+
+void T_SkelHangThink(objtype *ob)
+{
+ ob->temp1 -= realtics;
+ if (ob->temp1 <= 0)
+ {
+ ob->state = &s_skel_1;
+ ob->ticcount = ob->state->tictime;
+ ob->obclass = skeletonobj;
+ ob->speed = 2036;
+ ob->flags |= of_shootable;
+ ob->hitpoints = EasyHitPoints(12);
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// EasyHitPoints
+//
+// Checks to see if the player has selected the easy mode for playing.
+// If so then the normal hit points are cut in half.
+// This is when the object is spawned.
+//
+// Parms
+// NrmHitPts - the normal hit points
+//
+// Returns
+// Half of NrmHitPts
+//
+/////////////////////////////////////////////////////////////////////////////
+
+int EasyHitPoints(int NrmHitPts)
+{
+ if (EASYMODEON) // Wimpy, Wimpy, Wimpy!!!!!
+ {
+ return(NrmHitPts/4);
+ }
+ else
+ return(NrmHitPts);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// EasyDoDamage
+//
+// Checks to see if the player has selected the easy mode for playing.
+// If so then the normal amount of damage is cut in half.
+// This is called each time a monster does damage.
+//
+// Parms
+// Damage - the normal damage taken
+//
+// Returns
+// Half of Damage
+//
+/////////////////////////////////////////////////////////////////////////////
+
+int EasyDoDamage(int Damage)
+{
+ if (EASYMODEON) // Wimpy, Wimpy, Wimpy!!!!!
+ return(Damage/2);
+ else
+ return(Damage);
+}
+
diff --git a/C5_ASM.ASM b/C5_ASM.ASM
index 05eb2f0..a4390b2 100644
--- a/C5_ASM.ASM
+++ b/C5_ASM.ASM
@@ -1,4 +1,4 @@
-; Catacomb Abyss Source Code
+; Catacomb Armageddon Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
diff --git a/C5_DEBUG.C b/C5_DEBUG.C
index c631b43..d8e2b1a 100644
--- a/C5_DEBUG.C
+++ b/C5_DEBUG.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -53,6 +53,7 @@
=============================================================================
*/
+short colordelay=0;
boolean autofire=false;
int maporgx;
int maporgy;
@@ -62,56 +63,6 @@ void ViewMap (void);
//===========================================================================
-
-/*
-==================
-=
-= DebugMemory
-=
-==================
-*/
-
-void DebugMemory (void)
-{
- int i;
- char scratch[80],str[10];
- long mem;
- spritetype _seg *block;
-
- VW_FixRefreshBuffer ();
- CenterWindow (16,7);
-
-#if 0
- CA_OpenDebug ();
- for (i=0;i<NUMCHUNKS;i++)
- {
- if (grsegs[i])
- {
- strcpy (scratch,"Chunk:");
- itoa (i,str,10);
- strcat (scratch,str);
- strcat (scratch,"\n");
- write (debughandle,scratch,strlen(scratch));
- }
- }
- CA_CloseDebug ();
-#endif
-
- 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 ();
-}
-
-//===========================================================================
-
#if 0
/*
================
@@ -189,7 +140,22 @@ int DebugKeys (void)
boolean esc;
int level,i;
-#if 0
+#if DEBUG_KEYS_AVAILABLE
+ if (Keyboard[sc_R])
+ {
+ CenterWindow (12,2);
+ if (autofire)
+ US_PrintCentered ("Rapid-Fire OFF");
+ else
+ US_PrintCentered ("Rapid-Fire ON");
+ VW_UpdateScreen();
+ IN_Ack();
+ autofire ^= 1;
+ return 1;
+ }
+#endif
+
+#if DEBUG_KEYS_AVAILABLE
if (Keyboard[sc_A])
{
char levelstr[50];
@@ -252,7 +218,7 @@ int DebugKeys (void)
//
if (Keyboard[sc_RightArrow])
{
- if (mapon < LASTMAP-2)
+ if (mapon < LASTMAP-1)
{
MM_SetPurge(&grsegs[LEVEL1TEXT+mapon],3);
mapon++;
@@ -298,25 +264,12 @@ int DebugKeys (void)
DrawText(true);
status_flag = 0;
}
-#endif
- if (Keyboard[sc_T])
- {
- VW_FixRefreshBuffer ();
- CenterWindow (16,4);
-
- US_Print("Tics :");
- US_PrintUnsigned (tics);
- US_Print("\nReal Tics :");
- US_PrintUnsigned(realtics);
- VW_UpdateScreen();
- IN_Ack ();
- }
if (Keyboard[sc_V])
{
displayofs = bufferofs = screenloc[screenpage];
- CenterWindow (20,5);
+ CenterWindow (16,4);
US_CPrint("\n"GAMENAME);
US_CPrint(VERSION);
US_CPrint(REVISION);
@@ -324,6 +277,7 @@ int DebugKeys (void)
IN_Ack ();
}
+
if (Keyboard[sc_Q]) // Q = Insta-Quit!
Quit("Insta-Quit!");
@@ -337,6 +291,8 @@ int DebugKeys (void)
IN_Ack();
return 1;
}
+#endif
+
// if (Keyboard[sc_E])
// FaceDoor((player->x>>16l)+1,(player->y>>16l));
@@ -360,6 +316,69 @@ int DebugKeys (void)
}
#endif
+
+#if 1//DEBUG_KEYS_AVAILABLE
+ if (Keyboard[sc_O])
+ {
+ extern unsigned objectcount,latchmemavail;
+ unsigned unused,total;
+
+ CenterWindow (30,13);
+ US_Print ("Objects: ");
+ US_PrintUnsigned (objectcount);
+
+ US_Print("\n\nTics: ");
+ US_PrintUnsigned (tics);
+ US_Print(" Real Tics: ");
+ US_PrintUnsigned(realtics);
+
+ US_Print ("\n\n Total Available: ");
+ US_PrintUnsigned (mminfo.mainmem/1024);
+ US_Print ("k\n Mem In Use: ");
+ unused=MM_UnusedMemory()/1024;
+ US_PrintUnsigned (unused);
+ US_Print ("k\n Mem After Purge: ");
+ total=MM_TotalFree()/1024;
+ US_PrintUnsigned (total);
+ US_Print ("k (");
+ US_PrintUnsigned (total-unused);
+
+ US_Print (")\n\nLatch Mem Free: ");
+ US_PrintUnsigned (latchmemavail);
+ US_Print ("\n");
+ VW_UpdateScreen();
+ IN_Ack();
+ }
+
+ if (colordelay<1)
+ {
+ if (Keyboard[26])
+ {
+ extern unsigned *groundcolor,debug_gnd;
+
+ groundcolor = &debug_gnd;
+ debug_gnd += 0x0101;
+ if (debug_gnd == 0x1010)
+ debug_gnd = 0;
+ colordelay = 10;
+ }
+
+ if (Keyboard[27])
+ {
+ extern unsigned *skycolor,debug_sky;
+
+ skycolor = &debug_sky;
+ debug_sky += 0x0101;
+ if (debug_sky == 0x1010)
+ debug_sky = 0;
+ colordelay = 10;
+ }
+ }
+ else
+ colordelay -= realtics;
+#endif
+
+
#if 0
if (Keyboard[sc_C]) // C = count objects
{
@@ -445,21 +464,15 @@ int DebugKeys (void)
}
gamestate.gems[4] = GEM_DELAY_TIME;
redraw_gems = true;
- for (i=0;i<8;i++)
- GiveScroll (i,false);
+///////// for (i=0;i<8;i++)
+///////// GiveScroll (i,false);
IN_Ack ();
return 1;
}
- if (Keyboard[sc_M]) // M = memory info
- {
- DebugMemory();
- return 1;
- }
-
#if DEBUG_OVERHEAD
- if (Keyboard[sc_O]) // O = overhead
+ if (Keyboard[sc_Z]) // O is used elsewhere...
{
ViewMap();
return 1;
@@ -511,7 +524,7 @@ int DebugKeys (void)
{
CenterWindow(26,3);
PrintY+=6;
- US_Print(" Warp to which level(0-18):");
+ US_Print(" Warp to which level(0-16):");
VW_UpdateScreen();
esc = !US_LineInput (px,py,str,NULL,true,2,0);
if (!esc)
@@ -544,11 +557,11 @@ int DebugKeys (void)
}
#endif
- if (LastScan >= sc_1 && LastScan <= sc_8) // free scrolls
- {
- GiveScroll (LastScan-sc_1,false);
- IN_ClearKeysDown ();
- }
+//////// if (LastScan >= sc_1 && LastScan <= sc_8) // free scrolls
+//////// {
+//////// GiveScroll (LastScan-sc_1,false);
+//////// IN_ClearKeysDown ();
+//////// }
return 0;
}
diff --git a/C5_DRAW.C b/C5_DRAW.C
index e4c59f3..bab5ea3 100644
--- a/C5_DRAW.C
+++ b/C5_DRAW.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -21,10 +21,10 @@
#include "DEF.H"
#pragma hdrstop
-//#define DRAWEACH // draw walls one at a time for debugging
+//#define DRAWEACH // draw walls one at a time for debugging
-unsigned highest;
-unsigned mostwalls,numwalls;
+unsigned highest;
+unsigned mostwalls,numwalls;
/*
=============================================================================
@@ -34,19 +34,19 @@ unsigned mostwalls,numwalls;
=============================================================================
*/
-#define PI 3.141592657
-#define ANGLEQUAD (ANGLES/4)
+#define PI 3.141592657
+#define ANGLEQUAD (ANGLES/4)
-unsigned oldend;
+unsigned oldend;
-#define FINEANGLES 3600
+#define FINEANGLES 3600
-#define MINRATIO 16
+#define MINRATIO 16
-const unsigned MAXSCALEHEIGHT = (VIEWWIDTH/2);
-const unsigned MAXVISHEIGHT = (VIEWHEIGHT/2);
-const unsigned BASESCALE = 32;
+const unsigned MAXSCALEHEIGHT = (VIEWWIDTH/2);
+const unsigned MAXVISHEIGHT = (VIEWHEIGHT/2);
+const unsigned BASESCALE = 32;
/*
=============================================================================
@@ -64,10 +64,10 @@ const unsigned BASESCALE = 32;
unsigned screenloc[3]= {PAGE1START,PAGE2START,PAGE3START};
unsigned freelatch = FREESTART;
-boolean fizzlein;
+boolean fizzlein;
-long scaleshapecalll;
-long scaletablecall;
+long scaleshapecalll;
+long scaletablecall;
/*
=============================================================================
@@ -77,12 +77,12 @@ long scaletablecall;
=============================================================================
*/
-long bytecount,endcount; // for profiling
-int animframe;
-int pixelangle[VIEWWIDTH];
-int far finetangent[FINEANGLES+1];
-int fineviewangle;
-unsigned viewxpix,viewypix;
+long bytecount,endcount; // for profiling
+int animframe;
+int pixelangle[VIEWWIDTH];
+int far finetangent[FINEANGLES+1];
+int fineviewangle;
+unsigned viewxpix,viewypix;
/*
============================================================================
@@ -92,25 +92,25 @@ unsigned viewxpix,viewypix;
============================================================================
*/
-fixed tileglobal = TILEGLOBAL;
-fixed focallength = FOCALLENGTH;
-fixed mindist = MINDIST;
-int viewheight = VIEWHEIGHT;
+fixed tileglobal = TILEGLOBAL;
+fixed focallength = FOCALLENGTH;
+fixed mindist = MINDIST;
+int viewheight = VIEWHEIGHT;
fixed scale;
-tilept tile,lasttile, // tile of wall being followed
- focal, // focal point in tiles
- left,mid,right; // rightmost tile in view
+tilept tile,lasttile, // tile of wall being followed
+ focal, // focal point in tiles
+ left,mid,right; // rightmost tile in view
globpt edge,view;
-int segstart[VIEWHEIGHT], // addline tracks line segment and draws
+int segstart[VIEWHEIGHT], // addline tracks line segment and draws
segend[VIEWHEIGHT],
- segcolor[VIEWHEIGHT]; // only when the color changes
+ segcolor[VIEWHEIGHT]; // only when the color changes
-walltype walls[MAXWALLS],*leftwall,*rightwall;
+walltype walls[MAXWALLS],*leftwall,*rightwall;
//==========================================================================
@@ -133,29 +133,29 @@ fixed prestep;
fixed sintable[ANGLES+ANGLES/4],*costable = sintable+(ANGLES/4);
-fixed viewx,viewy; // the focal point
-int viewangle;
-fixed viewsin,viewcos;
+fixed viewx,viewy; // the focal point
+int viewangle;
+fixed viewsin,viewcos;
-int zbuffer[VIEWXH+1]; // holds the height of the wall at that point
+int zbuffer[VIEWXH+1]; // holds the height of the wall at that point
//==========================================================================
-void DrawLine (int xl, int xh, int y,int color);
-void DrawWall (walltype *wallptr);
-void TraceRay (unsigned angle);
-fixed FixedByFrac (fixed a, fixed b);
-fixed FixedAdd (void);
-fixed TransformX (fixed gx, fixed gy);
-int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max);
-int BackTrace (int finish);
-void ForwardTrace (void);
-int TurnClockwise (void);
-int TurnCounterClockwise (void);
-void FollowWall (void);
-
-void NewScene (void);
-void BuildTables (void);
+void DrawLine (int xl, int xh, int y,int color);
+void DrawWall (walltype *wallptr);
+void TraceRay (unsigned angle);
+fixed FixedByFrac (fixed a, fixed b);
+fixed FixedAdd (void);
+fixed TransformX (fixed gx, fixed gy);
+int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max);
+int BackTrace (int finish);
+void ForwardTrace (void);
+int TurnClockwise (void);
+int TurnCounterClockwise (void);
+void FollowWall (void);
+
+void NewScene (void);
+void BuildTables (void);
//==========================================================================
@@ -175,9 +175,9 @@ void BuildTables (void);
==================
*/
-unsigned static char dotmask[8] = {0x80,0x40,0x20,0x10,8,4,2,1};
-unsigned static char leftmask[8] = {0xff,0x7f,0x3f,0x1f,0xf,7,3,1};
-unsigned static char rightmask[8] = {0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
+unsigned static char dotmask[8] = {0x80,0x40,0x20,0x10,8,4,2,1};
+unsigned static char leftmask[8] = {0xff,0x7f,0x3f,0x1f,0xf,7,3,1};
+unsigned static char rightmask[8] = {0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};
void DrawLine (int xl, int xh, int y,int color)
{
@@ -203,9 +203,9 @@ void DrawLine (int xl, int xh, int y,int color)
//
// set the GC index register to point to the bit mask register
//
- asm mov al,GC_BITMASK
- asm mov dx,GC_INDEX
- asm out dx,al
+ asm mov al,GC_BITMASK
+ asm mov dx,GC_INDEX
+ asm out dx,al
if (xlb==xhb)
{
@@ -215,50 +215,50 @@ void DrawLine (int xl, int xh, int y,int color)
maskleft&=maskright;
- asm mov es,[screenseg]
- asm mov di,[dest]
- asm mov dx,GC_INDEX+1
+ asm mov es,[screenseg]
+ asm mov di,[dest]
+ asm mov dx,GC_INDEX+1
- asm mov al,[BYTE PTR maskleft]
- asm out dx,al // mask off pixels
+ asm mov al,[BYTE PTR maskleft]
+ asm out dx,al // mask off pixels
- asm mov al,[BYTE PTR color]
- asm xchg al,[es:di] // load latches and write pixels
+ asm mov al,[BYTE PTR color]
+ asm xchg al,[es:di] // load latches and write pixels
return;
}
-asm mov es,[screenseg]
-asm mov di,[dest]
-asm mov dx,GC_INDEX+1
-asm mov bh,[BYTE PTR color]
+asm mov es,[screenseg]
+asm mov di,[dest]
+asm mov dx,GC_INDEX+1
+asm mov bh,[BYTE PTR color]
//
// draw left side
//
-asm mov al,[BYTE PTR maskleft]
-asm out dx,al // mask off pixels
+asm mov al,[BYTE PTR maskleft]
+asm out dx,al // mask off pixels
-asm mov al,bh
-asm xchg al,[es:di] // load latches and write pixels
-asm inc di
+asm mov al,bh
+asm xchg al,[es:di] // load latches and write pixels
+asm inc di
//
// draw middle
//
-asm mov al,255
-asm out dx,al // no masking
+asm mov al,255
+asm out dx,al // no masking
-asm mov al,bh
-asm mov cx,[mid]
-asm rep stosb
+asm mov al,bh
+asm mov cx,[mid]
+asm rep stosb
//
// draw right side
//
-asm mov al,[BYTE PTR maskright]
-asm out dx,al // mask off pixels
-asm xchg bh,[es:di] // load latches and write pixels
+asm mov al,[BYTE PTR maskright]
+asm out dx,al // mask off pixels
+asm xchg bh,[es:di] // load latches and write pixels
}
@@ -289,9 +289,9 @@ void DrawLineDot (int xl, int xh, int y,int color)
//
// set the GC index register to point to the bit mask register
//
- asm mov al,GC_BITMASK
- asm mov dx,GC_INDEX
- asm out dx,al
+ asm mov al,GC_BITMASK
+ asm mov dx,GC_INDEX
+ asm out dx,al
if (xlb==xhb)
{
@@ -301,69 +301,69 @@ void DrawLineDot (int xl, int xh, int y,int color)
maskleft&=maskright;
- asm mov es,[screenseg]
- asm mov di,[dest]
- asm mov dx,GC_INDEX+1
+ asm mov es,[screenseg]
+ asm mov di,[dest]
+ asm mov dx,GC_INDEX+1
- asm mov al,[BYTE PTR maskleft]
- asm out dx,al // mask off pixels
+ asm mov al,[BYTE PTR maskleft]
+ asm out dx,al // mask off pixels
- asm mov al,[BYTE PTR color]
- asm xchg al,[es:di] // load latches and write pixels
+ asm mov al,[BYTE PTR color]
+ asm xchg al,[es:di] // load latches and write pixels
//
// write the black dot at the start
//
- asm mov al,[BYTE PTR maskdot]
- asm out dx,al // mask off pixels
+ asm mov al,[BYTE PTR maskdot]
+ asm out dx,al // mask off pixels
- asm xor al,al
- asm xchg al,[es:di] // load latches and write pixels
+ asm xor al,al
+ asm xchg al,[es:di] // load latches and write pixels
return;
}
-asm mov es,[screenseg]
-asm mov di,[dest]
-asm mov dx,GC_INDEX+1
-asm mov bh,[BYTE PTR color]
+asm mov es,[screenseg]
+asm mov di,[dest]
+asm mov dx,GC_INDEX+1
+asm mov bh,[BYTE PTR color]
//
// draw left side
//
-asm mov al,[BYTE PTR maskleft]
-asm out dx,al // mask off pixels
+asm mov al,[BYTE PTR maskleft]
+asm out dx,al // mask off pixels
-asm mov al,bh
-asm xchg al,[es:di] // load latches and write pixels
+asm mov al,bh
+asm xchg al,[es:di] // load latches and write pixels
//
// write the black dot at the start
//
-asm mov al,[BYTE PTR maskdot]
-asm out dx,al // mask off pixels
-asm xor al,al
-asm xchg al,[es:di] // load latches and write pixels
-asm inc di
+asm mov al,[BYTE PTR maskdot]
+asm out dx,al // mask off pixels
+asm xor al,al
+asm xchg al,[es:di] // load latches and write pixels
+asm inc di
//
// draw middle
//
-asm mov al,255
-asm out dx,al // no masking
+asm mov al,255
+asm out dx,al // no masking
-asm mov al,bh
-asm mov cx,[mid]
-asm rep stosb
+asm mov al,bh
+asm mov cx,[mid]
+asm rep stosb
//
// draw right side
//
-asm mov al,[BYTE PTR maskright]
-asm out dx,al // mask off pixels
-asm xchg bh,[es:di] // load latches and write pixels
+asm mov al,[BYTE PTR maskright]
+asm out dx,al // mask off pixels
+asm xchg bh,[es:di] // load latches and write pixels
}
@@ -372,7 +372,7 @@ asm xchg bh,[es:di] // load latches and write pixels
//==========================================================================
-long wallscalesource;
+long wallscalesource;
#ifdef DRAWEACH
/*
@@ -385,7 +385,7 @@ long wallscalesource;
void near ScaleOneWall (int xl, int xh)
{
- int x,pixwidth,height;
+ int x,pixwidth,height;
*(((unsigned *)&wallscalesource)+1) = wallseg[xl];
@@ -401,190 +401,281 @@ void near ScaleOneWall (int xl, int xh)
//
// scale a byte wide strip of wall
//
- asm mov bx,[x]
- asm mov di,bx
- asm shr di,1
- asm shr di,1
- asm shr di,1 // X in bytes
- asm add di,[bufferofs]
- asm and bx,7
- asm shl bx,1
- asm shl bx,1
- asm shl bx,1
- asm add bx,[pixwidth] // bx = pixel*8+pixwidth-1
- asm dec bx
- asm mov al,BYTE PTR [bitmasks1+bx]
- asm mov dx,GC_INDEX+1
- asm out dx,al // set bit mask register
- asm mov es,[screenseg]
- asm lds si,[wallscalesource]
- asm call [DWORD PTR ss:scaletablecall] // scale the line of pixels
-
- asm mov al,BYTE PTR [ss:bitmasks2+bx]
- asm or al,al
- asm jz nosecond
+ asm mov bx,[x]
+ asm mov di,bx
+ asm shr di,1
+ asm shr di,1
+ asm shr di,1 // X in bytes
+ asm add di,[bufferofs]
+ asm and bx,7
+ asm shl bx,1
+ asm shl bx,1
+ asm shl bx,1
+ asm add bx,[pixwidth] // bx = pixel*8+pixwidth-1
+ asm dec bx
+ asm mov al,BYTE PTR [bitmasks1+bx]
+ asm mov dx,GC_INDEX+1
+ asm out dx,al // set bit mask register
+ asm mov es,[screenseg]
+ asm lds si,[wallscalesource]
+ asm call [DWORD PTR ss:scaletablecall] // scale the line of pixels
+
+ asm mov al,BYTE PTR [ss:bitmasks2+bx]
+ asm or al,al
+ asm jz nosecond
//
// 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 ss:scaletablecall] // scale the line of pixels
+ asm inc di
+ asm out dx,al // set bit mask register
+ asm call [DWORD PTR ss:scaletablecall] // scale the line of pixels
nosecond:
- asm mov ax,ss
- asm mov ds,ax
+ asm mov ax,ss
+ asm mov ds,ax
}
}
#endif
+char wall_anim_pos[NUMFLOORS];
+
// EAST / WEST WALLS
//
-int walllight1[NUMFLOORS] = {0,
- W_WARP1EWPIC,
- W_NEMPICEWPIC,W_PENTAEWPIC,W_ALTER_LFPIC,W_ALTER_RTPIC,
- W_SUB1EWPIC,W_SUB2EWPIC,W_SUB3EWPIC,
+int far walllight1[NUMFLOORS] = {0,
- W_TORCH1PIC,W_TORCH2PIC,
- W_LSUB_STONEPIC,
- W_BLOODY_LSUB_STONEPIC,
- W_BREATH_LWALL1PIC,W_BREATH_LWALL2PIC,
+ CRYSTAL_LIGHT_1PIC,
+ CRYSTAL_LIGHT_2PIC,
+ CRYSTAL_LIGHT_3PIC,
+ CRYSTAL_LIGHT_4PIC, //4
- EXPWALL1PIC,EXPWALL2PIC,EXPWALL3PIC,
+ FIRE_WALL_1PIC,
+ FIRE_WALL_2PIC,
+ FIRE_WALL_3PIC,
+ FIRE_WALL_4PIC, //8
- W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,
+ BRN_STONE_GATEPIC,
+ BRN_STONE_WALL_1PIC,
+ KUDZU_WEAK_LIGHTPIC,
+ KUDZU_LIGHT_WALLPIC,
+ HEDGE_WALLPIC,
+ HEDGE_EYESPIC, //14
- W_WATER1EWPIC,W_DRAIN1EWPIC,
- W_WATER2EWPIC,W_DRAIN2EWPIC,
+ W_GEN_DOOR1PIC, //15
+ BRN_WINDOW_LIGHTPIC,
- W_WOODEN_DOORPIC,W_WOOD_DOOREWPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,
+ ALTAR_LEFTPIC,
+ ALTAR_RIGHTPIC,
+ GRAY_LIGHT_WALLPIC,
+ GRAY_LIGHT_SIGNPIC, //20
- W_FINALEXITPIC,
+ MANICLE_LIGHT_WALLPIC,
+ MANICLE_LIGHT_BLOODYPIC,
- W_WATER_EXP1PIC,W_WATER_EXP2PIC,W_WATER_EXP3PIC,
+ LIGHT_CURTAIN_WINDOWPIC,
+ LIGHT_CURTAIN_WALLPIC,
+ BRN_LIGHT_SIGNPIC, //25
- W_PRE_CHEATSPIC,W_CHEAT_WARPPIC,W_CHEAT_FREEZEPIC,W_SURFACE_PLAQPIC,
+ LIGHT_STONE_WALLPIC,
- W_WATER_GATEEW1PIC,
- WALL8LPIC,WALL9LPIC,WALL10DPIC,WALL11LPIC,WALL12LPIC,WALL13LPIC,WALL14LPIC,WALL15LPIC,
- WALL16LPIC,WALL17LPIC,W_WINDOWEWPIC,WALL19LPIC,WALL20LPIC,WALL21LPIC,
- WALL22LPIC,WALL23LPIC,WALL24LPIC,WALL25LPIC,WALL26LPIC,WALL27LPIC,
- WALL28LPIC,WALL29LPIC,WALL30LPIC,WALL31LPIC,
- W_BREATH_LWALL4PIC,W_BREATH_LWALL3PIC,
- MAGE_STATUEPIC,ZOMBIE_STATUEPIC,EYE_STATUEPIC,NEM_STATUEPIC,
- SKELETON_STATUEPIC,SPOOK_STATUEPIC,ORCH_STATUEPIC,
- };
+ W_GEN_DOOR2PIC, //27
-// NORTH / SOUTH WALLS
-//
-int walldark1[NUMFLOORS] = {0,
- W_WARP1NSPIC,
- W_NEMPICEWPIC,W_PENTANSPIC,1,1,
- W_SUB1NSPIC,W_SUB2NSPIC,W_SUB3NSPIC,
+ TROLL_LIGHT_STONEPIC,
- W_TORCH1PIC,W_TORCH2PIC,
- W_DSUB_STONEPIC,
- W_BLOODY_DSUB_STONEPIC,
- W_BREATH_DWALL1PIC,W_BREATH_DWALL2PIC,
+ BRN_FLAGSTONE_LIGHT_2PIC,
- EXPWALL1PIC,EXPWALL2PIC,EXPWALL3PIC,
+ W_CRYSTAL_DOORPIC,
- W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,
+ DMG_BRN_FSTN_LTPIC,
- W_WATER1NSPIC,W_DRAIN1NSPIC,
- W_WATER2NSPIC,W_DRAIN2NSPIC,
- W_WOODEN_DOORPIC,W_WOOD_DOORNSPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,
+ RUST_METAL_LIGHTPIC,
+ GRAY_METAL_LIGHTPIC, //33
- W_FINALEXITPIC,
+ WEAK_STONE_LIGHTPIC,
- W_WATER_EXP1PIC,W_WATER_EXP2PIC,W_WATER_EXP3PIC,
+ DMG_FIN_FSTN_LTPIC,
- W_CHEAT_GODPIC,W_CHEAT_ITEMSPIC,W_POST_CHEATPIC,W_SURFACE_PLAQPIC,
+ WEAK_GRAY_RFGSTN_LIGHTPIC,
+ 0,
- W_WATER_GATENS1PIC,
- WALL8DPIC,WALL9DPIC,WALL10LPIC,WALL11DPIC,WALL12DPIC,WALL13DPIC,WALL14DPIC,WALL15DPIC,
- WALL16DPIC,WALL17DPIC,W_WINDOWNSPIC,WALL19DPIC,WALL20DPIC,WALL21DPIC,
- WALL22DPIC,WALL23DPIC,WALL24DPIC,WALL25DPIC,WALL26DPIC,WALL27DPIC,
- WALL28DPIC,WALL29DPIC,WALL30DPIC,WALL31DPIC,
- W_BREATH_DWALL4PIC,W_BREATH_DWALL3PIC,
- MAGE_STATUEPIC,ZOMBIE_STATUEPIC,EYE_STATUEPIC,NEM_STATUEPIC,
- SKELETON_STATUEPIC,SPOOK_STATUEPIC,ORCH_STATUEPIC,
- };
+ WEAK_CRYSTAL_LIGHTPIC,
-// EAST / WEST WALLS
-//
-int walllight2[NUMFLOORS] = {0,
- W_WARP2EWPIC,
- W_NEMPICEWPIC,W_PENTAEWPIC,W_ALTER_LFPIC,W_ALTER_RTPIC,
- W_SUB1EWPIC,W_SUB2EWPIC,W_SUB3EWPIC,
+ RED_MUD_LIGHTPIC,
+
+ STEEL_DOOR1PIC, //40
+
+ RED_MUD_WEAK_LIGHTPIC,
+
+ STEEL_DOOR2PIC, //42
- W_TORCH2PIC,W_TORCH1PIC,
- W_LSUB_STONEPIC,
- W_BLOODY_LSUB_STONEPIC,
- W_BREATH_LWALL2PIC,W_BREATH_LWALL1PIC,
+ HORN_DOORPIC,
+ TROLL_BLOODY_LT_STONEPIC,
+ CLOSED_DOOR_1PIC,
- EXPWALL2PIC,EXPWALL1PIC,EXPWALL3PIC,
+ GRY_DOOR_LTPIC, //46
- W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,
+ BRN_DOOR_LTPIC, //47
- W_WATER2EWPIC,W_DRAIN2EWPIC,
- W_WATER1EWPIC,W_DRAIN1EWPIC,
+ GRY_FGSTN_LTPIC, //48
+ DOOR_2PIC,
- W_WOODEN_DOORPIC,W_WOOD_DOOREWPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,
+ WATER_LIGHT_WEAK_1PIC,
+ WATER_LIGHT_WEAK_2PIC,
+ WATER_LIGHT_WEAK_3PIC, //52
- W_FINALEXITPIC,
+ WATER_LIGHT_1PIC,
+ WATER_LIGHT_2PIC,
+ WATER_LIGHT_3PIC,
- W_WATER_EXP2PIC,W_WATER_EXP1PIC,W_WATER_EXP1PIC,
+ LIGHT_BREATH_1PIC,
+ LIGHT_BREATH_2PIC,
+ LIGHT_BREATH_3PIC, //58
- W_PRE_CHEATSPIC,W_CHEAT_WARPPIC,W_CHEAT_FREEZEPIC,W_SURFACE_PLAQPIC,
+ EXP_WALL_1PIC,
+ EXP_WALL_2PIC,
+ EXP_WALL_3PIC,
- W_WATER_GATEEW2PIC,
- WALL8LPIC,WALL9LPIC,WALL10DPIC,WALL11LPIC,WALL12LPIC,WALL13LPIC,WALL14LPIC,WALL15LPIC,
- WALL16LPIC,WALL17LPIC,W_WINDOWEWPIC,WALL19LPIC,WALL20LPIC,WALL21LPIC,
- WALL22LPIC,WALL23LPIC,WALL24LPIC,WALL25LPIC,WALL26LPIC,WALL27LPIC,
- WALL28LPIC,WALL29LPIC,WALL30LPIC,WALL31LPIC,
- W_BREATH_LWALL3PIC,W_BREATH_LWALL4PIC,
- MAGE_STATUEPIC,ZOMBIE_STATUEPIC,EYE_STATUEPIC,NEM_STATUEPIC,
- SKELETON_STATUEPIC,SPOOK_STATUEPIC,ORCH_STATUEPIC,
+ WATER_EXP_WALL_1PIC,
+ WATER_EXP_WALL_2PIC,
+ WATER_EXP_WALL_3PIC, //64
+
+ FINALWALLPIC,
+
+ LT_SKEL1PIC,
+ DK_SKEL1PIC,
+ LT_SKEL2PIC,
+ DK_SKEL2PIC,
+
+ 0,
+
+ TAP_1PIC,
+ TAP_2PIC,
+ TAP_3PIC,
+ TAP_4PIC,
+ TAP_5PIC,
+
+ WATER_DOOR1_PIC,
+ WATER_DOOR2_PIC,
};
// NORTH / SOUTH WALLS
//
-int walldark2[NUMFLOORS] = {0,
- W_WARP2NSPIC,
- W_NEMPICEWPIC,W_PENTANSPIC,1,1,
- W_SUB1NSPIC,W_SUB2NSPIC,W_SUB3NSPIC,
+int far walldark1[NUMFLOORS] = {0,
+
+ CRYSTAL_DARK_1PIC,
+ CRYSTAL_DARK_2PIC,
+ CRYSTAL_DARK_3PIC,
+ CRYSTAL_DARK_4PIC, //4
+
+ FIRE_WALL_1PIC,
+ FIRE_WALL_2PIC,
+ FIRE_WALL_3PIC,
+ FIRE_WALL_4PIC, //8
+
+ BRN_STONE_GATEPIC,
+ BRN_STONE_WALL_2PIC,
+ KUDZU_WEAK_DARKPIC,
+ KUDZU_DARK_WALLPIC,
+ HEDGE_WALLPIC,
+ HEDGE_EYESPIC, //14
+
+ W_GEN_DOOR1PIC, //15
+ BRN_WINDOW_DARKPIC,
+
+ ALTAR_LEFTPIC,
+ ALTAR_RIGHTPIC,
+ GRAY_DARK_WALLPIC,
+ GRAY_DARK_SIGNPIC, //20
+
+ MANICLE_DARK_WALLPIC,
+ MANICLE_DARK_BLOODYPIC,
+
+ DARK_CURTAIN_WINDOWPIC,
+ DARK_CURTAIN_WALLPIC,
+ BRN_DARK_SIGNPIC,
+
+ DARK_STONE_WALLPIC,
+
+ W_GEN_DOOR2PIC, //27
+
+ TROLL_DARK_STONEPIC,
+
+ BRN_FLAGSTONE_DARK_2PIC,
+
+ W_CRYSTAL_DOORPIC, //30
+
+ DMG_BRN_FSTN_DKPIC,
+
+ RUST_METAL_DARKPIC,
+ GRAY_METAL_DARKPIC,
+
+ WEAK_STONE_DARKPIC,
+
+ DMG_FIN_FSTN_DKPIC, //35
+
+ WEAK_GRAY_RFGSTN_DARKPIC,
+ 0,
+
+ WEAK_CRYSTAL_DARKPIC,
+
+ BRN_MUD_DARKPIC,
+
+ STEEL_DOOR1PIC, //40
+
+ BRN_MUD_WEAK_DARKPIC,
+
+ STEEL_DOOR2PIC,
+
+ HORN_DOORPIC,
+ TROLL_BLOODY_DK_STONEPIC,
- W_TORCH2PIC,W_TORCH1PIC,
- W_DSUB_STONEPIC,
- W_BLOODY_DSUB_STONEPIC,
- W_BREATH_DWALL2PIC,W_BREATH_DWALL1PIC,
+ CLOSED_DOOR_1PIC,
- EXPWALL2PIC,EXPWALL1PIC,EXPWALL3PIC,
+ GRY_DOOR_DKPIC, //46
+ BRN_DOOR_DKPIC, //47
+ GRY_FGSTN_DKPIC, //48
+ DOOR_2PIC,
- W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,
+ WATER_DARK_WEAK_1PIC,
+ WATER_DARK_WEAK_2PIC,
+ WATER_DARK_WEAK_3PIC,
- W_WATER2NSPIC,W_DRAIN2NSPIC,
- W_WATER1NSPIC,W_DRAIN1NSPIC,
+ WATER_DARK_1PIC,
+ WATER_DARK_2PIC,
+ WATER_DARK_3PIC,
- W_WOODEN_DOORPIC,W_WOOD_DOORNSPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,
+ DARK_BREATH_1PIC,
+ DARK_BREATH_2PIC,
+ DARK_BREATH_3PIC,
- W_FINALEXITPIC,
+ EXP_WALL_1PIC,
+ EXP_WALL_2PIC,
+ EXP_WALL_3PIC,
- W_WATER_EXP2PIC,W_WATER_EXP1PIC,W_WATER_EXP1PIC,
+ WATER_EXP_WALL_1PIC,
+ WATER_EXP_WALL_2PIC,
+ WATER_EXP_WALL_3PIC,
- W_CHEAT_GODPIC,W_CHEAT_ITEMSPIC,W_POST_CHEATPIC,W_SURFACE_PLAQPIC,
+ FINALWALLPIC,
- W_WATER_GATENS2PIC,
- WALL8DPIC,WALL9DPIC,WALL10LPIC,WALL11DPIC,WALL12DPIC,WALL13DPIC,WALL14DPIC,WALL15DPIC,
- WALL16DPIC,WALL17DPIC,W_WINDOWNSPIC,WALL19DPIC,WALL20DPIC,WALL21DPIC,
- WALL22DPIC,WALL23DPIC,WALL24DPIC,WALL25DPIC,WALL26DPIC,WALL27DPIC,
- WALL28DPIC,WALL29DPIC,WALL30DPIC,WALL31DPIC,
- W_BREATH_DWALL3PIC,W_BREATH_DWALL4PIC,
- MAGE_STATUEPIC,ZOMBIE_STATUEPIC,EYE_STATUEPIC,NEM_STATUEPIC,
- SKELETON_STATUEPIC,SPOOK_STATUEPIC,ORCH_STATUEPIC,
+ LT_SKEL1PIC,
+ DK_SKEL1PIC,
+ LT_SKEL2PIC,
+ DK_SKEL2PIC,
+
+ 0,
+
+ TAP_1PIC,
+ TAP_2PIC,
+ TAP_3PIC,
+ TAP_4PIC,
+ TAP_5PIC,
+
+ WATER_DOOR1_PIC,
+ WATER_DOOR2_PIC,
};
+
/*
=====================
=
@@ -601,21 +692,18 @@ int walldark2[NUMFLOORS] = {0,
void DrawVWall (walltype *wallptr)
{
- int x,i;
- unsigned source;
- unsigned width,sourceint;
- unsigned wallpic,wallpicseg;
- unsigned skip;
- long fracheight,fracstep,longheightchange;
- unsigned height;
- int heightchange;
- unsigned slope,distance;
- int traceangle,angle;
- int mapadd;
- unsigned lastpix,lastsource,lastwidth;
-
- short mike;
-
+ int x,i;
+ unsigned source;
+ unsigned width,sourceint;
+ unsigned wallpic,wallpicseg;
+ unsigned skip;
+ long fracheight,fracstep,longheightchange;
+ unsigned height;
+ int heightchange;
+ unsigned slope,distance;
+ int traceangle,angle;
+ int mapadd;
+ unsigned lastpix,lastsource,lastwidth;
if (wallptr->rightclip < wallptr->leftclip)
Quit ("DrawVWall: Right < Left");
@@ -625,15 +713,15 @@ void DrawVWall (walltype *wallptr)
//
wallptr->height1 >>= 1;
wallptr->height2 >>= 1;
- wallptr->planecoord>>=10; // remove non significant bits
+ wallptr->planecoord>>=10; // remove non significant bits
width = wallptr->x2 - wallptr->x1;
if (width)
{
heightchange = wallptr->height2 - wallptr->height1;
- asm mov ax,[heightchange]
- asm mov WORD PTR [longheightchange+2],ax
- asm mov WORD PTR [longheightchange],0 // avoid long shift by 16
+ asm mov ax,[heightchange]
+ asm mov WORD PTR [longheightchange+2],ax
+ asm mov WORD PTR [longheightchange],0 // avoid long shift by 16
fracstep = longheightchange/width;
}
@@ -655,55 +743,41 @@ void DrawVWall (walltype *wallptr)
// find wall picture to map from
//
if (wallptr->side)
- { // east or west wall
-
- if (wallptr->color == 1)
- mike = 1;
-
- if (animframe)
- wallpic = walllight2[wallptr->color];
- else
- wallpic = walllight1[wallptr->color];
+ { // east or west wall
+ wallpic = walllight1[wallptr->color+wall_anim_pos[wallptr->color]];
if (wallptr->planecoord < viewxpix)
{
distance = viewxpix-wallptr->planecoord;
traceangle -= FINEANGLES/2;
- mapadd = (64-viewypix&63); // the pixel spot of the origin
+ mapadd = (64-viewypix&63); // the pixel spot of the origin
}
else
{
distance = wallptr->planecoord-viewxpix;
// traceangle is correct
- mapadd = viewypix&63; // the pixel spot of the origin
+ mapadd = viewypix&63; // the pixel spot of the origin
}
}
else
- { // north or south wall
-
- if (wallptr->color == 1)
- mike = 1;
-
- if (animframe)
- wallpic = walldark2[wallptr->color];
- else
- wallpic = walldark1[wallptr->color];
+ { // north or south wall
+ wallpic = walldark1[wallptr->color+wall_anim_pos[wallptr->color]];
if (wallptr->planecoord < viewypix)
{
distance = viewypix-wallptr->planecoord;
traceangle -= FINEANGLES/4;
- mapadd = viewxpix&63; // the pixel spot of the origin
+ mapadd = viewxpix&63; // the pixel spot of the origin
}
else
{
distance = wallptr->planecoord-viewypix;
traceangle -= FINEANGLES*3/4;
- mapadd = (64-viewxpix&63); // the pixel spot of the origin
+ mapadd = (64-viewxpix&63); // the pixel spot of the origin
}
}
- mapadd = 64*64-mapadd; // make sure it stays positive
+ mapadd = 64*64-mapadd; // make sure it stays positive
wallpicseg = (unsigned)walldirectory[wallpic-FIRSTWALLPIC];
if (traceangle > FINEANGLES/2)
@@ -721,27 +795,27 @@ void DrawVWall (walltype *wallptr)
//
// height
//
- asm mov ax,WORD PTR [fracheight]
- asm mov dx,WORD PTR [fracheight+2]
- asm mov cx,dx
- asm add ax,WORD PTR [fracstep]
- asm adc dx,WORD PTR [fracstep+2]
- asm mov WORD PTR [fracheight],ax
- asm mov WORD PTR [fracheight+2],dx
- asm mov bx,[x]
- asm shl bx,1
- asm cmp cx,MAXSCALEHEIGHT
- asm jbe storeheight
- asm mov cx,MAXSCALEHEIGHT
+ asm mov ax,WORD PTR [fracheight]
+ asm mov dx,WORD PTR [fracheight+2]
+ asm mov cx,dx
+ asm add ax,WORD PTR [fracstep]
+ asm adc dx,WORD PTR [fracstep+2]
+ asm mov WORD PTR [fracheight],ax
+ asm mov WORD PTR [fracheight+2],dx
+ asm mov bx,[x]
+ asm shl bx,1
+ asm cmp cx,MAXSCALEHEIGHT
+ asm jbe storeheight
+ asm mov cx,MAXSCALEHEIGHT
storeheight:
- asm mov WORD PTR [wallheight+bx],cx
- asm mov WORD PTR [zbuffer+bx],cx
+ asm mov WORD PTR [wallheight+bx],cx
+ asm mov WORD PTR [zbuffer+bx],cx
-// height = fracheight>>16;
-// fracheight += fracstep;
-// if (height > MAXSCALEHEIGHT)
-// height = MAXSCALEHEIGHT;
-// wallheight[x] = zbuffer[x] = height;
+// height = fracheight>>16;
+// fracheight += fracstep;
+// if (height > MAXSCALEHEIGHT)
+// height = MAXSCALEHEIGHT;
+// wallheight[x] = zbuffer[x] = height;
//
// texture map
@@ -763,26 +837,26 @@ storeheight:
source >>=20;
source += mapadd;
- source &= 63; // mask off the unused units
+ source &= 63; // mask off the unused units
source = 63-source;
- source <<= 6; // multiply by 64 for offset into pic
+ source <<= 6; // multiply by 64 for offset into pic
#endif
- asm mov ax,[distance]
- asm imul [slope] // ax is the source pixel
- asm mov al,ah
- asm shr al,1
- asm shr al,1 // low 6 bits is now pixel number
- asm add ax,[mapadd]
- asm and ax,63
- asm mov dx,63
- asm sub dx,ax // otherwise it is backwards
- asm shl dx,1
- asm shl dx,1
- asm shl dx,1
- asm shl dx,1
- asm shl dx,1
- asm shl dx,1 // *64 to index into shape
- asm mov [source],dx
+ asm mov ax,[distance]
+ asm imul [slope] // ax is the source pixel
+ asm mov al,ah
+ asm shr al,1
+ asm shr al,1 // low 6 bits is now pixel number
+ asm add ax,[mapadd]
+ asm and ax,63
+ asm mov dx,63
+ asm sub dx,ax // otherwise it is backwards
+ asm shl dx,1
+ asm shl dx,1
+ asm shl dx,1
+ asm shl dx,1
+ asm shl dx,1
+ asm shl dx,1 // *64 to index into shape
+ asm mov [source],dx
if (source != lastsource)
{
@@ -797,7 +871,7 @@ storeheight:
lastwidth = 1;
}
else
- lastwidth++; // optimized draw, same map as last one
+ lastwidth++; // optimized draw, same map as last one
}
wallofs[lastpix] = lastsource;
wallseg[lastpix] = wallpicseg;
@@ -817,8 +891,8 @@ storeheight:
= Follows a ray of the given angle from viewx,viewy in the global map until
= it hits a solid tile
= sets:
-= tile.x,tile.y : tile coordinates of contacted tile
-= tilecolor : solid tile's color
+= tile.x,tile.y : tile coordinates of contacted tile
+= tilecolor : solid tile's color
=
==================
*/
@@ -842,21 +916,21 @@ void TraceRay (unsigned angle)
fixtemp = FixedByFrac(prestep,traceystep);
tracey = viewy-fixtemp;
- tile.x = tracex>>TILESHIFT; // starting point in tiles
+ tile.x = tracex>>TILESHIFT; // starting point in tiles
tile.y = tracey>>TILESHIFT;
- if (tracexstep<0) // use 2's complement, not signed magnitude
+ if (tracexstep<0) // use 2's complement, not signed magnitude
tracexstep = -(tracexstep&0x7fffffff);
- if (traceystep<0) // use 2's complement, not signed magnitude
+ if (traceystep<0) // use 2's complement, not signed magnitude
traceystep = -(traceystep&0x7fffffff);
//
// we assume viewx,viewy is not inside a solid tile, so go ahead one step
//
- do // until a solid tile is hit
+ do // until a solid tile is hit
{
otx = tile.x;
oty = tile.y;
@@ -948,7 +1022,7 @@ void TraceRay (unsigned angle)
========================
*/
-#pragma warn -rvl // I stick the return value in with ASMs
+#pragma warn -rvl // I stick the return value in with ASMs
fixed FixedByFrac (fixed a, fixed b)
{
@@ -957,40 +1031,40 @@ fixed FixedByFrac (fixed a, fixed b)
//
// setup
//
-asm mov si,[WORD PTR b+2] // sign of result = sign of fraction
+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 mov ax,[WORD PTR a]
+asm mov cx,[WORD PTR a+2]
-asm or cx,cx
-asm jns aok: // negative?
-asm not ax
-asm not cx
-asm add ax,1
-asm adc cx,0
-asm xor si,0x8000 // toggle sign of result
+asm or cx,cx
+asm jns aok: // negative?
+asm not ax
+asm not cx
+asm add ax,1
+asm adc 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
+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 not ax
-asm not dx
-asm add ax,1
-asm adc dx,0
+asm test si,0x8000 // is the result negative?
+asm jz ansok:
+asm not ax
+asm not dx
+asm add ax,1
+asm adc dx,0
ansok:;
@@ -1014,44 +1088,44 @@ fixed FixedAdd (fixed a, fixed b)
{
fixed value;
-asm mov ax,[WORD PTR a]
-asm mov dx,[WORD PTR a+2]
+asm mov ax,[WORD PTR a]
+asm mov dx,[WORD PTR a+2]
-asm mov bx,[WORD PTR b]
-asm mov cx,[WORD PTR b+2]
+asm mov bx,[WORD PTR b]
+asm mov cx,[WORD PTR b+2]
-asm or dx,dx
-asm jns aok: // negative?
-asm and dx,0x7fff
-asm not ax // convert a from signed magnitude to 2's compl
-asm not dx
-asm add ax,1
-asm adc dx,0
+asm or dx,dx
+asm jns aok: // negative?
+asm and dx,0x7fff
+asm not ax // convert a from signed magnitude to 2's compl
+asm not dx
+asm add ax,1
+asm adc dx,0
aok:
-asm or cx,cx
-asm jns bok: // negative?
-asm and cx,0x7fff
-asm not bx // convert b from signed magnitude to 2's compl
-asm not cx
-asm add bx,1
-asm adc cx,0
+asm or cx,cx
+asm jns bok: // negative?
+asm and cx,0x7fff
+asm not bx // convert b from signed magnitude to 2's compl
+asm not cx
+asm add bx,1
+asm adc cx,0
bok:
-asm add ax,bx // perform the addition
-asm adc dx,cx
-asm jns done
+asm add ax,bx // perform the addition
+asm adc dx,cx
+asm jns done
-asm and dx,0x7fff // value was negative
-asm not ax // back to signed magnitude
-asm not dx
-asm add ax,1
-asm adc dx,0
+asm and dx,0x7fff // value was negative
+asm not ax // back to signed magnitude
+asm not dx
+asm add ax,1
+asm adc dx,0
done:
-asm mov [WORD PTR value],ax
-asm mov [WORD PTR value+2],dx
+asm mov [WORD PTR value],ax
+asm mov [WORD PTR value+2],dx
return value;
}
@@ -1066,18 +1140,18 @@ asm mov [WORD PTR value+2],dx
= TransformPoint
=
= Takes paramaters:
-= gx,gy : globalx/globaly of point
+= gx,gy : globalx/globaly of point
=
= globals:
-= viewx,viewy : point of view
-= viewcos,viewsin : sin/cos of viewangle
+= viewx,viewy : point of view
+= viewcos,viewsin : sin/cos of viewangle
=
=
= defines:
-= CENTERX : pixel location of center of view window
-= TILEGLOBAL : size of one
-= FOCALLENGTH : distance behind viewx/y for center of projection
-= scale : conversion from global value to screen value
+= CENTERX : pixel location of center of view window
+= TILEGLOBAL : size of one
+= FOCALLENGTH : distance behind viewx/y for center of projection
+= scale : conversion from global value to screen value
=
= returns:
= screenx,screenheight: projected edge location and size
@@ -1203,22 +1277,22 @@ fixed TransformX (fixed gx, fixed gy)
=
= Calculates:
=
-= scale projection constant
-= sintable/costable overlapping fractional tables
-= firstangle/lastangle angles from focalpoint to left/right view edges
-= prestep distance from focal point before checking for tiles
+= scale projection constant
+= sintable/costable overlapping fractional tables
+= firstangle/lastangle angles from focalpoint to left/right view edges
+= prestep distance from focal point before checking for tiles
=
==================
*/
void BuildTables (void)
{
- int i;
- long intang;
- long x;
- float angle,anglestep,radtoint;
- double tang;
- fixed value;
+ int i;
+ long intang;
+ long x;
+ float angle,anglestep,radtoint;
+ double tang;
+ fixed value;
//
// calculate the angle offset from view angle of each pixel's ray
@@ -1239,7 +1313,7 @@ void BuildTables (void)
// calculate fine tangents
// 1 sign bit, 5 units (clipped to), 10 fracs
//
-#define MININT (-MAXINT)
+#define MININT (-MAXINT)
for (i=0;i<FINEANGLES/4;i++)
{
@@ -1255,8 +1329,8 @@ void BuildTables (void)
intang = 0xff00 | (intang & 0xff);
finetangent[i] = intang;
-// finetangent[FINEANGLES/2+i] = intang;
-// finetangent[FINEANGLES/2-i-1] = -intang;
+// finetangent[FINEANGLES/2+i] = intang;
+// finetangent[FINEANGLES/2-i-1] = -intang;
finetangent[FINEANGLES-i-1] = -intang;
}
@@ -1321,50 +1395,93 @@ void BuildTables (void)
void ClearScreen (void)
{
unsigned topcolor=*skycolor, bottomcolor=*groundcolor;
+ unsigned topimage=topcolor&0xf0,bottomimage=bottomcolor&0xf0;
+ unsigned pfoffset=0;
+
+
+#if USE_STRIPS
+ if (topimage == 0x20) // special code for lightning
+ topimage = topcolor = 0;
+
+// Manually wipe screen with solid color.
+// If BOTH sky and ground are 'images' don't manually clear it!
+//
+ if ((!topimage) || (!bottomimage))
+ {
+#endif
//
// 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,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-VIEWWIDTH/8
-asm mov bl,VIEWWIDTH/16
-asm mov bh,CENTERY+1
+//asm mov dx,40-VIEWWIDTH/8 // dx = modulo
+asm mov bl,VIEWWIDTH/16
+asm mov bh,CENTERY+1
-asm mov ax,topcolor
-asm mov es,[screenseg]
-asm mov di,[bufferofs]
-asm add di,((SCREENWIDTH*VIEWY)+(VIEWX/8))
+asm mov ax,topcolor
+asm mov es,[screenseg]
+asm mov di,[bufferofs]
+asm add di,((SCREENWIDTH*VIEWY)+(VIEWX/8))
toploop:
-asm mov cl,bl
-asm rep stosw
-asm stosb
-asm add di,dx
-asm dec bh
-asm jnz toploop
+asm mov cl,bl
+asm rep stosw
+asm stosb
+//asm add di,dx // no need to add "0" modulo
+asm dec bh
+asm jnz toploop
-asm mov bh,CENTERY+1
-asm mov ax,bottomcolor
+asm mov bh,CENTERY+1
+asm mov ax,bottomcolor
bottomloop:
-asm mov cl,bl
-asm rep stosw
-asm stosb
-asm add di,dx
-asm dec bh
-asm jnz bottomloop
+asm mov cl,bl
+asm rep stosw
+asm stosb
+//asm add di,dx // no need to add "0" modulo
+asm dec bh
+asm jnz bottomloop
+
+#if USE_STRIPS
+ }
-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
+//
+// code to test parallax turning
+//
+
+ if (topimage)
+ {
+ topimage -= 16;
+ pfoffset = LONG_PERCENTAGE(3200,359,(359-player->angle),12);
+ while (pfoffset >= 640)
+ pfoffset -= 640;
+ LatchDrawPicStrip(0,0,SKY1PIC+topimage,pfoffset+8);
+ }
+
+ if (bottomimage)
+ {
+//// pfoffset = LONG_PERCENTAGE(3200,359,(359-player->angle),12)+320;
+// pfoffset += 320;
+// while (pfoffset >= 640)
+// pfoffset -= 640;
+// LatchDrawPicStrip(0,64,SKY1PIC+topimage,pfoffset+8);
+ bottomimage -= 16;
+ LatchDrawPic(0,64,GND1PIC+bottomimage);
+ }
+#endif
+
+
+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
}
@@ -1385,12 +1502,12 @@ void DrawWallList (void)
int i,leftx,newleft,rightclip;
walltype *wall, *check;
-asm mov ax,ds
-asm mov es,ax
-asm mov di,OFFSET wallwidth
-asm xor ax,ax
-asm mov cx,VIEWWIDTH/2
-asm rep stosw
+asm mov ax,ds
+asm mov es,ax
+asm mov di,OFFSET wallwidth
+asm xor ax,ax
+asm mov cx,VIEWWIDTH/2
+asm rep stosw
ClearScreen ();
@@ -1418,7 +1535,7 @@ asm rep stosw
rightclip=VIEWXH;
if (leftx < wall->x1 - 1)
- newleft = wall->x1-1; // there was black space between walls
+ newleft = wall->x1-1; // there was black space between walls
else
newleft = leftx;
@@ -1432,7 +1549,7 @@ asm rep stosw
}
#ifndef DRAWEACH
- ScaleWalls (); // draw all the walls
+ ScaleWalls (); // draw all the walls
#endif
}
@@ -1452,10 +1569,15 @@ objtype *depthsort[MAXACTORS];
void DrawScaleds (void)
{
- int i,j,least,numvisable,height;
- objtype *obj,**vislist,*farthest;
- memptr shape;
- byte *tilespot,*visspot;
+#if USE_INERT_LIST
+ extern inertobjtype inertobjlist[], *inert;
+
+ boolean inertlist=false;
+#endif
+ int i,j,least,numvisable,height;
+ objtype *obj,**vislist,*farthest;
+ memptr shape;
+ byte *tilespot,*visspot;
numvisable = 0;
@@ -1464,7 +1586,8 @@ void DrawScaleds (void)
//
vislist = &depthsort[0];
- for (obj = player->next;obj;obj=obj->next)
+ obj = player->next;
+ while (obj)
{
tilespot = &tilemap[0][0]+(obj->tilex<<6)+obj->tiley;
visspot = &spotvis[0][0]+(obj->tilex<<6)+obj->tiley;
@@ -1481,27 +1604,44 @@ void DrawScaleds (void)
|| ( *(visspot+64) && !*(tilespot+64) )
|| ( *(visspot+63) && !*(tilespot+63) ) )
{
- if ((obj->active == noalways) || (obj->active == always))
- obj->active = always;
- else
- obj->active = yes;
+#if USE_INERT_LIST
+ if (!inertlist)
+#endif
+ if ((obj->active == noalways) || (obj->active == always))
+ obj->active = always;
+ else
+ obj->active = yes;
TransformActor (obj);
if (!obj->viewheight || obj->viewheight > VIEWWIDTH)
- continue; // too close or far away
+ goto cont; // too close or far away
if (!obj->state->shapenum)
- continue;
+ goto cont;
*vislist++ = obj;
numvisable++;
}
else
- if ((obj->active != always) && (obj->active != noalways))
- obj->active = no;
+#if USE_INERT_LIST
+ if (!inertlist)
+#endif
+ if ((obj->active != always) && (obj->active != noalways))
+ obj->active = no;
+
+cont:;
+ obj = obj->next;
+#if USE_INERT_LIST
+ if ((!obj) && (!inertlist))
+ {
+ if (inert != inertobjlist)
+ obj = (objtype *)inertobjlist;
+ inertlist = true;
+ }
+#endif
}
if (vislist == &depthsort[0])
- return; // no visable objects
+ return; // no visable objects
//
// draw from back to front
@@ -1540,7 +1680,7 @@ void DrawScaleds (void)
void CalcTics (void)
{
- long newtime,oldtimecount;
+ long newtime,oldtimecount;
#ifdef PROFILE
@@ -1552,11 +1692,11 @@ void CalcTics (void)
// calculate tics since last refresh for adaptive timing
//
if (lasttimecount > TimeCount)
- TimeCount = lasttimecount; // if the game was paused a LONG time
+ TimeCount = lasttimecount; // if the game was paused a LONG time
#if 0
- if (DemoMode) // demo recording and playback needs
- { // to be constant
+ if (DemoMode) // demo recording and playback needs
+ { // to be constant
//
// take DEMOTICS or more tics, and modify Timecount to reflect time taken
//
@@ -1608,20 +1748,20 @@ void CalcTics (void)
========================
*/
-void DrawHand (void)
+void DrawHand (void)
{
- #define HAND_X_POS ((VIEWWIDTH/16)-(10/2)) // "10" = hand width in bytes
+ #define HAND_X_POS ((VIEWWIDTH/16)-(10/2)) // "10" = hand width in bytes
#define picnum HAND1PICM
memptr source;
unsigned dest,width,height;
-// if (gamestate.shotpower || boltsleft)
-// picnum += (((unsigned)TimeCount>>3)&1);
+// if (gamestate.shotpower || boltsleft)
+// picnum += (((unsigned)TimeCount>>3)&1);
source = grsegs[picnum];
- dest = ylookup[VIEWHEIGHT-handheight]+HAND_X_POS+bufferofs; // 12
+ dest = ylookup[VIEWHEIGHT-handheight]+HAND_X_POS+bufferofs; // 12
width = picmtable[picnum-STARTPICM].width;
height = picmtable[picnum-STARTPICM].height;
@@ -1640,7 +1780,7 @@ void DrawHand (void)
========================
*/
-void ThreeDRefresh (void)
+void ThreeDRefresh (void)
{
int tracedir;
@@ -1650,17 +1790,17 @@ restart:
//
// 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,[mapwidth] // mapheight*32 words
-asm shl cx,1
-asm shl cx,1
-asm shl cx,1
-asm shl cx,1
-asm shl cx,1
-asm rep stosw
+asm mov ax,ds
+asm mov es,ax
+asm mov di,OFFSET spotvis
+asm xor ax,ax
+asm mov cx,[mapwidth] // mapheight*32 words
+asm shl cx,1
+asm shl cx,1
+asm shl cx,1
+asm shl cx,1
+asm shl cx,1
+asm rep stosw
//
@@ -1673,7 +1813,7 @@ asm rep stosw
viewcos = costable[viewangle];
viewx = player->x - FixedByFrac(FOCALLENGTH,viewcos);
viewy = player->y + FixedByFrac(FOCALLENGTH,viewsin);
- viewx &= 0xfffffc00; // stop on a pixel boundary
+ viewx &= 0xfffffc00; // stop on a pixel boundary
viewy &= 0xfffffc00;
viewx += 0x180;
viewy += 0x180;
@@ -1728,22 +1868,23 @@ asm rep stosw
//
// draw the wall list saved be FollowWalls ()
//
- animframe = (TimeCount&8)>>3;
+// animframe = (TimeCount&8)>>3;
//
// draw all the scaled images
//
- asm mov dx,GC_INDEX
+ asm mov dx,GC_INDEX
- asm mov ax,GC_COLORDONTCARE
- asm out dx,ax // don't look at any of the planes
+ asm mov ax,GC_COLORDONTCARE
+ asm out dx,ax // don't look at any of the planes
- asm mov ax,GC_MODE + 256*(10) // read mode 1, write mode 2
- asm out dx,ax
+ 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
+ asm mov al,GC_BITMASK
+ asm out dx,al
+ AnimateWallList();
DrawWallList();
DrawScaleds();
@@ -1764,24 +1905,24 @@ asm rep stosw
fizzlein = false;
FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,true);
lasttimecount = TimeCount;
- if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
+ if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
}
-asm cli
-asm mov cx,[bufferofs]
-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 dec dx
-asm mov al,0dh // start address low register
-asm out dx,al
-asm inc dx
-asm mov al,cl
-asm out dx,al // set the low byte
-asm sti
+asm cli
+asm mov cx,[bufferofs]
+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 dec dx
+asm mov al,0dh // start address low register
+asm out dx,al
+asm inc dx
+asm mov al,cl
+asm out dx,al // set the low byte
+asm sti
displayofs = bufferofs;
diff --git a/C5_GAME.C b/C5_GAME.C
index edb7612..14693a7 100644
--- a/C5_GAME.C
+++ b/C5_GAME.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -37,50 +37,72 @@
=============================================================================
*/
-#define NUMLUMPS 36
+#define NUMLUMPS 61
-#define ORCLUMP 0
-#define TROLLLUMP 1
-#define BOLTLUMP 2
-#define NUKELUMP 3
-#define POTIONLUMP 4
+#define SUCCUBUSLUMP 0
+#define FATDEMONLUMP 1
+#define BOLTLUMP 2
+#define NUKELUMP 3
+#define POTIONLUMP 4
#define RKEYLUMP 5
#define YKEYLUMP 6
#define GKEYLUMP 7
#define BKEYLUMP 8
-#define SCROLLLUMP 9
+//#define SCROLLLUMP 9
#define CHESTLUMP 10
#define PLAYERLUMP 11
#define WALL1LUMP 12
#define WALL2LUMP 13
#define BDOORLUMP 14
-#define DEMONLUMP 15
-#define MAGELUMP 16
-#define BATLUMP 17
-#define GRELLUMP 18
-#define TOMBSTONESLUMP 19
-#define ZOMBIELUMP 20
-#define SPOOKLUMP 21
-#define SKELETONLUMP 22
-#define RGEMLUMP 23
-#define GGEMLUMP 24
-#define BGEMLUMP 25
-#define YGEMLUMP 26
-#define PGEMLUMP 27
-#define RKEY2LUMP 28
-#define WETMANLUMP 29
-#define OBJ_WARPLUMP 30
-#define EYELUMP 31
-#define REDDEMONLUMP 32
-#define PITLUMP 33
-#define FTIMELUMP 34
-#define WATERCHESTLUMP 35
-
-
+#define GODESSLUMP 15
+#define MAGELUMP 16
+#define BATLUMP 17
+#define GRELLUMP 18
+#define TOMBSTONESLUMP 19
+#define ZOMBIELUMP 20
+#define ANTLUMP 21
+#define SKELETONLUMP 22
+#define RGEMLUMP 23
+#define GGEMLUMP 24
+#define BGEMLUMP 25
+#define YGEMLUMP 26
+#define PGEMLUMP 27
+//#define RKEY2LUMP 28
+#define DRAGONLUMP 29
+#define OBJ_WARPLUMP 30
+#define EYELUMP 31
+#define REDDEMONLUMP 32
+//#define PITLUMP 33
+#define FTIMELUMP 34
+#define WATERCHESTLUMP 35
+#define TREELUMP 36
+#define ARCH1LUMP 37
+#define BUNNYLUMP 38
+#define ANTHILLLUMP 39
+#define COLUMNLUMP 40
+#define SULPHURGASLUMP 41
+#define FIREPOTLUMP 42
+//#define WHIRLPOOLLUMP 43
+#define FOUNTAINLUMP 44
+#define FORCEFIELDLUMP 45
+#define ARCH2LUMP 46
+#define ARCH3LUMP 47
+#define ARCH4LUMP 48
+#define ARCH5LUMP 49
+#define ARCH6LUMP 50
+#define SKELHANGLUMP 51
+//#define SKELPILELUMP 52
+#define ARCH7LUMP 53
+#define ARCH8LUMP 54
+#define ARCH9LUMP 55
+#define ARCH10LUMP 56
+#define ARCH11LUMP 57
+#define ARCH12LUMP 58
+#define ARCH13LUMP 59
int lumpstart[NUMLUMPS] = {
-ORC_LUMP_START,
-TROLL_LUMP_START,
+SUCCUBUS_LUMP_START,
+FATDEMON_LUMP_START,
BOLT_LUMP_START,
NUKE_LUMP_START,
POTION_LUMP_START,
@@ -88,40 +110,65 @@ RKEY_LUMP_START,
YKEY_LUMP_START,
GKEY_LUMP_START,
BKEY_LUMP_START,
-SCROLL_LUMP_START,
+0,
+//SCROLL_LUMP_START,
CHEST_LUMP_START,
PLAYER_LUMP_START,
//WALL1_LUMP_START,
//WALL2_LUMP_START,
//BDOOR_LUMP_START,
0,0,0,
-DEMON_LUMP_START,
+GODESS_LUMP_START,
MAGE_LUMP_START,
BAT_LUMP_START,
GREL_LUMP_START,
TOMBSTONES_LUMP_START,
ZOMBIE_LUMP_START,
-SPOOK_LUMP_START,
+ANT_LUMP_START,
SKELDUDE_LUMP_START,
RGEM_LUMP_START,
GGEM_LUMP_START,
BGEM_LUMP_START,
YGEM_LUMP_START,
PGEM_LUMP_START,
-RKEY2_LUMP_START,
-WETMAN_LUMP_START,
+0, //RKEY2_LUMP_START,
+DRAGON_LUMP_START,
OBJ_WARP_LUMP_START,
EYE_LUMP_START,
REDDEMON_LUMP_START,
-PIT_LUMP_START,
+0, //PIT_LUMP_START,
TIME_LUMP_START,
O_WATER_CHEST_LUMP_START,
+TREE_LUMP_START,
+ARCH1_LUMP_START,
+BUNNY_LUMP_START,
+ANTHILL_LUMP_START,
+COLUMN_LUMP_START,
+SULPHURGAS_LUMP_START,
+FIREPOT_LUMP_START,
+0, //WHIRLPOOL_LUMP_START,
+FOUNTAIN_LUMP_START,
+FORCEFIELD_LUMP_START,
+ARCH2_LUMP_START,
+ARCH3_LUMP_START,
+ARCH4_LUMP_START,
+ARCH5_LUMP_START,
+ARCH6_LUMP_START,
+SKELHANG_LUMP_START,
+0, //SKELPILE_LUMP_START,
+ARCH7_LUMP_START,
+ARCH8_LUMP_START,
+ARCH9_LUMP_START,
+ARCH10_LUMP_START,
+ARCH11_LUMP_START,
+ARCH12_LUMP_START,
+ARCH13_LUMP_START,
};
int lumpend[NUMLUMPS] = {
-ORC_LUMP_END,
-TROLL_LUMP_END,
+SUCCUBUS_LUMP_END,
+FATDEMON_LUMP_END,
BOLT_LUMP_END,
NUKE_LUMP_END,
POTION_LUMP_END,
@@ -129,37 +176,60 @@ RKEY_LUMP_END,
YKEY_LUMP_END,
GKEY_LUMP_END,
BKEY_LUMP_END,
-SCROLL_LUMP_END,
+0,
+//SCROLL_LUMP_END,
CHEST_LUMP_END,
PLAYER_LUMP_END,
-//WALL1_LUMP_END,
-//WALL2_LUMP_END,
-//BDOOR_LUMP_END,
0,0,0,
-DEMON_LUMP_END,
+GODESS_LUMP_END,
MAGE_LUMP_END,
BAT_LUMP_END,
GREL_LUMP_END,
TOMBSTONES_LUMP_END,
ZOMBIE_LUMP_END,
-SPOOK_LUMP_END,
+ANT_LUMP_END,
SKELDUDE_LUMP_END,
RGEM_LUMP_END,
GGEM_LUMP_END,
BGEM_LUMP_END,
YGEM_LUMP_END,
PGEM_LUMP_END,
-RKEY2_LUMP_END,
-WETMAN_LUMP_END,
+0, //RKEY2_LUMP_END,
+DRAGON_LUMP_END,
OBJ_WARP_LUMP_END,
EYE_LUMP_END,
REDDEMON_LUMP_END,
-PIT_LUMP_END,
+0, //PIT_LUMP_END,
TIME_LUMP_END,
O_WATER_CHEST_LUMP_END,
+TREE_LUMP_END,
+ARCH1_LUMP_END,
+BUNNY_LUMP_END,
+ANTHILL_LUMP_END,
+COLUMN_LUMP_END,
+SULPHURGAS_LUMP_END,
+FIREPOT_LUMP_END,
+0, //WHIRLPOOL_LUMP_END,
+FOUNTAIN_LUMP_END,
+FORCEFIELD_LUMP_END,
+ARCH2_LUMP_END,
+ARCH3_LUMP_END,
+ARCH4_LUMP_END,
+ARCH5_LUMP_END,
+ARCH6_LUMP_END,
+SKELHANG_LUMP_END,
+0, //SKELPILE_LUMP_END,
+ARCH7_LUMP_END,
+ARCH8_LUMP_END,
+ARCH9_LUMP_END,
+ARCH10_LUMP_END,
+ARCH11_LUMP_END,
+ARCH12_LUMP_END,
+ARCH13_LUMP_END,
};
+//extern unsigned scolor,gcolor;
/*
@@ -192,7 +262,7 @@ boolean lumpneeded[NUMLUMPS];
//==========================================================================
//
//
-// LOCAL PROTOTYPES
+// LOCAL PROTOTYPES
//
//
//==========================================================================
@@ -213,15 +283,18 @@ void CashPoints(void);
void ScanInfoPlane (void)
{
- extern unsigned gnd_colors[];
-
- char hibyte;
+ unsigned char hibyte;
unsigned x,y,i,j;
- int tile;
+ unsigned int tile;
unsigned far *start;
InitObjList(); // start spawning things with a clean slate
+ scolor = gcolor = 0;
+ skycolor = &scolor;
+ groundcolor = &gcolor;
+
+
memset (lumpneeded,0,sizeof(lumpneeded));
start = mapsegs[2];
@@ -231,7 +304,38 @@ void ScanInfoPlane (void)
tile = *start++;
hibyte = tile >> 8;
tile &= 0xff;
- if (!tile)
+
+ switch (hibyte)
+ {
+ char hi;
+
+ case 0xFB:
+ wall_anim_time = tile;
+ tile = 0;
+ break;
+
+ case 0xfa: // sky/ground color
+ case 0xf9: // sky/ground 'strip'
+ x++;
+ tile = *start++;
+ hi = tile >> 8;
+ tile &= 0xff;
+ switch (hibyte)
+ {
+ case 0xfa: // sky / ground color
+ scolor = ((hi)|(hi<<8));
+ gcolor = ((tile)|(tile<<8));
+ skycolor = &scolor;
+ groundcolor = &gcolor;
+ break;
+
+ case 0xf9: // sky / ground 'strip'
+ break;
+ }
+ break;
+ }
+
+ if ((!tile) || (hibyte))
continue;
switch (tile)
@@ -255,20 +359,7 @@ void ScanInfoPlane (void)
SpawnBonus(x,y,tile-5);
break;
- case 29:
- lumpneeded[RKEY2LUMP] = true;
- SpawnBonus(x,y,B_RKEY2);
- break;
-
- case 58:
- case 59:
- case 60:
- case 61:
- case 62:
- lumpneeded[tile-58+RGEMLUMP] = true;
- SpawnBonus(x,y,tile-58+B_RGEM);
- break;
-
+#if 0
case 12:
case 13:
case 14:
@@ -280,6 +371,12 @@ void ScanInfoPlane (void)
lumpneeded[SCROLLLUMP] = true;
SpawnBonus(x,y,B_SCROLL1+tile-12);
break;
+#endif
+
+ case 20:
+ lumpneeded[REDDEMONLUMP] = true;
+ SpawnRedDemon (x,y);
+ break;
#if 0
case 20: // goal
@@ -288,73 +385,36 @@ void ScanInfoPlane (void)
break;
#endif
- case 21: // chest
- if (gnd_colors[gamestate.mapon] == 0x0101)
- lumpneeded[WATERCHESTLUMP] = true;
- else
- lumpneeded[CHESTLUMP] = true;
- SpawnBonus(x,y,B_CHEST);
- break;
-
- case 31:
- case 32:
- case 33:
- case 34:
- case 35:
- lumpneeded[OBJ_WARPLUMP] = true;
- SpawnWarp (x,y,tile-30);
+ case 21:
+ lumpneeded[GODESSLUMP] = true;
+ SpawnGodess (x,y);
break;
- case 41:
- if (gamestate.difficulty <gd_Hard)
- break;
- case 36:
- if (gamestate.difficulty <gd_Normal)
- break;
case 22:
- lumpneeded[TROLLLUMP] = true;
- SpawnTroll (x,y);
+ lumpneeded[FATDEMONLUMP] = true;
+ SpawnFatDemon (x,y);
break;
- case 42:
- if (gamestate.difficulty <gd_Hard)
- break;
- case 37:
- if (gamestate.difficulty <gd_Normal)
- break;
case 23:
- lumpneeded[ORCLUMP] = true;
- SpawnOrc (x,y);
+ lumpneeded[SUCCUBUSLUMP] = true;
+ SpawnSuccubus (x,y);
+ break;
+
+ case 24:
+ lumpneeded[DRAGONLUMP] = true;
+ SpawnDragon(x,y);
break;
- case 43:
- if (gamestate.difficulty <gd_Hard)
- break;
- case 38:
- if (gamestate.difficulty <gd_Normal)
- break;
case 25:
lumpneeded[BATLUMP] = true;
SpawnBat (x,y);
break;
- case 44:
- if (gamestate.difficulty <gd_Hard)
- break;
- case 39:
- if (gamestate.difficulty <gd_Normal)
- break;
case 26:
- lumpneeded[DEMONLUMP] = true;
- SpawnDemon (x,y);
+ lumpneeded[EYELUMP] = true;
+ SpawnEye(x,y);
break;
- case 45:
- if (gamestate.difficulty <gd_Hard)
- break;
- case 40:
- if (gamestate.difficulty <gd_Normal)
- break;
case 27:
lumpneeded[MAGELUMP] = true;
SpawnMage (x,y);
@@ -365,98 +425,179 @@ void ScanInfoPlane (void)
SpawnGrelminar (x,y);
break;
-#if 0
- case 29:
- SpawnBounce (x,y,0);
+ case 30:
+ lumpneeded[ANTLUMP] = true;
+ SpawnAnt(x,y);
break;
- case 30:
- SpawnBounce (x,y,1);
+ case 31:
+ case 32:
+ case 33:
+ case 34:
+ case 35:
+ lumpneeded[OBJ_WARPLUMP] = true;
+ SpawnWarp (x,y,tile-30);
+ break;
+
+ case 36:
+ lumpneeded[ZOMBIELUMP] = true;
+ SpawnZombie(x,y);
+ break;
+
+ case 37:
+ lumpneeded[SKELETONLUMP] = true;
+ SpawnSkeleton(x,y);
+ break;
+
+ case 38:
+ lumpneeded[SKELETONLUMP] = true;
+ SpawnWallSkeleton(x,y);
+ break;
+
+ case 39:
+ lumpneeded[FTIMELUMP] = true;
+ SpawnFTime(x,y);
break;
-#endif
+ case 40:
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ lumpneeded[tile-40+RGEMLUMP] = true;
+ SpawnBonus(x,y,tile-40+B_RGEM);
+ break;
+
+ case 45:
case 46:
case 47:
- case 48:
lumpneeded[TOMBSTONESLUMP] = true;
- SpawnTombstone(x,y,tile-46);
- break;
+ SpawnTombstone(x,y,tile-45);
+ break;
- case 54:
- lumpneeded[PITLUMP] = true;
+#if 0
+ case 48:
+ lumpneeded[PITLUMP] = true;
SpawnWarp(x,y,0);
break;
-
- case 53:
- if (gamestate.difficulty <gd_Normal)
- break;
- case 52:
- lumpneeded[ZOMBIELUMP] = true;
- SpawnZombie(x,y);
+#endif
+ case 49: // chest
+ if (gcolor == 0x0101)
+ lumpneeded[WATERCHESTLUMP] = true;
+ else
+ lumpneeded[CHESTLUMP] = true;
+ SpawnBonus(x,y,B_CHEST);
break;
- case 51:
- if (gamestate.difficulty <gd_Hard)
- break;
case 50:
- if (gamestate.difficulty <gd_Normal)
- break;
- case 49:
- lumpneeded[SPOOKLUMP] = true;
- SpawnSpook(x,y);
+ lumpneeded[TREELUMP] = true;
+ SpawnTree(x,y);
break;
- case 57:
- lumpneeded[FTIMELUMP] = true;
- SpawnFTime(x,y);
+ case 51:
+ lumpneeded[BUNNYLUMP] = true;
+ SpawnBunny(x,y);
+ break;
+
+ case 52:
+ lumpneeded[ARCH1LUMP] = true;
+ SpawnArch(x,y,1);
+ break;
+
+ case 53:
+ lumpneeded[ANTHILLLUMP] = true;
+ SpawnWarp(x,y,0);
+ break;
+
+ case 54:
+ lumpneeded[COLUMNLUMP] = true;
+ SpawnMiscObjects(x,y,1); //1=column,2=sulphur hole,3=fire pot,4=fountain
break;
- case 56:
- if (gamestate.difficulty <gd_Normal)
- break;
case 55:
- lumpneeded[SKELETONLUMP] = true;
- SpawnSkeleton(x,y);
+ lumpneeded[SULPHURGASLUMP] = true;
+ SpawnMiscObjects(x,y,2);
+ break;
+
+ case 56:
+ lumpneeded[FIREPOTLUMP] = true;
+ SpawnMiscObjects(x,y,3);
+ break;
+
+ case 57:
+ lumpneeded[ARCH13LUMP] = true;
+ SpawnArch(x,y,13);
+ break;
+
+ case 58:
+ lumpneeded[FOUNTAINLUMP] = true;
+ SpawnMiscObjects(x,y,4);
+ break;
+
+ case 59:
+ lumpneeded[FORCEFIELDLUMP] = true;
+ SpawnForceField(x,y);
+ break;
+
+ case 60:
+ lumpneeded[ARCH2LUMP] = true;
+ SpawnArch(x,y,2);
+ break;
+
+ case 61:
+ lumpneeded[ARCH3LUMP] = true;
+ SpawnArch(x,y,3);
+ break;
+
+ case 62:
+ lumpneeded[ARCH4LUMP] = true;
+ SpawnArch(x,y,4);
break;
- case 65:
- if (gamestate.difficulty <gd_Hard)
- break;
- case 64:
- if (gamestate.difficulty <gd_Normal)
- break;
case 63:
- lumpneeded[WETMANLUMP] = true;
- SpawnWetMan(x,y);
+ lumpneeded[ARCH5LUMP] = true;
+ SpawnArch(x,y,5);
+ break;
+
+ case 64:
+ lumpneeded[ARCH6LUMP] = true;
+ SpawnArch(x,y,6);
+ break;
+
+ case 65:
+ lumpneeded[SKELHANGLUMP] = true;
+ lumpneeded[SKELETONLUMP] = true;
+ SpawnSkeletonHanging(x,y);
break;
- case 68:
- if (gamestate.difficulty <gd_Hard)
- break;
- case 67:
- if (gamestate.difficulty <gd_Normal)
- break;
case 66:
- lumpneeded[EYELUMP] = true;
- SpawnEye(x,y);
+ lumpneeded[ARCH12LUMP] = true;
+ SpawnArch(x,y,12);
+ break;
+
+ case 67:
+ lumpneeded[ARCH7LUMP] = true;
+ SpawnArch(x,y,7);
+ break;
+
+ case 68:
+ lumpneeded[ARCH8LUMP] = true;
+ SpawnArch(x,y,8);
break;
- case 71:
- if (gamestate.difficulty <gd_Hard)
- break;
- case 70:
- if (gamestate.difficulty <gd_Normal)
- break;
case 69:
- lumpneeded[SKELETONLUMP] = true;
- SpawnWallSkeleton(x,y);
+ lumpneeded[ARCH9LUMP] = true;
+ SpawnArch(x,y,9);
break;
- case 20:
- case 24:
- case 30:
- lumpneeded[REDDEMONLUMP] = true;
- SpawnRedDemon (x,y);
+ case 70:
+ lumpneeded[ARCH10LUMP] = true;
+ SpawnArch(x,y,10);
+ break;
+
+ case 71:
+ lumpneeded[ARCH11LUMP] = true;
+ SpawnArch(x,y,11);
break;
}
}
@@ -505,10 +646,10 @@ void ScanText (void)
=
==================
*/
-
+#if 0
static char *levelnames[] =
{
- "The Towne Cemetery",
+ "Programmers Test Map",
"The Garden of Tears",
"The Den of Zombies",
"The Mausoleum Grounds",
@@ -526,8 +667,30 @@ static char *levelnames[] =
"The Haunt of Nemesis",
"The Passage to the Surface",
"Big Jim's Domain",
- "Nolan's Nasty",
+ "Nolan",
+ "19",
+ "20",
+ "21",
+ "22",
+ "23",
+ "24",
+ "25",
+ "26",
+ "27",
+ "28",
+ "29",
+ "30",
+ "31",
+ "32",
+ "33",
+ "34",
+ "35",
+ "36",
+ "37",
+ "38",
+ "39",
};
+#endif
void DrawEnterScreen (void)
{
@@ -535,12 +698,13 @@ void DrawEnterScreen (void)
bufferofs = displayofs = screenloc[screenpage];
VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,0);
- width = strlen(levelnames[gamestate.mapon]);
+// width = strlen(levelnames[gamestate.mapon]);
+ width = strlen("You enter a new area ...");
if (width < 20)
width = 20;
- CenterWindow(width,5);
- US_CPrint("\nYou have arrived at\n");
- US_CPrint(levelnames[gamestate.mapon]);
+ CenterWindow(width,3);
+ US_CPrint("\nYou enter a new area ...\n");
+// US_CPrint(levelnames[gamestate.mapon]);
}
//==========================================================================
@@ -585,9 +749,7 @@ void CacheScaleds (void)
if (tileneeded[i])
{
SetupScaleWall (walllight1[i]);
- SetupScaleWall (walllight2[i]);
SetupScaleWall (walldark1[i]);
- SetupScaleWall (walldark2[i]);
}
//
@@ -610,6 +772,7 @@ void CacheScaleds (void)
//==========================================================================
+
/*
==================
=
@@ -622,6 +785,8 @@ void SetupGameLevel ()
{
int x,y,i,loop;
unsigned far *map,tile,far *spotptr,spot;
+ unsigned search_tile;
+ boolean exploding_walls_present = false;
memset (tileneeded,0,sizeof(tileneeded));
//
@@ -655,6 +820,7 @@ void SetupGameLevel ()
spot += mapwidth;
}
+
//
// copy the wall data to a data segment array
//
@@ -669,21 +835,46 @@ void SetupGameLevel ()
if (((*spotptr)>>8) == EXP_WALL_CODE)
{
- extern unsigned gnd_colors[];
-
- if (gnd_colors[gamestate.mapon] == 0x0101)
- tileneeded[WATEREXP] = tileneeded[WATEREXP+1] = tileneeded[WATEREXP+2] = true;
- else
- tileneeded[WALLEXP] = tileneeded[WALLEXP+1] = tileneeded[WALLEXP+2] = true;
+ exploding_walls_present = true;
}
if (tile<NUMFLOORS)
{
+#if 0
if (tile == WALL_SKELETON_CODE)
+ {
tileneeded[tile+1] = tileneeded[tile+2] = true;
-
- tileneeded[tile] = true;
- tilemap[x][y] = tile;
+ tilemap[x][y] = tile;
+ }
+#endif
+ if ((tile == 66) || (tile == 67) || (tile == 68) || (tile == 69))
+ {
+ if ((tile == 66) || (tile == 67))
+ tileneeded[tile+2] = true;
+ tileneeded[21] = tileneeded[tile] = true;
+ tilemap[x][y] = tile;
+ }
+ else
+ if (tile != INVISIBLEWALL)
+ {
+ tileneeded[tile] = true;
+ tilemap[x][y] = tile;
+ if (ANIM_FLAGS(tile))
+ {
+ search_tile = tile+(char signed)ANIM_FLAGS(tile);
+
+ if (!tileneeded[search_tile])
+ while (search_tile != tile)
+ {
+ tileneeded[search_tile] = true;
+ if (ANIM_FLAGS(search_tile))
+ search_tile += (char signed)ANIM_FLAGS(search_tile);
+ else
+ TrashProg("Unending Tile Animation!");
+ }
+ }
+
+ }
if (tile>0)
(unsigned)actorat[x][y] = tile;
}
@@ -695,14 +886,34 @@ void SetupGameLevel ()
// Mark any gfx chunks needed
//
-// CA_MarkGrChunk(NORTHICONSPR);
-// CA_CacheMarks(NULL);
+// CA_MarkGrChunk(NORTHICONSPR);
+// CA_CacheMarks(NULL);
+
//
// decide which graphics are needed and spawn actors
//
- zombie_base_delay = 0; // (1*60) + random(1*60);
+ zombie_base_delay = 0; // (1*60) + random(1*60);
ScanInfoPlane ();
+ _fmemset(wall_anim_pos,0,sizeof(wall_anim_pos));
+
+
+//
+// mark which exploding walls are needed ---- the check for floor color
+// is preformed in ScanInfoPlane.
+//
+
+ if (exploding_walls_present)
+ {
+ extern unsigned gnd_colors[];
+
+ if (gcolor == 0x0101)
+ tileneeded[WATEREXP] = tileneeded[WATEREXP+1] = tileneeded[WATEREXP+2] = true;
+ else
+ tileneeded[WALLEXP] = tileneeded[WALLEXP+1] = tileneeded[WALLEXP+2] = true;
+
+ }
+
//
// have the caching manager load and purge stuff to make sure all marks
@@ -711,7 +922,6 @@ void SetupGameLevel ()
CA_LoadAllSounds ();
}
-
//==========================================================================
/*
@@ -724,7 +934,8 @@ void SetupGameLevel ()
void LatchDrawPic (unsigned x, unsigned y, unsigned picnum)
{
- unsigned wide, height, source, dest;
+ unsigned height, source, dest;
+ unsigned wide;
wide = pictable[picnum-STARTPICS].width;
height = pictable[picnum-STARTPICS].height;
@@ -760,6 +971,60 @@ asm mov ds,ax // restore turbo's data
EGAWRITEMODE(0);
}
+#if USE_STRIPS
+
+//--------------------------------------------------------------------------
+// LatchDrawPicStrip() - srcoff is distance into source file (in PIXELS!)
+//--------------------------------------------------------------------------
+void LatchDrawPicStrip (unsigned x, unsigned y, unsigned picnum, unsigned srcoff)
+{
+ unsigned wide, height, source, dest, shift, srcmod;
+
+ shift = (srcoff & 7) >> 1;
+ srcoff >>= 3;
+ wide = pictable[picnum-STARTPICS].width;
+ srcmod = wide - linewidth + (shift != 3);
+ if (wide > linewidth)
+ wide = linewidth;
+ height = pictable[picnum-STARTPICS].height;
+ dest = bufferofs + ylookup[y]+x;
+
+ picnum = ((picnum - (FIRSTSTRIPPIC+1)) >> 2) + (shift);
+ source = latchpics[(FIRSTSTRIPPIC-FIRSTLATCHPIC+1)+picnum];
+
+ EGAWRITEMODE(1);
+ EGAMAPMASK(15);
+
+asm mov bx,[linewidth]
+asm sub bx,[wide]
+
+asm mov ax,[screenseg]
+asm mov es,ax
+asm mov ds,ax
+
+asm mov si,[source]
+asm add si,[srcoff]
+asm mov di,[dest]
+asm mov dx,[height] // scan lines to draw
+asm mov ax,[wide]
+
+lineloop:
+asm mov cx,ax
+asm rep movsb
+asm add di,bx
+asm add si,[srcmod]
+
+asm dec dx
+asm jnz lineloop
+
+asm mov ax,ss
+asm mov ds,ax // restore turbo's data segment
+
+ EGAWRITEMODE(0);
+}
+
+#endif
+
//==========================================================================
@@ -790,40 +1055,20 @@ void Victory (boolean playsounds)
SD_PlaySound (GETPOINTSSND);
}
-
FreeUpMemory();
if (!screenfaded)
VW_FadeOut();
- screenpage = 1;
- VW_SetScreen (screenloc[screenpage],0);
- bufferofs = displayofs = screenloc[screenpage];
- VW_Bar (0,0,320,120,0);
+ NormalScreen ();
+
+ screenpage = bufferofs = 0;
CA_CacheGrChunk (FINALEPIC);
UNMARKGRCHUNK(FINALEPIC);
VW_DrawPic(0, 0, FINALEPIC);
VW_FadeIn();
-
-#if 0
- FreeUpMemory();
-
- if (!screenfaded)
- VW_FadeOut();
- screenpage = 1;
- VW_SetScreen (screenloc[screenpage],0);
- if (!FindFile("FINALE."EXT,NULL,1))
- Quit("Error: Can't find victory screen.");
- if (LoadShape("FINALE."EXT,&shape))
- TrashProg("Can't load FINALE."EXT);
- bufferofs = displayofs = screenloc[screenpage];
- VW_Bar (0,0,320,120,0);
- UnpackEGAShapeToScreen(&shape,(320-shape.bmHdr.w)/2,0);
- FreeShape(&shape);
- VW_FadeIn();
-#endif
}
//==========================================================================
@@ -847,11 +1092,11 @@ void Died (void)
SD_PlaySound (GAMEOVERSND);
bufferofs = screenloc[(screenpage+1)%3];
DisplayMsg("Though fallen, your Spirit ...",NULL);
-// LatchDrawPic(0,0,DEADPIC);
-// FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,false);
+// LatchDrawPic(0,0,DEADPIC);
+// FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,false);
IN_ClearKeysDown();
while (!Keyboard[sc_Enter]);
-// IN_Ack();
+// IN_Ack();
VW_SetScreen (bufferofs,0);
VW_ColorBorder(0);
}
@@ -929,9 +1174,13 @@ void DrawPlayScreen (void)
===================
*/
+unsigned latchmemavail;
+
void LoadLatchMem (void)
{
- int i,j,p,m;
+ static unsigned base_destoff=0;
+ static int base_numpics=0;
+ int i,j,p,m,numpics;
byte far *src, far *dest;
unsigned destoff;
@@ -941,6 +1190,9 @@ void LoadLatchMem (void)
// draw some pics into latch memory
//
+ if (!base_numpics)
+ {
+
//
// tile 8s
//
@@ -997,10 +1249,45 @@ void LoadLatchMem (void)
//
// pics
//
+ numpics=1;
destoff = FP_OFF(dest);
- for (i=FIRSTLATCHPIC+1;i<FIRSTSCALEPIC;i++)
+ for (i=FIRSTLATCHPIC+1;i<FIRSTGROUNDPIC;i++)
+ {
+ latchpics[numpics++] = destoff;
+ CA_CacheGrChunk (i);
+ j = pictable[i-STARTPICS].width * pictable[i-STARTPICS].height;
+ VW_MemToScreen (grsegs[i],destoff,j,1);
+ destoff+=j;
+ MM_FreePtr (&grsegs[i]);
+ UNMARKGRCHUNK(i);
+ }
+
+ base_numpics = numpics;
+ base_destoff = destoff;
+
+ }
+
+ numpics = base_numpics;
+ destoff = base_destoff;
+
+#if USE_STRIPS
+//
+// ground pics
+//
+ numpics++;
+ for (i=FIRSTGROUNDPIC+1;i<FIRSTSTRIPPIC;i++)
{
- latchpics[i-FIRSTLATCHPIC] = destoff;
+ int shape = (*groundcolor & 0xf0) - 16;
+
+ // Is current shape needed?
+ //
+ if (shape != (i-(FIRSTGROUNDPIC+1)))
+ {
+ numpics++;
+ continue;
+ }
+
+ latchpics[numpics++] = destoff;
CA_CacheGrChunk (i);
j = pictable[i-STARTPICS].width * pictable[i-STARTPICS].height;
VW_MemToScreen (grsegs[i],destoff,j,1);
@@ -1009,6 +1296,81 @@ void LoadLatchMem (void)
UNMARKGRCHUNK(i);
}
+
+//
+// 'parallax' strips - used in place of a sky color
+//
+// Under current setup, each strip takes about 7k in latch memory.
+// To create 2 pixel scrolling, 4 strips are needed, that's 28k of
+// latch memory needed to produce this effect.
+//
+ numpics++;
+ for (i=FIRSTSTRIPPIC+1;i<FIRSTSCALEPIC;i++)
+ {
+ memptr work;
+ unsigned workdest,stripsize,planesize;
+ short loop,pic=i-STARTPICS;
+ int shape = (*skycolor & 0xf0) - 16;
+
+ // Is current shape needed?
+ //
+ if (shape != (i-(FIRSTSTRIPPIC+1)))
+ {
+ numpics++;
+ continue;
+ }
+
+ // CAL_ShiftSprite() works with the SRC and DST in the same
+ // segment. So we must allocate memory for two strips, and
+ // move the base strip into that segment. Then we can use the
+ // 2nd half of that memory for each shifted strip.
+ //
+ CA_CacheGrChunk (i);
+ planesize = (pictable[pic].width+1) * pictable[pic].height;
+ stripsize = planesize * 4;
+// MM_GetPtr(&work,(stripsize*2)+0000);
+ MM_GetPtr(&work,65536);
+ movedata((unsigned)grsegs[i],0,(unsigned)work,0,stripsize);
+ workdest = 32768; //(stripsize+15) & 0xFFF0;
+
+ // Free base strip
+ //
+ MM_FreePtr (&grsegs[i]);
+ UNMARKGRCHUNK(i);
+
+ // Create three shifted strips and move 'em to latch!
+ //
+ for (loop=3; loop; loop--)
+ {
+ // Produce current shift for this strip
+ //
+ latchpics[numpics++] = destoff;
+ CAL_ShiftSprite ((unsigned)work,0,workdest,pictable[pic].width,
+ pictable[pic].height,loop*2,false);
+
+ // Copy this shift to latch memory
+ //
+ VW_MemToScreen ((memptr)((unsigned)work+(workdest>>4)),destoff,planesize,1);
+ destoff+=planesize;
+ }
+
+ // Copy unshifted strip to latch
+ //
+ latchpics[numpics++] = destoff;
+ planesize = pictable[pic].width * pictable[pic].height;
+ VW_MemToScreen (work,destoff,planesize,1);
+ destoff+=planesize;
+
+ // Free work buffer
+ //
+ MM_FreePtr(&work);
+ }
+#endif
+
+// Keep track of how much latch memory we have...
+//
+ latchmemavail = 65535-destoff;
+
EGAMAPMASK(15);
}
@@ -1231,7 +1593,6 @@ restart:
wait = false;
}
-
#ifdef PROFILE
start = clock();
while (start == clock());
@@ -1256,8 +1617,16 @@ itoa(end-start,str,10);
NewGame();
case ex_loadedgame:
case ex_warped:
+ FreeUpMemory();
+ if (playstate != ex_resetgame)
+ DisplayMsg(" ", NULL);
+ DisplaySMsg(" ", NULL);
goto restart;
- break;
+ case ex_victorious:
+ screenpage = 0;
+ bufferofs = 0;
+ status_flag = 0;
+ return;
}
} while (1);
@@ -1285,4 +1654,4 @@ itoa(end-start,str,10);
SetupScaleWall (walldark1[i]);
SetupScaleWall (walldark2[i]);
}
-#endif \ No newline at end of file
+#endif
diff --git a/C5_MAIN.C b/C5_MAIN.C
index 715244d..c7e0f82 100644
--- a/C5_MAIN.C
+++ b/C5_MAIN.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -17,6 +17,7 @@
*/
// C3_MAIN.C
+
#define CATALOG
@@ -31,13 +32,6 @@
/*
=============================================================================
-
-=============================================================================
-*/
-
-/*
-=============================================================================
-
LOCAL CONSTANTS
=============================================================================
@@ -52,7 +46,7 @@
=============================================================================
*/
-textinfo MainHelpText;
+PresenterInfo MainHelpText;
GameDiff restartgame;
boolean loadedgame,abortgame,ingame;
@@ -66,11 +60,15 @@ gametype gamestate;
exittype playstate;
char SlowMode = 0;
int starting_level;
-boolean EASYMODEON;
+
+//extern unsigned scolor,gcolor; //NPM
short NumGames=0;
unsigned Flags=0;
+boolean LoadShapes = true;
+boolean EASYMODEON = false;
+
void DisplayIntroText(void);
/*
@@ -142,11 +140,10 @@ void NewGame (void)
gamestate.body = MAXBODY;
}
- BGFLAGS = 0;
+ BGFLAGS = BGF_NOT_LIGHTNING;
Flags &= FL_CLEAR;
boltsleft = bolttimer = 0;
- FreezeTime = 0;
// memset (gamestate.levels,-1,sizeof(gamestate.levels));
}
@@ -169,6 +166,12 @@ boolean SaveTheGame(int file)
objtype *o;
memptr bigbuffer;
+ // save the sky and ground colors
+ if (!CA_FarWrite(file,(void far *)&skycolor,sizeof(skycolor)))
+ return(false);
+ if (!CA_FarWrite(file,(void far *)&groundcolor,sizeof(groundcolor)))
+ return(false);
+
if (!CA_FarWrite(file,(void far *)&FreezeTime,sizeof(FreezeTime)))
return(false);
@@ -212,6 +215,7 @@ boolean SaveTheGame(int file)
//===========================================================================
+
/*
==================
=
@@ -232,6 +236,12 @@ boolean LoadTheGame(int file)
FreeUpMemory();
playstate = ex_loadedgame;
+ // load the sky and ground colors
+ if (!CA_FarRead(file,(void far *)&skycolor,sizeof(skycolor)))
+ return(false);
+ if (!CA_FarRead(file,(void far *)&groundcolor,sizeof(groundcolor)))
+ return(false);
+
if (!CA_FarRead(file,(void far *)&FreezeTime,sizeof(FreezeTime)))
return(false);
@@ -281,7 +291,8 @@ boolean LoadTheGame(int file)
tile = *map++;
if (tile<NUMFLOORS)
{
- tilemap[x][y] = tile;
+ if (tile != INVISIBLEWALL)
+ tilemap[x][y] = tile;
if (tile>0)
(unsigned)actorat[x][y] = tile;
}
@@ -489,14 +500,15 @@ void Quit (char *error, ...)
va_start(ap,error);
+#ifndef CATALOG
if (!error)
{
CA_SetAllPurge ();
-#ifndef CATALOG
CA_CacheGrChunk (PIRACY);
finscreen = (unsigned)grsegs[PIRACY];
-#endif
}
+#endif
+
ShutdownId ();
if (error && *error)
@@ -504,18 +516,11 @@ void Quit (char *error, ...)
vprintf(error,ap);
exit_code = 1;
}
-
#ifndef CATALOG
else
+ if (!NoWait)
{
movedata (finscreen,0,0xb800,0,4000);
-
- if (kbhit())
- {
- while (kbhit())
- bioskey(0);
- }
-
bioskey (0);
}
#endif
@@ -560,6 +565,31 @@ void TEDDeath(void)
//===========================================================================
/*
+====================
+=
+= DisplayDepartment
+=
+====================
+*/
+void DisplayDepartment(char *text)
+{
+ short temp;
+
+// bufferofs = 0;
+ PrintY = 1;
+ WindowX = 0;
+ WindowW = 320;
+
+ VW_Bar(WindowX,PrintY+1,WindowW,7,7);
+ temp = fontcolor;
+ fontcolor = 2;
+ US_CPrintLine (text);
+ fontcolor = temp;
+}
+
+
+
+/*
=====================
=
= DemoLoop
@@ -569,13 +599,20 @@ void TEDDeath(void)
void DemoLoop (void)
{
+
/////////////////////////////////////////////////////////////////////////////
// main game cycle
/////////////////////////////////////////////////////////////////////////////
-// displayofs = bufferofs = 0;
-// VW_Bar (0,0,320,200,0);
-// VW_SetScreen(0,0);
+ displayofs = bufferofs = 0;
+ VW_Bar (0,0,320,200,0);
+ VW_SetScreen(0,0);
+
+//
+// Read in all the graphic images needed for the title sequence
+//
+ VW_WaitVBL(1);
+ IN_ReadControl(0,&control);
// set EASYMODE
//
@@ -610,31 +647,57 @@ void DemoLoop (void)
GameLoop();
}
+
//-------------------------------------------------------------------------
// DisplayIntroText()
//-------------------------------------------------------------------------
void DisplayIntroText()
{
+ PresenterInfo pi;
+
+#ifdef TEXT_PRESENTER
char *toptext = "You stand before the gate leading into the Towne "
- "Cemetery. Night is falling as mournful wails mingle "
- "with the sound of your pounding heart.";
+ "of Morbidity.... "
+ "^XX";
- char *bottomtext = "Equipped with your wits and the Secret Knowledge of "
- "Magick, you venture forth on your quest to upset "
- "the dark schemes of Nemesis, your arch rival.";
+ char *bottomtext = "Enter now boldly to defeat the evil Nemesis "
+ "deep inside the catacombs."
+ "
+ "^XX";
+#endif
char oldfontcolor=fontcolor;
fontcolor = 14;
- WindowX=WindowY=0;
- PPT_RightEdge=319;
- PPT_LeftEdge=0;
+
+#ifdef TEXT_PRESENTER
+ pi.xl = 0;
+ pi.yl = 0;
+ pi.xh = 319;
+ pi.yh = 1;
+ pi.bgcolor = 0;
+ pi.script[0] = (char far *)toptext;
+ Presenter(&pi);
+
+ pi.yl = 160;
+ pi.yh = 161;
+ pi.script[0] = (char far *)bottomtext;
+ Presenter(&pi);
+
+#else
PrintY = 1;
- PrintPropText(toptext);
+ PrintX = 0;
+ WindowX = 0;
+ WindowW = 320;
+ US_Print (" You stand before the gate leading into\n");
+ US_Print (" the Towne of Morbidity...\n");
- PrintY = 160;
- PrintPropText(bottomtext);
+ PrintY = 180;
+ US_Print (" Enter now boldly to defeat the evil Nemesis\n");
+ US_Print (" deep inside the catacombs.\n");
+
+#endif
fontcolor = oldfontcolor;
}
@@ -820,8 +883,7 @@ void CheckMemory(void)
==========================
*/
-char *MainParmStrings[] = {"q","l","ver","nomemcheck",nil};
-boolean LaunchedFromShell = false;
+char *MainParmStrings[] = {"q","l","ver","nomemcheck","helptest",nil};
void main (void)
{
@@ -844,31 +906,45 @@ void main (void)
break;
case 2:
- printf("%s %s rev %s\n",GAMENAME,VERSION,REVISION);
+ printf("%s\n", GAMENAME);
+ printf("Copyright 1992-93 Softdisk Publishing\n");
+ printf("%s %s\n",VERSION,REVISION);
+ printf("\n");
exit(0);
break;
case 3:
Flags |= FL_NOMEMCHECK;
break;
+
+ case 4:
+ Flags |= (FL_HELPTEST|FL_QUICK);
+ break;
}
}
- if (!stricmp(_argv[1], "^(a@&r`"))
- LaunchedFromShell = true;
+ if (stricmp(_argv[1], "^(a@&r`"))
+ Quit("You must type CATARM to run CATACOMB ARMAGEDDON 3-D\n");
- if (!LaunchedFromShell)
- {
- clrscr();
- puts("You must type CATABYSS at the DOS prompt to run CATACOMB ABYSS 3-D.");
- exit(0);
- }
+ MainHelpText.xl = 0;
+ MainHelpText.yl = 0;
+ MainHelpText.xh = 639;
+ MainHelpText.yh = 199;
+ MainHelpText.bgcolor = 7;
+ MainHelpText.ltcolor = 15;
+ MainHelpText.dkcolor = 8;
+
+// jabhack();
randomize();
InitGame ();
+// CheckMemory ();
LoadLatchMem ();
+// if (!LoadTextFile("MAINHELP."EXT,&MainHelpText))
+// Quit("Can't load MAINHELP."EXT);
+
#ifdef PROFILE
NewGame ();
GameLoop ();
@@ -877,3 +953,100 @@ void main (void)
DemoLoop();
Quit(NULL);
}
+
+//-------------------------------------------------------------------------
+// Display640()
+//-------------------------------------------------------------------------
+void Display640()
+{
+// Can you believe it takes all this just to change to 640 mode!!???!
+//
+ VW_ScreenToScreen(0,FREESTART-STATUSLEN,40,80);
+ VW_SetLineWidth(80);
+ MoveScreen(0,0);
+ VW_Bar (0,0,640,200,0);
+ VW_SetScreenMode(EGA640GR);
+ VW_SetLineWidth(80);
+ BlackPalette();
+}
+
+//-------------------------------------------------------------------------
+// Display320()
+//-------------------------------------------------------------------------
+void Display320()
+{
+// Can you believe it takes all this just to change to 320 mode!!???!
+//
+ VW_ColorBorder(0);
+ VW_FadeOut();
+ VW_SetLineWidth(40);
+ MoveScreen(0,0);
+ VW_Bar (0,0,320,200,0);
+ VW_SetScreenMode(EGA320GR);
+ BlackPalette();
+ VW_ScreenToScreen(FREESTART-STATUSLEN,0,40,80);
+}
+
+void PrintHelp(void)
+{
+ char oldfontcolor = fontcolor;
+ PrintY = 1;
+ WindowX = 135;
+ WindowW = 640;
+
+ VW_FadeOut();
+ bufferofs = displayofs = screenloc[0];
+ VW_Bar(0,0,320,200,0);
+
+ Display640();
+
+ VW_Bar(0, 0, 640, 200, 7);
+
+ fontcolor = (7 ^ 1);
+ US_Print ("\n\n SUMMARY OF GAME CONTROLS\n\n");
+
+ fontcolor = (7 ^ 4);
+ US_Print (" ACTION\n\n");
+
+ US_Print ("Arrow keys, joystick, or mouse\n");
+ US_Print ("TAB or V while turning\n");
+ US_Print ("ALT or Button 2 while turning\n");
+ US_Print ("CTRL or Button 1\n");
+ US_Print ("Z\n");
+ US_Print ("X or Enter\n");
+ US_Print ("F1\n");
+ US_Print ("F2\n");
+ US_Print ("F3\n");
+ US_Print ("F4\n");
+ US_Print ("F5\n");
+ US_Print ("ESC\n\n");
+#ifndef CATALOG
+ fontcolor = (7 ^ 0);
+ US_Print (" (See complete Instructions for more info)\n");
+#endif
+
+ fontcolor = (7 ^ 8);
+ PrintX = 400;
+ PrintY = 37;
+ WindowX = 400;
+ US_Print (" REACTION\n\n");
+ US_Print ("Move and turn\n");
+ US_Print ("Turn quickly (Quick Turn)\n");
+ US_Print ("Move sideways\n");
+ US_Print ("Shoot a Missile\n");
+ US_Print ("Shoot a Zapper\n");
+ US_Print ("Shoot an Xterminator\n");
+ US_Print ("Help (this screen)\n");
+ US_Print ("Sound control\n");
+ US_Print ("Save game position\n");
+ US_Print ("Restore a saved game\n");
+ US_Print ("Joystick control\n");
+ US_Print ("System options\n\n\n");
+
+ VW_UpdateScreen();
+ VW_FadeIn();
+ VW_ColorBorder(8 | 56);
+ IN_Ack();
+ Display320();
+ fontcolor = oldfontcolor;
+} \ No newline at end of file
diff --git a/C5_PLAY.C b/C5_PLAY.C
index ba68993..96f7775 100644
--- a/C5_PLAY.C
+++ b/C5_PLAY.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -44,7 +44,10 @@
byte bcolor;
short skytimer=-1,skytimer_reset;
short groundtimer=-1,groundtimer_reset;
-unsigned *skycolor,*groundcolor;
+
+unsigned scolor,gcolor;
+unsigned *skycolor,*groundcolor,debug_sky,debug_gnd;
+
unsigned nocolorchange=0xFFFF;
byte BGFLAGS, // global that holds all current flags
bgflag; // used by BG changer, this flag is set when done
@@ -73,6 +76,10 @@ boolean running=false; //,slowturn;
int bordertime;
objtype objlist[MAXACTORS],*new,*obj,*player,*lastobj,*objfreelist;
+#if USE_INERT_LIST
+inertobjtype inertobjlist[MAXINERTOBJ],*inert;
+#endif
+
unsigned farmapylookup[MAPSIZE];
byte *nearmapylookup[MAPSIZE];
@@ -166,19 +173,6 @@ void CheckKeys (void)
if (screenfaded) // don't do anything with a faded screen
return;
- if (Keyboard[sc_M]&&Keyboard[sc_I]&&Keyboard[sc_K]&&Keyboard[sc_E])
- {
- CenterWindow (12,2);
- if (autofire)
- US_PrintCentered ("Auto-Bolt OFF");
- else
- US_PrintCentered ("Auto-Bolt ON");
- VW_UpdateScreen();
- IN_Ack();
- autofire ^= 1;
- return 1;
- }
-
#if 0
//
// pause key wierdness can't be checked as a scan code
@@ -294,8 +288,7 @@ deadloop:;
char ch;
DisplaySMsg("Options", NULL);
- if ((status_flag != S_TIMESTOP) || (Flags & FL_DEAD))
- status_flag = S_NONE;
+ status_flag = S_NONE;
if (Flags & FL_DEAD)
@@ -326,12 +319,10 @@ deadloop:;
VW_WaitVBL(60);
playstate = ex_resetgame;
Flags &= ~FL_DEAD;
- status_flag = S_NONE;
break;
case sc_Q:
DisplaySMsg("FARE THEE WELL!", NULL);
- status_flag = S_NONE;
VW_WaitVBL(120);
if (!Flags & FL_QUICK)
VW_FadeOut();
@@ -341,36 +332,22 @@ deadloop:;
break;
}
tics = realtics = 1;
-
- if (status_flag == S_TIMESTOP)
- DisplaySMsg("Time Stopped: ",NULL);
}
// F1 - DISPLAY HELP
//
if (Keyboard[sc_F1])
{
- boolean nohelp=false;
- extern textinfo MainHelpText;
+ PrintHelp();
- VW_FadeOut();
-
- FreeUpMemory();
- if (!FindFile("HELP.TXT",NULL,1))
- nohelp = true;
+#ifdef TEXT_PRESENTER
- if (LoadTextFile("HELP.TXT",&MainHelpText))
- {
- VW_SetSplitScreen(200);
- bufferofs = displayofs = screenloc[0];
- VW_Bar(0,0,320,200,0);
+ extern PresenterInfo MainHelpText;
- DisplayText(&MainHelpText);
- }
- else
- nohelp = true;
+ VW_FadeOut();
- if (nohelp)
+ FreeUpMemory();
+ if (!LoadPresenterScript("HELP.TXT",&MainHelpText))
{
VW_FadeIn();
CenterWindow(30,5);
@@ -378,9 +355,19 @@ deadloop:;
US_CPrint("Press any key.");
IN_Ack();
VW_FadeOut();
- nohelp = false;
}
- FreeTextFile(&MainHelpText);
+ else
+ {
+ VW_SetSplitScreen(200);
+ bufferofs = displayofs = screenloc[0];
+ VW_Bar(0,0,320,200,0);
+
+ Display640();
+ Presenter(&MainHelpText);
+ Display320();
+ }
+ FreePresenterScript(&MainHelpText);
+#endif
VW_SetSplitScreen(120);
VW_SetScreen(screenloc[0],0);
screenpage = 0;
@@ -416,6 +403,7 @@ deadloop:;
loadedgame = true;
playstate = ex_loadedgame;
Flags &= ~FL_DEAD;
+ lasttext = -1;
PostFullDisplay(false);
}
else
@@ -423,6 +411,8 @@ deadloop:;
{
PostFullDisplay(false);
Victory(false);
+ IN_Ack();
+// gamestate.mapon++;
}
else
PostFullDisplay(true);
@@ -437,7 +427,7 @@ deadloop:;
//
// F10-? debug keys
//
- if (Keyboard[sc_F10])
+ if (Keyboard[sc_BackSpace])
{
DebugKeys();
if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
@@ -529,6 +519,11 @@ void InitObjList (void)
//
GetNewObj (false);
player = new;
+
+#if USE_INERT_LIST
+ inert = inertobjlist;
+#endif
+
}
//===========================================================================
@@ -611,8 +606,46 @@ void RemoveObj (objtype *gone)
//
gone->prev = objfreelist;
objfreelist = gone;
+
+ objectcount--;
}
+#if USE_INERT_LIST
+
+//--------------------------------------------------------------------------
+// MoveObjToInert()
+//--------------------------------------------------------------------------
+void MoveObjToInert(objtype *obj)
+{
+
+ if (inert == &inertobjlist[MAXINERTOBJ])
+ return;
+
+// Transfer info needed by inert objtype
+//
+ inert->x = obj->x;
+ inert->y = obj->y;
+ inert->size = obj->size;
+ inert->viewx = obj->viewx;
+ inert->tilex = obj->tilex;
+ inert->tiley = obj->tiley;
+ inert->state = obj->state;
+ inert->ticcount = obj->ticcount;
+
+// Setup links between inert objects
+//
+ if (inert != inertobjlist)
+ (inert-1)->next = inert;
+ inert->next = NULL;
+ inert++;
+
+// Free 'real' object from list.
+//
+ RemoveObj(obj);
+}
+
+#endif
+
//==========================================================================
/*
@@ -733,7 +766,6 @@ void PlayLoop (void)
// int originx=0;
// int i=100;
signed long dx,dy,radius,psin,pcos,newx,newy;
- short jim;
int give;
short objnum;
signed long ox,oy,xl,xh,yl,yh,px,py,norm_dx,norm_dy;
@@ -746,11 +778,14 @@ void PlayLoop (void)
gamestate.shotpower = handheight = 0;
pointcount = pointsleft = 0;
+ status_flag = S_NONE;
+
+#if 0
// setup sky/ground colors and effects (based on level)
//
switch (gamestate.mapon)
{
- case 0:
+ case 255:
if (!(BGFLAGS & BGF_NIGHT))
{
InitBgChange(3*60,sky_daytonight,-1,NULL,BGF_NIGHT);
@@ -769,7 +804,13 @@ void PlayLoop (void)
skytimer = groundtimer = -1;
break;
}
+#endif
+ BGFLAGS |= BGF_NOT_LIGHTNING;
+ skytimer = groundtimer = -1;
+
+ debug_gnd = *groundcolor;
+ debug_sky = *skycolor;
RedrawStatusWindow();
ThreeDRefresh();
if (screenfaded)
@@ -791,18 +832,16 @@ void PlayLoop (void)
if (++TimeCount == 300)
return;
#endif
+ DisplayStatus(&status_flag);
objnum=0;
for (obj = player;obj;obj = obj->next)
{
if ((obj->active >= yes) && (!(FreezeTime && (obj!=player))))
{
-
-
if (obj->ticcount)
{
- obj->ticcount-=tics;
-
+ obj->ticcount-=realtics;
while ( obj->ticcount <= 0)
{
think = obj->state->think;
@@ -816,7 +855,6 @@ void PlayLoop (void)
RemoveObj (obj);
goto nextactor;
}
-
if (obj->state != oldstate)
break;
}
@@ -827,21 +865,17 @@ void PlayLoop (void)
RemoveObj (obj);
goto nextactor;
}
-
if (!obj->state->tictime)
{
obj->ticcount = 0;
goto nextactor;
}
-
if (obj->state->tictime>0)
obj->ticcount += obj->state->tictime;
}
}
-
think = obj->state->think;
-
if (think)
{
think (obj);
@@ -907,16 +941,23 @@ nextactor:;
RadarXY[objnum++][2]=shot_color[screenpage];
break;
- // BATS (DK GRAY)
+ // BATS (DK GRAY)
//
case batobj:
if (obj->active == always)
RadarXY[objnum++][2]=8;
break;
+ // RABBITS (LT GRAY)
+ //
+ case bunnyobj:
+ if (obj->active == always)
+ RadarXY[objnum++][2]=7;
+ break;
+
// RED GEM
//
- // EYE, RED DEMON (DK RED)
+ // EYE, RED DEMON (DK RED)
//
case eyeobj:
case reddemonobj:
@@ -935,35 +976,37 @@ nextactor:;
// BLUE GEM
//
- // WATER TROLL (LT BLUE)
+ // SUCCUBUS (LT BLUE)
//
- case wetobj:
+ case succubusobj:
if (gamestate.gems[B_BGEM-B_RGEM])
if (obj->active == always)
RadarXY[objnum++][2]=9;
break;
- // WATER TROLL (DK BLUE)
+ // WATER DRAGON (DK BLUE)
//
- case demonobj:
- if (gamestate.gems[B_BGEM-B_RGEM])
+ case wetobj:
+ if (gamestate.gems[B_GGEM-B_RGEM])
if (obj->active == always)
RadarXY[objnum++][2]=1;
break;
+
+
// GREEN GEM
//
- // GREEN TROLL (LT GREEN)
+ // GREEN TROLL (LT GREEN)
//
- case trollobj:
+ case fatdemonobj:
if (gamestate.gems[B_GGEM-B_RGEM])
if (obj->active == always)
RadarXY[objnum++][2]=10;
break;
- // ORC (DK GREEN)
+ // GODESS (DK GREEN)
//
- case orcobj:
+ case godessobj:
if (gamestate.gems[B_GGEM-B_RGEM])
if (obj->active == always)
RadarXY[objnum++][2]=2;
@@ -971,9 +1014,10 @@ nextactor:;
// YELLOW GEM
//
- // SPOOK (BROWN)
+ // ANT (BROWN)
//
- case spookobj:
+ case antobj:
+ case treeobj:
if (gamestate.gems[B_YGEM-B_RGEM])
if (obj->active == always)
RadarXY[objnum++][2]=6;
@@ -1012,6 +1056,30 @@ nextactor:;
}
RadarXY[objnum][2]=-1; // Signals end of RadarXY list...
+#if USE_INERT_LIST
+ if (inert != inertobjlist)
+ for (obj=(objtype *)inertobjlist;obj;obj=obj->next)
+ if (obj->ticcount)
+ {
+ obj->ticcount-=realtics;
+ while ( obj->ticcount <= 0)
+ {
+ obj->state = obj->state->next;
+ if (!obj->state)
+ Quit("Removable object in INERT list.");
+
+ if (!obj->state->tictime)
+ {
+ obj->ticcount = 0;
+ goto nextactor;
+ }
+
+ if (obj->state->tictime>0)
+ obj->ticcount += obj->state->tictime;
+ }
+ }
+#endif
+
if (bordertime)
{
bordertime -= realtics;
@@ -1022,21 +1090,17 @@ nextactor:;
}
}
+#if 1
// random lightning?
//
- if (BGFLAGS & (BGF_NIGHT|BGF_NOT_LIGHTNING))
- switch (gamestate.mapon)
+ if (BGFLAGS & (BGF_NOT_LIGHTNING))
+ {
+ if ((scolor & 0xe0) && (!(random(20-realtics))))
{
- case 0:
- case 1:
- case 3:
- if (!random(120-realtics))
- {
- BGFLAGS &= ~BGF_NOT_LIGHTNING;
- InitBgChange(1,sky_lightning,-1,NULL,BGF_NOT_LIGHTNING);
- }
- break;
+ BGFLAGS &= ~BGF_NOT_LIGHTNING;
+ InitBgChange(1,sky_lightning,-1,NULL,BGF_NOT_LIGHTNING);
}
+ }
// handle sky/ground color changes
//
@@ -1049,7 +1113,8 @@ nextactor:;
if (*skycolor == 0xffff)
{
skytimer = -1;
- skycolor--;
+// skycolor--;
+ skycolor = &scolor;
if (groundtimer == -1)
BGFLAGS |= bgflag;
}
@@ -1067,7 +1132,8 @@ nextactor:;
if (*groundcolor == 0xffff)
{
groundtimer = -1;
- groundcolor--;
+// groundcolor--;
+ groundcolor = &gcolor;
if (skytimer == -1)
BGFLAGS |= bgflag;
}
@@ -1075,6 +1141,7 @@ nextactor:;
groundtimer = groundtimer_reset;
}
}
+#endif
//
@@ -1122,10 +1189,11 @@ nextactor:;
if (playstate == ex_victorious)
{
Victory(true);
- Flags |= FL_DEAD;
+// Flags |= FL_DEAD;
+ IN_Ack();
+// gamestate.mapon++;
}
- DisplayStatus(&status_flag);
CheckKeys();
}while (!playstate);
diff --git a/C5_SCALE.C b/C5_SCALE.C
index 41f06e6..fee4dbe 100644
--- a/C5_SCALE.C
+++ b/C5_SCALE.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -479,10 +479,8 @@ void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale)
scale = (scale+1)/2;
if (!scale)
return; // too far away
-
if (scale>MAX_OBJ_SCALE)
scale = MAX_OBJ_SCALE;
-
comptable = scaledirectory[scale];
width = compshape->width;
@@ -490,7 +488,6 @@ void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale)
pixel = xcenter - scalewidth/2;
lastpixel = pixel+scalewidth-1;
-
if (pixel >= VIEWWIDTH || lastpixel < 0)
return; // totally off screen
diff --git a/C5_SCA_A.ASM b/C5_SCA_A.ASM
index 5bb5296..44c8eb1 100644
--- a/C5_SCA_A.ASM
+++ b/C5_SCA_A.ASM
@@ -1,4 +1,4 @@
-; Catacomb Abyss Source Code
+; Catacomb Armageddon Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
diff --git a/C5_STATE.C b/C5_STATE.C
index 3bff92b..ac10ae8 100644
--- a/C5_STATE.C
+++ b/C5_STATE.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -64,7 +64,7 @@ dirtype opposite[9] =
=
===================
*/
-void Internal_SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size,boolean UseDummy)
+void Internal_SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size, boolean UseDummy, boolean PutInActorat)
{
extern objtype dummyobj;
@@ -81,7 +81,7 @@ void Internal_SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned si
new->dir = nodir;
new->active = noalways;
- if (new != &dummyobj)
+ if (new != &dummyobj && PutInActorat)
actorat[new->tilex][new->tiley] = new;
}
@@ -151,18 +151,15 @@ void T_DoDamage (objtype *ob)
switch (ob->obclass)
{
- case orcobj:
- points = 4;
- break;
case zombieobj:
- case trollobj:
+ case fatdemonobj:
points = 8;
break;
case reddemonobj:
- case demonobj:
+ case godessobj:
points = 15;
break;
- case spookobj:
+ case antobj:
points = 2;
break;
case skeletonobj:
@@ -172,10 +169,14 @@ void T_DoDamage (objtype *ob)
case wetobj:
points = 7;
break;
-
+ case treeobj:
+ points = 7;
+ break;
+ case bunnyobj:
+ points = 4;
+ break;
}
- TakeDamage (EasyDoDamage(points));
-
+ TakeDamage (points);
ob->flags |= of_damagedone;
}
}
@@ -500,6 +501,7 @@ boolean Chase (objtype *ob, boolean diagonal)
void ShootActor (objtype *ob, unsigned damage)
{
ob->hitpoints -= damage;
+
if (ob->hitpoints<=0)
{
switch (ob->obclass)
@@ -507,20 +509,23 @@ void ShootActor (objtype *ob, unsigned damage)
case reddemonobj:
ob->state = &s_red_demondie1;
break;
- case orcobj:
- ob->state = &s_orcdie1;
+ case succubusobj:
+ ob->state = &s_succubus_death1;
break;
- case trollobj:
- ob->state = &s_trolldie1;
+ case fatdemonobj:
+ ob->state = &s_fatdemon_blowup1;
break;
- case demonobj:
- ob->state = &s_demondie1;
+ case godessobj:
+ ob->state = &s_godessdie1;
break;
case mageobj:
ob->state = &s_magedie1;
break;
case batobj:
ob->state = &s_batdie1;
+#if USE_INERT_LIST
+ ob->obclass = solidobj; // don't add this obj to inert list
+#endif
break;
case grelmobj:
ob->state = &s_greldie1;
@@ -534,21 +539,40 @@ void ShootActor (objtype *ob, unsigned damage)
ob->state = &s_skel_die1;
break;
- case spookobj:
- ob->state = &s_spookdie;
+ case antobj:
+ ob->state = &s_ant_die1;
break;
case wetobj:
ob->state = &s_wet_die1;
+#if USE_INERT_LIST
+ ob->obclass = solidobj; // don't add this obj to inert list
+#endif
break;
case eyeobj:
ob->state = &s_eye_die1;
break;
+ case sshotobj:
case eshotobj:
case mshotobj:
ob->state = &s_bonus_die;
+#if USE_INERT_LIST
+ ob->obclass = solidobj; // don't add these objs to inert list
+#endif
+ break;
+
+ case treeobj:
+ ob->state = &s_tree_death1;
+ ob->obclass = solidobj;
+ ob->temp1 = 3;
+ ob->flags &= ~of_damagedone;
+ CalcBounds(ob);
+ break;
+
+ case bunnyobj:
+ ob->state = &s_bunny_death1;
break;
case bonusobj:
@@ -571,15 +595,29 @@ void ShootActor (objtype *ob, unsigned damage)
status_delay = 80;
break;
}
+#if USE_INERT_LIST
+ ob->obclass = solidobj; // don't add this obj to inert list
+#endif
break;
}
- if (ob->obclass != solidobj)
+ if (ob->obclass != solidobj && ob->obclass != realsolidobj)
{
ob->obclass = inertobj;
ob->flags &= ~of_shootable;
actorat[ob->tilex][ob->tiley] = NULL;
+#if USE_INERT_LIST
+ MoveObjToInert(ob);
+#endif
+ }
+ else
+ {
+ if (ob->flags & of_forcefield)
+ {
+ ob->state = &s_force_field_die;
+ ob->flags &= ~of_shootable;
+ }
}
}
else
@@ -587,16 +625,19 @@ void ShootActor (objtype *ob, unsigned damage)
switch (ob->obclass)
{
case reddemonobj:
- ob->state = &s_red_demonouch;
+ if (!(random(8)))
+ ob->state = &s_red_demonouch;
+ else
+ return;
break;
- case orcobj:
- ob->state = &s_orcouch;
+ case succubusobj:
+ ob->state = &s_succubus_ouch;
break;
- case trollobj:
- ob->state = &s_trollouch;
+ case fatdemonobj:
+ ob->state = &s_fatdemon_ouch;
break;
- case demonobj:
- ob->state = &s_demonouch;
+ case godessobj:
+ ob->state = &s_godessouch;
break;
case mageobj:
ob->state = &s_mageouch;
@@ -610,8 +651,8 @@ void ShootActor (objtype *ob, unsigned damage)
ob->state = &s_zombie_ouch;
break;
- case spookobj:
- ob->state = &s_spookouch;
+ case antobj:
+ ob->state = &s_ant_ouch;
break;
case skeletonobj:
@@ -626,8 +667,16 @@ void ShootActor (objtype *ob, unsigned damage)
ob->state = &s_eye_ouch;
break;
+ case treeobj:
+ ob->state = &s_tree_ouch;
+ break;
+
+ case bunnyobj:
+ ob->state = &s_bunny_ouch;
+ break;
}
}
ob->ticcount = ob->state->tictime;
}
+
diff --git a/C5_TRACE.C b/C5_TRACE.C
index e26c2ad..d9ed20e 100644
--- a/C5_TRACE.C
+++ b/C5_TRACE.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -393,9 +393,8 @@ int BackTrace (int finish)
// rotate the X value to see if it is behind the view plane
//
if (TransformX (((long)tile.x<<16)+point1x[wall],
- ((long)tile.y<<16)+point1y[wall]) < FOCALLENGTH)
-// ((long)tile.y<<16)+point1y[wall]) < ((long)FOCALLENGTH+30000l))
- {
+ ((long)tile.y<<16)+point1y[wall]) < FOCALLENGTH)
+ {
tile.x = otx;
tile.y = oty;
return 0;
diff --git a/C5_WIZ.C b/C5_WIZ.C
index 8ebb28a..b899ef6 100644
--- a/C5_WIZ.C
+++ b/C5_WIZ.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -19,6 +19,7 @@
// C3_WIZ.C
#include "DEF.H"
+#include "gelib.h"
#pragma hdrstop
/*
@@ -29,7 +30,7 @@
=============================================================================
*/
-#define NUMSCROLLS 8
+////////#define NUMSCROLLS 8
#define SHOWITEMS 9
@@ -47,6 +48,7 @@
#define SPECTILESTART 0 // 18
+
#define SHOTDAMAGE 1
#define BIGSHOTDAMAGE 3
@@ -65,6 +67,12 @@
#define HANDPAUSE 60
+#define RIGHTEDGE 205;
+#define LEFTEDGE 95;
+#define PRNY 32;
+#define WINX 10;
+#define WINY 32;
+
/*
=============================================================================
@@ -79,7 +87,7 @@ int handheight;
int boltsleft,bolttimer;
short RadarXY[MAX_RADAR_BLIPS][3]={-1,-1,-1};
short radarx=RADARX,radary=RADARY,radar_xcenter=RADAR_XCENTER,radar_ycenter=RADAR_YCENTER;
-int key_x[4]={20,23,23,20},key_y[4]={30,57,30,57};
+int key_x[4]={24,27,27,24},key_y[4]={30,57,30,57};
boolean redraw_gems,button0down;
@@ -100,7 +108,6 @@ short RotateAngle = -1; // -1 == No Angle to turn to...
short FreezeTime = 0; // Stops all think (except player)
short RotateSpeed; // Speed (and dir) to rotate..
-short turntime = 0; // accumulated time for fast turning..
//===========================================================================
@@ -119,9 +126,9 @@ void GivePotion (void);
void TakePotion (void);
void GiveKey (int keytype);
void TakeKey (int keytype);
-void GiveScroll (int scrolltype,boolean show);
-void ReadScroll (int scroll);
-void DrawScrolls(void);
+////////////void GiveScroll (int scrolltype,boolean show);
+////////////void ReadScroll (int scroll);
+////////////void DrawScrolls(void);
void DrawNum(short x,short y,short value,short maxdigits);
@@ -213,15 +220,15 @@ void RedrawStatusWindow (void)
EGABITMASK(0xff);
for (keytype=0; keytype<4; keytype++)
DrawNum(key_x[keytype],key_y[keytype],gamestate.keys[keytype],2);
- DrawNum(17,54,gamestate.potions,2);
- DrawNum(17,36,gamestate.nukes,2);
- DrawNum(17,18,gamestate.bolts,2);
+ DrawNum(20,54,gamestate.potions,2);
+ DrawNum(20,36,gamestate.nukes,2);
+ DrawNum(20,18,gamestate.bolts,2);
DrawHealth();
DrawRadar();
EGAWRITEMODE(0);
DrawGems();
- DrawScrolls();
+//////// DrawScrolls();
redraw_gems = false;
}
@@ -242,7 +249,7 @@ void GiveBolt (void)
return;
SD_PlaySound (GETBOLTSND);
- DrawNum(17,18,++gamestate.bolts,2);
+ DrawNum(20,18,++gamestate.bolts,2);
}
@@ -257,7 +264,7 @@ void GiveBolt (void)
void TakeBolt (void)
{
SD_PlaySound (USEBOLTSND);
- DrawNum(17,18,--gamestate.bolts,2);
+ DrawNum(20,18,--gamestate.bolts,2);
}
//===========================================================================
@@ -276,7 +283,7 @@ void GiveNuke (void)
return;
SD_PlaySound (GETNUKESND);
- DrawNum(17,36,++gamestate.nukes,2);
+ DrawNum(20,36,++gamestate.nukes,2);
}
@@ -291,7 +298,7 @@ void GiveNuke (void)
void TakeNuke (void)
{
SD_PlaySound (USENUKESND);
- DrawNum(17,36,--gamestate.nukes,2);
+ DrawNum(20,36,--gamestate.nukes,2);
}
//===========================================================================
@@ -310,7 +317,7 @@ void GivePotion (void)
return;
SD_PlaySound (GETPOTIONSND);
- DrawNum(17,54,++gamestate.potions,2);
+ DrawNum(20,54,++gamestate.potions,2);
}
@@ -325,7 +332,7 @@ void GivePotion (void)
void TakePotion (void)
{
SD_PlaySound (USEPOTIONSND);
- DrawNum(17,54,--gamestate.potions,2);
+ DrawNum(20,54,--gamestate.potions,2);
}
//===========================================================================
@@ -440,6 +447,8 @@ void DrawGems()
//===========================================================================
+#if 0
+
/*
===============
=
@@ -486,6 +495,8 @@ void DrawScrolls()
DrawChar(x,y,SCROLLCHARS+loop);
}
}
+#endif
+
//===========================================================================
@@ -550,7 +561,7 @@ void DrawHealth()
percentage = PERCENTAGE(100,MAXBODY,gamestate.body,9);
- DrawNum(9,57,percentage,3);
+ DrawNum(11,57,percentage,3);
if (percentage > 75)
picnum = FACE1PIC;
@@ -573,10 +584,11 @@ void DrawHealth()
if (!percentage)
{
UNMARKGRCHUNK(picnum);
- VW_DrawPic(8,14,picnum);
+// VW_DrawPic(8,14,picnum);
+ VW_DrawPic(10,14,picnum);
}
else
- LatchDrawPic(8,14,picnum);
+ LatchDrawPic(10,14,picnum);
}
//===========================================================================
@@ -1016,6 +1028,25 @@ newline3:
}
#endif
+/////////////////////////////////////////////////////////////////////////////
+//
+// Check the object and make sure it is a monster. Used in making the sound
+// of a monster being shot.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+boolean PlayMonsterSound(classtype objclass)
+{
+ switch (objclass)
+ {
+ case solidobj:
+ case realsolidobj:
+ return false;
+ default:
+ return true;
+ }
+}
+
/*
=============================================================================
@@ -1123,14 +1154,25 @@ boolean JimsShotClipMove (objtype *ob, long xmove, long ymove)
ob->x -= xmove;
ob->y -= ymove;
- if (check->obclass != solidobj)
+ if (check->obclass != solidobj && check->obclass != hbunnyobj)
{
- SD_PlaySound (SHOOTMONSTERSND);
+ if (PlayMonsterSound(check->obclass))
+ SD_PlaySound (SHOOTMONSTERSND);
if (ob->obclass == bigpshotobj)
ShootActor (check,BIGSHOTDAMAGE);
else
ShootActor (check,SHOTDAMAGE);
}
+ else
+ if (check->obclass == solidobj && (check->flags & of_forcefield))
+ {
+ if (PlayMonsterSound(check->obclass))
+ SD_PlaySound (SHOOTMONSTERSND);
+ if (ob->obclass == bigpshotobj)
+ ShootActor (check,BIGSHOTDAMAGE);
+ else
+ ShootActor (check,SHOTDAMAGE);
+ }
ob->state = &s_pshot_exp1;
ob->ticcount = ob->state->tictime;
return(true);
@@ -1167,7 +1209,8 @@ void T_Pshot (objtype *ob)
if (check->obclass != solidobj)
{
- SD_PlaySound (SHOOTMONSTERSND);
+ if (PlayMonsterSound(check->obclass))
+ SD_PlaySound (SHOOTMONSTERSND);
if (ob->obclass == bigpshotobj)
ShootActor (check,BIGSHOTDAMAGE);
else
@@ -1238,9 +1281,10 @@ void T_Pshot (objtype *ob)
&& ob->yh >= check->yl)
{
- if (check->obclass != solidobj)
+ if (check->obclass != solidobj && check->obclass != hbunnyobj)
{
- SD_PlaySound (SHOOTMONSTERSND);
+ if (PlayMonsterSound(check->obclass))
+ SD_PlaySound (SHOOTMONSTERSND);
if (ob->obclass == bigpshotobj)
ShootActor (check,BIGSHOTDAMAGE);
else
@@ -1477,6 +1521,8 @@ void ContinueBolt (void)
void CastNuke (void)
{
+ extern boolean autofire;
+
int angle;
if (!gamestate.nukes)
@@ -1485,7 +1531,8 @@ void CastNuke (void)
return;
}
- TakeNuke ();
+ if (!autofire)
+ TakeNuke ();
lastnuke = TimeCount;
for (angle = 0; angle < ANGLES; angle+= ANGLES/16)
@@ -1572,6 +1619,62 @@ newline:
//===========================================================================
+#if 0
+
+////////////////////////////////////////////////////////////////////////////
+//
+// GetScrollText
+//
+// parms - scroll -- the number of the scroll to display
+// returns - a far pointer to the scroll text
+//
+////////////////////////////////////////////////////////////////////////////
+
+char far *GetScrollText (int scroll)
+{
+ boolean found;
+ int i;
+ char far *txt;
+ unsigned ofset;
+
+ CA_CacheGrChunk(SCROLLTEXT);
+
+ found = false;
+ i = 0;
+
+ txt = (char _seg *)grsegs[SCROLLTEXT];
+
+ while (!found)
+ {
+ while (*txt != '\n')
+ {
+ if (*txt == '\r')
+ *txt = 0;
+ txt++;
+ }
+ txt++;
+ if (i == scroll)
+ {
+ found = true;
+ ofset = FP_OFF(txt);
+
+ while (*txt != '\n')
+ {
+ if (*txt == '\r')
+ *txt = 0;
+ txt++;
+ }
+ }
+ i++;
+ }
+ txt = (char _seg *)grsegs[SCROLLTEXT]+ofset;
+
+ UNMARKGRCHUNK(SCROLLTEXT);
+ return(txt);
+} //End of GetScrollText
+
+//===========================================================================
+
/*
===============
=
@@ -1584,8 +1687,10 @@ extern boolean tileneeded[NUMFLOORS];
void ReadScroll (int scroll)
{
+ PresenterInfo pi;
int i;
unsigned *skytemp,*gndtemp,blackcolor=0;
+ char far *scrolltext;
DisplaySMsg("Reading Scroll", NULL);
bufferofs = displayofs = screenloc[screenpage];
@@ -1596,7 +1701,7 @@ void ReadScroll (int scroll)
FreeUpMemory();
CA_CacheGrChunk (SCROLLTOPPIC);
- CA_CacheGrChunk (SCROLL1PIC + scroll);
+ CA_CacheGrChunk (SCROLL1PIC);
CA_CacheGrChunk (SCROLLBOTTOMPIC);
skytemp = skycolor;
@@ -1605,33 +1710,43 @@ void ReadScroll (int scroll)
VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,0);
VW_DrawPic (10,0,SCROLLTOPPIC);
- VW_DrawPic (10,32,SCROLL1PIC + scroll);
+ VW_DrawPic (10,32,SCROLL1PIC);
VW_DrawPic (10,88,SCROLLBOTTOMPIC);
+ scrolltext = GetScrollText(scroll);
+
+ pi.xl = LEFTEDGE;
+ pi.yl = PRNY;
+ pi.xh = RIGHTEDGE;
+ pi.yh = PRNY+1;
+ pi.bgcolor = 7;
+ pi.script[0] = (char far *)scrolltext;
+ Presenter(&pi);
+
skycolor = skytemp;
groundcolor = gndtemp;
- UNMARKGRCHUNK(SCROLL1PIC + scroll);
+ UNMARKGRCHUNK(SCROLL1PIC);
UNMARKGRCHUNK(SCROLLTOPPIC);
UNMARKGRCHUNK(SCROLLBOTTOMPIC);
- MM_FreePtr (&grsegs[SCROLL1PIC + scroll]);
+ MM_FreePtr (&grsegs[SCROLL1PIC]);
MM_FreePtr (&grsegs[SCROLLTOPPIC]);
MM_FreePtr (&grsegs[SCROLLBOTTOMPIC]);
CacheScaleds();
IN_ClearKeysDown ();
-// MDM begin
lasttext = -1;
DisplayMsg("Press ENTER or ESC to exit.",NULL);
while ((!Keyboard[sc_Escape]) && (!Keyboard[sc_Enter]));
-// MDM end
IN_ClearKeysDown ();
if (status_flag == S_TIMESTOP)
DisplaySMsg("Time Stopped: ",NULL);
}
+#endif
+
//===============
//
@@ -1663,6 +1778,9 @@ void TakeDamage (int points)
if (!gamestate.body || (bordertime && bcolor==FLASHCOLOR) || godmode)
return;
+ if (points != 1)
+ points = EasyDoDamage(points);
+
if (points >= gamestate.body)
{
points = gamestate.body;
@@ -1819,27 +1937,30 @@ boolean HitSpecialTile (unsigned x, unsigned y, unsigned tile)
short keyspot;
unsigned temp,spot,curmap=gamestate.mapon,newlevel;
char *key_colors[] = {"a RED key",
- "a YELLOW key",
- "a GREEN key",
- "a BLUE key"};
+ "a YELLOW key",
+ "a GREEN key",
+ "a BLUE key"};
switch (tile)
{
- case 28:
+ case 65:
playstate = ex_victorious;
break;
- case 36: // Water gate
- case 24: // Steel gate (BLUE KEY REQ.)
- case 25: // Steel gate (RED KEY REQ.)
- case 26: // Steel gate (YELLOW KEY REQ.)
- case 27: // HOT Steel gate (YELLOW KEY REQ.)
- case 18: // Wooden Doorway
- case 19: // Wooden doorway with a GLOW - Oh, THATS's what IT is!
- case 1: // tile warp
- case 54: // DOWN stairs
- case 56: // UP stairs
- case 51: // generic door
+ case 9:
+ case 15:
+ case 27:
+ case 30:
+ case 40:
+ case 42:
+ case 43:
+ case 45:
+ case 46:
+ case 47:
+ case 49:
+ case 76:
+ case 77:
+
if (!playstate && !FreezeTime)
{
@@ -1848,8 +1969,8 @@ boolean HitSpecialTile (unsigned x, unsigned y, unsigned tile)
spot = (*(mapsegs[2]+farmapylookup[y]+x)) >> 8;
if (spot == CANT_OPEN_CODE) // CAN'T EVER OPEN (it's just for looks)
{
- CenterWindow(20,4);
- US_CPrint("\nThe door is blocked");
+ CenterWindow(30,4);
+ US_CPrint("\nThis door is permanently blocked");
VW_UpdateScreen();
IN_ClearKeysDown();
IN_Ack();
@@ -1978,13 +2099,14 @@ boolean TouchActor (objtype *ob, objtype *check)
case B_POTION: GivePotion (); break;
- case B_RKEY2: GiveKey(B_RKEY-B_RKEY); break;
+// case B_RKEY2: GiveKey(B_RKEY-B_RKEY); break;
case B_RKEY:
case B_YKEY:
case B_GKEY:
case B_BKEY: GiveKey (check->temp1-B_RKEY); break;
+#if 0
case B_SCROLL1:
case B_SCROLL2:
case B_SCROLL3:
@@ -1993,6 +2115,7 @@ boolean TouchActor (objtype *ob, objtype *check)
case B_SCROLL6:
case B_SCROLL7:
case B_SCROLL8: GiveScroll (check->temp1-B_SCROLL1,true); break;
+#endif
case B_CHEST: GiveChest (); break;
@@ -2015,15 +2138,16 @@ boolean TouchActor (objtype *ob, objtype *check)
RemoveObj (check);
return false;
- break;
case freezeobj:
StopTime();
(unsigned)actorat[check->tilex][check->tiley] = 0;
RemoveObj(check);
return(false);
- break;
+ case cloudobj:
+ TakeDamage(2);
+ return false;
}
return true;
@@ -2076,6 +2200,9 @@ boolean LocationInActor (objtype *ob)
check = actorat[x][y];
if (check>(objtype *)LASTTILE
&& (check->flags & of_shootable)
+ && (check->obclass != bonusobj)
+ && (check->obclass != freezeobj)
+ && (check->obclass != solidobj)
&& ob->xl-SIZE_TEST <= check->xh
&& ob->xh+SIZE_TEST >= check->xl
&& ob->yl-SIZE_TEST <= check->yh
@@ -2102,6 +2229,7 @@ void ClipXMove (objtype *ob, long xmove)
unsigned inside,total,tile;
objtype *check;
boolean moveok;
+ boolean invisible_present = false;
//
// move player and check to see if any corners are in solid tiles
@@ -2135,6 +2263,13 @@ void ClipXMove (objtype *ob, long xmove)
goto blockmove;
}
+ if (TILE_FLAGS((unsigned)check) & tf_INVISIBLE_WALL)
+ {
+ invisible_present = true;
+ goto blockmove;
+ }
+
+
if (TILE_FLAGS((unsigned)check) & tf_SOLID)
{
goto blockmove; // solid wall
@@ -2195,11 +2330,20 @@ blockmove:
}
}
else
- {
- if (xmove>=-2048 && xmove <=2048)
- return;
- moveok = true;
- }
+ if (invisible_present)
+ {
+ moveok = false;
+ if (xmove>=-2048 && xmove <=2048)
+ {
+ ob->x = basex;
+ ob->y = basey;
+ return;
+ }
+ }
+ else
+ if (xmove>=-2048 && xmove <=2048)
+ return;
+ moveok = true;
} while (1);
}
@@ -2220,6 +2364,7 @@ void ClipYMove (objtype *ob, long ymove)
unsigned inside,total,tile;
objtype *check;
boolean moveok;
+ boolean invisible_present = false;
//
// move player and check to see if any corners are in solid tiles
@@ -2252,6 +2397,13 @@ void ClipYMove (objtype *ob, long ymove)
goto blockmove;
}
+ if (TILE_FLAGS((unsigned)check) & tf_INVISIBLE_WALL)
+ {
+ invisible_present = true;
+ goto blockmove;
+ }
+
+
if (TILE_FLAGS((unsigned)check) & tf_SOLID) // LASTWALLTILE)
{
goto blockmove; // solid wall
@@ -2309,11 +2461,20 @@ blockmove:
}
}
else
- {
- if (ymove>=-2048 && ymove <=2048)
- return;
- moveok = true;
- }
+ if (invisible_present)
+ {
+ moveok = false;
+ if (ymove>=-2048 && ymove <=2048)
+ {
+ ob->x = basex;
+ ob->y = basey;
+ return;
+ }
+ }
+ else
+ if (ymove>=-2048 && ymove <=2048)
+ return;
+ moveok = true;
} while (1);
}
@@ -2574,22 +2735,19 @@ void ControlMovement (objtype *ob)
//
//
- // TURNING
+ // turning
//
if (control.xaxis == 1)
{
ob->angle -= tics;
-
- if (running)
- ob->angle -= (tics<<1); // FAST turn
-
+ if (running) // fast turn
+ ob->angle -= (tics<<1);
}
else if (control.xaxis == -1)
{
ob->angle+= tics;
-
- if (running)
- ob->angle += (tics<<1); // FAST turn
+ if (running) // fast turn
+ ob->angle += (tics<<1);
}
ob->angle -= (mousexmove/10);
@@ -2742,9 +2900,11 @@ void T_Player (objtype *ob)
if ( (Keyboard[sc_Enter] || Keyboard[sc_X]) && ((TimeCount-lastnuke > NUKETIME) || (autofire)))
CastNuke ();
+#if 0
scroll = LastScan-2;
if ( scroll>=0 && scroll<NUMSCROLLS && gamestate.scrolls[scroll])
ReadScroll (scroll);
+#endif
DrawText(false);
DrawHealth();
@@ -2984,7 +3144,7 @@ void FaceAngle(short DestAngle)
// RED GEM
//
- case demonobj:
+ case godessobj:
if (gamestate.gems[B_RGEM-B_RGEM])
if (obj->active == always)
RadarXY[objnum++][2]=12;
@@ -2992,7 +3152,7 @@ void FaceAngle(short DestAngle)
// GREEN GEM
//
- case trollobj:
+ case fatdemonobj:
if (gamestate.gems[B_GGEM-B_RGEM])
if (obj->active == always)
RadarXY[objnum++][2]=10;
diff --git a/DEF.H b/DEF.H
index 29de258..63c5a05 100644
--- a/DEF.H
+++ b/DEF.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -22,6 +22,8 @@
//#define PROFILE
+#define DEBUG_KEYS_AVAILABLE 0
+
/*
=============================================================================
@@ -31,32 +33,54 @@
*/
//
+// SOFTLIB GFX FILENAME
+//
+#define SLIB_GFX "ARM_SLIB."EXT
+
+
+#define USE_INERT_LIST false
+
+
+//
// MAX_BASE - represents 100 percent in 1st base
// MAX_PERC - represents 100 percent in 2nd base
// PERC - fractional portion of 2nd base
// SCALE - arbitrary scaling value (bigger number means more accurate)
//
-// ex: PERCENTAGE(320,16,8,8) returns 160
+// ex: PERCENTAGE(320,16,8,7) returns 160
//
+// Make sure values used won't overflow a WORD! In general, if largest number
+// to be used (320 in ex: above) * (1<<SCALE) is greater than 65535, use
+// LONG_PERCENTAGE or a lower SCALE. Using a SCALE of 8 in the example
+// above would overflow a WORD in some circumstances!
+//
+// LONG_PERCENTAGE is to be used for larger SCALEs, thus, giving you
+// massive accuracy!
//
#define PERCENTAGE(MAX_BASE,MAX_PERC,PERC,SCALE) ((unsigned)(MAX_BASE*((PERC<<SCALE)/MAX_PERC))>>SCALE)
+#define LONG_PERCENTAGE(MAX_BASE,MAX_PERC,PERC,SCALE) (((long)MAX_BASE*(((long)PERC<<SCALE)/MAX_PERC))>>SCALE)
#define PI 3.141592657
+//#define SIZE_TEST 65000
+#define SIZE_TEST 0
-#define SIZE_TEST 0 //50000 // DO NOT USE!! ARGH!
#define FL_QUICK 0x01
#define FL_NOMEMCHECK 0x02
+#define FL_HELPTEST 0x04
-#define FL_CLEAR (FL_QUICK|FL_NOMEMCHECK)
+#define FL_CLEAR (FL_QUICK|FL_NOMEMCHECK|FL_HELPTEST)
+#if 0
#define GEM_SHIFT 2
#define FL_RGEM 0x04
#define FL_GGEM 0x08
#define FL_BGEM 0x10
#define FL_YGEM 0x20
#define FL_PGEM 0x40
+#endif
+
#define FL_DEAD 0x80
@@ -102,10 +126,10 @@
#define MOUSEINT 0x33
#define EXPWALLSTART 8
-#define NUMEXPWALLS 7
-#define WALLEXP 15
-#define WATEREXP 29
-#define NUMFLOORS 71
+#define NUMEXPWALLS 7
+#define WALLEXP 59
+#define WATEREXP 62
+#define NUMFLOORS 80 //71
#define NUMLATCHPICS (FIRSTWALLPIC-FIRSTLATCHPIC) //+5
#define NUMSCALEPICS (FIRSTWALLPIC-FIRSTSCALEPIC) //+5
@@ -116,7 +140,7 @@
#define FLASHTICS 4
-#define NUMLEVELS 21
+#define NUMLEVELS 32 //21
#define VIEWX 0 // corner of view window
#define VIEWY 0
@@ -135,7 +159,6 @@
#define MINDIST (2*GLOBAL1/5)
#define FOCALLENGTH (TILEGLOBAL) // in global coordinates
-
#define ANGLES 360 // must be divisable by 4
#define MAPSIZE 64 // maps are 64*64 max
@@ -173,7 +196,7 @@
enum bonusnumbers {B_BOLT,B_NUKE,B_POTION,B_RKEY,B_YKEY,B_GKEY,B_BKEY,B_SCROLL1,
B_SCROLL2,B_SCROLL3,B_SCROLL4,B_SCROLL5,B_SCROLL6,B_SCROLL7,B_SCROLL8,
- B_GOAL,B_CHEST,B_RGEM,B_GGEM,B_BGEM,B_YGEM,B_PGEM,B_RKEY2};
+ B_GOAL,B_CHEST,B_RGEM,B_GGEM,B_BGEM,B_YGEM,B_PGEM};
#define MAX_DOOR_STORAGE 5
@@ -187,8 +210,10 @@ enum bonusnumbers {B_BOLT,B_NUKE,B_POTION,B_RKEY,B_YKEY,B_GKEY,B_BKEY,B_SCROLL1,
#define MAXREALTICS (2*60)
#define MAXFREEZETIME (100*30) // 50 secs (100 half)
-extern boolean EASYMODEON;
+#define INVISIBLEWALL 0x46
+
+#define USE_STRIPS FALSE
/*
=============================================================================
@@ -214,54 +239,79 @@ typedef struct
} walltype;
typedef enum
- {nothing,playerobj,bonusobj,orcobj,batobj,skeletonobj,trollobj,demonobj,
- mageobj,pshotobj,bigpshotobj,mshotobj,inertobj,bounceobj,grelmobj,
- gateobj,zombieobj,spookobj,wetobj,expobj,eyeobj,wallskelobj,eshotobj,
- gshotobj,reddemonobj,freezeobj,solidobj} classtype;
+ {nothing,playerobj,bonusobj,succubusobj,batobj,skeletonobj,fatdemonobj,godessobj,
+ mageobj,pshotobj,bigpshotobj,mshotobj,inertobj,bounceobj,grelmobj,sshotobj,
+ gateobj,zombieobj,antobj,wetobj,expobj,eyeobj,wallskelobj,eshotobj,treeobj,
+ gshotobj,reddemonobj,freezeobj,solidobj,cloudobj,dshotobj,hbunnyobj,bunnyobj,
+ realsolidobj} classtype;
typedef enum {north,east,south,west,northeast,southeast,southwest,
northwest,nodir} dirtype; // a catacombs 2 carryover
-
typedef struct statestruct
{
int shapenum;
int tictime;
void (*think) ();
- struct statestruct *next;
-} statetype;
+ struct statestruct far *next;
+} statetypestruct;
+
+#define statetype statetypestruct far
#define of_shootable 0x01
#define of_damagedone 0x02
+#define of_forcefield 0x40 // defines a solid object as a forcefield???????????
+#define of_tree 0x80 // used to identify between a tree and a statue --
+ // last minute changes for Greg
typedef struct objstruct
{
+
+ int ticcount; //
+ statetype *state; // THESE MEMBERS MUST BE IN THE SAME
+ fixed x,y; // ORDER AS THE MEMBERS DEFINED IN
+ int viewx; // IOBJSTRUCT OR ALL HELL WILL BREAK
+ unsigned tilex,tiley; // LOOSE!!
+ unsigned viewheight; //
+ unsigned size; //
+ struct objstruct *next; //
+
+
+ struct objstruct *prev;
enum {no,noalways,yes,always} active;
- int ticcount;
classtype obclass;
- statetype *state;
unsigned char flags;
-// boolean tileobject; // true if entirely inside one tile
long distance;
dirtype dir;
- fixed x,y;
- unsigned tilex,tiley;
- int viewx;
- unsigned viewheight;
int angle;
int hitpoints;
long speed;
- unsigned size; // global radius for hit rect calculation
fixed xl,xh,yl,yh; // hit rectangle
int temp1,temp2;
- struct objstruct *next,*prev;
} objtype;
+#if USE_INERT_LIST
+
+#define MAXINERTOBJ 20
+
+typedef struct iobjstruct {
+ int ticcount;
+ statetype *state;
+ fixed x,y;
+ int viewx;
+ unsigned tilex,tiley;
+ unsigned viewheight;
+ unsigned size;
+ struct iobjstruct *next;
+} inertobjtype;
+
+#endif
+
typedef enum {ex_stillplaying,ex_died,ex_warped,ex_resetgame
,ex_loadedgame,ex_victorious,ex_turning,ex_abort} exittype;
@@ -294,6 +344,7 @@ typedef struct
long score;
int body,shotpower;
+ short mapwidth,mapheight;
// levelinfo levels[NUMLEVELS];
} gametype;
@@ -305,7 +356,7 @@ typedef struct
=============================================================================
*/
-extern char inlevel[][2];
+extern char inlevel[][2];
extern char str[80],str2[20];
extern unsigned tedlevelnum;
extern boolean tedlevel;
@@ -313,6 +364,8 @@ extern gametype gamestate;
extern exittype playstate;
extern char SlowMode;
extern unsigned Flags;
+extern boolean LoadShapes;
+extern boolean EASYMODEON;
void NewGame (void);
@@ -328,6 +381,9 @@ void SetupScalePic (unsigned picnum);
void SetupScaleWall (unsigned picnum);
void SetupScaling (void);
void main (void);
+void Display320(void);
+void Display640(void);
+void PrintHelp(void);
/*
=============================================================================
@@ -351,7 +407,7 @@ extern unsigned textstarts[27];
void ScanInfoPlane (void);
void ScanText (void);
-void SetupGameLevel (void);
+void SetupGameLevel(void);
void Victory (boolean playsounds);
void Died (void);
void NormalScreen (void);
@@ -372,8 +428,8 @@ void GameLoop (void);
=============================================================================
*/
-#define BGF_NIGHT 0x01 // it is officially night
-#define BGF_NOT_LIGHTNING 0x02 // lightning flash has ended
+#define BGF_NIGHT 0x01 // it is officially night
+#define BGF_NOT_LIGHTNING 0x02 // lightning flash has ended
extern byte BGFLAGS,bcolor;
@@ -397,15 +453,14 @@ extern byte update[];
extern boolean godmode,singlestep;
extern int extravbls;
-extern int objectcount;
extern int mousexmove,mouseymove;
extern int pointcount,pointsleft;
extern status_flags status_flag;
extern int status_delay;
extern objtype dummyobj;
-extern short BeepTime; //
-
+extern short BeepTime;
+extern unsigned scolor,gcolor;
void CenterWindow(word w,word h);
void DebugMemory (void);
@@ -432,11 +487,12 @@ void DisplayStatus (status_flags *stat_flag);
//void SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size);
//void SpawnNewObjFrac (long x, long y, statetype *state, unsigned size);
-void Internal_SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size,boolean UseDummy);
+void Internal_SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size, boolean UseDummy, boolean PutInActorat);
void Internal_SpawnNewObjFrac (long x, long y, statetype *state, unsigned size,boolean UseDummy);
-#define DSpawnNewObj(x, y, state, size) Internal_SpawnNewObj(x,y,state,size,true)
-#define SpawnNewObj(x, y, state, size) Internal_SpawnNewObj(x,y,state,size,false)
+#define DSpawnNewObj(x, y, state, size) Internal_SpawnNewObj(x,y,state,size,true,true)
+#define SpawnNewObj(x, y, state, size) Internal_SpawnNewObj(x,y,state,size,false,true)
+#define ASpawnNewObj(x, y, state, size) Internal_SpawnNewObj(x,y,state,size,false,false)
#define SpawnNewObjFrac(x, y, state, size,Dummy) Internal_SpawnNewObjFrac(x, y, state, size,false)
#define DSpawnNewObjFrac(x, y, state, size) Internal_SpawnNewObjFrac(x, y, state, size,true)
@@ -520,13 +576,14 @@ extern fixed mindist;
extern int viewheight;
extern fixed scale;
-extern int walllight1[NUMFLOORS];
-extern int walldark1[NUMFLOORS];
-extern int walllight2[NUMFLOORS];
-extern int walldark2[NUMFLOORS];
+extern int far walllight1[NUMFLOORS];
+extern int far walldark1[NUMFLOORS];
extern unsigned topcolor,bottomcolor;
+extern char wall_anim_info[NUMFLOORS];
+extern char wall_anim_pos[NUMFLOORS];
+
//==========================================================================
void DrawLine (int xl, int xh, int y,int color);
@@ -663,32 +720,36 @@ void SpawnBigExplosion(fixed x, fixed y, short Delay, fixed Range);
int EasyHitPoints(int NrmHitPts);
int EasyDoDamage(int Damage);
-extern short zombie_base_delay;
+#define zombie_mode ob->temp1
+#define zombie_delay ob->temp2
-extern statetype s_trollouch;
-extern statetype s_trolldie1;
+enum zombie_modes {zm_wait_for_dark,zm_wait_to_rise,zm_active};
+enum eye_modes {em_other1,em_player1,em_other2,em_player2,em_other3,em_player3,em_other4,em_player4,em_dummy};
-extern statetype s_orcpause;
+#define MSHOTDAMAGE 2
+#define MSHOTSPEED 10000
-extern statetype s_orc1;
-extern statetype s_orc2;
-extern statetype s_orc3;
-extern statetype s_orc4;
+#define ESHOTDAMAGE 1
+#define ESHOTSPEED 5000
-extern statetype s_orcattack1;
-extern statetype s_orcattack2;
-extern statetype s_orcattack3;
+#define SSHOTDAMAGE 3
+#define SSHOTSPEED 6500
-extern statetype s_orcouch;
+#define RANDOM_ATTACK 20
-extern statetype s_orcdie1;
-extern statetype s_orcdie2;
-extern statetype s_orcdie3;
+extern dirtype dirtable[];
+extern short other_x[], other_y[];
+extern short zombie_base_delay;
+
+extern statetype s_fatdemon_ouch;
+extern statetype s_fatdemon_blowup1;
+extern statetype s_succubus_ouch;
+extern statetype s_succubus_death1;
-extern statetype s_demonouch;
-extern statetype s_demondie1;
+extern statetype s_godessouch;
+extern statetype s_godessdie1;
extern statetype s_mageouch;
extern statetype s_magedie1;
@@ -706,32 +767,17 @@ extern statetype s_zombie_rise2;
extern statetype s_zombie_rise3;
extern statetype s_zombie_rise4;
-extern statetype s_spook0_1;
-extern statetype s_spook0_2;
-extern statetype s_spook0_3;
-extern statetype s_spook0_4;
-extern statetype s_spook0;
-extern statetype s_spook1;
-extern statetype s_spook2;
-extern statetype s_spook3;
-extern statetype s_spook4;
-extern statetype s_spook5;
-extern statetype s_spook6;
-extern statetype s_spook_pause;
-extern statetype s_spook_attack1;
-extern statetype s_spook_attack2;
-extern statetype s_spook_attack3;
-extern statetype s_spookouch;
-extern statetype s_spookdie;
-extern statetype s_spookdie1;
-extern statetype s_spookdie2;
-extern statetype s_spookdie3;
-extern statetype s_spookdie4;
-extern statetype s_spookdie5;
-extern statetype s_spookdie6;
-extern statetype s_spookdie7;
-extern statetype s_spook_wait;
-
+extern statetype s_ant_wait;
+extern statetype s_ant_egg;
+extern statetype s_ant_walk1;
+extern statetype s_ant_walk2;
+extern statetype s_ant_walk3;
+extern statetype s_ant_attack1;
+extern statetype s_ant_pause;
+extern statetype s_ant_ouch;
+extern statetype s_ant_die1;
+extern statetype s_ant_die2;
+extern statetype s_ant_die3;
extern statetype s_skel_pause;
extern statetype s_skel_1;
@@ -795,10 +841,6 @@ extern statetype s_eye_2;
extern statetype s_eye_3;
extern statetype s_eye_4;
-//statetype s_eye_attack1 = {SKELETON_ATTACK_1PIC,20,NULL,&s_eye_attack2};
-//statetype s_eye_attack2 = {SKELETON_ATTACK_2PIC,10,T_DoDamage,&s_eye_attack3};
-//statetype s_eye_attack3 = {SKELETON_ATTACK_3PIC,40,NULL,&s_eye_pause};
-
extern statetype s_eye_ouch;
extern statetype s_eye_ouch2;
@@ -812,5 +854,12 @@ extern statetype s_mshot2;
extern statetype s_bonus_die;
extern statetype s_red_demonouch;
-
extern statetype s_red_demondie1;
+
+extern statetype s_bunny_death1;
+extern statetype s_bunny_ouch;
+
+extern statetype s_tree_death1;
+extern statetype s_tree_ouch;
+
+extern statetype s_force_field_die; \ No newline at end of file
diff --git a/GELIB.C b/GELIB.C
index 97de708..5e0bd6f 100644
--- a/GELIB.C
+++ b/GELIB.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -28,6 +28,8 @@
#include "DEF.H"
#include "gelib.h"
+#include "sl_file.h"
+
#define MAX_GAMELIST_NAMES 20
#define FNAME_LEN 9
@@ -44,6 +46,11 @@ short NumGames;
short PPT_LeftEdge=0,PPT_RightEdge=320;
boolean LeaveDriveOn=false,ge_textmode=true;
char Filename[FILENAME_LEN+1], ID[sizeof(GAMENAME)], VER[sizeof(SAVEVER_DATA)];
+short wall_anim_delay,wall_anim_time = 7;
+BufferedIO lzwBIO;
+
+
+
////////////////////////////////////////////////////////////////////////////
@@ -205,200 +212,6 @@ void DoPiracy()
#endif
#endif
-
-//--------------------------------------------------------------------------
-// PrintPropText()
-//--------------------------------------------------------------------------
-
-// THE FOLLOWING MUST BE INITIALIZED BEFORE CALLING THIS ROUTINE:
-//
-
-// WindowX, WindowW, PrintY - These are ID global variables and are
-// automatically initialized when using their window routines.
-//
-// WindowX is the left edge of the window.
-// WindowW is the width of the window.
-// PrintY is the top edge of the window area.
-//
-// All values are represented in unshifted pixels.
-
-// PPT_LeftEdge, PPT_RightEdge - These are globals used by PrintPropText().
-// They define the left and right edge of the text area in pixels.
-
-void PrintPropText(char far *text)
-{
- #define RETURN_CHAR '\n'
-
- char pb[200];
-
- fontstruct _seg *font = (fontstruct _seg *)grsegs[STARTFONT];
- char savech;
- short length,maxend,maxx,loop,curx;
- boolean centerit,lastcharcr;
-
- while (*text)
- {
- if (*text == '^')
- centerit=true,text++;
- else
- centerit=false;
-
- /* Search forward for the last possible character in the line. This
- ** character is: 1) RETURN (end of line) 2) ZERO (end of buffer)
- ** and 3) the character at "WP->vWidth" bytes from the start of the line.
- */
- curx=PPT_LeftEdge;
- length=0;
- while ((curx+font->width[text[length+1]] < PPT_RightEdge) &&
- (text[length]) &&
- (text[length] != RETURN_CHAR))
- curx+=font->width[text[length++]];
-
- /* Search backward from the point we just found for a SPACE (for word
- ** wrapping).
- */
- if ((text[length]) && (text[length] != RETURN_CHAR))
- {
- maxx = curx;
- maxend = length;
- while ((length) && (text[length] != ' '))
- curx-=font->width[text[length--]];
-
- /* Were there any SPACES on this line? If not, take the MAX!
- */
- if (!length)
- length=maxend,curx=maxx;
- }
-
- /* If we can, lets keep the SPACE or RETURN that follows a line at
- ** the end of that line.
- */
- if (((text[length] == ' ') || (text[length] == RETURN_CHAR)) && (length < PPT_RightEdge))
- length++;
-
- // All of this is kludged to work with ID _Print routines...
- //
- savech=text[length];
- text[length]=0;
- if (text[length-1] == RETURN_CHAR)
- {
- lastcharcr=true;
- text[length-1]=0;
- }
- else
- lastcharcr=false;
- _fmemcpy(pb,text,length+1);
- if (centerit)
- {
- US_CPrintLine(pb);
- }
- else
- {
- PrintX = PPT_LeftEdge;
- US_Print(pb);
- US_Print("\n");
- }
- if (lastcharcr)
- text[length-1]=RETURN_CHAR;
- text[length]=savech;
- //
- // end of ID _Print kludge...
-
- text += length;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////
-//
-// DisplayText()
-//
-void DisplayText(textinfo *textinfo)
-{
- #define PAGE_WIDTH 78
-
- int loop, PageNum, LastNum,num;
- boolean InHelp = true,faded_in = false;
- unsigned holddisp,holdpan,holdbuffer,holdaddress;
-
-// Can you believe it takes all this just to change to 640 mode!!???!
-//
- VW_ScreenToScreen(0,FREESTART-STATUSLEN,40,80);
- VW_SetLineWidth(80);
- MoveScreen(0,0);
- VW_Bar (0,0,640,200,0);
- VW_SetScreenMode(EGA640GR);
- VW_SetLineWidth(80);
- BlackPalette();
-
-// Now, let's display some text...
-//
- PPT_RightEdge=PAGE_WIDTH*8;
- PPT_LeftEdge=16;
- PrintY= 30;
- WindowX=WindowY=0;
-
- LastNum = -1;
- PageNum = 1;
- while (InHelp)
- {
- // Display new page of text.
- //
- if (PageNum != LastNum)
- {
- US_DrawWindow(1,1,PAGE_WIDTH,23);
- PrintPropText(textinfo->pages[PageNum-1]);
- LastNum = PageNum;
- }
-
- VW_UpdateScreen();
- if (!faded_in)
- {
- VW_FadeIn();
- faded_in = true;
- }
-
- // Scroll through text / exit.
- //
- IN_ReadControl(0,&control);
- if (control.button1 || Keyboard[1])
- InHelp=false;
- else
- {
- if (ControlTypeUsed != ctrl_Keyboard)
- control.dir = dir_None;
-
- if (((control.dir == dir_North) || (control.dir == dir_West)) && (PageNum > 1))
- {
- PageNum--;
- while ((control.dir == dir_North) || (control.dir == dir_West))
- IN_ReadControl(0,&control);
- }
- else
- if (((control.dir == dir_South) || (control.dir == dir_East)) && (PageNum < textinfo->totalpages))
- {
- PageNum++;
- while ((control.dir == dir_South) || (control.dir == dir_East))
- IN_ReadControl(0,&control);
- }
- }
- }
-
- // Wait for 'exit key' to be released.
- //
- while (control.button1 || Keyboard[1])
- IN_ReadControl(0,&control);
-
-// Can you believe it takes all this just to change to 320 mode!!???!
-//
- VW_FadeOut();
- VW_SetLineWidth(40);
- MoveScreen(0,0);
- VW_Bar (0,0,320,200,0);
- VW_SetScreenMode(EGA320GR);
- BlackPalette();
- VW_ScreenToScreen(FREESTART-STATUSLEN,0,40,80);
-}
-
//--------------------------------------------------------------------------
// BlackPalette()
//--------------------------------------------------------------------------
@@ -454,8 +267,7 @@ long Verify(char *filename)
void GE_SaveGame()
{
boolean GettingFilename=true;
- char drive;
-// char Filename[FILENAME_LEN+1],drive; //, ID[sizeof(GAMENAME)], VER[sizeof(SAVEVER_DATA)];
+// char Filename[FILENAME_LEN+1]; //, ID[sizeof(GAMENAME)], VER[sizeof(SAVEVER_DATA)];
int handle;
struct dfree dfree;
long davail;
@@ -475,22 +287,14 @@ void GE_SaveGame()
goto EXIT_FUNC;
if (!strlen(Filename))
goto EXIT_FUNC;
-
- drive = getdisk();
- getdfree(drive+1,&dfree);
+ getdfree(getdisk()+1,&dfree);
davail = (long)dfree.df_avail*(long)dfree.df_bsec*(long)dfree.df_sclus;
-
- if (davail < 10000l)
+ if (davail < 10000)
{
- char status[40] = "\nDrive: Free: ";
-
- US_CenterWindow(30,6);
+ US_CenterWindow(22,4);
US_Print("\n");
US_CPrintLine("Disk Full: Can't save game.");
US_CPrintLine("Try inserting another disk.");
- status[8] = drive+'A';
- itoa(davail,&status[18],10);
- US_CPrint(status);
VW_UpdateScreen();
IN_Ack();
@@ -926,241 +730,6 @@ void RefreshBOBList(objtype *obj)
-
-
-
-
-
-
-
-//==========================================================================
-// JAMPAK routines
-//==========================================================================
-#define N 4096
-#define F 18
-
-// THRESHOLD : encode string into position and length if match_length is
-// greater than this
-
-#define THRESHOLD 2
-
-// index for root of binary search trees
-//
-
-#define NIL N
-#define COMP "COMP"
-
-unsigned long textsize = 0, // text size counter
- codesize = 0, // code size counter
- printcount = 0; // counter for reporting progress every 1K bytes
-
-unsigned char far text_buf[N + F - 1];
-
-memptr segptr;
-
-BufferedIO lzwBIO;
-
-//--------------------------------------------------------------------------
-// BLoad()
-//--------------------------------------------------------------------------
-unsigned long BLoad(char *SourceFile, memptr *DstPtr)
-{
- int handle;
-
- memptr SrcPtr;
- longword i, j, k, r, c;
- word flags;
- byte Buffer[8];
- longword DstLen, SrcLen;
- boolean comp;
-
- if ((handle = open(SourceFile, O_RDONLY|O_BINARY)) == -1)
- return(0);
-
- // Look for 'COMP' header
- //
- read(handle,Buffer,4);
- comp = !strncmp(Buffer,COMP,4);
-
- // Get source and destination length.
- //
- if (comp)
- {
- SrcLen = Verify(SourceFile);
- read(handle,(void *)&DstLen,4);
- MM_GetPtr(DstPtr,DstLen);
- if (!*DstPtr)
- return(0);
- }
- else
- DstLen = Verify(SourceFile);
-
- // LZW decompress OR simply load the file.
- //
- if (comp)
- {
-
- if (MM_TotalFree() < SrcLen)
- {
- if (!InitBufferedIO(handle,&lzwBIO))
- TrashProg("No memory for buffered I/O.");
- lzwDecompressFromFile(&lzwBIO,MK_FP(*DstPtr,0),SrcLen+8);
- FreeBufferedIO(&lzwBIO);
- }
- else
- {
- CA_LoadFile(SourceFile,&SrcPtr);
- lzwDecompressFromRAM(MK_FP(SrcPtr,8),MK_FP(*DstPtr,0),SrcLen+8);
- MM_FreePtr(&SrcPtr);
- }
- }
- else
- CA_LoadFile(SourceFile,DstPtr);
-
- close(handle);
- return(DstLen);
-}
-
-//--------------------------------------------------------------------------
-// lzwDecompressFromRAM()
-//
-// SrcPtr - pointer to first byte of compressed data.
-// DstPtr - pointer to decompress memory area.
-// SrcLen - length of compressed data.
-//
-//--------------------------------------------------------------------------
-
-#undef nextch()
-#define nextch(ptr) *ptr++
-
-void lzwDecompressFromRAM(byte far *SrcPtr, byte far *DstPtr, longword SrcLen)
-{
- longword i, j, k, r, c;
- word flags;
- byte ch;
-
-
- for (i = 0; i < N - F; i++)
- text_buf[i] = ' ';
-
- r = N - F;
- flags = 0;
-
- for ( ; ; )
- {
- if (((flags >>= 1) & 256) == 0)
- {
- if (!(--SrcLen))
- break;
- c=nextch(SrcPtr);
-
- flags = c | 0xff00; /* uses higher byte cleverly */
- } /* to count eight */
-
- if (flags & 1)
- {
- if (!(--SrcLen))
- break;
- c=nextch(SrcPtr);
-
- *DstPtr++ = c;
- text_buf[r++] = c;
- r &= (N - 1);
- }
- else
- {
- if (!(--SrcLen))
- break;
- i=nextch(SrcPtr);
-
- if (!(--SrcLen))
- break;
- j=nextch(SrcPtr);
-
- i |= ((j & 0xf0) << 4);
- j = (j & 0x0f) + THRESHOLD;
-
- for (k = 0; k <= j; k++)
- {
- c = text_buf[(i + k) & (N - 1)];
- *DstPtr++ = c;
- text_buf[r++] = c;
- r &= (N - 1);
- }
- }
- }
-}
-
-//--------------------------------------------------------------------------
-// lzwDecompressFromHandle()
-//
-// SrcPtr - pointer to first byte of compressed data.
-// DstPtr - pointer to decompress memory area.
-// SrcLen - length of compressed data.
-//
-//--------------------------------------------------------------------------
-
-#undef nextch()
-#define nextch(handle) bio_readch(&lzwBIO)
-
-void lzwDecompressFromFile(BufferedIO *SrcPtr, byte far *DstPtr, longword SrcLen)
-{
- longword i, j, k, r, c;
- word flags;
- byte ch;
-
-
- for (i = 0; i < N - F; i++)
- text_buf[i] = ' ';
-
- r = N - F;
- flags = 0;
-
- for ( ; ; )
- {
- if (((flags >>= 1) & 256) == 0)
- {
- if (!(--SrcLen))
- break;
- c=nextch(SrcPtr);
-
- flags = c | 0xff00; /* uses higher byte cleverly */
- } /* to count eight */
-
- if (flags & 1)
- {
- if (!(--SrcLen))
- break;
- c=nextch(SrcPtr);
-
- *DstPtr++ = c;
- text_buf[r++] = c;
- r &= (N - 1);
- }
- else
- {
- if (!(--SrcLen))
- break;
- i=nextch(SrcPtr);
-
- if (!(--SrcLen))
- break;
- j=nextch(SrcPtr);
-
- i |= ((j & 0xf0) << 4);
- j = (j & 0x0f) + THRESHOLD;
-
- for (k = 0; k <= j; k++)
- {
- c = text_buf[(i + k) & (N - 1)];
- *DstPtr++ = c;
- text_buf[r++] = c;
- r &= (N - 1);
- }
- }
- }
-}
-
//--------------------------------------------------------------------------
// InitBufferedIO()
//--------------------------------------------------------------------------
@@ -1263,6 +832,9 @@ void SwapWord(unsigned int far *Var)
asm mov [es:bx],ax
}
+
+#if 0
+
////////////////////////////////////////////////////////////////////////////
//
// LoadShape()
@@ -1366,6 +938,7 @@ EXIT_FUNC:;
return (RT_CODE);
}
+#endif
////////////////////////////////////////////////////////////////////////////
//
@@ -1838,67 +1411,6 @@ void ReadGameList()
NumGames++;
}
-////////////////////////////////////////////////////////////////////////////
-//
-// LoadTextFile()
-//
-long LoadTextFile(char *filename,textinfo *textinfo)
-{
-#pragma warn -pia
- long size;
-
- if (!(size=BLoad(filename,&textinfo->textptr)))
- return(0);
- InitTextFile(textinfo);
-
- return(size);
-#pragma warn +pia
-}
-
-//-------------------------------------------------------------------------
-// FreeTextFile()
-//-------------------------------------------------------------------------
-void FreeTextFile(textinfo *textinfo)
-{
- if (textinfo->textptr)
- MM_FreePtr(&textinfo->textptr);
-}
-
-////////////////////////////////////////////////////////////////////////////
-//
-// InitTextFile()
-//
-void InitTextFile(textinfo *textinfo)
-{
- #define END_PAGE '@'
-
- char far *text = MK_FP(textinfo->textptr,0);
-
- textinfo->totalpages = 0;
- while (*text != END_PAGE)
- {
- if (textinfo->totalpages < MAX_TEXT_PAGES)
- textinfo->pages[textinfo->totalpages++] = text;
- else
- TrashProg("GE ERROR: Too many text pages. --> %d",textinfo->totalpages);
-
- while (*text != END_PAGE)
- {
- if ((*text == '\r') && (*(text+1) == '\n'))
- {
- *text = 32;
- *(text+1) = '\n';
- text+=2;
- }
- else
- text++;
- }
- *text = 0;
- text += 3;
- }
- *text = 0;
-}
-
#if 0
////////////////////////////////////////////////////////////////////////////
//
@@ -1924,6 +1436,7 @@ void CenterObj(objtype *obj, unsigned x, unsigned y)
}
#endif
+#if 0
//-------------------------------------------------------------------------
// cacheout()
//-------------------------------------------------------------------------
@@ -1954,6 +1467,7 @@ void cachein(short s,short e)
MM_SetPurge(&grsegs[i],0);
}
}
+#endif
#if 0
////////////////////////////////////////////////////////////////////////////
@@ -2067,7 +1581,7 @@ boolean visible_off(objtype *obj)
===================
*/
-#define PIXPERFRAME 10000 //1600
+#define PIXPERFRAME 10000
void FizzleFade (unsigned source, unsigned dest,
unsigned width,unsigned height, boolean abortable)
@@ -2206,9 +1720,9 @@ noxor:
if (rndval == 1) // entire sequence has been completed
goto exitfunc;
}
- frame++;
-// while (TimeCount<frame) // don't go too fast
-// ;
+// frame++;
+// while (TimeCount<frame); // don't go too fast
+
} while (1);
exitfunc:;
@@ -2217,6 +1731,7 @@ exitfunc:;
return;
}
+#if 0
//-------------------------------------------------------------------------
// mprintf()
//-------------------------------------------------------------------------
@@ -2264,6 +1779,7 @@ void mprintf(char *msg, ...)
va_end(ap);
}
+#endif
#if 0
@@ -2502,65 +2018,859 @@ void CacheAV(char *title)
current_disk = VIDEO_DISK;
}
}
+#endif
+
+#ifdef TEXT_PRESENTER
+//--------------------------------------------------------------------------
+//
+// TEXT PRESENTER CODE
+//
+//--------------------------------------------------------------------------
+
+typedef enum pi_stype {pis_pic2x,pis_latch_pic} pi_stype;
+
+
+typedef struct { // 4 bytes
+ unsigned shapenum;
+ pi_stype shape_type;
+} pi_shape_info;
+
+#define pia_active 0x01
+
+typedef struct { // 10 bytes
+ char baseshape;
+ char frame;
+ char maxframes;
+ short delay;
+ short maxdelay;
+ short x,y;
+} pi_anim_info;
+
+ #define PI_CASE_SENSITIVE
+
+ #define PI_RETURN_CHAR '\n'
+ #define PI_CONTROL_CHAR '^'
+
+ #define PI_CNVT_CODE(c1,c2) ((c1)|(c2<<8))
+
+// shape table provides a way for the presenter to access and
+// display any shape.
+//
+pi_shape_info far pi_shape_table[] = {
+
+ {BOLTOBJPIC,pis_pic2x}, // 0
+ {NUKEOBJPIC,pis_pic2x},
+ {SKELETON_1PIC,pis_pic2x},
+ {EYE_WALK1PIC,pis_pic2x},
+ {ZOMB_WALK1PIC,pis_pic2x},
+
+ {TIMEOBJ1PIC,pis_pic2x}, // 5
+ {POTIONOBJPIC,pis_pic2x},
+ {RKEYOBJPIC,pis_pic2x},
+ {YKEYOBJPIC,pis_pic2x},
+ {GKEYOBJPIC,pis_pic2x},
+
+ {BKEYOBJPIC,pis_pic2x}, // 10
+ {RGEM1PIC,pis_pic2x},
+ {GGEM1PIC,pis_pic2x},
+ {BGEM1PIC,pis_pic2x},
+ {YGEM1PIC,pis_pic2x},
+
+ {PGEM1PIC,pis_pic2x}, // 15
+ {CHESTOBJPIC,pis_pic2x},
+ {PSHOT1PIC,pis_pic2x},
+ {RED_DEMON1PIC,pis_pic2x},
+ {MAGE1PIC,pis_pic2x},
+
+ {BAT1PIC,pis_pic2x}, // 20
+ {GREL1PIC,pis_pic2x},
+ {GODESS_WALK1PIC,pis_pic2x},
+ {ANT_WALK1PIC,pis_pic2x},
+ {FATDEMON_WALK1PIC,pis_pic2x},
+
+ {SUCCUBUS_WALK1PIC,pis_pic2x}, //25
+ {TREE_WALK1PIC,pis_pic2x},
+ {DRAGON_WALK1PIC,pis_pic2x},
+ {BUNNY_LEFT1PIC,pis_pic2x},
+
+};
+
+// anim table holds info about each different animation.
+//
+pi_anim_info far pi_anim_table[] = {{0,0,3,0,10}, // 0 BOLT
+ {1,0,3,0,10}, // NUKE
+ {2,0,4,0,10}, // SKELETON
+ {3,0,3,0,10}, // EYE
+ {4,0,3,0,10}, // ZOMBIE
+ {5,0,2,0,10}, // 5 FREEZE TIME
+ {11,0,2,0,10}, // RED GEM
+ {12,0,2,0,10}, // GREEN GEM
+ {13,0,2,0,10}, // BLUE GEM
+ {14,0,2,0,10}, // YELLOW GEM
+
+ {15,0,2,0,10}, // 10 PURPLE GEM
+ {17,0,2,0,10}, // PLAYER'S SHOT
+ {18,0,3,0,10}, // RED DEMON
+ {19,0,2,0,10}, // MAGE
+ {20,0,4,0,10}, // BAT
+
+ {21,0,2,0,10}, // 15 GRELMINAR
+ {22,0,3,0,10}, // GODESS
+ {23,0,3,0,10}, // ANT
+ {24,0,4,0,10}, // FAT DEMON
+ {25,0,4,0,10}, // SUCCUBUS
+
+ {26,0,2,0,10}, // 20 TREE
+ {27,0,3,0,10}, // DRAGON
+ {28,0,2,0,10}, // BUNNY
+};
+
+// anim list is created on the fly from the anim table...
+// this allows a single animation to be display in more than
+// one place...
+//
+pi_anim_info far pi_anim_list[PI_MAX_ANIMS];
+boolean pi_recursing=false;
+
+//--------------------------------------------------------------------------
+// Presenter() - DANGEROUS DAVE "Presenter()" is more up-to-date than this.
+//
+//
+// Active control codes:
+//
+// ^CE - center text between 'left margin' and 'right margin'
+// ^FCn - set font color
+// ^LMnnn - set left margin (if 'nnn' == "fff" uses current x)
+// ^RMnnn - set right margin (if 'nnn' == "fff" uses current x)
+// ^EP - end of page (waits for up/down arrow)
+// ^PXnnn - move x to coordinate 'n'
+// ^PYnnn - move y to coordinate 'n'
+// ^XX - exit presenter
+// ^LJ - left justify --\ ^RJ doesn't handle imbedded control
+// ^RJ - right justify --/ codes properly. Use with caution.
+// ^BGn - set background color
+// ^ANnn - define animation
+// ^SHnnn - display shape 'n' at current x,y
+//
+//
+// Future control codes:
+//
+// ^OBnnn - activate object 'n'
+// ^FL - flush to edges (whatever it's called)
+//
+//
+// Other info:
+//
+// All 'n' values are hex numbers (0 - f), case insensitive.
+// The number of N's listed is the number of digits REQUIRED by that control
+// code. (IE: ^LMnnn MUST have 3 values! --> 003, 1a2, 01f, etc...)
+//
+// If a line consists only of control codes, the cursor is NOT advanced
+// to the next line (the ending <CR><LF> is skipped). If just ONE non-control
+// code is added, the number "8" for example, then the "8" is displayed
+// and the cursor is advanced to the next line.
+//
+// ^CE must be on the same line as the text it should center!
+//
+//--------------------------------------------------------------------------
+void Presenter(PresenterInfo *pi)
+{
+#ifdef AMIGA
+ XBitMap **font = pi->font;
+
+ #define ch_width(ch) font[ch]->pad
+ char font_height = font[0]->Rows;
+#else
+ fontstruct _seg *font = (fontstruct _seg *)grsegs[STARTFONT];
+
+ #define MAX_PB 150
+ #define ch_width(ch) font->width[ch]
+ char font_height = font->height-1; // "-1" squeezes font vertically
+ char pb[MAX_PB];
+ short length;
#endif
+ enum {jm_left,jm_right,jm_flush};
+ char justify_mode = jm_left;
+ boolean centering=false;
+
+ short bgcolor = pi->bgcolor;
+ short xl=pi->xl,yl=pi->yl,xh=pi->xh,yh=pi->yh;
+ short cur_x = xl, cur_y = yl;
+ char far *first_ch = pi->script[0];
+ char far *scan_ch,temp;
+ short scan_x,PageNum=0,numanims=0;
+ boolean up_released=true,dn_released=true;
+ boolean presenting=true,start_of_line=true;
+// if set background is first thing in file, make sure initial screen
+// clear uses this color.
+//
+ if (!_fstrncmp(first_ch,"^BG",3))
+ bgcolor = PI_VALUE(first_ch+3,1);
+
+ if (!pi_recursing)
+ {
+ PurgeAllGfx();
+ CachePage(first_ch);
+ }
+ VW_Bar(xl,yl,xh-xl+1,yh-yl+1,bgcolor);
+
+ while (presenting)
+ {
+//
+// HANDLE WORD-WRAPPING TEXT
+//
+ if (*first_ch != PI_CONTROL_CHAR)
+ {
+ start_of_line = false;
+ // Parse script until one of the following:
+ //
+ // 1) text extends beyond right margin
+ // 2) NULL termination is reached
+ // 3) PI_RETURN_CHAR is reached
+ // 4) PI_CONTROL_CHAR is reached
+ //
+ scan_x = cur_x;
+ scan_ch = first_ch;
+ while ((scan_x+ch_width(*scan_ch) <= xh) && (*scan_ch) &&
+ (*scan_ch != PI_RETURN_CHAR) && (*scan_ch != PI_CONTROL_CHAR))
+ scan_x += ch_width(*scan_ch++);
+
+ // if 'text extends beyond right margin', scan backwards for
+ // a SPACE
+ //
+ if (scan_x+ch_width(*scan_ch) > xh)
+ {
+ short last_x = scan_x;
+ char far *last_ch = scan_ch;
+ while ((scan_ch != first_ch) && (*scan_ch != ' ') && (*scan_ch != PI_RETURN_CHAR))
+ scan_x -= ch_width(*scan_ch--);
+ if (scan_ch == first_ch)
+ scan_ch = last_ch, scan_x = last_x;
+ }
+ // print current line
+ //
+#ifdef AMIGA
+ while (first_ch < scan_ch)
+ {
+ qBlit(font[*first_ch++],pi->dst,cur_x,cur_y);
+// qBlit(font[*first_ch],pi->dst,cur_x,cur_y);
+// cur_x += ch_width(*first_ch++);
+ }
+#else
+ temp = *scan_ch;
+ *scan_ch = 0;
+ if ((justify_mode == jm_right)&&(!centering))
+ {
+ unsigned width,height;
+ VWL_MeasureString(first_ch,&width,&height,font);
+ cur_x = xh-width;
+ if (cur_x < xl)
+ cur_x = xl;
+ }
+ px = cur_x;
+ py = cur_y;
+ length = scan_ch-first_ch+1; // USL_DrawString only works with
+ if (length > MAX_PB)
+ Quit("Presenter(): Print buffer string too long!");
+ _fmemcpy(pb,first_ch,length); // near pointers...
+ if (*first_ch != '\n')
+ USL_DrawString(pb);
+ *scan_ch = temp;
+ first_ch = scan_ch;
+#endif
+ cur_x = scan_x;
+ centering = false;
-#if 0
+ // skip SPACES / RETURNS at end of line
+ //
+ if ((*first_ch==' ') || (*first_ch==PI_RETURN_CHAR))
+ first_ch++;
-/////////////////////////////////////////////////////////////////////////////
+ // PI_CONTROL_CHARs don't advance to next character line
+ //
+ if (*scan_ch != PI_CONTROL_CHAR)
+ {
+ cur_x = xl;
+ cur_y += font_height;
+ }
+ }
+ else
//
-// GE_DecompressToRAM() -- This Decompression routine uses normal memory
-// allocation conventions..
+// HANDLE CONTROL CODES
//
-unsigned char huge *GE_DecompressToRAM(char *SourceFile, unsigned long *DataSize) /* Just the reverse of Encode(). */
+ {
+ PresenterInfo endmsg;
+ pi_anim_info far *anim;
+ pi_shape_info far *shape_info;
+ unsigned shapenum;
+ short length;
+ char far *s;
+
+ if (first_ch[-1] == '\n')
+ start_of_line = true;
+
+ first_ch++;
+#ifndef PI_CASE_SENSITIVE
+ *first_ch=toupper(*first_ch);
+ *(first_ch+1)=toupper(*(first_ch+1));
+#endif
+ switch (*((unsigned far *)first_ch)++)
+ {
+ // CENTER TEXT ------------------------------------------------------
+ //
+ case PI_CNVT_CODE('C','E'):
+ length = 0;
+ s = first_ch;
+ while (*s && (*s != PI_RETURN_CHAR))
+ {
+ switch (*s)
+ {
+ case PI_CONTROL_CHAR:
+ s++;
+ switch (*((unsigned *)s)++)
+ {
+#ifndef AMIGA
+ case PI_CNVT_CODE('F','C'):
+ case PI_CNVT_CODE('B','G'):
+ s++;
+ break;
+#endif
+
+ case PI_CNVT_CODE('L','M'):
+ case PI_CNVT_CODE('R','M'):
+ case PI_CNVT_CODE('S','H'):
+ case PI_CNVT_CODE('P','X'):
+ case PI_CNVT_CODE('P','Y'):
+ s += 3;
+ break;
+
+ case PI_CNVT_CODE('L','J'):
+ case PI_CNVT_CODE('R','J'):
+ // No parameters to pass over!
+ break;
+ }
+ break;
+
+ default:
+ length += ch_width(*s++);
+ break;
+ }
+ }
+ cur_x = ((xh-xl+1)-length)/2;
+ centering = true;
+ break;
+
+ // DRAW SHAPE -------------------------------------------------------
+ //
+ case PI_CNVT_CODE('S','H'):
+ shapenum = PI_VALUE(first_ch,3);
+ first_ch += 3;
+ shape_info = &pi_shape_table[shapenum];
+ switch (shape_info->shape_type)
+ {
+ short width;
+
+ case pis_pic2x:
+ cur_x = ((cur_x+2) + 7) & 0xFFF8;
+ width=BoxAroundPic(cur_x-2,cur_y-1,shape_info->shapenum,pi);
+ VW_DrawPic2x(cur_x>>3,cur_y,shape_info->shapenum);
+ cur_x += width;
+ break;
+ }
+ break;
+
+ // INIT ANIMATION ---------------------------------------------------
+ //
+ case PI_CNVT_CODE('A','N'):
+ shapenum = PI_VALUE(first_ch,2);
+ first_ch += 2;
+ _fmemcpy(&pi_anim_list[numanims],&pi_anim_table[shapenum],sizeof(pi_anim_info));
+ anim = &pi_anim_list[numanims++];
+ shape_info = &pi_shape_table[anim->baseshape+anim->frame];
+ switch (shape_info->shape_type)
+ {
+ short width;
+
+ case pis_pic2x:
+ cur_x = ((cur_x+2) + 7) & 0xFFF8;
+ width=BoxAroundPic(cur_x-2,cur_y-1,shape_info->shapenum,pi);
+ VW_DrawPic2x(cur_x>>3,cur_y,shape_info->shapenum);
+ anim->x = cur_x>>3;
+ anim->y = cur_y;
+ cur_x += width;
+ break;
+ }
+ break;
+
+#ifndef AMIGA
+ // FONT COLOR -------------------------------------------------------
+ //
+ case PI_CNVT_CODE('F','C'):
+ fontcolor = bgcolor ^ PI_VALUE(first_ch++,1);
+ break;
+#endif
+
+ // BACKGROUND COLOR -------------------------------------------------
+ //
+ case PI_CNVT_CODE('B','G'):
+ bgcolor = PI_VALUE(first_ch++,1);
+ break;
+
+ // LEFT MARGIN ------------------------------------------------------
+ //
+ case PI_CNVT_CODE('L','M'):
+ shapenum = PI_VALUE(first_ch,3);
+ first_ch += 3;
+ if (shapenum == 0xfff)
+ xl = cur_x;
+ else
+ xl = shapenum;
+ break;
+
+ // RIGHT MARGIN -----------------------------------------------------
+ //
+ case PI_CNVT_CODE('R','M'):
+ shapenum = PI_VALUE(first_ch,3);
+ first_ch += 3;
+ if (shapenum == 0xfff)
+ xh = cur_x;
+ else
+ xh = shapenum;
+ break;
+
+ // SET X COORDINATE -------------------------------------------------
+ //
+ case PI_CNVT_CODE('P','X'):
+ cur_x = PI_VALUE(first_ch,3);
+ first_ch += 3;
+ break;
+
+ // SET Y COORDINATE -------------------------------------------------
+ //
+ case PI_CNVT_CODE('P','Y'):
+ cur_y = PI_VALUE(first_ch,3);
+ first_ch += 3;
+ break;
+
+ // LEFT JUSTIFY -----------------------------------------------------
+ //
+ case PI_CNVT_CODE('L','J'):
+ justify_mode = jm_left;
+ break;
+
+ // RIGHT JUSTIFY ----------------------------------------------------
+ //
+ case PI_CNVT_CODE('R','J'):
+ justify_mode = jm_right;
+ break;
+
+ // END OF PAGE ------------------------------------------------------
+ //
+ case PI_CNVT_CODE('E','P'):
+ if (pi_recursing)
+ Quit("Presenter(): Can't use ^EP when recursing!");
+
+ endmsg.xl = cur_x;
+ endmsg.yl = yh-(font_height+2);
+ endmsg.xh = xh;
+ endmsg.yh = yh;
+ endmsg.bgcolor = bgcolor;
+ endmsg.ltcolor = pi->ltcolor;
+ endmsg.dkcolor = pi->dkcolor;
+ endmsg.script[0] = (char far *)"^CE^FC8- ^FC0ESC ^FC8to return to play, or ^FC0ARROW KEYS ^FC8to page through more Help -^XX";
+
+ pi_recursing = true;
+ Presenter(&endmsg);
+ pi_recursing = false;
+
+#ifndef AMIGA
+ if (screenfaded)
+ VW_FadeIn();
+ VW_ColorBorder(8 | 56);
+#endif
+
+ while (1)
+ {
+#ifndef AMIGA
+ long newtime;
+
+ VW_WaitVBL(1);
+ newtime = TimeCount;
+ realtics = tics = newtime-lasttimecount;
+ lasttimecount = newtime;
+#else
+ WaitVBL(1);
+ CALC_TICS;
+#endif
+ AnimatePage(numanims);
+ IN_ReadControl(0,&control);
+
+ if (control.button1 || Keyboard[1])
+ {
+ presenting=false;
+ break;
+ }
+ else
+ {
+ if (ControlTypeUsed != ctrl_Keyboard)
+ control.dir = dir_None;
+
+ if (((control.dir == dir_North) || (control.dir == dir_West)) && (PageNum))
+ {
+ if (up_released)
+ {
+ PageNum--;
+ up_released = false;
+ break;
+ }
+ }
+ else
+ {
+ up_released = true;
+ if (((control.dir == dir_South) || (control.dir == dir_East)) && (PageNum < pi->numpages-1))
+ {
+ if (dn_released)
+ {
+ PageNum++;
+ dn_released = false;
+ break;
+ }
+ }
+ else
+ dn_released = true;
+ }
+ }
+ }
+
+ cur_x = xl;
+ cur_y = yl;
+ if (cur_y+font_height > yh)
+ cur_y = yh-font_height;
+ first_ch = pi->script[PageNum];
+
+ numanims = 0;
+ PurgeAllGfx();
+ CachePage(first_ch);
+
+ VW_Bar(xl,yl,xh-xl+1,yh-yl+1,bgcolor);
+ break;
+
+ // EXIT PRESENTER ---------------------------------------------------
+ //
+ case PI_CNVT_CODE('X','X'):
+ presenting=false;
+ break;
+ }
+
+ if ((first_ch[0] == ' ') && (first_ch[1] == '\n') && start_of_line)
+ first_ch += 2;
+ }
+ }
+}
+
+//--------------------------------------------------------------------------
+// ResetAnims()
+//--------------------------------------------------------------------------
+void ResetAnims()
{
- FILE *infile; /* input & output files */
+ pi_anim_list[0].baseshape = -1;
+}
- unsigned long i, j, k, r, c;
- unsigned char huge *DataPtr;
- unsigned char huge *CurPtr;
- unsigned char Buffer[8];
- unsigned long DstLen;
+//--------------------------------------------------------------------------
+// AnimatePage()
+//--------------------------------------------------------------------------
+void AnimatePage(short numanims)
+{
+ pi_anim_info far *anim=pi_anim_list;
+ pi_shape_info far *shape_info;
- if (!(infile = fopen(SourceFile, "rb")))
- return(0);
+ while (numanims--)
+ {
+ anim->delay += tics;
+ if (anim->delay >= anim->maxdelay)
+ {
+ anim->delay = 0;
+ anim->frame++;
+ if (anim->frame == anim->maxframes)
+ anim->frame = 0;
- // Read Header....
+#if ANIM_USES_SHAPETABLE
+ shape_info = &pi_shape_table[anim->baseshape+anim->frame];
+#else
+ shape_info = &pi_shape_table[anim->baseshape];
+#endif
+ switch (shape_info->shape_type)
+ {
+ case pis_pic2x:
+#if ANIM_USES_SHAPETABLE
+ VW_DrawPic2x(anim->x,anim->y,shape_info->shapenum);
+#else
+ VW_DrawPic2x(anim->x,anim->y,shape_info->shapenum+anim->frame);
+#endif
+ break;
+ }
+ }
+ anim++;
+ }
+}
+
+//--------------------------------------------------------------------------
+// BoxAroundPic()
+//--------------------------------------------------------------------------
+short BoxAroundPic(short x1, short y1, unsigned picnum, PresenterInfo *pi)
+{
+ short x2,y2;
+
+ x2 = x1+(pictable[picnum-STARTPICS].width<<4)+2;
+ y2 = y1+(pictable[picnum-STARTPICS].height)+1;
+ VWB_Hlin(x1,x2,y1,pi->ltcolor);
+ VWB_Hlin(x1,x2,y2,pi->dkcolor);
+ VWB_Vlin(y1,y2,x1,pi->ltcolor);
+ VWB_Vlin(y1,y2,x1+1,pi->ltcolor);
+ VWB_Vlin(y1,y2,x2,pi->dkcolor);
+ VWB_Vlin(y1,y2,x2+1,pi->dkcolor);
+
+ return(x2-x1+1);
+}
- fread(Buffer,1,4,infile);
+//--------------------------------------------------------------------------
+// PurgeAllGfx()
+//--------------------------------------------------------------------------
+void PurgeAllGfx()
+{
+ ResetAnims();
+ FreeUpMemory();
+}
+
+//--------------------------------------------------------------------------
+// CachePage()
+//--------------------------------------------------------------------------
+void CachePage(char far *script)
+{
+ pi_anim_info far *anim;
+ short loop;
+ unsigned shapenum;
+ boolean end_of_page=false;
+ short numanims=0;
- if (strncmp(Buffer,COMP,4))
+ while (!end_of_page)
{
- fclose(infile);
- printf("NOT a JAM Compressed FILE!\n");
- return(0);
+ switch (*script++)
+ {
+ case PI_CONTROL_CHAR:
+#ifndef PI_CASE_SENSITIVE
+ *script=toupper(*script);
+ *(script+1)=toupper(*(script+1));
+#endif
+ switch (*((unsigned far *)script)++)
+ {
+ case PI_CNVT_CODE('S','H'):
+ shapenum = PI_VALUE(script,3);
+ script += 3;
+ CA_MarkGrChunk(pi_shape_table[shapenum].shapenum);
+ break;
+
+ case PI_CNVT_CODE('A','N'):
+ shapenum = PI_VALUE(script,2);
+ script += 2;
+
+ if (numanims++ == PI_MAX_ANIMS)
+ Quit("CachePage(): Too many anims on one page.");
+
+ anim = &pi_anim_table[shapenum];
+#if ANIM_USES_SHAPETABLE
+ for (loop=anim->baseshape;loop < anim->baseshape+anim->maxframes; loop++)
+ CA_MarkGrChunk(pi_shape_table[loop].shapenum);
+#else
+ shapenum = pi_shape_table[anim->baseshape].shapenum;
+ for (loop=0; loop<anim->maxframes; loop++)
+ CA_MarkGrChunk(shapenum+loop);
+#endif
+ break;
+
+ case PI_CNVT_CODE('X','X'):
+ case PI_CNVT_CODE('E','P'):
+ end_of_page = true;
+ break;
+ }
+ break;
+ }
}
- fread((void *)&DstLen,1,4,infile);
+ CA_CacheMarks(NULL);
+}
+
+//--------------------------------------------------------------------------
+// PI_VALUE()
+//--------------------------------------------------------------------------
+unsigned PI_VALUE(char far *ptr,char num_nybbles)
+{
+ char ch,nybble,shift;
+ unsigned value=0;
+
+ for (nybble=0; nybble<num_nybbles; nybble++)
+ {
+ shift = 4*(num_nybbles-nybble-1);
- if (!(DataPtr = farmalloc(DstLen)))
- return(0);
+ ch = *ptr++;
+ if (isxdigit(ch))
+ if (isalpha(ch))
+ value |= (toupper(ch)-'A'+10)<<shift;
+ else
+ value |= (ch-'0')<<shift;
+ }
+
+ return(value);
+}
- fclose(infile);
+//--------------------------------------------------------------------------
+// LoadPresenterScript()
+//--------------------------------------------------------------------------
+long LoadPresenterScript(char *filename,PresenterInfo *pi)
+{
+#pragma warn -pia
+ long size;
- *DataSize = DstLen;
+ if (!(size=BLoad(filename,&pi->scriptstart)))
+ return(0);
+ pi->script[0] = MK_FP(pi->scriptstart,0);
+ pi->script[0][size-1] = 0; // Last byte is trashed!
+ InitPresenterScript(pi);
- DecompressToRAMLocation(SourceFile,(unsigned char far *)DataPtr);
+ return(size);
+#pragma warn +pia
+}
- return(DataPtr);
+//-------------------------------------------------------------------------
+// FreePresenterScript()
+//-------------------------------------------------------------------------
+void FreePresenterScript(PresenterInfo *pi)
+{
+ if (pi->script)
+ MM_FreePtr(&pi->scriptstart);
}
+//-------------------------------------------------------------------------
+// InitPresenterScript()
+//-------------------------------------------------------------------------
+void InitPresenterScript(PresenterInfo *pi)
+{
+ char far *script = pi->script[0];
+
+ pi->numpages = 1; // Assume at least 1 page
+ while (*script)
+ {
+ switch (*script++)
+ {
+ case PI_CONTROL_CHAR:
+#ifndef PI_CASE_SENSITIVE
+ *script=toupper(*script);
+ *(script+1)=toupper(*(script+1));
#endif
+ switch (*((unsigned far *)script)++)
+ {
+ case PI_CNVT_CODE('E','P'):
+ if (pi->numpages < PI_MAX_PAGES)
+ pi->script[pi->numpages++] = script;
+ else
+ TrashProg("GE ERROR: Too many Presenter() pages. --> %d",pi->numpages);
+ break;
+ }
+ break;
+
+ case '\r':
+ if (*script == '\n')
+ {
+ *(script-1) = ' ';
+ script++;
+ }
+ break;
+ }
+ }
+
+ pi->numpages--; // Last page defined is not a real page.
+}
+#endif
+
+
+//-------------------------------------------------------------------------
+// AnimateWallList()
+//-------------------------------------------------------------------------
+void AnimateWallList(void)
+{
+ walltype *wall, *check;
+ unsigned i;
+ int tile,org_tile;
+
+ if (wall_anim_delay>0)
+ {
+ wall_anim_delay-=realtics;
+ return;
+ }
+
+ //
+ // Re-Init our counter...
+ //
+
+ wall_anim_delay = wall_anim_time;
+
+ //
+ // Clear all previous flags marking animation being DONE.
+ //
+
+ for (i=0;i<NUMFLOORS;i++)
+ TILE_FLAGS(i) &= ~tf_MARKED;
+
+
+ //
+ // Run though wall list updating only then needed animations
+ //
+
+ for (wall=&walls[1];wall<rightwall;wall++)
+ {
+ org_tile = tile = wall->color + wall_anim_pos[wall->color];
+
+ if (ANIM_FLAGS(tile))
+ {
+ do
+ {
+ if (!(TILE_FLAGS(tile) & tf_MARKED))
+ {
+ //
+ // update our offset table (0-NUMANIMS)
+ //
+
+ wall_anim_pos[tile] += (char signed)ANIM_FLAGS(tile+(char signed)wall_anim_pos[tile]);
+
+ //
+ // Mark tile as being already updated..
+ //
+
+ TILE_FLAGS(tile) |= tf_MARKED;
+ }
+
+ //
+ // Check rest of tiles in this animation string...
+ //
+
+ tile += (char signed)ANIM_FLAGS(tile);
+
+ } while (tile != org_tile);
+ }
+ }
+}
+
diff --git a/GELIB.H b/GELIB.H
index ccd4e64..eb25be6 100644
--- a/GELIB.H
+++ b/GELIB.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -16,38 +16,37 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "SL_FILE.h"
+
+
///////////////////////////////////////////////////////////////////////////
//
// Defines
//
-#define MAX_TEXT_PAGES 40
-#define SAVEVER_DATA "0.93"
+#define ANIM_USES_SHAPE_TABLE false
+#define PI_MAX_ANIMS 10
+#define PI_MAX_PAGES 40
+
+#define SAVEVER_DATA "0.01"
#define FILENAME_LEN 15
-#define GAMENAME "CATACOMB ABYSS 3-D"
-#define VERSION "V1.24 "
-#define REVISION "1"
+#define GAMENAME "CATACOMB ARMAGEDDON 3-D"
+#define VERSION "V1.02"
+#define REVISION " rev 1 "
//#define BOBLIST 1 //SP - Undefine if not using BOBList
-#define AUDIO_DISK (2)
-#define VIDEO_DISK (1)
-#define LEVEL_DISK (2)
+#define AUDIO_DISK (2)
+#define VIDEO_DISK (1)
+#define LEVEL_DISK (2)
-#define BIO_BUFFER_LEN (512)
+#define BIO_BUFFER_LEN (512)
#define TrashProg Quit
-///////////////////////////////////////////////////////////////////////////
-//
-// Externs
-//
+// #define AMIGA
-extern char Filename[], ID[], VER[];
-extern boolean ge_textmode;
-extern short PPT_LeftEdge,PPT_RightEdge;
-//extern boolean ConserveMemory;
typedef struct Sample {
char *filename;
@@ -56,17 +55,17 @@ typedef struct Sample {
typedef enum {ged_none, ged_SoundSource,ged_SoundBlaster} AudioDeviceType;
-typedef struct {
- memptr textptr;
- char far *pages[MAX_TEXT_PAGES];
- short totalpages;
-} textinfo;
+//typedef struct {
+// memptr textptr;
+// char far *pages[MAX_TEXT_PAGES];
+// short totalpages;
+//} textinfo;
typedef struct {
- int handle; // handle of file
- memptr buffer; // pointer to buffer
- word offset; // offset into buffer
- word status; // read/write status
+ int handle; // handle of file
+ memptr buffer; // pointer to buffer
+ word offset; // offset into buffer
+ word status; // read/write status
} BufferedIO;
typedef enum ANIMINFO {at_NONE,at_INIT,at_WAIT,at_ONCE,at_CYCLE,
@@ -75,8 +74,8 @@ typedef enum ANIMINFO {at_NONE,at_INIT,at_WAIT,at_ONCE,at_CYCLE,
} ANIMINFO;
struct BitMapHeader {
- unsigned int w,h,x,y;
- unsigned char d,trans,comp,pad;
+ unsigned int w,h,x,y;
+ unsigned char d,trans,comp,pad;
};
struct BitMap {
@@ -94,6 +93,39 @@ struct Shape {
struct BitMapHeader bmHdr;
};
+#ifdef AMIGA
+typedef struct {
+ char *script[PI_MAX_PAGES];
+ XBitMap **shapes;
+ XBitMap **font;
+ short xl,yl,xh,yh;
+ struct BitMap *dst;
+ char numpages,bgcolor;
+} PresenterInfo;
+#else
+typedef struct {
+ char far *script[PI_MAX_PAGES];
+ memptr scriptstart;
+ short xl,yl,xh,yh;
+ char numpages,bgcolor,ltcolor,dkcolor;
+} PresenterInfo;
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Externs
+//
+
+extern char Filename[], ID[], VER[];
+extern boolean ge_textmode;
+extern short PPT_LeftEdge,PPT_RightEdge;
+//extern boolean ConserveMemory;
+extern BufferedIO lzwBIO;
+extern short wall_anim_delay,wall_anim_time;
+
+
+
///////////////////////////////////////////////////////////////////////////
//
// Function prototypes
@@ -104,10 +136,10 @@ void MoveScreen(short x, short y);
void MoveGfxDst(short x, short y);
void DoPiracy(void);
void PrintPropText(char far *text);
-void DisplayText(textinfo *textinfo);
-long LoadTextFile(char *filename,textinfo *textinfo);
-void FreeTextFile(textinfo *textinfo);
-void InitTextFile(textinfo *textinfo);
+//void DisplayText(textinfo *textinfo);
+//long LoadTextFile(char *filename,textinfo *textinfo);
+//void FreeTextFile(textinfo *textinfo);
+//void InitTextFile(textinfo *textinfo);
long Verify(char *filename);
void GE_SaveGame(void);
boolean GE_LoadGame(void);
@@ -163,3 +195,16 @@ boolean FindFile(char *filename,char *disktext,char disknum);
void CacheAV(char *title);
void BlackPalette(void);
void ColoredPalette(void);
+void Presenter(PresenterInfo *pi);
+unsigned PI_VALUE(char far *ptr,char num_nybbles);
+long LoadPresenterScript(char *filename,PresenterInfo *pi);
+void FreePresenterScript(PresenterInfo *pi);
+void InitPresenterScript(PresenterInfo *pi);
+
+void AnimatePage(short numanims);
+short BoxAroundPic(short x1, short y1, unsigned picnum, PresenterInfo *pi);
+void PurgeAllGfx(void);
+void CachePage(char far *script);
+
+
+void AnimateWallList(void);
diff --git a/GFXE_ARM.EQU b/GFXE_ARM.EQU
index 97e2c33..f833b11 100644
--- a/GFXE_ARM.EQU
+++ b/GFXE_ARM.EQU
@@ -1,633 +1,542 @@
;=====================================
;
-; Graphics .EQU file for .ABS
-; IGRAB-ed on Thu Dec 02 11:58:33 1993
+; Graphics .EQU file for .ARM
+; IGRAB-ed on Thu Dec 02 13:59:00 1993
;
;=====================================
FINALEPIC = 4
STATUSPIC = 5
-SCROLLTOPPIC = 6
-SCROLLBOTTOMPIC = 7
-SCROLL1PIC = 8
-SCROLL2PIC = 9
-SCROLL3PIC = 10
-SCROLL4PIC = 11
-SCROLL5PIC = 12
-SCROLL6PIC = 13
-SCROLL7PIC = 14
-SCROLL8PIC = 15
-FACE5PIC = 16
-FIRSTLATCHPIC = 17
-FACE1PIC = 18
-FACE2PIC = 19
-FACE3PIC = 20
-FACE4PIC = 21
-RADAR_TOPPIC = 22
-RADAR_BOTTOMPIC = 23
-RADAR_RGEMPIC = 24
-RADAR_GGEMPIC = 25
-RADAR_BGEMPIC = 26
-RADAR_YGEMPIC = 27
-RADAR_PGEMPIC = 28
-FIRSTSCALEPIC = 29
-SKELETON_1PIC = 30
-SKELETON_2PIC = 31
-SKELETON_3PIC = 32
-SKELETON_4PIC = 33
-SKELETON_ATTACK_1PIC = 34
-SKELETON_ATTACK_2PIC = 35
-SKELETON_ATTACK_3PIC = 36
-SKELETON_OUCHPIC = 37
-SKELETON_DEATH_1PIC = 38
-SKELETON_DEATH_2PIC = 39
-SPOOK1PIC = 40
-SPOOK2PIC = 41
-SPOOK3PIC = 42
-SPOOK4PIC = 43
-SPOOK_ATTACKPIC = 44
-SPOOKHITPIC = 45
-SPOOK_INOUTPIC = 46
-TOMB1PIC = 47
-TOMB2PIC = 48
-TOMB3PIC = 49
-WET_BUBBLE1PIC = 50
-WET_BUBBLE2PIC = 51
-WET_EYESPIC = 52
-WET_RISE1PIC = 53
-WET_RISE2PIC = 54
-WET_WALK1PIC = 55
-WET_WALK2PIC = 56
-WET_WALK3PIC = 57
-WET_WALK4PIC = 58
-WET_ATTACK1PIC = 59
-WET_ATTACK2PIC = 60
-WET_ATTACK3PIC = 61
-WET_OUCHPIC = 62
-WET_DIE1PIC = 63
-WET_DIE2PIC = 64
-WET_DIE3PIC = 65
-OBJ_WARP1PIC = 66
-OBJ_WARP2PIC = 67
-OBJ_WARP3PIC = 68
-OBJ_WARP4PIC = 69
-EYE_WALK1PIC = 70
-EYE_WALK2PIC = 71
-EYE_WALK3PIC = 72
-EYE_OUCH1PIC = 73
-EYE_OUCH2PIC = 74
-EYE_DEATH1PIC = 75
-EYE_DEATH2PIC = 76
-EYE_DEATH3PIC = 77
-EYE_SHOT1PIC = 78
-EYE_SHOT2PIC = 79
-ZOMB_APPEAR1PIC = 80
-ZOMB_APPEAR2PIC = 81
-ZOMB_APPEAR3PIC = 82
-ZOMB_APPEAR4PIC = 83
-ZOMB_WALK1PIC = 84
-ZOMB_WALK2PIC = 85
-ZOMB_WALK3PIC = 86
-ZOMB_OUCHPIC = 87
-ZOMB_ATTACKPIC = 88
-ZOMB_DIE1PIC = 89
-ZOMB_DIE2PIC = 90
-ZOMB_DIE3PIC = 91
-ORC1PIC = 92
-ORC2PIC = 93
-ORC3PIC = 94
-ORC4PIC = 95
-ORCATTACK1PIC = 96
-ORCATTACK2PIC = 97
-ORCOUCHPIC = 98
-ORCDIE1PIC = 99
-ORCDIE2PIC = 100
-ORCDIE3PIC = 101
-TROLL1PIC = 102
-TROLL2PIC = 103
-TROLL3PIC = 104
-TROLL4PIC = 105
-TROLLOUCHPIC = 106
-TROLLATTACK1PIC = 107
-TROLLATTACK2PIC = 108
-TROLLATTACK3PIC = 109
-TROLLDIE1PIC = 110
-TROLLDIE2PIC = 111
-TROLLDIE3PIC = 112
-BOLTOBJPIC = 113
-BOLT2OBJPIC = 114
-BOLT3OBJPIC = 115
-NUKEOBJPIC = 116
-NUKE2OBJPIC = 117
-NUKE3OBJPIC = 118
-PITOBJPIC = 119
-TIMEOBJ1PIC = 120
-TIMEOBJ2PIC = 121
-O_WATER_CHEST1PIC = 122
-O_WATER_CHEST2PIC = 123
-POTIONOBJPIC = 124
-RKEYOBJPIC = 125
-YKEYOBJPIC = 126
-GKEYOBJPIC = 127
-BKEYOBJPIC = 128
-RGEM1PIC = 129
-RGEM2PIC = 130
-GGEM1PIC = 131
-GGEM2PIC = 132
-BGEM1PIC = 133
-BGEM2PIC = 134
-YGEM1PIC = 135
-YGEM2PIC = 136
-PGEM1PIC = 137
-PGEM2PIC = 138
-SCROLLOBJPIC = 139
-CHESTOBJPIC = 140
-RKEY2PIC = 141
-PSHOT1PIC = 142
-PSHOT2PIC = 143
-PSHOT_EXP1PIC = 144
-PSHOT_EXP2PIC = 145
-PSHOT_EXP3PIC = 146
-DEMON1PIC = 147
-DEMON2PIC = 148
-DEMON3PIC = 149
-DEMON4PIC = 150
-DEMONATTACK1PIC = 151
-DEMONATTACK2PIC = 152
-DEMONATTACK3PIC = 153
-DEMONOUCHPIC = 154
-DEMONDIE1PIC = 155
-DEMONDIE2PIC = 156
-DEMONDIE3PIC = 157
-RED_DEMON1PIC = 158
-RED_DEMON2PIC = 159
-RED_DEMON3PIC = 160
-RED_DEMON4PIC = 161
-RED_DEMONATTACK1PIC = 162
-RED_DEMONATTACK2PIC = 163
-RED_DEMONATTACK3PIC = 164
-RED_DEMONOUCHPIC = 165
-RED_DEMONDIE1PIC = 166
-RED_DEMONDIE2PIC = 167
-RED_DEMONDIE3PIC = 168
-MAGE1PIC = 169
-MAGE2PIC = 170
-MAGEOUCHPIC = 171
-MAGEATTACKPIC = 172
-MAGEDIE1PIC = 173
-MAGEDIE2PIC = 174
-BAT1PIC = 175
-BAT2PIC = 176
-BAT3PIC = 177
-BAT4PIC = 178
-BATDIE1PIC = 179
-BATDIE2PIC = 180
-GREL1PIC = 181
-GREL2PIC = 182
-GRELATTACKPIC = 183
-GRELHITPIC = 184
-GRELDIE1PIC = 185
-GRELDIE2PIC = 186
-GRELDIE3PIC = 187
-GRELDIE4PIC = 188
-GRELDIE5PIC = 189
-GRELDIE6PIC = 190
-SKULL_SHOTPIC = 191
-FIRSTWALLPIC = 192
-EXPWALL1PIC = 193
-EXPWALL2PIC = 194
-EXPWALL3PIC = 195
-W_WATER_EXP1PIC = 196
-W_WATER_EXP2PIC = 197
-W_WATER_EXP3PIC = 198
-W_NEMPICEWPIC = 199
-W_PENTAEWPIC = 200
-W_PENTANSPIC = 201
-W_ALTER_LFPIC = 202
-W_ALTER_RTPIC = 203
-W_SUB1EWPIC = 204
-W_SUB1NSPIC = 205
-W_SUB2EWPIC = 206
-W_SUB2NSPIC = 207
-W_SUB3EWPIC = 208
-W_SUB3NSPIC = 209
-WALL8LPIC = 210
-WALL8DPIC = 211
-WALL9LPIC = 212
-WALL9DPIC = 213
-WALL10LPIC = 214
-WALL10DPIC = 215
-WALL11LPIC = 216
-WALL11DPIC = 217
-WALL12LPIC = 218
-WALL12DPIC = 219
-WALL13LPIC = 220
-WALL13DPIC = 221
-WALL14LPIC = 222
-WALL14DPIC = 223
-WALL15LPIC = 224
-WALL15DPIC = 225
-WALL16LPIC = 226
-WALL16DPIC = 227
-WALL18LPIC = 228
-WALL18DPIC = 229
-WALL17LPIC = 230
-WALL17DPIC = 231
-WALL19LPIC = 232
-WALL19DPIC = 233
-WALL20LPIC = 234
-WALL20DPIC = 235
-WALL21LPIC = 236
-WALL21DPIC = 237
-WALL22LPIC = 238
-WALL22DPIC = 239
-WALL23LPIC = 240
-WALL23DPIC = 241
-WALL24LPIC = 242
-WALL24DPIC = 243
-WALL25LPIC = 244
-WALL25DPIC = 245
-WALL26LPIC = 246
-WALL26DPIC = 247
-WALL27LPIC = 248
-WALL27DPIC = 249
-WALL28LPIC = 250
-WALL28DPIC = 251
-WALL29LPIC = 252
-WALL29DPIC = 253
-WALL30LPIC = 254
-WALL30DPIC = 255
-WALL31LPIC = 256
-WALL31DPIC = 257
-W_WATER1EWPIC = 258
-W_WATER1NSPIC = 259
-W_WATER2EWPIC = 260
-W_WATER2NSPIC = 261
-W_FINALEXITPIC = 262
-W_DRAIN1EWPIC = 263
-W_DRAIN1NSPIC = 264
-W_DRAIN2EWPIC = 265
-W_DRAIN2NSPIC = 266
-W_WARP1EWPIC = 267
-W_WARP2EWPIC = 268
-W_WARP1NSPIC = 269
-W_WARP2NSPIC = 270
-W_WINDOWEWPIC = 271
-W_WINDOWNSPIC = 272
-W_WOOD_DOOREWPIC = 273
-W_WOOD_DOORNSPIC = 274
-W_WOODEN_DOORPIC = 275
-W_METAL_DOORPIC = 276
-W_GLOW_DOORPIC = 277
-W_TORCH1PIC = 278
-W_TORCH2PIC = 279
-W_LSUB_STONEPIC = 280
-W_DSUB_STONEPIC = 281
-W_BLOODY_LSUB_STONEPIC = 282
-W_BLOODY_DSUB_STONEPIC = 283
-W_BREATH_LWALL1PIC = 284
-W_BREATH_DWALL1PIC = 285
-W_BREATH_LWALL2PIC = 286
-W_BREATH_DWALL2PIC = 287
-W_WOOD_DOORWAYPIC = 288
-W_WOOD_DOORWAY_GLOWPIC = 289
-W_WATER_GATEEW1PIC = 290
-W_WATER_GATEEW2PIC = 291
-W_WATER_GATENS1PIC = 292
-W_WATER_GATENS2PIC = 293
-W_PRE_CHEATSPIC = 294
-W_CHEAT_GODPIC = 295
-W_CHEAT_WARPPIC = 296
-W_CHEAT_ITEMSPIC = 297
-W_CHEAT_FREEZEPIC = 298
-W_POST_CHEATPIC = 299
-W_SURFACE_PLAQPIC = 300
-W_BREATH_LWALL3PIC = 301
-W_BREATH_DWALL3PIC = 302
-W_BREATH_LWALL4PIC = 303
-W_BREATH_DWALL4PIC = 304
-MAGE_STATUEPIC = 305
-ZOMBIE_STATUEPIC = 306
-EYE_STATUEPIC = 307
-NEM_STATUEPIC = 308
-SKELETON_STATUEPIC = 309
-SPOOK_STATUEPIC = 310
-ORCH_STATUEPIC = 311
-LASTWALLPIC = 312
-
-HAND1PICM = 313
-
-NORTHICONSPR = 314
-
-LEVEL1TEXT = 605
-LEVEL2TEXT = 606
-LEVEL3TEXT = 607
-LEVEL4TEXT = 608
-LEVEL5TEXT = 609
-LEVEL6TEXT = 610
-LEVEL7TEXT = 611
-LEVEL8TEXT = 612
-LEVEL9TEXT = 613
-LEVEL10TEXT = 614
-LEVEL11TEXT = 615
-LEVEL12TEXT = 616
-LEVEL13TEXT = 617
-LEVEL14TEXT = 618
-LEVEL15TEXT = 619
-LEVEL16TEXT = 620
-LEVEL17TEXT = 621
-LEVEL18TEXT = 622
-LEVEL19TEXT = 623
-LEVEL20TEXT = 624
-PIRACY = 625
-
-SKELDUDE_LUMP_START = 30
-SKELDUDE_LUMP_END = 39
-
-SPOOK_LUMP_START = 40
-SPOOK_LUMP_END = 46
-
-TOMBSTONES_LUMP_START = 47
-TOMBSTONES_LUMP_END = 49
-
-WETMAN_LUMP_START = 50
-WETMAN_LUMP_END = 65
-
-OBJ_WARP_LUMP_START = 66
-OBJ_WARP_LUMP_END = 69
-
-EYE_LUMP_START = 70
-EYE_LUMP_END = 79
-
-ZOMBIE_LUMP_START = 80
-ZOMBIE_LUMP_END = 91
-
-ORC_LUMP_START = 92
-ORC_LUMP_END = 101
-
-TROLL_LUMP_START = 102
-TROLL_LUMP_END = 112
-
-BOLT_LUMP_START = 113
-BOLT_LUMP_END = 115
-
-NUKE_LUMP_START = 116
-NUKE_LUMP_END = 118
-
-PIT_LUMP_START = 119
-PIT_LUMP_END = 119
-
-TIME_LUMP_START = 120
-TIME_LUMP_END = 121
+FACE5PIC = 6
+FIRSTLATCHPIC = 7
+FACE1PIC = 8
+FACE2PIC = 9
+FACE3PIC = 10
+FACE4PIC = 11
+RADAR_TOPPIC = 12
+RADAR_BOTTOMPIC = 13
+RADAR_RGEMPIC = 14
+RADAR_GGEMPIC = 15
+RADAR_BGEMPIC = 16
+RADAR_YGEMPIC = 17
+RADAR_PGEMPIC = 18
+FIRSTGROUNDPIC = 19
+FIRSTSTRIPPIC = 20
+FIRSTSCALEPIC = 21
+SKELETON_1PIC = 22
+SKELETON_2PIC = 23
+SKELETON_3PIC = 24
+SKELETON_4PIC = 25
+SKELETON_ATTACK_1PIC = 26
+SKELETON_ATTACK_2PIC = 27
+SKELETON_ATTACK_3PIC = 28
+SKELETON_OUCHPIC = 29
+SKELETON_DEATH_1PIC = 30
+SKELETON_DEATH_2PIC = 31
+TOMB1PIC = 32
+TOMB2PIC = 33
+TOMB3PIC = 34
+OBJ_WARP1PIC = 35
+OBJ_WARP2PIC = 36
+OBJ_WARP3PIC = 37
+OBJ_WARP4PIC = 38
+EYE_WALK1PIC = 39
+EYE_WALK2PIC = 40
+EYE_WALK3PIC = 41
+EYE_OUCH1PIC = 42
+EYE_OUCH2PIC = 43
+EYE_DEATH1PIC = 44
+EYE_DEATH2PIC = 45
+EYE_DEATH3PIC = 46
+EYE_SCOWLPIC = 47
+EYE_SHOT1PIC = 48
+EYE_SHOT2PIC = 49
+ZOMB_APPEAR1PIC = 50
+ZOMB_APPEAR2PIC = 51
+ZOMB_APPEAR3PIC = 52
+ZOMB_APPEAR4PIC = 53
+ZOMB_WALK1PIC = 54
+ZOMB_WALK2PIC = 55
+ZOMB_WALK3PIC = 56
+ZOMB_OUCHPIC = 57
+ZOMB_ATTACKPIC = 58
+ZOMB_DIE1PIC = 59
+ZOMB_DIE2PIC = 60
+ZOMB_DIE3PIC = 61
+BOLTOBJPIC = 62
+BOLT2OBJPIC = 63
+BOLT3OBJPIC = 64
+NUKEOBJPIC = 65
+NUKE2OBJPIC = 66
+NUKE3OBJPIC = 67
+TIMEOBJ1PIC = 68
+TIMEOBJ2PIC = 69
+O_WATER_CHEST1PIC = 70
+O_WATER_CHEST2PIC = 71
+POTIONOBJPIC = 72
+RKEYOBJPIC = 73
+YKEYOBJPIC = 74
+GKEYOBJPIC = 75
+BKEYOBJPIC = 76
+RGEM1PIC = 77
+RGEM2PIC = 78
+GGEM1PIC = 79
+GGEM2PIC = 80
+BGEM1PIC = 81
+BGEM2PIC = 82
+YGEM1PIC = 83
+YGEM2PIC = 84
+PGEM1PIC = 85
+PGEM2PIC = 86
+CHESTOBJPIC = 87
+PSHOT1PIC = 88
+PSHOT2PIC = 89
+PSHOT_EXP1PIC = 90
+PSHOT_EXP2PIC = 91
+PSHOT_EXP3PIC = 92
+RED_DEMON1PIC = 93
+RED_DEMON2PIC = 94
+RED_DEMON3PIC = 95
+RED_DEMON4PIC = 96
+RED_DEMONATTACK1PIC = 97
+RED_DEMONATTACK2PIC = 98
+RED_DEMONATTACK3PIC = 99
+RED_DEMONOUCHPIC = 100
+RED_DEMONDIE1PIC = 101
+RED_DEMONDIE2PIC = 102
+RED_DEMONDIE3PIC = 103
+MAGE1PIC = 104
+MAGE2PIC = 105
+MAGEOUCHPIC = 106
+MAGEATTACKPIC = 107
+MAGEDIE1PIC = 108
+MAGEDIE2PIC = 109
+BAT1PIC = 110
+BAT2PIC = 111
+BAT3PIC = 112
+BAT4PIC = 113
+BATDIE1PIC = 114
+BATDIE2PIC = 115
+GREL1PIC = 116
+GREL2PIC = 117
+GRELATTACKPIC = 118
+GRELHITPIC = 119
+GRELDIE1PIC = 120
+GRELDIE2PIC = 121
+GRELDIE3PIC = 122
+GRELDIE4PIC = 123
+GRELDIE5PIC = 124
+GRELDIE6PIC = 125
+SKULL_SHOTPIC = 126
+GODESS_WALK1PIC = 127
+GODESS_WALK2PIC = 128
+GODESS_WALK3PIC = 129
+GODESS_ATTACK1PIC = 130
+GODESS_ATTACK2PIC = 131
+GODESS_ATTACK3PIC = 132
+GODESS_STATUEPIC = 133
+GODESS_OUCHPIC = 134
+GODESS_DEATH1PIC = 135
+GODESS_DEATH2PIC = 136
+ANT_EGG1PIC = 137
+ANT_EGG2PIC = 138
+ANT_WALK1PIC = 139
+ANT_WALK2PIC = 140
+ANT_WALK3PIC = 141
+ANT_ATTACKPIC = 142
+ANT_DEATH1PIC = 143
+ANT_DEATH2PIC = 144
+ANT_DEATH3PIC = 145
+FATDEMON_WALK1PIC = 146
+FATDEMON_WALK2PIC = 147
+FATDEMON_WALK3PIC = 148
+FATDEMON_WALK4PIC = 149
+FATDEMON_ATTACK1PIC = 150
+FATDEMON_ATTACK2PIC = 151
+FATDEMON_OUCHPIC = 152
+FATDEMON_BLOWUP1PIC = 153
+FATDEMON_BLOWUP2PIC = 154
+FATDEMON_BLOWUP3PIC = 155
+FATDEMON_EXPLODEPIC = 156
+FATDEMON_FEETPIC = 157
+SUCCUBUS_WALK1PIC = 158
+SUCCUBUS_WALK2PIC = 159
+SUCCUBUS_WALK3PIC = 160
+SUCCUBUS_WALK4PIC = 161
+SUCCUBUS_ATTACK1PIC = 162
+SUCCUBUS_ATTACK2PIC = 163
+SUCCUBUS_OUCHPIC = 164
+SUCCUBUS_DEATH1PIC = 165
+SUCCUBUS_DEATH2PIC = 166
+SUCCUBUS_SHOT1PIC = 167
+TREE_IDLEPIC = 168
+TREE_AWAKENINGPIC = 169
+TREE_WALK1PIC = 170
+TREE_WALK2PIC = 171
+TREE_ATTACK1PIC = 172
+TREE_ATTACK2PIC = 173
+TREE_ATTACK3PIC = 174
+TREE_DEATH1PIC = 175
+TREE_DEATH2PIC = 176
+TREE_DEATH3PIC = 177
+DRAGON_BUBBLES1PIC = 178
+DRAGON_BUBBLES2PIC = 179
+DRAGON_EYESPIC = 180
+DRAGON_RISE1PIC = 181
+DRAGON_RISE2PIC = 182
+DRAGON_WALK1PIC = 183
+DRAGON_WALK2PIC = 184
+DRAGON_WALK3PIC = 185
+DRAGON_WALK4PIC = 186
+DRAGON_ATTACK1PIC = 187
+DRAGON_ATTACK2PIC = 188
+DRAGON_ATTACK3PIC = 189
+DRAGON_OUCHPIC = 190
+DRAGON_DEATH1PIC = 191
+DRAGON_DEATH2PIC = 192
+DRAGON_DEATH3PIC = 193
+BUNNY_LEFT1PIC = 194
+BUNNY_LEFT2PIC = 195
+BUNNY_RIGHT1PIC = 196
+BUNNY_RIGHT2PIC = 197
+BUNNY_META1PIC = 198
+BUNNY_META2PIC = 199
+BUNNY_WALK1PIC = 200
+BUNNY_WALK2PIC = 201
+BUNNY_OUCHPIC = 202
+BUNNY_DEATH1PIC = 203
+BUNNY_DEATH2PIC = 204
+ARCH1PIC = 205
+ARCH2PIC = 206
+ARCH3PIC = 207
+ARCH4PIC = 208
+ARCH5PIC = 209
+ARCH6PIC = 210
+ARCH7PIC = 211
+ARCH8PIC = 212
+ARCH9PIC = 213
+ARCH10PIC = 214
+ARCH11PIC = 215
+ARCH12PIC = 216
+ARCH13PIC = 217
+ANT_HILLPIC = 218
+COLUMNPIC = 219
+SULPHUR_GAS_1PIC = 220
+SULPHUR_GAS_2PIC = 221
+SULPHUR_GAS_3PIC = 222
+FIRE_POT_1PIC = 223
+FIRE_POT_2PIC = 224
+SKEL_HANGPIC = 225
+FORCE_FIELD_1PIC = 226
+FORCE_FIELD_2PIC = 227
+FORCE_FIELD_3PIC = 228
+FORCE_FIELD_4PIC = 229
+WFOUNTAINPIC = 230
+FIRSTWALLPIC = 231
+CRYSTAL_LIGHT_1PIC = 232
+CRYSTAL_LIGHT_2PIC = 233
+CRYSTAL_LIGHT_3PIC = 234
+CRYSTAL_LIGHT_4PIC = 235
+CRYSTAL_DARK_1PIC = 236
+CRYSTAL_DARK_2PIC = 237
+CRYSTAL_DARK_3PIC = 238
+CRYSTAL_DARK_4PIC = 239
+FIRE_WALL_1PIC = 240
+FIRE_WALL_2PIC = 241
+FIRE_WALL_3PIC = 242
+FIRE_WALL_4PIC = 243
+BRN_STONE_GATEPIC = 244
+BRN_STONE_WALL_1PIC = 245
+BRN_STONE_WALL_2PIC = 246
+KUDZU_LIGHT_WALLPIC = 247
+KUDZU_DARK_WALLPIC = 248
+HEDGE_WALLPIC = 249
+HEDGE_EYESPIC = 250
+BRN_WINDOW_LIGHTPIC = 251
+ALTAR_LEFTPIC = 252
+ALTAR_RIGHTPIC = 253
+GRAY_LIGHT_WALLPIC = 254
+GRAY_DARK_WALLPIC = 255
+GRAY_LIGHT_SIGNPIC = 256
+GRAY_DARK_SIGNPIC = 257
+MANICLE_LIGHT_BLOODYPIC = 258
+MANICLE_DARK_BLOODYPIC = 259
+LIGHT_CURTAIN_WINDOWPIC = 260
+LIGHT_CURTAIN_WALLPIC = 261
+DARK_CURTAIN_WINDOWPIC = 262
+DARK_CURTAIN_WALLPIC = 263
+BRN_LIGHT_SIGNPIC = 264
+BRN_DARK_SIGNPIC = 265
+LIGHT_STONE_WALLPIC = 266
+DARK_STONE_WALLPIC = 267
+BRN_FLAGSTONE_LIGHT_2PIC = 268
+BRN_FLAGSTONE_DARK_2PIC = 269
+RUST_METAL_LIGHTPIC = 270
+RUST_METAL_DARKPIC = 271
+GRAY_METAL_LIGHTPIC = 272
+GRAY_METAL_DARKPIC = 273
+WEAK_STONE_LIGHTPIC = 274
+WEAK_STONE_DARKPIC = 275
+WEAK_GRAY_RFGSTN_LIGHTPIC = 276
+WEAK_GRAY_RFGSTN_DARKPIC = 277
+WEAK_CRYSTAL_LIGHTPIC = 278
+WEAK_CRYSTAL_DARKPIC = 279
+RED_MUD_LIGHTPIC = 280
+BRN_MUD_DARKPIC = 281
+RED_MUD_WEAK_LIGHTPIC = 282
+BRN_MUD_WEAK_DARKPIC = 283
+HORN_DOORPIC = 284
+CLOSED_DOOR_1PIC = 285
+DOOR_2PIC = 286
+WATER_LIGHT_WEAK_1PIC = 287
+WATER_LIGHT_WEAK_2PIC = 288
+WATER_LIGHT_WEAK_3PIC = 289
+WATER_DARK_WEAK_1PIC = 290
+WATER_DARK_WEAK_2PIC = 291
+WATER_DARK_WEAK_3PIC = 292
+WATER_LIGHT_1PIC = 293
+WATER_LIGHT_2PIC = 294
+WATER_LIGHT_3PIC = 295
+WATER_DARK_1PIC = 296
+WATER_DARK_2PIC = 297
+WATER_DARK_3PIC = 298
+TROLL_LIGHT_STONEPIC = 299
+TROLL_DARK_STONEPIC = 300
+TROLL_BLOODY_LT_STONEPIC = 301
+TROLL_BLOODY_DK_STONEPIC = 302
+LIGHT_BREATH_1PIC = 303
+LIGHT_BREATH_2PIC = 304
+LIGHT_BREATH_3PIC = 305
+DARK_BREATH_1PIC = 306
+DARK_BREATH_2PIC = 307
+DARK_BREATH_3PIC = 308
+EXP_WALL_1PIC = 309
+EXP_WALL_2PIC = 310
+EXP_WALL_3PIC = 311
+WATER_EXP_WALL_1PIC = 312
+WATER_EXP_WALL_2PIC = 313
+WATER_EXP_WALL_3PIC = 314
+W_GEN_DOOR1PIC = 315
+W_GEN_DOOR2PIC = 316
+W_CRYSTAL_DOORPIC = 317
+DMG_BRN_FSTN_LTPIC = 318
+DMG_BRN_FSTN_DKPIC = 319
+DMG_FIN_FSTN_LTPIC = 320
+DMG_FIN_FSTN_DKPIC = 321
+STEEL_DOOR1PIC = 322
+STEEL_DOOR2PIC = 323
+BRN_WINDOW_DARKPIC = 324
+GRY_DOOR_LTPIC = 325
+GRY_DOOR_DKPIC = 326
+BRN_DOOR_LTPIC = 327
+BRN_DOOR_DKPIC = 328
+GRY_FGSTN_LTPIC = 329
+GRY_FGSTN_DKPIC = 330
+KUDZU_WEAK_LIGHTPIC = 331
+KUDZU_WEAK_DARKPIC = 332
+LT_SKEL1PIC = 333
+DK_SKEL1PIC = 334
+LT_SKEL2PIC = 335
+DK_SKEL2PIC = 336
+MANICLE_LIGHT_WALLPIC = 337
+MANICLE_DARK_WALLPIC = 338
+TAP_1PIC = 339
+TAP_2PIC = 340
+TAP_3PIC = 341
+TAP_4PIC = 342
+TAP_5PIC = 343
+FINALWALLPIC = 344
+WATER_DOOR1_PIC = 345
+WATER_DOOR2_PIC = 346
+LASTWALLPIC = 347
+
+HAND1PICM = 348
+
+NORTHICONSPR = 349
+
+LEVEL1TEXT = 640
+LEVEL2TEXT = 641
+LEVEL3TEXT = 642
+LEVEL4TEXT = 643
+LEVEL5TEXT = 644
+LEVEL6TEXT = 645
+LEVEL7TEXT = 646
+LEVEL8TEXT = 647
+LEVEL9TEXT = 648
+LEVEL10TEXT = 649
+LEVEL11TEXT = 650
+LEVEL12TEXT = 651
+LEVEL13TEXT = 652
+LEVEL14TEXT = 653
+LEVEL15TEXT = 654
+LEVEL16TEXT = 655
+LEVEL17TEXT = 656
+PIRACY = 657
+
+SKELDUDE_LUMP_START = 22
+SKELDUDE_LUMP_END = 31
+
+TOMBSTONES_LUMP_START = 32
+TOMBSTONES_LUMP_END = 34
+
+OBJ_WARP_LUMP_START = 35
+OBJ_WARP_LUMP_END = 38
+
+EYE_LUMP_START = 39
+EYE_LUMP_END = 49
+
+ZOMBIE_LUMP_START = 50
+ZOMBIE_LUMP_END = 61
+
+BOLT_LUMP_START = 62
+BOLT_LUMP_END = 64
+
+NUKE_LUMP_START = 65
+NUKE_LUMP_END = 67
+
+TIME_LUMP_START = 68
+TIME_LUMP_END = 69
+
+O_WATER_CHEST_LUMP_START = 70
+O_WATER_CHEST_LUMP_END = 71
+
+POTION_LUMP_START = 72
+POTION_LUMP_END = 72
+
+RKEY_LUMP_START = 73
+RKEY_LUMP_END = 73
+
+YKEY_LUMP_START = 74
+YKEY_LUMP_END = 74
+
+GKEY_LUMP_START = 75
+GKEY_LUMP_END = 75
-O_WATER_CHEST_LUMP_START = 122
-O_WATER_CHEST_LUMP_END = 123
+BKEY_LUMP_START = 76
+BKEY_LUMP_END = 76
-POTION_LUMP_START = 124
-POTION_LUMP_END = 124
+RGEM_LUMP_START = 77
+RGEM_LUMP_END = 78
-RKEY_LUMP_START = 125
-RKEY_LUMP_END = 125
+GGEM_LUMP_START = 79
+GGEM_LUMP_END = 80
-YKEY_LUMP_START = 126
-YKEY_LUMP_END = 126
+BGEM_LUMP_START = 81
+BGEM_LUMP_END = 82
-GKEY_LUMP_START = 127
-GKEY_LUMP_END = 127
+YGEM_LUMP_START = 83
+YGEM_LUMP_END = 84
-BKEY_LUMP_START = 128
-BKEY_LUMP_END = 128
+PGEM_LUMP_START = 85
+PGEM_LUMP_END = 86
-RGEM_LUMP_START = 129
-RGEM_LUMP_END = 130
+CHEST_LUMP_START = 87
+CHEST_LUMP_END = 87
-GGEM_LUMP_START = 131
-GGEM_LUMP_END = 132
+PLAYER_LUMP_START = 88
+PLAYER_LUMP_END = 92
-BGEM_LUMP_START = 133
-BGEM_LUMP_END = 134
+REDDEMON_LUMP_START = 93
+REDDEMON_LUMP_END = 103
-YGEM_LUMP_START = 135
-YGEM_LUMP_END = 136
+MAGE_LUMP_START = 104
+MAGE_LUMP_END = 109
-PGEM_LUMP_START = 137
-PGEM_LUMP_END = 138
+BAT_LUMP_START = 110
+BAT_LUMP_END = 115
-SCROLL_LUMP_START = 139
-SCROLL_LUMP_END = 139
+GREL_LUMP_START = 116
+GREL_LUMP_END = 126
-CHEST_LUMP_START = 140
-CHEST_LUMP_END = 140
+GODESS_LUMP_START = 127
+GODESS_LUMP_END = 136
-RKEY2_LUMP_START = 141
-RKEY2_LUMP_END = 141
+ANT_LUMP_START = 137
+ANT_LUMP_END = 145
-PLAYER_LUMP_START = 142
-PLAYER_LUMP_END = 146
+FATDEMON_LUMP_START = 146
+FATDEMON_LUMP_END = 157
-DEMON_LUMP_START = 147
-DEMON_LUMP_END = 157
+SUCCUBUS_LUMP_START = 158
+SUCCUBUS_LUMP_END = 167
-REDDEMON_LUMP_START = 158
-REDDEMON_LUMP_END = 168
+TREE_LUMP_START = 168
+TREE_LUMP_END = 177
-MAGE_LUMP_START = 169
-MAGE_LUMP_END = 174
+DRAGON_LUMP_START = 178
+DRAGON_LUMP_END = 193
-BAT_LUMP_START = 175
-BAT_LUMP_END = 180
+BUNNY_LUMP_START = 194
+BUNNY_LUMP_END = 204
-GREL_LUMP_START = 181
-GREL_LUMP_END = 191
+ARCH1_LUMP_START = 205
+ARCH1_LUMP_END = 205
-EXPWALL_LUMP_START = 193
-EXPWALL_LUMP_END = 195
+ARCH2_LUMP_START = 206
+ARCH2_LUMP_END = 206
-W_WATER_EXP_LUMP_START = 196
-W_WATER_EXP_LUMP_END = 198
+ARCH3_LUMP_START = 207
+ARCH3_LUMP_END = 207
-WALL2_LUMP_START = 199
-WALL2_LUMP_END = 199
+ARCH4_LUMP_START = 208
+ARCH4_LUMP_END = 208
-WALL3_LUMP_START = 200
-WALL3_LUMP_END = 201
+ARCH5_LUMP_START = 209
+ARCH5_LUMP_END = 209
-WALL4_LUMP_START = 202
-WALL4_LUMP_END = 202
+ARCH6_LUMP_START = 210
+ARCH6_LUMP_END = 210
-WALL5_LUMP_START = 203
-WALL5_LUMP_END = 203
+ARCH7_LUMP_START = 211
+ARCH7_LUMP_END = 211
-WALL6_LUMP_START = 204
-WALL6_LUMP_END = 205
+ARCH8_LUMP_START = 212
+ARCH8_LUMP_END = 212
-WALL7_LUMP_START = 206
-WALL7_LUMP_END = 207
+ARCH9_LUMP_START = 213
+ARCH9_LUMP_END = 213
-WALL6_2_LUMP_START = 208
-WALL6_2_LUMP_END = 209
+ARCH10_LUMP_START = 214
+ARCH10_LUMP_END = 214
-WALL8_LUMP_START = 210
-WALL8_LUMP_END = 211
+ARCH11_LUMP_START = 215
+ARCH11_LUMP_END = 215
-WALL9_LUMP_START = 212
-WALL9_LUMP_END = 213
+ARCH12_LUMP_START = 216
+ARCH12_LUMP_END = 216
-WALL10_LUMP_START = 214
-WALL10_LUMP_END = 215
+ARCH13_LUMP_START = 217
+ARCH13_LUMP_END = 217
-WALL11_LUMP_START = 216
-WALL11_LUMP_END = 217
+ANTHILL_LUMP_START = 218
+ANTHILL_LUMP_END = 218
-WALL12_LUMP_START = 218
-WALL12_LUMP_END = 219
+COLUMN_LUMP_START = 219
+COLUMN_LUMP_END = 219
-WALL13_LUMP_START = 220
-WALL13_LUMP_END = 221
+SULPHURGAS_LUMP_START = 220
+SULPHURGAS_LUMP_END = 222
-WALL14_LUMP_START = 222
-WALL14_LUMP_END = 223
+FIREPOT_LUMP_START = 223
+FIREPOT_LUMP_END = 224
-WALL15_LUMP_START = 224
-WALL15_LUMP_END = 225
+SKELHANG_LUMP_START = 225
+SKELHANG_LUMP_END = 225
-WALL16_LUMP_START = 226
-WALL16_LUMP_END = 227
+FORCEFIELD_LUMP_START = 226
+FORCEFIELD_LUMP_END = 229
-WALL18_LUMP_START = 228
-WALL18_LUMP_END = 229
-
-WALL17_LUMP_START = 230
-WALL17_LUMP_END = 231
-
-WALL19_LUMP_START = 232
-WALL19_LUMP_END = 233
-
-WALL20_LUMP_START = 234
-WALL20_LUMP_END = 235
-
-WALL21_LUMP_START = 236
-WALL21_LUMP_END = 237
-
-WALL22_LUMP_START = 238
-WALL22_LUMP_END = 239
-
-WALL23_LUMP_START = 240
-WALL23_LUMP_END = 241
-
-WALL24_LUMP_START = 242
-WALL24_LUMP_END = 243
-
-WALL25_LUMP_START = 244
-WALL25_LUMP_END = 245
-
-WALL26_LUMP_START = 246
-WALL26_LUMP_END = 247
-
-WALL27_LUMP_START = 248
-WALL27_LUMP_END = 249
-
-WALL28_LUMP_START = 250
-WALL28_LUMP_END = 251
-
-WALL29_LUMP_START = 252
-WALL29_LUMP_END = 253
-
-WALL30_LUMP_START = 254
-WALL30_LUMP_END = 255
-
-WALL31_LUMP_START = 256
-WALL31_LUMP_END = 257
-
-WALL32_LUMP_START = 258
-WALL32_LUMP_END = 259
-
-WALL33_LUMP_START = 260
-WALL33_LUMP_END = 261
-
-WALL34_LUMP_START = 262
-WALL34_LUMP_END = 262
-
-WALL36_LUMP_START = 263
-WALL36_LUMP_END = 266
-
-W_WARP_LUMP_START = 267
-W_WARP_LUMP_END = 270
-
-W_TORCH_LUMP_START = 278
-W_TORCH_LUMP_END = 279
-
-SUB_STONE_LUMP_START = 280
-SUB_STONE_LUMP_END = 281
-
-BLOODY_SUB_STONE_LUMP_START = 282
-BLOODY_SUB_STONE_LUMP_END = 283
-
-W_BREATH_LUMP_START = 284
-W_BREATH_LUMP_END = 287
-
-W_WOOD_DOORWAY_LUMP_START = 288
-W_WOOD_DOORWAY_LUMP_END = 288
-
-W_WOOD_DOORWAY_GLOW_LUMP_START = 289
-W_WOOD_DOORWAY_GLOW_LUMP_END = 289
-
-W_WATER_GATES_LUMP_START = 290
-W_WATER_GATES_LUMP_END = 293
-
-W_PRE_CHEATS_LUMP_START = 294
-W_PRE_CHEATS_LUMP_END = 294
-
-W_CHEAT_GOD_LUMP_START = 295
-W_CHEAT_GOD_LUMP_END = 295
-
-W_CHEAT_WARP_LUMP_START = 296
-W_CHEAT_WARP_LUMP_END = 296
-
-W_CHEAT_ITEMS_LUMP_START = 297
-W_CHEAT_ITEMS_LUMP_END = 297
-
-W_CHEAT_FREEZE_LUMP_START = 298
-W_CHEAT_FREEZE_LUMP_END = 298
-
-W_POST_CHEAT_LUMP_START = 299
-W_POST_CHEAT_LUMP_END = 299
-
-W_SURFACE_PLAQ_LUMP_START = 300
-W_SURFACE_PLAQ_LUMP_END = 300
-
-W_BREATH2_LUMP_START = 301
-W_BREATH2_LUMP_END = 304
-
-W_MAGE_STATUE_LUMP_START = 305
-W_MAGE_STATUE_LUMP_END = 305
-
-W_ZOMBIE_STATUE_LUMP_START = 306
-W_ZOMBIE_STATUE_LUMP_END = 306
-
-W_EYE_STATUE_LUMP_START = 307
-W_EYE_STATUE_LUMP_END = 307
-
-W_NEM_STATUE_LUMP_START = 308
-W_NEM_STATUE_LUMP_END = 308
-
-W_SKELETION_STATUE_LUMP_START = 309
-W_SKELETION_STATUE_LUMP_END = 309
-
-W_SPOOK_STATUE_LUMP_START = 310
-W_SPOOK_STATUE_LUMP_END = 310
-
-W_ORCH_STATUE_LUMP_START = 311
-W_ORCH_STATUE_LUMP_END = 311
+FOUNTAIN_LUMP_START = 230
+FOUNTAIN_LUMP_END = 230
;
; Amount of each data item
;
-NUMCHUNKS = 626
+NUMCHUNKS = 658
NUMFONT = 1
NUMFONTM = 0
-NUMPICS = 309
+NUMPICS = 344
NUMPICM = 1
NUMSPRITES = 1
NUMTILE8 = 108
@@ -636,7 +545,7 @@ NUMTILE16 = 216
NUMTILE16M = 72
NUMTILE32 = 0
NUMTILE32M = 0
-NUMEXTERN = 21
+NUMEXTERN = 18
;
; File offsets for data items
;
@@ -647,15 +556,15 @@ STRUCTSPRITE = 2
STARTFONT = 3
STARTFONTM = 4
STARTPICS = 4
-STARTPICM = 313
-STARTSPRITES = 314
-STARTTILE8 = 315
-STARTTILE8M = 316
-STARTTILE16 = 317
-STARTTILE16M = 533
-STARTTILE32 = 605
-STARTTILE32M = 605
-STARTEXTERN = 605
+STARTPICM = 348
+STARTSPRITES = 349
+STARTTILE8 = 350
+STARTTILE8M = 351
+STARTTILE16 = 352
+STARTTILE16M = 568
+STARTTILE32 = 640
+STARTTILE32M = 640
+STARTEXTERN = 640
;
; Thank you for using IGRAB!
diff --git a/GFXE_ARM.H b/GFXE_ARM.H
index 2c6eed3..cbeb40a 100644
--- a/GFXE_ARM.H
+++ b/GFXE_ARM.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -18,733 +18,601 @@
//////////////////////////////////////
//
-// Graphics .H file for .ABS
-// IGRAB-ed on Thu Dec 02 11:58:32 1993
+// Graphics .H file for .ARM
+// IGRAB-ed on Thu Dec 02 13:58:59 1993
//
//////////////////////////////////////
typedef enum {
FINALEPIC=4,
STATUSPIC, // 5
- SCROLLTOPPIC, // 6
- SCROLLBOTTOMPIC, // 7
- SCROLL1PIC, // 8
- SCROLL2PIC, // 9
- SCROLL3PIC, // 10
- SCROLL4PIC, // 11
- SCROLL5PIC, // 12
- SCROLL6PIC, // 13
- SCROLL7PIC, // 14
- SCROLL8PIC, // 15
- FACE5PIC, // 16
- FIRSTLATCHPIC, // 17
- FACE1PIC, // 18
- FACE2PIC, // 19
- FACE3PIC, // 20
- FACE4PIC, // 21
- RADAR_TOPPIC, // 22
- RADAR_BOTTOMPIC, // 23
- RADAR_RGEMPIC, // 24
- RADAR_GGEMPIC, // 25
- RADAR_BGEMPIC, // 26
- RADAR_YGEMPIC, // 27
- RADAR_PGEMPIC, // 28
- FIRSTSCALEPIC, // 29
- // Lump Start
- SKELETON_1PIC, // 30
- SKELETON_2PIC, // 31
- SKELETON_3PIC, // 32
- SKELETON_4PIC, // 33
- SKELETON_ATTACK_1PIC, // 34
- SKELETON_ATTACK_2PIC, // 35
- SKELETON_ATTACK_3PIC, // 36
- SKELETON_OUCHPIC, // 37
- SKELETON_DEATH_1PIC, // 38
- SKELETON_DEATH_2PIC, // 39
- // Lump Start
- SPOOK1PIC, // 40
- SPOOK2PIC, // 41
- SPOOK3PIC, // 42
- SPOOK4PIC, // 43
- SPOOK_ATTACKPIC, // 44
- SPOOKHITPIC, // 45
- SPOOK_INOUTPIC, // 46
- // Lump Start
- TOMB1PIC, // 47
- TOMB2PIC, // 48
- TOMB3PIC, // 49
- // Lump Start
- WET_BUBBLE1PIC, // 50
- WET_BUBBLE2PIC, // 51
- WET_EYESPIC, // 52
- WET_RISE1PIC, // 53
- WET_RISE2PIC, // 54
- WET_WALK1PIC, // 55
- WET_WALK2PIC, // 56
- WET_WALK3PIC, // 57
- WET_WALK4PIC, // 58
- WET_ATTACK1PIC, // 59
- WET_ATTACK2PIC, // 60
- WET_ATTACK3PIC, // 61
- WET_OUCHPIC, // 62
- WET_DIE1PIC, // 63
- WET_DIE2PIC, // 64
- WET_DIE3PIC, // 65
- // Lump Start
- OBJ_WARP1PIC, // 66
- OBJ_WARP2PIC, // 67
- OBJ_WARP3PIC, // 68
- OBJ_WARP4PIC, // 69
- // Lump Start
- EYE_WALK1PIC, // 70
- EYE_WALK2PIC, // 71
- EYE_WALK3PIC, // 72
- EYE_OUCH1PIC, // 73
- EYE_OUCH2PIC, // 74
- EYE_DEATH1PIC, // 75
- EYE_DEATH2PIC, // 76
- EYE_DEATH3PIC, // 77
- EYE_SHOT1PIC, // 78
- EYE_SHOT2PIC, // 79
- // Lump Start
- ZOMB_APPEAR1PIC, // 80
- ZOMB_APPEAR2PIC, // 81
- ZOMB_APPEAR3PIC, // 82
- ZOMB_APPEAR4PIC, // 83
- ZOMB_WALK1PIC, // 84
- ZOMB_WALK2PIC, // 85
- ZOMB_WALK3PIC, // 86
- ZOMB_OUCHPIC, // 87
- ZOMB_ATTACKPIC, // 88
- ZOMB_DIE1PIC, // 89
- ZOMB_DIE2PIC, // 90
- ZOMB_DIE3PIC, // 91
- // Lump Start
- ORC1PIC, // 92
- ORC2PIC, // 93
- ORC3PIC, // 94
- ORC4PIC, // 95
- ORCATTACK1PIC, // 96
- ORCATTACK2PIC, // 97
- ORCOUCHPIC, // 98
- ORCDIE1PIC, // 99
- ORCDIE2PIC, // 100
- ORCDIE3PIC, // 101
- // Lump Start
- TROLL1PIC, // 102
- TROLL2PIC, // 103
- TROLL3PIC, // 104
- TROLL4PIC, // 105
- TROLLOUCHPIC, // 106
- TROLLATTACK1PIC, // 107
- TROLLATTACK2PIC, // 108
- TROLLATTACK3PIC, // 109
- TROLLDIE1PIC, // 110
- TROLLDIE2PIC, // 111
- TROLLDIE3PIC, // 112
- // Lump Start
- BOLTOBJPIC, // 113
- BOLT2OBJPIC, // 114
- BOLT3OBJPIC, // 115
- // Lump Start
- NUKEOBJPIC, // 116
- NUKE2OBJPIC, // 117
- NUKE3OBJPIC, // 118
- // Lump Start
- PITOBJPIC, // 119
- // Lump Start
- TIMEOBJ1PIC, // 120
- TIMEOBJ2PIC, // 121
- // Lump Start
- O_WATER_CHEST1PIC, // 122
- O_WATER_CHEST2PIC, // 123
- // Lump Start
- POTIONOBJPIC, // 124
- // Lump Start
- RKEYOBJPIC, // 125
- // Lump Start
- YKEYOBJPIC, // 126
- // Lump Start
- GKEYOBJPIC, // 127
- // Lump Start
- BKEYOBJPIC, // 128
- // Lump Start
- RGEM1PIC, // 129
- RGEM2PIC, // 130
- // Lump Start
- GGEM1PIC, // 131
- GGEM2PIC, // 132
- // Lump Start
- BGEM1PIC, // 133
- BGEM2PIC, // 134
- // Lump Start
- YGEM1PIC, // 135
- YGEM2PIC, // 136
- // Lump Start
- PGEM1PIC, // 137
- PGEM2PIC, // 138
- // Lump Start
- SCROLLOBJPIC, // 139
- // Lump Start
- CHESTOBJPIC, // 140
- // Lump Start
- RKEY2PIC, // 141
- // Lump Start
- PSHOT1PIC, // 142
- PSHOT2PIC, // 143
- PSHOT_EXP1PIC, // 144
- PSHOT_EXP2PIC, // 145
- PSHOT_EXP3PIC, // 146
- // Lump Start
- DEMON1PIC, // 147
- DEMON2PIC, // 148
- DEMON3PIC, // 149
- DEMON4PIC, // 150
- DEMONATTACK1PIC, // 151
- DEMONATTACK2PIC, // 152
- DEMONATTACK3PIC, // 153
- DEMONOUCHPIC, // 154
- DEMONDIE1PIC, // 155
- DEMONDIE2PIC, // 156
- DEMONDIE3PIC, // 157
- // Lump Start
- RED_DEMON1PIC, // 158
- RED_DEMON2PIC, // 159
- RED_DEMON3PIC, // 160
- RED_DEMON4PIC, // 161
- RED_DEMONATTACK1PIC, // 162
- RED_DEMONATTACK2PIC, // 163
- RED_DEMONATTACK3PIC, // 164
- RED_DEMONOUCHPIC, // 165
- RED_DEMONDIE1PIC, // 166
- RED_DEMONDIE2PIC, // 167
- RED_DEMONDIE3PIC, // 168
- // Lump Start
- MAGE1PIC, // 169
- MAGE2PIC, // 170
- MAGEOUCHPIC, // 171
- MAGEATTACKPIC, // 172
- MAGEDIE1PIC, // 173
- MAGEDIE2PIC, // 174
- // Lump Start
- BAT1PIC, // 175
- BAT2PIC, // 176
- BAT3PIC, // 177
- BAT4PIC, // 178
- BATDIE1PIC, // 179
- BATDIE2PIC, // 180
- // Lump Start
- GREL1PIC, // 181
- GREL2PIC, // 182
- GRELATTACKPIC, // 183
- GRELHITPIC, // 184
- GRELDIE1PIC, // 185
- GRELDIE2PIC, // 186
- GRELDIE3PIC, // 187
- GRELDIE4PIC, // 188
- GRELDIE5PIC, // 189
- GRELDIE6PIC, // 190
- SKULL_SHOTPIC, // 191
- FIRSTWALLPIC, // 192
- // Lump Start
- EXPWALL1PIC, // 193
- EXPWALL2PIC, // 194
- EXPWALL3PIC, // 195
- // Lump Start
- W_WATER_EXP1PIC, // 196
- W_WATER_EXP2PIC, // 197
- W_WATER_EXP3PIC, // 198
- // Lump Start
- W_NEMPICEWPIC, // 199
- // Lump Start
- W_PENTAEWPIC, // 200
- W_PENTANSPIC, // 201
- // Lump Start
- W_ALTER_LFPIC, // 202
- // Lump Start
- W_ALTER_RTPIC, // 203
- // Lump Start
- W_SUB1EWPIC, // 204
- W_SUB1NSPIC, // 205
- // Lump Start
- W_SUB2EWPIC, // 206
- W_SUB2NSPIC, // 207
- // Lump Start
- W_SUB3EWPIC, // 208
- W_SUB3NSPIC, // 209
- // Lump Start
- WALL8LPIC, // 210
- WALL8DPIC, // 211
- // Lump Start
- WALL9LPIC, // 212
- WALL9DPIC, // 213
- // Lump Start
- WALL10LPIC, // 214
- WALL10DPIC, // 215
- // Lump Start
- WALL11LPIC, // 216
- WALL11DPIC, // 217
- // Lump Start
- WALL12LPIC, // 218
- WALL12DPIC, // 219
- // Lump Start
- WALL13LPIC, // 220
- WALL13DPIC, // 221
- // Lump Start
- WALL14LPIC, // 222
- WALL14DPIC, // 223
- // Lump Start
- WALL15LPIC, // 224
- WALL15DPIC, // 225
- // Lump Start
- WALL16LPIC, // 226
- WALL16DPIC, // 227
- // Lump Start
- WALL18LPIC, // 228
- WALL18DPIC, // 229
- // Lump Start
- WALL17LPIC, // 230
- WALL17DPIC, // 231
- // Lump Start
- WALL19LPIC, // 232
- WALL19DPIC, // 233
- // Lump Start
- WALL20LPIC, // 234
- WALL20DPIC, // 235
- // Lump Start
- WALL21LPIC, // 236
- WALL21DPIC, // 237
- // Lump Start
- WALL22LPIC, // 238
- WALL22DPIC, // 239
- // Lump Start
- WALL23LPIC, // 240
- WALL23DPIC, // 241
- // Lump Start
- WALL24LPIC, // 242
- WALL24DPIC, // 243
- // Lump Start
- WALL25LPIC, // 244
- WALL25DPIC, // 245
- // Lump Start
- WALL26LPIC, // 246
- WALL26DPIC, // 247
- // Lump Start
- WALL27LPIC, // 248
- WALL27DPIC, // 249
- // Lump Start
- WALL28LPIC, // 250
- WALL28DPIC, // 251
- // Lump Start
- WALL29LPIC, // 252
- WALL29DPIC, // 253
- // Lump Start
- WALL30LPIC, // 254
- WALL30DPIC, // 255
- // Lump Start
- WALL31LPIC, // 256
- WALL31DPIC, // 257
- // Lump Start
- W_WATER1EWPIC, // 258
- W_WATER1NSPIC, // 259
- // Lump Start
- W_WATER2EWPIC, // 260
- W_WATER2NSPIC, // 261
- // Lump Start
- W_FINALEXITPIC, // 262
- // Lump Start
- W_DRAIN1EWPIC, // 263
- W_DRAIN1NSPIC, // 264
- W_DRAIN2EWPIC, // 265
- W_DRAIN2NSPIC, // 266
- // Lump Start
- W_WARP1EWPIC, // 267
- W_WARP2EWPIC, // 268
- W_WARP1NSPIC, // 269
- W_WARP2NSPIC, // 270
- W_WINDOWEWPIC, // 271
- W_WINDOWNSPIC, // 272
- W_WOOD_DOOREWPIC, // 273
- W_WOOD_DOORNSPIC, // 274
- W_WOODEN_DOORPIC, // 275
- W_METAL_DOORPIC, // 276
- W_GLOW_DOORPIC, // 277
- // Lump Start
- W_TORCH1PIC, // 278
- W_TORCH2PIC, // 279
- // Lump Start
- W_LSUB_STONEPIC, // 280
- W_DSUB_STONEPIC, // 281
- // Lump Start
- W_BLOODY_LSUB_STONEPIC, // 282
- W_BLOODY_DSUB_STONEPIC, // 283
- // Lump Start
- W_BREATH_LWALL1PIC, // 284
- W_BREATH_DWALL1PIC, // 285
- W_BREATH_LWALL2PIC, // 286
- W_BREATH_DWALL2PIC, // 287
- // Lump Start
- W_WOOD_DOORWAYPIC, // 288
- // Lump Start
- W_WOOD_DOORWAY_GLOWPIC, // 289
- // Lump Start
- W_WATER_GATEEW1PIC, // 290
- W_WATER_GATEEW2PIC, // 291
- W_WATER_GATENS1PIC, // 292
- W_WATER_GATENS2PIC, // 293
- // Lump Start
- W_PRE_CHEATSPIC, // 294
- // Lump Start
- W_CHEAT_GODPIC, // 295
- // Lump Start
- W_CHEAT_WARPPIC, // 296
- // Lump Start
- W_CHEAT_ITEMSPIC, // 297
- // Lump Start
- W_CHEAT_FREEZEPIC, // 298
- // Lump Start
- W_POST_CHEATPIC, // 299
- // Lump Start
- W_SURFACE_PLAQPIC, // 300
- // Lump Start
- W_BREATH_LWALL3PIC, // 301
- W_BREATH_DWALL3PIC, // 302
- W_BREATH_LWALL4PIC, // 303
- W_BREATH_DWALL4PIC, // 304
- // Lump Start
- MAGE_STATUEPIC, // 305
- // Lump Start
- ZOMBIE_STATUEPIC, // 306
- // Lump Start
- EYE_STATUEPIC, // 307
- // Lump Start
- NEM_STATUEPIC, // 308
- // Lump Start
- SKELETON_STATUEPIC, // 309
- // Lump Start
- SPOOK_STATUEPIC, // 310
- // Lump Start
- ORCH_STATUEPIC, // 311
- LASTWALLPIC, // 312
-
- HAND1PICM=313,
-
- NORTHICONSPR=314,
-
- LEVEL1TEXT=605,
- LEVEL2TEXT, // 606
- LEVEL3TEXT, // 607
- LEVEL4TEXT, // 608
- LEVEL5TEXT, // 609
- LEVEL6TEXT, // 610
- LEVEL7TEXT, // 611
- LEVEL8TEXT, // 612
- LEVEL9TEXT, // 613
- LEVEL10TEXT, // 614
- LEVEL11TEXT, // 615
- LEVEL12TEXT, // 616
- LEVEL13TEXT, // 617
- LEVEL14TEXT, // 618
- LEVEL15TEXT, // 619
- LEVEL16TEXT, // 620
- LEVEL17TEXT, // 621
- LEVEL18TEXT, // 622
- LEVEL19TEXT, // 623
- LEVEL20TEXT, // 624
- PIRACY, // 625
+ FACE5PIC, // 6
+ FIRSTLATCHPIC, // 7
+ FACE1PIC, // 8
+ FACE2PIC, // 9
+ FACE3PIC, // 10
+ FACE4PIC, // 11
+ RADAR_TOPPIC, // 12
+ RADAR_BOTTOMPIC, // 13
+ RADAR_RGEMPIC, // 14
+ RADAR_GGEMPIC, // 15
+ RADAR_BGEMPIC, // 16
+ RADAR_YGEMPIC, // 17
+ RADAR_PGEMPIC, // 18
+ FIRSTGROUNDPIC, // 19
+ FIRSTSTRIPPIC, // 20
+ FIRSTSCALEPIC, // 21
+ // Lump Start
+ SKELETON_1PIC, // 22
+ SKELETON_2PIC, // 23
+ SKELETON_3PIC, // 24
+ SKELETON_4PIC, // 25
+ SKELETON_ATTACK_1PIC, // 26
+ SKELETON_ATTACK_2PIC, // 27
+ SKELETON_ATTACK_3PIC, // 28
+ SKELETON_OUCHPIC, // 29
+ SKELETON_DEATH_1PIC, // 30
+ SKELETON_DEATH_2PIC, // 31
+ // Lump Start
+ TOMB1PIC, // 32
+ TOMB2PIC, // 33
+ TOMB3PIC, // 34
+ // Lump Start
+ OBJ_WARP1PIC, // 35
+ OBJ_WARP2PIC, // 36
+ OBJ_WARP3PIC, // 37
+ OBJ_WARP4PIC, // 38
+ // Lump Start
+ EYE_WALK1PIC, // 39
+ EYE_WALK2PIC, // 40
+ EYE_WALK3PIC, // 41
+ EYE_OUCH1PIC, // 42
+ EYE_OUCH2PIC, // 43
+ EYE_DEATH1PIC, // 44
+ EYE_DEATH2PIC, // 45
+ EYE_DEATH3PIC, // 46
+ EYE_SCOWLPIC, // 47
+ EYE_SHOT1PIC, // 48
+ EYE_SHOT2PIC, // 49
+ // Lump Start
+ ZOMB_APPEAR1PIC, // 50
+ ZOMB_APPEAR2PIC, // 51
+ ZOMB_APPEAR3PIC, // 52
+ ZOMB_APPEAR4PIC, // 53
+ ZOMB_WALK1PIC, // 54
+ ZOMB_WALK2PIC, // 55
+ ZOMB_WALK3PIC, // 56
+ ZOMB_OUCHPIC, // 57
+ ZOMB_ATTACKPIC, // 58
+ ZOMB_DIE1PIC, // 59
+ ZOMB_DIE2PIC, // 60
+ ZOMB_DIE3PIC, // 61
+ // Lump Start
+ BOLTOBJPIC, // 62
+ BOLT2OBJPIC, // 63
+ BOLT3OBJPIC, // 64
+ // Lump Start
+ NUKEOBJPIC, // 65
+ NUKE2OBJPIC, // 66
+ NUKE3OBJPIC, // 67
+ // Lump Start
+ TIMEOBJ1PIC, // 68
+ TIMEOBJ2PIC, // 69
+ // Lump Start
+ O_WATER_CHEST1PIC, // 70
+ O_WATER_CHEST2PIC, // 71
+ // Lump Start
+ POTIONOBJPIC, // 72
+ // Lump Start
+ RKEYOBJPIC, // 73
+ // Lump Start
+ YKEYOBJPIC, // 74
+ // Lump Start
+ GKEYOBJPIC, // 75
+ // Lump Start
+ BKEYOBJPIC, // 76
+ // Lump Start
+ RGEM1PIC, // 77
+ RGEM2PIC, // 78
+ // Lump Start
+ GGEM1PIC, // 79
+ GGEM2PIC, // 80
+ // Lump Start
+ BGEM1PIC, // 81
+ BGEM2PIC, // 82
+ // Lump Start
+ YGEM1PIC, // 83
+ YGEM2PIC, // 84
+ // Lump Start
+ PGEM1PIC, // 85
+ PGEM2PIC, // 86
+ // Lump Start
+ CHESTOBJPIC, // 87
+ // Lump Start
+ PSHOT1PIC, // 88
+ PSHOT2PIC, // 89
+ PSHOT_EXP1PIC, // 90
+ PSHOT_EXP2PIC, // 91
+ PSHOT_EXP3PIC, // 92
+ // Lump Start
+ RED_DEMON1PIC, // 93
+ RED_DEMON2PIC, // 94
+ RED_DEMON3PIC, // 95
+ RED_DEMON4PIC, // 96
+ RED_DEMONATTACK1PIC, // 97
+ RED_DEMONATTACK2PIC, // 98
+ RED_DEMONATTACK3PIC, // 99
+ RED_DEMONOUCHPIC, // 100
+ RED_DEMONDIE1PIC, // 101
+ RED_DEMONDIE2PIC, // 102
+ RED_DEMONDIE3PIC, // 103
+ // Lump Start
+ MAGE1PIC, // 104
+ MAGE2PIC, // 105
+ MAGEOUCHPIC, // 106
+ MAGEATTACKPIC, // 107
+ MAGEDIE1PIC, // 108
+ MAGEDIE2PIC, // 109
+ // Lump Start
+ BAT1PIC, // 110
+ BAT2PIC, // 111
+ BAT3PIC, // 112
+ BAT4PIC, // 113
+ BATDIE1PIC, // 114
+ BATDIE2PIC, // 115
+ // Lump Start
+ GREL1PIC, // 116
+ GREL2PIC, // 117
+ GRELATTACKPIC, // 118
+ GRELHITPIC, // 119
+ GRELDIE1PIC, // 120
+ GRELDIE2PIC, // 121
+ GRELDIE3PIC, // 122
+ GRELDIE4PIC, // 123
+ GRELDIE5PIC, // 124
+ GRELDIE6PIC, // 125
+ SKULL_SHOTPIC, // 126
+ // Lump Start
+ GODESS_WALK1PIC, // 127
+ GODESS_WALK2PIC, // 128
+ GODESS_WALK3PIC, // 129
+ GODESS_ATTACK1PIC, // 130
+ GODESS_ATTACK2PIC, // 131
+ GODESS_ATTACK3PIC, // 132
+ GODESS_STATUEPIC, // 133
+ GODESS_OUCHPIC, // 134
+ GODESS_DEATH1PIC, // 135
+ GODESS_DEATH2PIC, // 136
+ // Lump Start
+ ANT_EGG1PIC, // 137
+ ANT_EGG2PIC, // 138
+ ANT_WALK1PIC, // 139
+ ANT_WALK2PIC, // 140
+ ANT_WALK3PIC, // 141
+ ANT_ATTACKPIC, // 142
+ ANT_DEATH1PIC, // 143
+ ANT_DEATH2PIC, // 144
+ ANT_DEATH3PIC, // 145
+ // Lump Start
+ FATDEMON_WALK1PIC, // 146
+ FATDEMON_WALK2PIC, // 147
+ FATDEMON_WALK3PIC, // 148
+ FATDEMON_WALK4PIC, // 149
+ FATDEMON_ATTACK1PIC, // 150
+ FATDEMON_ATTACK2PIC, // 151
+ FATDEMON_OUCHPIC, // 152
+ FATDEMON_BLOWUP1PIC, // 153
+ FATDEMON_BLOWUP2PIC, // 154
+ FATDEMON_BLOWUP3PIC, // 155
+ FATDEMON_EXPLODEPIC, // 156
+ FATDEMON_FEETPIC, // 157
+ // Lump Start
+ SUCCUBUS_WALK1PIC, // 158
+ SUCCUBUS_WALK2PIC, // 159
+ SUCCUBUS_WALK3PIC, // 160
+ SUCCUBUS_WALK4PIC, // 161
+ SUCCUBUS_ATTACK1PIC, // 162
+ SUCCUBUS_ATTACK2PIC, // 163
+ SUCCUBUS_OUCHPIC, // 164
+ SUCCUBUS_DEATH1PIC, // 165
+ SUCCUBUS_DEATH2PIC, // 166
+ SUCCUBUS_SHOT1PIC, // 167
+ // Lump Start
+ TREE_IDLEPIC, // 168
+ TREE_AWAKENINGPIC, // 169
+ TREE_WALK1PIC, // 170
+ TREE_WALK2PIC, // 171
+ TREE_ATTACK1PIC, // 172
+ TREE_ATTACK2PIC, // 173
+ TREE_ATTACK3PIC, // 174
+ TREE_DEATH1PIC, // 175
+ TREE_DEATH2PIC, // 176
+ TREE_DEATH3PIC, // 177
+ // Lump Start
+ DRAGON_BUBBLES1PIC, // 178
+ DRAGON_BUBBLES2PIC, // 179
+ DRAGON_EYESPIC, // 180
+ DRAGON_RISE1PIC, // 181
+ DRAGON_RISE2PIC, // 182
+ DRAGON_WALK1PIC, // 183
+ DRAGON_WALK2PIC, // 184
+ DRAGON_WALK3PIC, // 185
+ DRAGON_WALK4PIC, // 186
+ DRAGON_ATTACK1PIC, // 187
+ DRAGON_ATTACK2PIC, // 188
+ DRAGON_ATTACK3PIC, // 189
+ DRAGON_OUCHPIC, // 190
+ DRAGON_DEATH1PIC, // 191
+ DRAGON_DEATH2PIC, // 192
+ DRAGON_DEATH3PIC, // 193
+ // Lump Start
+ BUNNY_LEFT1PIC, // 194
+ BUNNY_LEFT2PIC, // 195
+ BUNNY_RIGHT1PIC, // 196
+ BUNNY_RIGHT2PIC, // 197
+ BUNNY_META1PIC, // 198
+ BUNNY_META2PIC, // 199
+ BUNNY_WALK1PIC, // 200
+ BUNNY_WALK2PIC, // 201
+ BUNNY_OUCHPIC, // 202
+ BUNNY_DEATH1PIC, // 203
+ BUNNY_DEATH2PIC, // 204
+ // Lump Start
+ ARCH1PIC, // 205
+ // Lump Start
+ ARCH2PIC, // 206
+ // Lump Start
+ ARCH3PIC, // 207
+ // Lump Start
+ ARCH4PIC, // 208
+ // Lump Start
+ ARCH5PIC, // 209
+ // Lump Start
+ ARCH6PIC, // 210
+ // Lump Start
+ ARCH7PIC, // 211
+ // Lump Start
+ ARCH8PIC, // 212
+ // Lump Start
+ ARCH9PIC, // 213
+ // Lump Start
+ ARCH10PIC, // 214
+ // Lump Start
+ ARCH11PIC, // 215
+ // Lump Start
+ ARCH12PIC, // 216
+ // Lump Start
+ ARCH13PIC, // 217
+ // Lump Start
+ ANT_HILLPIC, // 218
+ // Lump Start
+ COLUMNPIC, // 219
+ // Lump Start
+ SULPHUR_GAS_1PIC, // 220
+ SULPHUR_GAS_2PIC, // 221
+ SULPHUR_GAS_3PIC, // 222
+ // Lump Start
+ FIRE_POT_1PIC, // 223
+ FIRE_POT_2PIC, // 224
+ // Lump Start
+ SKEL_HANGPIC, // 225
+ // Lump Start
+ FORCE_FIELD_1PIC, // 226
+ FORCE_FIELD_2PIC, // 227
+ FORCE_FIELD_3PIC, // 228
+ FORCE_FIELD_4PIC, // 229
+ // Lump Start
+ WFOUNTAINPIC, // 230
+ FIRSTWALLPIC, // 231
+ CRYSTAL_LIGHT_1PIC, // 232
+ CRYSTAL_LIGHT_2PIC, // 233
+ CRYSTAL_LIGHT_3PIC, // 234
+ CRYSTAL_LIGHT_4PIC, // 235
+ CRYSTAL_DARK_1PIC, // 236
+ CRYSTAL_DARK_2PIC, // 237
+ CRYSTAL_DARK_3PIC, // 238
+ CRYSTAL_DARK_4PIC, // 239
+ FIRE_WALL_1PIC, // 240
+ FIRE_WALL_2PIC, // 241
+ FIRE_WALL_3PIC, // 242
+ FIRE_WALL_4PIC, // 243
+ BRN_STONE_GATEPIC, // 244
+ BRN_STONE_WALL_1PIC, // 245
+ BRN_STONE_WALL_2PIC, // 246
+ KUDZU_LIGHT_WALLPIC, // 247
+ KUDZU_DARK_WALLPIC, // 248
+ HEDGE_WALLPIC, // 249
+ HEDGE_EYESPIC, // 250
+ BRN_WINDOW_LIGHTPIC, // 251
+ ALTAR_LEFTPIC, // 252
+ ALTAR_RIGHTPIC, // 253
+ GRAY_LIGHT_WALLPIC, // 254
+ GRAY_DARK_WALLPIC, // 255
+ GRAY_LIGHT_SIGNPIC, // 256
+ GRAY_DARK_SIGNPIC, // 257
+ MANICLE_LIGHT_BLOODYPIC, // 258
+ MANICLE_DARK_BLOODYPIC, // 259
+ LIGHT_CURTAIN_WINDOWPIC, // 260
+ LIGHT_CURTAIN_WALLPIC, // 261
+ DARK_CURTAIN_WINDOWPIC, // 262
+ DARK_CURTAIN_WALLPIC, // 263
+ BRN_LIGHT_SIGNPIC, // 264
+ BRN_DARK_SIGNPIC, // 265
+ LIGHT_STONE_WALLPIC, // 266
+ DARK_STONE_WALLPIC, // 267
+ BRN_FLAGSTONE_LIGHT_2PIC, // 268
+ BRN_FLAGSTONE_DARK_2PIC, // 269
+ RUST_METAL_LIGHTPIC, // 270
+ RUST_METAL_DARKPIC, // 271
+ GRAY_METAL_LIGHTPIC, // 272
+ GRAY_METAL_DARKPIC, // 273
+ WEAK_STONE_LIGHTPIC, // 274
+ WEAK_STONE_DARKPIC, // 275
+ WEAK_GRAY_RFGSTN_LIGHTPIC, // 276
+ WEAK_GRAY_RFGSTN_DARKPIC, // 277
+ WEAK_CRYSTAL_LIGHTPIC, // 278
+ WEAK_CRYSTAL_DARKPIC, // 279
+ RED_MUD_LIGHTPIC, // 280
+ BRN_MUD_DARKPIC, // 281
+ RED_MUD_WEAK_LIGHTPIC, // 282
+ BRN_MUD_WEAK_DARKPIC, // 283
+ HORN_DOORPIC, // 284
+ CLOSED_DOOR_1PIC, // 285
+ DOOR_2PIC, // 286
+ WATER_LIGHT_WEAK_1PIC, // 287
+ WATER_LIGHT_WEAK_2PIC, // 288
+ WATER_LIGHT_WEAK_3PIC, // 289
+ WATER_DARK_WEAK_1PIC, // 290
+ WATER_DARK_WEAK_2PIC, // 291
+ WATER_DARK_WEAK_3PIC, // 292
+ WATER_LIGHT_1PIC, // 293
+ WATER_LIGHT_2PIC, // 294
+ WATER_LIGHT_3PIC, // 295
+ WATER_DARK_1PIC, // 296
+ WATER_DARK_2PIC, // 297
+ WATER_DARK_3PIC, // 298
+ TROLL_LIGHT_STONEPIC, // 299
+ TROLL_DARK_STONEPIC, // 300
+ TROLL_BLOODY_LT_STONEPIC, // 301
+ TROLL_BLOODY_DK_STONEPIC, // 302
+ LIGHT_BREATH_1PIC, // 303
+ LIGHT_BREATH_2PIC, // 304
+ LIGHT_BREATH_3PIC, // 305
+ DARK_BREATH_1PIC, // 306
+ DARK_BREATH_2PIC, // 307
+ DARK_BREATH_3PIC, // 308
+ EXP_WALL_1PIC, // 309
+ EXP_WALL_2PIC, // 310
+ EXP_WALL_3PIC, // 311
+ WATER_EXP_WALL_1PIC, // 312
+ WATER_EXP_WALL_2PIC, // 313
+ WATER_EXP_WALL_3PIC, // 314
+ W_GEN_DOOR1PIC, // 315
+ W_GEN_DOOR2PIC, // 316
+ W_CRYSTAL_DOORPIC, // 317
+ DMG_BRN_FSTN_LTPIC, // 318
+ DMG_BRN_FSTN_DKPIC, // 319
+ DMG_FIN_FSTN_LTPIC, // 320
+ DMG_FIN_FSTN_DKPIC, // 321
+ STEEL_DOOR1PIC, // 322
+ STEEL_DOOR2PIC, // 323
+ BRN_WINDOW_DARKPIC, // 324
+ GRY_DOOR_LTPIC, // 325
+ GRY_DOOR_DKPIC, // 326
+ BRN_DOOR_LTPIC, // 327
+ BRN_DOOR_DKPIC, // 328
+ GRY_FGSTN_LTPIC, // 329
+ GRY_FGSTN_DKPIC, // 330
+ KUDZU_WEAK_LIGHTPIC, // 331
+ KUDZU_WEAK_DARKPIC, // 332
+ LT_SKEL1PIC, // 333
+ DK_SKEL1PIC, // 334
+ LT_SKEL2PIC, // 335
+ DK_SKEL2PIC, // 336
+ MANICLE_LIGHT_WALLPIC, // 337
+ MANICLE_DARK_WALLPIC, // 338
+ TAP_1PIC, // 339
+ TAP_2PIC, // 340
+ TAP_3PIC, // 341
+ TAP_4PIC, // 342
+ TAP_5PIC, // 343
+ FINALWALLPIC, // 344
+ WATER_DOOR1_PIC, // 345
+ WATER_DOOR2_PIC, // 346
+ LASTWALLPIC, // 347
+
+ HAND1PICM=348,
+
+ NORTHICONSPR=349,
+
+ LEVEL1TEXT=640,
+ LEVEL2TEXT, // 641
+ LEVEL3TEXT, // 642
+ LEVEL4TEXT, // 643
+ LEVEL5TEXT, // 644
+ LEVEL6TEXT, // 645
+ LEVEL7TEXT, // 646
+ LEVEL8TEXT, // 647
+ LEVEL9TEXT, // 648
+ LEVEL10TEXT, // 649
+ LEVEL11TEXT, // 650
+ LEVEL12TEXT, // 651
+ LEVEL13TEXT, // 652
+ LEVEL14TEXT, // 653
+ LEVEL15TEXT, // 654
+ LEVEL16TEXT, // 655
+ LEVEL17TEXT, // 656
+ PIRACY, // 657
ENUMEND
} graphicnums;
//
// Data LUMPs
//
-#define SKELDUDE_LUMP_START 30
-#define SKELDUDE_LUMP_END 39
-
-#define SPOOK_LUMP_START 40
-#define SPOOK_LUMP_END 46
-
-#define TOMBSTONES_LUMP_START 47
-#define TOMBSTONES_LUMP_END 49
-
-#define WETMAN_LUMP_START 50
-#define WETMAN_LUMP_END 65
-
-#define OBJ_WARP_LUMP_START 66
-#define OBJ_WARP_LUMP_END 69
-
-#define EYE_LUMP_START 70
-#define EYE_LUMP_END 79
-
-#define ZOMBIE_LUMP_START 80
-#define ZOMBIE_LUMP_END 91
-
-#define ORC_LUMP_START 92
-#define ORC_LUMP_END 101
-
-#define TROLL_LUMP_START 102
-#define TROLL_LUMP_END 112
-
-#define BOLT_LUMP_START 113
-#define BOLT_LUMP_END 115
-
-#define NUKE_LUMP_START 116
-#define NUKE_LUMP_END 118
-
-#define PIT_LUMP_START 119
-#define PIT_LUMP_END 119
-
-#define TIME_LUMP_START 120
-#define TIME_LUMP_END 121
-
-#define O_WATER_CHEST_LUMP_START 122
-#define O_WATER_CHEST_LUMP_END 123
-
-#define POTION_LUMP_START 124
-#define POTION_LUMP_END 124
-
-#define RKEY_LUMP_START 125
-#define RKEY_LUMP_END 125
-
-#define YKEY_LUMP_START 126
-#define YKEY_LUMP_END 126
-
-#define GKEY_LUMP_START 127
-#define GKEY_LUMP_END 127
-
-#define BKEY_LUMP_START 128
-#define BKEY_LUMP_END 128
-
-#define RGEM_LUMP_START 129
-#define RGEM_LUMP_END 130
-
-#define GGEM_LUMP_START 131
-#define GGEM_LUMP_END 132
-
-#define BGEM_LUMP_START 133
-#define BGEM_LUMP_END 134
-
-#define YGEM_LUMP_START 135
-#define YGEM_LUMP_END 136
-
-#define PGEM_LUMP_START 137
-#define PGEM_LUMP_END 138
-
-#define SCROLL_LUMP_START 139
-#define SCROLL_LUMP_END 139
-
-#define CHEST_LUMP_START 140
-#define CHEST_LUMP_END 140
-
-#define RKEY2_LUMP_START 141
-#define RKEY2_LUMP_END 141
-
-#define PLAYER_LUMP_START 142
-#define PLAYER_LUMP_END 146
-
-#define DEMON_LUMP_START 147
-#define DEMON_LUMP_END 157
-
-#define REDDEMON_LUMP_START 158
-#define REDDEMON_LUMP_END 168
-
-#define MAGE_LUMP_START 169
-#define MAGE_LUMP_END 174
-
-#define BAT_LUMP_START 175
-#define BAT_LUMP_END 180
-
-#define GREL_LUMP_START 181
-#define GREL_LUMP_END 191
-
-#define EXPWALL_LUMP_START 193
-#define EXPWALL_LUMP_END 195
-
-#define W_WATER_EXP_LUMP_START 196
-#define W_WATER_EXP_LUMP_END 198
-
-#define WALL2_LUMP_START 199
-#define WALL2_LUMP_END 199
-
-#define WALL3_LUMP_START 200
-#define WALL3_LUMP_END 201
-
-#define WALL4_LUMP_START 202
-#define WALL4_LUMP_END 202
-
-#define WALL5_LUMP_START 203
-#define WALL5_LUMP_END 203
-
-#define WALL6_LUMP_START 204
-#define WALL6_LUMP_END 205
-
-#define WALL7_LUMP_START 206
-#define WALL7_LUMP_END 207
-
-#define WALL6_2_LUMP_START 208
-#define WALL6_2_LUMP_END 209
+#define SKELDUDE_LUMP_START 22
+#define SKELDUDE_LUMP_END 31
-#define WALL8_LUMP_START 210
-#define WALL8_LUMP_END 211
+#define TOMBSTONES_LUMP_START 32
+#define TOMBSTONES_LUMP_END 34
-#define WALL9_LUMP_START 212
-#define WALL9_LUMP_END 213
+#define OBJ_WARP_LUMP_START 35
+#define OBJ_WARP_LUMP_END 38
-#define WALL10_LUMP_START 214
-#define WALL10_LUMP_END 215
+#define EYE_LUMP_START 39
+#define EYE_LUMP_END 49
-#define WALL11_LUMP_START 216
-#define WALL11_LUMP_END 217
+#define ZOMBIE_LUMP_START 50
+#define ZOMBIE_LUMP_END 61
-#define WALL12_LUMP_START 218
-#define WALL12_LUMP_END 219
+#define BOLT_LUMP_START 62
+#define BOLT_LUMP_END 64
-#define WALL13_LUMP_START 220
-#define WALL13_LUMP_END 221
+#define NUKE_LUMP_START 65
+#define NUKE_LUMP_END 67
-#define WALL14_LUMP_START 222
-#define WALL14_LUMP_END 223
+#define TIME_LUMP_START 68
+#define TIME_LUMP_END 69
-#define WALL15_LUMP_START 224
-#define WALL15_LUMP_END 225
+#define O_WATER_CHEST_LUMP_START 70
+#define O_WATER_CHEST_LUMP_END 71
-#define WALL16_LUMP_START 226
-#define WALL16_LUMP_END 227
+#define POTION_LUMP_START 72
+#define POTION_LUMP_END 72
-#define WALL18_LUMP_START 228
-#define WALL18_LUMP_END 229
+#define RKEY_LUMP_START 73
+#define RKEY_LUMP_END 73
-#define WALL17_LUMP_START 230
-#define WALL17_LUMP_END 231
+#define YKEY_LUMP_START 74
+#define YKEY_LUMP_END 74
-#define WALL19_LUMP_START 232
-#define WALL19_LUMP_END 233
+#define GKEY_LUMP_START 75
+#define GKEY_LUMP_END 75
-#define WALL20_LUMP_START 234
-#define WALL20_LUMP_END 235
+#define BKEY_LUMP_START 76
+#define BKEY_LUMP_END 76
-#define WALL21_LUMP_START 236
-#define WALL21_LUMP_END 237
+#define RGEM_LUMP_START 77
+#define RGEM_LUMP_END 78
-#define WALL22_LUMP_START 238
-#define WALL22_LUMP_END 239
+#define GGEM_LUMP_START 79
+#define GGEM_LUMP_END 80
-#define WALL23_LUMP_START 240
-#define WALL23_LUMP_END 241
+#define BGEM_LUMP_START 81
+#define BGEM_LUMP_END 82
-#define WALL24_LUMP_START 242
-#define WALL24_LUMP_END 243
+#define YGEM_LUMP_START 83
+#define YGEM_LUMP_END 84
-#define WALL25_LUMP_START 244
-#define WALL25_LUMP_END 245
+#define PGEM_LUMP_START 85
+#define PGEM_LUMP_END 86
-#define WALL26_LUMP_START 246
-#define WALL26_LUMP_END 247
+#define CHEST_LUMP_START 87
+#define CHEST_LUMP_END 87
-#define WALL27_LUMP_START 248
-#define WALL27_LUMP_END 249
+#define PLAYER_LUMP_START 88
+#define PLAYER_LUMP_END 92
-#define WALL28_LUMP_START 250
-#define WALL28_LUMP_END 251
+#define REDDEMON_LUMP_START 93
+#define REDDEMON_LUMP_END 103
-#define WALL29_LUMP_START 252
-#define WALL29_LUMP_END 253
+#define MAGE_LUMP_START 104
+#define MAGE_LUMP_END 109
-#define WALL30_LUMP_START 254
-#define WALL30_LUMP_END 255
+#define BAT_LUMP_START 110
+#define BAT_LUMP_END 115
-#define WALL31_LUMP_START 256
-#define WALL31_LUMP_END 257
+#define GREL_LUMP_START 116
+#define GREL_LUMP_END 126
-#define WALL32_LUMP_START 258
-#define WALL32_LUMP_END 259
+#define GODESS_LUMP_START 127
+#define GODESS_LUMP_END 136
-#define WALL33_LUMP_START 260
-#define WALL33_LUMP_END 261
+#define ANT_LUMP_START 137
+#define ANT_LUMP_END 145
-#define WALL34_LUMP_START 262
-#define WALL34_LUMP_END 262
+#define FATDEMON_LUMP_START 146
+#define FATDEMON_LUMP_END 157
-#define WALL36_LUMP_START 263
-#define WALL36_LUMP_END 266
+#define SUCCUBUS_LUMP_START 158
+#define SUCCUBUS_LUMP_END 167
-#define W_WARP_LUMP_START 267
-#define W_WARP_LUMP_END 270
+#define TREE_LUMP_START 168
+#define TREE_LUMP_END 177
-#define W_TORCH_LUMP_START 278
-#define W_TORCH_LUMP_END 279
+#define DRAGON_LUMP_START 178
+#define DRAGON_LUMP_END 193
-#define SUB_STONE_LUMP_START 280
-#define SUB_STONE_LUMP_END 281
+#define BUNNY_LUMP_START 194
+#define BUNNY_LUMP_END 204
-#define BLOODY_SUB_STONE_LUMP_START 282
-#define BLOODY_SUB_STONE_LUMP_END 283
+#define ARCH1_LUMP_START 205
+#define ARCH1_LUMP_END 205
-#define W_BREATH_LUMP_START 284
-#define W_BREATH_LUMP_END 287
+#define ARCH2_LUMP_START 206
+#define ARCH2_LUMP_END 206
-#define W_WOOD_DOORWAY_LUMP_START 288
-#define W_WOOD_DOORWAY_LUMP_END 288
+#define ARCH3_LUMP_START 207
+#define ARCH3_LUMP_END 207
-#define W_WOOD_DOORWAY_GLOW_LUMP_START 289
-#define W_WOOD_DOORWAY_GLOW_LUMP_END 289
+#define ARCH4_LUMP_START 208
+#define ARCH4_LUMP_END 208
-#define W_WATER_GATES_LUMP_START 290
-#define W_WATER_GATES_LUMP_END 293
+#define ARCH5_LUMP_START 209
+#define ARCH5_LUMP_END 209
-#define W_PRE_CHEATS_LUMP_START 294
-#define W_PRE_CHEATS_LUMP_END 294
+#define ARCH6_LUMP_START 210
+#define ARCH6_LUMP_END 210
-#define W_CHEAT_GOD_LUMP_START 295
-#define W_CHEAT_GOD_LUMP_END 295
+#define ARCH7_LUMP_START 211
+#define ARCH7_LUMP_END 211
-#define W_CHEAT_WARP_LUMP_START 296
-#define W_CHEAT_WARP_LUMP_END 296
+#define ARCH8_LUMP_START 212
+#define ARCH8_LUMP_END 212
-#define W_CHEAT_ITEMS_LUMP_START 297
-#define W_CHEAT_ITEMS_LUMP_END 297
+#define ARCH9_LUMP_START 213
+#define ARCH9_LUMP_END 213
-#define W_CHEAT_FREEZE_LUMP_START 298
-#define W_CHEAT_FREEZE_LUMP_END 298
+#define ARCH10_LUMP_START 214
+#define ARCH10_LUMP_END 214
-#define W_POST_CHEAT_LUMP_START 299
-#define W_POST_CHEAT_LUMP_END 299
+#define ARCH11_LUMP_START 215
+#define ARCH11_LUMP_END 215
-#define W_SURFACE_PLAQ_LUMP_START 300
-#define W_SURFACE_PLAQ_LUMP_END 300
+#define ARCH12_LUMP_START 216
+#define ARCH12_LUMP_END 216
-#define W_BREATH2_LUMP_START 301
-#define W_BREATH2_LUMP_END 304
+#define ARCH13_LUMP_START 217
+#define ARCH13_LUMP_END 217
-#define W_MAGE_STATUE_LUMP_START 305
-#define W_MAGE_STATUE_LUMP_END 305
+#define ANTHILL_LUMP_START 218
+#define ANTHILL_LUMP_END 218
-#define W_ZOMBIE_STATUE_LUMP_START 306
-#define W_ZOMBIE_STATUE_LUMP_END 306
+#define COLUMN_LUMP_START 219
+#define COLUMN_LUMP_END 219
-#define W_EYE_STATUE_LUMP_START 307
-#define W_EYE_STATUE_LUMP_END 307
+#define SULPHURGAS_LUMP_START 220
+#define SULPHURGAS_LUMP_END 222
-#define W_NEM_STATUE_LUMP_START 308
-#define W_NEM_STATUE_LUMP_END 308
+#define FIREPOT_LUMP_START 223
+#define FIREPOT_LUMP_END 224
-#define W_SKELETION_STATUE_LUMP_START 309
-#define W_SKELETION_STATUE_LUMP_END 309
+#define SKELHANG_LUMP_START 225
+#define SKELHANG_LUMP_END 225
-#define W_SPOOK_STATUE_LUMP_START 310
-#define W_SPOOK_STATUE_LUMP_END 310
+#define FORCEFIELD_LUMP_START 226
+#define FORCEFIELD_LUMP_END 229
-#define W_ORCH_STATUE_LUMP_START 311
-#define W_ORCH_STATUE_LUMP_END 311
+#define FOUNTAIN_LUMP_START 230
+#define FOUNTAIN_LUMP_END 230
//
// Amount of each data item
//
-#define NUMCHUNKS 626
+#define NUMCHUNKS 658
#define NUMFONT 1
#define NUMFONTM 0
-#define NUMPICS 309
+#define NUMPICS 344
#define NUMPICM 1
#define NUMSPRITES 1
#define NUMTILE8 108
@@ -753,7 +621,7 @@ typedef enum {
#define NUMTILE16M 72
#define NUMTILE32 0
#define NUMTILE32M 0
-#define NUMEXTERNS 21
+#define NUMEXTERNS 18
//
// File offsets for data items
//
@@ -764,15 +632,15 @@ typedef enum {
#define STARTFONT 3
#define STARTFONTM 4
#define STARTPICS 4
-#define STARTPICM 313
-#define STARTSPRITES 314
-#define STARTTILE8 315
-#define STARTTILE8M 316
-#define STARTTILE16 317
-#define STARTTILE16M 533
-#define STARTTILE32 605
-#define STARTTILE32M 605
-#define STARTEXTERNS 605
+#define STARTPICM 348
+#define STARTSPRITES 349
+#define STARTTILE8 350
+#define STARTTILE8M 351
+#define STARTTILE16 352
+#define STARTTILE16M 568
+#define STARTTILE32 640
+#define STARTTILE32M 640
+#define STARTEXTERNS 640
//
// Thank you for using IGRAB!
diff --git a/ID_ASM.EQU b/ID_ASM.EQU
index d1ccf55..01fe696 100644
--- a/ID_ASM.EQU
+++ b/ID_ASM.EQU
@@ -4,7 +4,7 @@
;----------------------------------------------------------------------------
-INCLUDE "GFXE_ABS.EQU"
+INCLUDE "GFXE_ARM.EQU"
;----------------------------------------------------------------------------
diff --git a/ID_CA.C b/ID_CA.C
index 069a47d..cfc772e 100644
--- a/ID_CA.C
+++ b/ID_CA.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -1021,7 +1021,7 @@ void CA_Startup (void)
// MDM begin - (GAMERS EDGE)
//
- if (!FindFile("GAMEMAPS."EXT,NULL,2))
+ if (!FindFile("GAMEMAPS."EXT,NULL,1))
Quit("CA_Startup(): Can't find level files.");
//
// MDM end
@@ -1220,13 +1220,15 @@ cachein:
*/
unsigned static sheight,swidth;
+boolean static dothemask;
void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,
- unsigned width, unsigned height, unsigned pixshift)
+ unsigned width, unsigned height, unsigned pixshift, boolean domask)
{
sheight = height; // because we are going to reassign bp
swidth = width;
+ dothemask = domask;
asm mov ax,[segment]
asm mov ds,ax // source and dest are in same segment, and all local
@@ -1238,6 +1240,9 @@ asm mov bp,[pixshift]
asm shl bp,1
asm mov bp,WORD PTR [shifttabletable+bp] // bp holds pointer to shift table
+asm cmp [ss:dothemask],0
+asm je skipmask
+
//
// table shift the mask
//
@@ -1268,6 +1273,8 @@ asm inc di // the last shifted byte has 1s in it
asm dec dx
asm jnz domaskrow
+skipmask:
+
//
// table shift the data
//
@@ -1405,7 +1412,7 @@ void CAL_CacheSprite (int chunk, byte far *compressed)
dest->width[i] = spr->width+1;
}
CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],
- dest->sourceoffset[2],spr->width,spr->height,4);
+ dest->sourceoffset[2],spr->width,spr->height,4,true);
break;
case 4:
@@ -1417,19 +1424,19 @@ void CAL_CacheSprite (int chunk, byte far *compressed)
dest->planesize[1] = bigplane;
dest->width[1] = spr->width+1;
CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],
- dest->sourceoffset[1],spr->width,spr->height,2);
+ dest->sourceoffset[1],spr->width,spr->height,2,true);
dest->sourceoffset[2] = shiftstarts[2];
dest->planesize[2] = bigplane;
dest->width[2] = spr->width+1;
CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],
- dest->sourceoffset[2],spr->width,spr->height,4);
+ dest->sourceoffset[2],spr->width,spr->height,4,true);
dest->sourceoffset[3] = shiftstarts[3];
dest->planesize[3] = bigplane;
dest->width[3] = spr->width+1;
CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],
- dest->sourceoffset[3],spr->width,spr->height,6);
+ dest->sourceoffset[3],spr->width,spr->height,6,true);
break;
@@ -1659,7 +1666,7 @@ void CA_CacheMap (int mapnum)
// MDM begin - (GAMERS EDGE)
//
- if (!FindFile("GAMEMAPS."EXT,NULL,2))
+ if (!FindFile("GAMEMAPS."EXT,NULL,1))
Quit("CA_CacheMap(): Can't find level files.");
//
// MDM end
diff --git a/ID_CA.H b/ID_CA.H
index ca6f3d7..0b6a758 100644
--- a/ID_CA.H
+++ b/ID_CA.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -42,8 +42,8 @@
#define GRHEADERLINKED
#define AUDIOHEADERLINKED
-#define NUMMAPS 19
-#define MAPPLANES 3
+#define NUMMAPS 39
+#define MAPPLANES 3
//===========================================================================
@@ -84,7 +84,7 @@ extern void (*finishcachebox) (void);
// just for the score box reshifting
void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,
- unsigned width, unsigned height, unsigned pixshift);
+ unsigned width, unsigned height, unsigned pixshift, boolean domask);
//===========================================================================
diff --git a/ID_HEADS.H b/ID_HEADS.H
index 5f176db..88f86d3 100644
--- a/ID_HEADS.H
+++ b/ID_HEADS.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -36,13 +36,13 @@
//--------------------------------------------------------------------------
-#define EXT "ABS"
+#define EXT "ARM"
extern char far introscn;
-#include "GFXE_ABS.H"
-#include "AUDIOABS.H"
-#include "MAPSABS.H"
+#include "GFXE_ARM.H"
+#include "AUDIOARM.H"
+#include "MAPSARM.H"
//--------------------------------------------------------------------------
@@ -56,7 +56,10 @@ extern char far introscn;
#define tf_SOLID 0x01
#define tf_SPECIAL 0x02
#define tf_EMBEDDED_KEY_COLOR 0x04
+#define tf_INVISIBLE_WALL 0x09
+#define tf_MARKED 0x80
+#define ANIM_FLAGS(tile) (tinf[ANIM+(tile)])
#define TILE_FLAGS(tile) (tinf[FLAGS+(tile)])
#define GATE_KEY_COLOR(tile) ((unsigned char)(TILE_FLAGS(tile)>>4))
diff --git a/ID_IN.C b/ID_IN.C
index fe51ad1..9beae17 100644
--- a/ID_IN.C
+++ b/ID_IN.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
diff --git a/ID_IN.H b/ID_IN.H
index 1ebc547..93c4add 100644
--- a/ID_IN.H
+++ b/ID_IN.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
diff --git a/ID_MM.C b/ID_MM.C
index 2729e1d..c2d8154 100644
--- a/ID_MM.C
+++ b/ID_MM.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -49,13 +49,17 @@ EMS / XMS unmanaged routines
#pragma warn -use
-//#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!"
+#if 0 // 1 == Debug/Dev ; 0 == Production/final
-#define OUT_OF_MEM_MSG "\n" \
- "You need more free memory to run CATACOMB ABYSS. Type START [ENTER]\n" \
- "and read the \"INFORMATION YOU SHOULD KNOW BEFORE PLAYING\" section\n" \
- "for more information about this.\n"
+#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!\nYou were short :%ld bytes"
+#else
+
+
+#define OUT_OF_MEM_MSG "\n" \
+ "You need more memory to run CATACOMB ARMAGEDDON. Read the INSTRUCTION\n" \
+ "section of the START program for tips on getting more memory.\n"
+#endif
/*
@@ -769,7 +773,7 @@ void MM_GetPtr (memptr *baseptr,unsigned long size)
}
if (bombonerror)
- Quit (OUT_OF_MEM_MSG);
+ Quit (OUT_OF_MEM_MSG,(size-mminfo.nearheap));
else
mmerror = true;
}
diff --git a/ID_MM.H b/ID_MM.H
index f9961b1..253b020 100644
--- a/ID_MM.H
+++ b/ID_MM.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
diff --git a/ID_RF.C b/ID_RF.C
index ea59b23..62dfa91 100644
--- a/ID_RF.C
+++ b/ID_RF.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -1479,7 +1479,6 @@ void RF_CalcTics (void)
TimeCount -= (tics-MAXTICS);
tics = MAXTICS;
}
-
}
}
diff --git a/ID_RF.H b/ID_RF.H
index b52fef9..8a3b0e2 100644
--- a/ID_RF.H
+++ b/ID_RF.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
diff --git a/ID_RF_A.ASM b/ID_RF_A.ASM
index ce699c2..77af0e9 100644
--- a/ID_RF_A.ASM
+++ b/ID_RF_A.ASM
@@ -1,4 +1,4 @@
-; Catacomb Abyss Source Code
+; Catacomb Armageddon Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
diff --git a/ID_SD.C b/ID_SD.C
index b6279d8..c62a0aa 100644
--- a/ID_SD.C
+++ b/ID_SD.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
diff --git a/ID_SD.H b/ID_SD.H
index 28a92db..d60aea3 100644
--- a/ID_SD.H
+++ b/ID_SD.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
diff --git a/ID_STRS.H b/ID_STRS.H
index 8229f58..c34a245 100644
--- a/ID_STRS.H
+++ b/ID_STRS.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
diff --git a/ID_US.C b/ID_US.C
index 4ff2bd3..082b231 100644
--- a/ID_US.C
+++ b/ID_US.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
diff --git a/ID_US.H b/ID_US.H
index bda9d2d..7acc243 100644
--- a/ID_US.H
+++ b/ID_US.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
diff --git a/ID_US_1.C b/ID_US_1.C
index f8e34c0..789229c 100644
--- a/ID_US_1.C
+++ b/ID_US_1.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -862,7 +862,7 @@ US_CPrintLine(char *s)
USL_MeasureString(s,&w,&h);
if (w > WindowW)
- Quit("US_CPrintLine() - String exceeds width\n-->%s",s);
+ Quit("US_CPrintLine() - String exceeds width");
px = WindowX + ((WindowW - w) / 2);
py = PrintY;
USL_DrawString(s);
diff --git a/ID_US_2.C b/ID_US_2.C
index ab779ff..3582803 100644
--- a/ID_US_2.C
+++ b/ID_US_2.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
diff --git a/ID_US_A.ASM b/ID_US_A.ASM
index c6c6130..a27ca54 100644
--- a/ID_US_A.ASM
+++ b/ID_US_A.ASM
@@ -1,4 +1,4 @@
-; Catacomb Abyss Source Code
+; Catacomb Armageddon Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
diff --git a/ID_VW.C b/ID_VW.C
index 9a22079..f6a0067 100644
--- a/ID_VW.C
+++ b/ID_VW.C
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -506,6 +506,33 @@ void VW_DrawPic(unsigned x, unsigned y, unsigned chunknum)
}
+// MDM (GAMERS EDGE) begin
+/*
+====================
+=
+= VW_DrawPic2x - Same as VW_DrawPic, but doubles pixels horizontally
+= (Great for drawing 320 graphics on 640 screen!)
+=
+= X in bytes, y in pixels, chunknum is the #defined picnum
+=
+====================
+*/
+
+void VW_DrawPic2x(unsigned x, unsigned y, unsigned chunknum)
+{
+ int picnum = chunknum - STARTPICS;
+ memptr source;
+ unsigned dest,width,height;
+
+ source = grsegs[chunknum];
+ dest = ylookup[y]+x+bufferofs;
+ width = pictable[picnum].width;
+ height = pictable[picnum].height;
+
+ VW_MemToScreen2x(source,dest,width,height);
+}
+// MDM (GAMERS EDGE) end
+
#endif
#if NUMPICM>0
@@ -1277,6 +1304,8 @@ void VW_QuitDoubleBuffer (void)
int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2)
{
+// MDM (GAMERS EDGE) begin - NOT NEEDED FOR 3D ENGINE
+#if 0
int x,y,xt1,yt1,xt2,yt2,nextline;
byte *mark;
@@ -1316,6 +1345,8 @@ int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2)
mark += nextline;
}
+#endif
+// MDM (GAMERS EDGE) end
return 1;
}
diff --git a/ID_VW.H b/ID_VW.H
index c9e81f0..49e41d3 100644
--- a/ID_VW.H
+++ b/ID_VW.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -274,6 +274,7 @@ void VW_SetAtrReg (int reg, int value);
void VW_MaskBlock(memptr segm,unsigned ofs,unsigned dest,
unsigned wide,unsigned height,unsigned planesize);
void VW_MemToScreen(memptr source,unsigned dest,unsigned width,unsigned height);
+void VW_MemToScreen2x(memptr source,unsigned dest,unsigned width,unsigned height);
void VW_ScreenToMem(unsigned source,memptr dest,unsigned width,unsigned height);
void VW_ScreenToScreen(unsigned source,unsigned dest,unsigned width,unsigned height);
@@ -307,6 +308,7 @@ void VW_DrawTile8(unsigned x, unsigned y, unsigned tile);
#endif
void VW_DrawPic(unsigned x, unsigned y, unsigned chunknum);
+void VW_DrawPic2x(unsigned x, unsigned y, unsigned chunknum);
void VW_DrawMPic(unsigned x, unsigned y, unsigned chunknum);
void VW_ClipDrawMPic(unsigned x, int y, unsigned chunknum);
@@ -368,4 +370,5 @@ void VWB_Plot (int x, int y, int color);
void VWB_Hlin (int x1, int x2, int y, int color);
void VWB_Vlin (int y1, int y2, int x, int color);
+void VWL_MeasureString (char far *string, word *width, word *height, fontstruct _seg *font);
//===========================================================================
diff --git a/ID_VW_A.ASM b/ID_VW_A.ASM
index 5debc87..d6376b2 100644
--- a/ID_VW_A.ASM
+++ b/ID_VW_A.ASM
@@ -1,4 +1,4 @@
-; Catacomb Abyss Source Code
+; Catacomb Armageddon Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
diff --git a/ID_VW_AC.ASM b/ID_VW_AC.ASM
index 20f809b..97352be 100644
--- a/ID_VW_AC.ASM
+++ b/ID_VW_AC.ASM
@@ -1,4 +1,4 @@
-; Catacomb Abyss Source Code
+; Catacomb Armageddon Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
diff --git a/ID_VW_AE.ASM b/ID_VW_AE.ASM
index 9854efe..e26c50b 100644
--- a/ID_VW_AE.ASM
+++ b/ID_VW_AE.ASM
@@ -1,4 +1,4 @@
-; Catacomb Abyss Source Code
+; Catacomb Armageddon Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
@@ -748,6 +748,154 @@ oddtoodd:
ENDP
+; MDM (GAMERS EDGE) begin
+
+
+MACRO XPAND_BYTE
+ test al,128 ; handle bit 7
+ jne @@over7
+ or [BYTE PTR es:di],11000000b
+@@over7:
+
+ test al,64 ; handle bit 6
+ jne @@over6
+ or [BYTE PTR es:di],00110000b
+@@over6:
+
+ test al,32 ; handle bit 5
+ jne @@over5
+ or [BYTE PTR es:di],00001100b
+@@over5:
+
+ test al,16 ; handle bit 4
+ jne @@over4
+ or [BYTE PTR es:di],00000011b
+@@over4:
+
+ inc di ; inc destination
+
+ test al,8 ; handle bit 3
+ jne @@over3
+ or [BYTE PTR es:di],11000000b
+@@over3:
+
+ test al,4 ; handle bit 2
+ jne @@over2
+ or [BYTE PTR es:di],00110000b
+@@over2:
+
+ test al,2 ; handle bit 1
+ jne @@over1
+ or [BYTE PTR es:di],00001100b
+@@over1:
+
+ test al,1 ; handle bit 0
+ jne @@over0
+ or [BYTE PTR es:di],00000011b
+@@over0:
+
+ inc si ; inc source
+ inc di ; inc destination
+ENDM
+
+
+;============================================================================
+;
+; VW_MemToScreen2x
+;
+; Basic block drawing routine. Takes a block shape at segment pointer source
+; with four planes of width by height data, and draws it to dest in the
+; virtual screen, based on linewidth. bufferofs is NOT accounted for.
+; There are four drawing routines to provide the best optimized code while
+; accounting for odd segment wrappings due to the floating screens.
+;
+;============================================================================
+
+DATASEG
+
+xpandhorz db 00000000b,00000011b,00001100b,00001111b
+ db 00110000b,00110011b,00111100b,00111111b
+ db 11000000b,11000011b,11001100b,11001111b
+ db 11110000b,11110011b,11111100b,11111111b
+
+CODESEG
+
+
+PROC VW_MemToScreen2x source:WORD, dest:WORD, wide:WORD, height:WORD
+PUBLIC VW_MemToScreen2x
+USES SI,DI
+
+ mov es,[screenseg]
+
+ mov bx,[linewidth]
+ sub bx,[wide]
+ sub bx,[wide]
+
+ mov ds,[source]
+
+
+ xor si,si ;block is segment aligned
+
+ mov ah,0001b ;map mask for plane 0
+
+@@depthloop:
+ mov al,SC_MAPMASK ;restore map mask in al
+ mov dx,SC_INDEX
+ WORDOUT
+
+ mov di,[dest] ;start at same place in all planes
+ mov dx,[height] ;scan lines to draw
+
+@@heightloop:
+ mov cx,[wide]
+@@widthloop:
+
+; handle first nybble
+;
+ push di
+ mov di,[si]
+ shr di,1
+ shr di,1
+ shr di,1
+ shr di,1
+ and di,15
+ mov al,[ss:xpandhorz+di]
+ pop di
+ mov [es:di],al
+ inc di
+
+; handle second nybble
+;
+ push di
+ mov di,[si]
+ and di,15
+ mov al,[ss:xpandhorz+di]
+ pop di
+ mov [es:di],al
+ inc si
+ inc di
+
+
+ dec cx
+ jne @@widthloop
+
+ add di,bx
+
+ dec dx
+ jnz @@heightloop
+
+ shl ah,1 ;shift plane mask over for next plane
+ cmp ah,10000b ;done all four planes?
+ jne @@depthloop
+
+ mov ax,ss
+ mov ds,ax ;restore turbo's data segment
+
+ ret
+
+ENDP
+; MDM (GAMERS EDGE) end
+
;===========================================================================
;
; VW_ScreenToMem
@@ -1075,7 +1223,7 @@ propchar dw ? ; the character number to shift
stringptr dw ?,?
-BUFFWIDTH = 80 ; MDM (GAMERS EDGE) - increased from 50
+BUFFWIDTH = 82 ; MDM (GAMERS EDGE) - increased from 50
BUFFHEIGHT = 20 ; must be twice as high as font for masked fonts
databuffer db BUFFWIDTH*BUFFHEIGHT dup (?)
diff --git a/JABHACK.ASM b/JABHACK.ASM
index 5f2684e..1621367 100644
--- a/JABHACK.ASM
+++ b/JABHACK.ASM
@@ -1,4 +1,4 @@
-; Catacomb Abyss Source Code
+; Catacomb Armageddon Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
diff --git a/JAMPAK.C b/JAMPAK.C
new file mode 100644
index 0000000..c12e038
--- /dev/null
+++ b/JAMPAK.C
@@ -0,0 +1,1113 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#pragma inline
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <alloc.h>
+#include <fcntl.h>
+#include <dos.h>
+#include <io.h>
+
+#include "def.h"
+#include "gelib.h"
+#include "jampak.h"
+
+
+
+//=========================================================================
+//
+//
+// LOCAL DEFINATIONS
+//
+//
+//=========================================================================
+
+//#define COMPRESSION_CODE // Comment define in for COMPRESS routines
+
+
+
+
+
+
+//=========================================================================
+//
+//
+// LOCAL VARIABLES
+//
+//
+//=========================================================================
+
+
+unsigned char far LZW_ring_buffer[LZW_N + LZW_F - 1];
+
+ // ring buffer of size LZW_N, with extra LZW_F-1 bytes to facilitate
+ // string comparison
+
+
+#ifdef COMPRESSION_CODE
+
+int LZW_match_pos,
+ LZW_match_len,
+
+ // MAtchLength of longest match. These are set by the InsertNode()
+ // procedure.
+
+ // left & right children & parents -- These constitute binary search trees. */
+
+ far LZW_left_child[LZW_N + 1],
+ far LZW_right_child[LZW_N + 257],
+ far LZW_parent[LZW_N + 1];
+
+#endif
+
+memptr segptr;
+BufferedIO lzwBIO;
+
+
+
+
+
+//=========================================================================
+//
+//
+// COMPRESSION SUPPORT ROUTINES
+//
+//
+//=========================================================================
+
+
+#ifdef COMPRESSION_CODE
+
+//---------------------------------------------------------------------------
+// InitLZWTree()
+//---------------------------------------------------------------------------
+void InitLZWTree(void) /* initialize trees */
+{
+ int i;
+
+ /* For i = 0 to LZW_N - 1, LZW_right_child[i] and LZW_left_child[i] will be the right and
+ left children of node i. These nodes need not be initialized.
+ Also, LZW_parent[i] is the parent of node i. These are initialized to
+ LZW_NIL (= LZW_N), which stands for 'not used.'
+ For i = 0 to 255, LZW_right_child[LZW_N + i + 1] is the root of the tree
+ for strings that begin with character i. These are initialized
+ to LZW_NIL. Note there are 256 trees. */
+
+ for (i = LZW_N + 1; i <= LZW_N + 256; i++)
+ LZW_right_child[i] = LZW_NIL;
+
+ for (i = 0; i < LZW_N; i++)
+ LZW_parent[i] = LZW_NIL;
+}
+
+
+
+
+
+//---------------------------------------------------------------------------
+// InsertLZWNode()
+//---------------------------------------------------------------------------
+void InsertLZWNode(unsigned long r)
+
+ /* Inserts string of length LZW_F, LZW_ring_buffer[r..r+LZW_F-1], into one of the
+ trees (LZW_ring_buffer[r]'th tree) and returns the longest-match position
+ and length via the global variables LZW_match_pos and LZW_match_len.
+ If LZW_match_len = LZW_F, then removes the old node in favor of the new
+ one, because the old one will be deleted sooner.
+ Note r plays double role, as tree node and position in buffer. */
+{
+ int i, p, cmp;
+ unsigned char *key;
+
+ cmp = 1;
+ key = &LZW_ring_buffer[r];
+ p = LZW_N + 1 + key[0];
+ LZW_right_child[r] = LZW_left_child[r] = LZW_NIL;
+ LZW_match_len = 0;
+
+ for ( ; ; )
+ {
+ if (cmp >= 0)
+ {
+ if (LZW_right_child[p] != LZW_NIL)
+ p = LZW_right_child[p];
+ else
+ {
+ LZW_right_child[p] = r;
+ LZW_parent[r] = p;
+ return;
+ }
+ }
+ else
+ {
+ if (LZW_left_child[p] != LZW_NIL)
+ p = LZW_left_child[p];
+ else
+ {
+ LZW_left_child[p] = r;
+ LZW_parent[r] = p;
+ return;
+ }
+ }
+
+ for (i = 1; i < LZW_F; i++)
+ if ((cmp = key[i] - LZW_ring_buffer[p + i]) != 0)
+ break;
+
+ if (i > LZW_match_len)
+ {
+ LZW_match_pos = p;
+ if ((LZW_match_len = i) >= LZW_F)
+ break;
+ }
+ }
+
+ LZW_parent[r] = LZW_parent[p];
+ LZW_left_child[r] = LZW_left_child[p];
+ LZW_right_child[r] = LZW_right_child[p];
+ LZW_parent[LZW_left_child[p]] = r;
+ LZW_parent[LZW_right_child[p]] = r;
+
+ if (LZW_right_child[LZW_parent[p]] == p)
+ LZW_right_child[LZW_parent[p]] = r;
+ else
+ LZW_left_child[LZW_parent[p]] = r;
+
+ LZW_parent[p] = LZW_NIL; /* remove p */
+}
+
+
+
+//---------------------------------------------------------------------------
+// DeleteLZWNode()
+//---------------------------------------------------------------------------
+void DeleteLZWNode(unsigned long p) /* deletes node p from tree */
+{
+ int q;
+
+ if (LZW_parent[p] == LZW_NIL)
+ return; /* not in tree */
+
+ if (LZW_right_child[p] == LZW_NIL)
+ q = LZW_left_child[p];
+ else
+ if (LZW_left_child[p] == LZW_NIL)
+ q = LZW_right_child[p];
+ else
+ {
+ q = LZW_left_child[p];
+ if (LZW_right_child[q] != LZW_NIL)
+ {
+ do {
+
+ q = LZW_right_child[q];
+
+ } while (LZW_right_child[q] != LZW_NIL);
+
+ LZW_right_child[LZW_parent[q]] = LZW_left_child[q];
+ LZW_parent[LZW_left_child[q]] = LZW_parent[q];
+ LZW_left_child[q] = LZW_left_child[p];
+ LZW_parent[LZW_left_child[p]] = q;
+ }
+
+ LZW_right_child[q] = LZW_right_child[p];
+ LZW_parent[LZW_right_child[p]] = q;
+ }
+
+ LZW_parent[q] = LZW_parent[p];
+ if (LZW_right_child[LZW_parent[p]] == p)
+ LZW_right_child[LZW_parent[p]] = q;
+ else
+ LZW_left_child[LZW_parent[p]] = q;
+
+ LZW_parent[p] = LZW_NIL;
+}
+#endif
+
+
+
+
+//=========================================================================
+//
+//
+// GENERAL FILE to FILE compression routines
+//
+// * Mainly for example usage of PTR/PTR (de)compression routines.
+//
+//
+//=========================================================================
+
+
+
+//////////////////////////////////////////////////////////////////////
+//
+// CompressFILEtoFILE() -- Compresses one file stream to another file stream
+//
+
+#ifdef COMPRESSION_CODE
+
+unsigned long CompressFILEtoFILE(FILE *infile, FILE *outfile,unsigned long DataLength)
+{
+ unsigned long returnval;
+
+ fwrite(COMP,4,1,outfile);
+ fwrite((char *)&DataLength,4,1,outfile);
+
+ returnval = 8+lzwCompress(infile,outfile,DataLength,(SRC_FFILE|DEST_FFILE));
+
+ return(returnval);
+}
+
+#endif
+
+#if 0
+/////////////////////////////////////////////////////////////////////////////
+//
+// DecompressFILEtoFILE()
+//
+void DecompressFILEtoFILE(FILE *infile, FILE *outfile)
+{
+ unsigned char Buffer[8];
+ unsigned long DataLength;
+
+ fread(Buffer,1,4,infile);
+
+ if (strncmp(Buffer,COMP,4))
+ {
+ printf("\nNot a JAM Compressed File!\n");
+ return;
+ }
+
+ fread((void *)&DataLength,1,4,infile);
+
+ lzwDecompress(infile,outfile,DataLength,(SRC_FFILE|DEST_FFILE));
+}
+#endif
+
+
+
+
+
+//==========================================================================
+//
+//
+// WRITE/READ PTR ROUTINES
+//
+//
+//==========================================================================
+
+
+
+//---------------------------------------------------------------------------
+// WritePtr() -- Outputs data to a particular ptr type
+//
+// PtrType MUST be of type DEST_TYPE.
+//
+// NOTE : For PtrTypes DEST_MEM a ZERO (0) is always returned.
+//
+//---------------------------------------------------------------------------
+int WritePtr(long outfile, unsigned char data, unsigned PtrType)
+{
+ int returnval = 0;
+
+ switch (PtrType & DEST_TYPES)
+ {
+ case DEST_FILE:
+ write(*(int far *)outfile,(char *)&data,1);
+ break;
+
+ case DEST_FFILE:
+ returnval = putc(data, *(FILE **)outfile);
+ break;
+
+ case DEST_MEM:
+// *(*(char far **)outfile++) = data; // Do NOT delete
+ *((char far *)*(char far **)outfile)++ = data;
+ break;
+
+ default:
+ TrashProg("WritePtr() : Unknown DEST_PTR type");
+ break;
+ }
+
+ return(returnval);
+
+}
+
+
+//---------------------------------------------------------------------------
+// ReadPtr() -- Reads data from a particular ptr type
+//
+// PtrType MUST be of type SRC_TYPE.
+//
+// RETURNS :
+// The char read in or EOF for SRC_FFILE type of reads.
+//
+//
+//---------------------------------------------------------------------------
+int ReadPtr(long infile, unsigned PtrType)
+{
+ int returnval = 0;
+
+ switch (PtrType & SRC_TYPES)
+ {
+ case SRC_FILE:
+ read(*(int far *)infile,(char *)&returnval,1);
+ break;
+
+ case SRC_FFILE:
+// JIM - JTR - is the following correct? "fgetc()" uses a near pointer.
+//
+ returnval = fgetc((FILE far *)*(FILE far **)infile);
+ break;
+
+ case SRC_BFILE:
+ returnval = bio_readch((BufferedIO *)*(void far **)infile);
+ break;
+
+ case SRC_MEM:
+ returnval = (char)*(*(char far **)infile++);
+// returnval = *((char far *)*(char far **)infile)++; // DO NOT DELETE!
+ break;
+
+ default:
+ TrashProg("ReadPtr() : Unknown SRC_PTR type");
+ break;
+ }
+
+ return(returnval);
+}
+
+
+
+
+//=========================================================================
+//
+//
+// COMPRESSION & DECOMPRESSION ROUTINES
+//
+//
+//=========================================================================
+
+
+//--------------------------------------------------------------------------
+//
+// lzwCompress() - Compresses data from an input ptr to a dest ptr
+//
+// PARAMS:
+// infile - Pointer at the BEGINNING of the data to compress
+// outfile - Pointer to the destination (no header).
+// DataLength - Number of bytes to compress.
+// PtrTypes - Type of pointers being used (SRC_FILE,DEST_FILE,SRC_MEM etc).
+//
+// RETURNS:
+// Length of compressed data.
+//
+// COMPTYPE : ct_LZW
+//
+// NOTES : Does not write ANY header information!
+//
+#ifdef COMPRESSION_CODE
+unsigned long lzwCompress(void far *infile, void far *outfile,unsigned long DataLength,unsigned PtrTypes)
+{
+ short i;
+ short c, len, r, s, last_LZW_match_len, code_buf_ptr;
+ unsigned char far code_buf[17], mask;
+ unsigned long complen = 0;
+
+ // initialize trees
+
+ InitLZWTree();
+
+ code_buf[0] = 0;
+
+ //
+ // code_buf[1..16] saves eight units of code, and code_buf[0] works
+ // as eight flags, "1" representing that the unit is an unencoded
+ // letter (1 byte), "0" a position-and-length pair (2 bytes). Thus,
+ // eight units require at most 16 bytes of code.
+ //
+
+ code_buf_ptr = mask = 1;
+ s = 0;
+ r = LZW_N - LZW_F;
+
+ // Clear the buffer with any character that will appear often.
+ //
+
+ for (i = s; i < r; i++)
+ LZW_ring_buffer[i] = ' ';
+
+ // Read LZW_F bytes into the last LZW_F bytes of the buffer
+ //
+
+ for (len = 0; (len < LZW_F) && DataLength; len++)
+ {
+ c = ReadPtr((long)&infile,PtrTypes);
+ DataLength--;
+
+ // text of size zero
+
+ LZW_ring_buffer[r + len] = c;
+ }
+
+ if (!(len && DataLength))
+ return(0);
+
+ //
+ // Insert the LZW_F strings, each of which begins with one or more
+ // 'space' characters. Note the order in which these strings
+ // are inserted. This way, degenerate trees will be less likely
+ // to occur.
+ //
+
+ for (i = 1; i <= LZW_F; i++)
+ InsertLZWNode(r - i);
+
+ //
+ // Finally, insert the whole string just read. The global
+ // variables LZW_match_len and LZW_match_pos are set. */
+ //
+
+ InsertLZWNode(r);
+
+ do {
+ // LZW_match_len may be spuriously long near the end of text.
+ //
+
+ if (LZW_match_len > len)
+ LZW_match_len = len;
+
+ if (LZW_match_len <= LZW_THRESHOLD)
+ {
+ // Not long enough match. Send one byte.
+ //
+
+ LZW_match_len = 1;
+
+ // 'send one byte' flag
+ //
+
+ code_buf[0] |= mask;
+
+ // Send uncoded.
+ //
+
+ code_buf[code_buf_ptr++] = LZW_ring_buffer[r];
+ }
+ else
+ {
+ code_buf[code_buf_ptr++] = (unsigned char) LZW_match_pos;
+ code_buf[code_buf_ptr++] = (unsigned char) (((LZW_match_pos >> 4) & 0xf0) | (LZW_match_len - (LZW_THRESHOLD + 1)));
+
+ // Send position and length pair.
+ // Note LZW_match_len > LZW_THRESHOLD.
+ }
+
+ if ((mask <<= 1) == 0)
+ {
+ // Shift mask left one bit.
+ // Send at most 8 units of data
+
+ for (i = 0; i < code_buf_ptr; i++)
+ WritePtr((long)&outfile,code_buf[i],PtrTypes);
+
+ complen += code_buf_ptr;
+ code_buf[0] = 0;
+ code_buf_ptr = mask = 1;
+ }
+
+ last_LZW_match_len = LZW_match_len;
+
+ for (i = 0; i < last_LZW_match_len && DataLength; i++)
+ {
+ c = ReadPtr((long)&infile,PtrTypes);
+ DataLength--;
+
+ DeleteLZWNode(s); // Delete old strings and
+ LZW_ring_buffer[s] = c; // read new bytes
+
+ // If the position is near the end of buffer, extend the
+ // buffer to make string comparison easier.
+
+ if (s < LZW_F - 1)
+ LZW_ring_buffer[s + LZW_N] = c;
+
+ // Since this is a ring buffer, inc the position modulo LZW_N.
+ //
+
+ s = (s + 1) & (LZW_N - 1);
+ r = (r + 1) & (LZW_N - 1);
+
+ // Register the string in LZW_ring_buffer[r..r+LZW_F-1]
+ //
+
+ InsertLZWNode(r);
+ }
+
+ while (i++ < last_LZW_match_len)
+ {
+ // After the end of text,
+ DeleteLZWNode(s); // no need to read, but
+
+ s = (s + 1) & (LZW_N - 1);
+ r = (r + 1) & (LZW_N - 1);
+
+ if (--len)
+ InsertLZWNode(r); // buffer may not be empty.
+ }
+
+ } while (len > 0); // until length of string to be processed is zero
+
+
+ if (code_buf_ptr > 1)
+ {
+ // Send remaining code.
+ //
+
+ for (i = 0; i < code_buf_ptr; i++)
+ WritePtr((long)&outfile,code_buf[i],PtrTypes);
+
+ complen += code_buf_ptr;
+ }
+
+ return(complen);
+}
+#endif
+
+
+
+
+//--------------------------------------------------------------------------
+//
+// lzwDecompress() - Compresses data from an input ptr to a dest ptr
+//
+// PARAMS:
+// infile - Pointer at the BEGINNING of the compressed data (no header!)
+// outfile - Pointer to the destination.
+// DataLength - Length of compressed data.
+// PtrTypes - Type of pointers being used (SRC_FILE,DEST_FILE,SRC_MEM etc).
+//
+// RETURNS:
+// Length of compressed data.
+//
+// COMPTYPE : ct_LZW
+//
+// NOTES : Does not write ANY header information!
+//
+void far lzwDecompress(void far *infile, void far *outfile,unsigned long DataLength,unsigned PtrTypes)
+{
+ int i, j, k, r, c;
+ unsigned int flags;
+
+ for (i = 0; i < LZW_N - LZW_F; i++)
+ LZW_ring_buffer[i] = ' ';
+
+ r = LZW_N - LZW_F;
+ flags = 0;
+
+ for ( ; ; )
+ {
+ if (((flags >>= 1) & 256) == 0)
+ {
+ c = ReadPtr((long)&infile,PtrTypes);
+ if (!DataLength--)
+ return;
+
+ flags = c | 0xff00; // uses higher byte cleverly to count 8
+ }
+
+ if (flags & 1)
+ {
+ c = ReadPtr((long)&infile,PtrTypes); // Could test for EOF iff FFILE type
+ if (!DataLength--)
+ return;
+
+ WritePtr((long)&outfile,c,PtrTypes);
+
+ LZW_ring_buffer[r++] = c;
+ r &= (LZW_N - 1);
+ }
+ else
+ {
+ i = ReadPtr((long)&infile,PtrTypes);
+ if (!DataLength--)
+ return;
+
+ j = ReadPtr((long)&infile,PtrTypes);
+ if (!DataLength--)
+ return;
+
+ i |= ((j & 0xf0) << 4);
+ j = (j & 0x0f) + LZW_THRESHOLD;
+
+ for (k = 0; k <= j; k++)
+ {
+ c = LZW_ring_buffer[(i + k) & (LZW_N - 1)];
+
+ WritePtr((long)&outfile,c,PtrTypes);
+
+ LZW_ring_buffer[r++] = c;
+ r &= (LZW_N - 1);
+ }
+ }
+ }
+}
+
+
+
+#if 0
+//=========================================================================
+//
+//
+// BUFFERED I/O ROUTINES
+//
+//
+//=========================================================================
+
+
+//--------------------------------------------------------------------------
+// InitBufferedIO()
+//--------------------------------------------------------------------------
+memptr InitBufferedIO(int handle, BufferedIO *bio)
+{
+ bio->handle = handle;
+ bio->offset = BIO_BUFFER_LEN;
+ bio->status = 0;
+ MM_GetPtr(&bio->buffer,BIO_BUFFER_LEN);
+
+ return(bio->buffer);
+}
+
+
+//--------------------------------------------------------------------------
+// FreeBufferedIO()
+//--------------------------------------------------------------------------
+void FreeBufferedIO(BufferedIO *bio)
+{
+ if (bio->buffer)
+ MM_FreePtr(&bio->buffer);
+}
+
+
+//--------------------------------------------------------------------------
+// bio_readch()
+//--------------------------------------------------------------------------
+byte bio_readch(BufferedIO *bio)
+{
+ byte far *buffer;
+
+ if (bio->offset == BIO_BUFFER_LEN)
+ {
+ bio->offset = 0;
+ bio_fillbuffer(bio);
+ }
+
+ buffer = MK_FP(bio->buffer,bio->offset++);
+
+ return(*buffer);
+}
+
+
+//--------------------------------------------------------------------------
+// bio_fillbuffer()
+//
+// BUGS (Not really bugs... More like RULES!)
+//
+// 1) This code assumes BIO_BUFFER_LEN is no smaller than
+// NEAR_BUFFER_LEN!!
+//
+// 2) BufferedIO.status should be altered by this code to report
+// read errors, end of file, etc... If you know how big the file
+// is you're reading, determining EOF should be no problem.
+//
+//--------------------------------------------------------------------------
+void bio_fillbuffer(BufferedIO *bio)
+{
+ #define NEAR_BUFFER_LEN (64)
+ byte near_buffer[NEAR_BUFFER_LEN];
+ short bio_length,bytes_read,bytes_requested;
+
+ bytes_read = 0;
+ bio_length = BIO_BUFFER_LEN;
+ while (bio_length)
+ {
+ if (bio_length > NEAR_BUFFER_LEN-1)
+ bytes_requested = NEAR_BUFFER_LEN;
+ else
+ bytes_requested = bio_length;
+
+ read(bio->handle,near_buffer,bytes_requested);
+ _fmemcpy(MK_FP(bio->buffer,bytes_read),near_buffer,bytes_requested);
+
+ bio_length -= bytes_requested;
+ bytes_read += bytes_requested;
+ }
+}
+
+
+#endif
+
+//=========================================================================
+//
+//
+// GENERAL LOAD ROUTINES
+//
+//
+//=========================================================================
+
+
+
+//--------------------------------------------------------------------------
+// BLoad()
+//--------------------------------------------------------------------------
+unsigned long BLoad(char *SourceFile, memptr *DstPtr)
+{
+ int handle;
+
+ memptr SrcPtr;
+ longword i, j, k, r, c;
+ word flags;
+ byte Buffer[8];
+ longword DstLen, SrcLen;
+ boolean comp;
+
+ if ((handle = open(SourceFile, O_RDONLY|O_BINARY)) == -1)
+ return(0);
+
+ // Look for 'COMP' header
+ //
+ read(handle,Buffer,4);
+ comp = !strncmp(Buffer,COMP,4);
+
+ // Get source and destination length.
+ //
+ if (comp)
+ {
+ SrcLen = Verify(SourceFile);
+ read(handle,(void *)&DstLen,4);
+ MM_GetPtr(DstPtr,DstLen);
+ if (!*DstPtr)
+ return(0);
+ }
+ else
+ DstLen = Verify(SourceFile);
+
+ // LZW decompress OR simply load the file.
+ //
+ if (comp)
+ {
+
+ if (MM_TotalFree() < SrcLen)
+ {
+ if (!InitBufferedIO(handle,&lzwBIO))
+ TrashProg("No memory for buffered I/O.");
+ lzwDecompress(&lzwBIO,MK_FP(*DstPtr,0),SrcLen,(SRC_BFILE|DEST_MEM));
+ FreeBufferedIO(&lzwBIO);
+ }
+ else
+ {
+ CA_LoadFile(SourceFile,&SrcPtr);
+ lzwDecompress(MK_FP(SrcPtr,8),MK_FP(*DstPtr,0),SrcLen,(SRC_MEM|DEST_MEM));
+ MM_FreePtr(&SrcPtr);
+ }
+ }
+ else
+ CA_LoadFile(SourceFile,DstPtr);
+
+ close(handle);
+ return(DstLen);
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+//
+// LoadLIBShape()
+//
+int LoadLIBShape(char *SLIB_Filename, char *Filename,struct Shape *SHP)
+{
+ #define CHUNK(Name) (*ptr == *Name) && \
+ (*(ptr+1) == *(Name+1)) && \
+ (*(ptr+2) == *(Name+2)) && \
+ (*(ptr+3) == *(Name+3))
+
+
+ int RT_CODE;
+ FILE *fp;
+ char CHUNK[5];
+ char far *ptr;
+ memptr IFFfile = NULL;
+ unsigned long FileLen, size, ChunkLen;
+ int loop;
+
+
+ RT_CODE = 1;
+
+ // Decompress to ram and return ptr to data and return len of data in
+ // passed variable...
+
+ if (!LoadLIBFile(SLIB_Filename,Filename,&IFFfile))
+ TrashProg("Error Loading Compressed lib shape!");
+
+ // Evaluate the file
+ //
+ ptr = MK_FP(IFFfile,0);
+ if (!CHUNK("FORM"))
+ goto EXIT_FUNC;
+ ptr += 4;
+
+ FileLen = *(long far *)ptr;
+ SwapLong((long far *)&FileLen);
+ ptr += 4;
+
+ if (!CHUNK("ILBM"))
+ goto EXIT_FUNC;
+ ptr += 4;
+
+ FileLen += 4;
+ while (FileLen)
+ {
+ ChunkLen = *(long far *)(ptr+4);
+ SwapLong((long far *)&ChunkLen);
+ ChunkLen = (ChunkLen+1) & 0xFFFFFFFE;
+
+ if (CHUNK("BMHD"))
+ {
+ ptr += 8;
+ SHP->bmHdr.w = ((struct BitMapHeader far *)ptr)->w;
+ SHP->bmHdr.h = ((struct BitMapHeader far *)ptr)->h;
+ SHP->bmHdr.x = ((struct BitMapHeader far *)ptr)->x;
+ SHP->bmHdr.y = ((struct BitMapHeader far *)ptr)->y;
+ SHP->bmHdr.d = ((struct BitMapHeader far *)ptr)->d;
+ SHP->bmHdr.trans = ((struct BitMapHeader far *)ptr)->trans;
+ SHP->bmHdr.comp = ((struct BitMapHeader far *)ptr)->comp;
+ SHP->bmHdr.pad = ((struct BitMapHeader far *)ptr)->pad;
+ SwapWord(&SHP->bmHdr.w);
+ SwapWord(&SHP->bmHdr.h);
+ SwapWord(&SHP->bmHdr.x);
+ SwapWord(&SHP->bmHdr.y);
+ ptr += ChunkLen;
+ }
+ else
+ if (CHUNK("BODY"))
+ {
+ ptr += 4;
+ size = *((long far *)ptr);
+ ptr += 4;
+ SwapLong((long far *)&size);
+ SHP->BPR = (SHP->bmHdr.w+7) >> 3;
+ MM_GetPtr(&SHP->Data,size);
+ if (!SHP->Data)
+ goto EXIT_FUNC;
+ movedata(FP_SEG(ptr),FP_OFF(ptr),FP_SEG(SHP->Data),0,size);
+ ptr += ChunkLen;
+
+ break;
+ }
+ else
+ ptr += ChunkLen+8;
+
+ FileLen -= ChunkLen+8;
+ }
+
+ RT_CODE = 0;
+
+EXIT_FUNC:;
+ if (IFFfile)
+ {
+// segptr = (memptr)FP_SEG(IFFfile);
+ MM_FreePtr(&IFFfile);
+ }
+
+ return (RT_CODE);
+}
+
+
+
+
+
+//----------------------------------------------------------------------------
+// LoadLIBFile() -- Copies a file from an existing archive to dos.
+//
+// PARAMETERS :
+//
+// LibName - Name of lib file created with SoftLib V1.0
+//
+// FileName - Name of file to load from lib file.
+//
+// MemPtr - (IF !NULL) - Pointer to memory to load into ..
+// (IF NULL) - Routine allocates necessary memory and
+// returns a MEM(SEG) pointer to memory allocated.
+//
+// RETURN :
+//
+// (IF !NULL) - A pointer to the loaded data.
+// (IF NULL) - Error!
+//
+//----------------------------------------------------------------------------
+memptr LoadLIBFile(char *LibName,char *FileName,memptr *MemPtr)
+{
+ int handle;
+ unsigned long header;
+ struct ChunkHeader Header;
+ unsigned long ChunkLen;
+ short x;
+ struct FileEntryHdr FileEntry; // Storage for file once found
+ struct FileEntryHdr FileEntryHeader; // Header used durring searching
+ struct SoftLibHdr LibraryHeader; // Library header - Version Checking
+ boolean FileFound = false;
+ unsigned long id_slib = ID_SLIB;
+ unsigned long id_chunk = ID_CHUNK;
+
+
+ //
+ // OPEN SOFTLIB FILE
+ //
+
+ if ((handle = open(LibName,O_RDONLY | O_BINARY, S_IREAD)) == -1)
+ return(NULL);
+
+
+ //
+ // VERIFY it is a SOFTLIB (SLIB) file
+ //
+
+ if (read(handle,&header,4) == -1)
+ {
+ close(handle);
+ return(NULL);
+ }
+
+ if (header != id_slib)
+ {
+ close(handle);
+ return(NULL);
+ }
+
+
+ //
+ // CHECK LIBRARY HEADER VERSION NUMBER
+ //
+
+ if (read(handle, &LibraryHeader,sizeof(struct SoftLibHdr)) == -1)
+ TrashProg("read error in LoadSLIBFile()\n%c",7);
+
+ if (LibraryHeader.Version > SOFTLIB_VER)
+ TrashProg("Unsupported file ver %d",LibraryHeader.Version);
+
+
+ //
+ // MANAGE FILE ENTRY HEADERS...
+ //
+
+ for (x = 1;x<=LibraryHeader.FileCount;x++)
+ {
+ if (read(handle, &FileEntryHeader,sizeof(struct FileEntryHdr)) == -1)
+ {
+ close(handle);
+ return(NULL);
+ }
+
+ if (!stricmp(FileEntryHeader.FileName,FileName))
+ {
+ FileEntry = FileEntryHeader;
+ FileFound = true;
+ }
+ }
+
+ //
+ // IF FILE HAS BEEN FOUND THEN SEEK TO POSITION AND EXTRACT
+ // ELSE RETURN WITH ERROR CODE...
+ //
+
+ if (FileFound)
+ {
+ if (lseek(handle,FileEntry.Offset,SEEK_CUR) == -1)
+ {
+ close(handle);
+ return(NULL);
+ }
+
+ //
+ // READ CHUNK HEADER - Verify we are at the beginning of a chunk..
+ //
+
+ if (read(handle,(char *)&Header,sizeof(struct ChunkHeader)) == -1)
+ TrashProg("LIB File - Unable to read Header!");
+
+ if (Header.HeaderID != id_chunk)
+ TrashProg("LIB File - BAD HeaderID!");
+
+ //
+ // Allocate memory if Necessary...
+ //
+
+
+ if (!*MemPtr)
+ MM_GetPtr(MemPtr,FileEntry.OrginalLength);
+
+ //
+ // Calculate the length of the data (without the chunk header).
+ //
+
+ ChunkLen = FileEntry.ChunkLen - sizeof(struct ChunkHeader);
+
+
+ //
+ // Extract Data from file
+ //
+
+ switch (Header.Compression)
+ {
+ case ct_LZW:
+ if (!InitBufferedIO(handle,&lzwBIO))
+ TrashProg("No memory for buffered I/O.");
+ lzwDecompress(&lzwBIO,MK_FP(*MemPtr,0),ChunkLen,(SRC_BFILE|DEST_MEM));
+ FreeBufferedIO(&lzwBIO);
+ break;
+
+ case ct_NONE:
+ if (!CA_FarRead(handle,MK_FP(*MemPtr,0),ChunkLen))
+ {
+ close(handle);
+ *MemPtr = NULL;
+ }
+ break;
+
+ default:
+ close(handle);
+ TrashProg("Uknown Chunk.Compression Type!");
+ break;
+ }
+ }
+ else
+ *MemPtr = NULL;
+
+ close(handle);
+ return(*MemPtr);
+}
+
+
+
+
diff --git a/JAMPAK.H b/JAMPAK.H
new file mode 100644
index 0000000..43f95ed
--- /dev/null
+++ b/JAMPAK.H
@@ -0,0 +1,118 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+//
+//
+//
+//
+//
+
+
+#define LZW_N 4096
+#define LZW_F 18
+
+
+// LZW_THRESHOLD :encode string into position and length if match_length is
+// greater than this
+
+#define LZW_THRESHOLD 2
+
+// index for root of binary search trees
+//
+
+#define LZW_NIL LZW_N
+
+
+//
+// FILE CHUNK IDs
+//
+// NOTE: The only reason for changing from COMP to CMP2 and having multi
+// comp header structs is for downward compatablity.
+//
+
+#define COMP ("COMP") // Comp type is ct_LZW ALWAYS!
+#define CMP2 ("CMP2") // Comp type is determined in header.
+
+
+//
+// COMPRESSION TYPES
+//
+
+#if 0
+//
+// FILE CHUNK HEADER FORMATS
+//
+
+struct COMPStruct
+{
+ unsigned long DecompLen;
+
+};
+
+
+struct CMP2Header
+{
+ unsigned CompType;
+ unsigned long DecompLen;
+
+};
+#endif
+
+memptr segptr;
+extern BufferedIO lzwBIO;
+
+
+//
+// PARAMETER PASSING TYPES (POINTER TYPES)
+//
+
+#define SRC_FILE (0x0001) // C's non-buffered file i/o
+#define SRC_FFILE (0x0002) // C's buffered ffile i/o
+#define SRC_MEM (0x0004) // FAR memory Ptrs
+#define SRC_BFILE (0x0008) // Buffered File I/O
+
+#define SRC_TYPES (SRC_FILE | SRC_FFILE | SRC_MEM | SRC_BFILE)
+
+#define DEST_FILE (0x0100) // C's non-buffered file i/o
+#define DEST_FFILE (0x0200) // C's buffered ffile i/o
+#define DEST_MEM (0x0400) // FAR memory Ptrs
+
+#define DEST_TYPES (DEST_FILE | DEST_FFILE | DEST_MEM)
+
+
+//---------------------------------------------------------------------------
+// FUNCTION PROTOTYPEING
+//---------------------------------------------------------------------------
+
+//void DecompressFILEtoFILE(FILE *infile, FILE *outfile);
+//unsigned long CompressFILEtoFILE(FILE *infile, FILE *outfile,unsigned long DataLength);
+
+
+unsigned long lzwCompress(void far *infile, void far *outfile,unsigned long DataLength,unsigned PtrTypes);
+void lzwDecompress(void far *infile, void far *outfile,unsigned long DataLength,unsigned PtrTypes);
+
+int WritePtr(long outfile, unsigned char data, unsigned PtrType);
+int ReadPtr(long infile, unsigned PtrType);
+
+//memptr InitBufferedIO(int handle, BufferedIO *bio);
+//void FreeBufferedIO(BufferedIO *bio);
+//byte bio_readch(BufferedIO *bio);
+
+unsigned long BLoad(char *SourceFile, memptr *DstPtr);
+memptr LoadLIBFile(char *LibName,char *FileName,memptr *MemPtr);
+int LoadLIBShape(char *SLIB_Filename, char *Filename,struct Shape *SHP);
diff --git a/JAM_IO.C b/JAM_IO.C
new file mode 100644
index 0000000..d0b019a
--- /dev/null
+++ b/JAM_IO.C
@@ -0,0 +1,121 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <alloc.h>
+#include <fcntl.h>
+#include <dos.h>
+#include <io.h>
+
+#include "def.h"
+#include "gelib.h"
+#include "jam_io.h"
+
+//----------------------------------------------------------------------------
+//
+// PTR/PTR COMPRESSION ROUTINES
+//
+//
+//----------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+// WritePtr() -- Outputs data to a particular ptr type
+//
+// PtrType MUST be of type DEST_TYPE.
+//
+// NOTE : For PtrTypes DEST_MEM a ZERO (0) is always returned.
+//
+//---------------------------------------------------------------------------
+char WritePtr(long outfile, unsigned char data, unsigned PtrType)
+{
+ int returnval = 0;
+
+ switch (PtrType & DEST_TYPES)
+ {
+ case DEST_FILE:
+ write(*(int far *)outfile,(char *)&data,1);
+ break;
+
+ case DEST_FFILE:
+ returnval = putc(data, *(FILE **)outfile);
+ break;
+
+ case DEST_IMEM:
+ printf("WritePtr - unsupported ptr type\n");
+ exit(0);
+ break;
+
+ case DEST_MEM:
+ *((char far *)*(char far **)outfile)++ = data;
+ break;
+ }
+
+ return(returnval);
+
+}
+
+
+//---------------------------------------------------------------------------
+// ReadPtr() -- Reads data from a particular ptr type
+//
+// PtrType MUST be of type SRC_TYPE.
+//
+// RETURNS :
+// The char read in or EOF for SRC_FFILE type of reads.
+//
+//
+//---------------------------------------------------------------------------
+int ReadPtr(long infile, unsigned PtrType)
+{
+ int returnval = 0;
+
+ switch (PtrType & SRC_TYPES)
+ {
+ case SRC_FILE:
+ read(*(int far *)infile,(char *)&returnval,1);
+ break;
+
+ case SRC_FFILE:
+ returnval = getc(*(FILE far **)infile
+ );
+ break;
+
+ case SRC_BFILE:
+ returnval = bio_readch((BufferedIO *)*(void far **)infile);
+ break;
+
+// case SRC_IMEM:
+// printf("WritePtr - unsupported ptr type\n");
+// exit(0);
+// break;
+
+ case SRC_MEM:
+ returnval = (unsigned char)*((char far *)*(char far **)infile)++;
+ break;
+ }
+
+ return(returnval);
+}
+
+
+
diff --git a/JAM_IO.H b/JAM_IO.H
new file mode 100644
index 0000000..77db01d
--- /dev/null
+++ b/JAM_IO.H
@@ -0,0 +1,107 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+//
+// UNIT : JAM_IO.h
+//
+// FUNCTION : General defines, prototypes, typedefs used in all the
+// supported compression techniques used in JAMPAK Ver x.x
+//
+//
+
+
+
+
+//==========================================================================
+//
+// PARAMETER PASSING TYPES
+//
+//
+ // SOURCE PARAMS (LO BYTE)
+
+#define SRC_FILE (0x0001) // GE Buffered IO
+#define SRC_FFILE (0x0002) // Stdio File IO (fwrite etc.)
+#define SRC_MEM (0x0004) // Std void ptr (alloc etc)
+#define SRC_BFILE (0x0008) // Buffered File I/O
+
+#define SRC_TYPES (SRC_FILE | SRC_FFILE | SRC_MEM | SRC_BFILE)
+
+ // DESTINATION PARAMS (HI BYTE)
+
+#define DEST_FILE (0x0100) // GE Buffered IO
+#define DEST_FFILE (0x0200) // Stdio File IO (fwrite etc.)
+#define DEST_MEM (0x0400) // Std void ptr (alloc etc)
+#define DEST_IMEM (0x0800) // ID Memory alloc
+
+#define DEST_TYPES (DEST_FILE | DEST_FFILE | DEST_MEM | DEST_IMEM)
+
+
+
+//=========================================================================
+//
+// FILE CHUNK IDs
+//
+// NOTE: The only reason for changing from COMP to CMP1 and having multi
+// comp header structs is for downward compatablity.
+//
+
+#define COMP ("COMP") // Comp type is ct_LZW ALWAYS!
+#define CMP1 ("CMP1") // Comp type is determined in header.
+
+
+//
+// COMPRESSION TYPES
+//
+typedef enum ct_TYPES
+{
+ ct_NONE = 0, // No compression - Just data..Rarely used!
+ ct_LZW, // LZW data compression
+ ct_LZH,
+
+} ct_TYPES;
+
+//
+// FILE CHUNK HEADER FORMATS
+//
+
+struct COMPStruct
+{
+ unsigned long DecompLen;
+
+};
+
+
+struct CMP1Header
+{
+ unsigned CompType; // SEE: ct_TYPES above for list of pos.
+ unsigned long OrginalLen; // Orginal FileLength of compressed Data.
+ unsigned long CompressLen; // Length of data after compression (A MUST for LZHUFF!)
+};
+
+
+
+//---------------------------------------------------------------------------
+//
+// FUNCTION PROTOTYPEING
+//
+//---------------------------------------------------------------------------
+
+char WritePtr(long outfile, unsigned char data, unsigned PtrType);
+int ReadPtr(long infile, unsigned PtrType);
+
+
diff --git a/LZHUF.C b/LZHUF.C
new file mode 100644
index 0000000..bca738e
--- /dev/null
+++ b/LZHUF.C
@@ -0,0 +1,1069 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+//===========================================================================
+//
+// LZHUFF COMPRESSION ROUTINES
+// VERSION 1.0
+//
+// Compression algrythim by Haruhiko OKUMURA
+// Implementation by Jim T. Row
+//
+//
+// Copyright (c) 1992 - Softdisk Publishing inc. - All rights reserved
+//
+//===========================================================================
+//
+// Compiler #ifdef switches
+//
+// LZHUFF_COMPRESSION & LZHUFF_DECOMPRESSION - not yet functional!
+//
+// Usage Explanition :
+//
+// if LZHUFF_COMPRESSION is defined then the compression code & data is
+// compiled and so-forth for the decompression code.
+//
+//---------------------------------------------------------------------------
+
+
+
+#include <fcntl.h>
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <alloc.h>
+#include <dos.h>
+
+#include "lzhuff.h"
+#include "jam_io.h"
+
+
+
+//===========================================================================
+//
+// SWITCHES
+//
+// NOTE : Make sure the appropriate switches are set in SOFT.c for Softlib
+// archive support.
+//
+//===========================================================================
+
+
+#define INCLUDE_LZH_COMP 0
+#define INCLUDE_LZH_DECOMP 1
+
+
+
+
+
+//===========================================================================
+//
+// DEFINES
+//
+//===========================================================================
+
+
+#define EXIT_OK 0
+#define EXIT_FAILED -1
+
+/* LZSS Parameters */
+
+#define N 4096 /* Size of string buffer */
+#define F 30 /* Size of look-ahead buffer */
+#define THRESHOLD 2
+#define NIL N /* End of tree's node */
+
+/* Huffman coding parameters */
+
+#define N_CHAR (256 - THRESHOLD + F) /* character code (= 0..N_CHAR-1) */
+#define T (N_CHAR * 2 - 1) /* Size of table */
+#define R (T - 1) /* root position */
+#define MAX_FREQ 0x8000 /* update when cumulative frequency */
+ /* reaches to this value */
+
+
+//==========================================================================
+//
+// LOCAL PROTOTYPES
+//
+//==========================================================================
+
+
+static void StartHuff();
+static void reconst();
+static void update(int c);
+
+
+static void DeleteNode(int p); /* Deleting node from the tree */
+static void InsertNode(int r); /* Inserting node to the tree */
+static void InitTree(void); /* Initializing tree */
+static void Putcode(long outfile_ptr, int l, unsigned c,unsigned PtrTypes); /* output c bits */
+static void EncodeChar(long outfile_ptr, unsigned c, unsigned PtrTypes);
+static void EncodePosition(long outfile_ptr, unsigned c, unsigned PtrTypes);
+static void EncodeEnd(long outfile_ptr,unsigned PtrTypes);
+
+
+static int GetByte(long infile_ptr, unsigned long *CompressLength, unsigned PtrTypes);
+static int GetBit(long infile_ptr, unsigned long *CompressLength, unsigned PtrTypes); /* get one bit */
+static int DecodeChar(long infile_ptr, unsigned long *CompressLength, unsigned PtrTypes);
+static int DecodePosition(long infile_ptr,unsigned long *CompressLength, unsigned PtrTypes);
+
+
+
+
+//==========================================================================
+//
+// USER AVAILABLE VECTORS
+//
+//==========================================================================
+
+
+
+
+//---------------------------------------------------------------------------
+//
+// LZHUFF DISPLAY VECTORS
+//
+// These vectors allow you to hook up any form of display you desire for
+// displaying the compression/decompression status.
+//
+// These routines are called inside of the compression/decompression routines
+// and pass the orginal size of data and current position within that
+// data. This allows for any kind of "% Done" messages.
+//
+// Your functions MUST have the following parameters in this order...
+//
+// void VectorRoutine(unsigned long OrginalSize,unsigned long CurPosition)
+//
+//
+
+#if INCLUDE_LZH_COMP
+void (*LZH_CompressDisplayVector)() = NULL;
+#endif
+
+#if INCLUDE_LZH_DECOMP
+void (*LZH_DecompressDisplayVector)() = NULL;
+#endif
+
+
+
+
+//===========================================================================
+//
+// GLOBAL VARIABLES
+//
+//===========================================================================
+ /* pointing children nodes (son[], son[] + 1)*/
+
+int far son[T];
+unsigned code, len;
+
+ //
+ // pointing parent nodes.
+ // area [T..(T + N_CHAR - 1)] are pointers for leaves
+ //
+
+int far prnt[T + N_CHAR];
+
+unsigned far freq[T + 1]; /* cumulative freq table */
+
+unsigned long textsize = 0, codesize = 0, printcount = 0,datasize;
+unsigned char far text_buf[N + F - 1];
+
+
+
+ //
+ // COMPRESSION VARIABLES
+ //
+
+#if INCLUDE_LZH_COMP
+
+static int match_position,match_length, lson[N + 1], rson[N + 257], dad[N + 1];
+unsigned putbuf = 0;
+unsigned char putlen = 0;
+
+ //
+ // Tables for encoding/decoding upper 6 bits of
+ // sliding dictionary pointer
+ //
+
+ //
+ // encoder table
+ //
+
+unsigned char far p_len[64] = {
+ 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
+};
+
+unsigned char far p_code[64] = {
+ 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
+ 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
+ 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
+ 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
+ 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
+ 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
+};
+#endif
+
+
+ //
+ // DECOMPRESSION VARIABLES
+ //
+
+
+ //
+ // decoder table
+ //
+
+#if INCLUDE_LZH_DECOMP
+
+unsigned char far d_code[256] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
+ 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
+ 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
+ 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
+ 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
+ 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
+ 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
+ 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
+ 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
+ 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
+ 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
+ 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
+ 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
+ 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+};
+
+unsigned char far d_len[256] = {
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+};
+
+unsigned getbuf = 0;
+unsigned char getlen = 0;
+
+#endif
+
+
+
+//===========================================================================
+//
+// COMPRESSION & DECOMPRESSION ROUTINES
+//
+//===========================================================================
+
+
+
+
+
+
+
+//---------------------------------------------------------------------------
+// StartHuff /* initialize freq tree */
+//---------------------------------------------------------------------------
+static void StartHuff()
+{
+ int i, j;
+
+ for (i = 0; i < N_CHAR; i++) {
+ freq[i] = 1;
+ son[i] = i + T;
+ prnt[i + T] = i;
+ }
+ i = 0; j = N_CHAR;
+ while (j <= R) {
+ freq[j] = freq[i] + freq[i + 1];
+ son[j] = i;
+ prnt[i] = prnt[i + 1] = j;
+ i += 2; j++;
+ }
+ freq[T] = 0xffff;
+ prnt[R] = 0;
+}
+
+
+
+
+
+
+//---------------------------------------------------------------------------
+// reconst /* reconstruct freq tree */
+//---------------------------------------------------------------------------
+static void reconst()
+{
+ int i, j, k;
+ unsigned f, l;
+
+ /* halven cumulative freq for leaf nodes */
+
+ j = 0;
+
+ for (i = 0; i < T; i++)
+ {
+ if (son[i] >= T)
+ {
+ freq[j] = (freq[i] + 1) / 2;
+ son[j] = son[i];
+ j++;
+ }
+ }
+
+ /* make a tree : first, connect children nodes */
+
+ for (i = 0, j = N_CHAR; j < T; i += 2, j++)
+ {
+ k = i + 1;
+ f = freq[j] = freq[i] + freq[k];
+
+ for (k = j - 1;f < freq[k]; k--);
+
+ k++;
+ l = (j - k) * 2;
+
+ (void)memmove(&freq[k + 1], &freq[k], l);
+ freq[k] = f;
+
+ (void)memmove(&son[k + 1], &son[k], l);
+ son[k] = i;
+ }
+
+ /* connect parent nodes */
+
+ for (i = 0; i < T; i++)
+ {
+ if ((k = son[i]) >= T)
+ {
+ prnt[k] = i;
+ }
+ else
+ {
+ prnt[k] = prnt[k + 1] = i;
+ }
+ }
+}
+
+
+
+
+
+
+//---------------------------------------------------------------------------
+// update() update freq tree
+//---------------------------------------------------------------------------
+static void update(int c)
+{
+ int i, j, k, l;
+
+ if (freq[R] == MAX_FREQ)
+ {
+ reconst();
+ }
+
+ c = prnt[c + T];
+
+ do {
+ k = ++freq[c];
+
+ //
+ // swap nodes to keep the tree freq-ordered
+ //
+
+ if (k > freq[l = c + 1])
+ {
+ while (k > freq[++l]);
+
+ l--;
+ freq[c] = freq[l];
+ freq[l] = k;
+
+ i = son[c];
+ prnt[i] = l;
+ if (i < T)
+ prnt[i + 1] = l;
+
+ j = son[l];
+ son[l] = i;
+
+ prnt[j] = c;
+ if (j < T)
+ prnt[j + 1] = c;
+
+ son[c] = j;
+
+ c = l;
+ }
+ } while ((c = prnt[c]) != 0); /* do it until reaching the root */
+}
+
+
+
+
+//===========================================================================
+//
+// COMPRESSION ROUTINES
+//
+//===========================================================================
+
+
+
+
+
+
+#if INCLUDE_LZH_COMP
+
+
+//---------------------------------------------------------------------------
+// DeleteNode
+//---------------------------------------------------------------------------
+static void DeleteNode(int p) /* Deleting node from the tree */
+{
+ int q;
+
+ if (dad[p] == NIL)
+ return; /* unregistered */
+
+ if (rson[p] == NIL)
+ q = lson[p];
+ else
+ if (lson[p] == NIL)
+ q = rson[p];
+ else
+ {
+ q = lson[p];
+ if (rson[q] != NIL)
+ {
+ do {
+ q = rson[q];
+ } while (rson[q] != NIL);
+
+ rson[dad[q]] = lson[q];
+ dad[lson[q]] = dad[q];
+ lson[q] = lson[p];
+ dad[lson[p]] = q;
+ }
+
+ rson[q] = rson[p];
+ dad[rson[p]] = q;
+ }
+
+ dad[q] = dad[p];
+
+ if (rson[dad[p]] == p)
+ rson[dad[p]] = q;
+ else
+ lson[dad[p]] = q;
+
+ dad[p] = NIL;
+}
+
+
+
+
+
+
+//---------------------------------------------------------------------------
+// InsertNode
+//---------------------------------------------------------------------------
+static void InsertNode(int r) /* Inserting node to the tree */
+{
+ int i, p, cmp;
+ unsigned char *key;
+ unsigned c;
+
+ cmp = 1;
+ key = &text_buf[r];
+ p = N + 1 + key[0];
+ rson[r] = lson[r] = NIL;
+ match_length = 0;
+ for ( ; ; )
+ {
+ if (cmp >= 0)
+ {
+ if (rson[p] != NIL)
+ p = rson[p];
+ else
+ {
+ rson[p] = r;
+ dad[r] = p;
+ return;
+ }
+ }
+ else
+ {
+ if (lson[p] != NIL)
+ p = lson[p];
+ else
+ {
+ lson[p] = r;
+ dad[r] = p;
+ return;
+ }
+ }
+
+
+ for (i = 1; i < F; i++)
+ if ((cmp = key[i] - text_buf[p + i]) != 0)
+ break;
+
+ if (i > THRESHOLD)
+ {
+ if (i > match_length)
+ {
+ match_position = ((r - p) & (N - 1)) - 1;
+ if ((match_length = i) >= F)
+ break;
+ }
+
+ if (i == match_length)
+ {
+ if ((c = ((r - p) & (N - 1)) - 1) < match_position)
+ {
+ match_position = c;
+ }
+ }
+ }
+ }
+
+ dad[r] = dad[p];
+ lson[r] = lson[p];
+ rson[r] = rson[p];
+ dad[lson[p]] = r;
+ dad[rson[p]] = r;
+
+ if (rson[dad[p]] == p)
+ rson[dad[p]] = r;
+ else
+ lson[dad[p]] = r;
+
+ dad[p] = NIL; /* remove p */
+}
+
+
+
+
+
+//---------------------------------------------------------------------------
+// InitTree
+//---------------------------------------------------------------------------
+static void InitTree(void) /* Initializing tree */
+{
+ int i;
+
+ for (i = N + 1; i <= N + 256; i++)
+ rson[i] = NIL; /* root */
+
+ for (i = 0; i < N; i++)
+ dad[i] = NIL; /* node */
+}
+
+
+
+
+
+
+//---------------------------------------------------------------------------
+// Putcode
+//---------------------------------------------------------------------------
+static void Putcode(long outfile_ptr, int l, unsigned c,unsigned PtrTypes) /* output c bits */
+{
+ putbuf |= c >> putlen;
+
+ if ((putlen += l) >= 8)
+ {
+ WritePtr(outfile_ptr, putbuf >> 8, PtrTypes);
+ codesize++;
+
+ if ((putlen -= 8) >= 8)
+ {
+ WritePtr(outfile_ptr, putbuf, PtrTypes);
+ codesize++;
+
+ putlen -= 8;
+ putbuf = c << (l - putlen);
+ }
+ else
+ {
+ putbuf <<= 8;
+ }
+ }
+}
+
+
+
+
+
+
+//---------------------------------------------------------------------------
+// EncodeChar
+//---------------------------------------------------------------------------
+static void EncodeChar(long outfile_ptr, unsigned c, unsigned PtrTypes)
+{
+ unsigned i;
+ int j, k;
+
+ i = 0;
+ j = 0;
+ k = prnt[c + T];
+
+ /* search connections from leaf node to the root */
+
+ do {
+ i >>= 1;
+
+ //
+ // if node's address is odd, output 1 else output 0
+ //
+
+ if (k & 1)
+ i += 0x8000;
+
+ j++;
+ } while ((k = prnt[k]) != R);
+
+ Putcode(outfile_ptr, j, i, PtrTypes);
+
+ code = i;
+ len = j;
+ update(c);
+}
+
+
+
+
+//---------------------------------------------------------------------------
+// EncodePosition
+//---------------------------------------------------------------------------
+static void EncodePosition(long outfile_ptr, unsigned c, unsigned PtrTypes)
+{
+ unsigned i;
+
+ //
+ // output upper 6 bits with encoding
+ //
+
+ i = c >> 6;
+ Putcode(outfile_ptr, p_len[i], (unsigned)p_code[i] << 8,PtrTypes);
+
+ //
+ // output lower 6 bits directly
+ //
+
+ Putcode(outfile_ptr, 6, (c & 0x3f) << 10,PtrTypes);
+}
+
+
+
+
+//---------------------------------------------------------------------------
+// EncodeEnd
+//---------------------------------------------------------------------------
+static void EncodeEnd(long outfile_ptr,unsigned PtrTypes)
+{
+ if (putlen)
+ {
+ WritePtr(outfile_ptr,(putbuf >> 8),PtrTypes);
+ codesize++;
+ }
+}
+
+#endif
+
+
+
+
+
+//===========================================================================
+//
+// DECOMPRESSION ROUTINES
+//
+//===========================================================================
+
+
+
+#if INCLUDE_LZH_DECOMP
+
+//---------------------------------------------------------------------------
+// GetByte
+//---------------------------------------------------------------------------
+static int GetByte(long infile_ptr, unsigned long *CompressLength, unsigned PtrTypes)
+{
+ unsigned i;
+
+ while (getlen <= 8)
+ {
+ if (*CompressLength)
+ {
+ i = ReadPtr(infile_ptr,PtrTypes);
+ (*CompressLength)--;
+ }
+ else
+ i = 0;
+
+ getbuf |= i << (8 - getlen);
+ getlen += 8;
+ }
+
+ i = getbuf;
+ getbuf <<= 8;
+ getlen -= 8;
+ return i>>8;
+}
+
+
+
+
+
+
+//---------------------------------------------------------------------------
+// GetBit
+//---------------------------------------------------------------------------
+static int GetBit(long infile_ptr, unsigned long *CompressLength, unsigned PtrTypes) /* get one bit */
+{
+ int i;
+
+ while (getlen <= 8)
+ {
+ if (*CompressLength)
+ {
+ i = ReadPtr(infile_ptr,PtrTypes);
+ (*CompressLength)--;
+ }
+ else
+ i = 0;
+
+ getbuf |= i << (8 - getlen);
+ getlen += 8;
+ }
+
+ i = getbuf;
+ getbuf <<= 1;
+ getlen--;
+ return (i < 0);
+}
+
+
+
+
+
+//---------------------------------------------------------------------------
+// DecodeChar
+//---------------------------------------------------------------------------
+static int DecodeChar(long infile_ptr, unsigned long *CompressLength, unsigned PtrTypes)
+{
+ unsigned c;
+
+ c = son[R];
+
+ /*
+ * start searching tree from the root to leaves.
+ * choose node #(son[]) if input bit == 0
+ * else choose #(son[]+1) (input bit == 1)
+ */
+
+ while (c < T)
+ {
+ c += GetBit(infile_ptr,CompressLength,PtrTypes);
+ c = son[c];
+ }
+
+ c -= T;
+ update(c);
+ return c;
+}
+
+
+
+
+
+//---------------------------------------------------------------------------
+// DecodePosition
+//---------------------------------------------------------------------------
+static int DecodePosition(long infile_ptr,unsigned long *CompressLength, unsigned PtrTypes)
+{
+ unsigned i, j, c;
+
+ //
+ // decode upper 6 bits from given table
+ //
+
+ i = GetByte(infile_ptr, CompressLength, PtrTypes);
+ c = (unsigned)d_code[i] << 6;
+ j = d_len[i];
+
+ //
+ // input lower 6 bits directly
+ //
+
+ j -= 2;
+ while (j--)
+ {
+ i = (i << 1) + GetBit(infile_ptr, CompressLength, PtrTypes);
+ }
+
+ return c | i & 0x3f;
+}
+
+#endif
+
+
+
+
+
+//===========================================================================
+//
+// EXTERNAL REFERENCED
+// COMPRESSION & DECOMPRESSION
+// ROUTINES
+//
+//===========================================================================
+
+
+
+
+#if INCLUDE_LZH_DECOMP
+
+//---------------------------------------------------------------------------
+// lzhDecompress()
+//---------------------------------------------------------------------------
+long lzhDecompress(void far *infile, void far *outfile, unsigned long OrginalLength, unsigned long CompressLength, unsigned PtrTypes)
+{
+ int i, j, k, r, c;
+ long count;
+
+ datasize = textsize = OrginalLength;
+ getbuf = 0;
+ getlen = 0;
+
+ if (textsize == 0)
+ return;
+
+ StartHuff();
+ for (i = 0; i < N - F; i++)
+ text_buf[i] = ' ';
+
+ r = N - F;
+
+ for (count = 0; count < textsize; )
+ {
+ c = DecodeChar((long)&infile,&CompressLength,PtrTypes);
+
+ if (c < 256)
+ {
+ WritePtr((long)&outfile,c,PtrTypes);
+ datasize--; // Dec # of bytes to write
+
+ text_buf[r++] = c;
+ r &= (N - 1);
+ count++; // inc count of bytes written
+ }
+ else
+ {
+ i = (r - DecodePosition((long)&infile,&CompressLength,PtrTypes) - 1) & (N - 1);
+ j = c - 255 + THRESHOLD;
+
+ for (k = 0; k < j; k++)
+ {
+ c = text_buf[(i + k) & (N - 1)];
+
+ WritePtr((long)&outfile,c,PtrTypes);
+ datasize--; // dec count of bytes to write
+
+ text_buf[r++] = c;
+ r &= (N - 1);
+ count++; // inc count of bytes written
+ }
+ }
+
+ if (LZH_DecompressDisplayVector && (count > printcount))
+ {
+ LZH_DecompressDisplayVector(OrginalLength,OrginalLength-datasize);
+ printcount += 1024;
+ }
+ }
+
+// printf("%12ld\n", count);
+
+ return(count);
+}
+
+#endif
+
+
+
+
+
+#if INCLUDE_LZH_COMP
+
+//---------------------------------------------------------------------------
+// lzhCompress()
+//---------------------------------------------------------------------------
+long lzhCompress(void far *infile, void far *outfile,unsigned long DataLength,unsigned PtrTypes)
+{
+ int i, c, len, r, s, last_match_length;
+
+ textsize = DataLength;
+
+ if (textsize == 0)
+ return;
+
+ getbuf = 0;
+ getlen = 0;
+ textsize = 0; /* rewind and rescan */
+ codesize = 0;
+ datasize = 0; // Init our counter of ReadData...
+ StartHuff();
+ InitTree();
+
+ s = 0;
+ r = N - F;
+
+ for (i = s; i < r; i++)
+ text_buf[i] = ' ';
+
+ for (len = 0; len < F && (DataLength > datasize); len++)
+ {
+ c = ReadPtr((long)&infile,PtrTypes);
+ datasize++; // Dec num of bytes to compress
+ text_buf[r + len] = c;
+ }
+
+ textsize = len;
+
+ for (i = 1; i <= F; i++)
+ InsertNode(r - i);
+
+ InsertNode(r);
+
+ do {
+ if (match_length > len)
+ match_length = len;
+
+ if (match_length <= THRESHOLD)
+ {
+ match_length = 1;
+ EncodeChar((long)&outfile,text_buf[r],PtrTypes);
+ }
+ else
+ {
+ EncodeChar((long)&outfile, 255 - THRESHOLD + match_length,PtrTypes);
+ EncodePosition((long)&outfile, match_position,PtrTypes);
+ }
+
+ last_match_length = match_length;
+
+ for (i = 0; i < last_match_length && (DataLength > datasize); i++)
+ {
+ c = ReadPtr((long)&infile,PtrTypes);
+ datasize++;
+
+ DeleteNode(s);
+ text_buf[s] = c;
+
+ if (s < F - 1)
+ text_buf[s + N] = c;
+
+ s = (s + 1) & (N - 1);
+ r = (r + 1) & (N - 1);
+ InsertNode(r);
+ }
+
+ if (LZH_CompressDisplayVector && ((textsize += i) > printcount))
+ {
+ LZH_CompressDisplayVector(DataLength,datasize);
+ printcount += 1024;
+ }
+
+
+ while (i++ < last_match_length)
+ {
+ DeleteNode(s);
+ s = (s + 1) & (N - 1);
+ r = (r + 1) & (N - 1);
+ if (--len)
+ InsertNode(r);
+ }
+
+ } while (len > 0);
+
+ EncodeEnd((long)&outfile,PtrTypes);
+
+ return(codesize);
+
+}
+
+
+#endif \ No newline at end of file
diff --git a/LZHUFF.H b/LZHUFF.H
new file mode 100644
index 0000000..1e4395e
--- /dev/null
+++ b/LZHUFF.H
@@ -0,0 +1,35 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+extern void (*LZH_CompressDisplayVector)();
+extern void (*LZH_DecompressDisplayVector)();
+
+
+
+//===========================================================================
+//
+// PROTOTYPES
+//
+//===========================================================================
+
+
+long lzhCompress(void far *infile, void far *outfile,unsigned long DataLength,unsigned PtrTypes);
+long lzhDecompress(void far *infile, void far *outfile, unsigned long OrginalLength, unsigned long CompressLength, unsigned PtrTypes);
+
+
+
diff --git a/LZW.C b/LZW.C
new file mode 100644
index 0000000..540cc7d
--- /dev/null
+++ b/LZW.C
@@ -0,0 +1,608 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+//===========================================================================
+//
+// LZW COMPRESSION ROUTINES
+// VERSION 1.1
+//
+// Compression algrythim by Haruhiko OKUMURA
+// Implementation by Jim T. Row
+//
+//
+// Copyright (c) 1992 - Softdisk Publishing inc. - All rights reserved
+//
+//===========================================================================
+//
+//
+//---------------------------------------------------------------------------
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <alloc.h>
+#include <fcntl.h>
+#include <dos.h>
+#include <io.h>
+
+#include "lzw.h"
+#include "jam_io.h"
+
+
+//===========================================================================
+//
+// SWITCHES
+//
+// NOTE : Make sure the appropriate switches are set in SOFT.c for Softlib
+// archive support.
+//
+//===========================================================================
+
+#define INCLUDE_LZW_COMP 0
+#define INCLUDE_LZW_DECOMP 1
+
+
+//===========================================================================
+//
+// DEFINES
+//
+//===========================================================================
+
+
+#define LZW_N 4096
+#define LZW_F 18
+
+#define LZW_THRESHOLD 2 // encode string into position and
+ // length if match_length is greater
+ // than this
+
+#define LZW_NIL LZW_N // index for root of bin search trees
+
+
+//============================================================================
+//
+// GLOBAL VARIABLES NECESSARY FOR
+//
+// COMP/DECOMP ROUTINES.
+//
+//============================================================================
+
+
+
+unsigned char far LZW_ring_buffer[LZW_N + LZW_F - 1]; // ring buffer of size
+ // LZW_N, with extra
+ // LZW_F-1 bytes to
+ // facilitate
+ // string comparison
+
+#if INCLUDE_LZW_COMP
+
+int LZW_match_pos, // MAtchLength of longest match. These are set by the
+ // InsertNode() procedure.
+ LZW_match_len,
+
+ // left & right children & parents -- These constitute binary search trees. */
+
+ LZW_left_child[LZW_N + 1],
+ LZW_right_child[LZW_N + 257],
+ LZW_parent[LZW_N + 1];
+
+#endif
+
+
+//============================================================================
+//
+// LZW DISPLAY VECTORS
+//
+// These vectors allow you to hook up any form of display you desire for
+// displaying the compression/decompression status.
+//
+// These routines are called inside of the compression/decompression routines
+// and pass the orginal size of data and current position within that
+// data. This allows for any kind of "% Done" messages.
+//
+// Your functions MUST have the following parameters in this order...
+//
+// void VectorRoutine(unsigned long OrginalSize,unsigned long CurPosition)
+//
+//
+
+void (*LZW_CompressDisplayVector)() = NULL;
+void (*LZW_DecompressDisplayVector)() = NULL;
+
+
+
+
+//============================================================================
+//
+// SUPPORT ROUTINES FOR LZW COMPRESSION
+//
+//============================================================================
+
+
+#if INCLUDE_LZW_COMP
+
+static void InitLZWTree(void) /* initialize trees */
+{
+ int i;
+
+ /* For i = 0 to LZW_N - 1, LZW_right_child[i] and LZW_left_child[i] will be the right and
+ left children of node i. These nodes need not be initialized.
+ Also, LZW_parent[i] is the parent of node i. These are initialized to
+ LZW_NIL (= LZW_N), which stands for 'not used.'
+ For i = 0 to 255, LZW_right_child[LZW_N + i + 1] is the root of the tree
+ for strings that begin with character i. These are initialized
+ to LZW_NIL. Note there are 256 trees. */
+
+ for (i = LZW_N + 1; i <= LZW_N + 256; i++)
+ LZW_right_child[i] = LZW_NIL;
+
+ for (i = 0; i < LZW_N; i++)
+ LZW_parent[i] = LZW_NIL;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+
+static void InsertLZWNode(unsigned long r)
+
+ /* Inserts string of length LZW_F, LZW_ring_buffer[r..r+LZW_F-1], into one of the
+ trees (LZW_ring_buffer[r]'th tree) and returns the longest-match position
+ and length via the global variables LZW_match_pos and LZW_match_len.
+ If LZW_match_len = LZW_F, then removes the old node in favor of the new
+ one, because the old one will be deleted sooner.
+ Note r plays double role, as tree node and position in buffer. */
+{
+ int i, p, cmp;
+ unsigned char *key;
+
+ cmp = 1;
+ key = &LZW_ring_buffer[r];
+ p = LZW_N + 1 + key[0];
+ LZW_right_child[r] = LZW_left_child[r] = LZW_NIL;
+ LZW_match_len = 0;
+
+ for ( ; ; )
+ {
+ if (cmp >= 0)
+ {
+ if (LZW_right_child[p] != LZW_NIL)
+ p = LZW_right_child[p];
+ else
+ {
+ LZW_right_child[p] = r;
+ LZW_parent[r] = p;
+ return;
+ }
+ }
+ else
+ {
+ if (LZW_left_child[p] != LZW_NIL)
+ p = LZW_left_child[p];
+ else
+ {
+ LZW_left_child[p] = r;
+ LZW_parent[r] = p;
+ return;
+ }
+ }
+
+ for (i = 1; i < LZW_F; i++)
+ if ((cmp = key[i] - LZW_ring_buffer[p + i]) != 0)
+ break;
+
+ if (i > LZW_match_len)
+ {
+ LZW_match_pos = p;
+ if ((LZW_match_len = i) >= LZW_F)
+ break;
+ }
+ }
+
+ LZW_parent[r] = LZW_parent[p];
+ LZW_left_child[r] = LZW_left_child[p];
+ LZW_right_child[r] = LZW_right_child[p];
+ LZW_parent[LZW_left_child[p]] = r;
+ LZW_parent[LZW_right_child[p]] = r;
+
+ if (LZW_right_child[LZW_parent[p]] == p)
+ LZW_right_child[LZW_parent[p]] = r;
+ else
+ LZW_left_child[LZW_parent[p]] = r;
+
+ LZW_parent[p] = LZW_NIL; /* remove p */
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+static void DeleteLZWNode(unsigned long p) /* deletes node p from tree */
+{
+ int q;
+
+ if (LZW_parent[p] == LZW_NIL)
+ return; /* not in tree */
+
+ if (LZW_right_child[p] == LZW_NIL)
+ q = LZW_left_child[p];
+ else
+ if (LZW_left_child[p] == LZW_NIL)
+ q = LZW_right_child[p];
+ else
+ {
+ q = LZW_left_child[p];
+ if (LZW_right_child[q] != LZW_NIL)
+ {
+ do {
+
+ q = LZW_right_child[q];
+
+ } while (LZW_right_child[q] != LZW_NIL);
+
+ LZW_right_child[LZW_parent[q]] = LZW_left_child[q];
+ LZW_parent[LZW_left_child[q]] = LZW_parent[q];
+ LZW_left_child[q] = LZW_left_child[p];
+ LZW_parent[LZW_left_child[p]] = q;
+ }
+
+ LZW_right_child[q] = LZW_right_child[p];
+ LZW_parent[LZW_right_child[p]] = q;
+ }
+
+ LZW_parent[q] = LZW_parent[p];
+ if (LZW_right_child[LZW_parent[p]] == p)
+ LZW_right_child[LZW_parent[p]] = q;
+ else
+ LZW_left_child[LZW_parent[p]] = q;
+
+ LZW_parent[p] = LZW_NIL;
+}
+
+
+
+//--------------------------------------------------------------------------
+//
+// lzwCompress() - Compresses data from an input ptr to a dest ptr
+//
+// PARAMS:
+// infile - Pointer at the BEGINNING of the data to compress
+// outfile - Pointer to the destination (no header).
+// DataLength - Number of bytes to compress.
+// PtrTypes - Type of pointers being used (SRC_FILE,DEST_FILE,SRC_MEM etc).
+//
+// RETURNS:
+// Length of compressed data.
+//
+// COMPTYPE : ct_LZW
+//
+// NOTES : Does not write ANY header information!
+//
+unsigned long lzwCompress(void far *infile, void far *outfile,unsigned long DataLength,unsigned PtrTypes)
+{
+ short i;
+ short c, len, r, s, last_LZW_match_len, code_buf_ptr;
+ unsigned char code_buf[17], mask;
+ unsigned long complen = 0;
+
+ unsigned CodeCount = 0;
+ unsigned long OrgDataLen = DataLength;
+
+ // initialize trees
+
+ InitLZWTree();
+
+ code_buf[0] = 0;
+
+ //
+ // code_buf[1..16] saves eight units of code, and code_buf[0] works
+ // as eight flags, "1" representing that the unit is an unencoded
+ // letter (1 byte), "0" a position-and-length pair (2 bytes). Thus,
+ // eight units require at most 16 bytes of code.
+ //
+
+ code_buf_ptr = mask = 1;
+ s = 0;
+ r = LZW_N - LZW_F;
+
+ // Clear the buffer with any character that will appear often.
+ //
+
+ for (i = s; i < r; i++)
+ LZW_ring_buffer[i] = ' ';
+
+ // Read LZW_F bytes into the last LZW_F bytes of the buffer
+ //
+
+ for (len = 0; (len < LZW_F) && DataLength; len++)
+ {
+ c = ReadPtr((long)&infile,PtrTypes);
+ DataLength--;
+
+ // text of size zero
+
+ LZW_ring_buffer[r + len] = c;
+ }
+
+ if (!(len && DataLength))
+ return(0);
+
+ //
+ // Insert the LZW_F strings, each of which begins with one or more
+ // 'space' characters. Note the order in which these strings
+ // are inserted. This way, degenerate trees will be less likely
+ // to occur.
+ //
+
+ for (i = 1; i <= LZW_F; i++)
+ InsertLZWNode(r - i);
+
+ //
+ // Finally, insert the whole string just read. The global
+ // variables LZW_match_len and LZW_match_pos are set. */
+ //
+
+ InsertLZWNode(r);
+
+ do {
+ // LZW_match_len may be spuriously long near the end of text.
+ //
+
+ if (LZW_match_len > len)
+ LZW_match_len = len;
+
+ if (LZW_match_len <= LZW_THRESHOLD)
+ {
+ // Not long enough match. Send one byte.
+ //
+
+ LZW_match_len = 1;
+
+ // 'send one byte' flag
+ //
+
+ code_buf[0] |= mask;
+
+ // Send uncoded.
+ //
+
+ code_buf[code_buf_ptr++] = LZW_ring_buffer[r];
+ }
+ else
+ {
+ code_buf[code_buf_ptr++] = (unsigned char) LZW_match_pos;
+ code_buf[code_buf_ptr++] = (unsigned char) (((LZW_match_pos >> 4) & 0xf0) | (LZW_match_len - (LZW_THRESHOLD + 1)));
+
+ // Send position and length pair.
+ // Note LZW_match_len > LZW_THRESHOLD.
+ }
+
+ if ((mask <<= 1) == 0)
+ {
+ // Shift mask left one bit.
+ // Send at most 8 units of data
+
+ for (i = 0; i < code_buf_ptr; i++)
+ WritePtr((long)&outfile,code_buf[i],PtrTypes);
+
+ complen += code_buf_ptr;
+ code_buf[0] = 0;
+ code_buf_ptr = mask = 1;
+ }
+
+ last_LZW_match_len = LZW_match_len;
+
+ for (i = 0; i < last_LZW_match_len && DataLength; i++)
+ {
+ c = ReadPtr((long)&infile,PtrTypes);
+ DataLength--;
+
+ DeleteLZWNode(s); // Delete old strings and
+ LZW_ring_buffer[s] = c; // read new bytes
+
+ // If the position is near the end of buffer, extend the
+ // buffer to make string comparison easier.
+
+ if (s < LZW_F - 1)
+ LZW_ring_buffer[s + LZW_N] = c;
+
+ // Since this is a ring buffer, inc the position modulo LZW_N.
+ //
+
+ s = (s + 1) & (LZW_N - 1);
+ r = (r + 1) & (LZW_N - 1);
+
+ // Register the string in LZW_ring_buffer[r..r+LZW_F-1]
+ //
+
+ InsertLZWNode(r);
+ }
+
+
+ //
+ // MANAGE DISPLAY VECTOR
+ //
+
+ if (LZW_CompressDisplayVector)
+ {
+ // Update display every 1k!
+ //
+
+ if ((CodeCount += i) > 1024)
+ {
+ LZW_CompressDisplayVector(OrgDataLen,OrgDataLen-DataLength);
+ CodeCount = 0;
+ }
+ }
+
+
+ //
+ // Manage Compression tree..
+ //
+
+ while (i++ < last_LZW_match_len)
+ {
+ // After the end of text,
+ DeleteLZWNode(s); // no need to read, but
+
+ s = (s + 1) & (LZW_N - 1);
+ r = (r + 1) & (LZW_N - 1);
+
+ if (--len)
+ InsertLZWNode(r); // buffer may not be empty.
+ }
+
+ } while (len > 0); // until length of string to be processed is zero
+
+
+ if (code_buf_ptr > 1)
+ {
+ // Send remaining code.
+ //
+
+ for (i = 0; i < code_buf_ptr; i++)
+ WritePtr((long)&outfile,code_buf[i],PtrTypes);
+
+ complen += code_buf_ptr;
+ }
+
+ if (LZW_CompressDisplayVector)
+ {
+ if ((CodeCount += i) > 1024)
+ {
+ LZW_CompressDisplayVector(OrgDataLen,OrgDataLen-DataLength);
+ }
+ }
+
+ return(complen);
+}
+
+#endif
+
+
+
+
+//============================================================================
+//
+// SUPPORT ROUTINES FOR LZW DECOMPRESSION
+//
+//============================================================================
+
+#if INCLUDE_LZW_DECOMP
+
+//--------------------------------------------------------------------------
+//
+// lzwDecompress() - Compresses data from an input ptr to a dest ptr
+//
+// PARAMS:
+// infile - Pointer at the BEGINNING of the compressed data (no header!)
+// outfile - Pointer to the destination.
+// DataLength - Number of bytes to decompress.
+// PtrTypes - Type of pointers being used (SRC_FILE,DEST_FILE,SRC_MEM etc).
+//
+// RETURNS:
+// Length of compressed data.
+//
+// COMPTYPE : ct_LZW
+//
+// NOTES : Does not write ANY header information!
+//
+void lzwDecompress(void far *infile, void far *outfile,unsigned long DataLength,unsigned PtrTypes)
+{
+ int i, j, k, r, c;
+ unsigned int flags;
+ unsigned char Buffer[8];
+// unsigned char LZW_ring_buffer[LZW_N + LZW_F - 1];
+
+ unsigned CodeCount = 0;
+ unsigned long OrgDataLen = DataLength;
+
+ for (i = 0; i < LZW_N - LZW_F; i++)
+ LZW_ring_buffer[i] = ' ';
+
+ r = LZW_N - LZW_F;
+ flags = 0;
+
+ for ( ; ; )
+ {
+ if (((flags >>= 1) & 256) == 0)
+ {
+ c = ReadPtr((long)&infile,PtrTypes);
+
+ flags = c | 0xff00; // uses higher byte cleverly to count 8
+ }
+
+ if (flags & 1)
+ {
+ c = ReadPtr((long)&infile,PtrTypes); // Could test for EOF iff FFILE type
+
+ WritePtr((long)&outfile,c,PtrTypes);
+
+ if (!--DataLength)
+ return;
+
+ LZW_ring_buffer[r++] = c;
+ r &= (LZW_N - 1);
+ }
+ else
+ {
+ i = ReadPtr((long)&infile,PtrTypes);
+
+ j = ReadPtr((long)&infile,PtrTypes);
+
+ i |= ((j & 0xf0) << 4);
+ j = (j & 0x0f) + LZW_THRESHOLD;
+
+ for (k = 0; k <= j; k++)
+ {
+ c = LZW_ring_buffer[(i + k) & (LZW_N - 1)];
+
+ WritePtr((long)&outfile,c,PtrTypes);
+
+ if (!--DataLength)
+ return;
+
+ LZW_ring_buffer[r++] = c;
+ r &= (LZW_N - 1);
+ }
+ }
+
+
+
+ //
+ // MANAGE DISPLAY VECTOR
+ //
+
+ if (LZW_DecompressDisplayVector)
+ {
+ //
+ // Update DisplayVector every 1K
+ //
+
+ if ((CodeCount+=k) > 1024)
+ {
+ LZW_DecompressDisplayVector(OrgDataLen,OrgDataLen-DataLength);
+ CodeCount = 0;
+ }
+ }
+
+ }
+}
+
+#endif
+
diff --git a/LZW.H b/LZW.H
new file mode 100644
index 0000000..6279e25
--- /dev/null
+++ b/LZW.H
@@ -0,0 +1,40 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+//--------------------------------------------------------------------------
+//
+// EXTERN DEFINITIONS FOR DISPLAY VEC ROUTINES
+//
+//--------------------------------------------------------------------------
+
+
+extern void (*LZW_CompressDisplayVector)();
+extern void (*LZW_DecompressDisplayVector)();
+
+
+//---------------------------------------------------------------------------
+//
+// FUNCTION PROTOTYPEING
+//
+//---------------------------------------------------------------------------
+
+
+
+unsigned long lzwCompress(void far *infile, void far *outfile,unsigned long DataLength,unsigned PtrTypes);
+void lzwDecompress(void far *infile, void far *outfile,unsigned long DataLength,unsigned PtrTypes);
+
diff --git a/MAPSARM.H b/MAPSARM.H
index 06005f9..b1de541 100644
--- a/MAPSARM.H
+++ b/MAPSARM.H
@@ -1,4 +1,4 @@
-/* Catacomb Abyss Source Code
+/* Catacomb Armageddon Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,7 @@
///////////////////////////////////////
//
-// TED5 Map Header for ABS
+// TED5 Map Header for ARM
//
///////////////////////////////////////
@@ -26,29 +26,23 @@
// Map Names
//
typedef enum {
- TOWNE_CEMETARY_MAP, // 0
- GARDEN_OF_TEARS_MAP, // 1
- DEN_OF_ZOMBIES_MAP, // 2
- MAUSOLEUM_GROUN_MAP, // 3
- MAUSOLEUM_MAIN_MAP, // 4
- MIKES_LEVEL_MAP, // 5
- CRYPT_OF_UNDEAD_MAP, // 6
- SUBVAULT_1_MAP, // 7
- AQUADUCT_MAP, // 8
- ORC_MINES_MAP, // 9
- TROLLS_LAIR_MAP, // 10
- DEMON_INFERNO_MAP, // 11
- BATTLEGROUND_MAP, // 12
- COVEN_OF_MAGES_MAP, // 13
- INNER_SANCTUM_MAP, // 14
- NEMESIS_HAUNT_MAP, // 15
+ TOWN_MORBIDITY_MAP, // 0
+ DARK_FOREST_MAP, // 1
+ GARDEN_OF_SOULS_MAP, // 2
+ LOST_CITY_DAMND_MAP, // 3
+ TEMPLE_OF_VIPER_MAP, // 4
+ TORTURE_CHAMBER_MAP, // 5
+ DEMONS_HOLD_MAP, // 6
+ COLONY_FIRE_ANT_MAP, // 7
+ HALL_WRETCH_POX_MAP, // 8
+ LAIR_OF_SUCUBUS_MAP, // 9
+ BLOOD_CHAMB_EYE_MAP, // 10
+ FLAMING_INFERNO_MAP, // 11
+ SUBTERR_RIVER_MAP, // 12
+ CRYSTAL_MAZE_MG_MAP, // 13
+ RAMPARTS_OF_NEM_MAP, // 14
+ FORTRESS_OF_NEM_MAP, // 15
PASSAGE_TO_SURF_MAP, // 16
- BIG_JIMS_DOMAIN_MAP, // 17
- NOLANS_NASTY_MAP, // 18
- TILE_TESTER_3_MAP, // 19
- TILE_TESTER_1_MAP, // 20
- TILE_TESTER_2_MAP, // 21
- GOOD_MAP_TO_USE_MAP, // 22
LASTMAP
} mapnames;
diff --git a/README.md b/README.md
index a1c774a..680f55a 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
-The Catacomb Abyss
-==================
+The Catacomb Armageddon
+=======================
-This repository contains the source code for The Catacomb Abyss. The source
-code is designed for Borland C++ 2.0, but compiled fine with Borland C++ 3.1 at
-the time of this release.
+This repository contains the source code for The Catacomb Armageddon. The
+source code is designed for Borland C++ 2.0, but compiled fine with Borland C++
+3.1 at the time of this release.
It is released under the GNU GPLv2. Please see COPYING for license details.
@@ -12,5 +12,5 @@ need to legally acquire the game data in order to use the exe built from this
source code.
To run the executable, the following command must be used or the check must be
-disabled in C4_MAIN.C:
- abysgame.exe ^(a@&r`
+disabled in C5_MAIN.C:
+ armgame.exe ^(a@&r`
diff --git a/SL_FILE.H b/SL_FILE.H
new file mode 100644
index 0000000..24849b1
--- /dev/null
+++ b/SL_FILE.H
@@ -0,0 +1,109 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _SL_FILE_H
+#define _SL_FILE_H
+
+
+//==========================================================================
+//
+// DEFINES
+//
+//==========================================================================
+
+#ifndef MakeID
+#define MakeID(a,b,c,d) (((long)(d)<<24L)|((long)(c)<<16L)|((long)(b)<<8L)|(long)(a))
+#endif
+
+
+#define ID_SLIB MakeID('S','L','I','B')
+#define SLIB ("SLIB")
+#define SOFTLIB_VER 2
+#define ID_CHUNK MakeID('C','U','N','K')
+
+
+
+//==========================================================================
+//
+// TYPES
+//
+//==========================================================================
+
+
+
+
+//--------------------------------------------------------------------------
+// SOFTLIB File Entry Types
+//--------------------------------------------------------------------------
+typedef enum LibFileTypes
+{
+ lib_DATA =0, // Just streight raw data
+// lib_AUDIO, // Multi chunk audio file
+
+} LibFileTypes;
+
+
+
+//--------------------------------------------------------------------------
+// SOFTLIB Library File header..
+//
+// * This header will NEVER change! *
+//--------------------------------------------------------------------------
+
+typedef struct SoftLibHdr
+{
+ unsigned Version; // Library Version Num
+ unsigned FileCount;
+} SoftlibHdr;
+
+
+
+//--------------------------------------------------------------------------
+// SOFTLIB Directory Entry Hdr
+//
+// This can change according to Version of SoftLib (Make sure we are
+// always downward compatable!
+//--------------------------------------------------------------------------
+
+#define SL_FILENAMESIZE 16
+
+typedef struct FileEntryHdr
+{
+ char FileName[SL_FILENAMESIZE]; // NOTE : May not be null terminated!
+ unsigned long Offset;
+ unsigned long ChunkLen;
+ unsigned long OrginalLength;
+ short Compression; // ct_TYPES
+} FileEntryHdr;
+
+
+
+//--------------------------------------------------------------------------
+// SOFTLIB Entry Chunk Header
+//--------------------------------------------------------------------------
+
+typedef struct ChunkHeader
+{
+ unsigned long HeaderID;
+ unsigned long OrginalLength;
+ short Compression; // ct_TYPES
+} ChunkHeader;
+
+
+
+#endif \ No newline at end of file
diff --git a/SOFT.C b/SOFT.C
new file mode 100644
index 0000000..f86481e
--- /dev/null
+++ b/SOFT.C
@@ -0,0 +1,479 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <alloc.h>
+#include <fcntl.h>
+#include <dos.h>
+#include <io.h>
+
+#include "def.h"
+#include "gelib.h"
+#include "soft.h"
+#include "lzw.h"
+#include "lzhuff.h"
+#include "jam_io.h"
+
+
+
+
+
+
+//===========================================================================
+//
+// SWITCHES
+//
+//===========================================================================
+
+#define LZH_SUPPORT 1
+#define LZW_SUPPORT 0
+
+
+
+
+//=========================================================================
+//
+//
+// GENERAL LOAD ROUTINES
+//
+//
+//=========================================================================
+
+
+
+//--------------------------------------------------------------------------
+// BLoad() -- THIS HAS NOT BEEN FULLY TESTED!
+//
+// NOTICE : This version of BLOAD is compatable with JAMPak V3.0 and the
+// new fileformat...
+//--------------------------------------------------------------------------
+unsigned long BLoad(char *SourceFile, memptr *DstPtr)
+{
+ int handle;
+
+ memptr SrcPtr;
+ unsigned long i, j, k, r, c;
+ word flags;
+ byte Buffer[8];
+ unsigned long SrcLen,DstLen;
+ struct CMP1Header CompHeader;
+ boolean Compressed = false;
+
+
+ memset((void *)&CompHeader,0,sizeof(struct CMP1Header));
+
+ //
+ // Open file to load....
+ //
+
+ if ((handle = open(SourceFile, O_RDONLY|O_BINARY)) == -1)
+ return(0);
+
+ //
+ // Look for JAMPAK headers
+ //
+
+ read(handle,Buffer,4);
+
+ if (!strncmp(Buffer,COMP,4))
+ {
+ //
+ // Compressed under OLD file format
+ //
+
+ Compressed = true;
+ SrcLen = Verify(SourceFile);
+
+ read(handle,(void *)&CompHeader.OrginalLen,4);
+ CompHeader.CompType = ct_LZW;
+ MM_GetPtr(DstPtr,CompHeader.OrginalLen);
+ if (!*DstPtr)
+ return(0);
+ }
+ else
+ if (!strncmp(Buffer,CMP1,4))
+ {
+ //
+ // Compressed under new file format...
+ //
+
+ Compressed = true;
+ SrcLen = Verify(SourceFile);
+
+ read(handle,(void *)&CompHeader,sizeof(struct CMP1Header));
+ MM_GetPtr(DstPtr,CompHeader.OrginalLen);
+ if (!*DstPtr)
+ return(0);
+ }
+ else
+ DstLen = Verify(SourceFile);
+
+
+ //
+ // Load the file in memory...
+ //
+
+ if (Compressed)
+ {
+ DstLen = CompHeader.OrginalLen;
+
+ if ((MM_TotalFree() < SrcLen) && (CompHeader.CompType))
+ {
+ if (!InitBufferedIO(handle,&lzwBIO))
+ TrashProg("No memory for buffered I/O.");
+
+ switch (CompHeader.CompType)
+ {
+ #if LZW_SUPPORT
+ case ct_LZW:
+ lzwDecompress(&lzwBIO,MK_FP(*DstPtr,0),CompHeader.OrginalLen,(SRC_BFILE|DEST_MEM));
+ break;
+ #endif
+
+ #if LZH_SUPPORT
+ case ct_LZH:
+ lzhDecompress(&lzwBIO,MK_FP(*DstPtr,0),CompHeader.OrginalLen,CompHeader.CompressLen,(SRC_BFILE|DEST_MEM));
+ break;
+ #endif
+
+ default:
+ TrashProg("BLoad() - Unrecognized/Supported compression");
+ break;
+ }
+
+ FreeBufferedIO(&lzwBIO);
+ }
+ else
+ {
+ CA_LoadFile(SourceFile,&SrcPtr);
+ switch (CompHeader.CompType)
+ {
+ #if LZW_SUPPORT
+ case ct_LZW:
+ lzwDecompress(MK_FP(SrcPtr,8),MK_FP(*DstPtr,0),CompHeader.OrginalLen,(SRC_MEM|DEST_MEM));
+ break;
+ #endif
+
+ #if LZH_SUPPORT
+ case ct_LZH:
+ lzhDecompress(MK_FP(SrcPtr,8),MK_FP(*DstPtr,0),CompHeader.OrginalLen,CompHeader.CompressLen,(SRC_MEM|DEST_MEM));
+ break;
+ #endif
+
+ default:
+ TrashProg("BLoad() - Unrecognized/Supported compression");
+ break;
+ }
+ MM_FreePtr(&SrcPtr);
+ }
+ }
+ else
+ CA_LoadFile(SourceFile,DstPtr);
+
+ close(handle);
+ return(DstLen);
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////////
+//
+// LoadLIBShape()
+//
+int LoadLIBShape(char *SLIB_Filename, char *Filename,struct Shape *SHP)
+{
+ #define CHUNK(Name) (*ptr == *Name) && \
+ (*(ptr+1) == *(Name+1)) && \
+ (*(ptr+2) == *(Name+2)) && \
+ (*(ptr+3) == *(Name+3))
+
+
+ int RT_CODE;
+ FILE *fp;
+ char CHUNK[5];
+ char far *ptr;
+ memptr IFFfile = NULL;
+ unsigned long FileLen, size, ChunkLen;
+ int loop;
+
+
+ RT_CODE = 1;
+
+ // Decompress to ram and return ptr to data and return len of data in
+ // passed variable...
+
+ if (!LoadLIBFile(SLIB_Filename,Filename,&IFFfile))
+ TrashProg("Error Loading Compressed lib shape!");
+
+ // Evaluate the file
+ //
+ ptr = MK_FP(IFFfile,0);
+ if (!CHUNK("FORM"))
+ goto EXIT_FUNC;
+ ptr += 4;
+
+ FileLen = *(long far *)ptr;
+ SwapLong((long far *)&FileLen);
+ ptr += 4;
+
+ if (!CHUNK("ILBM"))
+ goto EXIT_FUNC;
+ ptr += 4;
+
+ FileLen += 4;
+ while (FileLen)
+ {
+ ChunkLen = *(long far *)(ptr+4);
+ SwapLong((long far *)&ChunkLen);
+ ChunkLen = (ChunkLen+1) & 0xFFFFFFFE;
+
+ if (CHUNK("BMHD"))
+ {
+ ptr += 8;
+ SHP->bmHdr.w = ((struct BitMapHeader far *)ptr)->w;
+ SHP->bmHdr.h = ((struct BitMapHeader far *)ptr)->h;
+ SHP->bmHdr.x = ((struct BitMapHeader far *)ptr)->x;
+ SHP->bmHdr.y = ((struct BitMapHeader far *)ptr)->y;
+ SHP->bmHdr.d = ((struct BitMapHeader far *)ptr)->d;
+ SHP->bmHdr.trans = ((struct BitMapHeader far *)ptr)->trans;
+ SHP->bmHdr.comp = ((struct BitMapHeader far *)ptr)->comp;
+ SHP->bmHdr.pad = ((struct BitMapHeader far *)ptr)->pad;
+ SwapWord(&SHP->bmHdr.w);
+ SwapWord(&SHP->bmHdr.h);
+ SwapWord(&SHP->bmHdr.x);
+ SwapWord(&SHP->bmHdr.y);
+ ptr += ChunkLen;
+ }
+ else
+ if (CHUNK("BODY"))
+ {
+ ptr += 4;
+ size = *((long far *)ptr);
+ ptr += 4;
+ SwapLong((long far *)&size);
+ SHP->BPR = (SHP->bmHdr.w+7) >> 3;
+ MM_GetPtr(&SHP->Data,size);
+ if (!SHP->Data)
+ goto EXIT_FUNC;
+ movedata(FP_SEG(ptr),FP_OFF(ptr),FP_SEG(SHP->Data),0,size);
+ ptr += ChunkLen;
+
+ break;
+ }
+ else
+ ptr += ChunkLen+8;
+
+ FileLen -= ChunkLen+8;
+ }
+
+ RT_CODE = 0;
+
+EXIT_FUNC:;
+ if (IFFfile)
+ {
+// segptr = (memptr)FP_SEG(IFFfile);
+ MM_FreePtr(&IFFfile);
+ }
+
+ return (RT_CODE);
+}
+
+
+
+
+
+//----------------------------------------------------------------------------
+// LoadLIBFile() -- Copies a file from an existing archive to dos.
+//
+// PARAMETERS :
+//
+// LibName - Name of lib file created with SoftLib V1.0
+//
+// FileName - Name of file to load from lib file.
+//
+// MemPtr - (IF !NULL) - Pointer to memory to load into ..
+// (IF NULL) - Routine allocates necessary memory and
+// returns a MEM(SEG) pointer to memory allocated.
+//
+// RETURN :
+//
+// (IF !NULL) - A pointer to the loaded data.
+// (IF NULL) - Error!
+//
+//----------------------------------------------------------------------------
+memptr LoadLIBFile(char *LibName,char *FileName,memptr *MemPtr)
+{
+ int handle;
+ unsigned long header;
+ struct ChunkHeader Header;
+ unsigned long ChunkLen;
+ short x;
+ struct FileEntryHdr FileEntry; // Storage for file once found
+ struct FileEntryHdr FileEntryHeader; // Header used durring searching
+ struct SoftLibHdr LibraryHeader; // Library header - Version Checking
+ boolean FileFound = false;
+ unsigned long id_slib = ID_SLIB;
+ unsigned long id_chunk = ID_CHUNK;
+
+
+ //
+ // OPEN SOFTLIB FILE
+ //
+
+ if ((handle = open(LibName,O_RDONLY|O_BINARY, S_IREAD)) == -1)
+ return(NULL);
+
+
+ //
+ // VERIFY it is a SOFTLIB (SLIB) file
+ //
+
+ if (read(handle,&header,4) == -1)
+ {
+ close(handle);
+ return(NULL);
+ }
+
+ if (header != id_slib)
+ {
+ close(handle);
+ return(NULL);
+ }
+
+
+ //
+ // CHECK LIBRARY HEADER VERSION NUMBER
+ //
+
+ if (read(handle, &LibraryHeader,sizeof(struct SoftLibHdr)) == -1)
+ TrashProg("read error in LoadSLIBFile()\n%c",7);
+
+ if (LibraryHeader.Version > SOFTLIB_VER)
+ TrashProg("Unsupported file ver %d",LibraryHeader.Version);
+
+
+ //
+ // MANAGE FILE ENTRY HEADERS...
+ //
+
+ for (x = 1;x<=LibraryHeader.FileCount;x++)
+ {
+ if (read(handle, &FileEntryHeader,sizeof(struct FileEntryHdr)) == -1)
+ {
+ close(handle);
+ return(NULL);
+ }
+
+ if (!stricmp(FileEntryHeader.FileName,FileName))
+ {
+ FileEntry = FileEntryHeader;
+ FileFound = true;
+ }
+ }
+
+ //
+ // IF FILE HAS BEEN FOUND THEN SEEK TO POSITION AND EXTRACT
+ // ELSE RETURN WITH ERROR CODE...
+ //
+
+ if (FileFound)
+ {
+ if (lseek(handle,FileEntry.Offset,SEEK_CUR) == -1)
+ {
+ close(handle);
+ return(NULL);
+ }
+
+ //
+ // READ CHUNK HEADER - Verify we are at the beginning of a chunk..
+ //
+
+ if (read(handle,(char *)&Header,sizeof(struct ChunkHeader)) == -1)
+ TrashProg("LIB File - Unable to read Header!");
+
+ if (Header.HeaderID != id_chunk)
+ TrashProg("LIB File - BAD HeaderID!");
+
+ //
+ // Allocate memory if Necessary...
+ //
+
+
+ if (!*MemPtr)
+ MM_GetPtr(MemPtr,FileEntry.OrginalLength);
+
+ //
+ // Calculate the length of the data (without the chunk header).
+ //
+
+ ChunkLen = FileEntry.ChunkLen - sizeof(struct ChunkHeader);
+
+
+ //
+ // Extract Data from file
+ //
+
+ switch (Header.Compression)
+ {
+
+ #if LZW_SUPPORT
+ case ct_LZW:
+ if (!InitBufferedIO(handle,&lzwBIO))
+ TrashProg("No memory for buffered I/O.");
+ lzwDecompress(&lzwBIO,MK_FP(*MemPtr,0),FileEntry.OrginalLength,(SRC_BFILE|DEST_MEM));
+ FreeBufferedIO(&lzwBIO);
+ break;
+ #endif
+
+ #if LZH_SUPPORT
+ case ct_LZH:
+ if (!InitBufferedIO(handle,&lzwBIO))
+ TrashProg("No memory for buffered I/O.");
+ lzhDecompress(&lzwBIO, MK_FP(*MemPtr,0), FileEntry.OrginalLength, ChunkLen, (SRC_BFILE|DEST_MEM));
+ FreeBufferedIO(&lzwBIO);
+ break;
+ #endif
+
+ case ct_NONE:
+ if (!CA_FarRead(handle,MK_FP(*MemPtr,0),ChunkLen))
+ {
+// close(handle);
+ *MemPtr = NULL;
+ }
+ break;
+
+ default:
+ close(handle);
+ TrashProg("Unknown Chunk.Compression Type!");
+ break;
+ }
+ }
+ else
+ *MemPtr = NULL;
+
+ close(handle);
+ return(*MemPtr);
+}
+
+
+
+
diff --git a/SOFT.H b/SOFT.H
new file mode 100644
index 0000000..2226de6
--- /dev/null
+++ b/SOFT.H
@@ -0,0 +1,25 @@
+/* Catacomb Armageddon Source Code
+ * Copyright (C) 1993-2014 Flat Rock Software
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+//memptr InitBufferedIO(int handle, BufferedIO *bio);
+//void FreeBufferedIO(BufferedIO *bio);
+//byte bio_readch(BufferedIO *bio);
+
+unsigned long BLoad(char *SourceFile, memptr *DstPtr);
+memptr LoadLIBFile(char *LibName,char *FileName,memptr *MemPtr);
+int LoadLIBShape(char *SLIB_Filename, char *Filename,struct Shape *SHP);