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

📄 d_net.c

📁 制作游戏 魔法师传奇 源代码设计 MOFASHICHUANQI 经典老游戏
💻 C
📖 第 1 页 / 共 2 页
字号:
					localcmds[(realstart+j)%BACKUPTICS];

			if (remoteresend[i])
			{
				netbuffer->retransmitfrom = nettics[i];
				HSendPacket (i, NCMD_RETRANSMIT);
			}
			else
			{
				netbuffer->retransmitfrom = 0;
				HSendPacket (i, 0);
			}
		}

//
// listen for other packets
//
listen:

	GetPackets ();
}


/*
=====================
=
= CheckAbort
=
=====================
*/

void CheckAbort (void)
{
	event_t *ev;
	int             stoptic;

	stoptic = I_GetTime () + 2;
	while (I_GetTime() < stoptic)
		I_StartTic ();

	I_StartTic ();
	for ( ; eventtail != eventhead
	; eventtail = (++eventtail)&(MAXEVENTS-1) )
	{
		ev = &events[eventtail];
		if (ev->type == ev_keydown && ev->data1 == KEY_ESCAPE)
			I_Error ("Network game synchronization aborted.");
	}
}

/*
=====================
=
= D_ArbitrateNetStart
=
=====================
*/

void D_ArbitrateNetStart (void)
{
	int             i;
	boolean gotinfo[MAXNETNODES];
	boolean gotClass[MAXNETNODES];
#ifdef __WATCOMC__
	int nextTic;
	extern volatile int ticcount;

	nextTic = ticcount+8;
#endif

	autostart = true;

	memset (gotClass,0,sizeof(gotClass));
	memset (gotinfo,0,sizeof(gotinfo));
	gotClass[doomcom->consoleplayer] = true;
	do
	{
		i = 0;

		CheckAbort();
		while(HGetPacket())
		{ // Check for any incoming packets
			if(netbuffer->checksum&NCMD_SETUP && netbuffer->starttic >= 64)
			{
				
				PlayerClass[netbuffer->player] = netbuffer->starttic&0x3f;
				if(!gotClass[netbuffer->player])
				{
					gotClass[netbuffer->player] = true;
					ST_NetProgress();
					ST_Message("\n");
				}
				if(netbuffer->retransmitfrom)
				{ // that node has received info from all other nodes
					gotinfo[netbuffer->player] = true;
				}
			}
		}
#ifdef __WATCOMC__
		if(ticcount <= nextTic)
		{ // only send packets every half second
			continue;
		}
		nextTic = ticcount+8;
#endif
		// Keep sending out packets containing the console class
		for(i = 0; i < doomcom->numnodes; i++)
		{
			netbuffer->player = doomcom->consoleplayer;
			netbuffer->starttic = PlayerClass[doomcom->consoleplayer]+64;
			netbuffer->retransmitfrom = gotinfo[doomcom->consoleplayer];
			netbuffer->numtics = 0;
			HSendPacket(i, NCMD_SETUP);
		}
		for(i = 0; i < doomcom->numnodes; i++)
		{ // Make sure that all nodes have sent class info
			if (!gotClass[i])
			{
				ST_Message(".");
				break;
			}
		}
		if(i < doomcom->numnodes)
		{
			continue;
		}
		else
		{ // consoleplayer has received all player classes
			if(gotinfo[doomcom->consoleplayer])
			{
				CheckAbort();
			}
			else
			{
				gotinfo[doomcom->consoleplayer] = true;
				ST_Message("All player classes received, ready to proceed\n");
				ST_NetDone();
			}
		}
		for (i = 0; i < doomcom->numnodes; i++)
		{ // Make sure that all nodes are ready to proceed
			if (!gotinfo[i])
			{
				break;
			}
		}
	} while(i < doomcom->numnodes);

	memset (gotinfo,0,sizeof(gotinfo));

	if (doomcom->consoleplayer)
	{       // listen for setup info from key player
//              ST_Message ("listening for network start info...\n");
		while (1)
		{
			CheckAbort ();
			if (!HGetPacket ())
				continue;
			if(netbuffer->checksum & NCMD_SETUP && netbuffer->starttic < 64)
			{
				if (netbuffer->player != VERSION)
					I_Error ("Different HEXEN versions cannot play a net game!");
				startskill = netbuffer->retransmitfrom & 15;
				deathmatch = (netbuffer->retransmitfrom & 0xc0) >> 6;
				nomonsters = (netbuffer->retransmitfrom & 0x20) > 0;
				respawnparm = (netbuffer->retransmitfrom & 0x10) > 0;
				startmap = netbuffer->starttic & 0x3f;
				startepisode = 1;
				return;
			}
		}
	}
	else
	{       // key player, send the setup info
//              ST_Message ("sending network start info...\n");
		do
		{
			CheckAbort ();
			for (i=0 ; i<doomcom->numnodes ; i++)
			{
				netbuffer->retransmitfrom = startskill;
				if (deathmatch)
					netbuffer->retransmitfrom |= (deathmatch<<6);
				if (nomonsters)
					netbuffer->retransmitfrom |= 0x20;
				if (respawnparm)
					netbuffer->retransmitfrom |= 0x10;
				netbuffer->starttic = startmap&0x3f;
				netbuffer->player = VERSION;
				netbuffer->numtics = 0;
				HSendPacket (i, NCMD_SETUP);
			}

#if 1
			for(i = 10 ; i  &&  HGetPacket(); --i)
			{
 if((netbuffer->player&0x7f) < MAXNETNODES)
				gotinfo[netbuffer->player&0x7f] = true;
			}
#else
			while (HGetPacket ())
			{
				gotinfo[netbuffer->player&0x7f] = true;
			}
#endif

			for (i=1 ; i<doomcom->numnodes ; i++)
				if (!gotinfo[i])
					break;
		} while (i < doomcom->numnodes);
	}
}

/*
===================
=
= D_CheckNetGame
=
= Works out player numbers among the net participants
===================
*/

extern  int                     viewangleoffset;

void D_CheckNetGame (void)
{
	int             i;
	int pClass;

	for (i=0 ; i<MAXNETNODES ; i++)
	{
		nodeingame[i] = false;
		nettics[i] = 0;
		remoteresend[i] = false;        // set when local needs tics
		resendto[i] = 0;                        // which tic to start sending
	}

// I_InitNetwork sets doomcom and netgame
	I_InitNetwork ();
	if (doomcom->id != DOOMCOM_ID)
		I_Error ("Doomcom buffer invalid!");
	netbuffer = &doomcom->data;
	consoleplayer = displayplayer = doomcom->consoleplayer;
	pClass = PCLASS_FIGHTER;
	if(i = M_CheckParm("-class"))
	{
		pClass = atoi(myargv[i+1]);
		if(pClass > PCLASS_MAGE || pClass < PCLASS_FIGHTER)
		{
			I_Error("Invalid player class: %d\n", pClass);
		}
		ST_Message("\nPlayer Class: %d\n", pClass);
	}
	PlayerClass[consoleplayer] = pClass;
	if (netgame)
		D_ArbitrateNetStart ();
//ST_Message ("startskill %i  deathmatch: %i  startmap: %i  startepisode: %i\n", startskill, deathmatch, startmap, startepisode);

// read values out of doomcom
	ticdup = doomcom->ticdup;
	maxsend = BACKUPTICS/(2*ticdup)-1;
	if (maxsend<1)
		maxsend = 1;

	for (i=0 ; i<doomcom->numplayers ; i++)
		playeringame[i] = true;
	for (i=0 ; i<doomcom->numnodes ; i++)
		nodeingame[i] = true;

//ST_Message ("player %i of %i (%i nodes)\n", consoleplayer+1, doomcom->numplayers, doomcom->numnodes);

}

/*
==================
=
= D_QuitNetGame
=
= Called before quitting to leave a net game without hanging the
= other players
=
==================
*/

void D_QuitNetGame (void)
{
	int             i, j;

	if (debugfile)
		fclose (debugfile);

	if (!netgame || !usergame || consoleplayer == -1 || demoplayback)
		return;

// send a bunch of packets for security
	netbuffer->player = consoleplayer;
	netbuffer->numtics = 0;
	for (i=0 ; i<4 ; i++)
	{
		for (j=1 ; j<doomcom->numnodes ; j++)
			if (nodeingame[j])
				HSendPacket (j, NCMD_EXIT);
		I_WaitVBL (1);
	}
}



/*
===============
=
= TryRunTics
=
===============
*/

int     frametics[4], frameon;
int     frameskip[4];
int             oldnettics;
extern  boolean advancedemo;

void TryRunTics (void)
{
	int             i;
	int             lowtic;
	int             entertic;
	static int              oldentertics;
	int                             realtics, availabletics;
	int                             counts;
	int                             numplaying;

//
// get real tics
//
	entertic = I_GetTime ()/ticdup;
	realtics = entertic - oldentertics;
	oldentertics = entertic;

//
// get available tics
//
	NetUpdate ();

	lowtic = MAXINT;
	numplaying = 0;
	for (i=0 ; i<doomcom->numnodes ; i++)
		if (nodeingame[i])
		{
			numplaying++;
			if (nettics[i] < lowtic)
				lowtic = nettics[i];
		}
	availabletics = lowtic - gametic/ticdup;


//
// decide how many tics to run
//
	if (realtics < availabletics-1)
		counts = realtics+1;
	else if (realtics < availabletics)
		counts = realtics;
	else
		counts = availabletics;
	if (counts < 1)
		counts = 1;

	frameon++;

if (debugfile)
	fprintf (debugfile,"=======real: %i  avail: %i  game: %i\n",realtics, availabletics,counts);

	if (!demoplayback)
	{
	//=============================================================================
	//
	//      ideally nettics[0] should be 1 - 3 tics above lowtic
	//      if we are consistantly slower, speed up time
	//
		for (i=0 ; i<MAXPLAYERS ; i++)
			if (playeringame[i])
				break;
		if (consoleplayer == i)
		{       // the key player does not adapt
		}
		else
		{
			if (nettics[0] <= nettics[nodeforplayer[i]])
			{
				gametime--;
	//                      printf ("-");
			}
			frameskip[frameon&3] = (oldnettics > nettics[nodeforplayer[i]]);
			oldnettics = nettics[0];
			if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3])
			{
				skiptics = 1;
	//                      printf ("+");
			}
		}
	//=============================================================================
	}       // demoplayback

	//
	// wait for new tics if needed
	//
		while (lowtic < gametic/ticdup + counts)
		{

			NetUpdate ();
			lowtic = MAXINT;

			for (i=0 ; i<doomcom->numnodes ; i++)
				if (nodeingame[i] && nettics[i] < lowtic)
					lowtic = nettics[i];

			if (lowtic < gametic/ticdup)
				I_Error ("TryRunTics: lowtic < gametic");

			// don't stay in here forever -- give the menu a chance to work
			if (I_GetTime ()/ticdup - entertic >= 20)
			{
				MN_Ticker ();
				return;
			}
		}

//
// run the count * ticdup dics
//
	while (counts--)
	{
		for (i=0 ; i<ticdup ; i++)
		{
			if (gametic/ticdup > lowtic)
				I_Error ("gametic>lowtic");
			if (advancedemo)
				H2_DoAdvanceDemo ();
			MN_Ticker ();
			G_Ticker ();
			gametic++;
			//
			// modify command for duplicated tics
			//
			if (i != ticdup-1)
			{
				ticcmd_t        *cmd;
				int                     buf;
				int                     j;

				buf = (gametic/ticdup)%BACKUPTICS;
				for (j=0 ; j<MAXPLAYERS ; j++)
				{
					cmd = &netcmds[j][buf];
					cmd->chatchar = 0;
					if (cmd->buttons & BT_SPECIAL)
						cmd->buttons = 0;
				}
			}
		}
		NetUpdate ();                                   // check for new console commands
	}
}

⌨️ 快捷键说明

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