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

📄 d_net.c

📁 制作游戏 魔法师传奇 源代码设计 MOFASHICHUANQI 经典老游戏
💻 C
📖 第 1 页 / 共 2 页
字号:

//**************************************************************************
//**
//** d_net.c : Heretic 2 : Raven Software, Corp.
//**
//** $RCSfile: d_net.c,v $
//** $Revision: 1.16 $
//** $Date: 96/01/01 03:39:44 $
//** $Author: bgokey $
//**
//** This version has the fixed ticdup code.
//**
//**************************************************************************

#include "h2def.h"
#include "p_local.h"
#include <stdlib.h> // for atoi()

#define NCMD_EXIT               0x80000000
#define NCMD_RETRANSMIT 0x40000000
#define NCMD_SETUP              0x20000000
#define NCMD_KILL               0x10000000              // kill game
#define NCMD_CHECKSUM   0x0fffffff


doomcom_t               *doomcom;
doomdata_t              *netbuffer;             // points inside doomcom


/*
==============================================================================

							NETWORKING

gametic is the tic about to (or currently being) run
maketic is the tick that hasn't had control made for it yet
nettics[] has the maketics for all players

a gametic cannot be run until nettics[] > gametic for all players

==============================================================================
*/

#define RESENDCOUNT     10
#define PL_DRONE        0x80                            // bit flag in doomdata->player

ticcmd_t                localcmds[BACKUPTICS];

ticcmd_t        netcmds[MAXPLAYERS][BACKUPTICS];
int             nettics[MAXNETNODES];
boolean                 nodeingame[MAXNETNODES];        // set false as nodes leave game
boolean                 remoteresend[MAXNETNODES];      // set when local needs tics
int                             resendto[MAXNETNODES];                  // set when remote needs tics
int                             resendcount[MAXNETNODES];

int                             nodeforplayer[MAXPLAYERS];

int             maketic;
int                             lastnettic, skiptics;
int                             ticdup;
int                             maxsend;        // BACKUPTICS/(2*ticdup)-1

void H2_ProcessEvents (void);
void G_BuildTiccmd (ticcmd_t *cmd);
void H2_DoAdvanceDemo (void);
extern void ST_NetProgress(void);
extern void ST_NetDone(void);

boolean                 reboundpacket;
doomdata_t              reboundstore;


int     NetbufferSize (void)
{
	return (int)&(((doomdata_t *)0)->cmds[netbuffer->numtics]);
}

unsigned NetbufferChecksum (void)
{
	unsigned                c;
	int             i,l;

	c = 0x1234567;

#if defined(NeXT) || defined(NORMALUNIX)
	return 0;                       // byte order problems
#endif

	l = (NetbufferSize () - (int)&(((doomdata_t *)0)->retransmitfrom))/4;
	for (i=0 ; i<l ; i++)
		c += ((unsigned *)&netbuffer->retransmitfrom)[i] * (i+1);

	return c & NCMD_CHECKSUM;
}

int ExpandTics (int low)
{
	int     delta;

	delta = low - (maketic&0xff);

	if (delta >= -64 && delta <= 64)
		return (maketic&~0xff) + low;
	if (delta > 64)
		return (maketic&~0xff) - 256 + low;
	if (delta < -64)
		return (maketic&~0xff) + 256 + low;

	I_Error ("ExpandTics: strange value %i at maketic %i",low,maketic);
	return 0;
}


//============================================================================


/*
==============
=
= HSendPacket
=
==============
*/

void HSendPacket (int node, int flags)
{
	netbuffer->checksum = NetbufferChecksum () | flags;

	if (!node)
	{
		reboundstore = *netbuffer;
		reboundpacket = true;
		return;
	}

	if (demoplayback)
		return;

	if (!netgame)
		I_Error ("Tried to transmit to another node");

	doomcom->command = CMD_SEND;
	doomcom->remotenode = node;
	doomcom->datalength = NetbufferSize ();

if (debugfile)
{
	int             i;
	int             realretrans;
	if (netbuffer->checksum & NCMD_RETRANSMIT)
		realretrans = ExpandTics (netbuffer->retransmitfrom);
	else
		realretrans = -1;
	fprintf (debugfile,"send (%i + %i, R %i) [%i] "
	,ExpandTics(netbuffer->starttic),netbuffer->numtics, realretrans, doomcom->datalength);
	for (i=0 ; i<doomcom->datalength ; i++)
		fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
	fprintf (debugfile,"\n");
}

	I_NetCmd ();
}

//==========================================================================
//
// NET_SendFrags
//
//==========================================================================

void NET_SendFrags(player_t *player)
{
	int i;
	int frags;

	netbuffer->checksum = NetbufferChecksum();

	if (demoplayback)
	{
		return;
	}
	if (!netgame)
	{
		I_Error ("Tried to transmit to another node");
	}

	frags = 0;
	for(i = 0; i < MAXPLAYERS; i++)
	{
		frags += player->frags[i];
	}
	doomcom->command = CMD_FRAG;
	doomcom->remotenode = frags;
	doomcom->datalength = NetbufferSize ();

	I_NetCmd ();
}

/*
==============
=
= HGetPacket
=
= Returns false if no packet is waiting
=
==============
*/

boolean HGetPacket (void)
{
	if (reboundpacket)
	{
		*netbuffer = reboundstore;
		doomcom->remotenode = 0;
		reboundpacket = false;
		return true;
	}

	if (!netgame)
		return false;
	if (demoplayback)
		return false;

	doomcom->command = CMD_GET;
	I_NetCmd ();
	if (doomcom->remotenode == -1)
		return false;

	if (doomcom->datalength != NetbufferSize ())
	{
		if (debugfile)
			fprintf (debugfile,"bad packet length %i\n",doomcom->datalength);
		return false;
	}

	if (NetbufferChecksum () != (netbuffer->checksum&NCMD_CHECKSUM) )
	{
		if (debugfile)
			fprintf (debugfile,"bad packet checksum\n");
		return false;
	}

if (debugfile)
{
	int             realretrans;
			int     i;

	if (netbuffer->checksum & NCMD_SETUP)
		fprintf (debugfile,"setup packet\n");
	else
	{
		if (netbuffer->checksum & NCMD_RETRANSMIT)
			realretrans = ExpandTics (netbuffer->retransmitfrom);
		else
			realretrans = -1;
		fprintf (debugfile,"get %i = (%i + %i, R %i)[%i] ",doomcom->remotenode,
		ExpandTics(netbuffer->starttic),netbuffer->numtics, realretrans, doomcom->datalength);
		for (i=0 ; i<doomcom->datalength ; i++)
			fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
		fprintf (debugfile,"\n");
	}
}
	return true;
}


/*
===================
=
= GetPackets
=
===================
*/

char    exitmsg[80];

void GetPackets (void)
{
	int             netconsole;
	int             netnode;
	ticcmd_t        *src, *dest;
	int             realend;
	int             realstart;

	while (HGetPacket ())
	{
		if (netbuffer->checksum & NCMD_SETUP)
			continue;               // extra setup packet

		netconsole = netbuffer->player & ~PL_DRONE;
		netnode = doomcom->remotenode;
		//
		// to save bytes, only the low byte of tic numbers are sent
		// Figure out what the rest of the bytes are
		//
		realstart = ExpandTics (netbuffer->starttic);
		realend = (realstart+netbuffer->numtics);

		//
		// check for exiting the game
		//
		if (netbuffer->checksum & NCMD_EXIT)
		{
			if (!nodeingame[netnode])
				continue;
			nodeingame[netnode] = false;
			playeringame[netconsole] = false;
			strcpy (exitmsg, "PLAYER 1 LEFT THE GAME");
			exitmsg[7] += netconsole;
			P_SetMessage(&players[consoleplayer], exitmsg, true);
			S_StartSound(NULL, SFX_CHAT);
//			players[consoleplayer].message = exitmsg;
//                      if (demorecording)
//                              G_CheckDemoStatus ();
			continue;
		}

		//
		// check for a remote game kill
		//
		if (netbuffer->checksum & NCMD_KILL)
			I_Error ("Killed by network driver");

		nodeforplayer[netconsole] = netnode;

		//
		// check for retransmit request
		//
		if ( resendcount[netnode] <= 0
		&& (netbuffer->checksum & NCMD_RETRANSMIT) )
		{
			resendto[netnode] = ExpandTics(netbuffer->retransmitfrom);
if (debugfile)
fprintf (debugfile,"retransmit from %i\n", resendto[netnode]);
			resendcount[netnode] = RESENDCOUNT;
		}
		else
			resendcount[netnode]--;

		//
		// check for out of order / duplicated packet
		//
		if (realend == nettics[netnode])
			continue;

		if (realend < nettics[netnode])
		{
if (debugfile)
fprintf (debugfile,"out of order packet (%i + %i)\n" ,realstart,netbuffer->numtics);
			continue;
		}

		//
		// check for a missed packet
		//
		if (realstart > nettics[netnode])
		{
		// stop processing until the other system resends the missed tics
if (debugfile)
fprintf (debugfile,"missed tics from %i (%i - %i)\n", netnode, realstart, nettics[netnode]);
			remoteresend[netnode] = true;
			continue;
		}

//
// update command store from the packet
//
{
	int             start;

		remoteresend[netnode] = false;

		start = nettics[netnode] - realstart;
		src = &netbuffer->cmds[start];

		while (nettics[netnode] < realend)
		{
			dest = &netcmds[netconsole][nettics[netnode]%BACKUPTICS];
			nettics[netnode]++;
			*dest = *src;
			src++;
		}
	}
}

}

/*
=============
=
= NetUpdate
=
= Builds ticcmds for console player
= sends out a packet
=============
*/

int      gametime;

void NetUpdate (void)
{
	int             nowtime;
	int             newtics;
	int                             i,j;
	int                             realstart;
	int                             gameticdiv;

//
// check time
//
	nowtime = I_GetTime ()/ticdup;
	newtics = nowtime - gametime;
	gametime = nowtime;

	if (newtics <= 0)                       // nothing new to update
		goto listen;

	if (skiptics <= newtics)
	{
		newtics -= skiptics;
		skiptics = 0;
	}
	else
	{
		skiptics -= newtics;
		newtics = 0;
	}


	netbuffer->player = consoleplayer;

//
// build new ticcmds for console player
//
	gameticdiv = gametic/ticdup;
	for (i=0 ; i<newtics ; i++)
	{
		I_StartTic ();
		H2_ProcessEvents ();
		if (maketic - gameticdiv >= BACKUPTICS/2-1)
			break;          // can't hold any more
//printf ("mk:%i ",maketic);
		G_BuildTiccmd (&localcmds[maketic%BACKUPTICS]);
		maketic++;
	}


	if (singletics)
		return;         // singletic update is syncronous

//
// send the packet to the other nodes
//
	for (i=0 ; i<doomcom->numnodes ; i++)
		if (nodeingame[i])
		{
			netbuffer->starttic = realstart = resendto[i];
			netbuffer->numtics = maketic - realstart;
			if (netbuffer->numtics > BACKUPTICS)
				I_Error ("NetUpdate: netbuffer->numtics > BACKUPTICS");

			resendto[i] = maketic - doomcom->extratics;

			for (j=0 ; j< netbuffer->numtics ; j++)
				netbuffer->cmds[j] =

⌨️ 快捷键说明

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