// WL_MAIN.C #include #include "WL_DEF.H" #pragma hdrstop /* ============================================================================= WOLFENSTEIN 3-D An Id Software production by John Carmack ============================================================================= */ /* ============================================================================= LOCAL CONSTANTS ============================================================================= */ #define FOCALLENGTH (0x5700l) // in global coordinates #define VIEWGLOBAL 0x10000 // globals visable flush to wall #define VIEWWIDTH 256 // size of view window #define VIEWHEIGHT 144 /* ============================================================================= GLOBAL VARIABLES ============================================================================= */ char str[80],str2[20]; int tedlevelnum; boolean tedlevel; boolean nospr; boolean IsA386; int dirangle[9] = {0,ANGLES/8,2*ANGLES/8,3*ANGLES/8,4*ANGLES/8, 5*ANGLES/8,6*ANGLES/8,7*ANGLES/8,ANGLES}; // // proejection variables // fixed focallength; unsigned screenofs; int viewwidth; int viewheight; int centerx; int shootdelta; // pixels away from centerx a target can be fixed scale,maxslope; long heightnumerator; int minheightdiv; void Quit (char *error); boolean startgame,loadedgame,virtualreality; int mouseadjustment; char configname[13]="CONFIG."; /* ============================================================================= LOCAL VARIABLES ============================================================================= */ /* ==================== = = ReadConfig = ==================== */ void ReadConfig(void) { int file; SDMode sd; SMMode sm; SDSMode sds; if ( (file = open(configname,O_BINARY | O_RDONLY)) != -1) { // // valid config file // read(file,Scores,sizeof(HighScore) * MaxScores); read(file,&sd,sizeof(sd)); read(file,&sm,sizeof(sm)); read(file,&sds,sizeof(sds)); read(file,&mouseenabled,sizeof(mouseenabled)); read(file,&joystickenabled,sizeof(joystickenabled)); read(file,&joypadenabled,sizeof(joypadenabled)); read(file,&joystickprogressive,sizeof(joystickprogressive)); read(file,&joystickport,sizeof(joystickport)); read(file,&dirscan,sizeof(dirscan)); read(file,&buttonscan,sizeof(buttonscan)); read(file,&buttonmouse,sizeof(buttonmouse)); read(file,&buttonjoy,sizeof(buttonjoy)); read(file,&viewsize,sizeof(viewsize)); read(file,&mouseadjustment,sizeof(mouseadjustment)); close(file); if (sd == sdm_AdLib && !AdLibPresent && !SoundBlasterPresent) { sd = sdm_PC; sd = smm_Off; } if ((sds == sds_SoundBlaster && !SoundBlasterPresent) || (sds == sds_SoundSource && !SoundSourcePresent)) sds = sds_Off; if (!MousePresent) mouseenabled = false; if (!JoysPresent[joystickport]) joystickenabled = false; MainMenu[6].active=1; MainItems.curpos=0; } else { // // no config file, so select by hardware // if (SoundBlasterPresent || AdLibPresent) { sd = sdm_AdLib; sm = smm_AdLib; } else { sd = sdm_PC; sm = smm_Off; } if (SoundBlasterPresent) sds = sds_SoundBlaster; else if (SoundSourcePresent) sds = sds_SoundSource; else sds = sds_Off; if (MousePresent) mouseenabled = true; joystickenabled = false; joypadenabled = false; joystickport = 0; joystickprogressive = false; viewsize = 15; mouseadjustment=5; } SD_SetMusicMode (sm); SD_SetSoundMode (sd); SD_SetDigiDevice (sds); } /* ==================== = = WriteConfig = ==================== */ void WriteConfig(void) { int file; file = open(configname,O_CREAT | O_BINARY | O_WRONLY, S_IREAD | S_IWRITE | S_IFREG); if (file != -1) { write(file,Scores,sizeof(HighScore) * MaxScores); write(file,&SoundMode,sizeof(SoundMode)); write(file,&MusicMode,sizeof(MusicMode)); write(file,&DigiMode,sizeof(DigiMode)); write(file,&mouseenabled,sizeof(mouseenabled)); write(file,&joystickenabled,sizeof(joystickenabled)); write(file,&joypadenabled,sizeof(joypadenabled)); write(file,&joystickprogressive,sizeof(joystickprogressive)); write(file,&joystickport,sizeof(joystickport)); write(file,&dirscan,sizeof(dirscan)); write(file,&buttonscan,sizeof(buttonscan)); write(file,&buttonmouse,sizeof(buttonmouse)); write(file,&buttonjoy,sizeof(buttonjoy)); write(file,&viewsize,sizeof(viewsize)); write(file,&mouseadjustment,sizeof(mouseadjustment)); close(file); } } //=========================================================================== /* ======================== = = Patch386 = = Patch ldiv to use 32 bit instructions = ======================== */ char *JHParmStrings[] = {"no386",nil}; void Patch386 (void) { extern void far jabhack2(void); extern int far CheckIs386(void); int i; for (i = 1;i < _argc;i++) if (US_CheckParm(_argv[i],JHParmStrings) == 0) { IsA386 = false; return; } if (CheckIs386()) { IsA386 = true; jabhack2(); } else IsA386 = false; } //=========================================================================== /* ===================== = = NewGame = = Set up new game to start from the beginning = ===================== */ void NewGame (int difficulty,int episode) { memset (&gamestate,0,sizeof(gamestate)); gamestate.difficulty = difficulty; gamestate.weapon = gamestate.bestweapon = gamestate.chosenweapon = wp_pistol; gamestate.health = 100; gamestate.ammo = STARTAMMO; gamestate.lives = 3; gamestate.nextextra = EXTRAPOINTS; gamestate.episode=episode; startgame = true; } //=========================================================================== void DiskFlopAnim(int x,int y) { static char which=0; if (!x && !y) return; VWB_DrawPic(x,y,C_DISKLOADING1PIC+which); VW_UpdateScreen(); which^=1; } long DoChecksum(byte far *source,unsigned size,long checksum) { unsigned i; for (i=0;inext) size += sizeof(*ob); size += sizeof(nullobj); size += sizeof(gamestate) + sizeof(LRstruct)*8 + sizeof(tilemap) + sizeof(actorat) + sizeof(laststatobj) + sizeof(statobjlist) + sizeof(doorposition) + sizeof(pwallstate) + sizeof(pwallx) + sizeof(pwally) + sizeof(pwalldir) + sizeof(pwallpos); if (avail < size) { Message(STR_NOSPACE1"\n" STR_NOSPACE2); return false; } checksum = 0; DiskFlopAnim(x,y); CA_FarWrite (file,(void far *)&gamestate,sizeof(gamestate)); checksum = DoChecksum((byte far *)&gamestate,sizeof(gamestate),checksum); DiskFlopAnim(x,y); #ifdef SPEAR CA_FarWrite (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*20); checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*20,checksum); #else CA_FarWrite (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*8); checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*8,checksum); #endif DiskFlopAnim(x,y); CA_FarWrite (file,(void far *)tilemap,sizeof(tilemap)); checksum = DoChecksum((byte far *)tilemap,sizeof(tilemap),checksum); DiskFlopAnim(x,y); CA_FarWrite (file,(void far *)actorat,sizeof(actorat)); checksum = DoChecksum((byte far *)actorat,sizeof(actorat),checksum); CA_FarWrite (file,(void far *)areaconnect,sizeof(areaconnect)); CA_FarWrite (file,(void far *)areabyplayer,sizeof(areabyplayer)); for (ob = player ; ob ; ob=ob->next) { DiskFlopAnim(x,y); CA_FarWrite (file,(void far *)ob,sizeof(*ob)); } nullobj.active = ac_badobject; // end of file marker DiskFlopAnim(x,y); CA_FarWrite (file,(void far *)&nullobj,sizeof(nullobj)); DiskFlopAnim(x,y); CA_FarWrite (file,(void far *)&laststatobj,sizeof(laststatobj)); checksum = DoChecksum((byte far *)&laststatobj,sizeof(laststatobj),checksum); DiskFlopAnim(x,y); CA_FarWrite (file,(void far *)statobjlist,sizeof(statobjlist)); checksum = DoChecksum((byte far *)statobjlist,sizeof(statobjlist),checksum); DiskFlopAnim(x,y); CA_FarWrite (file,(void far *)doorposition,sizeof(doorposition)); checksum = DoChecksum((byte far *)doorposition,sizeof(doorposition),checksum); DiskFlopAnim(x,y); CA_FarWrite (file,(void far *)doorobjlist,sizeof(doorobjlist)); checksum = DoChecksum((byte far *)doorobjlist,sizeof(doorobjlist),checksum); DiskFlopAnim(x,y); CA_FarWrite (file,(void far *)&pwallstate,sizeof(pwallstate)); checksum = DoChecksum((byte far *)&pwallstate,sizeof(pwallstate),checksum); CA_FarWrite (file,(void far *)&pwallx,sizeof(pwallx)); checksum = DoChecksum((byte far *)&pwallx,sizeof(pwallx),checksum); CA_FarWrite (file,(void far *)&pwally,sizeof(pwally)); checksum = DoChecksum((byte far *)&pwally,sizeof(pwally),checksum); CA_FarWrite (file,(void far *)&pwalldir,sizeof(pwalldir)); checksum = DoChecksum((byte far *)&pwalldir,sizeof(pwalldir),checksum); CA_FarWrite (file,(void far *)&pwallpos,sizeof(pwallpos)); checksum = DoChecksum((byte far *)&pwallpos,sizeof(pwallpos),checksum); // // WRITE OUT CHECKSUM // CA_FarWrite (file,(void far *)&checksum,sizeof(checksum)); return(true); } //=========================================================================== /* ================== = = LoadTheGame = ================== */ boolean LoadTheGame(int file,int x,int y) { long checksum,oldchecksum; objtype *ob,nullobj; checksum = 0; DiskFlopAnim(x,y); CA_FarRead (file,(void far *)&gamestate,sizeof(gamestate)); checksum = DoChecksum((byte far *)&gamestate,sizeof(gamestate),checksum); DiskFlopAnim(x,y); #ifdef SPEAR CA_FarRead (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*20); checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*20,checksum); #else CA_FarRead (file,(void far *)&LevelRatios[0],sizeof(LRstruct)*8); checksum = DoChecksum((byte far *)&LevelRatios[0],sizeof(LRstruct)*8,checksum); #endif DiskFlopAnim(x,y); SetupGameLevel (); DiskFlopAnim(x,y); CA_FarRead (file,(void far *)tilemap,sizeof(tilemap)); checksum = DoChecksum((byte far *)tilemap,sizeof(tilemap),checksum); DiskFlopAnim(x,y); CA_FarRead (file,(void far *)actorat,sizeof(actorat)); checksum = DoChecksum((byte far *)actorat,sizeof(actorat),checksum); CA_FarRead (file,(void far *)areaconnect,sizeof(areaconnect)); CA_FarRead (file,(void far *)areabyplayer,sizeof(areabyplayer)); InitActorList (); DiskFlopAnim(x,y); CA_FarRead (file,(void far *)player,sizeof(*player)); while (1) { DiskFlopAnim(x,y); CA_FarRead (file,(void far *)&nullobj,sizeof(nullobj)); if (nullobj.active == ac_badobject) break; GetNewActor (); // don't copy over the links memcpy (new,&nullobj,sizeof(nullobj)-4); } DiskFlopAnim(x,y); CA_FarRead (file,(void far *)&laststatobj,sizeof(laststatobj)); checksum = DoChecksum((byte far *)&laststatobj,sizeof(laststatobj),checksum); DiskFlopAnim(x,y); CA_FarRead (file,(void far *)statobjlist,sizeof(statobjlist)); checksum = DoChecksum((byte far *)statobjlist,sizeof(statobjlist),checksum); DiskFlopAnim(x,y); CA_FarRead (file,(void far *)doorposition,sizeof(doorposition)); checksum = DoChecksum((byte far *)doorposition,sizeof(doorposition),checksum); DiskFlopAnim(x,y); CA_FarRead (file,(void far *)doorobjlist,sizeof(doorobjlist)); checksum = DoChecksum((byte far *)doorobjlist,sizeof(doorobjlist),checksum); DiskFlopAnim(x,y); CA_FarRead (file,(void far *)&pwallstate,sizeof(pwallstate)); checksum = DoChecksum((byte far *)&pwallstate,sizeof(pwallstate),checksum); CA_FarRead (file,(void far *)&pwallx,sizeof(pwallx)); checksum = DoChecksum((byte far *)&pwallx,sizeof(pwallx),checksum); CA_FarRead (file,(void far *)&pwally,sizeof(pwally)); checksum = DoChecksum((byte far *)&pwally,sizeof(pwally),checksum); CA_FarRead (file,(void far *)&pwalldir,sizeof(pwalldir)); checksum = DoChecksum((byte far *)&pwalldir,sizeof(pwalldir),checksum); CA_FarRead (file,(void far *)&pwallpos,sizeof(pwallpos)); checksum = DoChecksum((byte far *)&pwallpos,sizeof(pwallpos),checksum); CA_FarRead (file,(void far *)&oldchecksum,sizeof(oldchecksum)); if (oldchecksum != checksum) { Message(STR_SAVECHT1"\n" STR_SAVECHT2"\n" STR_SAVECHT3"\n" STR_SAVECHT4); IN_ClearKeysDown(); IN_Ack(); gamestate.score = 0; gamestate.lives = 1; gamestate.weapon = gamestate.chosenweapon = gamestate.bestweapon = wp_pistol; gamestate.ammo = 8; } return true; } //=========================================================================== /* ========================== = = ShutdownId = = Shuts down all ID_?? managers = ========================== */ void ShutdownId (void) { US_Shutdown (); SD_Shutdown (); PM_Shutdown (); IN_Shutdown (); VW_Shutdown (); CA_Shutdown (); MM_Shutdown (); } //=========================================================================== /* ================== = = BuildTables = = Calculates: = = scale projection constant = sintable/costable overlapping fractional tables = ================== */ const float radtoint = (float)FINEANGLES/2/PI; void BuildTables (void) { int i; float angle,anglestep; double tang; fixed value; // // calculate fine tangents // for (i=0;i>2 // heightnumerator = (TILEGLOBAL*scale)>>6; minheightdiv = heightnumerator/0x7fff +1; // // calculate the angle offset from view angle of each pixel's ray // for (i=0;i>= 8; } //=========================================================================== /* =================== = = SetupWalls = = Map tile values to scaled pics = =================== */ void SetupWalls (void) { int i; for (i=1;i=0) { if (lastsong >= 0) MusicMenu[start+lastsong].active = 1; StartCPMusic(songs[start + which]); MusicMenu[start+which].active = 2; DrawMenu (&MusicItems,&MusicMenu[start]); VW_UpdateScreen(); lastsong = which; } } while(which>=0); MenuFadeOut(); IN_ClearKeysDown(); #ifdef SPEAR UnCacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END); #else UnCacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END); #endif } #endif /* ========================== = = InitGame = = Load a few things right away = ========================== */ void InitGame (void) { int i,x,y; unsigned *blockstart; if (MS_CheckParm ("virtual")) virtualreality = true; else virtualreality = false; MM_Startup (); // so the signon screen can be freed SignonScreen (); VW_Startup (); IN_Startup (); PM_Startup (); PM_UnlockMainMem (); SD_Startup (); CA_Startup (); US_Startup (); #ifndef SPEAR if (mminfo.mainmem < 235000L) #else if (mminfo.mainmem < 257000L && !MS_CheckParm("debugmode")) #endif { memptr screen; CA_CacheGrChunk (ERRORSCREEN); screen = grsegs[ERRORSCREEN]; ShutdownId(); movedata ((unsigned)screen,7+7*160,0xb800,0,17*160); gotoxy (1,23); exit(1); } // // build some tables // InitDigiMap (); for (i=0;i YEAR || (d.month >= MONTH && d.day >= DAY)) { printf("Sorry, BETA-TESTING is over. Thanks for you help.\n"); exit(1); } #endif CheckForEpisodes(); Patch386 (); InitGame (); DemoLoop(); Quit("Demo loop exited???"); }