Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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