From bef7af18c671dbe1ff4d822206a15f4bcab56e67 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 19 Feb 2006 13:42:27 +0000 Subject: Move tic number expansion code to common code. Parse game data packets received from the server. Strip down d_net.[ch] to work through the new networking code. Remove game sync code. Remove i_net.[ch] as it is no longer needed. Working networking! Subversion-branch: /trunk/chocolate-doom Subversion-revision: 374 --- src/Makefile.am | 1 - src/d_net.c | 594 ++++++------------------------------------------------- src/doomstat.h | 13 +- src/g_game.c | 14 +- src/i_net.c | 364 ---------------------------------- src/i_net.h | 58 ------ src/net_client.c | 153 +++++++++++++- src/net_common.c | 32 ++- src/net_common.h | 12 +- src/net_server.c | 39 ++-- 10 files changed, 302 insertions(+), 978 deletions(-) delete mode 100644 src/i_net.c delete mode 100644 src/i_net.h diff --git a/src/Makefile.am b/src/Makefile.am index 942f974d..53aad1b6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,7 +43,6 @@ g_game.c g_game.h \ hu_lib.c hu_lib.h \ hu_stuff.c hu_stuff.h \ i_main.c \ -i_net.c i_net.h \ info.c info.h \ i_sound.c i_sound.h \ i_system.c i_system.h \ diff --git a/src/d_net.c b/src/d_net.c index 7327850d..8e6ec48e 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: d_net.c 291 2006-01-13 23:56:00Z fraggle $ +// $Id: d_net.c 374 2006-02-19 13:42:27Z fraggle $ // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005 Simon Howard @@ -22,6 +22,14 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.17 2006/02/19 13:42:27 fraggle +// Move tic number expansion code to common code. Parse game data packets +// received from the server. +// Strip down d_net.[ch] to work through the new networking code. Remove +// game sync code. +// Remove i_net.[ch] as it is no longer needed. +// Working networking! +// // Revision 1.16 2006/01/13 23:56:00 fraggle // Add text-mode I/O functions. // Use text-mode screen for the waiting screen. @@ -89,7 +97,7 @@ //----------------------------------------------------------------------------- -static const char rcsid[] = "$Id: d_net.c 291 2006-01-13 23:56:00Z fraggle $"; +static const char rcsid[] = "$Id: d_net.c 374 2006-02-19 13:42:27Z fraggle $"; #include "d_main.h" @@ -97,7 +105,6 @@ static const char rcsid[] = "$Id: d_net.c 291 2006-01-13 23:56:00Z fraggle $"; #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" @@ -117,7 +124,6 @@ static const char rcsid[] = "$Id: d_net.c 291 2006-01-13 23:56:00Z fraggle $"; doomcom_t* doomcom; -doomdata_t* netbuffer; // points inside doomcom // @@ -132,20 +138,12 @@ doomdata_t* netbuffer; // points inside doomcom #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 nettics[MAXPLAYERS]; int maketic; + int lastnettic; -int skiptics; int ticdup; int maxsend; // BACKUPTICS/(2*ticdup)-1 @@ -154,284 +152,6 @@ void D_ProcessEvents (void); void G_BuildTiccmd (ticcmd_t *cmd); void D_DoAdvanceDemo (void); -boolean reboundpacket; -doomdata_t reboundstore; - - - -// -// -// -int NetbufferSize (void) -{ - doomdata_t *dummy = NULL; - - return ((byte *) &dummy->cmds[netbuffer->numtics]) - ((byte *) dummy); -} - -// -// Checksum -// -unsigned NetbufferChecksum (void) -{ - unsigned c; - int i,l; - - c = 0x1234567; - - // FIXME -endianess? - return 0; // byte order problems - - l = (NetbufferSize () - (int)&(((doomdata_t *)0)->retransmitfrom))/4; - for (i=0 ; iretransmitfrom)[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 ; idatalength ; 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 ; idatalength ; 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 @@ -452,178 +172,46 @@ void NetUpdate (void) NET_CL_Run(); NET_SV_Run(); - + // check time nowtime = I_GetTime ()/ticdup; newtics = nowtime - gametime; gametime = nowtime; - + if (newtics <= 0) // nothing new to update - goto listen; + return; - 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 35) + break; + I_StartTic (); D_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 ; inumnodes ; 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] = - 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 (); -} - + G_BuildTiccmd(&cmd); + if (netgame) + { + NET_CL_SendTiccmd(&cmd, maketic); + } -// -// CheckAbort -// -void CheckAbort (void) -{ - event_t *ev; - int stoptic; - - stoptic = I_GetTime () + 2; - while (I_GetTime() < stoptic) - I_StartTic (); - - I_StartTic (); - - while ((ev = D_PopEvent()) != NULL) - { - if (ev->type == ev_keydown && ev->data1 == KEY_ESCAPE) - I_Error ("Network game synchronization aborted."); - } -} - + netcmds[consoleplayer][maketic % BACKUPTICS] = cmd; -// -// 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 != DOOM_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; - } - } + ++maketic; + nettics[consoleplayer] = maketic; } - else - { - // key player, send the setup info - printf ("sending network start info...\n"); - do - { - CheckAbort (); - for (i=0 ; inumnodes ; i++) - { - netbuffer->retransmitfrom = startskill; - if (deathmatch) - netbuffer->retransmitfrom |= (deathmatch<<6); - if (nomonsters) - netbuffer->retransmitfrom |= 0x20; - if (respawnparm) - netbuffer->retransmitfrom |= 0x10; - netbuffer->starttic = startepisode * 64 + startmap; - netbuffer->player = DOOM_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 ; inumnodes ; i++) - if (!gotinfo[i]) - break; - } while (i < doomcom->numnodes); - } -} // // D_CheckNetGame @@ -634,7 +222,22 @@ extern int viewangleoffset; void D_CheckNetGame (void) { net_addr_t *addr = NULL; - int i; + int i; + int num_players; + + // default values for single player + + consoleplayer = 0; + netgame = false; + ticdup = 1; + + for (i=0; i 0) { - addr = net_sdl_module.ResolveAddress("127.0.0.1"); + addr = net_sdl_module.ResolveAddress("localhost"); } if (addr != NULL) @@ -664,40 +267,19 @@ void D_CheckNetGame (void) } } - for (i=0 ; iid != DOOMCOM_ID) - I_Error ("Doomcom buffer invalid!"); - - netbuffer = &doomcom->data; - consoleplayer = displayplayer = doomcom->consoleplayer; - if (netgame) - D_ArbitrateNetStart (); printf ("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 ; inumplayers ; i++) - playeringame[i] = true; - for (i=0 ; inumnodes ; i++) - nodeingame[i] = true; - printf ("player %i of %i (%i nodes)\n", - consoleplayer+1, doomcom->numplayers, doomcom->numnodes); + consoleplayer+1, num_players, num_players); } @@ -716,20 +298,6 @@ void D_QuitNetGame (void) NET_SV_Shutdown(); NET_CL_Disconnect(); - - 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 ; jnumnodes ; j++) - if (nodeingame[j]) - HSendPacket (j, NCMD_EXIT); - I_WaitVBL (1); - } } @@ -737,9 +305,6 @@ void D_QuitNetGame (void) // // TryRunTics // -int frametics[4]; -int frameon; -int frameskip[4]; int oldnettics; extern boolean advancedemo; @@ -765,14 +330,15 @@ void TryRunTics (void) lowtic = INT_MAX; numplaying = 0; - for (i=0 ; inumnodes ; i++) + + for (i=0; i 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) @@ -828,8 +364,8 @@ void TryRunTics (void) NetUpdate (); lowtic = INT_MAX; - for (i=0 ; inumnodes ; i++) - if (nodeingame[i] && nettics[i] < lowtic) + for (i=0; i #include @@ -824,12 +832,14 @@ void G_Ticker (void) if (netgame && !netdemo && !(gametic%ticdup) ) { + /* if (gametic > BACKUPTICS && consistancy[i][buf] != cmd->consistancy) { I_Error ("consistency failure (%i should be %i)", cmd->consistancy, consistancy[i][buf]); } + */ if (players[i].mo) consistancy[i][buf] = players[i].mo->x; else diff --git a/src/i_net.c b/src/i_net.c deleted file mode 100644 index a79ec445..00000000 --- a/src/i_net.c +++ /dev/null @@ -1,364 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id: i_net.c 58 2005-08-30 22:15:11Z fraggle $ -// -// Copyright(C) 1993-1996 Id Software, Inc. -// Copyright(C) 2005 Simon Howard -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -// 02111-1307, USA. -// -// $Log$ -// Revision 1.7 2005/08/30 22:15:11 fraggle -// More Windows fixes -// -// Revision 1.6 2005/08/30 22:11:10 fraggle -// Windows fixes -// -// Revision 1.5 2005/08/12 16:54:15 fraggle -// Port network code to use SDL_net -// -// Revision 1.4 2005/08/04 18:42:15 fraggle -// Silence compiler warnings -// -// Revision 1.3 2005/07/23 18:56:07 fraggle -// Remove unneccessary pragmas -// -// Revision 1.2 2005/07/23 16:44:55 fraggle -// Update copyright to GNU GPL -// -// Revision 1.1.1.1 2005/07/23 16:20:32 fraggle -// Initial import -// -// -// DESCRIPTION: -// -//----------------------------------------------------------------------------- - -static const char -rcsid[] = "$Id: i_net.c 58 2005-08-30 22:15:11Z fraggle $"; - -#include -#include -#include - -#include - -#include "i_system.h" -#include "d_event.h" -#include "d_net.h" -#include "m_argv.h" - -#include "doomstat.h" - -#include "i_net.h" - - - - - -void NetSend (void); -boolean NetListen (void); - - -// -// NETWORKING -// - -int DOOMPORT = 8626; - -#ifndef NO_SDL_NET - -static UDPsocket udpsocket; -static UDPpacket *packet; - -static IPaddress sendaddress[MAXNETNODES]; - -void (*netget) (void); -void (*netsend) (void); - - -unsigned short host_to_net16(unsigned int value) -{ - union - { - unsigned short s; - char b[2]; - } data; - - SDLNet_Write16(value, data.b); - - return data.s; -} - -unsigned short net_to_host16(unsigned int value) -{ - unsigned short s = value; - - return SDLNet_Read16(&s); -} - -unsigned long host_to_net32(unsigned int value) -{ - union - { - unsigned long l; - char b[4]; - } data; - - SDLNet_Write32(value, data.b); - - return data.l; -} - -unsigned long net_to_host32(unsigned int value) -{ - union - { - unsigned long l; - char b[4]; - } data; - - data.l = value; - - return SDLNet_Read32(data.b); -} - - -// -// PacketSend -// -void PacketSend (void) -{ - int c; - doomdata_t *sw; - - sw = (doomdata_t *) packet->data; - - // byte swap - sw->checksum = host_to_net32(netbuffer->checksum); - sw->player = netbuffer->player; - sw->retransmitfrom = netbuffer->retransmitfrom; - sw->starttic = netbuffer->starttic; - sw->numtics = netbuffer->numtics; - - for (c=0 ; c< netbuffer->numtics ; c++) - { - sw->cmds[c].forwardmove = netbuffer->cmds[c].forwardmove; - sw->cmds[c].sidemove = netbuffer->cmds[c].sidemove; - sw->cmds[c].angleturn = host_to_net16(netbuffer->cmds[c].angleturn); - sw->cmds[c].consistancy = host_to_net16(netbuffer->cmds[c].consistancy); - sw->cmds[c].chatchar = netbuffer->cmds[c].chatchar; - sw->cmds[c].buttons = netbuffer->cmds[c].buttons; - } - - packet->len = doomcom->datalength; - packet->address = sendaddress[doomcom->remotenode]; - - if (!SDLNet_UDP_Send(udpsocket, -1, packet)) - { - I_Error("Error sending packet: %s", SDLNet_GetError()); - } -} - - -// -// PacketGet -// -void PacketGet (void) -{ - int i; - int c; - doomdata_t *sw; - int packets_read; - - packets_read = SDLNet_UDP_Recv(udpsocket, packet); - - if (packets_read < 0) - { - I_Error("Error reading packet: %s\n", SDLNet_GetError()); - } - - if (packets_read == 0) - { - doomcom->remotenode = -1; - return; - } - - // find remote node number - for (i=0 ; inumnodes ; i++) - if (packet->address.host == sendaddress[i].host - && packet->address.port == sendaddress[i].port) - break; - - if (i == doomcom->numnodes) - { - // packet is not from one of the players (new game broadcast) - doomcom->remotenode = -1; // no packet - return; - } - - doomcom->remotenode = i; // good packet from a game player - doomcom->datalength = packet->len; - - sw = (doomdata_t *) packet->data; - - // byte swap - netbuffer->checksum = net_to_host32(sw->checksum); - netbuffer->player = sw->player; - netbuffer->retransmitfrom = sw->retransmitfrom; - netbuffer->starttic = sw->starttic; - netbuffer->numtics = sw->numtics; - - for (c=0 ; c< netbuffer->numtics ; c++) - { - netbuffer->cmds[c].forwardmove = sw->cmds[c].forwardmove; - netbuffer->cmds[c].sidemove = sw->cmds[c].sidemove; - netbuffer->cmds[c].angleturn = net_to_host16(sw->cmds[c].angleturn); - netbuffer->cmds[c].consistancy = net_to_host16(sw->cmds[c].consistancy); - netbuffer->cmds[c].chatchar = sw->cmds[c].chatchar; - netbuffer->cmds[c].buttons = sw->cmds[c].buttons; - } -} - - -// -// I_InitNetwork -// -void I_InitNetwork (void) -{ - int i; - int p; - - doomcom = malloc (sizeof (*doomcom) ); - memset (doomcom, 0, sizeof(*doomcom) ); - - // set up for network - i = M_CheckParm ("-dup"); - if (i && i< myargc-1) - { - doomcom->ticdup = myargv[i+1][0]-'0'; - if (doomcom->ticdup < 1) - doomcom->ticdup = 1; - if (doomcom->ticdup > 9) - doomcom->ticdup = 9; - } - else - doomcom-> ticdup = 1; - - if (M_CheckParm ("-extratic")) - doomcom-> extratics = 1; - else - doomcom-> extratics = 0; - - p = M_CheckParm ("-port"); - if (p && p ... - i = M_CheckParm ("-net"); - if (!i) - { - // single player game - netgame = false; - doomcom->id = DOOMCOM_ID; - doomcom->numplayers = doomcom->numnodes = 1; - doomcom->deathmatch = false; - doomcom->consoleplayer = 0; - return; - } - - netsend = PacketSend; - netget = PacketGet; - netgame = true; - - // parse player number and host list - doomcom->consoleplayer = myargv[i+1][0]-'1'; - - doomcom->numnodes = 1; // this node for sure - - SDLNet_Init(); - - i++; - while (++i < myargc && myargv[i][0] != '-') - { - if (SDLNet_ResolveHost(&sendaddress[doomcom->numnodes], - myargv[i], DOOMPORT)) - { - I_Error("Unable to resolve %s", myargv[i]); - } - - doomcom->numnodes++; - } - - doomcom->id = DOOMCOM_ID; - doomcom->numplayers = doomcom->numnodes; - - // build message to receive - - udpsocket = SDLNet_UDP_Open(DOOMPORT); - - packet = SDLNet_AllocPacket(5000); -} - - -void I_NetCmd (void) -{ - if (doomcom->command == CMD_SEND) - { - netsend (); - } - else if (doomcom->command == CMD_GET) - { - netget (); - } - else - I_Error ("Bad net cmd: %i\n",doomcom->command); -} - -#else - -void I_NetCmd(void) -{ -} - - -void I_InitNetwork (void) -{ - doomcom = malloc (sizeof (*doomcom) ); - memset (doomcom, 0, sizeof(*doomcom) ); - - doomcom->ticdup = 1; - doomcom->extratics = 0; - - - // single player game - netgame = false; - doomcom->id = DOOMCOM_ID; - doomcom->numplayers = doomcom->numnodes = 1; - doomcom->deathmatch = false; - doomcom->consoleplayer = 0; - return; -} - - -#endif /* #ifndef NO_SDL_NET */ - - diff --git a/src/i_net.h b/src/i_net.h deleted file mode 100644 index 7e255dda..00000000 --- a/src/i_net.h +++ /dev/null @@ -1,58 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id: i_net.h 18 2005-07-23 18:56:07Z fraggle $ -// -// Copyright(C) 1993-1996 Id Software, Inc. -// Copyright(C) 2005 Simon Howard -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -// 02111-1307, USA. -// -// DESCRIPTION: -// System specific network interface stuff. -// -//----------------------------------------------------------------------------- - - -#ifndef __I_NET__ -#define __I_NET__ - - - - - -// Called by D_DoomMain. - - -void I_InitNetwork (void); -void I_NetCmd (void); - - -#endif -//----------------------------------------------------------------------------- -// -// $Log$ -// Revision 1.3 2005/07/23 18:56:07 fraggle -// Remove unneccessary pragmas -// -// Revision 1.2 2005/07/23 16:44:55 fraggle -// Update copyright to GNU GPL -// -// Revision 1.1.1.1 2005/07/23 16:20:32 fraggle -// Initial import -// -// -//----------------------------------------------------------------------------- diff --git a/src/net_client.c b/src/net_client.c index 1b5c057e..fba35cad 100644 --- a/src/net_client.c +++ b/src/net_client.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_client.c 371 2006-02-17 21:40:52Z fraggle $ +// $Id: net_client.c 374 2006-02-19 13:42:27Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,14 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.26 2006/02/19 13:42:27 fraggle +// Move tic number expansion code to common code. Parse game data packets +// received from the server. +// Strip down d_net.[ch] to work through the new networking code. Remove +// game sync code. +// Remove i_net.[ch] as it is no longer needed. +// Working networking! +// // Revision 1.25 2006/02/17 21:40:52 fraggle // Full working resends for client->server comms // @@ -139,6 +147,24 @@ typedef enum } net_clientstate_t; +// Type of structure used in the receive window + +typedef struct +{ + // Whether this tic has been received yet + + boolean active; + + // Last time we sent a resend request for this tic + + unsigned int resend_time; + + // Tic data from server + + net_full_ticcmd_t cmd; + +} net_server_recv_t; + static net_connection_t client_connection; static net_clientstate_t client_state; static net_addr_t *server_addr; @@ -181,6 +207,73 @@ static ticcmd_t last_ticcmd; static net_ticdiff_t ticcmd_send_queue[NET_TICCMD_QUEUE_SIZE]; +// Receive window + +static ticcmd_t recvwindow_cmd_base[MAXPLAYERS]; +static int recvwindow_start; +static net_server_recv_t recvwindow[BACKUPTICS]; + +#define NET_CL_ExpandTicNum(b) NET_ExpandTicNum(recvwindow_start, (b)) + +static void NET_CL_ExpandTiccmds(net_full_ticcmd_t *cmd) +{ + int i; + + for (i=0; iplayeringame[i]; + + if (playeringame[i]) + { + net_ticdiff_t *diff; + ticcmd_t ticcmd; + + diff = &cmd->cmds[i]; + + // Use the ticcmd diff to patch the previous ticcmd to + // the new ticcmd + + NET_TiccmdPatch(&recvwindow_cmd_base[i], diff, &ticcmd); + + // Save in d_net.c structures + + netcmds[i][nettics[i] % BACKUPTICS] = ticcmd; + ++nettics[i]; + + // Store a copy for next time + + recvwindow_cmd_base[i] = ticcmd; + } + } +} + +// Advance the receive window + +static void NET_CL_AdvanceWindow(void) +{ + while (recvwindow[0].active) + { + // Expand tic diff data into d_net.c structures + + NET_CL_ExpandTiccmds(&recvwindow[0].cmd); + + // Advance the window + + memcpy(recvwindow, recvwindow + 1, + sizeof(net_server_recv_t) * (BACKUPTICS - 1)); + memset(&recvwindow[BACKUPTICS-1], 0, sizeof(net_server_recv_t)); + + ++recvwindow_start; + + //printf("CL: advanced to %i\n", recvwindow_start); + } +} + // Shut down the client code, etc. Invoked after a disconnect. static void NET_CL_Shutdown(void) @@ -379,10 +472,60 @@ static void NET_CL_ParseGameStart(net_packet_t *packet) startmap = settings.map; startskill = settings.skill; + memset(recvwindow, 0, sizeof(recvwindow)); + recvwindow_start = 0; + memset(&recvwindow_cmd_base, 0, sizeof(recvwindow_cmd_base)); + netgame = true; autostart = true; } +static void NET_CL_ParseGameData(net_packet_t *packet) +{ + unsigned int seq, num_tics; + int i; + + // Read header + + if (!NET_ReadInt8(packet, &seq) + || !NET_ReadInt8(packet, &num_tics)) + { + return; + } + + // Expand byte value into the full tic number + + seq = NET_CL_ExpandTicNum(seq); + + for (i=0; i= BACKUPTICS) + { + // Out of range of the recv window + + continue; + } + + // Store in the receive window + + recvobj = &recvwindow[index]; + + recvobj->active = true; + recvobj->cmd = cmd; + } +} + static void NET_CL_ParseTimeRequest(net_packet_t *packet) { net_packet_t *reply; @@ -453,6 +596,7 @@ static void NET_CL_ParsePacket(net_packet_t *packet) break; case NET_PACKET_TYPE_GAMEDATA: + NET_CL_ParseGameData(packet); break; case NET_PACKET_TYPE_TIME_REQ: @@ -511,6 +655,13 @@ void NET_CL_Run(void) net_waiting_for_start = client_connection.state == NET_CONN_STATE_CONNECTED && client_state == CLIENT_STATE_WAITING_START; + + if (client_state == CLIENT_STATE_IN_GAME) + { + // Possibly advance the receive window + + NET_CL_AdvanceWindow(); + } } static void NET_CL_SendSYN(void) diff --git a/src/net_common.c b/src/net_common.c index 92c050e1..d79d30ec 100644 --- a/src/net_common.c +++ b/src/net_common.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_common.c 279 2006-01-10 19:59:26Z fraggle $ +// $Id: net_common.c 374 2006-02-19 13:42:27Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,14 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.5 2006/02/19 13:42:27 fraggle +// Move tic number expansion code to common code. Parse game data packets +// received from the server. +// Strip down d_net.[ch] to work through the new networking code. Remove +// game sync code. +// Remove i_net.[ch] as it is no longer needed. +// Working networking! +// // Revision 1.4 2006/01/10 19:59:26 fraggle // Reliable packet transport mechanism // @@ -489,3 +497,25 @@ net_packet_t *NET_Conn_NewReliable(net_connection_t *conn, int packet_type) return packet; } +// Used to expand the least significant byte of a tic number into +// the full tic number, from the current tic number + +unsigned int NET_ExpandTicNum(unsigned int relative, unsigned int b) +{ + unsigned int l, h; + unsigned int result; + + h = relative & ~0xff; + l = relative & 0xff; + + result = h | b; + + if (l < 0x40 && b > 0xb0) + result -= 0x100; + if (l > 0xb0 && b < 0x40) + result += 0x100; + + return result; +} + + diff --git a/src/net_common.h b/src/net_common.h index 4f5605dc..657804fb 100644 --- a/src/net_common.h +++ b/src/net_common.h @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_common.h 279 2006-01-10 19:59:26Z fraggle $ +// $Id: net_common.h 374 2006-02-19 13:42:27Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,14 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.4 2006/02/19 13:42:27 fraggle +// Move tic number expansion code to common code. Parse game data packets +// received from the server. +// Strip down d_net.[ch] to work through the new networking code. Remove +// game sync code. +// Remove i_net.[ch] as it is no longer needed. +// Working networking! +// // Revision 1.3 2006/01/10 19:59:26 fraggle // Reliable packet transport mechanism // @@ -103,5 +111,7 @@ void NET_Conn_Disconnect(net_connection_t *conn); void NET_Conn_Run(net_connection_t *conn); net_packet_t *NET_Conn_NewReliable(net_connection_t *conn, int packet_type); +unsigned int NET_ExpandTicNum(unsigned int relative, unsigned int b); + #endif /* #ifndef NET_COMMON_H */ diff --git a/src/net_server.c b/src/net_server.c index 05154a0a..6da52a3f 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -1,7 +1,7 @@ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // -// $Id: net_server.c 372 2006-02-17 21:42:13Z fraggle $ +// $Id: net_server.c 374 2006-02-19 13:42:27Z fraggle $ // // Copyright(C) 2005 Simon Howard // @@ -21,6 +21,14 @@ // 02111-1307, USA. // // $Log$ +// Revision 1.28 2006/02/19 13:42:27 fraggle +// Move tic number expansion code to common code. Parse game data packets +// received from the server. +// Strip down d_net.[ch] to work through the new networking code. Remove +// game sync code. +// Remove i_net.[ch] as it is no longer needed. +// Working networking! +// // Revision 1.27 2006/02/17 21:42:13 fraggle // Remove debug code // @@ -212,23 +220,7 @@ static net_gamesettings_t sv_settings; static unsigned int recvwindow_start; static net_client_recv_t recvwindow[BACKUPTICS][MAXPLAYERS]; -static unsigned int NET_SV_ExpandTicNum(unsigned int i) -{ - unsigned int l, h; - unsigned int result; - - h = recvwindow_start & ~0xff; - l = recvwindow_start & 0xff; - - result = h | i; - - if (l < 0x40 && i > 0xb0) - result -= 0x100; - if (l > 0xb0 && i < 0x40) - result += 0x100; - - return result; -} +#define NET_SV_ExpandTicNum(b) NET_ExpandTicNum(recvwindow_start, (b)) static void NET_SV_DisconnectClient(net_client_t *client) { @@ -800,6 +792,9 @@ static void NET_SV_ParseGameData(net_packet_t *packet, net_client_t *client) return; } + //if (rand() % 8 == 0) + // return; + player = client->player_number; // Read header @@ -1109,6 +1104,14 @@ static void NET_SV_PumpSendQueue(net_client_t *client) for (i=0; i