1 /+ 2 + Copyright 2022 – 2023 Aya Partridge 3 + Copyright 2018 - 2022 Michael D. Parker 4 + Distributed under the Boost Software License, Version 1.0. 5 + (See accompanying file LICENSE_1_0.txt or copy at 6 + http://www.boost.org/LICENSE_1_0.txt) 7 +/ 8 module sdl_net; 9 10 import bindbc.sdl.config; 11 static if(bindSDLNet): 12 import bindbc.sdl.codegen; 13 14 import sdl.version_: SDL_version; 15 16 alias SDLNet_version = SDL_version; 17 18 enum SDLNetSupport: SDLNet_version{ 19 noLibrary = SDLNet_version(0,0,0), 20 badLibrary = SDLNet_version(0,0,255), 21 v2_0_0 = SDLNet_version(2,0,0), 22 v2_0_1 = SDLNet_version(2,0,1), 23 v2_2 = SDLNet_version(2,2,0), 24 25 deprecated("Please use `v2_0_0` instead") sdlNet200 = SDLNet_version(2,0,0), 26 deprecated("Please use `v2_0_1` instead") sdlNet201 = SDLNet_version(2,0,1), 27 } 28 29 enum sdlNetSupport = (){ 30 version(SDL_Net_2_2) return SDLNetSupport.v2_2; 31 else version(SDL_Net_201) return SDLNetSupport.v2_0_1; 32 else return SDLNetSupport.v2_0_0; 33 }(); 34 35 enum SDL_NET_MAJOR_VERSION = sdlNetSupport.major; 36 enum SDL_NET_MINOR_VERSION = sdlNetSupport.minor; 37 enum SDL_NET_PATCHLEVEL = sdlNetSupport.patch; 38 39 pragma(inline, true) void SDL_NET_VERSION(SDLNet_version* X) @nogc nothrow pure @safe{ 40 X.major = SDL_NET_MAJOR_VERSION; 41 X.minor = SDL_NET_MINOR_VERSION; 42 X.patch = SDL_NET_PATCHLEVEL; 43 } 44 45 bool SDL_NET_VERSION_ATLEAST(ubyte X, ubyte Y, ubyte Z){ return SDLNet_version(SDL_NET_MAJOR_VERSION, SDL_NET_MINOR_VERSION, SDL_NET_PATCHLEVEL) >= SDLNet_version(X, Y, Z); } 46 47 struct IPaddress{ 48 uint host; 49 ushort port; 50 } 51 52 enum: uint{ 53 INADDR_ANY = 0x0000_0000, 54 INADDR_NONE = 0xFFFF_FFFF, 55 INADDR_LOOPBACK = 0x7F00_0001, 56 INADDR_BROADCAST = 0xFFFF_FFFF, 57 } 58 59 struct _TCPsocket; 60 alias TCPsocket = _TCPsocket*; 61 62 enum SDLNET_MAX_UDPCHANNELS = 32; 63 64 enum SDLNET_MAX_UDPADRESSES = 4; 65 66 struct _UDPsocket; 67 alias UDPsocket = _UDPsocket*; 68 69 struct UDPpacket{ 70 int channel; 71 ubyte* data; 72 int len; 73 int maxlen; 74 int status; 75 IPaddress address; 76 } 77 78 struct _SDLNet_SocketSet; 79 alias SDLNet_SocketSet = _SDLNet_SocketSet*; 80 81 struct _SDLNet_GenericSocket{ 82 int ready; 83 } 84 alias SDLNet_GenericSocket = _SDLNet_GenericSocket*; 85 86 pragma(inline, true) @nogc nothrow{ 87 int SDLNet_TCP_AddSocket(SDLNet_SocketSet set, TCPsocket sock){ 88 return SDLNet_AddSocket(set, cast(SDLNet_GenericSocket)sock); 89 } 90 91 int SDLNet_UDP_AddSocket(SDLNet_SocketSet set, UDPsocket sock){ 92 return SDLNet_AddSocket(set, cast(SDLNet_GenericSocket)sock); 93 } 94 95 int SDLNet_TCP_DelSocket(SDLNet_SocketSet set, TCPsocket sock){ 96 return SDLNet_DelSocket(set, cast(SDLNet_GenericSocket)sock); 97 } 98 99 int SDLNet_UDP_DelSocket(SDLNet_SocketSet set, UDPsocket sock){ 100 return SDLNet_DelSocket(set, cast(SDLNet_GenericSocket)sock); 101 } 102 103 bool SDLNet_SocketReady(TCPsocket sock){ 104 return (sock !is null) && (cast(SDLNet_GenericSocket)sock).ready; 105 } 106 107 bool SDLNet_SocketReady(UDPsocket sock){ 108 return (sock !is null) && (cast(SDLNet_GenericSocket)sock).ready; 109 } 110 111 pure{ 112 import sdl.endian: SDL_SwapBE16, SDL_SwapBE32; 113 114 void SDLNet_Write16(ushort value, void* areap){ 115 *cast(ushort*)areap = SDL_SwapBE16(value); 116 } 117 118 void SDLNet_Write32(uint value, void* areap){ 119 *cast(uint*)areap = SDL_SwapBE32(value); 120 } 121 122 ushort SDLNet_Read16(const(void)* areap){ 123 return SDL_SwapBE16(*cast(const(ushort)*)areap); 124 } 125 126 uint SDLNet_Read32(const(void)* areap){ 127 return SDL_SwapBE32(*cast(const(uint)*)areap); 128 } 129 } 130 } 131 132 mixin(joinFnBinds((){ 133 string[][] ret; 134 ret ~= makeFnBinds([ 135 [q{const(SDLNet_version)*}, q{SDLNet_Linked_Version}, q{}], 136 [q{int}, q{SDLNet_Init}, q{}], 137 [q{void}, q{SDLNet_Quit}, q{}], 138 [q{int}, q{SDLNet_ResolveHost}, q{IPaddress* address, const(char)* host, ushort port}], 139 [q{const(char)*}, q{SDLNet_ResolveIP}, q{const(IPaddress)* ip}], 140 [q{int}, q{SDLNet_GetLocalAddresses}, q{IPaddress* addresses, int maxcount}], 141 [q{TCPsocket}, q{SDLNet_TCP_Open}, q{IPaddress* ip}], 142 [q{TCPsocket}, q{SDLNet_TCP_Accept}, q{TCPsocket server}], 143 [q{IPaddress*}, q{SDLNet_TCP_GetPeerAddress}, q{TCPsocket sock}], 144 [q{int}, q{SDLNet_TCP_Send}, q{TCPsocket sock, const(void)* data, int len}], 145 [q{int}, q{SDLNet_TCP_Recv}, q{TCPsocket sock, void* data, int len}], 146 [q{void}, q{SDLNet_TCP_Close}, q{TCPsocket sock}], 147 [q{UDPpacket*}, q{SDLNet_AllocPacket}, q{int size}], 148 [q{int}, q{SDLNet_ResizePacket}, q{UDPpacket* packet, int newsize}], 149 [q{void}, q{SDLNet_FreePacket}, q{UDPpacket* packet}], 150 [q{UDPpacket**}, q{SDLNet_AllocPacketV}, q{int howmany, int size}], 151 [q{void}, q{SDLNet_FreePacketV}, q{UDPpacket** packetV}], 152 [q{UDPsocket}, q{SDLNet_UDP_Open}, q{ushort port}], 153 [q{void}, q{SDLNet_UDP_SetPacketLoss}, q{UDPsocket sock, int percent}], 154 [q{int}, q{SDLNet_UDP_Bind}, q{UDPsocket sock, int channel, const(IPaddress)* address}], 155 [q{void}, q{SDLNet_UDP_Unbind}, q{UDPsocket sock, int channel}], 156 [q{IPaddress*}, q{SDLNet_UDP_GetPeerAddress}, q{UDPsocket sock, int channel}], 157 [q{int}, q{SDLNet_UDP_SendV}, q{UDPsocket sock, UDPpacket** packets, int npackets}], 158 [q{int}, q{SDLNet_UDP_Send}, q{UDPsocket sock, int channel, UDPpacket* packet}], 159 [q{int}, q{SDLNet_UDP_RecvV}, q{UDPsocket sock, UDPpacket** packets}], 160 [q{int}, q{SDLNet_UDP_Recv}, q{UDPsocket sock, UDPpacket* packet}], 161 [q{void}, q{SDLNet_UDP_Close}, q{UDPsocket sock}], 162 [q{SDLNet_SocketSet}, q{SDLNet_AllocSocketSet}, q{int maxsockets}], 163 [q{int}, q{SDLNet_AddSocket}, q{SDLNet_SocketSet set, SDLNet_GenericSocket sock}], 164 [q{int}, q{SDLNet_DelSocket}, q{SDLNet_SocketSet set, SDLNet_GenericSocket sock}], 165 [q{int}, q{SDLNet_CheckSockets}, q{SDLNet_SocketSet set, uint timeout}], 166 [q{void}, q{SDLNet_FreeSocketSet}, q{SDLNet_SocketSet set}], 167 [q{void}, q{SDLNet_SetError}, q{const(char)* fmt, ...}], 168 [q{const(char)*}, q{SDLNet_GetError}, q{}], 169 ]); 170 return ret; 171 }())); 172 173 static if(!staticBinding): 174 import bindbc.loader; 175 176 private{ 177 SharedLib lib; 178 SDLNetSupport loadedVersion; 179 enum libNamesCT = (){ 180 version(Windows){ 181 return [ 182 `SDL2_net.dll`, 183 ]; 184 }else version(OSX){ 185 return [ 186 `libSDL2_net.dylib`, 187 `/opt/homebrew/lib/libSDL2_net.dylib`, 188 `SDL2_net`, 189 `/Library/Frameworks/SDL2_net.framework/SDL2_net`, 190 `/System/Library/Frameworks/SDL2_net.framework/SDL2_net`, 191 ]; 192 }else version(Posix){ 193 return [ 194 `libSDL2_net.so`, 195 `libSDL2_net-2.0.so`, 196 `libSDL2_net-2.0.so.0`, 197 ]; 198 }else static assert(0, "BindBC-SDL_net does not have library search paths set up for this platform"); 199 }(); 200 } 201 202 @nogc nothrow: 203 deprecated("Please use `SDLNet_Linked_Version` instead") 204 SDLNetSupport loadedSDLNetVersion(){ return loadedVersion; } 205 206 mixin(bindbc.sdl.codegen.makeDynloadFns("Net", [__MODULE__]));