2006-03-28 15:44:01 +00:00
|
|
|
/* Emacs style mode select -*- C++ -*-
|
|
|
|
*-----------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* PrBoom a Doom port merged with LxDoom and LSDLDoom
|
|
|
|
* based on BOOM, a modified and improved DOOM engine
|
|
|
|
* Copyright (C) 1999 by
|
|
|
|
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
|
|
|
|
* Copyright (C) 1999-2000 by
|
|
|
|
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*
|
|
|
|
* 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 "rockmacros.h"
|
|
|
|
|
|
|
|
#include "doomdef.h"
|
|
|
|
#include "doomtype.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_draw.h"
|
|
|
|
#include "r_main.h"
|
|
|
|
#include "d_main.h"
|
2006-12-13 04:44:17 +00:00
|
|
|
#include "d_deh.h" // Ty 04/08/98 - Externalizations
|
2006-03-28 15:44:01 +00:00
|
|
|
#include "am_map.h"
|
|
|
|
#include "m_swap.h"
|
|
|
|
|
2006-12-13 04:44:17 +00:00
|
|
|
// DEHacked support - Ty 03/09/97 // CPhipps - const char*'s
|
|
|
|
void ProcessDehFile(const char *filename, const char *outfilename, int lumpnum);
|
|
|
|
|
2006-03-28 15:44:01 +00:00
|
|
|
// CPhipps - removed wadfiles[] stuff
|
|
|
|
|
|
|
|
boolean devparm; // started game with -devparm
|
|
|
|
|
|
|
|
// jff 1/24/98 add new versions of these variables to remember command line
|
|
|
|
boolean clnomonsters; // checkparm of -nomonsters
|
|
|
|
boolean clrespawnparm; // checkparm of -respawn
|
|
|
|
boolean clfastparm; // checkparm of -fast
|
|
|
|
// jff 1/24/98 end definition of command line version of play mode switches
|
|
|
|
|
|
|
|
boolean nomonsters; // working -nomonsters
|
|
|
|
boolean respawnparm; // working -respawn
|
|
|
|
boolean fastparm; // working -fast
|
2007-06-03 22:03:36 +00:00
|
|
|
boolean dehout=true;
|
2006-03-28 15:44:01 +00:00
|
|
|
|
|
|
|
boolean singletics = false; // debug flag to cancel adaptiveness
|
|
|
|
|
2006-04-15 22:08:36 +00:00
|
|
|
bool doomexit;
|
2006-03-28 15:44:01 +00:00
|
|
|
|
|
|
|
//jff 1/22/98 parms for disabling music and sound
|
2006-04-15 22:08:36 +00:00
|
|
|
boolean nomusicparm=0;
|
2006-03-28 15:44:01 +00:00
|
|
|
|
|
|
|
//jff 4/18/98
|
|
|
|
extern boolean inhelpscreens;
|
|
|
|
|
|
|
|
skill_t startskill;
|
|
|
|
int startepisode;
|
|
|
|
int startmap;
|
|
|
|
boolean autostart;
|
|
|
|
int debugfile;
|
|
|
|
int ffmap;
|
|
|
|
|
|
|
|
boolean advancedemo;
|
|
|
|
|
|
|
|
extern boolean timingdemo, singledemo, demoplayback, fastdemo; // killough
|
|
|
|
|
|
|
|
int basetic;
|
|
|
|
|
|
|
|
void D_DoAdvanceDemo (void);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* D_PostEvent - Event handling
|
|
|
|
*
|
|
|
|
* Called by I/O functions when an event is received.
|
|
|
|
* Try event handlers for each code area in turn.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void D_PostEvent(event_t *ev)
|
|
|
|
{
|
|
|
|
/* cph - suppress all input events at game start
|
|
|
|
* FIXME: This is a lousy kludge */
|
2006-08-16 13:31:40 +00:00
|
|
|
if (gametic < 3)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(!M_Responder(ev)) {
|
|
|
|
if(gamestate == GS_LEVEL && (
|
|
|
|
HU_Responder(ev) ||
|
|
|
|
ST_Responder(ev) ||
|
|
|
|
AM_Responder(ev)
|
|
|
|
))
|
|
|
|
return;
|
|
|
|
else
|
|
|
|
G_Responder(ev);
|
|
|
|
}
|
2006-03-28 15:44:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// D_Wipe
|
|
|
|
//
|
|
|
|
// CPhipps - moved the screen wipe code from D_Display to here
|
|
|
|
// The screens to wipe between are already stored, this just does the timing
|
|
|
|
// and screen updating
|
|
|
|
|
|
|
|
static void D_Wipe(void)
|
|
|
|
{
|
|
|
|
boolean done;
|
|
|
|
int wipestart = I_GetTime () - 1;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
int nowtime, tics;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
//I_uSleep(5000); // CPhipps - don't thrash cpu in this loop
|
|
|
|
nowtime = I_GetTime();
|
|
|
|
tics = nowtime - wipestart;
|
|
|
|
}
|
|
|
|
while (!tics);
|
|
|
|
wipestart = nowtime;
|
|
|
|
|
|
|
|
done = wipe_ScreenWipe(0,0,SCREENWIDTH,SCREENHEIGHT,tics);
|
|
|
|
M_Drawer(); // menu is drawn even on top of wipes
|
|
|
|
I_FinishUpdate(); // page flip or blit buffer
|
|
|
|
}
|
|
|
|
while (!done);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// 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 boolean setsizeneeded;
|
|
|
|
extern int showMessages;
|
|
|
|
|
|
|
|
void D_Display (void)
|
|
|
|
{
|
2006-04-15 22:08:36 +00:00
|
|
|
static boolean isborderstate IDATA_ATTR= false;
|
|
|
|
static boolean borderwillneedredraw IDATA_ATTR= false;
|
|
|
|
static boolean inhelpscreensstate IDATA_ATTR= false;
|
|
|
|
static gamestate_t oldgamestate IDATA_ATTR= -1;
|
2006-03-28 15:44:01 +00:00
|
|
|
boolean wipe;
|
|
|
|
boolean viewactive = false, isborder = false;
|
|
|
|
|
|
|
|
if (nodrawers) // for comparative timing / profiling
|
|
|
|
return;
|
|
|
|
|
|
|
|
// save the current screen if about to wipe
|
|
|
|
if ((wipe = gamestate != wipegamestate))
|
|
|
|
wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
|
|
|
|
|
|
|
|
if (gamestate != GS_LEVEL) { // Not a level
|
|
|
|
switch (oldgamestate) {
|
|
|
|
case -1:
|
|
|
|
case GS_LEVEL:
|
|
|
|
V_SetPalette(0); // cph - use default (basic) palette
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (gamestate) {
|
|
|
|
case GS_INTERMISSION:
|
|
|
|
WI_Drawer();
|
|
|
|
break;
|
|
|
|
case GS_FINALE:
|
|
|
|
F_Drawer();
|
|
|
|
break;
|
|
|
|
case GS_DEMOSCREEN:
|
|
|
|
D_PageDrawer();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (gametic != basetic) { // In a level
|
|
|
|
boolean redrawborderstuff;
|
|
|
|
|
|
|
|
HU_Erase();
|
|
|
|
|
|
|
|
if (setsizeneeded) { // change the view size if needed
|
|
|
|
R_ExecuteSetViewSize();
|
|
|
|
oldgamestate = -1; // force background redraw
|
|
|
|
}
|
|
|
|
|
|
|
|
// Work out if the player view is visible, and if there is a border
|
|
|
|
viewactive = (!(automapmode & am_active) || (automapmode & am_overlay)) && !inhelpscreens;
|
|
|
|
isborder = viewactive ? (viewheight != SCREENHEIGHT) : (!inhelpscreens && (automapmode & am_active));
|
|
|
|
|
|
|
|
if (oldgamestate != GS_LEVEL) {
|
|
|
|
R_FillBackScreen (); // draw the pattern into the back screen
|
|
|
|
redrawborderstuff = isborder;
|
|
|
|
} else {
|
|
|
|
// CPhipps -
|
|
|
|
// If there is a border, and either there was no border last time,
|
|
|
|
// or the border might need refreshing, then redraw it.
|
|
|
|
redrawborderstuff = isborder && (!isborderstate || borderwillneedredraw);
|
|
|
|
// The border may need redrawing next time if the border surrounds the screen,
|
|
|
|
// and there is a menu being displayed
|
|
|
|
borderwillneedredraw = menuactive && isborder && viewactive && (viewwidth != SCREENWIDTH);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (redrawborderstuff)
|
|
|
|
R_DrawViewBorder();
|
|
|
|
|
|
|
|
// Now do the drawing
|
|
|
|
if (viewactive)
|
|
|
|
R_RenderPlayerView (&players[displayplayer]);
|
|
|
|
if (automapmode & am_active)
|
|
|
|
AM_Drawer();
|
|
|
|
ST_Drawer((viewheight != SCREENHEIGHT) || ((automapmode & am_active) && !(automapmode & am_overlay)), redrawborderstuff);
|
|
|
|
R_DrawViewBorder();
|
|
|
|
|
|
|
|
HU_Drawer();
|
|
|
|
}
|
|
|
|
|
|
|
|
inhelpscreensstate = inhelpscreens;
|
|
|
|
isborderstate = isborder;
|
|
|
|
oldgamestate = wipegamestate = gamestate;
|
|
|
|
|
|
|
|
// draw pause pic
|
|
|
|
if (paused) {
|
|
|
|
static int x;
|
|
|
|
|
|
|
|
if (!x) { // Cache results of x pos calc
|
|
|
|
int lump = W_GetNumForName("M_PAUSE");
|
|
|
|
const patch_t* p = W_CacheLumpNum(lump);
|
|
|
|
x = (320 - SHORT(p->width))/2;
|
|
|
|
W_UnlockLumpNum(lump);
|
|
|
|
}
|
|
|
|
|
|
|
|
// CPhipps - updated for new patch drawing
|
|
|
|
V_DrawNamePatch(x, (!(automapmode & am_active) || (automapmode & am_overlay))
|
|
|
|
? 4+(viewwindowy*200/SCREENHEIGHT) : 4, // cph - Must un-stretch viewwindowy
|
|
|
|
0, "M_PAUSE", CR_DEFAULT, VPT_STRETCH);
|
|
|
|
}
|
|
|
|
|
|
|
|
// menus go directly to the screen
|
|
|
|
M_Drawer(); // menu is drawn even on top of everything
|
|
|
|
D_BuildNewTiccmds();
|
|
|
|
|
|
|
|
// normal update
|
|
|
|
if (!wipe)
|
|
|
|
I_FinishUpdate (); // page flip or blit buffer
|
|
|
|
else {
|
|
|
|
// wipe update
|
|
|
|
wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
|
|
|
|
D_Wipe();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// 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
|
|
|
|
//
|
|
|
|
|
|
|
|
extern boolean demorecording;
|
|
|
|
|
|
|
|
static void D_DoomLoop (void)
|
|
|
|
{
|
|
|
|
basetic = gametic;
|
|
|
|
|
|
|
|
I_SubmitSound();
|
|
|
|
|
|
|
|
while (!doomexit)
|
|
|
|
{
|
|
|
|
// process one or more tics
|
|
|
|
if (singletics)
|
|
|
|
{
|
|
|
|
I_StartTic ();
|
|
|
|
G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]);
|
|
|
|
if (advancedemo)
|
|
|
|
D_DoAdvanceDemo ();
|
|
|
|
M_Ticker ();
|
|
|
|
G_Ticker ();
|
|
|
|
gametic++;
|
|
|
|
maketic++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
TryRunTics (); // will run at least one tic
|
|
|
|
|
|
|
|
// killough 3/16/98: change consoleplayer to displayplayer
|
|
|
|
if (players[displayplayer].mo) // cph 2002/08/10
|
|
|
|
S_UpdateSounds(players[displayplayer].mo);// move positional sounds
|
|
|
|
|
|
|
|
// Update display, next frame, with current state.
|
|
|
|
D_Display();
|
|
|
|
|
2006-04-15 22:08:36 +00:00
|
|
|
// Give the system some time
|
2006-03-28 15:44:01 +00:00
|
|
|
rb->yield();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// DEMO LOOP
|
|
|
|
//
|
|
|
|
|
|
|
|
static int demosequence; // killough 5/2/98: made static
|
|
|
|
static int pagetic;
|
|
|
|
static const char *pagename; // CPhipps - const
|
|
|
|
|
|
|
|
//
|
|
|
|
// D_PageTicker
|
|
|
|
// Handles timing for warped projection
|
|
|
|
//
|
|
|
|
void D_PageTicker(void)
|
|
|
|
{
|
|
|
|
if (--pagetic < 0)
|
|
|
|
D_AdvanceDemo();
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// D_PageDrawer
|
|
|
|
//
|
|
|
|
void D_PageDrawer(void)
|
|
|
|
{
|
|
|
|
// CPhipps - updated for new patch drawing
|
|
|
|
V_DrawNamePatch(0, 0, 0, pagename, CR_DEFAULT, VPT_STRETCH);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// D_AdvanceDemo
|
|
|
|
// Called after each demo or intro demosequence finishes
|
|
|
|
//
|
|
|
|
void D_AdvanceDemo (void)
|
|
|
|
{
|
|
|
|
advancedemo = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* killough 11/98: functions to perform demo sequences
|
|
|
|
* cphipps 10/99: constness fixes
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void D_SetPageName(const char *name)
|
|
|
|
{
|
|
|
|
pagename = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void D_DrawTitle1(const char *name)
|
|
|
|
{
|
|
|
|
S_StartMusic(mus_intro);
|
|
|
|
pagetic = (TICRATE*170)/35;
|
|
|
|
D_SetPageName(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void D_DrawTitle2(const char *name)
|
|
|
|
{
|
|
|
|
S_StartMusic(mus_dm2ttl);
|
|
|
|
D_SetPageName(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* killough 11/98: tabulate demo sequences
|
|
|
|
*/
|
|
|
|
|
|
|
|
static struct
|
|
|
|
{
|
|
|
|
void (*func)(const char *);
|
|
|
|
const char *name;
|
|
|
|
} const demostates[][4] =
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{D_DrawTitle1, "TITLEPIC"},
|
|
|
|
{D_DrawTitle1, "TITLEPIC"},
|
|
|
|
{D_DrawTitle2, "TITLEPIC"},
|
|
|
|
{D_DrawTitle1, "TITLEPIC"},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{G_DeferedPlayDemo, "demo1"},
|
|
|
|
{G_DeferedPlayDemo, "demo1"},
|
|
|
|
{G_DeferedPlayDemo, "demo1"},
|
|
|
|
{G_DeferedPlayDemo, "demo1"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{D_SetPageName, "CREDIT"},
|
|
|
|
{D_SetPageName, "CREDIT"},
|
|
|
|
{D_SetPageName, "CREDIT"},
|
|
|
|
{D_SetPageName, "CREDIT"},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{G_DeferedPlayDemo, "demo2"},
|
|
|
|
{G_DeferedPlayDemo, "demo2"},
|
|
|
|
{G_DeferedPlayDemo, "demo2"},
|
|
|
|
{G_DeferedPlayDemo, "demo2"},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{D_SetPageName, "HELP2"},
|
|
|
|
{D_SetPageName, "HELP2"},
|
|
|
|
{D_SetPageName, "CREDIT"},
|
|
|
|
{D_DrawTitle1, "TITLEPIC"},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{G_DeferedPlayDemo, "demo3"},
|
|
|
|
{G_DeferedPlayDemo, "demo3"},
|
|
|
|
{G_DeferedPlayDemo, "demo3"},
|
|
|
|
{G_DeferedPlayDemo, "demo3"},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{NULL,0},
|
|
|
|
{NULL,0},
|
|
|
|
{NULL,0},
|
|
|
|
{D_SetPageName, "CREDIT"},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{NULL,0},
|
|
|
|
{NULL,0},
|
|
|
|
{NULL,0},
|
|
|
|
{G_DeferedPlayDemo, "demo4"},
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
{NULL,0},
|
|
|
|
{NULL,0},
|
|
|
|
{NULL,0},
|
|
|
|
{NULL,0},
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This cycles through the demo sequences.
|
|
|
|
* killough 11/98: made table-driven
|
|
|
|
*/
|
|
|
|
|
|
|
|
void D_DoAdvanceDemo(void)
|
|
|
|
{
|
|
|
|
players[consoleplayer].playerstate = PST_LIVE; /* not reborn */
|
|
|
|
advancedemo = usergame = paused = false;
|
|
|
|
gameaction = ga_nothing;
|
|
|
|
|
|
|
|
pagetic = TICRATE * 11; /* killough 11/98: default behavior */
|
|
|
|
gamestate = GS_DEMOSCREEN;
|
|
|
|
|
|
|
|
if (netgame && !demoplayback) {
|
|
|
|
demosequence = 0;
|
|
|
|
} else
|
|
|
|
if (!demostates[++demosequence][gamemode].func)
|
|
|
|
demosequence = 0;
|
|
|
|
demostates[demosequence][gamemode].func(demostates[demosequence][gamemode].name);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// D_StartTitle
|
|
|
|
//
|
|
|
|
void D_StartTitle (void)
|
|
|
|
{
|
|
|
|
gameaction = ga_nothing;
|
|
|
|
demosequence = -1;
|
|
|
|
D_AdvanceDemo();
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// D_AddFile
|
|
|
|
//
|
|
|
|
// Rewritten by Lee Killough
|
|
|
|
//
|
|
|
|
// Ty 08/29/98 - add source parm to indicate where this came from
|
|
|
|
// CPhipps - static, const char* parameter
|
|
|
|
// - source is an enum
|
|
|
|
// - modified to allocate & use new wadfiles array
|
|
|
|
void D_AddFile (const char *file, wad_source_t source)
|
|
|
|
{
|
|
|
|
wadfiles = realloc(wadfiles, sizeof(*wadfiles)*(numwadfiles+1));
|
|
|
|
wadfiles[numwadfiles].name =
|
|
|
|
AddDefaultExtension(strcpy(malloc(strlen(file)+5), file), ".wad");
|
|
|
|
wadfiles[numwadfiles].src = source; // Ty 08/29/98
|
|
|
|
numwadfiles++;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// CheckIWAD
|
|
|
|
//
|
|
|
|
// Verify a file is indeed tagged as an IWAD
|
|
|
|
// Scan its lumps for levelnames and return gamemode as indicated
|
|
|
|
// Detect missing wolf levels in DOOM II
|
|
|
|
//
|
|
|
|
// The filename to check is passed in iwadname, the gamemode detected is
|
|
|
|
// returned in gmode, hassec returns the presence of secret levels
|
|
|
|
//
|
|
|
|
// jff 4/19/98 Add routine to test IWAD for validity and determine
|
|
|
|
// the gamemode from it. Also note if DOOM II, whether secret levels exist
|
|
|
|
// CPhipps - const char* for iwadname, made static
|
|
|
|
#if 0
|
|
|
|
static void CheckIWAD(const char *iwadname,GameMode_t *gmode,boolean *hassec)
|
|
|
|
{
|
|
|
|
if ( !fileexists (iwadname) )
|
|
|
|
{
|
|
|
|
int ud=0,rg=0,sw=0,cm=0,sc=0;
|
|
|
|
int handle;
|
|
|
|
|
|
|
|
// Identify IWAD correctly
|
|
|
|
if ( (handle = open (iwadname,O_RDONLY)) != -1)
|
|
|
|
{
|
|
|
|
wadinfo_t header;
|
|
|
|
|
|
|
|
// read IWAD header
|
|
|
|
read (handle, &header, sizeof(header));
|
|
|
|
if (!strncmp(header.identification,"IWAD",4))
|
|
|
|
{
|
|
|
|
size_t length;
|
|
|
|
filelump_t *fileinfo;
|
|
|
|
|
|
|
|
// read IWAD directory
|
|
|
|
header.numlumps = LONG(header.numlumps);
|
|
|
|
header.infotableofs = LONG(header.infotableofs);
|
|
|
|
length = header.numlumps;
|
|
|
|
fileinfo = malloc(length*sizeof(filelump_t));
|
|
|
|
lseek (handle, header.infotableofs, SEEK_SET);
|
|
|
|
read (handle, fileinfo, length*sizeof(filelump_t));
|
|
|
|
close(handle);
|
|
|
|
|
|
|
|
// scan directory for levelname lumps
|
|
|
|
while (length--)
|
|
|
|
if (fileinfo[length].name[0] == 'E' &&
|
|
|
|
fileinfo[length].name[2] == 'M' &&
|
|
|
|
fileinfo[length].name[4] == 0)
|
|
|
|
{
|
|
|
|
if (fileinfo[length].name[1] == '4')
|
|
|
|
++ud;
|
|
|
|
else if (fileinfo[length].name[1] == '3')
|
|
|
|
++rg;
|
|
|
|
else if (fileinfo[length].name[1] == '2')
|
|
|
|
++rg;
|
|
|
|
else if (fileinfo[length].name[1] == '1')
|
|
|
|
++sw;
|
|
|
|
}
|
|
|
|
else if (fileinfo[length].name[0] == 'M' &&
|
|
|
|
fileinfo[length].name[1] == 'A' &&
|
|
|
|
fileinfo[length].name[2] == 'P' &&
|
|
|
|
fileinfo[length].name[5] == 0)
|
|
|
|
{
|
|
|
|
++cm;
|
|
|
|
if (fileinfo[length].name[3] == '3')
|
|
|
|
if (fileinfo[length].name[4] == '1' ||
|
|
|
|
fileinfo[length].name[4] == '2')
|
|
|
|
++sc;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(fileinfo);
|
|
|
|
}
|
|
|
|
else // missing IWAD tag in header
|
|
|
|
I_Error("CheckIWAD: IWAD tag %s not present", iwadname);
|
|
|
|
}
|
|
|
|
else // error from open call
|
|
|
|
I_Error("CheckIWAD: Can't open IWAD %s", iwadname);
|
|
|
|
|
|
|
|
// Determine game mode from levels present
|
|
|
|
// Must be a full set for whichever mode is present
|
|
|
|
// Lack of wolf-3d levels also detected here
|
|
|
|
|
|
|
|
*gmode = indetermined;
|
|
|
|
*hassec = false;
|
|
|
|
if (cm>=30)
|
|
|
|
{
|
|
|
|
*gmode = commercial;
|
|
|
|
*hassec = sc>=2;
|
|
|
|
}
|
|
|
|
else if (ud>=9)
|
|
|
|
*gmode = retail;
|
|
|
|
else if (rg>=18)
|
|
|
|
*gmode = registered;
|
|
|
|
else if (sw>=9)
|
|
|
|
*gmode = shareware;
|
|
|
|
}
|
|
|
|
else // error from access call
|
|
|
|
I_Error("CheckIWAD: IWAD %s not readable", iwadname);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
void D_DoomMainSetup(void)
|
|
|
|
{
|
|
|
|
int p;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2006-04-02 01:52:44 +00:00
|
|
|
printf("Welcome to Rockdoom\n");
|
2006-03-28 15:44:01 +00:00
|
|
|
|
|
|
|
switch ( gamemode )
|
|
|
|
{
|
|
|
|
case retail:
|
2006-04-02 01:52:44 +00:00
|
|
|
printf ("The Ultimate DOOM Startup v%d.%d\n",DVERSION/100,DVERSION%100);
|
2006-03-28 15:44:01 +00:00
|
|
|
break;
|
|
|
|
case shareware:
|
2006-04-02 01:52:44 +00:00
|
|
|
printf ("DOOM Shareware Startup v%d.%d\n",DVERSION/100,DVERSION%100);
|
2006-03-28 15:44:01 +00:00
|
|
|
break;
|
|
|
|
case registered:
|
2006-04-02 01:52:44 +00:00
|
|
|
printf ("DOOM Registered Startup v%d.%d\n",DVERSION/100,DVERSION%100);
|
2006-03-28 15:44:01 +00:00
|
|
|
break;
|
|
|
|
case commercial:
|
|
|
|
switch (gamemission)
|
|
|
|
{
|
|
|
|
case pack_plut:
|
2006-04-02 01:52:44 +00:00
|
|
|
printf ("DOOM 2: Plutonia Experiment v%d.%d\n",DVERSION/100,DVERSION%100);
|
2006-03-28 15:44:01 +00:00
|
|
|
break;
|
|
|
|
case pack_tnt:
|
2006-04-02 01:52:44 +00:00
|
|
|
printf ("DOOM 2: TNT - Evilution v%d.%d\n",DVERSION/100,DVERSION%100);
|
2006-03-28 15:44:01 +00:00
|
|
|
break;
|
|
|
|
default:
|
2006-04-02 01:52:44 +00:00
|
|
|
printf ("DOOM 2: Hell on Earth v%d.%d\n",DVERSION/100,DVERSION%100);
|
2006-03-28 15:44:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
2006-04-02 01:52:44 +00:00
|
|
|
printf ("Public DOOM v%d.%d\n",DVERSION/100,DVERSION%100);
|
2006-03-28 15:44:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (devparm)
|
|
|
|
printf(D_DEVSTR);
|
|
|
|
|
|
|
|
// turbo option
|
|
|
|
if ((p=M_CheckParm ("-turbo")))
|
|
|
|
{
|
|
|
|
int scale = 200;
|
|
|
|
extern int forwardmove[2];
|
|
|
|
extern int sidemove[2];
|
|
|
|
|
|
|
|
if (p<myargc-1)
|
|
|
|
scale = atoi (myargv[p+1]);
|
|
|
|
if (scale < 10)
|
|
|
|
scale = 10;
|
|
|
|
if (scale > 400)
|
|
|
|
scale = 400;
|
|
|
|
printf ("turbo scale: %d%%\n",scale);
|
|
|
|
forwardmove[0] = forwardmove[0]*scale/100;
|
|
|
|
forwardmove[1] = forwardmove[1]*scale/100;
|
|
|
|
sidemove[0] = sidemove[0]*scale/100;
|
|
|
|
sidemove[1] = sidemove[1]*scale/100;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 ("-warp");
|
|
|
|
if (p && p < myargc-1)
|
|
|
|
{
|
|
|
|
if (gamemode == commercial)
|
|
|
|
startmap = atoi (myargv[p+1]);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
startepisode = myargv[p+1][0]-'0';
|
|
|
|
startmap = myargv[p+2][0]-'0';
|
|
|
|
}
|
|
|
|
autostart = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// CPhipps - move up netgame init
|
|
|
|
printf("D_InitNetGame: Checking for network game.\n");
|
|
|
|
D_InitNetGame();
|
|
|
|
|
|
|
|
// init subsystems
|
|
|
|
printf ("V_Init: allocate screens.\n");
|
|
|
|
V_Init ();
|
|
|
|
|
|
|
|
printf ("W_Init: Init WADfiles.\n");
|
|
|
|
W_Init();
|
|
|
|
|
2006-12-13 04:44:17 +00:00
|
|
|
if ((p = W_CheckNumForName("DEHACKED")) != -1) // cph - add dehacked-in-a-wad support
|
2007-06-03 22:03:36 +00:00
|
|
|
ProcessDehFile(NULL, dehout ? "/dehlog.txt" : NULL, p);
|
2006-12-13 04:44:17 +00:00
|
|
|
|
2006-03-28 15:44:01 +00:00
|
|
|
V_InitColorTranslation(); //jff 4/24/98 load color translation lumps
|
|
|
|
|
|
|
|
// 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.
|
2006-04-06 20:44:33 +00:00
|
|
|
const char name[23][8]=
|
2006-03-28 15:44:01 +00:00
|
|
|
{
|
|
|
|
"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)
|
2006-04-02 01:52:44 +00:00
|
|
|
I_Error("\nYou cannot -file with the shareware version. Register!\n");
|
2006-03-28 15:44:01 +00:00
|
|
|
|
|
|
|
// 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)
|
2006-04-02 01:52:44 +00:00
|
|
|
I_Error("This is not the registered version.\n");
|
2006-03-28 15:44:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Iff additonal PWAD files are used, print modified banner
|
|
|
|
if (modifiedgame)
|
|
|
|
printf ("ATTENTION: This version of DOOM has been modified.\n");
|
|
|
|
|
|
|
|
// Check and print which version is executed.
|
|
|
|
switch ( gamemode )
|
|
|
|
{
|
|
|
|
case shareware:
|
|
|
|
case indetermined:
|
|
|
|
printf ("Shareware!\n");
|
|
|
|
break;
|
|
|
|
case registered:
|
|
|
|
case retail:
|
|
|
|
case commercial:
|
|
|
|
printf ("Commercial product - do not distribute!\n");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// Ouch.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf ("M_Init: Init miscellaneous info.\n");
|
|
|
|
M_Init ();
|
|
|
|
|
|
|
|
printf ("R_Init: Init DOOM refresh daemon - ");
|
|
|
|
R_Init ();
|
|
|
|
|
|
|
|
printf ("P_Init: Init Playloop state.\n");
|
|
|
|
P_Init ();
|
|
|
|
|
|
|
|
printf ("I_Init: Setting up machine state.\n");
|
|
|
|
I_Init ();
|
|
|
|
|
|
|
|
printf ("S_Init: Setting up sound.\n");
|
|
|
|
S_Init (snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ );
|
|
|
|
|
|
|
|
printf ("HU_Init: Setting up heads up display.\n");
|
|
|
|
HU_Init ();
|
|
|
|
|
|
|
|
I_InitGraphics ();
|
|
|
|
|
|
|
|
printf ("ST_Init: Init status bar.\n");
|
|
|
|
ST_Init ();
|
|
|
|
|
|
|
|
// check for a driver that wants intermission stats
|
|
|
|
p = M_CheckParm ("-statcopy");
|
|
|
|
if (p && p<myargc-1)
|
|
|
|
{
|
|
|
|
// for statistics driver
|
|
|
|
extern void* statcopy;
|
|
|
|
|
2006-03-28 17:42:57 +00:00
|
|
|
statcopy = (void*)(long)atoi(myargv[p+1]);
|
2006-03-28 15:44:01 +00:00
|
|
|
printf ("External statistics registered.\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 ("-loadgame");
|
|
|
|
if (p && p < myargc-1)
|
|
|
|
G_LoadGame (atoi(myargv[p+1]), false);
|
|
|
|
|
|
|
|
if ( gameaction != ga_loadgame )
|
|
|
|
{
|
|
|
|
if (!singledemo) { /* killough 12/98 */
|
|
|
|
if (autostart || netgame)
|
|
|
|
G_InitNew (startskill, startepisode, startmap);
|
|
|
|
else
|
|
|
|
D_StartTitle (); // start up intro loop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// D_DoomMain
|
|
|
|
//
|
|
|
|
void D_DoomMain (void)
|
|
|
|
{
|
|
|
|
D_DoomMainSetup(); // get this crap off the stack
|
|
|
|
|
|
|
|
D_DoomLoop (); // never returns
|
|
|
|
}
|