|
@@ -0,0 +1,400 @@
|
|
|
+package ENet
|
|
|
+
|
|
|
+when ODIN_OS == "windows" {
|
|
|
+ when ODIN_ARCH == "amd64" {
|
|
|
+ foreign import ENet {
|
|
|
+ "lib/enet64.lib",
|
|
|
+ "system:Ws2_32.lib",
|
|
|
+ "system:Winmm.lib",
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ foreign import ENet {
|
|
|
+ "lib/enet.lib",
|
|
|
+ "system:Ws2_32.lib",
|
|
|
+ "system:Winmm.lib",
|
|
|
+ }
|
|
|
+ }
|
|
|
+} else {
|
|
|
+ foreign import ENet "system:enet"
|
|
|
+}
|
|
|
+
|
|
|
+VERSION_MAJOR :: u8(1)
|
|
|
+VERSION_MINOR :: u8(3)
|
|
|
+VERSION_PATCH :: u8(17)
|
|
|
+
|
|
|
+VERSION_CREATE :: #force_inline proc(major, minor, patch: u8) -> u32 {
|
|
|
+ return (u32(major) << 16) | (u32(minor) << 8) | u32(patch)
|
|
|
+}
|
|
|
+
|
|
|
+VERSION_GET_MAJOR :: #force_inline proc(version: u32) -> u8 {
|
|
|
+ return u8((version >> 16) & 0xff)
|
|
|
+}
|
|
|
+VERSION_GET_MINOR :: #force_inline proc(version: u32) -> u8 {
|
|
|
+ return u8((version >> 8) & 0xff)
|
|
|
+}
|
|
|
+VERSION_GET_PATCH :: #force_inline proc(version: u32) -> u8 {
|
|
|
+ return u8(version & 0xff)
|
|
|
+}
|
|
|
+
|
|
|
+// Odin does not have "macros" or compile-time evaluation of functions, so the
|
|
|
+// following is just the same as.
|
|
|
+// VERSION :: VERSION_CREATE(VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
|
|
|
+VERSION :: (u32(VERSION_MAJOR) << 16) | (u32(VERSION_MINOR) << 8) | u32(VERSION_PATCH)
|
|
|
+
|
|
|
+// Network byte order is always Big Endian. Instead of using the method ENet
|
|
|
+// uses (leveraging {n,h}to{n,h}{s,l}), we can just use Odin's endianess types
|
|
|
+// to get the correct byte swaps, if any.
|
|
|
+HOST_TO_NET_16 :: #force_inline proc(value: u16) -> u16 {
|
|
|
+ return transmute(u16)u16be(value)
|
|
|
+}
|
|
|
+
|
|
|
+HOST_TO_NET_32 :: #force_inline proc(value: u32) -> u32 {
|
|
|
+ return transmute(u32)u32be(value)
|
|
|
+}
|
|
|
+
|
|
|
+NET_TO_HOST_16 :: #force_inline proc(value: u16) -> u16 {
|
|
|
+ return u16(transmute(u16be)value)
|
|
|
+}
|
|
|
+
|
|
|
+NET_TO_HOST_32 :: #force_inline proc(value: u32) -> u32 {
|
|
|
+ return u32(transmute(u32be)value)
|
|
|
+}
|
|
|
+
|
|
|
+Version :: u32
|
|
|
+
|
|
|
+SocketType :: enum i32 {
|
|
|
+ STREAM = 1,
|
|
|
+ DATAGRAM = 2,
|
|
|
+}
|
|
|
+
|
|
|
+SocketWait :: enum i32 {
|
|
|
+ NONE = 0,
|
|
|
+ SEND = 1 << 0,
|
|
|
+ RECEIVE = 1 << 1,
|
|
|
+ INTERRUPT = 1 << 2,
|
|
|
+}
|
|
|
+
|
|
|
+SocketOption :: enum i32 {
|
|
|
+ NONBLOCK = 1,
|
|
|
+ BROADCAST = 2,
|
|
|
+ RCVBUF = 3,
|
|
|
+ SNDBUF = 4,
|
|
|
+ REUSEADDR = 5,
|
|
|
+ RCVTIMEO = 6,
|
|
|
+ SNDTIMEO = 7,
|
|
|
+ ERROR = 8,
|
|
|
+ NODELAY = 9,
|
|
|
+}
|
|
|
+
|
|
|
+SocketShutdown :: enum i32 {
|
|
|
+ READ = 0,
|
|
|
+ WRITE = 1,
|
|
|
+ READ_WRITE = 2,
|
|
|
+}
|
|
|
+
|
|
|
+HOST_ANY :: u32(0)
|
|
|
+HOST_BROADCAST :: u32(0xffffffff)
|
|
|
+PORT_ANY :: u16(0)
|
|
|
+
|
|
|
+Address :: struct {
|
|
|
+ host: u32,
|
|
|
+ port: u16,
|
|
|
+}
|
|
|
+
|
|
|
+PacketFlag :: enum i32 {
|
|
|
+ RELIABLE = 1 << 0,
|
|
|
+ UNSEQUENCED = 1 << 1,
|
|
|
+ NO_ALLOCATE = 1 << 2,
|
|
|
+ UNRELIABLE_FRAGMENT = 1 << 3,
|
|
|
+ FLAG_SENT = 1 << 8,
|
|
|
+}
|
|
|
+
|
|
|
+PacketFreeCallback :: proc "c" (packet: ^Packet)
|
|
|
+
|
|
|
+Packet :: struct {
|
|
|
+ referenceCount: uint,
|
|
|
+ flags: u32,
|
|
|
+ data: [^]u8,
|
|
|
+ dataLength: uint,
|
|
|
+ freeCallback: PacketFreeCallback,
|
|
|
+ userData: rawptr,
|
|
|
+}
|
|
|
+
|
|
|
+Acknowledgment :: struct {
|
|
|
+ acknowledgementList: ListNode,
|
|
|
+ sentTime: u32,
|
|
|
+ command: Protocol,
|
|
|
+}
|
|
|
+
|
|
|
+OutgoingCommand :: struct {
|
|
|
+ outgoingCommandList: ListNode,
|
|
|
+ reliableSequenceNumber: u16,
|
|
|
+ unreliableSequenceNumber: u16,
|
|
|
+ sentTime: u32,
|
|
|
+ roundTripTimeout: u32,
|
|
|
+ roundTripTimeoutLimit: u32,
|
|
|
+ fragmentOffset: u32,
|
|
|
+ fragmentLength: u16,
|
|
|
+ sendAttempts: u16,
|
|
|
+ command: Protocol,
|
|
|
+ packet: ^Packet,
|
|
|
+}
|
|
|
+
|
|
|
+IncomingCommand :: struct {
|
|
|
+ incomingCommandList: ListNode,
|
|
|
+ reliableSequenceNumber: u16,
|
|
|
+ unreliableSequenceNumber: u16,
|
|
|
+ command: Protocol,
|
|
|
+ fragmentCount: u32,
|
|
|
+ fragmentsRemaining: u32,
|
|
|
+ fragments: [^]u32,
|
|
|
+ packet: ^Packet,
|
|
|
+}
|
|
|
+
|
|
|
+PeerState :: enum i32 {
|
|
|
+ DISCONNECTED,
|
|
|
+ CONNECTING,
|
|
|
+ ACKNOWLEDGING_CONNECT,
|
|
|
+ CONNECTION_PENDING,
|
|
|
+ CONNECTION_SUCCEEDED,
|
|
|
+ CONNECTED,
|
|
|
+ DISCONNECT_LATER,
|
|
|
+ DISCONNECTING,
|
|
|
+ ACKNOWLEDGING_DISCONNECT,
|
|
|
+ ZOMBIE,
|
|
|
+}
|
|
|
+
|
|
|
+BUFFER_MAXIMUM :: (1 + 2 * PROTOCOL_MAXIMUM_PACKET_COMMANDS)
|
|
|
+
|
|
|
+HOST_RECEIVE_BUFFER_SIZE :: 256 * 1024
|
|
|
+HOST_SEND_BUFFER_SIZE :: 256 * 1024
|
|
|
+HOST_BANDWIDTH_THROTTLE_INTERVAL :: 1000
|
|
|
+HOST_DEFAULT_MTU :: 1400
|
|
|
+HOST_DEFAULT_MAXIMUM_PACKET_SIZE :: 32 * 1024 * 1024
|
|
|
+HOST_DEFAULT_MAXIMUM_WAITING_DATA :: 32 * 1024 * 1024
|
|
|
+
|
|
|
+PEER_DEFAULT_ROUND_TRIP_TIME :: 500
|
|
|
+PEER_DEFAULT_PACKET_THROTTLE :: 32
|
|
|
+PEER_PACKET_THROTTLE_SCALE :: 32
|
|
|
+PEER_PACKET_THROTTLE_COUNTER :: 7
|
|
|
+PEER_PACKET_THROTTLE_ACCELERATION :: 2
|
|
|
+PEER_PACKET_THROTTLE_DECELERATION :: 2
|
|
|
+PEER_PACKET_THROTTLE_INTERVAL :: 5000
|
|
|
+PEER_PACKET_LOSS_SCALE :: 1 << 16
|
|
|
+PEER_PACKET_LOSS_INTERVAL :: 10000
|
|
|
+PEER_WINDOW_SIZE_SCALE :: 64 * 1024
|
|
|
+PEER_TIMEOUT_LIMIT :: 32
|
|
|
+PEER_TIMEOUT_MINIMUM :: 5000
|
|
|
+PEER_TIMEOUT_MAXIMUM :: 30000
|
|
|
+PEER_PING_INTERVAL :: 500
|
|
|
+PEER_UNSEQUENCED_WINDOWS :: 64
|
|
|
+PEER_UNSEQUENCED_WINDOW_SIZE :: 1024
|
|
|
+PEER_FREE_UNSEQUENCED_WINDOWS :: 32
|
|
|
+PEER_RELIABLE_WINDOWS :: 16
|
|
|
+PEER_RELIABLE_WINDOW_SIZE :: 0x1000
|
|
|
+PEER_FREE_RELIABLE_WINDOWS :: 8
|
|
|
+
|
|
|
+Channel :: struct {
|
|
|
+ outgoingReliableSequenceNumber: u16,
|
|
|
+ outgoingUnreliableSequenceNumber: u16,
|
|
|
+ usedReliableWindows: u16,
|
|
|
+ reliableWindows: [PEER_RELIABLE_WINDOWS]u16,
|
|
|
+ incomingReliableSequenceNumber: u16,
|
|
|
+ incomingUnreliableSequenceNumber: u16,
|
|
|
+ incomingReliableCommands: List,
|
|
|
+ incomingUnreliableCommands: List,
|
|
|
+}
|
|
|
+
|
|
|
+PeerFlag :: enum i32 {
|
|
|
+ NEEDS_DISPATCH,
|
|
|
+}
|
|
|
+
|
|
|
+Peer :: struct {
|
|
|
+ dispatchList: ListNode,
|
|
|
+ host: ^Host,
|
|
|
+ outgoingPeerID: u16,
|
|
|
+ incomingPeerID: u16,
|
|
|
+ connectID: u32,
|
|
|
+ outgoingSessionID: u8,
|
|
|
+ incomingSessionID: u8,
|
|
|
+ address: Address,
|
|
|
+ data: rawptr,
|
|
|
+ state: PeerState,
|
|
|
+ channels: [^]Channel,
|
|
|
+ channelCount: uint,
|
|
|
+ incomingBandwidth: u32,
|
|
|
+ outgoingBandwidth: u32,
|
|
|
+ incomingBandwidthThrottleEpoch: u32,
|
|
|
+ outgoingBandwidthThrottleEpoch: u32,
|
|
|
+ incomingDataTotal: u32,
|
|
|
+ outgoingDataTotal: u32,
|
|
|
+ lastSendTime: u32,
|
|
|
+ lastReceiveTime: u32,
|
|
|
+ nextTimeout: u32,
|
|
|
+ earliestTimeout: u32,
|
|
|
+ packetLossEpoch: u32,
|
|
|
+ packetsSent: u32,
|
|
|
+ packetsLost: u32,
|
|
|
+ packetLoss: u32,
|
|
|
+ packetLossVariance: u32,
|
|
|
+ packetThrottle: u32,
|
|
|
+ packetThrottleLimit: u32,
|
|
|
+ packetThrottleCounter: u32,
|
|
|
+ packetThrottleEpoch: u32,
|
|
|
+ packetThrottleAcceleration: u32,
|
|
|
+ packetThrottleDeceleration: u32,
|
|
|
+ packetThrottleInterval: u32,
|
|
|
+ pingInterval: u32,
|
|
|
+ timeoutLimit: u32,
|
|
|
+ timeoutMinimum: u32,
|
|
|
+ timeoutMaximum: u32,
|
|
|
+ lastRoundTripTime: u32,
|
|
|
+ lowestRoundTripTime: u32,
|
|
|
+ lastRoundTripTimeVariance: u32,
|
|
|
+ highestRoundTripTimeVariance: u32,
|
|
|
+ roundTripTime: u32,
|
|
|
+ roundTripTimeVariance: u32,
|
|
|
+ mtu: u32,
|
|
|
+ windowSize: u32,
|
|
|
+ reliableDataInTransit: u32,
|
|
|
+ outgoingReliableSequenceNumber: u16,
|
|
|
+ acknowledgements: List,
|
|
|
+ sentReliableCommands: List,
|
|
|
+ sentUnreliableCommands: List,
|
|
|
+ outgoingCommands: List,
|
|
|
+ dispatchedCommands: List,
|
|
|
+ flags: u16,
|
|
|
+ reserved: u16,
|
|
|
+ incomingUnsequencedGroup: u16,
|
|
|
+ outgoingUnsequencedGroup: u16,
|
|
|
+ unsequencedWindow: [PEER_UNSEQUENCED_WINDOW_SIZE / 32]u32,
|
|
|
+ eventData: u32,
|
|
|
+ totalWaitingData: uint,
|
|
|
+}
|
|
|
+
|
|
|
+Compressor :: struct {
|
|
|
+ context_: rawptr,
|
|
|
+ compress: proc "c" (context_: rawptr, inBuffers: [^]Buffer, inBufferCount: uint, inLimit: uint, outData: [^]u8, outLimit: uint) -> uint,
|
|
|
+ decompress: proc "c" (context_: rawptr, inData: [^]u8, inLimit: uint, outData: [^]u8, outLimit: uint) -> uint,
|
|
|
+ destroy: proc "c" (context_: rawptr),
|
|
|
+}
|
|
|
+
|
|
|
+ChecksumCallback :: proc "c" (buffers: [^]Buffer, bufferCount: uint) -> u32
|
|
|
+InterceptCallback :: proc "c" (host: ^Host, event: ^Event) -> i32
|
|
|
+
|
|
|
+Host :: struct {
|
|
|
+ socket: Socket,
|
|
|
+ address: Address,
|
|
|
+ incomingBandwidth: u32,
|
|
|
+ outgoingBandwidth: u32,
|
|
|
+ bandwidthThrottleEpoch: u32,
|
|
|
+ mtu: u32,
|
|
|
+ randomSeed: u32,
|
|
|
+ recalculateBandwidthLimits: i32,
|
|
|
+ peers: [^]Peer,
|
|
|
+ peerCount: uint,
|
|
|
+ channelLimit: uint,
|
|
|
+ serviceTime: u32,
|
|
|
+ dispatchQueue: List,
|
|
|
+ continueSending: i32,
|
|
|
+ packetSize: uint,
|
|
|
+ headerFlags: u16,
|
|
|
+ commands: [PROTOCOL_MAXIMUM_PACKET_COMMANDS]Protocol,
|
|
|
+ commandCount: uint,
|
|
|
+ buffers: [BUFFER_MAXIMUM]Buffer,
|
|
|
+ bufferCount: uint,
|
|
|
+ checksum: ChecksumCallback,
|
|
|
+ compressor: Compressor,
|
|
|
+ packetData: [2][PROTOCOL_MAXIMUM_MTU]u8,
|
|
|
+ receivedAddress: Address,
|
|
|
+ receivedData: [^]u8,
|
|
|
+ receivedDataLength: uint,
|
|
|
+ totalSentData: u32,
|
|
|
+ totalSentPackets: u32,
|
|
|
+ totalReceivedData: u32,
|
|
|
+ totalReceivedPackets: u32,
|
|
|
+ intercept: InterceptCallback,
|
|
|
+ connectedPeers: uint,
|
|
|
+ bandwidthLimitedPeers: uint,
|
|
|
+ duplicatePeers: uint,
|
|
|
+ maximumPacketSize: uint,
|
|
|
+ maximumWaitingData: uint,
|
|
|
+}
|
|
|
+
|
|
|
+EventType :: enum i32 {
|
|
|
+ NONE = 0,
|
|
|
+ CONNECT = 1,
|
|
|
+ DISCONNECT = 2,
|
|
|
+ RECEIVE = 3,
|
|
|
+}
|
|
|
+
|
|
|
+Event :: struct {
|
|
|
+ type: EventType,
|
|
|
+ peer: ^Peer,
|
|
|
+ channelID: u8,
|
|
|
+ data: u32,
|
|
|
+ packet: ^Packet,
|
|
|
+}
|
|
|
+
|
|
|
+@(default_calling_convention="c", link_prefix="enet_")
|
|
|
+foreign ENet {
|
|
|
+ initialize :: proc() -> i32 ---
|
|
|
+ initialize_with_callbacks :: proc(version: Version, inits: ^Callbacks) -> i32 ---
|
|
|
+ deinitialize :: proc() ---
|
|
|
+ linked_version :: proc() -> Version ---
|
|
|
+ time_get :: proc() -> u32 ---
|
|
|
+ time_set :: proc(u32) ---
|
|
|
+
|
|
|
+ socket_create :: proc(SocketType) -> Socket ---
|
|
|
+ socket_bind :: proc(Socket, ^Address) -> i32 ---
|
|
|
+ socket_get_address :: proc(Socket, ^Address) -> i32 ---
|
|
|
+ socket_listen :: proc(Socket, i32) -> i32 ---
|
|
|
+ socket_accept :: proc(Socket, ^Address) -> Socket ---
|
|
|
+ socket_connect :: proc(Socket, ^Address) -> i32 ---
|
|
|
+ socket_send :: proc(Socket, ^Address, ^Buffer, uint) -> i32 ---
|
|
|
+ socket_receive :: proc(Socket, ^Address, ^Buffer, uint) -> i32 ---
|
|
|
+ socket_wait :: proc(Socket, ^u32, u32) -> i32 ---
|
|
|
+ socket_set_option :: proc(Socket, SocketOption, i32) -> i32 ---
|
|
|
+ socket_get_option :: proc(Socket, SocketOption, ^i32) -> i32 ---
|
|
|
+ socket_shutdown :: proc(Socket, SocketShutdown) -> i32 ---
|
|
|
+ socket_destroy :: proc(Socket) ---
|
|
|
+ socketset_select :: proc(Socket, ^SocketSet, ^SocketSet, u32) -> i32 ---
|
|
|
+
|
|
|
+ address_set_host_ip :: proc(address: ^Address, hostName: cstring) -> i32 ---
|
|
|
+ address_set_host :: proc(address: ^Address, hostName: cstring) -> i32 ---
|
|
|
+ address_get_host_ip :: proc(address: ^Address, hostName: [^]u8, nameLength: uint) -> i32 ---
|
|
|
+ address_get_host :: proc(address: ^Address, hostName: [^]u8, nameLength: uint) -> i32 ---
|
|
|
+
|
|
|
+ packet_create :: proc(rawptr, uint, u32) -> ^Packet ---
|
|
|
+ packet_destroy :: proc(^Packet) ---
|
|
|
+ packet_resize :: proc(^Packet, uint) -> i32 ---
|
|
|
+ crc32 :: proc(^Buffer, uint) -> u32 ---
|
|
|
+
|
|
|
+ host_create :: proc(^Address, uint, uint, u32, u32) -> ^Host ---
|
|
|
+ host_destroy :: proc(^Host) ---
|
|
|
+ host_connect :: proc(^Host, ^Address, uint, u32) -> ^Peer ---
|
|
|
+ host_check_events :: proc(^Host, ^Event) -> i32 ---
|
|
|
+ host_service :: proc(^Host, ^Event, u32) -> i32 ---
|
|
|
+ host_flush :: proc(^Host) ---
|
|
|
+ host_broadcast :: proc(^Host, u8, ^Packet) ---
|
|
|
+ host_compress :: proc(^Host, ^Compressor) ---
|
|
|
+ host_compress_with_range_coder :: proc(^Host) -> i32 ---
|
|
|
+ host_channel_limit :: proc(^Host, uint) ---
|
|
|
+ host_bandwidth_limit :: proc(^Host, u32, u32) ---
|
|
|
+
|
|
|
+ peer_send :: proc(^Peer, u8, ^Packet) -> i32 ---
|
|
|
+ peer_receive :: proc(^Peer, ^u8) -> ^Packet ---
|
|
|
+ peer_ping :: proc(^Peer) ---
|
|
|
+ peer_ping_interval :: proc(^Peer, u32) ---
|
|
|
+ peer_timeout :: proc(^Peer, u32, u32, u32) ---
|
|
|
+ peer_reset :: proc(^Peer) ---
|
|
|
+ peer_disconnect :: proc(^Peer, u32) ---
|
|
|
+ peer_disconnect_now :: proc(^Peer, u32) ---
|
|
|
+ peer_disconnect_later :: proc(^Peer, u32) ---
|
|
|
+ peer_throttle_configure :: proc(^Peer, u32, u32, u32) ---
|
|
|
+
|
|
|
+ range_coder_create :: proc() -> rawptr ---
|
|
|
+ range_coder_destroy :: proc(rawptr) ---
|
|
|
+ range_coder_compress :: proc(rawptr, [^]Buffer, uint, uint, [^]u8, uint) -> uint ---
|
|
|
+ range_coder_decompress :: proc(rawptr, [^]u8, uint, [^]u8, uint) -> uint ---
|
|
|
+}
|