]> 4ch.mooo.com Git - 16.git/blobdiff - 16/keen456/KEEN4-6/CK_KEEN.C
added keen 4-6 rebuild code for reference.... i need to stop doing this... xD
[16.git] / 16 / keen456 / KEEN4-6 / CK_KEEN.C
diff --git a/16/keen456/KEEN4-6/CK_KEEN.C b/16/keen456/KEEN4-6/CK_KEEN.C
deleted file mode 100755 (executable)
index 3cb12b9..0000000
+++ /dev/null
@@ -1,2509 +0,0 @@
-/* Reconstructed Commander Keen 4-6 Source Code\r
- * Copyright (C) 2021 K1n9_Duk3\r
- *\r
- * This file is loosely based on:\r
- * Keen Dreams Source Code\r
- * Copyright (C) 2014 Javier M. Chavez\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License along\r
- * with this program; if not, write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
- */\r
-\r
-/*\r
-CK_KEEN.C\r
-=========\r
-\r
-Contains the following actor types (in this order):\r
-\r
-- Keen (regular levels)\r
-\r
-*/\r
-\r
-#include "CK_DEF.H"\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                GLOBAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-Sint16 singlegravity;  // left over from Keen Dreams, not used in Keen 4-6\r
-\r
-Uint16 bounceangle [8][8] =\r
-{\r
-       { 0,  0,  0,  0,  0,  0,  0,  0},\r
-       { 7,  6,  5,  4,  3,  2,  1,  0},\r
-       { 5,  4,  3,  2,  1,  0, 15, 14},\r
-       { 5,  4,  3,  2,  1,  0, 15, 14},\r
-       { 3,  2,  1,  0, 15, 14, 13, 12},\r
-       { 9,  8,  7,  6,  5,  4,  3,  2},\r
-       { 9,  8,  7,  6,  5,  4,  3,  2},\r
-       {11, 10,  9,  8,  7,  6,  5,  4}\r
-};\r
-\r
-#ifndef KEEN4\r
-arrowdirtype arrowflip[] = {arrow_South, arrow_West, arrow_North, arrow_East, arrow_SouthWest, arrow_NorthWest, arrow_NorthEast, arrow_SouthEast};\r
-#endif\r
-\r
-statetype s_keenstand     = {KEENSTANDLSPR, KEENSTANDRSPR, stepthink, false, true, 4, 0, 32, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand};\r
-\r
-#ifdef KEEN5\r
-statetype s_keenride     = {KEENONPLATSPR, KEENONPLATSPR, stepthink, false, true, 4, 0, 32, KeenStandThink, KeenContact, KeenStandReact, &s_keenride};\r
-#endif\r
-\r
-statetype s_keenpauselook = {KEENLOOKUSPR, KEENLOOKUSPR, stepthink, false, true, 60, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand};\r
-\r
-statetype s_keenwait1    = {KEENWAITR2SPR, KEENWAITR2SPR, stepthink, false, true, 90, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait2};\r
-statetype s_keenwait2    = {KEENWAITR1SPR, KEENWAITR1SPR, stepthink, false, true, 10, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait3};\r
-statetype s_keenwait3    = {KEENWAITR2SPR, KEENWAITR2SPR, stepthink, false, true, 90, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait4};\r
-statetype s_keenwait4    = {KEENWAITR1SPR, KEENWAITR1SPR, stepthink, false, true, 10, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait5};\r
-statetype s_keenwait5    = {KEENWAITR2SPR, KEENWAITR2SPR, stepthink, false, true, 90, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenwait6};\r
-statetype s_keenwait6    = {KEENWAITR3SPR, KEENWAITR3SPR, stepthink, false, true, 70, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand};\r
-\r
-#ifdef KEEN4\r
-statetype s_keenmoon1     = {KEENMOON1SPR, KEENMOON1SPR, stepthink, false, true, 20, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenmoon2};\r
-statetype s_keenmoon2     = {KEENMOON2SPR, KEENMOON2SPR, stepthink, false, true, 90, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenmoon3};\r
-statetype s_keenmoon3     = {KEENMOON1SPR, KEENMOON1SPR, stepthink, false, true, 20, 0, 0, KeenPauseThink, KeenContact, KeenStandReact, &s_keenstand};\r
-#endif\r
-\r
-statetype s_keenread      = {KEENSITREAD1SPR, KEENSITREAD1SPR, step, false, true, 16, 0, 0, 0, KeenContact, KeenStandReact, &s_keenread2};\r
-statetype s_keenread2     = {KEENSITREAD2SPR, KEENSITREAD2SPR, step, false, true, 16, 0, 0, 0, KeenContact, KeenStandReact, &s_keenread3};\r
-statetype s_keenread3     = {KEENSITREAD3SPR, KEENSITREAD3SPR, step, false, true, 16, 0, 0, 0, KeenContact, KeenStandReact, &s_keenread4};\r
-statetype s_keenread4     = {KEENSITREAD4SPR, KEENSITREAD4SPR, step, false, true, 16, 0, 0, 0, KeenContact, KeenStandReact, &s_keenread5};\r
-statetype s_keenread5     = {KEENREAD1SPR, KEENREAD1SPR, stepthink, false, true, 300, 0, 0, KeenReadThink, KeenContact, KeenStandReact, &s_keenread6};\r
-statetype s_keenread6     = {KEENREAD2SPR, KEENREAD2SPR, stepthink, false, true, 16, 0, 0, KeenReadThink, KeenContact, KeenStandReact, &s_keenread7};\r
-statetype s_keenread7     = {KEENREAD3SPR, KEENREAD3SPR, stepthink, false, true, 16, 0, 0, KeenReadThink, KeenContact, KeenStandReact, &s_keenread5};\r
-statetype s_keenstopread  = {KEENSTOPREAD1SPR, KEENSTOPREAD1SPR, step, false, true, 12, 0, 0, 0, KeenContact, KeenStandReact, &s_keenstopread2};\r
-statetype s_keenstopread2 = {KEENSTOPREAD2SPR, KEENSTOPREAD2SPR, step, false, true, 12, 0, 0, 0, KeenContact, KeenStandReact, &s_keenstopread3};\r
-statetype s_keenstopread3 = {KEENSITREAD2SPR, KEENSITREAD2SPR, step, false, true, 12, 0, 0, 0, KeenContact, KeenStandReact, &s_keenstand};\r
-\r
-statetype s_keenlookup    = {KEENLOOKUSPR, KEENLOOKUSPR, stepthink, false, true, 30, 0, 0, KeenLookUpThink, KeenContact, KeenStandReact, &s_keenlookup2};\r
-statetype s_keenlookup2   = {KEENLOOKUSPR, KEENLOOKUSPR, think, false, true, 0, 0, 0, KeenLookUpThink, KeenPosContact, KeenStandReact, NULL};\r
-\r
-statetype s_keenlookdown  = {KEENLOOKD1SPR, KEENLOOKD1SPR, stepthink, false, true, 6, 0, 0, KeenLookDownThink, KeenContact, KeenStandReact, &s_keenlookdown2};\r
-statetype s_keenlookdown2 = {KEENLOOKD2SPR, KEENLOOKD2SPR, stepthink, false, true, 24, 0, 0, KeenLookDownThink, KeenPosContact, KeenStandReact, &s_keenlookdown3};\r
-statetype s_keenlookdown3 = {KEENLOOKD2SPR, KEENLOOKD2SPR, think, false, true, 0, 0, 0, KeenLookDownThink, KeenPosContact, KeenStandReact, NULL};\r
-statetype s_keenlookdown4 = {KEENLOOKD1SPR, KEENLOOKD1SPR, step, false, true, 6, 0, 0, 0, KeenContact, KeenStandReact, &s_keenstand};\r
-\r
-statetype s_keendrop   = {KEENLOOKD1SPR, KEENLOOKD1SPR, step, false, false, 0, 0, 0, KeenDropDownThink, KeenContact, KeenSimpleReact, &s_keenjump3};\r
-statetype s_keendead   = {-1, -1, think, false, false, 10, 0, 0, 0, 0, R_Draw, NULL};\r
-\r
-statetype s_keendie1     = {KEENDIE1SPR, KEENDIE1SPR, think, false, false, 100, 0, 0, KeenDieThink, 0, R_Draw, &s_keendie1};\r
-statetype s_keendie2     = {KEENDIE2SPR, KEENDIE2SPR, think, false, false, 100, 0, 0, KeenDieThink, 0, R_Draw, &s_keendie2};\r
-\r
-#ifdef KEEN4\r
-statetype s_keensuitdie1 = {SCUBAKEENDEAD1SPR, SCUBAKEENDEAD1SPR, think, false, false, 100, 0, 0, KeenDieThink, NULL, R_Draw, &s_keensuitdie1};\r
-statetype s_keensuitdie2 = {SCUBAKEENDEAD2SPR, SCUBAKEENDEAD2SPR, think, false, false, 100, 0, 0, KeenDieThink, NULL, R_Draw, &s_keensuitdie2};\r
-#endif\r
-\r
-statetype s_keenshoot1    = {KEENSHOOTLSPR, KEENSHOOTRSPR, step, false, true, 9, 0, 0, KeenShootThink, KeenContact, KeenStandReact, &s_keenshoot2};\r
-statetype s_keenshoot2    = {KEENSHOOTLSPR, KEENSHOOTRSPR, step, false, true, 6, 0, 0, 0, KeenContact, KeenStandReact, &s_keenstand};\r
-\r
-statetype s_keenshootup1  = {KEENSHOOTUSPR, KEENSHOOTUSPR, step, false, true, 9, 0, 0, KeenShootThink, KeenContact, KeenStandReact, &s_keenshootup2};\r
-statetype s_keenshootup2  = {KEENSHOOTUSPR, KEENSHOOTUSPR, step, false, true, 6, 0, 0, 0, KeenContact, KeenStandReact, &s_keenlookup};\r
-\r
-statetype s_keenswitch  = {KEENENTER1SPR, KEENENTER1SPR, step, false, true, 8, 0, 0, KeenSwitchThink, NULL, KeenStandReact, &s_keenswitch2};\r
-statetype s_keenswitch2 = {KEENENTER1SPR, KEENENTER1SPR, step, false, true, 8, 0, 0, 0, 0, KeenStandReact, &s_keenstand};\r
-statetype s_keenkey     = {KEENENTER1SPR, KEENENTER1SPR, step, false, true, 6, 0, 0, KeenKeyThink, NULL, KeenStandReact, &s_keenswitch2};\r
-\r
-statetype s_keenlineup  = {KEENENTER1SPR, KEENENTER1SPR, think, false, false, 0, 0, 0, T_LineUp, 0, R_Draw, NULL};\r
-#ifdef KEEN5\r
-statetype s_keenenter0   = {KEENENTER1SPR, KEENENTER1SPR, step, false, false, 45, 0, -64, NULL, NULL, R_Draw, &s_keenenter1};\r
-statetype s_keenteleport = {KEENWAITR2SPR, KEENWAITR2SPR, think, false, false, 0, 0, 0, NULL, NULL, R_Draw, NULL};\r
-#endif\r
-\r
-statetype s_keenenter1 = {KEENENTER1SPR, KEENENTER1SPR, step, false, false, 9, 0, -64, WalkSound1, NULL, R_Draw, &s_keenenter2};\r
-statetype s_keenenter2 = {KEENENTER2SPR, KEENENTER2SPR, step, false, false, 9, 0, -64, WalkSound2, NULL, R_Draw, &s_keenenter3};\r
-statetype s_keenenter3 = {KEENENTER3SPR, KEENENTER3SPR, step, false, false, 9, 0, -64, WalkSound1, NULL, R_Draw, &s_keenenter4};\r
-statetype s_keenenter4 = {KEENENTER4SPR, KEENENTER4SPR, step, false, false, 9, 0, -64, WalkSound2, NULL, R_Draw, &s_keenenter5};\r
-statetype s_keenenter5 = {KEENENTER5SPR, KEENENTER5SPR, step, false, false, 9, 0, -64, KeenEnterThink, NULL, R_Draw, &s_keenstand};\r
-#ifdef KEEN5\r
-statetype s_keenenter6 = {-1, -1, step, false, false, 9, 0, -64, KeenEnterThink, 0, R_Draw, &s_keenstand};\r
-#endif\r
-\r
-statetype s_keenpole      = {KEENSHINNYL1SPR, KEENSHINNYR1SPR, think, false, false, 0, 0, 0, KeenPoleThink, KeenPosContact, KeenSimpleReact, &s_keenpole};\r
-\r
-statetype s_keenclimb1 = {KEENSHINNYL1SPR, KEENSHINNYR1SPR, slidethink, false, false, 8, 0, 8, KeenClimbThink, KeenPosContact, KeenSimpleReact, &s_keenclimb2};\r
-statetype s_keenclimb2 = {KEENSHINNYL2SPR, KEENSHINNYR2SPR, slidethink, false, false, 8, 0, 8, KeenClimbThink, KeenPosContact, KeenSimpleReact, &s_keenclimb3};\r
-statetype s_keenclimb3 = {KEENSHINNYL3SPR, KEENSHINNYR3SPR, slidethink, false, false, 8, 0, 8, KeenClimbThink, KeenPosContact, KeenSimpleReact, &s_keenclimb1};\r
-\r
-statetype s_keenslide1 = {KEENSLIDED1SPR, KEENSLIDED1SPR, slide, false, false, 8, 0, 24, KeenDropThink, KeenPosContact, KeenPoleReact, &s_keenslide2};\r
-statetype s_keenslide2 = {KEENSLIDED2SPR, KEENSLIDED2SPR, slide, false, false, 8, 0, 24, KeenDropThink, KeenPosContact, KeenPoleReact, &s_keenslide3};\r
-statetype s_keenslide3 = {KEENSLIDED3SPR, KEENSLIDED3SPR, slide, false, false, 8, 0, 24, KeenDropThink, KeenPosContact, KeenPoleReact, &s_keenslide4};\r
-statetype s_keenslide4 = {KEENSLIDED4SPR, KEENSLIDED4SPR, slide, false, false, 8, 0, 24, KeenDropThink, KeenPosContact, KeenPoleReact, &s_keenslide1};\r
-\r
-statetype s_keenpoleshoot1 = {KEENPSHOOTLSPR, KEENPSHOOTRSPR, step, false, false, 9, 0, 0, KeenShootThink, KeenPosContact, KeenSimpleReact, &s_keenpoleshoot2};\r
-statetype s_keenpoleshoot2 = {KEENPSHOOTLSPR, KEENPSHOOTRSPR, step, false, false, 6, 0, 0, 0, KeenPosContact, KeenSimpleReact, &s_keenpole};\r
-\r
-statetype s_keenpoleshootup1 = {KEENPLSHOOTUSPR, KEENPRSHOOTUSPR, step, false, false, 9, 0, 0, KeenShootThink, KeenPosContact, KeenSimpleReact, &s_keenpoleshootup2};\r
-statetype s_keenpoleshootup2 = {KEENPLSHOOTUSPR, KEENPRSHOOTUSPR, step, false, false, 6, 0, 0, 0, KeenPosContact, KeenSimpleReact, &s_keenpole};\r
-\r
-statetype s_keenpoleshootdown1 = {KEENPLSHOOTDSPR, KEENPRSHOOTDSPR, step, false, false, 9, 0, 0, KeenShootThink, KeenPosContact, KeenSimpleReact, &s_keenpoleshootdown2};\r
-statetype s_keenpoleshootdown2 = {KEENPLSHOOTDSPR, KEENPRSHOOTDSPR, step, false, false, 6, 0, 0, 0, KeenPosContact, KeenSimpleReact, &s_keenpole};\r
-\r
-statetype s_keenwalk1     = {KEENRUNL1SPR, KEENRUNR1SPR, slidethink, true, true, 6, 24, 0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk2};\r
-statetype s_keenwalk2     = {KEENRUNL2SPR, KEENRUNR2SPR, slidethink, true, true, 6, 24, 0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk3};\r
-statetype s_keenwalk3     = {KEENRUNL3SPR, KEENRUNR3SPR, slidethink, true, true, 6, 24, 0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk4};\r
-statetype s_keenwalk4     = {KEENRUNL4SPR, KEENRUNR4SPR, slidethink, true, true, 6, 24, 0, KeenWalkThink, KeenContact, KeenWalkReact, &s_keenwalk1};\r
-\r
-statetype s_keenpogodown  = {KEENPOGOL2SPR, KEENPOGOR2SPR, step, true, false, 1, 0, 0, KeenBounceThink, KeenContact, KeenPogoReact, &s_keenpogo};\r
-statetype s_keenpogo      = {KEENPOGOL2SPR, KEENPOGOR2SPR, think, true, false, 0, 0, 0, KeenPogoThink, KeenContact, KeenPogoReact, &s_keenpogo2};\r
-statetype s_keenpogo2     = {KEENPOGOL1SPR, KEENPOGOR1SPR, think, true, false, 0, 0, 0, KeenPogoThink, KeenContact, KeenPogoReact, NULL};\r
-\r
-statetype s_keenjump1     = {KEENJUMPL1SPR, KEENJUMPR1SPR, think, false, false, 0, 0, 0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjump2};\r
-statetype s_keenjump2     = {KEENJUMPL2SPR, KEENJUMPR2SPR, think, false, false, 0, 0, 0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjump3};\r
-statetype s_keenjump3     = {KEENJUMPL3SPR, KEENJUMPR3SPR, stepthink, false, false, 50, 0, 0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjump4};\r
-statetype s_keenjump4     = {KEENJUMPL2SPR, KEENJUMPR2SPR, stepthink, false, false, 40, 0, 0, KeenAirThink, KeenContact, KeenAirReact, &s_keenjump3};\r
-\r
-statetype s_keenairshoot1 = {KEENJLSHOOTLSPR, KEENJRSHOOTRSPR, stepthink, false, false, 9, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenairshoot2};\r
-statetype s_keenairshoot2 = {KEENJLSHOOTLSPR, KEENJRSHOOTRSPR, stepthink, true, false, 1, 0, 0, KeenShootThink, KeenContact, KeenAirReact, &s_keenairshoot3};\r
-statetype s_keenairshoot3 = {KEENJLSHOOTLSPR, KEENJRSHOOTRSPR, stepthink, false, false, 6, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenjump3};\r
-\r
-statetype s_keenairshootup1 = {KEENJSHOOTUSPR, KEENJSHOOTUSPR, stepthink, false, false, 9, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenairshootup2};\r
-statetype s_keenairshootup2 = {KEENJSHOOTUSPR, KEENJSHOOTUSPR, stepthink, true, false, 1, 0, 0, KeenShootThink, KeenContact, KeenAirReact, &s_keenairshootup3};\r
-statetype s_keenairshootup3 = {KEENJSHOOTUSPR, KEENJSHOOTUSPR, stepthink, false, false, 6, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenjump3};\r
-\r
-statetype s_keenairshootdown1 = {KEENJSHOOTDSPR, KEENJSHOOTDSPR, stepthink, false, false, 9, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenairshootdown2};\r
-statetype s_keenairshootdown2 = {KEENJSHOOTDSPR, KEENJSHOOTDSPR, stepthink, true, false, 1, 0, 0, KeenShootThink, KeenContact, KeenAirReact, &s_keenairshootdown3};\r
-statetype s_keenairshootdown3 = {KEENJSHOOTDSPR, KEENJSHOOTDSPR, stepthink, false, false, 6, 0, 0, T_Projectile, KeenContact, KeenAirReact, &s_keenjump3};\r
-\r
-statetype s_keenholdon  = {KEENHANGLSPR, KEENHANGRSPR, step, false, false, 12, 0, 0, 0, KeenPosContact, KeenSimpleReact, &s_keenholdon2};\r
-statetype s_keenholdon2 = {KEENHANGLSPR, KEENHANGRSPR, think, false, false, 0, 0, 0, KeenHoldThink, KeenPosContact, KeenSimpleReact, NULL};\r
-\r
-statetype s_keenclimbup  = {KEENCLIMBEDGEL1SPR, KEENCLIMBEDGER1SPR, step, false, false, 10, 0, 0, T_PullUp1, KeenPosContact, KeenSimpleReact, &s_keenclimbup2};\r
-statetype s_keenclimbup2 = {KEENCLIMBEDGEL2SPR, KEENCLIMBEDGER2SPR, step, false, false, 10, 0, 0, T_PullUp2, KeenPosContact, KeenSimpleReact, &s_keenclimbup3};\r
-statetype s_keenclimbup3 = {KEENCLIMBEDGEL3SPR, KEENCLIMBEDGER3SPR, step, false, false, 10, 0, 0, T_PullUp3, KeenPosContact, KeenSimpleReact, &s_keenclimbup4};\r
-statetype s_keenclimbup4 = {KEENCLIMBEDGEL4SPR, KEENCLIMBEDGER4SPR, step, false, false, 10, 0, 0, T_PulledUp, KeenPosContact, KeenSimpleReact, &s_keenclimbup5};\r
-statetype s_keenclimbup5 = {KEENSTANDLSPR, KEENSTANDRSPR, step, false, false, 6, 0, 0, 0, KeenPosContact, KeenSimpleReact, &s_keenstand};\r
-\r
-Sint16 slopespeed[8] = {0, 0, 4, 4, 8, -4, -4, -8};\r
-Sint16 polexspeed[3] = {-8, 0, 8};\r
-\r
-Sint16 shotsinclip[4] = {0, 8, 5, 5};\r
-Sint16 bonussound[] = {\r
-       SND_GETKEY,SND_GETKEY,SND_GETKEY,SND_GETKEY,\r
-       SND_GETPOINTS,SND_GETPOINTS,SND_GETPOINTS,\r
-       SND_GETPOINTS,SND_GETPOINTS,SND_GETPOINTS,\r
-       SND_EXTRAKEEN,\r
-       SND_GETAMMO\r
-#ifdef KEEN5\r
-       ,SND_GETKEYCARD\r
-#endif\r
-};\r
-Sint16 bonuspoints[] = {\r
-       0, 0, 0, 0,\r
-       100, 200, 500,\r
-       1000, 2000, 5000,\r
-       0,\r
-       0\r
-#ifdef KEEN5\r
-       ,0\r
-#endif\r
-};\r
-Sint16 bonussprite[] = {\r
-       BONUSGEMSPR, BONUSGEMSPR, BONUSGEMSPR, BONUSGEMSPR,\r
-       BONUS100SPR, BONUS200SPR, BONUS500SPR,\r
-       BONUS1000SPR, BONUS2000SPR, BONUS5000SPR,\r
-       BONUS1UPSPR,\r
-       BONUSCLIPSPR\r
-#ifdef KEEN5\r
-       ,BONUSCARDSPR\r
-#endif\r
-};\r
-\r
-Uint16 zeromap = 0;\r
-\r
-// uninitialized variables:\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                LOCAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-Sint16 jumptime;\r
-Sint32 leavepoletime;\r
-Sint16 moonok;\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                               KEEN\r
-\r
-player->temp1 = pausetime / pointer to zees when sleeping\r
-player->temp2 = pausecount / stagecount\r
-player->temp3 =\r
-player->temp4 =\r
-\r
-=============================================================================\r
-*/\r
-\r
-\r
-/*\r
-===============\r
-=\r
-= SpawnKeen\r
-=\r
-===============\r
-*/\r
-\r
-void SpawnKeen(Sint16 x, Sint16 y, Sint16 dir)\r
-{\r
-       player->obclass = keenobj;\r
-       player->active = ac_allways;\r
-       player->priority = 1;\r
-       player->x = CONVERT_TILE_TO_GLOBAL(x);\r
-       player->y = CONVERT_TILE_TO_GLOBAL(y) - 0xF1;   //TODO: weird\r
-\r
-       player->xdir = dir;\r
-       player->ydir = 1;\r
-       NewState(player, &s_keenstand);\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CheckGrabPole\r
-=\r
-======================\r
-*/\r
-\r
-boolean CheckGrabPole(objtype *ob)\r
-{\r
-       Uint16 far *map;\r
-\r
-//\r
-// kludgy bit to not let you grab a pole the instant you jump off it\r
-//\r
-       if (lasttimecount < leavepoletime)\r
-       {\r
-               leavepoletime = 0;\r
-       }\r
-       else if (lasttimecount-leavepoletime < 19)\r
-       {\r
-               return false;\r
-       }\r
-\r
-       if (c.yaxis == -1)\r
-       {\r
-               map = mapsegs[1] + mapbwidthtable[(ob->top+6*PIXGLOBAL)/TILEGLOBAL]/2;\r
-       }\r
-       else\r
-       {\r
-               map = mapsegs[1] + mapbwidthtable[ob->tilebottom+1]/2;\r
-       }\r
-\r
-       map += ob->tilemidx;\r
-\r
-       if ((tinf[INTILE + *map] & 0x7F) == INTILE_POLE)\r
-       {\r
-               ob->x = CONVERT_TILE_TO_GLOBAL(ob->tilemidx-1) + 8*PIXGLOBAL;\r
-               xtry = 0;\r
-               ytry = c.yaxis * 32;\r
-               ob->needtoclip = cl_noclip;             // can climb through pole holes\r
-               ob->state = &s_keenpole;\r
-               return true;\r
-       }\r
-       return false;\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-======================\r
-=\r
-= CheckEnterHouse\r
-=\r
-= Checks for tiles that Keen can interact with by pressing up\r
-=\r
-======================\r
-*/\r
-\r
-boolean CheckEnterHouse(objtype *ob)\r
-{\r
-       Uint16 temp;\r
-#ifdef KEEN5\r
-       Uint16 infoval;\r
-#endif\r
-       Uint16 intile, intile2;\r
-\r
-       intile = tinf[INTILE + *(mapsegs[1]+mapbwidthtable[ob->tiletop]/2+ob->tilemidx)];\r
-       if (intile == INTILE_SWITCH0 || intile == INTILE_SWITCH1 || intile == INTILE_BRIDGESWITCH)\r
-       {\r
-               temp = CONVERT_TILE_TO_GLOBAL(ob->tilemidx) - 4*PIXGLOBAL;\r
-               if (ob->x != temp)\r
-               {\r
-                       ob->temp1 = temp;\r
-                       ob->state = &s_keenlineup;\r
-               }\r
-               else\r
-               {\r
-                       ob->state = &s_keenswitch;\r
-               }\r
-               upheld = true;\r
-               return true;\r
-       }\r
-       else if (intile == INTILE_DOOR || intile == INTILE_KEYCARDDOOR)\r
-       {\r
-               temp = CONVERT_TILE_TO_GLOBAL(ob->tilemidx) + 6*PIXGLOBAL;\r
-               intile2 = tinf[INTILE + *(mapsegs[1]+mapbwidthtable[ob->tiletop]/2+ob->tilemidx-1)];\r
-               if (intile2 == 2 || intile2 == 32)\r
-                       temp -= TILEGLOBAL;\r
-\r
-               // BUG:\r
-               //\r
-               // The s_keenenter? states rely on Keen's ydir being set to 1,\r
-               // which may not always be the case (e.g. if Keen was pushed off\r
-               // a pole by another actor in the level).\r
-               // If ydir is not 1, Keen will not move up during that animation\r
-               // which means the teleport coordinates won't be read from the\r
-               // intended tile position and Keen might end up teleporting to\r
-               // position 0, 0 in the map and thus win the current level.\r
-               // \r
-               // That can easily be avoided by setting ob->ydir to 1 when\r
-               // changing ob->state to s_keenenter0 or s_keenenter1.\r
-\r
-               if (ob->x != temp)\r
-               {\r
-                       ob->temp1 = temp;\r
-                       ob->state = &s_keenlineup;\r
-               }\r
-#ifdef KEEN5\r
-               else if (intile == INTILE_KEYCARDDOOR)\r
-               {\r
-                       if (gamestate.keycard)\r
-                       {\r
-                               gamestate.keycard = false;\r
-                               SD_PlaySound(SND_OPENCARDDOOR);\r
-                               GetNewObj(false);\r
-                               new->x = ob->tilemidx - 2;\r
-                               new->y = ob->tilebottom - 4;\r
-                               new->active = ac_allways;\r
-                               new->needtoclip = cl_noclip;\r
-                               new->obclass = inertobj;\r
-                               NewState(new, &s_carddoor);\r
-                               // Note: no invincibility here - card doors were always used as level exits in Keen 5\r
-                               ob->state = &s_keenenter0;\r
-                               ob->priority = 0;\r
-                               upheld = true;\r
-                               return true;\r
-                       }\r
-                       else\r
-                       {\r
-                               SD_PlaySound(SND_NOWAY);\r
-                               ob->state = &s_keenstand;\r
-                               upheld = true;\r
-                               return false;\r
-                       }\r
-               }\r
-#endif\r
-               else\r
-               {\r
-                       invincible = 110;       //about 1.57 seconds\r
-                       ob->state = &s_keenenter1;\r
-                       ob->priority = 0;\r
-#ifdef KEEN5\r
-                       {\r
-                               infoval = *(mapsegs[2]+mapbwidthtable[ob->tiletop]/2+ob->tilemidx);\r
-                               if (!infoval)\r
-                                       SpawnTeleport();\r
-                       }\r
-#endif\r
-               }\r
-               upheld = true;\r
-               return true;\r
-       }\r
-       return false;\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-============================\r
-=\r
-= WalkSound1\r
-=\r
-============================\r
-*/\r
-\r
-void WalkSound1(objtype *ob)\r
-{\r
-       SD_PlaySound(SND_WORLDWALK1);\r
-       ob++;                   // shut up compiler\r
-}\r
-\r
-/*\r
-============================\r
-=\r
-= WalkSound2\r
-=\r
-============================\r
-*/\r
-\r
-void WalkSound2(objtype *ob)\r
-{\r
-       SD_PlaySound(SND_WORLDWALK2);\r
-       ob++;                   // shut up compiler\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-============================\r
-=\r
-= KeenStandThink\r
-=\r
-============================\r
-*/\r
-\r
-void KeenStandThink(objtype *ob)\r
-{\r
-#ifdef KEEN5\r
-       if (ob->hitnorth == 25 && ob->state != &s_keenride)\r
-       {\r
-               ob->state = &s_keenride;\r
-       }\r
-#endif\r
-\r
-       if (c.xaxis)\r
-       {\r
-       // started walking\r
-               ob->state = &s_keenwalk1;\r
-               KeenWalkThink(ob);\r
-               xtry = (Sint16)(ob->xdir * ob->state->xmove * tics) / 4;\r
-       }\r
-       else if (firebutton && !fireheld)\r
-       {\r
-       // shoot current xdir\r
-               fireheld = true;\r
-               if (c.yaxis == -1)\r
-               {\r
-                       ob->state = &s_keenshootup1;\r
-               }\r
-               else\r
-               {\r
-                       ob->state = &s_keenshoot1;\r
-               }\r
-       }\r
-       else if (jumpbutton && ! jumpheld)\r
-       {\r
-       // jump straight up\r
-               jumpheld = true;\r
-               SD_PlaySound(SND_JUMP);\r
-               ob->xspeed = 0;\r
-               ob->yspeed = -40;\r
-               ytry = 0;\r
-               jumptime = 18;\r
-               ob->state = &s_keenjump1;\r
-       }\r
-       else if (pogobutton && !pogoheld)\r
-       {\r
-       // get on pogo\r
-               pogoheld = true;\r
-               SD_PlaySound(SND_JUMP);\r
-               ob->state = &s_keenpogodown;\r
-               ob->xspeed = 0;\r
-               ob->yspeed = -48;\r
-               ytry = 0;\r
-               jumptime = 24;\r
-       }\r
-       else\r
-       {\r
-               switch (c.yaxis)\r
-               {\r
-               case -1:\r
-                       if (CheckGrabPole(ob))\r
-                               break;\r
-                       if (upheld || !CheckEnterHouse(ob))\r
-                       {\r
-                               ob->state = &s_keenlookup;\r
-                       }\r
-                       break;\r
-               case 1:\r
-                       if (CheckGrabPole(ob))\r
-                               break;\r
-                       ob->state = &s_keenlookdown;\r
-               }\r
-               return;\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenPauseThink\r
-=\r
-= Do special animations in time\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenPauseThink(objtype *ob)\r
-{\r
-#ifdef KEEN5\r
-       if (ob->hitnorth == 25 && ob->state != &s_keenride)\r
-       {\r
-               ob->state = &s_keenride;\r
-       }\r
-#endif\r
-\r
-       if (c.dir != dir_None || jumpbutton || pogobutton || firebutton)\r
-       {\r
-               ob->temp1 = ob->temp2 = 0;                      // not paused any more\r
-               ob->state = &s_keenstand;\r
-               KeenStandThink(ob);\r
-       }\r
-       else\r
-       {\r
-               //only increase idle counter when NOT standing on a sprite:\r
-               if ((ob->hitnorth & ~7) != 0x18)\r
-                       ob->temp1 = ob->temp1 + tics;\r
-\r
-               switch (ob->temp2)\r
-               {\r
-               case 0:\r
-                       if (ob->temp1 > 200)\r
-                       {\r
-                               ob->temp2++;\r
-                               ob->state = &s_keenpauselook;\r
-                               ob->temp1 = 0;\r
-                       }\r
-                       break;\r
-               case 1:\r
-                       if (ob->temp1 > 300)\r
-                       {\r
-                               ob->temp2++;\r
-                               ob->temp1 = 0;\r
-#ifdef KEEN4\r
-                               if (moonok == 1)\r
-                               {\r
-                                       moonok = 2;     //don't moon again unless the level is restarted\r
-                                       ob->state = &s_keenmoon1;\r
-                               }\r
-                               else\r
-#endif\r
-                               {\r
-                                       ob->state = &s_keenwait1;\r
-                               }\r
-                       }\r
-                       break;\r
-               case 2:\r
-                       if (ob->temp1 > 700)\r
-                       {\r
-                               ob->temp2++;\r
-                               ob->state = &s_keenread;\r
-                               ob->temp1 = 0;\r
-                       }\r
-                       break;\r
-               }\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenReadThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenReadThink(objtype *ob)\r
-{\r
-       if (storedemo)\r
-       {\r
-               playstate = ex_abortgame;\r
-               IN_ClearKeysDown();\r
-       }\r
-       if (c.dir != dir_None || jumpbutton || pogobutton)\r
-       {\r
-               ob->temp1 = ob->temp2 = 0;\r
-               ob->state = &s_keenstopread;\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenLookUpThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenLookUpThink(objtype *ob)\r
-{\r
-       if (c.yaxis != -1 || c.xaxis\r
-               || (jumpbutton && !jumpheld)\r
-               || (pogobutton && !pogoheld)\r
-               || firebutton)\r
-       {\r
-               ob->state = &s_keenstand;\r
-               KeenStandThink(ob);\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenLookDownThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenLookDownThink(objtype *ob)\r
-{\r
-       Uint16 far *map;\r
-       Sint16 y, ymove;\r
-       Uint16 tile;\r
-\r
-       if (jumpbutton && ! jumpheld && (ob->hitnorth & 7) == 1)\r
-       {\r
-       //\r
-       // drop down a level\r
-       //\r
-               jumpheld = true;\r
-\r
-               y = ob->tilebottom;\r
-               map = (Uint16 far *)mapsegs[1] + mapbwidthtable[y]/2 + ob->tilemidx;\r
-               tile = *map;\r
-               if (tinf[WESTWALL+tile] || tinf[EASTWALL+tile] || tinf[SOUTHWALL+tile])\r
-                       return;                         // wall prevents drop down\r
-\r
-               map += mapwidth;\r
-               tile = *map;\r
-               if (tinf[WESTWALL+tile] || tinf[EASTWALL+tile] || tinf[SOUTHWALL+tile])\r
-                       return;                         // wall prevents drop down\r
-\r
-               ymove = max(4, tics) * PIXGLOBAL;\r
-               if (gamestate.riding)\r
-                       ymove += gamestate.riding->ymove;\r
-               ob->bottom += ymove;\r
-               gamestate.riding = NULL;\r
-               ob->y += ymove;\r
-               xtry = ytry = 0;\r
-               ob->state = &s_keenjump3;\r
-               ob->xspeed = ob->yspeed = 0;\r
-               SD_PlaySound(SND_PLUMMET);\r
-       }\r
-       else if (c.yaxis != 1 || c.xaxis\r
-               || (jumpbutton && !jumpheld)\r
-               || (pogobutton && !pogoheld))\r
-       {\r
-               ob->state = &s_keenlookdown4;\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenWalkThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenWalkThink(objtype *ob)\r
-{\r
-       Sint16 xmove;\r
-\r
-       if (c.xaxis == 0)\r
-       {\r
-       //\r
-       // stopped running\r
-       //\r
-               ob->state = &s_keenstand;\r
-               KeenStandThink(ob);\r
-               return;\r
-       }\r
-\r
-       ob->xdir = c.xaxis;\r
-\r
-       switch (c.yaxis)\r
-       {\r
-       case -1:\r
-               if (CheckGrabPole(ob))\r
-                       return;\r
-               if (upheld)\r
-                       return;\r
-               if (!CheckEnterHouse(ob))\r
-                       break;;\r
-               return;\r
-\r
-       case 1:\r
-               if (!CheckGrabPole(ob))\r
-                       break;\r
-               return;\r
-       }\r
-\r
-       if (firebutton && !fireheld)\r
-       {\r
-       //\r
-       // shoot\r
-       //\r
-               fireheld = true;\r
-               if (c.yaxis == -1)\r
-               {\r
-                       ob->state = &s_keenshootup1;\r
-               }\r
-               else\r
-               {\r
-                       ob->state = &s_keenshoot1;\r
-               }\r
-               return;\r
-       }\r
-\r
-       if (jumpbutton && !jumpheld)\r
-       {\r
-       //\r
-       // running jump\r
-       //\r
-               jumpheld = true;\r
-               SD_PlaySound(SND_JUMP);\r
-               ob->xspeed = ob->xdir * 16;\r
-               ob->yspeed = -40;\r
-               xtry = ytry = 0;\r
-               jumptime = 18;\r
-               ob->state = &s_keenjump1;\r
-       }\r
-\r
-       if (pogobutton && !pogoheld)\r
-       {\r
-       //\r
-       // get on pogo\r
-       //\r
-               pogoheld = true;\r
-               ob->state = &s_keenpogodown;\r
-               SD_PlaySound(SND_JUMP);\r
-               ob->xspeed = ob->xdir * 16;\r
-               ob->yspeed = -48;\r
-               xtry = 0;\r
-               jumptime = 24;\r
-               return;\r
-       }\r
-\r
-       //\r
-       // give speed for slopes\r
-       //\r
-       xmove = slopespeed[ob->hitnorth & 7] * tics;\r
-       xtry += xmove;\r
-\r
-       //\r
-       // handle walking sounds\r
-       //\r
-       if (ob->state == &s_keenwalk1 && ob->temp3 == 0)\r
-       {\r
-               SD_PlaySound(SND_WORLDWALK1);\r
-               ob->temp3 = 1;\r
-       }\r
-       else if (ob->state == &s_keenwalk3 && ob->temp3 == 0)\r
-       {\r
-               SD_PlaySound(SND_WORLDWALK2);\r
-               ob->temp3 = 1;\r
-       }\r
-       else if (ob->state == &s_keenwalk2 ||ob->state == &s_keenwalk4)\r
-       {\r
-               ob->temp3 = 0;\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= T_LineUp\r
-=\r
-= Lines up Keen's position for interacting with tiles (temp1 is desired x)\r
-=\r
-=======================\r
-*/\r
-\r
-void T_LineUp(objtype *ob)\r
-{\r
-       Sint16 xmove;\r
-\r
-       xmove = ob->temp1 - ob->x;\r
-       if (xmove < 0)\r
-       {\r
-               xtry = xtry - tics * 16;\r
-               if (xtry > xmove)\r
-                       return;\r
-       }\r
-       else if (xmove > 0)\r
-       {\r
-               xtry = xtry + tics * 16;\r
-               if (xtry < xmove)\r
-                       return;\r
-       }\r
-       xtry = xmove;\r
-       ob->temp1 = 0;\r
-       if (!CheckEnterHouse(ob))\r
-               ob->state = &s_keenstand;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenEnterThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenEnterThink(objtype *ob)\r
-{\r
-       Uint16 info;\r
-       Uint16 far *map;\r
-\r
-       map = mapsegs[2] + mapbwidthtable[ob->tilebottom]/2 + ob->tileleft;\r
-       info = *map;\r
-#ifdef KEEN5\r
-       if (!info)\r
-       {\r
-               playstate = ex_portout;\r
-               ob->state = &s_keenenter6;\r
-               return;\r
-       }\r
-       else if (info == 0xB1B1)\r
-       {\r
-               playstate = ex_completed;\r
-               ob->state = &s_keenenter6;\r
-               return;\r
-       }\r
-#endif\r
-       ob->y = (CONVERT_TILE_TO_GLOBAL(info & 0xFF) - TILEGLOBAL) + 15;\r
-       ob->x = CONVERT_TILE_TO_GLOBAL(info >> 8);\r
-       ob->priority = 1;\r
-       ob->needtoclip = cl_noclip;\r
-       ChangeState(ob, ob->state->nextstate);\r
-       ob->needtoclip = cl_midclip;\r
-       CenterActor(ob);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenSwitchThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenSwitchThink(objtype *ob)\r
-{\r
-       Uint16 intile, maptile, newtile, info, sx, sy, tileoff;\r
-       Uint16 far *map;\r
-       Uint16 tile, x, y;\r
-       Sint8 manim;\r
-\r
-       tileoff = mapbwidthtable[ob->tiletop]/2 + ob->tilemidx;\r
-       maptile = mapsegs[1][tileoff];\r
-       newtile = maptile + (Sint8)tinf[MANIM + maptile];\r
-       info = mapsegs[2][tileoff];\r
-       sx = info >> 8;\r
-       sy = info & 0xFF;\r
-       intile = tinf[INTILE + maptile];\r
-\r
-       RF_MemToMap(&newtile, 1, ob->tilemidx, ob->tiletop, 1, 1);\r
-       SD_PlaySound(SND_USESWITCH);\r
-       if (intile == INTILE_BRIDGESWITCH)\r
-       {\r
-               //toggle bridge:\r
-               for (y = sy; sy+2 > y; y++)\r
-               {\r
-                       map = mapsegs[1] + mapbwidthtable[y]/2 + sx - (y != sy);\r
-                       for (x = sx - (y != sy); x < mapwidth; x++)\r
-                       {\r
-                               tile = *(map++);\r
-                               manim = tinf[MANIM + tile];\r
-                               if (!manim)\r
-                                       break;\r
-\r
-                               tile += manim;\r
-                               RF_MemToMap(&tile, 1, x, y, 1, 1);\r
-                       }\r
-               }\r
-       }\r
-       else\r
-       {\r
-               //toggle platform blocker:\r
-               map = mapsegs[2] + mapbwidthtable[sy]/2 + sx;\r
-               tile = *map;\r
-#ifdef KEEN5\r
-               if (tile >= DIRARROWSTART && tile < DIRARROWEND)\r
-               {\r
-                       *map = arrowflip[tile-DIRARROWSTART]+DIRARROWSTART;\r
-                       return;\r
-               }\r
-#endif\r
-               *map = tile ^ PLATFORMBLOCK;\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenKeyThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenKeyThink(objtype *ob)\r
-{\r
-       Uint16 newtile, info, x, y, tileoff;\r
-       Uint16 far *map;\r
-       Uint16 tile, h;\r
-\r
-       tileoff = mapbwidthtable[ob->tilebottom]/2 + ob->tilemidx;\r
-       newtile = mapsegs[1][tileoff] + 18;\r
-       info = mapsegs[2][tileoff];\r
-       x = info >> 8;\r
-       y = info & 0xFF;\r
-       RF_MemToMap(&newtile, 1, ob->tilemidx, ob->tilebottom, 1, 1);\r
-       SD_PlaySound(SND_OPENDOOR);\r
-       GetNewObj(false);\r
-       new->x = x;\r
-       new->y = y;\r
-\r
-       if (x > mapwidth || x < 2 || y > mapheight || y < 2)\r
-               Quit("Keyholder points to a bad spot!");\r
-\r
-       map = mapsegs[1] + mapbwidthtable[y]/2 + x;\r
-       tile = *map;\r
-       h = 1;\r
-       map += mapwidth;\r
-       while (*map == tile)\r
-       {\r
-                       h++;\r
-                       map += mapwidth;\r
-       }\r
-       new->temp1 = h;\r
-       new->active = ac_allways;\r
-       new->needtoclip = cl_noclip;\r
-       new->obclass = inertobj;\r
-       NewState(new, &s_door1);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenAirThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenAirThink(objtype *ob)\r
-{\r
-       if (jumpcheat && jumpbutton)\r
-       {\r
-               ob->yspeed = -40;\r
-               jumptime = 18;\r
-               jumpheld = true;\r
-       }\r
-       if (jumptime)\r
-       {\r
-               if (jumptime <= tics)\r
-               {\r
-                       ytry = ob->yspeed * jumptime;\r
-                       jumptime = 0;\r
-               }\r
-               else\r
-               {\r
-                       ytry = ob->yspeed * tics;\r
-                       if (!jumpcheat)\r
-                               jumptime = jumptime - tics;\r
-               }\r
-               if (!jumpbutton)\r
-                       jumptime = 0;\r
-\r
-               if (jumptime == 0 && ob->state->nextstate)\r
-                       ob->state = ob->state->nextstate;       // switch to second jump stage\r
-       }\r
-       else\r
-       {\r
-               if (gamestate.difficulty == gd_Easy)\r
-               {\r
-                       DoWeakGravity(ob);\r
-               }\r
-               else\r
-               {\r
-                       DoGravity(ob);\r
-               }\r
-               if (ob->yspeed > 0 && ob->state != &s_keenjump3 && ob->state != &s_keenjump4)\r
-               {\r
-                       ob->state = ob->state->nextstate;       // switch to third jump stage\r
-               }\r
-       }\r
-\r
-//-------------\r
-\r
-       if (c.xaxis)\r
-       {\r
-               ob->xdir = c.xaxis;\r
-               AccelerateX(ob, c.xaxis*2, 24);\r
-       }\r
-       else\r
-       {\r
-               FrictionX(ob);\r
-       }\r
-\r
-       if (ob->hitsouth == 17)         // going through a pole hole\r
-       {\r
-               ob->xspeed = xtry = 0;\r
-       }\r
-\r
-       if (firebutton && !fireheld)\r
-       {\r
-               fireheld = true;\r
-       //\r
-       // shoot\r
-       //\r
-               switch (c.yaxis)\r
-               {\r
-               case -1:\r
-                       ob->state = &s_keenairshootup1;\r
-                       return;\r
-               case 0:\r
-                       ob->state = &s_keenairshoot1;\r
-                       return;\r
-               case 1:\r
-                       ob->state = &s_keenairshootdown1;\r
-                       return;\r
-               }\r
-       }\r
-\r
-       if (pogobutton && !pogoheld)\r
-       {\r
-               pogoheld = true;\r
-               ob->state = &s_keenpogo;\r
-               jumptime = 0;\r
-               return;\r
-       }\r
-\r
-       if (c.yaxis == -1)\r
-               CheckGrabPole(ob);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenBounceThink\r
-=\r
-= Gives an extra bit of height on the first pogo bounce and creates\r
-= the "impossible pogo trick" when the jump key is held down\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenBounceThink(objtype *ob)\r
-{\r
-       ob->yspeed = -48;\r
-       ytry = ob->yspeed * 6;\r
-       jumptime = 24;\r
-       SD_PlaySound(SND_POGOBOUNCE);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenPogoThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenPogoThink(objtype *ob)\r
-{\r
-       if (jumptime)\r
-       {\r
-               if (jumpbutton || jumptime <= 9)\r
-               {\r
-                       DoTinyGravity(ob);\r
-               }\r
-               else\r
-               {\r
-                       DoGravity(ob);\r
-               }\r
-               if (jumptime <= tics)\r
-               {\r
-                       jumptime = 0;\r
-               }\r
-               else\r
-               {\r
-                       jumptime = jumptime - tics;\r
-               }\r
-               if (jumptime == 0 && ob->state->nextstate)\r
-                       ob->state = ob->state->nextstate;\r
-       }\r
-       else\r
-       {\r
-               if (gamestate.difficulty == gd_Easy)\r
-               {\r
-                       DoWeakGravity(ob);\r
-               }\r
-               else\r
-               {\r
-                       DoGravity(ob);\r
-               }\r
-       }\r
-\r
-       if (c.xaxis)\r
-       {\r
-               if (ob->xspeed == 0)\r
-                       ob->xdir = c.xaxis;\r
-               AccelerateX(ob, c.xaxis, 24);\r
-       }\r
-       else\r
-       {\r
-               xtry = xtry + ob->xspeed * tics;\r
-               if (ob->xspeed > 0)\r
-               {\r
-                       ob->xdir = 1;\r
-               }\r
-               else if (ob->xspeed < 0)\r
-               {\r
-                       ob->xdir = -1;\r
-               }\r
-       }\r
-\r
-       if (ob->hitsouth == 17)         // going through a pole hole\r
-       {\r
-               ob->xspeed = xtry = 0;\r
-       }\r
-\r
-       if (firebutton && !fireheld)\r
-       {\r
-               fireheld = true;\r
-               switch (c.yaxis)\r
-               {\r
-               case -1:\r
-                       ob->state = &s_keenairshootup1;\r
-                       return;\r
-               case 0:\r
-                       ob->state = &s_keenairshoot1;\r
-                       return;\r
-               case 1:\r
-                       ob->state = &s_keenairshootdown1;\r
-                       return;\r
-               }\r
-       }\r
-\r
-       if (pogobutton && !pogoheld)\r
-       {\r
-               pogoheld = true;\r
-               ob->state = &s_keenjump3;\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= PoleActions\r
-=\r
-=======================\r
-*/\r
-\r
-void PoleActions(objtype *ob)\r
-{\r
-       if (c.xaxis)\r
-               ob->xdir = c.xaxis;\r
-\r
-       if (firebutton && !fireheld)\r
-       {\r
-               fireheld = true;\r
-               switch (c.yaxis)\r
-               {\r
-               case -1:\r
-                       ob->state = &s_keenpoleshootup1;\r
-                       break;\r
-               case 0:\r
-                       ob->state = &s_keenpoleshoot1;\r
-                       break;\r
-               case 1:\r
-                       ob->state = &s_keenpoleshootdown1;\r
-                       break;\r
-               }\r
-       }\r
-\r
-       if (jumpbutton && !jumpheld)            // jump off the pole\r
-       {\r
-               jumpheld = true;\r
-               SD_PlaySound(SND_JUMP);\r
-               ob->xspeed = polexspeed[c.xaxis+1];\r
-               ob->yspeed = -20;\r
-               ob->needtoclip = cl_midclip;\r
-               jumptime = 10;\r
-               ob->state = &s_keenjump1;\r
-               ob->ydir = 1;\r
-               leavepoletime = lasttimecount;\r
-       }\r
-}\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenPoleThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenPoleThink(objtype *ob)\r
-{\r
-       Uint16 tile;\r
-       Uint16 far *map;\r
-\r
-       switch (c.yaxis)\r
-       {\r
-       case -1:\r
-               ob->state = &s_keenclimb1;\r
-               ob->ydir = -1;\r
-               return;\r
-       case 1:\r
-               ob->state = &s_keenslide1;\r
-               ob->ydir = 1;\r
-               KeenDropThink(ob);\r
-               return;\r
-       }\r
-\r
-       if (c.xaxis)\r
-       {\r
-       //\r
-       // walk off pole if right next to ground\r
-       //\r
-               map = mapsegs[1] + (mapbwidthtable[ob->tilebottom+1]/2 + ob->tilemidx);\r
-               tile = *map;\r
-               if (tinf[NORTHWALL+tile])\r
-               {\r
-                       ob->xspeed = 0;\r
-                       ob->yspeed = 0;\r
-                       ob->needtoclip = cl_midclip;\r
-                       jumptime = 0;\r
-                       ob->state = &s_keenjump3;\r
-                       ob->ydir = 1;\r
-                       SD_PlaySound(SND_PLUMMET);\r
-                       return;\r
-               }\r
-       }\r
-       PoleActions(ob);\r
-}\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenClimbThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenClimbThink(objtype *ob)\r
-{\r
-       Uint16 far *map;\r
-\r
-       map = mapsegs[1] + mapbwidthtable[ob->tiletop]/2 + ob->tilemidx;\r
-       \r
-       if ((tinf[INTILE+*map] & 0x7F) != INTILE_POLE)\r
-       {\r
-               ytry = 0;\r
-               ob->state = &s_keenpole;                // ran out of pole\r
-               PoleActions(ob);\r
-               return;\r
-       }\r
-\r
-       switch (c.yaxis)\r
-       {\r
-       case 0:\r
-               ob->state = &s_keenpole;\r
-               ob->ydir = 0;\r
-               break;\r
-\r
-       case 1:\r
-               ob->state = &s_keenslide1;\r
-               ob->ydir = 1;\r
-               KeenDropThink(ob);\r
-               break;\r
-       }\r
-\r
-       PoleActions(ob);\r
-}\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenDropThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenDropThink(objtype *ob)\r
-{\r
-       Uint16 far *map;\r
-       Uint16 y;\r
-\r
-       y = CONVERT_GLOBAL_TO_TILE(ob->bottom - 4*PIXGLOBAL);\r
-       map = mapsegs[1] + mapbwidthtable[y]/2 + ob->tilemidx;\r
-\r
-       if ((tinf[INTILE+*map] & 0x7F) != INTILE_POLE)\r
-       {\r
-               SD_PlaySound(SND_PLUMMET);\r
-               ob->state = &s_keenjump3;               // ran out of pole\r
-               jumptime = 0;\r
-               ob->xspeed = polexspeed[c.xaxis+1];\r
-               ob->yspeed = 0;\r
-               ob->needtoclip = cl_midclip;\r
-               ob->tilebottom--;\r
-               return;\r
-       }\r
-\r
-       switch (c.yaxis)\r
-       {\r
-       case -1:\r
-               ob->state = &s_keenclimb1;\r
-               ob->ydir = -1;\r
-               break;\r
-\r
-       case 0:\r
-               ob->state = &s_keenpole;\r
-               ob->ydir = 0;\r
-               break;\r
-       }\r
-\r
-       PoleActions(ob);\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenDropDownThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenDropDownThink(objtype *ob)\r
-{\r
-       ob->needtoclip = cl_midclip;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenHoldThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenHoldThink(objtype *ob)\r
-{\r
-       Uint16 tile;\r
-\r
-       if (c.yaxis == -1 || ob->xdir == c.xaxis)\r
-       {\r
-               ob->state = &s_keenclimbup;\r
-               if (ob->xdir == 1)\r
-               {\r
-                       tile = *(mapsegs[1]+mapbwidthtable[ob->tiletop-1]/2+ob->tileright);\r
-               }\r
-               else\r
-               {\r
-                       tile = *(mapsegs[1]+mapbwidthtable[ob->tiletop-1]/2+ob->tileleft);\r
-               }\r
-               if (ob->xdir == 1)\r
-               {\r
-                       ytry = -16*PIXGLOBAL;\r
-               }\r
-               else\r
-               {\r
-                       ytry = -8*PIXGLOBAL;\r
-               }\r
-               if (!(tinf[INTILE+tile] & INTILE_FOREGROUND))\r
-                       ob->priority = 3;\r
-       }\r
-       else if (c.yaxis == 1 || c.xaxis && ob->xdir != c.xaxis)\r
-       {\r
-               ob->state = &s_keenjump3;\r
-               ob->needtoclip = cl_midclip;\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenShootThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenShootThink(objtype *ob)\r
-{\r
-// can't use &<var> in a switch statement...\r
-\r
-       if (ob->state == &s_keenshoot1)\r
-       {\r
-               if (ob->xdir == 1)\r
-               {\r
-                       SpawnShot(ob->x + 16*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_East);\r
-               }\r
-               else\r
-               {\r
-                       SpawnShot(ob->x - 8*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_West);\r
-               }\r
-       }\r
-       if (ob->state == &s_keenairshoot2)\r
-       {\r
-               if (ob->xdir == 1)\r
-               {\r
-                       SpawnShot(ob->x + 16*PIXGLOBAL, ob->y + 2*PIXGLOBAL, dir_East);\r
-               }\r
-               else\r
-               {\r
-                       SpawnShot(ob->x, ob->y + 2*PIXGLOBAL, dir_West);\r
-               }\r
-       }\r
-       if (ob->state == &s_keenairshootdown2)\r
-       {\r
-               SpawnShot(ob->x + 8*PIXGLOBAL, ob->y + 18*PIXGLOBAL, dir_South);\r
-       }\r
-       if (ob->state == &s_keenairshootup2)\r
-       {\r
-               SpawnShot(ob->x + 5*PIXGLOBAL, ob->y - 10*PIXGLOBAL, dir_North);\r
-       }\r
-       if (ob->state == &s_keenshootup1)\r
-       {\r
-               SpawnShot(ob->x + 5*PIXGLOBAL, ob->y - 10*PIXGLOBAL, dir_North);\r
-       }\r
-       if (ob->state == &s_keenpoleshoot1)\r
-       {\r
-               if (ob->xdir == 1)\r
-               {\r
-                       SpawnShot(ob->x + 16*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_East);\r
-               }\r
-               else\r
-               {\r
-                       SpawnShot(ob->x - 8*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_West);\r
-               }\r
-       }\r
-       if (ob->state == &s_keenpoleshootup1)\r
-       {\r
-               if (ob->xdir == 1)\r
-               {\r
-                       SpawnShot(ob->x + 6*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_North);\r
-               }\r
-               else\r
-               {\r
-                       SpawnShot(ob->x + 12*PIXGLOBAL, ob->y + 4*PIXGLOBAL, dir_North);\r
-               }\r
-       }\r
-       if (ob->state == &s_keenpoleshootdown1)\r
-       {\r
-               if (ob->xdir == 1)\r
-               {\r
-                       SpawnShot(ob->x + 6*PIXGLOBAL, ob->y + 24*PIXGLOBAL, dir_South);\r
-               }\r
-               else\r
-               {\r
-                       SpawnShot(ob->x + 12*PIXGLOBAL, ob->y + 24*PIXGLOBAL, dir_South);\r
-               }\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= T_PullUp1\r
-=\r
-=======================\r
-*/\r
-\r
-void T_PullUp1(objtype *ob)\r
-{\r
-       if (ob->xdir == 1)\r
-       {\r
-               xtry = 8*PIXGLOBAL;\r
-       }\r
-       else\r
-       {\r
-               ytry = -8*PIXGLOBAL;\r
-       }\r
-}\r
-\r
-/*\r
-=======================\r
-=\r
-= T_PullUp2\r
-=\r
-=======================\r
-*/\r
-\r
-void T_PullUp2(objtype *ob)\r
-{\r
-       if (ob->xdir == 1)\r
-       {\r
-               xtry = 8*PIXGLOBAL;\r
-               ytry = -8*PIXGLOBAL;\r
-       }\r
-       else\r
-       {\r
-               xtry = -8*PIXGLOBAL;\r
-               ytry = -8*PIXGLOBAL;\r
-       }\r
-}\r
-\r
-/*\r
-=======================\r
-=\r
-= T_PullUp3\r
-=\r
-=======================\r
-*/\r
-\r
-#pragma argsused\r
-void T_PullUp3(objtype *ob)\r
-{\r
-       ytry = -8*PIXGLOBAL;\r
-}\r
-\r
-/*\r
-=======================\r
-=\r
-= T_PulledUp\r
-=\r
-=======================\r
-*/\r
-\r
-void T_PulledUp(objtype *ob)\r
-{\r
-       ob->needtoclip = cl_midclip;\r
-       ob->priority = 1;\r
-       ytry = 8*PIXGLOBAL;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=======================\r
-=\r
-= KeenDieThink\r
-=\r
-=======================\r
-*/\r
-\r
-void KeenDieThink(objtype *ob)\r
-{\r
-       DoWeakGravity(ob);\r
-       xtry = ob->xspeed * tics;\r
-       if (!OnScreen(ob))\r
-               playstate = ex_died;\r
-}\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                               CONTACT ROUTINES\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*\r
-============================\r
-=\r
-= KillKeen\r
-=\r
-============================\r
-*/\r
-\r
-void KillKeen(void)\r
-{\r
-       if (invincible || godmode)\r
-               return;\r
-\r
-       if (player->state != &s_keendead)\r
-       {\r
-\r
-               moonok = 0;\r
-               invincible = 30;        //0.43 seconds\r
-               keenkilled = true;\r
-               player->needtoclip = cl_noclip;\r
-               player->priority = 3;\r
-#ifdef KEEN4\r
-               if (mapon == 17)\r
-               {\r
-                       if (US_RndT() < 0x80)\r
-                       {\r
-                               ChangeState(player, &s_keensuitdie1);\r
-                       }\r
-                       else\r
-                       {\r
-                               ChangeState(player, &s_keensuitdie2);\r
-                       }\r
-               }\r
-               else\r
-#endif\r
-               {\r
-                       if (US_RndT() < 0x80)\r
-                       {\r
-                               ChangeState(player, &s_keendie1);\r
-                       }\r
-                       else\r
-                       {\r
-                               ChangeState(player, &s_keendie2);\r
-                       }\r
-               }\r
-               SD_PlaySound(SND_KEENDEAD);\r
-               player->yspeed = -40;\r
-               player->xspeed = 16;\r
-       }\r
-}\r
-\r
-/*\r
-============================\r
-=\r
-= KeenContact\r
-=\r
-============================\r
-*/\r
-\r
-void KeenContact(objtype *ob, objtype *hit)\r
-{\r
-       switch (hit->obclass)\r
-       {\r
-       case bonusobj:\r
-               switch (hit->temp1)\r
-               {\r
-               case 0:\r
-               case 1:\r
-               case 2:\r
-               case 3:\r
-               case 4:\r
-               case 5:\r
-               case 6:\r
-               case 7:\r
-               case 8:\r
-               case 9:\r
-               case 10:\r
-               case 11:\r
-#ifdef KEEN5\r
-               case 12:\r
-#endif\r
-                       SD_PlaySound(bonussound[hit->temp1]);\r
-                       hit->obclass = inertobj;\r
-                       hit->priority = 3;\r
-                       hit->shapenum = bonussprite[hit->temp1];\r
-                       GivePoints(bonuspoints[hit->temp1]);\r
-                       if (hit->temp1 < 4)\r
-                       {\r
-                               gamestate.keys[hit->temp1]++;\r
-                       }\r
-                       else if (hit->temp1 == 10)\r
-                       {\r
-                               gamestate.lives++;\r
-                       }\r
-                       else if (hit->temp1 == 11)\r
-                       {\r
-                               gamestate.ammo += shotsinclip[gamestate.difficulty];\r
-                       }\r
-#ifdef KEEN5\r
-                       else if (hit->temp1 == 12)\r
-                       {\r
-                               gamestate.keycard = true;\r
-                       }\r
-#endif\r
-                       ChangeState(hit, &s_bonusrise);\r
-               }\r
-               break;\r
-\r
-#if defined KEEN4\r
-       case oracleobj:\r
-               if (!ob->hitnorth)\r
-                       break;\r
-\r
-               if (mapon == 14)\r
-               {\r
-                       RescueJanitor();\r
-                       RF_ForceRefresh();\r
-                       RemoveObj(hit);\r
-               }\r
-               else\r
-               {\r
-                       SD_PlaySound(SND_LINDSEY);\r
-                       playstate = ex_rescued;\r
-               }\r
-               break;\r
-       case stunnedobj:\r
-               if (hit->temp4 != bounderobj)\r
-                       break;\r
-               //no break here -- drop through to platformobj is intended!\r
-       case platformobj:\r
-               if (!gamestate.riding)\r
-               {\r
-                       ClipToSpriteTop(ob, hit);\r
-               }\r
-               else\r
-                       return;\r
-               break;\r
-       case bounderobj:\r
-               ClipToSprite(ob, hit, false);\r
-               break;\r
-       case lindseyobj:\r
-               PrincessLindsey();\r
-               RemoveObj(hit);\r
-               RF_ForceRefresh();\r
-               break;\r
-       case footobj:\r
-               playstate = ex_foot;\r
-               break;\r
-#elif defined KEEN5\r
-       case platformobj:\r
-               if (!gamestate.riding)\r
-                       ClipToSpriteTop(ob, hit);\r
-               break;\r
-#elif defined KEEN6\r
-       case stunshotobj:\r
-               if (hit->temp4)\r
-               {\r
-                       ExplodeShot(hit);\r
-                       ChangeState(ob, &s_keenstun);\r
-               }\r
-               // BUG: there is no break here - this causes the impossible bullet bug\r
-       case platformobj:\r
-               if (!gamestate.riding)\r
-                       ClipToSpriteTop(ob, hit);\r
-               break;\r
-#endif\r
-       }\r
-}\r
-\r
-/*\r
-============================\r
-=\r
-= KeenPosContact\r
-=\r
-============================\r
-*/\r
-\r
-void KeenPosContact(objtype *ob, objtype *hit)\r
-{\r
-       switch (hit->obclass)\r
-       {\r
-#if defined KEEN4\r
-       case platformobj:\r
-               // BUG: priority is not reset here\r
-               ob->needtoclip = cl_midclip;\r
-               ChangeState(ob, &s_keenjump3);\r
-               jumptime = ob->xspeed = ob->yspeed = 0;\r
-               ClipToSpriteTop(ob, hit);\r
-               break;\r
-       case madmushroomobj:\r
-       case arachnutobj:\r
-       case berkeloidobj:\r
-               KillKeen();\r
-               break;\r
-       case bounderobj:\r
-               ob->priority = 1;\r
-               ob->needtoclip = cl_midclip;\r
-               ChangeState(ob, &s_keenjump3);\r
-               jumptime = ob->xspeed = ob->yspeed = 0;\r
-               ClipToSprite(ob, hit, false);\r
-               break;\r
-#elif defined KEEN5\r
-       case platformobj:\r
-               // BUG: priority is not reset here\r
-               ob->needtoclip = cl_midclip;\r
-               ChangeState(ob, &s_keenjump3);\r
-               jumptime = ob->xspeed = ob->yspeed = 0;\r
-               ClipToSpriteTop(ob, hit);\r
-               break;\r
-       case amptonobj:\r
-       case scottieobj:\r
-               ob->priority = 1;\r
-               ob->needtoclip = cl_midclip;\r
-               ChangeState(ob, &s_keenjump3);\r
-               jumptime = ob->xspeed = ob->yspeed = 0;\r
-               break;\r
-#elif defined KEEN6\r
-       case platformobj:\r
-       case gikobj:\r
-       case flectobj:\r
-       case bloogletobj:\r
-               ob->priority = 1;\r
-               ob->needtoclip = cl_midclip;\r
-               ChangeState(ob, &s_keenjump3);\r
-               jumptime = ob->xspeed = ob->yspeed = 0;\r
-               ClipToSpriteTop(ob, hit);       // BUG: allows Keen to stand on Blooglets and Flects\r
-               break;\r
-#endif\r
-       }\r
-}\r
-\r
-/*\r
-============================\r
-=\r
-= HandleRiding\r
-=\r
-============================\r
-*/\r
-\r
-void HandleRiding(objtype *ob)\r
-{\r
-       objtype *plat;\r
-\r
-       plat = gamestate.riding;\r
-       if (ob->right < plat->left || ob->left > plat->right)\r
-       {\r
-               gamestate.riding = NULL;\r
-       }\r
-       else if (ob->ymove < 0)\r
-       {\r
-               gamestate.riding = NULL;\r
-               if (plat->ymove < 0)\r
-               {\r
-                       xtry = 0;\r
-                       ytry = plat->ymove;\r
-                       PushObj(ob);\r
-               }\r
-       }\r
-       else\r
-       {\r
-               xtry = plat->xmove;\r
-               ytry = plat->top - ob->bottom - 16;\r
-               PushObj(ob);\r
-\r
-#if GRMODE == CGAGR\r
-               if (ob->xmove == plat->xmove)\r
-               {\r
-                       ob->x &= ~0x3F;\r
-                       ob->x |= plat->x & 0x3F;\r
-               }\r
-#else\r
-               if (nopan)\r
-               {\r
-                       ob->x &= ~0x7F;\r
-                       ob->x |= plat->x & 0x7F;\r
-               }\r
-               else\r
-               {\r
-                       ob->x |= plat->x & 0x1F;\r
-               }\r
-#endif\r
-\r
-               if (ob->hitsouth)\r
-               {\r
-                       gamestate.riding = NULL;\r
-               }\r
-               else\r
-               {\r
-                       ob->hitnorth = 25;\r
-               }\r
-       }\r
-}\r
-\r
-/*\r
-============================\r
-=\r
-= TileBonus\r
-=\r
-============================\r
-*/\r
-\r
-void TileBonus(Uint16 x, Uint16 y, Uint16 bonus)\r
-{\r
-       RF_MemToMap(&zeromap, 1, x, y, 1, 1);\r
-       SD_PlaySound(bonussound[bonus]);\r
-       GivePoints(bonuspoints[bonus]);\r
-       if (bonus < 4)\r
-       {\r
-               gamestate.keys[bonus]++;\r
-       }\r
-       else if (bonus == 10)\r
-       {\r
-               gamestate.lives++;\r
-       }\r
-       else if (bonus == 11)\r
-       {\r
-               gamestate.ammo += shotsinclip[gamestate.difficulty];\r
-       }\r
-       GetNewObj(true);\r
-       new->obclass = inertobj;\r
-       new->priority = 3;\r
-       new->x = CONVERT_TILE_TO_GLOBAL(x);\r
-       new->y = CONVERT_TILE_TO_GLOBAL(y);\r
-       new->ydir = -1;\r
-       new->temp2 = new->shapenum = bonussprite[bonus];\r
-       NewState(new, &s_bonusrise);\r
-       new->needtoclip = cl_noclip;\r
-}\r
-\r
-/*\r
-============================\r
-=\r
-= GiveDrop\r
-=\r
-============================\r
-*/\r
-\r
-void GiveDrop(Uint16 x, Uint16 y)\r
-{\r
-       RF_MemToMap(&zeromap, 1, x, y, 1, 1);\r
-       SD_PlaySound(SND_GETWATER);\r
-       SpawnSplash(x, y);\r
-       if (++gamestate.drops == 100)\r
-       {\r
-               gamestate.drops = 0;\r
-               SD_PlaySound(SND_EXTRAKEEN);\r
-               gamestate.lives++;\r
-               GetNewObj(true);\r
-               new->obclass = inertobj;\r
-               new->priority = 3;\r
-               new->x = CONVERT_TILE_TO_GLOBAL(x);\r
-               new->y = CONVERT_TILE_TO_GLOBAL(y-1);\r
-               new->ydir = -1;\r
-               new->temp2 = new->shapenum = BONUS100UPSPR;\r
-               NewState(new, &s_bonusrise);\r
-               new->needtoclip = cl_noclip;\r
-       }\r
-}\r
-\r
-/*\r
-============================\r
-=\r
-= CheckInTiles\r
-=\r
-============================\r
-*/\r
-\r
-void CheckInTiles(objtype *ob)\r
-{\r
-       Uint16 x, y;\r
-       Uint16 far *map;\r
-       Uint16 rowdelta, intile, midx;\r
-\r
-       if (moonok == 1)\r
-               moonok = 0;\r
-\r
-       map = mapsegs[1] + mapbwidthtable[ob->tiletop]/2 + ob->tileleft;\r
-       rowdelta = mapwidth - (ob->tileright - ob->tileleft + 1);\r
-       for (y = ob->tiletop; y <= ob->tilebottom; y++, map += rowdelta)\r
-       {\r
-               for (x = ob->tileleft; x <= ob->tileright; x++, map++)\r
-               {\r
-                       if ((intile = tinf[INTILE + *map] & INTILE_TYPEMASK) != 0)\r
-                       {\r
-                               switch (intile)\r
-                               {\r
-                               case INTILE_DEADLY:\r
-                                       KillKeen();\r
-                                       break;\r
-\r
-                               case INTILE_DROP:\r
-                                       GiveDrop(x, y);\r
-                                       break;\r
-\r
-                               case INTILE_GEMSOCKET0:\r
-                               case INTILE_GEMSOCKET1:\r
-                               case INTILE_GEMSOCKET2:\r
-                               case INTILE_GEMSOCKET3:\r
-                                       if (ob->tilebottom != y || !ob->hitnorth\r
-                                               || ob->state == &s_keenkey\r
-                                               || !gamestate.keys[intile-INTILE_GEMSOCKET0])\r
-                                       {\r
-                                               return;\r
-                                       }\r
-\r
-                                       midx = CONVERT_TILE_TO_GLOBAL(x) + -4*PIXGLOBAL;\r
-                                       if (ob->x != midx)\r
-                                       {\r
-                                               ob->temp1 = midx;\r
-                                               ob->state = &s_keenlineup;\r
-                                               return;\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               gamestate.keys[intile-INTILE_GEMSOCKET0]--;\r
-                                               ChangeState(ob, &s_keenkey);\r
-                                       }\r
-                                       break;\r
-\r
-                               case INTILE_MOON:\r
-                                       if (moonok == 0)\r
-                                               moonok = 1;\r
-                                       break;\r
-\r
-                               case INTILE_BONUS100:\r
-                               case INTILE_BONUS200:\r
-                               case INTILE_BONUS500:\r
-                               case INTILE_BONUS1000:\r
-                               case INTILE_BONUS2000:\r
-                               case INTILE_BONUS5000:\r
-                               case INTILE_EXTRALIFE:\r
-                               case INTILE_AMMO:\r
-                                       TileBonus(x, y, (intile-INTILE_BONUS100)+4);\r
-                                       break;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                REACTION ROUTINES\r
-\r
-=============================================================================\r
-*/\r
-\r
-\r
-/*\r
-============================\r
-=\r
-= KeenSimpleReact\r
-=\r
-============================\r
-*/\r
-\r
-void KeenSimpleReact(objtype *ob)\r
-{\r
-       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-}\r
-\r
-\r
-/*\r
-============================\r
-=\r
-= KeenStandReact\r
-=\r
-============================\r
-*/\r
-\r
-void KeenStandReact(objtype *ob)\r
-{\r
-       if (!ob->hitnorth)\r
-       {\r
-       //\r
-       // walked off an edge\r
-       //\r
-               SD_PlaySound(SND_PLUMMET);\r
-               ob->xspeed = ob->xdir * 8;\r
-               ob->yspeed = 0;\r
-               ChangeState(ob, &s_keenjump3);\r
-               jumptime = 0;\r
-       }\r
-       else if ((ob->hitnorth & ~7) == 8)      // deadly floor!\r
-       {\r
-               KillKeen();\r
-       }\r
-       else if (ob->hitnorth == 41)\r
-       {\r
-               xtry = tics * 8;\r
-               ytry = 0;\r
-               ob->temp1 = 0;\r
-               ClipToWalls(ob);\r
-       }\r
-       else if (ob->hitnorth == 49)\r
-       {\r
-               xtry = tics * -8;\r
-               ytry = 0;\r
-               ob->temp1 = 0;\r
-               ClipToWalls(ob);\r
-       }\r
-\r
-       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-}\r
-\r
-/*\r
-============================\r
-=\r
-= KeenWalkReact\r
-=\r
-============================\r
-*/\r
-\r
-void KeenWalkReact(objtype *ob)\r
-{\r
-       if (!ob->hitnorth)\r
-       {\r
-       //\r
-       // walked off an edge\r
-       //\r
-               SD_PlaySound(SND_PLUMMET);\r
-               ob->xspeed = ob->xdir * 8;\r
-               ob->yspeed = 0;\r
-               ChangeState(ob, &s_keenjump3);\r
-               jumptime = 0;\r
-       }\r
-       else if ((ob->hitnorth & ~7) == 8)      // deadly floor!\r
-       {\r
-               KillKeen();\r
-       }\r
-       else if (ob->hitnorth == 41)\r
-       {\r
-               xtry = tics * 8;\r
-               ytry = 0;\r
-               ClipToWalls(ob);\r
-       }\r
-       else if (ob->hitnorth == 49)\r
-       {\r
-               xtry = tics * -8;\r
-               ytry = 0;\r
-               ClipToWalls(ob);\r
-       }\r
-       else if (ob->hiteast && ob->xdir == -1 || ob->hitwest && ob->xdir == 1)\r
-       {\r
-       //\r
-       // ran into a wall\r
-       //\r
-               ob->ticcount = 0;\r
-               ob->state = &s_keenstand;\r
-               ob->shapenum = ob->xdir == 1? s_keenstand.rightshapenum : s_keenstand.leftshapenum;\r
-       }\r
-\r
-       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-}\r
-\r
-/*\r
-============================\r
-=\r
-= KeenAirReact\r
-=\r
-============================\r
-*/\r
-\r
-void KeenAirReact(objtype *ob)\r
-{\r
-       Uint16 far *map;\r
-       Uint16 oldtop, graby, ty, tile;\r
-\r
-       if (ob->hiteast && ob->xdir == -1 || ob->hitwest && ob->xdir == 1)\r
-               ob->xspeed = 0;\r
-\r
-       if (ob->hitsouth)\r
-       {\r
-               if (ob->hitsouth == 17) // jumping up through a pole hole\r
-               {\r
-                       ob->y -= 2*PIXGLOBAL;\r
-                       ob->top -= 2*PIXGLOBAL;\r
-                       ob->xspeed = 0;\r
-                       ob->x = CONVERT_TILE_TO_GLOBAL(ob->tilemidx) - 2*PIXGLOBAL;\r
-               }\r
-               else\r
-               {\r
-#ifdef KEEN6\r
-                       if (ob->hitsouth == 33)\r
-                       {\r
-                               FlipBigSwitch(ob, false);\r
-                       }\r
-#endif\r
-                       if (!jumpcheat)\r
-                       {\r
-                               SD_PlaySound(SND_HELMETHIT);\r
-                               if (ob->hitsouth > 1)\r
-                               {\r
-                                       ob->yspeed += 16;\r
-                                       if (ob->yspeed < 0)     // push away from slopes\r
-                                               ob->yspeed = 0;\r
-                               }\r
-                               else\r
-                               {\r
-                                       ob->yspeed = 0;\r
-                               }\r
-                               jumptime = 0;\r
-                       }\r
-               }\r
-       }\r
-\r
-       if (ob->hitnorth)\r
-       {\r
-               ob->ymove = 0;\r
-               if ((ob->hitnorth & ~7) == 8)   // deadly floor!\r
-               {\r
-                       KillKeen();\r
-               }\r
-               else\r
-               {\r
-#if defined KEEN5\r
-                       if (ob->hitnorth == 57)\r
-                       {\r
-                               SD_PlaySound(SND_LANDONFUSE);\r
-                       }\r
-#elif defined KEEN6\r
-                       if (ob->hitnorth == 33)\r
-                       {\r
-                               FlipBigSwitch(ob, true);\r
-                       }\r
-#endif\r
-                       if (ob->hitnorth != 25 || !jumptime)    // KLUDGE to allow jumping off\r
-                       {\r
-                               ob->temp1 = ob->temp2 = 0;\r
-                               if (ob->state == &s_keenairshoot1)\r
-                               {\r
-                                       ChangeState(ob, &s_keenshoot1);\r
-                               }\r
-                               else if (ob->state == &s_keenairshootup1)\r
-                               {\r
-                                       ChangeState(ob, &s_keenshootup1);\r
-                               }\r
-                               else if (c.xaxis)\r
-                               {\r
-                                       ChangeState(ob, &s_keenwalk1);\r
-                               }\r
-                               else\r
-                               {\r
-                                       ChangeState(ob, &s_keenstand);\r
-                               }\r
-                               SD_PlaySound(SND_LAND);\r
-                       }\r
-               }\r
-       }\r
-       else if (ob->ymove > 0)\r
-       {\r
-//\r
-// check if there is an edge to grab\r
-//\r
-               oldtop = ob->top - ob->ymove;\r
-               graby = ((ob->top - 4*PIXGLOBAL) & 0xFF00) + 4*PIXGLOBAL;\r
-               ty = CONVERT_GLOBAL_TO_TILE(graby) - 1;\r
-               if (oldtop < graby && ob->top >= graby)\r
-               {\r
-                       if (c.xaxis == -1)\r
-                       {\r
-                               map = mapsegs[1] + mapbwidthtable[ty]/2 + ob->tileleft;\r
-                               if (ob->hiteast)\r
-                                       map--;\r
-                               tile = *map;\r
-                               if (!tinf[EASTWALL + tile] && !tinf[WESTWALL + tile]\r
-                                       && !tinf[NORTHWALL + tile] && !tinf[SOUTHWALL + tile]\r
-                                       && tinf[EASTWALL + map[mapwidth]] && tinf[NORTHWALL + map[mapwidth]]\r
-                                       )\r
-                               {\r
-                                       ob->xdir = -1;\r
-                                       ob->needtoclip = cl_noclip;\r
-                                       ob->x = (ob->x & 0xFF00) + 8*PIXGLOBAL;\r
-                                       ob->y = graby - 4*PIXGLOBAL;\r
-                                       ob->yspeed = ob->ymove = 0;\r
-                                       ChangeState(ob, &s_keenholdon);\r
-                               }\r
-                       }\r
-                       else if (c.xaxis == 1)\r
-                       {\r
-                               map = mapsegs[1] + mapbwidthtable[ty]/2 + ob->tileright;\r
-                               if (ob->hitwest)\r
-                                       map++;\r
-                               tile = *map;\r
-                               if (!tinf[EASTWALL + tile] && !tinf[WESTWALL + tile]\r
-                                       && !tinf[NORTHWALL + tile] && !tinf[SOUTHWALL + tile]\r
-                                       && tinf[WESTWALL + map[mapwidth]] && tinf[NORTHWALL + map[mapwidth]]\r
-                                       )\r
-                               {\r
-                                       ob->xdir = 1;\r
-                                       ob->needtoclip = cl_noclip;\r
-                                       ob->x = (ob->x & 0xFF00) + 16*PIXGLOBAL;\r
-                                       ob->y = graby - 4*PIXGLOBAL;\r
-                                       ob->yspeed = ob->ymove = 0;\r
-                                       ChangeState(ob, &s_keenholdon);\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-}\r
-\r
-#ifdef KEEN5\r
-/*\r
-============================\r
-=\r
-= BreakFuse\r
-=\r
-============================\r
-*/\r
-\r
-void BreakFuse(Uint16 tileX, Uint16 tileY)\r
-{\r
-       Uint16 tiles[] = {1932, 1950};  // should be 'static' for less overhead\r
-\r
-       // The original disassembly had some code here equivalent to this:\r
-       //\r
-       // _AX = tiles[0];\r
-       // _DX = 4;\r
-       //\r
-       // As it turned out, that was just a compiler quirk.\r
-\r
-       SpawnFuseFlash(tileX, tileY);\r
-       if (--gamestate.numfuses == 0)\r
-       {\r
-               SpawnDeadMachine();\r
-       }\r
-       RF_MemToMap(tiles, 1, tileX, tileY, 1, 2);\r
-}\r
-#endif\r
-\r
-/*\r
-============================\r
-=\r
-= KeenPogoReact\r
-=\r
-============================\r
-*/\r
-\r
-void KeenPogoReact(objtype *ob)\r
-{\r
-       if (ob->hiteast && ob->xdir == -1 || ob->hitwest && ob->xdir == 1)\r
-               ob->xspeed = 0;\r
-\r
-       if (ob->hitsouth)\r
-       {\r
-               if (ob->hitsouth == 17) // jumping up through a pole hole\r
-               {\r
-                       ob->y -= 2*PIXGLOBAL;\r
-                       ob->top -= 2*PIXGLOBAL;\r
-                       ob->xspeed = 0;\r
-                       ob->x = CONVERT_TILE_TO_GLOBAL(ob->tilemidx) - 2*PIXGLOBAL;\r
-               }\r
-               else\r
-               {\r
-#ifdef KEEN6\r
-                       if (ob->hitsouth == 33)\r
-                       {\r
-                               FlipBigSwitch(ob, false);\r
-                       }\r
-#endif\r
-                       if (!jumpcheat)\r
-                       {\r
-                               SD_PlaySound(SND_HELMETHIT);\r
-                               if (ob->hitsouth > 1)\r
-                               {\r
-                                       ob->yspeed += 16;\r
-                                       if (ob->yspeed < 0)     // push away from slopes\r
-                                               ob->yspeed = 0;\r
-                               }\r
-                               else\r
-                               {\r
-                                       ob->yspeed = 0;\r
-                               }\r
-                               jumptime = 0;\r
-                       }\r
-               }\r
-       }\r
-\r
-       if (ob->hitnorth)\r
-       {\r
-               ob->ymove = 0;\r
-               if ((ob->hitnorth & ~7) == 8)   // deadly floor!\r
-               {\r
-                       KillKeen();\r
-               }\r
-               else\r
-               {\r
-#if defined KEEN5\r
-                       if (ob->hitnorth == 57)\r
-                       {\r
-                               if (ob->yspeed < 48)\r
-                               {\r
-                                       SD_PlaySound(SND_LANDONFUSE);\r
-                               }\r
-                               else\r
-                               {\r
-                                       BreakFuse(ob->tilemidx, ob->tilebottom);\r
-                                       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-                                       return;\r
-                               }\r
-                       }\r
-#elif defined KEEN6\r
-                       if (ob->hitnorth == 33)\r
-                       {\r
-                               FlipBigSwitch(ob, true);\r
-                       }\r
-                       else if (ob->hitnorth == 41)\r
-                       {\r
-                               ob->xspeed += 8;\r
-                               if (ob->xspeed > 8)\r
-                                       ob->xspeed = 8;\r
-                       }\r
-                       else if (ob->hitnorth == 49)\r
-                       {\r
-                               ob->xspeed -= 8;\r
-                               if (ob->xspeed < -8)\r
-                                       ob->xspeed = -8;\r
-                       }\r
-#endif\r
-                       if (ob->hitnorth != 25 || !jumptime)    // KLUDGE to allow jumping off\r
-                       {\r
-                               ob->yspeed = -48;\r
-                               jumptime = 24;\r
-                               SD_PlaySound(SND_POGOBOUNCE);\r
-                               ChangeState(ob, &s_keenpogo);\r
-                       }\r
-               }\r
-       }\r
-\r
-       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-}\r
-\r
-/*\r
-============================\r
-=\r
-= KeenPoleReact\r
-=\r
-============================\r
-*/\r
-\r
-void KeenPoleReact(objtype *ob)\r
-{\r
-       Uint16 far *map;\r
-       Uint16 ymove;\r
-\r
-       map = mapsegs[1] + mapbwidthtable[ob->tilebottom]/2 + ob->tilemidx;\r
-       if (tinf[NORTHWALL + *map] == 1)\r
-       {\r
-               ymove = (ob->bottom & 0xFF) + 1;\r
-               ob->y -= ymove;\r
-               ob->bottom -= ymove;\r
-               ob->tilebottom--;\r
-               ob->needtoclip = cl_midclip;\r
-               ChangeState(ob, &s_keenlookdown);\r
-       }\r
-\r
-       RF_PlaceSprite(&ob->sprite, ob->x, ob->y, ob->shapenum, spritedraw, ob->priority);\r
-}\r