v4k-git-backup/demos/ports/doom/src/d_main.c

1259 lines
34 KiB
C

// 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();
}