OSDN Git Service

going on vacation >.<
[proj16/16.git] / src / core / wl_main.c
1 // WL_MAIN.C\r
2 \r
3 #include <conio.h>\r
4 #include "WL_DEF.H"\r
5 #pragma hdrstop\r
6 \r
7 \r
8 /*\r
9 =============================================================================\r
10 \r
11                                                    WOLFENSTEIN 3-D\r
12 \r
13                                           An Id Software production\r
14 \r
15                                                    by John Carmack\r
16 \r
17 =============================================================================\r
18 */\r
19 \r
20 /*\r
21 =============================================================================\r
22 \r
23                                                  LOCAL CONSTANTS\r
24 \r
25 =============================================================================\r
26 */\r
27 \r
28 \r
29 #define FOCALLENGTH     (0x5700l)               // in global coordinates\r
30 #define VIEWGLOBAL      0x10000                 // globals visable flush to wall\r
31 \r
32 #define VIEWWIDTH       256                     // size of view window\r
33 #define VIEWHEIGHT      144\r
34 \r
35 /*\r
36 =============================================================================\r
37 \r
38                                                  GLOBAL VARIABLES\r
39 \r
40 =============================================================================\r
41 */\r
42 \r
43 char            str[80],str2[20];\r
44 int                             tedlevelnum;\r
45 boolean         tedlevel;\r
46 boolean         nospr;\r
47 boolean         IsA386;\r
48 int                     dirangle[9] = {0,ANGLES/8,2*ANGLES/8,3*ANGLES/8,4*ANGLES/8,\r
49         5*ANGLES/8,6*ANGLES/8,7*ANGLES/8,ANGLES};\r
50 \r
51 //\r
52 // proejection variables\r
53 //\r
54 fixed           focallength;\r
55 unsigned        screenofs;\r
56 int             viewwidth;\r
57 int             viewheight;\r
58 int             centerx;\r
59 int             shootdelta;                     // pixels away from centerx a target can be\r
60 fixed           scale,maxslope;\r
61 long            heightnumerator;\r
62 int                     minheightdiv;\r
63 \r
64 \r
65 void            Quit (char *error);\r
66 \r
67 boolean         startgame,loadedgame,virtualreality;\r
68 int             mouseadjustment;\r
69 \r
70 char    configname[13]="CONFIG.";\r
71 \r
72 \r
73 /*\r
74 =============================================================================\r
75 \r
76                                                  LOCAL VARIABLES\r
77 \r
78 =============================================================================\r
79 */\r
80 \r
81 \r
82 /*\r
83 ====================\r
84 =\r
85 = ReadConfig\r
86 =\r
87 ====================\r
88 */\r
89 \r
90 void ReadConfig(void)\r
91 {\r
92         int                     file;\r
93         SDMode          sd;\r
94         SMMode          sm;\r
95         SDSMode         sds;\r
96 \r
97 \r
98         if ( (file = open(configname,O_BINARY | O_RDONLY)) != -1)\r
99         {\r
100         //\r
101         // valid config file\r
102         //\r
103                 read(file,Scores,sizeof(HighScore) * MaxScores);\r
104 \r
105                 read(file,&sd,sizeof(sd));\r
106                 read(file,&sm,sizeof(sm));\r
107                 read(file,&sds,sizeof(sds));\r
108 \r
109                 read(file,&mouseenabled,sizeof(mouseenabled));\r
110                 read(file,&joystickenabled,sizeof(joystickenabled));\r
111                 read(file,&joypadenabled,sizeof(joypadenabled));\r
112                 read(file,&joystickprogressive,sizeof(joystickprogressive));\r
113                 read(file,&joystickport,sizeof(joystickport));\r
114 \r
115                 read(file,&dirscan,sizeof(dirscan));\r
116                 read(file,&buttonscan,sizeof(buttonscan));\r
117                 read(file,&buttonmouse,sizeof(buttonmouse));\r
118                 read(file,&buttonjoy,sizeof(buttonjoy));\r
119 \r
120                 read(file,&viewsize,sizeof(viewsize));\r
121                 read(file,&mouseadjustment,sizeof(mouseadjustment));\r
122 \r
123                 close(file);\r
124 \r
125                 if (sd == sdm_AdLib && !AdLibPresent && !SoundBlasterPresent)\r
126                 {\r
127                         sd = sdm_PC;\r
128                         sd = smm_Off;\r
129                 }\r
130 \r
131                 if ((sds == sds_SoundBlaster && !SoundBlasterPresent) ||\r
132                         (sds == sds_SoundSource && !SoundSourcePresent))\r
133                         sds = sds_Off;\r
134 \r
135                 if (!MousePresent)\r
136                         mouseenabled = false;\r
137                 if (!JoysPresent[joystickport])\r
138                         joystickenabled = false;\r
139 \r
140                 MainMenu[6].active=1;\r
141                 MainItems.curpos=0;\r
142         }\r
143         else\r
144         {\r
145         //\r
146         // no config file, so select by hardware\r
147         //\r
148                 if (SoundBlasterPresent || AdLibPresent)\r
149                 {\r
150                         sd = sdm_AdLib;\r
151                         sm = smm_AdLib;\r
152                 }\r
153                 else\r
154                 {\r
155                         sd = sdm_PC;\r
156                         sm = smm_Off;\r
157                 }\r
158 \r
159                 if (SoundBlasterPresent)\r
160                         sds = sds_SoundBlaster;\r
161                 else if (SoundSourcePresent)\r
162                         sds = sds_SoundSource;\r
163                 else\r
164                         sds = sds_Off;\r
165 \r
166                 if (MousePresent)\r
167                         mouseenabled = true;\r
168 \r
169                 joystickenabled = false;\r
170                 joypadenabled = false;\r
171                 joystickport = 0;\r
172                 joystickprogressive = false;\r
173 \r
174                 viewsize = 15;\r
175                 mouseadjustment=5;\r
176         }\r
177 \r
178         SD_SetMusicMode (sm);\r
179         SD_SetSoundMode (sd);\r
180         SD_SetDigiDevice (sds);\r
181 \r
182 }\r
183 \r
184 \r
185 /*\r
186 ====================\r
187 =\r
188 = WriteConfig\r
189 =\r
190 ====================\r
191 */\r
192 \r
193 void WriteConfig(void)\r
194 {\r
195         int                     file;\r
196 \r
197         file = open(configname,O_CREAT | O_BINARY | O_WRONLY,\r
198                                 S_IREAD | S_IWRITE | S_IFREG);\r
199 \r
200         if (file != -1)\r
201         {\r
202                 write(file,Scores,sizeof(HighScore) * MaxScores);\r
203 \r
204                 write(file,&SoundMode,sizeof(SoundMode));\r
205                 write(file,&MusicMode,sizeof(MusicMode));\r
206                 write(file,&DigiMode,sizeof(DigiMode));\r
207 \r
208                 write(file,&mouseenabled,sizeof(mouseenabled));\r
209                 write(file,&joystickenabled,sizeof(joystickenabled));\r
210                 write(file,&joypadenabled,sizeof(joypadenabled));\r
211                 write(file,&joystickprogressive,sizeof(joystickprogressive));\r
212                 write(file,&joystickport,sizeof(joystickport));\r
213 \r
214                 write(file,&dirscan,sizeof(dirscan));\r
215                 write(file,&buttonscan,sizeof(buttonscan));\r
216                 write(file,&buttonmouse,sizeof(buttonmouse));\r
217                 write(file,&buttonjoy,sizeof(buttonjoy));\r
218 \r
219                 write(file,&viewsize,sizeof(viewsize));\r
220                 write(file,&mouseadjustment,sizeof(mouseadjustment));\r
221 \r
222                 close(file);\r
223         }\r
224 }\r
225 \r
226 \r
227 //===========================================================================\r
228 \r
229 \r
230 /*\r
231 ========================\r
232 =\r
233 = Patch386\r
234 =\r
235 = Patch ldiv to use 32 bit instructions\r
236 =\r
237 ========================\r
238 */\r
239 \r
240 char    *JHParmStrings[] = {"no386",nil};\r
241 void Patch386 (void)\r
242 {\r
243 extern void far jabhack2(void);\r
244 extern int far  CheckIs386(void);\r
245 \r
246         int     i;\r
247 \r
248         for (i = 1;i < _argc;i++)\r
249                 if (US_CheckParm(_argv[i],JHParmStrings) == 0)\r
250                 {\r
251                         IsA386 = false;\r
252                         return;\r
253                 }\r
254 \r
255         if (CheckIs386())\r
256         {\r
257                 IsA386 = true;\r
258                 jabhack2();\r
259         }\r
260         else\r
261                 IsA386 = false;\r
262 }\r
263 \r
264 //===========================================================================\r
265 \r
266 /*\r
267 =====================\r
268 =\r
269 = NewGame\r
270 =\r
271 = Set up new game to start from the beginning\r
272 =\r
273 =====================\r
274 */\r
275 \r
276 void NewGame (int difficulty,int episode)\r
277 {\r
278         memset (&gamestate,0,sizeof(gamestate));\r
279         gamestate.difficulty = difficulty;\r
280         gamestate.weapon = gamestate.bestweapon\r
281                 = gamestate.chosenweapon = wp_pistol;\r
282         gamestate.health = 100;\r
283         gamestate.ammo = STARTAMMO;\r
284         gamestate.lives = 3;\r
285         gamestate.nextextra = EXTRAPOINTS;\r
286         gamestate.episode=episode;\r
287 \r
288         startgame = true;\r
289 }\r
290 \r
291 //===========================================================================\r
292 \r
293 void DiskFlopAnim(int x,int y)\r
294 {\r
295  static char which=0;\r
296  if (!x && !y)\r
297    return;\r
298  VWB_DrawPic(x,y,C_DISKLOADING1PIC+which);\r
299  VW_UpdateScreen();\r
300  which^=1;\r
301 }\r
302 \r
303 \r
304 long DoChecksum(byte far *source,unsigned size,long checksum)\r
305 {\r
306  unsigned i;\r
307 \r
308  for (i=0;i<size-1;i++)\r
309    checksum += source[i]^source[i+1];\r
310 \r
311  return checksum;\r
312 }\r
313 \r
314 \r
315 /*\r
316 ==================\r
317 =\r
318 = SaveTheGame\r
319 =\r
320 ==================\r
321 */\r
322 \r
323 boolean SaveTheGame(int file,int x,int y)\r
324 {\r
325         struct diskfree_t dfree;\r
326         long avail,size,checksum;\r
327         objtype *ob,nullobj;\r
328 \r
329 \r
330         if (_dos_getdiskfree(0,&dfree))\r
331           Quit("Error in _dos_getdiskfree call");\r
332 \r
333         avail = (long)dfree.avail_clusters *\r
334                         dfree.bytes_per_sector *\r
335                         dfree.sectors_per_cluster;\r
336 \r
337         size = 0;\r
338         for (ob = player; ob ; ob=ob->next)\r
339           size += sizeof(*ob);\r
340         size += sizeof(nullobj);\r
341 \r
342         size += sizeof(gamestate) +\r
343                         sizeof(LRstruct)*8 +\r
344                         sizeof(tilemap) +\r
345                         sizeof(actorat) +\r
346                         sizeof(laststatobj) +\r
347                         sizeof(statobjlist) +\r
348                         sizeof(doorposition) +\r
349                         sizeof(pwallstate) +\r
350                         sizeof(pwallx) +\r
351                         sizeof(pwally) +\r
352                         sizeof(pwalldir) +\r
353                         sizeof(pwallpos);\r
354 \r
355         if (avail < size)\r
356         {\r
357          Message(STR_NOSPACE1"\n"\r
358                          STR_NOSPACE2);\r
359          return false;\r
360         }\r
361 \r
362         checksum = 0;\r
363 \r
364 \r
365         DiskFlopAnim(x,y);\r
366         CA_FarWrite (file,(void far *)&gamestate,sizeof(gamestate));\r
367         checksum = DoChecksum((byte far *)&gamestate,sizeof(gamestate),checksum);\r
368 \r
369         DiskFlopAnim(x,y);\r
370 #ifdef SPEAR\r
371         CA_FarWrite (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*20);\r
372         checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*20,checksum);\r
373 #else\r
374         CA_FarWrite (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*8);\r
375         checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*8,checksum);\r
376 #endif\r
377 \r
378         DiskFlopAnim(x,y);\r
379         CA_FarWrite (file,(void far *)tilemap,sizeof(tilemap));\r
380         checksum = DoChecksum((byte far *)tilemap,sizeof(tilemap),checksum);\r
381         DiskFlopAnim(x,y);\r
382         CA_FarWrite (file,(void far *)actorat,sizeof(actorat));\r
383         checksum = DoChecksum((byte far *)actorat,sizeof(actorat),checksum);\r
384 \r
385         CA_FarWrite (file,(void far *)areaconnect,sizeof(areaconnect));\r
386         CA_FarWrite (file,(void far *)areabyplayer,sizeof(areabyplayer));\r
387 \r
388         for (ob = player ; ob ; ob=ob->next)\r
389         {\r
390          DiskFlopAnim(x,y);\r
391          CA_FarWrite (file,(void far *)ob,sizeof(*ob));\r
392         }\r
393         nullobj.active = ac_badobject;          // end of file marker\r
394         DiskFlopAnim(x,y);\r
395         CA_FarWrite (file,(void far *)&nullobj,sizeof(nullobj));\r
396 \r
397 \r
398 \r
399         DiskFlopAnim(x,y);\r
400         CA_FarWrite (file,(void far *)&laststatobj,sizeof(laststatobj));\r
401         checksum = DoChecksum((byte far *)&laststatobj,sizeof(laststatobj),checksum);\r
402         DiskFlopAnim(x,y);\r
403         CA_FarWrite (file,(void far *)statobjlist,sizeof(statobjlist));\r
404         checksum = DoChecksum((byte far *)statobjlist,sizeof(statobjlist),checksum);\r
405 \r
406         DiskFlopAnim(x,y);\r
407         CA_FarWrite (file,(void far *)doorposition,sizeof(doorposition));\r
408         checksum = DoChecksum((byte far *)doorposition,sizeof(doorposition),checksum);\r
409         DiskFlopAnim(x,y);\r
410         CA_FarWrite (file,(void far *)doorobjlist,sizeof(doorobjlist));\r
411         checksum = DoChecksum((byte far *)doorobjlist,sizeof(doorobjlist),checksum);\r
412 \r
413         DiskFlopAnim(x,y);\r
414         CA_FarWrite (file,(void far *)&pwallstate,sizeof(pwallstate));\r
415         checksum = DoChecksum((byte far *)&pwallstate,sizeof(pwallstate),checksum);\r
416         CA_FarWrite (file,(void far *)&pwallx,sizeof(pwallx));\r
417         checksum = DoChecksum((byte far *)&pwallx,sizeof(pwallx),checksum);\r
418         CA_FarWrite (file,(void far *)&pwally,sizeof(pwally));\r
419         checksum = DoChecksum((byte far *)&pwally,sizeof(pwally),checksum);\r
420         CA_FarWrite (file,(void far *)&pwalldir,sizeof(pwalldir));\r
421         checksum = DoChecksum((byte far *)&pwalldir,sizeof(pwalldir),checksum);\r
422         CA_FarWrite (file,(void far *)&pwallpos,sizeof(pwallpos));\r
423         checksum = DoChecksum((byte far *)&pwallpos,sizeof(pwallpos),checksum);\r
424 \r
425         //\r
426         // WRITE OUT CHECKSUM\r
427         //\r
428         CA_FarWrite (file,(void far *)&checksum,sizeof(checksum));\r
429 \r
430         return(true);\r
431 }\r
432 \r
433 //===========================================================================\r
434 \r
435 /*\r
436 ==================\r
437 =\r
438 = LoadTheGame\r
439 =\r
440 ==================\r
441 */\r
442 \r
443 boolean LoadTheGame(int file,int x,int y)\r
444 {\r
445         long checksum,oldchecksum;\r
446         objtype *ob,nullobj;\r
447 \r
448 \r
449         checksum = 0;\r
450 \r
451         DiskFlopAnim(x,y);\r
452         CA_FarRead (file,(void far *)&gamestate,sizeof(gamestate));\r
453         checksum = DoChecksum((byte far *)&gamestate,sizeof(gamestate),checksum);\r
454 \r
455         DiskFlopAnim(x,y);\r
456 #ifdef SPEAR\r
457         CA_FarRead (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*20);\r
458         checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*20,checksum);\r
459 #else\r
460         CA_FarRead (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*8);\r
461         checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*8,checksum);\r
462 #endif\r
463 \r
464         DiskFlopAnim(x,y);\r
465         SetupGameLevel ();\r
466 \r
467         DiskFlopAnim(x,y);\r
468         CA_FarRead (file,(void far *)tilemap,sizeof(tilemap));\r
469         checksum = DoChecksum((byte far *)tilemap,sizeof(tilemap),checksum);\r
470         DiskFlopAnim(x,y);\r
471         CA_FarRead (file,(void far *)actorat,sizeof(actorat));\r
472         checksum = DoChecksum((byte far *)actorat,sizeof(actorat),checksum);\r
473 \r
474         CA_FarRead (file,(void far *)areaconnect,sizeof(areaconnect));\r
475         CA_FarRead (file,(void far *)areabyplayer,sizeof(areabyplayer));\r
476 \r
477 \r
478 \r
479         InitActorList ();\r
480         DiskFlopAnim(x,y);\r
481         CA_FarRead (file,(void far *)player,sizeof(*player));\r
482 \r
483         while (1)\r
484         {\r
485          DiskFlopAnim(x,y);\r
486                 CA_FarRead (file,(void far *)&nullobj,sizeof(nullobj));\r
487                 if (nullobj.active == ac_badobject)\r
488                         break;\r
489                 GetNewActor ();\r
490          // don't copy over the links\r
491                 memcpy (new,&nullobj,sizeof(nullobj)-4);\r
492         }\r
493 \r
494 \r
495 \r
496         DiskFlopAnim(x,y);\r
497         CA_FarRead (file,(void far *)&laststatobj,sizeof(laststatobj));\r
498         checksum = DoChecksum((byte far *)&laststatobj,sizeof(laststatobj),checksum);\r
499         DiskFlopAnim(x,y);\r
500         CA_FarRead (file,(void far *)statobjlist,sizeof(statobjlist));\r
501         checksum = DoChecksum((byte far *)statobjlist,sizeof(statobjlist),checksum);\r
502 \r
503         DiskFlopAnim(x,y);\r
504         CA_FarRead (file,(void far *)doorposition,sizeof(doorposition));\r
505         checksum = DoChecksum((byte far *)doorposition,sizeof(doorposition),checksum);\r
506         DiskFlopAnim(x,y);\r
507         CA_FarRead (file,(void far *)doorobjlist,sizeof(doorobjlist));\r
508         checksum = DoChecksum((byte far *)doorobjlist,sizeof(doorobjlist),checksum);\r
509 \r
510         DiskFlopAnim(x,y);\r
511         CA_FarRead (file,(void far *)&pwallstate,sizeof(pwallstate));\r
512         checksum = DoChecksum((byte far *)&pwallstate,sizeof(pwallstate),checksum);\r
513         CA_FarRead (file,(void far *)&pwallx,sizeof(pwallx));\r
514         checksum = DoChecksum((byte far *)&pwallx,sizeof(pwallx),checksum);\r
515         CA_FarRead (file,(void far *)&pwally,sizeof(pwally));\r
516         checksum = DoChecksum((byte far *)&pwally,sizeof(pwally),checksum);\r
517         CA_FarRead (file,(void far *)&pwalldir,sizeof(pwalldir));\r
518         checksum = DoChecksum((byte far *)&pwalldir,sizeof(pwalldir),checksum);\r
519         CA_FarRead (file,(void far *)&pwallpos,sizeof(pwallpos));\r
520         checksum = DoChecksum((byte far *)&pwallpos,sizeof(pwallpos),checksum);\r
521 \r
522         CA_FarRead (file,(void far *)&oldchecksum,sizeof(oldchecksum));\r
523 \r
524         if (oldchecksum != checksum)\r
525         {\r
526          Message(STR_SAVECHT1"\n"\r
527                          STR_SAVECHT2"\n"\r
528                          STR_SAVECHT3"\n"\r
529                          STR_SAVECHT4);\r
530 \r
531          IN_ClearKeysDown();\r
532          IN_Ack();\r
533 \r
534          gamestate.score = 0;\r
535          gamestate.lives = 1;\r
536          gamestate.weapon =\r
537            gamestate.chosenweapon =\r
538            gamestate.bestweapon = wp_pistol;\r
539          gamestate.ammo = 8;\r
540         }\r
541 \r
542         return true;\r
543 }\r
544 \r
545 //===========================================================================\r
546 \r
547 /*\r
548 ==========================\r
549 =\r
550 = ShutdownId\r
551 =\r
552 = Shuts down all ID_?? managers\r
553 =\r
554 ==========================\r
555 */\r
556 \r
557 void ShutdownId (void)\r
558 {\r
559         US_Shutdown ();\r
560         SD_Shutdown ();\r
561         PM_Shutdown ();\r
562         IN_Shutdown ();\r
563         VW_Shutdown ();\r
564         CA_Shutdown ();\r
565         MM_Shutdown ();\r
566 }\r
567 \r
568 \r
569 //===========================================================================\r
570 \r
571 /*\r
572 ==================\r
573 =\r
574 = BuildTables\r
575 =\r
576 = Calculates:\r
577 =\r
578 = scale                 projection constant\r
579 = sintable/costable     overlapping fractional tables\r
580 =\r
581 ==================\r
582 */\r
583 \r
584 const   float   radtoint = (float)FINEANGLES/2/PI;\r
585 \r
586 void BuildTables (void)\r
587 {\r
588   int           i;\r
589   float         angle,anglestep;\r
590   double        tang;\r
591   fixed         value;\r
592 \r
593 \r
594 //\r
595 // calculate fine tangents\r
596 //\r
597 \r
598         for (i=0;i<FINEANGLES/8;i++)\r
599         {\r
600                 tang = tan( (i+0.5)/radtoint);\r
601                 finetangent[i] = tang*TILEGLOBAL;\r
602                 finetangent[FINEANGLES/4-1-i] = 1/tang*TILEGLOBAL;\r
603         }\r
604 \r
605 //\r
606 // costable overlays sintable with a quarter phase shift\r
607 // ANGLES is assumed to be divisable by four\r
608 //\r
609 // The low word of the value is the fraction, the high bit is the sign bit,\r
610 // bits 16-30 should be 0\r
611 //\r
612 \r
613   angle = 0;\r
614   anglestep = PI/2/ANGLEQUAD;\r
615   for (i=0;i<=ANGLEQUAD;i++)\r
616   {\r
617         value=GLOBAL1*sin(angle);\r
618         sintable[i]=\r
619           sintable[i+ANGLES]=\r
620           sintable[ANGLES/2-i] = value;\r
621         sintable[ANGLES-i]=\r
622           sintable[ANGLES/2+i] = value | 0x80000000l;\r
623         angle += anglestep;\r
624   }\r
625 \r
626 }\r
627 \r
628 //===========================================================================\r
629 \r
630 \r
631 /*\r
632 ====================\r
633 =\r
634 = CalcProjection\r
635 =\r
636 = Uses focallength\r
637 =\r
638 ====================\r
639 */\r
640 \r
641 void CalcProjection (long focal)\r
642 {\r
643         int             i;\r
644         long            intang;\r
645         float   angle;\r
646         double  tang;\r
647         double  planedist;\r
648         double  globinhalf;\r
649         int             halfview;\r
650         double  halfangle,facedist;\r
651 \r
652 \r
653         focallength = focal;\r
654         facedist = focal+MINDIST;\r
655         halfview = viewwidth/2;                                 // half view in pixels\r
656 \r
657 //\r
658 // calculate scale value for vertical height calculations\r
659 // and sprite x calculations\r
660 //\r
661         scale = halfview*facedist/(VIEWGLOBAL/2);\r
662 \r
663 //\r
664 // divide heightnumerator by a posts distance to get the posts height for\r
665 // the heightbuffer.  The pixel height is height>>2\r
666 //\r
667         heightnumerator = (TILEGLOBAL*scale)>>6;\r
668         minheightdiv = heightnumerator/0x7fff +1;\r
669 \r
670 //\r
671 // calculate the angle offset from view angle of each pixel's ray\r
672 //\r
673 \r
674         for (i=0;i<halfview;i++)\r
675         {\r
676         // start 1/2 pixel over, so viewangle bisects two middle pixels\r
677                 tang = (long)i*VIEWGLOBAL/viewwidth/facedist;\r
678                 angle = atan(tang);\r
679                 intang = angle*radtoint;\r
680                 pixelangle[halfview-1-i] = intang;\r
681                 pixelangle[halfview+i] = -intang;\r
682         }\r
683 \r
684 //\r
685 // if a point's abs(y/x) is greater than maxslope, the point is outside\r
686 // the view area\r
687 //\r
688         maxslope = finetangent[pixelangle[0]];\r
689         maxslope >>= 8;\r
690 }\r
691 \r
692 \r
693 \r
694 //===========================================================================\r
695 \r
696 /*\r
697 ===================\r
698 =\r
699 = SetupWalls\r
700 =\r
701 = Map tile values to scaled pics\r
702 =\r
703 ===================\r
704 */\r
705 \r
706 void SetupWalls (void)\r
707 {\r
708         int     i;\r
709 \r
710         for (i=1;i<MAXWALLTILES;i++)\r
711         {\r
712                 horizwall[i]=(i-1)*2;\r
713                 vertwall[i]=(i-1)*2+1;\r
714         }\r
715 }\r
716 \r
717 //===========================================================================\r
718 \r
719 /*\r
720 ==========================\r
721 =\r
722 = SignonScreen\r
723 =\r
724 ==========================\r
725 */\r
726 \r
727 void SignonScreen (void)                        // VGA version\r
728 {\r
729         unsigned        segstart,seglength;\r
730 \r
731         VL_SetVGAPlaneMode ();\r
732         VL_TestPaletteSet ();\r
733         VL_SetPalette (&gamepal);\r
734 \r
735         if (!virtualreality)\r
736         {\r
737                 VW_SetScreen(0x8000,0);\r
738                 VL_MungePic (&introscn,320,200);\r
739                 VL_MemToScreen (&introscn,320,200,0,0);\r
740                 VW_SetScreen(0,0);\r
741         }\r
742 \r
743 //\r
744 // reclaim the memory from the linked in signon screen\r
745 //\r
746         segstart = FP_SEG(&introscn);\r
747         seglength = 64000/16;\r
748         if (FP_OFF(&introscn))\r
749         {\r
750                 segstart++;\r
751                 seglength--;\r
752         }\r
753         MML_UseSpace (segstart,seglength);\r
754 }\r
755 \r
756 \r
757 /*\r
758 ==========================\r
759 =\r
760 = FinishSignon\r
761 =\r
762 ==========================\r
763 */\r
764 \r
765 void FinishSignon (void)\r
766 {\r
767 \r
768 #ifndef SPEAR\r
769         VW_Bar (0,189,300,11,peekb(0xa000,0));\r
770         WindowX = 0;\r
771         WindowW = 320;\r
772         PrintY = 190;\r
773 \r
774         #ifndef JAPAN\r
775         SETFONTCOLOR(14,4);\r
776 \r
777         #ifdef SPANISH\r
778         US_CPrint ("Oprima una tecla");\r
779         #else\r
780         US_CPrint ("Press a key");\r
781         #endif\r
782 \r
783         #endif\r
784 \r
785         if (!NoWait)\r
786                 IN_Ack ();\r
787 \r
788         #ifndef JAPAN\r
789         VW_Bar (0,189,300,11,peekb(0xa000,0));\r
790 \r
791         PrintY = 190;\r
792         SETFONTCOLOR(10,4);\r
793 \r
794         #ifdef SPANISH\r
795         US_CPrint ("pensando...");\r
796         #else\r
797         US_CPrint ("Working...");\r
798         #endif\r
799 \r
800         #endif\r
801 \r
802         SETFONTCOLOR(0,15);\r
803 #else\r
804         if (!NoWait)\r
805                 VW_WaitVBL(3*70);\r
806 #endif\r
807 }\r
808 \r
809 //===========================================================================\r
810 \r
811 /*\r
812 =================\r
813 =\r
814 = MS_CheckParm\r
815 =\r
816 =================\r
817 */\r
818 \r
819 boolean MS_CheckParm (char far *check)\r
820 {\r
821         int             i;\r
822         char    *parm;\r
823 \r
824         for (i = 1;i<_argc;i++)\r
825         {\r
826                 parm = _argv[i];\r
827 \r
828                 while ( !isalpha(*parm) )       // skip - / \ etc.. in front of parm\r
829                         if (!*parm++)\r
830                                 break;                          // hit end of string without an alphanum\r
831 \r
832                 if ( !_fstricmp(check,parm) )\r
833                         return true;\r
834         }\r
835 \r
836         return false;\r
837 }\r
838 \r
839 //===========================================================================\r
840 \r
841 /*\r
842 =====================\r
843 =\r
844 = InitDigiMap\r
845 =\r
846 =====================\r
847 */\r
848 \r
849 static  int     wolfdigimap[] =\r
850                 {\r
851                         // These first sounds are in the upload version\r
852 #ifndef SPEAR\r
853                         HALTSND,                0,\r
854                         DOGBARKSND,             1,\r
855                         CLOSEDOORSND,           2,\r
856                         OPENDOORSND,            3,\r
857                         ATKMACHINEGUNSND,       4,\r
858                         ATKPISTOLSND,           5,\r
859                         ATKGATLINGSND,          6,\r
860                         SCHUTZADSND,            7,\r
861                         GUTENTAGSND,            8,\r
862                         MUTTISND,               9,\r
863                         BOSSFIRESND,            10,\r
864                         SSFIRESND,              11,\r
865                         DEATHSCREAM1SND,        12,\r
866                         DEATHSCREAM2SND,        13,\r
867                         DEATHSCREAM3SND,        13,\r
868                         TAKEDAMAGESND,          14,\r
869                         PUSHWALLSND,            15,\r
870 \r
871                         LEBENSND,               20,\r
872                         NAZIFIRESND,            21,\r
873                         SLURPIESND,             22,\r
874 \r
875                         YEAHSND,                                32,\r
876 \r
877 #ifndef UPLOAD\r
878                         // These are in all other episodes\r
879                         DOGDEATHSND,            16,\r
880                         AHHHGSND,               17,\r
881                         DIESND,                 18,\r
882                         EVASND,                 19,\r
883 \r
884                         TOT_HUNDSND,            23,\r
885                         MEINGOTTSND,            24,\r
886                         SCHABBSHASND,           25,\r
887                         HITLERHASND,            26,\r
888                         SPIONSND,               27,\r
889                         NEINSOVASSND,           28,\r
890                         DOGATTACKSND,           29,\r
891                         LEVELDONESND,           30,\r
892                         MECHSTEPSND,                    31,\r
893 \r
894                         SCHEISTSND,                             33,\r
895                         DEATHSCREAM4SND,                34,             // AIIEEE\r
896                         DEATHSCREAM5SND,                35,             // DEE-DEE\r
897                         DONNERSND,                              36,             // EPISODE 4 BOSS DIE\r
898                         EINESND,                                37,             // EPISODE 4 BOSS SIGHTING\r
899                         ERLAUBENSND,                    38,             // EPISODE 6 BOSS SIGHTING\r
900                         DEATHSCREAM6SND,                39,             // FART\r
901                         DEATHSCREAM7SND,                40,             // GASP\r
902                         DEATHSCREAM8SND,                41,             // GUH-BOY!\r
903                         DEATHSCREAM9SND,                42,             // AH GEEZ!\r
904                         KEINSND,                                43,             // EPISODE 5 BOSS SIGHTING\r
905                         MEINSND,                                44,             // EPISODE 6 BOSS DIE\r
906                         ROSESND,                                45,             // EPISODE 5 BOSS DIE\r
907 \r
908 #endif\r
909 #else\r
910 //\r
911 // SPEAR OF DESTINY DIGISOUNDS\r
912 //\r
913                         HALTSND,                0,\r
914                         CLOSEDOORSND,           2,\r
915                         OPENDOORSND,            3,\r
916                         ATKMACHINEGUNSND,       4,\r
917                         ATKPISTOLSND,           5,\r
918                         ATKGATLINGSND,          6,\r
919                         SCHUTZADSND,            7,\r
920                         BOSSFIRESND,            8,\r
921                         SSFIRESND,              9,\r
922                         DEATHSCREAM1SND,        10,\r
923                         DEATHSCREAM2SND,        11,\r
924                         TAKEDAMAGESND,          12,\r
925                         PUSHWALLSND,            13,\r
926                         AHHHGSND,               15,\r
927                         LEBENSND,               16,\r
928                         NAZIFIRESND,            17,\r
929                         SLURPIESND,             18,\r
930                         LEVELDONESND,           22,\r
931                         DEATHSCREAM4SND,                23,             // AIIEEE\r
932                         DEATHSCREAM3SND,        23,             // DOUBLY-MAPPED!!!\r
933                         DEATHSCREAM5SND,                24,             // DEE-DEE\r
934                         DEATHSCREAM6SND,                25,             // FART\r
935                         DEATHSCREAM7SND,                26,             // GASP\r
936                         DEATHSCREAM8SND,                27,             // GUH-BOY!\r
937                         DEATHSCREAM9SND,                28,             // AH GEEZ!\r
938                         GETGATLINGSND,                  38,             // Got Gat replacement\r
939 \r
940 #ifndef SPEARDEMO\r
941                         DOGBARKSND,             1,\r
942                         DOGDEATHSND,            14,\r
943                         SPIONSND,               19,\r
944                         NEINSOVASSND,           20,\r
945                         DOGATTACKSND,           21,\r
946                         TRANSSIGHTSND,                  29,             // Trans Sight\r
947                         TRANSDEATHSND,                  30,             // Trans Death\r
948                         WILHELMSIGHTSND,                31,             // Wilhelm Sight\r
949                         WILHELMDEATHSND,                32,             // Wilhelm Death\r
950                         UBERDEATHSND,                   33,             // Uber Death\r
951                         KNIGHTSIGHTSND,                 34,             // Death Knight Sight\r
952                         KNIGHTDEATHSND,                 35,             // Death Knight Death\r
953                         ANGELSIGHTSND,                  36,             // Angel Sight\r
954                         ANGELDEATHSND,                  37,             // Angel Death\r
955                         GETSPEARSND,                    39,             // Got Spear replacement\r
956 #endif\r
957 #endif\r
958                         LASTSOUND\r
959                 };\r
960 \r
961 \r
962 void InitDigiMap (void)\r
963 {\r
964         int                     *map;\r
965 \r
966         for (map = wolfdigimap;*map != LASTSOUND;map += 2)\r
967                 DigiMap[map[0]] = map[1];\r
968 \r
969 \r
970 }\r
971 \r
972 \r
973 #ifndef SPEAR\r
974 CP_iteminfo     MusicItems={CTL_X,CTL_Y,6,0,32};\r
975 CP_itemtype far MusicMenu[]=\r
976         {\r
977                 {1,"Get Them!",0},\r
978                 {1,"Searching",0},\r
979                 {1,"P.O.W.",0},\r
980                 {1,"Suspense",0},\r
981                 {1,"War March",0},\r
982                 {1,"Around The Corner!",0},\r
983 \r
984                 {1,"Nazi Anthem",0},\r
985                 {1,"Lurking...",0},\r
986                 {1,"Going After Hitler",0},\r
987                 {1,"Pounding Headache",0},\r
988                 {1,"Into the Dungeons",0},\r
989                 {1,"Ultimate Conquest",0},\r
990 \r
991                 {1,"Kill the S.O.B.",0},\r
992                 {1,"The Nazi Rap",0},\r
993                 {1,"Twelfth Hour",0},\r
994                 {1,"Zero Hour",0},\r
995                 {1,"Ultimate Conquest",0},\r
996                 {1,"Wolfpack",0}\r
997         };\r
998 #else\r
999 CP_iteminfo MusicItems={CTL_X,CTL_Y-20,9,0,32};\r
1000 CP_itemtype far MusicMenu[]=\r
1001    {\r
1002                 {1,"Funky Colonel Bill",0},\r
1003                 {1,"Death To The Nazis",0},\r
1004                 {1,"Tiptoeing Around",0},\r
1005                 {1,"Is This THE END?",0},\r
1006                 {1,"Evil Incarnate",0},\r
1007                 {1,"Jazzin' Them Nazis",0},\r
1008                 {1,"Puttin' It To The Enemy",0},\r
1009                 {1,"The SS Gonna Get You",0},\r
1010                 {1,"Towering Above",0}\r
1011         };\r
1012 #endif\r
1013 \r
1014 #ifndef SPEARDEMO\r
1015 void DoJukebox(void)\r
1016 {\r
1017         int which,lastsong=-1;\r
1018         unsigned start,songs[]=\r
1019                 {\r
1020 #ifndef SPEAR\r
1021                         GETTHEM_MUS,\r
1022                         SEARCHN_MUS,\r
1023                         POW_MUS,\r
1024                         SUSPENSE_MUS,\r
1025                         WARMARCH_MUS,\r
1026                         CORNER_MUS,\r
1027 \r
1028                         NAZI_OMI_MUS,\r
1029                         PREGNANT_MUS,\r
1030                         GOINGAFT_MUS,\r
1031                         HEADACHE_MUS,\r
1032                         DUNGEON_MUS,\r
1033                         ULTIMATE_MUS,\r
1034 \r
1035                         INTROCW3_MUS,\r
1036                         NAZI_RAP_MUS,\r
1037                         TWELFTH_MUS,\r
1038                         ZEROHOUR_MUS,\r
1039                         ULTIMATE_MUS,\r
1040                         PACMAN_MUS\r
1041 #else\r
1042                         XFUNKIE_MUS,             // 0\r
1043                         XDEATH_MUS,              // 2\r
1044                         XTIPTOE_MUS,             // 4\r
1045                         XTHEEND_MUS,             // 7\r
1046                         XEVIL_MUS,               // 17\r
1047                         XJAZNAZI_MUS,            // 18\r
1048                         XPUTIT_MUS,              // 21\r
1049                         XGETYOU_MUS,             // 22\r
1050                         XTOWER2_MUS              // 23\r
1051 #endif\r
1052                 };\r
1053         struct dostime_t time;\r
1054 \r
1055 \r
1056 \r
1057         IN_ClearKeysDown();\r
1058         if (!AdLibPresent && !SoundBlasterPresent)\r
1059                 return;\r
1060 \r
1061 \r
1062         MenuFadeOut();\r
1063 \r
1064 #ifndef SPEAR\r
1065 #ifndef UPLOAD\r
1066         _dos_gettime(&time);\r
1067         start = (time.hsecond%3)*6;\r
1068 #else\r
1069         start = 0;\r
1070 #endif\r
1071 #else\r
1072         start = 0;\r
1073 #endif\r
1074 \r
1075 \r
1076         CA_CacheGrChunk (STARTFONT+1);\r
1077 #ifdef SPEAR\r
1078         CacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);\r
1079 #else\r
1080         CacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END);\r
1081 #endif\r
1082         CA_LoadAllSounds ();\r
1083 \r
1084         fontnumber=1;\r
1085         ClearMScreen ();\r
1086         VWB_DrawPic(112,184,C_MOUSELBACKPIC);\r
1087         DrawStripes (10);\r
1088         SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR);\r
1089 \r
1090 #ifndef SPEAR\r
1091         DrawWindow (CTL_X-2,CTL_Y-6,280,13*7,BKGDCOLOR);\r
1092 #else\r
1093         DrawWindow (CTL_X-2,CTL_Y-26,280,13*10,BKGDCOLOR);\r
1094 #endif\r
1095 \r
1096         DrawMenu (&MusicItems,&MusicMenu[start]);\r
1097 \r
1098         SETFONTCOLOR (READHCOLOR,BKGDCOLOR);\r
1099         PrintY=15;\r
1100         WindowX = 0;\r
1101         WindowY = 320;\r
1102         US_CPrint ("Robert's Jukebox");\r
1103 \r
1104         SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR);\r
1105         VW_UpdateScreen();\r
1106         MenuFadeIn();\r
1107 \r
1108         do\r
1109         {\r
1110                 which = HandleMenu(&MusicItems,&MusicMenu[start],NULL);\r
1111                 if (which>=0)\r
1112                 {\r
1113                         if (lastsong >= 0)\r
1114                                 MusicMenu[start+lastsong].active = 1;\r
1115 \r
1116                         StartCPMusic(songs[start + which]);\r
1117                         MusicMenu[start+which].active = 2;\r
1118                         DrawMenu (&MusicItems,&MusicMenu[start]);\r
1119                         VW_UpdateScreen();\r
1120                         lastsong = which;\r
1121                 }\r
1122         } while(which>=0);\r
1123 \r
1124         MenuFadeOut();\r
1125         IN_ClearKeysDown();\r
1126 #ifdef SPEAR\r
1127         UnCacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);\r
1128 #else\r
1129         UnCacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END);\r
1130 #endif\r
1131 }\r
1132 #endif\r
1133 \r
1134 \r
1135 /*\r
1136 ==========================\r
1137 =\r
1138 = InitGame\r
1139 =\r
1140 = Load a few things right away\r
1141 =\r
1142 ==========================\r
1143 */\r
1144 \r
1145 void InitGame (void)\r
1146 {\r
1147         int                     i,x,y;\r
1148         unsigned        *blockstart;\r
1149 \r
1150         if (MS_CheckParm ("virtual"))\r
1151                 virtualreality = true;\r
1152         else\r
1153                 virtualreality = false;\r
1154 \r
1155         MM_Startup ();                  // so the signon screen can be freed\r
1156 \r
1157         SignonScreen ();\r
1158 \r
1159         VW_Startup ();\r
1160         IN_Startup ();\r
1161         PM_Startup ();\r
1162         PM_UnlockMainMem ();\r
1163         SD_Startup ();\r
1164         CA_Startup ();\r
1165         US_Startup ();\r
1166 \r
1167 \r
1168 #ifndef SPEAR\r
1169         if (mminfo.mainmem < 235000L)\r
1170 #else\r
1171         if (mminfo.mainmem < 257000L && !MS_CheckParm("debugmode"))\r
1172 #endif\r
1173         {\r
1174                 memptr screen;\r
1175 \r
1176                 CA_CacheGrChunk (ERRORSCREEN);\r
1177                 screen = grsegs[ERRORSCREEN];\r
1178                 ShutdownId();\r
1179                 movedata ((unsigned)screen,7+7*160,0xb800,0,17*160);\r
1180                 gotoxy (1,23);\r
1181                 exit(1);\r
1182         }\r
1183 \r
1184 \r
1185 //\r
1186 // build some tables\r
1187 //\r
1188         InitDigiMap ();\r
1189 \r
1190         for (i=0;i<MAPSIZE;i++)\r
1191         {\r
1192                 nearmapylookup[i] = &tilemap[0][0]+MAPSIZE*i;\r
1193                 farmapylookup[i] = i*64;\r
1194         }\r
1195 \r
1196         for (i=0;i<PORTTILESHIGH;i++)\r
1197                 uwidthtable[i] = UPDATEWIDE*i;\r
1198 \r
1199         blockstart = &blockstarts[0];\r
1200         for (y=0;y<UPDATEHIGH;y++)\r
1201                 for (x=0;x<UPDATEWIDE;x++)\r
1202                         *blockstart++ = SCREENWIDTH*16*y+x*TILEWIDTH;\r
1203 \r
1204         updateptr = &update[0];\r
1205 \r
1206         bufferofs = 0;\r
1207         displayofs = 0;\r
1208         ReadConfig ();\r
1209 \r
1210 \r
1211 //\r
1212 // HOLDING DOWN 'M' KEY?\r
1213 //\r
1214 #ifndef SPEARDEMO\r
1215         if (Keyboard[sc_M])\r
1216           DoJukebox();\r
1217         else\r
1218 #endif\r
1219 //\r
1220 // draw intro screen stuff\r
1221 //\r
1222         if (!virtualreality)\r
1223                 IntroScreen ();\r
1224 \r
1225 //\r
1226 // load in and lock down some basic chunks\r
1227 //\r
1228 \r
1229         CA_CacheGrChunk(STARTFONT);\r
1230         MM_SetLock (&grsegs[STARTFONT],true);\r
1231 \r
1232         LoadLatchMem ();\r
1233         BuildTables ();          // trig tables\r
1234         SetupWalls ();\r
1235 \r
1236 #if 0\r
1237 {\r
1238 int temp,i;\r
1239 temp = viewsize;\r
1240         profilehandle = open("SCALERS.TXT", O_CREAT | O_WRONLY | O_TEXT);\r
1241 for (i=1;i<20;i++)\r
1242         NewViewSize(i);\r
1243 viewsize = temp;\r
1244 close(profilehandle);\r
1245 }\r
1246 #endif\r
1247 \r
1248         NewViewSize (viewsize);\r
1249 \r
1250 \r
1251 //\r
1252 // initialize variables\r
1253 //\r
1254         InitRedShifts ();\r
1255         if (!virtualreality)\r
1256                 FinishSignon();\r
1257 \r
1258         displayofs = PAGE1START;\r
1259         bufferofs = PAGE2START;\r
1260 \r
1261         if (virtualreality)\r
1262         {\r
1263                 NoWait = true;\r
1264                 geninterrupt(0x60);\r
1265         }\r
1266 }\r
1267 \r
1268 //===========================================================================\r
1269 \r
1270 /*\r
1271 ==========================\r
1272 =\r
1273 = SetViewSize\r
1274 =\r
1275 ==========================\r
1276 */\r
1277 \r
1278 boolean SetViewSize (unsigned width, unsigned height)\r
1279 {\r
1280         viewwidth = width&~15;                  // must be divisable by 16\r
1281         viewheight = height&~1;                 // must be even\r
1282         centerx = viewwidth/2-1;\r
1283         shootdelta = viewwidth/10;\r
1284         screenofs = ((200-STATUSLINES-viewheight)/2*SCREENWIDTH+(320-viewwidth)/8);\r
1285 \r
1286 //\r
1287 // calculate trace angles and projection constants\r
1288 //\r
1289         CalcProjection (FOCALLENGTH);\r
1290 \r
1291 //\r
1292 // build all needed compiled scalers\r
1293 //\r
1294 //      MM_BombOnError (false);\r
1295         SetupScaling (viewwidth*1.5);\r
1296 #if 0\r
1297         MM_BombOnError (true);\r
1298         if (mmerror)\r
1299         {\r
1300                 Quit ("Can't build scalers!");\r
1301                 mmerror = false;\r
1302                 return false;\r
1303         }\r
1304 #endif\r
1305         return true;\r
1306 }\r
1307 \r
1308 \r
1309 void ShowViewSize (int width)\r
1310 {\r
1311         int     oldwidth,oldheight;\r
1312 \r
1313         oldwidth = viewwidth;\r
1314         oldheight = viewheight;\r
1315 \r
1316         viewwidth = width*16;\r
1317         viewheight = width*16*HEIGHTRATIO;\r
1318         DrawPlayBorder ();\r
1319 \r
1320         viewheight = oldheight;\r
1321         viewwidth = oldwidth;\r
1322 }\r
1323 \r
1324 \r
1325 void NewViewSize (int width)\r
1326 {\r
1327         CA_UpLevel ();\r
1328         MM_SortMem ();\r
1329         viewsize = width;\r
1330         SetViewSize (width*16,width*16*HEIGHTRATIO);\r
1331         CA_DownLevel ();\r
1332 }\r
1333 \r
1334 \r
1335 \r
1336 //===========================================================================\r
1337 \r
1338 /*\r
1339 ==========================\r
1340 =\r
1341 = Quit\r
1342 =\r
1343 ==========================\r
1344 */\r
1345 \r
1346 void Quit (char *error)\r
1347 {\r
1348         unsigned        finscreen;\r
1349         memptr  screen;\r
1350 \r
1351         if (virtualreality)\r
1352                 geninterrupt(0x61);\r
1353 \r
1354         ClearMemory ();\r
1355         if (!*error)\r
1356         {\r
1357          #ifndef JAPAN\r
1358          CA_CacheGrChunk (ORDERSCREEN);\r
1359          screen = grsegs[ORDERSCREEN];\r
1360          #endif\r
1361          WriteConfig ();\r
1362         }\r
1363         else\r
1364         {\r
1365          CA_CacheGrChunk (ERRORSCREEN);\r
1366          screen = grsegs[ERRORSCREEN];\r
1367         }\r
1368 \r
1369         ShutdownId ();\r
1370 \r
1371         if (error && *error)\r
1372         {\r
1373           movedata ((unsigned)screen,7,0xb800,0,7*160);\r
1374           gotoxy (10,4);\r
1375           puts(error);\r
1376           gotoxy (1,8);\r
1377           exit(1);\r
1378         }\r
1379         else\r
1380         if (!error || !(*error))\r
1381         {\r
1382                 clrscr();\r
1383                 #ifndef JAPAN\r
1384                 movedata ((unsigned)screen,7,0xb800,0,4000);\r
1385                 gotoxy(1,24);\r
1386                 #endif\r
1387 //asm   mov     bh,0\r
1388 //asm   mov     dh,23   // row\r
1389 //asm   mov     dl,0    // collumn\r
1390 //asm   mov ah,2\r
1391 //asm   int     0x10\r
1392         }\r
1393 \r
1394         exit(0);\r
1395 }\r
1396 \r
1397 //===========================================================================\r
1398 \r
1399 \r
1400 \r
1401 /*\r
1402 =====================\r
1403 =\r
1404 = DemoLoop\r
1405 =\r
1406 =====================\r
1407 */\r
1408 \r
1409 static  char *ParmStrings[] = {"baby","easy","normal","hard",""};\r
1410 \r
1411 void    DemoLoop (void)\r
1412 {\r
1413         static int LastDemo;\r
1414         int     i,level;\r
1415         long nsize;\r
1416         memptr  nullblock;\r
1417 \r
1418 //\r
1419 // check for launch from ted\r
1420 //\r
1421         if (tedlevel)\r
1422         {\r
1423                 NoWait = true;\r
1424                 NewGame(1,0);\r
1425 \r
1426                 for (i = 1;i < _argc;i++)\r
1427                 {\r
1428                         if ( (level = US_CheckParm(_argv[i],ParmStrings)) != -1)\r
1429                         {\r
1430                          gamestate.difficulty=level;\r
1431                          break;\r
1432                         }\r
1433                 }\r
1434 \r
1435 #ifndef SPEAR\r
1436                 gamestate.episode = tedlevelnum/10;\r
1437                 gamestate.mapon = tedlevelnum%10;\r
1438 #else\r
1439                 gamestate.episode = 0;\r
1440                 gamestate.mapon = tedlevelnum;\r
1441 #endif\r
1442                 GameLoop();\r
1443                 Quit (NULL);\r
1444         }\r
1445 \r
1446 \r
1447 //\r
1448 // main game cycle\r
1449 //\r
1450 \r
1451 \r
1452 //      nsize = (long)40*1024;\r
1453 //      MM_GetPtr(&nullblock,nsize);\r
1454 \r
1455 #ifndef DEMOTEST\r
1456 \r
1457         #ifndef UPLOAD\r
1458 \r
1459                 #ifndef GOODTIMES\r
1460                 #ifndef SPEAR\r
1461                 #ifndef JAPAN\r
1462                 if (!NoWait)\r
1463                         NonShareware();\r
1464                 #endif\r
1465                 #else\r
1466 \r
1467                         #ifndef GOODTIMES\r
1468                         #ifndef SPEARDEMO\r
1469                         CopyProtection();\r
1470                         #endif\r
1471                         #endif\r
1472 \r
1473                 #endif\r
1474                 #endif\r
1475         #endif\r
1476 \r
1477         StartCPMusic(INTROSONG);\r
1478 \r
1479 #ifndef JAPAN\r
1480         if (!NoWait)\r
1481                 PG13 ();\r
1482 #endif\r
1483 \r
1484 #endif\r
1485 \r
1486         while (1)\r
1487         {\r
1488                 while (!NoWait)\r
1489                 {\r
1490 //\r
1491 // title page\r
1492 //\r
1493                         MM_SortMem ();\r
1494 #ifndef DEMOTEST\r
1495 \r
1496 #ifdef SPEAR\r
1497                         CA_CacheGrChunk (TITLEPALETTE);\r
1498 \r
1499                         CA_CacheGrChunk (TITLE1PIC);\r
1500                         VWB_DrawPic (0,0,TITLE1PIC);\r
1501                         UNCACHEGRCHUNK (TITLE1PIC);\r
1502 \r
1503                         CA_CacheGrChunk (TITLE2PIC);\r
1504                         VWB_DrawPic (0,80,TITLE2PIC);\r
1505                         UNCACHEGRCHUNK (TITLE2PIC);\r
1506                         VW_UpdateScreen ();\r
1507                         VL_FadeIn(0,255,grsegs[TITLEPALETTE],30);\r
1508 \r
1509                         UNCACHEGRCHUNK (TITLEPALETTE);\r
1510 #else\r
1511                         CA_CacheScreen (TITLEPIC);\r
1512                         VW_UpdateScreen ();\r
1513                         VW_FadeIn();\r
1514 #endif\r
1515                         if (IN_UserInput(TickBase*15))\r
1516                                 break;\r
1517                         VW_FadeOut();\r
1518 //\r
1519 // credits page\r
1520 //\r
1521                         CA_CacheScreen (CREDITSPIC);\r
1522                         VW_UpdateScreen();\r
1523                         VW_FadeIn ();\r
1524                         if (IN_UserInput(TickBase*10))\r
1525                                 break;\r
1526                         VW_FadeOut ();\r
1527 //\r
1528 // high scores\r
1529 //\r
1530                         DrawHighScores ();\r
1531                         VW_UpdateScreen ();\r
1532                         VW_FadeIn ();\r
1533 \r
1534                         if (IN_UserInput(TickBase*10))\r
1535                                 break;\r
1536 #endif\r
1537 //\r
1538 // demo\r
1539 //\r
1540 \r
1541                         #ifndef SPEARDEMO\r
1542                         PlayDemo (LastDemo++%4);\r
1543                         #else\r
1544                         PlayDemo (0);\r
1545                         #endif\r
1546 \r
1547                         if (playstate == ex_abort)\r
1548                                 break;\r
1549                         StartCPMusic(INTROSONG);\r
1550                 }\r
1551 \r
1552                 VW_FadeOut ();\r
1553 \r
1554 #ifndef SPEAR\r
1555                 if (Keyboard[sc_Tab] && MS_CheckParm("goobers"))\r
1556 #else\r
1557                 if (Keyboard[sc_Tab] && MS_CheckParm("debugmode"))\r
1558 #endif\r
1559                         RecordDemo ();\r
1560                 else\r
1561                         US_ControlPanel (0);\r
1562 \r
1563                 if (startgame || loadedgame)\r
1564                 {\r
1565                         GameLoop ();\r
1566                         VW_FadeOut();\r
1567                         StartCPMusic(INTROSONG);\r
1568                 }\r
1569         }\r
1570 }\r
1571 \r
1572 \r
1573 //===========================================================================\r
1574 \r
1575 \r
1576 /*\r
1577 ==========================\r
1578 =\r
1579 = main\r
1580 =\r
1581 ==========================\r
1582 */\r
1583 \r
1584 char    *nosprtxt[] = {"nospr",nil};\r
1585 \r
1586 void main (void)\r
1587 {\r
1588         int     i;\r
1589 \r
1590 \r
1591 #ifdef BETA\r
1592         //\r
1593         // THIS IS FOR BETA ONLY!\r
1594         //\r
1595         struct dosdate_t d;\r
1596 \r
1597         _dos_getdate(&d);\r
1598         if (d.year > YEAR ||\r
1599                 (d.month >= MONTH && d.day >= DAY))\r
1600         {\r
1601          printf("Sorry, BETA-TESTING is over. Thanks for you help.\n");\r
1602          exit(1);\r
1603         }\r
1604 #endif\r
1605 \r
1606         CheckForEpisodes();\r
1607 \r
1608         Patch386 ();\r
1609 \r
1610         InitGame ();\r
1611 \r
1612         DemoLoop();\r
1613 \r
1614         Quit("Demo loop exited???");\r
1615 }\r
1616 \r