📄 d_net.c
字号:
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------//// $Id: d_net.c,v 1.2 2003/09/08 22:34:27 jasonk Exp $//// 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: d_net.c,v $// Revision 1.2 2003/09/08 22:34:27 jasonk// Updated files because this fucker won't build for no fucking good reason.//// Revision 1.1.1.1 2003/09/04 21:08:12 jasonk// Initial import//// Revision 1.1 2000/12/08 21:07:51 jeffw// nxdoom initial entry -- No nxdoom/Makefile so it won't build automatically////// DESCRIPTION:// DOOM Network game communication and protocol,// all OS independend parts.////-----------------------------------------------------------------------------static const char rcsid[] = "$Id: d_net.c,v 1.2 2003/09/08 22:34:27 jasonk Exp $";#include "m_menu.h"#include "i_system.h"#include "i_video.h"#include "i_net.h"#include "g_game.h"#include "doomdef.h"#include "doomstat.h"#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->playerticcmd_t localcmds[BACKUPTICS];ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];int nettics[MAXNETNODES];boolean nodeingame[MAXNETNODES]; // set false as nodes leave gameboolean remoteresend[MAXNETNODES]; // set when local needs ticsint resendto[MAXNETNODES]; // set when remote needs ticsint resendcount[MAXNETNODES];int nodeforplayer[MAXPLAYERS];int maketic;int lastnettic;int skiptics;int ticdup; int maxsend; // BACKUPTICS/(2*ticdup)-1void D_ProcessEvents (void); void G_BuildTiccmd (ticcmd_t *cmd); void D_DoAdvanceDemo (void); boolean reboundpacket;doomdata_t reboundstore;//////int NetbufferSize (void){ return (int)&(((doomdata_t *)0)->cmds[netbuffer->numtics]); }//// Checksum //unsigned NetbufferChecksum (void){ unsigned c; int i,l; c = 0x1234567; // FIXME -endianess?#ifdef 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//voidHSendPacket (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 ();}//// 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; 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -