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