Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8079 was 8079, checked in by landauf, 13 years ago

merged usability branch back to trunk

incomplete summary of the changes in this branch:

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