⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d_main.c

📁 DOOM游戏的源码,研究DOS下游戏设计
💻 C
📖 第 1 页 / 共 3 页
字号:
// 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 + -