1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
6 // Copyright (C) 1993-1996 by id Software, Inc.
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
18 // Revision 1.1 2000/02/29 18:21:04 stegerg
19 // Doom port based on ADoomPPC. Read README.AROS!
24 //-----------------------------------------------------------------------------
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
39 #include <sys/ioctl.h>
49 #pragma implementation "i_net.h"
57 // For some odd reason...
59 ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
60 (((unsigned long int)(x) & 0x0000ff00U) << 8) | \
61 (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
62 (((unsigned long int)(x) & 0xff000000U) >> 24)))
65 ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
66 (((unsigned short int)(x) & 0xff00) >> 8))) \
68 #define htonl(x) ntohl(x)
69 #define htons(x) ntohs(x)
72 boolean
NetListen (void);
79 int DOOMPORT
= (IPPORT_USERRESERVED
+0x1d );
84 struct sockaddr_in sendaddress
[MAXNETNODES
];
86 void (*netget
) (void);
87 void (*netsend
) (void);
98 s
= socket (PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
100 I_Error ("can't create socket: %s",strerror(errno
));
114 struct sockaddr_in address
;
116 memset (&address
, 0, sizeof(address
));
117 address
.sin_family
= AF_INET
;
118 address
.sin_addr
.s_addr
= INADDR_ANY
;
119 address
.sin_port
= port
;
121 v
= bind (s
, (void *)&address
, sizeof(address
));
123 I_Error ("BindToPort: bind: %s", strerror(errno
));
130 void PacketSend (void)
136 sw
.checksum
= htonl(netbuffer
->checksum
);
137 sw
.player
= netbuffer
->player
;
138 sw
.retransmitfrom
= netbuffer
->retransmitfrom
;
139 sw
.starttic
= netbuffer
->starttic
;
140 sw
.numtics
= netbuffer
->numtics
;
141 for (c
=0 ; c
< netbuffer
->numtics
; c
++)
143 sw
.cmds
[c
].forwardmove
= netbuffer
->cmds
[c
].forwardmove
;
144 sw
.cmds
[c
].sidemove
= netbuffer
->cmds
[c
].sidemove
;
145 sw
.cmds
[c
].angleturn
= htons(netbuffer
->cmds
[c
].angleturn
);
146 sw
.cmds
[c
].consistancy
= htons(netbuffer
->cmds
[c
].consistancy
);
147 sw
.cmds
[c
].chatchar
= netbuffer
->cmds
[c
].chatchar
;
148 sw
.cmds
[c
].buttons
= netbuffer
->cmds
[c
].buttons
;
151 //printf ("sending %i\n",gametic);
152 c
= sendto (sendsocket
, &sw
, doomcom
->datalength
153 ,0,(void *)&sendaddress
[doomcom
->remotenode
]
154 ,sizeof(sendaddress
[doomcom
->remotenode
]));
157 // I_Error ("SendPacket error: %s",strerror(errno));
164 void PacketGet (void)
168 struct sockaddr_in fromaddress
;
172 fromlen
= sizeof(fromaddress
);
173 c
= recvfrom (insocket
, &sw
, sizeof(sw
), 0
174 , (struct sockaddr
*)&fromaddress
, &fromlen
);
177 if (errno
!= EWOULDBLOCK
)
178 I_Error ("GetPacket: %s",strerror(errno
));
179 doomcom
->remotenode
= -1; // no packet
186 printf("len=%d:p=[0x%x 0x%x] \n", c
, *(int*)&sw
, *((int*)&sw
+1));
190 // find remote node number
191 for (i
=0 ; i
<doomcom
->numnodes
; i
++)
192 if ( fromaddress
.sin_addr
.s_addr
== sendaddress
[i
].sin_addr
.s_addr
)
195 if (i
== doomcom
->numnodes
)
197 // packet is not from one of the players (new game broadcast)
198 doomcom
->remotenode
= -1; // no packet
202 doomcom
->remotenode
= i
; // good packet from a game player
203 doomcom
->datalength
= c
;
206 netbuffer
->checksum
= ntohl(sw
.checksum
);
207 netbuffer
->player
= sw
.player
;
208 netbuffer
->retransmitfrom
= sw
.retransmitfrom
;
209 netbuffer
->starttic
= sw
.starttic
;
210 netbuffer
->numtics
= sw
.numtics
;
212 for (c
=0 ; c
< netbuffer
->numtics
; c
++)
214 netbuffer
->cmds
[c
].forwardmove
= sw
.cmds
[c
].forwardmove
;
215 netbuffer
->cmds
[c
].sidemove
= sw
.cmds
[c
].sidemove
;
216 netbuffer
->cmds
[c
].angleturn
= ntohs(sw
.cmds
[c
].angleturn
);
217 netbuffer
->cmds
[c
].consistancy
= ntohs(sw
.cmds
[c
].consistancy
);
218 netbuffer
->cmds
[c
].chatchar
= sw
.cmds
[c
].chatchar
;
219 netbuffer
->cmds
[c
].buttons
= sw
.cmds
[c
].buttons
;
225 int GetLocalAddress (void)
228 struct hostent
* hostentry
; // host information entry
232 v
= gethostname (hostname
, sizeof(hostname
));
234 I_Error ("GetLocalAddress : gethostname: errno %d",errno
);
236 hostentry
= gethostbyname (hostname
);
238 I_Error ("GetLocalAddress : gethostbyname: couldn't get local host");
240 return *(int *)hostentry
->h_addr_list
[0];
247 void I_InitNetwork (void)
249 boolean trueval
= true;
252 struct hostent
* hostentry
; // host information entry
254 doomcom
= malloc (sizeof (*doomcom
) );
255 memset (doomcom
, 0, sizeof(*doomcom
) );
257 // set up for network
258 i
= M_CheckParm ("-dup");
259 if (i
&& i
< myargc
-1)
261 doomcom
->ticdup
= myargv
[i
+1][0]-'0';
262 if (doomcom
->ticdup
< 1)
264 if (doomcom
->ticdup
> 9)
268 doomcom
-> ticdup
= 1;
270 if (M_CheckParm ("-extratic"))
271 doomcom
-> extratics
= 1;
273 doomcom
-> extratics
= 0;
275 p
= M_CheckParm ("-port");
278 DOOMPORT
= atoi (myargv
[p
+1]);
279 printf ("using alternate port %i\n",DOOMPORT
);
282 // parse network game options,
283 // -net <consoleplayer> <host> <host> ...
284 i
= M_CheckParm ("-net");
287 // single player game
289 doomcom
->id
= DOOMCOM_ID
;
290 doomcom
->numplayers
= doomcom
->numnodes
= 1;
291 doomcom
->deathmatch
= false;
292 doomcom
->consoleplayer
= 0;
296 netsend
= PacketSend
;
300 // parse player number and host list
301 doomcom
->consoleplayer
= myargv
[i
+1][0]-'1';
303 doomcom
->numnodes
= 1; // this node for sure
306 while (++i
< myargc
&& myargv
[i
][0] != '-')
308 sendaddress
[doomcom
->numnodes
].sin_family
= AF_INET
;
309 sendaddress
[doomcom
->numnodes
].sin_port
= htons(DOOMPORT
);
310 if (myargv
[i
][0] == '.')
312 sendaddress
[doomcom
->numnodes
].sin_addr
.s_addr
313 = inet_addr (myargv
[i
]+1);
317 hostentry
= gethostbyname (myargv
[i
]);
319 I_Error ("gethostbyname: couldn't find %s", myargv
[i
]);
320 sendaddress
[doomcom
->numnodes
].sin_addr
.s_addr
321 = *(int *)hostentry
->h_addr_list
[0];
326 doomcom
->id
= DOOMCOM_ID
;
327 doomcom
->numplayers
= doomcom
->numnodes
;
329 // build message to receive
330 insocket
= UDPsocket ();
331 BindToLocalPort (insocket
,htons(DOOMPORT
));
332 ioctl (insocket
, FIONBIO
, &trueval
);
334 sendsocket
= UDPsocket ();
340 if (doomcom
->command
== CMD_SEND
)
344 else if (doomcom
->command
== CMD_GET
)
349 I_Error ("Bad net cmd: %i\n",doomcom
->command
);