36 extern "C" { |
36 extern "C" { |
37 #endif |
37 #endif |
38 |
38 |
39 /* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL |
39 /* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL |
40 */ |
40 */ |
41 #define SDL_NET_MAJOR_VERSION 1 |
41 #define SDL_NET_MAJOR_VERSION 1 |
42 #define SDL_NET_MINOR_VERSION 2 |
42 #define SDL_NET_MINOR_VERSION 2 |
43 #define SDL_NET_PATCHLEVEL 8 |
43 #define SDL_NET_PATCHLEVEL 8 |
44 |
44 |
45 /* This macro can be used to fill a version structure with the compile-time |
45 /* This macro can be used to fill a version structure with the compile-time |
46 * version of the SDL_net library. |
46 * version of the SDL_net library. |
47 */ |
47 */ |
48 #define SDL_NET_VERSION(X) \ |
48 #define SDL_NET_VERSION(X) \ |
49 { \ |
49 { \ |
50 (X)->major = SDL_NET_MAJOR_VERSION; \ |
50 (X)->major = SDL_NET_MAJOR_VERSION; \ |
51 (X)->minor = SDL_NET_MINOR_VERSION; \ |
51 (X)->minor = SDL_NET_MINOR_VERSION; \ |
52 (X)->patch = SDL_NET_PATCHLEVEL; \ |
52 (X)->patch = SDL_NET_PATCHLEVEL; \ |
53 } |
53 } |
54 |
54 |
55 /* This function gets the version of the dynamically linked SDL_net library. |
55 /* This function gets the version of the dynamically linked SDL_net library. |
56 it should NOT be used to fill a version structure, instead you should |
56 it should NOT be used to fill a version structure, instead you should |
57 use the SDL_NET_VERSION() macro. |
57 use the SDL_NET_VERSION() macro. |
68 /***********************************************************************/ |
68 /***********************************************************************/ |
69 /* IPv4 hostname resolution API */ |
69 /* IPv4 hostname resolution API */ |
70 /***********************************************************************/ |
70 /***********************************************************************/ |
71 |
71 |
72 typedef struct { |
72 typedef struct { |
73 Uint32 host; /* 32-bit IPv4 host address */ |
73 Uint32 host; /* 32-bit IPv4 host address */ |
74 Uint16 port; /* 16-bit protocol port */ |
74 Uint16 port; /* 16-bit protocol port */ |
75 } IPaddress; |
75 } IPaddress; |
76 |
76 |
77 /* Resolve a host name and port to an IP address in network form. |
77 /* Resolve a host name and port to an IP address in network form. |
78 If the function succeeds, it will return 0. |
78 If the function succeeds, it will return 0. |
79 If the host couldn't be resolved, the host portion of the returned |
79 If the host couldn't be resolved, the host portion of the returned |
80 address will be INADDR_NONE, and the function will return -1. |
80 address will be INADDR_NONE, and the function will return -1. |
81 If 'host' is NULL, the resolved host will be set to INADDR_ANY. |
81 If 'host' is NULL, the resolved host will be set to INADDR_ANY. |
82 */ |
82 */ |
83 #ifndef INADDR_ANY |
83 #ifndef INADDR_ANY |
84 #define INADDR_ANY 0x00000000 |
84 #define INADDR_ANY 0x00000000 |
85 #endif |
85 #endif |
86 #ifndef INADDR_NONE |
86 #ifndef INADDR_NONE |
87 #define INADDR_NONE 0xFFFFFFFF |
87 #define INADDR_NONE 0xFFFFFFFF |
88 #endif |
88 #endif |
89 #ifndef INADDR_BROADCAST |
89 #ifndef INADDR_BROADCAST |
90 #define INADDR_BROADCAST 0xFFFFFFFF |
90 #define INADDR_BROADCAST 0xFFFFFFFF |
91 #endif |
91 #endif |
92 extern DECLSPEC int SDLCALL SDLNet_ResolveHost(IPaddress *address, const char *host, Uint16 port); |
92 extern DECLSPEC int SDLCALL SDLNet_ResolveHost(IPaddress *address, const char *host, Uint16 port); |
93 |
93 |
94 /* Resolve an ip address to a host name in canonical form. |
94 /* Resolve an ip address to a host name in canonical form. |
95 If the ip couldn't be resolved, this function returns NULL, |
95 If the ip couldn't be resolved, this function returns NULL, |
152 /***********************************************************************/ |
152 /***********************************************************************/ |
153 /* UDP network API */ |
153 /* UDP network API */ |
154 /***********************************************************************/ |
154 /***********************************************************************/ |
155 |
155 |
156 /* The maximum channels on a a UDP socket */ |
156 /* The maximum channels on a a UDP socket */ |
157 #define SDLNET_MAX_UDPCHANNELS 32 |
157 #define SDLNET_MAX_UDPCHANNELS 32 |
158 /* The maximum addresses bound to a single UDP socket channel */ |
158 /* The maximum addresses bound to a single UDP socket channel */ |
159 #define SDLNET_MAX_UDPADDRESSES 4 |
159 #define SDLNET_MAX_UDPADDRESSES 4 |
160 |
160 |
161 typedef struct _UDPsocket *UDPsocket; |
161 typedef struct _UDPsocket *UDPsocket; |
162 typedef struct { |
162 typedef struct { |
163 int channel; /* The src/dst channel of the packet */ |
163 int channel; /* The src/dst channel of the packet */ |
164 Uint8 *data; /* The packet data */ |
164 Uint8 *data; /* The packet data */ |
165 int len; /* The length of the packet data */ |
165 int len; /* The length of the packet data */ |
166 int maxlen; /* The size of the data buffer */ |
166 int maxlen; /* The size of the data buffer */ |
167 int status; /* packet status after sending */ |
167 int status; /* packet status after sending */ |
168 IPaddress address; /* The source/dest address of an incoming/outgoing packet */ |
168 IPaddress address; /* The source/dest address of an incoming/outgoing packet */ |
169 } UDPpacket; |
169 } UDPpacket; |
170 |
170 |
171 /* Allocate/resize/free a single UDP packet 'size' bytes long. |
171 /* Allocate/resize/free a single UDP packet 'size' bytes long. |
172 The new packet is returned, or NULL if the function ran out of memory. |
172 The new packet is returned, or NULL if the function ran out of memory. |
173 */ |
173 */ |
208 extern DECLSPEC int SDLCALL SDLNet_UDP_Bind(UDPsocket sock, int channel, const IPaddress *address); |
208 extern DECLSPEC int SDLCALL SDLNet_UDP_Bind(UDPsocket sock, int channel, const IPaddress *address); |
209 |
209 |
210 /* Unbind all addresses from the given channel */ |
210 /* Unbind all addresses from the given channel */ |
211 extern DECLSPEC void SDLCALL SDLNet_UDP_Unbind(UDPsocket sock, int channel); |
211 extern DECLSPEC void SDLCALL SDLNet_UDP_Unbind(UDPsocket sock, int channel); |
212 |
212 |
213 /* Get the primary IP address of the remote system associated with the |
213 /* Get the primary IP address of the remote system associated with the |
214 socket and channel. If the channel is -1, then the primary IP port |
214 socket and channel. If the channel is -1, then the primary IP port |
215 of the UDP socket is returned -- this is only meaningful for sockets |
215 of the UDP socket is returned -- this is only meaningful for sockets |
216 opened with a specific port. |
216 opened with a specific port. |
217 If the channel is not bound and not -1, this function returns NULL. |
217 If the channel is not bound and not -1, this function returns NULL. |
218 */ |
218 */ |
219 extern DECLSPEC IPaddress * SDLCALL SDLNet_UDP_GetPeerAddress(UDPsocket sock, int channel); |
219 extern DECLSPEC IPaddress * SDLCALL SDLNet_UDP_GetPeerAddress(UDPsocket sock, int channel); |
220 |
220 |
221 /* Send a vector of packets to the the channels specified within the packet. |
221 /* Send a vector of packets to the the channels specified within the packet. |
222 If the channel specified in the packet is -1, the packet will be sent to |
222 If the channel specified in the packet is -1, the packet will be sent to |
223 the address in the 'src' member of the packet. |
223 the address in the 'src' member of the packet. |
224 Each packet will be updated with the status of the packet after it has |
224 Each packet will be updated with the status of the packet after it has |
225 been sent, -1 if the packet send failed. |
225 been sent, -1 if the packet send failed. |
226 This function returns the number of packets sent. |
226 This function returns the number of packets sent. |
227 */ |
227 */ |
228 extern DECLSPEC int SDLCALL SDLNet_UDP_SendV(UDPsocket sock, UDPpacket **packets, int npackets); |
228 extern DECLSPEC int SDLCALL SDLNet_UDP_SendV(UDPsocket sock, UDPpacket **packets, int npackets); |
229 |
229 |
275 |
275 |
276 typedef struct _SDLNet_SocketSet *SDLNet_SocketSet; |
276 typedef struct _SDLNet_SocketSet *SDLNet_SocketSet; |
277 |
277 |
278 /* Any network socket can be safely cast to this socket type */ |
278 /* Any network socket can be safely cast to this socket type */ |
279 typedef struct _SDLNet_GenericSocket { |
279 typedef struct _SDLNet_GenericSocket { |
280 int ready; |
280 int ready; |
281 } *SDLNet_GenericSocket; |
281 } *SDLNet_GenericSocket; |
282 |
282 |
283 /* Allocate a socket set for use with SDLNet_CheckSockets() |
283 /* Allocate a socket set for use with SDLNet_CheckSockets() |
284 This returns a socket set for up to 'maxsockets' sockets, or NULL if |
284 This returns a socket set for up to 'maxsockets' sockets, or NULL if |
285 the function ran out of memory. |
285 the function ran out of memory. |
286 */ |
286 */ |
287 extern DECLSPEC SDLNet_SocketSet SDLCALL SDLNet_AllocSocketSet(int maxsockets); |
287 extern DECLSPEC SDLNet_SocketSet SDLCALL SDLNet_AllocSocketSet(int maxsockets); |
288 |
288 |
289 /* Add a socket to a set of sockets to be checked for available data */ |
289 /* Add a socket to a set of sockets to be checked for available data */ |
290 #define SDLNet_TCP_AddSocket(set, sock) \ |
290 #define SDLNet_TCP_AddSocket(set, sock) \ |
291 SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) |
291 SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) |
292 #define SDLNet_UDP_AddSocket(set, sock) \ |
292 #define SDLNet_UDP_AddSocket(set, sock) \ |
293 SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) |
293 SDLNet_AddSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) |
294 extern DECLSPEC int SDLCALL SDLNet_AddSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock); |
294 extern DECLSPEC int SDLCALL SDLNet_AddSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock); |
295 |
295 |
296 /* Remove a socket from a set of sockets to be checked for available data */ |
296 /* Remove a socket from a set of sockets to be checked for available data */ |
297 #define SDLNet_TCP_DelSocket(set, sock) \ |
297 #define SDLNet_TCP_DelSocket(set, sock) \ |
298 SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) |
298 SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) |
299 #define SDLNet_UDP_DelSocket(set, sock) \ |
299 #define SDLNet_UDP_DelSocket(set, sock) \ |
300 SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) |
300 SDLNet_DelSocket(set, SDL_reinterpret_cast(SDLNet_GenericSocket, sock)) |
301 extern DECLSPEC int SDLCALL SDLNet_DelSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock); |
301 extern DECLSPEC int SDLCALL SDLNet_DelSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock); |
302 |
302 |
303 /* This function checks to see if data is available for reading on the |
303 /* This function checks to see if data is available for reading on the |
304 given set of sockets. If 'timeout' is 0, it performs a quick poll, |
304 given set of sockets. If 'timeout' is 0, it performs a quick poll, |
305 otherwise the function returns when either data is available for |
305 otherwise the function returns when either data is available for |
306 reading, or the timeout in milliseconds has elapsed, which ever occurs |
306 reading, or the timeout in milliseconds has elapsed, which ever occurs |
307 first. This function returns the number of sockets ready for reading, |
307 first. This function returns the number of sockets ready for reading, |
308 or -1 if there was an error with the select() system call. |
308 or -1 if there was an error with the select() system call. |
309 */ |
309 */ |
310 extern DECLSPEC int SDLCALL SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout); |
310 extern DECLSPEC int SDLCALL SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout); |
311 |
311 |
312 /* After calling SDLNet_CheckSockets(), you can use this function on a |
312 /* After calling SDLNet_CheckSockets(), you can use this function on a |
313 socket that was in the socket set, to find out if data is available |
313 socket that was in the socket set, to find out if data is available |
314 for reading. |
314 for reading. |
315 */ |
315 */ |
316 #define SDLNet_SocketReady(sock) \ |
316 #define SDLNet_SocketReady(sock) \ |
317 ((sock != NULL) && SDL_reinterpret_cast(SDLNet_GenericSocket, sock)->ready) |
317 ((sock != NULL) && SDL_reinterpret_cast(SDLNet_GenericSocket, sock)->ready) |
318 |
318 |
319 /* Free a set of sockets allocated by SDL_NetAllocSocketSet() */ |
319 /* Free a set of sockets allocated by SDL_NetAllocSocketSet() */ |
320 extern DECLSPEC void SDLCALL SDLNet_FreeSocketSet(SDLNet_SocketSet set); |
320 extern DECLSPEC void SDLCALL SDLNet_FreeSocketSet(SDLNet_SocketSet set); |
321 |
321 |
322 |
322 |
350 |
350 |
351 /* Inline macro functions to read/write network data */ |
351 /* Inline macro functions to read/write network data */ |
352 |
352 |
353 /* Warning, some systems have data access alignment restrictions */ |
353 /* Warning, some systems have data access alignment restrictions */ |
354 #if defined(sparc) || defined(mips) |
354 #if defined(sparc) || defined(mips) |
355 #define SDL_DATA_ALIGNED 1 |
355 #define SDL_DATA_ALIGNED 1 |
356 #endif |
356 #endif |
357 #ifndef SDL_DATA_ALIGNED |
357 #ifndef SDL_DATA_ALIGNED |
358 #define SDL_DATA_ALIGNED 0 |
358 #define SDL_DATA_ALIGNED 0 |
359 #endif |
359 #endif |
360 |
360 |
361 /* Write a 16 bit value to network packet buffer */ |
361 /* Write a 16 bit value to network packet buffer */ |
362 #if !SDL_DATA_ALIGNED |
362 #if !SDL_DATA_ALIGNED |
363 #define SDLNet_Write16(value, areap) \ |
363 #define SDLNet_Write16(value, areap) \ |
364 (*SDL_reinterpret_cast(Uint16 *, areap) = SDL_SwapBE16(value)) |
364 (*SDL_reinterpret_cast(Uint16 *, areap) = SDL_SwapBE16(value)) |
365 #else |
365 #else |
366 #if SDL_BYTEORDER == SDL_BIG_ENDIAN |
366 #if SDL_BYTEORDER == SDL_BIG_ENDIAN |
367 #define SDLNet_Write16(value, areap) \ |
367 #define SDLNet_Write16(value, areap) \ |
368 do \ |
368 do \ |
369 { \ |
369 { \ |
370 Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ |
370 Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ |
371 area[0] = (value >> 8) & 0xFF; \ |
371 area[0] = (value >> 8) & 0xFF; \ |
372 area[1] = value & 0xFF; \ |
372 area[1] = value & 0xFF; \ |
373 } while ( 0 ) |
373 } while ( 0 ) |
374 #else |
374 #else |
375 #define SDLNet_Write16(value, areap) \ |
375 #define SDLNet_Write16(value, areap) \ |
376 do \ |
376 do \ |
377 { \ |
377 { \ |
378 Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ |
378 Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ |
379 area[1] = (value >> 8) & 0xFF; \ |
379 area[1] = (value >> 8) & 0xFF; \ |
380 area[0] = value & 0xFF; \ |
380 area[0] = value & 0xFF; \ |
381 } while ( 0 ) |
381 } while ( 0 ) |
382 #endif |
382 #endif |
383 #endif /* !SDL_DATA_ALIGNED */ |
383 #endif /* !SDL_DATA_ALIGNED */ |
384 |
384 |
385 /* Write a 32 bit value to network packet buffer */ |
385 /* Write a 32 bit value to network packet buffer */ |
386 #if !SDL_DATA_ALIGNED |
386 #if !SDL_DATA_ALIGNED |
387 #define SDLNet_Write32(value, areap) \ |
387 #define SDLNet_Write32(value, areap) \ |
388 *SDL_reinterpret_cast(Uint32 *, areap) = SDL_SwapBE32(value); |
388 *SDL_reinterpret_cast(Uint32 *, areap) = SDL_SwapBE32(value); |
389 #else |
389 #else |
390 #if SDL_BYTEORDER == SDL_BIG_ENDIAN |
390 #if SDL_BYTEORDER == SDL_BIG_ENDIAN |
391 #define SDLNet_Write32(value, areap) \ |
391 #define SDLNet_Write32(value, areap) \ |
392 do \ |
392 do \ |
393 { \ |
393 { \ |
394 Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ |
394 Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ |
395 area[0] = (value >> 24) & 0xFF; \ |
395 area[0] = (value >> 24) & 0xFF; \ |
396 area[1] = (value >> 16) & 0xFF; \ |
396 area[1] = (value >> 16) & 0xFF; \ |
397 area[2] = (value >> 8) & 0xFF; \ |
397 area[2] = (value >> 8) & 0xFF; \ |
398 area[3] = value & 0xFF; \ |
398 area[3] = value & 0xFF; \ |
399 } while ( 0 ) |
399 } while ( 0 ) |
400 #else |
400 #else |
401 #define SDLNet_Write32(value, areap) \ |
401 #define SDLNet_Write32(value, areap) \ |
402 do \ |
402 do \ |
403 { \ |
403 { \ |
404 Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ |
404 Uint8 *area = SDL_reinterpret_cast(Uint8 *, areap); \ |
405 area[3] = (value >> 24) & 0xFF; \ |
405 area[3] = (value >> 24) & 0xFF; \ |
406 area[2] = (value >> 16) & 0xFF; \ |
406 area[2] = (value >> 16) & 0xFF; \ |
407 area[1] = (value >> 8) & 0xFF; \ |
407 area[1] = (value >> 8) & 0xFF; \ |
408 area[0] = value & 0xFF; \ |
408 area[0] = value & 0xFF; \ |
409 } while ( 0 ) |
409 } while ( 0 ) |
410 #endif |
410 #endif |
411 #endif /* !SDL_DATA_ALIGNED */ |
411 #endif /* !SDL_DATA_ALIGNED */ |
412 |
412 |
413 /* Read a 16 bit value from network packet buffer */ |
413 /* Read a 16 bit value from network packet buffer */ |
414 #if !SDL_DATA_ALIGNED |
414 #if !SDL_DATA_ALIGNED |
415 #define SDLNet_Read16(areap) \ |
415 #define SDLNet_Read16(areap) \ |
416 (SDL_SwapBE16(*SDL_reinterpret_cast(Uint16 *, areap))) |
416 (SDL_SwapBE16(*SDL_reinterpret_cast(Uint16 *, areap))) |
417 #else |
417 #else |
418 #if SDL_BYTEORDER == SDL_BIG_ENDIAN |
418 #if SDL_BYTEORDER == SDL_BIG_ENDIAN |
419 #define SDLNet_Read16(areap) \ |
419 #define SDLNet_Read16(areap) \ |
420 (((SDL_reinterpret_cast(Uint8 *, areap))[0] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[1] << 0) |
420 (((SDL_reinterpret_cast(Uint8 *, areap))[0] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[1] << 0) |
421 #else |
421 #else |
422 #define SDLNet_Read16(areap) \ |
422 #define SDLNet_Read16(areap) \ |
423 (((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0) |
423 (((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0) |
424 #endif |
424 #endif |
425 #endif /* !SDL_DATA_ALIGNED */ |
425 #endif /* !SDL_DATA_ALIGNED */ |
426 |
426 |
427 /* Read a 32 bit value from network packet buffer */ |
427 /* Read a 32 bit value from network packet buffer */ |
428 #if !SDL_DATA_ALIGNED |
428 #if !SDL_DATA_ALIGNED |
429 #define SDLNet_Read32(areap) \ |
429 #define SDLNet_Read32(areap) \ |
430 (SDL_SwapBE32(*SDL_reinterpret_cast(Uint32 *, areap))) |
430 (SDL_SwapBE32(*SDL_reinterpret_cast(Uint32 *, areap))) |
431 #else |
431 #else |
432 #if SDL_BYTEORDER == SDL_BIG_ENDIAN |
432 #if SDL_BYTEORDER == SDL_BIG_ENDIAN |
433 #define SDLNet_Read32(areap) \ |
433 #define SDLNet_Read32(areap) \ |
434 (((SDL_reinterpret_cast(Uint8 *, areap))[0] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 16) | \ |
434 (((SDL_reinterpret_cast(Uint8 *, areap))[0] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 16) | \ |
435 ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[3] << 0) |
435 ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[3] << 0) |
436 #else |
436 #else |
437 #define SDLNet_Read32(areap) \ |
437 #define SDLNet_Read32(areap) \ |
438 (((SDL_reinterpret_cast(Uint8 *, areap))[3] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 16) | \ |
438 (((SDL_reinterpret_cast(Uint8 *, areap))[3] << 24) | ((SDL_reinterpret_cast(Uint8 *, areap))[2] << 16) | \ |
439 ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0) |
439 ((SDL_reinterpret_cast(Uint8 *, areap))[1] << 8) | (SDL_reinterpret_cast(Uint8 *, areap))[0] << 0) |
440 #endif |
440 #endif |
441 #endif /* !SDL_DATA_ALIGNED */ |
441 #endif /* !SDL_DATA_ALIGNED */ |
442 |
442 |
443 /* Ends C function definitions when using C++ */ |
443 /* Ends C function definitions when using C++ */ |
444 #ifdef __cplusplus |
444 #ifdef __cplusplus |