aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Mandel <richard@tech-transfer.com>2014-06-06 23:31:43 -0400
committerRichard Mandel <richard@tech-transfer.com>2014-06-06 23:31:43 -0400
commit4464c057e35a4af578dbd6399416bdbc5d913cc2 (patch)
tree8b94231a71a65967755e9de478e1c54631049cf1
parentf244eff51535983d48a18fd4c4e8bce7c6ba3950 (diff)
downloadcatacombabyss-4464c057e35a4af578dbd6399416bdbc5d913cc2.tar.gz
catacombabyss-4464c057e35a4af578dbd6399416bdbc5d913cc2.tar.bz2
catacombabyss-4464c057e35a4af578dbd6399416bdbc5d913cc2.zip
Catacomb Abyss open source release.HEADmaster
-rw-r--r--ABSADICT.OBJbin1151 -> 1151 bytes
-rw-r--r--ABSAHEAD.OBJbin501 -> 549 bytes
-rw-r--r--ABSEDICT.OBJbin1149 -> 1149 bytes
-rw-r--r--ABSEHEAD.OBJbin1579 -> 2023 bytes
-rw-r--r--ABSMHEAD.OBJbin746 -> 962 bytes
-rw-r--r--ABYSGAME.PRJbin11498 -> 11547 bytes
-rw-r--r--AUDIOABS.H30
-rw-r--r--C4_ACT1.C1784
-rw-r--r--C4_ASM.ASM55
-rw-r--r--C4_DEBUG.C286
-rw-r--r--C4_DRAW.C285
-rw-r--r--C4_GAME.C707
-rw-r--r--C4_MAIN.C349
-rw-r--r--C4_PLAY.C945
-rw-r--r--C4_SCALE.C24
-rw-r--r--C4_SCA_A.ASM2
-rw-r--r--C4_STATE.C145
-rw-r--r--C4_TRACE.C11
-rw-r--r--C4_WIZ.C1866
-rw-r--r--DEF.H353
-rw-r--r--GELIB.C2566
-rw-r--r--GELIB.H165
-rw-r--r--GFXE_ABS.EQU901
-rw-r--r--GFXE_ABS.H964
-rw-r--r--ID_ASM.EQU2
-rw-r--r--ID_CA.C98
-rw-r--r--ID_CA.H4
-rw-r--r--ID_HEADS.H31
-rw-r--r--ID_IN.C181
-rw-r--r--ID_IN.H6
-rw-r--r--ID_MM.C26
-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.C26
-rw-r--r--ID_SD.H3
-rw-r--r--ID_STRS.H2
-rw-r--r--ID_US.C20
-rw-r--r--ID_US.H7
-rw-r--r--ID_US_1.C66
-rw-r--r--ID_US_2.C18
-rw-r--r--ID_US_A.ASM2
-rw-r--r--ID_VW.C27
-rw-r--r--ID_VW.H3
-rw-r--r--ID_VW_A.ASM22
-rw-r--r--ID_VW_AC.ASM2
-rw-r--r--ID_VW_AE.ASM6
-rw-r--r--JABHACK.ASM2
-rw-r--r--MAPSABS.H48
-rw-r--r--MIKE.H736
-rw-r--r--README.md15
-rw-r--r--_SHRWARE.OBJbin0 -> 4147 bytes
53 files changed, 10610 insertions, 2190 deletions
diff --git a/ABSADICT.OBJ b/ABSADICT.OBJ
index c2f9fda..b0e8792 100644
--- a/ABSADICT.OBJ
+++ b/ABSADICT.OBJ
Binary files differ
diff --git a/ABSAHEAD.OBJ b/ABSAHEAD.OBJ
index 8906d30..9feed1a 100644
--- a/ABSAHEAD.OBJ
+++ b/ABSAHEAD.OBJ
Binary files differ
diff --git a/ABSEDICT.OBJ b/ABSEDICT.OBJ
index 991491a..2b16875 100644
--- a/ABSEDICT.OBJ
+++ b/ABSEDICT.OBJ
Binary files differ
diff --git a/ABSEHEAD.OBJ b/ABSEHEAD.OBJ
index df8c6b2..be2b224 100644
--- a/ABSEHEAD.OBJ
+++ b/ABSEHEAD.OBJ
Binary files differ
diff --git a/ABSMHEAD.OBJ b/ABSMHEAD.OBJ
index 1607914..e227b29 100644
--- a/ABSMHEAD.OBJ
+++ b/ABSMHEAD.OBJ
Binary files differ
diff --git a/ABYSGAME.PRJ b/ABYSGAME.PRJ
index 33d75d4..d5e9a95 100644
--- a/ABYSGAME.PRJ
+++ b/ABYSGAME.PRJ
Binary files differ
diff --git a/AUDIOABS.H b/AUDIOABS.H
index 44da68f..2187679 100644
--- a/AUDIOABS.H
+++ b/AUDIOABS.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss 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 .C3D
-// Created Wed Oct 30 22:44:13 1991
+// MUSE Header for .ABS
+// Created Thu Apr 16 14:56:19 1992
//
/////////////////////////////////////////////////
-#define NUMSOUNDS 30
-#define NUMSNDCHUNKS 91
+#define NUMSOUNDS 34
+#define NUMSNDCHUNKS 103
//
// Sound names & indexes
@@ -55,11 +55,15 @@ typedef enum {
SHOOTMONSTERSND, // 22
TAKEDMGHURTSND, // 23
BALLBOUNCESND, // 24
- COMPSCOREDSND, // 25
- KEENSCOREDSND, // 26
- COMPPADDLESND, // 27
- KEENPADDLESND, // 28
- NOWAYSND, // 29
+ NOWAYSND, // 25
+ WARPSND, // 26
+ HIT_GATESND, // 27
+ GETGEMSND, // 28
+ BOOMSND, // 29
+ GRELM_DEADSND, // 30
+ FREEZETIMESND, // 31
+ TIMERETURNSND, // 32
+ TICKSND, // 33
LASTSOUND
} soundnames;
@@ -67,9 +71,9 @@ typedef enum {
// Base offsets
//
#define STARTPCSOUNDS 0
-#define STARTADLIBSOUNDS 30
-#define STARTDIGISOUNDS 60
-#define STARTMUSIC 90
+#define STARTADLIBSOUNDS 34
+#define STARTDIGISOUNDS 68
+#define STARTMUSIC 102
//
// Music names & indexes
diff --git a/C4_ACT1.C b/C4_ACT1.C
index 2706b4f..4749b1b 100644
--- a/C4_ACT1.C
+++ b/C4_ACT1.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss 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 @@
// C3_PLAY.C
-#include "C3_DEF.H"
+#include "DEF.H"
#pragma hdrstop
/*
@@ -28,8 +28,17 @@
=============================================================================
*/
+void SpawnSkeleton(int tilex, int tiley);
+#define MSHOTDAMAGE 2
+#define MSHOTSPEED 10000
+
+#define ESHOTDAMAGE 1
+#define ESHOTSPEED 5000
+
+#define RANDOM_ATTACK 20
+
/*
=============================================================================
@@ -38,6 +47,13 @@
=============================================================================
*/
+boolean ShootPlayer (objtype *ob, short obclass, short speed, statetype *state);
+void T_ShootPlayer(objtype *ob);
+
+short zombie_base_delay;
+
+short other_x[] = {0,39,39,0},
+ other_y[] = {0,0,27,27};
/*
@@ -64,21 +80,50 @@ dirtype dirtable[9] = {northwest,north,northeast,west,nodir,east,
extern statetype s_boltbonus2;
extern statetype s_nukebonus2;
+extern statetype s_boltbonus3;
+extern statetype s_nukebonus3;
statetype s_boltbonus = {BOLTOBJPIC,8,NULL,&s_boltbonus2};
-statetype s_boltbonus2 = {BOLTOBJ2PIC,8,NULL,&s_boltbonus};
+statetype s_boltbonus2 = {BOLT2OBJPIC,8,NULL,&s_boltbonus3};
+statetype s_boltbonus3 = {BOLT3OBJPIC,8,NULL,&s_boltbonus};
statetype s_nukebonus = {NUKEOBJPIC,8,NULL,&s_nukebonus2};
-statetype s_nukebonus2 = {NUKEOBJ2PIC,8,NULL,&s_nukebonus};
+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_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_chestbonus = {CHESTOBJPIC,0,NULL,&s_chestbonus};
-statetype s_goalbonus = {NEMESISPIC,0,NULL,&s_goalbonus};
+//statetype s_goalbonus = {NEMESISPIC,0,NULL,&s_goalbonus};
+
+extern statetype s_waterchestbonus2;
+statetype s_waterchestbonus1 = {O_WATER_CHEST1PIC,8,NULL,&s_waterchestbonus2};
+statetype s_waterchestbonus2 = {O_WATER_CHEST2PIC,8,NULL,&s_waterchestbonus1};
+
+extern statetype s_rgem2bonus;
+extern statetype s_ygem2bonus;
+extern statetype s_ggem2bonus;
+extern statetype s_bgem2bonus;
+extern statetype s_pgem2bonus;
+
+statetype s_rgem1bonus = {RGEM1PIC,30,NULL,&s_rgem2bonus};
+statetype s_ygem1bonus = {YGEM1PIC,30,NULL,&s_ygem2bonus};
+statetype s_ggem1bonus = {GGEM1PIC,30,NULL,&s_ggem2bonus};
+statetype s_bgem1bonus = {BGEM1PIC,30,NULL,&s_bgem2bonus};
+statetype s_pgem1bonus = {PGEM1PIC,30,NULL,&s_pgem2bonus};
+
+statetype s_rgem2bonus = {RGEM2PIC,30,NULL,&s_rgem1bonus};
+statetype s_ygem2bonus = {YGEM2PIC,30,NULL,&s_ygem1bonus};
+statetype s_ggem2bonus = {GGEM2PIC,30,NULL,&s_ggem1bonus};
+statetype s_bgem2bonus = {BGEM2PIC,30,NULL,&s_bgem1bonus};
+statetype s_pgem2bonus = {PGEM2PIC,30,NULL,&s_pgem1bonus};
+
+statetype s_bonus_die = {0,8,NULL,NULL};
/*
===============
@@ -90,38 +135,124 @@ statetype s_goalbonus = {NEMESISPIC,0,NULL,&s_goalbonus};
void SpawnBonus (int tilex, int tiley, int number)
{
+ extern unsigned gnd_colors[];
+
statetype *state;
- if (number == B_BOLT)
- state = &s_boltbonus;
- else if (number == B_NUKE)
- state = &s_nukebonus;
- else if (number == B_POTION)
- state = &s_potionbonus;
- else if (number == B_RKEY)
- state = &s_rkeybonus;
- else if (number == B_YKEY)
- state = &s_ykeybonus;
- else if (number == B_GKEY)
- state = &s_gkeybonus;
- else if (number == B_BKEY)
- state = &s_bkeybonus;
- else if (number >= B_SCROLL1 && number <= B_SCROLL8)
- state = &s_scrollbonus;
- else if (number == B_CHEST)
- state = &s_chestbonus;
- else if (number == B_GOAL)
- state = &s_goalbonus;
+ switch (number)
+ {
+ case B_BOLT: state = &s_boltbonus; break;
+ case B_NUKE: state = &s_nukebonus; break;
+ case B_POTION: state = &s_potionbonus; break;
+
+ case B_RKEY: state = &s_rkeybonus; break;
+ case B_YKEY: state = &s_ykeybonus; break;
+ case B_GKEY: state = &s_gkeybonus; break;
+ case B_BKEY: state = &s_bkeybonus; break;
+
+ case B_RGEM: state = &s_rgem1bonus; break;
+ case B_YGEM: state = &s_ygem1bonus; break;
+ case B_GGEM: state = &s_ggem1bonus; break;
+ case B_BGEM: state = &s_bgem1bonus; break;
+ case B_PGEM: state = &s_pgem1bonus; break;
+
+ case B_CHEST:
+ if (gnd_colors[gamestate.mapon] == 0x0101)
+ state = &s_waterchestbonus1;
+ else
+ state = &s_chestbonus;
+ break;
+
+ case B_SCROLL1:
+ case B_SCROLL2:
+ case B_SCROLL3:
+ case B_SCROLL4:
+ case B_SCROLL5:
+ case B_SCROLL6:
+ case B_SCROLL7:
+ case B_SCROLL8: state = &s_scrollbonus; break;
+
+ case B_RKEY2: state = &s_rkey2bonus; break;
+
+ default:
+ Quit("SpawnBonus(): INVALID BONUS");
+ break;
+ }
SpawnNewObj (tilex,tiley,state,TILEGLOBAL/2);
- new->tileobject = true;
+// new->tileobject = true;
new->temp1 = number;
new->obclass = bonusobj;
- new->shootable = false;
+
+ switch (number)
+ {
+ case B_POTION:
+ case B_CHEST:
+ case B_BOLT:
+ case B_NUKE:
+ new->flags |= of_shootable;
+ break;
+
+ default:
+ new->flags &= ~of_shootable;
+ break;
+ }
+}
+
+
+/*
+===============
+=
+= SpawnTombstone
+=
+===============
+*/
+
+statetype s_tombs[3] = {{TOMB1PIC,8,NULL,&s_tombs[0]},
+ {TOMB2PIC,8,NULL,&s_tombs[1]},
+ {TOMB3PIC,8,NULL,&s_tombs[2]}};
+
+void SpawnTombstone (int tilex, int tiley, int shape)
+{
+ statetype *state=&s_tombs[shape];
+
+ SpawnNewObj (tilex,tiley,state,TILEGLOBAL/2);
+// new->tileobject = true;
+ new->obclass = solidobj;
+ new->flags |= of_shootable;
}
/*
+============================================================================
+
+ FREEZE TIME OBJECT
+
+============================================================================
+*/
+
+extern statetype s_ftimebonus;
+extern statetype s_ftimebonus2;
+
+statetype s_ftimebonus = {TIMEOBJ1PIC,6,NULL,&s_ftimebonus2};
+statetype s_ftimebonus2 = {TIMEOBJ2PIC,6,NULL,&s_ftimebonus};
+
+/*
+===============
+=
+= SpawnFTime
+=
+===============
+*/
+void SpawnFTime(int tilex, int tiley)
+{
+ SpawnNewObj(tilex,tiley,&s_ftimebonus,TILEGLOBAL/2);
+// new->tileobject = true;
+ new->obclass = freezeobj;
+ new->flags |= of_shootable;
+}
+
+/*
=============================================================================
EXPLODING WALL
@@ -154,13 +285,24 @@ statetype s_walldie6 = {0,-1,T_WallDie,NULL};
================
*/
+ extern unsigned gnd_colors[];
+
void ExplodeWall (int tilex, int tiley)
{
- SpawnNewObj (tilex,tiley,&s_walldie1,0);
+ unsigned tilenum;
+
+ DSpawnNewObj (tilex,tiley,&s_walldie1,0);
+ if (new == &dummyobj)
+ return;
new->obclass = inertobj;
- new->active = true;
+ new->active = always;
+ if (gnd_colors[gamestate.mapon] == 0x0101)
+ tilenum = WATEREXP;
+ else
+ tilenum = WALLEXP;
(unsigned)actorat[new->tilex][new->tiley] = tilemap[new->tilex][new->tiley] =
- *(mapsegs[0]+farmapylookup[new->tiley]+new->tilex) = WALLEXP;
+ *(mapsegs[0]+farmapylookup[new->tiley]+new->tilex) = tilenum;
+ *(mapsegs[2]+farmapylookup[new->tiley]+new->tilex) &= 0xFF;
}
@@ -174,86 +316,81 @@ void ExplodeWall (int tilex, int tiley)
void T_WallDie (objtype *ob)
{
- unsigned tile,other;
+ unsigned tile,other,spot,x,y;
if (++ob->temp1 == 3)
tile = 0;
else
- tile = WALLEXP-1 + ob->temp1;
+ if (gnd_colors[gamestate.mapon] == 0x0101)
+ tile = WATEREXP-1 + ob->temp1;
+ else
+ tile = WALLEXP-1 + ob->temp1;
+ x = ob->tilex;
+ y = ob->tiley;
- (unsigned)actorat[ob->tilex][ob->tiley] = tilemap[ob->tilex][ob->tiley] =
- *(mapsegs[0]+farmapylookup[ob->tiley]+ob->tilex) = tile;
+ (unsigned)actorat[x][y] = tilemap[x][y] = *(mapsegs[0]+farmapylookup[y]+x) = tile;
if (ob->temp1 == 1)
{
//
// blow up nearby walls
//
- other = tilemap[ob->tilex-1][ob->tiley];
- if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)
- ExplodeWall (ob->tilex-1,ob->tiley);
- other = tilemap[ob->tilex+1][ob->tiley];
- if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)
- ExplodeWall (ob->tilex+1,ob->tiley);
- other = tilemap[ob->tilex][ob->tiley-1];
- if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)
- ExplodeWall (ob->tilex,ob->tiley-1);
- other = tilemap[ob->tilex][ob->tiley+1];
- if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)
- ExplodeWall (ob->tilex,ob->tiley+1);
+ spot = (*(mapsegs[2]+farmapylookup[y]+(x-1))) >> 8;
+ if (spot == EXP_WALL_CODE)
+ ExplodeWall (x-1,y);
+ spot = (*(mapsegs[2]+farmapylookup[y]+(x+1))) >> 8;
+ if (spot == EXP_WALL_CODE)
+ ExplodeWall (x+1,y);
+ spot = (*(mapsegs[2]+farmapylookup[y-1]+x)) >> 8;
+ if (spot == EXP_WALL_CODE)
+ ExplodeWall (x,y-1);
+ spot = (*(mapsegs[2]+farmapylookup[y+1]+x)) >> 8;
+ if (spot == EXP_WALL_CODE)
+ ExplodeWall (x,y+1);
}
}
-
-
/*
=============================================================================
- WARP GATE
+ OBJ_WARP GATE
=============================================================================
*/
void T_Gate (objtype *ob);
-extern statetype s_gate1;
-extern statetype s_gate2;
-extern statetype s_gate3;
-extern statetype s_gate4;
+extern statetype s_obj_gate1;
+extern statetype s_obj_gate2;
+extern statetype s_obj_gate3;
+extern statetype s_obj_gate4;
-extern statetype s_fgate1;
-extern statetype s_fgate2;
-extern statetype s_fgate3;
-extern statetype s_fgate4;
+statetype s_obj_gate1 = {OBJ_WARP1PIC,10,T_Gate,&s_obj_gate2};
+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_gate1 = {WARP1PIC,12,T_Gate,&s_gate2};
-statetype s_gate2 = {WARP2PIC,12,T_Gate,&s_gate3};
-statetype s_gate3 = {WARP3PIC,12,T_Gate,&s_gate4};
-statetype s_gate4 = {WARP4PIC,12,T_Gate,&s_gate1};
+statetype s_pit = {PITOBJPIC,6,T_Gate,&s_pit};
-statetype s_fgate1 = {WARP1PIC,6,T_Gate,&s_fgate2};
-statetype s_fgate2 = {WARP2PIC,6,T_Gate,&s_fgate3};
-statetype s_fgate3 = {WARP3PIC,6,T_Gate,&s_fgate4};
-statetype s_fgate4 = {WARP4PIC,6,T_Gate,&s_fgate1};
-
-/*
-===============
-=
-= SpawnWarp
-=
-===============
-*/
+//---------------------------------------------------------------------------
+// SpawnWarp()
+//
+// TYPE : Type param is the gate number (1-what ever) will link you to
+// gate of that type.
+//---------------------------------------------------------------------------
void SpawnWarp (int tilex, int tiley, int type)
{
+
if (type)
- SpawnNewObj (tilex,tiley,&s_fgate1,TILEGLOBAL/3);
+ SpawnNewObj (tilex,tiley,&s_obj_gate1,TILEGLOBAL/3);
else
- SpawnNewObj (tilex,tiley,&s_gate1,TILEGLOBAL/3);
+ SpawnNewObj (tilex,tiley,&s_pit,TILEGLOBAL/3);
new->obclass = gateobj;
new->temp1 = type;
}
+
/*
===============
=
@@ -266,25 +403,36 @@ void SpawnWarp (int tilex, int tiley, int type)
void T_Gate (objtype *ob)
{
- int spot;
objtype *check;
- unsigned temp;
+ unsigned temp,spot;
if (CheckHandAttack (ob) && !playstate)
{
- //
- // warp
- //
- temp = bufferofs;
- bufferofs = 0;
- VW_Bar (26,4,232,9,STATUSCOLOR); // clear text description
- bufferofs = temp;
- IN_ClearKeysDown ();
- if (ob->temp1)
- {
+ // make
+ //
+// spot = (*(mapsegs[2]+farmapylookup[ob->tiley+1]+ob->tilex)) >> 8;
+// if (spot--)
+// if (gamestate.keys[spot])
+// TakeKey(spot);
+// else
+// return;
+
//
- // teleport inside level
+ // warp
//
+
+// temp = bufferofs;
+// bufferofs = 0;
+// VW_Bar (26,4,232,9,STATUSCOLOR); // clear text description
+// bufferofs = temp;
+
+// IN_ClearKeysDown ();
+ if (ob->temp1)
+ {
+ //
+ // teleport inside level
+ //
+
for (check=player->next;check;check=check->next)
if (check->obclass==gateobj && check->temp1==ob->temp1 &&
check != ob)
@@ -295,29 +443,29 @@ void T_Gate (objtype *ob)
Thrust (player->angle,TILEGLOBAL/2); // move forwards
Thrust (player->angle,TILEGLOBAL/2); // move forwards
fizzlein=true;
+ SD_PlaySound(WARPSND);
}
}
else
{
- //
- // teleport out of level
- //
+ //
+ // teleport out of level
+ //
+
playstate = ex_warped;
- spot = *(mapsegs[0]+farmapylookup[ob->tiley]+ob->tilex)-NAMESTART;
- if (spot<1)
- gamestate.mapon++;
- else
- gamestate.mapon=spot-1;
+ spot = (*(mapsegs[2]+farmapylookup[ob->tiley+1]+ob->tilex)) >> 8;
+ gamestate.mapon=spot;
SD_PlaySound(WARPUPSND);
}
}
}
+
/*
=============================================================================
- TROLLS
+ TROLLS
=============================================================================
*/
@@ -349,14 +497,14 @@ 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_trollattack1 = {TROLLATTACK1PIC,20,NULL,&s_trollattack2};
-statetype s_trollattack2 = {TROLLATTACK2PIC,10,T_DoDamage,&s_trollattack3};
-statetype s_trollattack3 = {TROLLATTACK2PIC,40,NULL,&s_trollpause};
+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_trollouch = {TROLLOUCHPIC,8,NULL,&s_troll1};
+statetype s_trollouch = {TROLLOUCHPIC,14,T_Troll,&s_troll1};
-statetype s_trolldie1 = {TROLLDIE1PIC,8,NULL,&s_trolldie2};
-statetype s_trolldie2 = {TROLLDIE2PIC,8,NULL,&s_trolldie3};
+statetype s_trolldie1 = {TROLLDIE1PIC,18,NULL,&s_trolldie2};
+statetype s_trolldie2 = {TROLLDIE2PIC,18,NULL,&s_trolldie3};
statetype s_trolldie3 = {TROLLDIE3PIC,0,NULL,&s_trolldie3};
@@ -370,11 +518,11 @@ statetype s_trolldie3 = {TROLLDIE3PIC,0,NULL,&s_trolldie3};
void SpawnTroll (int tilex, int tiley)
{
- SpawnNewObj(tilex,tiley,&s_troll1,40*PIXRADIUS);
+ SpawnNewObj(tilex,tiley,&s_troll1,35*PIXRADIUS);
new->speed = 2500;
new->obclass = trollobj;
- new->shootable = true;
- new->hitpoints = 10;
+ new->flags |= of_shootable;
+ new->hitpoints = EasyHitPoints(14);
}
@@ -388,7 +536,7 @@ void SpawnTroll (int tilex, int tiley)
void T_Troll (objtype *ob)
{
- if (Chase (ob,true))
+ if (Chase(ob,true) || (random(1000)<RANDOM_ATTACK))
{
ob->state = &s_trollattack1;
ob->ticcount = ob->state->tictime;
@@ -397,11 +545,755 @@ void T_Troll (objtype *ob)
}
+void T_WetMan(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_peek = {WET_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_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_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_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 = {WET_OUCHPIC,10,NULL,&s_wet_walk1};
+
+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};
+
+
+typedef enum {wt_BUBBLES,wt_WALK} WetManTypes;
+
+#define WT_TIMEREMAIN (ob->temp1)
+#define WT_STAGE (ob->temp2)
+
+
+/*
+===============
+=
+= SpawnWetMan
+=
+===============
+*/
+void SpawnWetMan(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);
+
+ new->obclass = wetobj;
+ new->speed = 1000;
+ new->flags &= ~of_shootable;
+ new->hitpoints = EasyHitPoints(18);
+}
+
+
+/*
+===============
+=
+= T_WetMan
+=
+===============
+*/
+
+void T_WetMan(objtype *ob)
+{
+ switch (WT_STAGE)
+ {
+ case wt_BUBBLES:
+ ob->flags &= ~of_shootable;
+ if (Chase(ob,true))
+ {
+ // RISE & GOTO WALK STAGE
+ //
+
+ WT_STAGE = wt_WALK;
+ WT_TIMEREMAIN = 60*5+random(60*5);
+ ob->state = &s_wet_rise1;
+ ob->speed = 2200;
+ ob->ticcount = ob->state->tictime;
+ }
+ else
+ {
+ // DEC COUNTER - And check for WALK
+ //
+ if ((WT_TIMEREMAIN-=realtics) < 0)
+ {
+ // RISE & GOTO WALK STAGE
+ //
+
+ WT_STAGE = wt_WALK;
+ WT_TIMEREMAIN = 60+random(60*2);
+ ob->state = &s_wet_rise1;
+ ob->speed = 2200;
+ ob->ticcount = ob->state->tictime;
+ }
+ else
+ if (random(1000)<5)
+ {
+ // RANDOM PEEK UP OUT OF WATER
+ //
+
+ ob->state=&s_wet_peek;
+ ob->ticcount = ob->state->tictime;
+ }
+ }
+ break;
+
+
+ case wt_WALK:
+ ob->flags |= of_shootable;
+ if (Chase(ob,true) || (random(1000)<RANDOM_ATTACK))
+ {
+ ob->state = &s_wet_attack1;
+ ob->ticcount = ob->state->tictime;
+ }
+ else
+ {
+ // DEC COUNTER - And check for SINK
+ //
+ if ((WT_TIMEREMAIN-=realtics) < 0)
+ {
+ // SINK & GOTO BUBBLE STAGE
+ //
+
+ WT_STAGE = wt_BUBBLES;
+ WT_TIMEREMAIN = 60*4+random(60*3);
+ ob->state = &s_wet_sink1;
+ ob->speed = 1200;
+ ob->ticcount = ob->state->tictime;
+ ob->flags &= ~of_shootable;
+ }
+
+ }
+ break;
+ }
+}
/*
=============================================================================
- ORCS
+ 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)
+ {
+ 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;
+ }
+ 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);
+}
+
+
+/*
+===============
+=
+= 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;
+
+ 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;
+
+ case zm_active:
+ if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
+ {
+ ob->state = &s_spook_attack1;
+ ob->ticcount = ob->state->tictime;
+ return;
+ }
+ 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
=============================================================================
*/
@@ -435,13 +1327,13 @@ 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,10,T_DoDamage,&s_orcattack3};
-statetype s_orcattack3 = {ORCATTACK2PIC,40,NULL,&s_orcpause};
+statetype s_orcattack2 = {ORCATTACK2PIC,20,NULL,&s_orcattack3};
+statetype s_orcattack3 = {ORCATTACK2PIC,30,T_DoDamage,&s_orcpause};
-statetype s_orcouch = {ORCOUCHPIC,10,NULL,&s_orc1};
+statetype s_orcouch = {ORCOUCHPIC,15,NULL,&s_orc1};
-statetype s_orcdie1 = {ORCDIE1PIC,8,NULL,&s_orcdie2};
-statetype s_orcdie2 = {ORCDIE2PIC,8,NULL,&s_orcdie3};
+statetype s_orcdie1 = {ORCDIE1PIC,18,NULL,&s_orcdie2};
+statetype s_orcdie2 = {ORCDIE2PIC,18,NULL,&s_orcdie3};
statetype s_orcdie3 = {ORCDIE3PIC,0,NULL,&s_orcdie3};
@@ -455,11 +1347,11 @@ statetype s_orcdie3 = {ORCDIE3PIC,0,NULL,&s_orcdie3};
void SpawnOrc (int tilex, int tiley)
{
- SpawnNewObj(tilex,tiley,&s_orc1,PIXRADIUS*32);
+ SpawnNewObj(tilex,tiley,&s_orc1,PIXRADIUS*35);
new->obclass = orcobj;
new->speed = 1536;
- new->shootable = true;
- new->hitpoints = 3;
+ new->flags |= of_shootable;
+ new->hitpoints = EasyHitPoints(6);
}
@@ -473,7 +1365,7 @@ void SpawnOrc (int tilex, int tiley)
void T_Orc (objtype *ob)
{
- if (Chase (ob,true))
+ if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
{
ob->state = &s_orcattack1;
ob->ticcount = ob->state->tictime;
@@ -485,7 +1377,7 @@ void T_Orc (objtype *ob)
/*
=============================================================================
- DEMON
+ DEMON
=============================================================================
*/
@@ -519,13 +1411,13 @@ 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,T_DoDamage,&s_demonattack3};
-statetype s_demonattack3 = {DEMONATTACK3PIC,30,NULL,&s_demonpause};
+statetype s_demonattack2 = {DEMONATTACK2PIC,20,NULL,&s_demonattack3};
+statetype s_demonattack3 = {DEMONATTACK3PIC,30,T_DoDamage,&s_demonpause};
-statetype s_demonouch = {DEMONOUCHPIC,10,NULL,&s_demon1};
+statetype s_demonouch = {DEMONOUCHPIC,15,T_Demon,&s_demon1};
-statetype s_demondie1 = {DEMONDIE1PIC,20,NULL,&s_demondie2};
-statetype s_demondie2 = {DEMONDIE2PIC,20,NULL,&s_demondie3};
+statetype s_demondie1 = {DEMONDIE1PIC,40,NULL,&s_demondie2};
+statetype s_demondie2 = {DEMONDIE2PIC,30,NULL,&s_demondie3};
statetype s_demondie3 = {DEMONDIE3PIC,0,NULL,&s_demondie3};
@@ -540,11 +1432,11 @@ statetype s_demondie3 = {DEMONDIE3PIC,0,NULL,&s_demondie3};
void SpawnDemon (int tilex, int tiley)
{
- SpawnNewObj(tilex,tiley,&s_demon1,TILEGLOBAL/2);
+ SpawnNewObj(tilex,tiley,&s_demon1,PIXRADIUS*35);
new->obclass = demonobj;
new->speed = 2048;
- new->shootable = true;
- new->hitpoints = 50;
+ new->flags |= of_shootable;
+ new->hitpoints = EasyHitPoints(50);
}
@@ -558,7 +1450,7 @@ void SpawnDemon (int tilex, int tiley)
void T_Demon (objtype *ob)
{
- if (Chase (ob,true))
+ if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))
{
ob->state = &s_demonattack1;
ob->ticcount = ob->state->tictime;
@@ -566,103 +1458,6 @@ void T_Demon (objtype *ob)
}
}
-/*
-=============================================================================
-
- MSHOTS
-
-temp1 = dir
-
-=============================================================================
-*/
-
-#define MSHOTDAMAGE 2
-#define MSHOTSPEED 10000
-
-void T_Mshot (objtype *ob);
-
-
-extern statetype s_mshot1;
-extern statetype s_mshot2;
-
-statetype s_mshot1 = {PSHOT1PIC,8,&T_Mshot,&s_mshot2};
-statetype s_mshot2 = {PSHOT2PIC,8,&T_Mshot,&s_mshot1};
-
-
-/*
-===============
-=
-= T_Mshot
-=
-===============
-*/
-
-void T_Mshot (objtype *ob)
-{
- objtype *check;
- long xmove,ymove,speed;
-
- xmove = ymove = 0;
-
- switch (ob->dir)
- {
- case north:
- ymove = -ob->speed*tics;
- break;
- case east:
- xmove = ob->speed*tics;
- break;
- case south:
- ymove = ob->speed*tics;
- break;
- case west:
- xmove = -ob->speed*tics;
- break;
- }
-
- ob->x+=xmove;
- ob->y+=ymove;
-
- CalcBounds (ob);
-
- ob->tilex = ob->x>>TILESHIFT;
- ob->tiley = ob->y>>TILESHIFT;
-
- if (tilemap[ob->tilex][ob->tiley])
- {
- SD_PlaySound (SHOOTWALLSND);
- ob->state = NULL;
- return;
- }
-
-//
-// check final position for monsters hit
-//
- if ( ob->xl <= player->xh
- && ob->xh >= player->xl
- && ob->yl <= player->yh
- && ob->yh >= player->yl)
- {
- TakeDamage (MSHOTDAMAGE*2);
- ob->state = NULL;
- return;
- }
-
- for (check = player->next; check; check=check->next)
- if (ob->shootable && ob->obclass != mageobj
- && ob->xl <= check->xh
- && ob->xh >= check->xl
- && ob->yl <= check->yh
- && ob->yh >= check->yl)
- {
- ShootActor (check,MSHOTDAMAGE);
- ob->state = NULL;
- return;
- }
-}
-
-
-
/*
=============================================================================
@@ -691,13 +1486,13 @@ extern statetype s_magedie1;
extern statetype s_magedie2;
-statetype s_magepause = {MAGE1PIC,100,NULL,&s_mage2};
+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_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};
@@ -706,6 +1501,9 @@ 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};
+
/*
===============
=
@@ -716,11 +1514,11 @@ statetype s_magedie2 = {MAGEDIE2PIC,0,NULL,&s_magedie2};
void SpawnMage (int tilex, int tiley)
{
- SpawnNewObj(tilex,tiley,&s_mage1,TILEGLOBAL/2);
+ SpawnNewObj(tilex,tiley,&s_mage1,PIXRADIUS*35);
new->obclass = mageobj;
- new->speed = 2048;
- new->shootable = true;
- new->hitpoints = 5;
+ new->speed = 3072;
+ new->flags |= of_shootable;
+ new->hitpoints = EasyHitPoints(5);
}
@@ -734,52 +1532,130 @@ void SpawnMage (int tilex, int tiley)
void T_Mage (objtype *ob)
{
- Chase (ob,false);
-//
-// check for line up with player
-//
+ fixed tempx,tempy;
+ unsigned temp_tilex,temp_tiley;
- if (ob->x-PIXRADIUS*14 < player->xh
- && ob->x+PIXRADIUS > player->xl)
+ eye_delay -= realtics;
+ if (eye_delay < 0)
{
- ob->temp1 = 1;
- ob->state = &s_mageattack1;
+ eye_mode = random(em_player4);
+ eye_delay = (10*60);
}
- else if (ob->y-PIXRADIUS*14 < player->yh
- && ob->y+PIXRADIUS > player->yl)
+
+ tempx = player->x;
+ tempy = player->y;
+ temp_tilex = player->tilex;
+ temp_tiley = player->tiley;
+
+
+ switch (eye_mode)
{
- ob->temp1 = 0;
- ob->state = &s_mageattack1;
+ 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};
+
+
/*
===============
=
-= T_MageShoot
+= SpawnRedDemon
=
===============
*/
-void T_MageShoot (objtype *ob)
+void SpawnRedDemon (int tilex, int tiley)
{
- SpawnNewObjFrac (ob->x,ob->y,&s_mshot1,PIXRADIUS*14);
- new->obclass = mshotobj;
- new->speed = MSHOTSPEED;
- if (ob->temp1)
- {
- if (ob->tiley < player->tiley)
- new->dir = south;
- else
- new->dir = north;
- }
- else
+ 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))
{
- if (ob->tilex < player->tilex)
- new->dir = east;
- else
- new->dir = west;
+ ob->state = &s_red_demonattack1;
+ ob->ticcount = ob->state->tictime;
+ return;
}
}
@@ -787,14 +1663,15 @@ void T_MageShoot (objtype *ob)
/*
=============================================================================
- nemesis
+ GRELMINAR
=============================================================================
*/
-void T_Nemesis (objtype *ob);
-void T_NemesisShoot (objtype *ob);
+void T_Grelminar (objtype *ob);
+void T_GrelminarShoot (objtype *ob);
+void T_Grelm_DropKey(objtype *ob);
extern statetype s_grelpause;
@@ -812,107 +1689,91 @@ 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_Nemesis,&s_grel2};
-statetype s_grel2 = {GREL2PIC,20,T_Nemesis,&s_grel1};
+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_NemesisShoot,&s_grelattack3};
+//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,20,NULL,&s_greldie2};
-statetype s_greldie2 = {GRELDIE2PIC,20,NULL,&s_greldie3};
-statetype s_greldie3 = {GRELDIE3PIC,20,NULL,&s_greldie4};
-statetype s_greldie4 = {GRELDIE4PIC,20,NULL,&s_greldie5};
-statetype s_greldie5 = {GRELDIE5PIC,20,NULL,&s_greldie6};
+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};
+
/*
===============
=
-= SpawnNemesis
+= SpawnGrelminar
=
===============
*/
-void SpawnNemesis (int tilex, int tiley)
+void SpawnGrelminar (int tilex, int tiley)
{
- SpawnNewObj(tilex,tiley,&s_grel1,PIXRADIUS*56);
+ SpawnNewObj(tilex,tiley,&s_grel1,PIXRADIUS*35);
new->obclass = grelmobj;
new->speed = 2048;
- new->shootable = true;
- new->hitpoints = 100;
+ new->flags |= of_shootable;
+ new->hitpoints = EasyHitPoints(100);
}
/*
===============
=
-= T_Nemesis
+= T_Grelminar
=
===============
*/
-void T_Nemesis (objtype *ob)
+void T_Grelminar (objtype *ob)
{
Chase (ob,false);
-//
-// check for line up with player
-//
- if (ob->tilex == player->tilex)
- {
- ob->temp1 = 1;
- ob->state = &s_grelattack1;
- }
- else if (ob->tiley == player->tiley)
- {
- ob->temp1 = 0;
- ob->state = &s_grelattack1;
- }
-}
+ if (!random(10))
+ if (ShootPlayer(ob,gshotobj,10000,&s_gshot1))
+ {
+ ob->state = &s_grelattack3;
+ }
+}
-/*
-===============
-=
-= T_NemesisShoot
-=
-===============
-*/
-void T_NemesisShoot (objtype *ob)
+//=================================
+//
+// T_Grelm_DropKey
+//
+//=================================
+void T_Grelm_DropKey(objtype *ob)
{
- SpawnNewObjFrac (ob->x,ob->y,&s_mshot1,PIXRADIUS*14);
- new->obclass = mshotobj;
- new->speed = MSHOTSPEED;
if (ob->temp1)
- {
- if (ob->tiley < player->tiley)
- new->dir = south;
- else
- new->dir = north;
- }
- else
- {
- if (ob->tilex < player->tilex)
- new->dir = east;
- else
- new->dir = west;
- }
-}
+ return;
+ SpawnBonus(ob->tilex,ob->tiley,B_RKEY);
+ SD_PlaySound(GRELM_DEADSND);
+ ob->temp1 = true;
+}
/*
=============================================================================
- BAT
+ BAT
=============================================================================
*/
@@ -936,8 +1797,8 @@ statetype s_bat4 = {BAT4PIC,6,T_Bat,&s_bat1};
statetype s_batpast = {BAT4PIC,80,T_BatPast,&s_bat1};
-statetype s_batdie1 = {BATDIE1PIC,8,NULL,&s_batdie2};
-statetype s_batdie2 = {BATDIE2PIC,8,NULL,NULL};
+statetype s_batdie1 = {BATDIE1PIC,18,NULL,&s_batdie2};
+statetype s_batdie2 = {BATDIE2PIC,18,NULL,NULL};
/*
@@ -950,9 +1811,9 @@ statetype s_batdie2 = {BATDIE2PIC,8,NULL,NULL};
void SpawnBat (int tilex, int tiley)
{
- SpawnNewObj(tilex,tiley,&s_bat1,PIXRADIUS*24);
+ SpawnNewObj(tilex,tiley,&s_bat1,PIXRADIUS*35);
new->obclass =batobj;
- new->shootable = true;
+ new->flags |= of_shootable;
new->hitpoints = 1;
new->speed = 2000;
@@ -1130,130 +1991,207 @@ void T_BatPast (objtype *ob)
}
+//--------------------------------------------------------------------------
+// ShootPlayer()
+//--------------------------------------------------------------------------
+boolean ShootPlayer(objtype *ob, short obclass, short speed, statetype *state)
+{
+ int angle = AngleNearPlayer(ob);
-/*
-=============================================================================
-
- BOUNCE
+ if (angle == -1)
+ return(false);
-temp2 = set when hit player, reset when hit wall
+ DSpawnNewObjFrac (ob->x,ob->y,state,PIXRADIUS*35);
+ new->speed = speed;
+ new->obclass = obclass;
+ new->active = always;
+ new->angle = angle;
-=============================================================================
-*/
+ return(true);
+}
-#define SPDBOUNCE 4096
-#define DMGBOUNCE 10
+//--------------------------------------------------------------------------
+// T_ShootPlayer()
+//--------------------------------------------------------------------------
+void T_ShootPlayer(objtype *ob)
+{
+ objtype *check;
+ long xmove,ymove,speed;
-void T_Bounce (objtype *ob);
+ speed = ob->speed*tics;
-extern statetype s_bounce1;
-extern statetype s_bounce2;
+ 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;
+ }
-statetype s_bounce1 = {BIGPSHOT1PIC,8,T_Bounce,&s_bounce2};
-statetype s_bounce2 = {BIGPSHOT2PIC,8,T_Bounce,&s_bounce1};
+ ob->tilex = ob->x >> TILESHIFT;
+ ob->tiley = ob->y >> TILESHIFT;
-/*
-===============
-=
-= SpawnBounce
-=
-===============
-*/
+// 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;
+ }
-void SpawnBounce (int tilex, int tiley, boolean towest)
-{
- SpawnNewObj(tilex,tiley,&s_bounce1,24*PIXRADIUS);
- new->obclass = bounceobj;
- if (towest)
- new->dir = west;
- else
- new->dir = north;
-}
+//
+//
+ 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;
-/*
-===============
-=
-= T_Bounce
-=
-===============
-*/
+ case gshotobj:
+ TakeDamage (25);
+ break;
+ }
+ ob->state = NULL;
+ return;
+ }
-void T_Bounce (objtype *ob)
-{
- long move;
- long deltax,deltay,size;
+// 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;
- move = SPDBOUNCE*tics;
- size = (long)ob->size + player->size + move;
+ case mshotobj:
+ ShootActor (check,MSHOTDAMAGE);
+ break;
- while (move)
- {
- deltax = ob->x - player->x;
- deltay = ob->y - player->y;
+ case gshotobj:
+ ShootActor (check,25);
+ break;
- if (deltax <= size && deltax >= -size
- && deltay <= size && deltay >= -size && !ob->temp2)
- {
- ob->temp2 = 1;
- TakeDamage (DMGBOUNCE);
+ case pshotobj:
+ ShootActor (check,25);
+ break;
+ }
+ ob->state = &s_pshot_exp1;
+ ob->ticcount = s_pshot_exp1.tictime;
+ return;
}
+}
- if (move < ob->distance)
+//-------------------------------------------------------------------------
+// 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)
{
- MoveObj (ob,move);
- break;
+ if (ob->tiley < player->tiley)
+ angle = 315;
+ else
+ angle = 45;
}
- 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;
-
- //
- // bounce if hit wall
- //
- switch (ob->dir)
+ else
{
- case north:
- if (tilemap[ob->tilex][--ob->tiley])
- {
- ob->dir = south;
- ob->tiley+=2;
- ob->temp2 = 0;
- }
- break;
- case east:
- if (tilemap[++ob->tilex][ob->tiley])
- {
- ob->dir = west;
- ob->tilex-=2;
- ob->temp2 = 0;
- }
- break;
- case south:
- if (tilemap[ob->tilex][++ob->tiley])
- {
- ob->dir = north;
- ob->tiley-=2;
- ob->temp2 = 0;
- }
- break;
- case west:
- if (tilemap[--ob->tilex][ob->tiley])
- {
- ob->dir = east;
- ob->tilex+=2;
- ob->temp2 = 0;
- }
- break;
+ if (ob->tiley < player->tiley)
+ angle = 225;
+ else
+ angle = 135;
}
- ob->distance = TILEGLOBAL;
+ return(angle);
+}
- actorat[ob->tilex][ob->tiley] = ob; // set down a new goal marker
+/////////////////////////////////////////////////////////////////////////////
+//
+// 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);
}
- CalcBounds (ob);
+ 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/C4_ASM.ASM b/C4_ASM.ASM
index d9da6eb..05eb2f0 100644
--- a/C4_ASM.ASM
+++ b/C4_ASM.ASM
@@ -1,4 +1,4 @@
-; Catacomb 3-D Source Code
+; Catacomb Abyss Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,9 @@ IDEAL
MODEL MEDIUM,C
-VIEWWIDTH = (33*8)
+INCLUDE "ID_ASM.EQU"
+
+VIEWWIDTH = (40*8) ;33
GC_INDEX = 03CEh
DATASEG
@@ -103,6 +105,8 @@ EXTRN scaledirectory:WORD ; array of MAXSCALE segment pointers to
; compiled scalers
EXTRN screenseg:WORD ; basically just 0xa000
EXTRN bufferofs:WORD ; offset of the current work screen
+EXTRN ylookup:WORD
+EXTRN screenpage:WORD
CODESEG
@@ -192,6 +196,53 @@ done:
ENDP
+;---------------------------------------------------------------------------
+;
+; RadarBlip()
+;
+; Displays a 'blip' (1 pixel wide X 2 pixel high) on the radar at
+; an (X,Y) relative to (RADAR_X,RADAR_Y) (defined below...)
+;
+;---------------------------------------------------------------------------
+
+PROC RadarBlip x:WORD, y:WORD, color:WORD
+USES SI,DI
+PUBLIC RadarBlip
+
+ mov ax,[screenseg]
+
+ mov es,ax
+ xor di,di
+
+ lea si,[ylookup]
+ add si,[y]
+ add si,[y]
+ add di,[si]
+
+ mov ax,[x]
+ shr ax,1
+ shr ax,1
+ shr ax,1
+ add di,ax
+
+ mov ax,[x]
+ and ax,7
+ mov cl,al
+ mov ah,080h
+ shr ah,cl
+ cli
+ mov al,GC_BITMASK
+ mov dx,GC_INDEX
+ out dx,ax
+ sti
+
+ mov ax,[color]
+ mov ah,[es:di] ; read into latches
+ mov [es:di],al ; write latches / color bit
+
+ ret
+
+ENDP
END
diff --git a/C4_DEBUG.C b/C4_DEBUG.C
index 4aa6831..c631b43 100644
--- a/C4_DEBUG.C
+++ b/C4_DEBUG.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,8 @@
// C3_DEBUG.C
-#include "C3_DEF.H"
+#include "DEF.H"
+#include "gelib.h"
#pragma hdrstop
/*
@@ -29,6 +30,9 @@
=============================================================================
*/
+#define DEBUG_OVERHEAD 0
+
+
#define VIEWTILEX 20
#define VIEWTILEY (VIEWHEIGHT/16)
@@ -49,17 +53,16 @@
=============================================================================
*/
-
+boolean autofire=false;
int maporgx;
int maporgy;
-enum {mapview,tilemapview,actoratview,visview} viewtype;
+enum {mapview,tilemapview,actoratview,visview,mapseg2,lastview} viewtype;
void ViewMap (void);
//===========================================================================
-
/*
==================
=
@@ -76,7 +79,7 @@ void DebugMemory (void)
spritetype _seg *block;
VW_FixRefreshBuffer ();
- US_CenterWindow (16,7);
+ CenterWindow (16,7);
#if 0
CA_OpenDebug ();
@@ -109,6 +112,7 @@ void DebugMemory (void)
//===========================================================================
+#if 0
/*
================
=
@@ -124,7 +128,7 @@ void PicturePause (void)
source = displayofs+panadjust;
- VW_ColorBorder (15);
+// VW_ColorBorder (15);
VW_SetLineWidth (40);
VW_SetScreen (0,0);
@@ -152,24 +156,11 @@ void PicturePause (void)
VW_WaitVBL(70);
Quit (NULL);
}
+#endif
//===========================================================================
-/*
-================
-=
-= ShapeTest
-=
-================
-*/
-
-void ShapeTest (void)
-{
-
-}
-
-
//===========================================================================
#define sc_1 0x02
@@ -198,6 +189,160 @@ int DebugKeys (void)
boolean esc;
int level,i;
+#if 0
+ if (Keyboard[sc_A])
+ {
+ char levelstr[50];
+ unsigned org_tile,org_mapon,msgnum;
+ boolean newmsg=true,newlevel=false;
+
+ VW_FixRefreshBuffer ();
+ CenterWindow (16,3);
+ US_Print("\n");
+ US_CPrint("Message Test");
+ VW_UpdateScreen();
+
+ org_mapon = mapon;
+ msgnum = (org_tile = *(mapsegs[0]+farmapylookup[player->tiley]+player->tilex))-NAMESTART;
+ while (1)
+ {
+ // Get outta' here
+ //
+ if (Keyboard[sc_Escape])
+ {
+ while (Keyboard[sc_Escape]);
+ break;
+ }
+
+ // Move to previous message
+ //
+ if (Keyboard[sc_UpArrow])
+ {
+ if (msgnum)
+ {
+ msgnum--;
+ newmsg = true;
+ }
+ }
+
+ // Move to next message
+ //
+ if (Keyboard[sc_DownArrow])
+ {
+ if (msgnum < 24)
+ {
+ msgnum++;
+ newmsg = true;
+ }
+ }
+
+ // Move to previous level
+ //
+ if (Keyboard[sc_LeftArrow])
+ {
+ if (mapon)
+ {
+ MM_SetPurge(&grsegs[LEVEL1TEXT+mapon],3);
+ mapon--;
+ newlevel = true;
+ }
+ }
+
+ // Move to next level
+ //
+ if (Keyboard[sc_RightArrow])
+ {
+ if (mapon < LASTMAP-2)
+ {
+ MM_SetPurge(&grsegs[LEVEL1TEXT+mapon],3);
+ mapon++;
+ newlevel = true;
+ }
+ }
+
+ // Load new level text
+ //
+ if (newlevel)
+ {
+ CA_CacheGrChunk(LEVEL1TEXT+mapon);
+ ScanText();
+ newmsg = true;
+ newlevel=false;
+ }
+
+ // Display new message text
+ //
+ if (newmsg)
+ {
+ *(mapsegs[0]+farmapylookup[player->tiley]+player->tilex) = msgnum+NAMESTART;
+ DrawText(true);
+ strcpy(levelstr,"Level: ");
+ itoa(mapon,levelstr+strlen(levelstr),10);
+ strcat(levelstr," Msg: ");
+ itoa(msgnum,levelstr+strlen(levelstr),10);
+ DisplaySMsg(levelstr,NULL);
+ newmsg = false;
+
+ if (Keyboard[sc_UpArrow] || Keyboard[sc_DownArrow] || Keyboard[sc_LeftArrow] || Keyboard[sc_RightArrow])
+ VW_WaitVBL(6);
+ }
+
+ }
+// Restore game
+//
+ MM_SetPurge(&grsegs[LEVEL1TEXT+mapon],3);
+ mapon = org_mapon;
+ CA_CacheGrChunk(LEVEL1TEXT+mapon);
+ ScanText();
+ *(mapsegs[0]+farmapylookup[player->tiley]+player->tilex) = org_tile;
+ 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);
+ US_CPrint("\n"GAMENAME);
+ US_CPrint(VERSION);
+ US_CPrint(REVISION);
+ VW_UpdateScreen();
+ IN_Ack ();
+ }
+
+ if (Keyboard[sc_Q]) // Q = Insta-Quit!
+ Quit("Insta-Quit!");
+
+ if (Keyboard[sc_Z]) // Z = freeze Time
+ {
+ if (FreezeTime)
+ FreezeTime = 1; // Allow refresh to dec to zero..
+ else
+ StopTime();
+
+ IN_Ack();
+ return 1;
+ }
+
+// if (Keyboard[sc_E])
+// FaceDoor((player->x>>16l)+1,(player->y>>16l));
+// FaceAngle(90);
+
+#if 0
if (Keyboard[sc_B]) // B = border color
{
CenterWindow(24,3);
@@ -213,9 +358,9 @@ int DebugKeys (void)
}
return 1;
}
+#endif
#if 0
-
if (Keyboard[sc_C]) // C = count objects
{
CountObjects();
@@ -234,9 +379,9 @@ int DebugKeys (void)
}
return 1;
}
-
#endif
+#if 0
if (Keyboard[sc_E]) // E = quit level
{
if (tedlevel)
@@ -244,7 +389,9 @@ int DebugKeys (void)
playstate = ex_warped;
gamestate.mapon++;
}
+#endif
+#if 0
if (Keyboard[sc_F]) // F = facing spot
{
CenterWindow (12,4);
@@ -258,6 +405,7 @@ int DebugKeys (void)
IN_Ack();
return 1;
}
+#endif
if (Keyboard[sc_G]) // G = god mode
{
@@ -271,12 +419,18 @@ int DebugKeys (void)
godmode ^= 1;
return 1;
}
+
+#if 0
if (Keyboard[sc_H]) // H = hurt self
{
TakeDamage (5);
}
- else if (Keyboard[sc_I]) // I = item cheat
+#endif
+
+ if (Keyboard[sc_I]) // I = item cheat
{
+ extern boolean redraw_gems;
+
CenterWindow (12,3);
US_PrintCentered ("Free items!");
VW_UpdateScreen();
@@ -285,31 +439,43 @@ int DebugKeys (void)
GiveBolt ();
GiveNuke ();
GivePotion ();
- if (!gamestate.keys[i])
+// if (!gamestate.keys[i])
GiveKey (i);
+ gamestate.gems[i] = GEM_DELAY_TIME;
}
+ gamestate.gems[4] = GEM_DELAY_TIME;
+ redraw_gems = true;
for (i=0;i<8;i++)
GiveScroll (i,false);
IN_Ack ();
return 1;
}
- else if (Keyboard[sc_M]) // M = memory info
+
+ if (Keyboard[sc_M]) // M = memory info
{
DebugMemory();
return 1;
}
- else if (Keyboard[sc_O]) // O = overhead
+
+#if DEBUG_OVERHEAD
+ if (Keyboard[sc_O]) // O = overhead
{
ViewMap();
return 1;
}
- else if (Keyboard[sc_P]) // P = pause with no screen disruptioon
+#endif
+
+#if 0
+ if (Keyboard[sc_P]) // P = pause with no screen disruptioon
{
PicturePause ();
return 1;
}
- else if (Keyboard[sc_S]) // S = slow motion
+#endif
+
+#if 0
+ if (Keyboard[sc_S]) // S = slow motion
{
singlestep^=1;
CenterWindow (18,3);
@@ -321,12 +487,10 @@ int DebugKeys (void)
IN_Ack ();
return 1;
}
- else if (Keyboard[sc_S]) // T = shape test
- {
- ShapeTest ();
- return 1;
- }
- else if (Keyboard[sc_V]) // V = extra VBLs
+#endif
+
+#if 0
+ if (Keyboard[sc_V]) // V = extra VBLs
{
CenterWindow(30,3);
PrintY+=6;
@@ -341,25 +505,30 @@ int DebugKeys (void)
}
return 1;
}
- else if (Keyboard[sc_W]) // W = warp to level
+#endif
+
+ if (Keyboard[sc_W]) // W = warp to level
{
CenterWindow(26,3);
PrintY+=6;
- US_Print(" Warp to which level(1-21):");
+ US_Print(" Warp to which level(0-18):");
VW_UpdateScreen();
esc = !US_LineInput (px,py,str,NULL,true,2,0);
if (!esc)
{
level = atoi (str);
- if (level>0 && level<21)
+ if (level>=0 && level<=LASTMAP-1)
{
- gamestate.mapon = level-1;
+ gamestate.mapon = level;
playstate = ex_warped;
+ lasttext = -1;
}
}
return 1;
}
- else if (Keyboard[sc_X]) // X = item cheat
+
+#if 0
+ if (Keyboard[sc_X]) // X = item cheat
{
CenterWindow (12,3);
US_PrintCentered ("Extra stuff!");
@@ -373,11 +542,9 @@ int DebugKeys (void)
IN_Ack ();
return 1;
}
- else if (Keyboard[sc_Z]) // Z = game over
- {
+#endif
- }
- else if (LastScan >= sc_1 && LastScan <= sc_8) // free scrolls
+ if (LastScan >= sc_1 && LastScan <= sc_8) // free scrolls
{
GiveScroll (LastScan-sc_1,false);
IN_ClearKeysDown ();
@@ -387,6 +554,8 @@ int DebugKeys (void)
}
+#if DEBUG_OVERHEAD
+
/*
=====================
=
@@ -437,7 +606,10 @@ asm mov ds,ax // restore turbo's data segment
EGAWRITEMODE(0);
}
+#endif
+
+#if DEBUG_OVERHEAD
/*
=====================
=
@@ -480,8 +652,10 @@ asm mov ds,ax // restore turbo's data segment
EGAWRITEMODE(0);
}
+#endif
+#if DEBUG_OVERHEAD
/*
===================
=
@@ -528,6 +702,12 @@ void OverheadRefresh (void)
tile = spotvis[x][y];
break;
+ case mapseg2:
+ tile = *(mapsegs[2]+farmapylookup[y]+x);
+ if (tile < 256)
+ tile = *(mapsegs[0]+farmapylookup[y]+x);
+ break;
+
}
if (tile<NUMTILE16)
@@ -574,24 +754,24 @@ void ViewMap (void)
//
// let user pan around
//
- IN_ReadControl(0,&c);
- if (c.xaxis == -1 && maporgx>0)
+ IN_ReadControl(0,&control);
+ if (control.xaxis == -1 && maporgx>0)
maporgx--;
- if (c.xaxis == 1 && maporgx<mapwidth-VIEWTILEX)
+ if (control.xaxis == 1 && maporgx<mapwidth-VIEWTILEX)
maporgx++;
- if (c.yaxis == -1 && maporgy>0)
+ if (control.yaxis == -1 && maporgy>0)
maporgy--;
- if (c.yaxis == 1 && maporgy<mapheight-VIEWTILEY)
+ if (control.yaxis == 1 && maporgy<mapheight-VIEWTILEY)
maporgy++;
- if (c.button0 && !button0held)
+ if (control.button0 && !button0held)
{
button0held = true;
viewtype++;
- if (viewtype>visview)
+ if (viewtype==lastview)
viewtype = mapview;
}
- if (!c.button0)
+ if (!control.button0)
button0held = false;
@@ -602,5 +782,5 @@ void ViewMap (void)
IN_ClearKeysDown ();
DrawPlayScreen ();
}
-
+#endif
diff --git a/C4_DRAW.C b/C4_DRAW.C
index dfb055e..e4c59f3 100644
--- a/C4_DRAW.C
+++ b/C4_DRAW.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss 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 @@
// C3_DRAW.C
-#include "C3_DEF.H"
+#include "DEF.H"
#pragma hdrstop
//#define DRAWEACH // draw walls one at a time for debugging
@@ -61,8 +61,8 @@ const unsigned BASESCALE = 32;
// maximum possible distance seperating them (for scaling overflow)
//
-unsigned screenloc[3]= {0x900,0x2000,0x3700};
-unsigned freelatch = 0x4e00;
+unsigned screenloc[3]= {PAGE1START,PAGE2START,PAGE3START};
+unsigned freelatch = FREESTART;
boolean fizzlein;
@@ -160,6 +160,7 @@ void BuildTables (void);
//==========================================================================
+#if 0
/*
==================
=
@@ -366,6 +367,8 @@ asm xchg bh,[es:di] // load latches and write pixels
}
+#endif
+
//==========================================================================
@@ -435,41 +438,152 @@ void near ScaleOneWall (int xl, int xh)
#endif
+// EAST / WEST WALLS
+//
int walllight1[NUMFLOORS] = {0,
- WALL1LPIC,WALL2LPIC,WALL3LPIC,WALL4LPIC,WALL5LPIC,WALL6LPIC,WALL7LPIC,
- WALL1LPIC,WALL2LPIC,WALL3LPIC,WALL4LPIC,WALL5LPIC,WALL6LPIC,WALL7LPIC,
+ W_WARP1EWPIC,
+ W_NEMPICEWPIC,W_PENTAEWPIC,W_ALTER_LFPIC,W_ALTER_RTPIC,
+ W_SUB1EWPIC,W_SUB2EWPIC,W_SUB3EWPIC,
+
+ W_TORCH1PIC,W_TORCH2PIC,
+ W_LSUB_STONEPIC,
+ W_BLOODY_LSUB_STONEPIC,
+ W_BREATH_LWALL1PIC,W_BREATH_LWALL2PIC,
+
EXPWALL1PIC,EXPWALL2PIC,EXPWALL3PIC,
- RDOOR1PIC,RDOOR2PIC,RDOOR1PIC,RDOOR2PIC,
- YDOOR1PIC,YDOOR2PIC,YDOOR1PIC,YDOOR2PIC,
- GDOOR1PIC,GDOOR2PIC,GDOOR1PIC,GDOOR2PIC,
- BDOOR1PIC,BDOOR2PIC,BDOOR1PIC,BDOOR2PIC};
+ W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,
+
+ W_WATER1EWPIC,W_DRAIN1EWPIC,
+ W_WATER2EWPIC,W_DRAIN2EWPIC,
+
+ W_WOODEN_DOORPIC,W_WOOD_DOOREWPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,
+
+ W_FINALEXITPIC,
+
+ W_WATER_EXP1PIC,W_WATER_EXP2PIC,W_WATER_EXP3PIC,
+
+ W_PRE_CHEATSPIC,W_CHEAT_WARPPIC,W_CHEAT_FREEZEPIC,W_SURFACE_PLAQPIC,
+
+ 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,
+ };
+
+// NORTH / SOUTH WALLS
+//
int walldark1[NUMFLOORS] = {0,
- WALL1DPIC,WALL2DPIC,WALL3DPIC,WALL4DPIC,WALL5DPIC,WALL6DPIC,WALL7DPIC,
- WALL1DPIC,WALL2DPIC,WALL3DPIC,WALL4DPIC,WALL5DPIC,WALL6DPIC,WALL7DPIC,
+ W_WARP1NSPIC,
+ W_NEMPICEWPIC,W_PENTANSPIC,1,1,
+ W_SUB1NSPIC,W_SUB2NSPIC,W_SUB3NSPIC,
+
+ W_TORCH1PIC,W_TORCH2PIC,
+ W_DSUB_STONEPIC,
+ W_BLOODY_DSUB_STONEPIC,
+ W_BREATH_DWALL1PIC,W_BREATH_DWALL2PIC,
+
EXPWALL1PIC,EXPWALL2PIC,EXPWALL3PIC,
- RDOOR1PIC,RDOOR2PIC,RDOOR1PIC,RDOOR2PIC,
- YDOOR1PIC,YDOOR2PIC,YDOOR1PIC,YDOOR2PIC,
- GDOOR1PIC,GDOOR2PIC,GDOOR1PIC,GDOOR2PIC,
- BDOOR1PIC,BDOOR2PIC,BDOOR1PIC,BDOOR2PIC};
+ W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,
+
+ W_WATER1NSPIC,W_DRAIN1NSPIC,
+ W_WATER2NSPIC,W_DRAIN2NSPIC,
+ W_WOODEN_DOORPIC,W_WOOD_DOORNSPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,
+
+ W_FINALEXITPIC,
+
+ W_WATER_EXP1PIC,W_WATER_EXP2PIC,W_WATER_EXP3PIC,
+
+ W_CHEAT_GODPIC,W_CHEAT_ITEMSPIC,W_POST_CHEATPIC,W_SURFACE_PLAQPIC,
+
+ 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,
+ };
+
+// EAST / WEST WALLS
+//
int walllight2[NUMFLOORS] = {0,
- WALL1LPIC,WALL2LPIC,WALL3LPIC,WALL4LPIC,WALL5LPIC,WALL6LPIC,WALL7LPIC,
- WALL1LPIC,WALL2LPIC,WALL3LPIC,WALL4LPIC,WALL5LPIC,WALL6LPIC,WALL7LPIC,
- EXPWALL1PIC,EXPWALL2PIC,EXPWALL3PIC,
- RDOOR2PIC,RDOOR1PIC,RDOOR2PIC,RDOOR1PIC,
- YDOOR2PIC,YDOOR1PIC,YDOOR2PIC,YDOOR1PIC,
- GDOOR2PIC,GDOOR1PIC,GDOOR2PIC,GDOOR1PIC,
- BDOOR2PIC,BDOOR1PIC,BDOOR2PIC,BDOOR1PIC};
+ W_WARP2EWPIC,
+ W_NEMPICEWPIC,W_PENTAEWPIC,W_ALTER_LFPIC,W_ALTER_RTPIC,
+ W_SUB1EWPIC,W_SUB2EWPIC,W_SUB3EWPIC,
+
+ W_TORCH2PIC,W_TORCH1PIC,
+ W_LSUB_STONEPIC,
+ W_BLOODY_LSUB_STONEPIC,
+ W_BREATH_LWALL2PIC,W_BREATH_LWALL1PIC,
+
+ EXPWALL2PIC,EXPWALL1PIC,EXPWALL3PIC,
+
+ W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,
+
+ W_WATER2EWPIC,W_DRAIN2EWPIC,
+ W_WATER1EWPIC,W_DRAIN1EWPIC,
+
+ W_WOODEN_DOORPIC,W_WOOD_DOOREWPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,
+ W_FINALEXITPIC,
+
+ W_WATER_EXP2PIC,W_WATER_EXP1PIC,W_WATER_EXP1PIC,
+
+ W_PRE_CHEATSPIC,W_CHEAT_WARPPIC,W_CHEAT_FREEZEPIC,W_SURFACE_PLAQPIC,
+
+ 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,
+ };
+
+// NORTH / SOUTH WALLS
+//
int walldark2[NUMFLOORS] = {0,
- WALL1DPIC,WALL2DPIC,WALL3DPIC,WALL4DPIC,WALL5DPIC,WALL6DPIC,WALL7DPIC,
- WALL1DPIC,WALL2DPIC,WALL3DPIC,WALL4DPIC,WALL5DPIC,WALL6DPIC,WALL7DPIC,
- EXPWALL1PIC,EXPWALL2PIC,EXPWALL3PIC,
- RDOOR2PIC,RDOOR1PIC,RDOOR2PIC,RDOOR1PIC,
- YDOOR2PIC,YDOOR1PIC,YDOOR2PIC,YDOOR1PIC,
- GDOOR2PIC,GDOOR1PIC,GDOOR2PIC,GDOOR1PIC,
- BDOOR2PIC,BDOOR1PIC,BDOOR2PIC,BDOOR1PIC};
+ W_WARP2NSPIC,
+ W_NEMPICEWPIC,W_PENTANSPIC,1,1,
+ W_SUB1NSPIC,W_SUB2NSPIC,W_SUB3NSPIC,
+
+ W_TORCH2PIC,W_TORCH1PIC,
+ W_DSUB_STONEPIC,
+ W_BLOODY_DSUB_STONEPIC,
+ W_BREATH_DWALL2PIC,W_BREATH_DWALL1PIC,
+
+ EXPWALL2PIC,EXPWALL1PIC,EXPWALL3PIC,
+
+ W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,
+
+ W_WATER2NSPIC,W_DRAIN2NSPIC,
+ W_WATER1NSPIC,W_DRAIN1NSPIC,
+
+ W_WOODEN_DOORPIC,W_WOOD_DOORNSPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,
+
+ W_FINALEXITPIC,
+
+ W_WATER_EXP2PIC,W_WATER_EXP1PIC,W_WATER_EXP1PIC,
+
+ W_CHEAT_GODPIC,W_CHEAT_ITEMSPIC,W_POST_CHEATPIC,W_SURFACE_PLAQPIC,
+
+ 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,
+ };
/*
=====================
@@ -500,6 +614,8 @@ void DrawVWall (walltype *wallptr)
int mapadd;
unsigned lastpix,lastsource,lastwidth;
+ short mike;
+
if (wallptr->rightclip < wallptr->leftclip)
Quit ("DrawVWall: Right < Left");
@@ -540,6 +656,10 @@ void DrawVWall (walltype *wallptr)
//
if (wallptr->side)
{ // east or west wall
+
+ if (wallptr->color == 1)
+ mike = 1;
+
if (animframe)
wallpic = walllight2[wallptr->color];
else
@@ -560,6 +680,10 @@ void DrawVWall (walltype *wallptr)
}
else
{ // north or south wall
+
+ if (wallptr->color == 1)
+ mike = 1;
+
if (animframe)
wallpic = walldark2[wallptr->color];
else
@@ -874,6 +998,65 @@ ansok:;
#pragma warn +rvl
+#if 0
+/*
+=========================
+=
+= FixedAdd
+=
+= add two 16 bit fixed point numbers
+= to subtract, invert the sign of B before invoking
+=
+=========================
+*/
+
+fixed FixedAdd (fixed a, fixed b)
+{
+ fixed value;
+
+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 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
+bok:
+
+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
+
+done:
+
+asm mov [WORD PTR value],ax
+asm mov [WORD PTR value+2],dx
+
+ return value;
+}
+#endif
+
//==========================================================================
@@ -1137,6 +1320,8 @@ void BuildTables (void)
void ClearScreen (void)
{
+ unsigned topcolor=*skycolor, bottomcolor=*groundcolor;
+
//
// clear the screen
//
@@ -1150,9 +1335,10 @@ asm mov dx,40-VIEWWIDTH/8
asm mov bl,VIEWWIDTH/16
asm mov bh,CENTERY+1
-asm xor ax,ax
+asm mov ax,topcolor
asm mov es,[screenseg]
asm mov di,[bufferofs]
+asm add di,((SCREENWIDTH*VIEWY)+(VIEWX/8))
toploop:
asm mov cl,bl
@@ -1163,7 +1349,7 @@ asm dec bh
asm jnz toploop
asm mov bh,CENTERY+1
-asm mov ax,0x0808
+asm mov ax,bottomcolor
bottomloop:
asm mov cl,bl
@@ -1280,9 +1466,6 @@ void DrawScaleds (void)
for (obj = player->next;obj;obj=obj->next)
{
- if (!obj->state->shapenum)
- continue;
-
tilespot = &tilemap[0][0]+(obj->tilex<<6)+obj->tiley;
visspot = &spotvis[0][0]+(obj->tilex<<6)+obj->tiley;
//
@@ -1298,14 +1481,23 @@ void DrawScaleds (void)
|| ( *(visspot+64) && !*(tilespot+64) )
|| ( *(visspot+63) && !*(tilespot+63) ) )
{
- obj->active = true;
+ 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
+ if (!obj->state->shapenum)
+ continue;
+
*vislist++ = obj;
numvisable++;
}
+ else
+ if ((obj->active != always) && (obj->active != noalways))
+ obj->active = no;
}
if (vislist == &depthsort[0])
@@ -1362,6 +1554,7 @@ void CalcTics (void)
if (lasttimecount > TimeCount)
TimeCount = lasttimecount; // if the game was paused a LONG time
+#if 0
if (DemoMode) // demo recording and playback needs
{ // to be constant
//
@@ -1372,15 +1565,16 @@ void CalcTics (void)
;
lasttimecount = oldtimecount + DEMOTICS;
TimeCount = lasttimecount + DEMOTICS;
- tics = DEMOTICS;
+ realtics = tics = DEMOTICS;
}
else
+#endif
{
//
// non demo, so report actual time
//
newtime = TimeCount;
- tics = newtime-lasttimecount;
+ realtics = tics = newtime-lasttimecount;
lasttimecount = newtime;
#ifdef FILEPROFILE
@@ -1396,6 +1590,9 @@ void CalcTics (void)
TimeCount -= (tics-MAXTICS);
tics = MAXTICS;
}
+
+ if (realtics>MAXREALTICS)
+ realtics = MAXREALTICS;
}
}
@@ -1413,16 +1610,18 @@ void CalcTics (void)
void DrawHand (void)
{
- int picnum;
+ #define HAND_X_POS ((VIEWWIDTH/16)-(10/2)) // "10" = hand width in bytes
+
+ #define picnum HAND1PICM
+
memptr source;
unsigned dest,width,height;
- picnum = HAND1PICM;
- 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]+12+bufferofs;
+ dest = ylookup[VIEWHEIGHT-handheight]+HAND_X_POS+bufferofs; // 12
width = picmtable[picnum-STARTPICM].width;
height = picmtable[picnum-STARTPICM].height;
diff --git a/C4_GAME.C b/C4_GAME.C
index a71d254..edb7612 100644
--- a/C4_GAME.C
+++ b/C4_GAME.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,10 @@
// C3_GAME.C
-#include "C3_DEF.H"
+#include <stdlib.h>
+
+#include "DEF.H"
+#include "gelib.h"
#pragma hdrstop
#ifdef PROFILE
@@ -34,37 +37,50 @@
=============================================================================
*/
-#define NUMLUMPS 25
-
-#define CONTROLSLUMP 0
-#define ORCLUMP 1
-#define TROLLLUMP 2
-#define WARPLUMP 3
-#define BOLTLUMP 4
-#define NUKELUMP 5
-#define POTIONLUMP 6
-#define RKEYLUMP 7
-#define YKEYLUMP 8
-#define GKEYLUMP 9
-#define BKEYLUMP 10
-#define SCROLLLUMP 11
-#define CHESTLUMP 12
-#define PLAYERLUMP 13
-#define WALL1LUMP 14
-#define WALL2LUMP 15
-#define BDOORLUMP 16
-#define DEMONLUMP 17
-#define MAGELUMP 18
-#define BATLUMP 19
-#define GRELLUMP 20
-#define GOALLUMP 21
+#define NUMLUMPS 36
+
+#define ORCLUMP 0
+#define TROLLLUMP 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 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
+
int lumpstart[NUMLUMPS] = {
-CONTROLS_LUMP_START,
ORC_LUMP_START,
TROLL_LUMP_START,
-WARP_LUMP_START,
BOLT_LUMP_START,
NUKE_LUMP_START,
POTION_LUMP_START,
@@ -75,22 +91,37 @@ BKEY_LUMP_START,
SCROLL_LUMP_START,
CHEST_LUMP_START,
PLAYER_LUMP_START,
-WALL1_LUMP_START,
-WALL2_LUMP_START,
-BDOOR_LUMP_START,
+//WALL1_LUMP_START,
+//WALL2_LUMP_START,
+//BDOOR_LUMP_START,
+0,0,0,
DEMON_LUMP_START,
MAGE_LUMP_START,
BAT_LUMP_START,
GREL_LUMP_START,
-NEMESISPIC
+TOMBSTONES_LUMP_START,
+ZOMBIE_LUMP_START,
+SPOOK_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,
+OBJ_WARP_LUMP_START,
+EYE_LUMP_START,
+REDDEMON_LUMP_START,
+PIT_LUMP_START,
+TIME_LUMP_START,
+O_WATER_CHEST_LUMP_START,
};
int lumpend[NUMLUMPS] = {
-CONTROLS_LUMP_END,
ORC_LUMP_END,
TROLL_LUMP_END,
-WARP_LUMP_END,
BOLT_LUMP_END,
NUKE_LUMP_END,
POTION_LUMP_END,
@@ -101,18 +132,36 @@ BKEY_LUMP_END,
SCROLL_LUMP_END,
CHEST_LUMP_END,
PLAYER_LUMP_END,
-WALL1_LUMP_END,
-WALL2_LUMP_END,
-BDOOR_LUMP_END,
+//WALL1_LUMP_END,
+//WALL2_LUMP_END,
+//BDOOR_LUMP_END,
+0,0,0,
DEMON_LUMP_END,
MAGE_LUMP_END,
BAT_LUMP_END,
GREL_LUMP_END,
-NEMESISPIC
+TOMBSTONES_LUMP_END,
+ZOMBIE_LUMP_END,
+SPOOK_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,
+OBJ_WARP_LUMP_END,
+EYE_LUMP_END,
+REDDEMON_LUMP_END,
+PIT_LUMP_END,
+TIME_LUMP_END,
+O_WATER_CHEST_LUMP_END,
};
+
/*
=============================================================================
@@ -125,6 +174,8 @@ unsigned latchpics[NUMLATCHPICS];
unsigned tileoffsets[NUMTILE16];
unsigned textstarts[27];
+boolean splitscreen=false;
+
/*
=============================================================================
@@ -138,6 +189,17 @@ boolean lumpneeded[NUMLUMPS];
//===========================================================================
+//==========================================================================
+//
+//
+// LOCAL PROTOTYPES
+//
+//
+//==========================================================================
+
+void CashPoints(void);
+
+
/*
==========================
@@ -151,6 +213,9 @@ boolean lumpneeded[NUMLUMPS];
void ScanInfoPlane (void)
{
+ extern unsigned gnd_colors[];
+
+ char hibyte;
unsigned x,y,i,j;
int tile;
unsigned far *start;
@@ -164,6 +229,8 @@ void ScanInfoPlane (void)
for (x=0;x<mapwidth;x++)
{
tile = *start++;
+ hibyte = tile >> 8;
+ tile &= 0xff;
if (!tile)
continue;
@@ -188,6 +255,20 @@ 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;
+
case 12:
case 13:
case 14:
@@ -200,21 +281,30 @@ void ScanInfoPlane (void)
SpawnBonus(x,y,B_SCROLL1+tile-12);
break;
+#if 0
case 20: // goal
lumpneeded[GOALLUMP] = true;
SpawnBonus(x,y,B_GOAL);
break;
+#endif
case 21: // chest
- lumpneeded[CHESTLUMP] = true;
+ if (gnd_colors[gamestate.mapon] == 0x0101)
+ lumpneeded[WATERCHESTLUMP] = true;
+ else
+ lumpneeded[CHESTLUMP] = true;
SpawnBonus(x,y,B_CHEST);
- break;
+ break;
- case 24:
- lumpneeded[WARPLUMP] = true;
- SpawnWarp (x,y,0);
+ case 31:
+ case 32:
+ case 33:
+ case 34:
+ case 35:
+ lumpneeded[OBJ_WARPLUMP] = true;
+ SpawnWarp (x,y,tile-30);
break;
-//------
+
case 41:
if (gamestate.difficulty <gd_Hard)
break;
@@ -271,10 +361,11 @@ void ScanInfoPlane (void)
break;
case 28:
- lumpneeded[GRELLUMP] = true;
- SpawnNemesis (x,y);
+ lumpneeded[RKEYLUMP] = lumpneeded[GRELLUMP] = true;
+ SpawnGrelminar (x,y);
break;
+#if 0
case 29:
SpawnBounce (x,y,0);
break;
@@ -282,13 +373,90 @@ void ScanInfoPlane (void)
case 30:
SpawnBounce (x,y,1);
break;
+#endif
- case 31:
- case 32:
- case 33:
- case 34:
- lumpneeded[WARPLUMP] = true;
- SpawnWarp (x,y,tile-30);
+ case 46:
+ case 47:
+ case 48:
+ lumpneeded[TOMBSTONESLUMP] = true;
+ SpawnTombstone(x,y,tile-46);
+ break;
+
+ case 54:
+ lumpneeded[PITLUMP] = true;
+ SpawnWarp(x,y,0);
+ break;
+
+ case 53:
+ if (gamestate.difficulty <gd_Normal)
+ break;
+ case 52:
+ lumpneeded[ZOMBIELUMP] = true;
+ SpawnZombie(x,y);
+ 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);
+ break;
+
+ case 57:
+ lumpneeded[FTIMELUMP] = true;
+ SpawnFTime(x,y);
+ break;
+
+ case 56:
+ if (gamestate.difficulty <gd_Normal)
+ break;
+ case 55:
+ lumpneeded[SKELETONLUMP] = true;
+ SpawnSkeleton(x,y);
+ 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);
+ 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);
+ 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);
+ break;
+
+ case 20:
+ case 24:
+ case 30:
+ lumpneeded[REDDEMONLUMP] = true;
+ SpawnRedDemon (x,y);
break;
}
}
@@ -340,41 +508,39 @@ void ScanText (void)
static char *levelnames[] =
{
- "The Approach",
- "Nemesis's Keep",
- "Ground Floor",
- "Second Floor",
- "Third Floor",
- "Tower One",
- "Tower Two",
- "Secret Halls",
- "Access Floor",
- "The Dungeon",
- "Lower Dungeon",
- "Catacomb",
- "Lower Reaches",
- "The Warrens",
- "Hidden Caverns",
- "The Fens of Insanity",
- "Chaos Corridors",
- "The Labyrinth",
- "Halls of Blood",
- "Nemesis's Lair"
+ "The Towne Cemetery",
+ "The Garden of Tears",
+ "The Den of Zombies",
+ "The Mausoleum Grounds",
+ "The Main Floor of the Mausoleum",
+ "Mike's Blastable Passage",
+ "The Crypt of Nemesis the Undead",
+ "The Subterranean Vault",
+ "The Ancient Aqueduct",
+ "The Orc Mines",
+ "The Lair of the Troll",
+ "The Demon's Inferno",
+ "The Battleground of the Titans",
+ "The Coven of Mages",
+ "The Inner Sanctum",
+ "The Haunt of Nemesis",
+ "The Passage to the Surface",
+ "Big Jim's Domain",
+ "Nolan's Nasty",
};
+
void DrawEnterScreen (void)
{
- int x,y;
-
- VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,9); // Medium blue
-
- x = (VIEWWIDTH - (18 * 8)) / 2 -3;
- y = (VIEWHEIGHT - (5 * 8)) / 2;
- VW_DrawPic(x / 8,y,ENTERPLAQUEPIC);
-
- WindowX = x;
- WindowW = 18 * 8;
- PrintY = (VIEWHEIGHT/2) + 3;
- US_CPrint (levelnames[gamestate.mapon]);
+ int width;
+
+ bufferofs = displayofs = screenloc[screenpage];
+ VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,0);
+ width = strlen(levelnames[gamestate.mapon]);
+ if (width < 20)
+ width = 20;
+ CenterWindow(width,5);
+ US_CPrint("\nYou have arrived at\n");
+ US_CPrint(levelnames[gamestate.mapon]);
}
//==========================================================================
@@ -452,21 +618,23 @@ void CacheScaleds (void)
==================
*/
-void SetupGameLevel (void)
+void SetupGameLevel ()
{
- int x,y,i;
- unsigned far *map,tile,spot;
+ int x,y,i,loop;
+ unsigned far *map,tile,far *spotptr,spot;
memset (tileneeded,0,sizeof(tileneeded));
//
// randomize if not a demo
//
+#if 0
if (DemoMode)
{
US_InitRndT(false);
gamestate.difficulty = gd_Normal;
}
else
+#endif
US_InitRndT(true);
//
@@ -493,29 +661,47 @@ void SetupGameLevel (void)
memset (tilemap,0,sizeof(tilemap));
memset (actorat,0,sizeof(actorat));
map = mapsegs[0];
+ spotptr = mapsegs[2];
for (y=0;y<mapheight;y++)
for (x=0;x<mapwidth;x++)
{
tile = *map++;
+
+ 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;
+ }
+
if (tile<NUMFLOORS)
{
+ if (tile == WALL_SKELETON_CODE)
+ tileneeded[tile+1] = tileneeded[tile+2] = true;
+
tileneeded[tile] = true;
tilemap[x][y] = tile;
- if (tile>=EXPWALLSTART && tile<EXPWALLSTART+NUMEXPWALLS)
- {
- tileneeded[WALLEXP] = tileneeded[WALLEXP+1]
- = tileneeded[WALLEXP+2] = true;
- }
-
if (tile>0)
(unsigned)actorat[x][y] = tile;
}
+ spotptr++;
}
+ //
+ // Mark any gfx chunks needed
+ //
+
+// CA_MarkGrChunk(NORTHICONSPR);
+// CA_CacheMarks(NULL);
+
//
// decide which graphics are needed and spawn actors
//
+ zombie_base_delay = 0; // (1*60) + random(1*60);
ScanInfoPlane ();
//
@@ -523,7 +709,6 @@ void SetupGameLevel (void)
// are in memory
//
CA_LoadAllSounds ();
-
}
@@ -586,32 +771,64 @@ asm mov ds,ax // restore turbo's data
=====================
*/
-void Victory (void)
+void Victory (boolean playsounds)
{
- FreeUpMemory ();
- NormalScreen ();
+ struct Shape shape;
+
+ if (playsounds)
+ {
+ SD_PlaySound (GETBOLTSND);
+ SD_WaitSoundDone ();
+ SD_PlaySound (GETNUKESND);
+ SD_WaitSoundDone ();
+ SD_PlaySound (GETPOTIONSND);
+ SD_WaitSoundDone ();
+ SD_PlaySound (GETKEYSND);
+ SD_WaitSoundDone ();
+ SD_PlaySound (GETSCROLLSND);
+ SD_WaitSoundDone ();
+ 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);
+
CA_CacheGrChunk (FINALEPIC);
- VWB_DrawPic (0,0,FINALEPIC);
UNMARKGRCHUNK(FINALEPIC);
- VW_UpdateScreen ();
- SD_PlaySound (GETBOLTSND);
- SD_WaitSoundDone ();
- SD_PlaySound (GETNUKESND);
- SD_WaitSoundDone ();
- SD_PlaySound (GETPOTIONSND);
- SD_WaitSoundDone ();
- SD_PlaySound (GETKEYSND);
- SD_WaitSoundDone ();
- SD_PlaySound (GETSCROLLSND);
- SD_WaitSoundDone ();
- SD_PlaySound (GETPOINTSSND);
- SD_WaitSoundDone ();
- IN_ClearKeysDown ();
- IN_Ack();
+ 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
}
//==========================================================================
+#if 0
/*
===================
=
@@ -629,12 +846,16 @@ void Died (void)
FreeUpMemory ();
SD_PlaySound (GAMEOVERSND);
bufferofs = screenloc[(screenpage+1)%3];
- LatchDrawPic(0,0,DEADPIC);
- FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,false);
+ DisplayMsg("Though fallen, your Spirit ...",NULL);
+// LatchDrawPic(0,0,DEADPIC);
+// FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,false);
IN_ClearKeysDown();
- IN_Ack();
+ while (!Keyboard[sc_Enter]);
+// IN_Ack();
VW_SetScreen (bufferofs,0);
+ VW_ColorBorder(0);
}
+#endif
//==========================================================================
@@ -654,6 +875,7 @@ void NormalScreen (void)
bufferofs = SCREEN2START;
VW_Bar(0,0,320,200,0);
VW_SetScreen (displayofs,0);
+ splitscreen = false;
}
//==========================================================================
@@ -673,33 +895,24 @@ void DrawPlayScreen (void)
screenpage = 0;
bufferofs = 0;
- VW_Bar (0,0,320,STATUSLINES,7);
+ VW_Bar (0,0,320,STATUSLINES,0);
for (i=0;i<3;i++)
{
bufferofs = screenloc[i];
- VW_Bar (0,0,320,VIEWHEIGHT,7);
+ VW_Bar (0,0,320,VIEWHEIGHT,0);
}
-
- VW_SetSplitScreen(144);
+ splitscreen = true;
+ VW_SetSplitScreen(120);
VW_SetScreen(screenloc[0],0);
- bufferofs = 0;
CA_CacheGrChunk (STATUSPIC);
- CA_CacheGrChunk (SIDEBARSPIC);
+ bufferofs = 0;
VW_DrawPic (0,0,STATUSPIC);
- for (i=0;i<3;i++)
- {
- bufferofs = screenloc[i];
- VW_DrawPic (33,0,SIDEBARSPIC);
- }
-
- grneeded[STATUSPIC]&= ~ca_levelbit;
- grneeded[SIDEBARSPIC]&= ~ca_levelbit;
+ grneeded[STATUSPIC] &= ~ca_levelbit;
MM_SetPurge(&grsegs[STATUSPIC],3);
- MM_SetPurge(&grsegs[SIDEBARSPIC],3);
RedrawStatusWindow ();
bufferofs = displayofs = screenloc[0];
@@ -804,163 +1017,6 @@ void LoadLatchMem (void)
/*
===================
=
-= FizzleFade
-=
-===================
-*/
-
-#define PIXPERFRAME 1600
-
-void FizzleFade (unsigned source, unsigned dest,
- unsigned width,unsigned height, boolean abortable)
-{
- unsigned drawofs,pagedelta;
- unsigned char maskb[8] = {1,2,4,8,16,32,64,128};
- unsigned x,y,p,frame;
- long rndval;
-
- pagedelta = dest-source;
- VW_SetScreen (dest,0);
- rndval = 1;
- y = 0;
-
-asm mov es,[screenseg]
-asm mov dx,SC_INDEX
-asm mov al,SC_MAPMASK
-asm out dx,al
-
- TimeCount=frame=0;
- do // while (1)
- {
- if (abortable)
- {
- IN_ReadControl(0,&c);
- if (c.button0 || c.button1 || Keyboard[sc_Space]
- || Keyboard[sc_Enter])
- {
- VW_ScreenToScreen (source,dest,width/8,height);
- return;
- }
- }
-
- for (p=0;p<PIXPERFRAME;p++)
- {
- //
- // seperate random value into x/y pair
- //
- asm mov ax,[WORD PTR rndval]
- asm mov dx,[WORD PTR rndval+2]
- asm mov bx,ax
- asm dec bl
- asm mov [BYTE PTR y],bl // low 8 bits - 1 = y xoordinate
- asm mov bx,ax
- asm mov cx,dx
- asm shr cx,1
- asm rcr bx,1
- asm shr bx,1
- asm shr bx,1
- asm shr bx,1
- asm shr bx,1
- asm shr bx,1
- asm shr bx,1
- asm shr bx,1
- asm mov [x],bx // next 9 bits = x xoordinate
- //
- // advance to next random element
- //
- asm shr dx,1
- asm rcr ax,1
- asm jnc noxor
- asm xor dx,0x0001
- asm xor ax,0x2000
-noxor:
- asm mov [WORD PTR rndval],ax
- asm mov [WORD PTR rndval+2],dx
-
- if (x>width || y>height)
- continue;
- drawofs = source+ylookup[y];
-
- asm mov cx,[x]
- asm mov si,cx
- asm and si,7
- asm mov dx,GC_INDEX
- asm mov al,GC_BITMASK
- asm mov ah,BYTE PTR [maskb+si]
- asm out dx,ax
-
- asm mov si,[drawofs]
- asm shr cx,1
- asm shr cx,1
- asm shr cx,1
- asm add si,cx
- asm mov di,si
- asm add di,[pagedelta]
-
- asm mov dx,GC_INDEX
- asm mov al,GC_READMAP // leave GC_INDEX set to READMAP
- asm out dx,al
-
- asm mov dx,SC_INDEX+1
- asm mov al,1
- asm out dx,al
- asm mov dx,GC_INDEX+1
- asm mov al,0
- asm out dx,al
-
- asm mov bl,[es:si]
- asm xchg [es:di],bl
-
- asm mov dx,SC_INDEX+1
- asm mov al,2
- asm out dx,al
- asm mov dx,GC_INDEX+1
- asm mov al,1
- asm out dx,al
-
- asm mov bl,[es:si]
- asm xchg [es:di],bl
-
- asm mov dx,SC_INDEX+1
- asm mov al,4
- asm out dx,al
- asm mov dx,GC_INDEX+1
- asm mov al,2
- asm out dx,al
-
- asm mov bl,[es:si]
- asm xchg [es:di],bl
-
- asm mov dx,SC_INDEX+1
- asm mov al,8
- asm out dx,al
- asm mov dx,GC_INDEX+1
- asm mov al,3
- asm out dx,al
-
- asm mov bl,[es:si]
- asm xchg [es:di],bl
-
- if (rndval == 1) // entire sequence has been completed
- {
- EGABITMASK(255);
- EGAMAPMASK(15);
- return;
- };
- }
- frame++;
- while (TimeCount<frame) // don't go too fast
- ;
- } while (1);
-
-
-}
-
-//==========================================================================
-
-/*
-===================
-=
= FizzleOut
=
===================
@@ -1003,6 +1059,8 @@ void FreeUpMemory (void)
//==========================================================================
+#if 0
+
/*
==================
=
@@ -1111,6 +1169,8 @@ void CheckHighScore (long score,word other)
}
}
+#endif
+
//==========================================================================
@@ -1124,6 +1184,7 @@ void CheckHighScore (long score,word other)
void GameLoop (void)
{
+ boolean wait = false;
int i,xl,yl,xh,yh;
char num[20];
#ifdef PROFILE
@@ -1131,6 +1192,7 @@ void GameLoop (void)
#endif
DrawPlayScreen ();
+ IN_ClearKeysDown();
restart:
if (!loadedgame)
@@ -1138,6 +1200,9 @@ restart:
gamestate.difficulty = restartgame;
restartgame = gd_Continue;
DrawEnterScreen ();
+ if (gamestate.mapon != 8)
+ fizzlein = true;
+ wait = true;
}
do
@@ -1148,14 +1213,33 @@ restart:
else
loadedgame = false;
+ FreeUpMemory();
+ LoadLatchMem();
CacheScaleds ();
+ if (EASYMODEON)
+ DisplaySMsg("*** NOVICE ***", NULL);
+ else
+ DisplaySMsg("*** WARRIOR ***", NULL);
+
+ status_delay = 250;
+
+ RedrawStatusWindow();
+ if (wait)
+ {
+ VW_WaitVBL(120);
+ wait = false;
+ }
+
+
#ifdef PROFILE
start = clock();
while (start == clock());
start++;
#endif
+
PlayLoop ();
+
#ifdef PROFILE
end = clock();
itoa(end-start,str,10);
@@ -1165,35 +1249,40 @@ itoa(end-start,str,10);
switch (playstate)
{
- case ex_died:
- Died ();
- NormalScreen ();
- FreeUpMemory ();
- CheckHighScore (gamestate.score,gamestate.mapon+1);
- return;
- case ex_warped:
- FizzleOut (true);
- if (gamestate.mapon >= NUMLEVELS)
- {
- Victory ();
- FreeUpMemory ();
- CheckHighScore(gamestate.score,gamestate.mapon+1);
- return;
- }
- break;
case ex_abort:
FreeUpMemory ();
return;
case ex_resetgame:
+ NewGame();
case ex_loadedgame:
+ case ex_warped:
goto restart;
- case ex_victorious:
- Victory ();
- FreeUpMemory();
- CheckHighScore(gamestate.score,gamestate.mapon+1);
- return;
+ break;
}
} while (1);
}
+
+
+#if 0
+//
+// make wall pictures purgable
+//
+ for (i=0;i<NUMSCALEWALLS;i++)
+ if (walldirectory[i])
+ MM_SetPurge (&(memptr)walldirectory[i],3);
+
+
+//
+// cache wall pictures back in
+//
+ for (i=1;i<NUMFLOORS;i++)
+ if (tileneeded[i])
+ {
+ SetupScaleWall (walllight1[i]);
+ SetupScaleWall (walllight2[i]);
+ SetupScaleWall (walldark1[i]);
+ SetupScaleWall (walldark2[i]);
+ }
+#endif \ No newline at end of file
diff --git a/C4_MAIN.C b/C4_MAIN.C
index 684cb32..715244d 100644
--- a/C4_MAIN.C
+++ b/C4_MAIN.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -17,18 +17,20 @@
*/
// C3_MAIN.C
+#define CATALOG
-#include "C3_DEF.H"
+
+#include <time.h>
+#include <stdarg.h>
+
+#include "DEF.H"
+#include "GELIB.H"
#pragma hdrstop
+#include <dir.h>
/*
=============================================================================
- CATACOMB 3-D
-
- An Id Software production
-
- by John Carmack
=============================================================================
*/
@@ -50,12 +52,26 @@
=============================================================================
*/
+textinfo MainHelpText;
+
+GameDiff restartgame;
+boolean loadedgame,abortgame,ingame;
+
+
memptr scalesegs[NUMPICS];
char str[80],str2[20];
unsigned tedlevelnum;
boolean tedlevel;
gametype gamestate;
exittype playstate;
+char SlowMode = 0;
+int starting_level;
+boolean EASYMODEON;
+
+short NumGames=0;
+unsigned Flags=0;
+
+void DisplayIntroText(void);
/*
=============================================================================
@@ -69,6 +85,7 @@ exittype playstate;
//===========================================================================
+#if 0
// JAB Hack begin
#define MyInterrupt 0x60
void interrupt (*intaddr)();
@@ -102,6 +119,7 @@ jabunhack(void)
setvect(MyInterrupt,oldintaddr);
}
// JAB Hack end
+#endif
//===========================================================================
@@ -117,9 +135,20 @@ jabunhack(void)
void NewGame (void)
{
- memset (&gamestate,0,sizeof(gamestate));
- gamestate.mapon = 0;
- gamestate.body = MAXBODY;
+ if (!loadedgame)
+ {
+ memset (&gamestate,0,sizeof(gamestate));
+ gamestate.mapon = starting_level;
+ gamestate.body = MAXBODY;
+ }
+
+ BGFLAGS = 0;
+ Flags &= FL_CLEAR;
+
+ boltsleft = bolttimer = 0;
+ FreezeTime = 0;
+
+// memset (gamestate.levels,-1,sizeof(gamestate.levels));
}
//===========================================================================
@@ -140,9 +169,15 @@ boolean SaveTheGame(int file)
objtype *o;
memptr bigbuffer;
+ if (!CA_FarWrite(file,(void far *)&FreezeTime,sizeof(FreezeTime)))
+ return(false);
+
if (!CA_FarWrite(file,(void far *)&gamestate,sizeof(gamestate)))
return(false);
+ if (!CA_FarWrite(file,(void far *)&EASYMODEON,sizeof(EASYMODEON)))
+ return(false);
+
expanded = mapwidth * mapheight * 2;
MM_GetPtr (&bigbuffer,expanded);
@@ -193,11 +228,24 @@ boolean LoadTheGame(int file)
unsigned far *map,tile;
memptr bigbuffer;
+ screenpage = 0;
+ FreeUpMemory();
+
+ playstate = ex_loadedgame;
+ if (!CA_FarRead(file,(void far *)&FreezeTime,sizeof(FreezeTime)))
+ return(false);
+
if (!CA_FarRead(file,(void far *)&gamestate,sizeof(gamestate)))
return(false);
+ if (!CA_FarRead(file,(void far *)&EASYMODEON,sizeof(EASYMODEON)))
+ return(false);
+
SetupGameLevel (); // load in and cache the base old level
+ if (!FindFile(Filename,"SAVE GAME",-1))
+ Quit("Error: Can't find saved game file!");
+
expanded = mapwidth * mapheight * 2;
MM_GetPtr (&bigbuffer,expanded);
@@ -346,6 +394,7 @@ void InitGame (void)
US_SetLoadSaveHooks(LoadTheGame,SaveTheGame,ResetGame);
+
//
// load in and lock down some basic chunks
//
@@ -356,17 +405,14 @@ void InitGame (void)
CA_MarkGrChunk(STARTTILE8);
CA_MarkGrChunk(STARTTILE8M);
CA_MarkGrChunk(HAND1PICM);
- CA_MarkGrChunk(HAND2PICM);
- CA_MarkGrChunk(ENTERPLAQUEPIC);
+ CA_MarkGrChunk(NORTHICONSPR);
CA_CacheMarks (NULL);
MM_SetLock (&grsegs[STARTFONT],true);
MM_SetLock (&grsegs[STARTTILE8],true);
MM_SetLock (&grsegs[STARTTILE8M],true);
MM_SetLock (&grsegs[HAND1PICM],true);
- MM_SetLock (&grsegs[HAND2PICM],true);
- MM_SetLock (&grsegs[ENTERPLAQUEPIC],true);
fontcolor = WHITE;
@@ -393,6 +439,7 @@ void InitGame (void)
// US_FinishTextScreen();
#endif
+#if 0
//
// reclaim the memory from the linked in text screen
//
@@ -403,11 +450,12 @@ void InitGame (void)
segstart++;
seglength--;
}
-
MML_UseSpace (segstart,seglength);
+#endif
VW_SetScreenMode (GRMODE);
- VW_ColorBorder (3);
+ ge_textmode = false;
+// VW_ColorBorder (3);
VW_ClearVideo (BLACK);
//
@@ -432,36 +480,65 @@ void clrscr (void); // can't include CONIO.H because of name conflicts...
==========================
*/
-void Quit (char *error)
+void Quit (char *error, ...)
{
+ short exit_code=0;
unsigned finscreen;
-#if 0
+ va_list ap;
+
+ va_start(ap,error);
+
if (!error)
{
CA_SetAllPurge ();
+#ifndef CATALOG
CA_CacheGrChunk (PIRACY);
finscreen = (unsigned)grsegs[PIRACY];
- }
#endif
-
+ }
ShutdownId ();
+
if (error && *error)
{
- puts(error);
- exit(1);
+ vprintf(error,ap);
+ exit_code = 1;
}
-#if 0
- if (!NoWait)
+#ifndef CATALOG
+ else
{
movedata (finscreen,0,0xb800,0,4000);
+
+ if (kbhit())
+ {
+ while (kbhit())
+ bioskey(0);
+ }
+
bioskey (0);
- clrscr();
}
#endif
- exit(0);
+ va_end(ap);
+
+#ifndef CATALOG
+ if (!error)
+ {
+ _argc = 2;
+ _argv[1] = "LAST.SHL";
+ _argv[2] = "ENDSCN.SCN";
+ _argv[3] = NULL;
+ if (execv("LOADSCN.EXE", _argv) == -1)
+ {
+ clrscr();
+ puts("Couldn't find executable LOADSCN.EXE.\n");
+ exit(1);
+ }
+ }
+#endif
+
+ exit(exit_code);
}
//===========================================================================
@@ -490,80 +567,111 @@ void TEDDeath(void)
=====================
*/
-static char *ParmStrings[] = {"easy","normal","hard",""};
-
void DemoLoop (void)
{
- int i,level;
+/////////////////////////////////////////////////////////////////////////////
+// main game cycle
+/////////////////////////////////////////////////////////////////////////////
+// displayofs = bufferofs = 0;
+// VW_Bar (0,0,320,200,0);
+// VW_SetScreen(0,0);
+
+// set EASYMODE
//
-// check for launch from ted
+ if (stricmp(_argv[2], "1") == 0)
+ EASYMODEON = true;
+ else
+ EASYMODEON = false;
+
+// restore game
//
- if (tedlevel)
+ if (stricmp(_argv[3], "1") == 0)
{
- NewGame();
- gamestate.mapon = tedlevelnum;
- restartgame = gd_Normal;
- for (i = 1;i < _argc;i++)
+ VW_FadeOut();
+ bufferofs = displayofs = 0;
+ VW_Bar(0,0,320,200,0);
+ if (GE_LoadGame())
{
- if ( (level = US_CheckParm(_argv[i],ParmStrings)) == -1)
- continue;
-
- restartgame = gd_Easy+level;
- break;
+ loadedgame = true;
+ playstate = ex_loadedgame;
+ Keyboard[sc_Enter] = true;
+ VW_Bar(0,0,320,200,0);
+ ColoredPalette();
}
- GameLoop();
- TEDDeath();
+ VW_Bar(0,0,320,200,0);
+ VW_FadeIn();
}
+ // Play a game
+ //
+ restartgame = gd_Normal;
+ NewGame();
+ GameLoop();
+}
-//
-// main game cycle
-//
- displayofs = bufferofs = 0;
- VW_Bar (0,0,320,200,0);
+//-------------------------------------------------------------------------
+// DisplayIntroText()
+//-------------------------------------------------------------------------
+void DisplayIntroText()
+{
+ 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.";
- while (1)
- {
- CA_CacheGrChunk (TITLEPIC);
- bufferofs = SCREEN2START;
- displayofs = SCREEN1START;
- VWB_DrawPic (0,0,TITLEPIC);
- MM_SetPurge (&grsegs[TITLEPIC],3);
- UNMARKGRCHUNK(TITLEPIC);
- FizzleFade (bufferofs,displayofs,320,200,true);
-
- if (!IN_UserInput(TickBase*3,false))
- {
- CA_CacheGrChunk (CREDITSPIC);
- VWB_DrawPic (0,0,CREDITSPIC);
- MM_SetPurge (&grsegs[CREDITSPIC],3);
- UNMARKGRCHUNK(CREDITSPIC);
- FizzleFade (bufferofs,displayofs,320,200,true);
+ 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 oldfontcolor=fontcolor;
- if (!IN_UserInput(TickBase*3,false))
- {
-highscores:
- DrawHighScores ();
- FizzleFade (bufferofs,displayofs,320,200,true);
- IN_UserInput(TickBase*3,false);
- }
+ fontcolor = 14;
+ WindowX=WindowY=0;
+ PPT_RightEdge=319;
+ PPT_LeftEdge=0;
- if (IN_IsUserInput())
- {
- US_ControlPanel ();
+ PrintY = 1;
+ PrintPropText(toptext);
- if (restartgame || loadedgame)
- {
- GameLoop ();
- goto highscores;
- }
- }
+ PrintY = 160;
+ PrintPropText(bottomtext);
+
+ fontcolor = oldfontcolor;
+}
+
+#if 0
+boolean ChooseGameLevel()
+{
+ char choices[] = {sc_Escape,sc_E,sc_N,sc_H,0},ch;
+
+ CenterWindow(20,10);
+ US_Print("\n Choose difficulty level:\n");
+ US_Print(" (E)asy\n");
+ US_Print(" (N)ormal\n");
+ US_Print(" (H)ard\n");
+ US_Print("\n (ESC)ape aborts\n");
+
+// VW_UpdateScreen();
+ if ((ch=GetKeyChoice(choices)) == sc_Escape)
+ {
+ while (Keyboard[sc_Escape]);
+ LastScan = 0;
+ return(false);
}
+
+ if (ch == sc_E)
+ restartgame = gd_Easy;
+ else
+ if (ch == sc_N)
+ restartgame = gd_Normal;
+ else
+ restartgame = gd_Hard;
+
+ return(true);
}
+#endif
+
//===========================================================================
@@ -579,6 +687,9 @@ void SetupScalePic (unsigned picnum)
{
unsigned scnum;
+ if (picnum == 1)
+ return;
+
scnum = picnum-FIRSTSCALEPIC;
if (shapedirectory[scnum])
@@ -610,6 +721,9 @@ void SetupScaleWall (unsigned picnum)
unsigned scnum;
byte far *dest;
+ if (picnum == 1)
+ return;
+
scnum = picnum-FIRSTWALLPIC;
if (walldirectory[scnum])
@@ -664,6 +778,7 @@ void HelpScreens (void)
}
+#if 0
/*
==================
=
@@ -672,12 +787,15 @@ void HelpScreens (void)
==================
*/
-#define MINMEMORY 335000l
+#define MINMEMORY 400000l
void CheckMemory(void)
{
unsigned finscreen;
+ if (Flags & FL_NOMEMCHECK)
+ return;
+
if (mminfo.nearheap+mminfo.farheap+mminfo.EMSmem+mminfo.XMSmem
>= MINMEMORY)
return;
@@ -689,6 +807,7 @@ void CheckMemory(void)
gotoxy (1,24);
exit(1);
}
+#endif
//===========================================================================
@@ -701,46 +820,53 @@ void CheckMemory(void)
==========================
*/
+char *MainParmStrings[] = {"q","l","ver","nomemcheck",nil};
+boolean LaunchedFromShell = false;
+
void main (void)
{
short i;
- if (stricmp(_argv[1], "/VER") == 0)
+ starting_level = 0;
+
+ for (i = 1;i < _argc;i++)
{
- printf("Catacomb 3-D version 1.22 (Rev 1)\n");
- printf("Copyright 1991-93 Softdisk Publishing\n");
- printf("Developed for use with 100%% IBM compatibles\n");
- printf("that have 640K memory and DOS version 3.3 or later\n");
- printf("and EGA graphics or better.\n");
- exit(0);
+ switch (US_CheckParm(_argv[i],MainParmStrings))
+ {
+ case 0:
+ Flags |= FL_QUICK;
+ break;
+
+ case 1:
+ starting_level = atoi(_argv[i]+1);
+ if ((starting_level < 0) || (starting_level > LASTMAP-1))
+ starting_level = 0;
+ break;
+
+ case 2:
+ printf("%s %s rev %s\n",GAMENAME,VERSION,REVISION);
+ exit(0);
+ break;
+
+ case 3:
+ Flags |= FL_NOMEMCHECK;
+ break;
+ }
}
- if (stricmp(_argv[1], "/?") == 0)
- {
- printf("Catacomb 3-D version 1.22\n");
- printf("Copyright 1991-93 Softdisk Publishing\n\n");
- printf("Syntax:\n");
- printf("CAT3D [/<switch>]\n\n");
- printf("Switch What it does\n");
- printf("/? This Information\n");
- printf("/VER Display Program Version Information\n");
- printf("/COMP Fix problems with SVGA screens\n");
- printf("/NOAL No AdLib or SoundBlaster detection\n");
- printf("/NOJOYS Tell program to ignore joystick\n");
- printf("/NOMOUSE Tell program to ignore mouse\n");
- printf("/HIDDENCARD Overrides video detection\n\n");
- printf("Each switch must include a '/' and multiple switches\n");
- printf("must be seperated by at least one space.\n\n");
+ if (!stricmp(_argv[1], "^(a@&r`"))
+ LaunchedFromShell = true;
+ if (!LaunchedFromShell)
+ {
+ clrscr();
+ puts("You must type CATABYSS at the DOS prompt to run CATACOMB ABYSS 3-D.");
exit(0);
}
- jabhack();
+ randomize();
InitGame ();
-
- CheckMemory ();
-
LoadLatchMem ();
#ifdef PROFILE
@@ -748,9 +874,6 @@ void main (void)
GameLoop ();
#endif
-//NewGame ();
-//GameLoop ();
-
DemoLoop();
- Quit("Demo loop exited???");
+ Quit(NULL);
}
diff --git a/C4_PLAY.C b/C4_PLAY.C
index 112041f..ba68993 100644
--- a/C4_PLAY.C
+++ b/C4_PLAY.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,8 @@
// C3_PLAY.C
-#include "C3_DEF.H"
+#include "DEF.H"
+#include "gelib.h"
#pragma hdrstop
/*
@@ -30,7 +31,7 @@
*/
#define POINTTICS 6
-
+#define PAUSE 300
/*
=============================================================================
@@ -40,8 +41,34 @@
=============================================================================
*/
-ControlInfo c;
-boolean running,slowturn;
+byte bcolor;
+short skytimer=-1,skytimer_reset;
+short groundtimer=-1,groundtimer_reset;
+unsigned *skycolor,*groundcolor;
+unsigned nocolorchange=0xFFFF;
+byte BGFLAGS, // global that holds all current flags
+ bgflag; // used by BG changer, this flag is set when done
+
+
+unsigned sky_daytonight[]={0x0909,0x0101,0x0808,0x0000,0xFFFF};
+//unsigned gnd_daytonight[]={0x0202,0xFFFF};
+
+unsigned sky_lightning[]={0x0101,0x0909,0x0f0f,0x0808,0x0000,0xFFFF};
+
+unsigned sky_colors[NUMLEVELS]={0x0000,0x0000,0x0000,0x0000,0x0808,
+ 0x0404,0x0000,0x0000,0x0000,0x0000,
+ 0x0000,0x0000,0x0000,0x0000,0x0606,
+ 0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x0000};
+unsigned gnd_colors[NUMLEVELS]={0x0202,0x0202,0x0606,0x0202,0x0707,
+ 0x0505,0x0808,0x0606,0x0101,0x0808,
+ 0x0606,0x0404,0x0808,0x0c0c,0x0e0e,
+ 0x0808,0x0808,0x0c0c,0x0000,0x0707,
+ 0x0808};
+
+
+ControlInfo control;
+boolean running=false; //,slowturn;
int bordertime;
objtype objlist[MAXACTORS],*new,*obj,*player,*lastobj,*objfreelist;
@@ -51,11 +78,13 @@ byte *nearmapylookup[MAPSIZE];
boolean singlestep,godmode;
int extravbls;
+status_flags status_flag;
+int status_delay;
//
// replacing refresh manager
//
-unsigned mapwidth,mapheight,tics;
+unsigned mapwidth,mapheight,tics,realtics;
boolean compatability;
byte *updateptr;
unsigned mapwidthtable[64];
@@ -69,6 +98,8 @@ byte update[UPDATESIZE];
int mousexmove,mouseymove;
int pointcount,pointsleft;
+short BeepTime = 0;
+
/*
=============================================================================
@@ -79,6 +110,8 @@ int pointcount,pointsleft;
void CalcBounds (objtype *ob);
void DrawPlayScreen (void);
+void PreFullDisplay(void);
+void PostFullDisplay(boolean draw_view);
//
@@ -96,6 +129,7 @@ int objectcount;
void StopMusic(void);
void StartMusic(void);
+void CalibrateJoystick(short joynum);
//==========================================================================
@@ -106,8 +140,8 @@ void StartMusic(void);
//
///////////////////////////////////////////////////////////////////////////
-#define MAXX 264
-#define MAXY 146
+#define MAXX 320
+#define MAXY 120
void CenterWindow(word w,word h)
{
@@ -127,9 +161,25 @@ void CenterWindow(word w,word h)
void CheckKeys (void)
{
+ extern boolean autofire;
+
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
//
@@ -138,42 +188,252 @@ void CheckKeys (void)
CenterWindow (8,3);
US_PrintCentered ("PAUSED");
VW_UpdateScreen ();
- SD_MusicOff();
+// SD_MusicOff();
IN_Ack();
- SD_MusicOn();
+// SD_MusicOn();
Paused = false;
if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
}
+ else
+ if (Keyboard[sc_Enter]) // P = pause with no screen disruptioon
+ {
+// SD_MusicOff();
+ DisplaySMsg("PAUSED",NULL);
+ IN_Ack();
+// SD_MusicOn();
+ if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
+ }
+ else
+ if (Keyboard[sc_S])
+ {
+ char *Text[] = {{"Slow Mode ON"},{"Slow Mode OFF"}};
+
+ SlowMode ^= 1;
+ extravbls = SlowMode << 3;
+ CenterWindow (8,3);
+ US_PrintCentered (Text[SlowMode]);
+ VW_UpdateScreen ();
+// SD_MusicOff();
+ IN_Ack();
+// SD_MusicOn();
+ if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
+ }
+#endif
+
+
+// F2 - SOUND OPTIONS
+//
+ if (Keyboard[sc_F2])
+ {
+ int height=7;
+ boolean ChoiceMade = false;
+
+ if (AdLibPresent)
+ height++;
+
+ VW_FixRefreshBuffer();
+ CenterWindow(22,height);
+ US_Print( "\n 1 ) NO SOUND \n");
+ US_Print( " 2 ) PC AUDIO \n");
+
+ if (AdLibPresent)
+ US_Print(" 3 ) ADLIB AUDIO\n");
+
+ US_Print( "\n ESC) EXIT ");
+ VW_UpdateScreen();
+
+ // Switch audio device ON/OFF & load sounds if there
+ // was a change in the device.
+
+ do {
+
+ if (Keyboard[1]) // ESC - Exit
+ ChoiceMade = true;
+ else
+ if (Keyboard[2]) // 1 - No Sound
+ {
+ SD_SetSoundMode(sdm_Off);
+ ChoiceMade = true;
+ }
+ else
+ if (Keyboard[3]) // 2 - PC Audio
+ {
+ SD_SetSoundMode(sdm_PC);
+// if (oldsoundmode != sdm_PC)
+ CA_LoadAllSounds();
+ ChoiceMade = true;
+ }
+ else
+ if ((Keyboard[4]) && AdLibPresent) // 3 - AdLib Audio
+ {
+ SD_SetSoundMode(sdm_AdLib);
+// if (oldsoundmode != sdm_AdLib)
+ CA_LoadAllSounds();
+ ChoiceMade = true;
+ }
+
+ } while (!ChoiceMade);
+ tics = realtics = 1;
+ IN_ClearKeysDown();
+ }
+// F5 - CALIBRATE JOYSTICK
//
-// F1-F7/ESC to enter control panel
+ if (Keyboard[sc_F5])
+ {
+ CalibrateJoystick(0);
+ tics = realtics = 1;
+ IN_ClearKeysDown();
+ }
+
+deadloop:;
+// ESCAPE - quits game
//
- if ( (LastScan >= sc_F1 && LastScan <= sc_F7) || LastScan == sc_Escape)
+ if ((Keyboard[sc_Escape]) || (Flags & FL_DEAD))
{
- StopMusic ();
- NormalScreen ();
- FreeUpMemory ();
- US_CenterWindow (20,8);
- US_CPrint ("Loading");
- VW_UpdateScreen ();
- US_ControlPanel();
- if (abortgame)
+ char ch;
+
+ DisplaySMsg("Options", NULL);
+ if ((status_flag != S_TIMESTOP) || (Flags & FL_DEAD))
+ status_flag = S_NONE;
+
+
+ if (Flags & FL_DEAD)
{
- playstate = ex_abort;
- return;
+ char choices[] = {sc_Escape,sc_R,sc_N,sc_Q,0};
+ ch = DisplayMsg("Restore New Quit",choices);
+ }
+ else
+ {
+ char choices[] = {sc_Escape,sc_S,sc_R,sc_N,sc_Q,0};
+ ch = DisplayMsg("Save Restore New Quit",choices);
}
- StartMusic ();
+ DrawText(true);
+
+ switch (ch)
+ {
+ case sc_S:
+ if (!(Flags & FL_DEAD))
+ Keyboard[sc_F3] = true;
+ break;
+
+ case sc_R:
+ Keyboard[sc_F4] = true;
+ break;
+
+ case sc_N:
+ DisplaySMsg("Starting anew", NULL);
+ 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();
+ NormalScreen();
+ FreeUpMemory();
+ Quit(NULL);
+ 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;
+
+ VW_FadeOut();
+
+ FreeUpMemory();
+ if (!FindFile("HELP.TXT",NULL,1))
+ nohelp = true;
+
+ if (LoadTextFile("HELP.TXT",&MainHelpText))
+ {
+ VW_SetSplitScreen(200);
+ bufferofs = displayofs = screenloc[0];
+ VW_Bar(0,0,320,200,0);
+
+ DisplayText(&MainHelpText);
+ }
+ else
+ nohelp = true;
+
+ if (nohelp)
+ {
+ VW_FadeIn();
+ CenterWindow(30,5);
+ US_CPrint("\nError loading HELP file.\n");
+ US_CPrint("Press any key.");
+ IN_Ack();
+ VW_FadeOut();
+ nohelp = false;
+ }
+ FreeTextFile(&MainHelpText);
+ VW_SetSplitScreen(120);
+ VW_SetScreen(screenloc[0],0);
+ screenpage = 0;
+ CacheScaleds();
+
+ bufferofs = 0;
+ RedrawStatusWindow();
+ ThreeDRefresh();
+ VW_FadeIn();
+ Keyboard[sc_F1] = false;
+ tics = realtics = 1;
+ IN_ClearKeysDown();
+ }
+
+// F3 - SAVE GAME
+//
+ if ((Keyboard[sc_F3]) && (!(Flags & FL_DEAD)))
+ {
+ PreFullDisplay();
+ GE_SaveGame();
+ PostFullDisplay(true);
+ tics = realtics = 1;
IN_ClearKeysDown();
- if (restartgame)
- playstate = ex_resetgame;
- if (loadedgame)
+ }
+
+// F4 - LOAD GAME
+//
+ if (Keyboard[sc_F4])
+ {
+ PreFullDisplay();
+ if (GE_LoadGame())
+ {
+ loadedgame = true;
playstate = ex_loadedgame;
- DrawPlayScreen ();
- CacheScaleds ();
- lasttimecount = TimeCount;
- if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
+ Flags &= ~FL_DEAD;
+ PostFullDisplay(false);
+ }
+ else
+ if (playstate == ex_victorious)
+ {
+ PostFullDisplay(false);
+ Victory(false);
+ }
+ else
+ PostFullDisplay(true);
+ Keyboard[sc_F5] = false;
+ tics = realtics = 1;
+ IN_ClearKeysDown();
}
+ if (Flags & FL_DEAD)
+ goto deadloop;
+
//
// F10-? debug keys
//
@@ -183,7 +443,32 @@ void CheckKeys (void)
if (MousePresent) Mouse(MDelta); // Clear accumulated mouse movement
lasttimecount = TimeCount;
}
+}
+//-------------------------------------------------------------------------
+// PreFullDisplay()
+//-------------------------------------------------------------------------
+void PreFullDisplay()
+{
+ VW_FadeOut();
+ VW_SetSplitScreen(200);
+ bufferofs = displayofs = screenloc[0];
+ VW_Bar(0,0,320,200,0);
+}
+
+//-------------------------------------------------------------------------
+// PostFullDisplay()
+//-------------------------------------------------------------------------
+void PostFullDisplay(boolean draw_view)
+{
+ VW_SetSplitScreen(120);
+ bufferofs = 0;
+ RedrawStatusWindow();
+ if (draw_view)
+ {
+ ThreeDRefresh();
+ VW_FadeIn();
+ }
}
@@ -342,7 +627,7 @@ void PollControls (void)
{
unsigned buttons;
- IN_ReadControl(0,&c);
+ IN_ReadControl(0,&control);
if (MousePresent)
{
@@ -353,38 +638,21 @@ void PollControls (void)
mouseymove = _DX;
if (buttons&1)
- c.button0 = 1;
+ control.button0 = 1;
if (buttons&2)
- c.button1 = 1;
+ control.button1 = 1;
}
- if (Controls[0]==ctrl_Joystick)
- {
- if (c.x>120 || c.x <-120 || c.y>120 || c.y<-120)
- running = true;
- else
- running = false;
- if (c.x>-48 && c.x<48)
- slowturn = true;
- else
- slowturn = false;
- }
+ if (Keyboard[sc_V] || Keyboard[sc_Tab])
+ running = true;
else
- {
- if (Keyboard[sc_RShift])
- running = true;
- else
- running = false;
- if (c.button0)
- slowturn = true;
- else
- slowturn = false;
- }
+ running = false;
}
//==========================================================================
+#if 0
/*
=================
=
@@ -438,6 +706,7 @@ void StartMusic(void)
SD_StartMusic((MusicGroup far *)audiosegs[STARTMUSIC + chunk]);
}
}
+#endif
//==========================================================================
@@ -452,7 +721,23 @@ void StartMusic(void)
void PlayLoop (void)
{
+ char shot_color[3] = {4,9,14};
+
+ int allgems[5]={GEM_DELAY_TIME, // used for Q & D comparison
+ GEM_DELAY_TIME, // for having all gems...
+ GEM_DELAY_TIME, // the "allgems" declaration MUST
+ GEM_DELAY_TIME, // match the "gems" declaration in
+ GEM_DELAY_TIME // the gametype structure!
+ };
+
+// 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;
+ short o_radius;
void (*think)();
@@ -461,8 +746,34 @@ void PlayLoop (void)
gamestate.shotpower = handheight = 0;
pointcount = pointsleft = 0;
- DrawLevelNumber (gamestate.mapon);
- DrawBars ();
+ // setup sky/ground colors and effects (based on level)
+ //
+ switch (gamestate.mapon)
+ {
+ case 0:
+ if (!(BGFLAGS & BGF_NIGHT))
+ {
+ InitBgChange(3*60,sky_daytonight,-1,NULL,BGF_NIGHT);
+ groundcolor = &gnd_colors[0];
+ }
+ else
+ {
+ skycolor = &sky_colors[0];
+ groundcolor = &gnd_colors[0];
+ }
+ break;
+
+ default:
+ skycolor = &sky_colors[gamestate.mapon];
+ groundcolor = &gnd_colors[gamestate.mapon];
+ skytimer = groundtimer = -1;
+ break;
+ }
+
+ RedrawStatusWindow();
+ ThreeDRefresh();
+ if (screenfaded)
+ VW_FadeIn();
#ifndef PROFILE
fizzlein = true; // fizzle fade in the first refresh
@@ -470,34 +781,44 @@ void PlayLoop (void)
TimeCount = lasttimecount = lastnuke = 0;
PollControls (); // center mouse
- StartMusic ();
+// StartMusic ();
do
{
#ifndef PROFILE
PollControls();
#else
- c.xaxis = 1;
+ control.xaxis = 1;
if (++TimeCount == 300)
return;
#endif
+ objnum=0;
for (obj = player;obj;obj = obj->next)
- if (obj->active)
+ {
+ if ((obj->active >= yes) && (!(FreezeTime && (obj!=player))))
{
+
+
if (obj->ticcount)
{
obj->ticcount-=tics;
+
while ( obj->ticcount <= 0)
{
think = obj->state->think;
if (think)
{
+ statetype *oldstate=obj->state;
+
think (obj);
if (!obj->state)
{
RemoveObj (obj);
goto nextactor;
}
+
+ if (obj->state != oldstate)
+ break;
}
obj->state = obj->state->next;
@@ -506,16 +827,21 @@ 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);
@@ -525,60 +851,507 @@ void PlayLoop (void)
nextactor:;
}
+ // keep a list of objects around the player for radar updates
+ //
+ if (obj == player)
+ {
+ px = player->x;
+ py = player->y;
+ psin = sintable[player->angle];
+ pcos = costable[player->angle];
+ xl = px-((long)RADAR_WIDTH<<TILESHIFT)/2;
+ xh = px+((long)RADAR_WIDTH<<TILESHIFT)/2-1;
+ yl = py-((long)RADAR_HEIGHT<<TILESHIFT)/2;
+ yh = py+((long)RADAR_HEIGHT<<TILESHIFT)/2;
+ }
+
+ if (objnum > MAX_RADAR_BLIPS-2)
+ objnum = MAX_RADAR_BLIPS-2;
+
+ ox = obj->x;
+ oy = obj->y;
+
+
+ if ((ox >= xl) && (ox <= xh) && (oy >= yl) && (oy <= yh))
+ {
+ norm_dx = (dx = px-ox)>>TILESHIFT;
+ norm_dy = (dy = oy-py)>>TILESHIFT;
+
+ o_radius = IntSqrt((norm_dx * norm_dx) + (norm_dy * norm_dy));
+
+ if (o_radius < RADAR_RADIUS)
+ {
+ newx = FixedByFrac(dy,pcos)-FixedByFrac(dx,psin);
+ newy = FixedByFrac(dy,psin)+FixedByFrac(dx,pcos);
+
+ RadarXY[objnum][0]=newx>>TILESHIFT;
+ RadarXY[objnum][1]=newy>>TILESHIFT;
+
+ // Define color to use for this object...
+ //
+
+ switch (obj->obclass)
+ {
+ // NO GEM NEEDED
+ //
+ // THE WIZARD! (YOU)
+ //
+ case playerobj:
+ RadarXY[objnum++][2]=15;
+ break;
+
+ // WIZARD'S SHOTS
+ //
+ case pshotobj:
+ case bigpshotobj:
+ RadarXY[objnum++][2]=shot_color[screenpage];
+ break;
+
+ // BATS (DK GRAY)
+ //
+ case batobj:
+ if (obj->active == always)
+ RadarXY[objnum++][2]=8;
+ break;
+
+ // RED GEM
+ //
+ // EYE, RED DEMON (DK RED)
+ //
+ case eyeobj:
+ case reddemonobj:
+ if (gamestate.gems[B_RGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=4;
+ break;
+
+ // RED MAGE (LT RED)
+ //
+ case mageobj:
+ if (gamestate.gems[B_RGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=12;
+ break;
+
+ // BLUE GEM
+ //
+ // WATER TROLL (LT BLUE)
+ //
+ case wetobj:
+ if (gamestate.gems[B_BGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=9;
+ break;
+
+ // WATER TROLL (DK BLUE)
+ //
+ case demonobj:
+ if (gamestate.gems[B_BGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=1;
+ break;
+
+ // GREEN GEM
+ //
+ // GREEN TROLL (LT GREEN)
+ //
+ case trollobj:
+ if (gamestate.gems[B_GGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=10;
+ break;
+
+ // ORC (DK GREEN)
+ //
+ case orcobj:
+ if (gamestate.gems[B_GGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=2;
+ break;
+
+ // YELLOW GEM
+ //
+ // SPOOK (BROWN)
+ //
+ case spookobj:
+ if (gamestate.gems[B_YGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=6;
+ break;
+
+ // SKELETON (YELLOW)
+ //
+ case skeletonobj:
+ if (gamestate.gems[B_YGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=14;
+ break;
+
+ // PURPLE GEM
+ //
+ // ZOMBIE
+ //
+ case zombieobj:
+ if (gamestate.gems[B_PGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=13;
+ break;
+
+ // ALL GEMS NEEDED
+ //
+ // NEMESIS
+ //
+ case grelmobj:
+ if (!memcmp(gamestate.gems,allgems,sizeof(gamestate.gems)))
+ if (obj->active == always)
+ RadarXY[objnum++][2]=15;
+ break;
+ }
+ }
+ }
+ }
+ RadarXY[objnum][2]=-1; // Signals end of RadarXY list...
if (bordertime)
{
- bordertime -= tics;
+ bordertime -= realtics;
if (bordertime<=0)
{
bordertime = 0;
- VW_ColorBorder (3);
+ VW_ColorBorder(0);
}
}
- if (pointcount)
+// random lightning?
+//
+ if (BGFLAGS & (BGF_NIGHT|BGF_NOT_LIGHTNING))
+ switch (gamestate.mapon)
+ {
+ case 0:
+ case 1:
+ case 3:
+ if (!random(120-realtics))
+ {
+ BGFLAGS &= ~BGF_NOT_LIGHTNING;
+ InitBgChange(1,sky_lightning,-1,NULL,BGF_NOT_LIGHTNING);
+ }
+ break;
+ }
+
+// handle sky/ground color changes
+//
+ if (skytimer != -1)
+ {
+ skytimer -= realtics;
+ if (skytimer < 0)
+ {
+ skycolor++;
+ if (*skycolor == 0xffff)
+ {
+ skytimer = -1;
+ skycolor--;
+ if (groundtimer == -1)
+ BGFLAGS |= bgflag;
+ }
+ else
+ skytimer = skytimer_reset;
+ }
+ }
+
+ if (groundtimer != -1)
+ {
+ groundtimer -= realtics;
+ if (groundtimer < 0)
+ {
+ groundcolor++;
+ if (*groundcolor == 0xffff)
+ {
+ groundtimer = -1;
+ groundcolor--;
+ if (skytimer == -1)
+ BGFLAGS |= bgflag;
+ }
+ else
+ groundtimer = groundtimer_reset;
+ }
+ }
+
+
+//
+// Handle FreezeTime counter..
+//
+ if (FreezeTime)
{
- pointcount -= tics;
- if (pointcount <= 0)
+ if (FreezeTime<20*30)
+ if ((BeepTime+=realtics)>=60)
+ {
+ BeepTime -= 60;
+ SD_PlaySound(TICKSND);
+ }
+
+ if ((FreezeTime-=realtics)<=0)
{
- pointcount += POINTTICS;
- give = (pointsleft > 1000)? 1000 :
- (
- (pointsleft > 100)? 100 :
- ((pointsleft < 20)? pointsleft : 20)
- );
- SD_PlaySound (GETPOINTSSND);
- AddPoints (give);
- pointsleft -= give;
- if (!pointsleft)
- pointcount = 0;
+ FreezeTime=0;
+ SD_PlaySound(TIMERETURNSND);
+ DisplaySMsg(NULL,NULL);
+ status_flag = S_NONE;
}
}
+
+// refresh all
+//
ThreeDRefresh ();
- CheckKeys();
- if (singlestep)
+ if (Flags & FL_DEAD)
{
- VW_WaitVBL(14);
- lasttimecount = TimeCount;
+ SD_PlaySound (GAMEOVERSND);
+ DisplaySMsg("DEAD",NULL);
+ DrawHealth();
+ if (gamestate.potions)
+ {
+ bufferofs = displayofs = screenloc[screenpage];
+ CenterWindow(35,3);
+ US_CPrint("\nYou should use your Cure Potions wisely\n");
+ IN_Ack();
+ }
+ }
+
+// check for win
+//
+ if (playstate == ex_victorious)
+ {
+ Victory(true);
+ Flags |= FL_DEAD;
}
- if (extravbls)
- VW_WaitVBL(extravbls);
+
+ DisplayStatus(&status_flag);
+ CheckKeys();
}while (!playstate);
- StopMusic ();
+// StopMusic ();
ingame = false;
if (bordertime)
{
bordertime = 0;
- VW_ColorBorder (3);
+ VW_ColorBorder(0);
}
- if (!abortgame)
- AddPoints (pointsleft);
- else
+ if (abortgame)
abortgame = false;
}
+//--------------------------------------------------------------------------
+// IntSqrt() - by Master Programmer, George Leritte!
+//--------------------------------------------------------------------------
+int IntSqrt(long va)
+{
+asm mov AX, word ptr va
+asm mov DX, word ptr va+2
+asm mov bx,dx // {bx = integer square root of dx:ax}
+asm or bx,ax // {if dx:ax=0 then return}
+asm jz isq01
+asm mov bx,dx
+asm shl bx,1
+asm or bl,ah
+asm or bl,al
+asm dec bx
+asm add bx,dx // { initial guess}
+asm jg isq10
+asm inc bx // { don't return zero}
+asm jg isq10
+asm mov bx,7fffh
+isq01:;
+ goto exitrout;
+
+isq10:;
+asm push ax
+asm push dx
+asm div bx
+asm sub ax,bx
+asm cmp ax,1
+asm jbe isq90
+asm cmp ax,-1
+asm jae isq90
+asm sar ax,1
+asm add bx,ax
+asm pop dx
+asm pop ax
+asm jmp isq10
+isq90:;
+asm pop dx
+asm pop ax
+exitrout:;
+asm mov ax,bx
+}
+
+//-------------------------------------------------------------------------
+// InitBgChange()
+//-------------------------------------------------------------------------
+void InitBgChange(short stimer, unsigned *scolors, short gtimer, unsigned *gcolors, byte flag)
+{
+ skytimer_reset = skytimer = stimer;
+ if (scolors)
+ skycolor = scolors;
+
+ groundtimer_reset = groundtimer = gtimer;
+ if (gcolors)
+ groundcolor = gcolors;
+
+ bgflag = flag;
+}
+
+////////////////////////////////////////////////////////
+//
+// DisplayStatus
+//
+// Stat_Flag - contains the type of status displayed
+// -- also uses status_delay (global variable) will not
+// change display until this variable is zero.
+// -- heirarchy is determined by the series of if statements,
+// to change it, rearrange th if statements.
+//
+////////////////////////////////////////////////////////
+
+#define MESSAGEDELAY 25
+void DisplayStatus (status_flags *stat_flag)
+{
+ status_flags temp_status;
+
+
+ if (*stat_flag == S_TIMESTOP)
+ return;
+
+ if (status_delay > 0)
+ {
+ status_delay -= realtics;
+ return;
+ }
+ else
+ status_delay = 0;
+
+ // check for a change in status from previous call
+
+ temp_status = S_VIEWING; //precaution
+
+ if (Keyboard[sc_Control] || control.button0)
+ temp_status = S_MISSLE;
+
+ if (Keyboard[sc_Z] && !Keyboard[sc_F10])
+ temp_status = S_ZAPPER;
+
+ if ((Keyboard[sc_X] && !Keyboard[sc_F10]) || Keyboard[sc_Enter])
+ temp_status = S_XTER;
+
+ if (control.x)
+ temp_status = S_TURN;
+
+ if ((Keyboard[sc_V] || Keyboard[sc_Tab]) && control.x)
+ temp_status = S_QTURN;
+
+ if (Keyboard[sc_Alt] && control.x)
+ temp_status = S_SIDESTEP;
+
+ if (control.y < 0)
+ temp_status = S_ADVANCE;
+
+ if (control.y > 0)
+ temp_status = S_RETREAT;
+
+ if (Keyboard[sc_F5])
+ temp_status = S_JOYSTICK;
+
+ if (Keyboard[sc_F4])
+ temp_status = S_RESTORING;
+
+ if (Keyboard[sc_F3])
+ temp_status = S_SAVING;
+
+ if (Keyboard[sc_F2])
+ temp_status = S_SND;
+
+ if (Keyboard[sc_F1])
+ temp_status = S_HELP;
+
+ if (temp_status != *stat_flag)
+ {
+ *stat_flag = temp_status;
+
+
+ switch (*stat_flag)
+ {
+ case S_MISSLE:
+ DisplaySMsg("Magick Missile", NULL);
+ status_delay = MESSAGEDELAY;
+ break;
+
+ case S_ZAPPER:
+ if (gamestate.bolts)
+ {
+ DisplaySMsg("Zapper", NULL);
+ status_delay = MESSAGEDELAY+10;
+ }
+ break;
+
+ case S_XTER:
+ if (gamestate.nukes)
+ {
+ DisplaySMsg("Xterminator", NULL);
+ status_delay = MESSAGEDELAY+5;
+ }
+ break;
+
+ case S_TURN:
+ DisplaySMsg("Turning", NULL);
+ status_delay = MESSAGEDELAY;
+ break;
+
+ case S_QTURN:
+ DisplaySMsg("Quick Turning", NULL);
+ status_delay = MESSAGEDELAY;
+ break;
+
+ case S_SIDESTEP:
+ DisplaySMsg("Sidestepping", NULL);
+ status_delay = MESSAGEDELAY;
+ break;
+
+ case S_ADVANCE:
+ DisplaySMsg("Advancing", NULL);
+ status_delay = MESSAGEDELAY;
+ break;
+
+ case S_RETREAT:
+ DisplaySMsg("Retreating", NULL);
+ status_delay = MESSAGEDELAY;
+ break;
+
+ case S_JOYSTICK:
+ DisplaySMsg("Adjusting Joystick", NULL);
+ break;
+
+ case S_RESTORING:
+ DisplaySMsg("Restoring", NULL);
+ break;
+
+ case S_SAVING:
+ DisplaySMsg("Saving", NULL);
+ break;
+
+ case S_SND:
+ DisplaySMsg("Select Sound", NULL);
+ break;
+
+ case S_HELP:
+ DisplaySMsg("Getting Help", NULL);
+ break;
+
+ case S_VIEWING:
+ DisplaySMsg("Viewing", NULL);
+ break;
+ }
+ bufferofs = displayofs = screenloc[screenpage];
+
+ }
+}
diff --git a/C4_SCALE.C b/C4_SCALE.C
index 018083d..41f06e6 100644
--- a/C4_SCALE.C
+++ b/C4_SCALE.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -18,15 +18,15 @@
// C3_SCALE.C
-#include "C3_DEF.H"
+#include "DEF.H"
#pragma hdrstop
//const unsigned viewheight = 144;
const unsigned screenbwide = 40;
const byte BACKGROUNDPIX = 5;
-unsigned shapesize[MAXSCALE+1];
-t_compscale _seg *scaledirectory[MAXSCALE+1];
+unsigned shapesize[NUMSCALEPICS];
+t_compscale _seg *scaledirectory[NUMSCALEPICS];
t_compshape _seg *shapedirectory[NUMSCALEPICS];
memptr walldirectory[NUMSCALEWALLS];
@@ -57,7 +57,7 @@ void DeplanePic (int picnum)
width = pictable[picnum-STARTPICS].width;
height = pictable[picnum-STARTPICS].height;
- if (width>64 || height!=64)
+ if (width>8 || height!=64)
Quit ("DePlanePic: Bad size shape");
memset (spotvis,BACKGROUNDPIX,sizeof(spotvis));
@@ -430,6 +430,10 @@ unsigned BuildCompShape (t_compshape _seg **finalspot)
// copy the final shape to a properly sized buffer
//
totalsize = FP_OFF(code);
+
+ if (totalsize >= (PAGELEN*2))
+ Quit("BuildCompShape(): Shape is too complex!");
+
MM_GetPtr ((memptr *)finalspot,totalsize);
_fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize);
// MM_FreePtr (&(memptr)work);
@@ -459,6 +463,9 @@ static long longtemp;
void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale)
{
+ #define MAX_OBJ_SCALE (MAXSCALE)
+
+
t_compscale _seg *comptable;
unsigned width,scalewidth;
int x,pixel,lastpixel,pixwidth,min;
@@ -472,8 +479,10 @@ void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale)
scale = (scale+1)/2;
if (!scale)
return; // too far away
- if (scale>MAXSCALE)
- scale = MAXSCALE;
+
+ if (scale>MAX_OBJ_SCALE)
+ scale = MAX_OBJ_SCALE;
+
comptable = scaledirectory[scale];
width = compshape->width;
@@ -481,6 +490,7 @@ 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/C4_SCA_A.ASM b/C4_SCA_A.ASM
index 58a8737..5bb5296 100644
--- a/C4_SCA_A.ASM
+++ b/C4_SCA_A.ASM
@@ -1,4 +1,4 @@
-; Catacomb 3-D Source Code
+; Catacomb Abyss Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
diff --git a/C4_STATE.C b/C4_STATE.C
index 8c31eb0..3bff92b 100644
--- a/C4_STATE.C
+++ b/C4_STATE.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss 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 @@
// C3_STATE.C
-#include "C3_DEF.H"
+#include "DEF.H"
#pragma hdrstop
/*
@@ -60,14 +60,15 @@ dirtype opposite[9] =
/*
===================
=
-= SpawnNewObj
+= Internal_SpawnNewObj
=
===================
*/
-
-void SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size)
+void Internal_SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size,boolean UseDummy)
{
- GetNewObj (false);
+ extern objtype dummyobj;
+
+ GetNewObj(UseDummy);
new->size = size;
new->state = state;
new->ticcount = random (state->tictime)+1;
@@ -78,17 +79,19 @@ void SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size)
new->y = ((long)y<<TILESHIFT)+TILEGLOBAL/2;
CalcBounds(new);
new->dir = nodir;
+ new->active = noalways;
- actorat[new->tilex][new->tiley] = new;
+ if (new != &dummyobj)
+ actorat[new->tilex][new->tiley] = new;
}
-void SpawnNewObjFrac (long x, long y, statetype *state, unsigned size)
+void Internal_SpawnNewObjFrac (long x, long y, statetype *state, unsigned size,boolean UseDummy)
{
- GetNewObj (false);
+ GetNewObj(UseDummy);
new->size = size;
new->state = state;
new->ticcount = random (state->tictime)+1;
- new->active = true;
+ new->active = noalways;
new->x = x;
new->y = y;
@@ -101,6 +104,7 @@ void SpawnNewObjFrac (long x, long y, statetype *state, unsigned size)
+
/*
===================
=
@@ -115,7 +119,7 @@ boolean CheckHandAttack (objtype *ob)
{
long deltax,deltay,size;
- size = (long)ob->size + player->size + ob->speed*tics;
+ size = (long)ob->size + player->size + ob->speed*tics + SIZE_TEST;
deltax = ob->x - player->x;
deltay = ob->y - player->y;
@@ -141,11 +145,7 @@ void T_DoDamage (objtype *ob)
int points;
- if (!CheckHandAttack (ob))
- {
- SD_PlaySound (MONSTERMISSSND);
- }
- else
+ if (CheckHandAttack(ob) && (!(ob->flags & of_damagedone)))
{
points = 0;
@@ -154,17 +154,30 @@ void T_DoDamage (objtype *ob)
case orcobj:
points = 4;
break;
+ case zombieobj:
case trollobj:
points = 8;
break;
+ case reddemonobj:
case demonobj:
points = 15;
break;
+ case spookobj:
+ points = 2;
+ break;
+ case skeletonobj:
+ points = 6;
+ break;
+
+ case wetobj:
+ points = 7;
+ break;
+
}
- TakeDamage (points);
- }
+ TakeDamage (EasyDoDamage(points));
- ob->state = ob->state->next;
+ ob->flags |= of_damagedone;
+ }
}
@@ -434,8 +447,10 @@ boolean Chase (objtype *ob, boolean diagonal)
long move;
long deltax,deltay,size;
+ ob->flags &= ~of_damagedone;
+
move = ob->speed*tics;
- size = (long)ob->size + player->size + move;
+ size = (long)ob->size + player->size + move + SIZE_TEST;
while (move)
{
@@ -489,40 +504,91 @@ void ShootActor (objtype *ob, unsigned damage)
{
switch (ob->obclass)
{
+ case reddemonobj:
+ ob->state = &s_red_demondie1;
+ break;
case orcobj:
ob->state = &s_orcdie1;
- GivePoints (100);
break;
case trollobj:
ob->state = &s_trolldie1;
- GivePoints (400);
break;
case demonobj:
ob->state = &s_demondie1;
- GivePoints (1000);
break;
case mageobj:
ob->state = &s_magedie1;
- GivePoints (600);
break;
case batobj:
ob->state = &s_batdie1;
- GivePoints (100);
break;
case grelmobj:
ob->state = &s_greldie1;
- GivePoints (10000);
break;
+ case zombieobj:
+ ob->state = &s_zombie_death1;
+ break;
+
+ case skeletonobj:
+ ob->state = &s_skel_die1;
+ break;
+
+ case spookobj:
+ ob->state = &s_spookdie;
+ break;
+
+ case wetobj:
+ ob->state = &s_wet_die1;
+ break;
+
+ case eyeobj:
+ ob->state = &s_eye_die1;
+ break;
+
+ case eshotobj:
+ case mshotobj:
+ ob->state = &s_bonus_die;
+ break;
+
+ case bonusobj:
+ case freezeobj:
+ switch (ob->temp1)
+ {
+ case B_POTION:
+ case B_CHEST:
+ case B_NUKE:
+ case B_BOLT:
+ ob->state = &s_pshot_exp1;
+ ob->obclass = expobj;
+ ob->ticcount = ob->state->tictime;
+ SpawnBigExplosion(ob->x,ob->y,12,(16l<<16L));
+ bordertime = FLASHTICS<<2;
+ bcolor = 14;
+ VW_ColorBorder(14 | 56);
+ DisplaySMsg("Item destroyed", NULL);
+ status_flag = S_NONE;
+ status_delay = 80;
+ break;
+ }
+ break;
+
+ }
+
+ if (ob->obclass != solidobj)
+ {
+ ob->obclass = inertobj;
+ ob->flags &= ~of_shootable;
+ actorat[ob->tilex][ob->tiley] = NULL;
}
- ob->obclass = inertobj;
- ob->shootable = false;
- actorat[ob->tilex][ob->tiley] = NULL;
}
else
{
switch (ob->obclass)
{
+ case reddemonobj:
+ ob->state = &s_red_demonouch;
+ break;
case orcobj:
ob->state = &s_orcouch;
break;
@@ -535,10 +601,31 @@ void ShootActor (objtype *ob, unsigned damage)
case mageobj:
ob->state = &s_mageouch;
break;
+
case grelmobj:
ob->state = &s_grelouch;
break;
+ case zombieobj:
+ ob->state = &s_zombie_ouch;
+ break;
+
+ case spookobj:
+ ob->state = &s_spookouch;
+ break;
+
+ case skeletonobj:
+ ob->state = &s_skel_ouch;
+ break;
+
+ case wetobj:
+ ob->state = &s_wet_ouch;
+ break;
+
+ case eyeobj:
+ ob->state = &s_eye_ouch;
+ break;
+
}
}
ob->ticcount = ob->state->tictime;
diff --git a/C4_TRACE.C b/C4_TRACE.C
index 45cb1bc..e26c2ad 100644
--- a/C4_TRACE.C
+++ b/C4_TRACE.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss 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 @@
// C3_TRACE.C
-#include "C3_DEF.H"
+#include "DEF.H"
#pragma hdrstop
/*
@@ -393,8 +393,9 @@ 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]) < FOCALLENGTH)
+// ((long)tile.y<<16)+point1y[wall]) < ((long)FOCALLENGTH+30000l))
+ {
tile.x = otx;
tile.y = oty;
return 0;
@@ -767,7 +768,7 @@ advance:
//
// somethiing got messed up! Correct by thrusting ahead...
//
- VW_ColorBorder(6);
+// VW_ColorBorder(6);
bordertime = 60;
Thrust(player->angle,TILEGLOBAL/4);
player->angle+=5;
diff --git a/C4_WIZ.C b/C4_WIZ.C
index 1d68bc7..8ebb28a 100644
--- a/C4_WIZ.C
+++ b/C4_WIZ.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss 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 @@
// C3_WIZ.C
-#include "C3_DEF.H"
+#include "DEF.H"
#pragma hdrstop
/*
@@ -37,7 +37,7 @@
#define NUMBOLTS 10
#define BOLTTICS 6
-#define STATUSCOLOR 4
+#define STATUSCOLOR 8
#define TEXTCOLOR 14
#define SIDEBARWIDTH 5
@@ -45,27 +45,25 @@
#define BODYLINE 8
#define POWERLINE 80
-#define SPECTILESTART 18
-
+#define SPECTILESTART 0 // 18
#define SHOTDAMAGE 1
#define BIGSHOTDAMAGE 3
#define PLAYERSPEED 5120
-#define RUNSPEED 8192
+#define RUNSPEED (8192<<1)
#define SHOTSPEED 10000
-#define LASTWALLTILE 17
-#define LASTSPECIALTILE 37
+//#define LASTWALLTILE 47
+//#define LASTSPECIALTILE 37
-#define FIRETIME 4 // DEBUG 60
+#define LASTTILE (LASTWALLPIC-FIRSTWALLPIC) // 47
-#define HANDPAUSE 60
+#define FIRETIME 2
-#define COMPASSX 33
-#define COMPASSY 0
+#define HANDPAUSE 60
/*
=============================================================================
@@ -76,8 +74,14 @@
*/
long lastnuke,lasthand;
+int lasttext;
int handheight;
-int boltsleft;
+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};
+
+boolean redraw_gems,button0down;
/*
=============================================================================
@@ -87,15 +91,24 @@ int boltsleft;
=============================================================================
*/
-int lasttext,lastcompass;
-int bolttimer;
+int lastradar;
unsigned lastfiretime;
int strafeangle[9] = {0,90,180,270,45,135,225,315,0};
+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..
//===========================================================================
+void CalcBounds(objtype *ob);
+boolean VerifyGateExit(void);
+void DrawNSEWIcons(void);
+void DrawGems(void);
+void DrawRadar (void);
void DrawChar (unsigned x, unsigned y, unsigned tile);
void RedrawStatusWindow (void);
void GiveBolt (void);
@@ -108,10 +121,9 @@ void GiveKey (int keytype);
void TakeKey (int keytype);
void GiveScroll (int scrolltype,boolean show);
void ReadScroll (int scroll);
-void GivePoints (int points);
-void DrawLevelNumber (int number);
-void DrawText (void);
-void DrawBars (void);
+void DrawScrolls(void);
+
+void DrawNum(short x,short y,short value,short maxdigits);
//----------
@@ -122,12 +134,13 @@ void CastNuke (void);
void DrinkPotion (void);
//----------
+void DrawHealth(void);
void SpawnPlayer (int tilex, int tiley, int dir);
void Thrust (int angle, unsigned speed);
void T_Player (objtype *ob);
-void AddPoints (int points);
+//void AddPoints (int points);
void ClipMove (objtype *ob, long xmove, long ymove);
boolean ShotClipMove (objtype *ob, long xmove, long ymove);
@@ -195,35 +208,21 @@ asm mov ds,ax
void RedrawStatusWindow (void)
{
- int i,j,x;
-
- DrawLevelNumber (gamestate.mapon);
- lasttext = -1;
- lastcompass = -1;
-
- j = gamestate.bolts < SHOWITEMS ? gamestate.bolts : SHOWITEMS;
- for (i=0;i<j;i++)
- DrawChar(7+i,20,BOLTCHAR);
- j = gamestate.nukes < SHOWITEMS ? gamestate.nukes : SHOWITEMS;
- for (i=0;i<j;i++)
- DrawChar(7+i,30,NUKECHAR);
- j = gamestate.potions < SHOWITEMS ? gamestate.potions : SHOWITEMS;
- for (i=0;i<j;i++)
- DrawChar(7+i,40,POTIONCHAR);
-
- x=24;
- for (i=0;i<4;i++)
- for (j=0;j<gamestate.keys[i];j++)
- DrawChar(x++,20,KEYCHARS+i);
-
- x=24;
- for (i=0;i<8;i++)
- if (gamestate.scrolls[i])
- DrawChar(x++,30,SCROLLCHARS+i);
+ short keytype;
- AddPoints(0);
+ 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);
- DrawBars ();
+ DrawHealth();
+ DrawRadar();
+ EGAWRITEMODE(0);
+ DrawGems();
+ DrawScrolls();
+ redraw_gems = false;
}
@@ -239,9 +238,11 @@ void RedrawStatusWindow (void)
void GiveBolt (void)
{
+ if (gamestate.bolts == 99)
+ return;
+
SD_PlaySound (GETBOLTSND);
- if (++gamestate.bolts<=9)
- DrawChar(6+gamestate.bolts,20,BOLTCHAR);
+ DrawNum(17,18,++gamestate.bolts,2);
}
@@ -256,8 +257,7 @@ void GiveBolt (void)
void TakeBolt (void)
{
SD_PlaySound (USEBOLTSND);
- if (--gamestate.bolts<=9)
- DrawChar(7+gamestate.bolts,20,BLANKCHAR);
+ DrawNum(17,18,--gamestate.bolts,2);
}
//===========================================================================
@@ -272,9 +272,11 @@ void TakeBolt (void)
void GiveNuke (void)
{
+ if (gamestate.nukes == 99)
+ return;
+
SD_PlaySound (GETNUKESND);
- if (++gamestate.nukes<=9)
- DrawChar(6+gamestate.nukes,30,NUKECHAR);
+ DrawNum(17,36,++gamestate.nukes,2);
}
@@ -289,8 +291,7 @@ void GiveNuke (void)
void TakeNuke (void)
{
SD_PlaySound (USENUKESND);
- if (--gamestate.nukes<=9)
- DrawChar(7+gamestate.nukes,30,BLANKCHAR);
+ DrawNum(17,36,--gamestate.nukes,2);
}
//===========================================================================
@@ -305,9 +306,11 @@ void TakeNuke (void)
void GivePotion (void)
{
+ if (gamestate.potions == 99)
+ return;
+
SD_PlaySound (GETPOTIONSND);
- if (++gamestate.potions<=9)
- DrawChar(6+gamestate.potions,40,POTIONCHAR);
+ DrawNum(17,54,++gamestate.potions,2);
}
@@ -322,8 +325,7 @@ void GivePotion (void)
void TakePotion (void)
{
SD_PlaySound (USEPOTIONSND);
- if (--gamestate.potions<=9)
- DrawChar(7+gamestate.potions,40,BLANKCHAR);
+ DrawNum(17,54,--gamestate.potions,2);
}
//===========================================================================
@@ -340,14 +342,11 @@ void GiveKey (int keytype)
{
int i,j,x;
- SD_PlaySound (GETKEYSND);
- gamestate.keys[keytype]++;
-
- x=24;
- for (i=0;i<4;i++)
- for (j=0;j<gamestate.keys[i];j++)
- DrawChar(x++,20,KEYCHARS+i);
+ if (gamestate.keys[keytype] == 99)
+ return;
+ SD_PlaySound (GETKEYSND);
+ DrawNum(key_x[keytype],key_y[keytype],++gamestate.keys[keytype],2);
}
@@ -362,16 +361,81 @@ void GiveKey (int keytype)
void TakeKey (int keytype)
{
int i,j,x;
+ char *key_colors[] = {"a RED key",
+ "a YELLOW key",
+ "a GREEN key",
+ "a BLUE key"};
+
+
+ SD_PlaySound (USEKEYSND);
+ DrawNum(key_x[keytype],key_y[keytype],--gamestate.keys[keytype],2);
+ displayofs = bufferofs = screenloc[screenpage];
+ CenterWindow(20,5);
+ US_CPrint("\nYou use\n");
+ US_CPrint(key_colors[keytype]);
+ VW_UpdateScreen();
+ VW_WaitVBL(120);
+}
+
+
+//===========================================================================
+
+/*
+===============
+=
+= GiveGem
+=
+===============
+*/
+
+void GiveGem (int gemtype)
+{
+#if 0
+ int i,j,x;
+
+ SD_PlaySound (GETKEYSND);
+ DrawNum(key_x[keytype],key_y[keytype],++gamestate.keys[keytype],2);
+#endif
+}
+
+
+/*
+===============
+=
+= TakeGem
+=
+===============
+*/
+
+void TakeGem (int gemtype)
+{
+#if 0
+ int i,j,x;
SD_PlaySound (USEKEYSND);
- gamestate.keys[keytype]--;
+ DrawNum(key_x[keytype],key_y[keytype],--gamestate.keys[keytype],2);
+#endif
+}
- x=24;
- for (i=0;i<4;i++)
- for (j=0;j<gamestate.keys[i];j++)
- DrawChar(x++,20,KEYCHARS+i);
+/*
+===============
+=
+= DrawGem
+=
+===============
+*/
+
+void DrawGems()
+{
+ short loop;
+
+ redraw_gems = false;
- DrawChar(x,20,BLANKCHAR);
+ bufferofs = 0;
+ LatchDrawPic (31,51,RADAR_BOTTOMPIC);
+ for (loop=0; loop<5; loop++)
+ if (gamestate.gems[loop])
+ LatchDrawPic (32+loop,53,RADAR_RGEMPIC+loop);
}
//===========================================================================
@@ -386,21 +450,46 @@ void TakeKey (int keytype)
void GiveScroll (int scrolltype,boolean show)
{
- int i,x;
+ int i,j,x,y,scrollnum;
SD_PlaySound (GETSCROLLSND);
gamestate.scrolls[scrolltype] = true;
- x=24;
- for (i=0;i<8;i++)
- if (gamestate.scrolls[i])
- DrawChar(x++,30,SCROLLCHARS+i);
+ y = 30 + ((scrolltype > 3) * 10);
+ x = 26 + (scrolltype % 4);
+ DrawChar(x,y,SCROLLCHARS+scrolltype);
+
if (show)
ReadScroll(scrolltype);
}
+/*
+===============
+=
+= DrawScrolls
+=
+= Force draw of all scrolls
+=
+===============
+*/
+void DrawScrolls()
+{
+ int loop,x,y;
+
+ VW_Bar(210,30,30,18,0xf);
+
+ for (loop=0;loop<8;loop++)
+ if (gamestate.scrolls[loop])
+ {
+ y = 30 + ((loop > 3) * 10);
+ x = 26 + (loop % 4);
+ DrawChar(x,y,SCROLLCHARS+loop);
+ }
+}
+
//===========================================================================
+#if 0
/*
===============
=
@@ -414,10 +503,12 @@ void GivePoints (int points)
pointcount = 1;
pointsleft += points;
}
+#endif
//===========================================================================
+#if 0
/*
===============
=
@@ -440,6 +531,7 @@ void AddPoints (int points)
for (i=0;i<len;i++)
DrawChar(x++,40,NUMBERCHARS+str[i]-'0');
}
+#endif
//===========================================================================
@@ -447,15 +539,116 @@ void AddPoints (int points)
/*
===============
=
+= DrawHealth
+=
+===============
+*/
+void DrawHealth()
+{
+ char picnum;
+ int percentage;
+
+ percentage = PERCENTAGE(100,MAXBODY,gamestate.body,9);
+
+ DrawNum(9,57,percentage,3);
+
+ if (percentage > 75)
+ picnum = FACE1PIC;
+ else
+ if (percentage > 50)
+ picnum = FACE2PIC;
+ else
+ if (percentage > 25)
+ picnum = FACE3PIC;
+ else
+ if (percentage)
+ picnum = FACE4PIC;
+ else
+ {
+ picnum = FACE5PIC;
+ CA_CacheGrChunk (picnum);
+ }
+
+ bufferofs = 0;
+ if (!percentage)
+ {
+ UNMARKGRCHUNK(picnum);
+ VW_DrawPic(8,14,picnum);
+ }
+ else
+ LatchDrawPic(8,14,picnum);
+}
+
+//===========================================================================
+
+/*
+===============
+=
+= DrawFreezeTime
+=
+===============
+*/
+void DrawFreezeTime()
+{
+ long percentage;
+ percentage = PERCENTAGE(100,MAXFREEZETIME,(long)FreezeTime,7);
+ DrawNum(23,70,percentage,3);
+}
+
+//===========================================================================
+
+/*
+===============
+=
+= DrawNum
+=
+===============
+*/
+void DrawNum(short x,short y,short value,short maxdigits)
+{
+ char str[10],len,i;
+
+ itoa(value,str,10);
+ len=strlen(str);
+
+ for (i=len; i<maxdigits; i++)
+ DrawChar(x++,y,BLANKCHAR);
+
+ for (i=0;i<len;i++)
+ DrawChar(x++,y,NUMBERCHARS+str[i]-'0');
+}
+
+//===========================================================================
+
+/*
+===============
+=
= GiveChest
=
===============
*/
-void GiveChest (void)
+void GiveChest(void)
{
- SD_PlaySound (GETPOINTSSND);
- GivePoints ((gamestate.mapon+1)*100);
+ char i;
+
+ for (i=0;i<random(4);i++)
+ {
+ GiveBolt();
+ SD_WaitSoundDone();
+ }
+
+ for (i=0;i<random(3);i++)
+ {
+ GiveNuke();
+ SD_WaitSoundDone();
+ }
+
+ for (i=0;i<random(2);i++)
+ {
+ GivePotion();
+ SD_WaitSoundDone();
+ }
}
@@ -472,13 +665,13 @@ void GiveChest (void)
void GiveGoal (void)
{
SD_PlaySound (GETPOINTSSND);
- GivePoints (100000);
playstate = ex_victorious;
}
//===========================================================================
+#if 0
/*
===============
=
@@ -505,6 +698,7 @@ void DrawLevelNumber (int number)
US_PrintUnsigned (number+1);
fontcolor = temp;
}
+#endif
//===========================================================================
@@ -517,7 +711,7 @@ void DrawLevelNumber (int number)
===============
*/
-void DrawText (void)
+void DrawText (boolean draw_text_whether_it_needs_it_or_not)
{
unsigned number;
char str[80];
@@ -532,25 +726,82 @@ void DrawText (void)
if ( number>26 )
number = 0;
- if (number == lasttext)
+ if ((number == lasttext) && (!draw_text_whether_it_needs_it_or_not))
return;
- bufferofs = 0;
lasttext = number;
- PrintY = 4;
- WindowX = 26;
- WindowW = 232;
-
text = (char _seg *)grsegs[LEVEL1TEXT+mapon]+textstarts[number];
_fmemcpy (str,text,80);
+ DisplayMsg(str,NULL);
+}
+
+//===========================================================================
- VW_Bar (26,4,232,9,STATUSCOLOR);
+/*
+===============
+=
+= DisplayMsg
+=
+===============
+*/
+
+char DisplayMsg(char *text,char *choices)
+{
+ char ch=true;
+ short temp;
+
+ bufferofs = 0;
+ PrintY = 1;
+ WindowX = 20;
+ WindowW = 270;
+
+ VW_Bar (WindowX,2,WindowW,8,STATUSCOLOR);
temp = fontcolor;
fontcolor = TEXTCOLOR^STATUSCOLOR;
- US_CPrintLine (str);
+ US_CPrintLine (text);
fontcolor = temp;
+
+ if (choices)
+ {
+ ch=GetKeyChoice(choices,true);
+ LastScan = 0;
+ }
+
+ return(ch);
+}
+
+/*
+===============
+=
+= DisplaySMsg
+=
+===============
+*/
+char DisplaySMsg(char *text,char *choices)
+{
+ char ch=true;
+ short temp;
+
+ bufferofs = 0;
+ PrintY = 69;
+ WindowX = 98;
+ WindowW = 115;
+
+ VW_Bar(WindowX,PrintY+1,WindowW,8,STATUSCOLOR);
+ temp = fontcolor;
+ fontcolor = TEXTCOLOR^STATUSCOLOR;
+ US_CPrintLine (text);
+ fontcolor = temp;
+
+ if (choices)
+ {
+ ch=GetKeyChoice(choices,true);
+ LastScan = 0;
+ }
+
+ return(ch);
}
//===========================================================================
@@ -558,38 +809,68 @@ void DrawText (void)
/*
===============
=
-= DrawCompass
+= DrawRadar
=
===============
*/
-void DrawCompass (void)
+void DrawRadar (void)
{
int angle,number;
+ short objnum;
- //
- // draw the compass if needed
- //
- angle = player->angle-ANGLES/4;
- angle -= ANGLES/32;
- if (angle<0)
- angle+=ANGLES;
- number = angle/(ANGLES/16);
- if (number>15) // because 360 angles doesn't divide by 16
- number = 15;
-
- if (number == lastcompass)
- return;
+ bufferofs = 0;
+ LatchDrawPic (radarx,radary,RADAR_TOPPIC);
- lastcompass = number;
+ asm cli
+ asm mov dx,GC_INDEX
+ asm mov ax,2*256+GC_MODE
+ asm out dx,ax // write mode 2
- bufferofs = 0;
- LatchDrawPic (COMPASSX,COMPASSY,COMPAS1PIC+15-number);
+ asm mov ax,GC_DATAROTATE
+ asm out dx,ax // no rotation / logical operation
+
+ asm mov dx,SC_INDEX
+ asm mov al,SC_MAPMASK
+ asm mov ah,15
+ asm out dx,ax // write to all four planes
+ asm sti
+
+ objnum = 0;
+ while (RadarXY[objnum][2] != -1)
+ {
+ RadarBlip(radar_xcenter+RadarXY[objnum][0],radar_ycenter+RadarXY[objnum][1],RadarXY[objnum][2]);
+ objnum++;
+ }
+
+ asm cli
+ asm mov dx,GC_INDEX
+ asm mov ax,255*256+GC_BITMASK
+ asm out dx,ax // reset bitmask to %11111111
+ asm sti
}
//===========================================================================
+//--------------------------------------------------------------------------
+// DrawNSEWIcons(void)
+//--------------------------------------------------------------------------
+
+void DrawRadarObj(short dx, short dy, unsigned sprnum,signed long psin,signed long pcos);
+
+void DrawNSEWIcons()
+{
+ signed x,y;
+
+ x = -FixedByFrac(RADAR_X_IRADIUS,costable[player->angle]);
+ y = -FixedByFrac(RADAR_Y_IRADIUS,sintable[player->angle]);
+
+ VWB_DrawSprite(radar_xcenter+x-3,radar_ycenter+y-3,NORTHICONSPR);
+
+}
+
+#if 0
/*
===============
=
@@ -733,6 +1014,7 @@ newline3:
EGAWRITEMODE(0);
}
+#endif
/*
@@ -749,17 +1031,23 @@ void T_Pshot (objtype *ob);
extern statetype s_pshot1;
extern statetype s_pshot2;
-extern statetype s_bigpshot1;
-extern statetype s_bigpshot2;
+//extern statetype s_bigpshot1;
+//extern statetype s_bigpshot2;
statetype s_pshot1 = {PSHOT1PIC,8,&T_Pshot,&s_pshot2};
statetype s_pshot2 = {PSHOT2PIC,8,&T_Pshot,&s_pshot1};
-statetype s_shotexplode = {PSHOT2PIC,8,NULL,NULL};
-statetype s_bigpshot1 = {BIGPSHOT1PIC,8,&T_Pshot,&s_bigpshot2};
-statetype s_bigpshot2 = {BIGPSHOT2PIC,8,&T_Pshot,&s_bigpshot1};
+statetype s_pshot_exp1 = {PSHOT_EXP1PIC,7,NULL,&s_pshot_exp2};
+statetype s_pshot_exp2 = {PSHOT_EXP2PIC,7,NULL,&s_pshot_exp3};
+statetype s_pshot_exp3 = {PSHOT_EXP3PIC,7,NULL,NULL};
+
+
+//statetype s_shotexplode = {PSHOT2PIC,8,NULL,NULL};
+
+//statetype s_bigpshot1 = {BIGPSHOT1PIC,8,&T_Pshot,&s_bigpshot2};
+//statetype s_bigpshot2 = {BIGPSHOT2PIC,8,&T_Pshot,&s_bigpshot1};
/*
@@ -772,12 +1060,14 @@ statetype s_bigpshot2 = {BIGPSHOT2PIC,8,&T_Pshot,&s_bigpshot1};
void SpawnPShot (void)
{
- SpawnNewObjFrac (player->x,player->y,&s_pshot1,PIXRADIUS*14);
+ DSpawnNewObjFrac (player->x,player->y,&s_pshot1,PIXRADIUS*7);
new->obclass = pshotobj;
new->speed = SHOTSPEED;
new->angle = player->angle;
+ new->active = always;
}
+#if 0
void SpawnBigPShot (void)
{
SpawnNewObjFrac (player->x,player->y,&s_bigpshot1,24*PIXRADIUS);
@@ -785,6 +1075,70 @@ void SpawnBigPShot (void)
new->speed = SHOTSPEED;
new->angle = player->angle;
}
+#endif
+
+
+/*
+===================
+=
+= JimsShotClipMove
+=
+= Only checks corners, so the object better be less than one tile wide!
+=
+===================
+*/
+boolean JimsShotClipMove (objtype *ob, long xmove, long ymove)
+{
+ int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;
+ long intersect,basex,basey,pointx,pointy;
+ unsigned inside,total,tile;
+ objtype *check;
+ boolean moveok;
+
+//
+// move player and check to see if any corners are in solid tiles
+//
+// basex = ob->x;
+// basey = ob->y;
+
+// ob->x += xmove;
+// ob->y += ymove;
+
+// CalcBounds (ob);
+
+ xl = ob->xl>>TILESHIFT;
+ yl = ob->yl>>TILESHIFT;
+
+ xh = ob->xh>>TILESHIFT;
+ yh = ob->yh>>TILESHIFT;
+
+ for (y=yl;y<=yh;y++)
+ for (x=xl;x<=xh;x++)
+ {
+ check = actorat[x][y];
+
+ if ((!check) || (check == player) || (!(check->flags & of_shootable)))
+ continue;
+
+ ob->x -= xmove;
+ ob->y -= ymove;
+
+ if (check->obclass != solidobj)
+ {
+ 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);
+ }
+
+ return(false); // move is OK!
+
+}
/*
@@ -794,7 +1148,7 @@ void SpawnBigPShot (void)
=
===============
*/
-
+#if 0
void T_Pshot (objtype *ob)
{
objtype *check;
@@ -804,18 +1158,23 @@ void T_Pshot (objtype *ob)
// check current position for monsters having moved into it
//
for (check = player->next; check; check=check->next)
- if (check->shootable
+ if ((check->flags & of_shootable)
&& ob->xl <= check->xh
&& ob->xh >= check->xl
&& ob->yl <= check->yh
&& ob->yh >= check->yl)
{
- SD_PlaySound (SHOOTMONSTERSND);
- if (ob->obclass == bigpshotobj)
- ShootActor (check,BIGSHOTDAMAGE);
- else
- ShootActor (check,SHOTDAMAGE);
- ob->state = &s_shotexplode;
+
+ if (check->obclass != solidobj)
+ {
+ 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;
}
@@ -831,7 +1190,7 @@ void T_Pshot (objtype *ob)
if (ShotClipMove(ob,xmove,ymove))
{
- ob->state = &s_shotexplode;
+ ob->state = &s_pshot_exp1;
ob->ticcount = ob->state->tictime;
return;
}
@@ -843,31 +1202,94 @@ void T_Pshot (objtype *ob)
// check final position for monsters hit
//
for (check = player->next; check; check=check->next)
- if (ob->shootable
+ if ((ob->flags & of_shootable)
&& ob->xl <= check->xh
&& ob->xh >= check->xl
&& ob->yl <= check->yh
&& ob->yh >= check->yl)
{
ShootActor (check,SHOTDAMAGE);
- ob->state = &s_shotexplode;
+ ob->state = &s_pshot_exp1;
ob->ticcount = ob->state->tictime;
return;
}
-
}
+#endif
+void T_Pshot (objtype *ob)
+{
+ objtype *check;
+ long xmove,ymove,speed;
+ int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;
+ long intersect,basex,basey,pointx,pointy;
+ unsigned inside,total,tile;
+ boolean moveok;
+
+//
+// check current position for monsters having moved into it
+//
+ for (check = player->next; check; check=check->next)
+ if ((check->flags & of_shootable)
+ && ob->xl <= check->xh
+ && ob->xh >= check->xl
+ && ob->yl <= check->yh
+ && ob->yh >= check->yl)
+ {
+
+ if (check->obclass != solidobj)
+ {
+ SD_PlaySound (SHOOTMONSTERSND);
+ if (ob->obclass == bigpshotobj)
+ ShootActor (check,BIGSHOTDAMAGE);
+ else
+ ShootActor (check,SHOTDAMAGE);
+ }
+
+ ob->state = &s_pshot_exp1;
+ ob->obclass = expobj;
+ ob->ticcount = ob->state->tictime;
+ return;
+ }
+
+
+//
+// move ahead, possibly hitting a wall
+//
+ 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->obclass = expobj;
+ ob->ticcount = ob->state->tictime;
+ return;
+ }
+
+ ob->tilex = ob->x >> TILESHIFT;
+ ob->tiley = ob->y >> TILESHIFT;
+
+//
+// check final position for monsters hit
+//
+
+ JimsShotClipMove(obj,xmove,ymove);
+
+}
+
+
/*
=============================================================================
- PLAYER ACTIONS
+ PLAYER ACTIONS
=============================================================================
*/
-
/*
===============
=
@@ -886,7 +1308,7 @@ void BuildShotPower (void)
return;
newlines = 0;
- for (i=lasttimecount-tics;i<lasttimecount;i++)
+ for (i=lasttimecount-realtics;i<lasttimecount;i++)
newlines += (i&1);
gamestate.shotpower += newlines;
@@ -896,50 +1318,6 @@ void BuildShotPower (void)
newlines -= (gamestate.shotpower - MAXSHOTPOWER);
gamestate.shotpower = MAXSHOTPOWER;
}
-
- topline = MAXSHOTPOWER - gamestate.shotpower;
-
- source = latchpics[L_SHOTBAR]+topline*SIDEBARWIDTH;
- dest = (POWERLINE+topline)*SCREENWIDTH+34;
-
- asm mov es,[screenseg]
- asm mov si,[source]
- asm mov di,[dest]
-
- EGAWRITEMODE(1);
-
- if (newlines)
- {
- asm mov cx,[newlines]
-newline:
- asm mov al,[es:si]
- asm mov [es:di+PAGE1START],al
- asm mov [es:di+PAGE2START],al
- asm mov [es:di+PAGE3START],al
- asm mov al,[es:si+1]
- asm mov [es:di+1+PAGE1START],al
- asm mov [es:di+1+PAGE2START],al
- asm mov [es:di+1+PAGE3START],al
- asm mov al,[es:si+2]
- asm mov [es:di+2+PAGE1START],al
- asm mov [es:di+2+PAGE2START],al
- asm mov [es:di+2+PAGE3START],al
- asm mov al,[es:si+3]
- asm mov [es:di+3+PAGE1START],al
- asm mov [es:di+3+PAGE2START],al
- asm mov [es:di+3+PAGE3START],al
- asm mov al,[es:si+4]
- asm mov [es:di+4+PAGE1START],al
- asm mov [es:di+4+PAGE2START],al
- asm mov [es:di+4+PAGE3START],al
-
- asm add di,SCREENWIDTH
- asm add si,5
-
- asm loop newline
- }
-
- EGAWRITEMODE(0);
}
@@ -957,6 +1335,7 @@ void ClearShotPower (void)
{
unsigned source,dest,topline;
+#if 0
topline = MAXSHOTPOWER - gamestate.shotpower;
source = latchpics[L_NOSHOT]+topline*SIDEBARWIDTH;
@@ -1000,6 +1379,7 @@ newline:
asm loop newline
EGAWRITEMODE(0);
+#endif
gamestate.shotpower = 0;
}
@@ -1023,6 +1403,7 @@ void Shoot (void)
//===========================================================================
+#if 0
/*
===============
=
@@ -1037,6 +1418,7 @@ void BigShoot (void)
SD_PlaySound (BIGSHOOTSND);
SpawnBigPShot ();
}
+#endif
//===========================================================================
@@ -1059,7 +1441,7 @@ void CastBolt (void)
TakeBolt ();
boltsleft = NUMBOLTS;
bolttimer = BOLTTICS;
- BigShoot ();
+ Shoot ();
}
@@ -1073,12 +1455,12 @@ void CastBolt (void)
void ContinueBolt (void)
{
- bolttimer-=tics;
+ bolttimer-=realtics;
if (bolttimer<0)
{
boltsleft--;
bolttimer = BOLTTICS;
- BigShoot ();
+ Shoot ();
}
}
@@ -1108,10 +1490,11 @@ void CastNuke (void)
for (angle = 0; angle < ANGLES; angle+= ANGLES/16)
{
- SpawnNewObjFrac (player->x,player->y,&s_bigpshot1,24*PIXRADIUS);
+ DSpawnNewObjFrac (player->x,player->y,&s_pshot1,24*PIXRADIUS);
new->obclass = bigpshotobj;
new->speed = SHOTSPEED;
new->angle = angle;
+ new->active = always;
}
}
@@ -1135,9 +1518,13 @@ void DrinkPotion (void)
return;
}
+ DisplaySMsg("Curing", NULL);
TakePotion ();
gamestate.body = MAXBODY;
+ VW_WaitVBL(30);
+ status_flag = S_NONE;
+#if 0
//
// draw a full up bar
//
@@ -1178,6 +1565,7 @@ newline:
asm loop newline
EGAWRITEMODE(0);
+#endif
}
@@ -1197,43 +1585,68 @@ extern boolean tileneeded[NUMFLOORS];
void ReadScroll (int scroll)
{
int i;
+ unsigned *skytemp,*gndtemp,blackcolor=0;
-//
-// make wall pictures purgable
-//
- for (i=0;i<NUMSCALEWALLS;i++)
- if (walldirectory[i])
- MM_SetPurge (&(memptr)walldirectory[i],3);
+ DisplaySMsg("Reading Scroll", NULL);
+ bufferofs = displayofs = screenloc[screenpage];
+
+ if (status_flag != S_TIMESTOP)
+ status_flag = S_NONE;
+
+ FreeUpMemory();
CA_CacheGrChunk (SCROLLTOPPIC);
CA_CacheGrChunk (SCROLL1PIC + scroll);
- VW_DrawPic (0,0,SCROLLTOPPIC);
- VW_DrawPic (0,32,SCROLL1PIC + scroll);
+ CA_CacheGrChunk (SCROLLBOTTOMPIC);
+
+ skytemp = skycolor;
+ gndtemp = groundcolor;
+ skycolor = groundcolor = &blackcolor;
+
+ VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,0);
+ VW_DrawPic (10,0,SCROLLTOPPIC);
+ VW_DrawPic (10,32,SCROLL1PIC + scroll);
+ VW_DrawPic (10,88,SCROLLBOTTOMPIC);
+
+ skycolor = skytemp;
+ groundcolor = gndtemp;
+
UNMARKGRCHUNK(SCROLL1PIC + scroll);
UNMARKGRCHUNK(SCROLLTOPPIC);
+ UNMARKGRCHUNK(SCROLLBOTTOMPIC);
MM_FreePtr (&grsegs[SCROLL1PIC + scroll]);
MM_FreePtr (&grsegs[SCROLLTOPPIC]);
+ MM_FreePtr (&grsegs[SCROLLBOTTOMPIC]);
-//
-// cache wall pictures back in
-//
- for (i=1;i<NUMFLOORS;i++)
- if (tileneeded[i])
- {
- SetupScaleWall (walllight1[i]);
- SetupScaleWall (walllight2[i]);
- SetupScaleWall (walldark1[i]);
- SetupScaleWall (walldark2[i]);
- }
+ CacheScaleds();
- VW_WaitVBL(80);
-waitkey:
IN_ClearKeysDown ();
- IN_Ack();
+// 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);
}
+//===============
+//
+// StopTime()
+//
+//
+//===============
+void StopTime()
+{
+ FreezeTime = MAXFREEZETIME;
+ SD_PlaySound(FREEZETIMESND);
+ DisplaySMsg("Time Stopped: ",NULL);
+ status_flag = S_TIMESTOP;
+}
+
/*
===============
@@ -1247,71 +1660,31 @@ void TakeDamage (int points)
{
unsigned source,dest,topline;
- if (!gamestate.body || bordertime || godmode)
+ if (!gamestate.body || (bordertime && bcolor==FLASHCOLOR) || godmode)
return;
if (points >= gamestate.body)
{
points = gamestate.body;
- playstate = ex_died;
+ Flags |= FL_DEAD;
}
- bordertime = points*FLASHTICS;
+ bordertime = FLASHTICS<<2;
+ bcolor = FLASHCOLOR;
VW_ColorBorder (FLASHCOLOR);
+ DisplaySMsg("Damaging blows!", NULL);
+ status_flag = S_NONE;
+ status_delay = 80;
+
if (gamestate.body<MAXBODY/3)
SD_PlaySound (TAKEDMGHURTSND);
else
SD_PlaySound (TAKEDAMAGESND);
gamestate.body -= points;
-//
-// shrink the body bar
-//
- source = latchpics[L_NOBODY]+gamestate.body*SIDEBARWIDTH;
- dest = (BODYLINE+gamestate.body)*SCREENWIDTH+34;
-
-
- asm mov es,[screenseg]
- asm mov si,[source]
- asm mov di,[dest]
-
- EGAWRITEMODE(1);
-
- asm mov cx,[points]
-newline:
- asm mov al,[es:si]
- asm mov [es:di+PAGE1START],al
- asm mov [es:di+PAGE2START],al
- asm mov [es:di+PAGE3START],al
- asm mov al,[es:si+1]
- asm mov [es:di+1+PAGE1START],al
- asm mov [es:di+1+PAGE2START],al
- asm mov [es:di+1+PAGE3START],al
- asm mov al,[es:si+2]
- asm mov [es:di+2+PAGE1START],al
- asm mov [es:di+2+PAGE2START],al
- asm mov [es:di+2+PAGE3START],al
- asm mov al,[es:si+3]
- asm mov [es:di+3+PAGE1START],al
- asm mov [es:di+3+PAGE2START],al
- asm mov [es:di+3+PAGE3START],al
- asm mov al,[es:si+4]
- asm mov [es:di+4+PAGE1START],al
- asm mov [es:di+4+PAGE2START],al
- asm mov [es:di+4+PAGE3START],al
-
- asm add di,SCREENWIDTH
- asm add si,5
-
- asm loop newline
-
- EGAWRITEMODE(0);
-
}
-
-
/*
=============================================================================
@@ -1321,6 +1694,7 @@ newline:
*/
+#if 0
/*
==================
=
@@ -1369,7 +1743,65 @@ void OpenDoor (unsigned bx, unsigned by, unsigned doorbase)
y++;
}
}
+#endif
+#if 0
+/*
+==================
+=
+= RemoveWalls - similar to OpenDoor(), but on a different plane
+=
+==================
+*/
+void RemoveWalls (unsigned bx, unsigned by, unsigned remove_code)
+{
+ int x,y;
+ unsigned far *map,*p2;
+
+ x=bx;
+ y=by;
+ p2 = *(mapsegs[2]+farmapylookup[y]+x);
+ map = mapsegs[0]+farmapylookup[y]+x;
+ while (*p2 == remove_code)
+ {
+ tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
+ map--;
+ p2--;
+ x--;
+ }
+ x=bx+1;
+ p2 = *(mapsegs[2]+farmapylookup[y]+x);
+ map = mapsegs[0]+farmapylookup[y]+x;
+ while (*p2 == remove_code)
+ {
+ tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
+ map++;
+ p2++;
+ x++;
+ }
+ x=bx;
+ y=by-1;
+ p2 = *(mapsegs[2]+farmapylookup[y]+x);
+ map = mapsegs[0]+farmapylookup[y]+x;
+ while (*p2 == remove_code)
+ {
+ tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
+ map-=mapwidth;
+ p2 -= mapwidth;
+ y--;
+ }
+ y=by+1;
+ p2 = *(mapsegs[2]+farmapylookup[y]+x);
+ map = mapsegs[0]+farmapylookup[y]+x;
+ while (*p2 == remove_code)
+ {
+ tilemap[x][y] = (unsigned)actorat[x][y] = *map = 0;
+ map+=mapwidth;
+ p2 += mapwidth;
+ y++;
+ }
+}
+#endif
/*
==================
@@ -1383,53 +1815,140 @@ void OpenDoor (unsigned bx, unsigned by, unsigned doorbase)
boolean HitSpecialTile (unsigned x, unsigned y, unsigned tile)
{
+ objtype *check;
+ short keyspot;
+ unsigned temp,spot,curmap=gamestate.mapon,newlevel;
+ char *key_colors[] = {"a RED key",
+ "a YELLOW key",
+ "a GREEN key",
+ "a BLUE key"};
+
switch (tile)
{
- case 0:
- case 1:
- case 2:
- case 3:
- if (!gamestate.keys[0])
- return true;
- TakeKey(0);
- OpenDoor (x,y,SPECTILESTART+0);
- return false;
-
- case 4:
- case 5:
- case 6:
- case 7:
- if (!gamestate.keys[1])
- return true;
- TakeKey(1);
- OpenDoor (x,y,SPECTILESTART+4);
- return false;
-
- case 8:
- case 9:
- case 10:
- case 11:
- if (!gamestate.keys[2])
- return true;
- TakeKey(2);
- OpenDoor (x,y,SPECTILESTART+8);
- return false;
-
- case 12:
- case 13:
- case 14:
- case 15:
- if (!gamestate.keys[3])
- return true;
- TakeKey(3);
- OpenDoor (x,y,SPECTILESTART+12);
- return false;
+ case 28:
+ 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
+ if (!playstate && !FreezeTime)
+ {
+ // Is this an openable door? (Is "openable" a word?)
+ //
+ 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");
+ VW_UpdateScreen();
+ IN_ClearKeysDown();
+ IN_Ack();
+ return;
+ }
+
+ // make sure player has key to get into door
+ //
+
+ if (TILE_FLAGS(tile) & tf_EMBEDDED_KEY_COLOR)
+ keyspot = GATE_KEY_COLOR(tile);
+ else
+ keyspot = (*(mapsegs[2]+farmapylookup[y+1]+x)) >> 8;
+
+ if (keyspot--)
+ if (!gamestate.keys[keyspot])
+ {
+ SD_PlaySound(HIT_GATESND);
+ CenterWindow(20,5);
+ US_CPrint("\nYou need\n");
+ US_CPrint(key_colors[keyspot]);
+ VW_UpdateScreen();
+ IN_ClearKeysDown();
+ IN_Ack();
+ return;
+ }
+
+ //
+ // deal with this gate (warp? simply open? whatever...)
+ //
+ switch (spot)
+ {
+ case NEXT_LEVEL_CODE: // WARP TO NEXT LEVEL
+ newlevel = gamestate.mapon+1;
+ playstate = ex_warped;
+ break;
+
+ case REMOVE_DOOR_CODE: // REMOVE DOOR
+ (unsigned)actorat[x][y] = tilemap[x][y] = *(mapsegs[0]+farmapylookup[y]+x) = 0;
+ *(mapsegs[2]+farmapylookup[y+1]+x) = 0; // key no longer needed
+ if (keyspot>=0)
+ TakeKey(keyspot);
+ break;
+
+ default: // WARP TO A LEVEL
+ newlevel = spot;
+ playstate = ex_warped;
+ break;
+ }
+
+ if (playstate == ex_warped)
+ {
+ SD_PlaySound(HIT_GATESND);
+// levelinfo *li=&gamestate.levels[curmap];
+
+// OldAngle = FaceDoor(x,y);
+
+ if (!VerifyGateExit())
+ {
+ IN_ClearKeysDown ();
+ playstate = ex_stillplaying;
+ break;
+ }
+
+// FaceAngle(OldAngle);
+
+ if (keyspot>=0)
+ TakeKey(keyspot);
+ *(mapsegs[2]+farmapylookup[y+1]+x) = 0; // key no longer needed
+
+ gamestate.mapon = newlevel;
+ SD_PlaySound(WARPUPSND);
+ IN_ClearKeysDown ();
+
+// li->x = player->tilex;
+// li->y = player->tiley;
+// li->angle = player->angle+180;
+// if (li->angle > 360)
+// li->angle -= 360;
+ }
+ }
+ break;
}
return true;
}
+//-------------------------------------------------------------------------
+// VerifyGateExit()
+//-------------------------------------------------------------------------
+boolean VerifyGateExit()
+{
+ char choices[] = {sc_Escape,sc_Y,sc_N,0},ch;
+
+ ch=DisplayMsg("Pass this way? Y/N",choices);
+ DrawText(true);
+
+ return(ch == sc_Y);
+}
/*
@@ -1450,27 +1969,63 @@ boolean TouchActor (objtype *ob, objtype *check)
switch (check->obclass)
{
- case bonusobj:
- if (check->temp1 == B_BOLT)
- GiveBolt ();
- else if (check->temp1 == B_NUKE)
- GiveNuke ();
- else if (check->temp1 == B_POTION)
- GivePotion ();
- else if (check->temp1 >= B_RKEY && check->temp1 <= B_BKEY)
- GiveKey (check->temp1-B_RKEY);
- else if (check->temp1 >= B_SCROLL1 && check->temp1 <= B_SCROLL8)
- GiveScroll (check->temp1-B_SCROLL1,true);
- else if (check->temp1 == B_CHEST)
- GiveChest ();
- else if (check->temp1 == B_GOAL)
- GiveGoal ();
- (unsigned)actorat[check->tilex][check->tiley] = 0;
- RemoveObj (check);
-
- return false;
+ case bonusobj:
+ switch (check->temp1)
+ {
+ case B_BOLT: GiveBolt (); break;
+
+ case B_NUKE: GiveNuke (); break;
+
+ case B_POTION: GivePotion (); 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;
+
+ case B_SCROLL1:
+ case B_SCROLL2:
+ case B_SCROLL3:
+ case B_SCROLL4:
+ case B_SCROLL5:
+ case B_SCROLL6:
+ case B_SCROLL7:
+ case B_SCROLL8: GiveScroll (check->temp1-B_SCROLL1,true); break;
+
+ case B_CHEST: GiveChest (); break;
+
+ case B_RGEM:
+ case B_YGEM:
+ case B_GGEM:
+ case B_BGEM:
+ case B_PGEM:
+ SD_PlaySound(GETGEMSND);
+ gamestate.gems[check->temp1-B_RGEM] = GEM_DELAY_TIME;
+ redraw_gems = true;
+ break;
+
+ default:
+ Quit("TouchActor(): INVALID BONUS");
+ break;
+ }
+
+ (unsigned)actorat[check->tilex][check->tiley] = 0;
+ RemoveObj (check);
+
+ return false;
+ break;
+
+ case freezeobj:
+ StopTime();
+ (unsigned)actorat[check->tilex][check->tiley] = 0;
+ RemoveObj(check);
+ return(false);
+ break;
}
+
return true;
}
@@ -1519,30 +2074,28 @@ boolean LocationInActor (objtype *ob)
for (y=ymin;y<ymax;y++)
{
check = actorat[x][y];
- if (check>(objtype *)LASTSPECIALTILE
- && check->shootable
- && ob->xl <= check->xh
- && ob->xh >= check->xl
- && ob->yl <= check->yh
- && ob->yh >= check->yl)
- return true;
+ if (check>(objtype *)LASTTILE
+ && (check->flags & of_shootable)
+ && ob->xl-SIZE_TEST <= check->xh
+ && ob->xh+SIZE_TEST >= check->xl
+ && ob->yl-SIZE_TEST <= check->yh
+ && ob->yh+SIZE_TEST >= check->yl)
+ return true;
}
return false;
}
-
/*
===================
=
-= ClipMove
+= ClipXMove
=
= Only checks corners, so the object better be less than one tile wide!
=
===================
*/
-
-void ClipMove (objtype *ob, long xmove, long ymove)
+void ClipXMove (objtype *ob, long xmove)
{
int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;
long intersect,basex,basey,pointx,pointy;
@@ -1557,7 +2110,6 @@ void ClipMove (objtype *ob, long xmove, long ymove)
basey = ob->y;
ob->x += xmove;
- ob->y += ymove;
CalcBounds (ob);
@@ -1571,19 +2123,24 @@ void ClipMove (objtype *ob, long xmove, long ymove)
for (x=xl;x<=xh;x++)
{
check = actorat[x][y];
+
if (!check)
continue; // blank floor, walk ok
- if ((unsigned)check<=LASTWALLTILE)
- goto blockmove; // solid wall
-
- if ((unsigned)check<=LASTSPECIALTILE)
+ if ((unsigned)check <= LASTTILE)
{
- if ( HitSpecialTile (x,y,(unsigned)check-SPECTILESTART) )
- goto blockmove; // whatever it was, it blocked the move
- else
- continue;
+ if (TILE_FLAGS((unsigned)check) & tf_SPECIAL)
+ {
+ HitSpecialTile(x,y,(unsigned)check-SPECTILESTART);
+ goto blockmove;
+ }
+
+ if (TILE_FLAGS((unsigned)check) & tf_SOLID)
+ {
+ goto blockmove; // solid wall
+ }
}
+
TouchActor(ob,check); // pick up items
}
@@ -1596,7 +2153,6 @@ void ClipMove (objtype *ob, long xmove, long ymove)
if (LocationInActor(ob))
{
ob->x += xmove;
- ob->y -= ymove;
if (LocationInActor(ob))
ob->x -= xmove;
}
@@ -1606,23 +2162,134 @@ void ClipMove (objtype *ob, long xmove, long ymove)
blockmove:
- if (!SD_SoundPlaying())
- SD_PlaySound (HITWALLSND);
+// if (!SD_SoundPlaying())
+// SD_PlaySound (HITWALLSND);
moveok = false;
do
{
xmove /= 2;
- ymove /= 2;
if (moveok)
{
ob->x += xmove;
- ob->y += ymove;
}
else
{
ob->x -= xmove;
+ }
+ CalcBounds (ob);
+ xl = ob->xl>>TILESHIFT;
+ yl = ob->yl>>TILESHIFT;
+ xh = ob->xh>>TILESHIFT;
+ yh = ob->yh>>TILESHIFT;
+ if (tilemap[xl][yl] || tilemap[xh][yl]
+ || tilemap[xh][yh] || tilemap[xl][yh] )
+ {
+ 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);
+}
+
+
+/*
+===================
+=
+= ClipYMove
+=
+= Only checks corners, so the object better be less than one tile wide!
+=
+===================
+*/
+void ClipYMove (objtype *ob, long ymove)
+{
+ int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;
+ long intersect,basex,basey,pointx,pointy;
+ unsigned inside,total,tile;
+ objtype *check;
+ boolean moveok;
+
+//
+// move player and check to see if any corners are in solid tiles
+//
+ basex = ob->x;
+ basey = ob->y;
+
+ ob->y += ymove;
+
+ CalcBounds (ob);
+
+ xl = ob->xl>>TILESHIFT;
+ yl = ob->yl>>TILESHIFT;
+
+ xh = ob->xh>>TILESHIFT;
+ yh = ob->yh>>TILESHIFT;
+
+ for (y=yl;y<=yh;y++)
+ for (x=xl;x<=xh;x++)
+ {
+ check = actorat[x][y];
+ if (!check)
+ continue; // blank floor, walk ok
+
+ if ((unsigned)check <= LASTTILE)
+ {
+ if (TILE_FLAGS((unsigned)check) & tf_SPECIAL) // <=LASTSPECIALTILE)
+ {
+ HitSpecialTile (x,y,(unsigned)check-SPECTILESTART);
+ goto blockmove;
+ }
+
+ if (TILE_FLAGS((unsigned)check) & tf_SOLID) // LASTWALLTILE)
+ {
+ goto blockmove; // solid wall
+ }
+ }
+
+ TouchActor(ob,check); // pick up items
+ }
+
+//
+// check nearby actors
+//
+ if (LocationInActor(ob))
+ {
+ if (LocationInActor(ob))
+ {
+ ob->y -= ymove;
+ }
+ }
+ return; // move is OK!
+
+
+blockmove:
+
+// if (!SD_SoundPlaying())
+// SD_PlaySound (HITWALLSND);
+
+ moveok = false;
+
+ do
+ {
+ ymove /= 2;
+ if (moveok)
+ {
+ ob->y += ymove;
+ }
+ else
+ {
ob->y -= ymove;
}
CalcBounds (ob);
@@ -1634,7 +2301,7 @@ blockmove:
|| tilemap[xh][yh] || tilemap[xl][yh] )
{
moveok = false;
- if (xmove>=-2048 && xmove <=2048 && ymove>=-2048 && ymove <=2048)
+ if (ymove>=-2048 && ymove <=2048)
{
ob->x = basex;
ob->y = basey;
@@ -1643,7 +2310,7 @@ blockmove:
}
else
{
- if (xmove>=-2048 && xmove <=2048 && ymove>=-2048 && ymove <=2048)
+ if (ymove>=-2048 && ymove <=2048)
return;
moveok = true;
}
@@ -1668,7 +2335,7 @@ boolean ShotClipMove (objtype *ob, long xmove, long ymove)
{
int xl,yl,xh,yh,tx,ty,nt1,nt2,x,y;
long intersect,basex,basey,pointx,pointy;
- unsigned inside,total,tile;
+ unsigned inside,total,spot,tile;
objtype *check;
boolean moveok;
@@ -1692,13 +2359,20 @@ boolean ShotClipMove (objtype *ob, long xmove, long ymove)
for (y=yl;y<=yh;y++)
for (x=xl;x<=xh;x++)
{
- tile = tilemap[x][y];
- if (tile)
- {
- if ((unsigned)(tile-EXPWALLSTART)<NUMEXPWALLS)
- ExplodeWall (x,y);
+ spot = (*(mapsegs[2]+farmapylookup[y]+x)) >> 8;
+ if (spot == EXP_WALL_CODE)
+ switch (ob->obclass)
+ {
+ case pshotobj:
+ case bigpshotobj:
+ ExplodeWall (x,y);
+ goto blockmove;
+ break;
+ }
+
+ tile = *(mapsegs[0]+farmapylookup[y]+x);
+ if (TILE_FLAGS(tile) & tf_SOLID)
goto blockmove;
- }
}
return false; // move is OK!
@@ -1753,7 +2427,7 @@ blockmove:
/*
=============================================================================
- PLAYER CONTROL
+ PLAYER CONTROL
=============================================================================
*/
@@ -1774,16 +2448,29 @@ statetype s_player = {0,0,&T_Player,&s_player};
void SpawnPlayer (int tilex, int tiley, int dir)
{
+#if 0
+ levelinfo *li=&gamestate.levels[gamestate.mapon];
+
+ if (li->x != -1)
+ {
+ tilex = li->x;
+ tiley = li->y;
+ player->angle = li->angle;
+ }
+ else
+ player->angle = (1-dir)*90;
+#endif
+
player->obclass = playerobj;
- player->active = true;
+ player->active = always;
player->tilex = tilex;
player->tiley = tiley;
player->x = ((long)tilex<<TILESHIFT)+TILEGLOBAL/2;
player->y = ((long)tiley<<TILESHIFT)+TILEGLOBAL/2;
player->state = &s_player;
- player->angle = (1-dir)*90;
player->size = MINDIST;
- CalcBounds (player);
+ CalcBounds(player);
+ player->angle = (1-dir)*90;
if (player->angle<0)
player->angle += ANGLES;
}
@@ -1815,7 +2502,8 @@ void Thrust (int angle, unsigned speed)
xmove = FixedByFrac(speed,costable[angle]);
ymove = -FixedByFrac(speed,sintable[angle]);
- ClipMove(player,xmove,ymove);
+ ClipXMove(player,xmove);
+ ClipYMove(player,ymove);
player->tilex = player->x >> TILESHIFT;
player->tiley = player->y >> TILESHIFT;
}
@@ -1836,7 +2524,7 @@ void ControlMovement (objtype *ob)
long speed;
- if (c.button1)
+ if (control.button1)
{
//
// strafing
@@ -1851,19 +2539,13 @@ void ControlMovement (objtype *ob)
else
speed = -(long)mousexmove*300;
- if (c.xaxis == -1)
+ if (control.xaxis == -1)
{
- if (running)
- speed += RUNSPEED*tics;
- else
- speed += PLAYERSPEED*tics;
+ speed += PLAYERSPEED*tics;
}
- else if (c.xaxis == 1)
+ else if (control.xaxis == 1)
{
- if (running)
- speed -= RUNSPEED*tics;
- else
- speed -= PLAYERSPEED*tics;
+ speed -= PLAYERSPEED*tics;
}
if (speed > 0)
@@ -1892,19 +2574,22 @@ void ControlMovement (objtype *ob)
//
//
- // turning
+ // TURNING
//
- if (c.xaxis == 1)
+ if (control.xaxis == 1)
{
ob->angle -= tics;
- if (running) // fast turn
- ob->angle -= tics;
+
+ if (running)
+ ob->angle -= (tics<<1); // FAST turn
+
}
- else if (c.xaxis == -1)
+ else if (control.xaxis == -1)
{
ob->angle+= tics;
- if (running) // fast turn
- ob->angle += tics;
+
+ if (running)
+ ob->angle += (tics<<1); // FAST turn
}
ob->angle -= (mousexmove/10);
@@ -1926,19 +2611,13 @@ void ControlMovement (objtype *ob)
else
speed = -(long)mouseymove*200;
- if (c.yaxis == -1)
+ if (control.yaxis == -1)
{
- if (running)
- speed += RUNSPEED*tics;
- else
- speed += PLAYERSPEED*tics;
+ speed += PLAYERSPEED*tics;
}
- else if (c.yaxis == 1)
+ else if (control.yaxis == 1)
{
- if (running)
- speed -= RUNSPEED*tics;
- else
- speed -= PLAYERSPEED*tics;
+ speed -= PLAYERSPEED*tics;
}
if (speed > 0)
@@ -1969,10 +2648,14 @@ void ControlMovement (objtype *ob)
void T_Player (objtype *ob)
{
- int angle,speed,scroll;
+ extern boolean autofire;
+
+ int angle,speed,scroll,loop;
unsigned text,tilex,tiley;
long lspeed;
+// boolean radar_moved=false;
+
ControlMovement (ob);
@@ -1982,7 +2665,7 @@ void T_Player (objtype *ob)
//
if (boltsleft)
{
- handheight+=(tics<<2);
+ handheight+=(realtics<<2);
if (handheight>MAXHANDHEIGHT)
handheight = MAXHANDHEIGHT;
@@ -1991,9 +2674,36 @@ void T_Player (objtype *ob)
}
else
{
- if (c.button0)
+ if (control.button0)
{
- handheight+=(tics<<2);
+ handheight+=(realtics<<2);
+ if (handheight>MAXHANDHEIGHT)
+ handheight = MAXHANDHEIGHT;
+ lasthand = lasttimecount;
+
+ if (!button0down)
+ Shoot();
+
+ if (!autofire)
+ button0down=true;
+ }
+ else
+ {
+ if (lasttimecount > lasthand+HANDPAUSE)
+ {
+ handheight-=(realtics<<1);
+ if (handheight<0)
+ handheight = 0;
+ }
+
+ button0down = false;
+ }
+}
+
+#if 0
+ if (control.button0)
+ {
+ handheight+=(realtics<<2);
if (handheight>MAXHANDHEIGHT)
handheight = MAXHANDHEIGHT;
@@ -2005,42 +2715,422 @@ void T_Player (objtype *ob)
{
if (lasttimecount > lasthand+HANDPAUSE)
{
- handheight-=(tics<<1);
+ handheight-=(realtics<<1);
if (handheight<0)
handheight = 0;
}
- if (gamestate.shotpower == MAXSHOTPOWER)
- {
- lastfiretime = (unsigned)TimeCount/FIRETIME;
- BigShoot ();
- }
- else if (gamestate.shotpower)
+ if (gamestate.shotpower)
{
lastfiretime = (unsigned)TimeCount/FIRETIME;
Shoot ();
}
}
}
+#endif
//
// special actions
//
- if ( (Keyboard[sc_Space] || Keyboard[sc_H]) && gamestate.body != MAXBODY)
+ if ((Keyboard[sc_Space] || Keyboard[sc_C]) && gamestate.body != MAXBODY)
DrinkPotion ();
- if (Keyboard[sc_B] && !boltsleft)
+ if (Keyboard[sc_Z] && !boltsleft)
CastBolt ();
- if ( (Keyboard[sc_Enter] || Keyboard[sc_N]) && TimeCount-lastnuke > NUKETIME)
+ if ( (Keyboard[sc_Enter] || Keyboard[sc_X]) && ((TimeCount-lastnuke > NUKETIME) || (autofire)))
CastNuke ();
scroll = LastScan-2;
if ( scroll>=0 && scroll<NUMSCROLLS && gamestate.scrolls[scroll])
ReadScroll (scroll);
- DrawText ();
- DrawCompass ();
+ DrawText(false);
+ DrawHealth();
+ if (FreezeTime)
+ DrawFreezeTime();
+ DrawRadar();
+ EGAWRITEMODE(0);
+ DrawNSEWIcons();
+
+ if (redraw_gems)
+ DrawGems();
+
+#if 0
+// gems fade out over time...
+//
+ for (loop=0; loop<5; loop++)
+ if (gamestate.gems[loop])
+ {
+ gamestate.gems[loop] -= realtics;
+ if (gamestate.gems[loop] < 0)
+ {
+ gamestate.gems[loop] = 0;
+ redraw_gems = true;
+ }
+ }
+#endif
+}
+
+#if 0
+//------------------------------------------------------------------------
+// FaceDir() -
+//
+// PARAMS : x,y - pixle coords to bring in to view.
+//
+// NOTE : Params CAN NOT be shifted fracs!
+//------------------------------------------------------------------------
+void FaceDir(short x,short y,boolean StopTime)
+{
+ short diff;
+
+ RotateAngle = CalcAngle(x-(player->x>>16l),(player->y>>16l)-y);
+ FreezeTime = StopTime;
+
+ diff = player->angle - RotateAngle;
+
+ if (((diff>0) && (diff<180)) || ((diff<0) && (diff>-180)))
+ RotateSpeed = -ROTATE_SPEED;
+ else
+ RotateSpeed = ROTATE_SPEED;
+}
+#endif
+
+#if 0
+//------------------------------------------------------------------------
+// CalcAngle() -
+//
+// DESC: Calculates the angle from a given dy & dx
+//------------------------------------------------------------------------
+short CalcAngle(short dx,short dy)
+{
+ #define degtorad (180/PI)
+ float angle;
+ short diff;
+ float rad_angle;
+
+ if (dx)
+ {
+ angle = atan((float)dy/dx)* degtorad;
+ if (angle<=0)
+ angle += 180;
+ if (dy>0)
+ angle += 180;
+ }
+ else
+ {
+ // 90 Deg shift
+
+ if (dy < 0)
+ angle = 0 + 90; // Above player (NORTH)
+ else
+ angle = 180 + 90; // Below player (SOUTH)
+ }
+
+ if (!angle) // HACK
+ angle++;
+
+ return((short)abs(angle));
+}
+
+#endif
+
+#if 0
+
+//-------------------------------------------------------------------------
+// RotateView() -
+//
+// DESC : Rotates view (current view of game) to a dest angle.
+//-------------------------------------------------------------------------
+void RotateView()
+{
+ short LastPos;
+
+ // Store old angle position then change angle...
+ //
+
+ LastPos = player->angle;
+
+ player->angle += RotateSpeed;
+
+ // Check to see if we cranked past out dest angle...
+ //
+
+
+ if ((player->angle>ANGLES) || (!player->angle))
+ player->angle = 1;
+ else
+ if (player->angle<1)
+ player->angle = ANGLES;
+
+ // Check to see if we over shot our dest angle...
+ //
+
+ if (((LastPos < RotateAngle) && (player->angle > RotateAngle) && (RotateSpeed > 0)) ||
+ ((LastPos > RotateAngle) && (player->angle < RotateAngle) && (RotateSpeed < 0)))
+ player->angle = RotateAngle;
+
+ // Check for ending force turn....
+ //
+
+ if (player->angle == RotateAngle)
+ RotateAngle = -1;
}
+
+
+//--------------------------------------------------------------------------
+// InitRotate()
+//--------------------------------------------------------------------------
+void InitRotate(short DestAngle)
+{
+ if (player->angle != DestAngle)
+ {
+ RotateAngle = DestAngle;
+
+ if (player->angle > DestAngle)
+ RotateSpeed = -ROTATE_SPEED;
+ else
+ RotateSpeed = ROTATE_SPEED;
+
+ if (abs(player->angle - RotateAngle) > 180)
+ RotateSpeed =- RotateSpeed;
+ }
+}
+
+
+
+//------------------------------------------------------------------------
+// FaceAngle() -
+//
+// PARAMS : DestAngle - Destination angle to turn to
+//------------------------------------------------------------------------
+void FaceAngle(short DestAngle)
+{
+ signed long dx,dy,radius,psin,pcos,newx,newy;
+ int give;
+ short objnum,LastPos;
+ signed long ox,oy,xl,xh,yl,yh,px,py,norm_dx,norm_dy;
+ short o_radius;
+ void (*think)();
+
+
+ // Calculate the direction we want to turn to...
+ //
+
+ InitRotate(DestAngle);
+
+ RedrawStatusWindow();
+
+ while (RotateAngle != -1)
+ {
+
+ RotateView();
+
+// PollControls();
+
+ objnum=0;
+
+ for (obj = player;obj;obj = obj->next)
+ {
+ if (obj->active >= yes)
+ {
+
+ // keep a list of objects around the player for radar updates
+ //
+ if (obj == player)
+ {
+ px = player->x;
+ py = player->y;
+ psin = sintable[player->angle];
+ pcos = costable[player->angle];
+ xl = px-((long)RADAR_WIDTH<<TILESHIFT)/2;
+ xh = px+((long)RADAR_WIDTH<<TILESHIFT)/2-1;
+ yl = py-((long)RADAR_HEIGHT<<TILESHIFT)/2;
+ yh = py+((long)RADAR_HEIGHT<<TILESHIFT)/2;
+ }
+
+ if (objnum > MAX_RADAR_BLIPS-2)
+ objnum = MAX_RADAR_BLIPS-2;
+
+ ox = obj->x;
+ oy = obj->y;
+
+
+ if ((ox >= xl) && (ox <= xh) && (oy >= yl) && (oy <= yh))
+ {
+ norm_dx = (dx = px-ox)>>TILESHIFT;
+ norm_dy = (dy = oy-py)>>TILESHIFT;
+
+ o_radius = IntSqrt((norm_dx * norm_dx) + (norm_dy * norm_dy));
+
+ if (o_radius < RADAR_RADIUS)
+ {
+ newx = FixedByFrac(dy,pcos)-FixedByFrac(dx,psin);
+ newy = FixedByFrac(dy,psin)+FixedByFrac(dx,pcos);
+
+ RadarXY[objnum][0]=newx>>TILESHIFT;
+ RadarXY[objnum][1]=newy>>TILESHIFT;
+
+ // Define color to use for this object...
+ //
+
+ switch (obj->obclass)
+ {
+ case playerobj:
+ RadarXY[objnum++][2]=15;
+ break;
+
+ // RED GEM
+ //
+ case demonobj:
+ if (gamestate.gems[B_RGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=12;
+ break;
+
+ // GREEN GEM
+ //
+ case trollobj:
+ if (gamestate.gems[B_GGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=10;
+ break;
+
+ // YELLOW GEM
+ //
+ case skeletonobj:
+ if (gamestate.gems[B_YGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=14;
+ break;
+
+ // BLUE GEM
+ //
+ case mageobj:
+ case wetobj:
+ if (gamestate.gems[B_BGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=9;
+ break;
+
+ // PURPLE GEM
+ //
+ case zombieobj:
+ if (gamestate.gems[B_PGEM-B_RGEM])
+ if (obj->active == always)
+ RadarXY[objnum++][2]=13;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ RadarXY[objnum][2]=-1; // Signals end of RadarXY list...
+
+// refresh all
+//
+
+ ThreeDRefresh();
+ DrawRadar();
+ EGAWRITEMODE(0);
+ DrawNSEWIcons();
+
+// CheckKeys();
+ }
+}
+
+
+//-------------------------------------------------------------------------
+// FaceDoor() - Turns the player to face a door (a tile) at a given TILE x & y
+//
+// RETURNS : Returns the orginal angle of the player.
+//------------------------------------------------------------------------
+short FaceDoor(short x, short y)
+{
+ short p_x,p_y,angle,old_angle;
+
+ old_angle = player->angle;
+
+ p_x = player->x>>16l;
+ p_y = player->y>>16l;
+
+ if (p_x != x)
+ {
+ if (p_x > x)
+ angle = 180; // Face Left
+ else
+ angle = 1; // Face Right
+ }
+
+ if (p_y != y)
+ {
+ if (p_y > y)
+ angle = 90; // Face Up
+ else
+ angle = 270; // Face Down
+ }
+
+ FaceAngle(angle);
+
+ return(old_angle);
+}
+
+
+#endif
+
+
+
+/*==========================================================================
+
+ EXPLOSION SPAWNING ROUTINES
+
+===========================================================================*/
+
+statetype s_explode = {0,1,T_ExpThink,&s_explode};
+
+//-------------------------------------------------------------------------
+// SpawnExplosion()
+//------------------------------------------------------------------------
+void SpawnExplosion(fixed x, fixed y, short Delay)
+{
+ DSpawnNewObjFrac(x,y,&s_explode,PIXRADIUS*7);
+ new->obclass = expobj;
+ new->active = always;
+ new->temp1 = Delay;
+}
+
+
+//---------------------------------------------------------------------------
+// T_ExpThink()
+//---------------------------------------------------------------------------
+void T_ExpThink(objtype *obj)
+{
+ if (obj->temp1)
+ {
+ if ((obj->temp1-=realtics) <= 0)
+ obj->temp1 = 0;
+ }
+ else
+ {
+ obj->state = &s_pshot_exp1;
+ obj->ticcount = obj->state->tictime;
+ SD_PlaySound(BOOMSND);
+ }
+}
+
+
+
+//-------------------------------------------------------------------------
+// SpawnBigExplosion()
+//------------------------------------------------------------------------
+void SpawnBigExplosion(fixed x, fixed y, short Delay, fixed Range)
+{
+ SpawnExplosion(x-random(Range),y+random(Range),random(Delay));
+ SpawnExplosion(x+random(Range),y-random(Range),random(Delay));
+ SpawnExplosion(x-random(Range),y-random(Range),random(Delay));
+ SpawnExplosion(x+random(Range),y+random(Range),random(Delay));
+}
+
diff --git a/DEF.H b/DEF.H
index c0fe07f..29de258 100644
--- a/DEF.H
+++ b/DEF.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -30,7 +30,71 @@
=============================================================================
*/
+//
+// 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
+//
+//
+#define PERCENTAGE(MAX_BASE,MAX_PERC,PERC,SCALE) ((unsigned)(MAX_BASE*((PERC<<SCALE)/MAX_PERC))>>SCALE)
+
+#define PI 3.141592657
+
+
+#define SIZE_TEST 0 //50000 // DO NOT USE!! ARGH!
+
+#define FL_QUICK 0x01
+#define FL_NOMEMCHECK 0x02
+
+#define FL_CLEAR (FL_QUICK|FL_NOMEMCHECK)
+
+#define GEM_SHIFT 2
+#define FL_RGEM 0x04
+#define FL_GGEM 0x08
+#define FL_BGEM 0x10
+#define FL_YGEM 0x20
+#define FL_PGEM 0x40
+#define FL_DEAD 0x80
+
+
+
+#define MAXBOLTS 10
+#define MAXNUKES 10
+#define MAXPOTIONS 10
+
+#define NUKE_COST (1000)
+#define BOLT_COST (1200)
+#define POTION_COST (1300)
+
+#define NUKE_COST_TXT ("1000") // Allows for Q&D positioning..
+#define BOLT_COST_TXT ("1200")
+#define POTION_COST_TXT ("1300")
+
+#define RADARX 31 // bytes
+#define RADARY 11 // pixels
+#define RADAR_WIDTH 51 // "
+#define RADAR_HEIGHT 51 // "
+#define RADAR_XCENTER ((RADARX*8)+(RADAR_WIDTH/2)+3) // "
+#define RADAR_YCENTER ((RADARY-8)+(RADAR_HEIGHT/2)+5) // "
+#define MAX_RADAR_BLIPS 60
+
+
+#define RADAR_RADIUS 17
+#define RADAR_RADIUS_NSEW 15
+#define RADAR_X_IRADIUS (113/5)
+#define RADAR_Y_IRADIUS (113/7)
+#define RADAR_ICON_CENTER 4 // Center offset into icon.
+
#define NAMESTART 180
+#define REMOVED_DOOR_TILE NAMESTART
+
+#define NEXT_LEVEL_CODE 0xff
+#define REMOVE_DOOR_CODE 0xfe
+#define CANT_OPEN_CODE 0xfd
+#define EXP_WALL_CODE 0xfc
#define UNMARKGRCHUNK(chunk) (grneeded[chunk]&=~ca_levelbit)
@@ -40,25 +104,24 @@
#define EXPWALLSTART 8
#define NUMEXPWALLS 7
#define WALLEXP 15
-#define NUMFLOORS 36
+#define WATEREXP 29
+#define NUMFLOORS 71
-#define NUMFLOORS 36
+#define NUMLATCHPICS (FIRSTWALLPIC-FIRSTLATCHPIC) //+5
+#define NUMSCALEPICS (FIRSTWALLPIC-FIRSTSCALEPIC) //+5
+#define NUMSCALEWALLS (LASTWALLPIC-FIRSTWALLPIC) //+5
-#define NUMLATCHPICS 100
-#define NUMSCALEPICS 100
-#define NUMSCALEWALLS 30
-
-#define FLASHCOLOR 5
+#define FLASHCOLOR 12
#define FLASHTICS 4
-#define NUMLEVELS 20
+#define NUMLEVELS 21
#define VIEWX 0 // corner of view window
#define VIEWY 0
-#define VIEWWIDTH (33*8) // size of view window
-#define VIEWHEIGHT (18*8)
+#define VIEWWIDTH (40*8) // size of view window // 33
+#define VIEWHEIGHT (15*8) // 18
#define VIEWXH (VIEWX+VIEWWIDTH-1)
#define VIEWYH (VIEWY+VIEWHEIGHT-1)
@@ -72,10 +135,11 @@
#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
-#define MAXACTORS 150 // max number of tanks, etc / map
+#define MAXACTORS 100 // max number of tanks, etc / map
#define NORTH 0
#define EAST 1
@@ -89,16 +153,19 @@
#define MAXSCALE (VIEWWIDTH/2)
-#define MAXBODY 64
+#define MAXBODY 100
#define MAXSHOTPOWER 56
#define SCREEN1START 0
#define SCREEN2START 8320
-#define PAGE1START 0x900
-#define PAGE2START 0x2000
-#define PAGE3START 0x3700
-#define FREESTART 0x4e00
+#define STATUSLEN 0xc80
+#define PAGELEN 0x1700
+
+#define PAGE1START STATUSLEN
+#define PAGE2START (PAGE1START+PAGELEN)
+#define PAGE3START (PAGE2START+PAGELEN)
+#define FREESTART (PAGE3START+PAGELEN)
#define PIXRADIUS 512
@@ -106,7 +173,21 @@
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_GOAL,B_CHEST,B_RGEM,B_GGEM,B_BGEM,B_YGEM,B_PGEM,B_RKEY2};
+
+
+#define MAX_DOOR_STORAGE 5
+
+#define GEM_DELAY_TIME (120*60)
+
+#define ROTATE_SPEED (6)
+
+#define WALL_SKELETON_CODE 6
+
+#define MAXREALTICS (2*60)
+
+#define MAXFREEZETIME (100*30) // 50 secs (100 half)
+extern boolean EASYMODEON;
/*
@@ -134,8 +215,9 @@ typedef struct
typedef enum
{nothing,playerobj,bonusobj,orcobj,batobj,skeletonobj,trollobj,demonobj,
- mageobj,pshotobj,bigpshotobj,mshotobj,inertobj,bounceobj,grelmobj
- ,gateobj} classtype;
+ mageobj,pshotobj,bigpshotobj,mshotobj,inertobj,bounceobj,grelmobj,
+ gateobj,zombieobj,spookobj,wetobj,expobj,eyeobj,wallskelobj,eshotobj,
+ gshotobj,reddemonobj,freezeobj,solidobj} classtype;
typedef enum {north,east,south,west,northeast,southeast,southwest,
northwest,nodir} dirtype; // a catacombs 2 carryover
@@ -149,16 +231,18 @@ typedef struct statestruct
struct statestruct *next;
} statetype;
+#define of_shootable 0x01
+#define of_damagedone 0x02
typedef struct objstruct
{
- enum {no,yes} active;
+ enum {no,noalways,yes,always} active;
int ticcount;
classtype obclass;
statetype *state;
- boolean shootable;
- boolean tileobject; // true if entirely inside one tile
+ unsigned char flags;
+// boolean tileobject; // true if entirely inside one tile
long distance;
dirtype dir;
@@ -179,19 +263,40 @@ typedef struct objstruct
} objtype;
+typedef enum {ex_stillplaying,ex_died,ex_warped,ex_resetgame
+ ,ex_loadedgame,ex_victorious,ex_turning,ex_abort} exittype;
+
+
+typedef enum {S_NONE, S_HELP, S_SND, S_SAVING, S_RESTORING,
+ S_JOYSTICK, S_RETREAT, S_ADVANCE, S_SIDESTEP, S_QTURN,
+ S_MISSLE, S_ZAPPER, S_XTER, S_CURING, S_READ,
+ S_VIEWING, S_ITEMDES, S_DAMAGE, S_TURN, S_TIMESTOP} status_flags;
+
+typedef struct {
+ char x,y;
+ unsigned ondoor,underdoor;
+} doorinfo;
+
+typedef struct {
+ char x,y;
+ short angle;
+ doorinfo doors[MAX_DOOR_STORAGE];
+} levelinfo;
+
typedef struct
{
int difficulty;
int mapon;
int bolts,nukes,potions,keys[4],scrolls[8];
+
+ int gems[5]; // "int allgems[5]" is used for 1:1 comparison
+ // in play loop for radar... CHANGE IT, TOO!
+
long score;
int body,shotpower;
+// levelinfo levels[NUMLEVELS];
} gametype;
-typedef enum {ex_stillplaying,ex_died,ex_warped,ex_resetgame
- ,ex_loadedgame,ex_victorious,ex_abort} exittype;
-
-
/*
=============================================================================
@@ -200,11 +305,14 @@ typedef enum {ex_stillplaying,ex_died,ex_warped,ex_resetgame
=============================================================================
*/
+extern char inlevel[][2];
extern char str[80],str2[20];
extern unsigned tedlevelnum;
extern boolean tedlevel;
extern gametype gamestate;
extern exittype playstate;
+extern char SlowMode;
+extern unsigned Flags;
void NewGame (void);
@@ -213,7 +321,7 @@ boolean LoadTheGame(int file);
void ResetGame(void);
void ShutdownId (void);
void InitGame (void);
-void Quit (char *error);
+void Quit (char *error, ...);
void TEDDeath(void);
void DemoLoop (void);
void SetupScalePic (unsigned picnum);
@@ -244,7 +352,7 @@ extern unsigned textstarts[27];
void ScanInfoPlane (void);
void ScanText (void);
void SetupGameLevel (void);
-void Victory (void);
+void Victory (boolean playsounds);
void Died (void);
void NormalScreen (void);
void DrawPlayScreen (void);
@@ -264,7 +372,14 @@ void GameLoop (void);
=============================================================================
*/
-extern ControlInfo c;
+#define BGF_NIGHT 0x01 // it is officially night
+#define BGF_NOT_LIGHTNING 0x02 // lightning flash has ended
+
+extern byte BGFLAGS,bcolor;
+
+extern unsigned *skycolor,*groundcolor;
+
+extern ControlInfo control;
extern boolean running,slowturn;
extern int bordertime;
@@ -282,8 +397,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; //
void CenterWindow(word w,word h);
@@ -296,7 +417,9 @@ void GetNewObj (boolean usedummy);
void RemoveObj (objtype *gone);
void PollControlls (void);
void PlayLoop (void);
+void InitBgChange(short stimer, unsigned *scolors, short gtimer, unsigned *gcolors, byte flag);
+void DisplayStatus (status_flags *stat_flag);
/*
=============================================================================
@@ -306,8 +429,17 @@ void PlayLoop (void);
=============================================================================
*/
-void SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size);
-void SpawnNewObjFrac (long x, long y, statetype *state, unsigned size);
+//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_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 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)
+
boolean CheckHandAttack (objtype *ob);
void T_DoDamage (objtype *ob);
boolean Walk (objtype *ob);
@@ -393,6 +525,8 @@ extern int walldark1[NUMFLOORS];
extern int walllight2[NUMFLOORS];
extern int walldark2[NUMFLOORS];
+extern unsigned topcolor,bottomcolor;
+
//==========================================================================
void DrawLine (int xl, int xh, int y,int color);
@@ -447,10 +581,10 @@ extern byte bitmasks1[8][8];
extern byte bitmasks2[8][8];
-extern t_compscale _seg *scaledirectory[MAXSCALE+1];
+extern t_compscale _seg *scaledirectory[NUMSCALEPICS];
extern t_compshape _seg *shapedirectory[NUMSCALEPICS];
extern memptr walldirectory[NUMSCALEWALLS];
-extern unsigned shapesize[MAXSCALE+1];
+extern unsigned shapesize[NUMSCALEPICS];
void DeplanePic (int picnum);
void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale);
@@ -487,9 +621,36 @@ void ScaleWalls (void);
#define MAXHANDHEIGHT 72
+extern statetype s_pshot_exp1;
+extern statetype s_pshot_exp2;
+extern statetype s_pshot_exp3;
+
extern long lastnuke;
+extern int lasttext;
extern int handheight;
-extern int boltsleft;
+extern int boltsleft,bolttimer;
+extern short RadarXY[][3];
+
+extern short RotateAngle;
+extern short FreezeTime;
+
+//void FaceDir(short x, short y, boolean StopTime);
+//short CalcAngle(short dx, short dy);
+
+void FaceAngle(short DestAngle);
+void RotateView();
+void InitRotate(short DestAngle);
+short FaceDoor(short x, short y);
+
+char DisplayMsg(char *text,char *choices);
+char DisplaySMsg(char *text,char *choices);
+
+extern statetype s_explode;
+
+void SpawnExplosion(fixed x, fixed y,short Delay);
+void T_ExpThink(objtype *obj);
+void SpawnBigExplosion(fixed x, fixed y, short Delay, fixed Range);
+
/*
=============================================================================
@@ -499,6 +660,11 @@ extern int boltsleft;
=============================================================================
*/
+int EasyHitPoints(int NrmHitPts);
+int EasyDoDamage(int Damage);
+
+extern short zombie_base_delay;
+
extern statetype s_trollouch;
extern statetype s_trolldie1;
@@ -531,3 +697,120 @@ extern statetype s_grelouch;
extern statetype s_greldie1;
extern statetype s_batdie1;
+
+extern statetype s_zombie_death1;
+extern statetype s_zombie_ouch;
+
+extern statetype s_zombie_rise1;
+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_skel_pause;
+extern statetype s_skel_1;
+extern statetype s_skel_2;
+extern statetype s_skel_3;
+extern statetype s_skel_4;
+extern statetype s_skel_attack1;
+extern statetype s_skel_attack2;
+extern statetype s_skel_attack3;
+extern statetype s_skel_ouch;
+extern statetype s_skel_die1;
+extern statetype s_skel_die2;
+extern statetype s_skel_die3;
+
+extern statetype s_wet_pause;
+
+extern statetype s_wet_bubbles1;
+extern statetype s_wet_bubbles2;
+extern statetype s_wet_bubbles3;
+extern statetype s_wet_bubbles4;
+
+extern statetype s_wet_peek;
+
+extern statetype s_wet_rise1;
+extern statetype s_wet_rise2;
+extern statetype s_wet_rise3;
+extern statetype s_wet_rise4;
+extern statetype s_wet_rise5;
+
+extern statetype s_wet_sink1;
+extern statetype s_wet_sink2;
+extern statetype s_wet_sink3;
+
+extern statetype s_wet_walk1;
+extern statetype s_wet_walk2;
+extern statetype s_wet_walk3;
+extern statetype s_wet_walk4;
+
+extern statetype s_wet_attack1;
+extern statetype s_wet_attack2;
+extern statetype s_wet_attack3;
+extern statetype s_wet_attack4;
+
+extern statetype s_wet_ouch;
+
+extern statetype s_wet_die1;
+extern statetype s_wet_die2;
+extern statetype s_wet_die3;
+extern statetype s_wet_die4;
+extern statetype s_wet_die5;
+
+extern statetype s_obj_gate1;
+extern statetype s_obj_gate2;
+extern statetype s_obj_gate3;
+extern statetype s_obj_gate4;
+
+extern statetype s_eye_pause;
+
+extern statetype s_eye_1;
+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;
+
+extern statetype s_eye_die1;
+extern statetype s_eye_die2;
+extern statetype s_eye_die3;
+
+extern statetype s_mshot1;
+extern statetype s_mshot2;
+
+extern statetype s_bonus_die;
+
+extern statetype s_red_demonouch;
+
+extern statetype s_red_demondie1;
diff --git a/GELIB.C b/GELIB.C
new file mode 100644
index 0000000..97de708
--- /dev/null
+++ b/GELIB.C
@@ -0,0 +1,2566 @@
+/* Catacomb Abyss 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 <dos.h>
+#include <conio.h>
+#include <stdio.h>
+#include <dir.h>
+#include "mem.h"
+#include "string.h"
+#include "time.h"
+#include "stdarg.h"
+#include "io.h"
+
+#include "DEF.H"
+#include "gelib.h"
+
+#define MAX_GAMELIST_NAMES 20
+#define FNAME_LEN 9
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Global variables
+//
+boolean InLoadSaveGame = false;
+//AudioDeviceType ge_DigiMode;
+boolean ConserveMemory = false;
+char GameListNames[MAX_GAMELIST_NAMES+1][FNAME_LEN],current_disk=1;
+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)];
+
+
+////////////////////////////////////////////////////////////////////////////
+//
+// CalibrateJoystick()
+//
+void CalibrateJoystick(short joynum)
+{
+ word minx,maxx,
+ miny,maxy;
+
+ IN_ClearKeysDown();
+
+ VW_HideCursor();
+
+ VW_FixRefreshBuffer();
+ CenterWindow(30,8);
+
+ US_Print("\n");
+ US_CPrintLine("Move joystick to the upper-left");
+ US_CPrintLine("and press one of the buttons.");
+ VW_UpdateScreen();
+
+ while ((LastScan != sc_Escape) && !IN_GetJoyButtonsDB(joynum));
+ if (LastScan == sc_Escape)
+ return;
+
+ IN_GetJoyAbs(joynum,&minx,&miny);
+ while (IN_GetJoyButtonsDB(joynum));
+
+ US_Print("\n");
+ US_CPrintLine("Move joystick to the lower-right");
+ US_CPrintLine("and press one of the buttons.");
+ VW_UpdateScreen();
+
+ while ((LastScan != sc_Escape) && !IN_GetJoyButtonsDB(joynum));
+ if (LastScan == sc_Escape)
+ return;
+
+ IN_GetJoyAbs(joynum,&maxx,&maxy);
+ if ((minx == maxx) && (miny == maxy))
+ return;
+
+ IN_SetupJoy(joynum,minx,maxx,miny,maxy);
+
+ while (IN_GetJoyButtonsDB(joynum));
+ if (LastScan)
+ IN_ClearKeysDown();
+
+ JoystickCalibrated = true;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// WaitKeyVBL()
+//
+void WaitKeyVBL(short key, short vbls)
+{
+ while (vbls--)
+ {
+ VW_WaitVBL(1);
+ IN_ReadControl(0,&control);
+ if ((control.button0|control.button1)||(Keyboard[key]))
+ break;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// MoveScreen()
+//
+// panadjust must be saved and restored if MoveScreen is being called from
+// inside a level.
+//
+void MoveScreen(short x, short y)
+{
+ unsigned address;
+
+ address = (y*linewidth)+(x/8);
+ VW_SetScreen(address,0);
+ bufferofs = displayofs = address;
+ panadjust=0;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// MoveGfxDst()
+//
+void MoveGfxDst(short x, short y)
+{
+ unsigned address;
+
+ address = (y*linewidth)+(x/8);
+ bufferofs = displayofs = address;
+}
+
+#if 0
+
+#if GRAPHIC_PIRATE
+
+///////////////////////////////////////////////////////////////////////////
+//
+// DoPiracy() - Graphics piracy code...
+//
+void DoPiracy()
+{
+ struct Shape Pirate1Shp;
+ struct Shape Pirate2Shp;
+
+ VW_SetScreenMode (EGA320GR);
+ VW_ClearVideo(BLACK);
+
+ // Load shapes...
+ //
+ if (LoadShape("PIRATE1E."EXT,&Pirate1Shp))
+ TrashProg("Can't load PIRATE1E.BIO");
+
+ if (LoadShape("PIRATE2E."EXT,&Pirate2Shp))
+ TrashProg("Can't load PIRATE2E.BIO");
+
+ // Deal with shapes...
+ //
+ VW_SetLineWidth(40);
+
+ VW_FadeOut();
+
+ MoveScreen(0,0);
+ UnpackEGAShapeToScreen(&Pirate1Shp,(linewidth-Pirate1Shp.BPR)<<2,0);
+
+ MoveScreen(0,200);
+ UnpackEGAShapeToScreen(&Pirate2Shp,(linewidth-Pirate2Shp.BPR)<<2,0);
+
+ MoveScreen(0,0);
+ VW_FadeIn();
+ WaitKeyVBL(57,200);
+ while (Keyboard[57]);
+
+ SD_PlaySound(GOOD_PICKSND);
+
+ MoveScreen(0,200);
+ WaitKeyVBL(57,300);
+ while (Keyboard[57]);
+ VW_FadeOut();
+
+ FreeShape(&Pirate1Shp);
+ FreeShape(&Pirate2Shp);
+}
+
+#else
+
+///////////////////////////////////////////////////////////////////////////
+//
+// DoPiracy() - Text-based piracy code...
+//
+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()
+//--------------------------------------------------------------------------
+void BlackPalette()
+{
+ extern char colors[7][17];
+
+ _ES=FP_SEG(&colors[0]);
+ _DX=FP_OFF(&colors[0]);
+ _AX=0x1002;
+ geninterrupt(0x10);
+ screenfaded = true;
+}
+
+//--------------------------------------------------------------------------
+// ColoredPalette()
+//--------------------------------------------------------------------------
+void ColoredPalette()
+{
+ extern char colors[7][17];
+
+ _ES=FP_SEG(&colors[3]);
+ _DX=FP_OFF(&colors[3]);
+ _AX=0x1002;
+ geninterrupt(0x10);
+ screenfaded = false;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Verify()
+//
+long Verify(char *filename)
+{
+ int handle;
+ long size;
+
+ if ((handle=open(filename,O_BINARY))==-1)
+ return (0);
+ size=filelength(handle);
+ close(handle);
+ return(size);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// GE_SaveGame
+//
+// Handles user i/o for saving a game
+//
+///////////////////////////////////////////////////////////////////////////
+
+void GE_SaveGame()
+{
+ boolean GettingFilename=true;
+ char drive;
+// char Filename[FILENAME_LEN+1],drive; //, ID[sizeof(GAMENAME)], VER[sizeof(SAVEVER_DATA)];
+ int handle;
+ struct dfree dfree;
+ long davail;
+
+ VW_FixRefreshBuffer();
+ ReadGameList();
+ while (GettingFilename)
+ {
+ DisplayGameList(2,7,3,10);
+ US_DrawWindow(5,1,30,3);
+ memset(Filename,0,sizeof(Filename));
+ US_CPrint("Enter name to SAVE this game:");
+ VW_UpdateScreen();
+ if (screenfaded)
+ VW_FadeIn();
+ if (!US_LineInput((linewidth<<2)-32,20,Filename,"",true,8,0))
+ goto EXIT_FUNC;
+ if (!strlen(Filename))
+ goto EXIT_FUNC;
+
+ drive = getdisk();
+ getdfree(drive+1,&dfree);
+ davail = (long)dfree.df_avail*(long)dfree.df_bsec*(long)dfree.df_sclus;
+
+ if (davail < 10000l)
+ {
+ char status[40] = "\nDrive: Free: ";
+
+ US_CenterWindow(30,6);
+ 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();
+ }
+ else
+ {
+ strcat(Filename,".SAV");
+ GettingFilename = false;
+ if (Verify(Filename)) // FILE EXISTS
+ {
+ US_CenterWindow(22,4);
+ US_CPrintLine("That file already exists...");
+ US_CPrintLine("Overwrite it ????");
+ US_CPrintLine("(Y)es or (N)o?");
+ VW_UpdateScreen();
+
+ while((!Keyboard[21]) && (!Keyboard[49]) && !Keyboard[27]);
+
+ if (Keyboard[27])
+ goto EXIT_FUNC;
+ if (Keyboard[49])
+ {
+ GettingFilename = true;
+ VW_UpdateScreen();
+ }
+ }
+ }
+ }
+
+ handle = open(Filename,O_RDWR|O_CREAT|O_BINARY,S_IREAD|S_IWRITE);
+ if (handle==-1)
+ goto EXIT_FUNC;
+
+ if ((!CA_FarWrite(handle,(void far *)GAMENAME,sizeof(GAMENAME))) || (!CA_FarWrite(handle,(void far *)SAVEVER_DATA,sizeof(SAVEVER_DATA))))
+ {
+ if (!screenfaded)
+ VW_FadeOut();
+
+ return;
+ }
+
+ if (!USL_SaveGame(handle))
+ Quit("Save game error");
+
+
+
+EXIT_FUNC:;
+
+ if (handle!=-1)
+ close(handle);
+
+ if (handle==-1)
+ {
+ remove(Filename);
+ US_CenterWindow(22,6);
+ US_CPrintLine("DISK ERROR");
+ US_CPrintLine("Check: Write protect...");
+ US_CPrintLine("File name...");
+ US_CPrintLine("Bytes free on disk...");
+ US_CPrintLine("Press SPACE to continue.");
+ VW_UpdateScreen();
+ while (!Keyboard[57]);
+ while (Keyboard[57]);
+ }
+
+ while (Keyboard[1]);
+
+ if (!screenfaded)
+ VW_FadeOut();
+}
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// GE_LoadGame
+//
+// Handles user i/o for loading a game
+//
+///////////////////////////////////////////////////////////////////////////
+
+boolean GE_LoadGame()
+{
+ boolean GettingFilename=true,rt_code=false;
+ int handle;
+
+ IN_ClearKeysDown();
+ memset(ID,0,sizeof(ID));
+ memset(VER,0,sizeof(VER));
+ VW_FixRefreshBuffer();
+ ReadGameList();
+ while (GettingFilename)
+ {
+ DisplayGameList(2,7,3,10);
+ US_DrawWindow(5,1,30,3);
+ memset(Filename,0,sizeof(Filename));
+ US_CPrint("Enter name of game to RESTORE:");
+ VW_UpdateScreen();
+ if (screenfaded)
+ VW_FadeIn();
+ if (!US_LineInput((linewidth<<2)-32,20,Filename,"",true,8,0))
+ goto EXIT_FUNC;
+ strcat(Filename,".SAV");
+ GettingFilename = false;
+
+ if (!Verify(Filename)) // FILE DOESN'T EXIST
+ {
+ US_CenterWindow(22,3);
+ US_CPrintLine(" That file doesn't exist....");
+ US_CPrintLine("Press SPACE to try again.");
+ VW_UpdateScreen();
+
+ while (!Keyboard[57]);
+ while (Keyboard[57]);
+ GettingFilename = true;
+ }
+ }
+
+ handle = open(Filename,O_RDWR|O_BINARY);
+ if (handle==-1)
+ goto EXIT_FUNC;
+
+ if ((!CA_FarRead(handle,(void far *)&ID,sizeof(ID))) || (!CA_FarRead(handle,(void far *)&VER,sizeof(VER))))
+ return(false);
+
+ if ((strcmp(ID,GAMENAME)) || (strcmp(VER,SAVEVER_DATA)))
+ {
+ US_CenterWindow(32,4);
+ US_CPrintLine("That isn't a "GAMENAME);
+ US_CPrintLine(".SAV file.");
+ US_CPrintLine("Press SPACE to continue.");
+ VW_UpdateScreen();
+ while (!Keyboard[57]);
+ while (Keyboard[57]);
+
+ if (!screenfaded)
+ VW_FadeOut();
+
+ return(false);
+ }
+
+ if (!USL_LoadGame(handle))
+ Quit("Load game error.");
+
+ rt_code = true;
+
+
+EXIT_FUNC:;
+ if (handle==-1)
+ {
+ US_CenterWindow(22,3);
+ US_CPrintLine("DISK ERROR ** LOAD **");
+ US_CPrintLine("Press SPACE to continue.");
+ while (!Keyboard[57]);
+ while (Keyboard[57]);
+ }
+ else
+ close(handle);
+
+ if (!screenfaded)
+ VW_FadeOut();
+
+ return(rt_code);
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// GE_HardError() - Handles the Abort/Retry/Fail sort of errors passed
+// from DOS. Hard coded to ignore if during Load/Save Game.
+//
+///////////////////////////////////////////////////////////////////////////
+#pragma warn -par
+#pragma warn -rch
+int GE_HardError(word errval,int ax,int bp,int si)
+{
+#define IGNORE 0
+#define RETRY 1
+#define ABORT 2
+extern void ShutdownId(void);
+
+static char buf[32];
+static WindowRec wr;
+static boolean oldleavedriveon;
+ int di;
+ char c,*s,*t;
+boolean holdscreenfaded;
+
+ if (InLoadSaveGame)
+ hardresume(IGNORE);
+
+
+ di = _DI;
+
+ oldleavedriveon = LeaveDriveOn;
+ LeaveDriveOn = false;
+
+ if (ax < 0)
+ s = "Device Error";
+ else
+ {
+ if ((di & 0x00ff) == 0)
+ s = "Drive ~ is Write Protected";
+ else
+ s = "Error on Drive ~";
+ for (t = buf;*s;s++,t++) // Can't use sprintf()
+ if ((*t = *s) == '~')
+ *t = (ax & 0x00ff) + 'A';
+ *t = '\0';
+ s = buf;
+ }
+
+ c = peekb(0x40,0x49); // Get the current screen mode
+ if ((c < 4) || (c == 7))
+ goto oh_kill_me;
+
+ // DEBUG - handle screen cleanup
+ holdscreenfaded=screenfaded;
+
+ US_SaveWindow(&wr);
+ VW_ClearVideo(0); ////////////// added for exiting
+ US_CenterWindow(30,3);
+ US_CPrint(s);
+ US_CPrint("(R)etry or (A)bort?");
+ VW_UpdateScreen();
+ if (holdscreenfaded)
+ VW_FadeIn();
+ IN_ClearKeysDown();
+
+asm sti // Let the keyboard interrupts come through
+
+ while (true)
+ {
+ switch (IN_WaitForASCII())
+ {
+ case key_Escape:
+ case 'a':
+ case 'A':
+ goto oh_kill_me;
+ break;
+ case key_Return:
+ case key_Space:
+ case 'r':
+ case 'R':
+ if (holdscreenfaded)
+ VW_FadeOut();
+ US_ClearWindow();
+ VW_UpdateScreen();
+ US_RestoreWindow(&wr);
+ LeaveDriveOn = oldleavedriveon;
+ return(RETRY);
+ break;
+ }
+ }
+
+oh_kill_me:
+ abortprogram = s;
+ TrashProg("Terminal Error: %s\n",s);
+// if (tedlevel)
+// fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");
+
+ return(ABORT);
+#undef IGNORE
+#undef RETRY
+#undef ABORT
+}
+#pragma warn +par
+#pragma warn +rch
+
+//--------------------------------------------------------------------------
+//
+//
+// B O B ROUTINES
+//
+//
+//--------------------------------------------------------------------------
+
+
+
+#ifdef BOBLIST
+
+////////////////////////////////////////////////////////////////////////////
+//
+// UpdateBOBList() - Adds a sprite to an objects BOBlist. The BOB List
+// must already be allocated and have an available slot.
+//
+// RETURNS : true = Success adding Sprite / false = Failure.
+//
+// NOTE : This also sets the users 'needtoreact' flag to true.
+//
+boolean UpdateBOBList(objtype *obj,struct Simple_Shape *Shape,shapeclass Class, short priority, spriteflags sprflags)
+{
+ struct BOB_Shape *CurBOBShape = NULL;
+
+#pragma warn -pia
+
+ if (CurBOBShape = obj->nextshape)
+ {
+ // Treverse down BOBList looking for a sprite with the same class
+ // OR an empty shape struct to store the new shape.
+
+ while ((CurBOBShape->class != Class) && (CurBOBShape->class) && CurBOBShape)
+ {
+ CurBOBShape = CurBOBShape->nextshape;
+ }
+
+ if (CurBOBShape)
+ {
+ RF_RemoveSprite(&CurBOBShape->sprite);
+ CurBOBShape->shapenum = Shape->shapenum;
+ CurBOBShape->x_offset = Shape->x_offset;
+ CurBOBShape->y_offset = Shape->y_offset;
+ CurBOBShape->priority = priority;
+ CurBOBShape->sprflags = sprflags;
+ CurBOBShape->class = Class;
+ return(true);
+ }
+ }
+ return(false);
+
+#pragma warn +pia
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RemoveBOBShape() - Removes a sprite from a BOBList.
+//
+// RETURNS : true = Success / false = Failure (shape not found)
+//
+boolean RemoveBOBShape(objtype *obj, shapeclass Class)
+{
+ struct BOB_Shape *CurBOBShape = NULL;
+
+#pragma warn -pia
+
+ if (CurBOBShape = obj->nextshape)
+ {
+ while ((CurBOBShape->class != Class) && (!CurBOBShape->class) && CurBOBShape)
+ {
+ CurBOBShape = CurBOBShape->nextshape;
+ }
+
+ if (CurBOBShape)
+ {
+ CurBOBShape->class = noshape;
+ return(true);
+ }
+ }
+ return(false);
+
+#pragma warn +pia
+
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RemoveBOBList() - Removes an entire BOBList attached to an object.
+//
+//
+void RemoveBOBList(objtype *obj)
+{
+ struct BOB_Shape *CurBOBShape;
+
+#pragma warn -pia
+
+ if (CurBOBShape = obj->nextshape)
+ {
+ // Treverse down BOBList looking for a sprite with the same class
+ // OR an empty shape struct to store the new shape.
+
+ while (CurBOBShape)
+ {
+ if (CurBOBShape->class)
+ {
+ CurBOBShape->class = noshape;
+ RF_RemoveSprite (&CurBOBShape->sprite);
+ }
+ CurBOBShape = CurBOBShape->nextshape;
+ }
+ }
+
+#pragma warn +pia
+
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// InitBOBList() -- This initializes a BOB list for all the possible shapes
+// attached at one time. This is done with an array of
+// BOB_Shape structs and links the 'nextshape' pointer to
+// to the next element.
+//
+//
+void InitBOBList(objtype *obj, struct BOB_Shape *BOB_Shape, short NumElements)
+{
+ struct BOB_Shape *CurShape;
+ short loop;
+
+ obj->nextshape = BOB_Shape;
+
+ for (loop=1;loop<NumElements;loop++)
+ {
+ CurShape = BOB_Shape++;
+ CurShape->nextshape = BOB_Shape;
+ }
+
+ BOB_Shape->nextshape = NULL;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+//
+// RefreshBOBList() -- This routine updates all sprites attached to the
+// BOBList and refreshes there position in the sprite
+// list.
+//
+void RefreshBOBList(objtype *obj)
+{
+ struct BOB_Shape *Shape;
+
+ Shape = obj->nextshape;
+
+ while (Shape)
+ {
+ if (Shape->class)
+ RF_PlaceSprite(&Shape->sprite,obj->x+Shape->x_offset,obj->y+Shape->y_offset, Shape->shapenum, spritedraw,Shape->priority,Shape->sprflags);
+ Shape = Shape->nextshape;
+ }
+}
+#endif
+
+
+
+
+
+
+
+
+
+
+//==========================================================================
+// 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()
+//--------------------------------------------------------------------------
+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;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// SwapLong()
+//
+void SwapLong(long far *Var)
+{
+ asm les bx,Var
+ asm mov ax,[es:bx]
+ asm xchg ah,al
+ asm xchg ax,[es:bx+2]
+ asm xchg ah,al
+ asm mov [es:bx],ax
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// SwapWord()
+//
+void SwapWord(unsigned int far *Var)
+{
+ asm les bx,Var
+ asm mov ax,[es:bx]
+ asm xchg ah,al
+ asm mov [es:bx],ax
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// LoadShape()
+//
+int LoadShape(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;
+// struct ffblk ffblk;
+ 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 (!(FileLen = BLoad(Filename,&IFFfile)))
+ TrashProg("Can't load Compressed Shape - Possibly corrupt file!");
+
+ // 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);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+//
+// FreeShape()
+//
+void FreeShape(struct Shape *shape)
+{
+ if (shape->Data)
+ MM_FreePtr(&shape->Data);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// UnpackEGAShapeToScreen()
+//
+int UnpackEGAShapeToScreen(struct Shape *SHP,int startx,int starty)
+{
+ int currenty;
+ signed char n, Rep, far *Src, far *Dst[8], loop, Plane;
+ unsigned int BPR, Height;
+ boolean NotWordAligned;
+
+ NotWordAligned = SHP->BPR & 1;
+ startx>>=3;
+ Src = MK_FP(SHP->Data,0);
+ currenty = starty;
+ Plane = 0;
+ Height = SHP->bmHdr.h;
+ while (Height--)
+ {
+ Dst[0] = (MK_FP(0xA000,displayofs));
+ Dst[0] += ylookup[currenty];
+ Dst[0] += startx;
+ for (loop=1; loop<SHP->bmHdr.d; loop++)
+ Dst[loop] = Dst[0];
+
+
+ for (Plane=0; Plane<SHP->bmHdr.d; Plane++)
+ {
+ outport(0x3c4,((1<<Plane)<<8)|2);
+
+ BPR = ((SHP->BPR+1) >> 1) << 1; // IGNORE WORD ALIGN
+ while (BPR)
+ {
+ if (SHP->bmHdr.comp)
+ n = *Src++;
+ else
+ n = BPR-1;
+
+ if (n < 0)
+ {
+ if (n != -128)
+ {
+ n = (-n)+1;
+ BPR -= n;
+ Rep = *Src++;
+ if ((!BPR) && (NotWordAligned)) // IGNORE WORD ALIGN
+ n--;
+
+ while (n--)
+ *Dst[Plane]++ = Rep;
+ }
+ else
+ BPR--;
+ }
+ else
+ {
+ n++;
+ BPR -= n;
+ if ((!BPR) && (NotWordAligned)) // IGNORE WORD ALIGN
+ n--;
+
+ while (n--)
+ *Dst[Plane]++ = *Src++;
+
+ if ((!BPR) && (NotWordAligned)) // IGNORE WORD ALIGN
+ Src++;
+ }
+ }
+ }
+ currenty++;
+ }
+
+ return(0);
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// GetKeyChoice()
+//
+char GetKeyChoice(char *choices,boolean clear)
+{
+ extern void DoEvents(void);
+
+ boolean waiting;
+ char *s,*ss;
+
+ IN_ClearKeysDown();
+
+ waiting = true;
+ while (waiting)
+ {
+ s = choices;
+ while (*s)
+ {
+ if (Keyboard[*s++])
+ {
+ waiting=false;
+ break;
+ }
+ }
+ }
+
+ IN_ClearKeysDown();
+
+ return(*(--s));
+}
+
+#if 0
+
+////////////////////////////////////////////////////////////////////////////
+//
+// AnimateObj()
+//
+boolean AnimateObj(objtype *obj)
+{
+ boolean Done;
+
+ Done = false;
+
+ if (obj->animtype == at_NONE) // Animation finished?
+ return(true); // YEP!
+
+ if (obj->animdelay) // Check animation delay.
+ {
+ obj->animdelay -= tics;
+ if (obj->animdelay < 0)
+ obj->animdelay = 0;
+ return(false);
+ }
+
+ switch (obj->animtype) // Animate this object!
+ {
+ case at_ONCE:
+ case at_CYCLE:
+ switch (obj->animdir)
+ {
+ case at_FWD:
+ if (obj->curframe < obj->maxframe)
+ AdvanceAnimFWD(obj);
+ else
+ if (obj->animtype == at_CYCLE)
+ {
+ obj->curframe = 0; // RESET CYCLE ANIMATION
+ obj->animdelay=1;
+ }
+ else
+ {
+ obj->animtype = at_NONE; // TERMINATE ONCE ANIM
+ Done = true;
+ }
+ break;
+
+ case at_REV:
+ if (obj->curframe > 0)
+ AdvanceAnimREV(obj);
+ else
+ if (obj->animtype == at_CYCLE)
+ {
+ obj->curframe = obj->maxframe; // RESET CYCLE ANIMATION
+ obj->animdelay = 1;
+ }
+ else
+ {
+ obj->animtype = at_NONE; // TERMINATE ONCE ANIM
+ Done = true;
+ }
+ break; // REV
+ }
+ break;
+
+ case at_REBOUND:
+ switch (obj->animdir)
+ {
+ case at_FWD:
+ if (obj->curframe < obj->maxframe)
+ AdvanceAnimFWD(obj);
+ else
+ {
+ obj->animdir = at_REV;
+ obj->animdelay = 1;
+ }
+ break;
+
+ case at_REV:
+ if (obj->curframe > 0)
+ AdvanceAnimREV(obj);
+ else
+ {
+ obj->animdir = at_FWD;
+ obj->animdelay = 1;
+ Done = true;
+ }
+ break;
+ }
+ break; /* REBOUND */
+
+ case at_WAIT:
+ Done = true;
+ break;
+ }
+
+ return(Done);
+}
+
+void AdvanceAnimFWD(objtype *obj) // Advances a Frame of ANIM for ONCE,CYCLE, REBOUND
+{
+ obj->curframe++; // INC frames
+ obj->animdelay = obj->maxdelay; // Init Delay Counter.
+ obj->needtoreact = true;
+}
+
+
+void AdvanceAnimREV(objtype *obj) // Advances a Frame of ANIM for ONCE,CYCLE, REBOUND
+{
+ obj->curframe--; // DEC frames
+ obj->animdelay = obj->maxdelay; // Init Delay Counter.
+ obj->needtoreact = true;
+}
+#endif
+
+#if 0
+///////////////////////////////////////////////////////////////////////////
+//
+// LoadASArray() - Load an array of audio samples in FAR memory.
+//
+void LoadASArray(struct Sample *ASArray)
+{
+ int loop = 0;
+
+ while (ASArray[loop].filename)
+ {
+ if (!BLoad(ASArray[loop].filename,(memptr *)&ASArray[loop].data))
+ TrashProg("Unable to load sample in LoadASArray()");
+ loop++;
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+//
+// FreeASArray() - Frees an ASArray from memory that has been loaded with
+// LoadASArray()
+//
+void FreeASArray(struct Sample *ASArray)
+{
+ unsigned loop = 0;
+
+ while (ASArray[loop].data)
+ {
+ MM_SetPurge((memptr *)&ASArray[loop++].data,3);
+ MM_FreePtr((memptr *)&ASArray[loop++].data);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////
+//
+// GE_LoadAllDigiSounds() - This is a hook that CA_LoadAllSounds()
+// calls to load all of the Digitized sounds for
+// Sound Blaster & Sound Source.
+//
+// NOTE : This stub would do any other necessary routines for DigiSounds
+// specific to GAMERS EDGE code. (Keeping seperate from ID's)
+//
+void GE_LoadAllDigiSounds()
+{
+ LoadASArray(DigiSounds);
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////
+//
+// GE_FreeAllDigiSounds() -- This is a hook that CA_LoadAllSounds()
+// calls to free all digitized sounds for
+// which ever hardware and allow for any necessary
+// clean up.
+//
+//
+// NOTE : This stub would do any other necessary routines for DigiSounds
+// specific to GAMERS EDGE code. (Keeping seperate from ID's)
+//
+void GE_FreeAllDigiSounds()
+{
+ FreeASArray(DigiSounds);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// GE_LoadAllSounds() - Loads ALL sounds needed for detected hardware.
+//
+void GE_LoadAllSounds()
+{
+ unsigned i,start;
+
+ start = STARTPCSOUNDS;
+ for (i=0;i<NUMSOUNDS;i++,start++)
+ CA_CacheAudioChunk (start);
+
+ if (AdLibPresent)
+ {
+ start = STARTADLIBSOUNDS;
+ for (i=0;i<NUMSOUNDS;i++,start++)
+ CA_CacheAudioChunk (start);
+ }
+
+ if (SoundBlasterPresent)
+ LoadASArray(DigiSounds);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//
+// GE_PurgeAllSounds() - Frees all sounds that were loaded.
+//
+void GE_PurgeAllSounds()
+{
+ unsigned start,i;
+
+ start = STARTPCSOUNDS;
+ for (i=0;i<NUMSOUNDS;i++,start++)
+ if (audiosegs[start])
+ MM_SetPurge (&(memptr)audiosegs[start],3); // make purgable
+
+
+ if (AdLibPresent)
+ {
+ start = STARTADLIBSOUNDS;
+ for (i=0;i<NUMSOUNDS;i++,start++)
+ if (audiosegs[start])
+ MM_SetPurge (&(memptr)audiosegs[start],3); // make purgable
+ }
+
+ if (SoundBlasterPresent)
+ GE_FreeAllDigiSounds();
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// PlaySample() -- Plays a DIGITIZED sample using SoundBlaster OR SoundSource
+//
+// PARAMETERS : Sample Number (Corresponding to ASArray "DigiSounds[]".
+//
+void PlaySample(unsigned SampleNum)
+{
+
+ if (!DigiSounds[SampleNum].data)
+ TrashProg("PlaySample - Trying to play an unloaded digi sound!");
+
+
+ switch (SoundMode) // external variable in ID_SD for sound mode..
+ {
+ case sdm_SoundBlaster:
+ case sdm_SoundBlasterAdLib:
+ SDL_SBPlaySample(MK_FP(DigiSounds[SampleNum].data,0));
+ break;
+
+ default:
+ TrashProg("PlaySample() - incorrect SoundMode for PlaySample()");
+ break;
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// SelectDigiAudio() -- This routine intergrates multi sound hardware with
+// id's routines.
+//
+void SelectDigiAudio(AudioDeviceType Device)
+{
+ switch (Device)
+ {
+ case ged_SoundSource:
+ case ged_SoundBlaster:
+ break;
+ }
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+//
+// DisplayGameList()
+//
+void DisplayGameList(short winx, short winy, short list_width, short list_height)
+{
+ #define SPACES 2
+
+ short width,col,row,orgcol,games_printed=0,h;
+
+ // Possibly shrink window.
+ //
+ h = (NumGames / list_width) + ((NumGames % list_width) > 0);
+ if (h < list_height)
+ list_height = h;
+
+ // Open window and print header...
+ //
+ US_DrawWindow(winx,winy,list_width*(8+SPACES*2),list_height+3);
+ US_CPrintLine("LIST OF SAVED GAMES");
+ US_Print("\n");
+
+ col = orgcol = PrintX;
+ row = PrintY;
+
+ // Display as many 'save game' files as can fit in the window.
+ //
+ width = list_width;
+ while ((games_printed<NumGames) && (list_height))
+ {
+ // Print filename and padding spaces.
+ //
+ US_Printxy(col+(SPACES*8),row,GameListNames[games_printed]);
+ col += 8*((SPACES*2)+8);
+
+ // Check for end-of-line or end-of-window.
+ //
+ width--;
+ if (!width)
+ {
+ col = orgcol;
+ row += 8;
+ width = list_width;
+ list_height--;
+ US_Print("\n");
+ }
+
+ games_printed++;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// ReadGameList()
+//
+void ReadGameList()
+{
+ struct ffblk ffblk;
+ short done,len;
+
+ NumGames = -1;
+ done = findfirst("*.sav",&ffblk,0);
+
+ while (!done)
+ {
+ if (NumGames == MAX_GAMELIST_NAMES)
+ memcpy(GameListNames,GameListNames[1],MAX_GAMELIST_NAMES*sizeof(GameListNames[0]));
+ else
+ NumGames++;
+
+ fnsplit(ffblk.ff_name,NULL,NULL,GameListNames[NumGames],NULL);
+
+ done=findnext(&ffblk);
+ }
+
+ 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
+////////////////////////////////////////////////////////////////////////////
+//
+// CenterObj()
+//
+void CenterObj(objtype *obj, unsigned x, unsigned y)
+{
+ spritetabletype far *sprite;
+ unsigned width, height;
+
+ sprite=&spritetable[obj->baseshape+obj->curframe-STARTSPRITES];
+
+ width = (sprite->xh-sprite->xl+(1<<G_P_SHIFT)) >> 1;
+ if (obj->sprflags&sf_vertflip)
+ {
+ height = (sprite->yl-(sprite->height<<G_P_SHIFT) + sprite->yh+(1<<G_P_SHIFT)) >> 1;
+ }
+ else
+ height = (sprite->yh-sprite->yl+(1<<G_P_SHIFT)) >> 1;
+
+ obj->x = x-width;
+ obj->y = y-height;
+}
+#endif
+
+//-------------------------------------------------------------------------
+// cacheout()
+//-------------------------------------------------------------------------
+void cacheout(short s,short e)
+{
+ short i;
+
+ for(i=(s);i<=(e);i++)
+ {
+ grneeded[i]&=~ca_levelbit;
+ if (grsegs[i])
+ MM_SetPurge(&grsegs[i],3);
+ }
+
+}
+
+//-------------------------------------------------------------------------
+// cachein()
+//-------------------------------------------------------------------------
+void cachein(short s,short e)
+{
+ short i;
+
+ for(i=(s);i<=(e);i++)
+ {
+ CA_MarkGrChunk(i);
+ if (grsegs[i])
+ MM_SetPurge(&grsegs[i],0);
+ }
+}
+
+#if 0
+////////////////////////////////////////////////////////////////////////////
+//
+// SetUpdateBlock()
+//
+void SetUpdateBlock(unsigned x,unsigned y,unsigned width,unsigned height,char refresh)
+{
+ eraseblocktype *erase;
+
+#if 0 //SP unsure if this is needed
+ x = (x+((MAPBORDER+MAPXLEFTOFFSET)<<4))>>3;
+ y += ((MAPBORDER+MAPYTOPOFFSET)<<4);
+#else
+ x = (x+(MAPBORDER<<4))>>3;
+ y += (MAPBORDER<<4);
+#endif
+ width >>= 3;
+
+ if (refresh & 1)
+ {
+ erase = eraselistptr[0]++;
+ erase->screenx=x;
+ erase->screeny=y;
+ erase->width=width;
+ erase->height=height;
+ }
+
+ if (refresh & 2)
+ {
+ erase = eraselistptr[1]++;
+ erase->screenx=x;
+ erase->screeny=y;
+ erase->width=width;
+ erase->height=height;
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+//
+// ObjHeight
+//
+unsigned ObjHeight(objtype *obj)
+{
+ spritetabletype far *sprite;
+
+ sprite=&spritetable[obj->baseshape+obj->curframe-STARTSPRITES];
+
+ if (obj->sprflags&sf_vertflip)
+ {
+ return((sprite->yl-(sprite->height<<G_P_SHIFT) + sprite->yh+(1<<G_P_SHIFT)) >> 1);
+ }
+ else
+ return((sprite->yh-sprite->yl+(1<<G_P_SHIFT)) >> 1);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+//
+// ObjWidth
+//
+unsigned ObjWidth(objtype *obj)
+{
+ spritetabletype far *sprite;
+
+ sprite=&spritetable[obj->baseshape+obj->curframe-STARTSPRITES];
+
+ return((sprite->xh-sprite->xl+(1<<G_P_SHIFT)) >> 1);
+}
+#endif
+
+#if 0
+//--------------------------------------------------------------------------
+// visible_on()
+//--------------------------------------------------------------------------
+boolean visible_on(objtype *obj)
+{
+ if (!(obj->flags & of_visible))
+ {
+ obj->needtoreact=true;
+ obj->flags |= of_visible;
+ return(true);
+ }
+
+ return(false);
+}
+
+//--------------------------------------------------------------------------
+// visible_off()
+//--------------------------------------------------------------------------
+boolean visible_off(objtype *obj)
+{
+ if (obj->flags & of_visible)
+ {
+ obj->needtoreact=true;
+ obj->flags &= ~of_visible;
+ return(true);
+ }
+
+ return(false);
+}
+#endif
+
+
+/*
+===================
+=
+= FizzleFade
+=
+===================
+*/
+
+#define PIXPERFRAME 10000 //1600
+
+void FizzleFade (unsigned source, unsigned dest,
+ unsigned width,unsigned height, boolean abortable)
+{
+ unsigned drawofs,pagedelta;
+ unsigned char maskb[8] = {1,2,4,8,16,32,64,128};
+ unsigned x,y,p,frame;
+ long rndval;
+ ScanCode lastLastScan=LastScan=0;
+
+ width--;
+ height--;
+
+ pagedelta = dest-source;
+// VW_SetScreen (dest,0);
+ rndval = 1;
+ y = 0;
+
+asm mov es,[screenseg]
+asm mov dx,SC_INDEX
+asm mov al,SC_MAPMASK
+asm out dx,al
+
+ TimeCount=frame=0;
+ do // while (1)
+ {
+ if ((abortable) || (Flags & FL_QUICK))
+ {
+ IN_ReadControl(0,&control);
+ if (control.button0 || control.button1 || (lastLastScan != LastScan)
+ || Keyboard[sc_Escape] || (Flags & FL_QUICK))
+ {
+ VW_ScreenToScreen (source,dest,(width+1)/8,height+1);
+ goto exitfunc;
+ }
+ }
+
+ for (p=0;p<PIXPERFRAME;p++)
+ {
+ //
+ // seperate random value into x/y pair
+ //
+ asm mov ax,[WORD PTR rndval]
+ asm mov dx,[WORD PTR rndval+2]
+ asm mov bx,ax
+ asm dec bl
+ asm mov [BYTE PTR y],bl // low 8 bits - 1 = y xoordinate
+ asm mov bx,ax
+ asm mov cx,dx
+ asm shr cx,1
+ asm rcr bx,1
+ asm shr bx,1
+ asm shr bx,1
+ asm shr bx,1
+ asm shr bx,1
+ asm shr bx,1
+ asm shr bx,1
+ asm shr bx,1
+ asm mov [x],bx // next 9 bits = x xoordinate
+ //
+ // advance to next random element
+ //
+ asm shr dx,1
+ asm rcr ax,1
+ asm jnc noxor
+ asm xor dx,0x0001
+ asm xor ax,0x2000
+noxor:
+ asm mov [WORD PTR rndval],ax
+ asm mov [WORD PTR rndval+2],dx
+
+ if (x>width || y>height)
+ continue;
+ drawofs = source+ylookup[y];
+
+ asm mov cx,[x]
+ asm mov si,cx
+ asm and si,7
+ asm mov dx,GC_INDEX
+ asm mov al,GC_BITMASK
+ asm mov ah,BYTE PTR [maskb+si]
+ asm out dx,ax
+
+ asm mov si,[drawofs]
+ asm shr cx,1
+ asm shr cx,1
+ asm shr cx,1
+ asm add si,cx
+ asm mov di,si
+ asm add di,[pagedelta]
+
+ asm mov dx,GC_INDEX
+ asm mov al,GC_READMAP // leave GC_INDEX set to READMAP
+ asm out dx,al
+
+ asm mov dx,SC_INDEX+1
+ asm mov al,1
+ asm out dx,al
+ asm mov dx,GC_INDEX+1
+ asm mov al,0
+ asm out dx,al
+
+ asm mov bl,[es:si]
+ asm xchg [es:di],bl
+
+ asm mov dx,SC_INDEX+1
+ asm mov al,2
+ asm out dx,al
+ asm mov dx,GC_INDEX+1
+ asm mov al,1
+ asm out dx,al
+
+ asm mov bl,[es:si]
+ asm xchg [es:di],bl
+
+ asm mov dx,SC_INDEX+1
+ asm mov al,4
+ asm out dx,al
+ asm mov dx,GC_INDEX+1
+ asm mov al,2
+ asm out dx,al
+
+ asm mov bl,[es:si]
+ asm xchg [es:di],bl
+
+ asm mov dx,SC_INDEX+1
+ asm mov al,8
+ asm out dx,al
+ asm mov dx,GC_INDEX+1
+ asm mov al,3
+ asm out dx,al
+
+ asm mov bl,[es:si]
+ asm xchg [es:di],bl
+
+ if (rndval == 1) // entire sequence has been completed
+ goto exitfunc;
+ }
+ frame++;
+// while (TimeCount<frame) // don't go too fast
+// ;
+ } while (1);
+
+exitfunc:;
+ EGABITMASK(255);
+ EGAMAPMASK(15);
+ return;
+}
+
+//-------------------------------------------------------------------------
+// mprintf()
+//-------------------------------------------------------------------------
+void mprintf(char *msg, ...)
+{
+ static char x=0;
+ static char y=0;
+ static char far *video = MK_FP(0xb000,0x0000);
+ char buffer[100],*ptr;
+
+ va_list(ap);
+
+ va_start(ap,msg);
+
+ vsprintf(buffer,msg,ap);
+
+ ptr = buffer;
+ while (*ptr)
+ {
+ switch (*ptr)
+ {
+ case '\n':
+ if (y >= 23)
+ {
+ video -= (x<<1);
+ _fmemcpy(MK_FP(0xb000,0x0000),MK_FP(0xb000,0x00a0),3840);
+ }
+ else
+ {
+ y++;
+ video += ((80-x)<<1);
+ }
+ x=0;
+ break;
+
+ default:
+ *video = *ptr;
+ video[1] = 15;
+ video += 2;
+ x++;
+ break;
+ }
+ ptr++;
+ }
+
+ va_end(ap);
+}
+
+#if 0
+
+//--------------------------------------------------------------------------
+// FULL SCREEN REFRESH/ANIM MANAGERS
+//--------------------------------------------------------------------------
+
+///////////////////////////////////////////////////////////////////////////
+//
+// InitLatchRefresh() -- Loads an ILBM (JAMPAK'd) into the Master Latch
+// to be used as the background refresh screen...
+//
+void InitLatchRefresh(char *filename)
+{
+ struct Shape RefreshShp;
+ short yofs;
+
+ VW_ClearVideo(0);
+
+ if (LoadShape(filename,&RefreshShp))
+ TrashProg("Can't load %s",filename);
+
+ VW_SetLineWidth(RefreshShp.BPR);
+
+ yofs = masterswap/SCREENWIDTH;
+ MoveGfxDst(0,yofs); // Handle title screen
+ UnpackEGAShapeToScreen(&RefreshShp,0,0);
+ FreeShape(&RefreshShp);
+
+ MoveScreen(0,0);
+ VW_InitDoubleBuffer();
+
+ RF_NewPosition(0,0);
+
+ RF_Refresh();
+
+ SetUpdateBlock(0,0,RefreshShp.bmHdr.w,RefreshShp.bmHdr.h,3);
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+//
+// InitFullScreenAnim() -- Initialize ALL necessary functions for full screen
+// animation types.
+//
+// filename - filename for background lbm.
+// SpawnAll - spawn function to call to spawn all inital objects..
+//
+void InitFullScreenAnim(char *filename, void (*SpawnAll)())
+{
+ unsigned old_flags;
+
+ old_flags = GE_SystemFlags.flags;
+ GE_SystemFlags.flags &= ~(GEsf_Tiles | GEsf_Panning | GEsf_RefreshVec);
+
+ CA_ClearMarks();
+
+ RFL_InitSpriteList();
+ InitObjArray();
+
+ if (SpawnAll)
+ SpawnAll();
+
+ CA_CacheMarks(NULL);
+
+ CalcInactivate();
+ CalcSprites();
+
+ InitLatchRefresh(filename);
+
+ RF_ForceRefresh();
+ RF_ForceRefresh();
+
+ GE_SystemFlags.flags = old_flags;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// DoFullScreenAnim() -- a General "Do-Every-Thing" function that
+// displays a full screen animation...
+//
+// filename - Filename of background lbm
+// SpawnAll - Function to call to spawn all inital objects (REQUIRED)
+// CheckKey - Function to call every cycle - The function called must
+// return a value of greater than zero (0) to terminate the
+// animation cycle. (REQUIRED)
+// CleanUp - Function to call upon exiting the animation. (OPTIONAL)
+//
+void DoFullScreenAnim(char *filename, void (*SpawnAll)(), short (*CheckKey)(),void (*CleanUp)())
+{
+ unsigned old_flags;
+ boolean ExitAnim = false;
+
+ // Save off the current system flags....
+
+ old_flags = GE_SystemFlags.flags;
+ GE_SystemFlags.flags &= ~(GEsf_Tiles | GEsf_Panning);
+
+// randomize();
+
+ // Init refresh latch screen, initalize all object, and setup video mode.
+
+ InitFullScreenAnim(filename,SpawnAll);
+
+ VW_FadeIn();
+
+ while (!ExitAnim)
+ {
+ CalcInactivate();
+ CalcSprites();
+ RF_Refresh();
+
+ ExitAnim = (boolean)CheckKey();
+ }
+
+// RemoveBOBList(player);
+// CalcInactivate();
+
+ if (CleanUp)
+ CleanUp();
+
+ // Restore old system flags...
+
+ GE_SystemFlags.flags = old_flags;
+}
+
+#endif
+
+//--------------------------------------------------------------------------
+// FindFile()
+//--------------------------------------------------------------------------
+boolean FindFile(char *filename,char *disktext,char disknum)
+{
+ extern boolean splitscreen;
+
+ char command[100];
+ char choices[]={sc_Escape,sc_Space,0},drive[2];
+ boolean fadeitout=false,rt_code=2;
+
+ if (!disktext)
+ disktext = GAMENAME;
+ drive[0] = getdisk() + 'A';
+ drive[1] = 0;
+ while (rt_code == 2)
+ {
+ if (Verify(filename))
+ rt_code = true;
+ else
+ {
+ if (ge_textmode)
+ {
+ clrscr();
+ gotoxy(1,1);
+ printf("\nInsert %s disk %d into drive %s.\n",disktext,disknum,drive);
+ printf("Press SPACE to continue, ESC to abort.\n");
+ }
+ else
+ {
+ if (splitscreen)
+ {
+ bufferofs = displayofs = screenloc[screenpage];
+ CenterWindow(38,5);
+ }
+ else
+ {
+ bufferofs = displayofs = 0;
+ US_CenterWindow(38,5);
+ }
+
+ strcpy(command,"\nInsert ");
+ strcat(command,disktext);
+ strcat(command," disk");
+ if (disknum != -1)
+ {
+ strcat(command," ");
+ itoa(disknum,command+strlen(command),10);
+ }
+ strcat(command," into drive ");
+ strcat(command,drive);
+ strcat(command,".");
+ US_CPrint(command);
+ US_CPrint("Press SPACE to continue, ESC to abort.");
+ }
+
+ sound(300);
+ VW_WaitVBL(20);
+ nosound();
+
+ if (!ge_textmode)
+ {
+ if (screenfaded)
+ {
+ VW_FadeIn();
+ fadeitout=true;
+ }
+ }
+ if (GetKeyChoice(choices,true) == sc_Escape)
+ rt_code = false;
+ }
+ }
+
+ if (!ge_textmode)
+ if (fadeitout)
+ VW_FadeOut();
+
+ return(rt_code);
+}
+
+#if 0
+//--------------------------------------------------------------------------
+// CacheAll()
+//--------------------------------------------------------------------------
+void CacheAV(char *title)
+{
+ if (Verify("EGAGRAPH."EXT))
+ {
+ CA_CacheMarks(title);
+ if (!FindFile("EGAGRAPH."EXT,AUDIO_DISK))
+ TrashProg("Can't find graphics files.");
+
+// cache in audio
+
+ current_disk = AUDIO_DISK;
+ }
+ else
+ {
+
+// cache in audio
+
+ if (!FindFile("EGAGRAPH."EXT,VIDEO_DISK))
+ TrashProg("Can't find audio files.");
+ CA_CacheMarks(title);
+
+ current_disk = VIDEO_DISK;
+ }
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#if 0
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// GE_DecompressToRAM() -- This Decompression routine uses normal memory
+// allocation conventions..
+//
+unsigned char huge *GE_DecompressToRAM(char *SourceFile, unsigned long *DataSize) /* Just the reverse of Encode(). */
+{
+ FILE *infile; /* input & output files */
+
+ unsigned long i, j, k, r, c;
+ unsigned char huge *DataPtr;
+ unsigned char huge *CurPtr;
+ unsigned char Buffer[8];
+ unsigned long DstLen;
+
+ if (!(infile = fopen(SourceFile, "rb")))
+ return(0);
+
+ // Read Header....
+
+ fread(Buffer,1,4,infile);
+
+ if (strncmp(Buffer,COMP,4))
+ {
+ fclose(infile);
+ printf("NOT a JAM Compressed FILE!\n");
+ return(0);
+ }
+
+ fread((void *)&DstLen,1,4,infile);
+
+ if (!(DataPtr = farmalloc(DstLen)))
+ return(0);
+
+ fclose(infile);
+
+ *DataSize = DstLen;
+
+ DecompressToRAMLocation(SourceFile,(unsigned char far *)DataPtr);
+
+ return(DataPtr);
+}
+
+#endif
diff --git a/GELIB.H b/GELIB.H
new file mode 100644
index 0000000..ccd4e64
--- /dev/null
+++ b/GELIB.H
@@ -0,0 +1,165 @@
+/* Catacomb Abyss 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.
+ */
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Defines
+//
+
+#define MAX_TEXT_PAGES 40
+#define SAVEVER_DATA "0.93"
+#define FILENAME_LEN 15
+
+#define GAMENAME "CATACOMB ABYSS 3-D"
+#define VERSION "V1.24 "
+#define REVISION "1"
+
+//#define BOBLIST 1 //SP - Undefine if not using BOBList
+
+#define AUDIO_DISK (2)
+#define VIDEO_DISK (1)
+#define LEVEL_DISK (2)
+
+#define BIO_BUFFER_LEN (512)
+
+#define TrashProg Quit
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Externs
+//
+
+extern char Filename[], ID[], VER[];
+extern boolean ge_textmode;
+extern short PPT_LeftEdge,PPT_RightEdge;
+//extern boolean ConserveMemory;
+
+typedef struct Sample {
+ char *filename;
+ memptr *data;
+} 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 {
+ 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,
+ at_REBOUND,at_EXTRA,
+ at_FWD,at_REV
+} ANIMINFO;
+
+struct BitMapHeader {
+ unsigned int w,h,x,y;
+ unsigned char d,trans,comp,pad;
+};
+
+struct BitMap {
+ unsigned int Width;
+ unsigned int Height;
+ unsigned int Depth;
+ unsigned int BytesPerRow;
+ char far *Planes[8];
+};
+
+struct Shape {
+ memptr Data;
+ long size;
+ unsigned int BPR;
+ struct BitMapHeader bmHdr;
+};
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Function prototypes
+//
+void WaitKeyVBL(short key, short vbls);
+void CalibrateJoystick(short joynum);
+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);
+long Verify(char *filename);
+void GE_SaveGame(void);
+boolean GE_LoadGame(void);
+int GE_HardError(word errval,int ax,int bp,int si);
+
+#ifdef BOBLIST
+
+
+boolean UpdateBOBList(objtype *obj,struct Simple_Shape *Shape,shapeclass Class, short priority, spriteflags sprflags);
+boolean RemoveBOBShape(objtype *obj, shapeclass Class);
+void RemoveBOBList(objtype *obj);
+void InitBOBList(objtype *obj, struct BOB_Shape *BOB_Shape, short NumElements);
+void RefreshBOBList(objtype *obj);
+#endif
+
+
+unsigned long BLoad(char *SourceFile, memptr *DstPtr);
+void lzwDecompressFromRAM(byte far *SrcPtr, byte far *DstPtr, longword SrcLen);
+void lzwDecompressFromFile(BufferedIO *SrcPtr, byte far *DstPtr, longword SrcLen);
+byte readch(int handle);
+
+memptr InitBufferedIO(int handle, BufferedIO *bio);
+void FreeBufferedIO(BufferedIO *bio);
+byte bio_readch(BufferedIO *bio);
+void bio_fillbuffer(BufferedIO *bio);
+
+
+void SwapLong(long far *Var);
+void SwapWord(unsigned int far *Var);
+int LoadShape(char *Filename,struct Shape *SHP);
+void FreeShape(struct Shape *shape);
+int UnpackEGAShapeToScreen(struct Shape *SHP,int startx,int starty);
+char GetKeyChoice(char *choices,boolean clear);
+boolean AnimateObj(objtype *obj);
+void AdvanceAnimFWD(objtype *obj);
+void AdvanceAnimREV(objtype *obj);
+
+void LoadASArray(struct Sample *ASArray);
+void FreeASArray(struct Sample *ASArray);
+//void SelectDigiAudio(AudioDeviceType Device);
+void PlaySample(unsigned SampleNum);
+void GE_FreeAllDigiSounds(void);
+void GE_LoadAllDigiSounds(void);
+void DisplayGameList(short winx, short winy, short list_width, short list_height);
+void ReadGameList(void);
+void CheckStack(void);
+void CenterObj(objtype *obj, unsigned x, unsigned y);
+void cachein(short s,short e);
+void cacheout(short s,short e);
+void FizzleFade (unsigned source, unsigned dest,unsigned width,unsigned height, boolean abortable);
+void mprintf(char *msg, ...);
+boolean FindFile(char *filename,char *disktext,char disknum);
+void CacheAV(char *title);
+void BlackPalette(void);
+void ColoredPalette(void);
diff --git a/GFXE_ABS.EQU b/GFXE_ABS.EQU
index 43f2189..97e2c33 100644
--- a/GFXE_ABS.EQU
+++ b/GFXE_ABS.EQU
@@ -1,307 +1,642 @@
;=====================================
;
-; Graphics .EQU file for .C3D
-; IGRAB-ed on Tue Dec 21 15:06:11 1993
+; Graphics .EQU file for .ABS
+; IGRAB-ed on Thu Dec 02 11:58:33 1993
;
;=====================================
-CP_MAINMENUPIC = 5
-CP_NEWGAMEMENUPIC = 6
-CP_LOADMENUPIC = 7
-CP_SAVEMENUPIC = 8
-CP_CONFIGMENUPIC = 9
-CP_SOUNDMENUPIC = 10
-CP_MUSICMENUPIC = 11
-CP_KEYBOARDMENUPIC = 12
-CP_KEYMOVEMENTPIC = 13
-CP_KEYBUTTONPIC = 14
-CP_JOYSTICKMENUPIC = 15
-CP_OPTIONSMENUPIC = 16
-CP_PADDLEWARPIC = 17
-CP_QUITPIC = 18
-CP_JOYSTICKPIC = 19
-CP_MENUSCREENPIC = 20
-TITLEPIC = 21
-CREDITSPIC = 22
-HIGHSCORESPIC = 23
-FINALEPIC = 24
-STATUSPIC = 25
-SIDEBARSPIC = 26
-SCROLLTOPPIC = 27
-SCROLL1PIC = 28
-SCROLL2PIC = 29
-SCROLL3PIC = 30
-SCROLL4PIC = 31
-SCROLL5PIC = 32
-SCROLL6PIC = 33
-SCROLL7PIC = 34
-SCROLL8PIC = 35
-FIRSTLATCHPIC = 36
-NOSHOTPOWERPIC = 37
-SHOTPOWERPIC = 38
-NOBODYPIC = 39
-BODYPIC = 40
-COMPAS1PIC = 41
-COMPAS2PIC = 42
-COMPAS3PIC = 43
-COMPAS4PIC = 44
-COMPAS5PIC = 45
-COMPAS6PIC = 46
-COMPAS7PIC = 47
-COMPAS8PIC = 48
-COMPAS9PIC = 49
-COMPAS10PIC = 50
-COMPAS11PIC = 51
-COMPAS12PIC = 52
-COMPAS13PIC = 53
-COMPAS14PIC = 54
-COMPAS15PIC = 55
-COMPAS16PIC = 56
-DEADPIC = 57
-FIRSTSCALEPIC = 58
-ORC1PIC = 59
-ORC2PIC = 60
-ORC3PIC = 61
-ORC4PIC = 62
-ORCATTACK1PIC = 63
-ORCATTACK2PIC = 64
-ORCOUCHPIC = 65
-ORCDIE1PIC = 66
-ORCDIE2PIC = 67
-ORCDIE3PIC = 68
-TROLL1PIC = 69
-TROLL2PIC = 70
-TROLL3PIC = 71
-TROLL4PIC = 72
-TROLLOUCHPIC = 73
-TROLLATTACK1PIC = 74
-TROLLATTACK2PIC = 75
-TROLLATTACK3PIC = 76
-TROLLDIE1PIC = 77
-TROLLDIE2PIC = 78
-TROLLDIE3PIC = 79
-WARP1PIC = 80
-WARP2PIC = 81
-WARP3PIC = 82
-WARP4PIC = 83
-BOLTOBJPIC = 84
-BOLTOBJ2PIC = 85
-NUKEOBJPIC = 86
-NUKEOBJ2PIC = 87
-POTIONOBJPIC = 88
-RKEYOBJPIC = 89
-YKEYOBJPIC = 90
-GKEYOBJPIC = 91
-BKEYOBJPIC = 92
-SCROLLOBJPIC = 93
-CHESTOBJPIC = 94
-PSHOT1PIC = 95
-PSHOT2PIC = 96
-BIGPSHOT1PIC = 97
-BIGPSHOT2PIC = 98
-DEMON1PIC = 99
-DEMON2PIC = 100
-DEMON3PIC = 101
-DEMON4PIC = 102
-DEMONATTACK1PIC = 103
-DEMONATTACK2PIC = 104
-DEMONATTACK3PIC = 105
-DEMONOUCHPIC = 106
-DEMONDIE1PIC = 107
-DEMONDIE2PIC = 108
-DEMONDIE3PIC = 109
-MAGE1PIC = 110
-MAGE2PIC = 111
-MAGEOUCHPIC = 112
-MAGEATTACKPIC = 113
-MAGEDIE1PIC = 114
-MAGEDIE2PIC = 115
-BAT1PIC = 116
-BAT2PIC = 117
-BAT3PIC = 118
-BAT4PIC = 119
-BATDIE1PIC = 120
-BATDIE2PIC = 121
-GREL1PIC = 122
-GREL2PIC = 123
-GRELATTACKPIC = 124
-GRELHITPIC = 125
-GRELDIE1PIC = 126
-GRELDIE2PIC = 127
-GRELDIE3PIC = 128
-GRELDIE4PIC = 129
-GRELDIE5PIC = 130
-GRELDIE6PIC = 131
-NEMESISPIC = 132
-FIRSTWALLPIC = 133
-EXPWALL1PIC = 134
-EXPWALL2PIC = 135
-EXPWALL3PIC = 136
-WALL1LPIC = 137
-WALL1DPIC = 138
-WALL2DPIC = 139
-WALL2LPIC = 140
-WALL3DPIC = 141
-WALL3LPIC = 142
-WALL4DPIC = 143
-WALL4LPIC = 144
-WALL5DPIC = 145
-WALL5LPIC = 146
-WALL6DPIC = 147
-WALL6LPIC = 148
-WALL7DPIC = 149
-WALL7LPIC = 150
-RDOOR1PIC = 151
-RDOOR2PIC = 152
-YDOOR1PIC = 153
-YDOOR2PIC = 154
-GDOOR1PIC = 155
-GDOOR2PIC = 156
-BDOOR1PIC = 157
-BDOOR2PIC = 158
-ENTERPLAQUEPIC = 159
-
-CP_MENUMASKPICM = 160
-HAND1PICM = 161
-HAND2PICM = 162
-
-PADDLESPR = 163
-BALLSPR = 164
-BALL1PIXELTOTHERIGHTSPR = 165
-
-LEVEL1TEXT = 456
-LEVEL2TEXT = 457
-LEVEL3TEXT = 458
-LEVEL4TEXT = 459
-LEVEL5TEXT = 460
-LEVEL6TEXT = 461
-LEVEL7TEXT = 462
-LEVEL8TEXT = 463
-LEVEL9TEXT = 464
-LEVEL10TEXT = 465
-LEVEL11TEXT = 466
-LEVEL12TEXT = 467
-LEVEL13TEXT = 468
-LEVEL14TEXT = 469
-LEVEL15TEXT = 470
-LEVEL16TEXT = 471
-LEVEL17TEXT = 472
-LEVEL18TEXT = 473
-LEVEL19TEXT = 474
-LEVEL20TEXT = 475
-OUTOFMEM = 476
-PIRACY = 477
-
-CONTROLS_LUMP_START = 5
-CONTROLS_LUMP_END = 20
-
-PADDLE_LUMP_START = 163
-PADDLE_LUMP_END = 165
-
-ORC_LUMP_START = 59
-ORC_LUMP_END = 68
-
-TROLL_LUMP_START = 69
-TROLL_LUMP_END = 79
-
-WARP_LUMP_START = 80
-WARP_LUMP_END = 83
-
-BOLT_LUMP_START = 84
-BOLT_LUMP_END = 85
-
-NUKE_LUMP_START = 86
-NUKE_LUMP_END = 87
-
-POTION_LUMP_START = 88
-POTION_LUMP_END = 88
-
-RKEY_LUMP_START = 89
-RKEY_LUMP_END = 89
-
-YKEY_LUMP_START = 90
-YKEY_LUMP_END = 90
-
-GKEY_LUMP_START = 91
-GKEY_LUMP_END = 91
-
-BKEY_LUMP_START = 92
-BKEY_LUMP_END = 92
-
-SCROLL_LUMP_START = 93
-SCROLL_LUMP_END = 93
-
-CHEST_LUMP_START = 94
-CHEST_LUMP_END = 94
-
-PLAYER_LUMP_START = 95
-PLAYER_LUMP_END = 98
-
-DEMON_LUMP_START = 99
-DEMON_LUMP_END = 109
+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
-MAGE_LUMP_START = 110
-MAGE_LUMP_END = 115
+O_WATER_CHEST_LUMP_START = 122
+O_WATER_CHEST_LUMP_END = 123
-BAT_LUMP_START = 116
-BAT_LUMP_END = 121
+POTION_LUMP_START = 124
+POTION_LUMP_END = 124
-GREL_LUMP_START = 122
-GREL_LUMP_END = 132
+RKEY_LUMP_START = 125
+RKEY_LUMP_END = 125
-EXPWALL_LUMP_START = 134
-EXPWALL_LUMP_END = 136
+YKEY_LUMP_START = 126
+YKEY_LUMP_END = 126
-WALL1_LUMP_START = 137
-WALL1_LUMP_END = 138
+GKEY_LUMP_START = 127
+GKEY_LUMP_END = 127
-WALL2_LUMP_START = 139
-WALL2_LUMP_END = 140
+BKEY_LUMP_START = 128
+BKEY_LUMP_END = 128
-WALL3_LUMP_START = 141
-WALL3_LUMP_END = 142
+RGEM_LUMP_START = 129
+RGEM_LUMP_END = 130
-WALL4_LUMP_START = 143
-WALL4_LUMP_END = 144
+GGEM_LUMP_START = 131
+GGEM_LUMP_END = 132
-WALL5_LUMP_START = 145
-WALL5_LUMP_END = 146
+BGEM_LUMP_START = 133
+BGEM_LUMP_END = 134
-WALL6_LUMP_START = 147
-WALL6_LUMP_END = 148
+YGEM_LUMP_START = 135
+YGEM_LUMP_END = 136
-WALL7_LUMP_START = 149
-WALL7_LUMP_END = 150
+PGEM_LUMP_START = 137
+PGEM_LUMP_END = 138
-RDOOR_LUMP_START = 151
-RDOOR_LUMP_END = 152
+SCROLL_LUMP_START = 139
+SCROLL_LUMP_END = 139
-YDOOR_LUMP_START = 153
-YDOOR_LUMP_END = 154
+CHEST_LUMP_START = 140
+CHEST_LUMP_END = 140
-GDOOR_LUMP_START = 155
-GDOOR_LUMP_END = 156
+RKEY2_LUMP_START = 141
+RKEY2_LUMP_END = 141
-BDOOR_LUMP_START = 157
-BDOOR_LUMP_END = 158
+PLAYER_LUMP_START = 142
+PLAYER_LUMP_END = 146
+
+DEMON_LUMP_START = 147
+DEMON_LUMP_END = 157
+
+REDDEMON_LUMP_START = 158
+REDDEMON_LUMP_END = 168
+
+MAGE_LUMP_START = 169
+MAGE_LUMP_END = 174
+
+BAT_LUMP_START = 175
+BAT_LUMP_END = 180
+
+GREL_LUMP_START = 181
+GREL_LUMP_END = 191
+
+EXPWALL_LUMP_START = 193
+EXPWALL_LUMP_END = 195
+
+W_WATER_EXP_LUMP_START = 196
+W_WATER_EXP_LUMP_END = 198
+
+WALL2_LUMP_START = 199
+WALL2_LUMP_END = 199
+
+WALL3_LUMP_START = 200
+WALL3_LUMP_END = 201
+
+WALL4_LUMP_START = 202
+WALL4_LUMP_END = 202
+
+WALL5_LUMP_START = 203
+WALL5_LUMP_END = 203
+
+WALL6_LUMP_START = 204
+WALL6_LUMP_END = 205
+
+WALL7_LUMP_START = 206
+WALL7_LUMP_END = 207
+
+WALL6_2_LUMP_START = 208
+WALL6_2_LUMP_END = 209
+
+WALL8_LUMP_START = 210
+WALL8_LUMP_END = 211
+
+WALL9_LUMP_START = 212
+WALL9_LUMP_END = 213
+
+WALL10_LUMP_START = 214
+WALL10_LUMP_END = 215
+
+WALL11_LUMP_START = 216
+WALL11_LUMP_END = 217
+
+WALL12_LUMP_START = 218
+WALL12_LUMP_END = 219
+
+WALL13_LUMP_START = 220
+WALL13_LUMP_END = 221
+
+WALL14_LUMP_START = 222
+WALL14_LUMP_END = 223
+
+WALL15_LUMP_START = 224
+WALL15_LUMP_END = 225
+
+WALL16_LUMP_START = 226
+WALL16_LUMP_END = 227
+
+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
;
; Amount of each data item
;
-NUMCHUNKS = 478
-NUMFONT = 2
+NUMCHUNKS = 626
+NUMFONT = 1
NUMFONTM = 0
-NUMPICS = 155
-NUMPICM = 3
-NUMSPRITES = 3
+NUMPICS = 309
+NUMPICM = 1
+NUMSPRITES = 1
NUMTILE8 = 108
NUMTILE8M = 36
NUMTILE16 = 216
NUMTILE16M = 72
NUMTILE32 = 0
NUMTILE32M = 0
-NUMEXTERN = 22
+NUMEXTERN = 21
;
; File offsets for data items
;
@@ -310,17 +645,17 @@ STRUCTPICM = 1
STRUCTSPRITE = 2
STARTFONT = 3
-STARTFONTM = 5
-STARTPICS = 5
-STARTPICM = 160
-STARTSPRITES = 163
-STARTTILE8 = 166
-STARTTILE8M = 167
-STARTTILE16 = 168
-STARTTILE16M = 384
-STARTTILE32 = 456
-STARTTILE32M = 456
-STARTEXTERN = 456
+STARTFONTM = 4
+STARTPICS = 4
+STARTPICM = 313
+STARTSPRITES = 314
+STARTTILE8 = 315
+STARTTILE8M = 316
+STARTTILE16 = 317
+STARTTILE16M = 533
+STARTTILE32 = 605
+STARTTILE32M = 605
+STARTEXTERN = 605
;
; Thank you for using IGRAB!
diff --git a/GFXE_ABS.H b/GFXE_ABS.H
index 7c443e8..2c6eed3 100644
--- a/GFXE_ABS.H
+++ b/GFXE_ABS.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -18,316 +18,742 @@
//////////////////////////////////////
//
-// Graphics .H file for .C3D
-// IGRAB-ed on Tue Dec 21 15:06:10 1993
+// Graphics .H file for .ABS
+// IGRAB-ed on Thu Dec 02 11:58:32 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
- CP_MAINMENUPIC=5,
- CP_NEWGAMEMENUPIC, // 6
- CP_LOADMENUPIC, // 7
- CP_SAVEMENUPIC, // 8
- CP_CONFIGMENUPIC, // 9
- CP_SOUNDMENUPIC, // 10
- CP_MUSICMENUPIC, // 11
- CP_KEYBOARDMENUPIC, // 12
- CP_KEYMOVEMENTPIC, // 13
- CP_KEYBUTTONPIC, // 14
- CP_JOYSTICKMENUPIC, // 15
- CP_OPTIONSMENUPIC, // 16
- CP_PADDLEWARPIC, // 17
- CP_QUITPIC, // 18
- CP_JOYSTICKPIC, // 19
- CP_MENUSCREENPIC, // 20
- TITLEPIC, // 21
- CREDITSPIC, // 22
- HIGHSCORESPIC, // 23
- FINALEPIC, // 24
- STATUSPIC, // 25
- SIDEBARSPIC, // 26
- SCROLLTOPPIC, // 27
- SCROLL1PIC, // 28
- SCROLL2PIC, // 29
- SCROLL3PIC, // 30
- SCROLL4PIC, // 31
- SCROLL5PIC, // 32
- SCROLL6PIC, // 33
- SCROLL7PIC, // 34
- SCROLL8PIC, // 35
- FIRSTLATCHPIC, // 36
- NOSHOTPOWERPIC, // 37
- SHOTPOWERPIC, // 38
- NOBODYPIC, // 39
- BODYPIC, // 40
- COMPAS1PIC, // 41
- COMPAS2PIC, // 42
- COMPAS3PIC, // 43
- COMPAS4PIC, // 44
- COMPAS5PIC, // 45
- COMPAS6PIC, // 46
- COMPAS7PIC, // 47
- COMPAS8PIC, // 48
- COMPAS9PIC, // 49
- COMPAS10PIC, // 50
- COMPAS11PIC, // 51
- COMPAS12PIC, // 52
- COMPAS13PIC, // 53
- COMPAS14PIC, // 54
- COMPAS15PIC, // 55
- COMPAS16PIC, // 56
- DEADPIC, // 57
- FIRSTSCALEPIC, // 58
- ORC1PIC, // 59
- ORC2PIC, // 60
- ORC3PIC, // 61
- ORC4PIC, // 62
- ORCATTACK1PIC, // 63
- ORCATTACK2PIC, // 64
- ORCOUCHPIC, // 65
- ORCDIE1PIC, // 66
- ORCDIE2PIC, // 67
- ORCDIE3PIC, // 68
- TROLL1PIC, // 69
- TROLL2PIC, // 70
- TROLL3PIC, // 71
- TROLL4PIC, // 72
- TROLLOUCHPIC, // 73
- TROLLATTACK1PIC, // 74
- TROLLATTACK2PIC, // 75
- TROLLATTACK3PIC, // 76
- TROLLDIE1PIC, // 77
- TROLLDIE2PIC, // 78
- TROLLDIE3PIC, // 79
- WARP1PIC, // 80
- WARP2PIC, // 81
- WARP3PIC, // 82
- WARP4PIC, // 83
- BOLTOBJPIC, // 84
- BOLTOBJ2PIC, // 85
- NUKEOBJPIC, // 86
- NUKEOBJ2PIC, // 87
- POTIONOBJPIC, // 88
- RKEYOBJPIC, // 89
- YKEYOBJPIC, // 90
- GKEYOBJPIC, // 91
- BKEYOBJPIC, // 92
- SCROLLOBJPIC, // 93
- CHESTOBJPIC, // 94
- PSHOT1PIC, // 95
- PSHOT2PIC, // 96
- BIGPSHOT1PIC, // 97
- BIGPSHOT2PIC, // 98
- DEMON1PIC, // 99
- DEMON2PIC, // 100
- DEMON3PIC, // 101
- DEMON4PIC, // 102
- DEMONATTACK1PIC, // 103
- DEMONATTACK2PIC, // 104
- DEMONATTACK3PIC, // 105
- DEMONOUCHPIC, // 106
- DEMONDIE1PIC, // 107
- DEMONDIE2PIC, // 108
- DEMONDIE3PIC, // 109
- MAGE1PIC, // 110
- MAGE2PIC, // 111
- MAGEOUCHPIC, // 112
- MAGEATTACKPIC, // 113
- MAGEDIE1PIC, // 114
- MAGEDIE2PIC, // 115
- BAT1PIC, // 116
- BAT2PIC, // 117
- BAT3PIC, // 118
- BAT4PIC, // 119
- BATDIE1PIC, // 120
- BATDIE2PIC, // 121
- GREL1PIC, // 122
- GREL2PIC, // 123
- GRELATTACKPIC, // 124
- GRELHITPIC, // 125
- GRELDIE1PIC, // 126
- GRELDIE2PIC, // 127
- GRELDIE3PIC, // 128
- GRELDIE4PIC, // 129
- GRELDIE5PIC, // 130
- GRELDIE6PIC, // 131
- NEMESISPIC, // 132
- FIRSTWALLPIC, // 133
- EXPWALL1PIC, // 134
- EXPWALL2PIC, // 135
- EXPWALL3PIC, // 136
- WALL1LPIC, // 137
- WALL1DPIC, // 138
- WALL2DPIC, // 139
- WALL2LPIC, // 140
- WALL3DPIC, // 141
- WALL3LPIC, // 142
- WALL4DPIC, // 143
- WALL4LPIC, // 144
- WALL5DPIC, // 145
- WALL5LPIC, // 146
- WALL6DPIC, // 147
- WALL6LPIC, // 148
- WALL7DPIC, // 149
- WALL7LPIC, // 150
- RDOOR1PIC, // 151
- RDOOR2PIC, // 152
- YDOOR1PIC, // 153
- YDOOR2PIC, // 154
- GDOOR1PIC, // 155
- GDOOR2PIC, // 156
- BDOOR1PIC, // 157
- BDOOR2PIC, // 158
- ENTERPLAQUEPIC, // 159
-
- CP_MENUMASKPICM=160,
- HAND1PICM, // 161
- HAND2PICM, // 162
-
- // Lump Start
- PADDLESPR=163,
- BALLSPR, // 164
- BALL1PIXELTOTHERIGHTSPR, // 165
-
- LEVEL1TEXT=456,
- LEVEL2TEXT, // 457
- LEVEL3TEXT, // 458
- LEVEL4TEXT, // 459
- LEVEL5TEXT, // 460
- LEVEL6TEXT, // 461
- LEVEL7TEXT, // 462
- LEVEL8TEXT, // 463
- LEVEL9TEXT, // 464
- LEVEL10TEXT, // 465
- LEVEL11TEXT, // 466
- LEVEL12TEXT, // 467
- LEVEL13TEXT, // 468
- LEVEL14TEXT, // 469
- LEVEL15TEXT, // 470
- LEVEL16TEXT, // 471
- LEVEL17TEXT, // 472
- LEVEL18TEXT, // 473
- LEVEL19TEXT, // 474
- LEVEL20TEXT, // 475
- OUTOFMEM, // 476
- PIRACY, // 477
+ 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
ENUMEND
} graphicnums;
//
// Data LUMPs
//
-#define CONTROLS_LUMP_START 5
-#define CONTROLS_LUMP_END 20
+#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 WALL8_LUMP_START 210
+#define WALL8_LUMP_END 211
+
+#define WALL9_LUMP_START 212
+#define WALL9_LUMP_END 213
+
+#define WALL10_LUMP_START 214
+#define WALL10_LUMP_END 215
+
+#define WALL11_LUMP_START 216
+#define WALL11_LUMP_END 217
+
+#define WALL12_LUMP_START 218
+#define WALL12_LUMP_END 219
+
+#define WALL13_LUMP_START 220
+#define WALL13_LUMP_END 221
+
+#define WALL14_LUMP_START 222
+#define WALL14_LUMP_END 223
+
+#define WALL15_LUMP_START 224
+#define WALL15_LUMP_END 225
+
+#define WALL16_LUMP_START 226
+#define WALL16_LUMP_END 227
+
+#define WALL18_LUMP_START 228
+#define WALL18_LUMP_END 229
+
+#define WALL17_LUMP_START 230
+#define WALL17_LUMP_END 231
+
+#define WALL19_LUMP_START 232
+#define WALL19_LUMP_END 233
+
+#define WALL20_LUMP_START 234
+#define WALL20_LUMP_END 235
+
+#define WALL21_LUMP_START 236
+#define WALL21_LUMP_END 237
+
+#define WALL22_LUMP_START 238
+#define WALL22_LUMP_END 239
+
+#define WALL23_LUMP_START 240
+#define WALL23_LUMP_END 241
+
+#define WALL24_LUMP_START 242
+#define WALL24_LUMP_END 243
+
+#define WALL25_LUMP_START 244
+#define WALL25_LUMP_END 245
+
+#define WALL26_LUMP_START 246
+#define WALL26_LUMP_END 247
+
+#define WALL27_LUMP_START 248
+#define WALL27_LUMP_END 249
+
+#define WALL28_LUMP_START 250
+#define WALL28_LUMP_END 251
-#define PADDLE_LUMP_START 163
-#define PADDLE_LUMP_END 165
+#define WALL29_LUMP_START 252
+#define WALL29_LUMP_END 253
-#define ORC_LUMP_START 59
-#define ORC_LUMP_END 68
+#define WALL30_LUMP_START 254
+#define WALL30_LUMP_END 255
-#define TROLL_LUMP_START 69
-#define TROLL_LUMP_END 79
+#define WALL31_LUMP_START 256
+#define WALL31_LUMP_END 257
-#define WARP_LUMP_START 80
-#define WARP_LUMP_END 83
+#define WALL32_LUMP_START 258
+#define WALL32_LUMP_END 259
-#define BOLT_LUMP_START 84
-#define BOLT_LUMP_END 85
+#define WALL33_LUMP_START 260
+#define WALL33_LUMP_END 261
-#define NUKE_LUMP_START 86
-#define NUKE_LUMP_END 87
+#define WALL34_LUMP_START 262
+#define WALL34_LUMP_END 262
-#define POTION_LUMP_START 88
-#define POTION_LUMP_END 88
+#define WALL36_LUMP_START 263
+#define WALL36_LUMP_END 266
-#define RKEY_LUMP_START 89
-#define RKEY_LUMP_END 89
+#define W_WARP_LUMP_START 267
+#define W_WARP_LUMP_END 270
-#define YKEY_LUMP_START 90
-#define YKEY_LUMP_END 90
+#define W_TORCH_LUMP_START 278
+#define W_TORCH_LUMP_END 279
-#define GKEY_LUMP_START 91
-#define GKEY_LUMP_END 91
+#define SUB_STONE_LUMP_START 280
+#define SUB_STONE_LUMP_END 281
-#define BKEY_LUMP_START 92
-#define BKEY_LUMP_END 92
+#define BLOODY_SUB_STONE_LUMP_START 282
+#define BLOODY_SUB_STONE_LUMP_END 283
-#define SCROLL_LUMP_START 93
-#define SCROLL_LUMP_END 93
+#define W_BREATH_LUMP_START 284
+#define W_BREATH_LUMP_END 287
-#define CHEST_LUMP_START 94
-#define CHEST_LUMP_END 94
+#define W_WOOD_DOORWAY_LUMP_START 288
+#define W_WOOD_DOORWAY_LUMP_END 288
-#define PLAYER_LUMP_START 95
-#define PLAYER_LUMP_END 98
+#define W_WOOD_DOORWAY_GLOW_LUMP_START 289
+#define W_WOOD_DOORWAY_GLOW_LUMP_END 289
-#define DEMON_LUMP_START 99
-#define DEMON_LUMP_END 109
+#define W_WATER_GATES_LUMP_START 290
+#define W_WATER_GATES_LUMP_END 293
-#define MAGE_LUMP_START 110
-#define MAGE_LUMP_END 115
+#define W_PRE_CHEATS_LUMP_START 294
+#define W_PRE_CHEATS_LUMP_END 294
-#define BAT_LUMP_START 116
-#define BAT_LUMP_END 121
+#define W_CHEAT_GOD_LUMP_START 295
+#define W_CHEAT_GOD_LUMP_END 295
-#define GREL_LUMP_START 122
-#define GREL_LUMP_END 132
+#define W_CHEAT_WARP_LUMP_START 296
+#define W_CHEAT_WARP_LUMP_END 296
-#define EXPWALL_LUMP_START 134
-#define EXPWALL_LUMP_END 136
+#define W_CHEAT_ITEMS_LUMP_START 297
+#define W_CHEAT_ITEMS_LUMP_END 297
-#define WALL1_LUMP_START 137
-#define WALL1_LUMP_END 138
+#define W_CHEAT_FREEZE_LUMP_START 298
+#define W_CHEAT_FREEZE_LUMP_END 298
-#define WALL2_LUMP_START 139
-#define WALL2_LUMP_END 140
+#define W_POST_CHEAT_LUMP_START 299
+#define W_POST_CHEAT_LUMP_END 299
-#define WALL3_LUMP_START 141
-#define WALL3_LUMP_END 142
+#define W_SURFACE_PLAQ_LUMP_START 300
+#define W_SURFACE_PLAQ_LUMP_END 300
-#define WALL4_LUMP_START 143
-#define WALL4_LUMP_END 144
+#define W_BREATH2_LUMP_START 301
+#define W_BREATH2_LUMP_END 304
-#define WALL5_LUMP_START 145
-#define WALL5_LUMP_END 146
+#define W_MAGE_STATUE_LUMP_START 305
+#define W_MAGE_STATUE_LUMP_END 305
-#define WALL6_LUMP_START 147
-#define WALL6_LUMP_END 148
+#define W_ZOMBIE_STATUE_LUMP_START 306
+#define W_ZOMBIE_STATUE_LUMP_END 306
-#define WALL7_LUMP_START 149
-#define WALL7_LUMP_END 150
+#define W_EYE_STATUE_LUMP_START 307
+#define W_EYE_STATUE_LUMP_END 307
-#define RDOOR_LUMP_START 151
-#define RDOOR_LUMP_END 152
+#define W_NEM_STATUE_LUMP_START 308
+#define W_NEM_STATUE_LUMP_END 308
-#define YDOOR_LUMP_START 153
-#define YDOOR_LUMP_END 154
+#define W_SKELETION_STATUE_LUMP_START 309
+#define W_SKELETION_STATUE_LUMP_END 309
-#define GDOOR_LUMP_START 155
-#define GDOOR_LUMP_END 156
+#define W_SPOOK_STATUE_LUMP_START 310
+#define W_SPOOK_STATUE_LUMP_END 310
-#define BDOOR_LUMP_START 157
-#define BDOOR_LUMP_END 158
+#define W_ORCH_STATUE_LUMP_START 311
+#define W_ORCH_STATUE_LUMP_END 311
//
// Amount of each data item
//
-#define NUMCHUNKS 478
-#define NUMFONT 2
+#define NUMCHUNKS 626
+#define NUMFONT 1
#define NUMFONTM 0
-#define NUMPICS 155
-#define NUMPICM 3
-#define NUMSPRITES 3
+#define NUMPICS 309
+#define NUMPICM 1
+#define NUMSPRITES 1
#define NUMTILE8 108
#define NUMTILE8M 36
#define NUMTILE16 216
#define NUMTILE16M 72
#define NUMTILE32 0
#define NUMTILE32M 0
-#define NUMEXTERNS 22
+#define NUMEXTERNS 21
//
// File offsets for data items
//
@@ -336,17 +762,17 @@ typedef enum {
#define STRUCTSPRITE 2
#define STARTFONT 3
-#define STARTFONTM 5
-#define STARTPICS 5
-#define STARTPICM 160
-#define STARTSPRITES 163
-#define STARTTILE8 166
-#define STARTTILE8M 167
-#define STARTTILE16 168
-#define STARTTILE16M 384
-#define STARTTILE32 456
-#define STARTTILE32M 456
-#define STARTEXTERNS 456
+#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
//
// Thank you for using IGRAB!
diff --git a/ID_ASM.EQU b/ID_ASM.EQU
index e5110cd..d1ccf55 100644
--- a/ID_ASM.EQU
+++ b/ID_ASM.EQU
@@ -4,7 +4,7 @@
;----------------------------------------------------------------------------
-INCLUDE "GFXE_C3D.EQU"
+INCLUDE "GFXE_ABS.EQU"
;----------------------------------------------------------------------------
diff --git a/ID_CA.C b/ID_CA.C
index b44bbb5..069a47d 100644
--- a/ID_CA.C
+++ b/ID_CA.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -799,7 +799,6 @@ asm mov ds,ax
=============================================================================
*/
-
/*
======================
=
@@ -832,9 +831,9 @@ void CAL_SetupGrFile (void)
// load ???dict.ext (huffman dictionary for graphics files)
//
- if ((handle = open(GREXT"DICT."EXTENSION,
+ if ((handle = open(GREXT"DICT."EXT,
O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open "GREXT"DICT."EXTENSION"!");
+ Quit ("Can't open "GREXT"DICT."EXT"!");
read(handle, &grhuffman, sizeof(grhuffman));
close(handle);
@@ -844,9 +843,9 @@ void CAL_SetupGrFile (void)
//
MM_GetPtr (&(memptr)grstarts,(NUMCHUNKS+1)*FILEPOSSIZE);
- if ((handle = open(GREXT"HEAD."EXTENSION,
+ if ((handle = open(GREXT"HEAD."EXT,
O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open "GREXT"HEAD."EXTENSION"!");
+ Quit ("Can't open "GREXT"HEAD."EXT"!");
CA_FarRead(handle, (memptr)grstarts, (NUMCHUNKS+1)*FILEPOSSIZE);
@@ -858,9 +857,9 @@ void CAL_SetupGrFile (void)
//
// Open the graphics file, leaving it open until the game is finished
//
- grhandle = open(GREXT"GRAPH."EXTENSION, O_RDONLY | O_BINARY);
+ grhandle = open(GREXT"GRAPH."EXT, O_RDONLY | O_BINARY);
if (grhandle == -1)
- Quit ("Cannot open "GREXT"GRAPH."EXTENSION"!");
+ Quit ("Cannot open "GREXT"GRAPH."EXT"!");
//
@@ -915,9 +914,9 @@ void CAL_SetupMapFile (void)
// load maphead.ext (offsets and tileinfo for map file)
//
#ifndef MAPHEADERLINKED
- if ((handle = open("MAPHEAD."EXTENSION,
+ if ((handle = open("MAPHEAD."EXT,
O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open MAPHEAD."EXTENSION"!");
+ Quit ("Can't open MAPHEAD."EXT"!");
length = filelength(handle);
MM_GetPtr (&(memptr)tinf,length);
CA_FarRead(handle, tinf, length);
@@ -932,13 +931,13 @@ void CAL_SetupMapFile (void)
// open the data file
//
#ifdef MAPHEADERLINKED
- if ((maphandle = open("GAMEMAPS."EXTENSION,
+ if ((maphandle = open("GAMEMAPS."EXT,
O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open GAMEMAPS."EXTENSION"!");
+ Quit ("Can't open GAMEMAPS."EXT"!");
#else
- if ((maphandle = open("MAPTEMP."EXTENSION,
+ if ((maphandle = open("MAPTEMP."EXT,
O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open MAPTEMP."EXTENSION"!");
+ Quit ("Can't open MAPTEMP."EXT"!");
#endif
}
@@ -962,9 +961,9 @@ void CAL_SetupAudioFile (void)
// load maphead.ext (offsets and tileinfo for map file)
//
#ifndef AUDIOHEADERLINKED
- if ((handle = open("AUDIOHED."EXTENSION,
+ if ((handle = open("AUDIOHED."EXT,
O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open AUDIOHED."EXTENSION"!");
+ Quit ("Can't open AUDIOHED."EXT"!");
length = filelength(handle);
MM_GetPtr (&(memptr)audiostarts,length);
CA_FarRead(handle, (byte far *)audiostarts, length);
@@ -979,13 +978,13 @@ void CAL_SetupAudioFile (void)
// open the data file
//
#ifndef AUDIOHEADERLINKED
- if ((audiohandle = open("AUDIOT."EXTENSION,
+ if ((audiohandle = open("AUDIOT."EXT,
O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open AUDIOT."EXTENSION"!");
+ Quit ("Can't open AUDIOT."EXT"!");
#else
- if ((audiohandle = open("AUDIO."EXTENSION,
+ if ((audiohandle = open("AUDIO."EXT,
O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open AUDIO."EXTENSION"!");
+ Quit ("Can't open AUDIO."EXT"!");
#endif
}
@@ -1009,15 +1008,38 @@ void CA_Startup (void)
profilehandle = open("PROFILE.TXT", O_CREAT | O_WRONLY | O_TEXT);
#endif
+// MDM begin - (GAMERS EDGE)
+//
+ if (!FindFile("AUDIO."EXT,NULL,2))
+ Quit("CA_Startup(): Can't find audio files.");
+//
+// MDM end
+
+#ifndef NOAUDIO
+ CAL_SetupAudioFile ();
+#endif
+
+// MDM begin - (GAMERS EDGE)
+//
+ if (!FindFile("GAMEMAPS."EXT,NULL,2))
+ Quit("CA_Startup(): Can't find level files.");
+//
+// MDM end
+
#ifndef NOMAPS
CAL_SetupMapFile ();
#endif
+
+// MDM begin - (GAMERS EDGE)
+//
+ if (!FindFile("EGAGRAPH."EXT,NULL,2))
+ Quit("CA_Startup(): Can't find graphics files.");
+//
+// MDM end
+
#ifndef NOGRAPHICS
CAL_SetupGrFile ();
#endif
-#ifndef NOAUDIO
- CAL_SetupAudioFile ();
-#endif
mapon = -1;
ca_levelbit = 1;
@@ -1077,6 +1099,13 @@ void CA_CacheAudioChunk (int chunk)
return; // allready in memory
}
+// MDM begin - (GAMERS EDGE)
+//
+ if (!FindFile("AUDIO."EXT,NULL,2))
+ Quit("CA_CacheAudioChunk(): Can't find audio files.");
+//
+// MDM end
+
//
// load the chunk into a buffer, either the miscbuffer if it fits, or allocate
// a larger buffer
@@ -1537,7 +1566,6 @@ void CAL_ReadGrChunk (int chunk)
MM_FreePtr(&bigbufferseg);
}
-
/*
======================
=
@@ -1562,6 +1590,13 @@ void CA_CacheGrChunk (int chunk)
return; // allready in memory
}
+// MDM begin - (GAMERS EDGE)
+//
+ if (!FindFile("EGAGRAPH."EXT,NULL,2))
+ Quit("CA_CacheGrChunk(): Can't find graphics files.");
+//
+// MDM end
+
//
// load the chunk into a buffer, either the miscbuffer if it fits, or allocate
// a larger buffer
@@ -1622,6 +1657,14 @@ void CA_CacheMap (int mapnum)
#endif
+// MDM begin - (GAMERS EDGE)
+//
+ if (!FindFile("GAMEMAPS."EXT,NULL,2))
+ Quit("CA_CacheMap(): Can't find level files.");
+//
+// MDM end
+
+
//
// free up memory from last map
//
@@ -2030,6 +2073,13 @@ void CA_CacheMarks (char *title)
if (!numcache) // nothing to cache!
return;
+// MDM begin - (GAMERS EDGE)
+//
+ if (!FindFile("EGAGRAPH."EXT,NULL,2))
+ Quit("CA_CacheMarks(): Can't find graphics files.");
+//
+// MDM end
+
if (dialog)
{
#ifdef PROFILE
diff --git a/ID_CA.H b/ID_CA.H
index 23007aa..ca6f3d7 100644
--- a/ID_CA.H
+++ b/ID_CA.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -42,7 +42,7 @@
#define GRHEADERLINKED
#define AUDIOHEADERLINKED
-#define NUMMAPS 30
+#define NUMMAPS 19
#define MAPPLANES 3
//===========================================================================
diff --git a/ID_HEADS.H b/ID_HEADS.H
index 622c069..5f176db 100644
--- a/ID_HEADS.H
+++ b/ID_HEADS.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -36,15 +36,31 @@
//--------------------------------------------------------------------------
-#define EXTENSION "C3D"
+#define EXT "ABS"
extern char far introscn;
-#include "GFXE_C3D.H"
-#include "AUDIOC3D.H"
+#include "GFXE_ABS.H"
+#include "AUDIOABS.H"
+#include "MAPSABS.H"
//--------------------------------------------------------------------------
+//
+// DEFINES THE TILE ATTRIBUTE CHECKING CONVENTION (macros).
+//
+// DEFINE CUSTOM BIT-FLAG NAMES...
+//
+
+
+#define tf_SOLID 0x01
+#define tf_SPECIAL 0x02
+#define tf_EMBEDDED_KEY_COLOR 0x04
+
+#define TILE_FLAGS(tile) (tinf[FLAGS+(tile)])
+
+#define GATE_KEY_COLOR(tile) ((unsigned char)(TILE_FLAGS(tile)>>4))
+
#define CAT3D
#define TEXTGR 0
@@ -52,6 +68,9 @@ extern char far introscn;
#define EGAGR 2
#define VGAGR 3
+#define EGA320GR 10 // MDM (GAMERS EDGE)
+#define EGA640GR 11 // MDM (GAMERS EDGE)
+
#define GRMODE EGAGR
#if GRMODE == EGAGR
@@ -99,7 +118,7 @@ typedef struct
#include "ID_US.H"
-void Quit (char *error); // defined in user program
+void Quit (char *error, ...); // defined in user program
//
// replacing refresh manager with custom routines
@@ -116,7 +135,7 @@ void Quit (char *error); // defined in user program
#define UPDATETERMINATE 0x0301
-extern unsigned mapwidth,mapheight,tics;
+extern unsigned mapwidth,mapheight,tics,realtics;
extern boolean compatability;
extern byte *updateptr;
diff --git a/ID_IN.C b/ID_IN.C
index b78ca43..fe51ad1 100644
--- a/ID_IN.C
+++ b/ID_IN.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -46,6 +46,9 @@
#define MaxJoyValue 5000
// Global variables
+ boolean JoystickCalibrated=false; // MDM (GAMERS EDGE) - added
+ ControlType ControlTypeUsed; // MDM (GAMERS EDGE) - added
+
boolean Keyboard[NumCodes],
JoysPresent[MaxJoys],
MousePresent;
@@ -56,9 +59,9 @@
JoystickDef JoyDefs[MaxJoys];
ControlType Controls[MaxPlayers];
- Demo DemoMode = demo_Off;
- byte _seg *DemoBuffer;
- word DemoOffset,DemoSize;
+// Demo DemoMode = demo_Off;
+// byte _seg *DemoBuffer;
+// word DemoOffset,DemoSize;
// Internal variables
static boolean IN_Started;
@@ -101,6 +104,7 @@ static byte far ASCIINames[] = // Unshifted ASCII for scan codes
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
},
+#if 0
*ScanNames[] = // Scan code names with single chars
{
"?","?","1","2","3","4","5","6","7","8","9","0","-","+","?","?",
@@ -112,13 +116,16 @@ static byte far ASCIINames[] = // Unshifted ASCII for scan codes
"?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
"?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"
}, // DEBUG - consolidate these
+#endif
+
far ExtScanCodes[] = // Scan codes with >1 char names
{
1,0xe,0xf,0x1d,0x2a,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,
0x3f,0x40,0x41,0x42,0x43,0x44,0x57,0x59,0x46,0x1c,0x36,
0x37,0x38,0x47,0x49,0x4f,0x51,0x52,0x53,0x45,0x48,
0x50,0x4b,0x4d,0x00
- },
+ };
+#if 0
*ExtScanNames[] = // Names corresponding to ExtScanCodes
{
"Esc","BkSp","Tab","Ctrl","LShft","Space","CapsLk","F1","F2","F3","F4",
@@ -126,6 +133,7 @@ static byte far ASCIINames[] = // Unshifted ASCII for scan codes
"PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up",
"Down","Left","Right",""
};
+#endif
static Direction DirTable[] = // Quick lookup for total direction
{
dir_NorthWest, dir_North, dir_NorthEast,
@@ -747,6 +755,158 @@ IN_ReadCursor(CursorInfo *info)
void
IN_ReadControl(int player,ControlInfo *info)
{
+ boolean realdelta=false; // MDM (GAMERS EDGE)
+ byte dbyte;
+ word buttons;
+ int dx,dy;
+ Motion mx,my;
+ ControlType type;
+register KeyboardDef *def;
+
+ dx = dy = 0;
+ mx = my = motion_None;
+ buttons = 0;
+
+#if 0
+ if (DemoMode == demo_Playback)
+ {
+ dbyte = DemoBuffer[DemoOffset + 1];
+ my = (dbyte & 3) - 1;
+ mx = ((dbyte >> 2) & 3) - 1;
+ buttons = (dbyte >> 4) & 3;
+
+ if (!(--DemoBuffer[DemoOffset]))
+ {
+ DemoOffset += 2;
+ if (DemoOffset >= DemoSize)
+ DemoMode = demo_PlayDone;
+ }
+
+ realdelta = false;
+ }
+ else if (DemoMode == demo_PlayDone)
+ Quit("Demo playback exceeded");
+ else
+#endif
+ {
+ // MDM begin (GAMERS EDGE) - added this block
+ ControlTypeUsed = ctrl_None;
+
+ // Handle mouse input...
+ //
+ if ((MousePresent) && (ControlTypeUsed == ctrl_None))
+ {
+ INL_GetMouseDelta(&dx,&dy);
+ buttons = INL_GetMouseButtons();
+ realdelta = true;
+ if (dx || dy || buttons)
+ ControlTypeUsed = ctrl_Mouse;
+ }
+
+ // Handle joystick input...
+ //
+ if ((JoystickCalibrated) && (ControlTypeUsed == ctrl_None))
+ {
+ type = ctrl_Joystick1;
+ INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false);
+ buttons = INL_GetJoyButtons(type - ctrl_Joystick);
+ realdelta = true;
+ if (dx || dy || buttons)
+ ControlTypeUsed = ctrl_Joystick;
+ }
+
+ // Handle keyboard input...
+ //
+ if (ControlTypeUsed == ctrl_None)
+ {
+ type = ctrl_Keyboard1;
+ def = &KbdDefs[type - ctrl_Keyboard];
+
+ if (Keyboard[def->upleft])
+ mx = motion_Left,my = motion_Up;
+ else if (Keyboard[def->upright])
+ mx = motion_Right,my = motion_Up;
+ else if (Keyboard[def->downleft])
+ mx = motion_Left,my = motion_Down;
+ else if (Keyboard[def->downright])
+ mx = motion_Right,my = motion_Down;
+
+ if (Keyboard[def->up])
+ my = motion_Up;
+ else if (Keyboard[def->down])
+ my = motion_Down;
+
+ if (Keyboard[def->left])
+ mx = motion_Left;
+ else if (Keyboard[def->right])
+ mx = motion_Right;
+
+ if (Keyboard[def->button0])
+ buttons += 1 << 0;
+ if (Keyboard[def->button1])
+ buttons += 1 << 1;
+ realdelta = false;
+ if (mx || my || buttons)
+ ControlTypeUsed = ctrl_Keyboard;
+ } // MDM end (GAMERS EDGE)
+ }
+
+ if (realdelta)
+ {
+ mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None);
+ my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None);
+ }
+ else
+ {
+ dx = mx * 127;
+ dy = my * 127;
+ }
+
+ info->x = dx;
+ info->xaxis = mx;
+ info->y = dy;
+ info->yaxis = my;
+ info->button0 = buttons & (1 << 0);
+ info->button1 = buttons & (1 << 1);
+ info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
+
+#if 0
+ if (DemoMode == demo_Record)
+ {
+ // Pack the control info into a byte
+ dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1);
+
+ if
+ (
+ (DemoBuffer[DemoOffset + 1] == dbyte)
+ && (DemoBuffer[DemoOffset] < 255)
+ )
+ (DemoBuffer[DemoOffset])++;
+ else
+ {
+ if (DemoOffset || DemoBuffer[DemoOffset])
+ DemoOffset += 2;
+
+ if (DemoOffset >= DemoSize)
+ Quit("Demo buffer overflow");
+
+ DemoBuffer[DemoOffset] = 1;
+ DemoBuffer[DemoOffset + 1] = dbyte;
+ }
+ }
+#endif
+}
+
+#if 0
+///////////////////////////////////////////////////////////////////////////
+//
+// IN_ReadControl() - Reads the device associated with the specified
+// player and fills in the control info struct
+//
+///////////////////////////////////////////////////////////////////////////
+void
+IN_ReadControl(int player,ControlInfo *info)
+{
boolean realdelta;
byte dbyte;
word buttons;
@@ -759,6 +919,7 @@ register KeyboardDef *def;
mx = my = motion_None;
buttons = 0;
+#if 0
if (DemoMode == demo_Playback)
{
dbyte = DemoBuffer[DemoOffset + 1];
@@ -778,6 +939,7 @@ register KeyboardDef *def;
else if (DemoMode == demo_PlayDone)
Quit("Demo playback exceeded");
else
+#endif
{
switch (type = Controls[player])
{
@@ -843,6 +1005,7 @@ register KeyboardDef *def;
info->button1 = buttons & (1 << 1);
info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
+#if 0
if (DemoMode == demo_Record)
{
// Pack the control info into a byte
@@ -866,7 +1029,9 @@ register KeyboardDef *def;
DemoBuffer[DemoOffset + 1] = dbyte;
}
}
+#endif
}
+#endif
///////////////////////////////////////////////////////////////////////////
//
@@ -881,6 +1046,7 @@ IN_SetControlType(int player,ControlType type)
Controls[player] = type;
}
+#if 0
///////////////////////////////////////////////////////////////////////////
//
// IN_StartDemoRecord() - Starts the demo recording, using a buffer the
@@ -941,7 +1107,10 @@ IN_FreeDemoBuffer(void)
if (DemoBuffer)
MM_FreePtr((memptr *)&DemoBuffer);
}
+#endif
+
+#if 0
///////////////////////////////////////////////////////////////////////////
//
// IN_GetScanName() - Returns a string containing the name of the
@@ -960,6 +1129,8 @@ IN_GetScanName(ScanCode scan)
return(ScanNames[scan]);
}
+#endif
+
///////////////////////////////////////////////////////////////////////////
//
diff --git a/ID_IN.H b/ID_IN.H
index 45477ec..1ebc547 100644
--- a/ID_IN.H
+++ b/ID_IN.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -124,6 +124,7 @@ typedef enum {
demo_Off,demo_Record,demo_Playback,demo_PlayDone
} Demo;
typedef enum {
+ ctrl_None, // MDM (GAMERS EDGE) - added
ctrl_Keyboard,
ctrl_Keyboard1 = ctrl_Keyboard,ctrl_Keyboard2,
ctrl_Joystick,
@@ -174,6 +175,9 @@ extern KeyboardDef KbdDefs[];
extern JoystickDef JoyDefs[];
extern ControlType Controls[MaxPlayers];
+extern boolean JoystickCalibrated; // MDM (GAMERS EDGE) - added
+extern ControlType ControlTypeUsed; // MDM (GAMERS EDGE) - added
+
extern Demo DemoMode;
extern byte _seg *DemoBuffer;
extern word DemoOffset,DemoSize;
diff --git a/ID_MM.C b/ID_MM.C
index 76a867d..2729e1d 100644
--- a/ID_MM.C
+++ b/ID_MM.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -21,8 +21,8 @@
/*
=============================================================================
- ID software memory manager
- --------------------------
+ ID software memory manager
+ --------------------------
Primary coder: John Carmack
@@ -48,6 +48,16 @@ EMS / XMS unmanaged routines
#pragma warn -pro
#pragma warn -use
+
+//#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!"
+
+#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"
+
+
+
/*
=============================================================================
@@ -759,7 +769,7 @@ void MM_GetPtr (memptr *baseptr,unsigned long size)
}
if (bombonerror)
- Quit ("MM_GetPtr: Out of memory!");
+ Quit (OUT_OF_MEM_MSG);
else
mmerror = true;
}
@@ -909,8 +919,8 @@ void MM_SortMem (void)
SD_StopSound();
- oldborder = bordercolor;
- VW_ColorBorder (15);
+// oldborder = bordercolor;
+// VW_ColorBorder (15);
if (beforesort)
beforesort();
@@ -976,7 +986,7 @@ void MM_SortMem (void)
if (aftersort)
aftersort();
- VW_ColorBorder (oldborder);
+// VW_ColorBorder (oldborder);
if (playing)
MM_SetLock(&(memptr)audiosegs[playing],false);
@@ -985,6 +995,7 @@ void MM_SortMem (void)
//==========================================================================
+#if 0
/*
=====================
=
@@ -1049,6 +1060,7 @@ write (debughandle,scratch,strlen(scratch));
VW_SetLineWidth(64);
bufferofs = temp;
}
+#endif
//==========================================================================
diff --git a/ID_MM.H b/ID_MM.H
index 49fb7ed..f9961b1 100644
--- a/ID_MM.H
+++ b/ID_MM.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss 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 fa08d19..ea59b23 100644
--- a/ID_RF.C
+++ b/ID_RF.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -1479,6 +1479,7 @@ void RF_CalcTics (void)
TimeCount -= (tics-MAXTICS);
tics = MAXTICS;
}
+
}
}
diff --git a/ID_RF.H b/ID_RF.H
index f11fdf8..b52fef9 100644
--- a/ID_RF.H
+++ b/ID_RF.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss 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 56db0c7..ce699c2 100644
--- a/ID_RF_A.ASM
+++ b/ID_RF_A.ASM
@@ -1,4 +1,4 @@
-; Catacomb 3-D Source Code
+; Catacomb Abyss 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 c8ee346..b6279d8 100644
--- a/ID_SD.C
+++ b/ID_SD.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -43,6 +43,8 @@
// NeedsMusic - load music?
//
+#define USE_MUSIC 0
+
#pragma hdrstop // Wierdo thing with MUSE
#include <dos.h>
@@ -736,6 +738,7 @@ asm out dx,al
HackCount++;
+#if USE_MUSIC
if (MusicMode == smm_AdLib)
{
SDL_ALService();
@@ -760,6 +763,7 @@ asm out dx,al
}
}
else
+#endif
{
if (!(++count & 1))
{
@@ -856,9 +860,11 @@ SDL_SetTimerSpeed(void)
{
word rate;
+#if USE_MUSIC
if (MusicMode == smm_AdLib)
rate = TickBase * 8;
else
+#endif
rate = TickBase * 2;
SDL_SetIntsPerSec(rate);
}
@@ -927,6 +933,7 @@ SD_SetSoundMode(SDMode mode)
boolean
SD_SetMusicMode(SMMode mode)
{
+#if USE_MUSIC
boolean result;
SD_FadeOutMusic();
@@ -957,6 +964,7 @@ SD_SetMusicMode(SMMode mode)
SDL_SetTimerSpeed();
return(result);
+#endif
}
///////////////////////////////////////////////////////////////////////////
@@ -997,7 +1005,9 @@ SD_Startup(void)
LocalTime = TimeCount = alTimeCount = 0;
SD_SetSoundMode(sdm_Off);
+#if USE_MUSIC
SD_SetMusicMode(smm_Off);
+#endif
if (!alNoCheck)
AdLibPresent = SDL_DetectAdLib();
@@ -1055,8 +1065,10 @@ SD_Default(boolean gotit,SDMode sd,SMMode sm)
if (AdLibPresent)
sm = smm_AdLib;
}
+#if USE_MUSIC
if (sm != MusicMode)
SD_SetMusicMode(sm);
+#endif
}
///////////////////////////////////////////////////////////////////////////
@@ -1071,7 +1083,9 @@ SD_Shutdown(void)
if (!SD_Started)
return;
+#if USE_MUSIC
SD_MusicOff();
+#endif
SDL_ShutDevice();
SDL_CleanDevice();
@@ -1202,7 +1216,9 @@ SD_WaitSoundDone(void)
void
SD_MusicOn(void)
{
+#if USE_MUSIC
sqActive = true;
+#endif
}
///////////////////////////////////////////////////////////////////////////
@@ -1213,6 +1229,7 @@ SD_MusicOn(void)
void
SD_MusicOff(void)
{
+#if USE_MUSIC
word i;
@@ -1226,6 +1243,7 @@ SD_MusicOff(void)
break;
}
sqActive = false;
+#endif
}
///////////////////////////////////////////////////////////////////////////
@@ -1236,6 +1254,7 @@ SD_MusicOff(void)
void
SD_StartMusic(MusicGroup far *music)
{
+#if USE_MUSIC
SD_MusicOff();
asm pushf
asm cli
@@ -1250,6 +1269,7 @@ asm cli
}
asm popf
+#endif
}
///////////////////////////////////////////////////////////////////////////
@@ -1261,6 +1281,7 @@ asm popf
void
SD_FadeOutMusic(void)
{
+#if USE_MUSIC
switch (MusicMode)
{
case smm_AdLib:
@@ -1268,6 +1289,7 @@ SD_FadeOutMusic(void)
SD_MusicOff();
break;
}
+#endif
}
///////////////////////////////////////////////////////////////////////////
@@ -1279,6 +1301,7 @@ SD_FadeOutMusic(void)
boolean
SD_MusicPlaying(void)
{
+#if USE_MUSIC
boolean result;
switch (MusicMode)
@@ -1292,4 +1315,5 @@ SD_MusicPlaying(void)
}
return(result);
+#endif
}
diff --git a/ID_SD.H b/ID_SD.H
index 701cb87..28a92db 100644
--- a/ID_SD.H
+++ b/ID_SD.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -177,6 +177,7 @@ extern boolean AdLibPresent,
extern SDMode SoundMode;
extern SMMode MusicMode;
extern longword TimeCount; // Global time in ticks
+extern SDMode oldsoundmode;
// Function prototypes
extern void SD_Startup(void),
diff --git a/ID_STRS.H b/ID_STRS.H
index 686e281..8229f58 100644
--- a/ID_STRS.H
+++ b/ID_STRS.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss 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 c1bb93e..4ff2bd3 100644
--- a/ID_US.C
+++ b/ID_US.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -465,12 +465,12 @@ USL_ScreenDraw(word x,word y,char *s,byte attr)
{
byte far *screen;
- // screen = MK_FP(0xb800,(x * 2) + (y * 80 * 2));
- // while (*s)
- // {
- // *screen++ = *s++;
- // *screen++ = attr;
- // }
+ screen = MK_FP(0xb800,(x * 2) + (y * 80 * 2));
+ while (*s)
+ {
+ *screen++ = *s++;
+ *screen++ = attr;
+ }
}
///////////////////////////////////////////////////////////////////////////
@@ -512,7 +512,7 @@ extern char far introscn;
USL_ClearTextScreen();
-// _fmemcpy(MK_FP(0xb800,0),7 + &introscn,80 * 25 * 2);
+ _fmemcpy(MK_FP(0xb800,0),7 + &introscn,80 * 25 * 2);
// Check for TED launching here
for (i = 1;i < _argc;i++)
@@ -641,12 +641,12 @@ void
US_FinishTextScreen(void)
{
// Change Loading... to Press a Key
- // USL_ScreenDraw(29,22," Ready - Press a Key ",0x9a);
+ USL_ScreenDraw(29,22," Ready - Press a Key ",0x9a);
if (!(tedlevel || NoWait))
{
IN_ClearKeysDown();
- // IN_Ack();
+ IN_Ack();
}
IN_ClearKeysDown();
diff --git a/ID_US.H b/ID_US.H
index f802cc0..bda9d2d 100644
--- a/ID_US.H
+++ b/ID_US.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -36,9 +36,6 @@
//#define HELPTEXTLINKED
-#define MaxX 320
-#define MaxY 200
-
#define MaxHelpLines 500
#define MaxHighName 57
@@ -82,6 +79,8 @@ extern boolean tedlevel;
extern word tedlevelnum;
extern void TEDDeath(void);
+extern word MaxX,MaxY; // MDM (GAMERS EDGE)
+
extern boolean ingame, // Set by game code if a game is in progress
abortgame, // Set if a game load failed
loadedgame, // Set if the current game was loaded
diff --git a/ID_US_1.C b/ID_US_1.C
index ad14b46..f8e34c0 100644
--- a/ID_US_1.C
+++ b/ID_US_1.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -67,6 +67,8 @@ extern ScanCode firescan;
word PrintX,PrintY;
word WindowX,WindowY,WindowW,WindowH;
+ word MaxX=320,MaxY=200; // MDM (GAMERS EDGE)
+
// Internal variables
#define ConfigVersion 1
@@ -198,7 +200,7 @@ oh_kill_me:
char *
USL_GiveSaveName(word game)
{
-static char name[] = "SAVEGAMx."EXTENSION;
+static char name[] = "SAVEGAMx."EXT;
name[7] = '0' + game;
return(name);
@@ -229,18 +231,18 @@ static void
USL_ReadConfig(void)
{
boolean gotit;
- char sig[sizeof(EXTENSION)];
+ char sig[sizeof(EXT)];
word version;
int file;
SDMode sd;
SMMode sm;
ControlType ctl;
- if ((file = open("CONFIG."EXTENSION,O_BINARY | O_RDONLY)) != -1)
+ if ((file = open("CONFIG."EXT,O_BINARY | O_RDONLY)) != -1)
{
- read(file,sig,sizeof(EXTENSION));
+ read(file,sig,sizeof(EXT));
read(file,&version,sizeof(version));
- if (strcmp(sig,EXTENSION) || (version != ConfigVersion))
+ if (strcmp(sig,EXT) || (version != ConfigVersion))
{
close(file);
goto rcfailed;
@@ -293,11 +295,11 @@ USL_WriteConfig(void)
int file;
version = ConfigVersion;
- file = open("CONFIG."EXTENSION,O_CREAT | O_BINARY | O_WRONLY,
+ file = open("CONFIG."EXT,O_CREAT | O_BINARY | O_WRONLY,
S_IREAD | S_IWRITE | S_IFREG);
if (file != -1)
{
- write(file,EXTENSION,sizeof(EXTENSION));
+ write(file,EXT,sizeof(EXT));
write(file,&version,sizeof(version));
write(file,Scores,sizeof(HighScore) * MaxScores);
write(file,&SoundMode,sizeof(SoundMode));
@@ -347,7 +349,7 @@ USL_CheckSavedGames(void)
if
(
(read(file,game,sizeof(*game)) == sizeof(*game))
- && (!strcmp(game->signature,EXTENSION))
+ && (!strcmp(game->signature,EXT))
&& (game->oldtest == &PrintX)
)
ok = true;
@@ -359,7 +361,7 @@ USL_CheckSavedGames(void)
game->present = true;
else
{
- strcpy(game->signature,EXTENSION);
+ strcpy(game->signature,EXT);
game->present = false;
strcpy(game->name,"Empty");
}
@@ -465,6 +467,7 @@ US_CheckParm(char *parm,char **strings)
return(-1);
}
+#if 0
///////////////////////////////////////////////////////////////////////////
//
// USL_ScreenDraw() - Draws a chunk of the text screen (called only by
@@ -490,6 +493,7 @@ USL_ScreenDraw(word x,word y,char *s,byte attr)
screen++;
}
}
+#endif
///////////////////////////////////////////////////////////////////////////
//
@@ -514,6 +518,7 @@ USL_ClearTextScreen(void)
geninterrupt(0x10);
}
+#if 0
///////////////////////////////////////////////////////////////////////////
//
// US_TextScreen() - Puts up the startup text screen
@@ -674,7 +679,7 @@ static byte colors[] = {4,6,13,15,15,15,15,15,15};
if (!(tedlevel || NoWait))
{
- // IN_ClearKeysDown();
+ IN_ClearKeysDown();
for (i = 0,up = true;!IN_UserInput(4,true);)
{
c = colors[i];
@@ -689,15 +694,16 @@ static byte colors[] = {4,6,13,15,15,15,15,15,15};
i = 1,up = true;
}
- // USL_ScreenDraw(29,22," Ready - Press a Key ",0x00 + c);
+ USL_ScreenDraw(29,22," Ready - Press a Key ",0x00 + c);
}
}
- // else
- // USL_ScreenDraw(29,22," Ready - Press a Key ",0x9a);
- // IN_ClearKeysDown();
+ else
+ USL_ScreenDraw(29,22," Ready - Press a Key ",0x9a);
+ IN_ClearKeysDown();
USL_ClearTextScreen();
}
+#endif
// Window/Printing routines
@@ -753,6 +759,31 @@ US_Print(char *s)
}
}
+// MDM - (GAMERS EDGE) begin
+
+///////////////////////////////////////////////////////////////////////////
+//
+// US_Printxy()
+//
+void US_Printxy(word x, word y, char *text)
+{
+ word orgx, orgy;
+
+ orgx = PrintX;
+ orgy = PrintY;
+
+// PrintX = WindowX+x;
+// PrintY = WindowY+y;
+ PrintX = x;
+ PrintY = y;
+ US_Print(text);
+
+ PrintX = orgx;
+ PrintY = orgy;
+}
+
+// MDM - (GAMERS EDGE) end
+
///////////////////////////////////////////////////////////////////////////
//
// US_PrintUnsigned() - Prints an unsigned long
@@ -831,7 +862,7 @@ US_CPrintLine(char *s)
USL_MeasureString(s,&w,&h);
if (w > WindowW)
- Quit("US_CPrintLine() - String exceeds width");
+ Quit("US_CPrintLine() - String exceeds width\n-->%s",s);
px = WindowX + ((WindowW - w) / 2);
py = PrintY;
USL_DrawString(s);
@@ -876,7 +907,7 @@ US_CPrint(char *s)
void
US_ClearWindow(void)
{
- VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
+ VWB_Bar(WindowX,WindowY,WindowW,WindowH,LT_GREY);
PrintX = WindowX;
PrintY = WindowY;
}
@@ -1283,3 +1314,4 @@ US_LineInput(int x,int y,char *buf,char *def,boolean escok,
IN_ClearKeysDown();
return(result);
}
+
diff --git a/ID_US_2.C b/ID_US_2.C
index d8b4dea..ab779ff 100644
--- a/ID_US_2.C
+++ b/ID_US_2.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -147,11 +147,11 @@ static boolean USL_ConfigCustom(UserCall call,struct UserItem far *item),
USL_LoadCustom(UserCall call,struct UserItem far *item),
USL_SaveCustom(UserCall call,struct UserItem far *item),
USL_ScoreCustom(UserCall call,struct UserItem far *item),
- USL_CompCustom(UserCall call,struct UserItem far *item),
+ USL_CompCustom(UserCall call,struct UserItem far *item);
#ifdef KEEN
USL_TwoCustom(UserCall call,struct UserItem far *item),
#endif
- USL_PongCustom(UserCall call,struct UserItem far *item);
+// USL_PongCustom(UserCall call,struct UserItem far *item);
#define DefButton(key,text) uii_Button,ui_Normal,key,text
#define DefRButton(key,text) uii_RadioButton,ui_Normal,key,text
@@ -281,7 +281,7 @@ static boolean USL_ConfigCustom(UserCall call,struct UserItem far *item),
UserItemGroup far configgroup = {8,0,CP_CONFIGMENUPIC,sc_None,configi,USL_ConfigCustom};
// Main menu
- UserItemGroup far ponggroup = {0,0,0,sc_None,0,USL_PongCustom};
+// UserItemGroup far ponggroup = {0,0,0,sc_None,0,USL_PongCustom};
UserItem far rooti[] =
{
{DefFolder(sc_N,"NEW GAME",&newgamegroup)},
@@ -290,7 +290,7 @@ static boolean USL_ConfigCustom(UserCall call,struct UserItem far *item),
{DefFolder(sc_C,"CONFIGURE",&configgroup)},
{DefButton(sc_R,nil),uc_Return}, // Return to Game/Demo
{DefButton(sc_E,"END GAME"),uc_Abort},
- {DefFolder(sc_B,"SKULL 'N' BONES",&ponggroup)},
+// {DefFolder(sc_B,"SKULL 'N' BONES",&ponggroup)},
{DefButton(sc_Q,"QUIT"),uc_Quit},
{uii_Bad}
};
@@ -1150,6 +1150,8 @@ USL_SaveCustom(UserCall call,UserItem far *item)
return(USL_LoadCustom(call,item));
}
+#if 0
+
#define PaddleMinX (CtlPanelSX + 3)
#define PaddleMaxX (CtlPanelEX - 15)
#define BallMinX (CtlPanelSX + 2)
@@ -1352,6 +1354,8 @@ USL_PongCustom(UserCall call,struct UserItem far *item)
return(true);
}
+#endif
+
// Flag management stuff
static void
USL_ClearFlags(UserItemGroup far *node)
@@ -1550,8 +1554,8 @@ USL_SetUpCtlPanel(void)
CA_UpLevel();
for (i = CONTROLS_LUMP_START;i <= CONTROLS_LUMP_END;i++)
CA_MarkGrChunk(i);
- for (i = PADDLE_LUMP_START;i <= PADDLE_LUMP_END;i++)
- CA_MarkGrChunk(i);
+// for (i = PADDLE_LUMP_START;i <= PADDLE_LUMP_END;i++)
+// CA_MarkGrChunk(i);
CA_MarkGrChunk(STARTFONT+1); // Little font
CA_MarkGrChunk(CP_MENUMASKPICM); // Mask for dialogs
CA_CacheMarks("Control Panel");
diff --git a/ID_US_A.ASM b/ID_US_A.ASM
index 15e6f12..c6c6130 100644
--- a/ID_US_A.ASM
+++ b/ID_US_A.ASM
@@ -1,4 +1,4 @@
-; Catacomb 3-D Source Code
+; Catacomb Abyss 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 625f08d..9a22079 100644
--- a/ID_VW.C
+++ b/ID_VW.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -176,7 +176,26 @@ void VW_SetScreenMode (int grmode)
case CGAGR: _AX = 4;
geninterrupt (0x10); // screenseg is actually a main mem buffer
break;
+
+ case EGA320GR: // MDM start (GAMERS EDGE)
+ MaxX=320;
+ MaxY=200;
+ _AX = 0xd|128;
+ geninterrupt (0x10);
+ screenseg=0xa000;
+ break;
+
+ case EGA640GR:
+ MaxX=640;
+ MaxY=200;
+ _AX = 0xe|128;
+ geninterrupt (0x10);
+ screenseg=0xa000;
+ break; // MDM end (GAMERS EDGE)
+
case EGAGR: _AX = 0xd;
+ MaxX=320;
+ MaxY=200;
geninterrupt (0x10);
screenseg=0xa000;
break;
@@ -914,7 +933,7 @@ done:
void
VWL_MeasureString (char far *string, word *width, word *height, fontstruct _seg *font)
{
- *height = font->height;
+ *height = font->height-1; // MDM (GAMERS EDGE) - squeeze font vertically...
for (*width = 0;*string;string++)
*width += font->width[*((byte far *)string)]; // proportional width
}
@@ -1371,8 +1390,8 @@ void VWB_DrawTile8M (int x, int y, int tile)
x+=pansx;
y+=pansy;
xb = x/SCREENXDIV; // use intermediate because VW_DT8M is macro
- if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+7,y+7))
- VW_DrawTile8M (xb,y,tile);
+// if (VW_MarkUpdateBlock (x&SCREENXMASK,y,(x&SCREENXMASK)+7,y+7)) // MDM (GAMER EDGE)
+ VW_DrawTile8M (xb,y,tile); // statement prevents drawing chars past 42
}
void VWB_DrawTile16 (int x, int y, int tile)
diff --git a/ID_VW.H b/ID_VW.H
index b3ae157..c9e81f0 100644
--- a/ID_VW.H
+++ b/ID_VW.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss Source Code
* Copyright (C) 1993-2014 Flat Rock Software
*
* This program is free software; you can redistribute it and/or modify
@@ -77,6 +77,7 @@
#define WHITE 15 // graphics mode independant colors
#define BLACK 0
+#define LT_GREY 7
#define FIRSTCOLOR 1
#define SECONDCOLOR 12
#define F_WHITE 0 // for XOR font drawing
diff --git a/ID_VW_A.ASM b/ID_VW_A.ASM
index 3c5132e..5debc87 100644
--- a/ID_VW_A.ASM
+++ b/ID_VW_A.ASM
@@ -1,4 +1,4 @@
-; Catacomb 3-D Source Code
+; Catacomb Abyss Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
@@ -50,6 +50,9 @@ screendest dw ?
linedelta dw ?
LABEL shiftdata0 WORD
+; dw 0
+
+if 1
dw 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
dw 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27
dw 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41
@@ -69,8 +72,12 @@ LABEL shiftdata0 WORD
dw 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237
dw 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251
dw 252, 253, 254, 255
+endif
LABEL shiftdata1 WORD
+; dw 0
+
+if 1
dw 0,32768, 1,32769, 2,32770, 3,32771, 4,32772, 5,32773, 6,32774
dw 7,32775, 8,32776, 9,32777, 10,32778, 11,32779, 12,32780, 13,32781
dw 14,32782, 15,32783, 16,32784, 17,32785, 18,32786, 19,32787, 20,32788
@@ -90,6 +97,7 @@ LABEL shiftdata1 WORD
dw 112,32880, 113,32881, 114,32882, 115,32883, 116,32884, 117,32885, 118,32886
dw 119,32887, 120,32888, 121,32889, 122,32890, 123,32891, 124,32892, 125,32893
dw 126,32894, 127,32895
+endif
LABEL shiftdata2 WORD
dw 0,16384,32768,49152, 1,16385,32769,49153, 2,16386,32770,49154, 3,16387
@@ -113,6 +121,9 @@ LABEL shiftdata2 WORD
dw 63,16447,32831,49215
LABEL shiftdata3 WORD
+; dw 0
+
+if 1
dw 0, 8192,16384,24576,32768,40960,49152,57344, 1, 8193,16385,24577,32769,40961
dw 49153,57345, 2, 8194,16386,24578,32770,40962,49154,57346, 3, 8195,16387,24579
dw 32771,40963,49155,57347, 4, 8196,16388,24580,32772,40964,49156,57348, 5, 8197
@@ -132,6 +143,7 @@ LABEL shiftdata3 WORD
dw 28, 8220,16412,24604,32796,40988,49180,57372, 29, 8221,16413,24605,32797,40989
dw 49181,57373, 30, 8222,16414,24606,32798,40990,49182,57374, 31, 8223,16415,24607
dw 32799,40991,49183,57375
+endif
LABEL shiftdata4 WORD
dw 0, 4096, 8192,12288,16384,20480,24576,28672,32768,36864,40960,45056,49152,53248
@@ -155,6 +167,9 @@ LABEL shiftdata4 WORD
dw 49167,53263,57359,61455
LABEL shiftdata5 WORD
+; dw 0
+
+if 1
dw 0, 2048, 4096, 6144, 8192,10240,12288,14336,16384,18432,20480,22528,24576,26624
dw 28672,30720,32768,34816,36864,38912,40960,43008,45056,47104,49152,51200,53248,55296
dw 57344,59392,61440,63488, 1, 2049, 4097, 6145, 8193,10241,12289,14337,16385,18433
@@ -174,6 +189,7 @@ LABEL shiftdata5 WORD
dw 7, 2055, 4103, 6151, 8199,10247,12295,14343,16391,18439,20487,22535,24583,26631
dw 28679,30727,32775,34823,36871,38919,40967,43015,45063,47111,49159,51207,53255,55303
dw 57351,59399,61447,63495
+endif
LABEL shiftdata6 WORD
dw 0, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216,10240,11264,12288,13312
@@ -197,6 +213,9 @@ LABEL shiftdata6 WORD
dw 61443,62467,63491,64515
LABEL shiftdata7 WORD
+; dw 0
+
+if 1
dw 0, 512, 1024, 1536, 2048, 2560, 3072, 3584, 4096, 4608, 5120, 5632, 6144, 6656
dw 7168, 7680, 8192, 8704, 9216, 9728,10240,10752,11264,11776,12288,12800,13312,13824
dw 14336,14848,15360,15872,16384,16896,17408,17920,18432,18944,19456,19968,20480,20992
@@ -216,6 +235,7 @@ LABEL shiftdata7 WORD
dw 49153,49665,50177,50689,51201,51713,52225,52737,53249,53761,54273,54785,55297,55809
dw 56321,56833,57345,57857,58369,58881,59393,59905,60417,60929,61441,61953,62465,62977
dw 63489,64001,64513,65025
+endif
shifttabletable dw shiftdata0,shiftdata1,shiftdata2,shiftdata3
dw shiftdata4,shiftdata5,shiftdata6,shiftdata7
diff --git a/ID_VW_AC.ASM b/ID_VW_AC.ASM
index f96072e..20f809b 100644
--- a/ID_VW_AC.ASM
+++ b/ID_VW_AC.ASM
@@ -1,4 +1,4 @@
-; Catacomb 3-D Source Code
+; Catacomb Abyss 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 13a7434..9854efe 100644
--- a/ID_VW_AE.ASM
+++ b/ID_VW_AE.ASM
@@ -1,4 +1,4 @@
-; Catacomb 3-D Source Code
+; Catacomb Abyss Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
@@ -1075,8 +1075,8 @@ propchar dw ? ; the character number to shift
stringptr dw ?,?
-BUFFWIDTH = 50
-BUFFHEIGHT = 32 ; must be twice as high as font for masked fonts
+BUFFWIDTH = 80 ; 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 6aaacd6..5f2684e 100644
--- a/JABHACK.ASM
+++ b/JABHACK.ASM
@@ -1,4 +1,4 @@
-; Catacomb 3-D Source Code
+; Catacomb Abyss Source Code
; Copyright (C) 1993-2014 Flat Rock Software
;
; This program is free software; you can redistribute it and/or modify
diff --git a/MAPSABS.H b/MAPSABS.H
index fc6bbbc..06005f9 100644
--- a/MAPSABS.H
+++ b/MAPSABS.H
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code
+/* Catacomb Abyss 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 C3D
+// TED5 Map Header for ABS
//
///////////////////////////////////////
@@ -26,26 +26,29 @@
// Map Names
//
typedef enum {
- APPROACH_MAP, // 0
- ENTRANCE_MAP, // 1
- GROUND_FLOOR_MAP, // 2
- SECOND_FLOOR_MAP, // 3
- THIRD_FLOOR_MAP, // 4
- TOWER_1_MAP, // 5
- TOWER_2_MAP, // 6
- SECRET_HALLS_MAP, // 7
- ACCESS_FLOOR_MAP, // 8
- DUNGEON_MAP, // 9
- LOWER_DUNGEON_MAP, // 10
- CATACOMB_MAP, // 11
- LOWER_REACHES_MAP, // 12
- WARRENS_MAP, // 13
- HIDDEN_CAVERNS_MAP, // 14
- FENSOFINSANITY_MAP, // 15
- CHAOSCORRIDORS_MAP, // 16
- LABYRINTH_MAP, // 17
- HALLS_OF_BLOOD_MAP, // 18
- NEMESISSLAIR_MAP, // 19
+ 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
+ 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;
@@ -53,3 +56,4 @@ typedef enum {
// TILEINFO offsets
//
#define ANIM 402
+#define FLAGS (ANIM+NUMTILE16)
diff --git a/MIKE.H b/MIKE.H
new file mode 100644
index 0000000..6768003
--- /dev/null
+++ b/MIKE.H
@@ -0,0 +1,736 @@
+/* Catacomb Abyss 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 "ID_HEADS.H"
+#include <MATH.H>
+#include <VALUES.H>
+
+//#define PROFILE
+
+/*
+=============================================================================
+
+ GLOBAL CONSTANTS
+
+=============================================================================
+*/
+
+#define PI 3.141592657
+
+#define ROTATE_SPEED (6)
+
+#define FL_QUICK 0x01
+
+#define FL_CLEAR 0x01
+
+#define GEM_SHIFT 1
+#define FL_RGEM 0x02
+#define FL_GGEM 0x04
+#define FL_BGEM 0x08
+#define FL_YGEM 0x10
+#define FL_PGEM 0x20
+
+#define MAXBOLTS 10
+#define MAXNUKES 10
+#define MAXPOTIONS 10
+
+#define NUKE_COST (1000)
+#define BOLT_COST (1200)
+#define POTION_COST (1300)
+
+#define NUKE_COST_TXT ("1000") // Allows for Q&D positioning..
+#define BOLT_COST_TXT ("1200")
+#define POTION_COST_TXT ("1300")
+
+#define RADARX 31 // bytes
+#define RADARY 11 // pixels
+#define RADAR_WIDTH 51 // "
+#define RADAR_HEIGHT 51 // "
+#define RADAR_XCENTER ((RADARX*8)+(RADAR_WIDTH/2)+3) // "
+#define RADAR_YCENTER ((RADARY-8)+(RADAR_HEIGHT/2)+5) // "
+#define MAX_RADAR_BLIPS 60
+
+
+#define RADAR_RADIUS 17
+#define RADAR_RADIUS_NSEW 15
+#define RADAR_X_IRADIUS (110/5)
+#define RADAR_Y_IRADIUS (110/7)
+#define RADAR_ICON_CENTER 4 // Center offset into icon.
+
+#define NAMESTART 180
+#define REMOVED_DOOR_TILE NAMESTART
+
+#define NEXT_LEVEL_CODE 0xff
+#define REMOVE_DOOR_CODE 0xfe
+#define CANT_OPEN_CODE 0xfd
+#define EXP_WALL_CODE 0xfc
+
+#define WALL_SKELETON_CODE 6
+
+#define UNMARKGRCHUNK(chunk) (grneeded[chunk]&=~ca_levelbit)
+
+#define MOUSEINT 0x33
+
+#define EXPWALLSTART 8
+#define NUMEXPWALLS 7
+#define WALLEXP 15
+
+#define NUMFLOORS 62+5
+
+#define NUMLATCHPICS (FIRSTWALLPIC-FIRSTLATCHPIC)+5
+#define NUMSCALEPICS (FIRSTWALLPIC-FIRSTSCALEPIC)+5
+#define NUMSCALEWALLS (LASTWALLPIC-FIRSTWALLPIC)+5
+
+
+#define FLASHCOLOR 12
+#define FLASHTICS 4
+
+
+#define NUMLEVELS 21
+
+#define VIEWX 0 // corner of view window
+#define VIEWY 0
+#define VIEWWIDTH (40*8) // size of view window // 33
+#define VIEWHEIGHT (15*8) // 18
+#define VIEWXH (VIEWX+VIEWWIDTH-1)
+#define VIEWYH (VIEWY+VIEWHEIGHT-1)
+
+#define CENTERX (VIEWX+VIEWWIDTH/2-1) // middle of view window
+#define CENTERY (VIEWY+VIEWHEIGHT/2-1)
+
+#define GLOBAL1 (1l<<16)
+#define TILEGLOBAL GLOBAL1
+#define TILESHIFT 16l
+
+#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
+#define MAXACTORS 100 // max number of tanks, etc / map
+
+#define NORTH 0
+#define EAST 1
+#define SOUTH 2
+#define WEST 3
+
+#define SIGN(x) ((x)>0?1:-1)
+#define ABS(x) ((int)(x)>0?(x):-(x))
+#define LABS(x) ((long)(x)>0?(x):-(x))
+
+#define MAXSCALE (VIEWWIDTH/2)
+
+
+#define MAXBODY 64
+#define MAXSHOTPOWER 56
+
+#define SCREEN1START 0
+#define SCREEN2START 8320
+
+//#define STATUallptr);
+void TraceRay (unsigned angle);
+fixed FixedByFrac (fixed a, fixed b);
+void TransformPoint (fixed gx, fixed gy, int *screenx, unsigned *screenheight);
+fixed TransformX (fixed gx, fixed gy);
+int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max);
+void ForwardTrace (void);
+int FinishWall (void);
+int TurnClockwise (void);
+int TurnCounterClockwise (void);
+void FollowWall (void);
+
+void NewScene (void);
+void BuildTables (void);
+
+
+/*
+=============================================================================
+
+ C3_SCALE DEFINITIONS
+
+=============================================================================
+*/
+
+
+#define COMPSCALECODESTART (65*6) // offset to start of code in comp scaler
+
+typedef struct
+{
+ unsigned codeofs[65];
+ unsigned start[65];
+ unsigned width[65];
+ byte code[];
+} t_compscale;
+
+typedef struct
+{
+ unsigned width;
+ unsigned codeofs[64];
+} t_compshape;
+
+
+extern unsigned scaleblockwidth,
+ scaleblockheight,
+ scalet pixel of wall (may not be visable)
+ unsigned height1,height2,color,walllength,side;
+ long planecoord;
+} walltype;
+
+typedef enum
+ {nothing,playerobj,bonusobj,orcobj,batobj,skeletonobj,trollobj,demonobj,
+ mageobj,pshotobj,bigpshotobj,mshotobj,inertobj,bounceobj,grelmobj,
+ gateobj,zombieobj,spookobj,wetobj,expobj,eyeobj,eshotobj,wallskelobj,
+ solidobj} 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;
+
+
+typedef struct objstruct
+{
+ enum {no,noalways,yes,always} active;
+ int ticcount;
+ classtype obclass;
+ statetype *state;
+
+ boolean shootable;
+ 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;
+
+
+typedef enum {ex_stillplaying,ex_died,ex_warped,ex_resetgame
+ ,ex_loadedgame,ex_victorious,ex_abort} exittype;
+
+
+typedef struct {
+ char x,y;
+ unsigned ondoor,underdoor;
+} doorinfo;
+
+typedef struct {
+ char x,y;
+ short angle;
+// doorinfo doors[MAX_DOOR_STORAGE];
+} levelinfo;
+
+typedef struct
+{
+ int difficulty;
+ int mapon;
+ int bolts,nukes,potions,keys[4],scrolls[8],gems[5];
+ long score;
+ int body,shotpower;
+ levelinfo levels[NUMLEVELS];
+} gametype;
+
+/*
+=============================================================================
+
+ C3_MAIN DEFINITIONS
+
+=============================================================================
+*/
+
+extern char inlevel[][2];
+extern char str[80],str2[20];
+extern unsigned tedlevelnum;
+extern boolean tedlevel;
+extern gametype gamestate;
+extern exittype playstate;
+extern char SlowMode;
+extern unsigned Flags;
+
+
+void NewGame (void);
+boolean SaveTheGame(int file);
+boolean LoadTheGame(int file);
+void ResetGame(void);
+void ShutdownId (void);
+void InitGame (void);
+void Quit (char *error);
+void TEDDeath(void);
+void DemoLoop (void);
+void SetupScalePic (unsigned picnum);
+void SetupScaleWall (unsigned picnum);
+void SetupScaling (void);
+void main (void);
+
+/*
+=============================================================================
+
+ C3_GAME DEFINITIONS
+
+=============================================================================
+*/
+
+extern unsigned latchpics[NUMLATCHPICS];
+extern unsigned tileoffsets[NUMTILE16];
+extern unsigned textstarts[27];
+
+
+#define L_CHARS 0
+#define L_NOSHOT 1
+#define L_SHOTBAR 2
+#define L_NOBODY 3
+#define L_BODYBAR 4
+
+
+void ScanInfoPlane (void);
+void ScanText (void);
+void SetupGameLevel (void);
+void Victory (void);
+void Died (void);
+void NormalScreen (void);
+void DrawPlayScreen (void);
+void LoadLatchMem (void);
+void FizzleFade (unsigned source, unsigned dest,
+ unsigned width,unsigned height, boolean abortable);
+void FizzleOut (int showlevel);
+void FreeUpMemory (void);
+void GameLoop (void);
+
+
+/*
+=============================================================================
+
+ C3_PLAY DEFINITIONS
+
+=============================================================================
+*/
+
+#define BGF_NIGHT 0x01 // it is officially night
+#define BGF_NOT_LIGHTNING 0x02 // lightning flash has ended
+
+extern byte BGFLAGS;
+
+extern unsigned *skycolor,*groundcolor;
+
+extern ControlInfo c;
+extern boolean running,slowturn;
+
+extern int bordertime;
+
+extern byte tilemap[MAPSIZE][MAPSIZE];
+extern objtype *actorat[MAPSIZE][MAPSIZE];
+extern byte spotvis[MAPSIZE][MAPSIZE];
+
+extern objtype objlist[MAXACTORS],*new,*obj,*player;
+
+extern unsigned farmapylookup[MAPSIZE];
+extern byte *nearmapylookup[MAPSIZE];
+extern byte update[];
+
+extern boolean godmode,singlestep;
+extern int extravbls;
+
+extern int mousexmove,mouseymove;
+extern int pointcount,pointsleft;
+
+
+void CenterWindow(word w,word h);
+void DebugMemory (void);
+void PicturePause (void);
+int DebugKeys (void);
+void CheckKeys (void);
+void InitObjList (void);
+void GetNewObj (boolean usedummy);
+void RemoveObj (objtype *gone);
+void PollControlls (void);
+void PlayLoop (void);
+void InitBgChange(short stimer, unsigned *scolors, short gtimer, unsigned *gcolors, byte flag);
+char GetKeyChoice(char *choices,boolean clear);
+
+
+/*
+=============================================================================
+
+ C3_STATE DEFINITIONS
+
+=============================================================================
+*/
+
+void SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size);
+void SpawnNewObjFrac (long x, long y, statetype *state, unsigned size);
+boolean CheckHandAttack (objtype *ob);
+void T_DoDamage (objtype *ob);
+boolean Walk (objtype *ob);
+void ChaseThink (objtype *obj, boolean diagonal);
+void MoveObj (objtype *ob, long move);
+boolean Chase (objtype *ob, boolean diagonal);
+
+extern dirtype opposite[9];
+
+/*
+=============================================================================
+
+ C3_TRACE DEFINITIONS
+
+=============================================================================
+*/
+
+int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max);
+int BackTrace (int finish);
+void ForwardTrace (void);
+int FinishWall (void);
+void InsideCorner (void);
+void OutsideCorner (void);
+void FollowWalls (void);
+
+extern boolean aborttrace;
+
+/*
+=============================================================================
+
+ C3_DRAW DEFINITIONS
+
+=============================================================================
+*/
+
+#define MAXWALLS 50
+#define DANGERHIGH 45
+
+#define MIDWALL (MAXWALLS/2)
+
+//==========================================================================
+
+extern tilept tile,lasttile,focal,left,mid,right;
+
+extern globpt edge,view;
+
+extern unsigned screenloc[3];
+extern unsigned freelatch;
+
+extern int screenpage;
+
+extern boolean fizzlein;
+
+extern long lasttimecount;
+
+extern int firstangle,lastangle;
+
+extern fixed prestep;
+
+extern int traceclip,tracetop;
+
+extern fixed sintable[ANGLES+ANGLES/4],*costable;
+
+extern fixed viewx,viewy,viewsin,viewcos; // the focal point
+extern int viewangle;
+
+extern fixed scale,scaleglobal;
+extern unsigned slideofs;
+
+extern int zbuffer[VIEWXH+1];
+
+extern walltype walls[MAXWALLS],*leftwall,*rightwall;
+
+
+extern fixed tileglobal;
+extern fixed focallength;
+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 unsigned topcolor,bottomcolor;
+
+//==========================================================================
+
+void DrawLine (int xl, int xh, int y,int color);
+void DrawWall (walltype *wallptr);
+void TraceRay (unsigned angle);
+fixed FixedByFrac (fixed a, fixed b);
+void TransformPoint (fixed gx, fixed gy, int *screenx, unsigned *screenheight);
+fixed TransformX (fixed gx, fixed gy);
+int FollowTrace (fixed tracex, fixed tracey, long deltax, long deltay, int max);
+void ForwardTrace (void);
+int FinishWall (void);
+int TurnClockwise (void);
+int TurnCounterClockwise (void);
+void FollowWall (void);
+
+void NewScene (void);
+void BuildTables (void);
+
+
+/*
+===============================tarted%
+
+
+SDL_ShutPCr
+
+
+
+SDL_ShutALw
+MusicGroup/
+AdLibSound byteSMMode'size_t
+ ptrdiff_t SoundCommon
+soundnames+ ActiveTrackZlongword SDMode#fpos_tPCSoundScanCoblockdest;
+
+extern byte plotpix[8];
+extern byte bitmasks1[8][8];
+extern byte bitmasks2[8][8];
+
+
+extern t_compscale _seg *scaledirectory[MAXSCALE+1];
+extern t_compshape _seg *shapedirectory[NUMSCALEPICS];
+extern memptr walldirectory[NUMSCALEWALLS];
+extern unsigned shapesize[MAXSCALE+1];
+
+void DeplanePic (int picnum);
+void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale);
+unsigned BuildCompShape (t_compshape _seg **finalspot);
+
+
+/*
+=============================================================================
+
+ C3_ASM DEFINITIONS
+
+=============================================================================
+*/
+
+extern unsigned wallheight [VIEWWIDTH];
+extern unsigned wallwidth [VIEWWIDTH];
+extern unsigned wallseg [VIEWWIDTH];
+extern unsigned wallofs [VIEWWIDTH];
+extern unsigned screenbyte [VIEWWIDTH];
+extern unsigned screenbit [VIEWWIDTH];
+extern unsigned bitmasks [64];
+
+extern long wallscalecall;
+
+void ScaleWalls (void);
+
+/*
+=============================================================================
+
+ C3_WIZ DEFINITIONS
+
+=============================================================================
+*/
+
+#define MAXHANDHEIGHT 72
+
+extern statetype s_pshot1;
+extern statetype s_pshot2;
+
+extern statetype s_pshot_exp1;
+extern statetype s_pshot_exp2;
+extern statetype s_pshot_exp3;
+
+extern long lastnuke;
+extern int handheight;
+extern int boltsleft;
+extern short RadarXY[][3];
+
+void DrawText (boolean draw_text_whether_it_needs_it_or_not);
+char DisplayMsg(char *text,char *choices);
+
+extern short RotateAngle;
+extern boolean FreezeTime;
+
+//void FaceDir(short x, short y, boolean StopTime);
+//short CalcAngle(short dx, short dy);
+
+void FaceAngle(short DestAngle);
+void RotateView();
+void InitRotate(short DestAngle);
+short FaceDoor(short x, short y);
+
+
+/*
+=============================================================================
+
+ C3_ACT1 DEFINITIONS
+
+=============================================================================
+*/
+
+extern short zombie_base_delay;
+
+extern statetype s_trollouch;
+extern statetype s_trolldie1;
+
+
+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;
+
+
+extern statetype s_demonouch;
+extern statetype s_demondie1;
+
+extern statetype s_mageouch;
+extern statetype s_magedie1;
+
+extern statetype s_grelouch;
+extern statetype s_greldie1;
+
+extern statetype s_batdie1;
+
+extern statetype s_zombie_death1;
+extern statetype s_zombie_ouch;
+
+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_skel_pause;
+extern statetype s_skel_1;
+extern statetype s_skel_2;
+extern statetype s_skel_3;
+extern statetype s_skel_4;
+extern statetype s_skel_attack1;
+extern statetype s_skel_attack2;
+extern statetype s_skel_attack3;
+extern statetype s_skel_ouch;
+extern statetype s_skel_die1;
+extern statetype s_skel_die2;
+extern statetype s_skel_die3;
+
+extern statetype s_wet_pause;
+
+extern statetype s_wet_bubbles1;
+extern statetype s_wet_bubbles2;
+extern statetype s_wet_bubbles3;
+extern statetype s_wet_bubbles4;
+
+extern statetype s_wet_peek;
+
+extern statetype s_wet_rise1;
+extern statetype s_wet_rise2;
+extern statetype s_wet_rise3;
+extern statetype s_wet_rise4;
+extern statetype s_wet_rise5;
+
+extern statetype s_wet_sink1;
+extern statetype s_wet_sink2;
+extern statetype s_wet_sink3;
+
+extern statetype s_wet_walk1;
+extern statetype s_wet_walk2;
+extern statetype s_wet_walk3;
+extern statetype s_wet_walk4;
+
+extern statetype s_wet_attack1;
+extern statetype s_wet_attack2;
+extern statetype s_wet_attack3;
+extern statetype s_wet_attack4;
+
+extern statetype s_wet_ouch;
+
+extern statetype s_wet_die1;
+extern statetype s_wet_die2;
+extern statetype s_wet_die3;
+extern statetype s_wet_die4;
+extern statetype s_wet_die5;
+
+
+extern statetype s_eye_pause;
+
+extern statetype s_eye_1;
+extern statetype s_eye_2;
+extern statetype s_eye_3;
+
+//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;
+
+extern statetype s_eye_die1;
+extern statetype s_eye_die2;
+extern statetype s_eye_die3;
+
+extern statetype s_mshot1;
+extern statetype s_mshot2;
+
+extern statetype s_obj_gate1;
+extern statetype s_obj_gate2;
+extern statetype s_obj_gate3;
+extern statetype s_obj_gate4;
+
diff --git a/README.md b/README.md
index 307d3b2..a1c774a 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,16 @@
-Catacomb 3-D: The Descent
-=========================
+The Catacomb Abyss
+==================
-This repository contains the source code for Catacomb 3-D (also known as
-Catacombs 3 or Catacomb 3-D: A New Dimension). 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 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.
It is released under the GNU GPLv2. Please see COPYING for license details.
This release does not affect the licensing for the game data files. You will
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`
diff --git a/_SHRWARE.OBJ b/_SHRWARE.OBJ
new file mode 100644
index 0000000..7626b6e
--- /dev/null
+++ b/_SHRWARE.OBJ
Binary files differ