]> 4ch.mooo.com Git - 16.git/blob - 16/cawat/C5_GAME.C
14693a7230a5538f7cd5669bf8db11d34626d5a0
[16.git] / 16 / cawat / C5_GAME.C
1 /* Catacomb Armageddon Source Code\r
2  * Copyright (C) 1993-2014 Flat Rock Software\r
3  *\r
4  * This program is free software; you can redistribute it and/or modify\r
5  * it under the terms of the GNU General Public License as published by\r
6  * the Free Software Foundation; either version 2 of the License, or\r
7  * (at your option) any later version.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along\r
15  * with this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
17  */\r
18 \r
19 // C3_GAME.C\r
20 \r
21 #include <stdlib.h>\r
22 \r
23 #include "DEF.H"\r
24 #include "gelib.h"\r
25 #pragma hdrstop\r
26 \r
27 #ifdef PROFILE\r
28 #include "TIME.H"\r
29 #endif\r
30 \r
31 \r
32 /*\r
33 =============================================================================\r
34 \r
35                                                  LOCAL CONSTANTS\r
36 \r
37 =============================================================================\r
38 */\r
39 \r
40 #define NUMLUMPS        61\r
41 \r
42 #define SUCCUBUSLUMP    0\r
43 #define FATDEMONLUMP    1\r
44 #define BOLTLUMP        2\r
45 #define NUKELUMP        3\r
46 #define POTIONLUMP      4\r
47 #define RKEYLUMP        5\r
48 #define YKEYLUMP        6\r
49 #define GKEYLUMP        7\r
50 #define BKEYLUMP        8\r
51 //#define SCROLLLUMP    9\r
52 #define CHESTLUMP       10\r
53 #define PLAYERLUMP      11\r
54 #define WALL1LUMP       12\r
55 #define WALL2LUMP       13\r
56 #define BDOORLUMP       14\r
57 #define GODESSLUMP      15\r
58 #define MAGELUMP        16\r
59 #define BATLUMP         17\r
60 #define GRELLUMP        18\r
61 #define TOMBSTONESLUMP  19\r
62 #define ZOMBIELUMP      20\r
63 #define ANTLUMP         21\r
64 #define SKELETONLUMP    22\r
65 #define RGEMLUMP        23\r
66 #define GGEMLUMP        24\r
67 #define BGEMLUMP        25\r
68 #define YGEMLUMP        26\r
69 #define PGEMLUMP        27\r
70 //#define RKEY2LUMP     28\r
71 #define DRAGONLUMP      29\r
72 #define OBJ_WARPLUMP    30\r
73 #define EYELUMP         31\r
74 #define REDDEMONLUMP    32\r
75 //#define PITLUMP       33\r
76 #define FTIMELUMP       34\r
77 #define WATERCHESTLUMP  35\r
78 #define TREELUMP        36\r
79 #define ARCH1LUMP       37\r
80 #define BUNNYLUMP       38\r
81 #define ANTHILLLUMP     39\r
82 #define COLUMNLUMP      40\r
83 #define SULPHURGASLUMP  41\r
84 #define FIREPOTLUMP     42\r
85 //#define WHIRLPOOLLUMP 43\r
86 #define FOUNTAINLUMP    44\r
87 #define FORCEFIELDLUMP  45\r
88 #define ARCH2LUMP       46\r
89 #define ARCH3LUMP       47\r
90 #define ARCH4LUMP       48\r
91 #define ARCH5LUMP       49\r
92 #define ARCH6LUMP       50\r
93 #define SKELHANGLUMP    51\r
94 //#define SKELPILELUMP  52\r
95 #define ARCH7LUMP       53\r
96 #define ARCH8LUMP       54\r
97 #define ARCH9LUMP       55\r
98 #define ARCH10LUMP      56\r
99 #define ARCH11LUMP      57\r
100 #define ARCH12LUMP      58\r
101 #define ARCH13LUMP      59\r
102 \r
103 int     lumpstart[NUMLUMPS] = {\r
104 SUCCUBUS_LUMP_START,\r
105 FATDEMON_LUMP_START,\r
106 BOLT_LUMP_START,\r
107 NUKE_LUMP_START,\r
108 POTION_LUMP_START,\r
109 RKEY_LUMP_START,\r
110 YKEY_LUMP_START,\r
111 GKEY_LUMP_START,\r
112 BKEY_LUMP_START,\r
113 0,\r
114 //SCROLL_LUMP_START,\r
115 CHEST_LUMP_START,\r
116 PLAYER_LUMP_START,\r
117 //WALL1_LUMP_START,\r
118 //WALL2_LUMP_START,\r
119 //BDOOR_LUMP_START,\r
120 0,0,0,\r
121 GODESS_LUMP_START,\r
122 MAGE_LUMP_START,\r
123 BAT_LUMP_START,\r
124 GREL_LUMP_START,\r
125 TOMBSTONES_LUMP_START,\r
126 ZOMBIE_LUMP_START,\r
127 ANT_LUMP_START,\r
128 SKELDUDE_LUMP_START,\r
129 RGEM_LUMP_START,\r
130 GGEM_LUMP_START,\r
131 BGEM_LUMP_START,\r
132 YGEM_LUMP_START,\r
133 PGEM_LUMP_START,\r
134 0,                                      //RKEY2_LUMP_START,\r
135 DRAGON_LUMP_START,\r
136 OBJ_WARP_LUMP_START,\r
137 EYE_LUMP_START,\r
138 REDDEMON_LUMP_START,\r
139 0,                                      //PIT_LUMP_START,\r
140 TIME_LUMP_START,\r
141 O_WATER_CHEST_LUMP_START,\r
142 TREE_LUMP_START,\r
143 ARCH1_LUMP_START,\r
144 BUNNY_LUMP_START,\r
145 ANTHILL_LUMP_START,\r
146 COLUMN_LUMP_START,\r
147 SULPHURGAS_LUMP_START,\r
148 FIREPOT_LUMP_START,\r
149 0,                                      //WHIRLPOOL_LUMP_START,\r
150 FOUNTAIN_LUMP_START,\r
151 FORCEFIELD_LUMP_START,\r
152 ARCH2_LUMP_START,\r
153 ARCH3_LUMP_START,\r
154 ARCH4_LUMP_START,\r
155 ARCH5_LUMP_START,\r
156 ARCH6_LUMP_START,\r
157 SKELHANG_LUMP_START,\r
158 0,                                      //SKELPILE_LUMP_START,\r
159 ARCH7_LUMP_START,\r
160 ARCH8_LUMP_START,\r
161 ARCH9_LUMP_START,\r
162 ARCH10_LUMP_START,\r
163 ARCH11_LUMP_START,\r
164 ARCH12_LUMP_START,\r
165 ARCH13_LUMP_START,\r
166 };\r
167 \r
168 \r
169 int     lumpend[NUMLUMPS] = {\r
170 SUCCUBUS_LUMP_END,\r
171 FATDEMON_LUMP_END,\r
172 BOLT_LUMP_END,\r
173 NUKE_LUMP_END,\r
174 POTION_LUMP_END,\r
175 RKEY_LUMP_END,\r
176 YKEY_LUMP_END,\r
177 GKEY_LUMP_END,\r
178 BKEY_LUMP_END,\r
179 0,\r
180 //SCROLL_LUMP_END,\r
181 CHEST_LUMP_END,\r
182 PLAYER_LUMP_END,\r
183 0,0,0,\r
184 GODESS_LUMP_END,\r
185 MAGE_LUMP_END,\r
186 BAT_LUMP_END,\r
187 GREL_LUMP_END,\r
188 TOMBSTONES_LUMP_END,\r
189 ZOMBIE_LUMP_END,\r
190 ANT_LUMP_END,\r
191 SKELDUDE_LUMP_END,\r
192 RGEM_LUMP_END,\r
193 GGEM_LUMP_END,\r
194 BGEM_LUMP_END,\r
195 YGEM_LUMP_END,\r
196 PGEM_LUMP_END,\r
197 0,                                      //RKEY2_LUMP_END,\r
198 DRAGON_LUMP_END,\r
199 OBJ_WARP_LUMP_END,\r
200 EYE_LUMP_END,\r
201 REDDEMON_LUMP_END,\r
202 0,                                      //PIT_LUMP_END,\r
203 TIME_LUMP_END,\r
204 O_WATER_CHEST_LUMP_END,\r
205 TREE_LUMP_END,\r
206 ARCH1_LUMP_END,\r
207 BUNNY_LUMP_END,\r
208 ANTHILL_LUMP_END,\r
209 COLUMN_LUMP_END,\r
210 SULPHURGAS_LUMP_END,\r
211 FIREPOT_LUMP_END,\r
212 0,                                      //WHIRLPOOL_LUMP_END,\r
213 FOUNTAIN_LUMP_END,\r
214 FORCEFIELD_LUMP_END,\r
215 ARCH2_LUMP_END,\r
216 ARCH3_LUMP_END,\r
217 ARCH4_LUMP_END,\r
218 ARCH5_LUMP_END,\r
219 ARCH6_LUMP_END,\r
220 SKELHANG_LUMP_END,\r
221 0,                                      //SKELPILE_LUMP_END,\r
222 ARCH7_LUMP_END,\r
223 ARCH8_LUMP_END,\r
224 ARCH9_LUMP_END,\r
225 ARCH10_LUMP_END,\r
226 ARCH11_LUMP_END,\r
227 ARCH12_LUMP_END,\r
228 ARCH13_LUMP_END,\r
229 };\r
230 \r
231 \r
232 //extern unsigned scolor,gcolor;\r
233 \r
234 \r
235 /*\r
236 =============================================================================\r
237 \r
238                                                  GLOBAL VARIABLES\r
239 \r
240 =============================================================================\r
241 */\r
242 \r
243 unsigned        latchpics[NUMLATCHPICS];\r
244 unsigned        tileoffsets[NUMTILE16];\r
245 unsigned        textstarts[27];\r
246 \r
247 boolean splitscreen=false;\r
248 \r
249 /*\r
250 =============================================================================\r
251 \r
252                                                  LOCAL VARIABLES\r
253 \r
254 =============================================================================\r
255 */\r
256 \r
257 boolean lumpneeded[NUMLUMPS];\r
258 \r
259 \r
260 //===========================================================================\r
261 \r
262 //==========================================================================\r
263 //\r
264 //\r
265 //                                                      LOCAL PROTOTYPES\r
266 //\r
267 //\r
268 //==========================================================================\r
269 \r
270 void CashPoints(void);\r
271 \r
272 \r
273 \r
274 /*\r
275 ==========================\r
276 =\r
277 = ScanInfoPlane\r
278 =\r
279 = Spawn all actors and mark down special places\r
280 =\r
281 ==========================\r
282 */\r
283 \r
284 void ScanInfoPlane (void)\r
285 {\r
286         unsigned char hibyte;\r
287         unsigned        x,y,i,j;\r
288         unsigned int tile;\r
289         unsigned        far     *start;\r
290 \r
291         InitObjList();                  // start spawning things with a clean slate\r
292 \r
293         scolor = gcolor = 0;\r
294         skycolor = &scolor;\r
295         groundcolor = &gcolor;\r
296 \r
297 \r
298         memset (lumpneeded,0,sizeof(lumpneeded));\r
299 \r
300         start = mapsegs[2];\r
301         for (y=0;y<mapheight;y++)\r
302                 for (x=0;x<mapwidth;x++)\r
303                 {\r
304                         tile = *start++;\r
305                         hibyte = tile >> 8;\r
306                         tile &= 0xff;\r
307 \r
308                         switch (hibyte)\r
309                         {\r
310                                 char hi;\r
311 \r
312                                 case 0xFB:\r
313                                         wall_anim_time = tile;\r
314                                         tile = 0;\r
315                                         break;\r
316 \r
317                                 case 0xfa:                                                              // sky/ground color\r
318                                 case 0xf9:                                                              // sky/ground 'strip'\r
319                                         x++;\r
320                                         tile = *start++;\r
321                                         hi = tile >> 8;\r
322                                         tile &= 0xff;\r
323                                         switch (hibyte)\r
324                                         {\r
325                                                 case 0xfa:                      // sky / ground color\r
326                                                         scolor = ((hi)|(hi<<8));\r
327                                                         gcolor = ((tile)|(tile<<8));\r
328                                                         skycolor = &scolor;\r
329                                                         groundcolor = &gcolor;\r
330                                                 break;\r
331 \r
332                                                 case 0xf9:                      // sky / ground 'strip'\r
333                                                 break;\r
334                                         }\r
335                                 break;\r
336                         }\r
337 \r
338                         if ((!tile) || (hibyte))\r
339                                 continue;\r
340 \r
341                         switch (tile)\r
342                         {\r
343                         case 1:\r
344                         case 2:\r
345                         case 3:\r
346                         case 4:\r
347                                 lumpneeded[PLAYERLUMP] = true;\r
348                                 SpawnPlayer(x,y,NORTH+tile-1);\r
349                                 break;\r
350 \r
351                         case 5:\r
352                         case 6:\r
353                         case 7:\r
354                         case 8:\r
355                         case 9:\r
356                         case 10:\r
357                         case 11:\r
358                                 lumpneeded[tile-5+BOLTLUMP] = true;\r
359                                 SpawnBonus(x,y,tile-5);\r
360                                 break;\r
361 \r
362 #if 0\r
363                         case 12:\r
364                         case 13:\r
365                         case 14:\r
366                         case 15:\r
367                         case 16:\r
368                         case 17:\r
369                         case 18:\r
370                         case 19:\r
371                                 lumpneeded[SCROLLLUMP] = true;\r
372                                 SpawnBonus(x,y,B_SCROLL1+tile-12);\r
373                                 break;\r
374 #endif\r
375 \r
376                         case 20:\r
377                                 lumpneeded[REDDEMONLUMP] = true;\r
378                                 SpawnRedDemon (x,y);\r
379                                 break;\r
380 \r
381 #if 0\r
382                         case 20:        // goal\r
383                                 lumpneeded[GOALLUMP] = true;\r
384                                 SpawnBonus(x,y,B_GOAL);\r
385                                 break;\r
386 #endif\r
387 \r
388                         case 21:\r
389                                 lumpneeded[GODESSLUMP] = true;\r
390                                 SpawnGodess (x,y);\r
391                                 break;\r
392 \r
393                         case 22:\r
394                                 lumpneeded[FATDEMONLUMP] = true;\r
395                                 SpawnFatDemon (x,y);\r
396                                 break;\r
397 \r
398                         case 23:\r
399                                 lumpneeded[SUCCUBUSLUMP] = true;\r
400                                 SpawnSuccubus (x,y);\r
401                                 break;\r
402 \r
403                         case 24:\r
404                                 lumpneeded[DRAGONLUMP] = true;\r
405                                 SpawnDragon(x,y);\r
406                                 break;\r
407 \r
408                         case 25:\r
409                                 lumpneeded[BATLUMP] = true;\r
410                                 SpawnBat (x,y);\r
411                                 break;\r
412 \r
413                         case 26:\r
414                                 lumpneeded[EYELUMP] = true;\r
415                                 SpawnEye(x,y);\r
416                                 break;\r
417 \r
418                         case 27:\r
419                                 lumpneeded[MAGELUMP] = true;\r
420                                 SpawnMage (x,y);\r
421                                 break;\r
422 \r
423                         case 28:\r
424                                 lumpneeded[RKEYLUMP] = lumpneeded[GRELLUMP] = true;\r
425                                 SpawnGrelminar (x,y);\r
426                                 break;\r
427 \r
428                         case 30:\r
429                                 lumpneeded[ANTLUMP] = true;\r
430                                 SpawnAnt(x,y);\r
431                                 break;\r
432 \r
433                         case 31:\r
434                         case 32:\r
435                         case 33:\r
436                         case 34:\r
437                         case 35:\r
438                                 lumpneeded[OBJ_WARPLUMP] = true;\r
439                                 SpawnWarp (x,y,tile-30);\r
440                                 break;\r
441 \r
442                         case 36:\r
443                                 lumpneeded[ZOMBIELUMP] = true;\r
444                                 SpawnZombie(x,y);\r
445                                 break;\r
446 \r
447                         case 37:\r
448                                 lumpneeded[SKELETONLUMP] = true;\r
449                                 SpawnSkeleton(x,y);\r
450                                 break;\r
451 \r
452                         case 38:\r
453                                 lumpneeded[SKELETONLUMP] = true;\r
454                                 SpawnWallSkeleton(x,y);\r
455                                 break;\r
456 \r
457                         case 39:\r
458                                 lumpneeded[FTIMELUMP] = true;\r
459                                 SpawnFTime(x,y);\r
460                                 break;\r
461 \r
462                         case 40:\r
463                         case 41:\r
464                         case 42:\r
465                         case 43:\r
466                         case 44:\r
467                                 lumpneeded[tile-40+RGEMLUMP] = true;\r
468                                 SpawnBonus(x,y,tile-40+B_RGEM);\r
469                         break;\r
470 \r
471                         case 45:\r
472                         case 46:\r
473                         case 47:\r
474                                 lumpneeded[TOMBSTONESLUMP] = true;\r
475                                 SpawnTombstone(x,y,tile-45);\r
476                                 break;\r
477 \r
478 #if 0\r
479                         case 48:\r
480                                 lumpneeded[PITLUMP]     = true;\r
481                                 SpawnWarp(x,y,0);\r
482                                 break;\r
483 #endif\r
484                         case 49:        // chest\r
485                                 if (gcolor == 0x0101)\r
486                                         lumpneeded[WATERCHESTLUMP] = true;\r
487                                 else\r
488                                         lumpneeded[CHESTLUMP] = true;\r
489                                 SpawnBonus(x,y,B_CHEST);\r
490                         break;\r
491 \r
492                         case 50:\r
493                                 lumpneeded[TREELUMP] = true;\r
494                                 SpawnTree(x,y);\r
495                                 break;\r
496 \r
497                         case 51:\r
498                                 lumpneeded[BUNNYLUMP] = true;\r
499                                 SpawnBunny(x,y);\r
500                                 break;\r
501 \r
502                         case 52:\r
503                                 lumpneeded[ARCH1LUMP] = true;\r
504                                 SpawnArch(x,y,1);\r
505                                 break;\r
506 \r
507                         case 53:\r
508                                 lumpneeded[ANTHILLLUMP] = true;\r
509                                 SpawnWarp(x,y,0);\r
510                                 break;\r
511 \r
512                         case 54:\r
513                                 lumpneeded[COLUMNLUMP] = true;\r
514                                 SpawnMiscObjects(x,y,1);                //1=column,2=sulphur hole,3=fire pot,4=fountain\r
515                                 break;\r
516 \r
517                         case 55:\r
518                                 lumpneeded[SULPHURGASLUMP] = true;\r
519                                 SpawnMiscObjects(x,y,2);\r
520                                 break;\r
521 \r
522                         case 56:\r
523                                 lumpneeded[FIREPOTLUMP] = true;\r
524                                 SpawnMiscObjects(x,y,3);\r
525                                 break;\r
526 \r
527                         case 57:\r
528                                 lumpneeded[ARCH13LUMP] = true;\r
529                                 SpawnArch(x,y,13);\r
530                                 break;\r
531 \r
532                         case 58:\r
533                                 lumpneeded[FOUNTAINLUMP] = true;\r
534                                 SpawnMiscObjects(x,y,4);\r
535                                 break;\r
536 \r
537                         case 59:\r
538                                 lumpneeded[FORCEFIELDLUMP] = true;\r
539                                 SpawnForceField(x,y);\r
540                                 break;\r
541 \r
542                         case 60:\r
543                                 lumpneeded[ARCH2LUMP] = true;\r
544                                 SpawnArch(x,y,2);\r
545                                 break;\r
546 \r
547                         case 61:\r
548                                 lumpneeded[ARCH3LUMP] = true;\r
549                                 SpawnArch(x,y,3);\r
550                                 break;\r
551 \r
552                         case 62:\r
553                                 lumpneeded[ARCH4LUMP] = true;\r
554                                 SpawnArch(x,y,4);\r
555                                 break;\r
556 \r
557                         case 63:\r
558                                 lumpneeded[ARCH5LUMP] = true;\r
559                                 SpawnArch(x,y,5);\r
560                                 break;\r
561 \r
562                         case 64:\r
563                                 lumpneeded[ARCH6LUMP] = true;\r
564                                 SpawnArch(x,y,6);\r
565                                 break;\r
566 \r
567                         case 65:\r
568                                 lumpneeded[SKELHANGLUMP] = true;\r
569                                 lumpneeded[SKELETONLUMP] = true;\r
570                                 SpawnSkeletonHanging(x,y);\r
571                                 break;\r
572 \r
573                         case 66:\r
574                                 lumpneeded[ARCH12LUMP] = true;\r
575                                 SpawnArch(x,y,12);\r
576                                 break;\r
577 \r
578                         case 67:\r
579                                 lumpneeded[ARCH7LUMP] = true;\r
580                                 SpawnArch(x,y,7);\r
581                                 break;\r
582 \r
583                         case 68:\r
584                                 lumpneeded[ARCH8LUMP] = true;\r
585                                 SpawnArch(x,y,8);\r
586                                 break;\r
587 \r
588                         case 69:\r
589                                 lumpneeded[ARCH9LUMP] = true;\r
590                                 SpawnArch(x,y,9);\r
591                                 break;\r
592 \r
593                         case 70:\r
594                                 lumpneeded[ARCH10LUMP] = true;\r
595                                 SpawnArch(x,y,10);\r
596                                 break;\r
597 \r
598                         case 71:\r
599                                 lumpneeded[ARCH11LUMP] = true;\r
600                                 SpawnArch(x,y,11);\r
601                                 break;\r
602                         }\r
603                 }\r
604 \r
605 }\r
606 \r
607 //==========================================================================\r
608 \r
609 /*\r
610 ==================\r
611 =\r
612 = ScanText\r
613 =\r
614 ==================\r
615 */\r
616 \r
617 void ScanText (void)\r
618 {\r
619         int     i;\r
620         char far *text;\r
621 \r
622         text = (char _seg *)grsegs[LEVEL1TEXT+mapon];\r
623 \r
624         textstarts[0] = 0;\r
625 \r
626         for (i=1;i<=26;i++)\r
627         {\r
628                 while (*text != '\n')\r
629                 {\r
630                         if (*text == '\r')\r
631                                 *text = 0;\r
632                         text++;\r
633                 }\r
634                 text++;\r
635                 textstarts[i] = FP_OFF(text);\r
636         }\r
637 \r
638 }\r
639 \r
640 //==========================================================================\r
641 \r
642 /*\r
643 ==================\r
644 =\r
645 = DrawEnterScreen\r
646 =\r
647 ==================\r
648 */\r
649 #if 0\r
650 static  char    *levelnames[] =\r
651                                 {\r
652                                         "Programmers Test Map",\r
653                                         "The Garden of Tears",\r
654                                         "The Den of Zombies",\r
655                                         "The Mausoleum Grounds",\r
656                                         "The Main Floor of the Mausoleum",\r
657                                         "Mike's Blastable Passage",\r
658                                         "The Crypt of Nemesis the Undead",\r
659                                         "The Subterranean Vault",\r
660                                         "The Ancient Aqueduct",\r
661                                         "The Orc Mines",\r
662                                         "The Lair of the Troll",\r
663                                         "The Demon's Inferno",\r
664                                         "The Battleground of the Titans",\r
665                                         "The Coven of Mages",\r
666                                         "The Inner Sanctum",\r
667                                         "The Haunt of Nemesis",\r
668                                         "The Passage to the Surface",\r
669                                         "Big Jim's Domain",\r
670                                         "Nolan",\r
671                                         "19",\r
672                                         "20",\r
673                                         "21",\r
674                                         "22",\r
675                                         "23",\r
676                                         "24",\r
677                                         "25",\r
678                                         "26",\r
679                                         "27",\r
680                                         "28",\r
681                                         "29",\r
682                                         "30",\r
683                                         "31",\r
684                                         "32",\r
685                                         "33",\r
686                                         "34",\r
687                                         "35",\r
688                                         "36",\r
689                                         "37",\r
690                                         "38",\r
691                                         "39",\r
692                                 };\r
693 #endif\r
694 \r
695 void DrawEnterScreen (void)\r
696 {\r
697         int width;\r
698 \r
699         bufferofs = displayofs = screenloc[screenpage];\r
700         VW_Bar(0,0,VIEWWIDTH,VIEWHEIGHT,0);\r
701 //      width = strlen(levelnames[gamestate.mapon]);\r
702         width = strlen("You enter a new area ...");\r
703         if (width < 20)\r
704                 width = 20;\r
705         CenterWindow(width,3);\r
706         US_CPrint("\nYou enter a new area ...\n");\r
707 //      US_CPrint(levelnames[gamestate.mapon]);\r
708 }\r
709 \r
710 //==========================================================================\r
711 \r
712 boolean tileneeded[NUMFLOORS];\r
713 \r
714 \r
715 /*\r
716 ==================\r
717 =\r
718 = CacheScaleds\r
719 =\r
720 ==================\r
721 */\r
722 \r
723 void CacheScaleds (void)\r
724 {\r
725         int     i,j;\r
726         unsigned        source,dest;\r
727 \r
728         FreeUpMemory ();\r
729         CA_CacheGrChunk(LEVEL1TEXT+mapon);\r
730         ScanText ();\r
731 \r
732 //\r
733 // make sure we are displaying screenpage 0\r
734 //\r
735         if (screenpage)\r
736         {\r
737                 source = screenloc[screenpage];\r
738                 dest = screenloc[0];\r
739                 VW_ScreenToScreen (source,dest,40,VIEWHEIGHT);\r
740                 screenpage = 0;\r
741                 VW_SetScreen (dest,0);\r
742                 displayofs = dest;\r
743         }\r
744 \r
745 //\r
746 // cache wall pictures\r
747 //\r
748         for (i=1;i<NUMFLOORS;i++)\r
749                 if (tileneeded[i])\r
750                 {\r
751                         SetupScaleWall (walllight1[i]);\r
752                         SetupScaleWall (walldark1[i]);\r
753                 }\r
754 \r
755 //\r
756 // cache the actor pictures\r
757 //\r
758         for (i=0;i<NUMLUMPS;i++)\r
759                 if (lumpneeded[i])\r
760                         for (j=lumpstart[i];j<=lumpend[i];j++)\r
761                                 SetupScalePic(j);\r
762 \r
763         source = screenloc[0];\r
764         for (i=1;i<=2;i++)\r
765         {\r
766                 dest = screenloc[i];\r
767                 VW_ScreenToScreen (source,dest,40,VIEWHEIGHT);\r
768         }\r
769 \r
770         screenpage = 1;\r
771 }\r
772 \r
773 //==========================================================================\r
774 \r
775 \r
776 /*\r
777 ==================\r
778 =\r
779 = SetupGameLevel\r
780 =\r
781 ==================\r
782 */\r
783 \r
784 void SetupGameLevel ()\r
785 {\r
786         int     x,y,i,loop;\r
787         unsigned        far *map,tile,far *spotptr,spot;\r
788         unsigned                search_tile;\r
789         boolean         exploding_walls_present = false;\r
790 \r
791         memset (tileneeded,0,sizeof(tileneeded));\r
792 //\r
793 // randomize if not a demo\r
794 //\r
795 #if 0\r
796         if (DemoMode)\r
797         {\r
798                 US_InitRndT(false);\r
799                 gamestate.difficulty = gd_Normal;\r
800         }\r
801         else\r
802 #endif\r
803                 US_InitRndT(true);\r
804 \r
805 //\r
806 // load the level\r
807 //\r
808         CA_CacheMap (gamestate.mapon);\r
809 \r
810         mapwidth = mapheaderseg[mapon]->width;\r
811         mapheight = mapheaderseg[mapon]->height;\r
812 \r
813 //\r
814 // make a lookup table for the maps left edge\r
815 //\r
816         spot = 0;\r
817         for (y=0;y<mapheight;y++)\r
818         {\r
819           farmapylookup[y] = spot;\r
820           spot += mapwidth;\r
821         }\r
822 \r
823 \r
824 //\r
825 // copy the wall data to a data segment array\r
826 //\r
827         memset (tilemap,0,sizeof(tilemap));\r
828         memset (actorat,0,sizeof(actorat));\r
829         map = mapsegs[0];\r
830         spotptr = mapsegs[2];\r
831         for (y=0;y<mapheight;y++)\r
832                 for (x=0;x<mapwidth;x++)\r
833                 {\r
834                         tile = *map++;\r
835 \r
836                         if (((*spotptr)>>8) == EXP_WALL_CODE)\r
837                         {\r
838                                 exploding_walls_present = true;\r
839                         }\r
840 \r
841                         if (tile<NUMFLOORS)\r
842                         {\r
843 #if 0\r
844                                 if (tile == WALL_SKELETON_CODE)\r
845                                 {\r
846                                         tileneeded[tile+1] = tileneeded[tile+2] = true;\r
847                                         tilemap[x][y] = tile;\r
848                                 }\r
849 #endif\r
850                                 if ((tile == 66) || (tile == 67) || (tile == 68) || (tile == 69))\r
851                                 {\r
852                                         if ((tile == 66) || (tile == 67))\r
853                                                 tileneeded[tile+2] = true;\r
854                                         tileneeded[21] = tileneeded[tile] = true;\r
855                                         tilemap[x][y] = tile;\r
856                                 }\r
857                                 else\r
858                                 if (tile != INVISIBLEWALL)\r
859                                 {\r
860                                         tileneeded[tile] = true;\r
861                                         tilemap[x][y] = tile;\r
862                                         if (ANIM_FLAGS(tile))\r
863                                         {\r
864                                                 search_tile = tile+(char signed)ANIM_FLAGS(tile);\r
865 \r
866                                                 if (!tileneeded[search_tile])\r
867                                                         while (search_tile != tile)\r
868                                                         {\r
869                                                                 tileneeded[search_tile] = true;\r
870                                                                 if (ANIM_FLAGS(search_tile))\r
871                                                                         search_tile += (char signed)ANIM_FLAGS(search_tile);\r
872                                                                 else\r
873                                                                         TrashProg("Unending Tile Animation!");\r
874                                                         }\r
875                                         }\r
876 \r
877                                 }\r
878                                 if (tile>0)\r
879                                         (unsigned)actorat[x][y] = tile;\r
880                         }\r
881                         spotptr++;\r
882                 }\r
883 \r
884 \r
885         //\r
886         // Mark any gfx chunks needed\r
887         //\r
888 \r
889 //      CA_MarkGrChunk(NORTHICONSPR);\r
890 //      CA_CacheMarks(NULL);\r
891 \r
892 \r
893 //\r
894 // decide which graphics are needed and spawn actors\r
895 //\r
896         zombie_base_delay = 0;  // (1*60) + random(1*60);\r
897         ScanInfoPlane ();\r
898         _fmemset(wall_anim_pos,0,sizeof(wall_anim_pos));\r
899 \r
900 \r
901 //\r
902 // mark which exploding walls are needed ---- the check for floor color\r
903 // is preformed in ScanInfoPlane.\r
904 //\r
905 \r
906         if (exploding_walls_present)\r
907         {\r
908                                 extern unsigned gnd_colors[];\r
909 \r
910                                 if (gcolor == 0x0101)\r
911                                         tileneeded[WATEREXP] = tileneeded[WATEREXP+1] = tileneeded[WATEREXP+2] = true;\r
912                                 else\r
913                                         tileneeded[WALLEXP] = tileneeded[WALLEXP+1] = tileneeded[WALLEXP+2] = true;\r
914 \r
915         }\r
916 \r
917 \r
918 //\r
919 // have the caching manager load and purge stuff to make sure all marks\r
920 // are in memory\r
921 //\r
922         CA_LoadAllSounds ();\r
923 }\r
924 \r
925 //==========================================================================\r
926 \r
927 /*\r
928 =====================\r
929 =\r
930 = LatchDrawPic\r
931 =\r
932 =====================\r
933 */\r
934 \r
935 void LatchDrawPic (unsigned x, unsigned y, unsigned picnum)\r
936 {\r
937         unsigned height, source, dest;\r
938         unsigned wide;\r
939 \r
940         wide = pictable[picnum-STARTPICS].width;\r
941         height = pictable[picnum-STARTPICS].height;\r
942         dest = bufferofs + ylookup[y]+x;\r
943         source = latchpics[picnum-FIRSTLATCHPIC];\r
944 \r
945         EGAWRITEMODE(1);\r
946         EGAMAPMASK(15);\r
947 \r
948 asm     mov     bx,[linewidth]\r
949 asm     sub     bx,[wide]\r
950 \r
951 asm     mov     ax,[screenseg]\r
952 asm     mov     es,ax\r
953 asm     mov     ds,ax\r
954 \r
955 asm     mov     si,[source]\r
956 asm     mov     di,[dest]\r
957 asm     mov     dx,[height]                             // scan lines to draw\r
958 asm     mov     ax,[wide]\r
959 \r
960 lineloop:\r
961 asm     mov     cx,ax\r
962 asm     rep     movsb\r
963 asm     add     di,bx\r
964 \r
965 asm     dec     dx\r
966 asm     jnz     lineloop\r
967 \r
968 asm     mov     ax,ss\r
969 asm     mov     ds,ax                                   // restore turbo's data segment\r
970 \r
971         EGAWRITEMODE(0);\r
972 }\r
973 \r
974 #if USE_STRIPS\r
975 \r
976 //--------------------------------------------------------------------------\r
977 // LatchDrawPicStrip() - srcoff is distance into source file (in PIXELS!)\r
978 //--------------------------------------------------------------------------\r
979 void LatchDrawPicStrip (unsigned x, unsigned y, unsigned picnum, unsigned srcoff)\r
980 {\r
981         unsigned wide, height, source, dest, shift, srcmod;\r
982 \r
983         shift = (srcoff & 7) >> 1;\r
984         srcoff >>= 3;\r
985         wide = pictable[picnum-STARTPICS].width;\r
986         srcmod = wide - linewidth + (shift != 3);\r
987         if (wide > linewidth)\r
988                 wide = linewidth;\r
989         height = pictable[picnum-STARTPICS].height;\r
990         dest = bufferofs + ylookup[y]+x;\r
991 \r
992         picnum = ((picnum - (FIRSTSTRIPPIC+1)) >> 2) + (shift);\r
993         source = latchpics[(FIRSTSTRIPPIC-FIRSTLATCHPIC+1)+picnum];\r
994 \r
995         EGAWRITEMODE(1);\r
996         EGAMAPMASK(15);\r
997 \r
998 asm     mov     bx,[linewidth]\r
999 asm     sub     bx,[wide]\r
1000 \r
1001 asm     mov     ax,[screenseg]\r
1002 asm     mov     es,ax\r
1003 asm     mov     ds,ax\r
1004 \r
1005 asm     mov     si,[source]\r
1006 asm       add            si,[srcoff]\r
1007 asm     mov     di,[dest]\r
1008 asm     mov     dx,[height]                             // scan lines to draw\r
1009 asm     mov     ax,[wide]\r
1010 \r
1011 lineloop:\r
1012 asm     mov     cx,ax\r
1013 asm     rep     movsb\r
1014 asm     add     di,bx\r
1015 asm       add     si,[srcmod]\r
1016 \r
1017 asm     dec     dx\r
1018 asm     jnz     lineloop\r
1019 \r
1020 asm     mov     ax,ss\r
1021 asm     mov     ds,ax                                   // restore turbo's data segment\r
1022 \r
1023         EGAWRITEMODE(0);\r
1024 }\r
1025 \r
1026 #endif\r
1027 \r
1028 \r
1029 //==========================================================================\r
1030 \r
1031 /*\r
1032 =====================\r
1033 =\r
1034 = Victory\r
1035 =\r
1036 =====================\r
1037 */\r
1038 \r
1039 void Victory (boolean playsounds)\r
1040 {\r
1041         struct Shape shape;\r
1042 \r
1043         if (playsounds)\r
1044         {\r
1045                 SD_PlaySound (GETBOLTSND);\r
1046                 SD_WaitSoundDone ();\r
1047                 SD_PlaySound (GETNUKESND);\r
1048                 SD_WaitSoundDone ();\r
1049                 SD_PlaySound (GETPOTIONSND);\r
1050                 SD_WaitSoundDone ();\r
1051                 SD_PlaySound (GETKEYSND);\r
1052                 SD_WaitSoundDone ();\r
1053                 SD_PlaySound (GETSCROLLSND);\r
1054                 SD_WaitSoundDone ();\r
1055                 SD_PlaySound (GETPOINTSSND);\r
1056         }\r
1057 \r
1058         FreeUpMemory();\r
1059 \r
1060         if (!screenfaded)\r
1061                 VW_FadeOut();\r
1062 \r
1063         NormalScreen ();\r
1064 \r
1065         screenpage = bufferofs = 0;\r
1066 \r
1067         CA_CacheGrChunk (FINALEPIC);\r
1068         UNMARKGRCHUNK(FINALEPIC);\r
1069         VW_DrawPic(0, 0, FINALEPIC);\r
1070 \r
1071         VW_FadeIn();\r
1072 }\r
1073 \r
1074 //==========================================================================\r
1075 \r
1076 #if 0\r
1077 /*\r
1078 ===================\r
1079 =\r
1080 = Died\r
1081 =\r
1082 ===================\r
1083 */\r
1084 \r
1085 void Died (void)\r
1086 {\r
1087         unsigned page1,page2;\r
1088 //\r
1089 // fizzle fade screen to grey\r
1090 //\r
1091         FreeUpMemory ();\r
1092         SD_PlaySound (GAMEOVERSND);\r
1093         bufferofs = screenloc[(screenpage+1)%3];\r
1094         DisplayMsg("Though fallen, your Spirit ...",NULL);\r
1095 //      LatchDrawPic(0,0,DEADPIC);\r
1096 //      FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,false);\r
1097         IN_ClearKeysDown();\r
1098         while (!Keyboard[sc_Enter]);\r
1099 //      IN_Ack();\r
1100         VW_SetScreen (bufferofs,0);\r
1101         VW_ColorBorder(0);\r
1102 }\r
1103 #endif\r
1104 \r
1105 //==========================================================================\r
1106 \r
1107 /*\r
1108 ===================\r
1109 =\r
1110 = NormalScreen\r
1111 =\r
1112 ===================\r
1113 */\r
1114 \r
1115 void NormalScreen (void)\r
1116 {\r
1117          VW_SetSplitScreen (200);\r
1118          bufferofs = displayofs = SCREEN1START;\r
1119          VW_Bar(0,0,320,200,0);\r
1120          bufferofs = SCREEN2START;\r
1121          VW_Bar(0,0,320,200,0);\r
1122          VW_SetScreen (displayofs,0);\r
1123          splitscreen = false;\r
1124 }\r
1125 \r
1126 //==========================================================================\r
1127 \r
1128 /*\r
1129 ===================\r
1130 =\r
1131 = DrawPlayScreen\r
1132 =\r
1133 ===================\r
1134 */\r
1135 \r
1136 void DrawPlayScreen (void)\r
1137 {\r
1138         int     i,j,p,m;\r
1139 \r
1140         screenpage = 0;\r
1141 \r
1142         bufferofs = 0;\r
1143         VW_Bar (0,0,320,STATUSLINES,0);\r
1144         for (i=0;i<3;i++)\r
1145         {\r
1146                 bufferofs = screenloc[i];\r
1147                 VW_Bar (0,0,320,VIEWHEIGHT,0);\r
1148         }\r
1149 \r
1150         splitscreen = true;\r
1151         VW_SetSplitScreen(120);\r
1152         VW_SetScreen(screenloc[0],0);\r
1153 \r
1154         CA_CacheGrChunk (STATUSPIC);\r
1155 \r
1156         bufferofs = 0;\r
1157         VW_DrawPic (0,0,STATUSPIC);\r
1158 \r
1159         grneeded[STATUSPIC] &= ~ca_levelbit;\r
1160         MM_SetPurge(&grsegs[STATUSPIC],3);\r
1161 \r
1162         RedrawStatusWindow ();\r
1163         bufferofs = displayofs = screenloc[0];\r
1164 }\r
1165 \r
1166 \r
1167 //==========================================================================\r
1168 \r
1169 /*\r
1170 ===================\r
1171 =\r
1172 = LoadLatchMem\r
1173 =\r
1174 ===================\r
1175 */\r
1176 \r
1177 unsigned latchmemavail;\r
1178 \r
1179 void LoadLatchMem (void)\r
1180 {\r
1181         static unsigned base_destoff=0;\r
1182         static int base_numpics=0;\r
1183         int     i,j,p,m,numpics;\r
1184         byte    far *src, far *dest;\r
1185         unsigned        destoff;\r
1186 \r
1187         EGAWRITEMODE(0);\r
1188 \r
1189 //\r
1190 // draw some pics into latch memory\r
1191 //\r
1192 \r
1193   if (!base_numpics)\r
1194   {\r
1195 \r
1196 //\r
1197 // tile 8s\r
1198 //\r
1199         latchpics[0] = freelatch;\r
1200         src = (byte _seg *)grsegs[STARTTILE8];\r
1201         dest = MK_FP(0xa000,freelatch);\r
1202 \r
1203         for (i=0;i<NUMTILE8;i++)\r
1204         {\r
1205                 for (p=0;p<4;p++)\r
1206                 {\r
1207                         m = 1<<p;\r
1208                         asm     mov     dx,SC_INDEX\r
1209                         asm     mov     al,SC_MAPMASK\r
1210                         asm     mov     ah,[BYTE PTR m]\r
1211                         asm     out     dx,ax\r
1212                         for (j=0;j<8;j++)\r
1213                                 *(dest+j)=*src++;\r
1214                 }\r
1215                 dest+=8;\r
1216         }\r
1217 \r
1218 //\r
1219 // tile 16s\r
1220 //\r
1221         src = (byte _seg *)grsegs[STARTTILE16];\r
1222 \r
1223         for (i=0;i<NUMTILE16;i++)\r
1224         {\r
1225                 CA_CacheGrChunk (STARTTILE16+i);\r
1226                 src = (byte _seg *)grsegs[STARTTILE16+i];\r
1227                 if (src)\r
1228                 {\r
1229                         tileoffsets[i] = FP_OFF(dest);\r
1230                         for (p=0;p<4;p++)\r
1231                         {\r
1232                                 m = 1<<p;\r
1233                                 asm     mov     dx,SC_INDEX\r
1234                                 asm     mov     al,SC_MAPMASK\r
1235                                 asm     mov     ah,[BYTE PTR m]\r
1236                                 asm     out     dx,ax\r
1237                                 for (j=0;j<32;j++)\r
1238                                         *(dest+j)=*src++;\r
1239                         }\r
1240                         dest+=32;\r
1241                         MM_FreePtr (&grsegs[STARTTILE16+i]);\r
1242                         UNMARKGRCHUNK(STARTTILE16+i);\r
1243                 }\r
1244                 else\r
1245                         tileoffsets[i] = 0;\r
1246         }\r
1247 \r
1248 \r
1249 //\r
1250 // pics\r
1251 //\r
1252         numpics=1;\r
1253         destoff = FP_OFF(dest);\r
1254         for (i=FIRSTLATCHPIC+1;i<FIRSTGROUNDPIC;i++)\r
1255         {\r
1256                 latchpics[numpics++] = destoff;\r
1257                 CA_CacheGrChunk (i);\r
1258                 j = pictable[i-STARTPICS].width * pictable[i-STARTPICS].height;\r
1259                 VW_MemToScreen (grsegs[i],destoff,j,1);\r
1260                 destoff+=j;\r
1261                 MM_FreePtr (&grsegs[i]);\r
1262                 UNMARKGRCHUNK(i);\r
1263         }\r
1264 \r
1265         base_numpics = numpics;\r
1266         base_destoff = destoff;\r
1267 \r
1268   }\r
1269 \r
1270         numpics = base_numpics;\r
1271         destoff = base_destoff;\r
1272 \r
1273 #if USE_STRIPS\r
1274 //\r
1275 // ground pics\r
1276 //\r
1277         numpics++;\r
1278         for (i=FIRSTGROUNDPIC+1;i<FIRSTSTRIPPIC;i++)\r
1279         {\r
1280                 int shape = (*groundcolor & 0xf0) - 16;\r
1281 \r
1282         // Is current shape needed?\r
1283         //\r
1284                 if (shape != (i-(FIRSTGROUNDPIC+1)))\r
1285                 {\r
1286                         numpics++;\r
1287                         continue;\r
1288                 }\r
1289 \r
1290                 latchpics[numpics++] = destoff;\r
1291                 CA_CacheGrChunk (i);\r
1292                 j = pictable[i-STARTPICS].width * pictable[i-STARTPICS].height;\r
1293                 VW_MemToScreen (grsegs[i],destoff,j,1);\r
1294                 destoff+=j;\r
1295                 MM_FreePtr (&grsegs[i]);\r
1296                 UNMARKGRCHUNK(i);\r
1297         }\r
1298 \r
1299 \r
1300 //\r
1301 // 'parallax' strips - used in place of a sky color\r
1302 //\r
1303 // Under current setup, each strip takes about 7k in latch memory.\r
1304 // To create 2 pixel scrolling, 4 strips are needed, that's 28k of\r
1305 // latch memory needed to produce this effect.\r
1306 //\r
1307         numpics++;\r
1308         for (i=FIRSTSTRIPPIC+1;i<FIRSTSCALEPIC;i++)\r
1309         {\r
1310                 memptr work;\r
1311                 unsigned workdest,stripsize,planesize;\r
1312                 short loop,pic=i-STARTPICS;\r
1313                 int shape = (*skycolor & 0xf0) - 16;\r
1314 \r
1315         // Is current shape needed?\r
1316         //\r
1317                 if (shape != (i-(FIRSTSTRIPPIC+1)))\r
1318                 {\r
1319                         numpics++;\r
1320                         continue;\r
1321                 }\r
1322 \r
1323         // CAL_ShiftSprite() works with the SRC and DST in the same\r
1324         // segment. So we must allocate memory for two strips, and\r
1325         // move the base strip into that segment. Then we can use the\r
1326         // 2nd half of that memory for each shifted strip.\r
1327         //\r
1328                 CA_CacheGrChunk (i);\r
1329                 planesize = (pictable[pic].width+1) * pictable[pic].height;\r
1330                 stripsize = planesize * 4;\r
1331 //              MM_GetPtr(&work,(stripsize*2)+0000);\r
1332                 MM_GetPtr(&work,65536);\r
1333                 movedata((unsigned)grsegs[i],0,(unsigned)work,0,stripsize);\r
1334                 workdest = 32768; //(stripsize+15) & 0xFFF0;\r
1335 \r
1336         // Free base strip\r
1337         //\r
1338                 MM_FreePtr (&grsegs[i]);\r
1339                 UNMARKGRCHUNK(i);\r
1340 \r
1341         // Create three shifted strips and move 'em to latch!\r
1342         //\r
1343                 for (loop=3; loop; loop--)\r
1344                 {\r
1345                 // Produce current shift for this strip\r
1346                 //\r
1347                         latchpics[numpics++] = destoff;\r
1348                         CAL_ShiftSprite ((unsigned)work,0,workdest,pictable[pic].width,\r
1349                                                                   pictable[pic].height,loop*2,false);\r
1350 \r
1351                 // Copy this shift to latch memory\r
1352                 //\r
1353                         VW_MemToScreen ((memptr)((unsigned)work+(workdest>>4)),destoff,planesize,1);\r
1354                         destoff+=planesize;\r
1355                 }\r
1356 \r
1357         // Copy unshifted strip to latch\r
1358         //\r
1359                 latchpics[numpics++] = destoff;\r
1360                 planesize = pictable[pic].width * pictable[pic].height;\r
1361                 VW_MemToScreen (work,destoff,planesize,1);\r
1362                 destoff+=planesize;\r
1363 \r
1364         // Free work buffer\r
1365         //\r
1366                 MM_FreePtr(&work);\r
1367         }\r
1368 #endif\r
1369 \r
1370 // Keep track of how much latch memory we have...\r
1371 //\r
1372         latchmemavail = 65535-destoff;\r
1373 \r
1374         EGAMAPMASK(15);\r
1375 }\r
1376 \r
1377 //==========================================================================\r
1378 \r
1379 /*\r
1380 ===================\r
1381 =\r
1382 = FizzleOut\r
1383 =\r
1384 ===================\r
1385 */\r
1386 \r
1387 void FizzleOut (int showlevel)\r
1388 {\r
1389         unsigned page1,page2;\r
1390 //\r
1391 // fizzle fade screen to grey\r
1392 //\r
1393         bufferofs = screenloc[(screenpage+1)%3];\r
1394         if (showlevel)\r
1395                 DrawEnterScreen ();\r
1396         FizzleFade(bufferofs,displayofs,VIEWWIDTH,VIEWHEIGHT,false);\r
1397 }\r
1398 \r
1399 //==========================================================================\r
1400 \r
1401 /*\r
1402 ====================\r
1403 =\r
1404 = FreeUpMemory\r
1405 =\r
1406 ====================\r
1407 */\r
1408 \r
1409 void FreeUpMemory (void)\r
1410 {\r
1411         int     i;\r
1412 \r
1413         for (i=0;i<NUMSCALEPICS;i++)\r
1414                 if (shapedirectory[i])\r
1415                         MM_SetPurge (&(memptr)shapedirectory[i],3);\r
1416 \r
1417         for (i=0;i<NUMSCALEWALLS;i++)\r
1418                 if (walldirectory[i])\r
1419                         MM_SetPurge (&(memptr)walldirectory[i],3);\r
1420 }\r
1421 \r
1422 //==========================================================================\r
1423 \r
1424 #if 0\r
1425 \r
1426 /*\r
1427 ==================\r
1428 =\r
1429 = DrawHighScores\r
1430 =\r
1431 ==================\r
1432 */\r
1433 \r
1434 void    DrawHighScores(void)\r
1435 {\r
1436         char            buffer[16],*str;\r
1437         word            i,j,\r
1438                                 w,h,\r
1439                                 x,y;\r
1440         HighScore       *s;\r
1441 \r
1442 \r
1443         CA_CacheGrChunk (HIGHSCORESPIC);\r
1444         VWB_DrawPic (0,0,HIGHSCORESPIC);\r
1445         MM_SetPurge (&grsegs[HIGHSCORESPIC],3);\r
1446         UNMARKGRCHUNK(HIGHSCORESPIC);\r
1447 \r
1448         for (i = 0,s = Scores;i < MaxScores;i++,s++)\r
1449         {\r
1450                 PrintY = 68 + (16 * i);\r
1451 \r
1452                 //\r
1453                 // name\r
1454                 //\r
1455                 PrintX = 60;\r
1456                 US_Print(s->name);\r
1457 \r
1458                 //\r
1459                 // level\r
1460                 //\r
1461                 ultoa(s->completed,buffer,10);\r
1462                 for (str = buffer;*str;str++)\r
1463                         *str = *str + (129 - '0');      // Used fixed-width numbers (129...)\r
1464                 USL_MeasureString(buffer,&w,&h);\r
1465                 PrintX = (25 * 8) - 8 - w;\r
1466                 US_Print(buffer);\r
1467 \r
1468                 //\r
1469                 // score\r
1470                 //\r
1471                 ultoa(s->score,buffer,10);\r
1472                 for (str = buffer;*str;str++)\r
1473                         *str = *str + (129 - '0');      // Used fixed-width numbers (129...)\r
1474                 USL_MeasureString(buffer,&w,&h);\r
1475                 PrintX = (34 * 8) - 8 - w;\r
1476                 US_Print(buffer);\r
1477         }\r
1478 \r
1479         fontcolor = F_BLACK;\r
1480 }\r
1481 \r
1482 \r
1483 \r
1484 /*\r
1485 =======================\r
1486 =\r
1487 = CheckHighScore\r
1488 =\r
1489 =======================\r
1490 */\r
1491 \r
1492 void    CheckHighScore (long score,word other)\r
1493 {\r
1494         word            i,j;\r
1495         int                     n;\r
1496         HighScore       myscore;\r
1497 \r
1498         strcpy(myscore.name,"");\r
1499         myscore.score = score;\r
1500         myscore.completed = other;\r
1501 \r
1502         for (i = 0,n = -1;i < MaxScores;i++)\r
1503         {\r
1504                 if\r
1505                 (\r
1506                         (myscore.score > Scores[i].score)\r
1507                 ||      (\r
1508                                 (myscore.score == Scores[i].score)\r
1509                         &&      (myscore.completed > Scores[i].completed)\r
1510                         )\r
1511                 )\r
1512                 {\r
1513                         for (j = MaxScores;--j > i;)\r
1514                                 Scores[j] = Scores[j - 1];\r
1515                         Scores[i] = myscore;\r
1516                         n = i;\r
1517                         HighScoresDirty = true;\r
1518                         break;\r
1519                 }\r
1520         }\r
1521 \r
1522         if (n != -1)\r
1523         {\r
1524         //\r
1525         // got a high score\r
1526         //\r
1527                 DrawHighScores ();\r
1528                 PrintY = 68 + (16 * n);\r
1529                 PrintX = 60;\r
1530                 US_LineInput(PrintX,PrintY,Scores[n].name,nil,true,MaxHighName,100);\r
1531         }\r
1532 }\r
1533 \r
1534 #endif\r
1535 \r
1536 \r
1537 //==========================================================================\r
1538 \r
1539 /*\r
1540 ===================\r
1541 =\r
1542 = GameLoop\r
1543 =\r
1544 ===================\r
1545 */\r
1546 \r
1547 void GameLoop (void)\r
1548 {\r
1549         boolean wait = false;\r
1550         int i,xl,yl,xh,yh;\r
1551         char num[20];\r
1552 #ifdef PROFILE\r
1553         clock_t start,end;\r
1554 #endif\r
1555 \r
1556         DrawPlayScreen ();\r
1557         IN_ClearKeysDown();\r
1558 \r
1559 restart:\r
1560         if (!loadedgame)\r
1561         {\r
1562                 gamestate.difficulty = restartgame;\r
1563                 restartgame = gd_Continue;\r
1564                 DrawEnterScreen ();\r
1565                 if (gamestate.mapon != 8)\r
1566                         fizzlein = true;\r
1567                 wait = true;\r
1568         }\r
1569 \r
1570         do\r
1571         {\r
1572                 playstate = gd_Continue;\r
1573                 if (!loadedgame)\r
1574                         SetupGameLevel ();\r
1575                 else\r
1576                         loadedgame = false;\r
1577 \r
1578                 FreeUpMemory();\r
1579                 LoadLatchMem();\r
1580                 CacheScaleds ();\r
1581 \r
1582                 if (EASYMODEON)\r
1583                         DisplaySMsg("*** NOVICE ***", NULL);\r
1584                 else\r
1585                         DisplaySMsg("*** WARRIOR ***", NULL);\r
1586 \r
1587                 status_delay = 250;\r
1588 \r
1589                 RedrawStatusWindow();\r
1590                 if (wait)\r
1591                 {\r
1592                         VW_WaitVBL(120);\r
1593                         wait = false;\r
1594                 }\r
1595 \r
1596 #ifdef PROFILE\r
1597 start = clock();\r
1598 while (start == clock());\r
1599 start++;\r
1600 #endif\r
1601 \r
1602                 PlayLoop ();\r
1603 \r
1604 #ifdef PROFILE\r
1605 end = clock();\r
1606 itoa(end-start,str,10);\r
1607                 Quit (str);\r
1608 #endif\r
1609 \r
1610 \r
1611                 switch (playstate)\r
1612                 {\r
1613                 case ex_abort:\r
1614                         FreeUpMemory ();\r
1615                         return;\r
1616                 case ex_resetgame:\r
1617                         NewGame();\r
1618                 case ex_loadedgame:\r
1619                 case ex_warped:\r
1620                         FreeUpMemory();\r
1621                         if (playstate != ex_resetgame)\r
1622                                 DisplayMsg("                                      ", NULL);\r
1623                         DisplaySMsg("                  ", NULL);\r
1624                         goto restart;\r
1625                 case ex_victorious:\r
1626                         screenpage = 0;\r
1627                         bufferofs = 0;\r
1628                         status_flag = 0;\r
1629                         return;\r
1630                 }\r
1631 \r
1632         } while (1);\r
1633 \r
1634 }\r
1635 \r
1636 \r
1637 #if 0\r
1638 //\r
1639 // make wall pictures purgable\r
1640 //\r
1641         for (i=0;i<NUMSCALEWALLS;i++)\r
1642                 if (walldirectory[i])\r
1643                         MM_SetPurge (&(memptr)walldirectory[i],3);\r
1644 \r
1645 \r
1646 //\r
1647 // cache wall pictures back in\r
1648 //\r
1649         for (i=1;i<NUMFLOORS;i++)\r
1650                 if (tileneeded[i])\r
1651                 {\r
1652                         SetupScaleWall (walllight1[i]);\r
1653                         SetupScaleWall (walllight2[i]);\r
1654                         SetupScaleWall (walldark1[i]);\r
1655                         SetupScaleWall (walldark2[i]);\r
1656                 }\r
1657 #endif\r