// wait for all ackreturns with timeout in seconds void Net_WaitAllAckReceived(UINT32 timeout) { tic_t tictac = I_GetTime(); timeout = tictac + timeout*TICRATE; HGetPacket(); while (timeout > I_GetTime() && !Net_AllAckReceived()) { while (tictac == I_GetTime()) I_Sleep(); tictac = I_GetTime(); HGetPacket(); Net_AckTicker(); } }
// // D_ArbitrateNetStart // void D_ArbitrateNetStart (void) { int i; boolean gotinfo[MAXNETNODES]; autostart = true; memset (gotinfo,0,sizeof(gotinfo)); if (doomcom->consoleplayer) { // listen for setup info from key player printf ("listening for network start info...\n"); while (1) { CheckAbort (); if (!HGetPacket ()) continue; if (netbuffer->checksum & NCMD_SETUP) { if (netbuffer->player != VERSION) I_Error ("Different DOOM 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 = netbuffer->starttic >> 6; return; } } }
// wait for all ackreturns with timeout in seconds void Net_WaitAllAckReceived(UINT32 timeout) { #ifdef NONET (void)timeout; #else tic_t tictac = I_GetTime(); timeout = tictac + timeout*NEWTICRATE; HGetPacket(); while (timeout > I_GetTime() && !Net_AllAckReceived()) { while (tictac == I_GetTime()) I_Sleep(); tictac = I_GetTime(); HGetPacket(); Net_AckTicker(); } #endif }
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++; } } } }
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 {