ref: 77536ac40b44c210f01141a3722104550a937cbe
dir: /doom-udpip/
diff 790a516884e45ee2a3a11b915f5e125a0ccb02ca uncommitted
--- a/sys/src/games/doom/i_net.c
+++ b/sys/src/games/doom/i_net.c
@@ -20,142 +20,296 @@
//
//-----------------------------------------------------------------------------
-static const char
-rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
-
#include "doomdef.h"
#include "doomstat.h"
-
-// #include "i_system.h"
-// #include "d_event.h"
-#include "d_net.h"
+#include <bio.h>
+#include <ndb.h>
+#include <ip.h>
+#include <thread.h>
#include "m_argv.h"
-
+#include "i_system.h"
+#include "d_net.h"
#include "i_net.h"
+#include "w_wad.h"
+typedef struct Addr Addr;
-//
-// I_InitNetwork
-//
-void I_InitNetwork (void)
+enum{
+ HDRSZ = 16+16+16+2+2 /* sizeof Udphdr w/o padding */
+};
+
+static char lsrv[6] = "666";
+
+struct Addr{
+ Udphdr h;
+ char srv[6]; /* convenience */
+ int ready; /* is connected to udp!*!lsrv */
+ long called;
+};
+static Addr raddr[MAXNETNODES];
+
+static int ucfd;
+static int udfd;
+static int upfd[2];
+static int upid;
+
+
+static void
+conreq(doomdata_t *d)
{
-printf("PORTME i_net.c I_InitNetwork (use 9P)\n");
+ int fd;
+ long t;
+ char ip[64];
+ Addr *p;
- doomcom = malloc (sizeof(*doomcom));
- memset (doomcom, 0, sizeof(*doomcom));
+ p = &raddr[doomcom->remotenode];
- /* set up for network */
- doomcom->ticdup = 1;
- doomcom->extratics = 0;
+ t = time(nil);
+ if(t - p->called < 1)
+ return;
-// netsend = PacketSend;
-// netget = PacketGet;
-// netgame = true;
+ snprint(ip, sizeof ip, "%I", p->h.raddr);
+ if((fd = dial(netmkaddr(ip, "udp", p->srv), lsrv, nil, nil)) < 0)
+ sysfatal("dial: %r");
+ if(write(fd, d, doomcom->datalength) != doomcom->datalength)
+ sysfatal("conreq: %r");
+ close(fd);
+ p->called = t;
+}
- /* parse player number and host list */
-// doomcom->consoleplayer = myargv[i+1][0]-'1';
+static void
+dsend(void)
+{
+ int i;
+ uchar buf[HDRSZ+sizeof(doomdata_t)];
+ doomdata_t d;
- doomcom->numnodes = 1; // this node for sure
+ hnputl(&d.checksum, netbuffer->checksum);
+ d.player = netbuffer->player;
+ d.retransmitfrom = netbuffer->retransmitfrom;
+ d.starttic = netbuffer->starttic;
+ d.numtics = netbuffer->numtics;
- doomcom->id = DOOMCOM_ID;
- doomcom->numplayers = doomcom->numnodes;
+ for(i = 0; i < netbuffer->numtics; i++){
+ d.cmds[i].forwardmove = netbuffer->cmds[i].forwardmove;
+ d.cmds[i].sidemove = netbuffer->cmds[i].sidemove;
+ hnputs(&d.cmds[i].angleturn, netbuffer->cmds[i].angleturn);
+ hnputs(&d.cmds[i].consistancy, netbuffer->cmds[i].consistancy);
+ d.cmds[i].chatchar = netbuffer->cmds[i].chatchar;
+ d.cmds[i].buttons = netbuffer->cmds[i].buttons;
+ }
-/*
- boolean trueval = true;
- int i;
- int p;
- struct hostent* hostentry; // host information entry
-
- 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<myargc-1)
- {
- DOOMPORT = atoi (myargv[p+1]);
- printf ("using alternate port %i\n",DOOMPORT);
- }
-
- // parse network game options,
- // -net <consoleplayer> <host> <host> ...
- 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;
- }
+ if(!raddr[doomcom->remotenode].ready){
+ conreq(&d);
+ return;
+ }
+ memcpy(buf, &raddr[doomcom->remotenode].h, HDRSZ);
+ memcpy(buf+HDRSZ, &d, sizeof d);
- netsend = PacketSend;
- netget = PacketGet;
- netgame = true;
+ i = doomcom->datalength + HDRSZ;
+ if(write(udfd, buf, i) != i)
+ sysfatal("dsend: %r");
+}
- // parse player number and host list
- doomcom->consoleplayer = myargv[i+1][0]-'1';
+static void
+drecv(void)
+{
+ int n;
+ ushort i;
+ doomdata_t d;
- doomcom->numnodes = 1; // this node for sure
-
- i++;
- while (++i < myargc && myargv[i][0] != '-')
- {
- sendaddress[doomcom->numnodes].sin_family = AF_INET;
- sendaddress[doomcom->numnodes].sin_port = htons(DOOMPORT);
- if (myargv[i][0] == '.')
- {
- sendaddress[doomcom->numnodes].sin_addr.s_addr
- = inet_addr (myargv[i]+1);
+ if(filelength(upfd[1]) < 1){
+ doomcom->remotenode = -1;
+ return;
}
- else
- {
- hostentry = gethostbyname (myargv[i]);
- if (!hostentry)
- I_Error ("gethostbyname: couldn't find %s", myargv[i]);
- sendaddress[doomcom->numnodes].sin_addr.s_addr
- = *(int *)hostentry->h_addr_list[0];
+ if((n = read(upfd[1], &d, sizeof d)) <= 0
+ || read(upfd[1], &i, sizeof i) <= 0)
+ sysfatal("drecv: %r");
+
+ doomcom->remotenode = i;
+ doomcom->datalength = n;
+
+ /* FIXME: proper read/write from/to struct */
+ netbuffer->checksum = nhgetl(&d.checksum);
+ netbuffer->player = d.player;
+ netbuffer->retransmitfrom = d.retransmitfrom;
+ netbuffer->starttic = d.starttic;
+ netbuffer->numtics = d.numtics;
+ for(i = 0; i < netbuffer->numtics; i++){
+ netbuffer->cmds[i].forwardmove = d.cmds[i].forwardmove;
+ netbuffer->cmds[i].sidemove = d.cmds[i].sidemove;
+ netbuffer->cmds[i].angleturn = nhgets(&d.cmds[i].angleturn);
+ netbuffer->cmds[i].consistancy = nhgets(&d.cmds[i].consistancy);
+ netbuffer->cmds[i].chatchar = d.cmds[i].chatchar;
+ netbuffer->cmds[i].buttons = d.cmds[i].buttons;
}
- doomcom->numnodes++;
- }
-
- doomcom->id = DOOMCOM_ID;
- doomcom->numplayers = doomcom->numnodes;
-*/
}
+static void
+uproc(void*)
+{
+ int n;
+ ushort i;
+ uchar buf[HDRSZ+sizeof(doomdata_t)];
+ Udphdr h;
-void I_NetCmd (void)
+ upid = getpid();
+ for(;;){
+ if((n = read(udfd, buf, sizeof buf)) <= 0)
+ break;
+ memcpy(&h, buf, HDRSZ);
+
+ for(i = 0; i < doomcom->numnodes; i++)
+ if(equivip6(h.raddr, raddr[i].h.raddr)
+ && nhgets(h.rport) == nhgets(raddr[i].h.rport))
+ break;
+ if(i == doomcom->numnodes)
+ continue; /* ignore messages from strangers */
+ if(!raddr[i].ready){ /* FIXME: urgh */
+ raddr[i].ready++;
+ memcpy(&raddr[i].h, &h, sizeof h);
+ }
+
+ if(write(upfd[0], buf+HDRSZ, n - HDRSZ) != n - HDRSZ
+ || write(upfd[0], &i, sizeof i) != sizeof i)
+ break;
+ }
+}
+
+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);
-*/
+ if(doomcom->command == CMD_SEND)
+ dsend();
+ else if(doomcom->command == CMD_GET)
+ drecv();
+ else
+ I_Error("invalid netcmd %d", doomcom->command);
+}
+
+void
+I_ShutdownNet(void)
+{
+ postnote(PNPROC, upid, "shutdown");
+ close(upfd[0]);
+ close(upfd[1]);
+ close(udfd);
+ close(ucfd);
+}
+
+static void
+initudp(void)
+{
+ char data[64], adir[40];
+
+ /* FIXME */
+ //if(myipaddr(raddr[0].h.raddr, nil) < 0)
+ // sysfatal("myipaddr: %r");
+
+ if((ucfd = announce(netmkaddr("*", "udp", lsrv), adir)) < 0)
+ sysfatal("announce: %r");
+ if(fprint(ucfd, "headers") < 0)
+ sysfatal("failed to set headers mode: %r");
+ snprint(data, sizeof data, "%s/data", adir);
+ if((udfd = open(data, ORDWR)) < 0)
+ sysfatal("open: %r");
+
+ if(pipe(upfd) < 0)
+ sysfatal("pipe: %r");
+ if(procrfork(uproc, nil, mainstacksize, RFFDG) < 0)
+ sysfatal("procrfork: %r");
+}
+
+static void
+csip(char *s, Addr *a) /* raddr!rsrv */
+{
+ int fd, n;
+ char buf[128], *f[3];
+
+ /* FIXME: get netmnt... */
+
+ if((fd = open("/net/cs", ORDWR)) < 0)
+ sysfatal("open: %r");
+
+ snprint(buf, sizeof buf, "udp!%s", s);
+ n = strlen(buf);
+ if(write(fd, buf, n) != n)
+ sysfatal("translating %s: %r", s);
+
+ seek(fd, 0, 0);
+ if((n = read(fd, buf, sizeof(buf)-1)) <= 0)
+ sysfatal("reading cs tables: %r");
+ buf[n] = 0;
+ close(fd);
+
+ if(getfields(buf, f, 3, 1, " !") < 2)
+ sysfatal("bad cs entry %s", buf);
+
+ if(parseip(a->h.raddr, f[1]) < 0)
+ sysfatal("parseip: %r");
+ hnputs(a->h.rport, atoi(f[2])); /* FIXME */
+ strncpy(a->srv, f[2], sizeof(a->srv)-1);
+}
+
+static int
+netopts(void)
+{
+ int i;
+
+ if((i = M_CheckParm("-dup")) && i < myargc - 1){
+ doomcom->ticdup = myargv[i+1][0] - '0';
+ if(doomcom->ticdup < 1)
+ doomcom->ticdup = 1;
+ if(doomcom->ticdup > 9)
+ doomcom->ticdup = 9;
+ }
+
+ if(M_CheckParm("-extratic"))
+ doomcom->extratics = 1;
+
+ if((i = M_CheckParm("-srv")) && i < myargc - 1)
+ strncpy(lsrv, myargv[i+1], sizeof(lsrv)-1);
+
+ /* [0-3], default 0; player 0 is special */
+ if((i = M_CheckParm("-pn")) && i < myargc - 1)
+ doomcom->consoleplayer = myargv[i+1][0] - '0';
+
+ /* FIXME: d_net.c: don't use remoteaddr=0 as special case (max+1?) */
+ /* remote host address list: -net raddr!rsrv.. */
+ if((i = M_CheckParm("-net")) == 0){
+ /* single player game */
+ doomcom->id = DOOMCOM_ID;
+ doomcom->numplayers = doomcom->numnodes = 1;
+ doomcom->deathmatch = false;
+ netgame = false;
+ return -1;
+ }
+ doomcom->numnodes++; /* raddr[0] is special cased because ??? */
+ while(++i < myargc && myargv[i][0] != '-'){
+ csip(myargv[i], &raddr[doomcom->numnodes]);
+ doomcom->numnodes++;
+ }
+
+ return 0;
+}
+
+void
+I_InitNetwork(void)
+{
+ doomcom = malloc(sizeof *doomcom);
+ memset(doomcom, 0, sizeof *doomcom);
+
+ doomcom->ticdup = 1;
+ doomcom->extratics = 0;
+ if(netopts() < 0)
+ return;
+ if(doomcom->numnodes < 2)
+ I_Error("netgame with a single node");
+ doomcom->id = DOOMCOM_ID;
+ doomcom->numplayers = doomcom->numnodes;
+
+ fmtinstall('I', eipfmt);
+ initudp();
+
+ netgame = true;
}
--- a/sys/src/games/doom/i_net.h
+++ b/sys/src/games/doom/i_net.h
@@ -35,6 +35,7 @@
void I_InitNetwork (void);
void I_NetCmd (void);
+void I_ShutdownNet (void);
#endif
--- a/sys/src/games/doom/i_system.c
+++ b/sys/src/games/doom/i_system.c
@@ -6,6 +6,7 @@
#include "i_system.h"
#include "i_sound.h"
#include "i_video.h"
+#include "i_net.h"
#include "d_main.h"
#include "d_net.h"
@@ -42,6 +43,7 @@
void I_Quit (void)
{
D_QuitNetGame ();
+ I_ShutdownNet();
I_ShutdownSound();
I_ShutdownMusic();
M_SaveDefaults ();
@@ -86,6 +88,7 @@
G_CheckDemoStatus();
D_QuitNetGame ();
+ I_ShutdownNet();
I_ShutdownGraphics();
exits("I_Error");
--- a/sys/src/games/doom/w_wad.h
+++ b/sys/src/games/doom/w_wad.h
@@ -67,6 +67,8 @@
void* W_CacheLumpNum (int lump, int tag);
void* W_CacheLumpName (char* name, int tag);
+vlong filelength(int);
+
#endif
//-----------------------------------------------------------------------------
//