// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // DOOM main program (D_DoomMain) and game loop (D_DoomLoop), // plus functions to determine game mode (shareware, registered), // parse command line parameters, configure game parameters (turbo), // and call the startup functions. // //----------------------------------------------------------------------------- #define BGCOLOR 7 #define FGCOLOR 8 #include "m_alloc.h" #include "doomdef.h" #include "doomstat.h" #include "dstrings.h" #include "sounds.h" #include "z_zone.h" #include "w_wad.h" #include "s_sound.h" #include "v_video.h" #include "f_finale.h" #include "f_wipe.h" #include "m_argv.h" #include "m_misc.h" #include "m_menu.h" #include "c_consol.h" #include "c_cmds.h" #include "c_dispch.h" #include "i_system.h" #include "i_sound.h" #include "i_video.h" #include "g_game.h" #include "hu_stuff.h" #include "wi_stuff.h" #include "st_stuff.h" #include "am_map.h" #include "p_setup.h" #include "r_local.h" #include "r_sky.h" #include "d_main.h" #include "d_dehack.h" #include "cmdlib.h" cvar_t *fraglimit; cvar_t *timelimit; cvar_t *turbo; extern void TurboCallback (cvar_t *); // // D-DoomLoop() // Not a globally visible function, // just included for source reference, // called by D_DoomMain, never exits. // Manages timing and IO, // calls all ?_Responder, ?_Ticker, and ?_Drawer, // calls I_GetTime, I_StartFrame, and I_StartTic // void D_DoomLoop (void); char* wadfiles[MAXWADFILES]; BOOL devparm; // started game with -devparm BOOL DrawNewHUD; // [RH] Draw the new HUD? BOOL drone; BOOL singletics = false; // debug flag to cancel adaptiveness //extern int soundVolume; //extern int sfxVolume; //extern int musicVolume; extern BOOL inhelpscreens; char startmap[8]; BOOL autostart; FILE* debugfile; BOOL advancedemo; char wadfile[1024]; // primary wad file void D_CheckNetGame (void); void D_ProcessEvents (void); void G_BuildTiccmd (ticcmd_t* cmd); void D_DoAdvanceDemo (void); // // EVENT HANDLING // // Events are asynchronous inputs generally generated by the game user. // Events can be discarded if no responder claims them // event_t events[MAXEVENTS]; int eventhead; int eventtail; // // D_PostEvent // Called by the I/O functions when input is detected // void D_PostEvent (const event_t* ev) { events[eventhead] = *ev; eventhead = (++eventhead)&(MAXEVENTS-1); } // // D_ProcessEvents // Send all the events of the given timestamp down the responder chain // // [RH] Stuff for screenmode testing extern int testingmode; extern void M_RestoreMode (void); void D_ProcessEvents (void) { event_t* ev; // IF STORE DEMO, DO NOT ACCEPT INPUT if ( ( gamemode == commercial ) && (W_CheckNumForName("map01")<0) ) return; // [RH] If testing mode, do not accept input until test is over if (testingmode) { if (testingmode <= I_GetTime()) { M_RestoreMode (); } return; } for ( ; eventtail != eventhead ; eventtail = (++eventtail)&(MAXEVENTS-1) ) { ev = &events[eventtail]; if (C_Responder (ev)) continue; // console ate the event if (M_Responder (ev)) continue; // menu ate the event G_Responder (ev); } } // [RH] Each time dmflags is changed, this function is called and // transforms it into an integer so that we don't need to make // the conversion each time we check its value. void DMFlagsCallback (cvar_t *var) { dmflags = (int)var->value; // In case DF_NO_FREELOOK was changed, reinitialize the sky // map. (If no freelook, then no need to stretch the sky.) if (textureheight) R_InitSkyMap (r_stretchsky); if (dmflags & DF_NO_FREELOOK) AddCommandString ("centerview"); } // // D_Display // draw current display, possibly wiping it from the previous // // wipegamestate can be set to -1 to force a wipe on the next draw gamestate_t wipegamestate = GS_DEMOSCREEN; extern BOOL setsizeneeded, setmodeneeded; extern int NewWidth, NewHeight, NewBpp; extern cvar_t *st_scale; void R_ExecuteSetViewSize (void); void D_Display (void) { static BOOL viewactivestate = false; static BOOL menuactivestate = false; static BOOL menuwasactive = false; static BOOL inhelpscreensstate = false; static BOOL fullscreen = false; static gamestate_t oldgamestate = -1; static int borderdrawcount; int nowtime; int tics; int wipestart; int y; BOOL done; BOOL wipe; BOOL redrawsbar; if (nodrawers) return; // for comparative timing / profiling redrawsbar = false; if (!menuwasactive && menuactive) menuwasactive = true; // [RH] change the screen mode if needed if (setmodeneeded) { int oldwidth = screens[0].width; int oldheight = screens[0].height; int oldbpp = screens[0].Bpp << 3; // Change screen mode. if (!V_SetResolution (NewWidth, NewHeight, NewBpp)) if (!V_SetResolution (oldwidth, oldheight, oldbpp)) I_FatalError ("Could not change screen mode"); // Recalculate various view parameters. setsizeneeded = true; // Trick status bar into rethinking its position :-) SetCVarFloat (st_scale, st_scale->value); // Redraw status bar. redrawsbar = true; // Refresh the console. C_NewModeAdjust (); // Fill the back screen. //R_FillBackScreen (); } // change the view size if needed if (setsizeneeded) { R_ExecuteSetViewSize (); oldgamestate = -1; // force background redraw borderdrawcount = 3; if (setmodeneeded) { setmodeneeded = false; R_FillBackScreen (); } } I_BeginUpdate (); // save the current screen if about to wipe if (gamestate != wipegamestate) { wipe = true; wipe_StartScreen(0, 0, screens[0].width, screens[0].height); } else wipe = false; if (gamestate == GS_LEVEL && gametic) { HU_Erase(); } // do buffered drawing switch (gamestate) { case GS_LEVEL: if (!gametic) break; if (wipe || (realviewheight != screens[0].height && fullscreen) || menuwasactive) { if (!menuactive) menuwasactive = false; redrawsbar = true; } if (inhelpscreensstate && !inhelpscreens) redrawsbar = true; // just put away the help screen ST_Drawer (realviewheight == screens[0].height, redrawsbar ); fullscreen = realviewheight == screens[0].height; break; case GS_INTERMISSION: WI_Drawer (); break; case GS_FINALE: F_Drawer (); break; case GS_DEMOSCREEN: D_PageDrawer (); break; } // draw buffered stuff to screen I_UpdateNoBlit (); // draw the view directly if (gamestate == GS_LEVEL && (!automapactive || viewactive) && gametic) { R_RenderPlayerView (&players[displayplayer]); } if (gamestate == GS_LEVEL && DrawNewHUD && viewactive) { ST_newDraw (); } if (automapactive) { AM_Drawer (); } if (gamestate == GS_LEVEL && gametic) { HU_Drawer (); } if (gamestate == GS_LEVEL) C_DrawMid (); // clean up border stuff if (gamestate != oldgamestate && gamestate != GS_LEVEL) V_SetBlend (0,0,0,0); // see if the border needs to be initially drawn if (gamestate == GS_LEVEL && oldgamestate != GS_LEVEL) { viewactivestate = false; // view was not active R_FillBackScreen (); // draw the pattern into the back screen } // see if the border needs to be updated to the screen if (gamestate == GS_LEVEL && (!automapactive || viewactive)) { if (menuactive || menuactivestate || !viewactivestate) borderdrawcount = 3; if (borderdrawcount) { R_DrawViewBorder (); // erase old menu stuff borderdrawcount--; } } menuactivestate = menuactive; viewactivestate = viewactive; inhelpscreensstate = inhelpscreens; oldgamestate = wipegamestate = gamestate; // [RH] Refresh the border here if the menu is active // since it might be dimming the background. if (menuactive && viewactive) R_DrawViewBorder (); // draw pause pic if (paused) { patch_t *pause = W_CacheLumpName ("M_PAUSE", PU_CACHE); if (automapactive && !viewactive) y = 4; else y = viewwindowy+4; V_DrawPatchCleanNoMove((screens[0].width-(pause->width)*CleanXfac)/2,y,&screens[0],pause); } C_DrawConsole (); // draw console // menus go directly to the screen M_Drawer (); // menu is drawn even on top of everything NetUpdate (); // send out any new accumulation // normal update if (!wipe) { I_FinishUpdate (); // page flip or blit buffer return; } // wipe update wipe_EndScreen(0, 0, screens[0].width, screens[0].height); wipestart = I_GetTime () - 1; I_FinishUpdate (); do { do { nowtime = I_GetTime (); tics = nowtime - wipestart; } while (!tics); wipestart = nowtime; I_BeginUpdate (); done = wipe_ScreenWipe(wipe_Melt , 0, 0, screens[0].width, screens[0].height, tics); I_UpdateNoBlit (); C_DrawConsole (); M_Drawer (); // menu is drawn even on top of wipes I_FinishUpdate (); // page flip or blit buffer } while (!done); } // // D_DoomLoop // extern BOOL demorecording; void D_DoomLoop (void) { if (demorecording) G_BeginRecording (); if (M_CheckParm ("-debugfile")) { char filename[20]; sprintf (filename,"debug%i.txt",consoleplayer); Printf ("debug output to: %s\n",filename); debugfile = fopen (filename,"w"); } I_InitGraphics (); C_InitConsole (screens[0].width, screens[0].height, true); InitItems (); // [RH] Lock any cvars that should be locked now that we're // about to begin the game. C_EnableNoSet (); // [RH] Now that all game subsystems have been initialized, // do all commands on the command line other than +set C_ExecCmdLineParams (false); while (1) { // frame syncronous IO operations I_StartFrame (); // process one or more tics if (singletics) { I_StartTic (); D_ProcessEvents (); G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]); if (advancedemo) D_DoAdvanceDemo (); C_Ticker (); M_Ticker (); G_Ticker (); gametic++; maketic++; Net_NewMakeTic (); } else { TryRunTics (); // will run at least one tic } // [RH] Use displayplayer rather than console player S_UpdateSounds (players[displayplayer].mo);// move positional sounds // Update display, next frame, with current state. D_Display (); // Sound mixing for the buffer is snychronous. I_UpdateSound(); } } // // DEMO LOOP // int demosequence; int pagetic; char *pagename; // // D_PageTicker // Handles timing for warped projection // void D_PageTicker (void) { if (--pagetic < 0) D_AdvanceDemo (); } // // D_PageDrawer // void D_PageDrawer (void) { V_DrawPatchIndirect (0,0, &screens[0], W_CacheLumpName(pagename, PU_CACHE)); } // // D_AdvanceDemo // Called after each demo or intro demosequence finishes // void D_AdvanceDemo (void) { advancedemo = true; } // // This cycles through the demo sequences. // FIXME - version dependend demo numbers? // void D_DoAdvanceDemo (void) { players[consoleplayer].playerstate = PST_LIVE; // not reborn advancedemo = false; usergame = false; // no save / end game here paused = false; gameaction = ga_nothing; if ( gamemode == retail ) demosequence = (demosequence+1)%7; else demosequence = (demosequence+1)%6; switch (demosequence) { case 0: if ( gamemode == commercial ) pagetic = TICRATE * 11; else pagetic = TICRATE * 5; gamestate = GS_DEMOSCREEN; pagename = "TITLEPIC"; if ( gamemode == commercial ) S_StartMusic("d_dm2ttl"); else S_StartMusic ("d_intro"); break; case 1: G_DeferedPlayDemo ("demo1"); break; case 2: pagetic = 200; gamestate = GS_DEMOSCREEN; pagename = "CREDIT"; break; case 3: G_DeferedPlayDemo ("demo2"); break; case 4: gamestate = GS_DEMOSCREEN; if ( gamemode == commercial) { pagetic = TICRATE * 11; pagename = "TITLEPIC"; S_StartMusic("d_dm2ttl"); } else { pagetic = 200; if ( gamemode == retail ) pagename = "CREDIT"; else pagename = "HELP2"; } break; case 5: G_DeferedPlayDemo ("demo3"); break; // THE DEFINITIVE DOOM Special Edition demo case 6: G_DeferedPlayDemo ("demo4"); break; } } // // D_StartTitle // void D_StartTitle (void) { gameaction = ga_nothing; demosequence = -1; D_AdvanceDemo (); } // print title for every printed line char title[128]; // // D_AddFile // void D_AddFile (char *file) { int numwadfiles; for (numwadfiles = 0 ; wadfiles[numwadfiles] ; numwadfiles++) ; wadfiles[numwadfiles] = copystring (file); } // // IdentifyVersion // Checks availability of IWAD files by name, // to determine whether registered/commercial features // should be executed (notably loading PWAD's). // void IdentifyVersion (void) { char* doom1wad; char* doomwad; char* doom2wad; char* doom2fwad; char* plutoniawad; char* tntwad; char* custwad; char* doomwaddir; char* home; char iwad[64]; char* iwadfull = NULL; int iwadindex; doomwaddir = home = progdir; // Commercial. doom2wad = Malloc(strlen(doomwaddir)+9+1); sprintf(doom2wad, "%sdoom2.wad", doomwaddir); // Registered. doomwad = Malloc(strlen(doomwaddir)+8+1); sprintf(doomwad, "%sdoom.wad", doomwaddir); // Shareware. doom1wad = Malloc(strlen(doomwaddir)+9+1); sprintf(doom1wad, "%sdoom1.wad", doomwaddir); // Bug, dear Shawn. // Insufficient malloc, caused spurious realloc errors. plutoniawad = Malloc(strlen(doomwaddir)+/*9*/12+1); sprintf(plutoniawad, "%splutonia.wad", doomwaddir); tntwad = Malloc(strlen(doomwaddir)+9+1); sprintf(tntwad, "%stnt.wad", doomwaddir); // French stuff. doom2fwad = Malloc(strlen(doomwaddir)+10+1); sprintf(doom2fwad, "%sdoom2f.wad", doomwaddir); if (FileExists (doom2fwad)) { iwadfull = doom2fwad; } else if (FileExists (doom2wad)) { iwadfull = doom2wad; } else if (FileExists (plutoniawad)) { iwadfull = plutoniawad; } else if (FileExists (tntwad)) { iwadfull = tntwad; } else if (FileExists (doomwad)) { iwadfull = doomwad; } else if (FileExists (doom1wad)) { iwadfull = doom1wad; } iwadindex = M_CheckParm ("-iwad"); if (iwadindex && iwadindex < myargc - 1) { iwadindex++; custwad = Malloc(strlen(myargv[iwadindex]) + 5); strcpy (custwad, myargv[iwadindex]); DefaultExtension (custwad, ".wad"); if (FileExists (custwad)) { iwadfull = custwad; } } if (iwadfull) ExtractFileBase (iwadfull, iwad); else iwad[0] = 0; if (stricmp (iwad, "doom2f") == 0) { gamemode = commercial; gamemission = doom2; // C'est ridicule! // Let's handle languages in config files, okay? language = french; Printf("French version\n"); } else if (stricmp (iwad, "doom2") == 0) { gamemode = commercial; gamemission = doom2; } else if (stricmp (iwad, "plutonia") == 0) { gamemode = commercial; gamemission = pack_plut; } else if (stricmp (iwad, "tnt") == 0) { gamemode = commercial; gamemission = pack_tnt; } else if (stricmp (iwad, "doom") == 0) { // Retail checking is handled later gamemode = registered; gamemission = doom; } else if (stricmp (iwad, "doom1") == 0) { gamemode = shareware; gamemission = doom; } else { Printf("Game mode indeterminate.\n"); gamemode = indetermined; } if (gamemode != indetermined) { D_AddFile (iwadfull); } } // // Find a Response File // void FindResponseFile (void) { int i; #define MAXARGVS 100 for (i = 1;i < myargc;i++) if (myargv[i][0] == '@') { FILE * handle; int size; int k; int index; int indexinfile; char *infile; char *file; char *moreargs[20]; char *firstargv; // READ THE RESPONSE FILE INTO MEMORY handle = fopen (&myargv[i][1],"rb"); if (!handle) { Printf ("\nNo such response file!"); exit(1); } Printf("Found response file %s!\n",&myargv[i][1]); fseek (handle,0,SEEK_END); size = ftell(handle); fseek (handle,0,SEEK_SET); file = Malloc (size); fread (file,size,1,handle); fclose (handle); // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG for (index = 0,k = i+1; k < myargc; k++) moreargs[index++] = myargv[k]; firstargv = myargv[0]; myargv = Malloc(sizeof(char *)*MAXARGVS); memset(myargv,0,sizeof(char *)*MAXARGVS); myargv[0] = firstargv; infile = file; indexinfile = k = 0; indexinfile++; // SKIP PAST ARGV[0] (KEEP IT) do { myargv[indexinfile++] = infile+k; while(k < size && ((*(infile+k)>= ' '+1) && (*(infile+k)<='z'))) k++; *(infile+k) = 0; while(k < size && ((*(infile+k)<= ' ') || (*(infile+k)>'z'))) k++; } while(k < size); for (k = 0;k < index;k++) myargv[indexinfile++] = moreargs[k]; myargc = indexinfile; // DISPLAY ARGS Printf("%d command-line args:\n",myargc); for (k=1;kvalue < 0.25) { SetCVarFloat (var, 0.25); } else if (var->value > 1) { SetCVarFloat (var, 1); } else { floop = ((int)(var->value * 4) << MF_TRANSLUCSHIFT) & MF_TRANSLUCBITS; mobjinfo[MT_SKULL].flags = (mobjinfo[MT_SKULL].flags & ~MF_TRANSLUCBITS) | floop; // Find all the lost souls in the world and change them, also. currentthinker = thinkercap.next; if (!currentthinker) return; while (currentthinker != &thinkercap) { if ( (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) && ((mobj_t *)currentthinker)->type == MT_SKULL ) ((mobj_t *)currentthinker)->flags = (((mobj_t *)currentthinker)->flags & ~MF_TRANSLUCBITS) | floop; currentthinker = currentthinker->next; } } } // // D_DoomMain // void D_DoomMain (void) { int p, flags; char file[256]; SetProgDir (); C_InstallCommands (); // [RH] Set default cvar values. These will // be overridden by the configfile. C_SetCVars (); { cvar_t *var = cvar ("transsouls", "0.75", CVAR_ARCHIVE|CVAR_CALLBACK); var->u.callback = TransSoulsCallback; } FindResponseFile (); { // [RH] Make sure zdoom.wad is always loaded, since // it contains stuff we need. char *zdoomwad; zdoomwad = Malloc (strlen (progdir) + 10); sprintf (zdoomwad, "%szdoom.wad", progdir); D_AddFile (zdoomwad); } IdentifyVersion (); modifiedgame = false; flags = (int)dmflagsvar->value; dmflagsvar->u.callback = DMFlagsCallback; if (M_CheckParm ("-nomonsters")) flags |= DF_NO_MONSTERS; if (M_CheckParm ("-respawn")) flags |= DF_MONSTERS_RESPAWN; if (M_CheckParm ("-fast")) flags |= DF_FAST_MONSTERS; devparm = M_CheckParm ("-devparm"); if (M_CheckParm ("-altdeath")) { SetCVarFloat (deathmatch, 1.0f); flags |= DF_ITEMS_RESPAWN; } else if (M_CheckParm ("-deathmatch")) { SetCVarFloat (deathmatch, 1.0f); flags |= DF_WEAPONS_STAY; } SetCVarFloat (dmflagsvar, (float)flags); switch (gamemode) { case shareware: I_SetTitleString ("DOOM Shareware Startup"); break; case registered: I_SetTitleString ("DOOM Registered Startup"); break; case commercial: switch (gamemission) { case doom2: I_SetTitleString ("DOOM 2: Hell on Earth"); break; case pack_plut: I_SetTitleString ("DOOM 2: Plutonia Experiment"); break; case pack_tnt: I_SetTitleString ("DOOM 2: TNT - Evilution"); break; case doom: case none: break; } break; default: I_SetTitleString ("Public DOOM -"); break; } if (devparm) Printf(D_DEVSTR); if (M_CheckParm("-cdrom")) { Printf(D_CDROM); } // turbo option // [RH] (Also exists as a cvar now.) { cvar_t *turbo = cvar ("turbo", "0", CVAR_CALLBACK); float tval; turbo->u.callback = TurboCallback; if ( (p=M_CheckParm ("-turbo")) ) { if (p < myargc - 1) tval = (float)atof (myargv[p+1]); else tval = 200.0f; Printf ("turbo scale: %g%%\n", tval); } else { tval = 100.0f; } SetCVarFloat (turbo, tval); } p = M_CheckParm ("-file"); if (p) { // the parms after p are wadfile/lump names, // until end of parms or another - preceded parm modifiedgame = true; // homebrew levels while (++p != myargc && myargv[p][0] != '-' && myargv[p][0] != '+') D_AddFile (myargv[p]); } if (!(p = M_CheckParm ("-playdemo")) ) if (!(p = M_CheckParm ("-timedemo")) ) { if ( (p = M_CheckParm ("-fastdemo")) ) fastdemo = true; } if (p && p < myargc-1) { strcpy (file, myargv[p+1]); DefaultExtension (file, ".lmp"); D_AddFile (file); Printf("Playing demo %s.\n", file); } // get skill / episode / map from parms if (gamemode == commercial) strcpy (startmap, "MAP01"); else strcpy (startmap, "E1M1"); autostart = false; p = M_CheckParm ("-skill"); if (p && p < myargc-1) { SetCVarFloat (gameskill, (float)(myargv[p+1][0]-'1')); autostart = true; } p = M_CheckParm ("-timer"); if (p && p < myargc-1) { int time = atoi(myargv[p+1]); Printf("Levels will end after %d minute",time); if (time > 1) Printf("s"); Printf(".\n"); SetCVarFloat (timelimit, (float)time); } p = M_CheckParm ("-avg"); if (p && p < myargc-1) { Printf("Austin Virtual Gaming: Levels will end after 20 minutes\n"); SetCVarFloat (timelimit, 20); } p = M_CheckParm ("-warp"); if (p && p < myargc-1) { int ep, map; if (gamemode == commercial) { ep = 1; map = atoi (myargv[p+1]); } else { ep = myargv[p+1][0]-'0'; map = myargv[p+2][0]-'0'; } strncpy (startmap, CalcMapName (ep, map), 8); autostart = true; } // [RH] Hack to handle +map p = M_CheckParm ("+map"); if (p && p < myargc-1) { strncpy (startmap, myargv[p+1], 8); myargv[p][0] = '-'; autostart = true; } // init subsystems Printf ("M_LoadDefaults: Load system defaults.\n"); M_LoadDefaults (); // load before initing other systems // [RH] do all +set commands on the command line C_ExecCmdLineParams (true); Printf ("Z_Init: Init zone memory allocation daemon. \n"); Z_Init (); Printf ("W_Init: Init WADfiles.\n"); W_InitMultipleFiles (wadfiles); // [RH] Load foreign language strings D_InitStrings (); // [RH] Apply any DeHackEd patch { int hack; hack = M_CheckParm ("-deh"); if (hack && hack < myargc - 1) DoDehPatch (myargv[hack + 1]); else DoDehPatch (NULL); // See if there's a patch in a PWAD } // [RH] Now that all text strings are set up, // insert them into the level and cluster data. G_SetLevelStrings (); // [RH] Parse through all loaded mapinfo lumps G_ParseMapInfo (); // [RH] Check for retail game if (gamemode == registered) { if (W_CheckNumForName ("e4m1") != -1) { gamemode = retail; I_SetTitleString ("The Ultimate DOOM Startup"); } } // Check for -file in shareware if (modifiedgame) { // These are the lumps that will be checked in IWAD, // if any one is not present, execution will be aborted. char name[23][8]= { "e2m1","e2m2","e2m3","e2m4","e2m5","e2m6","e2m7","e2m8","e2m9", "e3m1","e3m3","e3m3","e3m4","e3m5","e3m6","e3m7","e3m8","e3m9", "dphoof","bfgga0","heada1","cybra1","spida1d1" }; int i; if (gamemode == shareware) I_Error("\nYou cannot -file with the shareware " "version. Register!"); // Check for fake IWAD with right name, // but w/o all the lumps of the registered version. if (gamemode == registered || gamemode == retail) for (i = 0;i < 23; i++) if (W_CheckNumForName(name[i])<0) I_Error("\nThis is not the registered version."); } // Iff additonal PWAD files are used, print modified banner if (modifiedgame) { /*m*/Printf ( "===========================================================================\n" "ATTENTION: This version of DOOM has been modified. If you would like to\n" "get a copy of the original game, call 1-800-IDGAMES or see the readme file.\n" " You will not receive technical support for modified games.\n" "===========================================================================\n" ); } // Check and print which version is executed. switch ( gamemode ) { case shareware: case indetermined: Printf ( "===========================================================================\n" " Shareware!\n" "===========================================================================\n" ); break; case registered: case retail: case commercial: Printf ( "===========================================================================\n" " Commercial product - do not distribute!\n" " Please report software piracy to the SPA: 1-800-388-PIR8\n" "===========================================================================\n" ); break; default: // Ouch. break; } Printf ("\nI_StartGraphics: Determine display hardware.\n"); I_StartGraphics (); Printf ("V_Init: allocate screens.\n"); V_Init (); Printf ("M_Init: Init miscellaneous info.\n"); M_Init (); Printf ("R_Init: Init DOOM refresh daemon - "); R_Init (); Printf ("\nP_Init: Init Playloop state.\n"); P_Init (); Printf ("I_Init: Setting up machine state.\n"); I_Init (); Printf ("D_CheckNetGame: Checking network game status.\n"); D_CheckNetGame (); Printf ("S_Init: Setting up sound.\n"); S_Init ((int)snd_SfxVolume->value /* *8 */, snd_MusicVolume->value /* *8*/ ); Printf ("HU_Init: Setting up heads up display.\n"); HU_Init (); Printf ("ST_Init: Init status bar.\n"); ST_Init (); // check for a driver that wants intermission stats p = M_CheckParm ("-statcopy"); if (p && p