--- /dev/null
+// 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