Pārlūkot izejas kodu

Merge branch 'master' into windows-llvm-11.1.0

gingerBill 3 gadi atpakaļ
vecāks
revīzija
0cb42c1156

+ 5 - 13
core/runtime/dynamic_map_internal.odin

@@ -190,8 +190,6 @@ __slice_resize :: proc(array_: ^$T/[]$E, new_count: int, allocator: Allocator, l
 		return true
 	}
 
-	assert(allocator.procedure != nil)
-
 	old_size := array.len*size_of(T)
 	new_size := new_count*size_of(T)
 
@@ -256,7 +254,7 @@ __dynamic_map_get :: proc(h: Map_Header, hash: Map_Hash) -> rawptr {
 
 __dynamic_map_set :: proc(h: Map_Header, hash: Map_Hash, value: rawptr, loc := #caller_location) -> ^Map_Entry_Header #no_bounds_check {
 	index: int
-	assert(value != nil)
+	// assert(value != nil)
 
 	if len(h.m.hashes) == 0 {
 		__dynamic_map_reserve(h, INITIAL_MAP_CAP, loc)
@@ -289,8 +287,8 @@ __dynamic_map_set :: proc(h: Map_Header, hash: Map_Hash, value: rawptr, loc := #
 
 	if __dynamic_map_full(h) {
 		__dynamic_map_grow(h, loc)
-		index = __dynamic_map_find(h, hash).entry_index
-		assert(index >= 0)
+		// index = __dynamic_map_find(h, hash).entry_index
+		// assert(index >= 0)
 	}
 	
 	return __dynamic_map_get_entry(h, index)
@@ -315,12 +313,6 @@ __dynamic_map_hash_equal :: proc "contextless" (h: Map_Header, a, b: Map_Hash) -
 __dynamic_map_find :: proc(using h: Map_Header, hash: Map_Hash) -> Map_Find_Result #no_bounds_check {
 	fr := Map_Find_Result{-1, -1, -1}
 	if n := uintptr(len(m.hashes)); n > 0 {
-		for i in 0..<m.entries.len {
-			entry := __dynamic_map_get_entry(h, i)
-			assert(entry.next < m.entries.len)
-		}
-		
-		
 		fr.hash_index = int(hash.hash % n)
 		fr.entry_index = m.hashes[fr.hash_index]
 		for fr.entry_index >= 0 {
@@ -329,7 +321,7 @@ __dynamic_map_find :: proc(using h: Map_Header, hash: Map_Hash) -> Map_Find_Resu
 			if __dynamic_map_hash_equal(h, entry_hash, hash) {
 				return fr
 			}
-			assert(entry.next < m.entries.len)
+			// assert(entry.next < m.entries.len)
 			
 			fr.entry_prev = fr.entry_index
 			fr.entry_index = entry.next
@@ -358,7 +350,7 @@ __dynamic_map_delete_key :: proc(using h: Map_Header, hash: Map_Hash) {
 }
 
 __dynamic_map_get_entry :: proc(using h: Map_Header, index: int) -> ^Map_Entry_Header {
-	assert(0 <= index && index < m.entries.len)
+	// assert(0 <= index && index < m.entries.len)
 	return (^Map_Entry_Header)(uintptr(m.entries.data) + uintptr(index*entry_size))
 }
 

+ 18 - 18
core/slice/sort.odin

@@ -152,8 +152,8 @@ _max_depth :: proc(n: int) -> int { // 2*ceil(log2(n+1))
 }
 
 @(private)
-_quick_sort :: proc(data: $T/[]$E, a, b, max_depth: int) where ORD(E) {
-	median3 :: proc(data: T, m1, m0, m2: int) {
+_quick_sort :: proc(data: $T/[]$E, a, b, max_depth: int) where ORD(E) #no_bounds_check {
+	median3 :: proc(data: T, m1, m0, m2: int) #no_bounds_check {
 		if data[m1] < data[m0] {
 			swap(data, m1, m0)
 		}
@@ -165,7 +165,7 @@ _quick_sort :: proc(data: $T/[]$E, a, b, max_depth: int) where ORD(E) {
 		}
 	}
 
-	do_pivot :: proc(data: T, lo, hi: int) -> (midlo, midhi: int) {
+	do_pivot :: proc(data: T, lo, hi: int) -> (midlo, midhi: int) #no_bounds_check {
 		m := int(uint(lo+hi)>>1)
 		if hi-lo > 40 {
 			s := (hi-lo)/8
@@ -265,7 +265,7 @@ _quick_sort :: proc(data: $T/[]$E, a, b, max_depth: int) where ORD(E) {
 }
 
 @(private)
-_insertion_sort :: proc(data: $T/[]$E, a, b: int) where ORD(E) {
+_insertion_sort :: proc(data: $T/[]$E, a, b: int) where ORD(E) #no_bounds_check {
 	for i in a+1..<b {
 		for j := i; j > a && data[j] < data[j-1]; j -= 1 {
 			swap(data, j, j-1)
@@ -274,8 +274,8 @@ _insertion_sort :: proc(data: $T/[]$E, a, b: int) where ORD(E) {
 }
 
 @(private)
-_heap_sort :: proc(data: $T/[]$E, a, b: int) where ORD(E) {
-	sift_down :: proc(data: T, lo, hi, first: int) {
+_heap_sort :: proc(data: $T/[]$E, a, b: int) where ORD(E) #no_bounds_check {
+	sift_down :: proc(data: T, lo, hi, first: int) #no_bounds_check {
 		root := lo
 		for {
 			child := 2*root + 1
@@ -312,8 +312,8 @@ _heap_sort :: proc(data: $T/[]$E, a, b: int) where ORD(E) {
 
 
 @(private)
-_quick_sort_less :: proc(data: $T/[]$E, a, b, max_depth: int, less: proc(i, j: E) -> bool) {
-	median3 :: proc(data: T, m1, m0, m2: int, less: proc(i, j: E) -> bool) {
+_quick_sort_less :: proc(data: $T/[]$E, a, b, max_depth: int, less: proc(i, j: E) -> bool) #no_bounds_check {
+	median3 :: proc(data: T, m1, m0, m2: int, less: proc(i, j: E) -> bool) #no_bounds_check {
 		if less(data[m1], data[m0]) {
 			swap(data, m1, m0)
 		}
@@ -325,7 +325,7 @@ _quick_sort_less :: proc(data: $T/[]$E, a, b, max_depth: int, less: proc(i, j: E
 		}
 	}
 
-	do_pivot :: proc(data: T, lo, hi: int, less: proc(i, j: E) -> bool) -> (midlo, midhi: int) {
+	do_pivot :: proc(data: T, lo, hi: int, less: proc(i, j: E) -> bool) -> (midlo, midhi: int) #no_bounds_check {
 		m := int(uint(lo+hi)>>1)
 		if hi-lo > 40 {
 			s := (hi-lo)/8
@@ -424,7 +424,7 @@ _quick_sort_less :: proc(data: $T/[]$E, a, b, max_depth: int, less: proc(i, j: E
 }
 
 @(private)
-_insertion_sort_less :: proc(data: $T/[]$E, a, b: int, less: proc(i, j: E) -> bool) {
+_insertion_sort_less :: proc(data: $T/[]$E, a, b: int, less: proc(i, j: E) -> bool) #no_bounds_check {
 	for i in a+1..<b {
 		for j := i; j > a && less(data[j], data[j-1]); j -= 1 {
 			swap(data, j, j-1)
@@ -433,8 +433,8 @@ _insertion_sort_less :: proc(data: $T/[]$E, a, b: int, less: proc(i, j: E) -> bo
 }
 
 @(private)
-_heap_sort_less :: proc(data: $T/[]$E, a, b: int, less: proc(i, j: E) -> bool) {
-	sift_down :: proc(data: T, lo, hi, first: int, less: proc(i, j: E) -> bool) {
+_heap_sort_less :: proc(data: $T/[]$E, a, b: int, less: proc(i, j: E) -> bool) #no_bounds_check {
+	sift_down :: proc(data: T, lo, hi, first: int, less: proc(i, j: E) -> bool) #no_bounds_check {
 		root := lo
 		for {
 			child := 2*root + 1
@@ -471,8 +471,8 @@ _heap_sort_less :: proc(data: $T/[]$E, a, b: int, less: proc(i, j: E) -> bool) {
 
 
 @(private)
-_quick_sort_cmp :: proc(data: $T/[]$E, a, b, max_depth: int, cmp: proc(i, j: E) -> Ordering) {
-	median3 :: proc(data: T, m1, m0, m2: int, cmp: proc(i, j: E) -> Ordering) {
+_quick_sort_cmp :: proc(data: $T/[]$E, a, b, max_depth: int, cmp: proc(i, j: E) -> Ordering) #no_bounds_check {
+	median3 :: proc(data: T, m1, m0, m2: int, cmp: proc(i, j: E) -> Ordering) #no_bounds_check {
 		if cmp(data[m1], data[m0]) == .Less {
 			swap(data, m1, m0)
 		}
@@ -484,7 +484,7 @@ _quick_sort_cmp :: proc(data: $T/[]$E, a, b, max_depth: int, cmp: proc(i, j: E)
 		}
 	}
 
-	do_pivot :: proc(data: T, lo, hi: int, cmp: proc(i, j: E) -> Ordering) -> (midlo, midhi: int) {
+	do_pivot :: proc(data: T, lo, hi: int, cmp: proc(i, j: E) -> Ordering) -> (midlo, midhi: int) #no_bounds_check {
 		m := int(uint(lo+hi)>>1)
 		if hi-lo > 40 {
 			s := (hi-lo)/8
@@ -583,7 +583,7 @@ _quick_sort_cmp :: proc(data: $T/[]$E, a, b, max_depth: int, cmp: proc(i, j: E)
 }
 
 @(private)
-_insertion_sort_cmp :: proc(data: $T/[]$E, a, b: int, cmp: proc(i, j: E) -> Ordering) {
+_insertion_sort_cmp :: proc(data: $T/[]$E, a, b: int, cmp: proc(i, j: E) -> Ordering) #no_bounds_check {
 	for i in a+1..<b {
 		for j := i; j > a && cmp(data[j], data[j-1]) == .Less; j -= 1 {
 			swap(data, j, j-1)
@@ -592,8 +592,8 @@ _insertion_sort_cmp :: proc(data: $T/[]$E, a, b: int, cmp: proc(i, j: E) -> Orde
 }
 
 @(private)
-_heap_sort_cmp :: proc(data: $T/[]$E, a, b: int, cmp: proc(i, j: E) -> Ordering) {
-	sift_down :: proc(data: T, lo, hi, first: int, cmp: proc(i, j: E) -> Ordering) {
+_heap_sort_cmp :: proc(data: $T/[]$E, a, b: int, cmp: proc(i, j: E) -> Ordering) #no_bounds_check {
+	sift_down :: proc(data: T, lo, hi, first: int, cmp: proc(i, j: E) -> Ordering) #no_bounds_check {
 		root := lo
 		for {
 			child := 2*root + 1

+ 3 - 1
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
+_ :: vk
+_ :: ENet

+ 7 - 0
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.

+ 7 - 0
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" (),
+}

+ 400 - 0
vendor/ENet/enet.odin

@@ -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 ---
+}

BIN
vendor/ENet/lib/enet.lib


BIN
vendor/ENet/lib/enet64.lib


+ 10 - 0
vendor/ENet/list.odin

@@ -0,0 +1,10 @@
+package ENet
+
+ListNode :: struct {
+	next:     ^ListNode,
+	previous: ^ListNode,
+}
+
+List :: struct {
+	sentinel: ListNode,
+}

+ 164 - 0
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,
+}

+ 23 - 0
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
+}

+ 59 - 0
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)
+}

+ 81 - 0
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 import WinSock2 "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") fd_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 :: #force_inline proc (s: ^fd_set) {
+	s.fd_count = 0
+}
+
+@(private="file") FD_ISSET :: #force_inline proc (fd: SOCKET, s: ^fd_set) -> bool {
+	return __WSAFDIsSet(fd, s) != 0
+}
+// }
+
+Socket :: distinct SOCKET
+
+SOCKET_NULL :: Socket(~uintptr(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(SOCKET(socket), cast(^fd_set)sockset)
+}
+
+SOCKETSET_REMOVE :: #force_inline proc(sockset: ^SocketSet, socket: Socket) {
+	FD_CLR(SOCKET(socket), cast(^fd_set)sockset)
+}
+
+SOCKSET_CHECK :: #force_inline proc(sockset: ^SocketSet, socket: Socket) -> bool {
+	return FD_ISSET(SOCKET(socket), cast(^fd_set)sockset)
+}

+ 9 - 0
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 [MIT](http://enet.bespin.org/License.html) license.
+
+See also LICENSE in the `ENet` directory itself.