home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #2 / amigaacscoverdisc1998-021998.iso / games / doom / adoom / src / amiga_net.c < prev    next >
C/C++ Source or Header  |  1998-01-01  |  8KB  |  318 lines

  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4.  
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. #include <errno.h>
  9. #include <unistd.h>
  10. #include <netdb.h>
  11. #include <sys/ioctl.h>
  12.  
  13. #include <exec/exec.h>
  14. #include <proto/exec.h>
  15. #include <proto/socket.h>
  16.  
  17. #include "i_system.h"
  18. #include "d_event.h"
  19. #include "d_net.h"
  20. #include "m_argv.h"
  21.  
  22. #include "doomstat.h"
  23.  
  24. #include "i_net.h"
  25.  
  26. //
  27. // NETWORKING
  28. //
  29.  
  30. /**********************************************************************/
  31. struct Library *SocketBase = NULL;
  32.  
  33. static int DOOMPORT = (IPPORT_USERRESERVED + 0x1d);
  34.  
  35. static int sendsocket = -1;
  36. static int insocket = -1;
  37.  
  38. static struct sockaddr_in sendaddress[MAXNETNODES];
  39.  
  40. static void (*netget) (void);
  41. static void (*netsend) (void);
  42.  
  43.  
  44. /**********************************************************************/
  45. //
  46. // UDPsocket
  47. //
  48. static int UDPsocket (void)
  49. {
  50.   int s;
  51.  
  52.   // allocate a socket
  53.   s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  54.   if (s < 0)
  55.     I_Error ("can't create socket: %s", strerror(errno));
  56.   return s;
  57. }
  58.  
  59. /**********************************************************************/
  60. //
  61. // BindToLocalPort
  62. //
  63. static void BindToLocalPort (int s, int port)
  64. {
  65.   int v;
  66.   struct sockaddr_in address;
  67.  
  68.   memset (&address, 0, sizeof(address));
  69.   address.sin_family = AF_INET;
  70.   address.sin_addr.s_addr = INADDR_ANY;
  71.   address.sin_port = port;
  72.  
  73.   v = bind (s, (void *)&address, sizeof(address));
  74.   if (v == -1)
  75.     I_Error ("BindToPort: bind: %s", strerror(errno));
  76. }
  77.  
  78.  
  79. /**********************************************************************/
  80. //
  81. // PacketSend
  82. //
  83. static void PacketSend (void)
  84. {
  85.   int  c;
  86.   doomdata_t sw;
  87.  
  88.   // byte swap
  89.   sw.checksum = htonl(netbuffer->checksum);
  90.   sw.player = netbuffer->player;
  91.   sw.retransmitfrom = netbuffer->retransmitfrom;
  92.   sw.starttic = netbuffer->starttic;
  93.   sw.numtics = netbuffer->numtics;
  94.   for (c = 0 ; c < netbuffer->numtics; c++) {
  95.     sw.cmds[c].forwardmove = netbuffer->cmds[c].forwardmove;
  96.     sw.cmds[c].sidemove = netbuffer->cmds[c].sidemove;
  97.     sw.cmds[c].angleturn = htons(netbuffer->cmds[c].angleturn);
  98.     sw.cmds[c].consistancy = htons(netbuffer->cmds[c].consistancy);
  99.     sw.cmds[c].chatchar = netbuffer->cmds[c].chatchar;
  100.     sw.cmds[c].buttons = netbuffer->cmds[c].buttons;
  101.   }
  102.  
  103.   //printf ("sending %i\n",gametic);
  104.   c = sendto (sendsocket , (UBYTE *)&sw, doomcom->datalength,
  105.               0, (void *)&sendaddress[doomcom->remotenode],
  106.               sizeof(sendaddress[doomcom->remotenode]));
  107.   if (c == -1)
  108.     /* why does AmiTCP 4.3 return EINVAL instead of EWOULDBLOCK ??? */
  109.     if (errno != EWOULDBLOCK && errno != EINVAL)
  110.       I_Error ("SendPacket error: %s",strerror(errno));
  111. }
  112.  
  113.  
  114. /**********************************************************************/
  115. //
  116. // PacketGet
  117. //
  118. static void PacketGet (void)
  119. {
  120.   int i, c;
  121.   struct sockaddr_in fromaddress;
  122.   LONG fromlen;
  123.   doomdata_t sw;
  124.  
  125.   fromlen = sizeof(fromaddress);
  126.   c = recvfrom (insocket, (UBYTE *)&sw, sizeof(sw), 0,
  127.                 (struct sockaddr *)&fromaddress, &fromlen);
  128.   if (c == -1) {
  129.     /* why does AmiTCP 4.3 return EINVAL instead of EWOULDBLOCK ??? */
  130.     if (errno != EWOULDBLOCK && errno != EINVAL)
  131.       I_Error ("GetPacket: %s",strerror(errno));
  132.     doomcom->remotenode = -1;  // no packet
  133.     return;
  134.   }
  135.  
  136.   {
  137.     static int first=1;
  138.     if (first)
  139.       printf("len=%d:p=[0x%x 0x%x] \n", c, *(int*)&sw, *((int*)&sw+1));
  140.     first = 0;
  141.   }
  142.  
  143.   // find remote node number
  144.   for (i = 0; i < doomcom->numnodes; i++)
  145.     if (fromaddress.sin_addr.s_addr == sendaddress[i].sin_addr.s_addr)
  146.       break;
  147.  
  148.   if (i == doomcom->numnodes) {
  149.     // packet is not from one of the players (new game broadcast)
  150.     doomcom->remotenode = -1;  // no packet
  151.     return;
  152.   }
  153.  
  154.   doomcom->remotenode = i;   // good packet from a game player
  155.   doomcom->datalength = c;
  156.  
  157.   // byte swap
  158.   netbuffer->checksum = ntohl(sw.checksum);
  159.   netbuffer->player = sw.player;
  160.   netbuffer->retransmitfrom = sw.retransmitfrom;
  161.   netbuffer->starttic = sw.starttic;
  162.   netbuffer->numtics = sw.numtics;
  163.  
  164.   for (c = 0; c < netbuffer->numtics; c++) {
  165.     netbuffer->cmds[c].forwardmove = sw.cmds[c].forwardmove;
  166.     netbuffer->cmds[c].sidemove = sw.cmds[c].sidemove;
  167.     netbuffer->cmds[c].angleturn = ntohs(sw.cmds[c].angleturn);
  168.     netbuffer->cmds[c].consistancy = ntohs(sw.cmds[c].consistancy);
  169.     netbuffer->cmds[c].chatchar = sw.cmds[c].chatchar;
  170.     netbuffer->cmds[c].buttons = sw.cmds[c].buttons;
  171.   }
  172. }
  173.  
  174.  
  175. /**********************************************************************/
  176. #if 0
  177. static int GetLocalAddress (void)
  178. {
  179.   char hostname[1024];
  180.   struct hostent* hostentry; // host information entry
  181.   int v;
  182.  
  183.   // get local address
  184.   v = gethostname (hostname, sizeof(hostname));
  185.   if (v == -1)
  186.     I_Error ("GetLocalAddress : gethostname: errno %d",errno);
  187.  
  188.   hostentry = gethostbyname (hostname);
  189.   if (!hostentry)
  190.     I_Error ("GetLocalAddress : gethostbyname: couldn't get local host");
  191.  
  192.   return *(int *)hostentry->h_addr_list[0];
  193. }
  194. #endif
  195.  
  196. /**********************************************************************/
  197. //
  198. // I_InitNetwork
  199. //
  200. void I_InitNetwork (void)
  201. {
  202.   char trueval = true;
  203.   int i;
  204.   int p;
  205.   struct hostent* hostentry; // host information entry
  206.  
  207.   doomcom = malloc (sizeof (*doomcom) );
  208.   memset (doomcom, 0, sizeof(*doomcom) );
  209.  
  210.   // set up for network
  211.   i = M_CheckParm ("-dup");
  212.   if (i && i < myargc - 1) {
  213.     doomcom->ticdup = myargv[i+1][0]-'0';
  214.     if (doomcom->ticdup < 1)
  215.       doomcom->ticdup = 1;
  216.     if (doomcom->ticdup > 9)
  217.       doomcom->ticdup = 9;
  218.   } else
  219.     doomcom-> ticdup = 1;
  220.  
  221.   if (M_CheckParm ("-extratic"))
  222.     doomcom-> extratics = 1;
  223.   else
  224.     doomcom-> extratics = 0;
  225.  
  226.   p = M_CheckParm ("-port");
  227.   if (p && p < myargc - 1) {
  228.     DOOMPORT = atoi (myargv[p+1]);
  229.     printf ("using alternate port %i\n",DOOMPORT);
  230.   }
  231.  
  232.   // parse network game options,
  233.   //  -net <consoleplayer> <host> <host> ...
  234.   i = M_CheckParm ("-net");
  235.   if (!i) {
  236.     // single player game
  237.     netgame = false;
  238.     doomcom->id = DOOMCOM_ID;
  239.     doomcom->numplayers = doomcom->numnodes = 1;
  240.     doomcom->deathmatch = false;
  241.     doomcom->consoleplayer = 0;
  242.     return;
  243.   }
  244.  
  245.   if ((SocketBase = OpenLibrary ("bsdsocket.library", 0)) == NULL)
  246.     I_Error ("OpenLibrary(\"bsdsocket.library\") failed");
  247.  
  248.   netsend = PacketSend;
  249.   netget = PacketGet;
  250.   netgame = true;
  251.  
  252.   // parse player number and host list
  253.   doomcom->consoleplayer = myargv[i+1][0]-'1';
  254.  
  255.   doomcom->numnodes = 1; // this node for sure
  256.  
  257.   i++;
  258.   while (++i < myargc && myargv[i][0] != '-') {
  259.     sendaddress[doomcom->numnodes].sin_family = AF_INET;
  260.     sendaddress[doomcom->numnodes].sin_port = htons(DOOMPORT);
  261.     if (myargv[i][0] == '.') {
  262.       sendaddress[doomcom->numnodes].sin_addr.s_addr = inet_addr (myargv[i]+1);
  263.     } else {
  264.       hostentry = gethostbyname (myargv[i]);
  265.       if (!hostentry)
  266.         I_Error ("gethostbyname: couldn't find %s", myargv[i]);
  267.       sendaddress[doomcom->numnodes].sin_addr.s_addr =
  268.                                               *(int *)hostentry->h_addr_list[0];
  269.     }
  270.     doomcom->numnodes++;
  271.   }
  272.  
  273.   doomcom->id = DOOMCOM_ID;
  274.   doomcom->numplayers = doomcom->numnodes;
  275.  
  276.   // build message to receive
  277.   insocket = UDPsocket ();
  278.   sendsocket = UDPsocket ();
  279.  
  280.   BindToLocalPort (insocket, htons(DOOMPORT));
  281.  
  282.   /* set both sockets to non-blocking */
  283.   if (IoctlSocket (insocket, FIONBIO, &trueval) == -1 ||
  284.       IoctlSocket (sendsocket, FIONBIO, &trueval) == -1)
  285.     I_Error ("IoctlSocket() failed: %s", strerror(errno));
  286. }
  287.  
  288.  
  289. /**********************************************************************/
  290. void I_NetCmd (void)
  291. {
  292.   if (doomcom->command == CMD_SEND) {
  293.     netsend ();
  294.   } else if (doomcom->command == CMD_GET) {
  295.     netget ();
  296.   } else
  297.     I_Error ("Bad net cmd: %i\n",doomcom->command);
  298. }
  299.  
  300. /**********************************************************************/
  301. void _STDcleanup_net (void)
  302. {
  303.   if (insocket != -1) {
  304.     CloseSocket (insocket);
  305.     insocket = -1;
  306.   }
  307.   if (sendsocket != -1) {
  308.     CloseSocket (sendsocket);
  309.     sendsocket = -1;
  310.   }
  311.   if (SocketBase != NULL) {
  312.     CloseLibrary (SocketBase);
  313.     SocketBase = NULL;
  314.   }
  315. }
  316.  
  317. /**********************************************************************/
  318.