]> 4ch.mooo.com Git - 16.git/blobdiff - 16/keen456/KEEN4-6/CK_PLAY.C
added keen 4-6 rebuild code for reference.... i need to stop doing this... xD
[16.git] / 16 / keen456 / KEEN4-6 / CK_PLAY.C
diff --git a/16/keen456/KEEN4-6/CK_PLAY.C b/16/keen456/KEEN4-6/CK_PLAY.C
deleted file mode 100755 (executable)
index 0e08140..0000000
+++ /dev/null
@@ -1,2422 +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
-#include "CK_DEF.H"\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                GLOBAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-ScanCode firescan = sc_Space;\r
-\r
-boolean singlestep, jumpcheat, godmode, keenkilled;\r
-\r
-exittype playstate;\r
-gametype gamestate;\r
-\r
-objtype *new, *check, *player, *scoreobj;\r
-\r
-Uint16 originxtilemax;\r
-Uint16 originytilemax;\r
-\r
-ControlInfo c;\r
-boolean button2, button3;      // never used\r
-\r
-objtype dummyobj;\r
-\r
-Sint16 invincible;\r
-\r
-boolean oldshooting, showscorebox, joypad;\r
-\r
-Sint16 groundslam;\r
-\r
-boolean debugok;\r
-boolean jumpbutton, jumpheld, pogobutton, pogoheld, firebutton, fireheld, upheld;\r
-\r
-\r
-/*\r
-=============================================================================\r
-\r
-                                                LOCAL VARIABLES\r
-\r
-=============================================================================\r
-*/\r
-\r
-objtype *obj;\r
-\r
-Uint16 centerlevel;\r
-\r
-Uint16 objectcount;\r
-objtype objarray[MAXACTORS];\r
-objtype *lastobj;\r
-objtype *objfreelist;\r
-\r
-Sint16 inactivateleft;\r
-Sint16 inactivateright;\r
-Sint16 inactivatetop;\r
-Sint16 inactivatebottom;\r
-\r
-#ifdef KEEN6Ev15\r
-Uint16 __dummy__;      // never used, but must be present to recreate the original EXE\r
-#endif\r
-\r
-Uint16 extravbls;\r
-\r
-Uint16 windowofs;\r
-Sint16 vislines;\r
-boolean scrollup;\r
-\r
-Sint16 oldfirecount;\r
-\r
-//===========================================================================\r
-\r
-/*\r
-==================\r
-=\r
-= CountObjects\r
-=\r
-==================\r
-*/\r
-\r
-void CountObjects(void)\r
-{\r
-       Uint16 activeobjects, inactiveobjects;\r
-       objtype *ob;\r
-\r
-       activeobjects = inactiveobjects = 0;\r
-       for (ob=player; ob; ob=ob->next)\r
-       {\r
-               if (ob->active)\r
-               {\r
-                       activeobjects++;\r
-               }\r
-               else\r
-               {\r
-                       inactiveobjects++;\r
-               }\r
-       }\r
-       VW_FixRefreshBuffer();\r
-       US_CenterWindow(18, 4);\r
-       PrintY += 7;\r
-       US_Print("Active Objects :");\r
-       US_PrintUnsigned(activeobjects);\r
-       US_Print("\nInactive Objects:");\r
-       US_PrintUnsigned(inactiveobjects);\r
-       VW_UpdateScreen();\r
-       IN_Ack();\r
-}\r
-\r
-/*\r
-==================\r
-=\r
-= DebugMemory\r
-=\r
-==================\r
-*/\r
-\r
-void DebugMemory(void)\r
-{\r
-       VW_FixRefreshBuffer();\r
-       US_CenterWindow(16, 7);\r
-       US_CPrint("Memory Usage");\r
-       US_CPrint("------------");\r
-       US_Print("Total     :");\r
-       US_PrintUnsigned((mminfo.mainmem+mminfo.EMSmem+mminfo.XMSmem)/1024);\r
-       US_Print("k\nFree      :");\r
-       US_PrintUnsigned(MM_UnusedMemory()/1024);\r
-       US_Print("k\nWith purge:");\r
-       US_PrintUnsigned(MM_TotalFree()/1024);\r
-       US_Print("k\n");\r
-       VW_UpdateScreen();\r
-       IN_Ack();\r
-#if GRMODE != CGAGR\r
-       MM_ShowMemory();\r
-#endif\r
-}\r
-\r
-/*\r
-===================\r
-=\r
-= TestSprites\r
-=\r
-===================\r
-*/\r
-\r
-void TestSprites(void)\r
-{\r
-       Uint16 infox, infoy;\r
-       Sint16 chunk, oldchunk;\r
-       Sint16 shift;\r
-       Uint16 infobottom, drawx;\r
-       spritetabletype far *info;\r
-       Uint8 _seg *block;\r
-       Uint16 size;\r
-       Uint16 scan;\r
-       Uint32 totalsize;\r
-\r
-       VW_FixRefreshBuffer();\r
-       US_CenterWindow(30, 17);\r
-       totalsize = 0;\r
-       US_CPrint("Sprite Test");\r
-       US_CPrint("-----------");\r
-       infoy = PrintY;\r
-       infox = (PrintX + 56) & ~7;\r
-       drawx = infox + 40;\r
-       US_Print("Chunk:\nWidth:\nHeight:\nOrgx:\nOrgy:\nXl:\nYl:\nXh:\nYh:\nShifts:\nMem:\n");\r
-       infobottom = PrintY;\r
-       chunk = STARTSPRITES;\r
-       shift = 0;\r
-       while (1)\r
-       {\r
-               if (chunk >= STARTSPRITES+NUMSPRITES)\r
-               {\r
-                       chunk = STARTSPRITES+NUMSPRITES-1;\r
-               }\r
-               else if (chunk < STARTSPRITES)\r
-               {\r
-                       chunk = STARTSPRITES;\r
-               }\r
-               info = &spritetable[chunk-STARTSPRITES];\r
-               block = grsegs[chunk];\r
-               VWB_Bar(infox, infoy, 40, infobottom-infoy, WHITE);\r
-               PrintX = infox;\r
-               PrintY = infoy;\r
-               US_PrintUnsigned(chunk);\r
-               US_Print("\n");\r
-               PrintX = infox;\r
-               US_PrintUnsigned(info->width);\r
-               US_Print("\n");\r
-               PrintX = infox;\r
-               US_PrintUnsigned(info->height);\r
-               US_Print("\n");\r
-               PrintX = infox;\r
-               US_PrintSigned(info->orgx);\r
-               US_Print("\n");\r
-               PrintX = infox;\r
-               US_PrintSigned(info->orgy);\r
-               US_Print("\n");\r
-               PrintX = infox;\r
-               US_PrintSigned(info->xl);\r
-               US_Print("\n");\r
-               PrintX = infox;\r
-               US_PrintSigned(info->yl);\r
-               US_Print("\n");\r
-               PrintX = infox;\r
-               US_PrintSigned(info->xh);\r
-               US_Print("\n");\r
-               PrintX = infox;\r
-               US_PrintSigned(info->yh);\r
-               US_Print("\n");\r
-               PrintX = infox;\r
-               US_PrintSigned(info->shifts);\r
-               US_Print("\n");\r
-               PrintX = infox;\r
-               if (!block)\r
-               {\r
-                       US_Print("-----");\r
-               }\r
-               else\r
-               {\r
-                       size = ((spritetype far *)block)->sourceoffset[3] + ((spritetype far *)block)->planesize[3]*5;\r
-                       size = (size + 15) & ~15;       //round up to multiples of 16\r
-                       totalsize += size;      //useless: the value stored in 'totalsize' is never used\r
-                       US_PrintUnsigned(size);\r
-                       US_Print("=");\r
-               }\r
-               oldchunk = chunk;\r
-               do\r
-               {\r
-                       VWB_Bar(drawx, infoy, 110, infobottom-infoy, WHITE);\r
-                       if (block)\r
-                       {\r
-                               PrintX = drawx;\r
-                               PrintY = infoy;\r
-                               US_Print("Shift:");\r
-                               US_PrintUnsigned(shift);\r
-                               US_Print("\n");\r
-                               VWB_DrawSprite(drawx + 2*shift + 16, PrintY, chunk);\r
-                       }\r
-                       VW_UpdateScreen();\r
-                       scan = IN_WaitForKey();\r
-                       switch (scan)\r
-                       {\r
-                       case sc_UpArrow:\r
-                               chunk++;\r
-                               break;\r
-                       case sc_DownArrow:\r
-                               chunk--;\r
-                               break;\r
-                       case sc_PgUp:\r
-                               chunk += 10;\r
-                               if (chunk >= STARTSPRITES+NUMSPRITES)\r
-                               {\r
-                                       chunk = STARTSPRITES+NUMSPRITES-1;\r
-                               }\r
-                               break;\r
-                       case sc_PgDn:\r
-                               chunk -= 10;\r
-                               if (chunk < STARTSPRITES)\r
-                               {\r
-                                       chunk = STARTSPRITES;\r
-                               }\r
-                               break;\r
-                       case sc_LeftArrow:\r
-                               if (--shift == -1)\r
-                               {\r
-                                       shift = 3;\r
-                               }\r
-                               break;\r
-                       case sc_RightArrow:\r
-                               if (++shift == 4)\r
-                               {\r
-                                       shift = 0;\r
-                               }\r
-                               break;\r
-                       case sc_Escape:\r
-                               return;\r
-                       }\r
-\r
-               } while (chunk == oldchunk);\r
-\r
-       }\r
-}\r
-\r
-/*\r
-===================\r
-=\r
-= PicturePause\r
-=\r
-===================\r
-*/\r
-\r
-void PicturePause(void)\r
-{\r
-       Uint16 source;\r
-       Sint16 y;\r
-\r
-//\r
-// wait for a key press, abort if it's not Enter\r
-//\r
-       IN_ClearKeysDown();\r
-       while (!LastScan);\r
-       if (LastScan != sc_Enter)\r
-       {\r
-               IN_ClearKeysDown();\r
-               return;\r
-       }\r
-\r
-       SD_PlaySound(SND_JUMP);\r
-       SD_WaitSoundDone();\r
-\r
-//\r
-// rearrange onscreen image into base EGA layout, so that it\r
-// can be grabbed correctly by an external screenshot tool\r
-//\r
-       source = displayofs + panadjust;\r
-\r
-       VW_ColorBorder(15);     // white (can't use WHITE as parameter, since that's defined as 3 for CGA and this must use 15)\r
-       VW_SetLineWidth(40);\r
-       VW_SetScreen(0, 0);\r
-\r
-       if (source < 0x10000l-200*64)\r
-       {\r
-       //\r
-       // copy top line first\r
-       //\r
-               for (y=0; y<200; y++)\r
-               {\r
-                       VW_ScreenToScreen(source+y*64, y*40, 40, 1);\r
-               }\r
-       }\r
-       else\r
-       {\r
-       //\r
-       // copy bottom line first\r
-       //\r
-               for (y=199; y>=0; y--)\r
-               {\r
-                       VW_ScreenToScreen(source+y*64, y*40, 40, 1);\r
-               }\r
-       }\r
-\r
-//\r
-// shut down input manager so that screenshot tool can see input again\r
-//\r
-       IN_Shutdown();\r
-\r
-       SD_PlaySound(SND_EXTRAKEEN);\r
-       SD_WaitSoundDone();\r
-\r
-//\r
-// shut down the remaining ID managers, except VW (stay in graphics mode!)\r
-//\r
-       US_Shutdown();\r
-       SD_Shutdown();\r
-       IN_Shutdown();\r
-       RF_Shutdown();\r
-       CA_Shutdown();\r
-       MM_Shutdown();\r
-\r
-//\r
-// wait until user hits Escape\r
-//\r
-       while (((bioskey(0) >> 8) & 0xFF) != sc_Escape);\r
-\r
-//\r
-// back to text mode and exit to DOS\r
-//\r
-       VW_Shutdown();\r
-       exit(0);\r
-}\r
-\r
-/*\r
-===================\r
-=\r
-= MaskOnTile\r
-=\r
-===================\r
-*/\r
-\r
-void MaskOnTile(Uint16 dest, Uint16 source)\r
-{\r
-       Sint16 i;\r
-       Uint16 _seg *sourceseg;\r
-       Uint16 _seg *destseg;\r
-       Uint16 sourceval, maskindex, sourcemask;\r
-\r
-       sourceseg = (grsegs+STARTTILE16M)[source];\r
-       destseg = (grsegs+STARTTILE16M)[dest];\r
-       for (i=0; i<64; i++)\r
-       {\r
-               maskindex = i & 15;\r
-#ifdef KEEN6Ev15\r
-               sourceval = sourceseg[16+i];\r
-#else\r
-               sourceval = (sourceseg+16)[i];\r
-#endif\r
-               sourcemask = sourceseg[maskindex];\r
-               destseg[maskindex] &= sourcemask;\r
-               destseg[16+i] &= sourcemask;\r
-               destseg[16+i] |= sourceval;\r
-       }\r
-}\r
-\r
-/*\r
-===================\r
-=\r
-= WallDebug\r
-=\r
-===================\r
-*/\r
-\r
-void WallDebug(void)\r
-{\r
-       Sint16 i, val;\r
-\r
-       VW_FixRefreshBuffer();\r
-       US_CenterWindow(24, 3);\r
-       US_PrintCentered("WORKING");\r
-       VW_UpdateScreen();\r
-       for (i=STARTTILE16M+108; i<STARTTILE16M+124; i++)\r
-       {\r
-               CA_CacheGrChunk(i);\r
-       }\r
-       for (i=0; i<NUMTILE16M; i++)\r
-       {\r
-               if (!grsegs[STARTTILE16M+i])\r
-               {\r
-                       continue;\r
-               }\r
-               val = tinf[i+NORTHWALL] & 7;\r
-               if (val)\r
-               {\r
-                       MaskOnTile(i, val+107);\r
-               }\r
-               val = tinf[i+SOUTHWALL] & 7;\r
-               if (val)\r
-               {\r
-                       MaskOnTile(i, val+115);\r
-               }\r
-               val = tinf[i+EASTWALL] & 7;\r
-               if (val > 1)\r
-               {\r
-                       strcpy(str, "WallDebug: East wall other than 1:");\r
-                       itoa(i, str2, 10);\r
-                       strcat(str, str2);\r
-                       Quit(str);\r
-               }\r
-               if (val)\r
-               {\r
-                       MaskOnTile(i, val+114); //Note: val is always 1 here, so you could use 115 as 2nd arg\r
-               }\r
-               val = tinf[i+WESTWALL] & 7;\r
-               if (val > 1)\r
-               {\r
-                       strcpy(str, "WallDebug: West wall other than 1:");\r
-                       itoa(i, str2, 10);\r
-                       strcat(str, str2);\r
-                       Quit(str);\r
-               }\r
-               if (val)\r
-               {\r
-                       MaskOnTile(i, val+122); //Note: val is always 1 here, so you could use 123 as 2nd arg\r
-               }\r
-       }\r
-}\r
-\r
-\r
-//===========================================================================\r
-\r
-/*\r
-================\r
-=\r
-= DebugKeys\r
-=\r
-================\r
-*/\r
-\r
-boolean DebugKeys(void)\r
-{\r
-       Sint16 level, i, esc;\r
-\r
-       if (Keyboard[sc_B] && ingame)           // B = border color\r
-       {\r
-               VW_FixRefreshBuffer();\r
-               US_CenterWindow(24, 3);\r
-               PrintY += 6;\r
-               US_Print(" Border color (0-15):");\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 <= 15)\r
-                       {\r
-                               VW_ColorBorder(level);\r
-                       }\r
-               }\r
-               return true;\r
-       }\r
-\r
-       if (Keyboard[sc_C] && ingame)           // C = count objects\r
-       {\r
-               CountObjects();\r
-               return true;\r
-       }\r
-\r
-       if (Keyboard[sc_D] && ingame)           // D = start / end demo record\r
-       {\r
-               if (DemoMode == demo_Off)\r
-               {\r
-                       StartDemoRecord();\r
-               }\r
-               else if (DemoMode == demo_Record)\r
-               {\r
-                       EndDemoRecord();\r
-                       playstate = ex_completed;\r
-               }\r
-               return true;\r
-       }\r
-\r
-       if (Keyboard[sc_E] && ingame)           // E = quit level\r
-       {\r
-               if (tedlevel)\r
-               {\r
-                       TEDDeath();\r
-               }\r
-               playstate = ex_completed;\r
-               //BUG? there is no return in this branch (should return false)\r
-       }\r
-\r
-       if (Keyboard[sc_G] && ingame)           // G = god mode\r
-       {\r
-               VW_FixRefreshBuffer();\r
-               US_CenterWindow(12, 2);\r
-               if (godmode)\r
-               {\r
-                       US_PrintCentered("God mode OFF");\r
-               }\r
-               else\r
-               {\r
-                       US_PrintCentered("God mode ON");\r
-               }\r
-               VW_UpdateScreen();\r
-               IN_Ack();\r
-               godmode ^= true;\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_I])                        // I = item cheat\r
-       {\r
-               VW_FixRefreshBuffer();\r
-               US_CenterWindow(12, 3);\r
-               US_PrintCentered("Free items!");\r
-               for (i=0; i<4; i++)\r
-               {\r
-                       gamestate.keys[i] = 99;\r
-               }\r
-               gamestate.ammo = 99;\r
-#if defined KEEN4\r
-               gamestate.wetsuit = true;\r
-#elif defined KEEN5\r
-               gamestate.keycard = true;\r
-#elif defined KEEN6\r
-               gamestate.passcardstate=gamestate.hookstate=gamestate.sandwichstate = 1;\r
-#endif\r
-               VW_UpdateScreen();\r
-               IN_Ack();\r
-               GivePoints(3000);\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_J])                        // J = jump cheat\r
-       {\r
-               jumpcheat ^= true;\r
-               VW_FixRefreshBuffer();\r
-               US_CenterWindow(18, 3);\r
-               if (jumpcheat)\r
-               {\r
-                       US_PrintCentered("Jump cheat ON");\r
-               }\r
-               else\r
-               {\r
-                       US_PrintCentered("Jump cheat OFF");\r
-               }\r
-               VW_UpdateScreen();\r
-               IN_Ack();\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_M])                        // M = memory info\r
-       {\r
-               DebugMemory();\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_N])                        // N = no clip\r
-       {\r
-               VW_FixRefreshBuffer();\r
-               US_CenterWindow(18, 3);\r
-               if (player->needtoclip)\r
-               {\r
-                       US_PrintCentered("No clipping ON");\r
-                       player->needtoclip = cl_noclip;\r
-               }\r
-               else\r
-               {\r
-                       US_PrintCentered("No clipping OFF");\r
-                       player->needtoclip = cl_midclip;\r
-               }\r
-               VW_UpdateScreen();\r
-               IN_Ack();\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_P])                        // P = pause with no screen disruptioon\r
-       {\r
-               IN_ClearKeysDown();\r
-               PicturePause();\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_S] && ingame)      // S = slow motion\r
-       {\r
-               singlestep ^= true;\r
-               VW_FixRefreshBuffer();\r
-               US_CenterWindow(18, 3);\r
-               if (singlestep)\r
-               {\r
-                       US_PrintCentered("Slow motion ON");\r
-               }\r
-               else\r
-               {\r
-                       US_PrintCentered("Slow motion OFF");\r
-               }\r
-               VW_UpdateScreen();\r
-               IN_Ack();\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_T])                        // T = sprite test\r
-       {\r
-               TestSprites();\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_V])                        // V = extra VBLs\r
-       {\r
-               VW_FixRefreshBuffer();\r
-               US_CenterWindow(30, 3);\r
-               PrintY += 6;\r
-               US_Print("  Add how many extra VBLs(0-8):");\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 <= 8)\r
-                       {\r
-                               extravbls = level;\r
-                       }\r
-               }\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_W] && ingame)      // W = warp to level\r
-       {\r
-               VW_FixRefreshBuffer();\r
-               US_CenterWindow(26, 3);\r
-               PrintY += 6;\r
-               US_Print("  Warp to which level(1-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 <= 18)\r
-                       {\r
-                               gamestate.mapon = level;\r
-                               playstate = ex_warped;\r
-                       }\r
-               }\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_Y])                        // Y = wall debug\r
-       {\r
-               WallDebug();\r
-               return true;\r
-       }\r
-       else if (Keyboard[sc_Z])                        // Z = game over\r
-       {\r
-               gamestate.lives = 0;\r
-               KillKeen();\r
-               return false;\r
-       }\r
-       return false;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-================\r
-=\r
-= UserCheat\r
-=\r
-================\r
-*/\r
-\r
-void UserCheat(void)\r
-{\r
-       Sint16 i;\r
-\r
-       for (i=sc_A; i<=sc_Z; i++)      //Note: this does NOT check the keys in alphabetical order!\r
-       {\r
-               if (i != sc_B && i != sc_A && i != sc_T && Keyboard[i])\r
-               {\r
-                       return;\r
-               }\r
-       }\r
-       US_CenterWindow(20, 7);\r
-       PrintY += 2;\r
-       US_CPrint(\r
-               "Cheat Option!\n"\r
-               "\n"\r
-               "You just got all\n"\r
-               "the keys, 99 shots,\n"\r
-               "and an extra keen!");\r
-       VW_UpdateScreen();\r
-       IN_Ack();\r
-       RF_ForceRefresh();\r
-       gamestate.ammo = 99;\r
-       gamestate.lives++;\r
-#ifdef KEEN5\r
-       gamestate.keycard = true;\r
-#endif\r
-       gamestate.keys[0] = gamestate.keys[1] = gamestate.keys[2] = gamestate.keys[3] = 1;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=====================\r
-=\r
-= CheckKeys\r
-=\r
-=====================\r
-*/\r
-\r
-void CheckKeys(void)\r
-{\r
-       if (screenfaded)                        // don't do anything with a faded screen\r
-       {\r
-               return;\r
-       }\r
-\r
-//\r
-// Enter for status screen\r
-//\r
-       if (Keyboard[sc_Enter] || (GravisGamepad && GravisAction[ga_Status]))\r
-       {\r
-               StatusWindow();\r
-               IN_ClearKeysDown();\r
-               RF_ForceRefresh();\r
-               lasttimecount = TimeCount;      // BUG: should be the other way around\r
-       }\r
-\r
-//\r
-// pause key wierdness can't be checked as a scan code\r
-//\r
-       if (Paused)\r
-       {\r
-               SD_MusicOff();\r
-               VW_FixRefreshBuffer();\r
-               US_CenterWindow(8, 3);\r
-               US_PrintCentered("PAUSED");\r
-               VW_UpdateScreen();\r
-               IN_Ack();\r
-               RF_ForceRefresh();\r
-               Paused = false;\r
-               SD_MusicOn();\r
-       }\r
-\r
-#ifndef KEEN6\r
-//\r
-// F1 to enter help screens\r
-//\r
-       if (LastScan == sc_F1)\r
-       {\r
-               StopMusic();\r
-               HelpScreens();\r
-               StartMusic(gamestate.mapon);\r
-               if (showscorebox)\r
-               {\r
-                       scoreobj->temp2 = -1;\r
-                       scoreobj->temp1 = -1;\r
-                       scoreobj->temp3 = -1;\r
-                       scoreobj->temp4 = -1;\r
-               }\r
-               RF_ForceRefresh();\r
-       }\r
-#endif\r
-\r
-       if (!storedemo)\r
-       {\r
-//\r
-// F2-F7/ESC to enter control panel\r
-//\r
-               if (LastScan >= sc_F2 && LastScan <= sc_F7 || LastScan == sc_Escape)\r
-               {\r
-                       VW_FixRefreshBuffer();\r
-                       StopMusic();\r
-                       US_ControlPanel();\r
-                       RF_FixOfs();\r
-                       StartMusic(gamestate.mapon);\r
-                       if (!showscorebox && scoreobj->sprite)\r
-                       {\r
-                               RF_RemoveSprite(&scoreobj->sprite);\r
-                       }\r
-                       if (showscorebox)\r
-                       {\r
-                               scoreobj->temp2 = -1;\r
-                               scoreobj->temp1 = -1;\r
-                               scoreobj->temp3 = -1;\r
-                               scoreobj->temp4 = -1;\r
-                       }\r
-                       IN_ClearKeysDown();\r
-                       if (restartgame)\r
-                       {\r
-                               playstate = ex_resetgame;\r
-                       }\r
-                       else if (!loadedgame)\r
-                       {\r
-                               RF_ForceRefresh();\r
-                       }\r
-                       if (abortgame)\r
-                       {\r
-                               abortgame = false;\r
-                               playstate = ex_abortgame;\r
-                       }\r
-                       if (loadedgame)\r
-                       {\r
-                               playstate = ex_loadedgame;\r
-                       }\r
-                       lasttimecount = TimeCount;      // BUG: should be the other way around\r
-               }\r
-\r
-//\r
-// F9 boss key\r
-//\r
-               if (LastScan == sc_F9)\r
-               {\r
-                       VW_Shutdown();\r
-                       SD_MusicOff();\r
-                       cputs("C:>");\r
-                       IN_ClearKeysDown();\r
-                       while (LastScan != sc_Escape);\r
-                       VW_SetScreenMode(GRMODE);\r
-                       VW_ColorBorder(bordercolor);\r
-                       RF_ForceRefresh();\r
-                       IN_ClearKeysDown();\r
-                       lasttimecount = TimeCount;      // BUG: should be the other way around\r
-                       SD_MusicOn();\r
-               }\r
-       }\r
-\r
-//\r
-// B-A-T cheat code\r
-//\r
-       if (Keyboard[sc_B] && Keyboard[sc_A] && Keyboard[sc_T])\r
-       {\r
-               UserCheat();\r
-       }\r
-\r
-//\r
-// F10-? debug keys\r
-//\r
-       if (debugok && Keyboard[sc_F10])\r
-       {\r
-               if (DebugKeys())\r
-               {\r
-                       RF_ForceRefresh();\r
-                       lasttimecount = TimeCount;      // BUG: should be the other way around\r
-               }\r
-       }\r
-\r
-//\r
-// Ctrl-S toggles sound (only in storedemo mode)\r
-//\r
-       if (storedemo && Keyboard[sc_Control] && LastScan == sc_S)\r
-       {\r
-               if (SoundMode != sdm_Off)\r
-               {\r
-                       SD_SetSoundMode(sdm_Off);\r
-                       SD_SetMusicMode(smm_Off);\r
-               }\r
-               else\r
-               {\r
-                       if (AdLibPresent)\r
-                       {\r
-                               SD_SetSoundMode(sdm_AdLib);\r
-                               QuietFX = false;\r
-                               SD_SetMusicMode(smm_AdLib);\r
-                       }\r
-                       else\r
-                       {\r
-                               SD_SetSoundMode(sdm_PC);\r
-                               SD_SetMusicMode(smm_Off);\r
-                       }\r
-                       CA_LoadAllSounds();\r
-               }\r
-       }\r
-\r
-//\r
-// Ctrl-Q quick quit\r
-//\r
-       if (Keyboard[sc_Control] && LastScan == sc_Q)\r
-       {\r
-               IN_ClearKeysDown();\r
-               Quit(NULL);\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-==================\r
-=\r
-= PrintNumbers\r
-=\r
-==================\r
-*/\r
-\r
-void PrintNumbers(Sint16 x, Sint16 y, Sint16 maxlen, Sint16 basetile, Sint32 number)\r
-{\r
-       register Sint16 i;\r
-       Sint16 len;\r
-       char buffer[20];\r
-\r
-       ltoa(number, buffer, 10);\r
-       len = strlen(buffer);\r
-       i = maxlen;\r
-       while (i>len)\r
-       {\r
-               VWB_DrawTile8(x, y, basetile);\r
-               i--;\r
-               x += 8;\r
-       }\r
-       while (i>0)\r
-       {\r
-               VWB_DrawTile8(x, y, basetile+buffer[len-i]+(1-'0'));\r
-               i--;\r
-               x += 8;\r
-       }\r
-}\r
-\r
-/*\r
-==================\r
-=\r
-= DrawStatusWindow\r
-=\r
-==================\r
-*/\r
-\r
-#if GRMODE == CGAGR\r
-\r
-#define BACKCOLOR WHITE\r
-#define TEXTBACK BLACK\r
-#define NUMBERBACK BLACK\r
-\r
-#else\r
-\r
-#define BACKCOLOR LIGHTGRAY\r
-#define TEXTBACK WHITE\r
-#define NUMBERBACK BLACK\r
-\r
-#endif\r
-\r
-void DrawStatusWindow(void)\r
-{\r
-       Sint16 off, x, y, w, h, i;\r
-       Uint16 width, height;\r
-\r
-       x = 64;\r
-       y = 16;\r
-       w = 184;\r
-       h = 144;\r
-       VWB_DrawTile8(x, y, 54);\r
-       VWB_DrawTile8(x, y+h, 60);\r
-       for (i=x+8; i<=x+w-8; i+=8)\r
-       {\r
-               VWB_DrawTile8(i, y, 55);\r
-               VWB_DrawTile8(i, y+h, 61);\r
-       }\r
-       VWB_DrawTile8(i, y, 56);\r
-       VWB_DrawTile8(i, y+h, 62);\r
-       for (i=y+8; i<=y+h-8; i+=8)\r
-       {\r
-               VWB_DrawTile8(x, i, 57);\r
-               VWB_DrawTile8(x+w, i, 59);\r
-       }\r
-       VWB_Bar(72, 24, 176, 136, BACKCOLOR);\r
-\r
-       PrintY = 28;\r
-       WindowX = 80;\r
-       WindowW = 160;\r
-       US_CPrint("LOCATION");\r
-       VWB_Bar(79, 38, 162, 20, TEXTBACK);\r
-#ifdef KEEN5\r
-       if (mapon == 0 && player->y > 100*TILEGLOBAL)\r
-               _fstrcpy(str, levelnames[13]);\r
-       else\r
-               _fstrcpy(str, levelnames[gamestate.mapon]);\r
-#else\r
-       _fstrcpy(str, levelnames[gamestate.mapon]);\r
-#endif\r
-       SizeText(str, &width, &height);\r
-       PrintY = (20-height)/2+40-2;\r
-       US_CPrint(str);\r
-\r
-       PrintY = 61;\r
-       WindowX = 80;\r
-       WindowW = 64;\r
-       US_CPrint("SCORE");\r
-       VWB_Bar(79, 71, 66, 10, NUMBERBACK);\r
-       PrintNumbers(80, 72, 8, 41, gamestate.score);\r
-\r
-       PrintY = 61;\r
-       WindowX = 176;\r
-       WindowW = 64;\r
-       US_CPrint("EXTRA");\r
-       VWB_Bar(175, 71, 66, 10, NUMBERBACK);\r
-       PrintNumbers(176, 72, 8, 41, gamestate.nextextra);\r
-\r
-#if defined KEEN4\r
-       PrintY = 85;\r
-       WindowX = 80;\r
-       WindowW = 64;\r
-       US_CPrint("RESCUED");\r
-       VWB_Bar(79, 95, 66, 10, NUMBERBACK);\r
-       for (i = 0; i < gamestate.rescued; i++, off+=8)\r
-       {\r
-               VWB_DrawTile8(i*8 + 80, 96, 40);\r
-       }\r
-#elif defined KEEN5\r
-       PrintY = 92;\r
-       PrintX = 80;\r
-       US_Print("KEYCARD");\r
-       VWB_Bar(135, 91, 10, 10, NUMBERBACK);\r
-       if (gamestate.keycard)\r
-       {\r
-               VWB_DrawTile8(136, 92, 40);\r
-       }\r
-#endif\r
-\r
-       PrintY = 85;\r
-       WindowX = 176;\r
-       WindowW = 64;\r
-       US_CPrint("LEVEL");\r
-       VWB_Bar(175, 95, 66, 10, TEXTBACK);\r
-       PrintY = 96;\r
-       WindowX = 176;\r
-       WindowW = 64;\r
-       switch (gamestate.difficulty)\r
-       {\r
-       case gd_Easy:\r
-               US_CPrint("Easy");\r
-               break;\r
-       case gd_Normal:\r
-               US_CPrint("Normal");\r
-               break;\r
-       case gd_Hard:\r
-               US_CPrint("Hard");\r
-               break;\r
-       }\r
-\r
-#ifdef KEEN6\r
-       PrintX = 80;\r
-       PrintY = 96;\r
-       US_Print("ITEMS");\r
-       VWB_Bar(127, 95, 26, 10, NUMBERBACK);\r
-       if (gamestate.sandwichstate == 1)\r
-       {\r
-               VWB_DrawTile8(128, 96, 2);\r
-       }\r
-       else\r
-       {\r
-               VWB_DrawTile8(128, 96, 1);\r
-       }\r
-       if (gamestate.hookstate == 1)\r
-       {\r
-               VWB_DrawTile8(136, 96, 4);\r
-       }\r
-       else\r
-       {\r
-               VWB_DrawTile8(136, 96, 3);\r
-       }\r
-       if (gamestate.passcardstate == 1)\r
-       {\r
-               VWB_DrawTile8(144, 96, 6);\r
-       }\r
-       else\r
-       {\r
-               VWB_DrawTile8(144, 96, 5);\r
-       }\r
-#endif\r
-\r
-       PrintX = 80;\r
-       PrintY = 112;\r
-       US_Print("KEYS");\r
-       VWB_Bar(119, 111, 34, 10, NUMBERBACK);\r
-       for (i = 0; i < 4; i++)\r
-       {\r
-               if (gamestate.keys[i])\r
-               {\r
-                       VWB_DrawTile8(i*8+120, 112, 36+i);\r
-               }\r
-       }\r
-\r
-       PrintX = 176;\r
-       PrintY = 112;\r
-       US_Print("AMMO");\r
-       VWB_Bar(215, 111, 26, 10, NUMBERBACK);\r
-       PrintNumbers(216, 112, 3, 41, gamestate.ammo);\r
-\r
-       PrintX = 80;\r
-       PrintY = 128;\r
-       US_Print("KEENS");\r
-       VWB_Bar(127, 127, 18, 10, NUMBERBACK);\r
-       PrintNumbers(128, 128, 2, 41, gamestate.lives);\r
-\r
-       PrintX = 176;\r
-       PrintY = 128;\r
-       US_Print(DROPSNAME);\r
-       VWB_Bar(224, 127, 16, 10, NUMBERBACK);\r
-       PrintNumbers(224, 128, 2, 41, gamestate.drops);\r
-\r
-#ifdef KEEN4\r
-       VWB_Bar(79, 143, 66, 10, TEXTBACK);\r
-       PrintY = 144;\r
-       WindowX = 80;\r
-       WindowW = 64;\r
-       if (gamestate.wetsuit)\r
-       {\r
-               US_CPrint("Wetsuit");\r
-       }\r
-       else\r
-       {\r
-               US_CPrint("???");\r
-       }\r
-#endif\r
-\r
-       // draw the tiles for "PRESS A KEY":\r
-       for (i = 0; i < 10; i++)\r
-       {\r
-               VWB_DrawTile8(i*8+STATUS_PRESSKEY_X, 140, i+72);\r
-               VWB_DrawTile8(i*8+STATUS_PRESSKEY_X, 148, i+82);\r
-       }\r
-}\r
-\r
-/*\r
-==================\r
-=\r
-= ScrollStatusWindow\r
-=\r
-==================\r
-*/\r
-\r
-void ScrollStatusWindow(void)\r
-{\r
-       Uint16 source, dest;\r
-       Sint16 height;\r
-\r
-       if (vislines > 152)\r
-       {\r
-               height = vislines - 152;\r
-               source = windowofs + panadjust + 8;\r
-               dest = bufferofs + panadjust + 8;\r
-               VW_ScreenToScreen(source, dest, 192/BYTEPIXELS, height);\r
-               VW_ClipDrawMPic((pansx+136)/BYTEPIXELS, -(16-height)+pansy, METALPOLEPICM);\r
-               source = windowofs + panadjust + 16*SCREENWIDTH + 8*CHARWIDTH;\r
-               dest = bufferofs + panadjust + height*SCREENWIDTH + 8;\r
-               height = 152;\r
-       }\r
-       else\r
-       {\r
-               source = windowofs + panadjust + (152-vislines)*SCREENWIDTH + 16*SCREENWIDTH + 8*CHARWIDTH;\r
-               dest = bufferofs + panadjust + 8;\r
-               height = vislines;\r
-       }\r
-       if (height > 0)\r
-       {\r
-               VW_ScreenToScreen(source, dest, 192/BYTEPIXELS, height);\r
-       }\r
-       if (scrollup)\r
-       {\r
-               height = 168-vislines;\r
-               source = masterofs + panadjust + vislines*SCREENWIDTH + 8;\r
-               dest = bufferofs + panadjust + vislines*SCREENWIDTH + 8;\r
-               VW_ScreenToScreen(source, dest, 192/BYTEPIXELS, height);\r
-               height = vislines;\r
-               source = windowofs + panadjust + 8 - 24/BYTEPIXELS;\r
-               dest = bufferofs + panadjust + 8 - 24/BYTEPIXELS;\r
-               if (height > 0)\r
-                       VW_ScreenToScreen(source, dest, 24/BYTEPIXELS, height);\r
-       }\r
-       else\r
-       {\r
-               height = vislines + -72;\r
-               if (height > 0)\r
-               {\r
-                       source = windowofs + panadjust + 8 - 24/BYTEPIXELS;\r
-                       dest = bufferofs + panadjust + 8 - 24/BYTEPIXELS;\r
-                       if (height > 0)\r
-                               VW_ScreenToScreen(source, dest, 24/BYTEPIXELS, height);\r
-               }\r
-       }\r
-       if (vislines >= 72)\r
-       {\r
-               VW_ClipDrawMPic((pansx+40)/BYTEPIXELS, vislines-168+pansy, CORDPICM);\r
-       }\r
-       VW_UpdateScreen();\r
-}\r
-\r
-/*\r
-==================\r
-=\r
-= StatusWindow\r
-=\r
-==================\r
-*/\r
-\r
-void StatusWindow(void)\r
-{\r
-#if GRMODE == CGAGR\r
-\r
-       if (Keyboard[sc_A] && Keyboard[sc_2])\r
-       {\r
-               US_CenterWindow(20, 2);\r
-               PrintY += 2;\r
-               US_Print("Debug keys active");\r
-               VW_UpdateScreen();\r
-               IN_Ack();\r
-               debugok = true;\r
-       }\r
-\r
-       WindowX = 0;\r
-       WindowW = 320;\r
-       WindowY = 0;\r
-       WindowH = 200;\r
-       DrawStatusWindow();\r
-       VW_UpdateScreen();\r
-       IN_ClearKeysDown();\r
-       IN_Ack();\r
-\r
-#else\r
-\r
-       Uint16 oldbufferofs;\r
-\r
-       WindowX = 0;\r
-       WindowW = 320;\r
-       WindowY = 0;\r
-       WindowH = 200;\r
-\r
-       if (Keyboard[sc_A] && Keyboard[sc_2])\r
-       {\r
-               US_CenterWindow(20, 2);\r
-               PrintY += 2;\r
-               US_Print("Debug keys active");\r
-               VW_UpdateScreen();\r
-               IN_Ack();\r
-               debugok = true;\r
-       }\r
-\r
-       RF_Refresh();\r
-       RFL_InitAnimList();\r
-       oldbufferofs = bufferofs;\r
-       bufferofs = windowofs = RF_FindFreeBuffer();\r
-       VW_ScreenToScreen(displayofs, displayofs, 44, 224);     // useless (source and dest offsets are identical)\r
-       VW_ScreenToScreen(displayofs, masterofs, 44, 224);\r
-       VW_ScreenToScreen(displayofs, bufferofs, 44, 168);\r
-       DrawStatusWindow();\r
-       bufferofs = oldbufferofs;\r
-       RF_Refresh();\r
-\r
-       SD_PlaySound(SND_SHOWSTATUS);\r
-       vislines = 16;\r
-       scrollup = false;\r
-       RF_SetRefreshHook(ScrollStatusWindow);\r
-\r
-       while (true)\r
-       {\r
-               RF_Refresh();\r
-               if (vislines == 168)\r
-                       break;\r
-               vislines = vislines + tics*8;\r
-               if (vislines > 168)\r
-                       vislines = 168;\r
-       }\r
-\r
-       RF_Refresh();\r
-       RF_SetRefreshHook(NULL);\r
-       IN_ClearKeysDown();\r
-       IN_Ack();\r
-\r
-       SD_PlaySound(SND_HIDESTATUS);\r
-       vislines -= 16;\r
-       scrollup = true;\r
-       RF_SetRefreshHook(ScrollStatusWindow);\r
-\r
-       while (true)\r
-       {\r
-               RF_Refresh();\r
-               if (vislines == 0)\r
-                       break;\r
-               vislines = vislines - tics*8;\r
-               if (vislines < 0)\r
-                       vislines = 0;\r
-       }\r
-\r
-       RF_SetRefreshHook(NULL);\r
-\r
-       scoreobj->x = 0;        //force scorebox to redraw?\r
-\r
-#endif\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-==================\r
-=\r
-= CenterActor\r
-=\r
-==================\r
-*/\r
-\r
-void CenterActor(objtype *ob)\r
-{\r
-       Uint16 orgx, orgy;\r
-\r
-       centerlevel = 140;\r
-       if (ob->x < 152*PIXGLOBAL)\r
-       {\r
-               orgx = 0;\r
-       }\r
-       else\r
-       {\r
-               orgx = ob->x - 152*PIXGLOBAL;\r
-       }\r
-       if (mapon == 0)\r
-       {\r
-               if (ob->y < 80*PIXGLOBAL)\r
-               {\r
-                       orgy = 0;\r
-               }\r
-               else\r
-               {\r
-                       orgy = ob->y - 80*PIXGLOBAL;\r
-               }\r
-       }\r
-       else\r
-       {\r
-               if (ob->bottom < 140*PIXGLOBAL)\r
-               {\r
-                       orgy = 0;\r
-               }\r
-               else\r
-               {\r
-                       orgy = ob->bottom - 140*PIXGLOBAL;\r
-               }\r
-       }\r
-       if (!scorescreenkludge)\r
-       {\r
-               RF_NewPosition(orgx, orgy);\r
-       }\r
-\r
-//\r
-// update limits for onscreen and inactivate checks\r
-//\r
-       originxtilemax = (originxtile + PORTTILESWIDE) - 1;\r
-       originytilemax = (originytile + PORTTILESHIGH) - 1;\r
-       inactivateleft = originxtile - INACTIVATEDIST;\r
-       if (inactivateleft < 0)\r
-       {\r
-               inactivateleft = 0;\r
-       }\r
-       inactivateright = originxtilemax + INACTIVATEDIST;\r
-       if (inactivateright < 0)\r
-       {\r
-               inactivateright = 0;\r
-       }\r
-       inactivatetop = originytile - INACTIVATEDIST;\r
-       if (inactivatetop < 0)\r
-       {\r
-               inactivatetop = 0;\r
-       }\r
-       inactivatebottom = originytilemax + INACTIVATEDIST;\r
-       if (inactivatebottom < 0)\r
-       {\r
-               inactivatebottom = 0;\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-==================\r
-=\r
-= WorldScrollScreen\r
-=\r
-= Scroll if Keen is nearing an edge\r
-=\r
-==================\r
-*/\r
-\r
-void WorldScrollScreen(objtype *ob)\r
-{\r
-       Sint16 xscroll, yscroll;\r
-\r
-       if (keenkilled)\r
-               return;\r
-\r
-       if (ob->left < originxglobal + 9*TILEGLOBAL)\r
-       {\r
-               xscroll = ob->left - (originxglobal + 9*TILEGLOBAL);\r
-       }\r
-       else if (ob->right > originxglobal + 12*TILEGLOBAL)\r
-       {\r
-               xscroll = ob->right + 16 - (originxglobal + 12*TILEGLOBAL);\r
-       }\r
-       else\r
-       {\r
-               xscroll = 0;\r
-       }\r
-\r
-       if (ob->top < originyglobal + 5*TILEGLOBAL)\r
-       {\r
-               yscroll = ob->top - (originyglobal + 5*TILEGLOBAL);\r
-       }\r
-       else if (ob->bottom > originyglobal + 7*TILEGLOBAL)\r
-       {\r
-               yscroll = ob->bottom - (originyglobal + 7*TILEGLOBAL);\r
-       }\r
-       else\r
-       {\r
-               yscroll = 0;\r
-       }\r
-\r
-       if (!xscroll && !yscroll)\r
-               return;\r
-\r
-//\r
-// don't scroll more than one tile per frame\r
-//\r
-       if (xscroll >= 0x100)\r
-       {\r
-               xscroll = 0xFF;\r
-       }\r
-       else if (xscroll <= -0x100)\r
-       {\r
-               xscroll = -0xFF;\r
-       }\r
-       if (yscroll >= 0x100)\r
-       {\r
-               yscroll = 0xFF;\r
-       }\r
-       else if (yscroll <= -0x100)\r
-       {\r
-               yscroll = -0xFF;\r
-       }\r
-\r
-       RF_Scroll(xscroll, yscroll);\r
-\r
-//\r
-// update limits for onscreen and inactivate checks\r
-//\r
-       originxtilemax = (originxtile + PORTTILESWIDE) - 1;\r
-       originytilemax = (originytile + PORTTILESHIGH) - 1;\r
-       inactivateleft = originxtile - INACTIVATEDIST;\r
-       if (inactivateleft < 0)\r
-       {\r
-               inactivateleft = 0;\r
-       }\r
-       inactivateright = originxtilemax + INACTIVATEDIST;\r
-       if (inactivateright < 0)\r
-       {\r
-               inactivateright = 0;\r
-       }\r
-       inactivatetop = originytile - INACTIVATEDIST;\r
-       if (inactivatetop < 0)\r
-       {\r
-               inactivatetop = 0;\r
-       }\r
-       inactivatebottom = originytilemax + INACTIVATEDIST;\r
-       if (inactivatebottom < 0)\r
-       {\r
-               inactivatebottom = 0;\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-==================\r
-=\r
-= ScrollScreen\r
-=\r
-= Scroll if Keen is nearing an edge\r
-= Set playstate to ex_completes\r
-=\r
-==================\r
-*/\r
-\r
-void ScrollScreen(objtype *ob)\r
-{\r
-       Sint16 xscroll, yscroll, pix, speed;\r
-       Uint16 bottom;\r
-\r
-       if (keenkilled)\r
-               return;\r
-\r
-//\r
-// walked off edge of map?\r
-//\r
-       if (ob->left < originxmin || ob->right > originxmax + 320*PIXGLOBAL)\r
-       {\r
-               playstate = ex_completed;\r
-               return;\r
-       }\r
-\r
-//\r
-// fallen off bottom of world?\r
-//\r
-       if (ob->bottom > originymax + 13*TILEGLOBAL)\r
-       {\r
-               ob->y -= ob->bottom - (originymax + 13*TILEGLOBAL);\r
-               SD_PlaySound(SND_PLUMMET);\r
-               godmode = false;\r
-               KillKeen();\r
-               return;\r
-       }\r
-\r
-       xscroll=yscroll=0;\r
-\r
-       if (ob->x < originxglobal + 9*TILEGLOBAL)\r
-       {\r
-               xscroll = ob->x - (originxglobal + 9*TILEGLOBAL);\r
-       }\r
-       else if (ob->x > originxglobal + 12*TILEGLOBAL)\r
-       {\r
-               xscroll = ob->x - (originxglobal + 12*TILEGLOBAL);\r
-       }\r
-\r
-       if (ob->state == &s_keenlookup2)\r
-       {\r
-               if (centerlevel+tics > 167)\r
-               {\r
-                       pix = 167-centerlevel;\r
-               }\r
-               else\r
-               {\r
-                       pix = tics;\r
-               }\r
-               centerlevel += pix;\r
-               yscroll = CONVERT_PIXEL_TO_GLOBAL(-pix);\r
-       }\r
-       else if (ob->state == &s_keenlookdown3)\r
-       {\r
-               if (centerlevel-tics < 33)\r
-               {\r
-                       pix = centerlevel + -33;\r
-               }\r
-               else\r
-               {\r
-                       pix = tics;\r
-               }\r
-               centerlevel -= pix;\r
-               yscroll = CONVERT_PIXEL_TO_GLOBAL(pix);\r
-       }\r
-\r
-#ifdef KEEN6\r
-       if (groundslam)\r
-       {\r
-               static Sint16 shaketable[] = {0,\r
-                        -64,  -64,  -64,  64,  64,  64,\r
-                       -200, -200, -200, 200, 200, 200,\r
-                       -250, -250, -250, 250, 250, 250,\r
-                       -250, -250, -250, 250, 250, 250\r
-               };\r
-               yscroll = yscroll + (bottom - (ob->bottom + shaketable[groundslam]));   // BUG: 'bottom' has not been initialized yet!\r
-       }\r
-       else\r
-#endif\r
-       if ( (ob->hitnorth || !ob->needtoclip || ob->state == &s_keenholdon))\r
-       {\r
-               if (  ob->state != &s_keenclimbup\r
-                       && ob->state != &s_keenclimbup2\r
-                       && ob->state != &s_keenclimbup3\r
-                       && ob->state != &s_keenclimbup4)\r
-               {\r
-                       yscroll += ob->ymove;\r
-                       bottom = originyglobal + yscroll + CONVERT_PIXEL_TO_GLOBAL(centerlevel);\r
-                       if (ob->bottom == bottom)\r
-                       {\r
-                               // player didn't move, no additional scrolling\r
-                       }\r
-                       else\r
-                       {\r
-                               if (ob->bottom < bottom)\r
-                               {\r
-                                       pix = bottom - ob->bottom;\r
-                               }\r
-                               else\r
-                               {\r
-                                       pix = ob->bottom - bottom;\r
-                               }\r
-                               speed = CONVERT_PIXEL_TO_GLOBAL(pix) >> 7;\r
-                               if (speed > 0x30)\r
-                               {\r
-                                       speed = 0x30;\r
-                               }\r
-                               speed *= tics;\r
-                               if (speed < 0x10)\r
-                               {\r
-                                       if (pix < 0x10)\r
-                                       {\r
-                                               speed = pix;\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               speed = 0x10;\r
-                                       }\r
-                               }\r
-                               if (ob->bottom < bottom)\r
-                               {\r
-                                       yscroll -= speed;\r
-                               }\r
-                               else\r
-                               {\r
-                                       yscroll += speed;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       else\r
-       {\r
-               centerlevel = 140;\r
-       }\r
-\r
-       pix = (ob->bottom-32*PIXGLOBAL)-(originyglobal+yscroll);\r
-       if (pix < 0)\r
-       {\r
-               yscroll += pix;\r
-       }\r
-       pix = (ob->bottom+32*PIXGLOBAL)-(originyglobal+yscroll+200*PIXGLOBAL);\r
-       if (pix > 0)\r
-       {\r
-               yscroll += pix;\r
-       }\r
-\r
-       if (xscroll == 0 && yscroll == 0)\r
-               return;\r
-\r
-//\r
-// don't scroll more than one tile per frame\r
-//\r
-       if (xscroll >= 0x100)\r
-       {\r
-               xscroll = 0xFF;\r
-       }\r
-       else if (xscroll <= -0x100)\r
-       {\r
-               xscroll = -0xFF;\r
-       }\r
-       if (yscroll >= 0x100)\r
-       {\r
-               yscroll = 0xFF;\r
-       }\r
-       else if (yscroll <= -0x100)\r
-       {\r
-               yscroll = -0xFF;\r
-       }\r
-       RF_Scroll(xscroll, yscroll);\r
-\r
-//\r
-// update limits for onscreen and inactivate checks\r
-//\r
-       originxtilemax = (originxtile + PORTTILESWIDE) - 1;\r
-       originytilemax = (originytile + PORTTILESHIGH) - 1;\r
-       inactivateleft = originxtile - INACTIVATEDIST;\r
-       if (inactivateleft < 0)\r
-       {\r
-               inactivateleft = 0;\r
-       }\r
-       inactivateright = originxtilemax + INACTIVATEDIST;\r
-       if (inactivateright < 0)\r
-       {\r
-               inactivateright = 0;\r
-       }\r
-       inactivatetop = originytile - INACTIVATEDIST;\r
-       if (inactivatetop < 0)\r
-       {\r
-               inactivatetop = 0;\r
-       }\r
-       inactivatebottom = originytilemax + INACTIVATEDIST;\r
-       if (inactivatebottom < 0)\r
-       {\r
-               inactivatebottom = 0;\r
-       }\r
-}\r
-\r
-//===========================================================================\r
-\r
-\r
-/*\r
-#############################################################################\r
-\r
-                                 The objarray data structure\r
-\r
-#############################################################################\r
-\r
-Objarray contains structures for every actor currently playing.  The structure\r
-is accessed as a linked list starting at *player, ending when ob->next ==\r
-NULL.  GetNewObj inserts a new object at the end of the list, meaning that\r
-if an actor spawns another actor, the new one WILL get to think and react the\r
-same frame.  RemoveObj unlinks the given object and returns it to the free\r
-list, but does not damage the objects ->next pointer, so if the current object\r
-removes itself, a linked list following loop can still safely get to the\r
-next element.\r
-\r
-<backwardly linked free list>\r
-\r
-#############################################################################\r
-*/\r
-\r
-\r
-/*\r
-=========================\r
-=\r
-= InitObjArray\r
-=\r
-= Call to clear out the entire object list, returning them all to the free\r
-= list.  Allocates a special spot for the player.\r
-=\r
-=========================\r
-*/\r
-\r
-void InitObjArray(void)\r
-{\r
-       Sint16 i;\r
-\r
-       for (i=0; i<MAXACTORS; i++)\r
-       {\r
-               objarray[i].prev = &objarray[i+1];\r
-               objarray[i].next = NULL;\r
-       }\r
-\r
-       objarray[MAXACTORS-1].prev = NULL;\r
-\r
-       objfreelist = &objarray[0];\r
-       lastobj = NULL;\r
-\r
-       objectcount = 0;\r
-\r
-//\r
-// give the player and score the first free spots\r
-//\r
-       GetNewObj(false);\r
-       player = new;\r
-       GetNewObj(false);\r
-       scoreobj = new;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=========================\r
-=\r
-= GetNewObj\r
-=\r
-= Sets the global variable new to point to a free spot in objarray.\r
-= The free spot is inserted at the end of the liked list\r
-=\r
-= When the object list is full, the caller can either have it bomb out or\r
-= return a dummy object pointer that will never get used\r
-=\r
-= Returns -1 when list was full, otherwise returns 0.\r
-=\r
-=========================\r
-*/\r
-\r
-Sint16 GetNewObj(boolean usedummy)\r
-{\r
-       if (!objfreelist)\r
-       {\r
-               if (usedummy)\r
-               {\r
-                       new = &dummyobj;\r
-                       return -1;\r
-               }\r
-               Quit("GetNewObj: No free spots in objarray!");\r
-       }\r
-       new = objfreelist;\r
-       objfreelist = new->prev;\r
-       memset(new, 0, sizeof(*new));\r
-       if (lastobj)\r
-       {\r
-               lastobj->next = new;\r
-       }\r
-       new->prev = lastobj;    // new->next is allready NULL from memset\r
-\r
-       new->active = ac_yes;\r
-       new->needtoclip = cl_midclip;\r
-       lastobj = new;\r
-\r
-       objectcount++;\r
-       return 0;\r
-}\r
-\r
-//===========================================================================\r
-\r
-/*\r
-=========================\r
-=\r
-= RemoveObj\r
-=\r
-= Add the given object back into the free list, and unlink it from it's\r
-= neighbors\r
-=\r
-=========================\r
-*/\r
-\r
-void RemoveObj(objtype *ob)\r
-{\r
-       if (ob == player)\r
-               Quit("RemoveObj: Tried to remove the player!");\r
-\r
-//\r
-// erase it from the refresh manager\r
-//\r
-       RF_RemoveSprite(&ob->sprite);\r
-       if (ob->obclass == stunnedobj)\r
-       {\r
-               RF_RemoveSprite((void **)&ob->temp3);\r
-       }\r
-\r
-//\r
-// fix the next object's back link\r
-//\r
-       if (ob == lastobj)\r
-       {\r
-               lastobj = ob->prev;\r
-       }\r
-       else\r
-       {\r
-               ob->next->prev = ob->prev;\r
-       }\r
-\r
-//\r
-// fix the previous object's forward link\r
-//\r
-       ob->prev->next = ob->next;\r
-\r
-//\r
-// add it back in to the free list\r
-//\r
-       ob->prev = objfreelist;\r
-       objfreelist = ob;\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-====================\r
-=\r
-= GivePoints\r
-=\r
-= Grants extra men at 20k,40k,80k,160k,320k\r
-=\r
-====================\r
-*/\r
-\r
-void GivePoints(Uint16 points)\r
-{\r
-       gamestate.score += points;\r
-       if (!DemoMode && gamestate.score >= gamestate.nextextra)\r
-       {\r
-               SD_PlaySound(SND_EXTRAKEEN);\r
-               gamestate.lives++;\r
-               gamestate.nextextra *= 2;\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-===================\r
-=\r
-= PollControls\r
-=\r
-===================\r
-*/\r
-\r
-void PollControls(void)\r
-{\r
-       IN_ReadControl(0, &c);\r
-       if (c.yaxis != -1)\r
-               upheld = false;\r
-\r
-       if (GravisGamepad && !DemoMode)\r
-       {\r
-               jumpbutton = GravisAction[ga_Jump];\r
-               pogobutton = GravisAction[ga_Pogo];\r
-               firebutton = GravisAction[ga_Fire];\r
-               if (!jumpbutton)\r
-                       jumpheld = false;\r
-               if (!pogobutton)\r
-                       pogoheld = false;\r
-               if (!firebutton)\r
-                       fireheld = false;\r
-       }\r
-       else if (oldshooting || DemoMode)\r
-       {\r
-               if (c.button0 && c.button1)\r
-               {\r
-                       firebutton = true;\r
-                       jumpbutton = pogobutton = jumpheld = pogoheld = false;\r
-               }\r
-               else\r
-               {\r
-                       firebutton = fireheld = false;\r
-                       if (c.button0)\r
-                       {\r
-                               jumpbutton = true;\r
-                       }\r
-                       else\r
-                       {\r
-                               jumpbutton = jumpheld = false;\r
-                       }\r
-                       if (c.button1)\r
-                       {\r
-                               if (oldfirecount <= 8)\r
-                               {\r
-                                       oldfirecount = oldfirecount + tics;\r
-                               }\r
-                               else\r
-                               {\r
-                                       pogobutton = true;\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               if (oldfirecount != 0)\r
-                               {\r
-                                       pogobutton = true;\r
-                               }\r
-                               else\r
-                               {\r
-                                       pogobutton = pogoheld = false;\r
-                               }\r
-                               oldfirecount = 0;\r
-                       }\r
-               }\r
-       }\r
-       else\r
-       {\r
-               jumpbutton = c.button0;\r
-               pogobutton = c.button1;\r
-               firebutton = Keyboard[firescan];\r
-               if (!jumpbutton)\r
-                       jumpheld = false;\r
-               if (!pogobutton)\r
-                       pogoheld = false;\r
-               if (!firebutton)\r
-                       fireheld = false;\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-=================\r
-=\r
-= StopMusic\r
-=\r
-=================\r
-*/\r
-\r
-void StopMusic(void)\r
-{\r
-       Sint16 i;\r
-\r
-       SD_MusicOff();\r
-       for (i=0; i<LASTMUSIC; i++)\r
-       {\r
-               if (audiosegs[STARTMUSIC+i])\r
-               {\r
-#ifdef FIX_MUSIC_MEMORY_ISSUES\r
-                       //unlock any music blocks so that they can be purged\r
-                       MM_SetLock(&(memptr)audiosegs[STARTMUSIC+i], false);\r
-#endif\r
-                       MM_SetPurge(&(memptr)audiosegs[STARTMUSIC+i], PURGE_FIRST);\r
-               }\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-/*\r
-=================\r
-=\r
-= StartMusic\r
-=\r
-=================\r
-*/\r
-\r
-void StartMusic(Uint16 num)\r
-{\r
-       static Sint16 songs[] =\r
-       {\r
-#if defined KEEN4\r
-               SHADOWS_MUS,\r
-               KICKPANT_MUS,\r
-               OASIS_MUS,\r
-               OASIS_MUS,\r
-               TOOHOT_MUS,\r
-               TOOHOT_MUS,\r
-               KICKPANT_MUS,\r
-               OASIS_MUS,\r
-               VEGGIES_MUS,\r
-               VEGGIES_MUS,\r
-               VEGGIES_MUS,\r
-               TOOHOT_MUS,\r
-               TOOHOT_MUS,\r
-               TOOHOT_MUS,\r
-               TOOHOT_MUS,\r
-               TOOHOT_MUS,\r
-               TOOHOT_MUS,\r
-               VEGGIES_MUS,\r
-               OASIS_MUS,\r
-               -1\r
-#elif defined KEEN5\r
-               ROBOROCK_MUS,\r
-               WEDNESDY_MUS,\r
-               BREATHE_MUS,\r
-               SPHEREFUL_MUS,\r
-               TIGHTER_MUS,\r
-               SPHEREFUL_MUS,\r
-               TIGHTER_MUS,\r
-               SPHEREFUL_MUS,\r
-               TIGHTER_MUS,\r
-               SPHEREFUL_MUS,\r
-               TIGHTER_MUS,\r
-               SNOOPING_MUS,\r
-               FEARSOME_MUS,\r
-               BAGPIPES_MUS,\r
-               FANFARE_MUS,\r
-               SKATING_MUS,\r
-               ROCK_ME_MUS,\r
-               HAVING_T_MUS,\r
-               CAMEIN_MUS,\r
-               SHIKAIRE_MUS,\r
-#elif defined KEEN6\r
-               ALIENATE_MUS,\r
-               FASTER_MUS,\r
-               BRERTAR_MUS,\r
-               MAMSNAKE_MUS,\r
-               MAMSNAKE_MUS,\r
-               MAMSNAKE_MUS,\r
-               METAL_MUS,\r
-               TOFUTURE_MUS,\r
-               METAL_MUS,\r
-               BRERTAR_MUS,\r
-               FASTER_MUS,\r
-               TOFUTURE_MUS,\r
-               BRERTAR_MUS,\r
-               SPACFUNK_MUS,\r
-               SPACFUNK_MUS,\r
-               OMINOUS_MUS,\r
-               TOFUTURE_MUS,\r
-               WONDER_MUS,\r
-               WONDER_MUS,\r
-               WONDER_MUS\r
-#endif\r
-       };\r
-\r
-       Sint16 song;\r
-       boolean wasfaded;\r
-\r
-       if (num >= ARRAYLENGTH(songs) && num != 0xFFFF)\r
-       {\r
-               Quit("StartMusic() - bad level number");\r
-       }\r
-\r
-#ifdef FIX_MUSIC_MEMORY_ISSUES\r
-       StopMusic();\r
-#else\r
-       SD_MusicOff();\r
-#endif\r
-\r
-#ifdef KEEN4\r
-       if (num == 0xFFFF)\r
-       {\r
-               song = WONDER_MUS;\r
-       }\r
-       else\r
-       {\r
-               song = songs[num];\r
-       }\r
-#else\r
-       song = songs[num];\r
-#endif\r
-\r
-       if (song == -1 || MusicMode != smm_AdLib)\r
-       {\r
-               return;\r
-       }\r
-\r
-       MM_BombOnError(false);\r
-       CA_CacheAudioChunk(STARTMUSIC+song);\r
-       MM_BombOnError(true);\r
-       if (mmerror)\r
-       {\r
-               mmerror = false;\r
-               if (!DemoMode)\r
-               {\r
-                       US_CenterWindow(20, 8);\r
-                       PrintY += 20;\r
-                       US_CPrint("Insufficient memory\nfor background music!");\r
-                       VW_UpdateScreen();\r
-                       wasfaded = screenfaded;\r
-                       if (wasfaded)\r
-                       {\r
-                               VW_SetDefaultColors();\r
-                       }\r
-                       IN_ClearKeysDown();\r
-                       IN_UserInput(3*TickBase, false);\r
-                       if (wasfaded)\r
-                       {\r
-                               VW_FadeOut();\r
-                       }\r
-               }\r
-       }\r
-       else\r
-       {\r
-#ifdef FIX_MUSIC_MEMORY_ISSUES\r
-               //The current music should be locked, so the memory manager will not\r
-               //mess with it when compressing memory blocks in MM_SortMem().\r
-               MM_SetLock(&(memptr)audiosegs[STARTMUSIC+song], true);\r
-#endif\r
-               SD_StartMusic((MusicGroup far *)audiosegs[STARTMUSIC+song]);\r
-       }\r
-}\r
-\r
-//==========================================================================\r
-\r
-\r
-/*\r
-===================\r
-=\r
-= PlayLoop\r
-=\r
-===================\r
-*/\r
-\r
-void PlayLoop(void)\r
-{\r
-       objtype *check;\r
-\r
-       StartMusic(gamestate.mapon);\r
-       fireheld = pogoheld = upheld = jumpheld = false;\r
-       ingame = true;\r
-       playstate = ex_stillplaying;\r
-       invincible = keenkilled = oldfirecount = 0;\r
-\r
-       CenterActor(player);\r
-\r
-       if (DemoMode)\r
-       {\r
-               US_InitRndT(false);\r
-       }\r
-       else\r
-       {\r
-               US_InitRndT(true);\r
-       }\r
-       TimeCount = lasttimecount = tics = 3;\r
-\r
-       do\r
-       {\r
-               PollControls();\r
-\r
-//\r
-// go through state changes and propose movements\r
-//\r
-               for (obj=player; obj; obj=obj->next)\r
-               {\r
-                       if (!obj->active && obj->tileright >= originxtile-1\r
-                               && obj->tileleft <= originxtilemax+1 && obj->tiletop <= originytilemax+1\r
-                               && obj->tilebottom >= originytile-1)\r
-                       {\r
-                               obj->needtoreact = true;\r
-                               obj->active = ac_yes;\r
-                       }\r
-                       if (obj->active)\r
-                       {\r
-                               if (obj->tileright < inactivateleft\r
-                                       || obj->tileleft > inactivateright\r
-                                       || obj->tiletop > inactivatebottom\r
-                                       || obj->tilebottom < inactivatetop)\r
-                               {\r
-                                       if (obj->active == ac_removable)\r
-                                       {\r
-                                               RemoveObj(obj);\r
-                                               continue;\r
-                                       }\r
-                                       else if (obj->active != ac_allways)\r
-                                       {\r
-                                               if (US_RndT() < tics*2 || screenfaded || loadedgame)\r
-                                               {\r
-                                                       RF_RemoveSprite(&obj->sprite);\r
-                                                       if (obj->obclass == stunnedobj)\r
-                                                               RF_RemoveSprite((void **)&obj->temp3);\r
-                                                       obj->active = ac_no;\r
-                                                       continue;\r
-                                               }\r
-                                       }\r
-                               }\r
-                               StateMachine(obj);\r
-                       }\r
-               }\r
-\r
-               if (gamestate.riding)\r
-               {\r
-                       HandleRiding(player);\r
-               }\r
-\r
-//\r
-// check for and handle collisions between objects\r
-//\r
-               for (obj=player; obj; obj=obj->next)\r
-               {\r
-                       if (obj->active)\r
-                       {\r
-                               for (check=obj->next; check; check=check->next)\r
-                               {\r
-                                       if (!check->active)\r
-                                       {\r
-                                               continue;\r
-                                       }\r
-                                       if (obj->right > check->left && obj->left < check->right\r
-                                               && obj->top < check->bottom && obj->bottom > check->top)\r
-                                       {\r
-                                               if (obj->state->contact)\r
-                                               {\r
-                                                       obj->state->contact(obj, check);\r
-                                               }\r
-                                               if (check->state->contact)\r
-                                               {\r
-                                                       check->state->contact(check, obj);\r
-                                               }\r
-                                               if (obj->obclass == nothing)    //useless -- obclass is NOT set to nothing by RemoveObj\r
-                                               {\r
-                                                       break;\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-\r
-//\r
-// check intiles\r
-//\r
-               if (mapon != 0)\r
-               {\r
-                       CheckInTiles(player);\r
-               }\r
-               else\r
-               {\r
-                       CheckWorldInTiles(player);\r
-               }\r
-\r
-//\r
-// react to whatever happened, and post sprites to the refresh manager\r
-//\r
-               for (obj=player; obj; obj=obj->next)\r
-               {\r
-                       if (!obj->active)\r
-                       {\r
-                               continue;\r
-                       }\r
-                       if (obj->tilebottom >= mapheight-1)\r
-                       {\r
-                               if (obj->obclass == keenobj)\r
-                               {\r
-                                       playstate = ex_died;\r
-                               }\r
-                               else\r
-                               {\r
-                                       RemoveObj(obj);\r
-                               }\r
-                               continue;\r
-                       }\r
-                       if (obj->needtoreact && obj->state->react)\r
-                       {\r
-                               obj->needtoreact = false;\r
-                               obj->state->react(obj);\r
-                       }\r
-               }\r
-\r
-//\r
-// scroll the screen and update the score box\r
-//\r
-#ifdef KEEN4\r
-               if (mapon != 0 && mapon != 17)\r
-#else\r
-               if (mapon != 0)\r
-#endif\r
-               {\r
-                       ScrollScreen(player);\r
-               }\r
-               else\r
-               {\r
-                       WorldScrollScreen(player);\r
-               }\r
-               UpdateScore(scoreobj);\r
-               if (loadedgame)\r
-               {\r
-                       loadedgame = false;\r
-               }\r
-\r
-//\r
-// update the screen and calculate the number of tics it took to execute\r
-// this cycle of events (for adaptive timing of next cycle)\r
-//\r
-               RF_Refresh();\r
-\r
-               if (invincible)\r
-               {\r
-                       if ((invincible = invincible - tics) < 0)\r
-                               invincible = 0;\r
-               }\r
-\r
-#ifdef KEEN6\r
-               if (groundslam)\r
-               {\r
-                       if ((groundslam = groundslam - tics) < 0)\r
-                               groundslam = 0;\r
-               }\r
-#endif\r
-//\r
-// single step debug mode\r
-//\r
-               if (singlestep)\r
-               {\r
-                       VW_WaitVBL(14); //reduces framerate to 5 fps on VGA or 4.3 fps on EGA cards\r
-                       lasttimecount = TimeCount;\r
-               }\r
-//\r
-// extra VBLs debug mode\r
-//\r
-               if (extravbls)\r
-               {\r
-                       VW_WaitVBL(extravbls);\r
-               }\r
-\r
-//\r
-// handle user inputs\r
-//\r
-               if (DemoMode == demo_Playback)\r
-               {\r
-                       if (!screenfaded && IN_IsUserInput())\r
-                       {\r
-                               playstate = ex_completed;\r
-                               if (LastScan != sc_F1)\r
-                               {\r
-                                       LastScan = sc_Space;\r
-                               }\r
-                       }\r
-               }\r
-               else if (DemoMode == demo_PlayDone)\r
-               {\r
-                       playstate = ex_completed;\r
-               }\r
-               else\r
-               {\r
-                       CheckKeys();\r
-               }\r
-\r
-//\r
-// E-N-D cheat\r
-//\r
-               if (Keyboard[sc_E] && Keyboard[sc_N] && Keyboard[sc_D])\r
-               {\r
-#if defined KEEN4\r
-                       gamestate.rescued = 7;\r
-                       playstate = ex_rescued;\r
-#elif defined KEEN5\r
-                       playstate = ex_qedbroke;\r
-#elif defined KEEN6\r
-                       playstate = ex_molly;\r
-#endif\r
-               }\r
-\r
-       } while (playstate == ex_stillplaying);\r
-\r
-       ingame = false;\r
-       StopMusic();\r
-}
\ No newline at end of file