From 3f59fc8b771625aca9c3aefe03cf1038d8461963 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sun, 7 Jul 2019 22:00:20 -0400 Subject: Wolfenstein 3-D! This is a port of Wolf4SDL, which is derived from the original id software source release. The port runs on top of the SDL plugin runtime and is loaded as an overlay. Licensing of the game code is not an issue, as discussed below (essentially, the Debian project treats Wolf4SDL as GPLv2, with an email from John Carmack backing it up): http://forums.rockbox.org/index.php?topic=52872 Included is a copy of MAME's Yamaha OPL sound chip emulator (fmopl_gpl.c). This file was not part of the original Wolf4SDL source (which includes a non-GPL'd version), but was rather rebased from from a later MAME source which had been relicensed to GPLv2. Change-Id: I64c2ba035e0be7e2f49252f40640641416613439 --- apps/plugins/sdl/progs/wolf3d/wl_main.c | 1953 +++++++++++++++++++++++++++++++ 1 file changed, 1953 insertions(+) create mode 100644 apps/plugins/sdl/progs/wolf3d/wl_main.c (limited to 'apps/plugins/sdl/progs/wolf3d/wl_main.c') diff --git a/apps/plugins/sdl/progs/wolf3d/wl_main.c b/apps/plugins/sdl/progs/wolf3d/wl_main.c new file mode 100644 index 0000000000..e78274cbac --- /dev/null +++ b/apps/plugins/sdl/progs/wolf3d/wl_main.c @@ -0,0 +1,1953 @@ +// 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 = 19; // 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 defined _WIN32 + putenv("SDL_VIDEODRIVER=directx"); +#endif + 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 (); + +#if defined _WIN32 + if(!fullscreen) + { + struct SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + + if(SDL_GetWMInfo(&wmInfo) != -1) + { + HWND hwndSDL = wmInfo.window; + DWORD style = GetWindowLong(hwndSDL, GWL_STYLE) & ~WS_SYSMENU; + SetWindowLong(hwndSDL, GWL_STYLE, style); + SetWindowPos(hwndSDL, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + } + } +#endif + + 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 + if (Keyboard[sc_Control]) + { + 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" +#if defined(_arch_dreamcast) || defined(_WIN32) + " (default: current directory)\n" +#else + " (default: $HOME/.wolf4sdl)\n" +#endif +#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; +} -- cgit v1.2.3