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

📄 g_game.c

📁 游戏类程序源代码---WinDoom 3D源程序.zip
💻 C
📖 第 1 页 / 共 4 页
字号:
// 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:  none
//
//-----------------------------------------------------------------------------


static const char
rcsid[] = "$Id: g_game.c,v 1.8 1997/02/03 22:45:09 b1 Exp $";

#include <string.h>
#include <stdlib.h>

#include "doomdef.h" 
#include "doomstat.h"

#include "z_zone.h"
#include "f_finale.h"
#include "m_argv.h"
#include "m_misc.h"
#include "m_menu.h"
#include "m_random.h"
#include "i_system.h"

#include "p_setup.h"
#include "p_saveg.h"
#include "p_tick.h"

#include "d_main.h"

#include "wi_stuff.h"
#include "hu_stuff.h"
#include "st_stuff.h"
#include "am_map.h"

// Needs access to LFB.
#include "v_video.h"

#include "w_wad.h"

#include "p_local.h" 

#include "s_sound.h"

// Data.
#include "dstrings.h"
#include "sounds.h"

// SKY handling - still the wrong place.
#include "r_data.h"
#include "r_sky.h"



#include "g_game.h"


#define SAVEGAMESIZE	0x2c000
#define SAVESTRINGSIZE	24

void WriteDebug(char *);
char MsgText[256];

boolean	G_CheckDemoStatus (void); 
void	G_ReadDemoTiccmd (ticcmd_t* cmd); 
void	G_WriteDemoTiccmd (ticcmd_t* cmd); 
void	G_PlayerReborn (int player); 
void	G_InitNew (skill_t skill, int episode, int map); 
 
void	G_DoReborn (int playernum); 
 
void	G_DoLoadLevel (void); 
void	G_DoNewGame (void); 
void	G_DoLoadGame (void); 
void	G_DoPlayDemo (void); 
void	G_DoPlayDemo_II(void); 
void	G_DoCompleted (void); 
void	G_DoVictory (void); 
void	G_DoWorldDone (void); 
void	G_DoSaveGame (void); 
 
 
gameaction_t    gameaction; 
gamestate_t     gamestate; 
skill_t         gameskill; 
boolean		respawnmonsters;
int             gameepisode; 
int             gamemap; 
 
boolean         paused; 
boolean         sendpause;             	// send a pause event next tic 
boolean         sendsave;             	// send a save event next tic 
boolean         usergame;               // ok to save / end game 
 
boolean         timingdemo;             // if true, exit with report on completion 
boolean         nodrawers;              // for comparative timing purposes 
boolean         noblit;                 // for comparative timing purposes 
int             starttime;          	// for comparative timing purposes  	 
 
boolean         viewactive; 
 
boolean         deathmatch;           	// only if started as net death 
boolean         netgame;                // only true if packets are broadcast 
boolean         playeringame[MAXPLAYERS]; 
player_t        players[MAXPLAYERS]; 
 
int             consoleplayer;          // player taking events and displaying 
int             displayplayer;          // view being displayed 
int             gametic; 
int             levelstarttic;          // gametic at level start 
int             totalkills, totalitems, totalsecret;    // for intermission 
 
char            demoname[32]; 
int             demotype; 
boolean         demorecording; 
boolean         demoplayback; 
boolean		netdemo; 
byte*		demobuffer;
byte*		demo_p;
byte*		demoend; 
boolean         singledemo;            	// quit after playing a demo from cmdline 
 
boolean         precache = true;        // if true, load all graphics at start 
 
wbstartstruct_t wminfo;               	// parms for world map / intermission 
 
short		consistancy[MAXPLAYERS][BACKUPTICS]; 
 
byte*		savebuffer;
 
 
// 
// controls (have defaults) 
// 
int     key_right;
int		key_left;

int		key_up;
int		key_down; 
int     key_strafeleft;
int	    key_straferight; 
int     key_fire;
int		key_use;
int		key_strafe;
int     key_speed; 

int     key_mvert;
 
int     mousebfire; 
int     mousebstrafe; 
int     mousebforward; 
 
int     mouseb1;
int     mouseb2;
int     mouseb3;

int     joybfire; 
int     joybstrafe; 
int     joybuse; 
int     joybspeed; 

int     joyb1;
int     joyb2;
int     joyb3;
int     joyb4;
 
int     always_run;
int     swap_stereo;
int     mvert;
int     keylink;
int     link_alt;
 
#define MAXPLMOVE		(forwardmove[1]) 
 
#define TURBOTHRESHOLD	0x32

fixed_t		forwardmove[2] = {0x19, 0x32};
fixed_t		sidemove[2] = {0x18, 0x28}; 
fixed_t		angleturn[3] = {640, 1280, 320};	// + slow turn 

#define SLOWTURNTICS	6 
 
#define NUMKEYS		256 

boolean         gamekeydown[NUMKEYS]; 
int             turnheld;				// for accelerative turning 
 
boolean		mousearray[4]; 
boolean*	mousebuttons = &mousearray[1];		// allow [-1]

// mouse values are used once 
int             mousex;
int		mousey;         

int             dclicktime;
int		dclickstate;
int		dclicks; 
int             dclicktime2;
int		dclickstate2;
int		dclicks2;

// joystick values are repeated 
int             joyxmove;
int		joyymove;
boolean         joyarray[5]; 
boolean*	joybuttons = &joyarray[1];		// allow [-1] 
 
int		savegameslot; 
char		savedescription[32]; 
 
 
#define	BODYQUESIZE	32

mobj_t*		bodyque[BODYQUESIZE]; 
int		bodyqueslot; 
 
void*		statcopy;				// for statistics driver

// DQ start addition 
extern int gEyePixelOffset;
extern long ScreensYLookup[];
extern BUFFER gRenderBuffer;
// DQ end addition
 
 
int G_CmdChecksum (ticcmd_t* cmd) 
{ 
    int		i;
    int		sum = 0; 
	 
    for (i=0 ; i< sizeof(*cmd)/4 - 1 ; i++) 
	sum += ((int *)cmd)[i]; 
		 
    return sum; 
} 
 

//
// G_BuildTiccmd
// Builds a ticcmd from all of the available inputs
// or reads it from the demo buffer. 
// If recording a demo, write it out 
// 
void G_BuildTiccmd (ticcmd_t* cmd) 
   { 
    int       i; 
    boolean   strafe;
    boolean   bstrafe; 
    int       speed;
    int       tspeed; 
    int       forward;
    int       side;
    ticcmd_t *base;


    base = I_BaseTiccmd ();		// empty, or external driver
    memcpy (cmd,base,sizeof(*cmd)); 
	
    cmd->consistancy = consistancy[consoleplayer][maketic%BACKUPTICS]; 
 
    strafe = gamekeydown[key_strafe] || mousebuttons[mousebstrafe] || joybuttons[joybstrafe]; 
    if ((joybspeed == 31) || (always_run == TRUE))
       speed = 1;
    else
       speed = gamekeydown[key_speed] || joybuttons[joybspeed];
    
 
    forward = side = 0;
    
    // use two stage accelerative turning on the keyboard and joystick
    if (joyxmove < 0 || joyxmove > 0 || gamekeydown[key_right] || gamekeydown[key_left]) 
        turnheld += ticdup; 
    else 
        turnheld = 0; 

    if (turnheld < SLOWTURNTICS) 
        tspeed = 2;             // slow turn 
    else 
        tspeed = speed;
    
    // let movement keys cancel each other out
    if (strafe) 
       { 
        if (gamekeydown[key_right]) 
           {
            // fprintf(stderr, "strafe right\n");
            side += sidemove[speed]; 
           }
        if (gamekeydown[key_left]) 
           {
            // fprintf(stderr, "strafe left\n");
            side -= sidemove[speed]; 
           }
        if (joyxmove > 0) 
            side += sidemove[speed]; 
        if (joyxmove < 0) 
            side -= sidemove[speed]; 
       } 
    else 
       { 
        if (gamekeydown[key_right]) 
            cmd->angleturn -= angleturn[tspeed]; 
        if (gamekeydown[key_left]) 
            cmd->angleturn += angleturn[tspeed]; 
        if (joyxmove > 0) 
            cmd->angleturn -= angleturn[tspeed]; 
        if (joyxmove < 0) 
            cmd->angleturn += angleturn[tspeed]; 
       } 
 
    if (gamekeydown[key_up]) 
       {
        // fprintf(stderr, "up\n");
        forward += forwardmove[speed]; 
       }
    if (gamekeydown[key_down]) 
       {
        // fprintf(stderr, "down\n");
        forward -= forwardmove[speed]; 
       }
    if (joyymove < 0) 
        forward += forwardmove[speed]; 
    if (joyymove > 0) 
        forward -= forwardmove[speed]; 
    if (gamekeydown[key_straferight]) 
        side += sidemove[speed]; 
    if (gamekeydown[key_strafeleft]) 
        side -= sidemove[speed];
    
    // buttons
    cmd->chatchar = HU_dequeueChatChar(); 
 
    if (gamekeydown[key_fire] || mousebuttons[mousebfire] || joybuttons[joybfire]) 
       {
        cmd->buttons |= BT_ATTACK;
       }
 
    if (gamekeydown[key_use] || joybuttons[joybuse] ) 
       { 
        cmd->buttons |= BT_USE;
        // clear double clicks if hit use button 
        dclicks = 0;                   
       } 

    // chainsaw overrides 
    for (i = 0; i < NUMWEAPONS-1; i++)
        if (gamekeydown[KEY_1+i])
           { 
            cmd->buttons |= BT_CHANGE; 
            cmd->buttons |= i<<BT_WEAPONSHIFT; 
            break; 
           }
    
    // mouse
    if (mousebuttons[mousebforward]) 
        forward += forwardmove[speed];
    
    // forward double click
    if (mousebuttons[mousebforward] != dclickstate && dclicktime > 1 ) 
       { 
        dclickstate = mousebuttons[mousebforward]; 
        if (dclickstate) 
            dclicks++; 
        if (dclicks == 2) 
           { 
            cmd->buttons |= BT_USE; 
            dclicks = 0; 
           } 
        else 
            dclicktime = 0; 
       } 
    else 
       { 
        dclicktime += ticdup; 
        if (dclicktime > 20) 
           { 
            dclicks = 0; 
            dclickstate = 0; 
           } 
       }
    
    // strafe double click
    bstrafe = mousebuttons[mousebstrafe] || joybuttons[joybstrafe]; 
    if (bstrafe != dclickstate2 && dclicktime2 > 1 ) 
       { 
        dclickstate2 = bstrafe; 
        if (dclickstate2) 
            dclicks2++; 
        if (dclicks2 == 2) 
           { 
            cmd->buttons |= BT_USE; 
            dclicks2 = 0; 
           } 
        else 
           dclicktime2 = 0; 
       } 
    else 
       { 
        dclicktime2 += ticdup; 
        if (dclicktime2 > 20) 
           { 
            dclicks2 = 0; 
            dclickstate2 = 0; 
           } 
       } 
 
    forward += mousey; 
    if (strafe) 
        side += mousex*2; 
    else 
        cmd->angleturn -= mousex*0x8; 

    mousex = mousey = 0;
	 
    if (forward > MAXPLMOVE) 
        forward = MAXPLMOVE; 
    else
    if (forward < -MAXPLMOVE) 
        forward = -MAXPLMOVE; 
    if (side > MAXPLMOVE) 
        side = MAXPLMOVE; 
    else
    if (side < -MAXPLMOVE) 
        side = -MAXPLMOVE; 
 
    cmd->forwardmove += forward; 
    cmd->sidemove += side;
    
    // special buttons
    if (sendpause)
       { 
        sendpause = false; 
        cmd->buttons = BT_SPECIAL | BTS_PAUSE; 
       } 
 
    if (sendsave)
       { 
        sendsave = false; 
        cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (savegameslot << BTS_SAVESHIFT); 
       } 
   } 
 

//
// G_DoLoadLevel 
//
extern  gamestate_t     wipegamestate; 
 
void G_DoLoadLevel (void) 
{ 
    int             i; 
	 BUFFER			  TempBuffer;

    // Set the sky map.
    // First thing, we have a dummy sky texture name,
    //  a flat. The data is in the WAD only because
    //  we look for an actual index, instead of simply
    //  setting one.
    skyflatnum = R_FlatNumForName ( SKYFLATNAME );

    // DOOM determines the sky texture to be used
    // depending on the current episode, and the game version.
    if ( (gamemode == commercial) // Doom II
	 || ( gamemode == addon_tnt )
	 || ( gamemode == addon_plut ) )
    {
	skytexture = R_TextureNumForName ("SKY3");
	if (gamemap < 12)
	    skytexture = R_TextureNumForName ("SKY1");
	else
	    if (gamemap < 21)
		skytexture = R_TextureNumForName ("SKY2");
    //WriteDebug("Sky set...\n");
    }

    levelstarttic = gametic;        // for time calculation
    
    if (wipegamestate == GS_LEVEL) 
	wipegamestate = -1;             // force a wipe 

    gamestate = GS_LEVEL; 

    for (i=0 ; i<MAXPLAYERS ; i++) 
    { 
	if (playeringame[i] && players[i].playerstate == PST_DEAD) 
	    players[i].playerstate = PST_REBORN; 
	memset (players[i].frags,0,sizeof(players[i].frags)); 
    } 
		 
    //WriteDebug("P_SetupLevel\n");
    P_SetupLevel (gameepisode, gamemap, 0, gameskill);    
    displayplayer = consoleplayer;		// view the guy you are playing    
    starttime = I_GetTime (); 
    gameaction = ga_nothing; 
    //WriteDebug("Z_CheckHeap\n");
    Z_CheckHeap ();
    
    // clear cmd building stuff
    memset (gamekeydown, 0, sizeof(gamekeydown)); 
    joyxmove = joyymove = 0; 
    mousex = mousey = 0; 
    sendpause = sendsave = paused = false; 
    memset (mousebuttons, 0, sizeof(mousebuttons)); 
    memset (joybuttons, 0, sizeof(joybuttons)); 
    //WriteDebug("G_DoLoadLevel done\n");
	 TempBuffer.Buffer = screens[1]; // DQ - background screens
	 TempBuffer.YLookup = ScreensYLookup; // DQ
    R_FillBackScreen(&TempBuffer/*DQ*/);

} 
 
 
//
// G_Responder  
// Get info needed to make ticcmd_ts for the players.
// 
boolean G_Responder(event_t* ev) 
   { 
    // allow spy mode changes even during the demo
    if (gamestate == GS_LEVEL && ev->type == ev_keydown && ev->data1 == KEY_F12 && (singledemo || !deathmatch))
       {
        // spy mode 
        do 
           { 
            displayplayer++; 
            if (displayplayer == MAXPLAYERS) 
                displayplayer = 0; 
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -