Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/external/enet/win32.c @ 9365

Last change on this file since 9365 was 8351, checked in by rgrieder, 14 years ago

Merged kicklib2 branch back to trunk (includes former branches ois_update, mac_osx and kicklib).

Notes for updating

Linux:
You don't need an extra package for CEGUILua and Tolua, it's already shipped with CEGUI.
However you do need to make sure that the OgreRenderer is installed too with CEGUI 0.7 (may be a separate package).
Also, Orxonox now recognises if you install the CgProgramManager (a separate package available on newer Ubuntu on Debian systems).

Windows:
Download the new dependency packages versioned 6.0 and use these. If you have problems with that or if you don't like the in game console problem mentioned below, you can download the new 4.3 version of the packages (only available for Visual Studio 2005/2008).

Key new features:

  • *Support for Mac OS X*
  • Visual Studio 2010 support
  • Bullet library update to 2.77
  • OIS library update to 1.3
  • Support for CEGUI 0.7 —> Support for Arch Linux and even SuSE
  • Improved install target
  • Compiles now with GCC 4.6
  • Ogre Cg Shader plugin activated for Linux if available
  • And of course lots of bug fixes

There are also some regressions:

  • No support for CEGUI 0.5, Ogre 1.4 and boost 1.35 - 1.39 any more
  • In game console is not working in main menu for CEGUI 0.7
  • Tolua (just the C lib, not the application) and CEGUILua libraries are no longer in our repository. —> You will need to get these as well when compiling Orxonox
  • And of course lots of new bugs we don't yet know about
  • Property svn:eol-style set to native
File size: 10.9 KB
Line 
1/**
2 @file  win32.c
3 @brief ENet Win32 system specific functions
4*/
5#ifdef WIN32
6
7#define _WIN32_WINNT 0x0501
8
9#include <time.h>
10#define ENET_BUILDING_LIB 1
11#include "enet/enet.h"
12#include <ws2tcpip.h>
13
14static enet_uint32 timeBase = 0;
15
16int
17enet_initialize (void)
18{
19    WORD versionRequested = MAKEWORD (2, 2);
20    WSADATA wsaData;
21   
22    if (WSAStartup (versionRequested, & wsaData))
23       return -1;
24
25    if (LOBYTE (wsaData.wVersion) != 2||
26        HIBYTE (wsaData.wVersion) != 2)
27    {
28       WSACleanup ();
29       
30       return -1;
31    }
32
33    timeBeginPeriod (1);
34
35    return 0;
36}
37
38void
39enet_deinitialize (void)
40{
41    timeEndPeriod (1);
42
43    WSACleanup ();
44}
45
46enet_uint32
47enet_time_get (void)
48{
49    return (enet_uint32) timeGetTime () - timeBase;
50}
51
52void
53enet_time_set (enet_uint32 newTimeBase)
54{
55    timeBase = (enet_uint32) timeGetTime () - newTimeBase;
56}
57
58static enet_uint16
59enet_af (ENetAddressFamily family)
60{
61    if (family == ENET_IPV4)
62        return AF_INET;
63    if (family == ENET_IPV6)
64        return AF_INET6;
65    return 0;
66}
67
68static socklen_t
69enet_sa_size (ENetAddressFamily family)
70{
71    if (family == ENET_IPV4)
72        return sizeof (struct sockaddr_in);
73    if (family == ENET_IPV6)
74        return sizeof (struct sockaddr_in6);
75    return 0;
76}
77
78static ENetAddressFamily
79enet_address_set_address (ENetAddress * address, const struct sockaddr * sin)
80{
81    memset (address, 0, sizeof (ENetAddress));
82    if (sin -> sa_family == AF_INET)
83    {
84        address -> host = enet_address_map4 ((((struct sockaddr_in *) sin) -> sin_addr.s_addr));
85        /* address -> scopeID = 0; */
86        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in *) sin) -> sin_port);
87        return ENET_IPV4;
88    }
89    if (sin -> sa_family == AF_INET6)
90    {
91        address -> host = * (ENetHostAddress *) & ((struct sockaddr_in6 *) sin) -> sin6_addr;
92        address -> scopeID = ((struct sockaddr_in6 *) sin) -> sin6_scope_id;
93        address -> port = ENET_NET_TO_HOST_16 (((struct sockaddr_in6 *) sin) -> sin6_port);
94        return ENET_IPV6;
95    }
96    return ENET_NO_ADDRESS_FAMILY;
97}
98
99static int
100enet_address_set_sin (struct sockaddr * sin, const ENetAddress * address, ENetAddressFamily family)
101{
102    memset (sin, 0, enet_sa_size(family));
103    if (family == ENET_IPV4 &&
104      (enet_get_address_family (address) == ENET_IPV4 ||
105      !memcmp (& address -> host, & ENET_HOST_ANY, sizeof(ENetHostAddress))))
106    {
107        ((struct sockaddr_in *) sin) -> sin_family = AF_INET;
108        ((struct sockaddr_in *) sin) -> sin_addr = * (struct in_addr *) & address -> host.addr[12];
109        ((struct sockaddr_in *) sin) -> sin_port = ENET_HOST_TO_NET_16 (address -> port);
110        return 0;
111    }
112    else if (family == ENET_IPV6)
113    {
114        ((struct sockaddr_in6 *) sin) -> sin6_family = AF_INET6;
115        ((struct sockaddr_in6 *) sin) -> sin6_addr = * (struct in6_addr *) & address -> host;
116        ((struct sockaddr_in6 *) sin) -> sin6_scope_id = address -> scopeID;
117        ((struct sockaddr_in6 *) sin) -> sin6_port = ENET_HOST_TO_NET_16 (address -> port);
118        return 0;
119    }
120    return -1;
121}
122
123int
124enet_address_set_host (ENetAddress * address, const char * name)
125{
126    enet_uint16 port = address -> port;
127    struct addrinfo hints;
128    struct addrinfo * result;
129    struct addrinfo * res;
130
131    memset(& hints, 0, sizeof (hints));
132    hints.ai_flags = AI_ADDRCONFIG;
133    hints.ai_family = AF_UNSPEC;
134
135    if ( getaddrinfo(name, NULL, &hints, &result) )
136        return -1;
137
138    for (res = result; res != NULL; res = res -> ai_next)
139    {
140        if ( enet_address_set_address(address, res -> ai_addr) != ENET_NO_ADDRESS_FAMILY )
141            break;
142    }
143
144    address -> port = port;
145    freeaddrinfo(result);
146    if (res == NULL) return -1;
147
148    return 0;
149}
150
151static int
152enet_address_get_host_x (const ENetAddress * address, char * name, size_t nameLength, int flags)
153{
154    struct sockaddr_storage sin;
155    enet_address_set_sin((struct sockaddr *) & sin, address, ENET_IPV6);
156
157    if ( getnameinfo((struct sockaddr *) & sin, enet_sa_size (ENET_IPV6), name, nameLength, NULL, 0, flags))
158        return -1;
159
160    return 0;
161}
162
163int
164enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
165{
166    return enet_address_get_host_x(address, name, nameLength, NI_NUMERICHOST);
167}
168
169int
170enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
171{
172    return enet_address_get_host_x(address, name, nameLength, 0);
173}
174
175int
176enet_socket_bind (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
177{
178    struct sockaddr_storage sin;
179
180    if (address != NULL)
181    {
182        enet_address_set_sin((struct sockaddr *) & sin, address, family);
183    }
184    else
185    {
186        ENetAddress address_ = { ENET_HOST_ANY_INIT, 0, 0 };
187        enet_address_set_sin((struct sockaddr *) & sin, & address_, family);
188    }
189
190    return bind (socket, (struct sockaddr *) & sin, enet_sa_size(family)) == SOCKET_ERROR ? -1 : 0;
191}
192
193int
194enet_socket_listen (ENetSocket socket, int backlog)
195{
196    return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
197}
198
199ENetSocket
200enet_socket_create (ENetSocketType type, ENetAddressFamily family)
201{
202    ENetSocket sock = socket (enet_af (family), type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
203    return sock;
204}
205
206int
207enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
208{
209    int result = SOCKET_ERROR;
210    switch (option)
211    {
212        case ENET_SOCKOPT_NONBLOCK:
213        {
214            u_long nonBlocking = (u_long) value;
215            result = ioctlsocket (socket, FIONBIO, & nonBlocking);
216            break;
217        }
218
219        case ENET_SOCKOPT_BROADCAST:
220            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
221            break;
222
223        case ENET_SOCKOPT_REUSEADDR:
224            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
225            break;
226
227        case ENET_SOCKOPT_RCVBUF:
228            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
229            break;
230
231        case ENET_SOCKOPT_SNDBUF:
232            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
233            break;
234
235        default:
236            break;
237    }
238    return result == SOCKET_ERROR ? -1 : 0;
239}
240
241int
242enet_socket_connect (ENetSocket socket, const ENetAddress * address, ENetAddressFamily family)
243{
244    struct sockaddr_storage sin;
245    enet_address_set_sin((struct sockaddr *) & sin, address, family);
246
247    return connect (socket, (struct sockaddr *) & sin, enet_sa_size (family)) == SOCKET_ERROR ? -1 : 0;
248}
249
250ENetSocket
251enet_socket_accept (ENetSocket socket, ENetAddress * address, ENetAddressFamily family)
252{
253    SOCKET result;
254    struct sockaddr_storage sin;
255    socklen_t sinLength = enet_sa_size (family);
256
257    result = accept (socket, 
258                     address != NULL ? (struct sockaddr *) & sin : NULL,
259                     address != NULL ? & sinLength : NULL);
260
261    if (result == INVALID_SOCKET)
262      return ENET_SOCKET_NULL;
263
264    if (address != NULL)
265    {
266        enet_address_set_address(address, (struct sockaddr *) & sin);
267    }
268
269    return result;
270}
271
272void
273enet_socket_destroy (ENetSocket socket)
274{
275    closesocket (socket);
276}
277
278int
279enet_socket_send (ENetSocket socket,
280                  const ENetAddress * address,
281                  const ENetBuffer * buffers,
282                  size_t bufferCount,
283                  ENetAddressFamily family)
284{
285    struct sockaddr_storage sin;
286    DWORD sentLength;
287
288    if (address != NULL)
289    {
290        enet_address_set_sin((struct sockaddr *) & sin, address, family);
291    }
292
293    if (WSASendTo (socket, 
294                   (LPWSABUF) buffers,
295                   (DWORD) bufferCount,
296                   & sentLength,
297                   0,
298                   address != NULL ? (struct sockaddr *) & sin : 0,
299                   address != NULL ? enet_sa_size (family) : 0,
300                   NULL,
301                   NULL) == SOCKET_ERROR)
302    {
303       if (WSAGetLastError () == WSAEWOULDBLOCK)
304         return 0;
305
306       return -1;
307    }
308
309    return (int) sentLength;
310}
311
312int
313enet_socket_receive (ENetSocket socket,
314                     ENetAddress * address,
315                     ENetBuffer * buffers,
316                     size_t bufferCount,
317                     ENetAddressFamily family)
318{
319    INT sinLength = enet_sa_size (family);
320    DWORD flags = 0,
321          recvLength;
322    struct sockaddr_storage sin;
323
324    if (WSARecvFrom (socket,
325                     (LPWSABUF) buffers,
326                     (DWORD) bufferCount,
327                     & recvLength,
328                     & flags,
329                     address != NULL ? (struct sockaddr *) & sin : NULL,
330                     address != NULL ? & sinLength : NULL,
331                     NULL,
332                     NULL) == SOCKET_ERROR)
333    {
334       switch (WSAGetLastError ())
335       {
336       case WSAEWOULDBLOCK:
337       case WSAECONNRESET:
338          return 0;
339       }
340
341       return -1;
342    }
343
344    if (flags & MSG_PARTIAL)
345      return -1;
346
347    if (address != NULL)
348    {
349        enet_address_set_address(address, (struct sockaddr *) & sin);
350    }
351
352    return (int) recvLength;
353}
354
355int
356enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
357{
358    struct timeval timeVal;
359
360    timeVal.tv_sec = timeout / 1000;
361    timeVal.tv_usec = (timeout % 1000) * 1000;
362
363    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
364}
365
366int
367enet_socket_wait (ENetSocket socket4, ENetSocket socket6, enet_uint32 * condition, enet_uint32 timeout)
368{
369    fd_set readSet, writeSet;
370    struct timeval timeVal;
371    int selectCount;
372    ENetSocket maxSocket;
373
374    timeVal.tv_sec = timeout / 1000;
375    timeVal.tv_usec = (timeout % 1000) * 1000;
376
377    FD_ZERO (& readSet);
378    FD_ZERO (& writeSet);
379
380    if (* condition & ENET_SOCKET_WAIT_SEND)
381    {
382        if (socket4 != ENET_SOCKET_NULL)
383            FD_SET (socket4, & writeSet);
384        if (socket6 != ENET_SOCKET_NULL)
385            FD_SET (socket6, & writeSet);
386    }
387
388    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
389    {
390        if (socket4 != ENET_SOCKET_NULL)
391            FD_SET (socket4, & readSet);
392        if (socket6 != ENET_SOCKET_NULL)
393            FD_SET (socket6, & readSet);
394    }
395
396    maxSocket = 0;
397    if (socket4 != ENET_SOCKET_NULL)
398        maxSocket = socket4;
399    if (socket6 != ENET_SOCKET_NULL && socket6 > maxSocket)
400        maxSocket = socket6;
401
402    selectCount = select (maxSocket + 1, & readSet, & writeSet, NULL, & timeVal);
403
404    if (selectCount < 0)
405      return -1;
406
407    * condition = ENET_SOCKET_WAIT_NONE;
408
409    if (selectCount == 0)
410      return 0;
411
412    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & writeSet)) ||
413        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & writeSet)) )
414        * condition |= ENET_SOCKET_WAIT_SEND;
415
416    if ( (socket4 != ENET_SOCKET_NULL && FD_ISSET (socket4, & readSet)) ||
417        (socket6 != ENET_SOCKET_NULL && FD_ISSET (socket6, & readSet)) )
418        * condition |= ENET_SOCKET_WAIT_RECEIVE;
419
420    return 0;
421}
422
423#endif
424
Note: See TracBrowser for help on using the repository browser.