📄 d_main.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.
//
//-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: d_main.c,v 1.8 1997/02/03 22:45:09 b1 Exp $";
#define BGCOLOR 7
#define FGCOLOR 8
#ifdef NORMALUNIX
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
#include <direct.h>
#include <malloc.h>
#include <io.h>
#include <fcntl.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 "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"
#include "d_console.h"
char MsgText[256];
void WriteDebug(char *);
//
// 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];
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 = false; // debug flag to cancel adaptiveness
extern boolean plutonia, tnt;
//extern int soundVolume;
//extern int sfxVolume;
//extern int musicVolume;
extern boolean inhelpscreens;
skill_t startskill;
int startepisode;
int startmap;
boolean autostart;
FILE* debugfile;
boolean advancedemo;
char wadfile[1024]; // primary wad file
char mapdir[1024]; // directory of development maps
char basedefault[1024]; // default 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 (event_t* ev)
{
events[eventhead] = *ev;
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; eventtail = (++eventtail)&(MAXEVENTS-1))
{
ev = &events[eventtail];
if (CO_Responder(ev))
{
continue; // console ate the event
}
if (M_Responder(ev))
{
continue; // 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 = -1;
static int borderdrawcount;
int nowtime;
int tics;
int wipestart;
int y;
boolean done;
boolean wipe;
boolean redrawsbar;
if (nodrawers)
return; // for comparative timing / profiling
redrawsbar = false;
// change the view size if needed
if (setsizeneeded)
{
//WriteDebug("setsizeneeded...\n");
R_ExecuteSetViewSize ();
oldgamestate = -1; // force background redraw
borderdrawcount = 3;
}
// save the current screen if about to wipe
if (gamestate != wipegamestate)
{
//WriteDebug("wipe_StartScreen...\n");
wipe = true;
wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
}
else
wipe = false;
if (gamestate == GS_LEVEL && gametic)
{
//WriteDebug("HU_Erase...\n");
HU_Erase();
}
// do buffered drawing
switch (gamestate)
{
case GS_LEVEL:
//WriteDebug("GS_LEVEL - 1...\n");
if (!gametic)
break;
//WriteDebug("GS_LEVEL - 2...\n");
if (automapactive)
AM_Drawer ();
//WriteDebug("GS_LEVEL - 3...\n");
if (wipe || (viewheight != SCREENHEIGHT && fullscreen) )
redrawsbar = true;
if (inhelpscreensstate && !inhelpscreens)
redrawsbar = true; // just put away the help screen
//WriteDebug("GS_LEVEL - 4...\n");
ST_Drawer (viewheight == SCREENHEIGHT, redrawsbar );
//WriteDebug("GS_LEVEL - 5...\n");
fullscreen = viewheight == SCREENHEIGHT;
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)
{
//WriteDebug("R_RenderPlayerView...\n");
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 != SCREENWIDTH && viewheight != SCREENHEIGHT)
{
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
CO_Drawer(); // Console is drawn on top of even the menu...
NetUpdate (); // send out any new accumulation
// normal update
if (!wipe)
{
I_FinishUpdate (); // 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);
wipestart = nowtime;
done = wipe_ScreenWipe(wipe_Melt, 0, 0, SCREENWIDTH, SCREENHEIGHT, tics);
I_UpdateNoBlit ();
M_Drawer (); // menu is drawn even on top of wipes
CO_Drawer(); // Console is drawn on top of even the menu...
I_FinishUpdate (); // page flip or blit buffer
}
while(!done);
}
//
// D_DoomLoop
//
extern int demotype;
extern boolean 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);
sprintf(MsgText, "debug output to: %s\n",filename);
WriteDebug(MsgText);
debugfile = fopen (filename,"w");
}
I_InitGraphics ();
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 ();
#ifndef SNDSERV
// Sound mixing for the buffer is snychronous.
//I_UpdateSound();
#endif
// Synchronous sound output is explicitly called.
#ifndef SNDINTR
// Update sound output.
//I_SubmitSound();
#endif
}
}
void MY_DoomSetup(void)
{
if (demorecording)
G_BeginRecording ();
//WriteDebug("MY_DoomSetup...\n");
if (M_CheckParm ("-debugfile"))
{
char filename[20];
sprintf (filename,"debug%i.txt",consoleplayer);
//printf ("debug output to: %s\n",filename);
sprintf(MsgText, "debug output to: %s\n",filename);
WriteDebug(MsgText);
debugfile = fopen (filename,"w");
}
I_SetPalette (W_CacheLumpName("PLAYPAL", PU_CACHE));
}
void MY_DoomLoop (void)
{
//WriteDebug("MY_DoomLoop...\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -