From e15f2453399d0506692a64cdc190d4239a7c6661 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 23 Oct 2021 07:40:40 -0400 Subject: [PATCH 01/15] vendor ENet --- vendor/ENet/callbacks.odin | 7 + vendor/ENet/enet.odin | 392 +++++++++++++++++++++++++++++++++++++ vendor/ENet/lib/enet.lib | Bin 0 -> 48016 bytes vendor/ENet/lib/enet64.lib | Bin 0 -> 52236 bytes vendor/ENet/list.odin | 10 + vendor/ENet/protocol.odin | 164 ++++++++++++++++ vendor/ENet/time.odin | 23 +++ vendor/ENet/unix.odin | 59 ++++++ vendor/ENet/win32.odin | 81 ++++++++ 9 files changed, 736 insertions(+) create mode 100644 vendor/ENet/callbacks.odin create mode 100644 vendor/ENet/enet.odin create mode 100644 vendor/ENet/lib/enet.lib create mode 100644 vendor/ENet/lib/enet64.lib create mode 100644 vendor/ENet/list.odin create mode 100644 vendor/ENet/protocol.odin create mode 100644 vendor/ENet/time.odin create mode 100644 vendor/ENet/unix.odin create mode 100644 vendor/ENet/win32.odin diff --git a/vendor/ENet/callbacks.odin b/vendor/ENet/callbacks.odin new file mode 100644 index 000000000..444c191d6 --- /dev/null +++ b/vendor/ENet/callbacks.odin @@ -0,0 +1,7 @@ +package ENet + +Callbacks :: struct { + malloc: proc "c" (size: uint) -> rawptr, + free: proc "c" (memory: rawptr), + no_memory: proc "c" (), +} \ No newline at end of file diff --git a/vendor/ENet/enet.odin b/vendor/ENet/enet.odin new file mode 100644 index 000000000..175766ef1 --- /dev/null +++ b/vendor/ENet/enet.odin @@ -0,0 +1,392 @@ +package ENet + +when ODIN_OS == "windows" { + when ODIN_ARCH == "amd64" { + foreign import ENet "lib/enet64.lib" + } else { + foreign import ENet "lib/enet.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: cstring, nameLength: uint) -> i32 --- + address_get_host :: proc(address: ^Address, hostName: cstring, 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 --- +} \ No newline at end of file diff --git a/vendor/ENet/lib/enet.lib b/vendor/ENet/lib/enet.lib new file mode 100644 index 0000000000000000000000000000000000000000..f713886a8293a264b346dc02fe341ef41706a560 GIT binary patch literal 48016 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 Pwf{@)a~p$5f9n4S1!tn_ literal 0 HcmV?d00001 diff --git a/vendor/ENet/lib/enet64.lib b/vendor/ENet/lib/enet64.lib new file mode 100644 index 0000000000000000000000000000000000000000..21e4edf4aea3ef53326a0cd406af655ed1c22889 GIT binary patch literal 52236 zcmeFae|%KM)jxi3vV;&LHz?YuR9CxVwjd^eniXjGCY$80Y%mI9tds;o)y5 zZNly*xxKDUTdF=!Z9hDH{IpuzYFi(IXzgwglHjiZilEgZt(qnN0Id*E$@hI`?!CL4 z4bo5h^!fhr`P^4F_uMlxXMUYIb7tnu%*FFpG}Y97E$a$v@{^zN$>GHRR%=0_V>b6v zoh1l@TM#Bbocud8Ul7LrrcW1yFZ#{P6NIt9um4RD5`RjQApCd!8hJi(Nw#7ZA)T^ zF`vz-J|4aiRfk%wNyxm8O3J>DLq(V&Ynp22%+`t2q7IYO*+{6S+M3#WBON-X8L@rK zU+b^cYm}kau0a(gl&yhWRo|S7Mu1RzUU4LU0!rZ!+XrdxlqkUBY>_153&Z!$`ea!ct*@H=kW z%EE@?Ya5JMs^Z+j+K;!v-(1IY#@ka}ZO!dfwJoRxJwXf&W^Spk z(Tg@NZ+O5}wPP_X4BGUnwX3U|YisrT@}c&tZZ#N%eVJ^tV$~`VDe Vxj9BIq|U$ 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�y_s#UyQ^-dTb(p7Vv$TujYwiG(Ge5F!gZr2ADmIv2qN5 z!kFlI`!6^eyN0|Q@@7nbw9cblN@3k7N_C^HA0RAC^E~P*Tcu0o2L_jGW%>H?G;&{A zC3$B@uwfDT84NwJ-b`Fnu72)TKkRmgJ97{p>u+SOQvpnJ@V}5}6rB|O6@YTB^>D#} zJN%u)FapFvZ+V@&j|nv*4UhyIRRh+Rs%fn5cAS)gZvg{oNPV3tNref2~pjM^wpq>)LUgsw~-^31?l zMPs@&+`~h6)#%-sTm1>ux^5uk)~c-3L46&GbZZh>2L*o*PAJjJomgU)XOy)q7`3$r8D$f%y?=G|I|j+JEX_A^S5 zc4IYSqzsjZ!&}ZL5efSoC4Adw?!b`f4*$sDSoBn}(LpTAlEFk>IqpRW(g8aj$0t(9 z?*Ozt?<7NrIyiqX58QxDIZjHgXMw%$&&Ox+D@fwTs) zmjTg;Zyr)e2pAmEMN92}Bw8ReQP%FC2@uR~QP0MryIcDarP{4B@ABxNnofxd?Le-| zHKuXMT8R@(0zV_}a8(XCg0ZRExekOF_qw&UIoNE1Z4BqfsC}7>l)wWk1v3+nIN*+L zV}PkHdV-hR-I>(%868}g1lt!CXPE85MJuenJ89C&1;c4|&}HB4viIZkR^o%QLD_NB zvr@;4=p_{D7|HKmJ>?TU zjuD@Pv$yY|In*x@>EKLCg&FyH8 zVC(ZG+D$=rH`hEA3y1`X^}Yp|-FuVJp9lU(GBU$I-R)?#`mJDD{{^TPYQypN8~2ZM z*1Bl*Nf!Sw_*J|Dp_lP8n{CX498>c#+b?e%Qs~ccp!N_t41jnak*r6|YQKHZzLPhn zvR>IywngfEfq5xA;GR)ZjdN=uXr2N_!Rc?X@IB6o3f33Y(!TsLa`aO;8u2kk#+?r_ zHz^A^2X3dmSFfZFnqRc{FOV)n)4D$b1v}VJ8SRO)ePd>iS94(ILF@v<8x-kBq_^>od-y-&9Ax$q{y}EKZPXVm z;O+z$nEC|E&bcNjs57X($QVh>BjrjVkfi2iTwuFbP1-x)LxAnAL;B% zQY!YaaTpyk)JKVjx}a-peMOn>G+CyY(%q%WvfSbuuJ9rR@W!d(qzruY( z=!L=ykbFp*9dz2Jvqb&G1Ld4tWGD`~YSg|9*V~Zz?WDyf)W5O#ngF=NK^vX>%m%6O?G8U^+ky^=6gf;`7{^Y(LEnWgsCX_63Fs)w zLbsM}lb@sr6eRZndLvP|_<@HZ+X|K$)J2zqn4}=>URG)bWie>mhbY}>BnRk?;1TwQ z`ir+52-^OHH?~Dae3!s%2B{w%WJ$+z0#Eucz$b3#D&!w3Bh1`CVHnug03-EeGDVb| zGSP{p)F-QbWP{oMt^kd<{jE_+k^YE{EbDDe*vdqs7rM0V#MhPRar{nxJ#Y{^hDN`x z1l~HS1m3}~H!bjP8jkHei4_u@C47QjfxZm%?uz6(g5L>{J&v(ua0XIIMxEvJVC5jy|}D^JHckg|4tVY&JusaH-o1x`RIzZwAWHrcU}RfiPZ4*CI{j2@Z>Cs4jS z7wW>7)Dl?+R)W( zw9#4PvRGOTEof<;hwPZeZEjeG1xOOO!$lUFDBExpQ9x;$9e77_ww=tDI^Sk-9yVse z4v@5?BQ&Job8vBo=cmC&RO+Pp0XDM0eT#_SpM}tAQt01+#-u7GB=$==qG~b5F3*#8i

(LbL+o0JX0#4caM#h&RdHp*Th7MV|&w; zZd|&^c+9cAH4kkh5A@M2i!%U|6hhiwGY2<*JYVe zv~BuES1q95mvI0${JEsEUKE4T*h9B~&{6Kuf=kpeU(1}JDv%I!*$;7Tr1eqsd}Pu~ z9X4698C4|(o?@M}QC(8!qcpndS(w3V8+Q&#J=g~^bE11*kX4%0$*k_;6(?<2had@+ zCw1ORG}x`obXo2~ixQsShCLsZO7vX|<}#g}HciZ7#^}1~vKqmqIvDDZwKkb;)4Xcn z5E>;jFokJu228c@6(Qx?=3$(&8EdO%djZpM4jPg=K19xx@Qr8%gVF{zN4D87n5|$J zxsn<4mz^k6J|B$!8hiYD$VL26ag0bC9%a6UW1pgq<7_N-{t$Q#Sy4aNQ@=1%Ry!U7 zCF46A-w&GK_}GMx*tM*x$bV{^Rwnb)=JMb%Zz_Un{`EI(=y&6$2tr*>l|4Wbr z?B$YzzayaoVa;~bP>(c~WLg8T$ZJ_IKMfsm(nOwqD0&@?VC49z=tz0&4|>H=E0qF~ zFZ-|?zP)$|)Jm0B&0>MEs94W1I3t+e4zLd2V{)LGBT=#3t7>pof{S8*L|#1(F% z$quh$Z}__cK+G*-_ovixDbl4Lfd`ret@NVDpxZC^yX^aL{&R3DDqcP84nN}r9d{p_ zu|PJVUDK{AARZ^_fCpl+gW__jhwUTA{#)$2#a<=I5%g0eKj_NMN<+MmXn|nYRZA-9 zN1?gWvCfrDVyj2?9K<2QIFnkQw2?&|y8{&%Z$9hcJ&{cs@EtEhmg(fyvk)GV%I_LN zB$l6@NRTMi?sih^@r0+f(UpK6@y~Q8MJ4Aq)^h0PYrWxM+e5tVY|2I0MM^OI# zXnS?ki29{__|S%_I@-eQ(O1E2kQCJf&{^~A2%yvFeWS0^y#6}K9T+@d+2V)TVdZkr zjg)~dfau;0=8!sD$qi-ZlhOSI>gfx2;i2|$Ke*I+Grrlt0$hs~p+;B;uY-l~G2d5V zQICBSXzL`jhR=eHw-k7S`g#pJ+2H|}-=(npj<&w7grBx;f~O~uG4um(QYHF6{@*U7 z6w`M&Y&>Fg5?)N~{fsQO(%G zyn*!^dk%!q_uYfK2&_@W;&Ar)lhUvQzf#dEauvs}mJCc{m)Ku(VLTmPoU5cOIVI{K zizjfmB1oYd5R#O%N~F!`wPFjXYV|x#V%gn}7OZC%_Rr_&!XjKT0!6DOA6mssBQWE# z5lq-^f|NIqCE6lftT2E>k$|MV5TD2PQ|(~w1e2xMq4*rW=wL2GxTwfE#&`;5W|Rdd zQBG3looHU#!fB8<^O!tC|Hd#@h9QY2g_bgmjbS!1j0+efX_})rPYPX)54ZN4!*D6* zv+W+ocK=ziH(BmhV~S@xrlRoS4SYLC^uO2kZTqPI9oE8_(`Goi+wWHB(1w=F+&JVw z>S^D69sHvNzJ#=TRpZm2=?(nH6L30-nHIVfzS^u{nq47vxtdPN_%hWth6HC|t_f2i zY~6%rU9h!=5~YV_73S9Nqm;9t*m&W~(u#7^i!d2d+Q|5p=`5H=}a^)3Z5J=si;K9dwJ}3sgJHmCVO|SR7%4MNCy94%Cn8NB2@P zHTGK!$DyI%-cj1Do4_Jy+U~H7`wcjI{5zc8_0XuaN({2RK#Dv(Z070mDW*V^Y1ftTCbxb50inIU#FA4hW|*sPQrL5 zWG$OW{|X7+1g)f>X-}l)L@;i~97_8E>Q5%^l+|76S_CwK_O}Q_o4m?)+4r`e`~0&lsH)XYIT-q9YjzLJVOMa-gB~Q2Me!u zY#}6*LM2j32l+9gP&*>{3Po5Jh#OJ8K41jN)$0y#J`4!#(ZIV1y+z^%!o{NE_yq0o zo-C3!tD$dyA_c#L5AVE^9RK^SYi_jr-(@rv#|Kid7B1!UmMYCo>Qc&Y-(69jz7$Qe zAN`4f)9}PW$oI+&+)eqq@5^+V0rvRuPyb|Hcpk${?ZrhFX*2e<;a-y^wrXs;!2Q*g zj5m#WP->*r<2KR))CdAH-+KGRzPQAuNj!qxakS1C7|Fm;28j+pJ_avgK|jYLf)sil z194nfU70S0c4P8RHX01t32QS~qCa7AoUXM5KnQzn^bw8}2og1Ol!N^t_>MCuiYIBL zBXur;ds4SwOo+s8e>M^mMd;-Z zQzcXDS;P<WM$?N&dr{KAr&z@iH-@;Rj~f#KZY--&ys_6X z0K(Z4m;%5`bm>Q2C8&S~ppPptTrLb8pVXSi*>KOnW4$2~o1wEXchmNc=#y~IJe2mf z6G+KPBoAebzRVmE#ts1ofpT*m_TxOrM#@s?GDI4ifq%S?(OWq6(GpT@`+)6)egk7R zV}6k2Vek&iqt0mlsDA>j#?g&QfdlE(-sEdat^Ta|H@k5hewJSB*48+w*P`BQ{wM?p_oPO{ zMHIMjm*m2}Wa>`COC|_i9;kO+i!N3iuSfw}Sf;bGpoOhdp!iiQ>IaIt9j76e6ueFw zz_5og4Xd4OFC=Y%gn+n^6%iaUo4SLq{NZ4t&7g!sasbin1I`*K-J!oO}Y_ z=-yq&-lqRWk*z~yr|W5X2WwuFBUw=RQ1WQZG=v$WQ;wN_Kpx{`CL)l7ZW?VPL^Fm) zcg?Q3?pQ{iw+5iIk$eO1Ejk~aFS5!tPhPva=7p|=x_mF11Jx$0g|49O=Q`{IOlvNv zWsriWhw*{aGxlOUREN)BF*mvkB?n)Rn_pA$^@RS#?}!3-8Q;VzaHp;Yikp5{6o$*} z+t82sJu2|_EYJ`$(;ylR(F1Hhu&m-@?Px|a1^`oKsTlv0Mw~I6bTXrvo`Md}9`He?_KtWd{eSx0 zA43%;oTu<~VF-oMN`LBD|k(Hk?Ruo)0kxv&gQZ2r*S+bxRNqy z3|?3r^O4H~puT2MYhCqQTg44C=T7 z-+2zy)L1Jzx2-=w1uD{iVnF+&gsP;DfEz;?Cky-%u8Gr1x-gHOO_fdK1GRU!U8i1w z5{=a(wt}NrxZ4fATCCUwz*KBJeC($G@GZV+T%;?!CY7vqQcT=O)lU&Vp`nugrmJy^;|2e@F){-(+7H)NU+~@0_U%03jw2X7P8WO)Olkcq zQ(E6d7~d@gyJO|h&uHz1FHGqgx;hvgO0)Mux9dkS>qfJ!&hn!a$|i|9Qt}H>Dn(y!6$%X zd3c}YK??pS`C)_M*V$nB73M7rEHZNh)KO<{2h(n)P{y$S%@lkobQDF0EK;v;pb4H@*< zFq6&=bW$1cA|&+`3}}H96R@4Xg>r0gV73%`<6VOTE5U&;;mb8|DLC*6(xD^xlzKep zp7bK&Cu3hj!cE@KM0#R15C~)t5DG*7nWYr_4!%r};8xf+>CHK`j95Z%b<9h=k;rfw zlUZY=K2|D(&Vk?I9-a53P#cMrPx0@Rx2MznWn=eo(?0ES?jA$+3gQI)B<%6Rv76g3 zNV&Nk!Gv;JcE(eIcPGXLxq!)-;1`%unF;uDy#I)w3vdMQgZL?c59573#AOBGYP`u_ zeih&r@KnWxg7Ea01>pf)hf#^&w=TwgSj201XP<}LLa>9W7{5{Mo_vE0*T;FNw&=;{ zFP0Vp4Lmv~_8_V3G4PardW>(HU8Dy|WRKylf2O=nwP2B09gif zHF$^P$^dcPZAj`x%(V}Yl|jbvYrr3J6r_Mq=*zQ$Uw6+z6nrFlYv{Y-7-^ zfOs7L2?zy?ux*%e;bFS~@p!XQ7?(2F0zf>(1{3#l6E}#Cj8pkA%h=mH5kqfIWf~w( z`D#Esr9U-sj{xG7i%{fN7Te2!E@My?xP_-aXhOdS#7mNP9Op5AS7WM}$MH=-Jm*^g z@vy^yc+M|Fb@JFA1H{8V1BlaGk7W`&qxU%=NHUbme_)Rtcl|RUjw7DrP%R*g;NY(h z&dGXpjix})^-JhRs-Ut_8=hq!QY+JjMDubAYQBQ z0OGNAq2PIm{}B)mQG-I}uHS`s4%w^*l^XzYDw_fEuof@|_jffA9BKuW&r*2fOz}(i3$A$ z5U-CiFcpvOHb9(muZbHrp~*-lcbyH0hX8r~Ry~UeWdZ`5!?+{c#GxtZ{=m+wFXEG$EJis+c&B300V`02n>KtC=WU znC#||ks}L}-yBCd;*gOei`#V}3yPd#iLb3ZWD&k`n$`S~6G zQ*Rr`^a4YDZXB~880vXBCUO6o2$yt`dgNw6@#i1gCmauNK&ktL*BegeJ8{1nvXAsE z!GDsI@h5ek@WXICGwwl$hV}PEyic`H_-H~XUWRE@4En<{lT$F~r(mX=7^5z(PQfTC znA95wZ%y%YR|=*(1+ysy^Sczx&J@h+DVRekn2{7rHZK&Ekdf2NQ!v*iVaC5zf(*3y zW6)7kFq={^krd3|vupbElu(!RW~S%DiLaDB(&i4-y4srCtJeB`x30y8;i?+GXSP|; zfyKDXLf-&u2!N_p_05edd^L4d^=sfOG1RQa6-~ZbR|DfRuhNn3&0#fod!plsKysjczpr9+_;?q+13nrdrm>sx9Qd?47^ zDD+z#6E0#TQjO+zZ}SdDR=~RNRLcCO$FWtIP}D0|tXb7szsgrPW-q-?v2{g#VpdX_ zqN%o_o-Ut>^Hh9yKFfF&OM<~&lnI_D?519`wzZ*l)vdLwQO`U{Df_8w8fsTGC6v@@ zZ>~&Dp?}R6rO`Y=z`v$`ow1|Zisy8@s^=EyS6QMKIjrLM?16D#wdO>Q>J0>E0{&)4fMA^_osIr_e(h;y+WnP;OG5HoDPt zUBZDU@NodY&q%FHc*ff^KNV^F6I4n%lZBoV{KnfePrBh@s3Dgiuk;W%6Ss`VRaQN( z%%kpavC{rt1aUnn;vbgUY*xNtp>D&j;v(9DY@ILq?O2J2<;#fZzlhm^>wfmZxRnCq zT0LXVl)F5I+1k z5^T?e`W*LS-=`X$aO^&#r=KrR*XZm~!ni6zeW`6;zCueLI7l05Z@Xp|PF-c0zcx(? ze*->Xx!rcBnD4)_%>lRDnA`PmyBTf>*LH`PFNFd~3=4bhcwwc`$K>w73i4OsUJy~Q zM#|Zl^;F1tGFjeZF^ca*T>w=crceS=!m8^=z&~H!>E7+yZ}2)X7g+m z75Il;cK{;}oV2h9@$!1cf|PHfH?S@z%{K*$H`pddY;nu-*kn*pG$;0oVTX>I!ESK` zKH)wm zIw3j|38HU5m?z9+gt{9$2f96CWb}XswN=e6p0?6x7)s_a7K(8Q(p&7Dc0bp%jiof*oWXFH+re#wqAs z6sI@g6ka|IaFrv3tj%B5V58tIx(i6jdZtGs0*=#N*QN+Jhz z$N5>^Yp^o0=q$#@Fmix7|1vN-%9U|9-d{x=MhjD4Gnn`|XY34w)h%7XD%cz`8CP`c ztW5RAQ&g~f!5mDnNk8g6_FA$#lRru#gTn^t8j^B}TuzJRMEsm_Ii26@rjQ)M`MucI z$0Mac>>L4dG36)tf4oux*X!kdeAJ&6?{DMG9;9N3-w)SFtNFAi(4%fISD!~YEhBf@ zr{*e%u%aa)Kw_hsN^>Q-;(Z&vsqEHJiC6Qq(DzC$UBP+WF54B_b0&&=HwW6`OaNX3MSh^ z>6Bdi%wV`1>S?Yf{TFPg(VpDuZfr-{x~F_)4(_@*c90TY$XZeKP{#k)+4Y7CyIR)1VR z#D8sSWoz)yKHZ!)km}Ab(c#vldfeD}LoWVteR%N}*xDj^o+gf_yj$pL)1f3fM~<8N zIYz5*WMoz;qbA0!7niu@!bPaEVHAs+A)@)o#ri1x@2K=uH01$q8WvgdUp za|pkGjv_w>sRExseg?u-)d}S9&62&ax&P(in-Qa>J@QMCv%uW*@;tuNOaQM${VkZ( zw?g(n#vornu0!sHt_QLl*iZlUmo)ou86<7~D&+K%PHe>I{RZvA=W>G%D)$Nymat*> zwxZ)e5^)+=?t*fAF(}(`lumr5=pOh%xL!rvvGD<8mxMPYUUnRjiYBy*AsL7xq z)eft63`ok}0FqeNo$%H}rUZXU_^?4`AdZN1q6#FjqHlm6G2HJ!OANXjy}8Pu^+3%A zJ)_*qijFBdujnsD3*Z;2r3Cb-spTAywC^XN7Q>}59v(BO4QRDNTY;pdJCu73=y9Vx z1+>PXMHoL)UmoZQ!yN&V`fkH0YBk&{AgON~kZ31?)*9_jj5I;-0CgDdV?{VLkvQ2! z`7RvEF3JlHYEbQ5MI2$GHqUA3Lc zbt&prZI5zW6m3;)pK>`x1FFp{S5oAuc1XG1iuS1XfO0P?8dmM7a<3|SUA1p0S5-8o z+M~)HS9C(PCzbn1(I={{DR)}YS=D~2+=Qa9Rr{@S-zl0>?f1%EQFK+c*OdEB(Vwcl zt{f*g@iZnE>-|~EH7Meb-4>!09s#zjL^4@cBAJ33R6AGE?TY3pny;u)(PBmM^+;LM z%fcd@{58U40x=o1aJt0jXbEC$i~;ZI(Fn5vM^$CG+}@U{I3UdR$~8ZYqZ%Zrhpm~4 zFuQS7#Zx!1IRb`rWWc-&rWI8N%;#Wg5oVG$>9EbuU^sUMrEaiPgrSe7BFueYIGYBg z_*bkSl|{3V7}Mj-8rV3ri7?NB;Vc{290tR=HelYO&8#r)qKrMSr>KPLwEhC;++}>MpoSfK21BK?O;@EIo zCYM8ut^#YX*OYckQm9@LW&8il+*gRX4IyrG3$`hipp`vA#E?-~^i?>ZnJqgR&t9-C z&9)Xxo?DDsveIejNHo^gkjZA9lI;P%(t$xQSKJY;G7{eP4H4yzv@jBK6(hE=;^Z|5 zY>S#uYRIb+qTak|?IsWL^udzdjM~gJPQP2|cFJxsXIYr7LnyQmG3zMgB1SB_!SQ;K z*<$Dw`gPmRLPj~afc7Cuo~gH?Pb|k^xxZ_+@t-sn)$w9Nm4&12)_-Cu7j3IUkMJ1& zv4mU9dijWntvWFAJ*VA-E9=TsypD3Y=r_}P(w@=xp&VxO#flR-1-lyV>nYks;CQ2x ZeRh4hxLw<6yw=+b)%x})E1Phm`~zg;evJSC literal 0 HcmV?d00001 diff --git a/vendor/ENet/list.odin b/vendor/ENet/list.odin new file mode 100644 index 000000000..891f734df --- /dev/null +++ b/vendor/ENet/list.odin @@ -0,0 +1,10 @@ +package ENet + +ListNode :: struct { + next: ^ListNode, + previous: ^ListNode, +} + +List :: struct { + sentinel: ListNode, +} \ No newline at end of file diff --git a/vendor/ENet/protocol.odin b/vendor/ENet/protocol.odin new file mode 100644 index 000000000..e6cef3e4e --- /dev/null +++ b/vendor/ENet/protocol.odin @@ -0,0 +1,164 @@ +package ENet + +PROTOCOL_MINIMUM_MTU :: 576 +PROTOCOL_MAXIMUM_MTU :: 4096 +PROTOCOL_MAXIMUM_PACKET_COMMANDS :: 32 +PROTOCOL_MINIMUM_WINDOW_SIZE :: 4096 +PROTOCOL_MAXIMUM_WINDOW_SIZE :: 65536 +PROTOCOL_MINIMUM_CHANNEL_COUNT :: 1 +PROTOCOL_MAXIMUM_CHANNEL_COUNT :: 255 +PROTOCOL_MAXIMUM_PEER_ID :: 0xFFF +PROTOCOL_MAXIMUM_FRAGMENT_COUNT :: 1024 * 1024 + +ProtocolCommand :: enum i32 { + NONE = 0, + ACKNOWLEDGE = 1, + CONNECT = 2, + VERIFY_CONNECT = 3, + DISCONNECT = 4, + PING = 5, + SEND_RELIABLE = 6, + SEND_UNRELIABLE = 7, + SEND_FRAGMENT = 8, + SEND_UNSEQUENCED = 9, + BANDWIDTH_LIMIT = 10, + THROTTLE_CONFIGURE = 11, + SEND_UNRELIABLE_FRAGMENT = 12, + COUNT = 13, + MASK = 0x0F, +} + +ProtocolFlag :: enum i32 { + COMMAND_ACKNOWLEDGE = 1 << 7, + COMMAND_UNSEQUENCED = 1 << 6, + HEADER_COMPRESSED = 1 << 14, + HEADER_SENT_TIME = 1 << 15, + HEADER_MASK = HEADER_COMPRESSED | HEADER_SENT_TIME, + HEADER_SESSION_MASK = 3 << 12, + HEADER_SESSION_SHIFT = 12, +} + +ProtocolHeader :: struct #packed { + peerID: u16, + sentTime: u16, +} + +ProtocolCommandHeader :: struct #packed { + command: u8, + channelID: u8, + reliableSequenceNumber: u16, +} + +ProtocolAcknowledge :: struct #packed { + header: ProtocolCommandHeader, + outgoingPeerID: u16, + incomingSessionID: u8, + outgoingSessionID: u8, + mtu: u32, + windowSize: u32, + channelCount: u32, + incomingBandwidth: u32, + outgoingBandwidth: u32, + packetThrottleInterval: u32, + packetThrottleAcceleration: u32, + packetThrottleDeceleration: u32, + connectID: u32, + data: u32, +} + +ProtocolConnect :: struct #packed { + header: ProtocolCommandHeader, + outgoingPeerID: u16, + incomingSessionID: u8, + outgoingSessionID: u8, + mtu: u32, + windowSize: u32, + channelCount: u32, + incomingBandwidth: u32, + outgoingBandwidth: u32, + packetThrottleInterval: u32, + packetThrottleAcceleration: u32, + packetThrottleDeceleration: u32, + connectID: u32, + data: u32, +} + +ProtocolVerifyConnect :: struct #packed { + header: ProtocolCommandHeader, + outgoingPeerID: u16, + incomingSessionID: u8, + outgoingSessionID: u8, + mtu: u32, + windowSize: u32, + channelCount: u32, + incomingBandwidth: u32, + outgoingBandwidth: u32, + packetThrottleInterval: u32, + packetThrottleAcceleration: u32, + packetThrottleDeceleration: u32, + connectID: u32, +} + +ProtocolBandwidthLimit :: struct #packed { + header: ProtocolCommandHeader, + incomingBandwidth: u32, + outgoingBandwidth: u32, +} + +ProtocolThrottleConfigure :: struct #packed { + header: ProtocolCommandHeader, + packetThrottleInterval: u32, + packetThrottleAcceleration: u32, + packetThrottleDeceleration: u32, +} + +ProtocolDisconnect :: struct #packed { + header: ProtocolCommandHeader, + data: u32, +} + +ProtocolPing :: struct #packed { + header: ProtocolCommandHeader, +} + +ProtocolSendReliable :: struct #packed { + header: ProtocolCommandHeader, + dataLength: u16, +} + +ProtocolSendUnreliable :: struct #packed { + header: ProtocolCommandHeader, + unreliableSequenceNumber: u16, + dataLength: u16, +} + +ProtocolSendUnsequenced :: struct #packed { + header: ProtocolCommandHeader, + unsequencedGroup: u16, + dataLength: u16, +} + +ProtocolSendFragment :: struct #packed { + header: ProtocolCommandHeader, + startSequenceNumber: u16, + dataLength: u16, + fragmentCount: u32, + fragmentNumber: u32, + totalLength: u32, + fragmentOffset: u32, +} + +Protocol :: struct #raw_union { + header: ProtocolCommandHeader, + acknowledge: ProtocolAcknowledge, + connect: ProtocolConnect, + verifyConnect: ProtocolVerifyConnect, + disconnect: ProtocolDisconnect, + ping: ProtocolPing, + sendReliable: ProtocolSendReliable, + sendUnreliable: ProtocolSendUnreliable, + sendUnsequenced: ProtocolSendUnsequenced, + sendFragment: ProtocolSendFragment, + bandwidthLimit: ProtocolBandwidthLimit, + throttleConfigure: ProtocolThrottleConfigure, +} \ No newline at end of file diff --git a/vendor/ENet/time.odin b/vendor/ENet/time.odin new file mode 100644 index 000000000..87cef0bec --- /dev/null +++ b/vendor/ENet/time.odin @@ -0,0 +1,23 @@ +package ENet + +TIME_OVERFLOW :: u32(86400000) + +TIME_LESS :: #force_inline proc(a, b: u32) -> bool { + return a - b >= TIME_OVERFLOW +} + +TIME_GREATER :: #force_inline proc(a, b: u32) -> bool { + return b - a >= TIME_OVERFLOW +} + +TIME_LESS_EQUAL :: #force_inline proc(a, b: u32) -> bool { + return !TIME_GREATER(a, b) +} + +TIME_GREATER_EQUAL :: #force_inline proc(a, b: u32) -> bool { + return TIME_LESS(a, b) +} + +TIME_DIFFERENCE :: #force_inline proc(a, b: u32) -> u32 { + return a - b >= TIME_OVERFLOW ? b - a : a - b +} \ No newline at end of file diff --git a/vendor/ENet/unix.odin b/vendor/ENet/unix.odin new file mode 100644 index 000000000..ea6b84199 --- /dev/null +++ b/vendor/ENet/unix.odin @@ -0,0 +1,59 @@ +//+build linux, darwin, freebsd +package ENet + +// When we implement the appropriate bindings for Unix, the section separated +// by `{` and `}` here can be removed in favor of using the bindings. +// { +import "core:c" + +@(private="file") FD_SETSIZE :: 1024 + +@(private="file") fd_set :: struct { + fds_bits: [FD_SETSIZE / 8 / size_of(c.long)]c.ulong, +} + +@(private="file") FD_ZERO :: #force_inline proc(s: ^fd_set) { + for i := size_of(fd_set) / size_of(c.long); i != 0; i -= 1 { + s.fds_bits[i] = 0; + } +} + +@(private="file") FD_SET :: #force_inline proc(d: i32, s: ^fd_set) { + s.fds_bits[d / (8 * size_of(c.long))] |= c.ulong(1) << (c.ulong(d) % (8 * size_of(c.ulong))) +} + +@(private="file") FD_CLR :: #force_inline proc(d: i32, s: ^fd_set) { + s.fds_bits[d / (8 * size_of(c.long))] &= ~(c.ulong(1) << (c.ulong(d) % (8 * size_of(c.ulong)))) +} + +@(private="file") FD_ISSET :: #force_inline proc(d: i32, s: ^fd_set) -> bool { + return (s.fds_bits[d / (8 * size_of(c.long))] & c.ulong(1) << (c.ulong(d) % (8 * size_of(c.ulong)))) != 0 +} +// } + +Socket :: distinct i32 + +SOCKET_NULL :: Socket(-1) + +Buffer :: struct { + data: rawptr, + dataLength: uint, +} + +SocketSet :: distinct fd_set + +SOCKETSET_EMPTY :: #force_inline proc(sockset: ^SocketSet) { + FD_ZERO(cast(^fd_set)sockset) +} + +SOCKETSET_ADD :: #force_inline proc(sockset: ^SocketSet, socket: Socket) { + FD_SET(i32(socket), cast(^fd_set)sockset) +} + +SOCKETSET_REMOVE :: #force_inline proc(sockset: ^SocketSet, socket: Socket) { + FD_CLR(i32(socket), cast(^fd_set)sockset) +} + +SOCKSET_CHECK :: #force_inline proc(sockset: ^SocketSet, socket: Socket) -> bool { + return FD_ISSET(i32(socket), cast(^fd_set)sockset) +} \ No newline at end of file diff --git a/vendor/ENet/win32.odin b/vendor/ENet/win32.odin new file mode 100644 index 000000000..5f07a895f --- /dev/null +++ b/vendor/ENet/win32.odin @@ -0,0 +1,81 @@ +//+build windows +package ENet + +// When we implement the appropriate bindings for Windows, the section separated +// by `{` and `}` here can be removed in favor of using the bindings. +// { +foreign WinSock2 import "system:Ws2_32.lib" + +@(private="file", default_calling_convention="c") +foreign WinSock2 { + __WSAFDIsSet :: proc(fd: SOCKET, s: ^fd_set) -> i32 --- +} + +@(private="file") SOCKET :: uintptr + +@(private="file") FD_SETSIZE :: 64 + +@(private="file") fs_set :: struct { + fd_count: u32, + fd_array: [FD_SETSIZE]SOCKET, +} + +@(private="file") FD_CLR :: proc(fd: SOCKET, s: ^fd_set) { + for i := u32(0); i < s.fd_count; i += 1 { + if s.fd_array[i] == fd { + for i < s.fd_count - 1 { + s.fd_array[i] = s.fd_array[i + 1] + i += 1 + } + s.fd_count -= 1 + break + } + } +} + +@(private="file") FD_SET :: proc(fd: SOCKET, s: ^fd_set) { + for i := u32(0); i < s.fd_count; i += 1 { + if s.fd_array[i] == fd { + return + } + } + if s.fd_count >= FD_SETSIZE do return + s.fd_array[s.fd_count] = fd + s.fd_count += 1 +} + +@(private="file") FD_ZERO proc #force_inline (s: ^fd_set) { + s.fd_count = 0 +} + +@(private="file") FD_ISSET proc #force_inline (fd: SOCKET, s: ^fd_set) -> bool { + return __WSAFDIsSet(fd, s) != 0 +} +// } + +Socket :: distinct Socket + +SOCKET_NULL :: Socket(~0) + +Buffer :: struct { + data: rawptr, + dataLength: uint, +} + +SocketSet :: distinct fd_set + +SOCKETSET_EMPTY :: #force_inline proc(sockset: ^SocketSet) { + FD_ZERO(cast(^fd_set)sockset) +} + +SOCKETSET_ADD :: #force_inline proc(sockset: ^SocketSet, socket: Socket) { + FD_SET(i32(socket), cast(^fd_set)sockset) +} + +SOCKETSET_REMOVE :: #force_inline proc(sockset: ^SocketSet, socket: Socket) { + FD_CLR(i32(socket), cast(^fd_set)sockset) +} + +SOCKSET_CHECK :: #force_inline proc(sockset: ^SocketSet, socket: Socket) -> bool { + return FD_ISSET(i32(socket), cast(^fd_set)sockset) +} \ No newline at end of file From 88d6407092f82119c67fe89de740882f603d8f6d Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 23 Oct 2021 07:51:47 -0400 Subject: [PATCH 02/15] oops, semicolon --- vendor/ENet/enet.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/ENet/enet.odin b/vendor/ENet/enet.odin index 175766ef1..2446dc816 100644 --- a/vendor/ENet/enet.odin +++ b/vendor/ENet/enet.odin @@ -22,10 +22,10 @@ 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); + return u8((version >> 8) & 0xff) } VERSION_GET_PATCH :: #force_inline proc(version: u32) -> u8 { - return u8(version & 0xff); + return u8(version & 0xff) } // Odin does not have "macros" or compile-time evaluation of functions, so the From 71ae424aa84f7f385267f30df12a95c6038395dd Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 23 Oct 2021 07:56:37 -0400 Subject: [PATCH 03/15] add LICENSE --- vendor/ENet/LICENSE | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 vendor/ENet/LICENSE diff --git a/vendor/ENet/LICENSE b/vendor/ENet/LICENSE new file mode 100644 index 000000000..6906f8eb0 --- /dev/null +++ b/vendor/ENet/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2002-2020 Lee Salzman + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 7c336a6a82883446896dff12211051d5946af851 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 23 Oct 2021 08:12:46 -0400 Subject: [PATCH 04/15] update vendor README.md --- vendor/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vendor/README.md b/vendor/README.md index aced06b3c..918e19217 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -109,3 +109,12 @@ See also LICENSE.txt in the `glfw` directory itself. `portmidi_s.lib` is available under PortMidi's [MIT](https://sourceforge.net/projects/portmedia/) license. See also LICENSE.txt in the `portmidi` directory itself. + + +## ENet + +[ENet](http://enet.bespin.org/) Reliable UDP networking library. + +`enet.lib` and `enet64.lib` are available under ENet's [zlib/libpng](http://enet.bespin.org/License.html) license. + +See also LICENSE in the `ENet` directory iself. \ No newline at end of file From e6fb4ee26558aa1184d8a6624de2e67413a5070a Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 23 Oct 2021 08:13:03 -0400 Subject: [PATCH 05/15] typo --- vendor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/README.md b/vendor/README.md index 918e19217..826654c79 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -117,4 +117,4 @@ See also LICENSE.txt in the `portmidi` directory itself. `enet.lib` and `enet64.lib` are available under ENet's [zlib/libpng](http://enet.bespin.org/License.html) license. -See also LICENSE in the `ENet` directory iself. \ No newline at end of file +See also LICENSE in the `ENet` directory itself. \ No newline at end of file From a074c367fff1e2839dc6413b53b1ad0c99620337 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 23 Oct 2021 08:25:02 -0400 Subject: [PATCH 06/15] actually got the license wrong, it's MIT --- vendor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/README.md b/vendor/README.md index 826654c79..31751f8c7 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -115,6 +115,6 @@ See also LICENSE.txt in the `portmidi` directory itself. [ENet](http://enet.bespin.org/) Reliable UDP networking library. -`enet.lib` and `enet64.lib` are available under ENet's [zlib/libpng](http://enet.bespin.org/License.html) license. +`enet.lib` and `enet64.lib` are available under ENet's [MIT](http://enet.bespin.org/License.html) license. See also LICENSE in the `ENet` directory itself. \ No newline at end of file From 357d085ffbe16725463cd22dcf9f0fc12513c2c8 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 23 Oct 2021 13:09:54 -0400 Subject: [PATCH 07/15] use multi pointer here, cstring was incorrect --- vendor/ENet/enet.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/ENet/enet.odin b/vendor/ENet/enet.odin index 2446dc816..d71538800 100644 --- a/vendor/ENet/enet.odin +++ b/vendor/ENet/enet.odin @@ -354,8 +354,8 @@ foreign ENet { 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: cstring, nameLength: uint) -> i32 --- - address_get_host :: proc(address: ^Address, hostName: cstring, nameLength: uint) -> 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) --- From cac8582de17762319ad8da1e509f9aff9d7a241b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Prokop=20Rand=C3=A1=C4=8Dek?= Date: Sun, 24 Oct 2021 12:52:54 +0200 Subject: [PATCH 08/15] WindowShouldClose should return a bool --- vendor/glfw/wrapper.odin | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vendor/glfw/wrapper.odin b/vendor/glfw/wrapper.odin index 2eed82efe..853917661 100644 --- a/vendor/glfw/wrapper.odin +++ b/vendor/glfw/wrapper.odin @@ -52,7 +52,9 @@ DestroyWindow :: glfw.DestroyWindow WindowHint :: glfw.WindowHint DefaultWindowHints :: glfw.DefaultWindowHints WindowHintString :: glfw.WindowHintString -WindowShouldClose :: glfw.WindowShouldClose +WindowShouldClose :: proc "c" (window: WindowHandle) -> bool { + return glfw.WindowShouldClose(window) != 0 +} SwapInterval :: glfw.SwapInterval SwapBuffers :: glfw.SwapBuffers @@ -228,4 +230,4 @@ SetErrorCallback :: glfw.SetErrorCallback // Used by vendor:OpenGL gl_set_proc_address :: proc(p: rawptr, name: cstring) { (^rawptr)(p)^ = GetProcAddress(name) -} \ No newline at end of file +} From b77e2f59ed17c2cdadf218603281ef9709192306 Mon Sep 17 00:00:00 2001 From: Prokop Randacek Date: Sun, 24 Oct 2021 13:07:13 +0200 Subject: [PATCH 09/15] The better option --- vendor/glfw/bindings/bindings.odin | 2 +- vendor/glfw/wrapper.odin | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/vendor/glfw/bindings/bindings.odin b/vendor/glfw/bindings/bindings.odin index e65e9b2fc..90d5a0f9e 100644 --- a/vendor/glfw/bindings/bindings.odin +++ b/vendor/glfw/bindings/bindings.odin @@ -46,7 +46,7 @@ foreign glfw { WindowHint :: proc(hint, value: c.int) --- DefaultWindowHints :: proc() --- WindowHintString :: proc(hint: c.int, value: cstring) --- - WindowShouldClose :: proc(window: WindowHandle) -> c.int --- + WindowShouldClose :: proc(window: WindowHandle) -> b32 --- SwapInterval :: proc(interval: c.int) --- SwapBuffers :: proc(window: WindowHandle) --- diff --git a/vendor/glfw/wrapper.odin b/vendor/glfw/wrapper.odin index 853917661..2c09731ca 100644 --- a/vendor/glfw/wrapper.odin +++ b/vendor/glfw/wrapper.odin @@ -52,9 +52,7 @@ DestroyWindow :: glfw.DestroyWindow WindowHint :: glfw.WindowHint DefaultWindowHints :: glfw.DefaultWindowHints WindowHintString :: glfw.WindowHintString -WindowShouldClose :: proc "c" (window: WindowHandle) -> bool { - return glfw.WindowShouldClose(window) != 0 -} +WindowShouldClose :: glfw.WindowShouldClose SwapInterval :: glfw.SwapInterval SwapBuffers :: glfw.SwapBuffers From 37d3a8a8613c94e036e3e719a448ba29859f1654 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sun, 24 Oct 2021 10:54:46 -0400 Subject: [PATCH 10/15] fixes for windows --- vendor/ENet/enet.odin | 12 ++++++++++-- vendor/ENet/win32.odin | 18 +++++++++--------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/vendor/ENet/enet.odin b/vendor/ENet/enet.odin index d71538800..b92de9aa6 100644 --- a/vendor/ENet/enet.odin +++ b/vendor/ENet/enet.odin @@ -2,9 +2,17 @@ package ENet when ODIN_OS == "windows" { when ODIN_ARCH == "amd64" { - foreign import ENet "lib/enet64.lib" + foreign import ENet { + "lib/enet64.lib", + "system:Ws2_32.lib", + "system:Winmm.lib", + } } else { - foreign import ENet "lib/enet.lib" + foreign import ENet { + "lib/enet.lib", + "system:Ws2_32.lib", + "system:Winmm.lib", + } } } else { foreign import ENet "system:enet" diff --git a/vendor/ENet/win32.odin b/vendor/ENet/win32.odin index 5f07a895f..1df35ee45 100644 --- a/vendor/ENet/win32.odin +++ b/vendor/ENet/win32.odin @@ -4,7 +4,7 @@ package ENet // When we implement the appropriate bindings for Windows, the section separated // by `{` and `}` here can be removed in favor of using the bindings. // { -foreign WinSock2 import "system:Ws2_32.lib" +foreign import WinSock2 "system:Ws2_32.lib" @(private="file", default_calling_convention="c") foreign WinSock2 { @@ -15,7 +15,7 @@ foreign WinSock2 { @(private="file") FD_SETSIZE :: 64 -@(private="file") fs_set :: struct { +@(private="file") fd_set :: struct { fd_count: u32, fd_array: [FD_SETSIZE]SOCKET, } @@ -44,18 +44,18 @@ foreign WinSock2 { s.fd_count += 1 } -@(private="file") FD_ZERO proc #force_inline (s: ^fd_set) { +@(private="file") FD_ZERO :: #force_inline proc (s: ^fd_set) { s.fd_count = 0 } -@(private="file") FD_ISSET proc #force_inline (fd: SOCKET, s: ^fd_set) -> bool { +@(private="file") FD_ISSET :: #force_inline proc (fd: SOCKET, s: ^fd_set) -> bool { return __WSAFDIsSet(fd, s) != 0 } // } -Socket :: distinct Socket +Socket :: distinct SOCKET -SOCKET_NULL :: Socket(~0) +SOCKET_NULL :: Socket(~uintptr(0)) Buffer :: struct { data: rawptr, @@ -69,13 +69,13 @@ SOCKETSET_EMPTY :: #force_inline proc(sockset: ^SocketSet) { } SOCKETSET_ADD :: #force_inline proc(sockset: ^SocketSet, socket: Socket) { - FD_SET(i32(socket), cast(^fd_set)sockset) + FD_SET(SOCKET(socket), cast(^fd_set)sockset) } SOCKETSET_REMOVE :: #force_inline proc(sockset: ^SocketSet, socket: Socket) { - FD_CLR(i32(socket), cast(^fd_set)sockset) + FD_CLR(SOCKET(socket), cast(^fd_set)sockset) } SOCKSET_CHECK :: #force_inline proc(sockset: ^SocketSet, socket: Socket) -> bool { - return FD_ISSET(i32(socket), cast(^fd_set)sockset) + return FD_ISSET(SOCKET(socket), cast(^fd_set)sockset) } \ No newline at end of file From 72cc92dc5cf9e96b484020e3036487d8548f4f52 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Oct 2021 11:44:25 +0100 Subject: [PATCH 11/15] Add `llvm_get_inline_asm` for future compatibility --- src/llvm_backend_expr.cpp | 6 +----- src/llvm_backend_proc.cpp | 29 ++++++----------------------- src/llvm_backend_utility.cpp | 13 +++++++++++++ 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 214da9e10..6737c97bc 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2510,11 +2510,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { } LLVMTypeRef func_type = LLVMGetElementType(lb_type(p->module, t)); - LLVMValueRef the_asm = LLVMGetInlineAsm(func_type, - cast(char *)asm_string.text, cast(size_t)asm_string.len, - cast(char *)constraints_string.text, cast(size_t)constraints_string.len, - ia->has_side_effects, ia->is_align_stack, dialect - ); + LLVMValueRef the_asm = llvm_get_inline_asm(func_type, asm_string, constraints_string, ia->has_side_effects, ia->has_side_effects, dialect); GB_ASSERT(the_asm != nullptr); return {the_asm, t}; case_end; diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index e577dc248..a36762afb 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1335,22 +1335,12 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, if (build_context.metrics.arch == TargetArch_386 || build_context.metrics.arch == TargetArch_amd64) { LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false); - LLVMValueRef the_asm = LLVMGetInlineAsm(func_type, - cast(char *)"pause", 5, - cast(char *)"", 0, - /*HasSideEffects*/true, /*IsAlignStack*/false, - LLVMInlineAsmDialectATT - ); + LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("pause"), {}); GB_ASSERT(the_asm != nullptr); LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, ""); } else if (build_context.metrics.arch == TargetArch_arm64) { LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false); - LLVMValueRef the_asm = LLVMGetInlineAsm(func_type, - cast(char *)"yield", 5, - cast(char *)"", 0, - /*HasSideEffects*/true, /*IsAlignStack*/false, - LLVMInlineAsmDialectATT - ); + LLVMValueRef the_asm = llvm_get_inline_asm(func_type, str_lit("yield"), {}); GB_ASSERT(the_asm != nullptr); LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, ""); } @@ -1961,10 +1951,8 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, constraints = gb_string_appendc(constraints, regs[i]); constraints = gb_string_appendc(constraints, "}"); } - size_t asm_string_size = gb_strlen(asm_string); - size_t constraints_size = gb_string_length(constraints); - inline_asm = LLVMGetInlineAsm(func_type, asm_string, asm_string_size, constraints, constraints_size, true, false, LLVMInlineAsmDialectATT); + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); } break; case TargetArch_386: @@ -1995,10 +1983,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, constraints = gb_string_appendc(constraints, ",rm"); } - size_t asm_string_size = gb_strlen(asm_string); - size_t constraints_size = gb_string_length(constraints); - - inline_asm = LLVMGetInlineAsm(func_type, asm_string, asm_string_size, constraints, constraints_size, true, false, LLVMInlineAsmDialectATT); + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); } break; case TargetArch_arm64: @@ -2021,10 +2006,8 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, constraints = gb_string_appendc(constraints, regs[i]); constraints = gb_string_appendc(constraints, "}"); } - size_t asm_string_size = gb_strlen(asm_string); - size_t constraints_size = gb_string_length(constraints); - - inline_asm = LLVMGetInlineAsm(func_type, asm_string, asm_string_size, constraints, constraints_size, true, false, LLVMInlineAsmDialectATT); + + inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); } break; default: diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 0531c62bb..948180f30 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1379,3 +1379,16 @@ lbValue lb_soa_struct_cap(lbProcedure *p, lbValue value) { } return lb_emit_struct_ev(p, value, cast(i32)n); } + +LLVMValueRef llvm_get_inline_asm(LLVMTypeRef func_type, String const &str, String const &clobbers, bool has_side_effects=true, bool is_align_stack=false, LLVMInlineAsmDialect dialect=LLVMInlineAsmDialectATT) { + return LLVMGetInlineAsm(func_type, + cast(char *)str.text, cast(size_t)str.len, + cast(char *)clobbers.text, cast(size_t)clobbers.len, + /*HasSideEffects*/true, /*IsAlignStack*/false, + dialect + #if LLVM_VERSION_MAJOR >= 13 + , /*CanThrow*/false + #endif + ); +} + From d165de0d4db0da4169487dec182492294fdf0936 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Oct 2021 11:46:31 +0100 Subject: [PATCH 12/15] Move thread initialization variables in thread_unix.odin --- core/thread/thread_unix.odin | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index f78d8f66f..cee278c7a 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -76,6 +76,9 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ return nil } thread.creation_allocator = context.allocator + + sync.mutex_init(&thread.start_mutex) + sync.condition_init(&thread.start_gate, &thread.start_mutex) // Set thread priority. policy: i32 @@ -96,12 +99,13 @@ _create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^ if unix.pthread_create(&thread.unix_thread, &attrs, __linux_thread_entry_proc, thread) != 0 { free(thread, thread.creation_allocator) + + sync.condition_destroy(&thread.start_gate) + sync.mutex_destroy(&thread.start_mutex) return nil } thread.procedure = procedure - sync.mutex_init(&thread.start_mutex) - sync.condition_init(&thread.start_gate, &thread.start_mutex) return thread } From 9522c424607e2d864ea902e5032195debf71963e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Oct 2021 12:17:39 +0100 Subject: [PATCH 13/15] Change use of `LLVMSizeOf` to `lb_sizeof` --- src/llvm_backend_const.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 18b6ee6f6..bcf2905ba 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -99,7 +99,7 @@ LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) { return LLVMConstNull(dst); } - GB_ASSERT_MSG(LLVMSizeOf(dst) == LLVMSizeOf(src), "%s vs %s", LLVMPrintTypeToString(dst), LLVMPrintTypeToString(src)); + GB_ASSERT_MSG(lb_sizeof(dst) == lb_sizeof(src), "%s vs %s", LLVMPrintTypeToString(dst), LLVMPrintTypeToString(src)); LLVMTypeKind kind = LLVMGetTypeKind(dst); switch (kind) { case LLVMPointerTypeKind: From 98490454b6baf6b0c024bfa2871d5db467bee0e7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Oct 2021 12:50:34 +0100 Subject: [PATCH 14/15] Remove unneeded semicolons --- vendor/ENet/enet.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vendor/ENet/enet.odin b/vendor/ENet/enet.odin index b92de9aa6..8d068fbfc 100644 --- a/vendor/ENet/enet.odin +++ b/vendor/ENet/enet.odin @@ -60,7 +60,7 @@ NET_TO_HOST_32 :: #force_inline proc(value: u32) -> u32 { return u32(transmute(u32be)value) } -Version :: u32; +Version :: u32 SocketType :: enum i32 { STREAM = 1, @@ -109,7 +109,7 @@ PacketFlag :: enum i32 { FLAG_SENT = 1 << 8, } -PacketFreeCallback :: proc "c" (packet: ^Packet); +PacketFreeCallback :: proc "c" (packet: ^Packet) Packet :: struct { referenceCount: uint, From ce8ddd0c3f7e7c6387297420f1b05ab3674a5631 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 26 Oct 2021 12:50:48 +0100 Subject: [PATCH 15/15] Add vendor:ENet to all_vendor.odin --- examples/all/all_vendor.odin | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/all/all_vendor.odin b/examples/all/all_vendor.odin index 1ca04380f..777c184f9 100644 --- a/examples/all/all_vendor.odin +++ b/examples/all/all_vendor.odin @@ -11,6 +11,7 @@ import SDLNet "vendor:sdl2/net" import MIX "vendor:sdl2/mixer" import TTF "vendor:sdl2/ttf" import vk "vendor:vulkan" +import ENet "vendor:ENet" _ :: glfw _ :: gl @@ -21,4 +22,5 @@ _ :: IMG _ :: SDLNet _ :: MIX _ :: TTF -_ :: vk \ No newline at end of file +_ :: vk +_ :: ENet \ No newline at end of file