ref: 6638e8580dee0e8691a54da80058be66ab78bcd4
dir: /main.c/
// WL_MAIN.C #include <conio.h> #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;i<size-1;i++) checksum += source[i]^source[i+1]; return checksum; } /* ================== = = SaveTheGame = ================== */ boolean SaveTheGame(int file,int x,int y) { struct diskfree_t dfree; long avail,size,checksum; objtype *ob,nullobj; if (_dos_getdiskfree(0,&dfree)) Quit("Error in _dos_getdiskfree call"); avail = (long)dfree.avail_clusters * dfree.bytes_per_sector * dfree.sectors_per_cluster; size = 0; for (ob = player; ob ; ob=ob->next) 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<FINEANGLES/8;i++) { tang = tan( (i+0.5)/radtoint); finetangent[i] = tang*TILEGLOBAL; finetangent[FINEANGLES/4-1-i] = 1/tang*TILEGLOBAL; } // // costable overlays sintable with a quarter phase shift // ANGLES is assumed to be divisable by four // // The low word of the value is the fraction, the high bit is the sign bit, // bits 16-30 should be 0 // angle = 0; anglestep = PI/2/ANGLEQUAD; for (i=0;i<=ANGLEQUAD;i++) { value=GLOBAL1*sin(angle); sintable[i]= sintable[i+ANGLES]= sintable[ANGLES/2-i] = value; sintable[ANGLES-i]= sintable[ANGLES/2+i] = value | 0x80000000l; angle += anglestep; } } //=========================================================================== /* ==================== = = CalcProjection = = Uses focallength = ==================== */ void CalcProjection (long focal) { int i; long intang; float angle; double tang; double planedist; double globinhalf; int halfview; double halfangle,facedist; focallength = focal; facedist = focal+MINDIST; halfview = viewwidth/2; // half view in pixels // // calculate scale value for vertical height calculations // and sprite x calculations // scale = halfview*facedist/(VIEWGLOBAL/2); // // divide heightnumerator by a posts distance to get the posts height for // the heightbuffer. The pixel height is height>>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<halfview;i++) { // start 1/2 pixel over, so viewangle bisects two middle pixels tang = (long)i*VIEWGLOBAL/viewwidth/facedist; angle = atan(tang); intang = angle*radtoint; pixelangle[halfview-1-i] = intang; pixelangle[halfview+i] = -intang; } // // if a point's abs(y/x) is greater than maxslope, the point is outside // the view area // maxslope = finetangent[pixelangle[0]]; maxslope >>= 8; } //=========================================================================== /* =================== = = SetupWalls = = Map tile values to scaled pics = =================== */ void SetupWalls (void) { int i; for (i=1;i<MAXWALLTILES;i++) { horizwall[i]=(i-1)*2; vertwall[i]=(i-1)*2+1; } } //=========================================================================== /* ========================== = = SignonScreen = ========================== */ void SignonScreen (void) // VGA version { unsigned segstart,seglength; VL_SetVGAPlaneMode (); VL_TestPaletteSet (); VL_SetPalette (&gamepal); if (!virtualreality) { VW_SetScreen(0x8000,0); VL_MungePic (&introscn,320,200); VL_MemToScreen (&introscn,320,200,0,0); VW_SetScreen(0,0); } // // reclaim the memory from the linked in signon screen // segstart = FP_SEG(&introscn); seglength = 64000/16; if (FP_OFF(&introscn)) { segstart++; seglength--; } MML_UseSpace (segstart,seglength); } /* ========================== = = FinishSignon = ========================== */ void FinishSignon (void) { #ifndef SPEAR VW_Bar (0,189,300,11,peekb(0xa000,0)); WindowX = 0; WindowW = 320; PrintY = 190; #ifndef JAPAN SETFONTCOLOR(14,4); #ifdef SPANISH US_CPrint ("Oprima una tecla"); #else US_CPrint ("Press a key"); #endif #endif if (!NoWait) IN_Ack (); #ifndef JAPAN VW_Bar (0,189,300,11,peekb(0xa000,0)); PrintY = 190; SETFONTCOLOR(10,4); #ifdef SPANISH US_CPrint ("pensando..."); #else US_CPrint ("Working..."); #endif #endif SETFONTCOLOR(0,15); #else if (!NoWait) VW_WaitVBL(3*70); #endif } //=========================================================================== /* ================= = = MS_CheckParm = ================= */ boolean MS_CheckParm (char far *check) { int i; char *parm; for (i = 1;i<_argc;i++) { parm = _argv[i]; while ( !isalpha(*parm) ) // skip - / \ etc.. in front of parm if (!*parm++) break; // hit end of string without an alphanum if ( !_fstricmp(check,parm) ) return true; } return false; } //=========================================================================== /* ===================== = = InitDigiMap = ===================== */ static int wolfdigimap[] = { // These first sounds are in the upload version #ifndef SPEAR HALTSND, 0, DOGBARKSND, 1, CLOSEDOORSND, 2, OPENDOORSND, 3, ATKMACHINEGUNSND, 4, ATKPISTOLSND, 5, ATKGATLINGSND, 6, SCHUTZADSND, 7, GUTENTAGSND, 8, MUTTISND, 9, BOSSFIRESND, 10, SSFIRESND, 11, DEATHSCREAM1SND, 12, DEATHSCREAM2SND, 13, DEATHSCREAM3SND, 13, TAKEDAMAGESND, 14, PUSHWALLSND, 15, LEBENSND, 20, NAZIFIRESND, 21, SLURPIESND, 22, YEAHSND, 32, #ifndef UPLOAD // These are in all other episodes DOGDEATHSND, 16, AHHHGSND, 17, DIESND, 18, EVASND, 19, TOT_HUNDSND, 23, MEINGOTTSND, 24, SCHABBSHASND, 25, HITLERHASND, 26, SPIONSND, 27, NEINSOVASSND, 28, DOGATTACKSND, 29, LEVELDONESND, 30, MECHSTEPSND, 31, SCHEISTSND, 33, DEATHSCREAM4SND, 34, // AIIEEE DEATHSCREAM5SND, 35, // DEE-DEE DONNERSND, 36, // EPISODE 4 BOSS DIE EINESND, 37, // EPISODE 4 BOSS SIGHTING ERLAUBENSND, 38, // EPISODE 6 BOSS SIGHTING DEATHSCREAM6SND, 39, // FART DEATHSCREAM7SND, 40, // GASP DEATHSCREAM8SND, 41, // GUH-BOY! DEATHSCREAM9SND, 42, // AH GEEZ! KEINSND, 43, // EPISODE 5 BOSS SIGHTING MEINSND, 44, // EPISODE 6 BOSS DIE ROSESND, 45, // EPISODE 5 BOSS DIE #endif #else // // SPEAR OF DESTINY DIGISOUNDS // HALTSND, 0, CLOSEDOORSND, 2, OPENDOORSND, 3, ATKMACHINEGUNSND, 4, ATKPISTOLSND, 5, ATKGATLINGSND, 6, SCHUTZADSND, 7, BOSSFIRESND, 8, SSFIRESND, 9, DEATHSCREAM1SND, 10, DEATHSCREAM2SND, 11, TAKEDAMAGESND, 12, PUSHWALLSND, 13, AHHHGSND, 15, LEBENSND, 16, NAZIFIRESND, 17, SLURPIESND, 18, LEVELDONESND, 22, DEATHSCREAM4SND, 23, // AIIEEE DEATHSCREAM3SND, 23, // DOUBLY-MAPPED!!! DEATHSCREAM5SND, 24, // DEE-DEE DEATHSCREAM6SND, 25, // FART DEATHSCREAM7SND, 26, // GASP DEATHSCREAM8SND, 27, // GUH-BOY! DEATHSCREAM9SND, 28, // AH GEEZ! GETGATLINGSND, 38, // Got Gat replacement #ifndef SPEARDEMO DOGBARKSND, 1, DOGDEATHSND, 14, SPIONSND, 19, NEINSOVASSND, 20, DOGATTACKSND, 21, TRANSSIGHTSND, 29, // Trans Sight TRANSDEATHSND, 30, // Trans Death WILHELMSIGHTSND, 31, // Wilhelm Sight WILHELMDEATHSND, 32, // Wilhelm Death UBERDEATHSND, 33, // Uber Death KNIGHTSIGHTSND, 34, // Death Knight Sight KNIGHTDEATHSND, 35, // Death Knight Death ANGELSIGHTSND, 36, // Angel Sight ANGELDEATHSND, 37, // Angel Death GETSPEARSND, 39, // Got Spear replacement #endif #endif LASTSOUND }; void InitDigiMap (void) { int *map; for (map = wolfdigimap;*map != LASTSOUND;map += 2) DigiMap[map[0]] = map[1]; } #ifndef SPEAR CP_iteminfo MusicItems={CTL_X,CTL_Y,6,0,32}; CP_itemtype far MusicMenu[]= { {1,"Get Them!",0}, {1,"Searching",0}, {1,"P.O.W.",0}, {1,"Suspense",0}, {1,"War March",0}, {1,"Around The Corner!",0}, {1,"Nazi Anthem",0}, {1,"Lurking...",0}, {1,"Going After Hitler",0}, {1,"Pounding Headache",0}, {1,"Into the Dungeons",0}, {1,"Ultimate Conquest",0}, {1,"Kill the S.O.B.",0}, {1,"The Nazi Rap",0}, {1,"Twelfth Hour",0}, {1,"Zero Hour",0}, {1,"Ultimate Conquest",0}, {1,"Wolfpack",0} }; #else CP_iteminfo MusicItems={CTL_X,CTL_Y-20,9,0,32}; CP_itemtype far MusicMenu[]= { {1,"Funky Colonel Bill",0}, {1,"Death To The Nazis",0}, {1,"Tiptoeing Around",0}, {1,"Is This THE END?",0}, {1,"Evil Incarnate",0}, {1,"Jazzin' Them Nazis",0}, {1,"Puttin' It To The Enemy",0}, {1,"The SS Gonna Get You",0}, {1,"Towering Above",0} }; #endif #ifndef SPEARDEMO void DoJukebox(void) { int which,lastsong=-1; unsigned start,songs[]= { #ifndef SPEAR GETTHEM_MUS, SEARCHN_MUS, POW_MUS, SUSPENSE_MUS, WARMARCH_MUS, CORNER_MUS, NAZI_OMI_MUS, PREGNANT_MUS, GOINGAFT_MUS, HEADACHE_MUS, DUNGEON_MUS, ULTIMATE_MUS, INTROCW3_MUS, NAZI_RAP_MUS, TWELFTH_MUS, ZEROHOUR_MUS, ULTIMATE_MUS, PACMAN_MUS #else XFUNKIE_MUS, // 0 XDEATH_MUS, // 2 XTIPTOE_MUS, // 4 XTHEEND_MUS, // 7 XEVIL_MUS, // 17 XJAZNAZI_MUS, // 18 XPUTIT_MUS, // 21 XGETYOU_MUS, // 22 XTOWER2_MUS // 23 #endif }; struct dostime_t time; IN_ClearKeysDown(); if (!AdLibPresent && !SoundBlasterPresent) return; MenuFadeOut(); #ifndef SPEAR #ifndef UPLOAD _dos_gettime(&time); start = (time.hsecond%3)*6; #else start = 0; #endif #else start = 0; #endif CA_CacheGrChunk (STARTFONT+1); #ifdef SPEAR CacheLump (BACKDROP_LUMP_START,BACKDROP_LUMP_END); #else CacheLump (CONTROLS_LUMP_START,CONTROLS_LUMP_END); #endif CA_LoadAllSounds (); fontnumber=1; ClearMScreen (); VWB_DrawPic(112,184,C_MOUSELBACKPIC); DrawStripes (10); SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR); #ifndef SPEAR DrawWindow (CTL_X-2,CTL_Y-6,280,13*7,BKGDCOLOR); #else DrawWindow (CTL_X-2,CTL_Y-26,280,13*10,BKGDCOLOR); #endif DrawMenu (&MusicItems,&MusicMenu[start]); SETFONTCOLOR (READHCOLOR,BKGDCOLOR); PrintY=15; WindowX = 0; WindowY = 320; US_CPrint ("Robert's Jukebox"); SETFONTCOLOR (TEXTCOLOR,BKGDCOLOR); VW_UpdateScreen(); MenuFadeIn(); do { which = HandleMenu(&MusicItems,&MusicMenu[start],NULL); if (which>=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<MAPSIZE;i++) { nearmapylookup[i] = &tilemap[0][0]+MAPSIZE*i; farmapylookup[i] = i*64; } for (i=0;i<PORTTILESHIGH;i++) uwidthtable[i] = UPDATEWIDE*i; blockstart = &blockstarts[0]; for (y=0;y<UPDATEHIGH;y++) for (x=0;x<UPDATEWIDE;x++) *blockstart++ = SCREENWIDTH*16*y+x*TILEWIDTH; updateptr = &update[0]; bufferofs = 0; displayofs = 0; ReadConfig (); // // HOLDING DOWN 'M' KEY? // #ifndef SPEARDEMO if (Keyboard[sc_M]) DoJukebox(); else #endif // // draw intro screen stuff // if (!virtualreality) IntroScreen (); // // load in and lock down some basic chunks // CA_CacheGrChunk(STARTFONT); MM_SetLock (&grsegs[STARTFONT],true); LoadLatchMem (); BuildTables (); // trig tables SetupWalls (); #if 0 { int temp,i; temp = viewsize; profilehandle = open("SCALERS.TXT", O_CREAT | O_WRONLY | O_TEXT); for (i=1;i<20;i++) NewViewSize(i); viewsize = temp; close(profilehandle); } #endif NewViewSize (viewsize); // // initialize variables // InitRedShifts (); if (!virtualreality) FinishSignon(); displayofs = PAGE1START; bufferofs = PAGE2START; if (virtualreality) { NoWait = true; geninterrupt(0x60); } } //=========================================================================== /* ========================== = = SetViewSize = ========================== */ boolean SetViewSize (unsigned width, unsigned height) { viewwidth = width&~15; // must be divisable by 16 viewheight = height&~1; // must be even centerx = viewwidth/2-1; shootdelta = viewwidth/10; screenofs = ((200-STATUSLINES-viewheight)/2*SCREENWIDTH+(320-viewwidth)/8); // // calculate trace angles and projection constants // CalcProjection (FOCALLENGTH); // // build all needed compiled scalers // // MM_BombOnError (false); SetupScaling (viewwidth*1.5); #if 0 MM_BombOnError (true); if (mmerror) { Quit ("Can't build scalers!"); mmerror = false; return false; } #endif return true; } void ShowViewSize (int width) { int oldwidth,oldheight; oldwidth = viewwidth; oldheight = viewheight; viewwidth = width*16; viewheight = width*16*HEIGHTRATIO; DrawPlayBorder (); viewheight = oldheight; viewwidth = oldwidth; } void NewViewSize (int width) { CA_UpLevel (); MM_SortMem (); viewsize = width; SetViewSize (width*16,width*16*HEIGHTRATIO); CA_DownLevel (); } //=========================================================================== /* ========================== = = Quit = ========================== */ void Quit (char *error) { unsigned finscreen; memptr screen; if (virtualreality) geninterrupt(0x61); ClearMemory (); if (!*error) { #ifndef JAPAN CA_CacheGrChunk (ORDERSCREEN); screen = grsegs[ORDERSCREEN]; #endif WriteConfig (); } else { CA_CacheGrChunk (ERRORSCREEN); screen = grsegs[ERRORSCREEN]; } ShutdownId (); if (error && *error) { movedata ((unsigned)screen,7,0xb800,0,7*160); gotoxy (10,4); puts(error); gotoxy (1,8); exit(1); } else if (!error || !(*error)) { clrscr(); #ifndef JAPAN movedata ((unsigned)screen,7,0xb800,0,4000); gotoxy(1,24); #endif //asm mov bh,0 //asm mov dh,23 // row //asm mov dl,0 // collumn //asm mov ah,2 //asm int 0x10 } exit(0); } //=========================================================================== /* ===================== = = DemoLoop = ===================== */ static char *ParmStrings[] = {"baby","easy","normal","hard",""}; void DemoLoop (void) { static int LastDemo; int i,level; long nsize; memptr nullblock; // // check for launch from ted // if (tedlevel) { NoWait = true; NewGame(1,0); for (i = 1;i < _argc;i++) { if ( (level = US_CheckParm(_argv[i],ParmStrings)) != -1) { gamestate.difficulty=level; break; } } #ifndef SPEAR gamestate.episode = tedlevelnum/10; gamestate.mapon = tedlevelnum%10; #else gamestate.episode = 0; gamestate.mapon = tedlevelnum; #endif GameLoop(); Quit (NULL); } // // main game cycle // // nsize = (long)40*1024; // MM_GetPtr(&nullblock,nsize); #ifndef DEMOTEST #ifndef UPLOAD #ifndef GOODTIMES #ifndef SPEAR #ifndef JAPAN if (!NoWait) NonShareware(); #endif #else #ifndef GOODTIMES #ifndef SPEARDEMO CopyProtection(); #endif #endif #endif #endif #endif StartCPMusic(INTROSONG); #ifndef JAPAN if (!NoWait) PG13 (); #endif #endif while (1) { while (!NoWait) { // // title page // MM_SortMem (); #ifndef DEMOTEST #ifdef SPEAR CA_CacheGrChunk (TITLEPALETTE); CA_CacheGrChunk (TITLE1PIC); VWB_DrawPic (0,0,TITLE1PIC); UNCACHEGRCHUNK (TITLE1PIC); CA_CacheGrChunk (TITLE2PIC); VWB_DrawPic (0,80,TITLE2PIC); UNCACHEGRCHUNK (TITLE2PIC); VW_UpdateScreen (); VL_FadeIn(0,255,grsegs[TITLEPALETTE],30); UNCACHEGRCHUNK (TITLEPALETTE); #else CA_CacheScreen (TITLEPIC); VW_UpdateScreen (); VW_FadeIn(); #endif if (IN_UserInput(TickBase*15)) break; VW_FadeOut(); // // credits page // CA_CacheScreen (CREDITSPIC); VW_UpdateScreen(); VW_FadeIn (); if (IN_UserInput(TickBase*10)) break; VW_FadeOut (); // // high scores // DrawHighScores (); VW_UpdateScreen (); VW_FadeIn (); if (IN_UserInput(TickBase*10)) break; #endif // // demo // #ifndef SPEARDEMO PlayDemo (LastDemo++%4); #else PlayDemo (0); #endif if (playstate == ex_abort) break; StartCPMusic(INTROSONG); } VW_FadeOut (); #ifndef SPEAR if (Keyboard[sc_Tab] && MS_CheckParm("goobers")) #else if (Keyboard[sc_Tab] && MS_CheckParm("debugmode")) #endif RecordDemo (); else US_ControlPanel (0); if (startgame || loadedgame) { GameLoop (); VW_FadeOut(); StartCPMusic(INTROSONG); } } } //=========================================================================== /* ========================== = = main = ========================== */ char *nosprtxt[] = {"nospr",nil}; void main (void) { int i; #ifdef BETA // // THIS IS FOR BETA ONLY! // struct dosdate_t d; _dos_getdate(&d); if (d.year > 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???"); }