// WL_MAIN.C #include "wl_def.h" #pragma hdrstop #include "wl_atmos.h" #include /* ============================================================================= WOLFENSTEIN 3-D An Id Software production by John Carmack ============================================================================= */ extern byte signon[]; /* ============================================================================= 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]; 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 viewscreenx, viewscreeny; int viewwidth; int viewheight; short centerx; int shootdelta; // pixels away from centerx a target can be fixed scale; int32_t heightnumerator; void Quit (const char *error,...); boolean startgame; boolean loadedgame; int mouseadjustment; char configdir[256] = ""; char configname[13] = "config."; // // Command line parameter variables // boolean param_debugmode = false; boolean param_nowait = false; int param_difficulty = 1; // default is "normal" int param_tedlevel = -1; // default is not to start a level int param_joystickindex = 0; #if defined(_arch_dreamcast) int param_joystickhat = 0; int param_samplerate = 11025; // higher samplerates result in "out of memory" int param_audiobuffer = 4096 / (44100 / param_samplerate); #elif defined(GP2X_940) int param_joystickhat = -1; int param_samplerate = 11025; // higher samplerates result in "out of memory" int param_audiobuffer = 128; #else int param_joystickhat = -1; int param_samplerate = RB_SAMPR; int param_audiobuffer = 2048 / (44100 / RB_SAMPR); #endif int param_mission = 0; boolean param_goodtimes = false; boolean param_ignorenumchunks = false; /* ============================================================================= LOCAL VARIABLES ============================================================================= */ /* ==================== = = ReadConfig = ==================== */ void ReadConfig(void) { SDMode sd; SMMode sm; SDSMode sds; char configpath[300]; #ifdef _arch_dreamcast DC_LoadFromVMU(configname); #endif if(configdir[0]) snprintf(configpath, sizeof(configpath), "%s/%s", configdir, configname); else strcpy(configpath, configname); const int file = open(configpath, O_RDONLY | O_BINARY); if (file >= 0) { // // valid config file // word tmp; read(file,&tmp,sizeof(tmp)); if(tmp!=0xfefa) { close(file); goto noconfig; } 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)); boolean dummyJoypadEnabled; read(file,&dummyJoypadEnabled,sizeof(dummyJoypadEnabled)); boolean dummyJoystickProgressive; read(file,&dummyJoystickProgressive,sizeof(dummyJoystickProgressive)); int dummyJoystickPort = 0; read(file,&dummyJoystickPort,sizeof(dummyJoystickPort)); 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); /* hack to always enable sound */ sd = sdm_AdLib; sm = smm_AdLib; sds = sds_SoundBlaster; // make sure values are correct if(mouseenabled) mouseenabled=true; if(joystickenabled) joystickenabled=true; if (!MousePresent) mouseenabled = false; if (!IN_JoyPresent()) joystickenabled = false; if(mouseadjustment<0) mouseadjustment=0; else if(mouseadjustment>9) mouseadjustment=9; if(viewsize<4) viewsize=4; else if(viewsize>21) viewsize=21; MainMenu[6].active=1; MainItems.curpos=0; } else { // // no config file, so select by hardware // noconfig: // always -FW19 sd = sdm_AdLib; sm = smm_AdLib; sds = sds_SoundBlaster; if (MousePresent) mouseenabled = true; if (IN_JoyPresent()) joystickenabled = true; viewsize = 20; // start with a good size mouseadjustment=5; } SD_SetMusicMode (sm); SD_SetSoundMode (sd); SD_SetDigiDevice (sds); } /* ==================== = = WriteConfig = ==================== */ void WriteConfig(void) { char configpath[300]; #ifdef _arch_dreamcast fs_unlink(configname); #endif if(configdir[0]) snprintf(configpath, sizeof(configpath), "%s/%s", configdir, configname); else strcpy(configpath, configname); const int file = open(configpath, O_CREAT | O_WRONLY | O_BINARY, 0644); if (file != -1) { word tmp=0xfefa; write(file,&tmp,sizeof(tmp)); 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)); boolean dummyJoypadEnabled = false; write(file,&dummyJoypadEnabled,sizeof(dummyJoypadEnabled)); boolean dummyJoystickProgressive = false; write(file,&dummyJoystickProgressive,sizeof(dummyJoystickProgressive)); int dummyJoystickPort = 0; write(file,&dummyJoystickPort,sizeof(dummyJoystickPort)); 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); } #ifdef _arch_dreamcast DC_SaveToVMU(configname, NULL); #endif } //=========================================================================== /* ===================== = = 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 int8_t which=0; if (!x && !y) return; VWB_DrawPic(x,y,C_DISKLOADING1PIC+which); VW_UpdateScreen(); which^=1; } int32_t DoChecksum(byte *source,unsigned size,int32_t checksum) { unsigned i; for (i=0;inext) size += sizeof(*ob); size += sizeof(nullobj); size += sizeof(gamestate) + sizeof(LRstruct)*LRpack + sizeof(tilemap) + sizeof(actorat) + sizeof(laststatobj) + sizeof(statobjlist) + sizeof(doorposition) + sizeof(pwallstate) + sizeof(pwalltile) + sizeof(pwallx) + sizeof(pwally) + sizeof(pwalldir) + sizeof(pwallpos); if (avail < size) { Message(STR_NOSPACE1"\n"STR_NOSPACE2); return false; }*/ checksum = 0; DiskFlopAnim(x,y); fwrite(&gamestate,sizeof(gamestate),1,file); checksum = DoChecksum((byte *)&gamestate,sizeof(gamestate),checksum); DiskFlopAnim(x,y); fwrite(&LevelRatios[0],sizeof(LRstruct)*LRpack,1,file); checksum = DoChecksum((byte *)&LevelRatios[0],sizeof(LRstruct)*LRpack,checksum); DiskFlopAnim(x,y); fwrite(tilemap,sizeof(tilemap),1,file); checksum = DoChecksum((byte *)tilemap,sizeof(tilemap),checksum); DiskFlopAnim(x,y); int i; for(i=0;inext; DiskFlopAnim(x,y); for (; ob ; ob=ob->next) { memcpy(&nullobj,ob,sizeof(nullobj)); nullobj.state=(statetype *) ((uintptr_t)nullobj.state-(uintptr_t)&s_grdstand); fwrite(&nullobj,sizeof(nullobj),1,file); } nullobj.active = ac_badobject; // end of file marker DiskFlopAnim(x,y); fwrite(&nullobj,sizeof(nullobj),1,file); DiskFlopAnim(x,y); word laststatobjnum=(word) (laststatobj-statobjlist); fwrite(&laststatobjnum,sizeof(laststatobjnum),1,file); checksum = DoChecksum((byte *)&laststatobjnum,sizeof(laststatobjnum),checksum); DiskFlopAnim(x,y); for(i=0;istate=(statetype *) ((uintptr_t)player->state+(uintptr_t)&s_player); while (1) { DiskFlopAnim(x,y); fread (&nullobj,sizeof(nullobj),1,file); if (nullobj.active == ac_badobject) break; GetNewActor (); nullobj.state=(statetype *) ((uintptr_t)nullobj.state+(uintptr_t)&s_grdstand); // don't copy over the links memcpy (newobj,&nullobj,sizeof(nullobj)-8); } DiskFlopAnim(x,y); word laststatobjnum; fread (&laststatobjnum,sizeof(laststatobjnum),1,file); laststatobj=statobjlist+laststatobjnum; checksum = DoChecksum((byte *)&laststatobjnum,sizeof(laststatobjnum),checksum); DiskFlopAnim(x,y); for(i=0;i= (AREATILE+NUMMAPS))) { if (*map >= AREATILE) tile = *map; if (*(map-1-mapwidth) >= AREATILE) tile = *(map-1-mapwidth); if (*(map-1+mapwidth) >= AREATILE) tile = *(map-1+mapwidth); if ( *(map-2) >= AREATILE) tile = *(map-2); *(map-1) = tile; *(obj-1) = 0; } } } Thrust(0,0); // set player->areanumber to the floortile you're standing on fread (&oldchecksum,sizeof(oldchecksum),1,file); fread (&lastgamemusicoffset,sizeof(lastgamemusicoffset),1,file); if(lastgamemusicoffset<0) lastgamemusicoffset=0; if (oldchecksum != checksum) { Message(STR_SAVECHT1"\n" STR_SAVECHT2"\n" STR_SAVECHT3"\n" STR_SAVECHT4); IN_ClearKeysDown(); IN_Ack(); gamestate.oldscore = 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 (); // This line is completely useless... SD_Shutdown (); PM_Shutdown (); IN_Shutdown (); VW_Shutdown (); CA_Shutdown (); #if defined(GP2X_940) GP2X_Shutdown(); #endif } //=========================================================================== /* ================== = = BuildTables = = Calculates: = = scale projection constant = sintable/costable overlapping fractional tables = ================== */ const float radtoint = (float)(FINEANGLES/2/PI); void BuildTables (void) { // // calculate fine tangents // int i; for(i=0;i>2 // heightnumerator = (TILEGLOBAL*scale)>>6; // // calculate the angle offset from view angle of each pixel's ray // for (i=0;isplashf(0, "Preparing sounds (%d/%d)", ++i, ARRAYLEN(wolfdigimap)/3); DigiMap[map[0]] = map[1]; DigiChannel[map[1]] = map[2]; SD_PrepareSound(map[1]); rb->yield(); } } #ifndef SPEAR CP_iteminfo MusicItems={CTL_X,CTL_Y,6,0,32}; CP_itemtype 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 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; unsigned 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 }; IN_ClearKeysDown(); if (!AdLibPresent && !SoundBlasterPresent) return; MenuFadeOut(); #ifndef SPEAR #ifndef UPLOAD start = ((SDL_GetTicks()/10)%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 = ========================== */ static void InitGame() { #ifndef SPEARDEMO boolean didjukebox=false; #endif // initialize SDL if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { printf("Unable to init SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); int numJoysticks = SDL_NumJoysticks(); if(param_joystickindex && (param_joystickindex < -1 || param_joystickindex >= numJoysticks)) { if(!numJoysticks) printf("No joysticks are available to SDL!\n"); else printf("The joystick index must be between -1 and %i!\n", numJoysticks - 1); exit(1); } #if defined(GP2X_940) GP2X_MemoryInit(); #endif SignonScreen (); VH_Startup (); IN_Startup (); PM_Startup (); SD_Startup (); CA_Startup (); US_Startup (); // TODO: Will any memory checking be needed someday?? #ifdef NOTYET #ifndef SPEAR if (mminfo.mainmem < 235000L) #else if (mminfo.mainmem < 257000L && !MS_CheckParm("debugmode")) #endif { byte *screen; CA_CacheGrChunk (ERRORSCREEN); screen = grsegs[ERRORSCREEN]; ShutdownId(); /* memcpy((byte *)0xb8000,screen+7+7*160,17*160); gotoxy (1,23);*/ exit(1); } #endif // // build some tables // InitDigiMap (); rb->splash(0, "Reading configuration..."); ReadConfig(); rb->splash(0, "Reading saved games..."); SetupSaveGames(); // // HOLDING DOWN 'M' KEY? (Fire for rockbox) // #ifndef SPEARDEMO /* allow entering jukebox */ rb->sleep(HZ / 10); IN_ProcessEvents(); if (Keyboard[sc_Return]) { DoJukebox(); didjukebox=true; } else #endif // // draw intro screen stuff // IntroScreen (); #ifdef _arch_dreamcast //TODO: VMU Selection Screen #endif // // load in and lock down some basic chunks // rb->splash(0, "Loading..."); CA_CacheGrChunk(STARTFONT); CA_CacheGrChunk(STATUSBARPIC); LoadLatchMem (); BuildTables (); // trig tables SetupWalls (); rb->splash(0, "Loading (50%)..."); NewViewSize (viewsize); // // initialize variables // InitRedShifts (); #ifndef SPEARDEMO if(!didjukebox) #endif FinishSignon(); #ifdef NOTYET vdisp = (byte *) (0xa0000+PAGE1START); vbuf = (byte *) (0xa0000+PAGE2START); #endif } //=========================================================================== /* ========================== = = 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; if((unsigned) viewheight == screenHeight) viewscreenx = viewscreeny = screenofs = 0; else { viewscreenx = (screenWidth-viewwidth) / 2; viewscreeny = (screenHeight-scaleFactor*STATUSLINES-viewheight)/2; screenofs = viewscreeny*screenWidth+viewscreenx; } // // calculate trace angles and projection constants // CalcProjection (FOCALLENGTH); return true; } void ShowViewSize (int width) { int oldwidth,oldheight; oldwidth = viewwidth; oldheight = viewheight; if(width == 21) { viewwidth = screenWidth; viewheight = screenHeight; VWB_BarScaledCoord (0, 0, screenWidth, screenHeight, 0); } else if(width == 20) { viewwidth = screenWidth; viewheight = screenHeight - scaleFactor*STATUSLINES; DrawPlayBorder (); } else { viewwidth = width*16*screenWidth/320; viewheight = (int) (width*16*HEIGHTRATIO*screenHeight/200); DrawPlayBorder (); } viewwidth = oldwidth; viewheight = oldheight; } void NewViewSize (int width) { viewsize = width; if(viewsize == 21) SetViewSize(screenWidth, screenHeight); else if(viewsize == 20) SetViewSize(screenWidth, screenHeight - scaleFactor * STATUSLINES); else SetViewSize(width*16*screenWidth/320, (unsigned) (width*16*HEIGHTRATIO*screenHeight/200)); } //=========================================================================== /* ========================== = = Quit = ========================== */ void Quit (const char *errorStr, ...) { #ifdef NOTYET byte *screen; #endif char error[256]; if(errorStr != NULL) { va_list vlist; va_start(vlist, errorStr); vsprintf(error, errorStr, vlist); va_end(vlist); rb->splashf(HZ * 4, "FATAL: %s", error); } else error[0] = 0; if (!pictable) // don't try to display the red box before it's loaded { ShutdownId(); if (error && *error) { #ifdef NOTYET SetTextCursor(0,0); #endif puts(error); #ifdef NOTYET SetTextCursor(0,2); #endif VW_WaitVBL(100); } exit(1); } if (!error || !*error) { #ifdef NOTYET #ifndef JAPAN CA_CacheGrChunk (ORDERSCREEN); screen = grsegs[ORDERSCREEN]; #endif #endif WriteConfig (); } #ifdef NOTYET else { CA_CacheGrChunk (ERRORSCREEN); screen = grsegs[ERRORSCREEN]; } #endif ShutdownId (); if (error && *error) { #ifdef NOTYET memcpy((byte *)0xb8000,screen+7,7*160); SetTextCursor(9,3); #endif puts(error); #ifdef NOTYET SetTextCursor(0,7); #endif VW_WaitVBL(200); exit(1); } else if (!error || !(*error)) { #ifdef NOTYET #ifndef JAPAN memcpy((byte *)0xb8000,screen+7,24*160); // 24 for SPEAR/UPLOAD compatibility #endif SetTextCursor(0,23); #endif } exit(0); } //=========================================================================== /* ===================== = = DemoLoop = ===================== */ static void DemoLoop() { int LastDemo = 0; // // check for launch from ted // if (param_tedlevel != -1) { param_nowait = true; EnableEndGameMenuItem(); NewGame(param_difficulty,0); #ifndef SPEAR gamestate.episode = param_tedlevel/10; gamestate.mapon = param_tedlevel%10; #else gamestate.episode = 0; gamestate.mapon = param_tedlevel; #endif GameLoop(); Quit (NULL); } // // main game cycle // #ifndef DEMOTEST #ifndef UPLOAD #ifndef GOODTIMES #ifndef SPEAR #ifndef JAPAN if (!param_nowait) NonShareware(); #endif #else #ifndef GOODTIMES #ifndef SPEARDEMO extern void CopyProtection(void); if(!param_goodtimes) CopyProtection(); #endif #endif #endif #endif #endif StartCPMusic(INTROSONG); #ifndef JAPAN if (!param_nowait) PG13 (); #endif #endif while (1) { while (!param_nowait) { // // title page // #ifndef DEMOTEST #ifdef SPEAR SDL_Color pal[256]; CA_CacheGrChunk (TITLEPALETTE); VL_ConvertPalette(grsegs[TITLEPALETTE], pal, 256); 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,pal,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; VW_FadeOut(); if(screenHeight % 200 != 0) VL_ClearScreen(0); StartCPMusic(INTROSONG); } VW_FadeOut (); #ifdef DEBUGKEYS if (Keyboard[sc_Tab] && param_debugmode) RecordDemo (); else US_ControlPanel (0); #else US_ControlPanel (0); #endif if (startgame || loadedgame) { GameLoop (); if(!param_nowait) { VW_FadeOut(); StartCPMusic(INTROSONG); } } } } //=========================================================================== #define IFARG(str) if(!strcmp(arg, (str))) void CheckParameters(int argc, char *argv[]) { bool hasError = false, showHelp = false; bool sampleRateGiven = false, audioBufferGiven = false; int defaultSampleRate = param_samplerate; for(int i = 1; i < argc; i++) { char *arg = argv[i]; #ifndef SPEAR IFARG("--goobers") #else IFARG("--debugmode") #endif param_debugmode = true; else IFARG("--baby") param_difficulty = 0; else IFARG("--easy") param_difficulty = 1; else IFARG("--normal") param_difficulty = 2; else IFARG("--hard") param_difficulty = 3; else IFARG("--nowait") param_nowait = true; else IFARG("--tedlevel") { if(++i >= argc) { printf("The tedlevel option is missing the level argument!\n"); hasError = true; } else param_tedlevel = atoi(argv[i]); } else IFARG("--windowed") fullscreen = false; else IFARG("--windowed-mouse") { fullscreen = false; forcegrabmouse = true; } else IFARG("--res") { if(i + 2 >= argc) { printf("The res option needs the width and/or the height argument!\n"); hasError = true; } else { screenWidth = atoi(argv[++i]); screenHeight = atoi(argv[++i]); unsigned factor = screenWidth / 320; if(screenWidth % 320 || screenHeight != 200 * factor && screenHeight != 240 * factor) printf("Screen size must be a multiple of 320x200 or 320x240!\n"), hasError = true; } } else IFARG("--resf") { if(i + 2 >= argc) { printf("The resf option needs the width and/or the height argument!\n"); hasError = true; } else { screenWidth = atoi(argv[++i]); screenHeight = atoi(argv[++i]); if(screenWidth < 320) printf("Screen width must be at least 320!\n"), hasError = true; if(screenHeight < 200) printf("Screen height must be at least 200!\n"), hasError = true; } } else IFARG("--bits") { if(++i >= argc) { printf("The bits option is missing the color depth argument!\n"); hasError = true; } else { screenBits = atoi(argv[i]); switch(screenBits) { case 8: case 16: case 24: case 32: break; default: printf("Screen color depth must be 8, 16, 24, or 32!\n"); hasError = true; break; } } } else IFARG("--nodblbuf") usedoublebuffering = false; else IFARG("--extravbls") { if(++i >= argc) { printf("The extravbls option is missing the vbls argument!\n"); hasError = true; } else { extravbls = atoi(argv[i]); if(extravbls < 0) { printf("Extravbls must be positive!\n"); hasError = true; } } } else IFARG("--joystick") { if(++i >= argc) { printf("The joystick option is missing the index argument!\n"); hasError = true; } else param_joystickindex = atoi(argv[i]); // index is checked in InitGame } else IFARG("--joystickhat") { if(++i >= argc) { printf("The joystickhat option is missing the index argument!\n"); hasError = true; } else param_joystickhat = atoi(argv[i]); } else IFARG("--samplerate") { if(++i >= argc) { printf("The samplerate option is missing the rate argument!\n"); hasError = true; } else param_samplerate = atoi(argv[i]); sampleRateGiven = true; } else IFARG("--audiobuffer") { if(++i >= argc) { printf("The audiobuffer option is missing the size argument!\n"); hasError = true; } else param_audiobuffer = atoi(argv[i]); audioBufferGiven = true; } else IFARG("--mission") { if(++i >= argc) { printf("The mission option is missing the mission argument!\n"); hasError = true; } else { param_mission = atoi(argv[i]); if(param_mission < 0 || param_mission > 3) { printf("The mission option must be between 0 and 3!\n"); hasError = true; } } } else IFARG("--configdir") { if(++i >= argc) { printf("The configdir option is missing the dir argument!\n"); hasError = true; } else { size_t len = strlen(argv[i]); if(len + 2 > sizeof(configdir)) { printf("The config directory is too long!\n"); hasError = true; } else { strcpy(configdir, argv[i]); if(argv[i][len] != '/' && argv[i][len] != '\\') strcat(configdir, "/"); } } } else IFARG("--goodtimes") param_goodtimes = true; else IFARG("--ignorenumchunks") param_ignorenumchunks = true; else IFARG("--help") showHelp = true; else hasError = true; } if(hasError || showHelp) { if(hasError) printf("\n"); printf( "Wolf4SDL v1.7 ($Revision: 256 $)\n" "Ported by Chaos-Software (http://www.chaos-software.de.vu)\n" "Original Wolfenstein 3D by id Software\n\n" "Usage: Wolf4SDL [options]\n" "Options:\n" " --help This help page\n" " --tedlevel Starts the game in the given level\n" " --baby Sets the difficulty to baby for tedlevel\n" " --easy Sets the difficulty to easy for tedlevel\n" " --normal Sets the difficulty to normal for tedlevel\n" " --hard Sets the difficulty to hard for tedlevel\n" " --nowait Skips intro screens\n" " --windowed[-mouse] Starts the game in a window [and grabs mouse]\n" " --res Sets the screen resolution\n" " (must be multiple of 320x200 or 320x240)\n" " --resf Sets any screen resolution >= 320x200\n" " (which may result in graphic errors)\n" " --bits Sets the screen color depth\n" " (use this when you have palette/fading problems\n" " allowed: 8, 16, 24, 32, default: \"best\" depth)\n" " --nodblbuf Don't use SDL's double buffering\n" " --extravbls Sets a delay after each frame, which may help to\n" " reduce flickering (unit is currently 8 ms, default: 0)\n" " --joystick Use the index-th joystick if available\n" " (-1 to disable joystick, default: 0)\n" " --joystickhat Enables movement with the given coolie hat\n" " --samplerate Sets the sound sample rate (given in Hz, default: %i)\n" " --audiobuffer Sets the size of the audio buffer (-> sound latency)\n" " (given in bytes, default: 2048 / (44100 / samplerate))\n" " --ignorenumchunks Ignores the number of chunks in VGAHEAD.*\n" " (may be useful for some broken mods)\n" " --configdir Directory where config file and save games are stored\n" " (default: $HOME/.wolf4sdl)\n" #if defined(SPEAR) && !defined(SPEARDEMO) " --mission Mission number to play (0-3)\n" " (default: 0 -> .sod, 1-3 -> .sd*)\n" " --goodtimes Disable copy protection quiz\n" #endif , defaultSampleRate ); exit(1); } if(sampleRateGiven && !audioBufferGiven) param_audiobuffer = 2048 / (44100 / param_samplerate); } /* ========================== = = main = ========================== */ #define main my_main int main (int argc, char *argv[]) { #if defined(_arch_dreamcast) DC_Init(); #else CheckParameters(argc, argv); #endif CheckForEpisodes(); InitGame(); DemoLoop(); Quit("Demo loop exited???"); return 1; }