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