555 lines
12 KiB
C
555 lines
12 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.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
#define BGCOLOR 7
|
|
#define FGCOLOR 8
|
|
|
|
|
|
#include "os.h"
|
|
#include "cgdoom.h"
|
|
#include "cgdoom-alloc.h"
|
|
#include <stdlib.h>
|
|
|
|
#include "doomdef.h"
|
|
#include "doomstat.h"
|
|
|
|
#include "dstrings.h"
|
|
|
|
|
|
#include "z_zone.h"
|
|
#include "w_wad.h"
|
|
#include "v_video.h"
|
|
|
|
#include "f_finale.h"
|
|
#include "f_wipe.h"
|
|
|
|
#include "m_misc.h"
|
|
#include "m_menu.h"
|
|
|
|
#include "i_system.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"
|
|
|
|
|
|
//
|
|
// 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);
|
|
|
|
|
|
boolean devparm; // started game with -devparm
|
|
boolean nomonsters; // checkparm of -nomonsters
|
|
boolean respawnparm; // checkparm of -respawn
|
|
boolean fastparm; // checkparm of -fast
|
|
|
|
boolean drone;
|
|
|
|
boolean singletics = true;
|
|
|
|
boolean fuck = false;
|
|
|
|
|
|
extern boolean inhelpscreens;
|
|
|
|
skill_t startskill;
|
|
int startepisode;
|
|
int startmap;
|
|
boolean autostart;
|
|
|
|
boolean advancedemo;
|
|
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)
|
|
{
|
|
if (M_Responder (ev))
|
|
return; // menu ate the event
|
|
G_Responder (ev);
|
|
}
|
|
|
|
//
|
|
// 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 R_ExecuteSetViewSize (void);
|
|
|
|
void D_Display (void)
|
|
{
|
|
static boolean viewactivestate = false;
|
|
static boolean menuactivestate = false;
|
|
static boolean inhelpscreensstate = false;
|
|
static boolean fullscreen = false;
|
|
static gamestate_t oldgamestate = (gamestate_t)-1;
|
|
static int borderdrawcount;
|
|
int nowtime;
|
|
int tics;
|
|
int wipestart;
|
|
int y;
|
|
boolean done;
|
|
boolean wipe;
|
|
boolean redrawsbar;
|
|
|
|
redrawsbar = false;
|
|
|
|
// change the view size if needed
|
|
if (setsizeneeded)
|
|
{
|
|
R_ExecuteSetViewSize ();
|
|
oldgamestate = (gamestate_t)-1; // force background redraw
|
|
borderdrawcount = 3;
|
|
}
|
|
|
|
// save the current screen if about to wipe
|
|
if (gamestate != wipegamestate)
|
|
{
|
|
wipe = true;
|
|
wipe_StartScreen();
|
|
}
|
|
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 ((boolean)(viewheight == 200), redrawsbar );
|
|
fullscreen = (boolean)(viewheight == 200);
|
|
break;
|
|
|
|
case GS_INTERMISSION:
|
|
WI_Drawer ();
|
|
break;
|
|
|
|
case GS_FINALE:
|
|
F_Drawer ();
|
|
break;
|
|
|
|
case GS_DEMOSCREEN:
|
|
D_PageDrawer ();
|
|
break;
|
|
}
|
|
|
|
// draw the view directly
|
|
if (gamestate == GS_LEVEL && !automapactive && gametic)
|
|
R_RenderPlayerView (&players[0]);
|
|
|
|
if (gamestate == GS_LEVEL && gametic)
|
|
HU_Drawer ();
|
|
|
|
// clean up border stuff
|
|
if (gamestate != oldgamestate && gamestate != GS_LEVEL)
|
|
I_SetPalette ((byte *)W_CacheLumpNameConst ("PLAYPAL", PU_CACHE));
|
|
|
|
menuactivestate = menuactive;
|
|
viewactivestate = viewactive;
|
|
inhelpscreensstate = inhelpscreens;
|
|
oldgamestate = gamestate;
|
|
|
|
// draw pause pic
|
|
if (paused)
|
|
{
|
|
if (automapactive)
|
|
y = 4;
|
|
else
|
|
y = viewwindowy+4;
|
|
V_DrawPatchDirect(viewwindowx+(scaledviewwidth-68)/2, y ,0 ,W_CacheLumpNamePatch("M_PAUSE", PU_CACHE) );
|
|
}
|
|
|
|
// menus go directly to the screen
|
|
M_Drawer (); // menu is drawn even on top of everything
|
|
|
|
// normal update
|
|
if (!wipe)
|
|
{
|
|
I_Flip (); // page flip or blit buffer
|
|
return;
|
|
}
|
|
|
|
// wipe update
|
|
wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
|
|
|
|
wipestart = I_GetTime () - 1;
|
|
|
|
do
|
|
{
|
|
do
|
|
{
|
|
nowtime = I_GetTime ();
|
|
tics = nowtime - wipestart;
|
|
} while (tics<=0);
|
|
wipestart = nowtime;
|
|
done = wipe_ScreenWipe(wipe_Melt, SCREENWIDTH, SCREENHEIGHT, tics);
|
|
M_Drawer (); // menu is drawn even on top of wipes
|
|
I_Flip (); // page flip or blit buffer
|
|
} while (!done);
|
|
gamestate = oldgamestate;
|
|
wipegamestate= oldgamestate;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// D_DoomLoop
|
|
//
|
|
extern boolean demorecording;
|
|
extern int giRefreshMask;
|
|
void D_DoomLoop (void)
|
|
{
|
|
I_InitGraphics ();
|
|
|
|
while (!fuck)
|
|
{
|
|
I_StartTic ();
|
|
|
|
if (advancedemo)
|
|
D_DoAdvanceDemo ();
|
|
|
|
M_Ticker (); //Menu ticker
|
|
|
|
G_Ticker (); //Game ticker
|
|
|
|
gametic++;
|
|
|
|
// Update display, next frame, with current state
|
|
if(!(gametic & giRefreshMask))
|
|
{
|
|
D_Display ();
|
|
}
|
|
|
|
}
|
|
// I_ShutdownGraphics();
|
|
free(lumpinfo);
|
|
CGD_PRAM_Free(lumpcache);
|
|
I_ShutdownGraphics();
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// 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, (const patch_t *)W_CacheLumpNameConst(pagename, PU_CACHE));
|
|
}
|
|
|
|
|
|
//
|
|
// D_AdvanceDemo
|
|
// Called after each demo or intro demosequence finishes
|
|
//
|
|
void D_AdvanceDemo (void)
|
|
{
|
|
advancedemo = true;
|
|
}
|
|
|
|
int episode = 1;
|
|
int map = 1; //HACK
|
|
int skill = 2;
|
|
|
|
//
|
|
// 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";
|
|
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";
|
|
}
|
|
else
|
|
{
|
|
pagetic = 200;
|
|
|
|
if ( gamemode == retail )
|
|
pagename = "CREDIT";
|
|
else
|
|
pagename = "HELP2";
|
|
}
|
|
break;
|
|
case 5:
|
|
G_DeferedPlayDemo ("demo3");
|
|
break;
|
|
case 6:
|
|
G_DeferedPlayDemo ("demo4");
|
|
break;
|
|
}
|
|
|
|
/* CGDoom: Skip demos on option (often incompatible) */
|
|
if (gameaction == ga_playdemo && !CGD_EnableDemos) {
|
|
D_DoAdvanceDemo();
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// D_StartTitle
|
|
//
|
|
void D_StartTitle (void)
|
|
{
|
|
gameaction = ga_nothing;
|
|
demosequence = -1;
|
|
D_AdvanceDemo ();
|
|
}
|
|
|
|
|
|
|
|
|
|
// print title for every printed line
|
|
//char title[128];
|
|
|
|
//
|
|
// D_DoomMain
|
|
//
|
|
void D_DoomMain()
|
|
{
|
|
int ok_wad=0;
|
|
// int selected=1;
|
|
// int rskill=1;
|
|
int maxepisode=1;
|
|
skill=3;
|
|
|
|
// int repisode=1;
|
|
// int rmap=1;
|
|
|
|
/* CGDoom: Z_Init is executed early because we rely on the larger heap to
|
|
allocate the lump cache and lump info; normal heap isn't enough for WADs
|
|
larger than the shareware WAD */
|
|
Z_Init ();
|
|
|
|
for (int i = 0; true; i++)
|
|
{
|
|
int zone_size;
|
|
void *zone_base = I_ZoneBase(&zone_size, i);
|
|
if (zone_base == NULL)
|
|
break;
|
|
Z_AddZone (zone_base, zone_size);
|
|
}
|
|
|
|
ok_wad=W_InitMultipleFiles();
|
|
|
|
if(W_CheckNumForName("MAP01")!=-1)
|
|
gamemode=commercial;
|
|
else if(W_CheckNumForName("E1M1")==-1)
|
|
gamemode=indetermined;
|
|
else if (W_CheckNumForName("E2M1")==-1)
|
|
gamemode=shareware;
|
|
else if (W_CheckNumForName("E4M1")==-1)
|
|
gamemode=registered;
|
|
else
|
|
gamemode=retail;
|
|
|
|
if(gamemode == indetermined) // CX port
|
|
return; // CX port
|
|
|
|
if (W_CheckNumForName("E4M1")!=-1)
|
|
maxepisode = 4;
|
|
else if (W_CheckNumForName("E3M1")!=-1)
|
|
maxepisode = 3;
|
|
else if (W_CheckNumForName("E2M1")!=-1)
|
|
maxepisode = 2;
|
|
|
|
/* CGDoom: Override game mode for split WADs; we have single-episode WADs for
|
|
all episodes of Ultimate Doom, and they should identify as retail */
|
|
if (CGD_SingleEpisodeUltimate > 0) {
|
|
gamemode=retail;
|
|
maxepisode = CGD_SingleEpisodeUltimate;
|
|
}
|
|
|
|
|
|
nomonsters = 0;
|
|
respawnparm = 0;
|
|
fastparm = 0;
|
|
devparm = 0;
|
|
|
|
// get skill / episode / map from parms // DON'T, LEFT IN UNTIL OPCHECK
|
|
if(skill==0) startskill = sk_baby;
|
|
else if(skill==1) startskill = sk_easy;
|
|
else if(skill==2) startskill = sk_medium;
|
|
else if(skill==3) startskill = sk_hard;
|
|
else if(skill==4) startskill = sk_nightmare;
|
|
|
|
// init subsystems
|
|
//printf ("V_Init: Allocate screens\n");
|
|
V_Init ();
|
|
//printf ("Z_Init: Init zone memory allocation daemon \n");
|
|
//Z_Init ();
|
|
//printf ("W_Init: Init WADfiles\n");
|
|
|
|
W_InitMultipleFiles ();
|
|
//Just in case we haven't found the WAD files...
|
|
if (fuck)
|
|
return;
|
|
|
|
#ifdef CG_EMULATOR
|
|
// 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\n"
|
|
" do not distribute!\n"
|
|
"=====================================\n"
|
|
);
|
|
break;
|
|
|
|
default:
|
|
// Ouch.
|
|
break;
|
|
}
|
|
#endif //#ifdef CG_EMULATOR
|
|
//printf ("I_Init: Setting up machine state\n");
|
|
I_Init ();
|
|
//printf ("M_Init: Init miscellaneous info\n");
|
|
M_Init ();
|
|
//printf ("R_Init: Init DOOM refresh daemon \n");
|
|
R_Init ();
|
|
//printf ("P_Init: Init Playloop state\n");
|
|
P_Init ();
|
|
//printf ("HU_Init: Setup heads up display\n");
|
|
HU_Init ();
|
|
//printf ("ST_Init: Init status bar\n");
|
|
ST_Init ();
|
|
//printf ("Engage... \n");
|
|
|
|
if (autostart)
|
|
G_DeferedInitNew (startskill, startepisode, startmap);
|
|
else
|
|
D_StartTitle ();
|
|
|
|
D_DoomLoop (); // never returns, except when it does
|
|
I_Restore (); //calckill = bad
|
|
|
|
return;
|
|
}
|