1 /*
2 
3 Boost Software License - Version 1.0 - August 17th, 2003
4 
5 Permission is hereby granted, free of charge, to any person or organization
6 obtaining a copy of the software and accompanying documentation covered by
7 this license (the "Software") to use, reproduce, display, distribute,
8 execute, and transmit the Software, and to prepare derivative works of the
9 Software, and to permit third-parties to whom the Software is furnished to
10 do so, all subject to the following:
11 
12 The copyright notices in the Software and this entire statement, including
13 the above license grant, this restriction and the following disclaimer,
14 must be included in all copies of the Software, in whole or in part, and
15 all derivative works of the Software, unless such copies or derivative
16 works are solely in the form of machine-executable object code generated by
17 a source language processor.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 
27 */
28 module derelict.sdl.net;
29 
30 private
31 {
32     import derelict.util.loader;
33     import derelict.util.exception;
34     import derelict.util.compat;
35     import derelict.sdl.sdl;
36 }
37 
38 enum : Uint8
39 {
40     SDL_NET_MAJOR_VERSION           = 1,
41     SDL_NET_MINOR_VERSION           = 2,
42     SDL_NET_PATCHLEVEL              = 8,
43 }
44 
45 struct IPaddress
46 {
47     Uint32 host;
48     Uint16 port;
49 }
50 
51 // this is a hack to get around the removal of typedefs in D2.
52 struct TCPsocketStruct {}
53 alias TCPsocketStruct* TCPsocket;
54 
55 enum : uint
56 {
57     INADDR_ANY              = 0x00000000,
58     INADDR_NONE             = 0xFFFFFFFF,
59     INADDR_BROADCAST        = 0xFFFFFFFF,
60     SDLNET_MAX_UDPCHANNELS  = 32,
61     SDLNET_MAX_UDPADDRESSES = 4,
62 }
63 
64 // hack again
65 struct UDPsocketStruct {}
66 alias UDPsocketStruct* UDPsocket;
67 
68 struct UDPpacket
69 {
70     int channel;
71     Uint8 *data;
72     int len;
73     int maxlen;
74     int status;
75     IPaddress address;
76 }
77 
78 alias void* SDLNet_SocketSet;
79 
80 struct _SDLNet_GenericSocket
81 {
82     int ready;
83 }
84 alias _SDLNet_GenericSocket* SDLNet_GenericSocket;
85 
86 alias SDL_SetError SDLNet_SetError;
87 alias SDL_GetError SDLNet_GetError;
88 
89 void SDL_NET_VERSION(SDL_version* X)
90 {
91     X.major = SDL_NET_MAJOR_VERSION;
92     X.minor = SDL_NET_MINOR_VERSION;
93     X.patch = SDL_NET_PATCHLEVEL;
94 }
95 
96 int SDLNet_TCP_AddSocket(SDLNet_SocketSet set, TCPsocket sock)
97 {
98     return SDLNet_AddSocket(set, cast(SDLNet_GenericSocket)sock);
99 }
100 
101 int SDLNet_TCP_DelSocket(SDLNet_SocketSet set, TCPsocket sock)
102 {
103     return SDLNet_DelSocket(set, cast(SDLNet_GenericSocket)sock);
104 }
105 
106 int SDLNet_UDP_AddSocket(SDLNet_SocketSet set, UDPsocket sock)
107 {
108     return SDLNet_AddSocket(set, cast(SDLNet_GenericSocket)sock);
109 }
110 
111 int SDLNet_UDP_DelSocket(SDLNet_SocketSet set, UDPsocket sock)
112 {
113     return SDLNet_DelSocket(set, cast(SDLNet_GenericSocket)sock);
114 }
115 
116 bool SDLNet_SocketReady(TCPsocket sock)
117 {
118     return cast(bool)((sock !is null) && (cast(SDLNet_GenericSocket)sock).ready);
119 }
120 
121 bool SDLNet_SocketReady(UDPsocket sock)
122 {
123     return cast(bool)((sock !is null) && (cast(SDLNet_GenericSocket)sock).ready);
124 }
125 
126 void SDLNet_Write16(Uint16 value, void* areap)
127 {
128     Uint16* areap16 = cast(Uint16*)areap;
129     *areap16 = SDL_SwapBE16(value);
130 }
131 
132 Uint16 SDLNet_Read16(void *areap)
133 {
134     Uint16* areap16 = cast(Uint16*)areap;
135     return SDL_SwapBE16(*areap16);
136 }
137 
138 void SDLNet_Write32(Uint32 value, void* areap)
139 {
140     Uint32* areap32 = cast(Uint32*)areap;
141     *areap32 = SDL_SwapBE32(value);
142 }
143 
144 Uint32 SDLNet_Read32(void* areap)
145 {
146     Uint32* areap32 = cast(Uint32*)areap;
147     return SDL_SwapBE32(*areap32);
148 }
149 
150 extern(C)
151 {
152     alias CSDLVERPTR function() da_SDLNet_Linked_Version;
153     alias int function() da_SDLNet_Init;
154     alias void function() da_SDLNet_Quit;
155     alias int function(IPaddress*, in char*, Uint16) da_SDLNet_ResolveHost;
156     alias CCPTR function(in IPaddress*) da_SDLNet_ResolveIP;
157     alias int function(IPaddress*, int) da_SDLNet_GetLocalAddresses;
158     alias TCPsocket function(IPaddress*) da_SDLNet_TCP_Open;
159     alias TCPsocket function(TCPsocket) da_SDLNet_TCP_Accept;
160     alias IPaddress* function(TCPsocket) da_SDLNet_TCP_GetPeerAddress;
161     alias int function(TCPsocket,in void*,int) da_SDLNet_TCP_Send;
162     alias int function(TCPsocket,void*,int) da_SDLNet_TCP_Recv;
163     alias void function(TCPsocket) da_SDLNet_TCP_Close;
164     alias UDPpacket* function(int) da_SDLNet_AllocPacket;
165     alias int function(UDPpacket*) da_SDLNet_ResizePacket;
166     alias void function(UDPpacket*) da_SDLNet_FreePacket;
167     alias UDPpacket** function(int,int) da_SDLNet_AllocPacketV;
168     alias void function(UDPpacket**) da_SDLNet_FreePacketV;
169     alias UDPsocket function(Uint16) da_SDLNet_UDP_Open;
170     alias void function(Uint16) da_SDLNet_UDP_SetPacketLoss;
171     alias int function(UDPsocket,int,IPaddress*) da_SDLNet_UDP_Bind;
172     alias void function(UDPsocket,int) da_SDLNet_UDP_Unbind;
173     alias IPaddress* function(UDPsocket,int) da_SDLNet_UDP_GetPeerAddress;
174     alias int function(UDPsocket,UDPpacket**,int) da_SDLNet_UDP_SendV;
175     alias int function(UDPsocket,int,UDPpacket*) da_SDLNet_UDP_Send;
176     alias int function(UDPsocket,UDPpacket**) da_SDLNet_UDP_RecvV;
177     alias int function(UDPsocket,UDPpacket*) da_SDLNet_UDP_Recv;
178     alias void function(UDPsocket) da_SDLNet_UDP_Close;
179     alias SDLNet_SocketSet function(int) da_SDLNet_AllocSocketSet;
180     alias int function(SDLNet_SocketSet,SDLNet_GenericSocket) da_SDLNet_AddSocket;
181     alias int function(SDLNet_SocketSet,SDLNet_GenericSocket) da_SDLNet_DelSocket;
182     alias int function(SDLNet_SocketSet,Uint32) da_SDLNet_CheckSockets;
183     alias void function(SDLNet_SocketSet) da_SDLNet_FreeSocketSet;
184 }
185 
186 mixin(gsharedString!() ~
187 "
188 da_SDLNet_Linked_Version SDLNet_Linked_Version;
189 da_SDLNet_Init SDLNet_Init;
190 da_SDLNet_Quit SDLNet_Quit;
191 da_SDLNet_ResolveHost SDLNet_ResolveHost;
192 da_SDLNet_ResolveIP SDLNet_ResolveIP;
193 da_SDLNet_GetLocalAddresses SDLNet_GetLocalAddresses;
194 da_SDLNet_TCP_Open SDLNet_TCP_Open;
195 da_SDLNet_TCP_Accept SDLNet_TCP_Accept;
196 da_SDLNet_TCP_GetPeerAddress SDLNet_TCP_GetPeerAddress;
197 da_SDLNet_TCP_Send SDLNet_TCP_Send;
198 da_SDLNet_TCP_Recv SDLNet_TCP_Recv;
199 da_SDLNet_TCP_Close SDLNet_TCP_Close;
200 da_SDLNet_AllocPacket SDLNet_AllocPacket;
201 da_SDLNet_ResizePacket SDLNet_ResizePacket;
202 da_SDLNet_FreePacket SDLNet_FreePacket;
203 da_SDLNet_AllocPacketV SDLNet_AllocPacketV;
204 da_SDLNet_FreePacketV SDLNet_FreePacketV;
205 da_SDLNet_UDP_Open SDLNet_UDP_Open;
206 da_SDLNet_UDP_SetPacketLoss SDLNet_UDP_SetPacketLoss;
207 da_SDLNet_UDP_Bind SDLNet_UDP_Bind;
208 da_SDLNet_UDP_Unbind SDLNet_UDP_Unbind;
209 da_SDLNet_UDP_GetPeerAddress SDLNet_UDP_GetPeerAddress;
210 da_SDLNet_UDP_SendV SDLNet_UDP_SendV;
211 da_SDLNet_UDP_Send SDLNet_UDP_Send;
212 da_SDLNet_UDP_RecvV SDLNet_UDP_RecvV;
213 da_SDLNet_UDP_Recv SDLNet_UDP_Recv;
214 da_SDLNet_UDP_Close SDLNet_UDP_Close;
215 da_SDLNet_AllocSocketSet SDLNet_AllocSocketSet;
216 da_SDLNet_AddSocket SDLNet_AddSocket;
217 da_SDLNet_DelSocket SDLNet_DelSocket;
218 da_SDLNet_CheckSockets SDLNet_CheckSockets;
219 da_SDLNet_FreeSocketSet SDLNet_FreeSocketSet;
220 ");
221 
222 class DerelictSDLNetLoader : SharedLibLoader
223 {
224 public:
225     this()
226     {
227         super(
228             "SDL_net.dll",
229             "libSDL_net.so, libSDL_net-1.2.so, libSDL_net-1.2.so.0",
230             "../Frameworks/SDL_net.framework/SDL_net, /Library/Frameworks/SDL_net.framework/SDL_net, /System/Library/Frameworks/SDL_net.framework/SDL_net"
231         );
232     }
233 
234 protected:
235     override void loadSymbols()
236     {
237         if(!DerelictSDL.isLoaded)
238         {
239             throw new SharedLibLoadException("DerelictSDL must be loaded before attempting to load DerelictSDLNet!");
240         }
241 
242         bindFunc(cast(void**)&SDLNet_Linked_Version, "SDLNet_Linked_Version");
243         bindFunc(cast(void**)&SDLNet_Init, "SDLNet_Init");
244         bindFunc(cast(void**)&SDLNet_Quit, "SDLNet_Quit");
245         bindFunc(cast(void**)&SDLNet_ResolveHost, "SDLNet_ResolveHost");
246         bindFunc(cast(void**)&SDLNet_ResolveIP, "SDLNet_ResolveIP");
247         bindFunc(cast(void**)&SDLNet_GetLocalAddresses, "SDLNet_GetLocalAddresses");
248         bindFunc(cast(void**)&SDLNet_TCP_Open, "SDLNet_TCP_Open");
249         bindFunc(cast(void**)&SDLNet_TCP_Accept, "SDLNet_TCP_Accept");
250         bindFunc(cast(void**)&SDLNet_TCP_GetPeerAddress, "SDLNet_TCP_GetPeerAddress");
251         bindFunc(cast(void**)&SDLNet_TCP_Send, "SDLNet_TCP_Send");
252         bindFunc(cast(void**)&SDLNet_TCP_Recv, "SDLNet_TCP_Recv");
253         bindFunc(cast(void**)&SDLNet_TCP_Close, "SDLNet_TCP_Close");
254         bindFunc(cast(void**)&SDLNet_AllocPacket, "SDLNet_AllocPacket");
255         bindFunc(cast(void**)&SDLNet_ResizePacket, "SDLNet_ResizePacket");
256         bindFunc(cast(void**)&SDLNet_FreePacket, "SDLNet_FreePacket");
257         bindFunc(cast(void**)&SDLNet_AllocPacketV, "SDLNet_AllocPacketV");
258         bindFunc(cast(void**)&SDLNet_FreePacketV, "SDLNet_FreePacketV");
259         bindFunc(cast(void**)&SDLNet_UDP_Open, "SDLNet_UDP_Open");
260         bindFunc(cast(void**)&SDLNet_UDP_SetPacketLoss, "SDLNet_UDP_SetPacketLoss");
261         bindFunc(cast(void**)&SDLNet_UDP_Bind, "SDLNet_UDP_Bind");
262         bindFunc(cast(void**)&SDLNet_UDP_Unbind, "SDLNet_UDP_Unbind");
263         bindFunc(cast(void**)&SDLNet_UDP_GetPeerAddress, "SDLNet_UDP_GetPeerAddress");
264         bindFunc(cast(void**)&SDLNet_UDP_SendV, "SDLNet_UDP_SendV");
265         bindFunc(cast(void**)&SDLNet_UDP_Send, "SDLNet_UDP_Send");
266         bindFunc(cast(void**)&SDLNet_UDP_RecvV, "SDLNet_UDP_RecvV");
267         bindFunc(cast(void**)&SDLNet_UDP_Recv, "SDLNet_UDP_Recv");
268         bindFunc(cast(void**)&SDLNet_UDP_Close, "SDLNet_UDP_Close");
269         bindFunc(cast(void**)&SDLNet_AllocSocketSet, "SDLNet_AllocSocketSet");
270         bindFunc(cast(void**)&SDLNet_AddSocket, "SDLNet_AddSocket");
271         bindFunc(cast(void**)&SDLNet_DelSocket, "SDLNet_DelSocket");
272         bindFunc(cast(void**)&SDLNet_CheckSockets, "SDLNet_CheckSockets");
273         bindFunc(cast(void**)&SDLNet_FreeSocketSet, "SDLNet_FreeSocketSet");
274     }
275 }
276 
277 DerelictSDLNetLoader DerelictSDLNet;
278 
279 static this()
280 {
281     DerelictSDLNet = new DerelictSDLNetLoader();
282 }
283 
284 static ~this()
285 {
286     if(SharedLibLoader.isAutoUnloadEnabled())
287         DerelictSDLNet.unload();
288 }