home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 28
/
amigaformatcd28.iso
/
-websites-
/
amidoom
/
adoom_src-0.7.lha
/
ADoom_src
/
amiga_net.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-01-01
|
8KB
|
318 lines
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <exec/exec.h>
#include <proto/exec.h>
#include <proto/socket.h>
#include "i_system.h"
#include "d_event.h"
#include "d_net.h"
#include "m_argv.h"
#include "doomstat.h"
#include "i_net.h"
//
// NETWORKING
//
/**********************************************************************/
struct Library *SocketBase = NULL;
static int DOOMPORT = (IPPORT_USERRESERVED + 0x1d);
static int sendsocket = -1;
static int insocket = -1;
static struct sockaddr_in sendaddress[MAXNETNODES];
static void (*netget) (void);
static void (*netsend) (void);
/**********************************************************************/
//
// UDPsocket
//
static int UDPsocket (void)
{
int s;
// allocate a socket
s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s < 0)
I_Error ("can't create socket: %s", strerror(errno));
return s;
}
/**********************************************************************/
//
// BindToLocalPort
//
static void BindToLocalPort (int s, int port)
{
int v;
struct sockaddr_in address;
memset (&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = port;
v = bind (s, (void *)&address, sizeof(address));
if (v == -1)
I_Error ("BindToPort: bind: %s", strerror(errno));
}
/**********************************************************************/
//
// PacketSend
//
static void PacketSend (void)
{
int c;
doomdata_t sw;
// byte swap
sw.checksum = htonl(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 = htons(netbuffer->cmds[c].angleturn);
sw.cmds[c].consistancy = htons(netbuffer->cmds[c].consistancy);
sw.cmds[c].chatchar = netbuffer->cmds[c].chatchar;
sw.cmds[c].buttons = netbuffer->cmds[c].buttons;
}
//printf ("sending %i\n",gametic);
c = sendto (sendsocket , (UBYTE *)&sw, doomcom->datalength,
0, (void *)&sendaddress[doomcom->remotenode],
sizeof(sendaddress[doomcom->remotenode]));
if (c == -1)
/* why does AmiTCP 4.3 return EINVAL instead of EWOULDBLOCK ??? */
if (errno != EWOULDBLOCK && errno != EINVAL)
I_Error ("SendPacket error: %s",strerror(errno));
}
/**********************************************************************/
//
// PacketGet
//
static void PacketGet (void)
{
int i, c;
struct sockaddr_in fromaddress;
LONG fromlen;
doomdata_t sw;
fromlen = sizeof(fromaddress);
c = recvfrom (insocket, (UBYTE *)&sw, sizeof(sw), 0,
(struct sockaddr *)&fromaddress, &fromlen);
if (c == -1) {
/* why does AmiTCP 4.3 return EINVAL instead of EWOULDBLOCK ??? */
if (errno != EWOULDBLOCK && errno != EINVAL)
I_Error ("GetPacket: %s",strerror(errno));
doomcom->remotenode = -1; // no packet
return;
}
{
static int first=1;
if (first)
printf("len=%d:p=[0x%x 0x%x] \n", c, *(int*)&sw, *((int*)&sw+1));
first = 0;
}
// find remote node number
for (i = 0; i < doomcom->numnodes; i++)
if (fromaddress.sin_addr.s_addr == sendaddress[i].sin_addr.s_addr)
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 = c;
// byte swap
netbuffer->checksum = ntohl(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 = ntohs(sw.cmds[c].angleturn);
netbuffer->cmds[c].consistancy = ntohs(sw.cmds[c].consistancy);
netbuffer->cmds[c].chatchar = sw.cmds[c].chatchar;
netbuffer->cmds[c].buttons = sw.cmds[c].buttons;
}
}
/**********************************************************************/
#if 0
static int GetLocalAddress (void)
{
char hostname[1024];
struct hostent* hostentry; // host information entry
int v;
// get local address
v = gethostname (hostname, sizeof(hostname));
if (v == -1)
I_Error ("GetLocalAddress : gethostname: errno %d",errno);
hostentry = gethostbyname (hostname);
if (!hostentry)
I_Error ("GetLocalAddress : gethostbyname: couldn't get local host");
return *(int *)hostentry->h_addr_list[0];
}
#endif
/**********************************************************************/
//
// I_InitNetwork
//
void I_InitNetwork (void)
{
char 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 ((SocketBase = OpenLibrary ("bsdsocket.library", 0)) == NULL)
I_Error ("OpenLibrary(\"bsdsocket.library\") failed");
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
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);
} 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];
}
doomcom->numnodes++;
}
doomcom->id = DOOMCOM_ID;
doomcom->numplayers = doomcom->numnodes;
// build message to receive
insocket = UDPsocket ();
sendsocket = UDPsocket ();
BindToLocalPort (insocket, htons(DOOMPORT));
/* set both sockets to non-blocking */
if (IoctlSocket (insocket, FIONBIO, &trueval) == -1 ||
IoctlSocket (sendsocket, FIONBIO, &trueval) == -1)
I_Error ("IoctlSocket() failed: %s", strerror(errno));
}
/**********************************************************************/
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);
}
/**********************************************************************/
void _STDcleanup_net (void)
{
if (insocket != -1) {
CloseSocket (insocket);
insocket = -1;
}
if (sendsocket != -1) {
CloseSocket (sendsocket);
sendsocket = -1;
}
if (SocketBase != NULL) {
CloseLibrary (SocketBase);
SocketBase = NULL;
}
}
/**********************************************************************/