-/* 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
-K5_SPEC.C\r
-=========\r
-\r
-Contains (in this order):\r
-\r
-- lump definition\r
-- "Star Wars" crawl text\r
-- level names & messages\r
-- Airlock opening & closing code\r
-- ScanInfoPlane() - for spawning the level objects and marking required sprites\r
-- game over animation\r
-- messages for breaking fuses\r
-*/\r
-\r
-#include "CK_DEF.H"\r
-\r
-enum {\r
- HELP_LUMP, // 0\r
- CONTROLS_LUMP, // 1\r
- KEENTALK_LUMP, // 2\r
- LOADING_LUMP, // 3\r
- PADDLE_LUMP, // 4\r
- KEEN_LUMP, // 5\r
- SUGAR1_LUMP, // 6\r
- SUGAR2_LUMP, // 7\r
- SUGAR3_LUMP, // 8\r
- SUGAR4_LUMP, // 9\r
- SUGAR5_LUMP, // 10\r
- SUGAR6_LUMP, // 11\r
- ONEUP_LUMP, // 12\r
- KEYGEM_LUMP, // 13\r
- AMMO_LUMP, // 14\r
- LASER_LUMP, // 15\r
- WORLDKEEN_LUMP, // 16\r
- MASTER_LUMP, // 17\r
- SHIKADI_LUMP, // 18\r
- SHOCKSHUND_LUMP, // 19\r
- SPHEREFUL_LUMP, // 20\r
- SPARKY_LUMP, // 21\r
- MINE_LUMP, // 22\r
- SLICESTAR_LUMP, // 23\r
- ROBORED_LUMP, // 24\r
- SPIRO_LUMP, // 25\r
- AMPTON_LUMP, // 26\r
- VOLTE_LUMP, // 27\r
- SLOTPLAT_LUMP, // 28\r
- SPINDRED_LUMP, // 29\r
- SHELLEY_LUMP, // 30\r
- PLATFORM_LUMP, // 31\r
- SMALLPLAT_LUMP, // 32\r
- KEYCARD_LUMP, // 33\r
- SCOTTIE_LUMP, // 34\r
- FUSE_LUMP, // 35\r
- STAREXPLODE_LUMP, // 36\r
- TELEPORT_LUMP, // 37\r
-\r
- NUMLUMPS=42 // Keen 5 has 4 unused lumps at the end\r
-};\r
-\r
-Uint16 lumpstart[NUMLUMPS] = {\r
- HELP_LUMP_START,\r
- CONTROLS_LUMP_START,\r
- KEENTALK_LUMP_START,\r
- LOADING_LUMP_START,\r
- PADDLE_LUMP_START,\r
- KEEN_LUMP_START,\r
- SUGAR1_LUMP_START,\r
- SUGAR2_LUMP_START,\r
- SUGAR3_LUMP_START,\r
- SUGAR4_LUMP_START,\r
- SUGAR5_LUMP_START,\r
- SUGAR6_LUMP_START,\r
- ONEUP_LUMP_START,\r
- KEYGEM_LUMP_START,\r
- AMMO_LUMP_START,\r
- LASER_LUMP_START,\r
- WORLDKEEN_LUMP_START,\r
- MASTER_LUMP_START,\r
- SHIKADI_LUMP_START,\r
- SHOCKSHUND_LUMP_START,\r
- SPHEREFUL_LUMP_START,\r
- SPARKY_LUMP_START,\r
- MINE_LUMP_START,\r
- SLICESTAR_LUMP_START,\r
- ROBORED_LUMP_START,\r
- SPIRO_LUMP_START,\r
- AMPTON_LUMP_START,\r
- VOLTE_LUMP_START,\r
- SLOTPLAT_LUMP_START,\r
- SPINDRED_LUMP_START,\r
- SHELLEY_LUMP_START,\r
- PLATFORM_LUMP_START,\r
- MINIPLAT_LUMP_START,\r
- KEYCARD_LUMP_START,\r
- SCOTTIE_LUMP_START,\r
- FUSE_LUMP_START,\r
- STAREXPLODE_LUMP_START,\r
- TELEPORT_LUMP_START\r
-};\r
-\r
-Uint16 lumpend[NUMLUMPS] = {\r
- HELP_LUMP_END,\r
- CONTROLS_LUMP_END,\r
- KEENTALK_LUMP_END,\r
- LOADING_LUMP_END,\r
- PADDLE_LUMP_END,\r
- KEEN_LUMP_END,\r
- SUGAR1_LUMP_END,\r
- SUGAR2_LUMP_END,\r
- SUGAR3_LUMP_END,\r
- SUGAR4_LUMP_END,\r
- SUGAR5_LUMP_END,\r
- SUGAR6_LUMP_END,\r
- ONEUP_LUMP_END,\r
- KEYGEM_LUMP_END,\r
- AMMO_LUMP_END,\r
- LASER_LUMP_END,\r
- WORLDKEEN_LUMP_END,\r
- MASTER_LUMP_END,\r
- SHIKADI_LUMP_END,\r
- SHOCKSHUND_LUMP_END,\r
- SPHEREFUL_LUMP_END,\r
- SPARKY_LUMP_END,\r
- MINE_LUMP_END,\r
- SLICESTAR_LUMP_END,\r
- ROBORED_LUMP_END,\r
- SPIRO_LUMP_END,\r
- AMPTON_LUMP_END,\r
- VOLTE_LUMP_END,\r
- SLOTPLAT_LUMP_END,\r
- SPINDRED_LUMP_END,\r
- SHELLEY_LUMP_END,\r
- PLATFORM_LUMP_END,\r
- MINIPLAT_LUMP_END,\r
- KEYCARD_LUMP_END,\r
- SCOTTIE_LUMP_END,\r
- FUSE_LUMP_END,\r
- STAREXPLODE_LUMP_END,\r
- TELEPORT_LUMP_END\r
-};\r
-\r
-boolean lumpneeded[NUMLUMPS];\r
-\r
-#if GRMODE == EGAGR\r
-\r
-char far swtext[] =\r
- "Episode Five\n"\r
- "\n"\r
- "The Armageddon Machine\n"\r
- "\n"\r
- "After learning the\n"\r
- "location of the secret\n"\r
- "Shikadi base, Keen\n"\r
- "jumped in the trusty\n"\r
- "Bean-with-Bacon\n"\r
- "Megarocket and blasted\n"\r
- "across interstellar\n"\r
- "space.\n"\r
- "\n"\r
- "Seventy-five furious\n"\r
- "games of Paddle War\n"\r
- "later, Keen dropped\n"\r
- "out of lightspeed near\n"\r
- " the Korath system.\n"\r
- "\n"\r
- "He flew toward the\n"\r
- "planet, keeping it\n"\r
- "between him and the\n"\r
- "base.\n"\r
- "\n"\r
- "Pulling up underside\n"\r
- "and docking at the\n"\r
- "Ion Ventilation System,\n"\r
- "Keen must destroy the\n"\r
- "Shikadi Armageddon\n"\r
- "Machine before it\n"\r
- "explodes and destroys\n"\r
- "the Milky Way! He\n"\r
- "steps into the dark\n"\r
- "ventilation duct and\n"\r
- "begins his most\n"\r
- "dangerous adventure\n"\r
- "yet...\n";\r
-\r
-#endif\r
-\r
-char far l0n[] = "Omegamatic";\r
-char far l1n[] = "Ion Ventilation System";\r
-char far l2n[] = "Security Center";\r
-char far l3n[] = "Defense Tunnel Vlook";\r
-char far l4n[] = "Energy Flow Systems";\r
-char far l5n[] = "Defense Tunnel Burrh";\r
-char far l6n[] = "Regulation\nControl Center";\r
-char far l7n[] = "Defense Tunnel Sorra";\r
-char far l8n[] = "Neutrino\nBurst Injector";\r
-char far l9n[] = "Defense Tunnel Teln";\r
-char far l10n[] = "Brownian\nMotion Inducer";\r
-char far l11n[] = "Gravitational\nDamping Hub";\r
-char far l12n[] = "Quantum\nExplosion Dynamo";\r
-char far l13n[] = "Korath III Base";\r
-char far l14n[] = "BWBMegarocket";\r
-char far l15n[] = "High Scores";\r
-\r
-char far l0e[] = "Keen purposefully\nwanders about the\nOmegamatic";\r
-char far l1e[] = "Keen investigates the\nIon Ventilation System";\r
-char far l2e[] = "Keen struts through\nthe Security Center";\r
-char far l3e[] = "Keen invades\nDefense Tunnel Vlook";\r
-char far l4e[] = "Keen engages\nEnergy Flow Systems";\r
-char far l5e[] = "Keen barrels into\nDefense Tunnel Burrh";\r
-char far l6e[] = "Keen goes nuts in\nthe Regulation\nControl Center";\r
-char far l7e[] = "Keen regrets entering\nDefense Tunnel Sorra";\r
-char far l8e[] = "Keen blows through\nthe Neutrino\nBurst Injector";\r
-char far l9e[] = "Keen trots through\nDefense Tunnel Teln";\r
-char far l10e[] = "Keen breaks into\nthe Brownian\nMotion Inducer";\r
-char far l11e[] = "Keen hurries through\nthe Gravitational\nDamping Hub";\r
-char far l12e[] = "Keen explodes into\nthe Quantum\nExplosion Dynamo";\r
-char far l13e[] = "Keen faces danger\nin the secret\nKorath III Base";\r
-char far l14e[] = "Keen will not be\nin the BWBMegarocket";\r
-char far l15e[] = "Keen unexplainedly\nfinds himself by\ntheHigh Scores"; // sic!\r
-\r
-char far *levelnames[GAMELEVELS] = {\r
- l0n,\r
- l1n,\r
- l2n,\r
- l3n,\r
- l4n,\r
- l5n,\r
- l6n,\r
- l7n,\r
- l8n,\r
- l9n,\r
- l10n,\r
- l11n,\r
- l12n,\r
- l13n,\r
- l14n,\r
- l15n\r
-};\r
-\r
-char far *levelenter[GAMELEVELS] = {\r
- l0e,\r
- l1e,\r
- l2e,\r
- l3e,\r
- l4e,\r
- l5e,\r
- l6e,\r
- l7e,\r
- l8e,\r
- l9e,\r
- l10e,\r
- l11e,\r
- l12e,\r
- l13e,\r
- l14e,\r
- l15e\r
-};\r
-\r
-Uint16 bonuslump[] = {\r
- KEYGEM_LUMP, KEYGEM_LUMP, KEYGEM_LUMP, KEYGEM_LUMP,\r
- SUGAR1_LUMP, SUGAR2_LUMP, SUGAR3_LUMP,\r
- SUGAR4_LUMP, SUGAR5_LUMP, SUGAR6_LUMP,\r
- ONEUP_LUMP, AMMO_LUMP, KEYCARD_LUMP, 0, 0\r
-};\r
-\r
-//============================================================================\r
-\r
-/*\r
-===========================\r
-=\r
-= OpenMapDoor\r
-=\r
-===========================\r
-*/\r
-\r
-void OpenMapDoor(Sint16 tileX, Sint16 tileY)\r
-{\r
- Sint16 x, y;\r
- Uint16 tiles[2][2];\r
-\r
- for (y=0; y<2; y++)\r
- {\r
- for (x=0; x<2; x++)\r
- {\r
- tiles[y][x] = *(mapsegs[1]+mapbwidthtable[y]/2 + x + 10);\r
- }\r
- }\r
- RF_MemToMap(&tiles[0][0], 1, tileX, tileY, 2, 2);\r
-}\r
-\r
-/*\r
-===========================\r
-=\r
-= CloseMapDoor\r
-=\r
-===========================\r
-*/\r
-\r
-void CloseMapDoor(Sint16 tileX, Sint16 tileY)\r
-{\r
- Sint16 x, y;\r
- Uint16 tiles[2][2];\r
-\r
- for (y=0; y<2; y++)\r
- {\r
- for (x=0; x<2; x++)\r
- {\r
- tiles[y][x] = *(mapsegs[1]+mapbwidthtable[y]/2 + x);\r
- }\r
- }\r
- RF_MemToMap(&tiles[0][0], 1, tileX, tileY, 2, 2);\r
-}\r
-\r
-//============================================================================\r
-\r
-/*\r
-==========================\r
-=\r
-= ScanInfoPlane\r
-=\r
-= Spawn all actors and mark down special places\r
-=\r
-==========================\r
-*/\r
-\r
-void ScanInfoPlane(void)\r
-{\r
- Uint16 i, x, y, chunk;\r
- Sint16 info;\r
- Uint16 far *map;\r
- objtype *ob;\r
-\r
- InitObjArray(); // start spawning things with a clean slate\r
-\r
- memset(lumpneeded, 0, sizeof(lumpneeded));\r
- gamestate.numfuses = 0;\r
-\r
- map = mapsegs[2];\r
-\r
- for (y=0; y<mapheight; y++)\r
- {\r
- for (x=0; x<mapwidth; x++)\r
- {\r
- info = *map++;\r
-\r
- if (info == 0)\r
- continue;\r
-\r
- switch (info)\r
- {\r
- case 1:\r
- SpawnKeen(x, y, 1);\r
- SpawnScore();\r
- lumpneeded[KEEN_LUMP] = true;\r
- CA_MarkGrChunk(SCOREBOXSPR);\r
- break;\r
-\r
- case 2:\r
- SpawnKeen(x, y, -1);\r
- SpawnScore();\r
- lumpneeded[KEEN_LUMP] = true;\r
- CA_MarkGrChunk(SCOREBOXSPR);\r
- break;\r
-\r
- case 3:\r
- SpawnScore();\r
- lumpneeded[WORLDKEEN_LUMP] = true;\r
- CA_MarkGrChunk(SCOREBOXSPR);\r
- if (playstate == ex_portout)\r
- break;\r
- SpawnWorldKeen(x, y);\r
- break;\r
-\r
- case 26:\r
- if (playstate != ex_portout)\r
- break;\r
- SpawnWorldKeenPort(x, y);\r
- break;\r
-\r
- case 6:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 5:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 4:\r
- SpawnSparky(x, y);\r
- lumpneeded[SPARKY_LUMP] = true;\r
- break;\r
-\r
- case 9:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 8:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 7:\r
- SpawnMine(x, y);\r
- lumpneeded[MINE_LUMP] = true;\r
- break;\r
-\r
- case 12:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 11:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 10:\r
- SpawnSlicestarSlide(x, y, 0);\r
- lumpneeded[SLICESTAR_LUMP] = true;\r
- break;\r
-\r
- case 15:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 14:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 13:\r
- SpawnRoboRed(x, y);\r
- lumpneeded[ROBORED_LUMP] = true;\r
- break;\r
-\r
- case 18:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 17:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 16:\r
- SpawnSpirogrip(x, y);\r
- lumpneeded[SPIRO_LUMP] = true;\r
- break;\r
-\r
- case 21:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 20:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 19:\r
- SpawnSlicestarBounce(x, y);\r
- lumpneeded[SLICESTAR_LUMP] = true;\r
- break;\r
-\r
- case 24:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 23:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 22:\r
- SpawnSlicestarSlide(x, y, 1);\r
- lumpneeded[SLICESTAR_LUMP] = true;\r
- break;\r
-\r
- case 25:\r
- RF_SetScrollBlock(x, y, true);\r
- break;\r
-\r
- // case 26 (teleported map keen) is handled above\r
-\r
- case 27:\r
- case 28:\r
- case 29:\r
- case 30:\r
- SpawnPlatform(x, y, info-27, 0);\r
- lumpneeded[PLATFORM_LUMP] = true;\r
- break;\r
-\r
- // case 31 is the block icon\r
-\r
- case 32:\r
- SpawnDropPlat(x, y);\r
- lumpneeded[PLATFORM_LUMP] = true;\r
- break;\r
-\r
- case 35:\r
- SpawnStaticPlat(x, y);\r
- lumpneeded[PLATFORM_LUMP] = true;\r
- break;\r
- case 34:\r
- if (gamestate.difficulty > gd_Normal)\r
- break;\r
- SpawnStaticPlat(x, y);\r
- lumpneeded[PLATFORM_LUMP] = true;\r
- break;\r
- case 33:\r
- if (gamestate.difficulty > gd_Easy)\r
- break;\r
- SpawnStaticPlat(x, y);\r
- lumpneeded[PLATFORM_LUMP] = true;\r
- break;\r
-\r
- case 36:\r
- case 37:\r
- case 38:\r
- case 39:\r
- SpawnGoPlat(x, y, info-36, 0);\r
- lumpneeded[PLATFORM_LUMP] = true;\r
- break;\r
-\r
- case 40:\r
- SpawnSneakPlat(x, y);\r
- lumpneeded[PLATFORM_LUMP] = true;\r
- break;\r
-\r
- case 41:\r
- if (gamestate.mapon == 12)\r
- {\r
- gamestate.numfuses = 4;\r
- SpawnQed(x, y);\r
- }\r
- else\r
- {\r
- gamestate.numfuses++;\r
- }\r
- lumpneeded[FUSE_LUMP] = true;\r
- break;\r
-\r
- case 44:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 43:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 42:\r
- SpawnAmpton(x, y);\r
- lumpneeded[AMPTON_LUMP] = true;\r
- break;\r
-\r
- case 53:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 49:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 45:\r
- SpawnCannon(x, y, 0);\r
- lumpneeded[LASER_LUMP] = true;\r
- break;\r
-\r
- case 54:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 50:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 46:\r
- SpawnCannon(x, y, 1);\r
- lumpneeded[LASER_LUMP] = true;\r
- break;\r
-\r
- case 55:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 51:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 47:\r
- SpawnCannon(x, y, 2);\r
- lumpneeded[LASER_LUMP] = true;\r
- break;\r
-\r
- case 56:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 52:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 48:\r
- SpawnCannon(x, y, 3);\r
- lumpneeded[LASER_LUMP] = true;\r
- break;\r
-\r
- case 69:\r
- if (gamestate.ammo >= 5)\r
- break;\r
- info = 68; // spawn ammo\r
- //no break here!\r
- case 57:\r
- case 58:\r
- case 59:\r
- case 60:\r
- case 61:\r
- case 62:\r
- case 63:\r
- case 64:\r
- case 65:\r
- case 66:\r
- case 67:\r
- case 68:\r
- SpawnBonus(x, y, info-57);\r
- lumpneeded[bonuslump[info-57]] = true;\r
- break;\r
- case 70:\r
- SpawnBonus(x, y, info-58);\r
- lumpneeded[bonuslump[info-58]] = true;\r
- break;\r
-\r
- case 73:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 72:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 71:\r
- SpawnVolte(x, y);\r
- lumpneeded[VOLTE_LUMP] = true;\r
- break;\r
-\r
- case 76:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 75:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 74:\r
- SpawnShelly(x, y);\r
- lumpneeded[SHELLEY_LUMP] = true;\r
- break;\r
-\r
- case 79:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 78:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 77:\r
- SpawnSpindread(x, y);\r
- lumpneeded[SPINDRED_LUMP] = true;\r
- break;\r
-\r
- case 80:\r
- case 81:\r
- case 82:\r
- case 83:\r
- SpawnGoPlat(x, y, info-80, 1);\r
- lumpneeded[SLOTPLAT_LUMP] = true;\r
- break;\r
-\r
- case 84:\r
- case 85:\r
- case 86:\r
- case 87:\r
- SpawnPlatform(x, y, info-84, 1);\r
- lumpneeded[SLOTPLAT_LUMP] = true;\r
- break;\r
-\r
- case 90:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 89:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 88:\r
- SpawnMaster(x, y);\r
- lumpneeded[MASTER_LUMP] = true;\r
- break;\r
-\r
- // cases 91 to 98 are direction arrows\r
-\r
- case 101:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 100:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 99:\r
- SpawnShikadi(x, y);\r
- lumpneeded[SHIKADI_LUMP] = true;\r
- break;\r
-\r
- case 104:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 103:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 102:\r
- SpawnPet(x, y);\r
- lumpneeded[SHOCKSHUND_LUMP] = true;\r
- break;\r
-\r
- case 107:\r
- if (gamestate.difficulty < gd_Hard)\r
- break;\r
- case 106:\r
- if (gamestate.difficulty < gd_Normal)\r
- break;\r
- case 105:\r
- SpawnSphereful(x, y);\r
- lumpneeded[SPHEREFUL_LUMP] = true;\r
- break;\r
-\r
- // cases 108 to 123 are wall collision icons for the WallDebug cheat\r
-\r
- case 124:\r
- SpawnScottie(x, y);\r
- lumpneeded[SCOTTIE_LUMP] = true;\r
- break;\r
-\r
- case 125:\r
- lumpneeded[TELEPORT_LUMP] = true;\r
-\r
- }\r
- }\r
- }\r
-\r
- for (ob = player; ob; ob = ob->next)\r
- {\r
- if (ob->active != ac_allways)\r
- ob->active = ac_no;\r
- }\r
-\r
- for (i = 0; i < NUMLUMPS; i++)\r
- {\r
- if (lumpneeded[i])\r
- {\r
- for (chunk = lumpstart[i]; chunk <= lumpend[i]; chunk++)\r
- {\r
- CA_MarkGrChunk(chunk);\r
- }\r
- }\r
- }\r
-\r
- // Keen 5 addition to PatchWorldMap (PatchWorldMap is shared across Keen 4-6)\r
- if (gamestate.mapon == 0)\r
- {\r
- info = CONVERT_GLOBAL_TO_TILE(player->y);\r
- if (info < 75 || info > 100)\r
- {\r
- CloseMapDoor(24, 76);\r
- OpenMapDoor(22, 55);\r
- }\r
- if (gamestate.leveldone[4] && gamestate.leveldone[6] && gamestate.leveldone[8] && gamestate.leveldone[10]\r
- && (info > 39 || info > 100) )\r
- {\r
- OpenMapDoor(26, 55);\r
- }\r
- if (info <= 39 || info > 100)\r
- {\r
- OpenMapDoor(24, 30);\r
- }\r
- }\r
-}\r
-\r
-/*\r
-=============================================================================\r
-\r
- GAME OVER SEQUENCE\r
-\r
-=============================================================================\r
-*/\r
-\r
-/*\r
-------------------------------------------------------------------------------\r
-The galaxy explosion chunk contains data in the following format:\r
-\r
-struct {\r
- Uint16 posx[4000];\r
- Uint16 velx[4000];\r
- Uint16 posy[4000];\r
- Uint16 vely[4000];\r
-};\r
-\r
-The values are stored as "fixed point" numbers (divide each number by 128 to\r
-get the amount in pixel units). The code in MoveStars basically does the\r
-following:\r
-\r
-1. set all pixels on the screen to black\r
-\r
-2. for each of the 4000 entries do:\r
-\r
-2.1 x := posx[i] + velx[i]\r
-\r
-2.2 if x (in pixels) is < 0 or > 320 then go to 2.8\r
-\r
-2.3 posx[i] := x\r
-\r
-2.4 y := posy[i] + vely[i]\r
-\r
-2.5 if y (in pixels) is < 0 or > 200 then go to 2.8\r
-\r
-2.6 posy[i] := y\r
-\r
-2.7 draw a white pixel at position (x, y) on the screen\r
-\r
-2.8 continue with the next entry\r
-\r
-------------------------------------------------------------------------------\r
-*/\r
-\r
-#if GRMODE == CGAGR\r
-\r
-Uint8 plotpixels[8] = {0xC0, 0x30, 0x0C, 0x03};\r
-\r
-/*\r
-===========================\r
-=\r
-= MoveStars CGA\r
-=\r
-===========================\r
-*/\r
-\r
-void MoveStars(void)\r
-{\r
- asm {\r
- mov ax, screenseg;\r
- mov es, ax;\r
- mov ds, word ptr grsegs + 2*GALAXY;\r
- mov cx, 2000h;\r
- xor ax, ax;\r
- xor di, di;\r
- rep stosw;\r
- mov si, 7998;\r
- }\r
-l1:\r
- asm {\r
- mov ax, [si]; // get posx\r
- add ax, [si+8000]; // add velx\r
- cmp ax, 40960; // check if new posx is on screen\r
- ja l2;\r
- mov [si], ax; // set new posx\r
- mov bx, [si+16000]; // get posy\r
- add bx, [si+24000]; // add vely\r
- cmp bx, 25600; // check if new posy is on screen\r
- ja l2;\r
- mov [si+16000], bx; // set new posy\r
- mov cl, 7;\r
- shr bx, cl;\r
- shl bx, 1;\r
- mov di, word ptr ss:ylookup[bx];\r
- mov bx, ax;\r
- mov cl, 9;\r
- shr ax, cl;\r
- add di, ax;\r
- mov cl, 7;\r
- shr bx, cl;\r
- and bx, 3;\r
- mov al, BYTE PTR ss:plotpixels[bx];\r
- or es:[di], al; // draw the pixel\r
- }\r
-l2:\r
- asm {\r
- sub si, 2;\r
- jns l1;\r
- mov ax, ss;\r
- mov ds, ax;\r
- }\r
-}\r
-\r
-/*\r
-===========================\r
-=\r
-= GameOver CGA\r
-=\r
-===========================\r
-*/\r
-\r
-void GameOver(void)\r
-{\r
- Sint16 i;\r
-\r
- FreeGraphics();\r
- CA_CacheGrChunk(MILKYWAYPIC);\r
- CA_CacheGrChunk(GALAXY);\r
- CA_CacheGrChunk(GAMEOVERPIC);\r
- RF_FixOfs();\r
- VW_ClearVideo(BLACK);\r
- VWB_DrawPic(0, 0, MILKYWAYPIC);\r
- VW_UpdateScreen();\r
-\r
- SD_WaitSoundDone();\r
- SD_PlaySound(SND_GAMEOVER2);\r
- SD_WaitSoundDone();\r
- SD_PlaySound(SND_GAMEOVER1);\r
-\r
- IN_ClearKeysDown();\r
- VW_SetLineWidth(80);\r
-\r
- for (i=0; i<60; i++)\r
- {\r
- lasttimecount = TimeCount;\r
- MoveStars();\r
- VW_UpdateScreen();\r
-\r
- do {} while (TimeCount-lasttimecount < 4);\r
-\r
- if (LastScan)\r
- break;\r
- }\r
-\r
- VW_SetLineWidth(SCREENWIDTH);\r
- VW_ClearVideo(BLACK);\r
- StartMusic(18);\r
- VWB_DrawPic(32, 80, GAMEOVERPIC);\r
- VW_UpdateScreen();\r
- IN_UserInput(24*TickBase, false);\r
- StopMusic();\r
-}\r
-\r
-//============================================================================\r
-\r
-#else\r
-\r
-Uint16 dim[18] = {8, 8, 7, 15, 7, 8, 0, 8, 7, 15, 7, 8, 0, 0, 0, 0, 0, 0};\r
-Uint16 bright[18] = {7, 7, 7, 7, 7, 15, 7, 8, 0, 7, 15, 7, 8, 0, 0, 0, 0, 0};\r
-Uint8 galaxycolors[17] = {0, 1, 2, 3, 4, 5, 6, 7, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 3};\r
-Uint8 plotpixels[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};\r
-\r
-/*\r
-===========================\r
-=\r
-= MoveStars EGA\r
-=\r
-===========================\r
-*/\r
-\r
-void MoveStars(Uint16 dest)\r
-{\r
- asm {\r
- mov dx, GC_INDEX;\r
- mov al, GC_BITMASK;\r
- out dx, al;\r
- inc dx;\r
- mov ds, word ptr grsegs + 2*GALAXY;\r
- mov ax, 0A000h;\r
- mov es, ax;\r
- mov cx, 1000h;\r
- xor ax, ax;\r
- mov di, dest;\r
- rep stosw;\r
- mov si, 7998;\r
- }\r
-l1:\r
- asm {\r
- mov ax, [si]; // get posx\r
- add ax, [si+8000]; // add velx\r
- cmp ax, 40960; // check if new posx is on screen\r
- ja l2;\r
- mov [si], ax; // set new posx\r
- mov bx, [si+16000]; // get posy\r
- add bx, [si+24000]; // add vely\r
- cmp bx, 25600; // check if new posy is on screen\r
- ja l2;\r
- mov [si+16000], bx; // set new posy\r
- mov cl, 7;\r
- shr bx, cl;\r
- shl bx, 1;\r
- mov di, word ptr ss:ylookup[bx];\r
- add di, dest;\r
- mov bx, ax;\r
- mov cl, 10;\r
- shr ax, cl;\r
- add di, ax;\r
- mov cl, 7;\r
- shr bx, cl;\r
- and bx, 7;\r
- mov al, BYTE PTR ss:plotpixels[bx];\r
- out dx, al;\r
- mov al, 0Fh;\r
- xchg al, es:[di]; // draw the pixel\r
- }\r
-l2:\r
- asm {\r
- sub si, 2;\r
- jns l1;\r
- mov ax, ss;\r
- mov ds, ax;\r
- mov al, 0FFh;\r
- out dx, al;\r
- }\r
-}\r
-\r
-/*\r
-===========================\r
-=\r
-= SetCrtc EGA\r
-=\r
-===========================\r
-*/\r
-\r
-void SetCrtc(Uint16 addr)\r
-{\r
- asm {\r
- cli;\r
- mov cx, addr;\r
- mov dx, CRTC_INDEX;\r
- mov al, CRTC_STARTHIGH;\r
- out dx, al;\r
- inc dx;\r
- mov al, ch;\r
- out dx, al;\r
- dec dx;\r
- mov al, CRTC_STARTLOW;\r
- out dx, al;\r
- inc dx;\r
- mov al, cl;\r
- out dx, al;\r
- sti;\r
- }\r
-}\r
-\r
-/*\r
-===========================\r
-=\r
-= GameOver EGA\r
-=\r
-===========================\r
-*/\r
-\r
-void GameOver(void)\r
-{\r
- Sint16 i;\r
-\r
- FreeGraphics();\r
- VW_FadeOut();\r
- CA_CacheGrChunk(MILKYWAYPIC);\r
- CA_CacheGrChunk(GALAXY);\r
- CA_CacheGrChunk(GAMEOVERPIC);\r
- VW_SetLineWidth(40);\r
- VW_SetScreen(0, 0);\r
- bufferofs = 0;\r
- VW_ClearVideo(0);\r
- VW_DrawPic(0, 0, MILKYWAYPIC);\r
- VW_ScreenToScreen(0, 0x2000, 40, 200);\r
- VW_FadeIn();\r
- IN_ClearKeysDown();\r
- SD_PlaySound(SND_GAMEOVER2);\r
-\r
- for (i=0; i<18; i++)\r
- {\r
- galaxycolors[8] = dim[i];\r
- galaxycolors[7] = bright[i];\r
-\r
- SetPalette(galaxycolors);\r
-\r
- VW_WaitVBL(10);\r
- if (LastScan)\r
- goto gameover;\r
- }\r
-\r
- EGAWRITEMODE(2);\r
- EGAMAPMASK(15);\r
- SD_PlaySound(SND_GAMEOVER1);\r
-\r
- for (i=0; i<30; i++)\r
- {\r
- lasttimecount = TimeCount;\r
- MoveStars(0x2000);\r
- SetCrtc(0x2000);\r
- do {} while (TimeCount-lasttimecount < 4);\r
-\r
- lasttimecount = TimeCount;\r
- MoveStars(0);\r
- SetCrtc(0);\r
- do {} while (TimeCount-lasttimecount < 4);\r
-\r
- if (LastScan)\r
- goto gameover;\r
- }\r
-\r
-gameover:\r
- EGAWRITEMODE(0);\r
- VW_ClearVideo(BLACK);\r
- VW_SetLineWidth(SCREENWIDTH);\r
- VW_SetDefaultColors();\r
- RF_FixOfs();\r
- StartMusic(18);\r
- VWB_DrawPic(32, 80, GAMEOVERPIC);\r
- VW_UpdateScreen();\r
- IN_UserInput(24*TickBase, false);\r
- StopMusic();\r
-}\r
-\r
-#endif\r
-\r
-//============================================================================\r
-\r
-/*\r
-===========================\r
-=\r
-= FinishedFuse\r
-=\r
-===========================\r
-*/\r
-\r
-void FinishedFuse(void)\r
-{\r
- SD_WaitSoundDone();\r
- CA_UpLevel();\r
-#if 0\r
- // bugfix:\r
- CA_ClearMarks(); // don't cache more than we actually need here\r
-#endif\r
- CA_MarkGrChunk(KEENTALK1PIC);\r
- CA_MarkGrChunk(KEENTALK2PIC);\r
- CA_CacheMarks(NULL);\r
-\r
- VW_FixRefreshBuffer();\r
- US_CenterWindow(26, 8);\r
- WindowW -= 48;\r
- VWB_DrawPic(WindowX+WindowW, WindowY, KEENTALK1PIC);\r
- PrintY += 12;\r
- if (gamestate.mapon == 13)\r
- {\r
- US_CPrint(\r
- "I wonder what that\n"\r
- "fuse was for....\n"\r
- );\r
- }\r
- else\r
- {\r
- US_CPrint(\r
- "One of the four\n"\r
- "machines protecting the\n"\r
- "main elevator shaft--\n"\r
- "toast!\n"\r
- );\r
- }\r
- VW_UpdateScreen();\r
- VW_WaitVBL(30);\r
- IN_ClearKeysDown();\r
- IN_Ack();\r
-\r
- VWB_DrawPic(WindowX+WindowW, WindowY, KEENTALK2PIC);\r
- VW_UpdateScreen();\r
- VW_WaitVBL(30);\r
- IN_ClearKeysDown();\r
- IN_Ack();\r
-\r
- CA_DownLevel();\r
- StopMusic();\r
-}
\ No newline at end of file