Catacomb Abyss open source release.
authorRichard Mandel <richard@tech-transfer.com>
Sat, 7 Jun 2014 03:31:43 +0000 (23:31 -0400)
committerRichard Mandel <richard@tech-transfer.com>
Sat, 7 Jun 2014 03:31:43 +0000 (23:31 -0400)
53 files changed:
ABSADICT.OBJ
ABSAHEAD.OBJ
ABSEDICT.OBJ
ABSEHEAD.OBJ
ABSMHEAD.OBJ
ABYSGAME.PRJ
AUDIOABS.H
C4_ACT1.C
C4_ASM.ASM
C4_DEBUG.C
C4_DRAW.C
C4_GAME.C
C4_MAIN.C
C4_PLAY.C
C4_SCALE.C
C4_SCA_A.ASM
C4_STATE.C
C4_TRACE.C
C4_WIZ.C
DEF.H
GELIB.C [new file with mode: 0644]
GELIB.H [new file with mode: 0644]
GFXE_ABS.EQU
GFXE_ABS.H
ID_ASM.EQU
ID_CA.C
ID_CA.H
ID_HEADS.H
ID_IN.C
ID_IN.H
ID_MM.C
ID_MM.H
ID_RF.C
ID_RF.H
ID_RF_A.ASM
ID_SD.C
ID_SD.H
ID_STRS.H
ID_US.C
ID_US.H
ID_US_1.C
ID_US_2.C
ID_US_A.ASM
ID_VW.C
ID_VW.H
ID_VW_A.ASM
ID_VW_AC.ASM
ID_VW_AE.ASM
JABHACK.ASM
MAPSABS.H
MIKE.H [new file with mode: 0644]
README.md
_SHRWARE.OBJ [new file with mode: 0644]

index c2f9fdaf068880229749bf824d8262c028112355..b0e8792347769d2702986979e80716691b9a9867 100644 (file)
Binary files a/ABSADICT.OBJ and b/ABSADICT.OBJ differ
index 8906d303e19a8ea68863baf26f502faedf4b470b..9feed1a25dc7f5933965819e8a2bbf18b22fa24f 100644 (file)
Binary files a/ABSAHEAD.OBJ and b/ABSAHEAD.OBJ differ
index 991491ac1f1f441e2bd0b951eaa29a8c5b93ccb6..2b16875ac24a6074a8f121758ef5ea03c4a7e389 100644 (file)
Binary files a/ABSEDICT.OBJ and b/ABSEDICT.OBJ differ
index df8c6b22d0a012260506cb260408522f6378c397..be2b224398df6b4d36a9504c83e14369d150dbb2 100644 (file)
Binary files a/ABSEHEAD.OBJ and b/ABSEHEAD.OBJ differ
index 16079143eac2ac95a187c91a061312471e7af25b..e227b29ee1c6c03bdd842d623438024cbbb62dfa 100644 (file)
Binary files a/ABSMHEAD.OBJ and b/ABSMHEAD.OBJ differ
index 33d75d4a1f0cfa21f250cd2a22188063ce8c7359..d5e9a9546569cc56ceabcb69e06935c249fa7348 100644 (file)
Binary files a/ABYSGAME.PRJ and b/ABYSGAME.PRJ differ
index 44da68faef1151d9b54b39b4942cb2af4fc6e764..2187679cec30ebca691cde4afd745b43fb02cd90 100644 (file)
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code\r
+/* Catacomb Abyss Source Code\r
  * Copyright (C) 1993-2014 Flat Rock Software\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
 \r
 /////////////////////////////////////////////////\r
 //\r
-// MUSE Header for .C3D\r
-// Created Wed Oct 30 22:44:13 1991\r
+// MUSE Header for .ABS\r
+// Created Thu Apr 16 14:56:19 1992\r
 //\r
 /////////////////////////////////////////////////\r
 \r
-#define NUMSOUNDS              30\r
-#define NUMSNDCHUNKS           91\r
+#define NUMSOUNDS              34\r
+#define NUMSNDCHUNKS           103\r
 \r
 //\r
 // Sound names & indexes\r
@@ -55,11 +55,15 @@ typedef enum {
                SHOOTMONSTERSND,         // 22\r
                TAKEDMGHURTSND,          // 23\r
                BALLBOUNCESND,           // 24\r
-               COMPSCOREDSND,           // 25\r
-               KEENSCOREDSND,           // 26\r
-               COMPPADDLESND,           // 27\r
-               KEENPADDLESND,           // 28\r
-               NOWAYSND,                // 29\r
+               NOWAYSND,                // 25\r
+               WARPSND,                 // 26\r
+               HIT_GATESND,             // 27\r
+               GETGEMSND,               // 28\r
+               BOOMSND,                 // 29\r
+               GRELM_DEADSND,           // 30\r
+               FREEZETIMESND,           // 31\r
+               TIMERETURNSND,           // 32\r
+               TICKSND,                 // 33\r
                LASTSOUND\r
             } soundnames;\r
 \r
@@ -67,9 +71,9 @@ typedef enum {
 // Base offsets\r
 //\r
 #define STARTPCSOUNDS          0\r
-#define STARTADLIBSOUNDS       30\r
-#define STARTDIGISOUNDS                60\r
-#define STARTMUSIC             90\r
+#define STARTADLIBSOUNDS       34\r
+#define STARTDIGISOUNDS                68\r
+#define STARTMUSIC             102\r
 \r
 //\r
 // Music names & indexes\r
index 2706b4f1c3b59ef28747945562853c333952bf83..4749b1ba15fe5e9675496b1cb040ec2cb48aef70 100644 (file)
--- a/C4_ACT1.C
+++ b/C4_ACT1.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code\r
+/* Catacomb Abyss Source Code\r
  * Copyright (C) 1993-2014 Flat Rock Software\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
@@ -18,7 +18,7 @@
 \r
 // C3_PLAY.C\r
 \r
-#include "C3_DEF.H"\r
+#include "DEF.H"\r
 #pragma hdrstop\r
 \r
 /*\r
 \r
 =============================================================================\r
 */\r
+void SpawnSkeleton(int tilex, int tiley);\r
 \r
 \r
+#define MSHOTDAMAGE    2\r
+#define MSHOTSPEED     10000\r
+\r
+#define ESHOTDAMAGE    1\r
+#define ESHOTSPEED     5000\r
+\r
+#define RANDOM_ATTACK 20\r
+\r
 /*\r
 =============================================================================\r
 \r
 =============================================================================\r
 */\r
 \r
+boolean ShootPlayer (objtype *ob, short obclass, short speed, statetype *state);\r
+void T_ShootPlayer(objtype *ob);\r
+\r
+short zombie_base_delay;\r
+\r
+short other_x[] = {0,39,39,0},\r
+               other_y[] = {0,0,27,27};\r
 \r
 \r
 /*\r
@@ -64,21 +80,50 @@ dirtype dirtable[9] = {northwest,north,northeast,west,nodir,east,
 \r
 extern statetype       s_boltbonus2;\r
 extern statetype       s_nukebonus2;\r
+extern statetype       s_boltbonus3;\r
+extern statetype       s_nukebonus3;\r
 \r
 statetype s_boltbonus = {BOLTOBJPIC,8,NULL,&s_boltbonus2};\r
-statetype s_boltbonus2 = {BOLTOBJ2PIC,8,NULL,&s_boltbonus};\r
+statetype s_boltbonus2 = {BOLT2OBJPIC,8,NULL,&s_boltbonus3};\r
+statetype s_boltbonus3 = {BOLT3OBJPIC,8,NULL,&s_boltbonus};\r
 \r
 statetype s_nukebonus = {NUKEOBJPIC,8,NULL,&s_nukebonus2};\r
-statetype s_nukebonus2 = {NUKEOBJ2PIC,8,NULL,&s_nukebonus};\r
+statetype s_nukebonus2 = {NUKE2OBJPIC,8,NULL,&s_nukebonus3};\r
+statetype s_nukebonus3 = {NUKE3OBJPIC,8,NULL,&s_nukebonus};\r
 \r
 statetype s_potionbonus = {POTIONOBJPIC,0,NULL,&s_potionbonus};\r
+statetype s_rkey2bonus = {RKEY2PIC,0,NULL,&s_rkey2bonus};\r
 statetype s_rkeybonus = {RKEYOBJPIC,0,NULL,&s_rkeybonus};\r
 statetype s_ykeybonus = {YKEYOBJPIC,0,NULL,&s_ykeybonus};\r
 statetype s_gkeybonus = {GKEYOBJPIC,0,NULL,&s_gkeybonus};\r
 statetype s_bkeybonus = {BKEYOBJPIC,0,NULL,&s_bkeybonus};\r
 statetype s_scrollbonus = {SCROLLOBJPIC,0,NULL,&s_scrollbonus};\r
 statetype s_chestbonus = {CHESTOBJPIC,0,NULL,&s_chestbonus};\r
-statetype s_goalbonus = {NEMESISPIC,0,NULL,&s_goalbonus};\r
+//statetype s_goalbonus = {NEMESISPIC,0,NULL,&s_goalbonus};\r
+\r
+extern statetype s_waterchestbonus2;\r
+statetype s_waterchestbonus1 = {O_WATER_CHEST1PIC,8,NULL,&s_waterchestbonus2};\r
+statetype s_waterchestbonus2 = {O_WATER_CHEST2PIC,8,NULL,&s_waterchestbonus1};\r
+\r
+extern statetype s_rgem2bonus;\r
+extern statetype s_ygem2bonus;\r
+extern statetype s_ggem2bonus;\r
+extern statetype s_bgem2bonus;\r
+extern statetype s_pgem2bonus;\r
+\r
+statetype s_rgem1bonus = {RGEM1PIC,30,NULL,&s_rgem2bonus};\r
+statetype s_ygem1bonus = {YGEM1PIC,30,NULL,&s_ygem2bonus};\r
+statetype s_ggem1bonus = {GGEM1PIC,30,NULL,&s_ggem2bonus};\r
+statetype s_bgem1bonus = {BGEM1PIC,30,NULL,&s_bgem2bonus};\r
+statetype s_pgem1bonus = {PGEM1PIC,30,NULL,&s_pgem2bonus};\r
+\r
+statetype s_rgem2bonus = {RGEM2PIC,30,NULL,&s_rgem1bonus};\r
+statetype s_ygem2bonus = {YGEM2PIC,30,NULL,&s_ygem1bonus};\r
+statetype s_ggem2bonus = {GGEM2PIC,30,NULL,&s_ggem1bonus};\r
+statetype s_bgem2bonus = {BGEM2PIC,30,NULL,&s_bgem1bonus};\r
+statetype s_pgem2bonus = {PGEM2PIC,30,NULL,&s_pgem1bonus};\r
+\r
+statetype s_bonus_die = {0,8,NULL,NULL};\r
 \r
 /*\r
 ===============\r
@@ -90,37 +135,123 @@ statetype s_goalbonus = {NEMESISPIC,0,NULL,&s_goalbonus};
 \r
 void SpawnBonus (int tilex, int tiley, int number)\r
 {\r
+       extern unsigned gnd_colors[];\r
+\r
        statetype *state;\r
 \r
-       if (number == B_BOLT)\r
-               state = &s_boltbonus;\r
-       else if (number == B_NUKE)\r
-               state = &s_nukebonus;\r
-       else if (number == B_POTION)\r
-               state = &s_potionbonus;\r
-       else if (number == B_RKEY)\r
-               state = &s_rkeybonus;\r
-       else if (number == B_YKEY)\r
-               state = &s_ykeybonus;\r
-       else if (number == B_GKEY)\r
-               state = &s_gkeybonus;\r
-       else if (number == B_BKEY)\r
-               state = &s_bkeybonus;\r
-       else if (number >= B_SCROLL1 && number <= B_SCROLL8)\r
-               state = &s_scrollbonus;\r
-       else if (number == B_CHEST)\r
-               state = &s_chestbonus;\r
-       else if (number == B_GOAL)\r
-               state = &s_goalbonus;\r
+       switch (number)\r
+       {\r
+               case B_BOLT:                    state = &s_boltbonus;           break;\r
+               case B_NUKE:                    state = &s_nukebonus;           break;\r
+               case B_POTION:                  state = &s_potionbonus;         break;\r
+\r
+               case B_RKEY:                    state = &s_rkeybonus;           break;\r
+               case B_YKEY:                    state = &s_ykeybonus;           break;\r
+               case B_GKEY:                    state = &s_gkeybonus;           break;\r
+               case B_BKEY:                    state = &s_bkeybonus;           break;\r
+\r
+               case B_RGEM:                    state = &s_rgem1bonus;          break;\r
+               case B_YGEM:                    state = &s_ygem1bonus;          break;\r
+               case B_GGEM:                    state = &s_ggem1bonus;          break;\r
+               case B_BGEM:                    state = &s_bgem1bonus;          break;\r
+               case B_PGEM:                    state = &s_pgem1bonus;          break;\r
+\r
+               case B_CHEST:\r
+                       if (gnd_colors[gamestate.mapon] == 0x0101)\r
+                               state = &s_waterchestbonus1;\r
+                       else\r
+                               state = &s_chestbonus;\r
+               break;\r
+\r
+               case B_SCROLL1:\r
+               case B_SCROLL2:\r
+               case B_SCROLL3:\r
+               case B_SCROLL4:\r
+               case B_SCROLL5:\r
+               case B_SCROLL6:\r
+               case B_SCROLL7:\r
+               case B_SCROLL8:                 state = &s_scrollbonus;         break;\r
+\r
+               case B_RKEY2:                   state = &s_rkey2bonus;          break;\r
+\r
+               default:\r
+                       Quit("SpawnBonus(): INVALID BONUS");\r
+               break;\r
+       }\r
 \r
        SpawnNewObj (tilex,tiley,state,TILEGLOBAL/2);\r
-       new->tileobject = true;\r
+//     new->tileobject = true;\r
        new->temp1 = number;\r
        new->obclass = bonusobj;\r
-       new->shootable = false;\r
+\r
+       switch (number)\r
+       {\r
+               case B_POTION:\r
+               case B_CHEST:\r
+               case B_BOLT:\r
+               case B_NUKE:\r
+                       new->flags |= of_shootable;\r
+               break;\r
+\r
+               default:\r
+                       new->flags &= ~of_shootable;\r
+               break;\r
+       }\r
 }\r
 \r
 \r
+/*\r
+===============\r
+=\r
+= SpawnTombstone\r
+=\r
+===============\r
+*/\r
+\r
+statetype s_tombs[3] = {{TOMB1PIC,8,NULL,&s_tombs[0]},\r
+                                                               {TOMB2PIC,8,NULL,&s_tombs[1]},\r
+                                                               {TOMB3PIC,8,NULL,&s_tombs[2]}};\r
+\r
+void SpawnTombstone (int tilex, int tiley, int shape)\r
+{\r
+       statetype *state=&s_tombs[shape];\r
+\r
+       SpawnNewObj (tilex,tiley,state,TILEGLOBAL/2);\r
+//     new->tileobject = true;\r
+       new->obclass = solidobj;\r
+       new->flags |= of_shootable;\r
+}\r
+\r
+\r
+/*\r
+============================================================================\r
+\r
+                                                                       FREEZE TIME OBJECT\r
+\r
+============================================================================\r
+*/\r
+\r
+extern statetype s_ftimebonus;\r
+extern statetype s_ftimebonus2;\r
+\r
+statetype s_ftimebonus = {TIMEOBJ1PIC,6,NULL,&s_ftimebonus2};\r
+statetype s_ftimebonus2 = {TIMEOBJ2PIC,6,NULL,&s_ftimebonus};\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnFTime\r
+=\r
+===============\r
+*/\r
+void SpawnFTime(int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_ftimebonus,TILEGLOBAL/2);\r
+//     new->tileobject = true;\r
+       new->obclass = freezeobj;\r
+       new->flags |= of_shootable;\r
+}\r
+\r
 /*\r
 =============================================================================\r
 \r
@@ -154,13 +285,24 @@ statetype s_walldie6 = {0,-1,T_WallDie,NULL};
 ================\r
 */\r
 \r
+       extern unsigned gnd_colors[];\r
+\r
 void ExplodeWall (int tilex, int tiley)\r
 {\r
-       SpawnNewObj (tilex,tiley,&s_walldie1,0);\r
+       unsigned tilenum;\r
+\r
+       DSpawnNewObj (tilex,tiley,&s_walldie1,0);\r
+       if (new == &dummyobj)\r
+               return;\r
        new->obclass = inertobj;\r
-       new->active = true;\r
+       new->active = always;\r
+       if (gnd_colors[gamestate.mapon] == 0x0101)\r
+               tilenum = WATEREXP;\r
+       else\r
+               tilenum = WALLEXP;\r
        (unsigned)actorat[new->tilex][new->tiley] = tilemap[new->tilex][new->tiley] =\r
-       *(mapsegs[0]+farmapylookup[new->tiley]+new->tilex) = WALLEXP;\r
+               *(mapsegs[0]+farmapylookup[new->tiley]+new->tilex) = tilenum;\r
+       *(mapsegs[2]+farmapylookup[new->tiley]+new->tilex) &= 0xFF;\r
 }\r
 \r
 \r
@@ -174,86 +316,81 @@ void ExplodeWall (int tilex, int tiley)
 \r
 void T_WallDie (objtype *ob)\r
 {\r
-       unsigned tile,other;\r
+       unsigned tile,other,spot,x,y;\r
 \r
        if (++ob->temp1 == 3)\r
                tile = 0;\r
        else\r
-               tile = WALLEXP-1 + ob->temp1;\r
+               if (gnd_colors[gamestate.mapon] == 0x0101)\r
+                       tile = WATEREXP-1 + ob->temp1;\r
+               else\r
+                       tile = WALLEXP-1 + ob->temp1;\r
+       x = ob->tilex;\r
+       y = ob->tiley;\r
 \r
-       (unsigned)actorat[ob->tilex][ob->tiley] = tilemap[ob->tilex][ob->tiley] =\r
-       *(mapsegs[0]+farmapylookup[ob->tiley]+ob->tilex) = tile;\r
+       (unsigned)actorat[x][y] = tilemap[x][y] = *(mapsegs[0]+farmapylookup[y]+x) = tile;\r
 \r
        if (ob->temp1 == 1)\r
        {\r
        //\r
        // blow up nearby walls\r
        //\r
-               other = tilemap[ob->tilex-1][ob->tiley];\r
-               if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)\r
-                       ExplodeWall (ob->tilex-1,ob->tiley);\r
-               other = tilemap[ob->tilex+1][ob->tiley];\r
-               if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)\r
-                       ExplodeWall (ob->tilex+1,ob->tiley);\r
-               other = tilemap[ob->tilex][ob->tiley-1];\r
-               if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)\r
-                       ExplodeWall (ob->tilex,ob->tiley-1);\r
-               other = tilemap[ob->tilex][ob->tiley+1];\r
-               if ((unsigned)(other-EXPWALLSTART)<NUMEXPWALLS)\r
-                       ExplodeWall (ob->tilex,ob->tiley+1);\r
+               spot = (*(mapsegs[2]+farmapylookup[y]+(x-1))) >> 8;\r
+               if (spot == EXP_WALL_CODE)\r
+                       ExplodeWall (x-1,y);\r
+               spot = (*(mapsegs[2]+farmapylookup[y]+(x+1))) >> 8;\r
+               if (spot == EXP_WALL_CODE)\r
+                       ExplodeWall (x+1,y);\r
+               spot = (*(mapsegs[2]+farmapylookup[y-1]+x)) >> 8;\r
+               if (spot == EXP_WALL_CODE)\r
+                       ExplodeWall (x,y-1);\r
+               spot = (*(mapsegs[2]+farmapylookup[y+1]+x)) >> 8;\r
+               if (spot == EXP_WALL_CODE)\r
+                       ExplodeWall (x,y+1);\r
        }\r
 }\r
-\r
-\r
 /*\r
 =============================================================================\r
 \r
-                                                WARP GATE\r
+                                                               OBJ_WARP GATE\r
 \r
 =============================================================================\r
 */\r
 \r
 void T_Gate (objtype *ob);\r
 \r
-extern statetype s_gate1;\r
-extern statetype s_gate2;\r
-extern statetype s_gate3;\r
-extern statetype s_gate4;\r
+extern statetype s_obj_gate1;\r
+extern statetype s_obj_gate2;\r
+extern statetype s_obj_gate3;\r
+extern statetype s_obj_gate4;\r
 \r
-extern statetype s_fgate1;\r
-extern statetype s_fgate2;\r
-extern statetype s_fgate3;\r
-extern statetype s_fgate4;\r
+statetype s_obj_gate1 = {OBJ_WARP1PIC,10,T_Gate,&s_obj_gate2};\r
+statetype s_obj_gate2 = {OBJ_WARP2PIC,10,T_Gate,&s_obj_gate3};\r
+statetype s_obj_gate3 = {OBJ_WARP3PIC,10,T_Gate,&s_obj_gate4};\r
+statetype s_obj_gate4 = {OBJ_WARP4PIC,10,T_Gate,&s_obj_gate1};\r
 \r
-statetype s_gate1 = {WARP1PIC,12,T_Gate,&s_gate2};\r
-statetype s_gate2 = {WARP2PIC,12,T_Gate,&s_gate3};\r
-statetype s_gate3 = {WARP3PIC,12,T_Gate,&s_gate4};\r
-statetype s_gate4 = {WARP4PIC,12,T_Gate,&s_gate1};\r
+statetype s_pit = {PITOBJPIC,6,T_Gate,&s_pit};\r
 \r
-statetype s_fgate1 = {WARP1PIC,6,T_Gate,&s_fgate2};\r
-statetype s_fgate2 = {WARP2PIC,6,T_Gate,&s_fgate3};\r
-statetype s_fgate3 = {WARP3PIC,6,T_Gate,&s_fgate4};\r
-statetype s_fgate4 = {WARP4PIC,6,T_Gate,&s_fgate1};\r
-\r
-/*\r
-===============\r
-=\r
-= SpawnWarp\r
-=\r
-===============\r
-*/\r
 \r
+//---------------------------------------------------------------------------\r
+//     SpawnWarp()\r
+//\r
+// TYPE : Type param is the gate number (1-what ever) will link you to\r
+//                      gate of that type.\r
+//---------------------------------------------------------------------------\r
 void SpawnWarp (int tilex, int tiley, int type)\r
 {\r
+\r
        if (type)\r
-               SpawnNewObj (tilex,tiley,&s_fgate1,TILEGLOBAL/3);\r
+               SpawnNewObj (tilex,tiley,&s_obj_gate1,TILEGLOBAL/3);\r
        else\r
-               SpawnNewObj (tilex,tiley,&s_gate1,TILEGLOBAL/3);\r
+               SpawnNewObj (tilex,tiley,&s_pit,TILEGLOBAL/3);\r
        new->obclass = gateobj;\r
        new->temp1 = type;\r
 }\r
 \r
 \r
+\r
 /*\r
 ===============\r
 =\r
@@ -266,25 +403,36 @@ void SpawnWarp (int tilex, int tiley, int type)
 \r
 void T_Gate (objtype *ob)\r
 {\r
-       int     spot;\r
        objtype *check;\r
-       unsigned        temp;\r
+       unsigned        temp,spot;\r
 \r
        if (CheckHandAttack (ob) && !playstate)\r
        {\r
-       //\r
-       // warp\r
-       //\r
-               temp = bufferofs;\r
-               bufferofs = 0;\r
-               VW_Bar (26,4,232,9,STATUSCOLOR);                // clear text description\r
-               bufferofs = temp;\r
-               IN_ClearKeysDown ();\r
-               if (ob->temp1)\r
-               {\r
+               // make\r
                //\r
-               // teleport inside level\r
+//             spot = (*(mapsegs[2]+farmapylookup[ob->tiley+1]+ob->tilex)) >> 8;\r
+//             if (spot--)\r
+//                     if (gamestate.keys[spot])\r
+//                             TakeKey(spot);\r
+//                     else\r
+//                             return;\r
+\r
+               //\r
+               // warp\r
                //\r
+\r
+//             temp = bufferofs;\r
+//             bufferofs = 0;\r
+//             VW_Bar (26,4,232,9,STATUSCOLOR);                // clear text description\r
+//             bufferofs = temp;\r
+\r
+//             IN_ClearKeysDown ();\r
+               if (ob->temp1)\r
+               {\r
+                       //\r
+                       // teleport inside level\r
+                       //\r
+\r
                        for (check=player->next;check;check=check->next)\r
                                if (check->obclass==gateobj && check->temp1==ob->temp1 &&\r
                                        check != ob)\r
@@ -295,29 +443,29 @@ void T_Gate (objtype *ob)
                                        Thrust (player->angle,TILEGLOBAL/2);            // move forwards\r
                                        Thrust (player->angle,TILEGLOBAL/2);            // move forwards\r
                                        fizzlein=true;\r
+                                       SD_PlaySound(WARPSND);\r
                                }\r
                }\r
                else\r
                {\r
-               //\r
-               // teleport out of level\r
-               //\r
+                       //\r
+                       // teleport out of level\r
+                       //\r
+\r
                        playstate = ex_warped;\r
-                       spot = *(mapsegs[0]+farmapylookup[ob->tiley]+ob->tilex)-NAMESTART;\r
-                       if (spot<1)\r
-                               gamestate.mapon++;\r
-                       else\r
-                               gamestate.mapon=spot-1;\r
+                       spot = (*(mapsegs[2]+farmapylookup[ob->tiley+1]+ob->tilex)) >> 8;\r
+                       gamestate.mapon=spot;\r
                        SD_PlaySound(WARPUPSND);\r
                }\r
        }\r
 }\r
 \r
 \r
+\r
 /*\r
 =============================================================================\r
 \r
-                                                  TROLLS\r
+                                                       TROLLS\r
 \r
 =============================================================================\r
 */\r
@@ -349,14 +497,14 @@ statetype s_troll2 = {TROLL2PIC,13,T_Troll,&s_troll3};
 statetype s_troll3 = {TROLL3PIC,13,T_Troll,&s_troll4};\r
 statetype s_troll4 = {TROLL4PIC,13,T_Troll,&s_troll1};\r
 \r
-statetype s_trollattack1 = {TROLLATTACK1PIC,20,NULL,&s_trollattack2};\r
-statetype s_trollattack2 = {TROLLATTACK2PIC,10,T_DoDamage,&s_trollattack3};\r
-statetype s_trollattack3 = {TROLLATTACK2PIC,40,NULL,&s_trollpause};\r
+statetype s_trollattack1 = {TROLLATTACK1PIC,15,NULL,&s_trollattack2};\r
+statetype s_trollattack2 = {TROLLATTACK2PIC,15,NULL,&s_trollattack3};\r
+statetype s_trollattack3 = {TROLLATTACK3PIC,30,T_DoDamage,&s_trollpause};\r
 \r
-statetype s_trollouch = {TROLLOUCHPIC,8,NULL,&s_troll1};\r
+statetype s_trollouch = {TROLLOUCHPIC,14,T_Troll,&s_troll1};\r
 \r
-statetype s_trolldie1 = {TROLLDIE1PIC,8,NULL,&s_trolldie2};\r
-statetype s_trolldie2 = {TROLLDIE2PIC,8,NULL,&s_trolldie3};\r
+statetype s_trolldie1 = {TROLLDIE1PIC,18,NULL,&s_trolldie2};\r
+statetype s_trolldie2 = {TROLLDIE2PIC,18,NULL,&s_trolldie3};\r
 statetype s_trolldie3 = {TROLLDIE3PIC,0,NULL,&s_trolldie3};\r
 \r
 \r
@@ -370,11 +518,11 @@ statetype s_trolldie3 = {TROLLDIE3PIC,0,NULL,&s_trolldie3};
 \r
 void SpawnTroll (int tilex, int tiley)\r
 {\r
-       SpawnNewObj(tilex,tiley,&s_troll1,40*PIXRADIUS);\r
+       SpawnNewObj(tilex,tiley,&s_troll1,35*PIXRADIUS);\r
        new->speed = 2500;\r
        new->obclass = trollobj;\r
-       new->shootable = true;\r
-       new->hitpoints = 10;\r
+       new->flags |= of_shootable;\r
+       new->hitpoints = EasyHitPoints(14);\r
 }\r
 \r
 \r
@@ -388,7 +536,7 @@ void SpawnTroll (int tilex, int tiley)
 \r
 void T_Troll (objtype *ob)\r
 {\r
-       if (Chase (ob,true))\r
+       if (Chase(ob,true) || (random(1000)<RANDOM_ATTACK))\r
        {\r
                ob->state = &s_trollattack1;\r
                ob->ticcount = ob->state->tictime;\r
@@ -397,11 +545,755 @@ void T_Troll (objtype *ob)
 }\r
 \r
 \r
+void T_WetMan(objtype *ob);\r
+\r
+\r
+//statetype s_wet_pause = {WET_WALK1PIC,25,NULL,&s_wet_walk1};\r
+\r
+statetype s_wet_bubbles1 = {WET_BUBBLE1PIC,13,T_WetMan,&s_wet_bubbles2};\r
+statetype s_wet_bubbles2 = {WET_BUBBLE2PIC,15,T_WetMan,&s_wet_bubbles1};\r
+statetype s_wet_bubbles3 = {0,18,T_WetMan,&s_wet_bubbles1};\r
+\r
+statetype s_wet_peek = {WET_EYESPIC,45,NULL,&s_wet_bubbles1};\r
+\r
+//statetype s_wet_rise1 = {WET_BUBBLE1PIC,14,NULL,&s_wet_rise2};\r
+statetype s_wet_rise1 = {WET_BUBBLE2PIC,15,NULL,&s_wet_rise3};\r
+statetype s_wet_rise3 = {WET_EYESPIC,20,NULL,&s_wet_rise4};\r
+statetype s_wet_rise4 = {WET_RISE1PIC,20,NULL,&s_wet_rise5};\r
+statetype s_wet_rise5 = {WET_RISE2PIC,20,NULL,&s_wet_walk1};\r
+\r
+statetype s_wet_sink1 = {WET_RISE2PIC,20,NULL,&s_wet_sink2};\r
+statetype s_wet_sink2 = {WET_RISE1PIC,20,NULL,&s_wet_sink3};\r
+statetype s_wet_sink3 = {WET_EYESPIC,20,NULL,&s_wet_bubbles1};\r
+\r
+statetype s_wet_walk1 = {WET_WALK1PIC,12,T_WetMan,&s_wet_walk2};\r
+statetype s_wet_walk2 = {WET_WALK2PIC,12,T_WetMan,&s_wet_walk3};\r
+statetype s_wet_walk3 = {WET_WALK3PIC,12,T_WetMan,&s_wet_walk4};\r
+statetype s_wet_walk4 = {WET_WALK4PIC,12,T_WetMan,&s_wet_walk1};\r
+\r
+\r
+statetype s_wet_attack1 = {WET_ATTACK1PIC,10,NULL,&s_wet_attack2};\r
+statetype s_wet_attack2 = {WET_ATTACK2PIC,10,NULL,&s_wet_attack3};\r
+statetype s_wet_attack3 = {WET_ATTACK2PIC,10,NULL,&s_wet_attack4};\r
+statetype s_wet_attack4 = {WET_ATTACK3PIC,10,T_DoDamage,&s_wet_walk1};\r
+\r
+statetype s_wet_ouch = {WET_OUCHPIC,10,NULL,&s_wet_walk1};\r
+\r
+statetype s_wet_die1 = {WET_DIE1PIC,27,NULL,&s_wet_die2};\r
+statetype s_wet_die2 = {WET_DIE2PIC,29,NULL,&s_wet_die3};\r
+statetype s_wet_die3 = {WET_DIE3PIC,44,NULL,&s_wet_die4};\r
+statetype s_wet_die4 = {WET_BUBBLE2PIC,26,NULL,&s_wet_die5};\r
+statetype s_wet_die5 = {WET_BUBBLE1PIC,23,NULL,NULL};\r
+\r
+\r
+typedef enum {wt_BUBBLES,wt_WALK} WetManTypes;\r
+\r
+#define WT_TIMEREMAIN  (ob->temp1)\r
+#define WT_STAGE                       (ob->temp2)\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnWetMan\r
+=\r
+===============\r
+*/\r
+void SpawnWetMan(int tilex, int tiley)\r
+{\r
+       objtype *ob;\r
+       SpawnNewObj(tilex,tiley,&s_wet_bubbles1,PIXRADIUS*35);\r
+       ob=new;\r
+\r
+       WT_STAGE = wt_BUBBLES;\r
+       WT_TIMEREMAIN = 60*4+random(60*3);\r
+\r
+       new->obclass = wetobj;\r
+       new->speed = 1000;\r
+       new->flags &= ~of_shootable;\r
+       new->hitpoints = EasyHitPoints(18);\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_WetMan\r
+=\r
+===============\r
+*/\r
+\r
+void T_WetMan(objtype *ob)\r
+{\r
+       switch (WT_STAGE)\r
+       {\r
+               case wt_BUBBLES:\r
+                       ob->flags &= ~of_shootable;\r
+                       if (Chase(ob,true))\r
+                       {\r
+                               // RISE & GOTO WALK STAGE\r
+                               //\r
+\r
+                               WT_STAGE = wt_WALK;\r
+                               WT_TIMEREMAIN = 60*5+random(60*5);\r
+                               ob->state = &s_wet_rise1;\r
+                               ob->speed = 2200;\r
+                               ob->ticcount = ob->state->tictime;\r
+                       }\r
+                       else\r
+                       {\r
+                               // DEC COUNTER - And check for WALK\r
+                               //\r
+                               if ((WT_TIMEREMAIN-=realtics) < 0)\r
+                               {\r
+                                       // RISE & GOTO WALK STAGE\r
+                                       //\r
+\r
+                                       WT_STAGE = wt_WALK;\r
+                                       WT_TIMEREMAIN = 60+random(60*2);\r
+                                       ob->state = &s_wet_rise1;\r
+                                       ob->speed = 2200;\r
+                                       ob->ticcount = ob->state->tictime;\r
+                               }\r
+                               else\r
+                               if (random(1000)<5)\r
+                               {\r
+                                       // RANDOM PEEK UP OUT OF WATER\r
+                                       //\r
+\r
+                                       ob->state=&s_wet_peek;\r
+                                       ob->ticcount = ob->state->tictime;\r
+                               }\r
+                       }\r
+                       break;\r
+\r
+\r
+               case wt_WALK:\r
+                       ob->flags |= of_shootable;\r
+                       if (Chase(ob,true) || (random(1000)<RANDOM_ATTACK))\r
+                       {\r
+                               ob->state = &s_wet_attack1;\r
+                               ob->ticcount = ob->state->tictime;\r
+                       }\r
+                       else\r
+                       {\r
+                               // DEC COUNTER - And check for SINK\r
+                               //\r
+                               if ((WT_TIMEREMAIN-=realtics) < 0)\r
+                               {\r
+                                       // SINK & GOTO BUBBLE STAGE\r
+                                       //\r
+\r
+                                       WT_STAGE = wt_BUBBLES;\r
+                                       WT_TIMEREMAIN = 60*4+random(60*3);\r
+                                       ob->state = &s_wet_sink1;\r
+                                       ob->speed = 1200;\r
+                                       ob->ticcount = ob->state->tictime;\r
+                                       ob->flags &= ~of_shootable;\r
+                               }\r
+\r
+                       }\r
+                       break;\r
+       }\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                       ZOMBIE\r
+\r
+=============================================================================\r
+*/\r
+\r
+extern statetype s_zombie_rise1;\r
+extern statetype s_zombie_rise2;\r
+extern statetype s_zombie_rise3;\r
+extern statetype s_zombie_rise4;\r
+\r
+extern statetype s_zombie_alive1;\r
+extern statetype s_zombie_alive2;\r
+extern statetype s_zombie_alive3;\r
+\r
+//extern statetype s_zombie_attack1;\r
+\r
+extern statetype s_zombie_death1;\r
+extern statetype s_zombie_death2;\r
+extern statetype s_zombie_death3;\r
+\r
+void T_Zombie (objtype *ob);\r
+void T_ZombieRisen(objtype *obj);\r
+\r
+statetype s_zombie_risen = {ZOMB_WALK3PIC,1,T_ZombieRisen,&s_zombie_alive1};\r
+\r
+statetype s_zombie_pause = {ZOMB_WALK1PIC,20,NULL,&s_zombie_alive1};\r
+\r
+statetype s_zombie_inground = {0,13,T_Zombie,&s_zombie_inground};\r
+\r
+statetype s_zombie_rise1 = {ZOMB_APPEAR1PIC,24,NULL,&s_zombie_rise2};\r
+statetype s_zombie_rise2 = {ZOMB_APPEAR2PIC,24,NULL,&s_zombie_rise3};\r
+statetype s_zombie_rise3 = {ZOMB_APPEAR3PIC,24,NULL,&s_zombie_rise4};\r
+statetype s_zombie_rise4 = {ZOMB_APPEAR4PIC,24,NULL,&s_zombie_risen};\r
+\r
+statetype s_zombie_alive1 = {ZOMB_WALK1PIC,13,T_Zombie,&s_zombie_alive2};\r
+statetype s_zombie_alive2 = {ZOMB_WALK2PIC,13,T_Zombie,&s_zombie_alive3};\r
+statetype s_zombie_alive3 = {ZOMB_WALK3PIC,13,T_Zombie,&s_zombie_alive1};\r
+\r
+statetype s_zombie_death1 = {ZOMB_DIE1PIC,16,NULL,&s_zombie_death2};\r
+statetype s_zombie_death2 = {ZOMB_DIE2PIC,16,NULL,&s_zombie_death3};\r
+statetype s_zombie_death3 = {ZOMB_DIE3PIC,16,NULL,&s_zombie_death3};\r
+\r
+statetype s_zombie_attack  = {ZOMB_ATTACKPIC,15,T_DoDamage,&s_zombie_pause};\r
+//statetype s_zombie_attack1 = {ZOMB_ATTACKPIC,15,NULL,&s_zombie_pause};\r
+\r
+statetype s_zombie_ouch = {ZOMB_OUCHPIC,15,NULL,&s_zombie_alive1};\r
+\r
+\r
+\r
+\r
+enum zombie_modes {zm_wait_for_dark,zm_wait_to_rise,zm_active};\r
+\r
+#define zombie_mode    ob->temp1\r
+#define zombie_delay   ob->temp2\r
+\r
+\r
+//--------------------------------------------------------------------------\r
+// SpawnZombie()\r
+//--------------------------------------------------------------------------\r
+void SpawnZombie (int tilex, int tiley)\r
+{\r
+       objtype *ob;\r
+       short current_zombie_delay;\r
+       unsigned tile;\r
+\r
+       SpawnNewObj(tilex,tiley,&s_zombie_inground,35*PIXRADIUS);\r
+       ob = new;\r
+       zombie_mode = zm_wait_for_dark;\r
+\r
+       tile = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);\r
+       if (tile)\r
+               zombie_delay = (tile>>8)*30;\r
+       else\r
+       {\r
+               current_zombie_delay = (2*60)+random(4*60);\r
+               zombie_delay = zombie_base_delay+current_zombie_delay;\r
+               zombie_base_delay += current_zombie_delay;\r
+               if (zombie_base_delay > 8*60)\r
+                       zombie_base_delay = 0;\r
+       }\r
+\r
+       new->speed = 2500;\r
+       new->obclass = zombieobj;\r
+       new->hitpoints = EasyHitPoints(5);\r
+       new->active = yes;\r
+       new->flags &= ~of_shootable;\r
+}\r
+\r
+//--------------------------------------------------------------------------\r
+// T_Zombie()\r
+//--------------------------------------------------------------------------\r
+void T_Zombie (objtype *ob)\r
+{\r
+       switch (zombie_mode)\r
+       {\r
+               case zm_wait_for_dark:\r
+                       if (gamestate.mapon == 0)\r
+                       {\r
+                               if (BGFLAGS & BGF_NIGHT)\r
+                                       zombie_mode = zm_wait_to_rise;\r
+                       }\r
+                       else\r
+                               zombie_mode = zm_wait_to_rise;\r
+               break;\r
+\r
+               case zm_wait_to_rise:\r
+                       if (zombie_delay < 0)\r
+                       {\r
+                               if ((ob->tilex == player->tilex) && (ob->tiley == player->tiley))\r
+                                       break;\r
+\r
+                               ob->active = always;\r
+                               ob->state = &s_zombie_rise1;\r
+                               ob->ticcount = ob->state->tictime;              // JIM Added\r
+                               zombie_mode = zm_active;\r
+                       }\r
+                       else\r
+                               zombie_delay -= tics;\r
+\r
+               break;\r
+\r
+               case zm_active:\r
+                       if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))\r
+                       {\r
+                               ob->state = &s_zombie_attack;\r
+                               ob->ticcount = ob->state->tictime;\r
+                               return;\r
+                       }\r
+               break;\r
+       }\r
+}\r
+\r
+//--------------------------------------------------------------------------\r
+// T_ZombieRisen()\r
+//--------------------------------------------------------------------------\r
+void T_ZombieRisen(objtype *obj)\r
+{\r
+       obj->flags |= of_shootable;\r
+}\r
+\r
+\r
 \r
 /*\r
 =============================================================================\r
 \r
-                                                  ORCS\r
+                                                                                       SPOOKS\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_Spook(objtype *ob);\r
+\r
+statetype s_spook_wait = {0,10,T_Spook,&s_spook_wait};\r
+\r
+statetype s_spook0 = {SPOOK_INOUTPIC,7,NULL,&s_spook0_1};\r
+statetype s_spook0_1 = {0,7,NULL,&s_spook0_2};\r
+statetype s_spook0_2 = {SPOOK_INOUTPIC,7,NULL,&s_spook1};\r
+\r
+statetype s_spook1 = {SPOOK1PIC,10,NULL,&s_spook2};\r
+statetype s_spook2 = {SPOOK2PIC,10,T_Spook,&s_spook3};\r
+statetype s_spook3 = {SPOOK3PIC,10,T_Spook,&s_spook4};\r
+statetype s_spook4 = {SPOOK4PIC,10,T_Spook,&s_spook5};\r
+statetype s_spook5 = {SPOOK3PIC,10,T_Spook,&s_spook6};\r
+statetype s_spook6 = {SPOOK2PIC,10,T_Spook,&s_spook1};\r
+\r
+statetype s_spook_attack1 = {SPOOK_ATTACKPIC,35,NULL,&s_spook_attack3};\r
+statetype s_spook_attack3 = {SPOOK3PIC,20,T_DoDamage,&s_spook1};\r
+\r
+statetype s_spook_pause  = {SPOOK1PIC,20,NULL,&s_spook1};\r
+\r
+statetype s_spookouch = {SPOOKHITPIC,5,NULL,&s_spook1};\r
+\r
+statetype s_spookdie = {SPOOK_INOUTPIC,9,NULL,&s_spookdie1};\r
+statetype s_spookdie1 = {SPOOK4PIC,9,NULL,&s_spookdie2};\r
+statetype s_spookdie2 = {SPOOK_INOUTPIC,9,NULL,&s_spookdie3};\r
+statetype s_spookdie3 = {SPOOK4PIC,9,NULL,&s_spookdie4};\r
+statetype s_spookdie4 = {SPOOK_INOUTPIC,9,NULL,&s_spookdie5};\r
+statetype s_spookdie5 = {0,11,NULL,NULL};\r
+\r
+#define spook_mode     ob->temp1\r
+#define spook_delay    ob->temp2\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnSpook\r
+=\r
+===============\r
+*/\r
+void SpawnSpook(int tilex, int tiley)\r
+{\r
+       objtype *ob;\r
+       unsigned tile;\r
+       SpawnNewObj(tilex,tiley,&s_spook_wait,PIXRADIUS*35);\r
+       ob = new;\r
+\r
+       tile = *(mapsegs[2]+farmapylookup[tiley+1]+tilex);\r
+       if (tile)\r
+               spook_delay = (tile>>8)*30;\r
+       else\r
+               spook_delay = 2*60+random(5*60);\r
+\r
+       spook_mode = zm_wait_for_dark;\r
+\r
+       new->active = yes;\r
+       new->obclass = spookobj;\r
+       new->speed = 1900;\r
+       new->flags &= ~of_shootable;\r
+       new->hitpoints = EasyHitPoints(5);\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Spook\r
+=\r
+===============\r
+*/\r
+void T_Spook(objtype *ob)\r
+{\r
+       switch (zombie_mode)\r
+       {\r
+               case zm_wait_for_dark:\r
+                       if (!gamestate.mapon)\r
+                       {\r
+                               if (BGFLAGS & BGF_NIGHT)\r
+                                       spook_mode = zm_wait_to_rise;\r
+                       }\r
+                       else\r
+                               spook_mode = zm_wait_to_rise;\r
+               break;\r
+\r
+               case zm_wait_to_rise:\r
+                       spook_delay -= tics;\r
+                       if (spook_delay < 0)\r
+                       {\r
+                               if ((ob->tilex == player->tilex) && (ob->tiley == player->tiley))\r
+                                       break;\r
+\r
+                               ob->active = always;\r
+                               ob->flags |= of_shootable;\r
+                               ob->state = &s_spook0;\r
+                               ob->ticcount = ob->state->tictime;\r
+                               spook_mode = zm_active;\r
+                       }\r
+                       else\r
+                               spook_delay -= tics;\r
+               break;\r
+\r
+               case zm_active:\r
+                       if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))\r
+                       {\r
+                               ob->state = &s_spook_attack1;\r
+                               ob->ticcount = ob->state->tictime;\r
+                               return;\r
+                       }\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                               SKELETON IN WALL\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_WallSkeleton(objtype *ob);\r
+\r
+extern statetype s_skel_1;\r
+\r
+statetype s_wallskel = {0,40,T_WallSkeleton,&s_wallskel};\r
+statetype s_wallskel2 = {0,1,NULL,NULL};\r
+\r
+\r
+enum wskel_modes {ws_wall1,ws_wall2,ws_wall3,ws_exit};\r
+\r
+#define wskel_mode     ob->temp1\r
+#define wskel_delay    ob->temp2\r
+#define wskel_base     ob->angle\r
+#define wskel_wallx    ob->hitpoints\r
+#define wskel_wally    ob->speed\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnWallSkeleton\r
+=\r
+===============\r
+*/\r
+void SpawnWallSkeleton(int tilex, int tiley)\r
+{\r
+       char xofs[] = {0,0,-1,+1};\r
+       char yofs[] = {-1,+1,0,0};\r
+\r
+       objtype *ob;\r
+       int wallx=tilex,wally=tiley,wallbase,wallmode,loop;\r
+       unsigned tile,current_delay;\r
+\r
+       for (loop=0; loop<4; loop++)\r
+       {\r
+               tile = *(mapsegs[0]+farmapylookup[tiley+yofs[loop]]+tilex+xofs[loop]);\r
+               switch (tile)\r
+               {\r
+                       case WALL_SKELETON_CODE:\r
+                       case WALL_SKELETON_CODE+1:\r
+                       case WALL_SKELETON_CODE+2:\r
+                               wallmode = ws_wall1+(tile-WALL_SKELETON_CODE);\r
+                               wallbase = WALL_SKELETON_CODE;\r
+                               goto foundtile;\r
+                       break;\r
+\r
+                       case 41:\r
+                       case 43:\r
+                               wallmode = ws_wall1+(tile-41);\r
+                               wallbase = 41;\r
+                               goto foundtile;\r
+                       break;\r
+\r
+                       case 42:\r
+                       case 44:\r
+                               wallmode = ws_wall1+(tile-42);\r
+                               wallbase = 42;\r
+                               goto foundtile;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       return;\r
+foundtile:;\r
+\r
+       wallx += xofs[loop];\r
+       wally += yofs[loop];\r
+\r
+       SpawnNewObj(tilex,tiley,&s_wallskel,PIXRADIUS*35);\r
+       ob = new;\r
+       new->obclass = wallskelobj;\r
+       new->speed = 1900;\r
+       new->flags &= ~of_shootable;\r
+       new->hitpoints = EasyHitPoints(5);\r
+\r
+//     new->tilex = wallx;\r
+//     new->tiley = wally;\r
+       wskel_wallx = wallx;\r
+       wskel_wally = wally;\r
+       wskel_base = wallbase;\r
+       new->active = no;\r
+\r
+       wskel_mode = wallmode;\r
+\r
+       tile = *(mapsegs[2]+farmapylookup[wally]+wallx);\r
+       if (tile)\r
+               wskel_delay = (tile>>8)*30;\r
+       else\r
+       {\r
+               current_delay = (2*60)+random(4*60);\r
+               wskel_delay = zombie_base_delay+current_delay;\r
+               zombie_base_delay += current_delay;\r
+               if (zombie_base_delay > 8*60)\r
+                       zombie_base_delay = 0;\r
+       }\r
+}\r
+\r
+/*\r
+===============\r
+=\r
+= T_WallSkeleton\r
+=\r
+===============\r
+*/\r
+void T_WallSkeleton(objtype *ob)\r
+{\r
+       int x=wskel_wallx,y=wskel_wally;\r
+\r
+       wskel_delay -= realtics;\r
+       if (wskel_delay > 0)\r
+               return;\r
+\r
+       switch (wskel_mode)\r
+       {\r
+               case ws_wall2:\r
+                       if ((wskel_base == 41) || (wskel_base == 42))\r
+                               wskel_mode++;\r
+               case ws_wall1:\r
+               case ws_wall3:\r
+                       (unsigned)actorat[x][y]\r
+                               = tilemap[x][y]\r
+                               = *(mapsegs[0]+farmapylookup[y]+x)\r
+                               = wskel_base+(wskel_mode-ws_wall1);\r
+\r
+                       wskel_mode++;\r
+                       wskel_delay = (120);\r
+                       ob->active = always;\r
+               break;\r
+\r
+               case ws_exit:\r
+//                     wskel_delay = 0;\r
+//                     if (objectcount >= MAXACTORS-3)\r
+//                             break;\r
+\r
+                       (unsigned)actorat[x][y]\r
+                               = tilemap[x][y]\r
+                               = *(mapsegs[0]+farmapylookup[y]+x)\r
+                               = wskel_base;\r
+                       ob->tilex = ob->x >> TILESHIFT;\r
+                       ob->tiley = ob->y >> TILESHIFT;\r
+\r
+                       ob->obclass = skeletonobj;\r
+                       ob->speed = 2036;\r
+                       ob->flags |= of_shootable;\r
+                       ob->hitpoints = EasyHitPoints(12);\r
+                       ob->state = &s_skel_1;\r
+                       ob->ticcount = ob->state->tictime;\r
+\r
+//                     SpawnSkeleton(ob->tilex,ob->tiley);\r
+//                     ob->state = NULL;\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                               SKELETONS\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_Skeleton(objtype *ob);\r
+\r
+\r
+\r
+\r
+statetype s_skel_pause = {SKELETON_1PIC,40,NULL,&s_skel_2};\r
+\r
+statetype s_skel_1 = {SKELETON_1PIC,10,T_Skeleton,&s_skel_2};\r
+statetype s_skel_2 = {SKELETON_2PIC,10,T_Skeleton,&s_skel_3};\r
+statetype s_skel_3 = {SKELETON_3PIC,10,T_Skeleton,&s_skel_4};\r
+statetype s_skel_4 = {SKELETON_4PIC,10,T_Skeleton,&s_skel_1};\r
+\r
+statetype s_skel_attack1 = {SKELETON_ATTACK_1PIC,12,NULL,&s_skel_attack2};\r
+statetype s_skel_attack2 = {SKELETON_ATTACK_2PIC,12,NULL,&s_skel_attack3};\r
+statetype s_skel_attack3 = {SKELETON_ATTACK_3PIC,12,T_DoDamage,&s_skel_pause};\r
+\r
+statetype s_skel_ouch = {SKELETON_OUCHPIC,8,NULL,&s_skel_1};\r
+\r
+statetype s_skel_die1 = {SKELETON_OUCHPIC,18,NULL,&s_skel_die2};\r
+statetype s_skel_die2 = {SKELETON_DEATH_1PIC,18,NULL,&s_skel_die3};\r
+statetype s_skel_die3 = {SKELETON_DEATH_2PIC,18,NULL,&s_skel_die3};\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnSkeleton\r
+=\r
+===============\r
+*/\r
+void SpawnSkeleton(int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_skel_1,PIXRADIUS*35);\r
+       new->obclass = skeletonobj;\r
+       new->speed = 2036;\r
+       new->flags |= of_shootable;\r
+       new->hitpoints = EasyHitPoints(12);\r
+}\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= T_Skeleton\r
+=\r
+===============\r
+*/\r
+\r
+void T_Skeleton(objtype *ob)\r
+{\r
+       if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))\r
+       {\r
+               ob->state = &s_skel_attack1;\r
+               ob->ticcount = ob->state->tictime;\r
+               return;\r
+       }\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                               EYE\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_Eye(objtype *ob);\r
+boolean T_EyeShoot (objtype *ob, boolean eyeshot);\r
+\r
+\r
+\r
+\r
+statetype s_eye_pause = {EYE_WALK1PIC,40,NULL,&s_eye_2};\r
+\r
+statetype s_eye_1 = {EYE_WALK1PIC,20,T_Eye,&s_eye_2};\r
+statetype s_eye_2 = {EYE_WALK2PIC,20,T_Eye,&s_eye_3};\r
+statetype s_eye_3 = {EYE_WALK3PIC,20,T_Eye,&s_eye_4};\r
+statetype s_eye_4 = {EYE_WALK2PIC,20,T_Eye,&s_eye_1};\r
+\r
+statetype s_eye_ouch = {EYE_OUCH1PIC,8,NULL,&s_eye_ouch2};\r
+statetype s_eye_ouch2 = {EYE_OUCH2PIC,8,NULL,&s_eye_1};\r
+\r
+statetype s_eye_die1 = {EYE_DEATH1PIC,22,NULL,&s_eye_die2};\r
+statetype s_eye_die2 = {EYE_DEATH2PIC,22,NULL,&s_eye_die3};\r
+statetype s_eye_die3 = {EYE_DEATH2PIC,22,NULL,NULL};\r
+\r
+extern statetype s_eshot2;\r
+\r
+statetype s_eshot1 = {EYE_SHOT1PIC,8,&T_ShootPlayer,&s_eshot2};\r
+statetype s_eshot2 = {EYE_SHOT2PIC,8,&T_ShootPlayer,&s_eshot1};\r
+\r
+enum eye_modes {em_other1,em_player1,em_other2,em_player2,em_other3,em_player3,em_other4,em_player4};\r
+\r
+#define eye_mode       ob->temp1\r
+#define eye_delay      ob->temp2\r
+\r
+//-------------------------------------------------------------------------\r
+// SpawnEye()\r
+//-------------------------------------------------------------------------\r
+void SpawnEye(int tilex, int tiley)\r
+{\r
+       objtype *ob;\r
+\r
+       SpawnNewObj(tilex,tiley,&s_eye_1,PIXRADIUS*35);\r
+       ob = new;\r
+       new->obclass = eyeobj;\r
+       new->speed = 1200;\r
+       new->flags |= of_shootable;\r
+       new->hitpoints = EasyHitPoints(14);\r
+       eye_mode = em_other1;\r
+}\r
+\r
+\r
+//-------------------------------------------------------------------------\r
+// T_Eye()\r
+//-------------------------------------------------------------------------\r
+void T_Eye(objtype *ob)\r
+{\r
+       fixed tempx,tempy;\r
+       unsigned temp_tilex,temp_tiley;\r
+\r
+       eye_delay -= realtics;\r
+       if (eye_delay < 0)\r
+       {\r
+               eye_mode = random(em_player4);\r
+               eye_delay = (10*60);\r
+       }\r
+\r
+       tempx = player->x;\r
+       tempy = player->y;\r
+       temp_tilex = player->tilex;\r
+       temp_tiley = player->tiley;\r
+\r
+\r
+       switch (eye_mode)\r
+       {\r
+               case em_other1:\r
+               case em_other2:\r
+               case em_other3:\r
+               case em_other4:\r
+                       player->x = ((long)other_x[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;\r
+                       player->y = ((long)other_y[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;\r
+                       player->tilex = other_x[eye_mode];\r
+                       player->tiley = other_y[eye_mode];\r
+               break;\r
+       }\r
+\r
+       if (Chase(ob,true))\r
+               eye_delay = 0;\r
+\r
+       player->x = tempx;\r
+       player->y = tempy;\r
+       player->tilex = temp_tilex;\r
+       player->tiley = temp_tiley;\r
+\r
+       if (!random(2))\r
+               ShootPlayer(ob,eshotobj,ESHOTSPEED,&s_eshot1);\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                       ORCS\r
 \r
 =============================================================================\r
 */\r
@@ -435,13 +1327,13 @@ statetype s_orc3 = {ORC3PIC,20,T_Orc,&s_orc4};
 statetype s_orc4 = {ORC4PIC,20,T_Orc,&s_orc1};\r
 \r
 statetype s_orcattack1 = {ORCATTACK1PIC,20,NULL,&s_orcattack2};\r
-statetype s_orcattack2 = {ORCATTACK2PIC,10,T_DoDamage,&s_orcattack3};\r
-statetype s_orcattack3 = {ORCATTACK2PIC,40,NULL,&s_orcpause};\r
+statetype s_orcattack2 = {ORCATTACK2PIC,20,NULL,&s_orcattack3};\r
+statetype s_orcattack3 = {ORCATTACK2PIC,30,T_DoDamage,&s_orcpause};\r
 \r
-statetype s_orcouch = {ORCOUCHPIC,10,NULL,&s_orc1};\r
+statetype s_orcouch = {ORCOUCHPIC,15,NULL,&s_orc1};\r
 \r
-statetype s_orcdie1 = {ORCDIE1PIC,8,NULL,&s_orcdie2};\r
-statetype s_orcdie2 = {ORCDIE2PIC,8,NULL,&s_orcdie3};\r
+statetype s_orcdie1 = {ORCDIE1PIC,18,NULL,&s_orcdie2};\r
+statetype s_orcdie2 = {ORCDIE2PIC,18,NULL,&s_orcdie3};\r
 statetype s_orcdie3 = {ORCDIE3PIC,0,NULL,&s_orcdie3};\r
 \r
 \r
@@ -455,11 +1347,11 @@ statetype s_orcdie3 = {ORCDIE3PIC,0,NULL,&s_orcdie3};
 \r
 void SpawnOrc (int tilex, int tiley)\r
 {\r
-       SpawnNewObj(tilex,tiley,&s_orc1,PIXRADIUS*32);\r
+       SpawnNewObj(tilex,tiley,&s_orc1,PIXRADIUS*35);\r
        new->obclass = orcobj;\r
        new->speed = 1536;\r
-       new->shootable = true;\r
-       new->hitpoints = 3;\r
+       new->flags |= of_shootable;\r
+       new->hitpoints = EasyHitPoints(6);\r
 }\r
 \r
 \r
@@ -473,7 +1365,7 @@ void SpawnOrc (int tilex, int tiley)
 \r
 void T_Orc (objtype *ob)\r
 {\r
-       if (Chase (ob,true))\r
+       if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))\r
        {\r
                ob->state = &s_orcattack1;\r
                ob->ticcount = ob->state->tictime;\r
@@ -485,7 +1377,7 @@ void T_Orc (objtype *ob)
 /*\r
 =============================================================================\r
 \r
-                                                  DEMON\r
+                                                       DEMON\r
 \r
 =============================================================================\r
 */\r
@@ -519,13 +1411,13 @@ statetype s_demon3 = {DEMON3PIC,20,T_Demon,&s_demon4};
 statetype s_demon4 = {DEMON4PIC,20,T_Demon,&s_demon1};\r
 \r
 statetype s_demonattack1 = {DEMONATTACK1PIC,20,NULL,&s_demonattack2};\r
-statetype s_demonattack2 = {DEMONATTACK2PIC,20,T_DoDamage,&s_demonattack3};\r
-statetype s_demonattack3 = {DEMONATTACK3PIC,30,NULL,&s_demonpause};\r
+statetype s_demonattack2 = {DEMONATTACK2PIC,20,NULL,&s_demonattack3};\r
+statetype s_demonattack3 = {DEMONATTACK3PIC,30,T_DoDamage,&s_demonpause};\r
 \r
-statetype s_demonouch = {DEMONOUCHPIC,10,NULL,&s_demon1};\r
+statetype s_demonouch = {DEMONOUCHPIC,15,T_Demon,&s_demon1};\r
 \r
-statetype s_demondie1 = {DEMONDIE1PIC,20,NULL,&s_demondie2};\r
-statetype s_demondie2 = {DEMONDIE2PIC,20,NULL,&s_demondie3};\r
+statetype s_demondie1 = {DEMONDIE1PIC,40,NULL,&s_demondie2};\r
+statetype s_demondie2 = {DEMONDIE2PIC,30,NULL,&s_demondie3};\r
 statetype s_demondie3 = {DEMONDIE3PIC,0,NULL,&s_demondie3};\r
 \r
 \r
@@ -540,130 +1432,33 @@ statetype s_demondie3 = {DEMONDIE3PIC,0,NULL,&s_demondie3};
 \r
 void SpawnDemon (int tilex, int tiley)\r
 {\r
-       SpawnNewObj(tilex,tiley,&s_demon1,TILEGLOBAL/2);\r
+       SpawnNewObj(tilex,tiley,&s_demon1,PIXRADIUS*35);\r
        new->obclass = demonobj;\r
-       new->speed = 2048;\r
-       new->shootable = true;\r
-       new->hitpoints = 50;\r
-}\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= T_Demon\r
-=\r
-===============\r
-*/\r
-\r
-void T_Demon (objtype *ob)\r
-{\r
-       if (Chase (ob,true))\r
-       {\r
-               ob->state = &s_demonattack1;\r
-               ob->ticcount = ob->state->tictime;\r
-               return;\r
-       }\r
-}\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                       MSHOTS\r
-\r
-temp1 = dir\r
-\r
-=============================================================================\r
-*/\r
-\r
-#define MSHOTDAMAGE    2\r
-#define MSHOTSPEED     10000\r
-\r
-void T_Mshot (objtype *ob);\r
-\r
-\r
-extern statetype s_mshot1;\r
-extern statetype s_mshot2;\r
-\r
-statetype s_mshot1 = {PSHOT1PIC,8,&T_Mshot,&s_mshot2};\r
-statetype s_mshot2 = {PSHOT2PIC,8,&T_Mshot,&s_mshot1};\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= T_Mshot\r
-=\r
-===============\r
-*/\r
-\r
-void T_Mshot (objtype *ob)\r
-{\r
-       objtype *check;\r
-       long    xmove,ymove,speed;\r
-\r
-       xmove = ymove = 0;\r
-\r
-       switch (ob->dir)\r
-       {\r
-       case north:\r
-               ymove = -ob->speed*tics;\r
-               break;\r
-       case east:\r
-               xmove = ob->speed*tics;\r
-               break;\r
-       case south:\r
-               ymove = ob->speed*tics;\r
-               break;\r
-       case west:\r
-               xmove = -ob->speed*tics;\r
-               break;\r
-       }\r
-\r
-       ob->x+=xmove;\r
-       ob->y+=ymove;\r
-\r
-       CalcBounds (ob);\r
+       new->speed = 2048;\r
+       new->flags |= of_shootable;\r
+       new->hitpoints = EasyHitPoints(50);\r
+}\r
 \r
-       ob->tilex = ob->x>>TILESHIFT;\r
-       ob->tiley = ob->y>>TILESHIFT;\r
 \r
-       if (tilemap[ob->tilex][ob->tiley])\r
-       {\r
-               SD_PlaySound (SHOOTWALLSND);\r
-               ob->state = NULL;\r
-               return;\r
-       }\r
+/*\r
+===============\r
+=\r
+= T_Demon\r
+=\r
+===============\r
+*/\r
 \r
-//\r
-// check final position for monsters hit\r
-//\r
-       if ( ob->xl <= player->xh\r
-       && ob->xh >= player->xl\r
-       && ob->yl <= player->yh\r
-       && ob->yh >= player->yl)\r
+void T_Demon (objtype *ob)\r
+{\r
+       if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))\r
        {\r
-               TakeDamage (MSHOTDAMAGE*2);\r
-               ob->state = NULL;\r
+               ob->state = &s_demonattack1;\r
+               ob->ticcount = ob->state->tictime;\r
                return;\r
        }\r
-\r
-       for (check = player->next; check; check=check->next)\r
-               if (ob->shootable && ob->obclass != mageobj\r
-               && ob->xl <= check->xh\r
-               && ob->xh >= check->xl\r
-               && ob->yl <= check->yh\r
-               && ob->yh >= check->yl)\r
-               {\r
-                       ShootActor (check,MSHOTDAMAGE);\r
-                       ob->state = NULL;\r
-                       return;\r
-               }\r
 }\r
 \r
 \r
-\r
-\r
 /*\r
 =============================================================================\r
 \r
@@ -691,13 +1486,13 @@ extern   statetype s_magedie1;
 extern statetype s_magedie2;\r
 \r
 \r
-statetype s_magepause = {MAGE1PIC,100,NULL,&s_mage2};\r
+statetype s_magepause = {MAGE1PIC,10,NULL,&s_mage2};\r
 \r
 statetype s_mage1 = {MAGE1PIC,20,T_Mage,&s_mage2};\r
 statetype s_mage2 = {MAGE2PIC,20,T_Mage,&s_mage1};\r
 \r
-statetype s_mageattack1 = {MAGEATTACKPIC,20,NULL,&s_mageattack2};\r
-statetype s_mageattack2 = {MAGEATTACKPIC,-1,T_MageShoot,&s_mageattack3};\r
+//statetype s_mageattack1 = {MAGEATTACKPIC,20,NULL,&s_mageattack2};\r
+//statetype s_mageattack2 = {MAGEATTACKPIC,-1,T_MageShoot,&s_mageattack3};\r
 statetype s_mageattack3 = {MAGEATTACKPIC,30,NULL,&s_magepause};\r
 \r
 statetype s_mageouch = {MAGEOUCHPIC,10,NULL,&s_mage1};\r
@@ -706,6 +1501,9 @@ statetype s_magedie1 = {MAGEDIE1PIC,20,NULL,&s_magedie2};
 statetype s_magedie2 = {MAGEDIE2PIC,0,NULL,&s_magedie2};\r
 \r
 \r
+statetype s_mshot1 = {PSHOT1PIC,8,&T_ShootPlayer,&s_mshot2};\r
+statetype s_mshot2 = {PSHOT2PIC,8,&T_ShootPlayer,&s_mshot1};\r
+\r
 /*\r
 ===============\r
 =\r
@@ -716,11 +1514,11 @@ statetype s_magedie2 = {MAGEDIE2PIC,0,NULL,&s_magedie2};
 \r
 void SpawnMage (int tilex, int tiley)\r
 {\r
-       SpawnNewObj(tilex,tiley,&s_mage1,TILEGLOBAL/2);\r
+       SpawnNewObj(tilex,tiley,&s_mage1,PIXRADIUS*35);\r
        new->obclass = mageobj;\r
-       new->speed = 2048;\r
-       new->shootable = true;\r
-       new->hitpoints = 5;\r
+       new->speed = 3072;\r
+       new->flags |= of_shootable;\r
+       new->hitpoints = EasyHitPoints(5);\r
 }\r
 \r
 \r
@@ -734,52 +1532,130 @@ void SpawnMage (int tilex, int tiley)
 \r
 void T_Mage (objtype *ob)\r
 {\r
-       Chase (ob,false);\r
-//\r
-// check for line up with player\r
-//\r
+       fixed tempx,tempy;\r
+       unsigned temp_tilex,temp_tiley;\r
 \r
-       if (ob->x-PIXRADIUS*14 < player->xh\r
-       && ob->x+PIXRADIUS > player->xl)\r
+       eye_delay -= realtics;\r
+       if (eye_delay < 0)\r
        {\r
-               ob->temp1 = 1;\r
-               ob->state = &s_mageattack1;\r
+               eye_mode = random(em_player4);\r
+               eye_delay = (10*60);\r
        }\r
-       else if (ob->y-PIXRADIUS*14 < player->yh\r
-       && ob->y+PIXRADIUS > player->yl)\r
+\r
+       tempx = player->x;\r
+       tempy = player->y;\r
+       temp_tilex = player->tilex;\r
+       temp_tiley = player->tiley;\r
+\r
+\r
+       switch (eye_mode)\r
        {\r
-               ob->temp1 = 0;\r
-               ob->state = &s_mageattack1;\r
+               case em_other1:\r
+               case em_other2:\r
+               case em_other3:\r
+               case em_other4:\r
+                       player->x = ((long)other_x[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;\r
+                       player->y = ((long)other_y[eye_mode]<<TILESHIFT)+TILEGLOBAL/2;\r
+                       player->tilex = other_x[eye_mode];\r
+                       player->tiley = other_y[eye_mode];\r
+               break;\r
        }\r
+\r
+       if (Chase(ob,true))\r
+               eye_delay = 0;\r
+\r
+       player->x = tempx;\r
+       player->y = tempy;\r
+       player->tilex = temp_tilex;\r
+       player->tiley = temp_tiley;\r
+\r
+       if (!random(10))\r
+               if (ShootPlayer(ob,mshotobj,MSHOTSPEED,&s_mshot1))\r
+               {\r
+                       ob->state = &s_mageattack3;\r
+                       ob->ticcount = ob->state->tictime;\r
+               }\r
+}\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                               RED DEMON\r
+\r
+=============================================================================\r
+*/\r
+\r
+void T_RedDemon (objtype *ob);\r
+\r
+extern statetype s_red_demonpause;\r
+\r
+extern statetype s_red_demon1;\r
+extern statetype s_red_demon2;\r
+extern statetype s_red_demon3;\r
+extern statetype s_red_demon4;\r
+\r
+extern statetype s_red_demonattack1;\r
+extern statetype s_red_demonattack2;\r
+extern statetype s_red_demonattack3;\r
+\r
+extern statetype s_red_demonouch;\r
+\r
+extern statetype s_red_demondie1;\r
+extern statetype s_red_demondie2;\r
+extern statetype s_red_demondie3;\r
+\r
+statetype s_red_demonpause = {RED_DEMON1PIC,40,NULL,&s_red_demon2};\r
+\r
+statetype s_red_demon1 = {RED_DEMON1PIC,20,T_RedDemon,&s_red_demon2};\r
+statetype s_red_demon2 = {RED_DEMON2PIC,20,T_RedDemon,&s_red_demon3};\r
+statetype s_red_demon3 = {RED_DEMON3PIC,20,T_RedDemon,&s_red_demon4};\r
+statetype s_red_demon4 = {RED_DEMON4PIC,20,T_RedDemon,&s_red_demon1};\r
+\r
+statetype s_red_demonattack1 = {RED_DEMONATTACK1PIC,20,NULL,&s_red_demonattack2};\r
+statetype s_red_demonattack2 = {RED_DEMONATTACK2PIC,20,NULL,&s_red_demonattack3};\r
+statetype s_red_demonattack3 = {RED_DEMONATTACK3PIC,30,T_DoDamage,&s_red_demon2};\r
+\r
+statetype s_red_demonouch = {RED_DEMONOUCHPIC,15,T_RedDemon,&s_red_demon1};\r
+\r
+statetype s_red_demondie1 = {RED_DEMONDIE1PIC,40,NULL,&s_red_demondie2};\r
+statetype s_red_demondie2 = {RED_DEMONDIE2PIC,30,NULL,&s_red_demondie3};\r
+statetype s_red_demondie3 = {RED_DEMONDIE3PIC,0,NULL,&s_red_demondie3};\r
+\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= SpawnRedDemon\r
+=\r
+===============\r
+*/\r
+\r
+void SpawnRedDemon (int tilex, int tiley)\r
+{\r
+       SpawnNewObj(tilex,tiley,&s_red_demon1,PIXRADIUS*35);\r
+       new->obclass = reddemonobj;\r
+       new->speed = 2048;\r
+       new->flags |= of_shootable;\r
+       new->hitpoints = EasyHitPoints(50);\r
 }\r
 \r
 \r
 /*\r
 ===============\r
 =\r
-= T_MageShoot\r
+= T_RedDemon\r
 =\r
 ===============\r
 */\r
 \r
-void T_MageShoot (objtype *ob)\r
+void T_RedDemon (objtype *ob)\r
 {\r
-       SpawnNewObjFrac (ob->x,ob->y,&s_mshot1,PIXRADIUS*14);\r
-       new->obclass = mshotobj;\r
-       new->speed = MSHOTSPEED;\r
-       if (ob->temp1)\r
-       {\r
-               if (ob->tiley < player->tiley)\r
-                       new->dir = south;\r
-               else\r
-                       new->dir = north;\r
-       }\r
-       else\r
+       if (Chase (ob,true) || (random(1000)<RANDOM_ATTACK))\r
        {\r
-               if (ob->tilex < player->tilex)\r
-                       new->dir = east;\r
-               else\r
-                       new->dir = west;\r
+               ob->state = &s_red_demonattack1;\r
+               ob->ticcount = ob->state->tictime;\r
+               return;\r
        }\r
 }\r
 \r
@@ -787,14 +1663,15 @@ void T_MageShoot (objtype *ob)
 /*\r
 =============================================================================\r
 \r
-                                                       nemesis\r
+                                                       GRELMINAR\r
 \r
 =============================================================================\r
 */\r
 \r
 \r
-void T_Nemesis (objtype *ob);\r
-void T_NemesisShoot (objtype *ob);\r
+void T_Grelminar (objtype *ob);\r
+void T_GrelminarShoot (objtype *ob);\r
+void T_Grelm_DropKey(objtype *ob);\r
 \r
 extern statetype s_grelpause;\r
 \r
@@ -812,107 +1689,91 @@ extern  statetype s_greldie2;
 extern statetype s_greldie3;\r
 extern statetype s_greldie4;\r
 extern statetype s_greldie5;\r
+extern         statetype s_greldie5a;\r
 extern statetype s_greldie6;\r
 \r
 \r
 statetype s_grelpause = {GREL1PIC,50,NULL,&s_grel2};\r
 \r
-statetype s_grel1 = {GREL1PIC,20,T_Nemesis,&s_grel2};\r
-statetype s_grel2 = {GREL2PIC,20,T_Nemesis,&s_grel1};\r
+statetype s_grel1 = {GREL1PIC,20,T_Grelminar,&s_grel2};\r
+statetype s_grel2 = {GREL2PIC,20,T_Grelminar,&s_grel1};\r
 \r
-statetype s_grelattack1 = {GRELATTACKPIC,20,NULL,&s_grelattack2};\r
-statetype s_grelattack2 = {GRELATTACKPIC,-1,T_NemesisShoot,&s_grelattack3};\r
+//statetype s_grelattack1 = {GRELATTACKPIC,20,NULL,&s_grelattack2};\r
+//statetype s_grelattack2 = {GRELATTACKPIC,-1,T_GrelminarShoot,&s_grelattack3};\r
 statetype s_grelattack3 = {GRELATTACKPIC,30,NULL,&s_grelpause};\r
 \r
 statetype s_grelouch = {GRELHITPIC,6,NULL,&s_grel1};\r
 \r
-statetype s_greldie1 = {GRELDIE1PIC,20,NULL,&s_greldie2};\r
-statetype s_greldie2 = {GRELDIE2PIC,20,NULL,&s_greldie3};\r
-statetype s_greldie3 = {GRELDIE3PIC,20,NULL,&s_greldie4};\r
-statetype s_greldie4 = {GRELDIE4PIC,20,NULL,&s_greldie5};\r
-statetype s_greldie5 = {GRELDIE5PIC,20,NULL,&s_greldie6};\r
+statetype s_greldie1 = {GRELDIE1PIC,22,NULL,&s_greldie2};\r
+statetype s_greldie2 = {GRELDIE2PIC,22,NULL,&s_greldie3};\r
+statetype s_greldie3 = {GRELDIE3PIC,22,NULL,&s_greldie4};\r
+statetype s_greldie4 = {GRELDIE4PIC,22,NULL,&s_greldie5};\r
+statetype s_greldie5 = {GRELDIE5PIC,22,NULL,&s_greldie5a};\r
+statetype s_greldie5a = {GRELDIE5PIC,1,T_Grelm_DropKey,&s_greldie6};\r
 statetype s_greldie6 = {GRELDIE6PIC,0,NULL,&s_greldie6};\r
 \r
 \r
+extern statetype s_gshot1;\r
+\r
+statetype s_gshot1 = {SKULL_SHOTPIC,8,T_ShootPlayer,&s_gshot1};\r
+\r
 /*\r
 ===============\r
 =\r
-= SpawnNemesis\r
+= SpawnGrelminar\r
 =\r
 ===============\r
 */\r
 \r
-void SpawnNemesis (int tilex, int tiley)\r
+void SpawnGrelminar (int tilex, int tiley)\r
 {\r
-       SpawnNewObj(tilex,tiley,&s_grel1,PIXRADIUS*56);\r
+       SpawnNewObj(tilex,tiley,&s_grel1,PIXRADIUS*35);\r
        new->obclass = grelmobj;\r
        new->speed = 2048;\r
-       new->shootable = true;\r
-       new->hitpoints = 100;\r
+       new->flags |= of_shootable;\r
+       new->hitpoints = EasyHitPoints(100);\r
 }\r
 \r
 \r
 /*\r
 ===============\r
 =\r
-= T_Nemesis\r
+= T_Grelminar\r
 =\r
 ===============\r
 */\r
 \r
-void T_Nemesis (objtype *ob)\r
+void T_Grelminar (objtype *ob)\r
 {\r
        Chase (ob,false);\r
-//\r
-// check for line up with player\r
-//\r
-       if (ob->tilex == player->tilex)\r
-       {\r
-               ob->temp1 = 1;\r
-               ob->state = &s_grelattack1;\r
-       }\r
-       else if (ob->tiley == player->tiley)\r
-       {\r
-               ob->temp1 = 0;\r
-               ob->state = &s_grelattack1;\r
-       }\r
-}\r
 \r
+       if (!random(10))\r
+               if (ShootPlayer(ob,gshotobj,10000,&s_gshot1))\r
+               {\r
+                       ob->state = &s_grelattack3;\r
+               }\r
+}\r
 \r
-/*\r
-===============\r
-=\r
-= T_NemesisShoot\r
-=\r
-===============\r
-*/\r
 \r
-void T_NemesisShoot (objtype *ob)\r
+//=================================\r
+//\r
+// T_Grelm_DropKey\r
+//\r
+//=================================\r
+void T_Grelm_DropKey(objtype *ob)\r
 {\r
-       SpawnNewObjFrac (ob->x,ob->y,&s_mshot1,PIXRADIUS*14);\r
-       new->obclass = mshotobj;\r
-       new->speed = MSHOTSPEED;\r
        if (ob->temp1)\r
-       {\r
-               if (ob->tiley < player->tiley)\r
-                       new->dir = south;\r
-               else\r
-                       new->dir = north;\r
-       }\r
-       else\r
-       {\r
-               if (ob->tilex < player->tilex)\r
-                       new->dir = east;\r
-               else\r
-                       new->dir = west;\r
-       }\r
-}\r
+               return;\r
 \r
+       SpawnBonus(ob->tilex,ob->tiley,B_RKEY);\r
+       SD_PlaySound(GRELM_DEADSND);\r
+       ob->temp1 = true;\r
+}\r
 \r
 /*\r
 =============================================================================\r
 \r
-                                                  BAT\r
+                                                       BAT\r
 \r
 =============================================================================\r
 */\r
@@ -936,8 +1797,8 @@ statetype s_bat4 = {BAT4PIC,6,T_Bat,&s_bat1};
 \r
 statetype s_batpast = {BAT4PIC,80,T_BatPast,&s_bat1};\r
 \r
-statetype s_batdie1 = {BATDIE1PIC,8,NULL,&s_batdie2};\r
-statetype s_batdie2 = {BATDIE2PIC,8,NULL,NULL};\r
+statetype s_batdie1 = {BATDIE1PIC,18,NULL,&s_batdie2};\r
+statetype s_batdie2 = {BATDIE2PIC,18,NULL,NULL};\r
 \r
 \r
 /*\r
@@ -950,9 +1811,9 @@ statetype s_batdie2 = {BATDIE2PIC,8,NULL,NULL};
 \r
 void SpawnBat (int tilex, int tiley)\r
 {\r
-       SpawnNewObj(tilex,tiley,&s_bat1,PIXRADIUS*24);\r
+       SpawnNewObj(tilex,tiley,&s_bat1,PIXRADIUS*35);\r
        new->obclass =batobj;\r
-       new->shootable = true;\r
+       new->flags |= of_shootable;\r
 \r
        new->hitpoints = 1;\r
        new->speed = 2000;\r
@@ -1130,130 +1991,207 @@ void T_BatPast (objtype *ob)
 }\r
 \r
 \r
+//--------------------------------------------------------------------------\r
+// ShootPlayer()\r
+//--------------------------------------------------------------------------\r
+boolean ShootPlayer(objtype *ob, short obclass, short speed, statetype *state)\r
+{\r
+       int angle = AngleNearPlayer(ob);\r
 \r
-/*\r
-=============================================================================\r
-\r
-                                                  BOUNCE\r
+       if (angle == -1)\r
+               return(false);\r
 \r
-temp2 = set when hit player, reset when hit wall\r
+       DSpawnNewObjFrac (ob->x,ob->y,state,PIXRADIUS*35);\r
+       new->speed = speed;\r
+       new->obclass = obclass;\r
+       new->active = always;\r
+       new->angle = angle;\r
 \r
-=============================================================================\r
-*/\r
+       return(true);\r
+}\r
 \r
-#define SPDBOUNCE      4096\r
-#define DMGBOUNCE      10\r
+//--------------------------------------------------------------------------\r
+// T_ShootPlayer()\r
+//--------------------------------------------------------------------------\r
+void T_ShootPlayer(objtype *ob)\r
+{\r
+       objtype *check;\r
+       long xmove,ymove,speed;\r
 \r
-void T_Bounce (objtype *ob);\r
+       speed = ob->speed*tics;\r
 \r
-extern statetype s_bounce1;\r
-extern statetype s_bounce2;\r
+       xmove = FixedByFrac(speed,costable[ob->angle]);\r
+       ymove = -FixedByFrac(speed,sintable[ob->angle]);\r
 \r
+       if (ShotClipMove(ob,xmove,ymove))\r
+       {\r
+               ob->state = &s_pshot_exp1;\r
+               ob->ticcount = ob->state->tictime;\r
+               return;\r
+       }\r
 \r
-statetype s_bounce1 = {BIGPSHOT1PIC,8,T_Bounce,&s_bounce2};\r
-statetype s_bounce2 = {BIGPSHOT2PIC,8,T_Bounce,&s_bounce1};\r
+       ob->tilex = ob->x >> TILESHIFT;\r
+       ob->tiley = ob->y >> TILESHIFT;\r
 \r
-/*\r
-===============\r
-=\r
-= SpawnBounce\r
-=\r
-===============\r
-*/\r
+// check for collision with wall\r
+//\r
+       if (tilemap[ob->tilex][ob->tiley])\r
+       {\r
+               SD_PlaySound (SHOOTWALLSND);\r
+               ob->state = &s_pshot_exp1;\r
+               ob->ticcount = s_pshot_exp1.tictime;\r
+               return;\r
+       }\r
 \r
-void SpawnBounce (int tilex, int tiley, boolean towest)\r
-{\r
-       SpawnNewObj(tilex,tiley,&s_bounce1,24*PIXRADIUS);\r
-       new->obclass = bounceobj;\r
-       if (towest)\r
-               new->dir = west;\r
-       else\r
-               new->dir = north;\r
-}\r
+//\r
+//\r
+       if ( ob->xl <= player->xh\r
+       && ob->xh >= player->xl\r
+       && ob->yl <= player->yh\r
+       && ob->yh >= player->yl)\r
+       {\r
+               switch (ob->obclass)\r
+               {\r
+                       case eshotobj:\r
+                               TakeDamage (ESHOTDAMAGE);\r
+                       break;\r
 \r
+                       case mshotobj:\r
+                               TakeDamage (MSHOTDAMAGE);\r
+                       break;\r
 \r
-/*\r
-===============\r
-=\r
-= T_Bounce\r
-=\r
-===============\r
-*/\r
+                       case gshotobj:\r
+                               TakeDamage (25);\r
+                       break;\r
+               }\r
+               ob->state = NULL;\r
+               return;\r
+       }\r
 \r
-void T_Bounce (objtype *ob)\r
-{\r
-       long move;\r
-       long deltax,deltay,size;\r
+// check for collision\r
+//\r
+       for (check = player->next; check; check=check->next)\r
+               if ((ob->flags & of_shootable) && ob->obclass != mageobj\r
+               && ob->xl <= check->xh\r
+               && ob->xh >= check->xl\r
+               && ob->yl <= check->yh\r
+               && ob->yh >= check->yl)\r
+               {\r
+                       switch (ob->obclass)\r
+                       {\r
+                               case eshotobj:\r
+                                       ShootActor (check,ESHOTDAMAGE);\r
+                               break;\r
 \r
-       move = SPDBOUNCE*tics;\r
-       size = (long)ob->size + player->size + move;\r
+                               case mshotobj:\r
+                                       ShootActor (check,MSHOTDAMAGE);\r
+                               break;\r
 \r
-       while (move)\r
-       {\r
-               deltax = ob->x - player->x;\r
-               deltay = ob->y - player->y;\r
+                               case gshotobj:\r
+                                       ShootActor (check,25);\r
+                               break;\r
 \r
-               if (deltax <= size && deltax >= -size\r
-               && deltay <= size && deltay >= -size && !ob->temp2)\r
-               {\r
-                       ob->temp2 = 1;\r
-                       TakeDamage (DMGBOUNCE);\r
+                               case pshotobj:\r
+                                       ShootActor (check,25);\r
+                               break;\r
+                       }\r
+                       ob->state = &s_pshot_exp1;\r
+                       ob->ticcount = s_pshot_exp1.tictime;\r
+                       return;\r
                }\r
+}\r
 \r
-               if (move < ob->distance)\r
+//-------------------------------------------------------------------------\r
+// AngleNearPlayer()\r
+//-------------------------------------------------------------------------\r
+int AngleNearPlayer(objtype *ob)\r
+{\r
+       int angle=-1;\r
+       int xdiff = ob->tilex-player->tilex;\r
+       int ydiff = ob->tiley-player->tiley;\r
+\r
+       if (ob->tiley == player->tiley)\r
+       {\r
+               if (ob->tilex < player->tilex)\r
+                       angle = 0;\r
+               else\r
+                       angle = 180;\r
+       }\r
+       else\r
+       if (ob->tilex == player->tilex)\r
+       {\r
+               if (ob->tiley < player->tiley)\r
+                       angle = 270;\r
+               else\r
+                       angle = 90;\r
+       }\r
+       else\r
+       if (xdiff == ydiff)\r
+               if (ob->tilex < player->tilex)\r
                {\r
-                       MoveObj (ob,move);\r
-                       break;\r
+                       if (ob->tiley < player->tiley)\r
+                               angle = 315;\r
+                       else\r
+                               angle = 45;\r
                }\r
-               actorat[ob->tilex][ob->tiley] = 0;      // pick up marker from goal\r
-\r
-               ob->x = ((long)ob->tilex<<TILESHIFT)+TILEGLOBAL/2;\r
-               ob->y = ((long)ob->tiley<<TILESHIFT)+TILEGLOBAL/2;\r
-               move -= ob->distance;\r
-\r
-               //\r
-               // bounce if hit wall\r
-               //\r
-               switch (ob->dir)\r
+               else\r
                {\r
-               case north:\r
-                       if (tilemap[ob->tilex][--ob->tiley])\r
-                       {\r
-                               ob->dir = south;\r
-                               ob->tiley+=2;\r
-                               ob->temp2 = 0;\r
-                       }\r
-                       break;\r
-               case east:\r
-                       if (tilemap[++ob->tilex][ob->tiley])\r
-                       {\r
-                               ob->dir = west;\r
-                               ob->tilex-=2;\r
-                               ob->temp2 = 0;\r
-                       }\r
-                       break;\r
-               case south:\r
-                       if (tilemap[ob->tilex][++ob->tiley])\r
-                       {\r
-                               ob->dir = north;\r
-                               ob->tiley-=2;\r
-                               ob->temp2 = 0;\r
-                       }\r
-                       break;\r
-               case west:\r
-                       if (tilemap[--ob->tilex][ob->tiley])\r
-                       {\r
-                               ob->dir = east;\r
-                               ob->tilex+=2;\r
-                               ob->temp2 = 0;\r
-                       }\r
-                       break;\r
+                       if (ob->tiley < player->tiley)\r
+                               angle = 225;\r
+                       else\r
+                               angle = 135;\r
                }\r
 \r
-               ob->distance = TILEGLOBAL;\r
+       return(angle);\r
+}\r
 \r
-               actorat[ob->tilex][ob->tiley] = ob;     // set down a new goal marker\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+//     EasyHitPoints\r
+//\r
+//     Checks to see if the player has selected the easy mode for playing.\r
+//     If so then the normal hit points are cut in half.\r
+//     This is when the object is spawned.\r
+//\r
+//     Parms\r
+//             NrmHitPts - the normal hit points\r
+//\r
+//     Returns\r
+//             Half of NrmHitPts\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+int EasyHitPoints(int NrmHitPts)\r
+{\r
+       if (EASYMODEON)                         // Wimpy, Wimpy, Wimpy!!!!!\r
+       {\r
+               return(NrmHitPts/4);\r
        }\r
-       CalcBounds (ob);\r
+       else\r
+               return(NrmHitPts);\r
+}\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+//\r
+//     EasyDoDamage\r
+//\r
+//     Checks to see if the player has selected the easy mode for playing.\r
+//     If so then the normal amount of damage is cut in half.\r
+//     This is called each time a monster does damage.\r
+//\r
+//     Parms\r
+//             Damage - the normal damage taken\r
+//\r
+//     Returns\r
+//             Half of Damage\r
+//\r
+/////////////////////////////////////////////////////////////////////////////\r
+\r
+int EasyDoDamage(int Damage)\r
+{\r
+       if (EASYMODEON)                         // Wimpy, Wimpy, Wimpy!!!!!\r
+               return(Damage/2);\r
+       else\r
+               return(Damage);\r
 }\r
 \r
index d9da6eb64c3388a8ef18db1a06d17e11d755af2b..05eb2f080816ba03752d97e95c6c36de750ddb5b 100644 (file)
@@ -1,4 +1,4 @@
-; Catacomb 3-D Source Code\r
+; Catacomb Abyss Source Code\r
 ; Copyright (C) 1993-2014 Flat Rock Software\r
 ;\r
 ; This program is free software; you can redistribute it and/or modify\r
@@ -19,7 +19,9 @@ IDEAL
 \r
 MODEL  MEDIUM,C\r
 \r
-VIEWWIDTH      =       (33*8)\r
+INCLUDE        "ID_ASM.EQU"\r
+\r
+VIEWWIDTH      =       (40*8)                  ;33\r
 GC_INDEX       =       03CEh\r
 \r
 DATASEG\r
@@ -103,6 +105,8 @@ EXTRN       scaledirectory:WORD                     ; array of MAXSCALE segment pointers to
                                                                        ; compiled scalers\r
 EXTRN  screenseg:WORD                          ; basically just 0xa000\r
 EXTRN  bufferofs:WORD                          ; offset of the current work screen\r
+EXTRN ylookup:WORD\r
+EXTRN screenpage:WORD\r
 \r
 CODESEG\r
 \r
@@ -192,6 +196,53 @@ done:
 \r
 ENDP\r
 \r
+;---------------------------------------------------------------------------\r
+;\r
+; RadarBlip()\r
+;\r
+; Displays a 'blip' (1 pixel wide X 2 pixel high) on the radar at\r
+; an (X,Y) relative to (RADAR_X,RADAR_Y) (defined below...)\r
+;\r
+;---------------------------------------------------------------------------\r
+\r
+PROC   RadarBlip x:WORD, y:WORD, color:WORD\r
+USES   SI,DI\r
+PUBLIC RadarBlip\r
+\r
+       mov     ax,[screenseg]\r
+\r
+       mov     es,ax\r
+       xor     di,di\r
+\r
+       lea     si,[ylookup]\r
+       add     si,[y]\r
+       add     si,[y]\r
+       add     di,[si]\r
+\r
+       mov     ax,[x]\r
+       shr     ax,1\r
+       shr     ax,1\r
+       shr     ax,1\r
+       add     di,ax\r
+\r
+       mov     ax,[x]\r
+       and     ax,7\r
+       mov     cl,al\r
+       mov     ah,080h\r
+       shr     ah,cl\r
+       cli\r
+       mov     al,GC_BITMASK\r
+       mov     dx,GC_INDEX\r
+       out     dx,ax\r
+       sti\r
+\r
+       mov     ax,[color]\r
+       mov     ah,[es:di]                                              ; read into latches\r
+       mov     [es:di],al                                              ; write latches / color bit\r
+\r
+       ret\r
+\r
+ENDP\r
 \r
 END\r
 \r
index 4aa683123983b7a265791184bd17ffd519f0244d..c631b43eb514339bb0b53f6e4ccf68f3400e4592 100644 (file)
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code\r
+/* Catacomb Abyss Source Code\r
  * Copyright (C) 1993-2014 Flat Rock Software\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
@@ -18,7 +18,8 @@
 \r
 // C3_DEBUG.C\r
 \r
-#include "C3_DEF.H"\r
+#include "DEF.H"\r
+#include "gelib.h"\r
 #pragma hdrstop\r
 \r
 /*\r
@@ -29,6 +30,9 @@
 =============================================================================\r
 */\r
 \r
+#define DEBUG_OVERHEAD 0\r
+\r
+\r
 #define VIEWTILEX      20\r
 #define VIEWTILEY      (VIEWHEIGHT/16)\r
 \r
 =============================================================================\r
 */\r
 \r
-\r
+boolean autofire=false;\r
 int    maporgx;\r
 int    maporgy;\r
-enum {mapview,tilemapview,actoratview,visview} viewtype;\r
+enum {mapview,tilemapview,actoratview,visview,mapseg2,lastview}        viewtype;\r
 \r
 void ViewMap (void);\r
 \r
 //===========================================================================\r
 \r
 \r
-\r
 /*\r
 ==================\r
 =\r
@@ -76,7 +79,7 @@ void DebugMemory (void)
        spritetype _seg *block;\r
 \r
        VW_FixRefreshBuffer ();\r
-       US_CenterWindow (16,7);\r
+       CenterWindow (16,7);\r
 \r
 #if 0\r
        CA_OpenDebug ();\r
@@ -109,6 +112,7 @@ void DebugMemory (void)
 \r
 //===========================================================================\r
 \r
+#if 0\r
 /*\r
 ================\r
 =\r
@@ -124,7 +128,7 @@ void PicturePause (void)
 \r
        source = displayofs+panadjust;\r
 \r
-       VW_ColorBorder (15);\r
+//     VW_ColorBorder (15);\r
        VW_SetLineWidth (40);\r
        VW_SetScreen (0,0);\r
 \r
@@ -152,24 +156,11 @@ void PicturePause (void)
        VW_WaitVBL(70);\r
        Quit (NULL);\r
 }\r
+#endif\r
 \r
 \r
 //===========================================================================\r
 \r
-/*\r
-================\r
-=\r
-= ShapeTest\r
-=\r
-================\r
-*/\r
-\r
-void ShapeTest (void)\r
-{\r
-\r
-}\r
-\r
-\r
 //===========================================================================\r
 \r
 #define        sc_1                    0x02\r
@@ -198,6 +189,160 @@ int DebugKeys (void)
        boolean esc;\r
        int level,i;\r
 \r
+#if 0\r
+       if (Keyboard[sc_A])\r
+       {\r
+               char levelstr[50];\r
+               unsigned org_tile,org_mapon,msgnum;\r
+               boolean newmsg=true,newlevel=false;\r
+\r
+               VW_FixRefreshBuffer ();\r
+               CenterWindow (16,3);\r
+               US_Print("\n");\r
+               US_CPrint("Message Test");\r
+               VW_UpdateScreen();\r
+\r
+               org_mapon = mapon;\r
+               msgnum = (org_tile = *(mapsegs[0]+farmapylookup[player->tiley]+player->tilex))-NAMESTART;\r
+               while (1)\r
+               {\r
+       // Get outta' here\r
+       //\r
+                       if (Keyboard[sc_Escape])\r
+                       {\r
+                               while (Keyboard[sc_Escape]);\r
+                               break;\r
+                       }\r
+\r
+       // Move to previous message\r
+       //\r
+                       if (Keyboard[sc_UpArrow])\r
+                       {\r
+                               if (msgnum)\r
+                               {\r
+                                       msgnum--;\r
+                                       newmsg = true;\r
+                               }\r
+                       }\r
+\r
+       // Move to next message\r
+       //\r
+                       if (Keyboard[sc_DownArrow])\r
+                       {\r
+                               if (msgnum < 24)\r
+                               {\r
+                                       msgnum++;\r
+                                       newmsg = true;\r
+                               }\r
+                       }\r
+\r
+       // Move to previous level\r
+       //\r
+                       if (Keyboard[sc_LeftArrow])\r
+                       {\r
+                               if (mapon)\r
+                               {\r
+                                       MM_SetPurge(&grsegs[LEVEL1TEXT+mapon],3);\r
+                                       mapon--;\r
+                                       newlevel = true;\r
+                               }\r
+                       }\r
+\r
+       // Move to next level\r
+       //\r
+                       if (Keyboard[sc_RightArrow])\r
+                       {\r
+                               if (mapon < LASTMAP-2)\r
+                               {\r
+                                       MM_SetPurge(&grsegs[LEVEL1TEXT+mapon],3);\r
+                                       mapon++;\r
+                                       newlevel = true;\r
+                               }\r
+                       }\r
+\r
+       // Load new level text\r
+       //\r
+                       if (newlevel)\r
+                       {\r
+                               CA_CacheGrChunk(LEVEL1TEXT+mapon);\r
+                               ScanText();\r
+                               newmsg = true;\r
+                               newlevel=false;\r
+                       }\r
+\r
+       // Display new message text\r
+       //\r
+                       if (newmsg)\r
+                       {\r
+                               *(mapsegs[0]+farmapylookup[player->tiley]+player->tilex) = msgnum+NAMESTART;\r
+                               DrawText(true);\r
+                               strcpy(levelstr,"Level: ");\r
+                               itoa(mapon,levelstr+strlen(levelstr),10);\r
+                               strcat(levelstr,"  Msg: ");\r
+                               itoa(msgnum,levelstr+strlen(levelstr),10);\r
+                               DisplaySMsg(levelstr,NULL);\r
+                               newmsg = false;\r
+\r
+                               if (Keyboard[sc_UpArrow] || Keyboard[sc_DownArrow] || Keyboard[sc_LeftArrow] || Keyboard[sc_RightArrow])\r
+                                       VW_WaitVBL(6);\r
+                       }\r
+\r
+               }\r
+// Restore game\r
+//\r
+               MM_SetPurge(&grsegs[LEVEL1TEXT+mapon],3);\r
+               mapon = org_mapon;\r
+               CA_CacheGrChunk(LEVEL1TEXT+mapon);\r
+               ScanText();\r
+               *(mapsegs[0]+farmapylookup[player->tiley]+player->tilex) = org_tile;\r
+               DrawText(true);\r
+               status_flag = 0;\r
+       }\r
+#endif\r
+\r
+       if (Keyboard[sc_T])\r
+       {\r
+               VW_FixRefreshBuffer ();\r
+               CenterWindow (16,4);\r
+\r
+               US_Print("Tics      :");\r
+               US_PrintUnsigned (tics);\r
+               US_Print("\nReal Tics :");\r
+               US_PrintUnsigned(realtics);\r
+               VW_UpdateScreen();\r
+               IN_Ack ();\r
+       }\r
+\r
+       if (Keyboard[sc_V])\r
+       {\r
+               displayofs = bufferofs = screenloc[screenpage];\r
+               CenterWindow (20,5);\r
+               US_CPrint("\n"GAMENAME);\r
+               US_CPrint(VERSION);\r
+               US_CPrint(REVISION);\r
+               VW_UpdateScreen();\r
+               IN_Ack ();\r
+       }\r
+\r
+       if (Keyboard[sc_Q])                     // Q = Insta-Quit!\r
+               Quit("Insta-Quit!");\r
+\r
+       if (Keyboard[sc_Z])             // Z = freeze Time\r
+       {\r
+               if (FreezeTime)\r
+                 FreezeTime = 1;               // Allow refresh to dec to zero..\r
+               else\r
+                       StopTime();\r
+\r
+               IN_Ack();\r
+               return 1;\r
+       }\r
+\r
+//     if (Keyboard[sc_E])\r
+//             FaceDoor((player->x>>16l)+1,(player->y>>16l));\r
+//             FaceAngle(90);\r
+\r
+#if 0\r
        if (Keyboard[sc_B])             // B = border color\r
        {\r
                CenterWindow(24,3);\r
@@ -213,9 +358,9 @@ int DebugKeys (void)
                }\r
                return 1;\r
        }\r
+#endif\r
 \r
 #if 0\r
-\r
        if (Keyboard[sc_C])             // C = count objects\r
        {\r
                CountObjects();\r
@@ -234,9 +379,9 @@ int DebugKeys (void)
                }\r
                return 1;\r
        }\r
-\r
 #endif\r
 \r
+#if 0\r
        if (Keyboard[sc_E])             // E = quit level\r
        {\r
                if (tedlevel)\r
@@ -244,7 +389,9 @@ int DebugKeys (void)
                playstate = ex_warped;\r
                gamestate.mapon++;\r
        }\r
+#endif\r
 \r
+#if 0\r
        if (Keyboard[sc_F])             // F = facing spot\r
        {\r
                CenterWindow (12,4);\r
@@ -258,6 +405,7 @@ int DebugKeys (void)
                IN_Ack();\r
                return 1;\r
        }\r
+#endif\r
 \r
        if (Keyboard[sc_G])             // G = god mode\r
        {\r
@@ -271,12 +419,18 @@ int DebugKeys (void)
                godmode ^= 1;\r
                return 1;\r
        }\r
+\r
+#if 0\r
        if (Keyboard[sc_H])             // H = hurt self\r
        {\r
                TakeDamage (5);\r
        }\r
-       else if (Keyboard[sc_I])                        // I = item cheat\r
+#endif\r
+\r
+       if (Keyboard[sc_I])                     // I = item cheat\r
        {\r
+               extern boolean redraw_gems;\r
+\r
                CenterWindow (12,3);\r
                US_PrintCentered ("Free items!");\r
                VW_UpdateScreen();\r
@@ -285,31 +439,43 @@ int DebugKeys (void)
                        GiveBolt ();\r
                        GiveNuke ();\r
                        GivePotion ();\r
-                       if (!gamestate.keys[i])\r
+//                     if (!gamestate.keys[i])\r
                                GiveKey (i);\r
+                       gamestate.gems[i] = GEM_DELAY_TIME;\r
                }\r
+               gamestate.gems[4] = GEM_DELAY_TIME;\r
+               redraw_gems = true;\r
                for (i=0;i<8;i++)\r
                        GiveScroll (i,false);\r
 \r
                IN_Ack ();\r
                return 1;\r
        }\r
-       else if (Keyboard[sc_M])                        // M = memory info\r
+\r
+       if (Keyboard[sc_M])                     // M = memory info\r
        {\r
                DebugMemory();\r
                return 1;\r
        }\r
-       else if (Keyboard[sc_O])                        // O = overhead\r
+\r
+#if DEBUG_OVERHEAD\r
+       if (Keyboard[sc_O])                     // O = overhead\r
        {\r
                ViewMap();\r
                return 1;\r
        }\r
-       else if (Keyboard[sc_P])                        // P = pause with no screen disruptioon\r
+#endif\r
+\r
+#if 0\r
+       if (Keyboard[sc_P])                     // P = pause with no screen disruptioon\r
        {\r
                PicturePause ();\r
                return 1;\r
        }\r
-       else if (Keyboard[sc_S])        // S = slow motion\r
+#endif\r
+\r
+#if 0\r
+       if (Keyboard[sc_S])     // S = slow motion\r
        {\r
                singlestep^=1;\r
                CenterWindow (18,3);\r
@@ -321,12 +487,10 @@ int DebugKeys (void)
                IN_Ack ();\r
                return 1;\r
        }\r
-       else if (Keyboard[sc_S])        // T = shape test\r
-       {\r
-               ShapeTest ();\r
-               return 1;\r
-       }\r
-       else if (Keyboard[sc_V])                        // V = extra VBLs\r
+#endif\r
+\r
+#if 0\r
+       if (Keyboard[sc_V])                     // V = extra VBLs\r
        {\r
                CenterWindow(30,3);\r
                PrintY+=6;\r
@@ -341,25 +505,30 @@ int DebugKeys (void)
                }\r
                return 1;\r
        }\r
-       else if (Keyboard[sc_W])        // W = warp to level\r
+#endif\r
+\r
+       if (Keyboard[sc_W])     // W = warp to level\r
        {\r
                CenterWindow(26,3);\r
                PrintY+=6;\r
-               US_Print("  Warp to which level(1-21):");\r
+               US_Print("  Warp to which level(0-18):");\r
                VW_UpdateScreen();\r
                esc = !US_LineInput (px,py,str,NULL,true,2,0);\r
                if (!esc)\r
                {\r
                        level = atoi (str);\r
-                       if (level>0 && level<21)\r
+                       if (level>=0 && level<=LASTMAP-1)\r
                        {\r
-                               gamestate.mapon = level-1;\r
+                               gamestate.mapon = level;\r
                                playstate = ex_warped;\r
+                               lasttext = -1;\r
                        }\r
                }\r
                return 1;\r
        }\r
-       else if (Keyboard[sc_X])                        // X = item cheat\r
+\r
+#if 0\r
+       if (Keyboard[sc_X])                     // X = item cheat\r
        {\r
                CenterWindow (12,3);\r
                US_PrintCentered ("Extra stuff!");\r
@@ -373,11 +542,9 @@ int DebugKeys (void)
                IN_Ack ();\r
                return 1;\r
        }\r
-       else if (Keyboard[sc_Z])                        // Z = game over\r
-       {\r
+#endif\r
 \r
-       }\r
-       else if (LastScan >= sc_1 && LastScan <= sc_8)  // free scrolls\r
+       if (LastScan >= sc_1 && LastScan <= sc_8)       // free scrolls\r
        {\r
                GiveScroll (LastScan-sc_1,false);\r
                IN_ClearKeysDown ();\r
@@ -387,6 +554,8 @@ int DebugKeys (void)
 }\r
 \r
 \r
+#if DEBUG_OVERHEAD\r
+\r
 /*\r
 =====================\r
 =\r
@@ -437,7 +606,10 @@ asm        mov     ds,ax                                   // restore turbo's data segment
        EGAWRITEMODE(0);\r
 }\r
 \r
+#endif\r
+\r
 \r
+#if DEBUG_OVERHEAD\r
 /*\r
 =====================\r
 =\r
@@ -480,8 +652,10 @@ asm        mov     ds,ax                                   // restore turbo's data segment
 \r
        EGAWRITEMODE(0);\r
 }\r
+#endif\r
 \r
 \r
+#if DEBUG_OVERHEAD\r
 /*\r
 ===================\r
 =\r
@@ -528,6 +702,12 @@ void OverheadRefresh (void)
                                tile = spotvis[x][y];\r
                                break;\r
 \r
+                       case mapseg2:\r
+                               tile = *(mapsegs[2]+farmapylookup[y]+x);\r
+                               if (tile < 256)\r
+                                       tile = *(mapsegs[0]+farmapylookup[y]+x);\r
+                       break;\r
+\r
                        }\r
 \r
                        if (tile<NUMTILE16)\r
@@ -574,24 +754,24 @@ void ViewMap (void)
 //\r
 // let user pan around\r
 //\r
-               IN_ReadControl(0,&c);\r
-               if (c.xaxis == -1 && maporgx>0)\r
+               IN_ReadControl(0,&control);\r
+               if (control.xaxis == -1 && maporgx>0)\r
                        maporgx--;\r
-               if (c.xaxis == 1 && maporgx<mapwidth-VIEWTILEX)\r
+               if (control.xaxis == 1 && maporgx<mapwidth-VIEWTILEX)\r
                        maporgx++;\r
-               if (c.yaxis == -1 && maporgy>0)\r
+               if (control.yaxis == -1 && maporgy>0)\r
                        maporgy--;\r
-               if (c.yaxis == 1 && maporgy<mapheight-VIEWTILEY)\r
+               if (control.yaxis == 1 && maporgy<mapheight-VIEWTILEY)\r
                        maporgy++;\r
 \r
-               if (c.button0 && !button0held)\r
+               if (control.button0 && !button0held)\r
                {\r
                        button0held = true;\r
                        viewtype++;\r
-                       if (viewtype>visview)\r
+                       if (viewtype==lastview)\r
                                viewtype = mapview;\r
                }\r
-               if (!c.button0)\r
+               if (!control.button0)\r
                        button0held = false;\r
 \r
 \r
@@ -602,5 +782,5 @@ void ViewMap (void)
        IN_ClearKeysDown ();\r
        DrawPlayScreen ();\r
 }\r
-\r
+#endif\r
 \r
index dfb055e52bcb337ee984254ebabed6e19836c014..e4c59f3c08f1c22728415cc6c97f5f29ae8f2e34 100644 (file)
--- a/C4_DRAW.C
+++ b/C4_DRAW.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code\r
+/* Catacomb Abyss Source Code\r
  * Copyright (C) 1993-2014 Flat Rock Software\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
@@ -18,7 +18,7 @@
 \r
 // C3_DRAW.C\r
 \r
-#include "C3_DEF.H"\r
+#include "DEF.H"\r
 #pragma hdrstop\r
 \r
 //#define DRAWEACH                             // draw walls one at a time for debugging\r
@@ -61,8 +61,8 @@ const unsigned        BASESCALE               = 32;
 // maximum possible distance seperating them (for scaling overflow)\r
 //\r
 \r
-unsigned screenloc[3]= {0x900,0x2000,0x3700};\r
-unsigned freelatch = 0x4e00;\r
+unsigned screenloc[3]= {PAGE1START,PAGE2START,PAGE3START};\r
+unsigned freelatch = FREESTART;\r
 \r
 boolean                fizzlein;\r
 \r
@@ -160,6 +160,7 @@ void        BuildTables (void);
 //==========================================================================\r
 \r
 \r
+#if 0\r
 /*\r
 ==================\r
 =\r
@@ -366,6 +367,8 @@ asm xchg    bh,[es:di]      // load latches and write pixels
 \r
 }\r
 \r
+#endif\r
+\r
 //==========================================================================\r
 \r
 \r
@@ -435,41 +438,152 @@ void near ScaleOneWall (int xl, int xh)
 \r
 #endif\r
 \r
+// EAST / WEST WALLS\r
+//\r
 int    walllight1[NUMFLOORS] = {0,\r
-       WALL1LPIC,WALL2LPIC,WALL3LPIC,WALL4LPIC,WALL5LPIC,WALL6LPIC,WALL7LPIC,\r
-       WALL1LPIC,WALL2LPIC,WALL3LPIC,WALL4LPIC,WALL5LPIC,WALL6LPIC,WALL7LPIC,\r
+       W_WARP1EWPIC,\r
+       W_NEMPICEWPIC,W_PENTAEWPIC,W_ALTER_LFPIC,W_ALTER_RTPIC,\r
+       W_SUB1EWPIC,W_SUB2EWPIC,W_SUB3EWPIC,\r
+\r
+       W_TORCH1PIC,W_TORCH2PIC,\r
+       W_LSUB_STONEPIC,\r
+       W_BLOODY_LSUB_STONEPIC,\r
+       W_BREATH_LWALL1PIC,W_BREATH_LWALL2PIC,\r
+\r
        EXPWALL1PIC,EXPWALL2PIC,EXPWALL3PIC,\r
-       RDOOR1PIC,RDOOR2PIC,RDOOR1PIC,RDOOR2PIC,\r
-       YDOOR1PIC,YDOOR2PIC,YDOOR1PIC,YDOOR2PIC,\r
-       GDOOR1PIC,GDOOR2PIC,GDOOR1PIC,GDOOR2PIC,\r
-       BDOOR1PIC,BDOOR2PIC,BDOOR1PIC,BDOOR2PIC};\r
 \r
+       W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,\r
+\r
+       W_WATER1EWPIC,W_DRAIN1EWPIC,\r
+       W_WATER2EWPIC,W_DRAIN2EWPIC,\r
+\r
+       W_WOODEN_DOORPIC,W_WOOD_DOOREWPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,\r
+\r
+       W_FINALEXITPIC,\r
+\r
+       W_WATER_EXP1PIC,W_WATER_EXP2PIC,W_WATER_EXP3PIC,\r
+\r
+       W_PRE_CHEATSPIC,W_CHEAT_WARPPIC,W_CHEAT_FREEZEPIC,W_SURFACE_PLAQPIC,\r
+\r
+       W_WATER_GATEEW1PIC,\r
+       WALL8LPIC,WALL9LPIC,WALL10DPIC,WALL11LPIC,WALL12LPIC,WALL13LPIC,WALL14LPIC,WALL15LPIC,\r
+       WALL16LPIC,WALL17LPIC,W_WINDOWEWPIC,WALL19LPIC,WALL20LPIC,WALL21LPIC,\r
+       WALL22LPIC,WALL23LPIC,WALL24LPIC,WALL25LPIC,WALL26LPIC,WALL27LPIC,\r
+       WALL28LPIC,WALL29LPIC,WALL30LPIC,WALL31LPIC,\r
+       W_BREATH_LWALL4PIC,W_BREATH_LWALL3PIC,\r
+       MAGE_STATUEPIC,ZOMBIE_STATUEPIC,EYE_STATUEPIC,NEM_STATUEPIC,\r
+       SKELETON_STATUEPIC,SPOOK_STATUEPIC,ORCH_STATUEPIC,\r
+       };\r
+\r
+// NORTH / SOUTH WALLS\r
+//\r
 int    walldark1[NUMFLOORS] = {0,\r
-       WALL1DPIC,WALL2DPIC,WALL3DPIC,WALL4DPIC,WALL5DPIC,WALL6DPIC,WALL7DPIC,\r
-       WALL1DPIC,WALL2DPIC,WALL3DPIC,WALL4DPIC,WALL5DPIC,WALL6DPIC,WALL7DPIC,\r
+       W_WARP1NSPIC,\r
+       W_NEMPICEWPIC,W_PENTANSPIC,1,1,\r
+       W_SUB1NSPIC,W_SUB2NSPIC,W_SUB3NSPIC,\r
+\r
+       W_TORCH1PIC,W_TORCH2PIC,\r
+       W_DSUB_STONEPIC,\r
+       W_BLOODY_DSUB_STONEPIC,\r
+       W_BREATH_DWALL1PIC,W_BREATH_DWALL2PIC,\r
+\r
        EXPWALL1PIC,EXPWALL2PIC,EXPWALL3PIC,\r
-       RDOOR1PIC,RDOOR2PIC,RDOOR1PIC,RDOOR2PIC,\r
-       YDOOR1PIC,YDOOR2PIC,YDOOR1PIC,YDOOR2PIC,\r
-       GDOOR1PIC,GDOOR2PIC,GDOOR1PIC,GDOOR2PIC,\r
-       BDOOR1PIC,BDOOR2PIC,BDOOR1PIC,BDOOR2PIC};\r
 \r
+       W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,\r
+\r
+       W_WATER1NSPIC,W_DRAIN1NSPIC,\r
+       W_WATER2NSPIC,W_DRAIN2NSPIC,\r
+       W_WOODEN_DOORPIC,W_WOOD_DOORNSPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,\r
+\r
+       W_FINALEXITPIC,\r
+\r
+       W_WATER_EXP1PIC,W_WATER_EXP2PIC,W_WATER_EXP3PIC,\r
+\r
+       W_CHEAT_GODPIC,W_CHEAT_ITEMSPIC,W_POST_CHEATPIC,W_SURFACE_PLAQPIC,\r
+\r
+       W_WATER_GATENS1PIC,\r
+       WALL8DPIC,WALL9DPIC,WALL10LPIC,WALL11DPIC,WALL12DPIC,WALL13DPIC,WALL14DPIC,WALL15DPIC,\r
+       WALL16DPIC,WALL17DPIC,W_WINDOWNSPIC,WALL19DPIC,WALL20DPIC,WALL21DPIC,\r
+       WALL22DPIC,WALL23DPIC,WALL24DPIC,WALL25DPIC,WALL26DPIC,WALL27DPIC,\r
+       WALL28DPIC,WALL29DPIC,WALL30DPIC,WALL31DPIC,\r
+       W_BREATH_DWALL4PIC,W_BREATH_DWALL3PIC,\r
+       MAGE_STATUEPIC,ZOMBIE_STATUEPIC,EYE_STATUEPIC,NEM_STATUEPIC,\r
+       SKELETON_STATUEPIC,SPOOK_STATUEPIC,ORCH_STATUEPIC,\r
+       };\r
+\r
+// EAST / WEST WALLS\r
+//\r
 int    walllight2[NUMFLOORS] = {0,\r
-       WALL1LPIC,WALL2LPIC,WALL3LPIC,WALL4LPIC,WALL5LPIC,WALL6LPIC,WALL7LPIC,\r
-       WALL1LPIC,WALL2LPIC,WALL3LPIC,WALL4LPIC,WALL5LPIC,WALL6LPIC,WALL7LPIC,\r
-       EXPWALL1PIC,EXPWALL2PIC,EXPWALL3PIC,\r
-       RDOOR2PIC,RDOOR1PIC,RDOOR2PIC,RDOOR1PIC,\r
-       YDOOR2PIC,YDOOR1PIC,YDOOR2PIC,YDOOR1PIC,\r
-       GDOOR2PIC,GDOOR1PIC,GDOOR2PIC,GDOOR1PIC,\r
-       BDOOR2PIC,BDOOR1PIC,BDOOR2PIC,BDOOR1PIC};\r
+       W_WARP2EWPIC,\r
+       W_NEMPICEWPIC,W_PENTAEWPIC,W_ALTER_LFPIC,W_ALTER_RTPIC,\r
+       W_SUB1EWPIC,W_SUB2EWPIC,W_SUB3EWPIC,\r
+\r
+       W_TORCH2PIC,W_TORCH1PIC,\r
+       W_LSUB_STONEPIC,\r
+       W_BLOODY_LSUB_STONEPIC,\r
+       W_BREATH_LWALL2PIC,W_BREATH_LWALL1PIC,\r
+\r
+       EXPWALL2PIC,EXPWALL1PIC,EXPWALL3PIC,\r
+\r
+       W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,\r
+\r
+       W_WATER2EWPIC,W_DRAIN2EWPIC,\r
+       W_WATER1EWPIC,W_DRAIN1EWPIC,\r
+\r
+       W_WOODEN_DOORPIC,W_WOOD_DOOREWPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,\r
 \r
+       W_FINALEXITPIC,\r
+\r
+       W_WATER_EXP2PIC,W_WATER_EXP1PIC,W_WATER_EXP1PIC,\r
+\r
+       W_PRE_CHEATSPIC,W_CHEAT_WARPPIC,W_CHEAT_FREEZEPIC,W_SURFACE_PLAQPIC,\r
+\r
+       W_WATER_GATEEW2PIC,\r
+       WALL8LPIC,WALL9LPIC,WALL10DPIC,WALL11LPIC,WALL12LPIC,WALL13LPIC,WALL14LPIC,WALL15LPIC,\r
+       WALL16LPIC,WALL17LPIC,W_WINDOWEWPIC,WALL19LPIC,WALL20LPIC,WALL21LPIC,\r
+       WALL22LPIC,WALL23LPIC,WALL24LPIC,WALL25LPIC,WALL26LPIC,WALL27LPIC,\r
+       WALL28LPIC,WALL29LPIC,WALL30LPIC,WALL31LPIC,\r
+       W_BREATH_LWALL3PIC,W_BREATH_LWALL4PIC,\r
+       MAGE_STATUEPIC,ZOMBIE_STATUEPIC,EYE_STATUEPIC,NEM_STATUEPIC,\r
+       SKELETON_STATUEPIC,SPOOK_STATUEPIC,ORCH_STATUEPIC,\r
+       };\r
+\r
+// NORTH / SOUTH WALLS\r
+//\r
 int    walldark2[NUMFLOORS] = {0,\r
-       WALL1DPIC,WALL2DPIC,WALL3DPIC,WALL4DPIC,WALL5DPIC,WALL6DPIC,WALL7DPIC,\r
-       WALL1DPIC,WALL2DPIC,WALL3DPIC,WALL4DPIC,WALL5DPIC,WALL6DPIC,WALL7DPIC,\r
-       EXPWALL1PIC,EXPWALL2PIC,EXPWALL3PIC,\r
-       RDOOR2PIC,RDOOR1PIC,RDOOR2PIC,RDOOR1PIC,\r
-       YDOOR2PIC,YDOOR1PIC,YDOOR2PIC,YDOOR1PIC,\r
-       GDOOR2PIC,GDOOR1PIC,GDOOR2PIC,GDOOR1PIC,\r
-       BDOOR2PIC,BDOOR1PIC,BDOOR2PIC,BDOOR1PIC};\r
+       W_WARP2NSPIC,\r
+       W_NEMPICEWPIC,W_PENTANSPIC,1,1,\r
+       W_SUB1NSPIC,W_SUB2NSPIC,W_SUB3NSPIC,\r
+\r
+       W_TORCH2PIC,W_TORCH1PIC,\r
+       W_DSUB_STONEPIC,\r
+       W_BLOODY_DSUB_STONEPIC,\r
+       W_BREATH_DWALL2PIC,W_BREATH_DWALL1PIC,\r
+\r
+       EXPWALL2PIC,EXPWALL1PIC,EXPWALL3PIC,\r
+\r
+       W_WOOD_DOORWAYPIC,W_WOOD_DOORWAY_GLOWPIC,\r
+\r
+       W_WATER2NSPIC,W_DRAIN2NSPIC,\r
+       W_WATER1NSPIC,W_DRAIN1NSPIC,\r
+\r
+       W_WOODEN_DOORPIC,W_WOOD_DOORNSPIC,W_METAL_DOORPIC,W_GLOW_DOORPIC,\r
+\r
+       W_FINALEXITPIC,\r
+\r
+       W_WATER_EXP2PIC,W_WATER_EXP1PIC,W_WATER_EXP1PIC,\r
+\r
+       W_CHEAT_GODPIC,W_CHEAT_ITEMSPIC,W_POST_CHEATPIC,W_SURFACE_PLAQPIC,\r
+\r
+       W_WATER_GATENS2PIC,\r
+       WALL8DPIC,WALL9DPIC,WALL10LPIC,WALL11DPIC,WALL12DPIC,WALL13DPIC,WALL14DPIC,WALL15DPIC,\r
+       WALL16DPIC,WALL17DPIC,W_WINDOWNSPIC,WALL19DPIC,WALL20DPIC,WALL21DPIC,\r
+       WALL22DPIC,WALL23DPIC,WALL24DPIC,WALL25DPIC,WALL26DPIC,WALL27DPIC,\r
+       WALL28DPIC,WALL29DPIC,WALL30DPIC,WALL31DPIC,\r
+       W_BREATH_DWALL3PIC,W_BREATH_DWALL4PIC,\r
+       MAGE_STATUEPIC,ZOMBIE_STATUEPIC,EYE_STATUEPIC,NEM_STATUEPIC,\r
+       SKELETON_STATUEPIC,SPOOK_STATUEPIC,ORCH_STATUEPIC,\r
+       };\r
 \r
 /*\r
 =====================\r
@@ -500,6 +614,8 @@ void DrawVWall (walltype *wallptr)
        int                     mapadd;\r
        unsigned        lastpix,lastsource,lastwidth;\r
 \r
+       short mike;\r
+\r
 \r
        if (wallptr->rightclip < wallptr->leftclip)\r
                Quit ("DrawVWall: Right < Left");\r
@@ -540,6 +656,10 @@ void DrawVWall (walltype *wallptr)
        //\r
        if (wallptr->side)\r
        {       // east or west wall\r
+\r
+               if (wallptr->color == 1)\r
+                       mike = 1;\r
+\r
                if (animframe)\r
                        wallpic = walllight2[wallptr->color];\r
                else\r
@@ -560,6 +680,10 @@ void DrawVWall (walltype *wallptr)
        }\r
        else\r
        {       // north or south wall\r
+\r
+               if (wallptr->color == 1)\r
+                       mike = 1;\r
+\r
                if (animframe)\r
                        wallpic = walldark2[wallptr->color];\r
                else\r
@@ -874,6 +998,65 @@ ansok:;
 \r
 #pragma warn +rvl\r
 \r
+#if 0\r
+/*\r
+=========================\r
+=\r
+= FixedAdd\r
+=\r
+= add two 16 bit fixed point numbers\r
+= to subtract, invert the sign of B before invoking\r
+=\r
+=========================\r
+*/\r
+\r
+fixed FixedAdd (fixed a, fixed b)\r
+{\r
+  fixed value;\r
+\r
+asm    mov     ax,[WORD PTR a]\r
+asm    mov     dx,[WORD PTR a+2]\r
+\r
+asm    mov     bx,[WORD PTR b]\r
+asm    mov     cx,[WORD PTR b+2]\r
+\r
+asm    or      dx,dx\r
+asm    jns     aok:            // negative?\r
+asm    and     dx,0x7fff\r
+asm    not     ax              // convert a from signed magnitude to 2's compl\r
+asm    not     dx\r
+asm    add     ax,1\r
+asm    adc     dx,0\r
+aok:\r
+\r
+asm    or      cx,cx\r
+asm    jns     bok:            // negative?\r
+asm    and     cx,0x7fff\r
+asm    not     bx              // convert b from signed magnitude to 2's compl\r
+asm    not     cx\r
+asm    add     bx,1\r
+asm    adc     cx,0\r
+bok:\r
+\r
+asm    add     ax,bx           // perform the addition\r
+asm    adc     dx,cx\r
+asm    jns     done\r
+\r
+asm    and     dx,0x7fff       // value was negative\r
+asm    not     ax              // back to signed magnitude\r
+asm    not     dx\r
+asm    add     ax,1\r
+asm    adc     dx,0\r
+\r
+done:\r
+\r
+asm    mov     [WORD PTR value],ax\r
+asm    mov     [WORD PTR value+2],dx\r
+\r
+  return value;\r
+}\r
+#endif\r
+\r
 //==========================================================================\r
 \r
 \r
@@ -1137,6 +1320,8 @@ void BuildTables (void)
 \r
 void ClearScreen (void)\r
 {\r
+       unsigned topcolor=*skycolor, bottomcolor=*groundcolor;\r
+\r
   //\r
   // clear the screen\r
   //\r
@@ -1150,9 +1335,10 @@ asm      mov     dx,40-VIEWWIDTH/8
 asm    mov     bl,VIEWWIDTH/16\r
 asm    mov     bh,CENTERY+1\r
 \r
-asm    xor     ax,ax\r
+asm    mov     ax,topcolor\r
 asm    mov     es,[screenseg]\r
 asm    mov     di,[bufferofs]\r
+asm    add     di,((SCREENWIDTH*VIEWY)+(VIEWX/8))\r
 \r
 toploop:\r
 asm    mov     cl,bl\r
@@ -1163,7 +1349,7 @@ asm       dec     bh
 asm    jnz     toploop\r
 \r
 asm    mov     bh,CENTERY+1\r
-asm    mov     ax,0x0808\r
+asm    mov     ax,bottomcolor\r
 \r
 bottomloop:\r
 asm    mov     cl,bl\r
@@ -1280,9 +1466,6 @@ void DrawScaleds (void)
 \r
        for (obj = player->next;obj;obj=obj->next)\r
        {\r
-               if (!obj->state->shapenum)\r
-                       continue;\r
-\r
                tilespot = &tilemap[0][0]+(obj->tilex<<6)+obj->tiley;\r
                visspot = &spotvis[0][0]+(obj->tilex<<6)+obj->tiley;\r
                //\r
@@ -1298,14 +1481,23 @@ void DrawScaleds (void)
                || ( *(visspot+64) && !*(tilespot+64) )\r
                || ( *(visspot+63) && !*(tilespot+63) ) )\r
                {\r
-                       obj->active = true;\r
+                       if ((obj->active == noalways) || (obj->active == always))\r
+                               obj->active = always;\r
+                       else\r
+                               obj->active = yes;\r
                        TransformActor (obj);\r
                        if (!obj->viewheight || obj->viewheight > VIEWWIDTH)\r
                                continue;                       // too close or far away\r
 \r
+                       if (!obj->state->shapenum)\r
+                               continue;\r
+\r
                        *vislist++ = obj;\r
                        numvisable++;\r
                }\r
+               else\r
+                       if ((obj->active != always) && (obj->active != noalways))\r
+                               obj->active = no;\r
        }\r
 \r
        if (vislist == &depthsort[0])\r
@@ -1362,6 +1554,7 @@ void CalcTics (void)
        if (lasttimecount > TimeCount)\r
                TimeCount = lasttimecount;              // if the game was paused a LONG time\r
 \r
+#if 0\r
        if (DemoMode)                                   // demo recording and playback needs\r
        {                                                               // to be constant\r
 //\r
@@ -1372,15 +1565,16 @@ void CalcTics (void)
                ;\r
                lasttimecount = oldtimecount + DEMOTICS;\r
                TimeCount = lasttimecount + DEMOTICS;\r
-               tics = DEMOTICS;\r
+               realtics = tics = DEMOTICS;\r
        }\r
        else\r
+#endif\r
        {\r
 //\r
 // non demo, so report actual time\r
 //\r
                newtime = TimeCount;\r
-               tics = newtime-lasttimecount;\r
+               realtics = tics = newtime-lasttimecount;\r
                lasttimecount = newtime;\r
 \r
 #ifdef FILEPROFILE\r
@@ -1396,6 +1590,9 @@ void CalcTics (void)
                        TimeCount -= (tics-MAXTICS);\r
                        tics = MAXTICS;\r
                }\r
+\r
+               if (realtics>MAXREALTICS)\r
+                       realtics = MAXREALTICS;\r
        }\r
 }\r
 \r
@@ -1413,16 +1610,18 @@ void CalcTics (void)
 \r
 void   DrawHand (void)\r
 {\r
-       int     picnum;\r
+       #define HAND_X_POS      ((VIEWWIDTH/16)-(10/2))         // "10" = hand width in bytes\r
+\r
+       #define picnum HAND1PICM\r
+\r
        memptr source;\r
        unsigned dest,width,height;\r
 \r
-       picnum = HAND1PICM;\r
-       if (gamestate.shotpower || boltsleft)\r
-               picnum += (((unsigned)TimeCount>>3)&1);\r
+//     if (gamestate.shotpower || boltsleft)\r
+//             picnum += (((unsigned)TimeCount>>3)&1);\r
 \r
        source = grsegs[picnum];\r
-       dest = ylookup[VIEWHEIGHT-handheight]+12+bufferofs;\r
+       dest = ylookup[VIEWHEIGHT-handheight]+HAND_X_POS+bufferofs;                     // 12\r
        width = picmtable[picnum-STARTPICM].width;\r
        height = picmtable[picnum-STARTPICM].height;\r
 \r
index a71d25462c921982977eb0b9dcb5fca133a83d3b..edb7612e49b4fe4edfcd57f56680d84a93ed1f8b 100644 (file)
--- a/C4_GAME.C
+++ b/C4_GAME.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code\r
+/* Catacomb Abyss Source Code\r
  * Copyright (C) 1993-2014 Flat Rock Software\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
 \r
 // C3_GAME.C\r
 \r
-#include "C3_DEF.H"\r
+#include <stdlib.h>\r
+\r
+#include "DEF.H"\r
+#include "gelib.h"\r
 #pragma hdrstop\r
 \r
 #ifdef PROFILE\r
 =============================================================================\r
 */\r
 \r
-#define NUMLUMPS        25\r
-\r
-#define CONTROLSLUMP    0\r
-#define ORCLUMP         1\r
-#define TROLLLUMP        2\r
-#define WARPLUMP        3\r
-#define BOLTLUMP        4\r
-#define NUKELUMP        5\r
-#define POTIONLUMP      6\r
-#define RKEYLUMP        7\r
-#define YKEYLUMP        8\r
-#define GKEYLUMP        9\r
-#define BKEYLUMP        10\r
-#define SCROLLLUMP      11\r
-#define CHESTLUMP       12\r
-#define PLAYERLUMP      13\r
-#define WALL1LUMP       14\r
-#define WALL2LUMP       15\r
-#define BDOORLUMP       16\r
-#define DEMONLUMP               17\r
-#define MAGELUMP                18\r
-#define BATLUMP                 19\r
-#define GRELLUMP                20\r
-#define GOALLUMP                21\r
+#define NUMLUMPS        36\r
+\r
+#define ORCLUMP                        0\r
+#define TROLLLUMP                      1\r
+#define BOLTLUMP                       2\r
+#define NUKELUMP                       3\r
+#define POTIONLUMP                     4\r
+#define RKEYLUMP        5\r
+#define YKEYLUMP        6\r
+#define GKEYLUMP        7\r
+#define BKEYLUMP        8\r
+#define SCROLLLUMP      9\r
+#define CHESTLUMP       10\r
+#define PLAYERLUMP      11\r
+#define WALL1LUMP       12\r
+#define WALL2LUMP       13\r
+#define BDOORLUMP       14\r
+#define DEMONLUMP               15\r
+#define MAGELUMP                16\r
+#define BATLUMP                 17\r
+#define GRELLUMP                18\r
+#define TOMBSTONESLUMP                   19\r
+#define ZOMBIELUMP                               20\r
+#define SPOOKLUMP                                        21\r
+#define SKELETONLUMP                             22\r
+#define RGEMLUMP                                         23\r
+#define GGEMLUMP                                         24\r
+#define BGEMLUMP                                         25\r
+#define YGEMLUMP                                         26\r
+#define PGEMLUMP                                         27\r
+#define RKEY2LUMP                                        28\r
+#define WETMANLUMP                               29\r
+#define OBJ_WARPLUMP                             30\r
+#define EYELUMP                                          31\r
+#define REDDEMONLUMP            32\r
+#define PITLUMP                                          33\r
+#define FTIMELUMP                                        34\r
+#define WATERCHESTLUMP                   35\r
+\r
 \r
 \r
 int     lumpstart[NUMLUMPS] = {\r
-CONTROLS_LUMP_START,\r
 ORC_LUMP_START,\r
 TROLL_LUMP_START,\r
-WARP_LUMP_START,\r
 BOLT_LUMP_START,\r
 NUKE_LUMP_START,\r
 POTION_LUMP_START,\r
@@ -75,22 +91,37 @@ BKEY_LUMP_START,
 SCROLL_LUMP_START,\r
 CHEST_LUMP_START,\r
 PLAYER_LUMP_START,\r
-WALL1_LUMP_START,\r
-WALL2_LUMP_START,\r
-BDOOR_LUMP_START,\r
+//WALL1_LUMP_START,\r
+//WALL2_LUMP_START,\r
+//BDOOR_LUMP_START,\r
+0,0,0,\r
 DEMON_LUMP_START,\r
 MAGE_LUMP_START,\r
 BAT_LUMP_START,\r
 GREL_LUMP_START,\r
-NEMESISPIC\r
+TOMBSTONES_LUMP_START,\r
+ZOMBIE_LUMP_START,\r
+SPOOK_LUMP_START,\r
+SKELDUDE_LUMP_START,\r
+RGEM_LUMP_START,\r
+GGEM_LUMP_START,\r
+BGEM_LUMP_START,\r
+YGEM_LUMP_START,\r
+PGEM_LUMP_START,\r
+RKEY2_LUMP_START,\r
+WETMAN_LUMP_START,\r
+OBJ_WARP_LUMP_START,\r
+EYE_LUMP_START,\r
+REDDEMON_LUMP_START,\r
+PIT_LUMP_START,\r
+TIME_LUMP_START,\r
+O_WATER_CHEST_LUMP_START,\r
 };\r
 \r
 \r
 int     lumpend[NUMLUMPS] = {\r
-CONTROLS_LUMP_END,\r
 ORC_LUMP_END,\r
 TROLL_LUMP_END,\r
-WARP_LUMP_END,\r
 BOLT_LUMP_END,\r
 NUKE_LUMP_END,\r
 POTION_LUMP_END,\r
@@ -101,18 +132,36 @@ BKEY_LUMP_END,
 SCROLL_LUMP_END,\r
 CHEST_LUMP_END,\r
 PLAYER_LUMP_END,\r
-WALL1_LUMP_END,\r
-WALL2_LUMP_END,\r
-BDOOR_LUMP_END,\r
+//WALL1_LUMP_END,\r
+//WALL2_LUMP_END,\r
+//BDOOR_LUMP_END,\r
+0,0,0,\r
 DEMON_LUMP_END,\r
 MAGE_LUMP_END,\r
 BAT_LUMP_END,\r
 GREL_LUMP_END,\r
-NEMESISPIC\r
+TOMBSTONES_LUMP_END,\r
+ZOMBIE_LUMP_END,\r
+SPOOK_LUMP_END,\r
+SKELDUDE_LUMP_END,\r
+RGEM_LUMP_END,\r
+GGEM_LUMP_END,\r
+BGEM_LUMP_END,\r
+YGEM_LUMP_END,\r
+PGEM_LUMP_END,\r
+RKEY2_LUMP_END,\r
+WETMAN_LUMP_END,\r
+OBJ_WARP_LUMP_END,\r
+EYE_LUMP_END,\r
+REDDEMON_LUMP_END,\r
+PIT_LUMP_END,\r
+TIME_LUMP_END,\r
+O_WATER_CHEST_LUMP_END,\r
 };\r
 \r
 \r
 \r
+\r
 /*\r
 =============================================================================\r
 \r
@@ -125,6 +174,8 @@ unsigned        latchpics[NUMLATCHPICS];
 unsigned        tileoffsets[NUMTILE16];\r
 unsigned        textstarts[27];\r
 \r
+boolean splitscreen=false;\r
+\r
 /*\r
 =============================================================================\r
 \r
@@ -138,6 +189,17 @@ boolean lumpneeded[NUMLUMPS];
 \r
 //===========================================================================\r
 \r
+//==========================================================================\r
+//\r
+//\r
+//                                                     LOCAL PROTOTYPES\r
+//\r
+//\r
+//==========================================================================\r
+\r
+void CashPoints(void);\r
+\r
+\r
 \r
 /*\r
 ==========================\r
@@ -151,6 +213,9 @@ boolean lumpneeded[NUMLUMPS];
 \r
 void ScanInfoPlane (void)\r
 {\r
+       extern unsigned gnd_colors[];\r
+\r
+       char hibyte;\r
        unsigned        x,y,i,j;\r
        int                     tile;\r
        unsigned        far     *start;\r
@@ -164,6 +229,8 @@ void ScanInfoPlane (void)
                for (x=0;x<mapwidth;x++)\r
                {\r
                        tile = *start++;\r
+                       hibyte = tile >> 8;\r
+                       tile &= 0xff;\r
                        if (!tile)\r
                                continue;\r
 \r
@@ -188,6 +255,20 @@ void ScanInfoPlane (void)
                                SpawnBonus(x,y,tile-5);\r
                                break;\r
 \r
+                       case 29:\r
+                               lumpneeded[RKEY2LUMP] = true;\r
+                               SpawnBonus(x,y,B_RKEY2);\r
+                       break;\r
+\r
+                       case 58:\r
+                       case 59:\r
+                       case 60:\r
+                       case 61:\r
+                       case 62:\r
+                               lumpneeded[tile-58+RGEMLUMP] = true;\r
+                               SpawnBonus(x,y,tile-58+B_RGEM);\r
+                       break;\r
+\r
                        case 12:\r
                        case 13:\r
                        case 14:\r
@@ -200,21 +281,30 @@ void ScanInfoPlane (void)
                                SpawnBonus(x,y,B_SCROLL1+tile-12);\r
                                break;\r
 \r
+#if 0\r
                        case 20:        // goal\r
                                lumpneeded[GOALLUMP] = true;\r
                                SpawnBonus(x,y,B_GOAL);\r
                                break;\r
+#endif\r
 \r
                        case 21:        // chest\r
-                               lumpneeded[CHESTLUMP] = true;\r
+                               if (gnd_colors[gamestate.mapon] == 0x0101)\r
+                                       lumpneeded[WATERCHESTLUMP] = true;\r
+                               else\r
+                                       lumpneeded[CHESTLUMP] = true;\r
                                SpawnBonus(x,y,B_CHEST);\r
-                               break;\r
+                       break;\r
 \r
-                       case 24:\r
-                               lumpneeded[WARPLUMP] = true;\r
-                               SpawnWarp (x,y,0);\r
+                       case 31:\r
+                       case 32:\r
+                       case 33:\r
+                       case 34:\r
+                       case 35:\r
+                               lumpneeded[OBJ_WARPLUMP] = true;\r
+                               SpawnWarp (x,y,tile-30);\r
                                break;\r
-//------\r
+\r
                        case 41:\r
                                if (gamestate.difficulty <gd_Hard)\r
                                        break;\r
@@ -271,10 +361,11 @@ void ScanInfoPlane (void)
                                break;\r
 \r
                        case 28:\r
-                               lumpneeded[GRELLUMP] = true;\r
-                               SpawnNemesis (x,y);\r
+                               lumpneeded[RKEYLUMP] = lumpneeded[GRELLUMP] = true;\r
+                               SpawnGrelminar (x,y);\r
                                break;\r
 \r
+#if 0\r
                        case 29:\r
                                SpawnBounce (x,y,0);\r
                                break;\r
@@ -282,13 +373,90 @@ void ScanInfoPlane (void)
                        case 30:\r
                                SpawnBounce (x,y,1);\r
                                break;\r
+#endif\r
 \r
-                       case 31:\r
-                       case 32:\r
-                       case 33:\r
-                       case 34:\r
-                               lumpneeded[WARPLUMP] = true;\r
-                               SpawnWarp (x,y,tile-30);\r
+                       case 46:\r
+                       case 47:\r
+                       case 48:\r
+                               lumpneeded[TOMBSTONESLUMP] = true;\r
+                               SpawnTombstone(x,y,tile-46);\r
+                       break;\r
+\r
+                       case 54:\r
+                               lumpneeded[PITLUMP]     = true;\r
+                               SpawnWarp(x,y,0);\r
+                               break;\r
+\r
+                       case 53:\r
+                               if (gamestate.difficulty <gd_Normal)\r
+                                       break;\r
+                       case 52:\r
+                               lumpneeded[ZOMBIELUMP] = true;\r
+                               SpawnZombie(x,y);\r
+                       break;\r
+\r
+                       case 51:\r
+                               if (gamestate.difficulty <gd_Hard)\r
+                                       break;\r
+                       case 50:\r
+                               if (gamestate.difficulty <gd_Normal)\r
+                                       break;\r
+                       case 49:\r
+                               lumpneeded[SPOOKLUMP] = true;\r
+                               SpawnSpook(x,y);\r
+                               break;\r
+\r
+                       case 57:\r
+                               lumpneeded[FTIMELUMP] = true;\r
+                               SpawnFTime(x,y);\r
+                               break;\r
+\r
+                       case 56:\r
+                               if (gamestate.difficulty <gd_Normal)\r
+                                       break;\r
+                       case 55:\r
+                               lumpneeded[SKELETONLUMP] = true;\r
+                               SpawnSkeleton(x,y);\r
+                               break;\r
+\r
+                       case 65:\r
+                               if (gamestate.difficulty <gd_Hard)\r
+                                       break;\r
+                       case 64:\r
+                               if (gamestate.difficulty <gd_Normal)\r
+                                       break;\r
+                       case 63:\r
+                               lumpneeded[WETMANLUMP] = true;\r
+                               SpawnWetMan(x,y);\r
+                               break;\r
+\r
+                       case 68:\r
+                               if (gamestate.difficulty <gd_Hard)\r
+                                       break;\r
+                       case 67:\r
+                               if (gamestate.difficulty <gd_Normal)\r
+                                       break;\r
+                       case 66:\r
+                               lumpneeded[EYELUMP] = true;\r
+                               SpawnEye(x,y);\r
+                               break;\r
+\r
+                       case 71:\r
+                               if (gamestate.difficulty <gd_Hard)\r
+                                       break;\r
+                       case 70:\r
+                               if (gamestate.difficulty <gd_Normal)\r
+                                       break;\r
+                       case 69:\r
+                               lumpneeded[SKELETONLUMP] = true;\r
+                               SpawnWallSkeleton(x,y);\r
+                               break;\r
+\r
+                       case 20:\r
+                       case 24:\r
+                       case 30:\r
+                               lumpneeded[REDDEMONLUMP] = true;\r
+                               SpawnRedDemon (x,y);\r
                                break;\r
                        }\r
                }\r
@@ -340,41 +508,39 @@ void ScanText (void)
 \r
 static  char    *levelnames[] =\r
                                {\r
-                                       "The Approach",\r
-                                       "Nemesis's Keep",\r
-                                       "Ground Floor",\r
-                                       "Second Floor",\r
-                                       "Third Floor",\r
-                                       "Tower One",\r
-                                       "Tower Two",\r
-                                       "Secret Halls",\r
-                                       "Access Floor",\r
-                                       "The Dungeon",\r
-                                       "Lower Dungeon",\r
-                                       "Catacomb",\r
-                                       "Lower Reaches",\r
-                                       "The Warrens",\r
-                                       "Hidden Caverns",\r
-                                       "The Fens of Insanity",\r
-                                       "Chaos Corridors",\r
-                                       "The Labyrinth",\r
-                                       "Halls of Blood",\r
-                                       "Nemesis's Lair"\r
+                                       "The Towne Cemetery",\r
+                                       "The Garden of Tears",\r
+                                       "The Den of Zombies",\r
+                                       "The Mausoleum Grounds",\r
+                                       "The Main Floor of the Mausoleum",\r
+                                       "Mike's Blastable Passage",\r
+                                       "The Crypt of Nemesis the Undead",\r
+                                       "The Subterranean Vault",\r
+                                       "The Ancient Aqueduct",\r
+                                       "The Orc Mines",\r
+                                       "The Lair of the Troll",\r
+                                       "The Demon's Inferno",\r
+                                       "The Battleground of the Titans",\r
+                                       "The Coven of Mages",\r
+                                       "The Inner Sanctum",\r
+                                       "The Haunt of Nemesis",\r
+                                       "The Passage to the Surface",\r
+                                       "Big Jim's Domain",\r
+                                       "Nolan's Nasty",\r
                                };\r
+\r
 void DrawEnterScreen (void)\r
 {\r
-       int     x,y;\r
-\r
-       VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,9);     // Medium blue\r
-\r
-       x = (VIEWWIDTH - (18 * 8)) / 2 -3;\r
-       y = (VIEWHEIGHT - (5 * 8)) / 2;\r
-       VW_DrawPic(x / 8,y,ENTERPLAQUEPIC);\r
-\r
-       WindowX = x;\r
-       WindowW = 18 * 8;\r
-       PrintY = (VIEWHEIGHT/2) + 3;\r
-       US_CPrint (levelnames[gamestate.mapon]);\r
+       int width;\r
+\r
+       bufferofs = displayofs = screenloc[screenpage];\r
+       VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,0);\r
+       width = strlen(levelnames[gamestate.mapon]);\r
+       if (width < 20)\r
+               width = 20;\r
+       CenterWindow(width,5);\r
+       US_CPrint("\nYou have arrived at\n");\r
+       US_CPrint(levelnames[gamestate.mapon]);\r
 }\r
 \r
 //==========================================================================\r
@@ -452,21 +618,23 @@ void CacheScaleds (void)
 ==================\r
 */\r
 \r
-void SetupGameLevel (void)\r
+void SetupGameLevel ()\r
 {\r
-       int     x,y,i;\r
-       unsigned        far *map,tile,spot;\r
+       int     x,y,i,loop;\r
+       unsigned        far *map,tile,far *spotptr,spot;\r
 \r
        memset (tileneeded,0,sizeof(tileneeded));\r
 //\r
 // randomize if not a demo\r
 //\r
+#if 0\r
        if (DemoMode)\r
        {\r
                US_InitRndT(false);\r
                gamestate.difficulty = gd_Normal;\r
        }\r
        else\r
+#endif\r
                US_InitRndT(true);\r
 \r
 //\r
@@ -493,29 +661,47 @@ void SetupGameLevel (void)
        memset (tilemap,0,sizeof(tilemap));\r
        memset (actorat,0,sizeof(actorat));\r
        map = mapsegs[0];\r
+       spotptr = mapsegs[2];\r
        for (y=0;y<mapheight;y++)\r
                for (x=0;x<mapwidth;x++)\r
                {\r
                        tile = *map++;\r
+\r
+                       if (((*spotptr)>>8) == EXP_WALL_CODE)\r
+                       {\r
+                               extern unsigned gnd_colors[];\r
+\r
+                               if (gnd_colors[gamestate.mapon] == 0x0101)\r
+                                       tileneeded[WATEREXP] = tileneeded[WATEREXP+1] = tileneeded[WATEREXP+2] = true;\r
+                               else\r
+                                       tileneeded[WALLEXP] = tileneeded[WALLEXP+1] = tileneeded[WALLEXP+2] = true;\r
+                       }\r
+\r
                        if (tile<NUMFLOORS)\r
                        {\r
+                               if (tile == WALL_SKELETON_CODE)\r
+                                       tileneeded[tile+1] = tileneeded[tile+2] = true;\r
+\r
                                tileneeded[tile] = true;\r
                                tilemap[x][y] = tile;\r
-                               if (tile>=EXPWALLSTART && tile<EXPWALLSTART+NUMEXPWALLS)\r
-                               {\r
-                                       tileneeded[WALLEXP] = tileneeded[WALLEXP+1]\r
-                                       = tileneeded[WALLEXP+2] = true;\r
-                               }\r
-\r
                                if (tile>0)\r
                                        (unsigned)actorat[x][y] = tile;\r
                        }\r
+                       spotptr++;\r
                }\r
 \r
 \r
+       //\r
+       // Mark any gfx chunks needed\r
+       //\r
+\r
+//     CA_MarkGrChunk(NORTHICONSPR);\r
+//     CA_CacheMarks(NULL);\r
+\r
 //\r
 // decide which graphics are needed and spawn actors\r
 //\r
+       zombie_base_delay = 0;  // (1*60) + random(1*60);\r
        ScanInfoPlane ();\r
 \r
 //\r
@@ -523,7 +709,6 @@ void SetupGameLevel (void)
 // are in memory\r
 //\r
        CA_LoadAllSounds ();\r
-\r
 }\r
 \r
 \r
@@ -586,32 +771,64 @@ asm     mov     ds,ax                                   // restore turbo's data
 =====================\r
 */\r
 \r
-void Victory (void)\r
+void Victory (boolean playsounds)\r
 {\r
-       FreeUpMemory ();\r
-       NormalScreen ();\r
+       struct Shape shape;\r
+\r
+       if (playsounds)\r
+       {\r
+               SD_PlaySound (GETBOLTSND);\r
+               SD_WaitSoundDone ();\r
+               SD_PlaySound (GETNUKESND);\r
+               SD_WaitSoundDone ();\r
+               SD_PlaySound (GETPOTIONSND);\r
+               SD_WaitSoundDone ();\r
+               SD_PlaySound (GETKEYSND);\r
+               SD_WaitSoundDone ();\r
+               SD_PlaySound (GETSCROLLSND);\r
+               SD_WaitSoundDone ();\r
+               SD_PlaySound (GETPOINTSSND);\r
+       }\r
+\r
+\r
+       FreeUpMemory();\r
+\r
+       if (!screenfaded)\r
+               VW_FadeOut();\r
+\r
+       screenpage = 1;\r
+       VW_SetScreen (screenloc[screenpage],0);\r
+       bufferofs = displayofs = screenloc[screenpage];\r
+       VW_Bar (0,0,320,120,0);\r
+\r
        CA_CacheGrChunk (FINALEPIC);\r
-       VWB_DrawPic (0,0,FINALEPIC);\r
        UNMARKGRCHUNK(FINALEPIC);\r
-       VW_UpdateScreen ();\r
-       SD_PlaySound (GETBOLTSND);\r
-       SD_WaitSoundDone ();\r
-       SD_PlaySound (GETNUKESND);\r
-       SD_WaitSoundDone ();\r
-       SD_PlaySound (GETPOTIONSND);\r
-       SD_WaitSoundDone ();\r
-       SD_PlaySound (GETKEYSND);\r
-       SD_WaitSoundDone ();\r
-       SD_PlaySound (GETSCROLLSND);\r
-       SD_WaitSoundDone ();\r
-       SD_PlaySound (GETPOINTSSND);\r
-       SD_WaitSoundDone ();\r
-       IN_ClearKeysDown ();\r
-       IN_Ack();\r
+       VW_DrawPic(0, 0, FINALEPIC);\r
+\r
+       VW_FadeIn();\r
+\r
+#if 0\r
+       FreeUpMemory();\r
+\r
+       if (!screenfaded)\r
+               VW_FadeOut();\r
+       screenpage = 1;\r
+       VW_SetScreen (screenloc[screenpage],0);\r
+       if (!FindFile("FINALE."EXT,NULL,1))\r
+               Quit("Error: Can't find victory screen.");\r
+       if (LoadShape("FINALE."EXT,&shape))\r
+               TrashProg("Can't load FINALE."EXT);\r
+       bufferofs = displayofs = screenloc[screenpage];\r
+       VW_Bar (0,0,320,120,0);\r
+       UnpackEGAShapeToScreen(&shape,(320-shape.bmHdr.w)/2,0);\r
+       FreeShape(&shape);\r
+       VW_FadeIn();\r
+#endif\r
 }\r
 \r
 //==========================================================================\r
 \r
+#if 0\r
 /*\r
 ===================\r
 =\r
@@ -629,12 +846,16 @@ void Died (void)
        FreeUpMemory ();\r
        SD_PlaySound (GAMEOVERSND);\r
        bufferofs = screenloc[(screenpage+1)%3];\r
-       LatchDrawPic(0,0,DEADPIC);\r
-       FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,false);\r
+       DisplayMsg("Though fallen, your Spirit ...",NULL);\r
+//     LatchDrawPic(0,0,DEADPIC);\r
+//     FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,false);\r
        IN_ClearKeysDown();\r
-       IN_Ack();\r
+       while (!Keyboard[sc_Enter]);\r
+//     IN_Ack();\r
        VW_SetScreen (bufferofs,0);\r
+       VW_ColorBorder(0);\r
 }\r
+#endif\r
 \r
 //==========================================================================\r
 \r
@@ -654,6 +875,7 @@ void NormalScreen (void)
         bufferofs = SCREEN2START;\r
         VW_Bar(0,0,320,200,0);\r
         VW_SetScreen (displayofs,0);\r
+        splitscreen = false;\r
 }\r
 \r
 //==========================================================================\r
@@ -673,33 +895,24 @@ void DrawPlayScreen (void)
        screenpage = 0;\r
 \r
        bufferofs = 0;\r
-       VW_Bar (0,0,320,STATUSLINES,7);\r
+       VW_Bar (0,0,320,STATUSLINES,0);\r
        for (i=0;i<3;i++)\r
        {\r
                bufferofs = screenloc[i];\r
-               VW_Bar (0,0,320,VIEWHEIGHT,7);\r
+               VW_Bar (0,0,320,VIEWHEIGHT,0);\r
        }\r
 \r
-\r
-       VW_SetSplitScreen(144);\r
+       splitscreen = true;\r
+       VW_SetSplitScreen(120);\r
        VW_SetScreen(screenloc[0],0);\r
-       bufferofs = 0;\r
 \r
        CA_CacheGrChunk (STATUSPIC);\r
-       CA_CacheGrChunk (SIDEBARSPIC);\r
 \r
+       bufferofs = 0;\r
        VW_DrawPic (0,0,STATUSPIC);\r
 \r
-       for (i=0;i<3;i++)\r
-       {\r
-               bufferofs = screenloc[i];\r
-               VW_DrawPic (33,0,SIDEBARSPIC);\r
-       }\r
-\r
-       grneeded[STATUSPIC]&= ~ca_levelbit;\r
-       grneeded[SIDEBARSPIC]&= ~ca_levelbit;\r
+       grneeded[STATUSPIC] &= ~ca_levelbit;\r
        MM_SetPurge(&grsegs[STATUSPIC],3);\r
-       MM_SetPurge(&grsegs[SIDEBARSPIC],3);\r
 \r
        RedrawStatusWindow ();\r
        bufferofs = displayofs = screenloc[0];\r
@@ -801,163 +1014,6 @@ void LoadLatchMem (void)
 \r
 //==========================================================================\r
 \r
-/*\r
-===================\r
-=\r
-= FizzleFade\r
-=\r
-===================\r
-*/\r
-\r
-#define PIXPERFRAME     1600\r
-\r
-void FizzleFade (unsigned source, unsigned dest,\r
-       unsigned width,unsigned height, boolean abortable)\r
-{\r
-       unsigned        drawofs,pagedelta;\r
-       unsigned        char maskb[8] = {1,2,4,8,16,32,64,128};\r
-       unsigned        x,y,p,frame;\r
-       long            rndval;\r
-\r
-       pagedelta = dest-source;\r
-       VW_SetScreen (dest,0);\r
-       rndval = 1;\r
-       y = 0;\r
-\r
-asm     mov     es,[screenseg]\r
-asm     mov     dx,SC_INDEX\r
-asm     mov     al,SC_MAPMASK\r
-asm     out     dx,al\r
-\r
-       TimeCount=frame=0;\r
-       do      // while (1)\r
-       {\r
-               if (abortable)\r
-               {\r
-                       IN_ReadControl(0,&c);\r
-                       if (c.button0 || c.button1 || Keyboard[sc_Space]\r
-                       || Keyboard[sc_Enter])\r
-                       {\r
-                               VW_ScreenToScreen (source,dest,width/8,height);\r
-                               return;\r
-                       }\r
-               }\r
-\r
-               for (p=0;p<PIXPERFRAME;p++)\r
-               {\r
-                       //\r
-                       // seperate random value into x/y pair\r
-                       //\r
-                       asm     mov     ax,[WORD PTR rndval]\r
-                       asm     mov     dx,[WORD PTR rndval+2]\r
-                       asm     mov     bx,ax\r
-                       asm     dec     bl\r
-                       asm     mov     [BYTE PTR y],bl                 // low 8 bits - 1 = y xoordinate\r
-                       asm     mov     bx,ax\r
-                       asm     mov     cx,dx\r
-                       asm     shr     cx,1\r
-                       asm     rcr     bx,1\r
-                       asm     shr     bx,1\r
-                       asm     shr     bx,1\r
-                       asm     shr     bx,1\r
-                       asm     shr     bx,1\r
-                       asm     shr     bx,1\r
-                       asm     shr     bx,1\r
-                       asm     shr     bx,1\r
-                       asm     mov     [x],bx                                  // next 9 bits = x xoordinate\r
-                       //\r
-                       // advance to next random element\r
-                       //\r
-                       asm     shr     dx,1\r
-                       asm     rcr     ax,1\r
-                       asm     jnc     noxor\r
-                       asm     xor     dx,0x0001\r
-                       asm     xor     ax,0x2000\r
-noxor:\r
-                       asm     mov     [WORD PTR rndval],ax\r
-                       asm     mov     [WORD PTR rndval+2],dx\r
-\r
-                       if (x>width || y>height)\r
-                               continue;\r
-                       drawofs = source+ylookup[y];\r
-\r
-                       asm     mov     cx,[x]\r
-                       asm     mov     si,cx\r
-                       asm     and     si,7\r
-                       asm     mov dx,GC_INDEX\r
-                       asm     mov al,GC_BITMASK\r
-                       asm     mov     ah,BYTE PTR [maskb+si]\r
-                       asm     out dx,ax\r
-\r
-                       asm     mov     si,[drawofs]\r
-                       asm     shr     cx,1\r
-                       asm     shr     cx,1\r
-                       asm     shr     cx,1\r
-                       asm     add     si,cx\r
-                       asm     mov     di,si\r
-                       asm     add     di,[pagedelta]\r
-\r
-                       asm     mov     dx,GC_INDEX\r
-                       asm     mov     al,GC_READMAP                   // leave GC_INDEX set to READMAP\r
-                       asm     out     dx,al\r
-\r
-                       asm     mov     dx,SC_INDEX+1\r
-                       asm     mov     al,1\r
-                       asm     out     dx,al\r
-                       asm     mov     dx,GC_INDEX+1\r
-                       asm     mov     al,0\r
-                       asm     out     dx,al\r
-\r
-                       asm     mov     bl,[es:si]\r
-                       asm     xchg [es:di],bl\r
-\r
-                       asm     mov     dx,SC_INDEX+1\r
-                       asm     mov     al,2\r
-                       asm     out     dx,al\r
-                       asm     mov     dx,GC_INDEX+1\r
-                       asm     mov     al,1\r
-                       asm     out     dx,al\r
-\r
-                       asm     mov     bl,[es:si]\r
-                       asm     xchg [es:di],bl\r
-\r
-                       asm     mov     dx,SC_INDEX+1\r
-                       asm     mov     al,4\r
-                       asm     out     dx,al\r
-                       asm     mov     dx,GC_INDEX+1\r
-                       asm     mov     al,2\r
-                       asm     out     dx,al\r
-\r
-                       asm     mov     bl,[es:si]\r
-                       asm     xchg [es:di],bl\r
-\r
-                       asm     mov     dx,SC_INDEX+1\r
-                       asm     mov     al,8\r
-                       asm     out     dx,al\r
-                       asm     mov     dx,GC_INDEX+1\r
-                       asm     mov     al,3\r
-                       asm     out     dx,al\r
-\r
-                       asm     mov     bl,[es:si]\r
-                       asm     xchg [es:di],bl\r
-\r
-                       if (rndval == 1)                // entire sequence has been completed\r
-                       {\r
-                               EGABITMASK(255);\r
-                               EGAMAPMASK(15);\r
-                               return;\r
-                       };\r
-               }\r
-               frame++;\r
-               while (TimeCount<frame)         // don't go too fast\r
-               ;\r
-       } while (1);\r
-\r
-\r
-}\r
-\r
-//==========================================================================\r
-\r
 /*\r
 ===================\r
 =\r
@@ -1003,6 +1059,8 @@ void FreeUpMemory (void)
 \r
 //==========================================================================\r
 \r
+#if 0\r
+\r
 /*\r
 ==================\r
 =\r
@@ -1111,6 +1169,8 @@ void    CheckHighScore (long score,word other)
        }\r
 }\r
 \r
+#endif\r
+\r
 \r
 //==========================================================================\r
 \r
@@ -1124,6 +1184,7 @@ void    CheckHighScore (long score,word other)
 \r
 void GameLoop (void)\r
 {\r
+       boolean wait = false;\r
        int i,xl,yl,xh,yh;\r
        char num[20];\r
 #ifdef PROFILE\r
@@ -1131,6 +1192,7 @@ void GameLoop (void)
 #endif\r
 \r
        DrawPlayScreen ();\r
+       IN_ClearKeysDown();\r
 \r
 restart:\r
        if (!loadedgame)\r
@@ -1138,6 +1200,9 @@ restart:
                gamestate.difficulty = restartgame;\r
                restartgame = gd_Continue;\r
                DrawEnterScreen ();\r
+               if (gamestate.mapon != 8)\r
+                       fizzlein = true;\r
+               wait = true;\r
        }\r
 \r
        do\r
@@ -1148,14 +1213,33 @@ restart:
                else\r
                        loadedgame = false;\r
 \r
+               FreeUpMemory();\r
+               LoadLatchMem();\r
                CacheScaleds ();\r
 \r
+               if (EASYMODEON)\r
+                       DisplaySMsg("*** NOVICE ***", NULL);\r
+               else\r
+                       DisplaySMsg("*** WARRIOR ***", NULL);\r
+\r
+               status_delay = 250;\r
+\r
+               RedrawStatusWindow();\r
+               if (wait)\r
+               {\r
+                       VW_WaitVBL(120);\r
+                       wait = false;\r
+               }\r
+\r
+\r
 #ifdef PROFILE\r
 start = clock();\r
 while (start == clock());\r
 start++;\r
 #endif\r
+\r
                PlayLoop ();\r
+\r
 #ifdef PROFILE\r
 end = clock();\r
 itoa(end-start,str,10);\r
@@ -1165,35 +1249,40 @@ itoa(end-start,str,10);
 \r
                switch (playstate)\r
                {\r
-               case ex_died:\r
-                       Died ();\r
-                       NormalScreen ();\r
-                       FreeUpMemory ();\r
-                       CheckHighScore (gamestate.score,gamestate.mapon+1);\r
-                       return;\r
-               case ex_warped:\r
-                       FizzleOut (true);\r
-                       if (gamestate.mapon >= NUMLEVELS)\r
-                       {\r
-                               Victory ();\r
-                               FreeUpMemory ();\r
-                               CheckHighScore(gamestate.score,gamestate.mapon+1);\r
-                               return;\r
-                       }\r
-                       break;\r
                case ex_abort:\r
                        FreeUpMemory ();\r
                        return;\r
                case ex_resetgame:\r
+                       NewGame();\r
                case ex_loadedgame:\r
+               case ex_warped:\r
                        goto restart;\r
-               case ex_victorious:\r
-                       Victory ();\r
-                       FreeUpMemory();\r
-                       CheckHighScore(gamestate.score,gamestate.mapon+1);\r
-                       return;\r
+               break;\r
                }\r
 \r
        } while (1);\r
 \r
 }\r
+\r
+\r
+#if 0\r
+//\r
+// make wall pictures purgable\r
+//\r
+       for (i=0;i<NUMSCALEWALLS;i++)\r
+               if (walldirectory[i])\r
+                       MM_SetPurge (&(memptr)walldirectory[i],3);\r
+\r
+\r
+//\r
+// cache wall pictures back in\r
+//\r
+       for (i=1;i<NUMFLOORS;i++)\r
+               if (tileneeded[i])\r
+               {\r
+                       SetupScaleWall (walllight1[i]);\r
+                       SetupScaleWall (walllight2[i]);\r
+                       SetupScaleWall (walldark1[i]);\r
+                       SetupScaleWall (walldark2[i]);\r
+               }\r
+#endif
\ No newline at end of file
index 684cb3294e05ced581e9b50e77d094732a477b7a..715244d3af89efeb2afae268d8dda6edcfdbb87d 100644 (file)
--- a/C4_MAIN.C
+++ b/C4_MAIN.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code\r
+/* Catacomb Abyss Source Code\r
  * Copyright (C) 1993-2014 Flat Rock Software\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
  */\r
 \r
 // C3_MAIN.C\r
+#define CATALOG\r
 \r
-#include "C3_DEF.H"\r
+\r
+#include <time.h>\r
+#include <stdarg.h>\r
+\r
+#include "DEF.H"\r
+#include "GELIB.H"\r
 #pragma hdrstop\r
+#include <dir.h>\r
 \r
 /*\r
 =============================================================================\r
 \r
-                                                  CATACOMB 3-D\r
-\r
-                                         An Id Software production\r
-\r
-                                                  by John Carmack\r
 \r
 =============================================================================\r
 */\r
 =============================================================================\r
 */\r
 \r
+textinfo MainHelpText;\r
+\r
+GameDiff restartgame;\r
+boolean loadedgame,abortgame,ingame;\r
+\r
+\r
 memptr         scalesegs[NUMPICS];\r
 char           str[80],str2[20];\r
 unsigned       tedlevelnum;\r
 boolean                tedlevel;\r
 gametype       gamestate;\r
 exittype       playstate;\r
+char   SlowMode = 0;\r
+int starting_level;\r
+boolean EASYMODEON;\r
+\r
+short NumGames=0;\r
+unsigned Flags=0;\r
+\r
+void DisplayIntroText(void);\r
 \r
 /*\r
 =============================================================================\r
@@ -69,6 +85,7 @@ exittype      playstate;
 \r
 //===========================================================================\r
 \r
+#if 0\r
 // JAB Hack begin\r
 #define        MyInterrupt     0x60\r
 void interrupt (*intaddr)();\r
@@ -102,6 +119,7 @@ jabunhack(void)
        setvect(MyInterrupt,oldintaddr);\r
 }\r
 //     JAB Hack end\r
+#endif\r
 \r
 //===========================================================================\r
 \r
@@ -117,9 +135,20 @@ jabunhack(void)
 \r
 void NewGame (void)\r
 {\r
-       memset (&gamestate,0,sizeof(gamestate));\r
-       gamestate.mapon = 0;\r
-       gamestate.body = MAXBODY;\r
+       if (!loadedgame)\r
+       {\r
+               memset (&gamestate,0,sizeof(gamestate));\r
+               gamestate.mapon = starting_level;\r
+               gamestate.body = MAXBODY;\r
+       }\r
+\r
+       BGFLAGS = 0;\r
+       Flags &= FL_CLEAR;\r
+\r
+       boltsleft = bolttimer = 0;\r
+       FreezeTime = 0;\r
+\r
+//     memset (gamestate.levels,-1,sizeof(gamestate.levels));\r
 }\r
 \r
 //===========================================================================\r
@@ -140,9 +169,15 @@ boolean    SaveTheGame(int file)
        objtype *o;\r
        memptr  bigbuffer;\r
 \r
+       if (!CA_FarWrite(file,(void far *)&FreezeTime,sizeof(FreezeTime)))\r
+               return(false);\r
+\r
        if (!CA_FarWrite(file,(void far *)&gamestate,sizeof(gamestate)))\r
                return(false);\r
 \r
+       if (!CA_FarWrite(file,(void far *)&EASYMODEON,sizeof(EASYMODEON)))\r
+               return(false);\r
+\r
        expanded = mapwidth * mapheight * 2;\r
        MM_GetPtr (&bigbuffer,expanded);\r
 \r
@@ -193,11 +228,24 @@ boolean   LoadTheGame(int file)
        unsigned        far *map,tile;\r
        memptr          bigbuffer;\r
 \r
+       screenpage = 0;\r
+       FreeUpMemory();\r
+\r
+       playstate = ex_loadedgame;\r
+       if (!CA_FarRead(file,(void far *)&FreezeTime,sizeof(FreezeTime)))\r
+               return(false);\r
+\r
        if (!CA_FarRead(file,(void far *)&gamestate,sizeof(gamestate)))\r
                return(false);\r
 \r
+       if (!CA_FarRead(file,(void far *)&EASYMODEON,sizeof(EASYMODEON)))\r
+               return(false);\r
+\r
        SetupGameLevel ();              // load in and cache the base old level\r
 \r
+       if (!FindFile(Filename,"SAVE GAME",-1))\r
+               Quit("Error: Can't find saved game file!");\r
+\r
        expanded = mapwidth * mapheight * 2;\r
        MM_GetPtr (&bigbuffer,expanded);\r
 \r
@@ -346,6 +394,7 @@ void InitGame (void)
 \r
        US_SetLoadSaveHooks(LoadTheGame,SaveTheGame,ResetGame);\r
 \r
+\r
 //\r
 // load in and lock down some basic chunks\r
 //\r
@@ -356,17 +405,14 @@ void InitGame (void)
        CA_MarkGrChunk(STARTTILE8);\r
        CA_MarkGrChunk(STARTTILE8M);\r
        CA_MarkGrChunk(HAND1PICM);\r
-       CA_MarkGrChunk(HAND2PICM);\r
-       CA_MarkGrChunk(ENTERPLAQUEPIC);\r
 \r
+       CA_MarkGrChunk(NORTHICONSPR);\r
        CA_CacheMarks (NULL);\r
 \r
        MM_SetLock (&grsegs[STARTFONT],true);\r
        MM_SetLock (&grsegs[STARTTILE8],true);\r
        MM_SetLock (&grsegs[STARTTILE8M],true);\r
        MM_SetLock (&grsegs[HAND1PICM],true);\r
-       MM_SetLock (&grsegs[HAND2PICM],true);\r
-       MM_SetLock (&grsegs[ENTERPLAQUEPIC],true);\r
 \r
        fontcolor = WHITE;\r
 \r
@@ -393,6 +439,7 @@ void InitGame (void)
 //     US_FinishTextScreen();\r
 #endif\r
 \r
+#if 0\r
 //\r
 // reclaim the memory from the linked in text screen\r
 //\r
@@ -403,11 +450,12 @@ void InitGame (void)
                segstart++;\r
                seglength--;\r
        }\r
-\r
        MML_UseSpace (segstart,seglength);\r
+#endif\r
 \r
        VW_SetScreenMode (GRMODE);\r
-       VW_ColorBorder (3);\r
+       ge_textmode = false;\r
+//     VW_ColorBorder (3);\r
        VW_ClearVideo (BLACK);\r
 \r
 //\r
@@ -432,36 +480,65 @@ void clrscr (void);               // can't include CONIO.H because of name conflicts...
 ==========================\r
 */\r
 \r
-void Quit (char *error)\r
+void Quit (char *error, ...)\r
 {\r
+       short exit_code=0;\r
        unsigned        finscreen;\r
 \r
-#if 0\r
+       va_list ap;\r
+\r
+       va_start(ap,error);\r
+\r
        if (!error)\r
        {\r
                CA_SetAllPurge ();\r
+#ifndef CATALOG\r
                CA_CacheGrChunk (PIRACY);\r
                finscreen = (unsigned)grsegs[PIRACY];\r
-       }\r
 #endif\r
-\r
+       }\r
        ShutdownId ();\r
+\r
        if (error && *error)\r
        {\r
-         puts(error);\r
-         exit(1);\r
+               vprintf(error,ap);\r
+               exit_code = 1;\r
        }\r
 \r
-#if 0\r
-       if (!NoWait)\r
+#ifndef CATALOG\r
+       else\r
        {\r
                movedata (finscreen,0,0xb800,0,4000);\r
+\r
+               if (kbhit())\r
+               {\r
+                       while (kbhit())\r
+                               bioskey(0);\r
+               }\r
+\r
                bioskey (0);\r
-               clrscr();\r
        }\r
 #endif\r
 \r
-       exit(0);\r
+       va_end(ap);\r
+\r
+#ifndef CATALOG\r
+       if (!error)\r
+       {\r
+               _argc = 2;\r
+               _argv[1] = "LAST.SHL";\r
+               _argv[2] = "ENDSCN.SCN";\r
+               _argv[3] = NULL;\r
+               if (execv("LOADSCN.EXE", _argv) == -1)\r
+               {\r
+                       clrscr();\r
+                       puts("Couldn't find executable LOADSCN.EXE.\n");\r
+                       exit(1);\r
+               }\r
+       }\r
+#endif\r
+\r
+       exit(exit_code);\r
 }\r
 \r
 //===========================================================================\r
@@ -490,80 +567,111 @@ void     TEDDeath(void)
 =====================\r
 */\r
 \r
-static char *ParmStrings[] = {"easy","normal","hard",""};\r
-\r
 void   DemoLoop (void)\r
 {\r
-       int     i,level;\r
+/////////////////////////////////////////////////////////////////////////////\r
+// main game cycle\r
+/////////////////////////////////////////////////////////////////////////////\r
 \r
+//     displayofs = bufferofs = 0;\r
+//     VW_Bar (0,0,320,200,0);\r
+//     VW_SetScreen(0,0);\r
+\r
+//     set EASYMODE\r
 //\r
-// check for launch from ted\r
+       if (stricmp(_argv[2], "1") == 0)\r
+               EASYMODEON = true;\r
+       else\r
+               EASYMODEON = false;\r
+\r
+// restore game\r
 //\r
-       if (tedlevel)\r
+       if (stricmp(_argv[3], "1") == 0)\r
        {\r
-               NewGame();\r
-               gamestate.mapon = tedlevelnum;\r
-               restartgame = gd_Normal;\r
-               for (i = 1;i < _argc;i++)\r
+               VW_FadeOut();\r
+               bufferofs = displayofs = 0;\r
+               VW_Bar(0,0,320,200,0);\r
+               if (GE_LoadGame())\r
                {\r
-                       if ( (level = US_CheckParm(_argv[i],ParmStrings)) == -1)\r
-                               continue;\r
-\r
-                       restartgame = gd_Easy+level;\r
-                       break;\r
+                       loadedgame = true;\r
+                       playstate = ex_loadedgame;\r
+                       Keyboard[sc_Enter] = true;\r
+                       VW_Bar(0,0,320,200,0);\r
+                       ColoredPalette();\r
                }\r
-               GameLoop();\r
-               TEDDeath();\r
+               VW_Bar(0,0,320,200,0);\r
+               VW_FadeIn();\r
        }\r
 \r
+       // Play a game\r
+       //\r
+               restartgame = gd_Normal;\r
+               NewGame();\r
+               GameLoop();\r
+}\r
 \r
-//\r
-// main game cycle\r
-//\r
-       displayofs = bufferofs = 0;\r
-       VW_Bar (0,0,320,200,0);\r
+//-------------------------------------------------------------------------\r
+// DisplayIntroText()\r
+//-------------------------------------------------------------------------\r
+void DisplayIntroText()\r
+{\r
+       char *toptext = "You stand before the gate leading into the Towne "\r
+                                                "Cemetery. Night is falling as mournful wails mingle "\r
+                                                "with the sound of your pounding heart.";\r
 \r
-       while (1)\r
-       {\r
-               CA_CacheGrChunk (TITLEPIC);\r
-               bufferofs = SCREEN2START;\r
-               displayofs = SCREEN1START;\r
-               VWB_DrawPic (0,0,TITLEPIC);\r
-               MM_SetPurge (&grsegs[TITLEPIC],3);\r
-               UNMARKGRCHUNK(TITLEPIC);\r
-               FizzleFade (bufferofs,displayofs,320,200,true);\r
-\r
-               if (!IN_UserInput(TickBase*3,false))\r
-               {\r
-                       CA_CacheGrChunk (CREDITSPIC);\r
-                       VWB_DrawPic (0,0,CREDITSPIC);\r
-                       MM_SetPurge (&grsegs[CREDITSPIC],3);\r
-                       UNMARKGRCHUNK(CREDITSPIC);\r
-                       FizzleFade (bufferofs,displayofs,320,200,true);\r
+       char *bottomtext = "Equipped with your wits and the Secret Knowledge of "\r
+                                                        "Magick, you venture forth on your quest to upset "\r
+                                                        "the dark schemes of Nemesis, your arch rival.";\r
 \r
-               }\r
+       char oldfontcolor=fontcolor;\r
 \r
-               if (!IN_UserInput(TickBase*3,false))\r
-               {\r
-highscores:\r
-                       DrawHighScores ();\r
-                       FizzleFade (bufferofs,displayofs,320,200,true);\r
-                       IN_UserInput(TickBase*3,false);\r
-               }\r
+       fontcolor = 14;\r
+       WindowX=WindowY=0;\r
+       PPT_RightEdge=319;\r
+       PPT_LeftEdge=0;\r
 \r
-               if (IN_IsUserInput())\r
-               {\r
-                       US_ControlPanel ();\r
+       PrintY = 1;\r
+       PrintPropText(toptext);\r
 \r
-                       if (restartgame || loadedgame)\r
-                       {\r
-                               GameLoop ();\r
-                               goto highscores;\r
-                       }\r
-               }\r
+       PrintY = 160;\r
+       PrintPropText(bottomtext);\r
+\r
+       fontcolor = oldfontcolor;\r
+}\r
+\r
+#if 0\r
+boolean ChooseGameLevel()\r
+{\r
+       char choices[] = {sc_Escape,sc_E,sc_N,sc_H,0},ch;\r
+\r
+       CenterWindow(20,10);\r
 \r
+       US_Print("\n   Choose difficulty level:\n");\r
+       US_Print("       (E)asy\n");\r
+       US_Print("       (N)ormal\n");\r
+       US_Print("       (H)ard\n");\r
+       US_Print("\n      (ESC)ape aborts\n");\r
+\r
+//     VW_UpdateScreen();\r
+       if ((ch=GetKeyChoice(choices)) == sc_Escape)\r
+       {\r
+               while (Keyboard[sc_Escape]);\r
+               LastScan = 0;\r
+               return(false);\r
        }\r
+\r
+       if (ch == sc_E)\r
+               restartgame = gd_Easy;\r
+       else\r
+       if (ch == sc_N)\r
+               restartgame = gd_Normal;\r
+       else\r
+               restartgame = gd_Hard;\r
+\r
+       return(true);\r
 }\r
+#endif\r
+\r
 \r
 //===========================================================================\r
 \r
@@ -579,6 +687,9 @@ void SetupScalePic (unsigned picnum)
 {\r
        unsigned        scnum;\r
 \r
+       if (picnum == 1)\r
+               return;\r
+\r
        scnum = picnum-FIRSTSCALEPIC;\r
 \r
        if (shapedirectory[scnum])\r
@@ -610,6 +721,9 @@ void SetupScaleWall (unsigned picnum)
        unsigned        scnum;\r
        byte    far *dest;\r
 \r
+       if (picnum == 1)\r
+               return;\r
+\r
        scnum = picnum-FIRSTWALLPIC;\r
 \r
        if (walldirectory[scnum])\r
@@ -664,6 +778,7 @@ void HelpScreens (void)
 }\r
 \r
 \r
+#if 0\r
 /*\r
 ==================\r
 =\r
@@ -672,12 +787,15 @@ void HelpScreens (void)
 ==================\r
 */\r
 \r
-#define MINMEMORY      335000l\r
+#define MINMEMORY      400000l\r
 \r
 void   CheckMemory(void)\r
 {\r
        unsigned        finscreen;\r
 \r
+       if (Flags & FL_NOMEMCHECK)\r
+               return;\r
+\r
        if (mminfo.nearheap+mminfo.farheap+mminfo.EMSmem+mminfo.XMSmem\r
                >= MINMEMORY)\r
                return;\r
@@ -689,6 +807,7 @@ void        CheckMemory(void)
        gotoxy (1,24);\r
        exit(1);\r
 }\r
+#endif\r
 \r
 //===========================================================================\r
 \r
@@ -701,46 +820,53 @@ void      CheckMemory(void)
 ==========================\r
 */\r
 \r
+char                   *MainParmStrings[] = {"q","l","ver","nomemcheck",nil};\r
+boolean                LaunchedFromShell = false;\r
+\r
 void main (void)\r
 {\r
        short i;\r
 \r
-       if (stricmp(_argv[1], "/VER") == 0)\r
+       starting_level = 0;\r
+\r
+       for (i = 1;i < _argc;i++)\r
        {\r
-               printf("Catacomb 3-D version 1.22  (Rev 1)\n");\r
-               printf("Copyright 1991-93 Softdisk Publishing\n");\r
-               printf("Developed for use with 100%% IBM compatibles\n");\r
-               printf("that have 640K memory and DOS version 3.3 or later\n");\r
-               printf("and EGA graphics or better.\n");\r
-               exit(0);\r
+               switch (US_CheckParm(_argv[i],MainParmStrings))\r
+               {\r
+                       case 0:\r
+                               Flags |= FL_QUICK;\r
+                       break;\r
+\r
+                       case 1:\r
+                               starting_level = atoi(_argv[i]+1);\r
+                               if ((starting_level < 0) || (starting_level > LASTMAP-1))\r
+                                       starting_level = 0;\r
+                       break;\r
+\r
+                       case 2:\r
+                               printf("%s  %s  rev %s\n",GAMENAME,VERSION,REVISION);\r
+                               exit(0);\r
+                       break;\r
+\r
+                       case 3:\r
+                               Flags |= FL_NOMEMCHECK;\r
+                       break;\r
+               }\r
        }\r
 \r
-       if (stricmp(_argv[1], "/?") == 0)\r
-       {\r
-               printf("Catacomb 3-D version 1.22\n");\r
-               printf("Copyright 1991-93 Softdisk Publishing\n\n");\r
-               printf("Syntax:\n");\r
-               printf("CAT3D [/<switch>]\n\n");\r
-               printf("Switch       What it does\n");\r
-               printf("/?           This Information\n");\r
-               printf("/VER         Display Program Version Information\n");\r
-               printf("/COMP        Fix problems with SVGA screens\n");\r
-               printf("/NOAL        No AdLib or SoundBlaster detection\n");\r
-               printf("/NOJOYS      Tell program to ignore joystick\n");\r
-               printf("/NOMOUSE     Tell program to ignore mouse\n");\r
-               printf("/HIDDENCARD  Overrides video detection\n\n");\r
-               printf("Each switch must include a '/' and multiple switches\n");\r
-               printf("must be seperated by at least one space.\n\n");\r
+       if (!stricmp(_argv[1], "^(a@&r`"))\r
+                       LaunchedFromShell = true;\r
 \r
+       if (!LaunchedFromShell)\r
+       {\r
+               clrscr();\r
+               puts("You must type CATABYSS at the DOS prompt to run CATACOMB ABYSS 3-D.");\r
                exit(0);\r
        }\r
 \r
-       jabhack();\r
+       randomize();\r
 \r
        InitGame ();\r
-\r
-       CheckMemory ();\r
-\r
        LoadLatchMem ();\r
 \r
 #ifdef PROFILE\r
@@ -748,9 +874,6 @@ void main (void)
        GameLoop ();\r
 #endif\r
 \r
-//NewGame ();\r
-//GameLoop ();\r
-\r
        DemoLoop();\r
-       Quit("Demo loop exited???");\r
+       Quit(NULL);\r
 }\r
index 112041f966abc5e1758ca809cd81e80eee78ea45..ba68993fddf1772a6c1bad79c6d5e2217b576b8c 100644 (file)
--- a/C4_PLAY.C
+++ b/C4_PLAY.C
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code\r
+/* Catacomb Abyss Source Code\r
  * Copyright (C) 1993-2014 Flat Rock Software\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
@@ -18,7 +18,8 @@
 \r
 // C3_PLAY.C\r
 \r
-#include "C3_DEF.H"\r
+#include "DEF.H"\r
+#include "gelib.h"\r
 #pragma hdrstop\r
 \r
 /*\r
@@ -30,7 +31,7 @@
 */\r
 \r
 #define POINTTICS      6\r
-\r
+#define PAUSE 300\r
 \r
 /*\r
 =============================================================================\r
 =============================================================================\r
 */\r
 \r
-ControlInfo    c;\r
-boolean                running,slowturn;\r
+byte bcolor;\r
+short skytimer=-1,skytimer_reset;\r
+short groundtimer=-1,groundtimer_reset;\r
+unsigned *skycolor,*groundcolor;\r
+unsigned nocolorchange=0xFFFF;\r
+byte BGFLAGS,                          // global that holds all current flags\r
+         bgflag;                               // used by BG changer, this flag is set when done\r
+\r
+\r
+unsigned sky_daytonight[]={0x0909,0x0101,0x0808,0x0000,0xFFFF};\r
+//unsigned gnd_daytonight[]={0x0202,0xFFFF};\r
+\r
+unsigned sky_lightning[]={0x0101,0x0909,0x0f0f,0x0808,0x0000,0xFFFF};\r
+\r
+unsigned sky_colors[NUMLEVELS]={0x0000,0x0000,0x0000,0x0000,0x0808,\r
+                                                                                 0x0404,0x0000,0x0000,0x0000,0x0000,\r
+                                                                                 0x0000,0x0000,0x0000,0x0000,0x0606,\r
+                                                                                 0x0000,0x0000,0x0000,0x0000,0x0000,\r
+                                                                                 0x0000};\r
+unsigned gnd_colors[NUMLEVELS]={0x0202,0x0202,0x0606,0x0202,0x0707,\r
+                                                                                 0x0505,0x0808,0x0606,0x0101,0x0808,\r
+                                                                                 0x0606,0x0404,0x0808,0x0c0c,0x0e0e,\r
+                                                                                 0x0808,0x0808,0x0c0c,0x0000,0x0707,\r
+                                                                                 0x0808};\r
+\r
+\r
+ControlInfo    control;\r
+boolean                running=false; //,slowturn;\r
 \r
 int                    bordertime;\r
 objtype objlist[MAXACTORS],*new,*obj,*player,*lastobj,*objfreelist;\r
@@ -51,11 +78,13 @@ byte                *nearmapylookup[MAPSIZE];
 \r
 boolean                singlestep,godmode;\r
 int                    extravbls;\r
+status_flags    status_flag;\r
+int             status_delay;\r
 \r
 //\r
 // replacing refresh manager\r
 //\r
-unsigned       mapwidth,mapheight,tics;\r
+unsigned       mapwidth,mapheight,tics,realtics;\r
 boolean                compatability;\r
 byte           *updateptr;\r
 unsigned       mapwidthtable[64];\r
@@ -69,6 +98,8 @@ byte          update[UPDATESIZE];
 int            mousexmove,mouseymove;\r
 int            pointcount,pointsleft;\r
 \r
+short BeepTime = 0;\r
+\r
 /*\r
 =============================================================================\r
 \r
@@ -79,6 +110,8 @@ int          pointcount,pointsleft;
 \r
 void CalcBounds (objtype *ob);\r
 void DrawPlayScreen (void);\r
+void PreFullDisplay(void);\r
+void PostFullDisplay(boolean draw_view);\r
 \r
 \r
 //\r
@@ -96,6 +129,7 @@ int  objectcount;
 void StopMusic(void);\r
 void StartMusic(void);\r
 \r
+void CalibrateJoystick(short joynum);\r
 \r
 //==========================================================================\r
 \r
@@ -106,8 +140,8 @@ void StartMusic(void);
 //\r
 ///////////////////////////////////////////////////////////////////////////\r
 \r
-#define MAXX   264\r
-#define MAXY   146\r
+#define MAXX   320\r
+#define MAXY   120\r
 \r
 void   CenterWindow(word w,word h)\r
 {\r
@@ -127,9 +161,25 @@ void       CenterWindow(word w,word h)
 \r
 void CheckKeys (void)\r
 {\r
+       extern boolean autofire;\r
+\r
        if (screenfaded)                        // don't do anything with a faded screen\r
                return;\r
 \r
+       if (Keyboard[sc_M]&&Keyboard[sc_I]&&Keyboard[sc_K]&&Keyboard[sc_E])\r
+       {\r
+               CenterWindow (12,2);\r
+               if (autofire)\r
+                 US_PrintCentered ("Auto-Bolt OFF");\r
+               else\r
+                 US_PrintCentered ("Auto-Bolt ON");\r
+               VW_UpdateScreen();\r
+               IN_Ack();\r
+               autofire ^= 1;\r
+               return 1;\r
+       }\r
+\r
+#if 0\r
 //\r
 // pause key wierdness can't be checked as a scan code\r
 //\r
@@ -138,42 +188,252 @@ void CheckKeys (void)
                CenterWindow (8,3);\r
                US_PrintCentered ("PAUSED");\r
                VW_UpdateScreen ();\r
-               SD_MusicOff();\r
+//             SD_MusicOff();\r
                IN_Ack();\r
-               SD_MusicOn();\r
+//             SD_MusicOn();\r
                Paused = false;\r
                if (MousePresent) Mouse(MDelta);        // Clear accumulated mouse movement\r
        }\r
+       else\r
+       if (Keyboard[sc_Enter])                 // P = pause with no screen disruptioon\r
+       {\r
+//             SD_MusicOff();\r
+               DisplaySMsg("PAUSED",NULL);\r
+               IN_Ack();\r
+//             SD_MusicOn();\r
+               if (MousePresent) Mouse(MDelta);        // Clear accumulated mouse movement\r
+       }\r
+       else\r
+       if (Keyboard[sc_S])\r
+       {\r
+               char *Text[] = {{"Slow Mode ON"},{"Slow Mode OFF"}};\r
+\r
+               SlowMode ^= 1;\r
+               extravbls = SlowMode << 3;\r
+               CenterWindow (8,3);\r
+               US_PrintCentered (Text[SlowMode]);\r
+               VW_UpdateScreen ();\r
+//             SD_MusicOff();\r
+               IN_Ack();\r
+//             SD_MusicOn();\r
+               if (MousePresent) Mouse(MDelta);        // Clear accumulated mouse movement\r
+       }\r
+#endif\r
+\r
+\r
+// F2 - SOUND OPTIONS\r
+//\r
+       if (Keyboard[sc_F2])\r
+       {\r
+               int height=7;\r
+               boolean ChoiceMade = false;\r
+\r
+               if (AdLibPresent)\r
+                       height++;\r
+\r
+               VW_FixRefreshBuffer();\r
+               CenterWindow(22,height);\r
+               US_Print( "\n        1 )  NO SOUND \n");\r
+               US_Print(   "        2 )  PC  AUDIO \n");\r
+\r
+               if (AdLibPresent)\r
+                       US_Print("        3 ) ADLIB AUDIO\n");\r
+\r
+               US_Print( "\n       ESC)    EXIT    ");\r
+               VW_UpdateScreen();\r
+\r
+               // Switch audio device ON/OFF & load sounds if there\r
+               // was a change in the device.\r
+\r
+               do {\r
+\r
+                       if (Keyboard[1])                                                                // ESC - Exit\r
+                               ChoiceMade = true;\r
+                       else\r
+                       if (Keyboard[2])                                                                // 1 - No Sound\r
+                       {\r
+                               SD_SetSoundMode(sdm_Off);\r
+                               ChoiceMade = true;\r
+                       }\r
+                       else\r
+                       if (Keyboard[3])                                                        // 2 - PC Audio\r
+                       {\r
+                               SD_SetSoundMode(sdm_PC);\r
+//                             if (oldsoundmode != sdm_PC)\r
+                                       CA_LoadAllSounds();\r
+                               ChoiceMade = true;\r
+                       }\r
+                       else\r
+                       if ((Keyboard[4]) &&    AdLibPresent)           // 3 - AdLib Audio\r
+                       {\r
+                               SD_SetSoundMode(sdm_AdLib);\r
+//                             if (oldsoundmode != sdm_AdLib)\r
+                                       CA_LoadAllSounds();\r
+                               ChoiceMade = true;\r
+                       }\r
+\r
+               } while (!ChoiceMade);\r
+               tics = realtics = 1;\r
+               IN_ClearKeysDown();\r
+       }\r
 \r
+// F5 - CALIBRATE JOYSTICK\r
 //\r
-// F1-F7/ESC to enter control panel\r
+       if (Keyboard[sc_F5])\r
+       {\r
+               CalibrateJoystick(0);\r
+               tics = realtics = 1;\r
+               IN_ClearKeysDown();\r
+       }\r
+\r
+deadloop:;\r
+// ESCAPE - quits game\r
 //\r
-       if ( (LastScan >= sc_F1 && LastScan <= sc_F7) || LastScan == sc_Escape)\r
+       if ((Keyboard[sc_Escape]) || (Flags & FL_DEAD))\r
        {\r
-               StopMusic ();\r
-               NormalScreen ();\r
-               FreeUpMemory ();\r
-               US_CenterWindow (20,8);\r
-               US_CPrint ("Loading");\r
-               VW_UpdateScreen ();\r
-               US_ControlPanel();\r
-               if (abortgame)\r
+               char ch;\r
+\r
+               DisplaySMsg("Options", NULL);\r
+               if ((status_flag != S_TIMESTOP) || (Flags & FL_DEAD))\r
+                       status_flag = S_NONE;\r
+\r
+\r
+               if (Flags & FL_DEAD)\r
                {\r
-                       playstate = ex_abort;\r
-                       return;\r
+                       char choices[] = {sc_Escape,sc_R,sc_N,sc_Q,0};\r
+                       ch = DisplayMsg("Restore          New          Quit",choices);\r
+               }\r
+               else\r
+               {\r
+                       char choices[] = {sc_Escape,sc_S,sc_R,sc_N,sc_Q,0};\r
+                       ch = DisplayMsg("Save       Restore       New       Quit",choices);\r
                }\r
-               StartMusic ();\r
+               DrawText(true);\r
+\r
+               switch (ch)\r
+               {\r
+                       case sc_S:\r
+                               if (!(Flags & FL_DEAD))\r
+                                       Keyboard[sc_F3] = true;\r
+                       break;\r
+\r
+                       case sc_R:\r
+                               Keyboard[sc_F4] = true;\r
+                       break;\r
+\r
+                       case sc_N:\r
+                               DisplaySMsg("Starting anew", NULL);\r
+                               VW_WaitVBL(60);\r
+                               playstate = ex_resetgame;\r
+                               Flags &= ~FL_DEAD;\r
+                               status_flag = S_NONE;\r
+                       break;\r
+\r
+                       case sc_Q:\r
+                               DisplaySMsg("FARE THEE WELL!", NULL);\r
+                               status_flag = S_NONE;\r
+                               VW_WaitVBL(120);\r
+                               if (!Flags & FL_QUICK)\r
+                                       VW_FadeOut();\r
+                               NormalScreen();\r
+                               FreeUpMemory();\r
+                               Quit(NULL);\r
+                       break;\r
+               }\r
+               tics = realtics = 1;\r
+\r
+               if (status_flag == S_TIMESTOP)\r
+                       DisplaySMsg("Time Stopped:     ",NULL);\r
+       }\r
+\r
+// F1 - DISPLAY HELP\r
+//\r
+       if (Keyboard[sc_F1])\r
+       {\r
+               boolean nohelp=false;\r
+               extern textinfo MainHelpText;\r
+\r
+               VW_FadeOut();\r
+\r
+               FreeUpMemory();\r
+               if (!FindFile("HELP.TXT",NULL,1))\r
+                       nohelp = true;\r
+\r
+               if (LoadTextFile("HELP.TXT",&MainHelpText))\r
+               {\r
+                       VW_SetSplitScreen(200);\r
+                       bufferofs = displayofs = screenloc[0];\r
+                       VW_Bar(0,0,320,200,0);\r
+\r
+                       DisplayText(&MainHelpText);\r
+               }\r
+               else\r
+                       nohelp = true;\r
+\r
+               if (nohelp)\r
+               {\r
+                       VW_FadeIn();\r
+                       CenterWindow(30,5);\r
+                       US_CPrint("\nError loading HELP file.\n");\r
+                       US_CPrint("Press any key.");\r
+                       IN_Ack();\r
+                       VW_FadeOut();\r
+                       nohelp = false;\r
+               }\r
+               FreeTextFile(&MainHelpText);\r
+               VW_SetSplitScreen(120);\r
+               VW_SetScreen(screenloc[0],0);\r
+               screenpage = 0;\r
+               CacheScaleds();\r
+\r
+               bufferofs = 0;\r
+               RedrawStatusWindow();\r
+               ThreeDRefresh();\r
+               VW_FadeIn();\r
+               Keyboard[sc_F1] = false;\r
+               tics = realtics = 1;\r
+               IN_ClearKeysDown();\r
+       }\r
+\r
+// F3 - SAVE GAME\r
+//\r
+       if ((Keyboard[sc_F3]) && (!(Flags & FL_DEAD)))\r
+       {\r
+               PreFullDisplay();\r
+               GE_SaveGame();\r
+               PostFullDisplay(true);\r
+               tics = realtics = 1;\r
                IN_ClearKeysDown();\r
-               if (restartgame)\r
-                       playstate = ex_resetgame;\r
-               if (loadedgame)\r
+       }\r
+\r
+// F4 - LOAD GAME\r
+//\r
+       if (Keyboard[sc_F4])\r
+       {\r
+               PreFullDisplay();\r
+               if (GE_LoadGame())\r
+               {\r
+                       loadedgame = true;\r
                        playstate = ex_loadedgame;\r
-               DrawPlayScreen ();\r
-               CacheScaleds ();\r
-               lasttimecount = TimeCount;\r
-               if (MousePresent) Mouse(MDelta);        // Clear accumulated mouse movement\r
+                       Flags &= ~FL_DEAD;\r
+                       PostFullDisplay(false);\r
+               }\r
+               else\r
+               if (playstate == ex_victorious)\r
+               {\r
+                       PostFullDisplay(false);\r
+                       Victory(false);\r
+               }\r
+               else\r
+                       PostFullDisplay(true);\r
+               Keyboard[sc_F5] = false;\r
+               tics = realtics = 1;\r
+               IN_ClearKeysDown();\r
        }\r
 \r
+       if (Flags & FL_DEAD)\r
+               goto deadloop;\r
+\r
 //\r
 // F10-? debug keys\r
 //\r
@@ -183,7 +443,32 @@ void CheckKeys (void)
                if (MousePresent) Mouse(MDelta);        // Clear accumulated mouse movement\r
                lasttimecount = TimeCount;\r
        }\r
+}\r
 \r
+//-------------------------------------------------------------------------\r
+// PreFullDisplay()\r
+//-------------------------------------------------------------------------\r
+void PreFullDisplay()\r
+{\r
+       VW_FadeOut();\r
+       VW_SetSplitScreen(200);\r
+       bufferofs = displayofs = screenloc[0];\r
+       VW_Bar(0,0,320,200,0);\r
+}\r
+\r
+//-------------------------------------------------------------------------\r
+// PostFullDisplay()\r
+//-------------------------------------------------------------------------\r
+void PostFullDisplay(boolean draw_view)\r
+{\r
+       VW_SetSplitScreen(120);\r
+       bufferofs = 0;\r
+       RedrawStatusWindow();\r
+       if (draw_view)\r
+       {\r
+               ThreeDRefresh();\r
+               VW_FadeIn();\r
+       }\r
 }\r
 \r
 \r
@@ -342,7 +627,7 @@ void PollControls (void)
 {\r
        unsigned buttons;\r
 \r
-       IN_ReadControl(0,&c);\r
+       IN_ReadControl(0,&control);\r
 \r
        if (MousePresent)\r
        {\r
@@ -353,38 +638,21 @@ void PollControls (void)
                mouseymove = _DX;\r
 \r
                if (buttons&1)\r
-                       c.button0 = 1;\r
+                       control.button0 = 1;\r
                if (buttons&2)\r
-                       c.button1 = 1;\r
+                       control.button1 = 1;\r
 \r
        }\r
 \r
-       if (Controls[0]==ctrl_Joystick)\r
-       {\r
-               if (c.x>120 || c.x <-120 || c.y>120 || c.y<-120)\r
-                       running = true;\r
-               else\r
-                       running = false;\r
-               if (c.x>-48 && c.x<48)\r
-                       slowturn = true;\r
-               else\r
-                       slowturn = false;\r
-       }\r
+       if (Keyboard[sc_V] || Keyboard[sc_Tab])\r
+               running = true;\r
        else\r
-       {\r
-               if (Keyboard[sc_RShift])\r
-                       running = true;\r
-               else\r
-                       running = false;\r
-               if (c.button0)\r
-                       slowturn = true;\r
-               else\r
-                       slowturn = false;\r
-       }\r
+               running = false;\r
 }\r
 \r
 //==========================================================================\r
 \r
+#if 0\r
 /*\r
 =================\r
 =\r
@@ -438,6 +706,7 @@ void StartMusic(void)
                SD_StartMusic((MusicGroup far *)audiosegs[STARTMUSIC + chunk]);\r
        }\r
 }\r
+#endif\r
 \r
 //==========================================================================\r
 \r
@@ -452,7 +721,23 @@ void StartMusic(void)
 \r
 void PlayLoop (void)\r
 {\r
+       char shot_color[3] = {4,9,14};\r
+\r
+       int allgems[5]={GEM_DELAY_TIME,         // used for Q & D comparison\r
+                                                GEM_DELAY_TIME,                // for having all gems...\r
+                                                GEM_DELAY_TIME,                // the "allgems" declaration MUST\r
+                                                GEM_DELAY_TIME,                // match the "gems" declaration in\r
+                                                GEM_DELAY_TIME         // the gametype structure!\r
+                                               };\r
+\r
+//     int originx=0;\r
+//     int i=100;\r
+       signed long dx,dy,radius,psin,pcos,newx,newy;\r
+       short jim;\r
        int             give;\r
+       short objnum;\r
+       signed long ox,oy,xl,xh,yl,yh,px,py,norm_dx,norm_dy;\r
+       short o_radius;\r
 \r
        void (*think)();\r
 \r
@@ -461,8 +746,34 @@ void PlayLoop (void)
        gamestate.shotpower = handheight = 0;\r
        pointcount = pointsleft = 0;\r
 \r
-       DrawLevelNumber (gamestate.mapon);\r
-       DrawBars ();\r
+       // setup sky/ground colors and effects (based on level)\r
+       //\r
+       switch (gamestate.mapon)\r
+       {\r
+               case 0:\r
+                       if (!(BGFLAGS & BGF_NIGHT))\r
+                       {\r
+                               InitBgChange(3*60,sky_daytonight,-1,NULL,BGF_NIGHT);\r
+                               groundcolor = &gnd_colors[0];\r
+                       }\r
+                       else\r
+                       {\r
+                               skycolor = &sky_colors[0];\r
+                               groundcolor = &gnd_colors[0];\r
+                       }\r
+               break;\r
+\r
+               default:\r
+                       skycolor = &sky_colors[gamestate.mapon];\r
+                       groundcolor = &gnd_colors[gamestate.mapon];\r
+                       skytimer = groundtimer = -1;\r
+               break;\r
+       }\r
+\r
+       RedrawStatusWindow();\r
+       ThreeDRefresh();\r
+       if (screenfaded)\r
+               VW_FadeIn();\r
 \r
 #ifndef PROFILE\r
        fizzlein = true;                                // fizzle fade in the first refresh\r
@@ -470,34 +781,44 @@ void PlayLoop (void)
        TimeCount = lasttimecount = lastnuke = 0;\r
 \r
        PollControls ();                                // center mouse\r
-       StartMusic ();\r
+//     StartMusic ();\r
        do\r
        {\r
 #ifndef PROFILE\r
                PollControls();\r
 #else\r
-               c.xaxis = 1;\r
+               control.xaxis = 1;\r
                if (++TimeCount == 300)\r
                        return;\r
 #endif\r
 \r
+               objnum=0;\r
                for (obj = player;obj;obj = obj->next)\r
-                       if (obj->active)\r
+               {\r
+                       if ((obj->active >= yes) && (!(FreezeTime && (obj!=player))))\r
                        {\r
+\r
+\r
                                if (obj->ticcount)\r
                                {\r
                                        obj->ticcount-=tics;\r
+\r
                                        while ( obj->ticcount <= 0)\r
                                        {\r
                                                think = obj->state->think;\r
                                                if (think)\r
                                                {\r
+                                                       statetype *oldstate=obj->state;\r
+\r
                                                        think (obj);\r
                                                        if (!obj->state)\r
                                                        {\r
                                                                RemoveObj (obj);\r
                                                                goto nextactor;\r
                                                        }\r
+\r
+                                                       if (obj->state != oldstate)\r
+                                                               break;\r
                                                }\r
 \r
                                                obj->state = obj->state->next;\r
@@ -506,16 +827,21 @@ void PlayLoop (void)
                                                        RemoveObj (obj);\r
                                                        goto nextactor;\r
                                                }\r
+\r
                                                if (!obj->state->tictime)\r
                                                {\r
                                                        obj->ticcount = 0;\r
                                                        goto nextactor;\r
                                                }\r
+\r
                                                if (obj->state->tictime>0)\r
                                                        obj->ticcount += obj->state->tictime;\r
                                        }\r
                                }\r
+\r
+\r
                                think = obj->state->think;\r
+\r
                                if (think)\r
                                {\r
                                        think (obj);\r
@@ -525,60 +851,507 @@ void PlayLoop (void)
 nextactor:;\r
                        }\r
 \r
+                       // keep a list of objects around the player for radar updates\r
+                       //\r
+                               if (obj == player)\r
+                               {\r
+                                       px = player->x;\r
+                                       py = player->y;\r
+                                       psin = sintable[player->angle];\r
+                                       pcos = costable[player->angle];\r
+                                       xl = px-((long)RADAR_WIDTH<<TILESHIFT)/2;\r
+                                       xh = px+((long)RADAR_WIDTH<<TILESHIFT)/2-1;\r
+                                       yl = py-((long)RADAR_HEIGHT<<TILESHIFT)/2;\r
+                                       yh = py+((long)RADAR_HEIGHT<<TILESHIFT)/2;\r
+                               }\r
+\r
+                               if (objnum > MAX_RADAR_BLIPS-2)\r
+                                       objnum = MAX_RADAR_BLIPS-2;\r
+\r
+                               ox = obj->x;\r
+                               oy = obj->y;\r
+\r
+\r
+                               if ((ox >= xl) && (ox <= xh) && (oy >= yl) && (oy <= yh))\r
+                               {\r
+                                       norm_dx = (dx = px-ox)>>TILESHIFT;\r
+                                       norm_dy = (dy = oy-py)>>TILESHIFT;\r
+\r
+                                       o_radius = IntSqrt((norm_dx * norm_dx) + (norm_dy * norm_dy));\r
+\r
+                                       if (o_radius < RADAR_RADIUS)\r
+                                       {\r
+                                               newx = FixedByFrac(dy,pcos)-FixedByFrac(dx,psin);\r
+                                               newy = FixedByFrac(dy,psin)+FixedByFrac(dx,pcos);\r
+\r
+                                               RadarXY[objnum][0]=newx>>TILESHIFT;\r
+                                               RadarXY[objnum][1]=newy>>TILESHIFT;\r
+\r
+                                               // Define color to use for this object...\r
+                                               //\r
+\r
+                                               switch (obj->obclass)\r
+                                               {\r
+                       // NO GEM NEEDED\r
+                       //\r
+                                       // THE WIZARD! (YOU)\r
+                                       //\r
+                                                       case playerobj:\r
+                                                               RadarXY[objnum++][2]=15;\r
+                                                       break;\r
+\r
+                                       // WIZARD'S SHOTS\r
+                                       //\r
+                                                       case pshotobj:\r
+                                                       case bigpshotobj:\r
+                                                               RadarXY[objnum++][2]=shot_color[screenpage];\r
+                                                       break;\r
+\r
+                                       // BATS                                                 (DK GRAY)\r
+                                       //\r
+                                                       case batobj:\r
+                                                               if (obj->active == always)\r
+                                                                       RadarXY[objnum++][2]=8;\r
+                                                       break;\r
+\r
+                       // RED GEM\r
+                       //\r
+                                       // EYE, RED DEMON                       (DK RED)\r
+                                       //\r
+                                                       case eyeobj:\r
+                                                       case reddemonobj:\r
+                                                               if (gamestate.gems[B_RGEM-B_RGEM])\r
+                                                                       if (obj->active == always)\r
+                                                                               RadarXY[objnum++][2]=4;\r
+                                                       break;\r
+\r
+                                       // RED MAGE                                                     (LT RED)\r
+                                       //\r
+                                                       case mageobj:\r
+                                                               if (gamestate.gems[B_RGEM-B_RGEM])\r
+                                                                       if (obj->active == always)\r
+                                                                               RadarXY[objnum++][2]=12;\r
+                                                       break;\r
+\r
+                       // BLUE GEM\r
+                       //\r
+                                       // WATER TROLL                                          (LT BLUE)\r
+                                       //\r
+                                                       case wetobj:\r
+                                                               if (gamestate.gems[B_BGEM-B_RGEM])\r
+                                                                       if (obj->active == always)\r
+                                                                               RadarXY[objnum++][2]=9;\r
+                                                       break;\r
+\r
+                                       // WATER TROLL                                          (DK BLUE)\r
+                                       //\r
+                                                       case demonobj:\r
+                                                               if (gamestate.gems[B_BGEM-B_RGEM])\r
+                                                                       if (obj->active == always)\r
+                                                                               RadarXY[objnum++][2]=1;\r
+                                                       break;\r
+\r
+                       // GREEN GEM\r
+                       //\r
+                                       // GREEN TROLL                                          (LT GREEN)\r
+                                       //\r
+                                                       case trollobj:\r
+                                                               if (gamestate.gems[B_GGEM-B_RGEM])\r
+                                                                       if (obj->active == always)\r
+                                                                               RadarXY[objnum++][2]=10;\r
+                                                       break;\r
+\r
+                                       // ORC                                                          (DK GREEN)\r
+                                       //\r
+                                                       case orcobj:\r
+                                                               if (gamestate.gems[B_GGEM-B_RGEM])\r
+                                                                       if (obj->active == always)\r
+                                                                               RadarXY[objnum++][2]=2;\r
+                                                       break;\r
+\r
+                       // YELLOW GEM\r
+                       //\r
+                                       // SPOOK                                                                (BROWN)\r
+                                       //\r
+                                                       case spookobj:\r
+                                                               if (gamestate.gems[B_YGEM-B_RGEM])\r
+                                                                       if (obj->active == always)\r
+                                                                               RadarXY[objnum++][2]=6;\r
+                                                       break;\r
+\r
+                                       // SKELETON                                                     (YELLOW)\r
+                                       //\r
+                                                       case skeletonobj:\r
+                                                               if (gamestate.gems[B_YGEM-B_RGEM])\r
+                                                                       if (obj->active == always)\r
+                                                                               RadarXY[objnum++][2]=14;\r
+                                                       break;\r
+\r
+                       // PURPLE GEM\r
+                       //\r
+                                       // ZOMBIE\r
+                                       //\r
+                                                       case zombieobj:\r
+                                                               if (gamestate.gems[B_PGEM-B_RGEM])\r
+                                                                       if (obj->active == always)\r
+                                                                               RadarXY[objnum++][2]=13;\r
+                                                       break;\r
+\r
+                       // ALL GEMS NEEDED\r
+                       //\r
+                                       // NEMESIS\r
+                                       //\r
+                                                       case grelmobj:\r
+                                                               if (!memcmp(gamestate.gems,allgems,sizeof(gamestate.gems)))\r
+                                                                       if (obj->active == always)\r
+                                                                               RadarXY[objnum++][2]=15;\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                               }\r
+               }\r
+               RadarXY[objnum][2]=-1;          // Signals end of RadarXY list...\r
 \r
                if (bordertime)\r
                {\r
-                       bordertime -= tics;\r
+                       bordertime -= realtics;\r
                        if (bordertime<=0)\r
                        {\r
                                bordertime = 0;\r
-                               VW_ColorBorder (3);\r
+                               VW_ColorBorder(0);\r
                        }\r
                }\r
 \r
-               if (pointcount)\r
+// random lightning?\r
+//\r
+       if (BGFLAGS & (BGF_NIGHT|BGF_NOT_LIGHTNING))\r
+               switch (gamestate.mapon)\r
+               {\r
+                       case 0:\r
+                       case 1:\r
+                       case 3:\r
+                               if (!random(120-realtics))\r
+                               {\r
+                                       BGFLAGS &= ~BGF_NOT_LIGHTNING;\r
+                                       InitBgChange(1,sky_lightning,-1,NULL,BGF_NOT_LIGHTNING);\r
+                               }\r
+                       break;\r
+               }\r
+\r
+// handle sky/ground color changes\r
+//\r
+               if (skytimer != -1)\r
+               {\r
+                       skytimer -= realtics;\r
+                       if (skytimer < 0)\r
+                       {\r
+                               skycolor++;\r
+                               if (*skycolor == 0xffff)\r
+                               {\r
+                                       skytimer = -1;\r
+                                       skycolor--;\r
+                                       if (groundtimer == -1)\r
+                                               BGFLAGS |= bgflag;\r
+                               }\r
+                               else\r
+                                       skytimer = skytimer_reset;\r
+                       }\r
+               }\r
+\r
+               if (groundtimer != -1)\r
+               {\r
+                       groundtimer -= realtics;\r
+                       if (groundtimer < 0)\r
+                       {\r
+                               groundcolor++;\r
+                               if (*groundcolor == 0xffff)\r
+                               {\r
+                                       groundtimer = -1;\r
+                                       groundcolor--;\r
+                                       if (skytimer == -1)\r
+                                               BGFLAGS |= bgflag;\r
+                               }\r
+                               else\r
+                                       groundtimer = groundtimer_reset;\r
+                       }\r
+               }\r
+\r
+\r
+//\r
+//             Handle FreezeTime counter..\r
+//\r
+               if (FreezeTime)\r
                {\r
-                       pointcount -= tics;\r
-                       if (pointcount <= 0)\r
+                       if (FreezeTime<20*30)\r
+                               if ((BeepTime+=realtics)>=60)\r
+                               {\r
+                                       BeepTime -= 60;\r
+                                       SD_PlaySound(TICKSND);\r
+                               }\r
+\r
+                       if ((FreezeTime-=realtics)<=0)\r
                        {\r
-                               pointcount += POINTTICS;\r
-                               give = (pointsleft > 1000)? 1000 :\r
-                                               (\r
-                                                       (pointsleft > 100)? 100 :\r
-                                                               ((pointsleft < 20)? pointsleft : 20)\r
-                                               );\r
-                               SD_PlaySound (GETPOINTSSND);\r
-                               AddPoints (give);\r
-                               pointsleft -= give;\r
-                               if (!pointsleft)\r
-                                       pointcount = 0;\r
+                               FreezeTime=0;\r
+                               SD_PlaySound(TIMERETURNSND);\r
+                               DisplaySMsg(NULL,NULL);\r
+                               status_flag = S_NONE;\r
                        }\r
                }\r
 \r
+\r
+// refresh all\r
+//\r
                ThreeDRefresh ();\r
 \r
-               CheckKeys();\r
-               if (singlestep)\r
+               if (Flags & FL_DEAD)\r
                {\r
-                       VW_WaitVBL(14);\r
-                       lasttimecount = TimeCount;\r
+                       SD_PlaySound (GAMEOVERSND);\r
+                       DisplaySMsg("DEAD",NULL);\r
+                       DrawHealth();\r
+                       if (gamestate.potions)\r
+                       {\r
+                                bufferofs = displayofs = screenloc[screenpage];\r
+                                CenterWindow(35,3);\r
+                                US_CPrint("\nYou should use your Cure Potions wisely\n");\r
+                                IN_Ack();\r
+                       }\r
+               }\r
+\r
+// check for win\r
+//\r
+               if (playstate == ex_victorious)\r
+               {\r
+                       Victory(true);\r
+                       Flags |= FL_DEAD;\r
                }\r
-               if (extravbls)\r
-                       VW_WaitVBL(extravbls);\r
+\r
+               DisplayStatus(&status_flag);\r
+               CheckKeys();\r
 \r
        }while (!playstate);\r
-       StopMusic ();\r
+//     StopMusic ();\r
 \r
        ingame = false;\r
        if (bordertime)\r
        {\r
                bordertime = 0;\r
-               VW_ColorBorder (3);\r
+               VW_ColorBorder(0);\r
        }\r
 \r
-       if (!abortgame)\r
-               AddPoints (pointsleft);\r
-       else\r
+       if (abortgame)\r
                abortgame = false;\r
 }\r
 \r
+//--------------------------------------------------------------------------\r
+// IntSqrt() - by Master Programmer, George Leritte!\r
+//--------------------------------------------------------------------------\r
+int IntSqrt(long va)\r
+{\r
+asm     mov     AX, word ptr va\r
+asm     mov     DX, word ptr va+2\r
+asm     mov     bx,dx           // {bx = integer square root of dx:ax}\r
+asm     or      bx,ax           // {if dx:ax=0 then return}\r
+asm     jz      isq01\r
+asm     mov     bx,dx\r
+asm     shl     bx,1\r
+asm     or      bl,ah\r
+asm     or      bl,al\r
+asm     dec     bx\r
+asm     add     bx,dx           // { initial guess}\r
+asm     jg      isq10\r
+asm     inc     bx              // { don't return zero}\r
+asm     jg      isq10\r
+asm     mov     bx,7fffh\r
+isq01:;\r
+                 goto    exitrout;\r
+\r
+isq10:;\r
+asm     push    ax\r
+asm     push    dx\r
+asm     div     bx\r
+asm     sub     ax,bx\r
+asm     cmp     ax,1\r
+asm     jbe     isq90\r
+asm     cmp     ax,-1\r
+asm     jae     isq90\r
+asm     sar     ax,1\r
+asm     add     bx,ax\r
+asm     pop     dx\r
+asm     pop     ax\r
+asm     jmp     isq10\r
+isq90:;\r
+asm     pop     dx\r
+asm     pop     ax\r
+exitrout:;\r
+asm     mov     ax,bx\r
+}\r
+\r
+//-------------------------------------------------------------------------\r
+// InitBgChange()\r
+//-------------------------------------------------------------------------\r
+void InitBgChange(short stimer, unsigned *scolors, short gtimer, unsigned *gcolors, byte flag)\r
+{\r
+       skytimer_reset = skytimer = stimer;\r
+       if (scolors)\r
+               skycolor = scolors;\r
+\r
+       groundtimer_reset = groundtimer = gtimer;\r
+       if (gcolors)\r
+               groundcolor = gcolors;\r
+\r
+       bgflag = flag;\r
+}\r
+\r
+////////////////////////////////////////////////////////\r
+//\r
+// DisplayStatus\r
+//\r
+//  Stat_Flag -  contains the type of status displayed\r
+//  -- also uses status_delay (global variable) will not\r
+//     change display until this variable is zero.\r
+//  -- heirarchy is determined by the series of if statements,\r
+//        to change it, rearrange th if statements.\r
+//\r
+////////////////////////////////////////////////////////\r
+\r
+#define MESSAGEDELAY  25\r
+void DisplayStatus (status_flags *stat_flag)\r
+{\r
+       status_flags temp_status;\r
+\r
+\r
+       if (*stat_flag == S_TIMESTOP)\r
+         return;\r
+\r
+       if (status_delay > 0)\r
+       {\r
+               status_delay -= realtics;\r
+               return;\r
+       }\r
+       else\r
+               status_delay = 0;\r
+\r
+       // check for a change in status from previous call\r
+\r
+       temp_status = S_VIEWING;                             //precaution\r
+\r
+       if (Keyboard[sc_Control] || control.button0)\r
+               temp_status = S_MISSLE;\r
+\r
+       if (Keyboard[sc_Z] && !Keyboard[sc_F10])\r
+               temp_status = S_ZAPPER;\r
+\r
+       if ((Keyboard[sc_X] && !Keyboard[sc_F10]) || Keyboard[sc_Enter])\r
+               temp_status = S_XTER;\r
+\r
+       if (control.x)\r
+               temp_status = S_TURN;\r
+\r
+       if ((Keyboard[sc_V] || Keyboard[sc_Tab]) && control.x)\r
+               temp_status = S_QTURN;\r
+\r
+       if (Keyboard[sc_Alt] && control.x)\r
+               temp_status = S_SIDESTEP;\r
+\r
+       if (control.y < 0)\r
+               temp_status = S_ADVANCE;\r
+\r
+       if (control.y > 0)\r
+               temp_status = S_RETREAT;\r
+\r
+       if (Keyboard[sc_F5])\r
+               temp_status = S_JOYSTICK;\r
+\r
+       if (Keyboard[sc_F4])\r
+               temp_status = S_RESTORING;\r
+\r
+       if (Keyboard[sc_F3])\r
+               temp_status = S_SAVING;\r
+\r
+       if (Keyboard[sc_F2])\r
+               temp_status = S_SND;\r
+\r
+       if (Keyboard[sc_F1])\r
+               temp_status = S_HELP;\r
+\r
+       if (temp_status != *stat_flag)\r
+       {\r
+               *stat_flag = temp_status;\r
+\r
+\r
+               switch (*stat_flag)\r
+               {\r
+                       case S_MISSLE:\r
+                               DisplaySMsg("Magick Missile", NULL);\r
+                               status_delay = MESSAGEDELAY;\r
+                       break;\r
+\r
+                       case S_ZAPPER:\r
+                               if (gamestate.bolts)\r
+                               {\r
+                                       DisplaySMsg("Zapper", NULL);\r
+                                       status_delay = MESSAGEDELAY+10;\r
+                               }\r
+                       break;\r
+\r
+                       case S_XTER:\r
+                               if (gamestate.nukes)\r
+                               {\r
+                                       DisplaySMsg("Xterminator", NULL);\r
+                                       status_delay = MESSAGEDELAY+5;\r
+                               }\r
+                       break;\r
+\r
+                       case S_TURN:\r
+                               DisplaySMsg("Turning", NULL);\r
+                               status_delay = MESSAGEDELAY;\r
+                       break;\r
+\r
+                       case S_QTURN:\r
+                               DisplaySMsg("Quick Turning", NULL);\r
+                               status_delay = MESSAGEDELAY;\r
+                       break;\r
+\r
+                       case S_SIDESTEP:\r
+                               DisplaySMsg("Sidestepping", NULL);\r
+                               status_delay = MESSAGEDELAY;\r
+                       break;\r
+\r
+                       case S_ADVANCE:\r
+                               DisplaySMsg("Advancing", NULL);\r
+                               status_delay = MESSAGEDELAY;\r
+                       break;\r
+\r
+                       case S_RETREAT:\r
+                               DisplaySMsg("Retreating", NULL);\r
+                               status_delay = MESSAGEDELAY;\r
+                       break;\r
+\r
+                       case S_JOYSTICK:\r
+                               DisplaySMsg("Adjusting Joystick", NULL);\r
+                       break;\r
+\r
+                       case S_RESTORING:\r
+                               DisplaySMsg("Restoring", NULL);\r
+                       break;\r
+\r
+                       case S_SAVING:\r
+                               DisplaySMsg("Saving", NULL);\r
+                       break;\r
+\r
+                       case S_SND:\r
+                               DisplaySMsg("Select Sound", NULL);\r
+                       break;\r
+\r
+                       case S_HELP:\r
+                               DisplaySMsg("Getting Help", NULL);\r
+                       break;\r
+\r
+                       case S_VIEWING:\r
+                               DisplaySMsg("Viewing", NULL);\r
+                       break;\r
+               }\r
+               bufferofs = displayofs = screenloc[screenpage];\r
+\r
+       }\r
+}\r
index 018083d36b5edb3e6e7dabddb60ac070df172bf0..41f06e6e326d38f09d4e0acd435c471ab86f80b3 100644 (file)
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code\r
+/* Catacomb Abyss Source Code\r
  * Copyright (C) 1993-2014 Flat Rock Software\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
 \r
 // C3_SCALE.C\r
 \r
-#include "C3_DEF.H"\r
+#include "DEF.H"\r
 #pragma hdrstop\r
 \r
 //const        unsigned        viewheight = 144;\r
 const  unsigned        screenbwide = 40;\r
 const  byte            BACKGROUNDPIX   =   5;\r
 \r
-unsigned               shapesize[MAXSCALE+1];\r
-t_compscale _seg *scaledirectory[MAXSCALE+1];\r
+unsigned               shapesize[NUMSCALEPICS];\r
+t_compscale _seg *scaledirectory[NUMSCALEPICS];\r
 t_compshape _seg *shapedirectory[NUMSCALEPICS];\r
 memptr                 walldirectory[NUMSCALEWALLS];\r
 \r
@@ -57,7 +57,7 @@ void DeplanePic (int picnum)
        width = pictable[picnum-STARTPICS].width;\r
        height = pictable[picnum-STARTPICS].height;\r
 \r
-       if (width>64 || height!=64)\r
+       if (width>8 || height!=64)\r
                Quit ("DePlanePic: Bad size shape");\r
 \r
        memset (spotvis,BACKGROUNDPIX,sizeof(spotvis));\r
@@ -430,6 +430,10 @@ unsigned BuildCompShape (t_compshape _seg **finalspot)
 // copy the final shape to a properly sized buffer\r
 //\r
        totalsize = FP_OFF(code);\r
+\r
+       if (totalsize >= (PAGELEN*2))\r
+               Quit("BuildCompShape(): Shape is too complex!");\r
+\r
        MM_GetPtr ((memptr *)finalspot,totalsize);\r
        _fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize);\r
 //     MM_FreePtr (&(memptr)work);\r
@@ -459,6 +463,9 @@ static      long            longtemp;
 \r
 void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale)\r
 {\r
+       #define MAX_OBJ_SCALE (MAXSCALE)\r
+\r
+\r
        t_compscale _seg *comptable;\r
        unsigned        width,scalewidth;\r
        int                     x,pixel,lastpixel,pixwidth,min;\r
@@ -472,8 +479,10 @@ void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale)
        scale = (scale+1)/2;\r
        if (!scale)\r
                return;                                                         // too far away\r
-       if (scale>MAXSCALE)\r
-               scale = MAXSCALE;\r
+\r
+       if (scale>MAX_OBJ_SCALE)\r
+               scale = MAX_OBJ_SCALE;\r
+\r
        comptable = scaledirectory[scale];\r
 \r
        width = compshape->width;\r
@@ -481,6 +490,7 @@ void ScaleShape (int xcenter, t_compshape _seg *compshape, unsigned scale)
 \r
        pixel = xcenter - scalewidth/2;\r
        lastpixel = pixel+scalewidth-1;\r
+\r
        if (pixel >= VIEWWIDTH || lastpixel < 0)\r
                return;                                                         // totally off screen\r
 \r
index 58a8737a7c4eafdef2043b2c833e241b78651110..5bb52967c55858697e6181a5de82930eea447d4c 100644 (file)
@@ -1,4 +1,4 @@
-; Catacomb 3-D Source Code\r
+; Catacomb Abyss Source Code\r
 ; Copyright (C) 1993-2014 Flat Rock Software\r
 ;\r
 ; This program is free software; you can redistribute it and/or modify\r
index 8c31eb0681719d8a160811aeddf612a818b9886a..3bff92b3b3860302e949bdd0abf1c895eb1de2d3 100644 (file)
@@ -1,4 +1,4 @@
-/* Catacomb 3-D Source Code\r
+/* Catacomb Abyss Source Code\r
  * Copyright (C) 1993-2014 Flat Rock Software\r
  *\r
  * This program is free software; you can redistribute it and/or modify\r
@@ -18,7 +18,7 @@
 \r
 // C3_STATE.C\r
 \r
-#include "C3_DEF.H"\r
+#include "DEF.H"\r
 #pragma hdrstop\r
 \r
 /*\r
@@ -60,14 +60,15 @@ dirtype opposite[9] =
 /*\r
 ===================\r
 =\r
-= SpawnNewObj\r
+= Internal_SpawnNewObj\r
 =\r
 ===================\r
 */\r
-\r
-void SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size)\r
+void Internal_SpawnNewObj (unsigned x, unsigned y, statetype *state, unsigned size,boolean UseDummy)\r
 {\r
-       GetNewObj (false);\r
+       extern objtype dummyobj;\r
+\r
+       GetNewObj(UseDummy);\r
        new->