home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #2 / amigaacscoverdisc1998-021998.iso / games / doom / source / linuxdoom-1.10 / i_net.c < prev    next >
C/C++ Source or Header  |  1997-12-22  |  8KB  |  349 lines

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