]> 4ch.mooo.com Git - 16.git/blobdiff - 16/sod8086/wl_main.c
got 8086 port of wolf3d to work and sod to work
[16.git] / 16 / sod8086 / wl_main.c
diff --git a/16/sod8086/wl_main.c b/16/sod8086/wl_main.c
new file mode 100755 (executable)
index 0000000..1604802
--- /dev/null
@@ -0,0 +1,1618 @@
+// WL_MAIN.C\r
+\r
+#include <conio.h>\r
+#include "WL_DEF.H"\r
+#pragma hdrstop\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                  WOLFENSTEIN 3-D\r
+\r
+                                         An Id Software production\r
+\r
+                                                  by John Carmack\r
+\r
+=============================================================================\r
+*/\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL CONSTANTS\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+#define FOCALLENGTH     (0x5700l)               // in global coordinates\r
+#define VIEWGLOBAL      0x10000                 // globals visable flush to wall\r
+\r
+#define VIEWWIDTH       256                     // size of view window\r
+#define VIEWHEIGHT      144\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                GLOBAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+char            str[80],str2[20];\r
+int                            tedlevelnum;\r
+boolean         tedlevel;\r
+boolean         nospr;\r
+boolean         IsA386;\r
+int                     dirangle[9] = {0,ANGLES/8,2*ANGLES/8,3*ANGLES/8,4*ANGLES/8,\r
+       5*ANGLES/8,6*ANGLES/8,7*ANGLES/8,ANGLES};\r
+\r
+//\r
+// proejection variables\r
+//\r
+fixed           focallength;\r
+unsigned        screenofs;\r
+int             viewwidth;\r
+int             viewheight;\r
+int             centerx;\r
+int             shootdelta;                     // pixels away from centerx a target can be\r
+fixed           scale,maxslope;\r
+long            heightnumerator;\r
+int                     minheightdiv;\r
+\r
+\r
+void            Quit (char *error);\r
+\r
+boolean         startgame,loadedgame,virtualreality;\r
+int             mouseadjustment;\r
+\r
+char   configname[13]="CONFIG.";\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= ReadConfig\r
+=\r
+====================\r
+*/\r
+\r
+void ReadConfig(void)\r
+{\r
+       int                     file;\r
+       SDMode          sd;\r
+       SMMode          sm;\r
+       SDSMode         sds;\r
+\r
+\r
+       if ( (file = open(configname,O_BINARY | O_RDONLY)) != -1)\r
+       {\r
+       //\r
+       // valid config file\r
+       //\r
+               read(file,Scores,sizeof(HighScore) * MaxScores);\r
+\r
+               read(file,&sd,sizeof(sd));\r
+               read(file,&sm,sizeof(sm));\r
+               read(file,&sds,sizeof(sds));\r
+\r
+               read(file,&mouseenabled,sizeof(mouseenabled));\r
+               read(file,&joystickenabled,sizeof(joystickenabled));\r
+               read(file,&joypadenabled,sizeof(joypadenabled));\r
+               read(file,&joystickprogressive,sizeof(joystickprogressive));\r
+               read(file,&joystickport,sizeof(joystickport));\r
+\r
+               read(file,&dirscan,sizeof(dirscan));\r
+               read(file,&buttonscan,sizeof(buttonscan));\r
+               read(file,&buttonmouse,sizeof(buttonmouse));\r
+               read(file,&buttonjoy,sizeof(buttonjoy));\r
+\r
+               read(file,&viewsize,sizeof(viewsize));\r
+               read(file,&mouseadjustment,sizeof(mouseadjustment));\r
+\r
+               close(file);\r
+\r
+               if (sd == sdm_AdLib && !AdLibPresent && !SoundBlasterPresent)\r
+               {\r
+                       sd = sdm_PC;\r
+                       sd = smm_Off;\r
+               }\r
+\r
+               if ((sds == sds_SoundBlaster && !SoundBlasterPresent) ||\r
+                       (sds == sds_SoundSource && !SoundSourcePresent))\r
+                       sds = sds_Off;\r
+\r
+               if (!MousePresent)\r
+                       mouseenabled = false;\r
+               if (!JoysPresent[joystickport])\r
+                       joystickenabled = false;\r
+\r
+               MainMenu[6].active=1;\r
+               MainItems.curpos=0;\r
+       }\r
+       else\r
+       {\r
+       //\r
+       // no config file, so select by hardware\r
+       //\r
+               if (SoundBlasterPresent || AdLibPresent)\r
+               {\r
+                       sd = sdm_AdLib;\r
+                       sm = smm_AdLib;\r
+               }\r
+               else\r
+               {\r
+                       sd = sdm_PC;\r
+                       sm = smm_Off;\r
+               }\r
+\r
+               if (SoundBlasterPresent)\r
+                       sds = sds_SoundBlaster;\r
+               else if (SoundSourcePresent)\r
+                       sds = sds_SoundSource;\r
+               else\r
+                       sds = sds_Off;\r
+\r
+               if (MousePresent)\r
+                       mouseenabled = true;\r
+\r
+               joystickenabled = false;\r
+               joypadenabled = false;\r
+               joystickport = 0;\r
+               joystickprogressive = false;\r
+\r
+               viewsize = 15;\r
+               mouseadjustment=5;\r
+       }\r
+\r
+       SD_SetMusicMode (sm);\r
+       SD_SetSoundMode (sd);\r
+       SD_SetDigiDevice (sds);\r
+\r
+}\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= WriteConfig\r
+=\r
+====================\r
+*/\r
+\r
+void WriteConfig(void)\r
+{\r
+       int                     file;\r
+\r
+       file = open(configname,O_CREAT | O_BINARY | O_WRONLY,\r
+                               S_IREAD | S_IWRITE | S_IFREG);\r
+\r
+       if (file != -1)\r
+       {\r
+               write(file,Scores,sizeof(HighScore) * MaxScores);\r
+\r
+               write(file,&SoundMode,sizeof(SoundMode));\r
+               write(file,&MusicMode,sizeof(MusicMode));\r
+               write(file,&DigiMode,sizeof(DigiMode));\r
+\r
+               write(file,&mouseenabled,sizeof(mouseenabled));\r
+               write(file,&joystickenabled,sizeof(joystickenabled));\r
+               write(file,&joypadenabled,sizeof(joypadenabled));\r
+               write(file,&joystickprogressive,sizeof(joystickprogressive));\r
+               write(file,&joystickport,sizeof(joystickport));\r
+\r
+               write(file,&dirscan,sizeof(dirscan));\r
+               write(file,&buttonscan,sizeof(buttonscan));\r
+               write(file,&buttonmouse,sizeof(buttonmouse));\r
+               write(file,&buttonjoy,sizeof(buttonjoy));\r
+\r
+               write(file,&viewsize,sizeof(viewsize));\r
+               write(file,&mouseadjustment,sizeof(mouseadjustment));\r
+\r
+               close(file);\r
+       }\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+========================\r
+=\r
+= Patch386\r
+=\r
+= Patch ldiv to use 32 bit instructions\r
+=\r
+========================\r
+*/\r
+\r
+char    *JHParmStrings[] = {"no386",nil};\r
+void Patch386 (void)\r
+{\r
+extern void far jabhack2(void);\r
+extern int far  CheckIs386(void);\r
+\r
+       int     i;\r
+\r
+       for (i = 1;i < _argc;i++)\r
+               if (US_CheckParm(_argv[i],JHParmStrings) == 0)\r
+               {\r
+                       IsA386 = false;\r
+                       return;\r
+               }\r
+\r
+       if (CheckIs386())\r
+       {\r
+               IsA386 = true;\r
+               jabhack2();\r
+       }\r
+       else\r
+               IsA386 = false;\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= NewGame\r
+=\r
+= Set up new game to start from the beginning\r
+=\r
+=====================\r
+*/\r
+\r
+void NewGame (int difficulty,int episode)\r
+{\r
+       memset (&gamestate,0,sizeof(gamestate));\r
+       gamestate.difficulty = difficulty;\r
+       gamestate.weapon = gamestate.bestweapon\r
+               = gamestate.chosenweapon = wp_pistol;\r
+       gamestate.health = 100;\r
+       gamestate.ammo = STARTAMMO;\r
+       gamestate.lives = 3;\r
+       gamestate.nextextra = EXTRAPOINTS;\r
+       gamestate.episode=episode;\r
+\r
+       startgame = true;\r
+}\r
+\r
+//===========================================================================\r
+\r
+void DiskFlopAnim(int x,int y)\r
+{\r
+ static char which=0;\r
+ if (!x && !y)\r
+   return;\r
+ VWB_DrawPic(x,y,C_DISKLOADING1PIC+which);\r
+ VW_UpdateScreen();\r
+ which^=1;\r
+}\r
+\r
+\r
+long DoChecksum(byte far *source,unsigned size,long checksum)\r
+{\r
+ unsigned i;\r
+\r
+ for (i=0;i<size-1;i++)\r
+   checksum += source[i]^source[i+1];\r
+\r
+ return checksum;\r
+}\r
+\r
+\r
+/*\r
+==================\r
+=\r
+= SaveTheGame\r
+=\r
+==================\r
+*/\r
+\r
+boolean SaveTheGame(int file,int x,int y)\r
+{\r
+       struct diskfree_t dfree;\r
+       long avail,size,checksum;\r
+       objtype *ob,nullobj;\r
+\r
+\r
+       if (_dos_getdiskfree(0,&dfree))\r
+         Quit("Error in _dos_getdiskfree call");\r
+\r
+       avail = (long)dfree.avail_clusters *\r
+                       dfree.bytes_per_sector *\r
+                       dfree.sectors_per_cluster;\r
+\r
+       size = 0;\r
+       for (ob = player; ob ; ob=ob->next)\r
+         size += sizeof(*ob);\r
+       size += sizeof(nullobj);\r
+\r
+       size += sizeof(gamestate) +\r
+                       sizeof(LRstruct)*8 +\r
+                       sizeof(tilemap) +\r
+                       sizeof(actorat) +\r
+                       sizeof(laststatobj) +\r
+                       sizeof(statobjlist) +\r
+                       sizeof(doorposition) +\r
+                       sizeof(pwallstate) +\r
+                       sizeof(pwallx) +\r
+                       sizeof(pwally) +\r
+                       sizeof(pwalldir) +\r
+                       sizeof(pwallpos);\r
+\r
+       if (avail < size)\r
+       {\r
+        Message(STR_NOSPACE1"\n"\r
+                        STR_NOSPACE2);\r
+        return false;\r
+       }\r
+\r
+       checksum = 0;\r
+\r
+\r
+       DiskFlopAnim(x,y);\r
+       CA_FarWrite (file,(void far *)&gamestate,sizeof(gamestate));\r
+       checksum = DoChecksum((byte far *)&gamestate,sizeof(gamestate),checksum);\r
+\r
+       DiskFlopAnim(x,y);\r
+#ifdef SPEAR\r
+       CA_FarWrite (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*20);\r
+       checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*20,checksum);\r
+#else\r
+       CA_FarWrite (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*8);\r
+       checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*8,checksum);\r
+#endif\r
+\r
+       DiskFlopAnim(x,y);\r
+       CA_FarWrite (file,(void far *)tilemap,sizeof(tilemap));\r
+       checksum = DoChecksum((byte far *)tilemap,sizeof(tilemap),checksum);\r
+       DiskFlopAnim(x,y);\r
+       CA_FarWrite (file,(void far *)actorat,sizeof(actorat));\r
+       checksum = DoChecksum((byte far *)actorat,sizeof(actorat),checksum);\r
+\r
+       CA_FarWrite (file,(void far *)areaconnect,sizeof(areaconnect));\r
+       CA_FarWrite (file,(void far *)areabyplayer,sizeof(areabyplayer));\r
+\r
+       for (ob = player ; ob ; ob=ob->next)\r
+       {\r
+        DiskFlopAnim(x,y);\r
+        CA_FarWrite (file,(void far *)ob,sizeof(*ob));\r
+       }\r
+       nullobj.active = ac_badobject;          // end of file marker\r
+       DiskFlopAnim(x,y);\r
+       CA_FarWrite (file,(void far *)&nullobj,sizeof(nullobj));\r
+\r
+\r
+\r
+       DiskFlopAnim(x,y);\r
+       CA_FarWrite (file,(void far *)&laststatobj,sizeof(laststatobj));\r
+       checksum = DoChecksum((byte far *)&laststatobj,sizeof(laststatobj),checksum);\r
+       DiskFlopAnim(x,y);\r
+       CA_FarWrite (file,(void far *)statobjlist,sizeof(statobjlist));\r
+       checksum = DoChecksum((byte far *)statobjlist,sizeof(statobjlist),checksum);\r
+\r
+       DiskFlopAnim(x,y);\r
+       CA_FarWrite (file,(void far *)doorposition,sizeof(doorposition));\r
+       checksum = DoChecksum((byte far *)doorposition,sizeof(doorposition),checksum);\r
+       DiskFlopAnim(x,y);\r
+       CA_FarWrite (file,(void far *)doorobjlist,sizeof(doorobjlist));\r
+       checksum = DoChecksum((byte far *)doorobjlist,sizeof(doorobjlist),checksum);\r
+\r
+       DiskFlopAnim(x,y);\r
+       CA_FarWrite (file,(void far *)&pwallstate,sizeof(pwallstate));\r
+       checksum = DoChecksum((byte far *)&pwallstate,sizeof(pwallstate),checksum);\r
+       CA_FarWrite (file,(void far *)&pwallx,sizeof(pwallx));\r
+       checksum = DoChecksum((byte far *)&pwallx,sizeof(pwallx),checksum);\r
+       CA_FarWrite (file,(void far *)&pwally,sizeof(pwally));\r
+       checksum = DoChecksum((byte far *)&pwally,sizeof(pwally),checksum);\r
+       CA_FarWrite (file,(void far *)&pwalldir,sizeof(pwalldir));\r
+       checksum = DoChecksum((byte far *)&pwalldir,sizeof(pwalldir),checksum);\r
+       CA_FarWrite (file,(void far *)&pwallpos,sizeof(pwallpos));\r
+       checksum = DoChecksum((byte far *)&pwallpos,sizeof(pwallpos),checksum);\r
+\r
+       //\r
+       // WRITE OUT CHECKSUM\r
+       //\r
+       CA_FarWrite (file,(void far *)&checksum,sizeof(checksum));\r
+\r
+       return(true);\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+==================\r
+=\r
+= LoadTheGame\r
+=\r
+==================\r
+*/\r
+\r
+boolean LoadTheGame(int file,int x,int y)\r
+{\r
+       long checksum,oldchecksum;\r
+       objtype *ob,nullobj;\r
+\r
+\r
+       checksum = 0;\r
+\r
+       DiskFlopAnim(x,y);\r
+       CA_FarRead (file,(void far *)&gamestate,sizeof(gamestate));\r
+       checksum = DoChecksum((byte far *)&gamestate,sizeof(gamestate),checksum);\r
+\r
+       DiskFlopAnim(x,y);\r
+#ifdef SPEAR\r
+       CA_FarRead (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*20);\r
+       checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*20,checksum);\r
+#else\r
+       CA_FarRead (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*8);\r
+       checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*8,checksum);\r
+#endif\r
+\r
+       DiskFlopAnim(x,y);\r
+       SetupGameLevel ();\r
+\r
+       DiskFlopAnim(x,y);\r
+       CA_FarRead (file,(void far *)tilemap,sizeof(tilemap));\r
+       checksum = DoChecksum((byte far *)tilemap,sizeof(tilemap),checksum);\r
+       DiskFlopAnim(x,y);\r
+       CA_FarRead (file,(void far *)actorat,sizeof(actorat));\r
+       checksum = DoChecksum((byte far *)actorat,sizeof(actorat),checksum);\r
+\r
+       CA_FarRead (file,(void far *)areaconnect,sizeof(areaconnect));\r
+       CA_FarRead (file,(void far *)areabyplayer,sizeof(areabyplayer));\r
+\r
+\r
+\r
+       InitActorList ();\r
+       DiskFlopAnim(x,y);\r
+       CA_FarRead (file,(void far *)player,sizeof(*player));\r
+\r
+       while (1)\r
+       {\r
+        DiskFlopAnim(x,y);\r
+               CA_FarRead (file,(void far *)&nullobj,sizeof(nullobj));\r
+               if (nullobj.active == ac_badobject)\r
+                       break;\r
+               GetNewActor ();\r
+        // don't copy over the links\r
+               memcpy (new,&nullobj,sizeof(nullobj)-4);\r
+       }\r
+\r
+\r
+\r
+       DiskFlopAnim(x,y);\r
+       CA_FarRead (file,(void far *)&laststatobj,sizeof(laststatobj));\r
+       checksum = DoChecksum((byte far *)&laststatobj,sizeof(laststatobj),checksum);\r
+       DiskFlopAnim(x,y);\r
+       CA_FarRead (file,(void far *)statobjlist,sizeof(statobjlist));\r
+       checksum = DoChecksum((byte far *)statobjlist,sizeof(statobjlist),checksum);\r
+\r
+       DiskFlopAnim(x,y);\r
+       CA_FarRead (file,(void far *)doorposition,sizeof(doorposition));\r
+       checksum = DoChecksum((byte far *)doorposition,sizeof(doorposition),checksum);\r
+       DiskFlopAnim(x,y);\r
+       CA_FarRead (file,(void far *)doorobjlist,sizeof(doorobjlist));\r
+       checksum = DoChecksum((byte far *)doorobjlist,sizeof(doorobjlist),checksum);\r
+\r
+       DiskFlopAnim(x,y);\r
+       CA_FarRead (file,(void far *)&pwallstate,sizeof(pwallstate));\r
+       checksum = DoChecksum((byte far *)&pwallstate,sizeof(pwallstate),checksum);\r
+       CA_FarRead (file,(void far *)&pwallx,sizeof(pwallx));\r
+       checksum = DoChecksum((byte far *)&pwallx,sizeof(pwallx),checksum);\r
+       CA_FarRead (file,(void far *)&pwally,sizeof(pwally));\r
+       checksum = DoChecksum((byte far *)&pwally,sizeof(pwally),checksum);\r
+       CA_FarRead (file,(void far *)&pwalldir,sizeof(pwalldir));\r
+       checksum = DoChecksum((byte far *)&pwalldir,sizeof(pwalldir),checksum);\r
+       CA_FarRead (file,(void far *)&pwallpos,sizeof(pwallpos));\r
+       checksum = DoChecksum((byte far *)&pwallpos,sizeof(pwallpos),checksum);\r
+\r
+       CA_FarRead (file,(void far *)&oldchecksum,sizeof(oldchecksum));\r
+\r
+       if (oldchecksum != checksum)\r
+       {\r
+        Message(STR_SAVECHT1"\n"\r
+                        STR_SAVECHT2"\n"\r
+                        STR_SAVECHT3"\n"\r
+                        STR_SAVECHT4);\r
+\r
+        IN_ClearKeysDown();\r
+        IN_Ack();\r
+\r
+        gamestate.score = 0;\r
+        gamestate.lives = 1;\r
+        gamestate.weapon =\r
+          gamestate.chosenweapon =\r
+          gamestate.bestweapon = wp_pistol;\r
+        gamestate.ammo = 8;\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+==========================\r
+=\r
+= ShutdownId\r
+=\r
+= Shuts down all ID_?? managers\r
+=\r
+==========================\r
+*/\r
+\r
+void ShutdownId (void)\r
+{\r
+       US_Shutdown ();\r
+       SD_Shutdown ();\r
+       PM_Shutdown ();\r
+       IN_Shutdown ();\r
+       VW_Shutdown ();\r
+       CA_Shutdown ();\r
+       MM_Shutdown ();\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+/*\r
+==================\r
+=\r
+= BuildTables\r
+=\r
+= Calculates:\r
+=\r
+= scale                 projection constant\r
+= sintable/costable     overlapping fractional tables\r
+=\r
+==================\r
+*/\r
+\r
+const   float   radtoint = (float)FINEANGLES/2/PI;\r
+\r
+void BuildTables (void)\r
+{\r
+  int           i;\r
+  float         angle,anglestep;\r
+  double        tang;\r
+  fixed         value;\r
+\r
+\r
+//\r
+// calculate fine tangents\r
+//\r
+\r
+       for (i=0;i<FINEANGLES/8;i++)\r
+       {\r
+               tang = tan( (i+0.5)/radtoint);\r
+               finetangent[i] = tang*TILEGLOBAL;\r
+               finetangent[FINEANGLES/4-1-i] = 1/tang*TILEGLOBAL;\r
+       }\r
+\r
+//\r
+// costable overlays sintable with a quarter phase shift\r
+// ANGLES is assumed to be divisable by four\r
+//\r
+// The low word of the value is the fraction, the high bit is the sign bit,\r
+// bits 16-30 should be 0\r
+//\r
+\r
+  angle = 0;\r
+  anglestep = PI/2/ANGLEQUAD;\r
+  for (i=0;i<=ANGLEQUAD;i++)\r
+  {\r
+       value=GLOBAL1*sin(angle);\r
+       sintable[i]=\r
+         sintable[i+ANGLES]=\r
+         sintable[ANGLES/2-i] = value;\r
+       sintable[ANGLES-i]=\r
+         sintable[ANGLES/2+i] = value | 0x80000000l;\r
+       angle += anglestep;\r
+  }\r
+\r
+}\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+====================\r
+=\r
+= CalcProjection\r
+=\r
+= Uses focallength\r
+=\r
+====================\r
+*/\r
+\r
+void CalcProjection (long focal)\r
+{\r
+       int             i;\r
+       long            intang;\r
+       float   angle;\r
+       double  tang;\r
+       double  planedist;\r
+       double  globinhalf;\r
+       int             halfview;\r
+       double  halfangle,facedist;\r
+\r
+\r
+       focallength = focal;\r
+       facedist = focal+MINDIST;\r
+       halfview = viewwidth/2;                                 // half view in pixels\r
+\r
+//\r
+// calculate scale value for vertical height calculations\r
+// and sprite x calculations\r
+//\r
+       scale = halfview*facedist/(VIEWGLOBAL/2);\r
+\r
+//\r
+// divide heightnumerator by a posts distance to get the posts height for\r
+// the heightbuffer.  The pixel height is height>>2\r
+//\r
+       heightnumerator = (TILEGLOBAL*scale)>>6;\r
+       minheightdiv = heightnumerator/0x7fff +1;\r
+\r
+//\r
+// calculate the angle offset from view angle of each pixel's ray\r
+//\r
+\r
+       for (i=0;i<halfview;i++)\r
+       {\r
+       // start 1/2 pixel over, so viewangle bisects two middle pixels\r
+               tang = (long)i*VIEWGLOBAL/viewwidth/facedist;\r
+               angle = atan(tang);\r
+               intang = angle*radtoint;\r
+               pixelangle[halfview-1-i] = intang;\r
+               pixelangle[halfview+i] = -intang;\r
+       }\r
+\r
+//\r
+// if a point's abs(y/x) is greater than maxslope, the point is outside\r
+// the view area\r
+//\r
+       maxslope = finetangent[pixelangle[0]];\r
+       maxslope >>= 8;\r
+}\r
+\r
+\r
+\r
+//===========================================================================\r
+\r
+/*\r
+===================\r
+=\r
+= SetupWalls\r
+=\r
+= Map tile values to scaled pics\r
+=\r
+===================\r
+*/\r
+\r
+void SetupWalls (void)\r
+{\r
+       int     i;\r
+\r
+       for (i=1;i<MAXWALLTILES;i++)\r
+       {\r
+               horizwall[i]=(i-1)*2;\r
+               vertwall[i]=(i-1)*2+1;\r
+       }\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+==========================\r
+=\r
+= SignonScreen\r
+=\r
+==========================\r
+*/\r
+\r
+void SignonScreen (void)                        // VGA version\r
+{\r
+       unsigned        segstart,seglength;\r
+\r
+       VL_SetVGAPlaneMode ();\r
+       VL_TestPaletteSet ();\r
+       VL_SetPalette (&gamepal);\r
+\r
+       if (!virtualreality)\r
+       {\r
+               VW_SetScreen(0x8000,0);\r
+               VL_MungePic (&introscn,320,200);\r
+               VL_MemToScreen (&introscn,320,200,0,0);\r
+               VW_SetScreen(0,0);\r
+       }\r
+\r
+//\r
+// reclaim the memory from the linked in signon screen\r
+//\r
+       segstart = FP_SEG(&introscn);\r
+       seglength = 64000/16;\r
+       if (FP_OFF(&introscn))\r
+       {\r
+               segstart++;\r
+               seglength--;\r
+       }\r
+       MML_UseSpace (segstart,seglength);\r
+}\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= FinishSignon\r
+=\r
+==========================\r
+*/\r
+\r
+void FinishSignon (void)\r
+{\r
+\r
+#ifndef SPEAR\r
+       VW_Bar (0,189,300,11,peekb(0xa000,0));\r
+       WindowX = 0;\r
+       WindowW = 320;\r
+       PrintY = 190;\r
+\r
+       #ifndef JAPAN\r
+       SETFONTCOLOR(14,4);\r
+\r
+       #ifdef SPANISH\r
+       US_CPrint ("Oprima una tecla");\r
+       #else\r
+       US_CPrint ("Press a key");\r
+       #endif\r
+\r
+       #endif\r
+\r
+       if (!NoWait)\r
+               IN_Ack ();\r
+\r
+       #ifndef JAPAN\r
+       VW_Bar (0,189,300,11,peekb(0xa000,0));\r
+\r
+       PrintY = 190;\r
+       SETFONTCOLOR(10,4);\r
+\r
+       #ifdef SPANISH\r
+       US_CPrint ("pensando...");\r
+       #else\r
+       US_CPrint ("Working...");\r
+       #endif\r
+\r
+       #endif\r
+\r
+       SETFONTCOLOR(0,15);\r
+#else\r
+       if (!NoWait)\r
+               VW_WaitVBL(3*70);\r
+#endif\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=================\r
+=\r
+= MS_CheckParm\r
+=\r
+=================\r
+*/\r
+\r
+boolean MS_CheckParm (char far *check)\r
+{\r
+       int             i;\r
+       char    *parm;\r
+\r
+       for (i = 1;i<_argc;i++)\r
+       {\r
+               parm = _argv[i];\r
+\r
+               while ( !isalpha(*parm) )       // skip - / \ etc.. in front of parm\r
+                       if (!*parm++)\r
+                               break;                          // hit end of string without an alphanum\r
+\r
+               if ( !_fstricmp(check,parm) )\r
+                       return true;\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+=====================\r
+=\r
+= InitDigiMap\r
+=\r
+=====================\r
+*/\r
+\r
+static  int     wolfdigimap[] =\r
+               {\r
+                       // These first sounds are in the upload version\r
+#ifndef SPEAR\r
+                       HALTSND,                0,\r
+                       DOGBARKSND,             1,\r
+                       CLOSEDOORSND,           2,\r
+                       OPENDOORSND,            3,\r
+                       ATKMACHINEGUNSND,       4,\r
+                       ATKPISTOLSND,           5,\r
+                       ATKGATLINGSND,          6,\r
+                       SCHUTZADSND,            7,\r
+                       GUTENTAGSND,            8,\r
+                       MUTTISND,               9,\r
+                       BOSSFIRESND,            10,\r
+                       SSFIRESND,              11,\r
+                       DEATHSCREAM1SND,        12,\r
+                       DEATHSCREAM2SND,        13,\r
+                       DEATHSCREAM3SND,        13,\r
+                       TAKEDAMAGESND,          14,\r
+                       PUSHWALLSND,            15,\r
+\r
+                       LEBENSND,               20,\r
+                       NAZIFIRESND,            21,\r
+                       SLURPIESND,             22,\r
+\r
+                       YEAHSND,                                32,\r
+\r
+#ifndef UPLOAD\r
+                       // These are in all other episodes\r
+                       DOGDEATHSND,            16,\r
+                       AHHHGSND,               17,\r
+                       DIESND,                 18,\r
+                       EVASND,                 19,\r
+\r
+                       TOT_HUNDSND,            23,\r
+                       MEINGOTTSND,            24,\r
+                       SCHABBSHASND,           25,\r
+                       HITLERHASND,            26,\r
+                       SPIONSND,               27,\r
+                       NEINSOVASSND,           28,\r
+                       DOGATTACKSND,           29,\r
+                       LEVELDONESND,           30,\r
+                       MECHSTEPSND,                    31,\r
+\r
+                       SCHEISTSND,                             33,\r
+                       DEATHSCREAM4SND,                34,             // AIIEEE\r
+                       DEATHSCREAM5SND,                35,             // DEE-DEE\r
+                       DONNERSND,                              36,             // EPISODE 4 BOSS DIE\r
+                       EINESND,                                37,             // EPISODE 4 BOSS SIGHTING\r
+                       ERLAUBENSND,                    38,             // EPISODE 6 BOSS SIGHTING\r
+                       DEATHSCREAM6SND,                39,             // FART\r
+                       DEATHSCREAM7SND,                40,             // GASP\r
+                       DEATHSCREAM8SND,                41,             // GUH-BOY!\r
+                       DEATHSCREAM9SND,                42,             // AH GEEZ!\r
+                       KEINSND,                                43,             // EPISODE 5 BOSS SIGHTING\r
+                       MEINSND,                                44,             // EPISODE 6 BOSS DIE\r
+                       ROSESND,                                45,             // EPISODE 5 BOSS DIE\r
+\r
+#endif\r
+#else\r
+//\r
+// SPEAR OF DESTINY DIGISOUNDS\r
+//\r
+                       HALTSND,                0,\r
+                       CLOSEDOORSND,           2,\r
+                       OPENDOORSND,            3,\r
+                       ATKMACHINEGUNSND,       4,\r
+                       ATKPISTOLSND,           5,\r
+                       ATKGATLINGSND,          6,\r
+                       SCHUTZADSND,            7,\r
+                       BOSSFIRESND,            8,\r
+                       SSFIRESND,              9,\r
+                       DEATHSCREAM1SND,        10,\r
+                       DEATHSCREAM2SND,        11,\r
+                       TAKEDAMAGESND,          12,\r
+                       PUSHWALLSND,            13,\r
+                       AHHHGSND,               15,\r
+                       LEBENSND,               16,\r
+                       NAZIFIRESND,            17,\r
+                       SLURPIESND,             18,\r
+                       LEVELDONESND,           22,\r
+                       DEATHSCREAM4SND,                23,             // AIIEEE\r
+                       DEATHSCREAM3SND,        23,             // DOUBLY-MAPPED!!!\r
+                       DEATHSCREAM5SND,                24,             // DEE-DEE\r
+                       DEATHSCREAM6SND,                25,             // FART\r
+                       DEATHSCREAM7SND,                26,             // GASP\r
+                       DEATHSCREAM8SND,                27,             // GUH-BOY!\r
+                       DEATHSCREAM9SND,                28,             // AH GEEZ!\r
+                       GETGATLINGSND,                  38,             // Got Gat replacement\r
+\r
+#ifndef SPEARDEMO\r
+                       DOGBARKSND,             1,\r
+                       DOGDEATHSND,            14,\r
+                       SPIONSND,               19,\r
+                       NEINSOVASSND,           20,\r
+                       DOGATTACKSND,           21,\r
+                       TRANSSIGHTSND,                  29,             // Trans Sight\r
+                       TRANSDEATHSND,                  30,             // Trans Death\r
+                       WILHELMSIGHTSND,                31,             // Wilhelm Sight\r
+                       WILHELMDEATHSND,                32,             // Wilhelm Death\r
+                       UBERDEATHSND,                   33,             // Uber Death\r
+                       KNIGHTSIGHTSND,                 34,             // Death Knight Sight\r
+                       KNIGHTDEATHSND,                 35,             // Death Knight Death\r
+                       ANGELSIGHTSND,                  36,             // Angel Sight\r
+                       ANGELDEATHSND,                  37,             // Angel Death\r
+                       GETSPEARSND,                    39,             // Got Spear replacement\r
+#endif\r
+#endif\r
+                       LASTSOUND\r
+               };\r
+\r
+\r
+void InitDigiMap (void)\r
+{\r
+       int                     *map;\r
+\r
+       for (map = wolfdigimap;*map != LASTSOUND;map += 2)\r
+               DigiMap[map[0]] = map[1];\r
+\r
+\r
+}\r
+\r
+\r
+#ifndef SPEAR\r
+CP_iteminfo    MusicItems={CTL_X,CTL_Y,6,0,32};\r
+CP_itemtype far MusicMenu[]=\r
+       {\r
+               {1,"Get Them!",0},\r
+               {1,"Searching",0},\r
+               {1,"P.O.W.",0},\r
+               {1,"Suspense",0},\r
+               {1,"War March",0},\r
+               {1,"Around The Corner!",0},\r
+\r
+               {1,"Nazi Anthem",0},\r
+               {1,"Lurking...",0},\r
+               {1,"Going After Hitler",0},\r
+               {1,"Pounding Headache",0},\r
+               {1,"Into the Dungeons",0},\r
+               {1,"Ultimate Conquest",0},\r
+\r
+               {1,"Kill the S.O.B.",0},\r
+               {1,"The Nazi Rap",0},\r
+               {1,"Twelfth Hour",0},\r
+               {1,"Zero Hour",0},\r
+               {1,"Ultimate Conquest",0},\r
+               {1,"Wolfpack",0}\r
+       };\r
+#else\r
+CP_iteminfo MusicItems={CTL_X,CTL_Y-20,9,0,32};\r
+CP_itemtype far MusicMenu[]=\r
+   {\r
+               {1,"Funky Colonel Bill",0},\r
+               {1,"Death To The Nazis",0},\r
+               {1,"Tiptoeing Around",0},\r
+               {1,"Is This THE END?",0},\r
+               {1,"Evil Incarnate",0},\r
+               {1,"Jazzin' Them Nazis",0},\r
+               {1,"Puttin' It To The Enemy",0},\r
+               {1,"The SS Gonna Get You",0},\r
+               {1,"Towering Above",0}\r
+       };\r
+#endif\r
+\r
+#ifndef SPEARDEMO\r
+void DoJukebox(void)\r
+{\r
+       int which,lastsong=-1;\r
+       unsigned start,songs[]=\r
+               {\r
+#ifndef SPEAR\r
+                       GETTHEM_MUS,\r
+                       SEARCHN_MUS,\r
+                       POW_MUS,\r
+                       SUSPENSE_MUS,\r
+                       WARMARCH_MUS,\r
+                       CORNER_MUS,\r
+\r
+                       NAZI_OMI_MUS,\r
+                       PREGNANT_MUS,\r
+                       GOINGAFT_MUS,\r
+                       HEADACHE_MUS,\r
+                       DUNGEON_MUS,\r
+                       ULTIMATE_MUS,\r
+\r
+                       INTROCW3_MUS,\r
+                       NAZI_RAP_MUS,\r
+                       TWELFTH_MUS,\r
+                       ZEROHOUR_MUS,\r
+                       ULTIMATE_MUS,\r
+                       PACMAN_MUS\r
+#else\r
+                       XFUNKIE_MUS,             // 0\r
+                       XDEATH_MUS,              // 2\r
+                       XTIPTOE_MUS,             // 4\r
+                       XTHEEND_MUS,             // 7\r
+                       XEVIL_MUS,               // 17\r
+                       XJAZNAZI_MUS,            // 18\r
+                       XPUTIT_MUS,              // 21\r
+                       XGETYOU_MUS,             // 22\r
+                       XTOWER2_MUS              // 23\r
+#endif\r
+               };\r
+       struct dostime_t time;\r
+\r
+\r
+\r
+       IN_ClearKeysDown();\r
+       if (!AdLibPresent && !SoundBlasterPresent)\r
+               return;\r
+\r
+\r
+       MenuFadeOut();\r
+\r
+#ifndef SPEAR\r
+#ifndef UPLOAD\r
+       _dos_gettime(&time);\r
+       start = (time.hsecond%3)*6;\r
+#else\r
+       start = 0;\r
+#endif\r
+#else\r
+       start = 0;\r
+#endif\r
+\r
+\r
+       CA_CacheGrChunk (STARTFONT+1);\r
+#ifdef SPEAR\r
+       CacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);\r
+#else\r
+       CacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END);\r
+#endif\r
+       CA_LoadAllSounds ();\r
+\r
+       fontnumber=1;\r
+       ClearMScreen ();\r
+       VWB_DrawPic(112,184,C_MOUSELBACKPIC);\r
+       DrawStripes (10);\r
+       SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR);\r
+\r
+#ifndef SPEAR\r
+       DrawWindow (CTL_X-2,CTL_Y-6,280,13*7,BKGDCOLOR);\r
+#else\r
+       DrawWindow (CTL_X-2,CTL_Y-26,280,13*10,BKGDCOLOR);\r
+#endif\r
+\r
+       DrawMenu (&MusicItems,&MusicMenu[start]);\r
+\r
+       SETFONTCOLOR (READHCOLOR,BKGDCOLOR);\r
+       PrintY=15;\r
+       WindowX = 0;\r
+       WindowY = 320;\r
+       US_CPrint ("Robert's Jukebox");\r
+\r
+       SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR);\r
+       VW_UpdateScreen();\r
+       MenuFadeIn();\r
+\r
+       do\r
+       {\r
+               which = HandleMenu(&MusicItems,&MusicMenu[start],NULL);\r
+               if (which>=0)\r
+               {\r
+                       if (lastsong >= 0)\r
+                               MusicMenu[start+lastsong].active = 1;\r
+\r
+                       StartCPMusic(songs[start + which]);\r
+                       MusicMenu[start+which].active = 2;\r
+                       DrawMenu (&MusicItems,&MusicMenu[start]);\r
+                       VW_UpdateScreen();\r
+                       lastsong = which;\r
+               }\r
+       } while(which>=0);\r
+\r
+       MenuFadeOut();\r
+       IN_ClearKeysDown();\r
+#ifdef SPEAR\r
+       UnCacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END);\r
+#else\r
+       UnCacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END);\r
+#endif\r
+}\r
+#endif\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= InitGame\r
+=\r
+= Load a few things right away\r
+=\r
+==========================\r
+*/\r
+\r
+void InitGame (void)\r
+{\r
+       int                     i,x,y;\r
+       unsigned        *blockstart;\r
+\r
+       if (MS_CheckParm ("virtual"))\r
+               virtualreality = true;\r
+       else\r
+               virtualreality = false;\r
+\r
+       MM_Startup ();                  // so the signon screen can be freed\r
+\r
+       SignonScreen ();\r
+\r
+       VW_Startup ();\r
+       IN_Startup ();\r
+       PM_Startup ();\r
+       PM_UnlockMainMem ();\r
+       SD_Startup ();\r
+       CA_Startup ();\r
+       US_Startup ();\r
+\r
+\r
+#ifndef SPEAR\r
+       if (mminfo.mainmem < 235000L)\r
+#else\r
+       if (mminfo.mainmem < 257000L && !MS_CheckParm("debugmode"))\r
+#endif\r
+       {\r
+               memptr screen;\r
+\r
+               CA_CacheGrChunk (ERRORSCREEN);\r
+               screen = grsegs[ERRORSCREEN];\r
+               ShutdownId();\r
+               movedata ((unsigned)screen,7+7*160,0xb800,0,17*160);\r
+               gotoxy (1,23);\r
+               exit(1);\r
+       }\r
+\r
+\r
+//\r
+// build some tables\r
+//\r
+       InitDigiMap ();\r
+\r
+       for (i=0;i<MAPSIZE;i++)\r
+       {\r
+               nearmapylookup[i] = &tilemap[0][0]+MAPSIZE*i;\r
+               farmapylookup[i] = i*64;\r
+       }\r
+\r
+       for (i=0;i<PORTTILESHIGH;i++)\r
+               uwidthtable[i] = UPDATEWIDE*i;\r
+\r
+       blockstart = &blockstarts[0];\r
+       for (y=0;y<UPDATEHIGH;y++)\r
+               for (x=0;x<UPDATEWIDE;x++)\r
+                       *blockstart++ = SCREENWIDTH*16*y+x*TILEWIDTH;\r
+\r
+       updateptr = &update[0];\r
+\r
+       bufferofs = 0;\r
+       displayofs = 0;\r
+       ReadConfig ();\r
+\r
+\r
+//\r
+// HOLDING DOWN 'M' KEY?\r
+//\r
+#ifndef SPEARDEMO\r
+       if (Keyboard[sc_M])\r
+         DoJukebox();\r
+       else\r
+#endif\r
+//\r
+// draw intro screen stuff\r
+//\r
+       if (!virtualreality)\r
+               IntroScreen ();\r
+\r
+//\r
+// load in and lock down some basic chunks\r
+//\r
+\r
+       CA_CacheGrChunk(STARTFONT);\r
+       MM_SetLock (&grsegs[STARTFONT],true);\r
+\r
+       LoadLatchMem ();\r
+       BuildTables ();          // trig tables\r
+       SetupWalls ();\r
+\r
+#if 0\r
+{\r
+int temp,i;\r
+temp = viewsize;\r
+       profilehandle = open("SCALERS.TXT", O_CREAT | O_WRONLY | O_TEXT);\r
+for (i=1;i<20;i++)\r
+       NewViewSize(i);\r
+viewsize = temp;\r
+close(profilehandle);\r
+}\r
+#endif\r
+\r
+       NewViewSize (viewsize);\r
+\r
+\r
+//\r
+// initialize variables\r
+//\r
+       InitRedShifts ();\r
+       if (!virtualreality)\r
+               FinishSignon();\r
+\r
+       displayofs = PAGE1START;\r
+       bufferofs = PAGE2START;\r
+\r
+       if (virtualreality)\r
+       {\r
+               NoWait = true;\r
+               geninterrupt(0x60);\r
+       }\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+==========================\r
+=\r
+= SetViewSize\r
+=\r
+==========================\r
+*/\r
+\r
+boolean SetViewSize (unsigned width, unsigned height)\r
+{\r
+       viewwidth = width&~15;                  // must be divisable by 16\r
+       viewheight = height&~1;                 // must be even\r
+       centerx = viewwidth/2-1;\r
+       shootdelta = viewwidth/10;\r
+       screenofs = ((200-STATUSLINES-viewheight)/2*SCREENWIDTH+(320-viewwidth)/8);\r
+\r
+//\r
+// calculate trace angles and projection constants\r
+//\r
+       CalcProjection (FOCALLENGTH);\r
+\r
+//\r
+// build all needed compiled scalers\r
+//\r
+//     MM_BombOnError (false);\r
+       SetupScaling (viewwidth*1.5);\r
+#if 0\r
+       MM_BombOnError (true);\r
+       if (mmerror)\r
+       {\r
+               Quit ("Can't build scalers!");\r
+               mmerror = false;\r
+               return false;\r
+       }\r
+#endif\r
+       return true;\r
+}\r
+\r
+\r
+void ShowViewSize (int width)\r
+{\r
+       int     oldwidth,oldheight;\r
+\r
+       oldwidth = viewwidth;\r
+       oldheight = viewheight;\r
+\r
+       viewwidth = width*16;\r
+       viewheight = width*16*HEIGHTRATIO;\r
+       DrawPlayBorder ();\r
+\r
+       viewheight = oldheight;\r
+       viewwidth = oldwidth;\r
+}\r
+\r
+\r
+void NewViewSize (int width)\r
+{\r
+       CA_UpLevel ();\r
+       MM_SortMem ();\r
+       viewsize = width;\r
+       SetViewSize (width*16,width*16*HEIGHTRATIO);\r
+       CA_DownLevel ();\r
+}\r
+\r
+\r
+\r
+//===========================================================================\r
+\r
+/*\r
+==========================\r
+=\r
+= Quit\r
+=\r
+==========================\r
+*/\r
+\r
+void Quit (char *error)\r
+{\r
+       unsigned        finscreen;\r
+       memptr  screen;\r
+\r
+       if (virtualreality)\r
+               geninterrupt(0x61);\r
+\r
+       ClearMemory ();\r
+       if (!*error)\r
+       {\r
+        #ifndef JAPAN\r
+        CA_CacheGrChunk (ORDERSCREEN);\r
+        screen = grsegs[ORDERSCREEN];\r
+        #endif\r
+        WriteConfig ();\r
+       }\r
+       else\r
+       {\r
+        CA_CacheGrChunk (ERRORSCREEN);\r
+        screen = grsegs[ERRORSCREEN];\r
+       }\r
+\r
+       ShutdownId ();\r
+\r
+       if (error && *error)\r
+       {\r
+         movedata ((unsigned)screen,7,0xb800,0,7*160);\r
+         gotoxy (10,4);\r
+         puts(error);\r
+         gotoxy (1,8);\r
+         exit(1);\r
+       }\r
+       else\r
+       if (!error || !(*error))\r
+       {\r
+               clrscr();\r
+               #ifndef JAPAN\r
+               movedata ((unsigned)screen,7,0xb800,0,4000);\r
+               gotoxy(1,24);\r
+               #endif\r
+//asm  mov     bh,0\r
+//asm  mov     dh,23   // row\r
+//asm  mov     dl,0    // collumn\r
+//asm  mov ah,2\r
+//asm  int     0x10\r
+       }\r
+\r
+       exit(0);\r
+}\r
+\r
+//===========================================================================\r
+\r
+\r
+\r
+/*\r
+=====================\r
+=\r
+= DemoLoop\r
+=\r
+=====================\r
+*/\r
+\r
+static  char *ParmStrings[] = {"baby","easy","normal","hard",""};\r
+\r
+void    DemoLoop (void)\r
+{\r
+       static int LastDemo;\r
+       int     i,level;\r
+       long nsize;\r
+       memptr  nullblock;\r
+\r
+//\r
+// check for launch from ted\r
+//\r
+       if (tedlevel)\r
+       {\r
+               NoWait = true;\r
+               NewGame(1,0);\r
+\r
+               for (i = 1;i < _argc;i++)\r
+               {\r
+                       if ( (level = US_CheckParm(_argv[i],ParmStrings)) != -1)\r
+                       {\r
+                        gamestate.difficulty=level;\r
+                        break;\r
+                       }\r
+               }\r
+\r
+#ifndef SPEAR\r
+               gamestate.episode = tedlevelnum/10;\r
+               gamestate.mapon = tedlevelnum%10;\r
+#else\r
+               gamestate.episode = 0;\r
+               gamestate.mapon = tedlevelnum;\r
+#endif\r
+               GameLoop();\r
+               Quit (NULL);\r
+       }\r
+\r
+\r
+//\r
+// main game cycle\r
+//\r
+\r
+\r
+//     nsize = (long)40*1024;\r
+//     MM_GetPtr(&nullblock,nsize);\r
+\r
+#ifndef DEMOTEST\r
+\r
+       #ifndef UPLOAD\r
+\r
+               #ifndef GOODTIMES\r
+               #ifndef SPEAR\r
+               #ifndef JAPAN\r
+               if (!NoWait)\r
+                       NonShareware();\r
+               #endif\r
+               #else\r
+\r
+#if 0\r
+                       #ifndef GOODTIMES\r
+                       #ifndef SPEARDEMO\r
+                       CopyProtection();\r
+                       #endif\r
+                       #endif\r
+#endif\r
+\r
+               #endif\r
+               #endif\r
+       #endif\r
+\r
+       StartCPMusic(INTROSONG);\r
+\r
+#ifndef JAPAN\r
+       if (!NoWait)\r
+               PG13 ();\r
+#endif\r
+\r
+#endif\r
+\r
+       while (1)\r
+       {\r
+               while (!NoWait)\r
+               {\r
+//\r
+// title page\r
+//\r
+                       MM_SortMem ();\r
+#ifndef DEMOTEST\r
+\r
+#ifdef SPEAR\r
+                       CA_CacheGrChunk (TITLEPALETTE);\r
+\r
+                       CA_CacheGrChunk (TITLE1PIC);\r
+                       VWB_DrawPic (0,0,TITLE1PIC);\r
+                       UNCACHEGRCHUNK (TITLE1PIC);\r
+\r
+                       CA_CacheGrChunk (TITLE2PIC);\r
+                       VWB_DrawPic (0,80,TITLE2PIC);\r
+                       UNCACHEGRCHUNK (TITLE2PIC);\r
+                       VW_UpdateScreen ();\r
+                       VL_FadeIn(0,255,grsegs[TITLEPALETTE],30);\r
+\r
+                       UNCACHEGRCHUNK (TITLEPALETTE);\r
+#else\r
+                       CA_CacheScreen (TITLEPIC);\r
+                       VW_UpdateScreen ();\r
+                       VW_FadeIn();\r
+#endif\r
+                       if (IN_UserInput(TickBase*15))\r
+                               break;\r
+                       VW_FadeOut();\r
+//\r
+// credits page\r
+//\r
+                       CA_CacheScreen (CREDITSPIC);\r
+                       VW_UpdateScreen();\r
+                       VW_FadeIn ();\r
+                       if (IN_UserInput(TickBase*10))\r
+                               break;\r
+                       VW_FadeOut ();\r
+//\r
+// high scores\r
+//\r
+                       DrawHighScores ();\r
+                       VW_UpdateScreen ();\r
+                       VW_FadeIn ();\r
+\r
+                       if (IN_UserInput(TickBase*10))\r
+                               break;\r
+#endif\r
+//\r
+// demo\r
+//\r
+\r
+                       #ifndef SPEARDEMO\r
+                       PlayDemo (LastDemo++%4);\r
+                       #else\r
+                       PlayDemo (0);\r
+                       #endif\r
+\r
+                       if (playstate == ex_abort)\r
+                               break;\r
+                       StartCPMusic(INTROSONG);\r
+               }\r
+\r
+               VW_FadeOut ();\r
+\r
+#ifndef SPEAR\r
+               if (Keyboard[sc_Tab] && MS_CheckParm("goobers"))\r
+#else\r
+               if (Keyboard[sc_Tab] && MS_CheckParm("debugmode"))\r
+#endif\r
+                       RecordDemo ();\r
+               else\r
+                       US_ControlPanel (0);\r
+\r
+               if (startgame || loadedgame)\r
+               {\r
+                       GameLoop ();\r
+                       VW_FadeOut();\r
+                       StartCPMusic(INTROSONG);\r
+               }\r
+       }\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= main\r
+=\r
+==========================\r
+*/\r
+\r
+char    *nosprtxt[] = {"nospr",nil};\r
+\r
+void main (void)\r
+{\r
+       int     i;\r
+\r
+\r
+#ifdef BETA\r
+       //\r
+       // THIS IS FOR BETA ONLY!\r
+       //\r
+       struct dosdate_t d;\r
+\r
+       _dos_getdate(&d);\r
+       if (d.year > YEAR ||\r
+               (d.month >= MONTH && d.day >= DAY))\r
+       {\r
+        printf("Sorry, BETA-TESTING is over. Thanks for you help.\n");\r
+        exit(1);\r
+       }\r
+#endif\r
+\r
+       CheckForEpisodes();\r
+\r
+       //00--  Patch386 ();\r
+\r
+       InitGame ();\r
+\r
+       DemoLoop();\r
+\r
+       Quit("Demo loop exited???");\r
+}\r
+\r