?? d_main.c
字號(hào):
// 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"
// DQ addition for test
#include "dxerr.h"
// DQ end addition
char MsgText[256];
void WriteDebug(char *);
// DQ addition start
int gEyePixelOffset = 8; // send half to each separation, rounding the odd half to the positive offset
int gLCDYaw16thDegree = 32; // parallel views are preferred for stereo, to prevent keystoning
BOOL bInStereo = FALSE;
extern menu_t* currentMenu;
extern short itemOn; // menu item skull is on
extern long ScreensYLookup[];
void GetRenderBuffer(BOOL bLeftEye, BOOL bStereo, PBUFFER RenderBuffer, PBUFFER RenderViewWindowBuffer);
extern long ScreensYLookup[];
extern BUFFER gRenderBuffer;
extern BOOL bInGame;
// DQ addition end
//
// 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;
// DQ start addition
void R_ExecuteSetViewSize (int iRightPixelOffset,
int iLeftPixelOffset);
void R_SetCameraPosition(BOOL bLeftEye);
BOOL redrawborder = FALSE;
// DQ end addition
//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;
// DQ added start
int iEyeCounter = 0; // right first, left second
BOOL bEndWipe = FALSE;
byte * RightEndScreen = NULL;
BOOL bStereo;
int EyeOffset;
int TextEyeOffset;
int Yaw;
static int StatusBarRepeat = 0;
boolean Newmenuactive;
boolean Prevmenuactive;
short NewitemOn;
short PrevitemOn;
short NewlastOn;
short PrevlastOn;
void * NewcurrentMenu;
void * PrevcurrentMenu;
BUFFER RenderBuffer;
BUFFER RenderViewWindowBuffer;
BUFFER StartBuffer;
BUFFER BackgroundBuffer;
BUFFER LeftEndBuffer;
BUFFER RightEndBuffer;
BUFFER StatusBarBuffer;
boolean bRedrawBorder;
static short RedrawBorderRepeat = 0;
// DQ added end
if (nodrawers)
return; // for comparative timing / profiling
//WriteDebug("D_Display\n");
redrawsbar = false;
if (setsizeneeded)
{
R_ExecuteSetViewSize (EyeOffset/2,
-((EyeOffset+1)/2));
oldgamestate = -1; // force background redraw
borderdrawcount = 3;
}
// DQ start addition
// keep these values constant throughout this procedure, even if the user changes
// them with the console or menu or keyboard
bRedrawBorder = setsizeneeded | redrawborder;
if (bRedrawBorder)
{
RedrawBorderRepeat = 4;
}
redrawborder = FALSE; // turn the flag back off.
bStereo = bInStereo;
EyeOffset = gEyePixelOffset;
TextEyeOffset = (bStereo ? 6 : 0);
Yaw = gLCDYaw16thDegree;
wipe = false;
if (gamestate != wipegamestate)
{
wipe = true;
}
BackgroundBuffer.Buffer = screens[1];
BackgroundBuffer.YLookup = ScreensYLookup;
StartBuffer.Buffer = screens[2];
StartBuffer.YLookup = ScreensYLookup;
LeftEndBuffer.Buffer = screens[3];
LeftEndBuffer.YLookup = ScreensYLookup;
StatusBarBuffer.Buffer = screens[4];
StatusBarBuffer.YLookup = ScreensYLookup;
Prevmenuactive = menuactive;
PrevcurrentMenu = currentMenu;
PrevitemOn = itemOn;
PrevlastOn = currentMenu->lastOn;
// keep looping while wiping. If mono, just render left eye
for (iEyeCounter = (bStereo ? 0 : 1);
iEyeCounter < 2 && bInGame;
iEyeCounter++) // 0 = right, 1 = left
{
GetRenderBuffer(iEyeCounter == 1, bStereo, &RenderBuffer, &RenderViewWindowBuffer);
R_SetCameraPosition(iEyeCounter == 1); // 0 = right, 1 = left
if (bRedrawBorder || RedrawBorderRepeat > 0)
{
R_DrawViewBorder(&RenderBuffer, &BackgroundBuffer); // DQ
if (RedrawBorderRepeat > 0) // repeat the border on all surfaces
{
RedrawBorderRepeat--;
}
}
// save the current screen if about to wipe
if (gamestate != wipegamestate)
{
//WriteDebug("wipe_StartScreen...\n");
// wipe = true; // DQ moved outside of loop
// DQ - use the image that is in RenderBuffer as the wipe screen for both eyes - it
// is a bit old but since we almost always wipe from a static screen all buffers would
// have the image, and it gets garbled so the stereo effect from it is unnecessary
// DQ start addition
wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT, &StartBuffer/*DQ*/, &RenderBuffer);
}
// DQ end addition
//wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); // original line
// else // DQ moved outside of loop
// wipe = false; // DQ moved outside of loop
if (gamestate == GS_LEVEL && gametic)
{
//WriteDebug("HU_Erase...\n");
HU_Erase(&RenderBuffer, &BackgroundBuffer); // DQ
//HU_Erase();
}
// DQ addition end
// 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 (&RenderBuffer/*DQ*/);
//WriteDebug("GS_LEVEL - 3...\n");
if (wipe || (viewheight != SCREENHEIGHT && fullscreen) || setsizeneeded/*DQ*/)
redrawsbar = true;
if (inhelpscreensstate && !inhelpscreens)
redrawsbar = true; // just put away the help screen
// DQ start addition
// since we have up to four buffers if we are rendering directly into
// the display surface, and we only draw the status bar when needed, I
// am going to draw the status bar five consecutive renderings. Since
// we rotate through the buffers, the status bar will be rendered into
// all of them. If we are not rendering into the display buffer, then
// we just end up with four extra updates. Five, so we will draw at least
// two sets of pairs
if (redrawsbar)
{
StatusBarRepeat = 5;
}
if (StatusBarRepeat > 0)
{
redrawsbar = TRUE;
StatusBarRepeat--;
}
// DQ end addition
//WriteDebug("GS_LEVEL - 4...\n");
redrawsbar = TRUE; // forced to true, so that both eyes get same image
ST_Drawer (viewheight == SCREENHEIGHT, redrawsbar, &RenderBuffer, &StatusBarBuffer); // DQ
//ST_Drawer (viewheight == SCREENHEIGHT, redrawsbar);
//WriteDebug("GS_LEVEL - 5...\n");
fullscreen = viewheight == SCREENHEIGHT;
break;
case GS_INTERMISSION:
// the intermission background image was put into the background buffer
// in the call to G_DoCompleted
WI_Drawer ((iEyeCounter == 0 ? -(TextEyeOffset/2) : (TextEyeOffset+1)/2)/*DQ*/,
&RenderBuffer/*DQ*/,
&BackgroundBuffer/*DQ*/);
break;
case GS_FINALE:
F_Drawer (&RenderBuffer/*DQ*/);
break;
case GS_DEMOSCREEN:
D_PageDrawer (&RenderBuffer/*DQ*/);
break;
}
// draw buffered stuff to screen
I_UpdateNoBlit();
// draw the view directly
if (gamestate == GS_LEVEL && !automapactive && gametic)
{
// DQ start addition
//WriteDebug("R_RenderPlayerView...\n");
if (iEyeCounter == 0)
{
// render right eye
R_RenderPlayerView (&players[displayplayer],
(fixed_t)(EyeOffset/2) << FRACBITS,
Yaw,
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -