// 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. // //----------------------------------------------------------------------------- #include "doom_config.h" #if defined(DOOM_WIN32) #define X_OK 0 #define W_OK 2 #define R_OK 4 #define RW_OK 6 #elif defined(DOOM_APPLE) #endif #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 "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 "d_main.h" #define MAXARGVS 100 char* wadfiles[MAXWADFILES]; doom_boolean devparm; // started game with -devparm doom_boolean nomonsters; // checkparm of -nomonsters doom_boolean respawnparm; // checkparm of -respawn doom_boolean fastparm; // checkparm of -fast doom_boolean drone; doom_boolean singletics = true; // debug flag to cancel adaptiveness doom_boolean is_wiping_screen = false; skill_t startskill; int startepisode; int startmap; doom_boolean autostart; void* debugfile = 0; doom_boolean advancedemo; char wadfile[1024]; // primary wad file char mapdir[1024]; // directory of development maps char basedefault[1024]; // default file // // 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; // wipegamestate can be set to -1 to force a wipe on the next draw gamestate_t wipegamestate = GS_DEMOSCREEN; void R_ExecuteSetViewSize(void); // print title for every printed line char title[128]; extern doom_boolean inhelpscreens; extern doom_boolean setsizeneeded; extern int showMessages; extern doom_boolean demorecording; void D_DoomLoop(void); void D_CheckNetGame(void); void D_ProcessEvents(void); void G_BuildTiccmd(ticcmd_t* cmd); void D_DoAdvanceDemo(void); // // D_PostEvent // Called by the I/O functions when input is detected // void D_PostEvent(event_t* ev) { events[eventhead] = *ev; eventhead++; eventhead = (eventhead) & (MAXEVENTS - 1); } // // D_ProcessEvents // Send all the events of the given timestamp down the responder chain // void D_ProcessEvents(void) { event_t* ev; // IF STORE DEMO, DO NOT ACCEPT INPUT if ((gamemode == commercial) && (W_CheckNumForName("map01") < 0)) return; for (; eventtail != eventhead; ) { ev = &events[eventtail]; if (!M_Responder(ev)) G_Responder(ev); // else menu ate the event eventtail++; eventtail = (eventtail) & (MAXEVENTS - 1); } } // // D_Display // draw current display, possibly wiping it from the previous // void D_Display(void) { static doom_boolean viewactivestate = false; static doom_boolean menuactivestate = false; static doom_boolean inhelpscreensstate = false; static doom_boolean fullscreen = false; static gamestate_t oldgamestate = -1; static int borderdrawcount; int wipestart; int y; doom_boolean wipe; doom_boolean redrawsbar; if (nodrawers) return; // for comparative timing / profiling redrawsbar = false; // change the view size if needed if (setsizeneeded) { R_ExecuteSetViewSize(); oldgamestate = -1; // force background redraw borderdrawcount = 3; } // save the current screen if about to wipe if (gamestate != wipegamestate) { wipe = true; wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); } else wipe = false; if (gamestate == GS_LEVEL && gametic) HU_Erase(); // do buffered drawing switch (gamestate) { case GS_LEVEL: if (!gametic) break; if (automapactive) AM_Drawer(); if (wipe || (viewheight != 200 && fullscreen)) redrawsbar = true; if (inhelpscreensstate && !inhelpscreens) redrawsbar = true; // just put away the help screen ST_Drawer(viewheight == 200, redrawsbar); fullscreen = viewheight == 200; 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 && gametic) R_RenderPlayerView(&players[displayplayer]); if (gamestate == GS_LEVEL && gametic) HU_Drawer(); // clean up border stuff if (gamestate != oldgamestate && gamestate != GS_LEVEL) I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE)); // 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 && scaledviewwidth != 320) { if (menuactive || menuactivestate || !viewactivestate) borderdrawcount = 3; if (borderdrawcount) { R_DrawViewBorder(); // erase old menu stuff borderdrawcount--; } } menuactivestate = menuactive; viewactivestate = viewactive; inhelpscreensstate = inhelpscreens; oldgamestate = wipegamestate = gamestate; // draw pause pic if (paused) { if (automapactive) y = 4; else y = viewwindowy + 4; V_DrawPatchDirect(viewwindowx + (scaledviewwidth - 68) / 2, y, 0, W_CacheLumpName("M_PAUSE", PU_CACHE)); } // menus go directly to the screen M_Drawer(); // menu is drawn even on top of everything NetUpdate(); // send out any new accumulation // normal update is_wiping_screen = wipe; if (!wipe) { I_FinishUpdate(); // page flip or blit buffer return; } // wipe update wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); wipestart = I_GetTime() - 1; #if 0 // [pd] Moved to D_UpdateWipe do { do { nowtime = I_GetTime(); tics = nowtime - wipestart; } while (!tics); wipestart = nowtime; done = wipe_ScreenWipe(wipe_Melt , 0, 0, SCREENWIDTH, SCREENHEIGHT, tics); I_UpdateNoBlit(); M_Drawer(); // menu is drawn even on top of wipes I_FinishUpdate(); // page flip or blit buffer } while (!done); #endif } // // D_DoomLoop // void D_UpdateWipe(void) { if (wipe_ScreenWipe(wipe_Melt, 0, 0, SCREENWIDTH, SCREENHEIGHT, 1)) is_wiping_screen = false; } void D_DoomLoop(void) { #if 0 // [pd] Moved to D_DoomMain() if (demorecording) G_BeginRecording(); if (M_CheckParm("-debugfile")) { char filename[20]; //doom_sprintf(filename, "debug%i.txt", consoleplayer); doom_print("debug output to: %s\n", filename); debugfile = doom_open(filename, "w"); } I_InitGraphics(); #endif // 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(); M_Ticker(); G_Ticker(); gametic++; maketic++; } else { TryRunTics(); // will run at least one tic } S_UpdateSounds(players[consoleplayer].mo);// move positional sounds // Update display, next frame, with current state. D_Display(); #if 0 // [pd] Sound is queried by the application's audio thread. // Sound mixing for the buffer is snychronous. I_UpdateSound(); // Synchronous sound output is explicitly called. // Update sound output. I_SubmitSound(); #endif } } // // 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_DrawPatch(0, 0, 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 = 35 * 11; else pagetic = 170; gamestate = GS_DEMOSCREEN; pagename = "TITLEPIC"; if (gamemode == commercial) S_StartMusic(mus_dm2ttl); else S_StartMusic(mus_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 = 35 * 11; pagename = "TITLEPIC"; S_StartMusic(mus_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(); } // // D_AddFile // void D_AddFile(char* file) { int numwadfiles; char* newfile; for (numwadfiles = 0; wadfiles[numwadfiles]; numwadfiles++) ; newfile = doom_malloc(doom_strlen(file) + 1); doom_strcpy(newfile, file); wadfiles[numwadfiles] = newfile; } // // 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* doomuwad; char* doom2wad; char* doom2fwad; char* plutoniawad; char* tntwad; char* home; char* doomwaddir; doomwaddir = doom_getenv("DOOMWADDIR"); if (!doomwaddir) doomwaddir = "."; // Commercial. doom2wad = doom_malloc(doom_strlen(doomwaddir) + 1 + 9 + 1); //doom_sprintf(doom2wad, "%s/doom2.wad", doomwaddir); doom_strcpy(doom2wad, doomwaddir); doom_concat(doom2wad, "/doom2.wad"); // Retail. doomuwad = doom_malloc(doom_strlen(doomwaddir) + 1 + 8 + 1); //doom_sprintf(doomuwad, "%s/doomu.wad", doomwaddir); doom_strcpy(doomuwad, doomwaddir); doom_concat(doomuwad, "/doomu.wad"); // Registered. doomwad = doom_malloc(doom_strlen(doomwaddir) + 1 + 8 + 1); //doom_sprintf(doomwad, "%s/doom.wad", doomwaddir); doom_strcpy(doomwad, doomwaddir); doom_concat(doomwad, "/doom.wad"); // Shareware. doom1wad = doom_malloc(doom_strlen(doomwaddir) + 1 + 9 + 1); //doom_sprintf(doom1wad, "%s/doom1.wad", doomwaddir); doom_strcpy(doom1wad, doomwaddir); doom_concat(doom1wad, "/doom1.wad"); // Bug, dear Shawn. // Insufficient malloc, caused spurious realloc errors. plutoniawad = doom_malloc(doom_strlen(doomwaddir) + 1 +/*9*/12 + 1); //doom_sprintf(plutoniawad, "%s/plutonia.wad", doomwaddir); doom_strcpy(plutoniawad, doomwaddir); doom_concat(plutoniawad, "/plutonia.wad"); tntwad = doom_malloc(doom_strlen(doomwaddir) + 1 + 9 + 1); //doom_sprintf(tntwad, "%s/tnt.wad", doomwaddir); doom_strcpy(tntwad, doomwaddir); doom_concat(tntwad, "/tnt.wad"); // French stuff. doom2fwad = doom_malloc(doom_strlen(doomwaddir) + 1 + 10 + 1); //doom_sprintf(doom2fwad, "%s/doom2f.wad", doomwaddir); doom_strcpy(doom2fwad, doomwaddir); doom_concat(doom2fwad, "/doom2f.wad"); #if !defined(DOOM_WIN32) home = doom_getenv("HOME"); if (!home) I_Error("Error: Please set $HOME to your home directory"); #else home = "."; #endif //doom_sprintf(basedefault, "%s/.doomrc", home); doom_strcpy(basedefault, home); doom_concat(basedefault, "/.doomrc"); if (M_CheckParm("-shdev")) { gamemode = shareware; devparm = true; D_AddFile(DEVDATA"doom1.wad"); D_AddFile(DEVMAPS"data_se/texture1.lmp"); D_AddFile(DEVMAPS"data_se/pnames.lmp"); doom_strcpy(basedefault, DEVDATA"default.cfg"); return; } if (M_CheckParm("-regdev")) { gamemode = registered; devparm = true; D_AddFile(DEVDATA"doom.wad"); D_AddFile(DEVMAPS"data_se/texture1.lmp"); D_AddFile(DEVMAPS"data_se/texture2.lmp"); D_AddFile(DEVMAPS"data_se/pnames.lmp"); doom_strcpy(basedefault, DEVDATA"default.cfg"); return; } if (M_CheckParm("-comdev")) { gamemode = commercial; devparm = true; /* I don't bother if(plutonia) D_AddFile (DEVDATA"plutonia.wad"); else if(tnt) D_AddFile (DEVDATA"tnt.wad"); else*/ D_AddFile(DEVDATA"doom2.wad"); D_AddFile(DEVMAPS"cdata/texture1.lmp"); D_AddFile(DEVMAPS"cdata/pnames.lmp"); doom_strcpy(basedefault, DEVDATA"default.cfg"); return; } void* f; if (f = doom_open(doom2fwad, "rb")) { doom_close(f); gamemode = commercial; // C'est ridicule! // Let's handle languages in config files, okay? language = french; doom_print("French version\n"); D_AddFile(doom2fwad); return; } if (f = doom_open(doom2wad, "rb")) { doom_close(f); gamemode = commercial; D_AddFile(doom2wad); return; } if (f = doom_open(plutoniawad, "rb")) { doom_close(f); gamemode = commercial; D_AddFile(plutoniawad); return; } if (f = doom_open(tntwad, "rb")) { doom_close(f); gamemode = commercial; D_AddFile(tntwad); return; } if (f = doom_open(doomuwad, "rb")) { doom_close(f); gamemode = retail; D_AddFile(doomuwad); return; } if (f = doom_open(doomwad, "rb")) { doom_close(f); gamemode = registered; D_AddFile(doomwad); return; } if (f = doom_open(doom1wad, "rb")) { doom_close(f); gamemode = shareware; D_AddFile(doom1wad); return; } doom_print("Game mode indeterminate.\n"); gamemode = indetermined; } // // Find a Response File // void FindResponseFile(void) { int i; for (i = 1; i < myargc; i++) if (myargv[i][0] == '@') { void* handle = 0; int size; int k; int index; int indexinfile; char* infile; char* file; char* moreargs[20]; char* firstargv; // READ THE RESPONSE FILE INTO MEMORY handle = doom_open(&myargv[i][1], "rb"); if (!handle) { doom_print("\nNo such response file!"); doom_exit(1); } doom_print("Found response file %s!\n"); doom_print(&myargv[i][1]); doom_print("!\n"); doom_seek(handle, 0, DOOM_SEEK_END); size = doom_tell(handle); doom_seek(handle, 0, DOOM_SEEK_SET); file = doom_malloc(size); doom_read(handle, file, size * 1); doom_close(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 = doom_malloc(sizeof(char*) * MAXARGVS); doom_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 doom_print(doom_itoa(myargc, 10)); doom_print(" command-line args:\n"); for (k = 1; k < myargc; k++) { //doom_print("%s\n", myargv[k]); doom_print(myargv[k]); doom_print("\n"); } break; } } // // D_DoomMain // void D_DoomMain(void) { int p; char file[256]; FindResponseFile(); IdentifyVersion(); modifiedgame = false; nomonsters = M_CheckParm("-nomonsters"); respawnparm = M_CheckParm("-respawn"); fastparm = M_CheckParm("-fast"); devparm = M_CheckParm("-devparm"); if (M_CheckParm("-altdeath")) deathmatch = 2; else if (M_CheckParm("-deathmatch")) deathmatch = 1; switch (gamemode) { case retail: //doom_sprintf(title, // " " // "The Ultimate DOOM Startup v%i.%i" // " ", // VERSION / 100, VERSION % 100); doom_strcpy(title, " " "The Ultimate DOOM Startup v"); doom_concat(title, doom_itoa(VERSION / 100, 10)); doom_concat(title, "."); doom_concat(title, doom_itoa(VERSION % 100, 10)); doom_concat(title, " "); break; case shareware: //doom_sprintf(title, // " " // "DOOM Shareware Startup v%i.%i" // " ", // VERSION / 100, VERSION % 100); doom_strcpy(title, " " "DOOM Shareware Startup v"); doom_concat(title, doom_itoa(VERSION / 100, 10)); doom_concat(title, "."); doom_concat(title, doom_itoa(VERSION % 100, 10)); doom_concat(title, " "); break; case registered: //doom_sprintf(title, // " " // "DOOM Registered Startup v%i.%i" // " ", // VERSION / 100, VERSION % 100); doom_strcpy(title, " " "DOOM Registered Startup v"); doom_concat(title, doom_itoa(VERSION / 100, 10)); doom_concat(title, "."); doom_concat(title, doom_itoa(VERSION % 100, 10)); doom_concat(title, " "); break; case commercial: //doom_sprintf(title, // " " // "DOOM 2: Hell on Earth v%i.%i" // " ", // VERSION / 100, VERSION % 100); doom_strcpy(title, " " "DOOM 2: Hell on Earth v"); doom_concat(title, doom_itoa(VERSION / 100, 10)); doom_concat(title, "."); doom_concat(title, doom_itoa(VERSION % 100, 10)); doom_concat(title, " "); break; /*FIXME case pack_plut: sprintf (title, " " "DOOM 2: Plutonia Experiment v%i.%i" " ", VERSION/100,VERSION%100); break; case pack_tnt: sprintf (title, " " "DOOM 2: TNT - Evilution v%i.%i" " ", VERSION/100,VERSION%100); break; */ default: //doom_sprintf(title, // " " // "Public DOOM - v%i.%i" // " ", // VERSION / 100, VERSION % 100); doom_strcpy(title, " " "Public DOOM - v"); doom_concat(title, doom_itoa(VERSION / 100, 10)); doom_concat(title, "."); doom_concat(title, doom_itoa(VERSION % 100, 10)); doom_concat(title, " "); break; } //doom_print("%s\n", title); doom_print(title); doom_print("\n"); if (devparm) doom_print(D_DEVSTR); #if 0 // [pd] Ignore cdrom if (M_CheckParm("-cdrom")) { doom_print(D_CDROM); mkdir("c:\\doomdata", 0); doom_strcpy(basedefault, "c:/doomdata/default.cfg"); } #endif // turbo option if ((p = M_CheckParm("-turbo"))) { int scale = 200; extern int forwardmove[2]; extern int sidemove[2]; if (p < myargc - 1) scale = doom_atoi(myargv[p + 1]); if (scale < 10) scale = 10; if (scale > 400) scale = 400; //doom_print("turbo scale: %i%%\n", scale); doom_print("turbo scale: "); doom_print(doom_itoa(scale, 10)); doom_print("%%\n"); forwardmove[0] = forwardmove[0] * scale / 100; forwardmove[1] = forwardmove[1] * scale / 100; sidemove[0] = sidemove[0] * scale / 100; sidemove[1] = sidemove[1] * scale / 100; } // add any files specified on the command line with -file wadfile // to the wad list // // convenience hack to allow -wart e m to add a wad file // prepend a tilde to the filename so wadfile will be reloadable p = M_CheckParm("-wart"); if (p) { myargv[p][4] = 'p'; // big hack, change to -warp // Map name handling. switch (gamemode) { case shareware: case retail: case registered: //doom_sprintf(file, "~"DEVMAPS"E%cM%c.wad", myargv[p + 1][0], myargv[p + 2][0]); doom_strcpy(file, "~"DEVMAPS"E"); doom_concat(file, doom_ctoa(myargv[p + 1][0])); doom_concat(file, "M"); doom_concat(file, doom_ctoa(myargv[p + 2][0])); doom_concat(file, ".wad"); //doom_print("Warping to Episode %s, Map %s.\n", myargv[p + 1], myargv[p + 2]); doom_print("Warping to Episode "); doom_print(myargv[p + 1]); doom_print(", Map "); doom_print(myargv[p + 2]); doom_print(".\n"); break; case commercial: default: p = doom_atoi(myargv[p + 1]); if (p < 10) { //doom_sprintf(file, "~"DEVMAPS"cdata/map0%i.wad", p); doom_strcpy(file, "~"DEVMAPS"cdata/map0"); doom_concat(file, doom_itoa(p, 10)); doom_concat(file, ".wad"); } else { //doom_sprintf(file, "~"DEVMAPS"cdata/map%i.wad", p); doom_strcpy(file, "~"DEVMAPS"cdata/map"); doom_concat(file, doom_itoa(p, 10)); doom_concat(file, ".wad"); } break; } D_AddFile(file); } 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] != '-') D_AddFile(myargv[p]); } p = M_CheckParm("-playdemo"); if (!p) p = M_CheckParm("-timedemo"); if (p && p < myargc - 1) { //doom_sprintf(file, "%s.lmp", myargv[p + 1]); doom_strcpy(file, myargv[p + 1]); doom_concat(file, ".lmp"); D_AddFile(file); //doom_print("Playing demo %s.lmp.\n", myargv[p + 1]); doom_print("Playing demo "); doom_print(myargv[p + 1]); doom_print(".lmp.\n"); } // get skill / episode / map from parms startskill = sk_medium; startepisode = 1; startmap = 1; autostart = false; p = M_CheckParm("-skill"); if (p && p < myargc - 1) { startskill = myargv[p + 1][0] - '1'; autostart = true; } p = M_CheckParm("-episode"); if (p && p < myargc - 1) { startepisode = myargv[p + 1][0] - '0'; startmap = 1; autostart = true; } p = M_CheckParm("-timer"); if (p && p < myargc - 1 && deathmatch) { int time; time = doom_atoi(myargv[p + 1]); //doom_print("Levels will end after %d minute", time); doom_print("Levels will end after "); doom_print(doom_itoa(time, 10)); doom_print(" minute"); if (time > 1) doom_print("s"); doom_print(".\n"); } p = M_CheckParm("-avg"); if (p && p < myargc - 1 && deathmatch) doom_print("Austin Virtual Gaming: Levels will end after 20 minutes\n"); p = M_CheckParm("-warp"); if (p && p < myargc - 1) { if (gamemode == commercial) startmap = doom_atoi(myargv[p + 1]); else { startepisode = myargv[p + 1][0] - '0'; startmap = myargv[p + 2][0] - '0'; } autostart = true; } // init subsystems doom_print("V_Init: allocate screens.\n"); V_Init(); doom_print("M_LoadDefaults: Load system defaults.\n"); M_LoadDefaults(); // load before initing other systems doom_print("Z_Init: Init zone memory allocation daemon. \n"); Z_Init(); doom_print("W_Init: Init WADfiles.\n"); W_InitMultipleFiles(wadfiles); // 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("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) for (i = 0; i < 23; i++) if (W_CheckNumForName(name[i]) < 0) I_Error("Error: \nThis is not the registered version."); } // Iff additonal PWAD files are used, print modified banner if (modifiedgame) { /*m*/doom_print( "===========================================================================\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" //" press enter to continue\n" "===========================================================================\n" ); //getchar(); } // Check and print which version is executed. switch (gamemode) { case shareware: case indetermined: doom_print( "===========================================================================\n" " Shareware!\n" "===========================================================================\n" ); break; case registered: case retail: case commercial: doom_print( "===========================================================================\n" " Commercial product - do not distribute!\n" " Please report software piracy to the SPA: 1-800-388-PIR8\n" "===========================================================================\n" ); break; default: // Ouch. break; } doom_print("M_Init: Init miscellaneous info.\n"); M_Init(); doom_print("R_Init: Init DOOM refresh daemon - "); R_Init(); doom_print("\nP_Init: Init Playloop state.\n"); P_Init(); doom_print("I_Init: Setting up machine state.\n"); I_Init(); doom_print("D_CheckNetGame: Checking network game status.\n"); D_CheckNetGame(); doom_print("S_Init: Setting up sound.\n"); S_Init(snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/); doom_print("HU_Init: Setting up heads up display.\n"); HU_Init(); doom_print("ST_Init: Init status bar.\n"); ST_Init(); // check for a driver that wants intermission stats #if 0 // [pd] Unsure how to test this p = M_CheckParm("-statcopy"); if (p && p < myargc - 1) { // for statistics driver extern void* statcopy; statcopy = (void*)atoll(myargv[p + 1]); doom_print("External statistics registered.\n"); } #endif // start the apropriate game based on parms p = M_CheckParm("-record"); if (p && p < myargc - 1) { G_RecordDemo(myargv[p + 1]); autostart = true; } p = M_CheckParm("-playdemo"); if (p && p < myargc - 1) { singledemo = true; // quit after one demo G_DeferedPlayDemo(myargv[p + 1]); D_DoomLoop(); // never returns } p = M_CheckParm("-timedemo"); if (p && p < myargc - 1) { G_TimeDemo(myargv[p + 1]); D_DoomLoop(); // never returns } p = M_CheckParm("-loadgame"); if (p && p < myargc - 1) { #if 0 // [pd] We don't support the cdrom flag if (M_CheckParm("-cdrom")) { //doom_sprintf(file, "c:\\doomdata\\"SAVEGAMENAME"%c.dsg", myargv[p + 1][0]); } else #endif { //doom_sprintf(file, SAVEGAMENAME"%c.dsg", myargv[p + 1][0]); doom_strcpy(file, SAVEGAMENAME); doom_concat(file, doom_ctoa(myargv[p + 1][0])); doom_concat(file, ".dsg"); } G_LoadGame(file); } if (gameaction != ga_loadgame) { if (autostart || netgame) G_InitNew(startskill, startepisode, startmap); else D_StartTitle(); // start up intro loop } // D_DoomLoop (); // never returns [ddps] Called by app if (demorecording) G_BeginRecording(); if (M_CheckParm("-debugfile")) { char filename[20]; //doom_sprintf(filename, "debug%i.txt", consoleplayer); doom_strcpy(filename, "debug"); doom_concat(filename, doom_itoa(consoleplayer, 10)); doom_concat(filename, ".txt"); //doom_print("debug output to: %s\n", filename); doom_print("debug output to: "); doom_print(filename); doom_print("\n"); debugfile = doom_open(filename, "w"); } I_InitGraphics(); }