OSDN Git Service

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