]> 4ch.mooo.com Git - 16.git/blob - 16/keen456/KEEN4-6/KEEN6/K6_SPEC.C
extrcted keen code remake
[16.git] / 16 / keen456 / KEEN4-6 / KEEN6 / K6_SPEC.C
1 /* Reconstructed Commander Keen 4-6 Source Code\r
2  * Copyright (C) 2021 K1n9_Duk3\r
3  *\r
4  * This file is loosely based on:\r
5  * Keen Dreams Source Code\r
6  * Copyright (C) 2014 Javier M. Chavez\r
7  *\r
8  * This program is free software; you can redistribute it and/or modify\r
9  * it under the terms of the GNU General Public License as published by\r
10  * the Free Software Foundation; either version 2 of the License, or\r
11  * (at your option) any later version.\r
12  *\r
13  * This program is distributed in the hope that it will be useful,\r
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
16  * GNU General Public License for more details.\r
17  *\r
18  * You should have received a copy of the GNU General Public License along\r
19  * with this program; if not, write to the Free Software Foundation, Inc.,\r
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
21  */\r
22 \r
23 /*\r
24 K6_SPEC.C\r
25 =========\r
26 \r
27 Contains (in this order):\r
28 \r
29 - lump definition\r
30 - "Star Wars" crawl text\r
31 - level names & messages\r
32 - ScanInfoPlane() - for spawning the level objects and marking required sprites\r
33 - stunned state for Keen\r
34 - code to flip the big yellow switches\r
35 - messages for sandwich, rope and passcard\r
36 */\r
37 \r
38 #include "CK_DEF.H"\r
39 \r
40 enum {\r
41         CONTROLS_LUMP,    //  0\r
42         KEEN_LUMP,        //  1\r
43         SUGAR1_LUMP,      //  2\r
44         SUGAR2_LUMP,      //  3\r
45         SUGAR3_LUMP,      //  4\r
46         SUGAR4_LUMP,      //  5\r
47         SUGAR5_LUMP,      //  6\r
48         SUGAR6_LUMP,      //  7\r
49         ONEUP_LUMP,       //  8\r
50         KEYGEM_LUMP,      //  9\r
51         AMMO_LUMP,        // 10\r
52         WORLDKEEN_LUMP,   // 11\r
53         UNUSED1_LUMP,     // 12\r
54         BLOOG_LUMP,       // 13\r
55         RBLOOGLET_LUMP,   // 14\r
56         YBLOOGLET_LUMP,   // 15\r
57         BBLOOGLET_LUMP,   // 16\r
58         GBLOOGLET_LUMP,   // 17\r
59         PLATFORM_LUMP,    // 18\r
60         GIK_LUMP,         // 19\r
61         BLORB_LUMP,       // 20\r
62         BOBBA_LUMP,       // 21\r
63         BABOBBA_LUMP,     // 22\r
64         BLOOGUARD_LUMP,   // 23\r
65         FLECT_LUMP,       // 24\r
66         BIP_LUMP,         // 25\r
67         BIPSQUISHED_LUMP, // 26\r
68         BIPSHIP_LUMP,     // 27\r
69         NOSPIKE_LUMP,     // 28\r
70         ORBATRIX_LUMP,    // 29\r
71         CEILICK_LUMP,     // 30\r
72         FLEEX_LUMP,       // 31\r
73         HOOK_LUMP,        // 32\r
74         SANDWICH_LUMP,    // 33\r
75         LASER_LUMP,       // 34\r
76         PASSCARD_LUMP,    // 35\r
77         MOLLY_LUMP,       // 36\r
78 \r
79         NUMLUMPS=40       // Keen 6 has 3 unused lumps at the end\r
80 };\r
81 \r
82 Uint16 lumpstart[NUMLUMPS] = {\r
83         CONTROLS_LUMP_START,\r
84         KEEN_LUMP_START,\r
85         SUGAR1_LUMP_START,\r
86         SUGAR2_LUMP_START,\r
87         SUGAR3_LUMP_START,\r
88         SUGAR4_LUMP_START,\r
89         SUGAR5_LUMP_START,\r
90         SUGAR6_LUMP_START,\r
91         ONEUP_LUMP_START,\r
92         KEYGEM_LUMP_START,\r
93         AMMO_LUMP_START,\r
94         WORLDKEEN_LUMP_START,\r
95         0,\r
96         BLOOG_LUMP_START,\r
97         RBLOOGLET_LUMP_START,\r
98         YBLOOGLET_LUMP_START,\r
99         BBLOOGLET_LUMP_START,\r
100         GBLOOGLET_LUMP_START,\r
101         PLATFORM_LUMP_START,\r
102         GIK_LUMP_START,\r
103         BLORB_LUMP_START,\r
104         BOBBA_LUMP_START,\r
105         BABOBBA_LUMP_START,\r
106         BLOOGUARD_LUMP_START,\r
107         FLECT_LUMP_START,\r
108         BIP_LUMP_START,\r
109         BIPSQUISHED_LUMP_START,\r
110         BIPSHIP_LUMP_START,\r
111         NOSPIKE_LUMP_START,\r
112         ORBATRIX_LUMP_START,\r
113         CEILICK_LUMP_START,\r
114         FLEEX_LUMP_START,\r
115         HOOK_LUMP_START,\r
116         SANDWICH_LUMP_START,\r
117         LASER_LUMP_START,\r
118         PASSCARD_LUMP_START,\r
119         MOLLY_LUMP_START\r
120 };\r
121 \r
122 Uint16 lumpend[NUMLUMPS] = {\r
123         CONTROLS_LUMP_END,\r
124         KEEN_LUMP_END,\r
125         SUGAR1_LUMP_END,\r
126         SUGAR2_LUMP_END,\r
127         SUGAR3_LUMP_END,\r
128         SUGAR4_LUMP_END,\r
129         SUGAR5_LUMP_END,\r
130         SUGAR6_LUMP_END,\r
131         ONEUP_LUMP_END,\r
132         KEYGEM_LUMP_END,\r
133         AMMO_LUMP_END,\r
134         WORLDKEEN_LUMP_END,\r
135         0,\r
136         BLOOG_LUMP_END,\r
137         RBLOOGLET_LUMP_END,\r
138         YBLOOGLET_LUMP_END,\r
139         BBLOOGLET_LUMP_END,\r
140         GBLOOGLET_LUMP_END,\r
141         PLATFORM_LUMP_END,\r
142         GIK_LUMP_END,\r
143         BLORB_LUMP_END,\r
144         BOBBA_LUMP_END,\r
145         BABOBBA_LUMP_END,\r
146         BLOOGUARD_LUMP_END,\r
147         FLECT_LUMP_END,\r
148         BIP_LUMP_END,\r
149         BIPSQUISHED_LUMP_END,\r
150         BIPSHIP_LUMP_END,\r
151         NOSPIKE_LUMP_END,\r
152         ORBATRIX_LUMP_END,\r
153         CEILICK_LUMP_END,\r
154         FLEEX_LUMP_END,\r
155         HOOK_LUMP_END,\r
156         SANDWICH_LUMP_END,\r
157         LASER_LUMP_END,\r
158         PASSCARD_LUMP_END,\r
159         MOLLY_LUMP_END\r
160 };\r
161 \r
162 boolean lumpneeded[NUMLUMPS];\r
163 \r
164 #if GRMODE == EGAGR\r
165 \r
166 char far swtext[] =\r
167         "Episode Six\n"\r
168         "\n"\r
169         "Aliens Ate My\n"\r
170         "Baby Sitter!\n"\r
171         "\n"\r
172         "While out in his\n"\r
173         "backyard clubhouse,\n"\r
174         "Billy's baby sitter\n"\r
175         "Molly calls him for\n"\r
176         "dinner. He continues\n"\r
177         "working on his new\n"\r
178         "wrist computer.\n"\r
179         "\n"\r
180         "Suddenly, there is a\n"\r
181         "loud noise outside.\n"\r
182         "\n"\r
183         "Rushing out, Keen finds\n"\r
184         "his baby sitter gone\n"\r
185         "and a note on a patch\n"\r
186         "of scorched grass.  The\n"\r
187         "Bloogs of Fribbulus Xax\n"\r
188         "are going to make a\n"\r
189         "meal out of Molly!\n"\r
190         "\n"\r
191         "You've got to rescue\n"\r
192         "her, because your\n"\r
193         "parents will never\n"\r
194         "believe you when you\n"\r
195         "tell them...\n"\r
196         "\n"\r
197         "\"Aliens Ate My\n"\r
198         "Baby Sitter!\"\n";\r
199 \r
200 #endif\r
201 \r
202 char far l0n[] = "Fribbulus Xax";\r
203 char far l1n[] = "Bloogwaters\nCrossing";\r
204 char far l2n[] = "Guard Post One";\r
205 char far l3n[] = "First Dome\nof Darkness";\r
206 char far l4n[] = "Second Dome\nof Darkness";\r
207 char far l5n[] = "The Bloogdome";\r
208 char far l6n[] = "Bloogton Mfg.,\nIncorporated";\r
209 char far l7n[] = "Bloogton Tower";\r
210 char far l8n[] = "Bloogfoods, Inc.";\r
211 char far l9n[] = "Guard Post Two";\r
212 char far l10n[] = "Bloogville";\r
213 char far l11n[] = "BASA";\r
214 char far l12n[] = "Guard Post Three";\r
215 char far l13n[] = "Bloogbase Rec\nDistrict";\r
216 char far l14n[] = "Bloogbase Mgmt.\nDistrict";\r
217 char far l15n[] = "Bloog Control Center";\r
218 char far l16n[] = "Blooglab";\r
219 char far l17n[] = "Bean-with-Bacon\nMegarocket";\r
220 char far l18n[] = "High Scores";\r
221 \r
222 char far l0e[] = "Keen attacks\nFribbulus Xax";\r
223 char far l1e[] = "Keen hops across\nBloogwaters\nCrossing";\r
224 char far l2e[] = "Keen fights his way\nthrough Guard Post One";\r
225 char far l3e[] = "Keen crosses into the\nFirst Dome of Darkness";\r
226 char far l4e[] = "Keen dares to enter the\nSecond Dome of Darkness";\r
227 char far l5e[] = "Keen foolishly enters\nthe Bloogdome";\r
228 char far l6e[] = "Keen makes his way\ninto Bloogton\nManufacturing";\r
229 char far l7e[] = "Keen ascends\nBloogton Tower";\r
230 char far l8e[] = "Keen hungrily enters\nBloogfoods, Inc.";\r
231 char far l9e[] = "Keen smashes through\nGuard Post Two";\r
232 char far l10e[] = "Keen seeks thrills\nin Bloogville";\r
233 char far l11e[] = "Keen rockets into the\nBloog Aeronautics and\nSpace Administration";\r
234 char far l12e[] = "Keen boldly assaults\nGuard Post Three";\r
235 char far l13e[] = "Keen whoops it up in\nthe Bloogbae\nRecreational District";  // sic!\r
236 char far l14e[] = "Keen purposefully struts\ninto the Bloogbase\nManagement District";\r
237 char far l15e[] = "Keen bravely enters the\nBloog Control Center,\nlooking for Molly";\r
238 char far l16e[] = "Keen warily enters\nBlooglab Space\nStation";\r
239 char far l17e[] = "Keen returns to the\nBean-with-Bacon\nMegarocket";\r
240 char far l18e[] = "Keen is in the High\nScore screen. Call Id!";\r
241 \r
242 char far *levelnames[GAMELEVELS] = {\r
243         l0n,\r
244         l1n,\r
245         l2n,\r
246         l3n,\r
247         l4n,\r
248         l5n,\r
249         l6n,\r
250         l7n,\r
251         l8n,\r
252         l9n,\r
253         l10n,\r
254         l11n,\r
255         l12n,\r
256         l13n,\r
257         l14n,\r
258         l15n,\r
259         l16n,\r
260         l17n,\r
261         l18n\r
262 };\r
263 \r
264 char far *levelenter[GAMELEVELS] = {\r
265         l0e,\r
266         l1e,\r
267         l2e,\r
268         l3e,\r
269         l4e,\r
270         l5e,\r
271         l6e,\r
272         l7e,\r
273         l8e,\r
274         l9e,\r
275         l10e,\r
276         l11e,\r
277         l12e,\r
278         l13e,\r
279         l14e,\r
280         l15e,\r
281         l16e,\r
282         l17e,\r
283         l18e\r
284 };\r
285 \r
286 Uint16 bonuslump[] = {\r
287         KEYGEM_LUMP, KEYGEM_LUMP, KEYGEM_LUMP, KEYGEM_LUMP,\r
288         SUGAR1_LUMP, SUGAR2_LUMP, SUGAR3_LUMP,\r
289         SUGAR4_LUMP, SUGAR5_LUMP, SUGAR6_LUMP,\r
290         ONEUP_LUMP, AMMO_LUMP, AMMO_LUMP, 0, 0\r
291 };\r
292 \r
293 //============================================================================\r
294 \r
295 /*\r
296 ==========================\r
297 =\r
298 = ScanInfoPlane\r
299 =\r
300 = Spawn all actors and mark down special places\r
301 =\r
302 ==========================\r
303 */\r
304 \r
305 void ScanInfoPlane(void)\r
306 {\r
307         Uint16 i, x, y, chunk;\r
308         Sint16 info;\r
309         Uint16 far *map;\r
310         objtype *ob;\r
311 \r
312         InitObjArray();                  // start spawning things with a clean slate\r
313 \r
314         memset(lumpneeded, 0, sizeof(lumpneeded));\r
315         map = mapsegs[2];\r
316 \r
317         for (y=0; y<mapheight; y++)\r
318         {\r
319                 for (x=0; x<mapwidth; x++)\r
320                 {\r
321                         info = *map++;\r
322 \r
323                         if (info == 0)\r
324                                 continue;\r
325 \r
326                         switch (info)\r
327                         {\r
328                         case 1:\r
329                                 SpawnKeen(x, y, 1);\r
330                                 SpawnScore();\r
331                                 lumpneeded[KEEN_LUMP] = true;\r
332                                 CA_MarkGrChunk(SCOREBOXSPR);\r
333                                 break;\r
334 \r
335                         case 2:\r
336                                 SpawnKeen(x, y, -1);\r
337                                 SpawnScore();\r
338                                 lumpneeded[KEEN_LUMP] = true;\r
339                                 CA_MarkGrChunk(SCOREBOXSPR);\r
340                                 break;\r
341 \r
342                         case 3:\r
343                                 SpawnWorldKeen(x, y);\r
344                                 SpawnScore();\r
345                                 lumpneeded[WORLDKEEN_LUMP] = true;\r
346                                 CA_MarkGrChunk(SCOREBOXSPR);\r
347                                 break;\r
348 \r
349                         case 6:\r
350                                 if (gamestate.difficulty < gd_Hard)\r
351                                         break;\r
352                         case 5:\r
353                                 if (gamestate.difficulty < gd_Normal)\r
354                                         break;\r
355                         case 4:\r
356                                 SpawnBloog(x, y);\r
357                                 lumpneeded[BLOOG_LUMP] = true;\r
358                                 break;\r
359 \r
360                         case 7:\r
361                         case 8:\r
362                         case 9:\r
363                         case 10:\r
364                         case 11:\r
365                         case 12:\r
366                         case 13:\r
367                         case 14:\r
368                                 SpawnBlooglet(x, y, info-7);\r
369                                 lumpneeded[(info-7) % 4 + RBLOOGLET_LUMP] = true;\r
370                                 if (info > 10)\r
371                                         lumpneeded[KEYGEM_LUMP] = true;\r
372                                 break;\r
373 \r
374                         case 15:\r
375                         case 16:\r
376                                 SpawnGrappleSpot(x, y, info-15);\r
377                                 break;\r
378 \r
379                         // case 17 is not used\r
380 \r
381                         case 20:\r
382                                 if (gamestate.difficulty < gd_Hard)\r
383                                         break;\r
384                         case 19:\r
385                                 if (gamestate.difficulty < gd_Normal)\r
386                                         break;\r
387                         case 18:\r
388                                 SpawnFleex(x, y);\r
389                                 lumpneeded[FLEEX_LUMP] = true;\r
390                                 break;\r
391 \r
392                         case 21:\r
393                         case 22:\r
394                         case 23:\r
395                         case 24:\r
396                                 SpawnMolly(x, y);\r
397                                 lumpneeded[MOLLY_LUMP] = true;\r
398                                 break;\r
399 \r
400                         case 25:\r
401                                 RF_SetScrollBlock(x, y, true);\r
402                                 break;\r
403 \r
404                         case 26:\r
405                                 RF_SetScrollBlock(x, y, false);\r
406                                 break;\r
407 \r
408                         case 27:\r
409                         case 28:\r
410                         case 29:\r
411                         case 30:\r
412                                 SpawnPlatform(x, y, info-27);\r
413                                 lumpneeded[PLATFORM_LUMP] = true;\r
414                                 break;\r
415 \r
416                         // case 31 is the block icon\r
417 \r
418                         case 32:\r
419                                 SpawnDropPlat(x, y);\r
420                                 lumpneeded[PLATFORM_LUMP] = true;\r
421                                 break;\r
422 \r
423                         case 35:\r
424                                 SpawnStaticPlat(x, y);\r
425                                 lumpneeded[PLATFORM_LUMP] = true;\r
426                                 break;\r
427                         case 34:\r
428                                 if (gamestate.difficulty > gd_Normal)\r
429                                         break;\r
430                                 SpawnStaticPlat(x, y);\r
431                                 lumpneeded[PLATFORM_LUMP] = true;\r
432                                 break;\r
433                         case 33:\r
434                                 if (gamestate.difficulty > gd_Easy)\r
435                                         break;\r
436                                 SpawnStaticPlat(x, y);\r
437                                 lumpneeded[PLATFORM_LUMP] = true;\r
438                                 break;\r
439 \r
440                         case 36:\r
441                         case 37:\r
442                         case 38:\r
443                         case 39:\r
444                                 SpawnGoPlat(x, y, info-36);\r
445                                 lumpneeded[PLATFORM_LUMP] = true;\r
446                                 lumpneeded[BIPSQUISHED_LUMP] = true;    // why?\r
447                                 break;\r
448 \r
449                         case 40:\r
450                                 SpawnSneakPlat(x, y);\r
451                                 lumpneeded[PLATFORM_LUMP] = true;\r
452                                 break;\r
453 \r
454                         case 43:\r
455                                 if (gamestate.difficulty < gd_Hard)\r
456                                         break;\r
457                         case 42:\r
458                                 if (gamestate.difficulty < gd_Normal)\r
459                                         break;\r
460                         case 41:\r
461                                 SpawnBobba(x, y);\r
462                                 lumpneeded[BOBBA_LUMP] = true;\r
463                                 break;\r
464 \r
465                         case 44:\r
466                         case 45:\r
467                                 SpawnSatelliteStop(x, y, info-44);\r
468                                 break;\r
469 \r
470                         // case 46 is not used\r
471 \r
472                         case 49:\r
473                                 if (gamestate.difficulty < gd_Hard)\r
474                                         break;\r
475                         case 48:\r
476                                 if (gamestate.difficulty < gd_Normal)\r
477                                         break;\r
478                         case 47:\r
479                                 SpawnNospike(x, y);\r
480                                 lumpneeded[NOSPIKE_LUMP] = true;\r
481                                 break;\r
482 \r
483                         case 52:\r
484                                 if (gamestate.difficulty < gd_Hard)\r
485                                         break;\r
486                         case 51:\r
487                                 if (gamestate.difficulty < gd_Normal)\r
488                                         break;\r
489                         case 50:\r
490                                 SpawnGik(x, y);\r
491                                 lumpneeded[GIK_LUMP] = true;\r
492                                 break;\r
493 \r
494                         case 53:\r
495                         case 54:\r
496                         case 55:\r
497                         case 56:\r
498                                 SpawnCannon(x, y, info-53);\r
499                                 lumpneeded[LASER_LUMP] = true;\r
500                                 break;\r
501 \r
502                         case 69:\r
503                                 if (gamestate.ammo >= 5)\r
504                                         break;\r
505                                 info = 68;\r
506                                 // no break here!\r
507                         case 57:\r
508                         case 58:\r
509                         case 59:\r
510                         case 60:\r
511                         case 61:\r
512                         case 62:\r
513                         case 63:\r
514                         case 64:\r
515                         case 65:\r
516                         case 66:\r
517                         case 67:\r
518                         case 68:\r
519                                 SpawnBonus(x, y, info-57);\r
520                                 lumpneeded[bonuslump[info-57]] = true;\r
521                                 break;\r
522 \r
523                         case 72:\r
524                                 if (gamestate.difficulty < gd_Hard)\r
525                                         break;\r
526                         case 71:\r
527                                 if (gamestate.difficulty < gd_Normal)\r
528                                         break;\r
529                         case 70:\r
530                                 SpawnOrbatrix(x, y);\r
531                                 lumpneeded[ORBATRIX_LUMP] = true;\r
532                                 break;\r
533 \r
534                         case 75:\r
535                                 if (gamestate.difficulty < gd_Hard)\r
536                                         break;\r
537                         case 74:\r
538                                 if (gamestate.difficulty < gd_Normal)\r
539                                         break;\r
540                         case 73:\r
541                                 SpawnBipship(x, y);\r
542                                 lumpneeded[BIP_LUMP]=lumpneeded[BIPSHIP_LUMP]=lumpneeded[BIPSQUISHED_LUMP] = true;\r
543                                 break;\r
544 \r
545                         case 78:\r
546                                 if (gamestate.difficulty < gd_Hard)\r
547                                         break;\r
548                         case 77:\r
549                                 if (gamestate.difficulty < gd_Normal)\r
550                                         break;\r
551                         case 76:\r
552                                 SpawnFlect(x, y);\r
553                                 lumpneeded[FLECT_LUMP] = true;\r
554                                 break;\r
555 \r
556                         case 81:\r
557                                 if (gamestate.difficulty < gd_Hard)\r
558                                         break;\r
559                         case 80:\r
560                                 if (gamestate.difficulty < gd_Normal)\r
561                                         break;\r
562                         case 79:\r
563                                 SpawnBlorb(x, y);\r
564                                 lumpneeded[BLORB_LUMP] = true;\r
565                                 break;\r
566 \r
567                         case 84:\r
568                                 if (gamestate.difficulty < gd_Hard)\r
569                                         break;\r
570                         case 83:\r
571                                 if (gamestate.difficulty < gd_Normal)\r
572                                         break;\r
573                         case 82:\r
574                                 SpawnCeilick(x, y);\r
575                                 lumpneeded[CEILICK_LUMP] = true;\r
576                                 break;\r
577 \r
578                         case 87:\r
579                                 if (gamestate.difficulty < gd_Hard)\r
580                                         break;\r
581                         case 86:\r
582                                 if (gamestate.difficulty < gd_Normal)\r
583                                         break;\r
584                         case 85:\r
585                                 SpawnBlooguard(x, y);\r
586                                 lumpneeded[BLOOGUARD_LUMP] = true;\r
587                                 break;\r
588 \r
589                         case 88:\r
590                                 SpawnGrabbiter(x, y);\r
591                                 // no additional lump needed - sprites are in WORLDKEEN_LUMP\r
592                                 break;\r
593 \r
594                         case 89:\r
595                                 SpawnSatellite(x, y);\r
596                                 // no additional lump needed - sprites are in WORLDKEEN_LUMP\r
597                                 break;\r
598 \r
599                         // case 90 is not used\r
600                         // cases 91 to 98 are direction arrows\r
601 \r
602                         case 99:\r
603                                 SpawnHook(x, y);\r
604                                 lumpneeded[HOOK_LUMP] = true;\r
605                                 break;\r
606 \r
607                         case 100:\r
608                                 SpawnSandwich(x, y);\r
609                                 lumpneeded[SANDWICH_LUMP] = true;\r
610                                 break;\r
611 \r
612                         case 101:\r
613                                 SpawnPasscard(x, y);\r
614                                 lumpneeded[PASSCARD_LUMP] = true;\r
615                                 break;\r
616 \r
617                         case 104:\r
618                                 if (gamestate.difficulty < gd_Hard)\r
619                                         break;\r
620                         case 103:\r
621                                 if (gamestate.difficulty < gd_Normal)\r
622                                         break;\r
623                         case 102:\r
624                                 SpawnBabobba(x, y);\r
625                                 lumpneeded[BABOBBA_LUMP] = true;\r
626                                 break;\r
627 \r
628                         case 105:\r
629                         case 106:\r
630                                 SpawnRocket(x, y, info-105);\r
631                                 // no additional lump needed - sprites are in WORLDKEEN_LUMP\r
632                                 break;\r
633                         }\r
634                 }\r
635         }\r
636 \r
637         for (ob = player; ob; ob = ob->next)\r
638         {\r
639                 if (ob->active != ac_allways)\r
640                         ob->active = ac_no;\r
641         }\r
642 \r
643         for (i = 0; i < NUMLUMPS; i++)\r
644         {\r
645                 if (lumpneeded[i])\r
646                 {\r
647                         for (chunk = lumpstart[i]; chunk <= lumpend[i]; chunk++)\r
648                         {\r
649                                 CA_MarkGrChunk(chunk);\r
650                         }\r
651                 }\r
652         }\r
653 }\r
654 \r
655 //============================================================================\r
656 \r
657 statetype s_keenstun = {KEENSTUNSPR, KEENSTUNSPR, step, false, true, 60, 0, 0, T_Projectile, KeenContact, KeenStandReact, &s_keenstand};\r
658 \r
659 //============================================================================\r
660 \r
661 /*\r
662 ===========================\r
663 =\r
664 = FlipBigSwitch\r
665 =\r
666 ===========================\r
667 */\r
668 \r
669 void FlipBigSwitch(objtype *ob, boolean isup)\r
670 {\r
671         Uint16 x, y;\r
672         Uint16 far *map;\r
673         Uint16 top, mid, bot;\r
674         Uint16 *tileptr;\r
675         Uint16 tile, tx, ty, xi, yi, offset, anim;\r
676         Uint16 tiles[6];\r
677 \r
678         //\r
679         // handle flipping the switch itself:\r
680         //\r
681         if (isup)\r
682         {\r
683                 ty = ob->tilebottom;\r
684         }\r
685         else\r
686         {\r
687                 ty = ob->tiletop - 2;\r
688         }\r
689         tx = ob->tileleft - 1;\r
690         map = mapsegs[2] + mapbwidthtable[ty+1]/2 + tx + 1;\r
691         while (*map == 0)\r
692         {\r
693                 map++;\r
694                 tx++;\r
695         }\r
696         map = mapsegs[1] + mapbwidthtable[ty]/2 + tx;\r
697         tileptr = tiles;\r
698         for (y = 0; y < 3; y++, map += mapwidth)\r
699         {\r
700                 for (x = 0; x < 2; tileptr++, x++)\r
701                 {\r
702                         tile = map[x];\r
703                         *tileptr = tile + (Sint8)tinf[tile+MANIM];\r
704                 }\r
705         }\r
706         RF_MemToMap(tiles, 1, tx, ty, 2, 3);\r
707 \r
708         tile = *(mapsegs[2]+mapbwidthtable[ty+1]/2 + tx + 1);\r
709         x = tile >> 8;\r
710         y = tile & 0xFF;\r
711         SD_PlaySound(SND_USESWITCH);\r
712 \r
713         //\r
714         // toggle whatever was linked to the switch (at tile x, y):\r
715         //\r
716         offset = mapbwidthtable[y]/2 + x;\r
717         map = mapsegs[2] + offset;\r
718         tile = *map;\r
719 \r
720         if (tile >= DIRARROWSTART && tile < DIRARROWEND)\r
721         {\r
722                 // turn direction arrow:\r
723                 *map = arrowflip[tile-DIRARROWSTART] + DIRARROWSTART;\r
724         }\r
725         else\r
726         {\r
727                 map = mapsegs[1] + offset;\r
728                 tile = *map;\r
729                 switch (tinf[tile+INTILE] & INTILE_TYPEMASK)\r
730                 {\r
731                 case INTILE_NOTHING:    // no special tiles\r
732                         mapsegs[2][offset] ^= PLATFORMBLOCK;\r
733                         break;\r
734 \r
735                 case INTILE_BRIDGE:     // bridge\r
736                         for (yi=y; y+2 > yi; yi++)\r
737                         {\r
738                                 map = mapsegs[1] + mapbwidthtable[yi]/2 + x - (yi != y);\r
739                                 for (xi = x - (yi != y); xi < mapwidth; xi++)\r
740                                 {\r
741                                         tile = *map;\r
742                                         map++;\r
743                                         anim = tinf[tile + MANIM];\r
744                                         if (!anim)\r
745                                                 break;\r
746                                         tile += (Sint8)anim;\r
747                                         RF_MemToMap(&tile, 1, xi, yi, 1, 1);\r
748                                 }\r
749                         }\r
750                         break;\r
751 \r
752                 case INTILE_FORCEFIELD: // active force field\r
753                         map = mapsegs[1];\r
754                         top = *map;\r
755                         mid = *++map;\r
756                         bot = *++map;\r
757                         map = mapsegs[1] + mapbwidthtable[y+1]/2 + x;\r
758 \r
759                         RF_MemToMap(&top, 1, x, y++, 1, 1);\r
760                         while (tinf[*map+INTILE] == INTILE_DEADLY)\r
761                         {\r
762                                 RF_MemToMap(&mid, 1, x, y++, 1, 1);\r
763                                 map += mapwidth;\r
764                         }\r
765                         RF_MemToMap(&bot, 1, x, y, 1, 1);\r
766                         break;\r
767 \r
768                 case INTILE_FORCEFIELDEND:      // inactive force field\r
769                         map = mapsegs[1] + 3;\r
770                         top = *map;\r
771                         mid = *++map;\r
772                         bot = *++map;\r
773                         map = mapsegs[1] + mapbwidthtable[y+1]/2 + x;\r
774 \r
775                         RF_MemToMap(&top, 1, x, y++, 1, 1);\r
776                         while (tinf[*map+INTILE] != INTILE_FORCEFIELDEND)\r
777                         {\r
778                                 RF_MemToMap(&mid, 1, x, y++, 1, 1);\r
779                                 map += mapwidth;\r
780                         }\r
781                         RF_MemToMap(&bot, 1, x, y, 1, 1);\r
782                 }\r
783         }\r
784 }\r
785 \r
786 //============================================================================\r
787 \r
788 /*\r
789 ===========================\r
790 =\r
791 = GotSandwich\r
792 =\r
793 ===========================\r
794 */\r
795 \r
796 void GotSandwich(void)\r
797 {\r
798         SD_WaitSoundDone();\r
799         SD_PlaySound(SND_QUESTITEM);\r
800         CA_UpLevel();   // kinda useless without CA_CacheMarks or CA_SetGrPurge\r
801         // BUG: haven't made anything purgable here, caching the pic may cause an "out of memory" crash\r
802         CA_CacheGrChunk(KEENTALK1PIC);\r
803 \r
804         US_CenterWindow(26, 8);\r
805         VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC);\r
806         WindowW -= 48;\r
807         PrintY += 12;\r
808         US_CPrint(\r
809                 "This is the second\n"\r
810                 "biggest sandwich\n"\r
811                 "I ever saw!\n"\r
812                 );\r
813         VW_UpdateScreen();\r
814         VW_WaitVBL(30);\r
815         IN_ClearKeysDown();\r
816         IN_Ack();\r
817         CA_DownLevel();\r
818         gamestate.sandwichstate = 1;\r
819 }\r
820 \r
821 /*\r
822 ===========================\r
823 =\r
824 = GotHook\r
825 =\r
826 ===========================\r
827 */\r
828 \r
829 void GotHook(void)\r
830 {\r
831         SD_WaitSoundDone();\r
832         SD_PlaySound(SND_QUESTITEM);\r
833         CA_UpLevel();   // kinda useless without CA_CacheMarks or CA_SetGrPurge\r
834         // BUG: haven't made anything purgable here, caching the pic may cause an "out of memory" crash\r
835         CA_CacheGrChunk(KEENTALK1PIC);\r
836 \r
837         US_CenterWindow(26, 8);\r
838         VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC);\r
839         WindowW -= 48;\r
840         PrintY += 12;\r
841         US_CPrint(\r
842                 "Wow! A rope and\n"\r
843                 "grappling hook!\n"\r
844                 "They look useful!\n"\r
845                 );\r
846         VW_UpdateScreen();\r
847         VW_WaitVBL(30);\r
848         IN_ClearKeysDown();\r
849         IN_Ack();\r
850         CA_DownLevel();\r
851         gamestate.hookstate = 1;\r
852 }\r
853 \r
854 /*\r
855 ===========================\r
856 =\r
857 = GotPasscard\r
858 =\r
859 ===========================\r
860 */\r
861 \r
862 void GotPasscard(void)\r
863 {\r
864         SD_WaitSoundDone();\r
865         SD_PlaySound(SND_QUESTITEM);\r
866         CA_UpLevel();   // kinda useless without CA_CacheMarks or CA_SetGrPurge\r
867         // BUG: haven't made anything purgable here, caching the pic may cause an "out of memory" crash\r
868         CA_CacheGrChunk(KEENTALK1PIC);\r
869 \r
870         US_CenterWindow(26, 8);\r
871         VWB_DrawPic(WindowX+WindowW-48, WindowY, KEENTALK1PIC);\r
872         WindowW -= 48;\r
873         PrintY += 4;\r
874         US_CPrint(\r
875                 "What's this? Cool!\n"\r
876                 "A passcard for\n"\r
877                 "the Bloogstar Rocket!\n"\r
878                 "(It can fly through\n"\r
879                 "their force field.)"\r
880                 );\r
881         VW_UpdateScreen();\r
882         VW_WaitVBL(30);\r
883         IN_ClearKeysDown();\r
884         IN_Ack();\r
885         CA_DownLevel();\r
886         gamestate.passcardstate = 1;\r
887 }\r