Browse Source

Merge branch 'master' into allocator-mode-alloc-non-zeroed

gingerBill 2 years ago
parent
commit
f76316f889
93 changed files with 3821 additions and 2594 deletions
  1. 0 17
      .github/workflows/ci.yml
  2. 1 1
      .github/workflows/nightly.yml
  3. 1 1
      .gitignore
  4. 1 1
      README.md
  5. 25 1
      build_odin.sh
  6. 2 5
      core/bytes/buffer.odin
  7. 1 1
      core/bytes/bytes.odin
  8. 15 2
      core/c/libc/errno.odin
  9. 4 1
      core/c/libc/stdio.odin
  10. 7 9
      core/encoding/json/unmarshal.odin
  11. 1 1
      core/fmt/fmt.odin
  12. 3 3
      core/fmt/fmt_os.odin
  13. 4 2
      core/hash/hash.odin
  14. 9 0
      core/math/rand/rand.odin
  15. 2 6
      core/mem/raw.odin
  16. 331 0
      core/mem/virtual/arena.odin
  17. 0 41
      core/mem/virtual/arena_util.odin
  18. 0 171
      core/mem/virtual/growing_arena.odin
  19. 0 153
      core/mem/virtual/static_arena.odin
  20. 18 15
      core/mem/virtual/virtual.odin
  21. 0 26
      core/mem/virtual/virtual_platform.odin
  22. 1 4
      core/os/dir_windows.odin
  23. 4 2
      core/os/file_windows.odin
  24. 1 1
      core/os/os2/file_windows.odin
  25. 32 11
      core/os/os_darwin.odin
  26. 32 3
      core/os/os_wasi.odin
  27. 10 10
      core/os/stat_windows.odin
  28. 1 29
      core/runtime/core_builtin.odin
  29. 3 3
      core/runtime/error_checks.odin
  30. 1 1
      core/runtime/procs_darwin.odin
  31. 2 2
      core/slice/slice.odin
  32. 3 2
      core/slice/sort_private.odin
  33. 41 2
      core/strconv/strconv.odin
  34. 1 1
      core/strings/strings.odin
  35. 1 0
      core/sys/info/platform_darwin.odin
  36. 30 0
      core/sys/windows/advapi32.odin
  37. 9 0
      core/sys/windows/comctl32.odin
  38. 1 0
      core/sys/windows/gdi32.odin
  39. 173 0
      core/sys/windows/kernel32.odin
  40. 6 0
      core/sys/windows/shell32.odin
  41. 1 0
      core/sys/windows/shlwapi.odin
  42. 280 4
      core/sys/windows/types.odin
  43. 4 0
      core/sys/windows/user32.odin
  44. 4 4
      core/sys/windows/util.odin
  45. 1095 1084
      core/sys/windows/window_messages.odin
  46. 34 32
      core/time/time.odin
  47. 2 0
      core/time/time_wasi.odin
  48. 10 3
      core/time/time_windows.odin
  49. 1 1
      src/big_int.cpp
  50. 12 9
      src/build_settings.cpp
  51. 141 3
      src/check_builtin.cpp
  52. 5 0
      src/check_decl.cpp
  53. 64 16
      src/check_expr.cpp
  54. 5 1
      src/check_stmt.cpp
  55. 12 1
      src/checker.cpp
  56. 4 0
      src/checker_builtin_procs.hpp
  57. 1 1
      src/docs_writer.cpp
  58. 7 0
      src/exact_value.cpp
  59. 44 19
      src/llvm_abi.cpp
  60. 29 2
      src/llvm_backend.cpp
  61. 2 1
      src/llvm_backend.hpp
  62. 20 3
      src/llvm_backend_const.cpp
  63. 114 0
      src/llvm_backend_debug.cpp
  64. 25 26
      src/llvm_backend_expr.cpp
  65. 40 9
      src/llvm_backend_general.cpp
  66. 60 4
      src/llvm_backend_proc.cpp
  67. 1 1
      src/llvm_backend_type.cpp
  68. 37 48
      src/main.cpp
  69. 38 0
      src/types.cpp
  70. 12 6
      tests/issues/run.bat
  71. 8 7
      tests/issues/run.sh
  72. 146 177
      tests/issues/test_issue_1592.odin
  73. 62 0
      tests/issues/test_issue_2087.odin
  74. 13 0
      tests/issues/test_issue_2113.odin
  75. 2 17
      tests/issues/test_issue_829.odin
  76. 3 3
      vendor/darwin/Foundation/NSApplication.odin
  77. 16 0
      vendor/darwin/Foundation/NSWindow.odin
  78. 5 1
      vendor/darwin/Foundation/objc.odin
  79. 190 149
      vendor/directx/d3d11/d3d11.odin
  80. 339 311
      vendor/directx/d3d12/d3d12.odin
  81. 53 46
      vendor/directx/d3d_compiler/d3d_compiler.odin
  82. 40 31
      vendor/directx/dxgi/dxgi.odin
  83. 1 0
      vendor/glfw/bindings/bindings.odin
  84. 3 0
      vendor/glfw/constants.odin
  85. 0 33
      vendor/glfw/native.odin
  86. 16 0
      vendor/glfw/native_darwin.odin
  87. 15 0
      vendor/glfw/native_linux.odin
  88. 15 0
      vendor/glfw/native_windows.odin
  89. 1 1
      vendor/stb/rect_pack/stb_rect_pack.odin
  90. 1 1
      vendor/stb/truetype/stb_truetype.odin
  91. 1 1
      vendor/stb/vorbis/stb_vorbis.odin
  92. 7 7
      vendor/vulkan/_gen/create_vulkan_odin_wrapper.py
  93. 3 3
      vendor/vulkan/procedures.odin

+ 0 - 17
.github/workflows/ci.yml

@@ -38,11 +38,6 @@ jobs:
           cd tests/vendor
           cd tests/vendor
           make
           make
         timeout-minutes: 10
         timeout-minutes: 10
-      - name: Odin issues tests
-        run: |
-          cd tests/issues
-          ./run.sh
-        timeout-minutes: 10
       - name: Odin check examples/all for Linux i386
       - name: Odin check examples/all for Linux i386
         run: ./odin check examples/all -vet -strict-style -target:linux_i386
         run: ./odin check examples/all -vet -strict-style -target:linux_i386
         timeout-minutes: 10
         timeout-minutes: 10
@@ -92,11 +87,6 @@ jobs:
           cd tests/vendor
           cd tests/vendor
           make
           make
         timeout-minutes: 10
         timeout-minutes: 10
-      - name: Odin issues tests
-        run: |
-          cd tests/issues
-          ./run.sh
-        timeout-minutes: 10
       - name: Odin check examples/all for Darwin arm64
       - name: Odin check examples/all for Darwin arm64
         run: ./odin check examples/all -vet -strict-style -target:darwin_arm64
         run: ./odin check examples/all -vet -strict-style -target:darwin_arm64
         timeout-minutes: 10
         timeout-minutes: 10
@@ -163,13 +153,6 @@ jobs:
           cd tests\core\math\big
           cd tests\core\math\big
           call build.bat
           call build.bat
         timeout-minutes: 10
         timeout-minutes: 10
-      - name: Odin issues tests
-        shell: cmd
-        run: |
-          call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat
-          cd tests\issues
-          call run.bat
-        timeout-minutes: 10
       - name: Odin check examples/all for Windows 32bits
       - name: Odin check examples/all for Windows 32bits
         shell: cmd
         shell: cmd
         run: |
         run: |

+ 1 - 1
.github/workflows/nightly.yml

@@ -50,7 +50,7 @@ jobs:
         run: |
         run: |
           mkdir dist
           mkdir dist
           cp odin dist
           cp odin dist
-          cp libLLVM*.so dist
+          cp libLLVM* dist
           cp -r shared dist
           cp -r shared dist
           cp -r core dist
           cp -r core dist
           cp -r vendor dist
           cp -r vendor dist

+ 1 - 1
.gitignore

@@ -271,7 +271,7 @@ odin
 odin.dSYM
 odin.dSYM
 *.bin
 *.bin
 demo.bin
 demo.bin
-libLLVM*.so
+libLLVM*.so*
 
 
 # shared collection
 # shared collection
 shared/
 shared/

+ 1 - 1
README.md

@@ -82,7 +82,7 @@ A wiki maintained by the Odin community.
 
 
 #### [Odin Discord](https://discord.gg/sVBPHEv)
 #### [Odin Discord](https://discord.gg/sVBPHEv)
 
 
-Get live support and talk with other odiners on the Odin Discord.
+Get live support and talk with other Odin programmers on the Odin Discord.
 
 
 ### Articles
 ### Articles
 
 

+ 25 - 1
build_odin.sh

@@ -44,6 +44,12 @@ config_darwin() {
 		fi
 		fi
 	fi
 	fi
 
 
+	MAX_LLVM_VERSION=("14.999.999")
+	if [ $(version $($LLVM_CONFIG --version)) -gt $(version $MAX_LLVM_VERSION) ]; then
+		echo "Tried to use " $(which $LLVM_CONFIG) "version" $($LLVM_CONFIG --version)
+		panic "Requirement: llvm-config must be base version smaller than 15"
+	fi
+
 	LDFLAGS="$LDFLAGS -liconv -ldl"
 	LDFLAGS="$LDFLAGS -liconv -ldl"
 	CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
 	CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
 	LDFLAGS="$LDFLAGS -lLLVM-C"
 	LDFLAGS="$LDFLAGS -lLLVM-C"
@@ -97,10 +103,20 @@ config_linux() {
 		panic "Requirement: llvm-config must be base version greater than 11"
 		panic "Requirement: llvm-config must be base version greater than 11"
 	fi
 	fi
 
 
+	MAX_LLVM_VERSION=("14.999.999")
+	if [ $(version $($LLVM_CONFIG --version)) -gt $(version $MAX_LLVM_VERSION) ]; then
+		echo "Tried to use " $(which $LLVM_CONFIG) "version" $($LLVM_CONFIG --version)
+		panic "Requirement: llvm-config must be base version smaller than 15"
+	fi
+
 	LDFLAGS="$LDFLAGS -ldl"
 	LDFLAGS="$LDFLAGS -ldl"
 	CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
 	CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
 	LDFLAGS="$LDFLAGS $($LLVM_CONFIG  --libs core native --system-libs --libfiles) -Wl,-rpath=\$ORIGIN"
 	LDFLAGS="$LDFLAGS $($LLVM_CONFIG  --libs core native --system-libs --libfiles) -Wl,-rpath=\$ORIGIN"
-	cp $($LLVM_CONFIG --libfiles) ./
+
+	# Creates a copy of the llvm library in the build dir, this is meant to support compiler explorer.
+	# The annoyance is that this copy can be cluttering the development folder. TODO: split staging folders
+	# for development and compiler explorer builds
+	cp $(readlink -f $($LLVM_CONFIG --libfiles)) ./
 }
 }
 
 
 build_odin() {
 build_odin() {
@@ -130,6 +146,14 @@ run_demo() {
 	./odin run examples/demo/demo.odin -file
 	./odin run examples/demo/demo.odin -file
 }
 }
 
 
+have_which() {
+	if ! which which > /dev/null 2>&1; then
+		panic "Could not find \`which\`"
+	fi
+}
+
+have_which
+
 case $OS in
 case $OS in
 Linux)
 Linux)
 	config_linux
 	config_linux

+ 2 - 5
core/bytes/buffer.odin

@@ -240,14 +240,11 @@ buffer_read_ptr :: proc(b: ^Buffer, ptr: rawptr, size: int) -> (n: int, err: io.
 buffer_read_at :: proc(b: ^Buffer, p: []byte, offset: int) -> (n: int, err: io.Error) {
 buffer_read_at :: proc(b: ^Buffer, p: []byte, offset: int) -> (n: int, err: io.Error) {
 	b.last_read = .Invalid
 	b.last_read = .Invalid
 
 
-	if offset < 0 || offset >= len(b.buf) {
+	if uint(offset) >= len(b.buf) {
 		err = .Invalid_Offset
 		err = .Invalid_Offset
 		return
 		return
 	}
 	}
-
-	if 0 <= offset && offset < len(b.buf) {
-		n = copy(p, b.buf[offset:])
-	}
+	n = copy(p, b.buf[offset:])
 	if n > 0 {
 	if n > 0 {
 		b.last_read = .Read
 		b.last_read = .Read
 	}
 	}

+ 1 - 1
core/bytes/bytes.odin

@@ -638,7 +638,7 @@ trim_left_proc :: proc(s: []byte, p: proc(rune) -> bool) -> []byte {
 
 
 index_rune :: proc(s: []byte, r: rune) -> int {
 index_rune :: proc(s: []byte, r: rune) -> int {
 	switch {
 	switch {
-	case 0 <= r && r < utf8.RUNE_SELF:
+	case u32(r) < utf8.RUNE_SELF:
 		return index_byte(s, byte(r))
 		return index_byte(s, byte(r))
 
 
 	case r == utf8.RUNE_ERROR:
 	case r == utf8.RUNE_ERROR:

+ 15 - 2
core/c/libc/errno.odin

@@ -14,11 +14,24 @@ when ODIN_OS == .Windows {
 //	EDOM,
 //	EDOM,
 //	EILSEQ
 //	EILSEQ
 //	ERANGE
 //	ERANGE
-when ODIN_OS == .Linux || ODIN_OS == .FreeBSD {
+when ODIN_OS == .Linux {
 	@(private="file")
 	@(private="file")
 	@(default_calling_convention="c")
 	@(default_calling_convention="c")
 	foreign libc {
 	foreign libc {
-		@(link_name="__libc_errno_location")
+		@(link_name="__errno_location")
+		_get_errno :: proc() -> ^int ---
+	}
+
+	EDOM   :: 33
+	EILSEQ :: 84
+	ERANGE :: 34
+}
+
+when ODIN_OS == .FreeBSD {
+	@(private="file")
+	@(default_calling_convention="c")
+	foreign libc {
+		@(link_name="__error")
 		_get_errno :: proc() -> ^int ---
 		_get_errno :: proc() -> ^int ---
 	}
 	}
 
 

+ 4 - 1
core/c/libc/stdio.odin

@@ -1,7 +1,10 @@
 package libc
 package libc
 
 
 when ODIN_OS == .Windows {
 when ODIN_OS == .Windows {
-	foreign import libc "system:libucrt.lib"
+	foreign import libc {
+		"system:libucrt.lib",
+		"system:legacy_stdio_definitions.lib",
+	}
 } else when ODIN_OS == .Darwin {
 } else when ODIN_OS == .Darwin {
 	foreign import libc "system:System.framework"
 	foreign import libc "system:System.framework"
 } else {
 } else {

+ 7 - 9
core/encoding/json/unmarshal.odin

@@ -380,20 +380,18 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
 				field := any{field_ptr, type.id}
 				field := any{field_ptr, type.id}
 				unmarshal_value(p, field) or_return
 				unmarshal_value(p, field) or_return
 					
 					
+				if parse_comma(p) {
+					break struct_loop
+				}
+				continue struct_loop
+			} else {
+				// allows skipping unused struct fields
+				parse_value(p) or_return
 				if parse_comma(p) {
 				if parse_comma(p) {
 					break struct_loop
 					break struct_loop
 				}
 				}
 				continue struct_loop
 				continue struct_loop
 			}
 			}
-			
-			// NOTE(bill, 2022-09-14): Previously this would not be allowed
-			//         {"foo": 123, "bar": 456}
-			//         T :: struct{foo: int}
-			// `T` is missing the `bar` field
-			// The line below is commented out to ignore fields in an object which
-			// do not have a corresponding target field
-			//
-			// return Unsupported_Type_Error{v.id, p.curr_token}
 		}
 		}
 		
 		
 	case reflect.Type_Info_Map:
 	case reflect.Type_Info_Map:

+ 1 - 1
core/fmt/fmt.odin

@@ -975,7 +975,7 @@ fmt_string :: proc(fi: ^Info, s: string, verb: rune) {
 				}
 				}
 			}
 			}
 			else {
 			else {
-				io.write_string(fi.writer, s[:fi.width], &fi.n)
+				io.write_string(fi.writer, s, &fi.n)
 			}
 			}
 		}
 		}
 		else
 		else

+ 3 - 3
core/fmt/fmt_os.odin

@@ -16,7 +16,7 @@ fprintln :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
 	w := io.to_writer(os.stream_from_handle(fd))
 	w := io.to_writer(os.stream_from_handle(fd))
 	return wprintln(w=w, args=args, sep=sep)
 	return wprintln(w=w, args=args, sep=sep)
 }
 }
-// fprintf formats according to the specififed format string and writes to fd
+// fprintf formats according to the specified format string and writes to fd
 fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
 fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
 	w := io.to_writer(os.stream_from_handle(fd))
 	w := io.to_writer(os.stream_from_handle(fd))
 	return wprintf(w, fmt, ..args)
 	return wprintf(w, fmt, ..args)
@@ -34,12 +34,12 @@ fprint_typeid :: proc(fd: os.Handle, id: typeid) -> (n: int, err: io.Error) {
 print   :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stdout, args=args, sep=sep) }
 print   :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stdout, args=args, sep=sep) }
 // println formats using the default print settings and writes to os.stdout
 // println formats using the default print settings and writes to os.stdout
 println :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stdout, args=args, sep=sep) }
 println :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stdout, args=args, sep=sep) }
-// printf formats according to the specififed format string and writes to os.stdout
+// printf formats according to the specified format string and writes to os.stdout
 printf  :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args) }
 printf  :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args) }
 
 
 // eprint formats using the default print settings and writes to os.stderr
 // eprint formats using the default print settings and writes to os.stderr
 eprint   :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stderr, args=args, sep=sep) }
 eprint   :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stderr, args=args, sep=sep) }
 // eprintln formats using the default print settings and writes to os.stderr
 // eprintln formats using the default print settings and writes to os.stderr
 eprintln :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stderr, args=args, sep=sep) }
 eprintln :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stderr, args=args, sep=sep) }
-// eprintf formats according to the specififed format string and writes to os.stderr
+// eprintf formats according to the specified format string and writes to os.stderr
 eprintf  :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args) }
 eprintf  :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args) }

+ 4 - 2
core/hash/hash.odin

@@ -72,8 +72,9 @@ djbx33a :: proc(data: []byte, seed := u32(5381)) -> (result: [16]byte) #no_bound
 	return
 	return
 }
 }
 
 
+// If you have a choice, prefer fnv32a
 @(optimization_mode="speed")
 @(optimization_mode="speed")
-fnv32 :: proc(data: []byte, seed := u32(0x811c9dc5)) -> u32 {
+fnv32_no_a :: proc(data: []byte, seed := u32(0x811c9dc5)) -> u32 {
 	h: u32 = seed
 	h: u32 = seed
 	for b in data {
 	for b in data {
 		h = (h * 0x01000193) ~ u32(b)
 		h = (h * 0x01000193) ~ u32(b)
@@ -81,8 +82,9 @@ fnv32 :: proc(data: []byte, seed := u32(0x811c9dc5)) -> u32 {
 	return h
 	return h
 }
 }
 
 
+// If you have a choice, prefer fnv64a
 @(optimization_mode="speed")
 @(optimization_mode="speed")
-fnv64 :: proc(data: []byte, seed := u64(0xcbf29ce484222325)) -> u64 {
+fnv64_no_a :: proc(data: []byte, seed := u64(0xcbf29ce484222325)) -> u64 {
 	h: u64 = seed
 	h: u64 = seed
 	for b in data {
 	for b in data {
 		h = (h * 0x100000001b3) ~ u64(b)
 		h = (h * 0x100000001b3) ~ u64(b)

+ 9 - 0
core/math/rand/rand.odin

@@ -182,3 +182,12 @@ shuffle :: proc(array: $T/[]$E, r: ^Rand = nil) {
 		array[i], array[j] = array[j], array[i]
 		array[i], array[j] = array[j], array[i]
 	}
 	}
 }
 }
+
+// Returns a random element from the given slice
+choice :: proc(array: $T/[]$E, r: ^Rand = nil) -> (res: E) {
+	n := i64(len(array))
+	if n < 1 {
+		return E{}
+	}
+	return array[int63_max(n, r)]
+}

+ 2 - 6
core/mem/raw.odin

@@ -1,5 +1,6 @@
 package mem
 package mem
 
 
+import "core:builtin"
 import "core:runtime"
 import "core:runtime"
 
 
 Raw_Any           :: runtime.Raw_Any
 Raw_Any           :: runtime.Raw_Any
@@ -21,12 +22,7 @@ make_any :: proc "contextless" (data: rawptr, id: typeid) -> any {
 	return transmute(any)Raw_Any{data, id}
 	return transmute(any)Raw_Any{data, id}
 }
 }
 
 
-raw_array_data         :: runtime.raw_array_data
-raw_simd_data          :: runtime.raw_simd_data
-raw_string_data        :: runtime.raw_string_data
-raw_slice_data         :: runtime.raw_slice_data
-raw_dynamic_array_data :: runtime.raw_dynamic_array_data
-raw_data               :: runtime.raw_data
+raw_data :: builtin.raw_data
 
 
 
 
 Poly_Raw_Map_Entry :: struct($Key, $Value: typeid) {
 Poly_Raw_Map_Entry :: struct($Key, $Value: typeid) {

+ 331 - 0
core/mem/virtual/arena.odin

@@ -0,0 +1,331 @@
+package mem_virtual
+
+import "core:mem"
+
+Arena_Kind :: enum uint {
+	Growing = 0, // Chained memory blocks (singly linked list).
+	Static  = 1, // Fixed reservation sized.
+	Buffer  = 2, // Uses a fixed sized buffer.
+}
+
+Arena :: struct {
+	kind:               Arena_Kind,
+	curr_block:         ^Memory_Block,
+	total_used:         uint,
+	total_reserved:     uint,
+	minimum_block_size: uint,
+	temp_count:         uint,
+}
+
+
+// 1 MiB should be enough to start with
+DEFAULT_ARENA_STATIC_COMMIT_SIZE         :: 1<<20
+DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE :: DEFAULT_ARENA_STATIC_COMMIT_SIZE
+
+// 1 GiB on 64-bit systems, 128 MiB on 32-bit systems by default
+DEFAULT_ARENA_STATIC_RESERVE_SIZE :: 1<<30 when size_of(uintptr) == 8 else 1<<27
+
+
+
+@(require_results)
+arena_init_growing :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE) -> (err: Allocator_Error) {
+	arena.kind           = .Growing
+	arena.curr_block     = memory_block_alloc(0, reserved, {}) or_return
+	arena.total_used     = 0
+	arena.total_reserved = arena.curr_block.reserved
+	return
+}
+
+
+@(require_results)
+arena_init_static :: proc(arena: ^Arena, reserved: uint, commit_size: uint = DEFAULT_ARENA_STATIC_COMMIT_SIZE) -> (err: Allocator_Error) {
+	arena.kind           = .Static
+	arena.curr_block     = memory_block_alloc(commit_size, reserved, {}) or_return
+	arena.total_used     = 0
+	arena.total_reserved = arena.curr_block.reserved
+	return
+}
+
+@(require_results)
+arena_init_buffer :: proc(arena: ^Arena, buffer: []byte) -> (err: Allocator_Error) {
+	if len(buffer) < size_of(Memory_Block) {
+		return .Out_Of_Memory
+	}
+
+	arena.kind = .Buffer
+
+	mem.zero_slice(buffer)
+
+	block_base := raw_data(buffer)
+	block := (^Memory_Block)(block_base)
+	block.base      = block_base[size_of(Memory_Block):]
+	block.reserved  = len(buffer) - size_of(Memory_Block)
+	block.committed = block.reserved
+	block.used      = 0
+
+	arena.curr_block = block
+	arena.total_used = 0
+	arena.total_reserved = arena.curr_block.reserved
+	return
+}
+
+@(require_results)
+arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
+	assert(alignment & (alignment-1) == 0, "non-power of two alignment", loc)
+
+	size := size
+	if size == 0 {
+		return nil, nil
+	}
+
+	switch arena.kind {
+	case .Growing:
+		if arena.curr_block == nil || (safe_add(arena.curr_block.used, size) or_else 0) > arena.curr_block.reserved {
+			size = mem.align_forward_uint(size, alignment)
+			if arena.minimum_block_size == 0 {
+				arena.minimum_block_size = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE
+			}
+
+			block_size := max(size, arena.minimum_block_size)
+
+			new_block := memory_block_alloc(size, block_size, {}) or_return
+			new_block.prev = arena.curr_block
+			arena.curr_block = new_block
+			arena.total_reserved += new_block.reserved
+		}
+
+		prev_used := arena.curr_block.used
+		data, err = alloc_from_memory_block(arena.curr_block, size, alignment)
+		arena.total_used += arena.curr_block.used - prev_used
+	case .Static:
+		if arena.curr_block == nil {
+			if arena.minimum_block_size == 0 {
+				arena.minimum_block_size = DEFAULT_ARENA_STATIC_RESERVE_SIZE
+			}
+			arena_init_static(arena=arena, reserved=arena.minimum_block_size, commit_size=DEFAULT_ARENA_STATIC_COMMIT_SIZE) or_return
+		}
+		fallthrough
+	case .Buffer:
+		if arena.curr_block == nil {
+			return nil, .Out_Of_Memory
+		}
+		data, err = alloc_from_memory_block(arena.curr_block, size, alignment)
+		arena.total_used = arena.curr_block.used
+	}
+	return
+}
+
+arena_static_reset_to :: proc(arena: ^Arena, pos: uint, loc := #caller_location) -> bool {
+	if arena.curr_block != nil {
+		assert(arena.kind != .Growing, "expected a non .Growing arena", loc)
+
+		prev_pos := arena.curr_block.used
+		arena.curr_block.used = clamp(pos, 0, arena.curr_block.reserved)
+
+		if prev_pos < pos {
+			mem.zero_slice(arena.curr_block.base[arena.curr_block.used:][:pos-prev_pos])
+		}
+		arena.total_used = arena.curr_block.used
+		return true
+	} else if pos == 0 {
+		arena.total_used = 0
+		return true
+	}
+	return false
+}
+
+arena_growing_free_last_memory_block :: proc(arena: ^Arena, loc := #caller_location) {
+	if free_block := arena.curr_block; free_block != nil {
+		assert(arena.kind == .Growing, "expected a .Growing arena", loc)
+		arena.curr_block = free_block.prev
+		memory_block_dealloc(free_block)
+	}
+}
+
+arena_free_all :: proc(arena: ^Arena) {
+	switch arena.kind {
+	case .Growing:
+		for arena.curr_block != nil {
+			arena_growing_free_last_memory_block(arena)
+		}
+		arena.total_reserved = 0
+	case .Static, .Buffer:
+		arena_static_reset_to(arena, 0)
+	}
+	arena.total_used = 0
+}
+
+arena_destroy :: proc(arena: ^Arena) {
+	arena_free_all(arena)
+	if arena.kind != .Buffer {
+		memory_block_dealloc(arena.curr_block)
+	}
+	arena.curr_block = nil
+	arena.total_used     = 0
+	arena.total_reserved = 0
+	arena.temp_count     = 0
+}
+
+arena_growing_bootstrap_new :: proc{
+	arena_growing_bootstrap_new_by_offset,
+	arena_growing_bootstrap_new_by_name,
+}
+
+arena_static_bootstrap_new :: proc{
+	arena_static_bootstrap_new_by_offset,
+	arena_static_bootstrap_new_by_name,
+}
+
+@(require_results)
+arena_growing_bootstrap_new_by_offset :: proc($T: typeid, offset_to_arena: uintptr, minimum_block_size: uint = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE) -> (ptr: ^T, err: Allocator_Error) {
+	bootstrap: Arena
+	bootstrap.kind = .Growing
+	bootstrap.minimum_block_size = minimum_block_size
+
+	data := arena_alloc(&bootstrap, size_of(T), align_of(T)) or_return
+
+	ptr = (^T)(raw_data(data))
+
+	(^Arena)(uintptr(ptr) + offset_to_arena)^ = bootstrap
+
+	return
+}
+
+@(require_results)
+arena_growing_bootstrap_new_by_name :: proc($T: typeid, $field_name: string, minimum_block_size: uint = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE) -> (ptr: ^T, err: Allocator_Error) {
+	return arena_growing_bootstrap_new_by_offset(T, offset_of_by_string(T, field_name), minimum_block_size)
+}
+
+@(require_results)
+arena_static_bootstrap_new_by_offset :: proc($T: typeid, offset_to_arena: uintptr, reserved: uint) -> (ptr: ^T, err: Allocator_Error) {
+	bootstrap: Arena
+	bootstrap.kind = .Static
+	bootstrap.minimum_block_size = reserved
+
+	data := arena_alloc(&bootstrap, size_of(T), align_of(T)) or_return
+
+	ptr = (^T)(raw_data(data))
+
+	(^Arena)(uintptr(ptr) + offset_to_arena)^ = bootstrap
+
+	return
+}
+
+@(require_results)
+arena_static_bootstrap_new_by_name :: proc($T: typeid, $field_name: string, reserved: uint) -> (ptr: ^T, err: Allocator_Error) {
+	return arena_static_bootstrap_new_by_offset(T, offset_of_by_string(T, field_name), reserved)
+}
+
+
+@(require_results)
+arena_allocator :: proc(arena: ^Arena) -> mem.Allocator {
+	return mem.Allocator{arena_allocator_proc, arena}
+}
+
+arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
+                             size, alignment: int,
+                             old_memory: rawptr, old_size: int,
+                             location := #caller_location) -> (data: []byte, err: Allocator_Error) {
+	arena := (^Arena)(allocator_data)
+
+	size, alignment := uint(size), uint(alignment)
+	old_size := uint(old_size)
+
+	switch mode {
+	case .Alloc, .Alloc_Non_Zeroed:
+		return arena_alloc(arena, size, alignment)
+	case .Free:
+		err = .Mode_Not_Implemented
+	case .Free_All:
+		arena_free_all(arena)
+	case .Resize:
+		old_data := ([^]byte)(old_memory)
+
+		switch {
+		case old_data == nil:
+			return arena_alloc(arena, size, alignment)
+		case size == old_size:
+			// return old memory
+			data = old_data[:size]
+			return
+		case size == 0:
+			err = .Mode_Not_Implemented
+			return
+		case (uintptr(old_data) & uintptr(alignment-1) == 0) && size < old_size:
+			// shrink data in-place
+			data = old_data[:size]
+			return
+		}
+
+		new_memory := arena_alloc(arena, size, alignment) or_return
+		if new_memory == nil {
+			return
+		}
+		copy(new_memory, old_data[:old_size])
+		return new_memory, nil
+	case .Query_Features:
+		set := (^mem.Allocator_Mode_Set)(old_memory)
+		if set != nil {
+			set^ = {.Alloc, .Alloc_Non_Zeroed, .Free_All, .Resize, .Query_Features}
+		}
+	case .Query_Info:
+		err = .Mode_Not_Implemented
+	}
+
+	return
+}
+
+
+
+
+Arena_Temp :: struct {
+	arena: ^Arena,
+	block: ^Memory_Block,
+	used:  uint,
+}
+
+@(require_results)
+arena_temp_begin :: proc(arena: ^Arena, loc := #caller_location) -> (temp: Arena_Temp) {
+	assert(arena != nil, "nil arena", loc)
+	temp.arena = arena
+	temp.block = arena.curr_block
+	if arena.curr_block != nil {
+		temp.used = arena.curr_block.used
+	}
+	arena.temp_count += 1
+	return
+}
+
+arena_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) {
+	assert(temp.arena != nil, "nil arena", loc)
+	arena := temp.arena
+
+	memory_block_found := false
+	for block := arena.curr_block; block != nil; block = block.prev {
+		if block == temp.block {
+			memory_block_found = true
+			break
+		}
+	}
+	if !memory_block_found {
+		assert(arena.curr_block == temp.block, "memory block stored within Arena_Temp not owned by Arena", loc)
+	}
+
+	for arena.curr_block != temp.block {
+		arena_growing_free_last_memory_block(arena)
+	}
+
+	if block := arena.curr_block; block != nil {
+		assert(block.used >= temp.used, "out of order use of arena_temp_end", loc)
+		amount_to_zero := min(block.used-temp.used, block.reserved-block.used)
+		mem.zero_slice(block.base[temp.used:][:amount_to_zero])
+		block.used = temp.used
+	}
+
+	assert(arena.temp_count > 0, "double-use of arena_temp_end", loc)
+	arena.temp_count -= 1
+}
+
+arena_check_temp :: proc(arena: ^Arena, loc := #caller_location) {
+	assert(arena.temp_count == 0, "Arena_Temp not been ended", loc)
+}

+ 0 - 41
core/mem/virtual/arena_util.odin

@@ -1,41 +0,0 @@
-package mem_virtual
-
-arena_init :: proc{
-	static_arena_init,
-	growing_arena_init,
-}
-
-arena_temp_begin :: proc{
-	static_arena_temp_begin,
-	growing_arena_temp_begin,
-}
-
-arena_temp_end :: proc{
-	static_arena_temp_end,
-	growing_arena_temp_end,
-}
-
-arena_check_temp :: proc{
-	static_arena_check_temp,
-	growing_arena_check_temp,
-}
-
-arena_allocator :: proc{
-	static_arena_allocator,
-	growing_arena_allocator,
-}
-
-arena_alloc :: proc{
-	static_arena_alloc,
-	growing_arena_alloc,
-}
-
-arena_free_all :: proc{
-	static_arena_free_all,
-	growing_arena_free_all,
-}
-
-arena_destroy :: proc{
-	static_arena_destroy,
-	growing_arena_destroy,
-}

+ 0 - 171
core/mem/virtual/growing_arena.odin

@@ -1,171 +0,0 @@
-package mem_virtual
-
-import "core:mem"
-
-Growing_Arena :: struct {
-	curr_block:     ^Memory_Block,
-	total_used:     uint,
-	total_reserved: uint,
-	
-	minimum_block_size: uint,
-	temp_count: int,
-}
-
-DEFAULT_MINIMUM_BLOCK_SIZE :: 1<<20 // 1 MiB should be enough
-
-growing_arena_init :: proc(arena: ^Growing_Arena, reserved: uint = DEFAULT_MINIMUM_BLOCK_SIZE) -> (err: Allocator_Error) {
-	arena.curr_block = memory_block_alloc(0, reserved, {}) or_return
-	arena.total_used = 0
-	arena.total_reserved = arena.curr_block.reserved
-	return
-}
-
-growing_arena_alloc :: proc(arena: ^Growing_Arena, min_size: int, alignment: int) -> (data: []byte, err: Allocator_Error) {
-	align_forward_offset :: proc "contextless" (arena: ^Growing_Arena, alignment: int) -> uint #no_bounds_check {
-		alignment_offset := uint(0)
-		ptr := uintptr(arena.curr_block.base[arena.curr_block.used:])
-		mask := uintptr(alignment-1)
-		if ptr & mask != 0 {
-			alignment_offset = uint(alignment) - uint(ptr & mask)
-		}
-		return alignment_offset
-	}
-	
-	assert(mem.is_power_of_two(uintptr(alignment)))
-
-	size := uint(0)
-	if arena.curr_block != nil {
-		size = uint(min_size) + align_forward_offset(arena, alignment)
-	}
-	
-	if arena.curr_block == nil || arena.curr_block.used + size > arena.curr_block.reserved {
-		size = uint(mem.align_forward_int(min_size, alignment))
-		arena.minimum_block_size = max(DEFAULT_MINIMUM_BLOCK_SIZE, arena.minimum_block_size)
-		
-		block_size := max(size, arena.minimum_block_size)
-		
-		new_block := memory_block_alloc(size, block_size, {}) or_return
-		new_block.prev = arena.curr_block
-		arena.curr_block = new_block
-		arena.total_reserved += new_block.reserved	
-	}	
-	
-	
-	data, err = alloc_from_memory_block(arena.curr_block, int(size), alignment)
-	if err == nil {
-		arena.total_used += size
-	}
-	return
-}
-
-growing_arena_free_last_memory_block :: proc(arena: ^Growing_Arena) {
-	free_block := arena.curr_block
-	arena.curr_block = free_block.prev
-	memory_block_dealloc(free_block)
-}
-
-growing_arena_free_all :: proc(arena: ^Growing_Arena) {
-	for arena.curr_block != nil {
-		growing_arena_free_last_memory_block(arena)
-	}
-	arena.total_used = 0
-	arena.total_reserved = 0
-}
-
-growing_arena_destroy :: proc(arena: ^Growing_Arena) {
-	growing_arena_free_all(arena)
-}
-
-growing_arena_bootstrap_new_by_offset :: proc($T: typeid, offset_to_arena: uintptr, minimum_block_size := DEFAULT_MINIMUM_BLOCK_SIZE) -> (ptr: ^T, err: Allocator_Error) {
-	bootstrap: Growing_Arena
-	bootstrap.minimum_block_size = minimum_block_size
-	
-	data := growing_arena_alloc(&bootstrap, size_of(T), align_of(T)) or_return
-	
-	ptr = (^T)(raw_data(data))
-	
-	(^Growing_Arena)(uintptr(ptr) + offset_to_arena)^ = bootstrap
-	
-	return
-}
-
-growing_arena_bootstrap_new_by_name :: proc($T: typeid, $field_name: string, minimum_block_size := DEFAULT_MINIMUM_BLOCK_SIZE) -> (ptr: ^T, err: Allocator_Error) { 
-	return growing_arena_bootstrap_new_by_offset(T, offset_of_by_string(T, field_name), minimum_block_size)
-}
-growing_arena_bootstrap_new :: proc{
-	growing_arena_bootstrap_new_by_offset, 
-	growing_arena_bootstrap_new_by_name,
-}
-
-growing_arena_allocator :: proc(arena: ^Growing_Arena) -> mem.Allocator {
-	return mem.Allocator{growing_arena_allocator_proc, arena}
-}
-
-growing_arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
-                                     size, alignment: int,
-                                     old_memory: rawptr, old_size: int,
-                                     location := #caller_location) -> (data: []byte, err: Allocator_Error) {
-	arena := (^Growing_Arena)(allocator_data)
-		
-	switch mode {
-	case .Alloc, .Alloc_Non_Zeroed:
-		return growing_arena_alloc(arena, size, alignment)
-	case .Free:
-		err = .Mode_Not_Implemented
-		return
-	case .Free_All:
-		growing_arena_free_all(arena)
-		return
-	case .Resize:
-		return mem.default_resize_bytes_align(mem.byte_slice(old_memory, old_size), size, alignment, growing_arena_allocator(arena), location)
-		
-	case .Query_Features, .Query_Info:
-		err = .Mode_Not_Implemented
-		return	
-	}	
-	
-	err = .Mode_Not_Implemented
-	return 
-}
-
-Growing_Arena_Temp :: struct {
-	arena: ^Growing_Arena,
-	block: ^Memory_Block,
-	used:  uint,
-}
-
-growing_arena_temp_begin :: proc(arena: ^Growing_Arena) -> (temp: Growing_Arena_Temp) {
-	temp.arena = arena
-	temp.block = arena.curr_block
-	if arena.curr_block != nil {
-		temp.used = arena.curr_block.used
-	}
-	arena.temp_count += 1
-	return
-}
-
-growing_arena_temp_end :: proc(temp: Growing_Arena_Temp, loc := #caller_location) {
-	assert(temp.arena != nil, "nil arena", loc)
-	arena := temp.arena
-	
-	for arena.curr_block != temp.block {
-		growing_arena_free_last_memory_block(arena)
-	}
-	
-	if block := arena.curr_block; block != nil {
-		assert(block.used >= temp.used, "out of order use of growing_arena_temp_end", loc)
-		amount_to_zero := min(block.used-temp.used, block.reserved-block.used)
-		mem.zero_slice(block.base[temp.used:][:amount_to_zero])
-		block.used = temp.used
-	}
-	
-	assert(arena.temp_count > 0, "double-use of growing_arena_temp_end", loc)
-	arena.temp_count -= 1
-}
-
-growing_arena_check_temp :: proc(arena: ^Growing_Arena, loc := #caller_location) {
-	assert(arena.temp_count == 0, "Growing_Arena_Temp not been ended", loc)
-}
-
-
-

+ 0 - 153
core/mem/virtual/static_arena.odin

@@ -1,153 +0,0 @@
-package mem_virtual
-
-import "core:mem"
-
-Static_Arena :: struct {
-	block: ^Memory_Block,
-	total_used:     uint,
-	total_reserved: uint,
-	
-	minimum_block_size: uint,
-	temp_count: int,
-}
-
-STATIC_ARENA_DEFAULT_COMMIT_SIZE  :: 1<<20 // 1 MiB should be enough to start with
-
-// 1 GiB on 64-bit systems, 128 MiB on 32-bit systems by default
-STATIC_ARENA_DEFAULT_RESERVE_SIZE :: 1<<30 when size_of(uintptr) == 8 else 1<<27
-
-static_arena_init :: proc(arena: ^Static_Arena, reserved: uint, commit_size: uint = STATIC_ARENA_DEFAULT_COMMIT_SIZE) -> (err: Allocator_Error) {	
-	arena.block = memory_block_alloc(commit_size, reserved, {}) or_return
-	arena.total_used = 0
-	arena.total_reserved = arena.block.reserved
-	return
-} 
-
-static_arena_destroy :: proc(arena: ^Static_Arena) {
-	memory_block_dealloc(arena.block)
-	arena^ = {}
-} 
-
-
-static_arena_alloc :: proc(arena: ^Static_Arena, size: int, alignment: int) -> (data: []byte, err: Allocator_Error) {
-	align_forward :: #force_inline proc "contextless" (ptr: uint, align: uint) -> uint {
-		mask := align-1
-		return (ptr + mask) &~ mask
-	}
-	
-	if arena.block == nil {
-		reserve_size := max(arena.minimum_block_size, STATIC_ARENA_DEFAULT_RESERVE_SIZE)
-		static_arena_init(arena, reserve_size, STATIC_ARENA_DEFAULT_COMMIT_SIZE) or_return
-	}
-	
-	MINIMUM_ALIGN :: 2*align_of(uintptr)
-	
-	defer arena.total_used = arena.block.used
-	return alloc_from_memory_block(arena.block, size, max(MINIMUM_ALIGN, alignment))
-}
-
-static_arena_reset_to :: proc(arena: ^Static_Arena, pos: uint) -> bool {
-	if arena.block != nil {
-		prev_pos := arena.block.used
-		arena.block.used = clamp(pos, 0, arena.block.reserved)
-		
-		if prev_pos < pos {
-			mem.zero_slice(arena.block.base[arena.block.used:][:pos-prev_pos])
-		}
-		return true
-	} else if pos == 0 {
-		return true
-	}
-	return false
-}
-
-static_arena_free_all :: proc(arena: ^Static_Arena) {
-	static_arena_reset_to(arena, 0)
-}
-
-
-static_arena_bootstrap_new_by_offset :: proc($T: typeid, offset_to_arena: uintptr, reserved: uint) -> (ptr: ^T, err: Allocator_Error) {
-	bootstrap: Static_Arena
-	bootstrap.minimum_block_size = reserved
-	
-	data := static_arena_alloc(&bootstrap, size_of(T), align_of(T)) or_return
-	
-	ptr = (^T)(raw_data(data))
-	
-	(^Static_Arena)(uintptr(ptr) + offset_to_arena)^ = bootstrap
-	
-	return
-}
-
-static_arena_bootstrap_new_by_name :: proc($T: typeid, $field_name: string, reserved: uint) -> (ptr: ^T, err: Allocator_Error) { 
-	return static_arena_bootstrap_new_by_offset(T, offset_of_by_string(T, field_name), reserved)
-}
-static_arena_bootstrap_new :: proc{
-	static_arena_bootstrap_new_by_offset, 
-	static_arena_bootstrap_new_by_name,
-}
-
-
-static_arena_allocator :: proc(arena: ^Static_Arena) -> mem.Allocator {
-	return mem.Allocator{static_arena_allocator_proc, arena}
-}
-
-static_arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
-                             size, alignment: int,
-                             old_memory: rawptr, old_size: int,
-                             location := #caller_location) -> (data: []byte, err: Allocator_Error) {
-	arena := (^Static_Arena)(allocator_data)
-	
-	switch mode {
-	case .Alloc, .Alloc_Non_Zeroed:
-		return static_arena_alloc(arena, size, alignment)
-	case .Free:
-		err = .Mode_Not_Implemented
-		return
-	case .Free_All:
-		static_arena_free_all(arena)
-		return
-	case .Resize:
-		return mem.default_resize_bytes_align(mem.byte_slice(old_memory, old_size), size, alignment, static_arena_allocator(arena), location)
-		
-	case .Query_Features, .Query_Info:
-		err = .Mode_Not_Implemented
-		return	
-	}	
-	
-	err = .Mode_Not_Implemented
-	return 
-}
-
-
-Static_Arena_Temp :: struct {
-	arena: ^Static_Arena,
-	used:  uint,
-}
-
-
-static_arena_temp_begin :: proc(arena: ^Static_Arena) -> (temp: Static_Arena_Temp) {
-	temp.arena = arena
-	temp.used = arena.block.used if arena.block != nil else 0
-	arena.temp_count += 1
-	return
-}
-
-static_arena_temp_end :: proc(temp: Static_Arena_Temp, loc := #caller_location) {
-	assert(temp.arena != nil, "nil arena", loc)
-	arena := temp.arena
-	
-	used := arena.block.used if arena.block != nil else 0
-	
-	assert(temp.used >= used, "invalid Static_Arena_Temp", loc)
-	
-	static_arena_reset_to(arena, temp.used)
-	
-	assert(arena.temp_count > 0, "double-use of static_arena_temp_end", loc)
-	arena.temp_count -= 1
-}
-
-
-static_arena_check_temp :: proc(arena: ^Static_Arena, loc := #caller_location) {
-	assert(arena.temp_count == 0, "Static_Arena_Temp not been ended", loc)
-}

+ 18 - 15
core/mem/virtual/virtual.odin

@@ -1,6 +1,7 @@
 package mem_virtual
 package mem_virtual
 
 
 import "core:mem"
 import "core:mem"
+import "core:intrinsics"
 
 
 DEFAULT_PAGE_SIZE := uint(4096)
 DEFAULT_PAGE_SIZE := uint(4096)
 
 
@@ -95,18 +96,11 @@ memory_block_alloc :: proc(committed, reserved: uint, flags: Memory_Block_Flags)
 	pmblock.block.committed = committed
 	pmblock.block.committed = committed
 	pmblock.block.reserved  = reserved
 	pmblock.block.reserved  = reserved
 
 
-	sentinel := &global_platform_memory_block_sentinel
-	platform_mutex_lock()
-	pmblock.next = sentinel
-	pmblock.prev = sentinel.prev
-	pmblock.prev.next = pmblock
-	pmblock.next.prev = pmblock
-	platform_mutex_unlock()
 	
 	
 	return &pmblock.block, nil
 	return &pmblock.block, nil
 }
 }
 
 
-alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: int) -> (data: []byte, err: Allocator_Error) {
+alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint) -> (data: []byte, err: Allocator_Error) {
 	calc_alignment_offset :: proc "contextless" (block: ^Memory_Block, alignment: uintptr) -> uint {
 	calc_alignment_offset :: proc "contextless" (block: ^Memory_Block, alignment: uintptr) -> uint {
 		alignment_offset := uint(0)
 		alignment_offset := uint(0)
 		ptr := uintptr(block.base[block.used:])
 		ptr := uintptr(block.base[block.used:])
@@ -134,11 +128,18 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: int)
 		return nil
 		return nil
 	}
 	}
 
 
+	if block == nil {
+		return nil, .Out_Of_Memory
+	}
 
 
 	alignment_offset := calc_alignment_offset(block, uintptr(alignment))
 	alignment_offset := calc_alignment_offset(block, uintptr(alignment))
-	size := uint(min_size) + alignment_offset
+	size, size_ok := safe_add(min_size, alignment_offset)
+	if !size_ok {
+		err = .Out_Of_Memory
+		return
+	}
 
 
-	if block.used + size > block.reserved {
+	if to_be_used, ok := safe_add(block.used, size); !ok || to_be_used > block.reserved {
 		err = .Out_Of_Memory
 		err = .Out_Of_Memory
 		return
 		return
 	}
 	}
@@ -153,12 +154,14 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: int)
 
 
 memory_block_dealloc :: proc(block_to_free: ^Memory_Block) {
 memory_block_dealloc :: proc(block_to_free: ^Memory_Block) {
 	if block := (^Platform_Memory_Block)(block_to_free); block != nil {
 	if block := (^Platform_Memory_Block)(block_to_free); block != nil {
-		platform_mutex_lock()
-		block.prev.next = block.next
-		block.next.prev = block.prev
-		platform_mutex_unlock()
-		
 		platform_memory_free(block)
 		platform_memory_free(block)
 	}
 	}
 }
 }
 
 
+
+
+@(private)
+safe_add :: #force_inline proc "contextless" (x, y: uint) -> (uint, bool) {
+	z, did_overflow := intrinsics.overflow_add(x, y)
+	return z, !did_overflow
+}

+ 0 - 26
core/mem/virtual/virtual_platform.odin

@@ -1,13 +1,10 @@
 //+private
 //+private
 package mem_virtual
 package mem_virtual
 
 
-import "core:sync"
-
 Platform_Memory_Block :: struct {
 Platform_Memory_Block :: struct {
 	block:      Memory_Block,
 	block:      Memory_Block,
 	committed:  uint,
 	committed:  uint,
 	reserved:   uint,
 	reserved:   uint,
-	prev, next: ^Platform_Memory_Block,
 } 
 } 
 
 
 platform_memory_alloc :: proc "contextless" (to_commit, to_reserve: uint) -> (block: ^Platform_Memory_Block, err: Allocator_Error) {
 platform_memory_alloc :: proc "contextless" (to_commit, to_reserve: uint) -> (block: ^Platform_Memory_Block, err: Allocator_Error) {
@@ -33,28 +30,6 @@ platform_memory_free :: proc "contextless" (block: ^Platform_Memory_Block) {
 	}
 	}
 }
 }
 
 
-platform_mutex_lock :: proc() {
-	sync.mutex_lock(&global_memory_block_mutex)
-}
-
-platform_mutex_unlock :: proc() {
-	sync.mutex_unlock(&global_memory_block_mutex)
-}
-
-global_memory_block_mutex: sync.Mutex
-global_platform_memory_block_sentinel: Platform_Memory_Block
-global_platform_memory_block_sentinel_set: bool
-
-@(init)
-platform_memory_init :: proc() {
-	if !global_platform_memory_block_sentinel_set {
-		_platform_memory_init()
-		global_platform_memory_block_sentinel.prev = &global_platform_memory_block_sentinel
-		global_platform_memory_block_sentinel.next = &global_platform_memory_block_sentinel
-		global_platform_memory_block_sentinel_set = true
-	}
-}
-
 platform_memory_commit :: proc "contextless" (block: ^Platform_Memory_Block, to_commit: uint) -> (err: Allocator_Error) {
 platform_memory_commit :: proc "contextless" (block: ^Platform_Memory_Block, to_commit: uint) -> (err: Allocator_Error) {
 	if to_commit < block.committed {
 	if to_commit < block.committed {
 		return nil
 		return nil
@@ -63,7 +38,6 @@ platform_memory_commit :: proc "contextless" (block: ^Platform_Memory_Block, to_
 		return .Out_Of_Memory
 		return .Out_Of_Memory
 	}
 	}
 
 
-
 	commit(block, to_commit) or_return
 	commit(block, to_commit) or_return
 	block.committed = to_commit
 	block.committed = to_commit
 	return nil
 	return nil

+ 1 - 4
core/os/dir_windows.odin

@@ -2,7 +2,6 @@ package os
 
 
 import win32 "core:sys/windows"
 import win32 "core:sys/windows"
 import "core:strings"
 import "core:strings"
-import "core:time"
 
 
 read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) {
 read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Errno) {
 	find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW) -> (fi: File_Info) {
 	find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW) -> (fi: File_Info) {
@@ -41,9 +40,7 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F
 			// fi.mode |= file_type_mode(h);
 			// fi.mode |= file_type_mode(h);
 		}
 		}
 
 
-		fi.creation_time     = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
-		fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
-		fi.access_time       = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
+		windows_set_file_info_times(&fi, d)
 
 
 		fi.is_dir = fi.mode & File_Mode_Dir != 0
 		fi.is_dir = fi.mode & File_Mode_Dir != 0
 		return
 		return

+ 4 - 2
core/os/file_windows.odin

@@ -162,7 +162,8 @@ read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 	total_read: int
 	total_read: int
 	length := len(data)
 	length := len(data)
 
 
-	to_read := min(win32.DWORD(length), MAX_RW)
+	// NOTE(Jeroen): `length` can't be casted to win32.DWORD here because it'll overflow if > 4 GiB and return 0 if exactly that.
+	to_read := min(i64(length), MAX_RW)
 
 
 	e: win32.BOOL
 	e: win32.BOOL
 	if is_console {
 	if is_console {
@@ -172,7 +173,8 @@ read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 			return int(total_read), err
 			return int(total_read), err
 		}
 		}
 	} else {
 	} else {
-		e = win32.ReadFile(handle, &data[total_read], to_read, &single_read_length, nil)
+		// NOTE(Jeroen): So we cast it here *after* we've ensured that `to_read` is at most MAX_RW (1 GiB)
+		e = win32.ReadFile(handle, &data[total_read], win32.DWORD(to_read), &single_read_length, nil)
 	}
 	}
 	if single_read_length <= 0 || !e {
 	if single_read_length <= 0 || !e {
 		err := Errno(win32.GetLastError())
 		err := Errno(win32.GetLastError())

+ 1 - 1
core/os/os2/file_windows.odin

@@ -130,7 +130,7 @@ _new_file :: proc(handle: uintptr, name: string) -> ^File {
 	f := new(File, _file_allocator())
 	f := new(File, _file_allocator())
 
 
 	f.impl.allocator = _file_allocator()
 	f.impl.allocator = _file_allocator()
-	f.impl.fd = rawptr(fd)
+	f.impl.fd = rawptr(handle)
 	f.impl.name = strings.clone(name, f.impl.allocator)
 	f.impl.name = strings.clone(name, f.impl.allocator)
 	f.impl.wname = win32.utf8_to_wstring(name, f.impl.allocator)
 	f.impl.wname = win32.utf8_to_wstring(name, f.impl.allocator)
 
 

+ 32 - 11
core/os/os_darwin.odin

@@ -369,27 +369,48 @@ close :: proc(fd: Handle) -> bool {
 	return _unix_close(fd) == 0
 	return _unix_close(fd) == 0
 }
 }
 
 
+@(private)
+MAX_RW :: 0x7fffffff // The limit on Darwin is max(i32), trying to read/write more than that fails.
+
 write :: proc(fd: Handle, data: []u8) -> (int, Errno) {
 write :: proc(fd: Handle, data: []u8) -> (int, Errno) {
 	assert(fd != -1)
 	assert(fd != -1)
 
 
-	if len(data) == 0 {
-		return 0, 0
-	}
-	bytes_written := _unix_write(fd, raw_data(data), len(data))
-	if bytes_written == -1 {
-		return 0, 1
+	bytes_total := len(data)
+	bytes_written_total := 0
+
+	for bytes_written_total < bytes_total {
+		bytes_to_write := min(bytes_total - bytes_written_total, MAX_RW)
+		slice := data[bytes_written_total:bytes_written_total + bytes_to_write]
+		bytes_written := _unix_write(fd, raw_data(slice), bytes_to_write)
+		if bytes_written == -1 {
+			return bytes_written_total, 1
+		}
+		bytes_written_total += bytes_written
 	}
 	}
-	return bytes_written, 0
+
+	return bytes_written_total, 0
 }
 }
 
 
 read :: proc(fd: Handle, data: []u8) -> (int, Errno) {
 read :: proc(fd: Handle, data: []u8) -> (int, Errno) {
 	assert(fd != -1)
 	assert(fd != -1)
 
 
-	bytes_read := _unix_read(fd, raw_data(data), len(data))
-	if bytes_read == -1 {
-		return 0, 1
+	bytes_total := len(data)
+	bytes_read_total := 0
+
+	for bytes_read_total < bytes_total {
+		bytes_to_read := min(bytes_total - bytes_read_total, MAX_RW)
+		slice := data[bytes_read_total:bytes_read_total + bytes_to_read]
+		bytes_read := _unix_read(fd, raw_data(slice), bytes_to_read)
+		if bytes_read == -1 {
+			return bytes_read_total, 1
+		}
+		if bytes_read == 0 {
+			break
+		}
+		bytes_read_total += bytes_read
 	}
 	}
-	return bytes_read, 0
+
+	return bytes_read_total, 0
 }
 }
 
 
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
 seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {

+ 32 - 3
core/os/os_wasi.odin

@@ -24,7 +24,7 @@ O_CLOEXEC  :: 0x80000
 stdin:  Handle = 0
 stdin:  Handle = 0
 stdout: Handle = 1
 stdout: Handle = 1
 stderr: Handle = 2
 stderr: Handle = 2
-
+current_dir: Handle = 3
 
 
 write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
 	iovs := wasi.ciovec_t(data)
 	iovs := wasi.ciovec_t(data)
@@ -47,7 +47,36 @@ read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
 	return int(n), Errno(err)
 	return int(n), Errno(err)
 }
 }
 open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
 open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
-	return 0, -1
+	oflags: wasi.oflags_t
+	if mode & O_CREATE == O_CREATE {
+		oflags += {.CREATE}
+	}
+	if mode & O_EXCL == O_EXCL {
+		oflags += {.EXCL}
+	}
+	if mode & O_TRUNC == O_TRUNC {
+		oflags += {.TRUNC}
+	}
+
+	rights: wasi.rights_t = {.FD_SEEK, .FD_FILESTAT_GET}
+	switch mode & (O_RDONLY|O_WRONLY|O_RDWR) {
+	case O_RDONLY: rights += {.FD_READ}
+	case O_WRONLY: rights += {.FD_WRITE}
+	case O_RDWR:   rights += {.FD_READ, .FD_WRITE}
+	}
+
+	fdflags: wasi.fdflags_t
+	if mode & O_APPEND == O_APPEND {
+		fdflags += {.APPEND}
+	}
+	if mode & O_NONBLOCK == O_NONBLOCK {
+		fdflags += {.NONBLOCK}
+	}
+	if mode & O_SYNC == O_SYNC {
+		fdflags += {.SYNC}
+	}
+	fd, err := wasi.path_open(wasi.fd_t(current_dir),{.SYMLINK_FOLLOW},path,oflags,rights,{},fdflags)
+	return Handle(fd), Errno(err)
 }
 }
 close :: proc(fd: Handle) -> Errno {
 close :: proc(fd: Handle) -> Errno {
 	err := wasi.fd_close(wasi.fd_t(fd))
 	err := wasi.fd_close(wasi.fd_t(fd))
@@ -96,4 +125,4 @@ heap_free :: proc(ptr: rawptr) {
 exit :: proc "contextless" (code: int) -> ! {
 exit :: proc "contextless" (code: int) -> ! {
 	runtime._cleanup_runtime_contextless()
 	runtime._cleanup_runtime_contextless()
 	wasi.proc_exit(wasi.exitcode_t(code))
 	wasi.proc_exit(wasi.exitcode_t(code))
-}
+}

+ 10 - 10
core/os/stat_windows.odin

@@ -228,6 +228,13 @@ file_mode_from_file_attributes :: proc(FileAttributes: win32.DWORD, h: win32.HAN
 	return
 	return
 }
 }
 
 
+@(private)
+windows_set_file_info_times :: proc(fi: ^File_Info, d: ^$T) {
+	fi.creation_time     = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
+	fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
+	fi.access_time       = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
+}
+
 @(private)
 @(private)
 file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string) -> (fi: File_Info, e: Errno) {
 file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string) -> (fi: File_Info, e: Errno) {
 	fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow)
 	fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow)
@@ -235,9 +242,7 @@ file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_
 	fi.mode |= file_mode_from_file_attributes(d.dwFileAttributes, nil, 0)
 	fi.mode |= file_mode_from_file_attributes(d.dwFileAttributes, nil, 0)
 	fi.is_dir = fi.mode & File_Mode_Dir != 0
 	fi.is_dir = fi.mode & File_Mode_Dir != 0
 
 
-	fi.creation_time     = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
-	fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
-	fi.access_time       = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
+	windows_set_file_info_times(&fi, d)
 
 
 	fi.fullpath, e = full_path_from_name(name)
 	fi.fullpath, e = full_path_from_name(name)
 	fi.name = basename(fi.fullpath)
 	fi.name = basename(fi.fullpath)
@@ -252,9 +257,7 @@ file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string)
 	fi.mode |= file_mode_from_file_attributes(d.dwFileAttributes, nil, 0)
 	fi.mode |= file_mode_from_file_attributes(d.dwFileAttributes, nil, 0)
 	fi.is_dir = fi.mode & File_Mode_Dir != 0
 	fi.is_dir = fi.mode & File_Mode_Dir != 0
 
 
-	fi.creation_time     = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
-	fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
-	fi.access_time       = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
+	windows_set_file_info_times(&fi, d)
 
 
 	fi.fullpath, e = full_path_from_name(name)
 	fi.fullpath, e = full_path_from_name(name)
 	fi.name = basename(fi.fullpath)
 	fi.name = basename(fi.fullpath)
@@ -290,10 +293,7 @@ file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HAN
 	fi.mode |= file_mode_from_file_attributes(ti.FileAttributes, h, ti.ReparseTag)
 	fi.mode |= file_mode_from_file_attributes(ti.FileAttributes, h, ti.ReparseTag)
 	fi.is_dir = fi.mode & File_Mode_Dir != 0
 	fi.is_dir = fi.mode & File_Mode_Dir != 0
 
 
-	fi.creation_time     = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftCreationTime))
-	fi.modification_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastWriteTime))
-	fi.access_time       = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
-
+	windows_set_file_info_times(&fi, &d)
 
 
 	return fi, ERROR_NONE
 	return fi, ERROR_NONE
 }
 }

+ 1 - 29
core/runtime/core_builtin.odin

@@ -672,7 +672,7 @@ shrink_dynamic_array :: proc(array: ^$T/[dynamic]$E, new_cap := -1, loc := #call
 @builtin
 @builtin
 map_insert :: proc(m: ^$T/map[$K]$V, key: K, value: V, loc := #caller_location) -> (ptr: ^V) {
 map_insert :: proc(m: ^$T/map[$K]$V, key: K, value: V, loc := #caller_location) -> (ptr: ^V) {
 	key, value := key, value
 	key, value := key, value
-	h := __get_map_header(T)
+	h := __get_map_header_table(T)
 
 
 	e := __dynamic_map_set(m, h, __get_map_key_hash(&key), &key, &value, loc)
 	e := __dynamic_map_set(m, h, __get_map_key_hash(&key), &key, &value, loc)
 	return (^V)(uintptr(e) + h.value_offset)
 	return (^V)(uintptr(e) + h.value_offset)
@@ -731,34 +731,6 @@ card :: proc(s: $S/bit_set[$E; $U]) -> int {
 
 
 
 
 
 
-@builtin
-raw_array_data :: proc "contextless" (a: $P/^($T/[$N]$E)) -> [^]E {
-	return ([^]E)(a)
-}
-@builtin
-raw_simd_data :: proc "contextless" (a: $P/^($T/#simd[$N]$E)) -> [^]E {
-	return ([^]E)(a)
-}
-@builtin
-raw_slice_data :: proc "contextless" (s: $S/[]$E) -> [^]E {
-	ptr := (transmute(Raw_Slice)s).data
-	return ([^]E)(ptr)
-}
-@builtin
-raw_dynamic_array_data :: proc "contextless" (s: $S/[dynamic]$E) -> [^]E {
-	ptr := (transmute(Raw_Dynamic_Array)s).data
-	return ([^]E)(ptr)
-}
-@builtin
-raw_string_data :: proc "contextless" (s: $S/string) -> [^]u8 {
-	return (transmute(Raw_String)s).data
-}
-
-@builtin
-raw_data :: proc{raw_array_data, raw_slice_data, raw_dynamic_array_data, raw_string_data, raw_simd_data}
-
-
-
 @builtin
 @builtin
 @(disabled=ODIN_DISABLE_ASSERT)
 @(disabled=ODIN_DISABLE_ASSERT)
 assert :: proc(condition: bool, message := "", loc := #caller_location) {
 assert :: proc(condition: bool, message := "", loc := #caller_location) {

+ 3 - 3
core/runtime/error_checks.odin

@@ -18,7 +18,7 @@ type_assertion_trap :: proc "contextless" () -> ! {
 
 
 
 
 bounds_check_error :: proc "contextless" (file: string, line, column: i32, index, count: int) {
 bounds_check_error :: proc "contextless" (file: string, line, column: i32, index, count: int) {
-	if 0 <= index && index < count {
+	if uint(index) < uint(count) {
 		return
 		return
 	}
 	}
 	@(cold)
 	@(cold)
@@ -99,8 +99,8 @@ dynamic_array_expr_error :: proc "contextless" (file: string, line, column: i32,
 
 
 
 
 matrix_bounds_check_error :: proc "contextless" (file: string, line, column: i32, row_index, column_index, row_count, column_count: int) {
 matrix_bounds_check_error :: proc "contextless" (file: string, line, column: i32, row_index, column_index, row_count, column_count: int) {
-	if 0 <= row_index && row_index < row_count &&
-	   0 <= column_index && column_index < column_count {
+	if uint(row_index) < uint(row_count) &&
+	   uint(column_index) < uint(column_count) {
 		return
 		return
 	}
 	}
 	@(cold)
 	@(cold)

+ 1 - 1
core/runtime/procs_darwin.odin

@@ -12,7 +12,7 @@ objc_SEL :: ^intrinsics.objc_selector
 foreign Foundation {
 foreign Foundation {
 	objc_lookUpClass :: proc "c" (name: cstring) -> objc_Class ---
 	objc_lookUpClass :: proc "c" (name: cstring) -> objc_Class ---
 	sel_registerName :: proc "c" (name: cstring) -> objc_SEL ---
 	sel_registerName :: proc "c" (name: cstring) -> objc_SEL ---
-	objc_allocateClassPair :: proc "c" (superclass: objc_Class, name: cstring, extraBytes: uint) ---
+	objc_allocateClassPair :: proc "c" (superclass: objc_Class, name: cstring, extraBytes: uint) -> objc_Class ---
 
 
 	objc_msgSend        :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) ---
 	objc_msgSend        :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) ---
 	objc_msgSend_fpret  :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) -> f64 ---
 	objc_msgSend_fpret  :: proc "c" (self: objc_id, op: objc_SEL, #c_vararg args: ..any) -> f64 ---

+ 2 - 2
core/slice/slice.odin

@@ -321,14 +321,14 @@ last_ptr :: proc(array: $T/[]$E) -> ^E {
 }
 }
 
 
 get :: proc(array: $T/[]$E, index: int) -> (value: E, ok: bool) {
 get :: proc(array: $T/[]$E, index: int) -> (value: E, ok: bool) {
-	if 0 <= index && index < len(array) {
+	if uint(index) < len(array) {
 		value = array[index]
 		value = array[index]
 		ok = true
 		ok = true
 	}
 	}
 	return
 	return
 }
 }
 get_ptr :: proc(array: $T/[]$E, index: int) -> (value: ^E, ok: bool) {
 get_ptr :: proc(array: $T/[]$E, index: int) -> (value: ^E, ok: bool) {
-	if 0 <= index && index < len(array) {
+	if uint(index) < len(array) {
 		value = &array[index]
 		value = &array[index]
 		ok = true
 		ok = true
 	}
 	}

+ 3 - 2
core/slice/sort_private.odin

@@ -177,7 +177,6 @@ _quick_sort_general :: proc(data: $T/[]$E, a, b, max_depth: int, call: $P, $KIND
 }
 }
 
 
 
 
-// merge sort
 _stable_sort_general :: proc(data: $T/[]$E, call: $P, $KIND: Sort_Kind) where (ORD(E) && KIND == .Ordered) || (KIND != .Ordered) #no_bounds_check {
 _stable_sort_general :: proc(data: $T/[]$E, call: $P, $KIND: Sort_Kind) where (ORD(E) && KIND == .Ordered) || (KIND != .Ordered) #no_bounds_check {
 	less :: #force_inline proc(a, b: E, call: P) -> bool {
 	less :: #force_inline proc(a, b: E, call: P) -> bool {
 		when KIND == .Ordered {
 		when KIND == .Ordered {
@@ -190,7 +189,9 @@ _stable_sort_general :: proc(data: $T/[]$E, call: $P, $KIND: Sort_Kind) where (O
 			#panic("unhandled Sort_Kind")
 			#panic("unhandled Sort_Kind")
 		}
 		}
 	}
 	}
-
+	
+	// insertion sort
+	// TODO(bill): use a different algorithm as insertion sort is O(n^2)
 	n := len(data)
 	n := len(data)
 	for i in 1..<n {
 	for i in 1..<n {
 		for j := i; j > 0 && less(data[j], data[j-1], call); j -= 1 {
 		for j := i; j > 0 && less(data[j], data[j-1], call); j -= 1 {

+ 41 - 2
core/strconv/strconv.odin

@@ -567,7 +567,7 @@ parse_f32 :: proc(s: string, n: ^int = nil) -> (value: f32, ok: bool) {
 // ```
 // ```
 parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
 parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
 	s := str
 	s := str
-	defer if n != nil { n^ = len(str)-len(s) }
+	defer if n != nil { n^ = len(str) - len(s) }
 	if s == "" {
 	if s == "" {
 		return
 		return
 	}
 	}
@@ -575,9 +575,11 @@ parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
 	i := 0
 	i := 0
 
 
 	sign: f64 = 1
 	sign: f64 = 1
+	seen_sign := true
 	switch s[i] {
 	switch s[i] {
 	case '-': i += 1; sign = -1
 	case '-': i += 1; sign = -1
 	case '+': i += 1
 	case '+': i += 1
+	case: seen_sign = false
 	}
 	}
 
 
 	for ; i < len(s); i += 1 {
 	for ; i < len(s); i += 1 {
@@ -588,6 +590,38 @@ parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
 
 
 		v := _digit_value(r)
 		v := _digit_value(r)
 		if v >= 10 {
 		if v >= 10 {
+			if r == '.' || r == 'e' || r == 'E' { // Skip parsing NaN and Inf if it's probably a regular float
+				break
+			}
+			if len(s) >= 3 + i {
+				buf: [4]u8
+				copy(buf[:], s[i:][:3])
+
+				v2 := transmute(u32)buf
+				v2 &= 0xDFDFDFDF // Knock out lower-case bits
+
+				buf = transmute([4]u8)v2
+
+				when ODIN_ENDIAN == .Little {
+					if v2 == 0x464e49 { // "INF"
+						s = s[3+i:]
+						value = 0h7ff00000_00000000 if sign == 1 else 0hfff00000_00000000
+						return value, len(s) == 0
+					} else if v2 == 0x4e414e { // "NAN"
+						s = s[3+i:]
+						return 0h7ff80000_00000001, len(s) == 0
+					}
+				} else {
+					if v2 == 0x494e4600 { // "\0FNI"
+						s = s[3+i:]
+						value = 0h7ff00000_00000000 if sign == 1 else 0hfff00000_00000000
+						return value, len(s) == 0
+					} else if v2 == 0x4e414e00 { // "\0NAN"
+						s = s[3+i:]
+						return 0h7ff80000_00000001, len(s) == 0
+					}
+				}
+			}
 			break
 			break
 		}
 		}
 		value *= 10
 		value *= 10
@@ -645,8 +679,13 @@ parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
 			for exp >   0 { scale *=   10; exp -=  1 }
 			for exp >   0 { scale *=   10; exp -=  1 }
 		}
 		}
 	}
 	}
-	s = s[i:]
 
 
+	// If we only consumed a sign, return false
+	if i == 1 && seen_sign {
+		return 0, false
+	}
+
+	s = s[i:]
 	if frac {
 	if frac {
 		value = sign * (value/scale)
 		value = sign * (value/scale)
 	} else {
 	} else {

+ 1 - 1
core/strings/strings.odin

@@ -760,7 +760,7 @@ last_index_byte :: proc(s: string, c: byte) -> int {
 */
 */
 index_rune :: proc(s: string, r: rune) -> int {
 index_rune :: proc(s: string, r: rune) -> int {
 	switch {
 	switch {
-	case 0 <= r && r < utf8.RUNE_SELF:
+	case u32(r) < utf8.RUNE_SELF:
 		return index_byte(s, byte(r))
 		return index_byte(s, byte(r))
 
 
 	case r == utf8.RUNE_ERROR:
 	case r == utf8.RUNE_ERROR:

+ 1 - 0
core/sys/info/platform_darwin.odin

@@ -464,6 +464,7 @@ macos_release_map: map[string]Darwin_To_Release = {
 	"21F2092"  = {{21, 5, 0}, "macOS", {"Monterey",      {12, 4, 0}}},
 	"21F2092"  = {{21, 5, 0}, "macOS", {"Monterey",      {12, 4, 0}}},
 	"21G72"    = {{21, 6, 0}, "macOS", {"Monterey",      {12, 5, 0}}},
 	"21G72"    = {{21, 6, 0}, "macOS", {"Monterey",      {12, 5, 0}}},
 	"21G83"    = {{21, 6, 0}, "macOS", {"Monterey",      {12, 5, 1}}},
 	"21G83"    = {{21, 6, 0}, "macOS", {"Monterey",      {12, 5, 1}}},
+	"21G115"   = {{21, 6, 0}, "macOS", {"Monterey",      {12, 6, 0}}},
 }
 }
 
 
 @(private)
 @(private)

+ 30 - 0
core/sys/windows/advapi32.odin

@@ -128,4 +128,34 @@ foreign advapi32 {
 		lpData: LPCVOID,
 		lpData: LPCVOID,
 		cbData: DWORD,
 		cbData: DWORD,
 	) -> LSTATUS ---
 	) -> LSTATUS ---
+
+	GetFileSecurityW :: proc(
+		lpFileName: LPCWSTR,
+		RequestedInformation: SECURITY_INFORMATION,
+		pSecurityDescriptor: PSECURITY_DESCRIPTOR,
+		nLength: DWORD,
+		lpnLengthNeeded: LPDWORD,
+	) -> BOOL ---
+
+	DuplicateToken :: proc(
+		ExistingTokenHandle: HANDLE,
+		ImpersonationLevel: SECURITY_IMPERSONATION_LEVEL,
+		DuplicateTokenHandle: PHANDLE,
+	) -> BOOL ---
+
+	MapGenericMask :: proc(
+		AccessMask: PDWORD,
+		GenericMapping: PGENERIC_MAPPING,
+	) ---
+
+	AccessCheck :: proc(
+		pSecurityDescriptor: PSECURITY_DESCRIPTOR,
+		ClientToken: HANDLE,
+		DesiredAccess: DWORD,
+		GenericMapping: PGENERIC_MAPPING,
+		PrivilegeSet: PPRIVILEGE_SET,
+		PrivilegeSetLength: LPDWORD,
+		GrantedAccess: LPDWORD,
+		AccessStatus: LPBOOL,
+	) -> BOOL ---
 }
 }

+ 9 - 0
core/sys/windows/comctl32.odin

@@ -0,0 +1,9 @@
+// +build windows
+package sys_windows
+
+foreign import "system:Comctl32.lib"
+
+@(default_calling_convention="stdcall")
+foreign Comctl32 {
+	LoadIconWithScaleDown :: proc(hinst: HINSTANCE, pszName: PCWSTR, cx: c_int, cy: c_int, phico: ^HICON) -> HRESULT ---
+}

+ 1 - 0
core/sys/windows/gdi32.odin

@@ -77,6 +77,7 @@ foreign gdi32 {
 	) -> HFONT ---
 	) -> HFONT ---
 	TextOutW :: proc(hdc: HDC, x, y: c_int, lpString: LPCWSTR, c: c_int) -> BOOL ---
 	TextOutW :: proc(hdc: HDC, x, y: c_int, lpString: LPCWSTR, c: c_int) -> BOOL ---
 	GetTextExtentPoint32W :: proc(hdc: HDC, lpString: LPCWSTR, c: c_int, psizl: LPSIZE) -> BOOL ---
 	GetTextExtentPoint32W :: proc(hdc: HDC, lpString: LPCWSTR, c: c_int, psizl: LPSIZE) -> BOOL ---
+	GetTextMetricsW :: proc(hdc: HDC, lptm: LPTEXTMETRICW) -> BOOL ---
 }
 }
 
 
 RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF {
 RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF {

+ 173 - 0
core/sys/windows/kernel32.odin

@@ -248,6 +248,17 @@ foreign kernel32 {
 	GetModuleHandleW :: proc(lpModuleName: LPCWSTR) -> HMODULE ---
 	GetModuleHandleW :: proc(lpModuleName: LPCWSTR) -> HMODULE ---
 	GetModuleHandleA :: proc(lpModuleName: LPCSTR) -> HMODULE ---
 	GetModuleHandleA :: proc(lpModuleName: LPCSTR) -> HMODULE ---
 	GetSystemTimeAsFileTime :: proc(lpSystemTimeAsFileTime: LPFILETIME) ---
 	GetSystemTimeAsFileTime :: proc(lpSystemTimeAsFileTime: LPFILETIME) ---
+	GetSystemTimePreciseAsFileTime :: proc(lpSystemTimeAsFileTime: LPFILETIME) ---
+	FileTimeToSystemTime :: proc(lpFileTime: ^FILETIME, lpSystemTime: ^SYSTEMTIME) -> BOOL ---
+	SystemTimeToTzSpecificLocalTime :: proc(
+		lpTimeZoneInformation: ^TIME_ZONE_INFORMATION,
+		lpUniversalTime: ^SYSTEMTIME,
+		lpLocalTime: ^SYSTEMTIME,
+	) -> BOOL ---
+	SystemTimeToFileTime :: proc(
+		lpSystemTime: ^SYSTEMTIME,
+		lpFileTime: LPFILETIME,
+	) -> BOOL ---
 	CreateEventW :: proc(
 	CreateEventW :: proc(
 		lpEventAttributes: LPSECURITY_ATTRIBUTES,
 		lpEventAttributes: LPSECURITY_ATTRIBUTES,
 		bManualReset: BOOL,
 		bManualReset: BOOL,
@@ -346,6 +357,13 @@ foreign kernel32 {
 	GenerateConsoleCtrlEvent :: proc(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> BOOL ---
 	GenerateConsoleCtrlEvent :: proc(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> BOOL ---
 	FreeConsole :: proc() -> BOOL ---
 	FreeConsole :: proc() -> BOOL ---
 	GetConsoleWindow :: proc() -> HWND ---
 	GetConsoleWindow :: proc() -> HWND ---
+
+	GetDiskFreeSpaceExW :: proc(
+		lpDirectoryName: LPCWSTR,
+		lpFreeBytesAvailableToCaller: PULARGE_INTEGER,
+		lpTotalNumberOfBytes: PULARGE_INTEGER,
+		lpTotalNumberOfFreeBytes: PULARGE_INTEGER,
+	) -> BOOL ---
 }
 }
 
 
 
 
@@ -820,3 +838,158 @@ foreign kernel32 {
 
 
 HandlerRoutine :: proc "stdcall" (dwCtrlType: DWORD) -> BOOL
 HandlerRoutine :: proc "stdcall" (dwCtrlType: DWORD) -> BOOL
 PHANDLER_ROUTINE :: HandlerRoutine
 PHANDLER_ROUTINE :: HandlerRoutine
+
+
+
+
+DCB_Config :: struct {
+	fParity: bool,
+	fOutxCtsFlow: bool,
+	fOutxDsrFlow: bool,
+	fDtrControl: DTR_Control,
+	fDsrSensitivity: bool,
+	fTXContinueOnXoff: bool,
+	fOutX: bool,
+	fInX: bool,
+	fErrorChar: bool,
+	fNull: bool,
+	fRtsControl: RTS_Control,
+	fAbortOnError: bool,
+	BaudRate: DWORD,
+	ByteSize: BYTE,
+	Parity: Parity,
+	StopBits: Stop_Bits,
+	XonChar: byte,
+	XoffChar: byte,
+	ErrorChar: byte,
+	EvtChar: byte,
+}
+DTR_Control :: enum byte {
+	Disable = 0,
+	Enable = 1,
+	Handshake = 2,
+}
+RTS_Control :: enum byte {
+	Disable   = 0,
+	Enable    = 1,
+	Handshake = 2,
+	Toggle    = 3,
+}
+Parity :: enum byte {
+	None  = 0,
+	Odd   = 1,
+	Even  = 2,
+	Mark  = 3,
+	Space = 4,
+}
+Stop_Bits :: enum byte {
+	One = 0,
+	One_And_A_Half = 1,
+	Two = 2,
+}
+
+// A helper procedure to set the values of a DCB structure.
+init_dcb_with_config :: proc "contextless" (dcb: ^DCB, config: DCB_Config) {
+	out: u32
+
+	// NOTE(tetra, 2022-09-21): On both Clang 14 on Windows, and MSVC, the bits in the bitfield
+	// appear to be defined from LSB to MSB order.
+	// i.e: `fBinary` (the first bitfield in the C source) is the LSB in the `settings` u32.
+
+	out |= u32(1) << 0 // fBinary must always be true on Windows.
+
+	out |= u32(config.fParity) << 1
+	out |= u32(config.fOutxCtsFlow) << 2
+	out |= u32(config.fOutxDsrFlow) << 3
+
+	out |= u32(config.fDtrControl) << 4
+
+	out |= u32(config.fDsrSensitivity) << 6
+	out |= u32(config.fTXContinueOnXoff) << 7
+	out |= u32(config.fOutX) << 8
+	out |= u32(config.fInX) << 9
+	out |= u32(config.fErrorChar) << 10
+	out |= u32(config.fNull) << 11
+
+	out |= u32(config.fRtsControl) << 12
+
+	out |= u32(config.fAbortOnError) << 14
+
+	dcb.settings = out
+
+	dcb.BaudRate = config.BaudRate
+	dcb.ByteSize = config.ByteSize
+	dcb.Parity = config.Parity
+	dcb.StopBits = config.StopBits
+	dcb.XonChar = config.XonChar
+	dcb.XoffChar = config.XoffChar
+	dcb.ErrorChar = config.ErrorChar
+	dcb.EvtChar = config.EvtChar
+
+	dcb.DCBlength = size_of(DCB)
+}
+get_dcb_config :: proc "contextless" (dcb: DCB) -> (config: DCB_Config) {
+	config.fParity = bool((dcb.settings >> 1) & 0x01)
+	config.fOutxCtsFlow = bool((dcb.settings >> 2) & 0x01)
+	config.fOutxDsrFlow = bool((dcb.settings >> 3) & 0x01)
+
+	config.fDtrControl = DTR_Control((dcb.settings >> 4) & 0x02)
+
+	config.fDsrSensitivity = bool((dcb.settings >> 6) & 0x01)
+	config.fTXContinueOnXoff = bool((dcb.settings >> 7) & 0x01)
+	config.fOutX = bool((dcb.settings >> 8) & 0x01)
+	config.fInX = bool((dcb.settings >> 9) & 0x01)
+	config.fErrorChar = bool((dcb.settings >> 10) & 0x01)
+	config.fNull = bool((dcb.settings >> 11) & 0x01)
+
+	config.fRtsControl = RTS_Control((dcb.settings >> 12) & 0x02)
+
+	config.fAbortOnError = bool((dcb.settings >> 14) & 0x01)
+
+	config.BaudRate = dcb.BaudRate
+	config.ByteSize = dcb.ByteSize
+	config.Parity = dcb.Parity
+	config.StopBits = dcb.StopBits
+	config.XonChar = dcb.XonChar
+	config.XoffChar = dcb.XoffChar
+	config.ErrorChar = dcb.ErrorChar
+	config.EvtChar = dcb.EvtChar
+
+	return
+}
+
+// NOTE(tetra): See get_dcb_config() and init_dcb_with_config() for help with initializing this.
+DCB :: struct {
+	DCBlength: DWORD, // NOTE(tetra): Must be set to size_of(DCB).
+	BaudRate: DWORD,
+	settings: u32, // NOTE(tetra): These are bitfields in the C struct.
+	wReserved: WORD,
+	XOnLim: WORD,
+	XOffLim: WORD,
+	ByteSize: BYTE,
+	Parity: Parity,
+	StopBits: Stop_Bits,
+	XonChar: byte,
+	XoffChar: byte,
+	ErrorChar: byte,
+	EofChar: byte,
+	EvtChar: byte,
+	wReserved1: WORD,
+}
+
+@(default_calling_convention="stdcall")
+foreign kernel32 {
+	GetCommState :: proc(handle: HANDLE, dcb: ^DCB) -> BOOL ---
+	SetCommState :: proc(handle: HANDLE, dcb: ^DCB) -> BOOL ---
+}
+
+
+LPFIBER_START_ROUTINE :: #type proc "stdcall" (lpFiberParameter: LPVOID)
+
+@(default_calling_convention = "stdcall")
+foreign kernel32 {
+	CreateFiber :: proc(dwStackSize: SIZE_T, lpStartAddress: LPFIBER_START_ROUTINE, lpParameter: LPVOID) -> LPVOID ---
+	DeleteFiber :: proc(lpFiber: LPVOID) ---
+	ConvertThreadToFiber :: proc(lpParameter: LPVOID) -> LPVOID ---
+	SwitchToFiber :: proc(lpFiber: LPVOID) ---
+}

+ 6 - 0
core/sys/windows/shell32.odin

@@ -14,4 +14,10 @@ foreign shell32 {
 		lpDirectory: LPCWSTR,
 		lpDirectory: LPCWSTR,
 		nShowCmd: INT,
 		nShowCmd: INT,
 	) -> HINSTANCE ---
 	) -> HINSTANCE ---
+	SHCreateDirectoryExW :: proc(
+		hwnd: HWND,
+		pszPath: LPCWSTR,
+		psa: ^SECURITY_ATTRIBUTES,
+	) -> c_int ---
+	SHFileOperationW :: proc(lpFileOp: LPSHFILEOPSTRUCTW) -> c_int ---
 }
 }

+ 1 - 0
core/sys/windows/shlwapi.odin

@@ -8,4 +8,5 @@ foreign shlwapi {
 	PathFileExistsW    :: proc(pszPath: wstring) -> BOOL ---
 	PathFileExistsW    :: proc(pszPath: wstring) -> BOOL ---
 	PathFindExtensionW :: proc(pszPath: wstring) -> wstring ---
 	PathFindExtensionW :: proc(pszPath: wstring) -> wstring ---
 	PathFindFileNameW  :: proc(pszPath: wstring) -> wstring ---
 	PathFindFileNameW  :: proc(pszPath: wstring) -> wstring ---
+	SHAutoComplete     :: proc(hwndEdit: HWND, dwFlags: DWORD) -> LWSTDAPI ---
 }
 }

+ 280 - 4
core/sys/windows/types.odin

@@ -20,6 +20,7 @@ DWORD :: c_ulong
 DWORDLONG :: c.ulonglong
 DWORDLONG :: c.ulonglong
 QWORD :: c.ulonglong
 QWORD :: c.ulonglong
 HANDLE :: distinct LPVOID
 HANDLE :: distinct LPVOID
+PHANDLE :: ^HANDLE
 HINSTANCE :: HANDLE
 HINSTANCE :: HANDLE
 HMODULE :: distinct HINSTANCE
 HMODULE :: distinct HINSTANCE
 HRESULT :: distinct LONG
 HRESULT :: distinct LONG
@@ -43,6 +44,7 @@ BOOLEAN :: distinct b8
 GROUP :: distinct c_uint
 GROUP :: distinct c_uint
 LARGE_INTEGER :: distinct c_longlong
 LARGE_INTEGER :: distinct c_longlong
 ULARGE_INTEGER :: distinct c_ulonglong
 ULARGE_INTEGER :: distinct c_ulonglong
+PULARGE_INTEGER :: ^ULARGE_INTEGER
 LONG :: c_long
 LONG :: c_long
 UINT :: c_uint
 UINT :: c_uint
 INT  :: c_int
 INT  :: c_int
@@ -133,6 +135,11 @@ LPWSAOVERLAPPED :: distinct rawptr
 LPWSAOVERLAPPED_COMPLETION_ROUTINE :: distinct rawptr
 LPWSAOVERLAPPED_COMPLETION_ROUTINE :: distinct rawptr
 LPCVOID :: rawptr
 LPCVOID :: rawptr
 
 
+PACCESS_TOKEN :: PVOID
+PSECURITY_DESCRIPTOR :: PVOID
+PSID :: PVOID
+PCLAIMS_BLOB :: PVOID
+
 PCONDITION_VARIABLE :: ^CONDITION_VARIABLE
 PCONDITION_VARIABLE :: ^CONDITION_VARIABLE
 PLARGE_INTEGER :: ^LARGE_INTEGER
 PLARGE_INTEGER :: ^LARGE_INTEGER
 PSRWLOCK :: ^SRWLOCK
 PSRWLOCK :: ^SRWLOCK
@@ -175,6 +182,7 @@ FILE_SHARE_DELETE: DWORD : 0x00000004
 FILE_GENERIC_ALL: DWORD : 0x10000000
 FILE_GENERIC_ALL: DWORD : 0x10000000
 FILE_GENERIC_EXECUTE: DWORD : 0x20000000
 FILE_GENERIC_EXECUTE: DWORD : 0x20000000
 FILE_GENERIC_READ: DWORD : 0x80000000
 FILE_GENERIC_READ: DWORD : 0x80000000
+FILE_ALL_ACCESS :: STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF
 
 
 FILE_ACTION_ADDED            :: 0x00000001
 FILE_ACTION_ADDED            :: 0x00000001
 FILE_ACTION_REMOVED          :: 0x00000002
 FILE_ACTION_REMOVED          :: 0x00000002
@@ -230,6 +238,20 @@ SECURITY_SQOS_PRESENT: DWORD : 0x00100000
 
 
 FIONBIO: c_ulong : 0x8004667e
 FIONBIO: c_ulong : 0x8004667e
 
 
+OWNER_SECURITY_INFORMATION               :: 0x00000001
+GROUP_SECURITY_INFORMATION               :: 0x00000002
+DACL_SECURITY_INFORMATION                :: 0x00000004
+SACL_SECURITY_INFORMATION                :: 0x00000008
+LABEL_SECURITY_INFORMATION               :: 0x00000010
+ATTRIBUTE_SECURITY_INFORMATION           :: 0x00000020
+SCOPE_SECURITY_INFORMATION               :: 0x00000040
+PROCESS_TRUST_LABEL_SECURITY_INFORMATION :: 0x00000080
+ACCESS_FILTER_SECURITY_INFORMATION       :: 0x00000100
+BACKUP_SECURITY_INFORMATION              :: 0x00010000
+PROTECTED_DACL_SECURITY_INFORMATION      :: 0x80000000
+PROTECTED_SACL_SECURITY_INFORMATION      :: 0x40000000
+UNPROTECTED_DACL_SECURITY_INFORMATION    :: 0x20000000
+UNPROTECTED_SACL_SECURITY_INFORMATION    :: 0x10000000
 
 
 GET_FILEEX_INFO_LEVELS :: distinct i32
 GET_FILEEX_INFO_LEVELS :: distinct i32
 GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0
 GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0
@@ -773,6 +795,30 @@ MSG :: struct {
 
 
 LPMSG :: ^MSG
 LPMSG :: ^MSG
 
 
+TEXTMETRICW :: struct {
+	tmHeight: LONG,
+	tmAscent: LONG,
+	tmDescent: LONG,
+	tmInternalLeading: LONG,
+	tmExternalLeading: LONG,
+	tmAveCharWidth: LONG,
+	tmMaxCharWidth: LONG,
+	tmWeight: LONG,
+	tmOverhang: LONG,
+	tmDigitizedAspectX: LONG,
+	tmDigitizedAspectY: LONG,
+	tmFirstChar: WCHAR,
+	tmLastChar: WCHAR,
+	tmDefaultChar: WCHAR,
+	tmBreakChar: WCHAR,
+	tmItalic: BYTE,
+	tmUnderlined: BYTE,
+	tmStruckOut: BYTE,
+	tmPitchAndFamily: BYTE,
+	tmCharSet: BYTE,
+}
+LPTEXTMETRICW :: ^TEXTMETRICW
+
 PAINTSTRUCT :: struct {
 PAINTSTRUCT :: struct {
 	hdc: HDC,
 	hdc: HDC,
 	fErase: BOOL,
 	fErase: BOOL,
@@ -879,6 +925,48 @@ NM_FONTCHANGED          :: NM_OUTOFMEMORY-22
 NM_CUSTOMTEXT           :: NM_OUTOFMEMORY-23 // uses NMCUSTOMTEXT struct
 NM_CUSTOMTEXT           :: NM_OUTOFMEMORY-23 // uses NMCUSTOMTEXT struct
 NM_TVSTATEIMAGECHANGING :: NM_OUTOFMEMORY-23 // uses NMTVSTATEIMAGECHANGING struct, defined after HTREEITEM
 NM_TVSTATEIMAGECHANGING :: NM_OUTOFMEMORY-23 // uses NMTVSTATEIMAGECHANGING struct, defined after HTREEITEM
 
 
+PCZZWSTR :: ^WCHAR
+
+SHFILEOPSTRUCTW :: struct {
+	hwnd: HWND,
+	wFunc: UINT,
+	pFrom: PCZZWSTR,
+	pTo: PCZZWSTR,
+	fFlags: FILEOP_FLAGS,
+	fAnyOperationsAborted: BOOL,
+	hNameMappings: LPVOID,
+	lpszProgressTitle: PCWSTR, // only used if FOF_SIMPLEPROGRESS
+}
+LPSHFILEOPSTRUCTW :: ^SHFILEOPSTRUCTW
+
+// Shell File Operations
+FO_MOVE   :: 0x0001
+FO_COPY   :: 0x0002
+FO_DELETE :: 0x0003
+FO_RENAME :: 0x0004
+
+// SHFILEOPSTRUCT.fFlags and IFileOperation::SetOperationFlags() flag values
+FOF_MULTIDESTFILES        :: 0x0001
+FOF_CONFIRMMOUSE          :: 0x0002
+FOF_SILENT                :: 0x0004  // don't display progress UI (confirm prompts may be displayed still)
+FOF_RENAMEONCOLLISION     :: 0x0008  // automatically rename the source files to avoid the collisions
+FOF_NOCONFIRMATION        :: 0x0010  // don't display confirmation UI, assume "yes" for cases that can be bypassed, "no" for those that can not
+FOF_WANTMAPPINGHANDLE     :: 0x0020  // Fill in SHFILEOPSTRUCT.hNameMappings
+                                     // Must be freed using SHFreeNameMappings
+FOF_ALLOWUNDO             :: 0x0040  // enable undo including Recycle behavior for IFileOperation::Delete()
+FOF_FILESONLY             :: 0x0080  // only operate on the files (non folders), both files and folders are assumed without this
+FOF_SIMPLEPROGRESS        :: 0x0100  // means don't show names of files
+FOF_NOCONFIRMMKDIR        :: 0x0200  // don't dispplay confirmatino UI before making any needed directories, assume "Yes" in these cases
+FOF_NOERRORUI             :: 0x0400  // don't put up error UI, other UI may be displayed, progress, confirmations
+FOF_NOCOPYSECURITYATTRIBS :: 0x0800  // dont copy file security attributes (ACLs)
+FOF_NORECURSION           :: 0x1000  // don't recurse into directories for operations that would recurse
+FOF_NO_CONNECTED_ELEMENTS :: 0x2000  // don't operate on connected elements ("xxx_files" folders that go with .htm files)
+FOF_WANTNUKEWARNING       :: 0x4000  // during delete operation, warn if object is being permanently destroyed instead of recycling (partially overrides FOF_NOCONFIRMATION)
+FOF_NORECURSEREPARSE      :: 0x8000  // deprecated; the operations engine always does the right thing on FolderLink objects (symlinks, reparse points, folder shortcuts)
+FOF_NO_UI                 :: (FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR) // don't display any UI at all
+
+FILEOP_FLAGS :: WORD
+
 DEVMODEW :: struct {
 DEVMODEW :: struct {
 	dmDeviceName:   [32]wchar_t,
 	dmDeviceName:   [32]wchar_t,
 	dmSpecVersion:   WORD,
 	dmSpecVersion:   WORD,
@@ -1066,8 +1154,14 @@ WS_EX_TOPMOST               : UINT : 0x0000_0008
 WS_EX_TRANSPARENT           : UINT : 0x0000_0020
 WS_EX_TRANSPARENT           : UINT : 0x0000_0020
 WS_EX_WINDOWEDGE            : UINT : 0x0000_0100
 WS_EX_WINDOWEDGE            : UINT : 0x0000_0100
 
 
-PBS_SMOOTH   :: 0x01
-PBS_VERTICAL :: 0x04
+PBS_SMOOTH        :: 0x01
+PBS_VERTICAL      :: 0x04
+PBS_MARQUEE       :: 0x08
+PBS_SMOOTHREVERSE :: 0x10
+
+PBST_NORMAL :: 0x0001
+PBST_ERROR  :: 0x0002
+PBST_PAUSED :: 0x0003
 
 
 QS_ALLEVENTS      : UINT : QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY
 QS_ALLEVENTS      : UINT : QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY
 QS_ALLINPUT       : UINT : QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE
 QS_ALLINPUT       : UINT : QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE
@@ -1462,6 +1556,24 @@ IDI_WARNING      := IDI_EXCLAMATION
 IDI_ERROR        := IDI_HAND
 IDI_ERROR        := IDI_HAND
 IDI_INFORMATION  := IDI_ASTERISK
 IDI_INFORMATION  := IDI_ASTERISK
 
 
+IMAGE_BITMAP      :: 0
+IMAGE_ICON        :: 1
+IMAGE_CURSOR      :: 2
+IMAGE_ENHMETAFILE :: 3
+
+LR_DEFAULTCOLOR     :: 0x00000000
+LR_MONOCHROME       :: 0x00000001
+LR_COLOR            :: 0x00000002
+LR_COPYRETURNORG    :: 0x00000004
+LR_COPYDELETEORG    :: 0x00000008
+LR_LOADFROMFILE     :: 0x00000010
+LR_LOADTRANSPARENT  :: 0x00000020
+LR_DEFAULTSIZE      :: 0x00000040
+LR_VGACOLOR         :: 0x00000080
+LR_LOADMAP3DCOLORS  :: 0x00001000
+LR_CREATEDIBSECTION :: 0x00002000
+LR_COPYFROMRESOURCE :: 0x00004000
+LR_SHARED           :: 0x00008000
 
 
 // DIB color table identifiers
 // DIB color table identifiers
 DIB_RGB_COLORS :: 0
 DIB_RGB_COLORS :: 0
@@ -1662,6 +1774,7 @@ WSAENOTCONN: c_int : 10057
 WSAESHUTDOWN: c_int : 10058
 WSAESHUTDOWN: c_int : 10058
 WSAETIMEDOUT: c_int : 10060
 WSAETIMEDOUT: c_int : 10060
 WSAECONNREFUSED: c_int : 10061
 WSAECONNREFUSED: c_int : 10061
+WSATRY_AGAIN: c_int : 11002
 
 
 MAX_PROTOCOL_CHAIN: DWORD : 7
 MAX_PROTOCOL_CHAIN: DWORD : 7
 
 
@@ -1773,12 +1886,15 @@ WAIT_FAILED: DWORD : 0xFFFFFFFF
 
 
 PIPE_ACCESS_INBOUND: DWORD : 0x00000001
 PIPE_ACCESS_INBOUND: DWORD : 0x00000001
 PIPE_ACCESS_OUTBOUND: DWORD : 0x00000002
 PIPE_ACCESS_OUTBOUND: DWORD : 0x00000002
+PIPE_ACCESS_DUPLEX: DWORD : 0x00000003
 FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD : 0x00080000
 FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD : 0x00080000
 FILE_FLAG_OVERLAPPED: DWORD : 0x40000000
 FILE_FLAG_OVERLAPPED: DWORD : 0x40000000
 PIPE_WAIT: DWORD : 0x00000000
 PIPE_WAIT: DWORD : 0x00000000
 PIPE_TYPE_BYTE: DWORD : 0x00000000
 PIPE_TYPE_BYTE: DWORD : 0x00000000
+PIPE_TYPE_MESSAGE: DWORD : 0x00000004
 PIPE_REJECT_REMOTE_CLIENTS: DWORD : 0x00000008
 PIPE_REJECT_REMOTE_CLIENTS: DWORD : 0x00000008
 PIPE_READMODE_BYTE: DWORD : 0x00000000
 PIPE_READMODE_BYTE: DWORD : 0x00000000
+PIPE_READMODE_MESSAGE: DWORD : 0x00000002
 PIPE_ACCEPT_REMOTE_CLIENTS: DWORD : 0x00000000
 PIPE_ACCEPT_REMOTE_CLIENTS: DWORD : 0x00000000
 
 
 FD_SETSIZE :: 64
 FD_SETSIZE :: 64
@@ -1792,7 +1908,58 @@ HEAP_ZERO_MEMORY: DWORD : 0x00000008
 HANDLE_FLAG_INHERIT: DWORD : 0x00000001
 HANDLE_FLAG_INHERIT: DWORD : 0x00000001
 HANDLE_FLAG_PROTECT_FROM_CLOSE :: 0x00000002
 HANDLE_FLAG_PROTECT_FROM_CLOSE :: 0x00000002
 
 
-TOKEN_READ: DWORD : 0x20008
+GENERIC_MAPPING :: struct {
+	GenericRead: ACCESS_MASK,
+	GenericWrite: ACCESS_MASK,
+	GenericExecute: ACCESS_MASK,
+	GenericAll: ACCESS_MASK,
+}
+PGENERIC_MAPPING :: ^GENERIC_MAPPING
+
+SECURITY_IMPERSONATION_LEVEL :: enum {
+	SecurityAnonymous,
+	SecurityIdentification,
+	SecurityImpersonation,
+	SecurityDelegation,
+}
+
+SECURITY_INFORMATION :: DWORD
+ANYSIZE_ARRAY :: 1
+
+LUID_AND_ATTRIBUTES :: struct {
+	Luid: LUID,
+	Attributes: DWORD,
+}
+
+PRIVILEGE_SET :: struct {
+	PrivilegeCount: DWORD,
+	Control: DWORD,
+	Privilege: [ANYSIZE_ARRAY]LUID_AND_ATTRIBUTES,
+}
+PPRIVILEGE_SET :: ^PRIVILEGE_SET
+
+// Token Specific Access Rights.
+TOKEN_ASSIGN_PRIMARY    :: 0x0001
+TOKEN_DUPLICATE         :: 0x0002
+TOKEN_IMPERSONATE       :: 0x0004
+TOKEN_QUERY             :: 0x0008
+TOKEN_QUERY_SOURCE      :: 0x0010
+TOKEN_ADJUST_PRIVILEGES :: 0x0020
+TOKEN_ADJUST_GROUPS     :: 0x0040
+TOKEN_ADJUST_DEFAULT    :: 0x0080
+TOKEN_ADJUST_SESSIONID  :: 0x0100
+
+TOKEN_ALL_ACCESS_P :: STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY |\
+	TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT
+
+TOKEN_ALL_ACCESS                :: TOKEN_ALL_ACCESS_P | TOKEN_ADJUST_SESSIONID
+TOKEN_READ                      :: STANDARD_RIGHTS_READ | TOKEN_QUERY
+TOKEN_WRITE                     :: STANDARD_RIGHTS_WRITE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT
+TOKEN_EXECUTE                   :: STANDARD_RIGHTS_EXECUTE
+TOKEN_TRUST_CONSTRAINT_MASK     :: STANDARD_RIGHTS_READ | TOKEN_QUERY | TOKEN_QUERY_SOURCE
+TOKEN_ACCESS_PSEUDO_HANDLE_WIN8 :: TOKEN_QUERY | TOKEN_QUERY_SOURCE
+TOKEN_ACCESS_PSEUDO_HANDLE      :: TOKEN_ACCESS_PSEUDO_HANDLE_WIN8
+
 
 
 CP_ACP        :: 0     // default to ANSI code page
 CP_ACP        :: 0     // default to ANSI code page
 CP_OEMCP      :: 1     // default to OEM  code page
 CP_OEMCP      :: 1     // default to OEM  code page
@@ -2100,9 +2267,10 @@ FILETIME :: struct {
 
 
 FILETIME_as_unix_nanoseconds :: proc "contextless" (ft: FILETIME) -> i64 {
 FILETIME_as_unix_nanoseconds :: proc "contextless" (ft: FILETIME) -> i64 {
 	t := i64(u64(ft.dwLowDateTime) | u64(ft.dwHighDateTime) << 32)
 	t := i64(u64(ft.dwLowDateTime) | u64(ft.dwHighDateTime) << 32)
-	return (t - 0x019db1ded53e8000) * 100
+	return (t - 116444736000000000) * 100
 }
 }
 
 
+
 OVERLAPPED :: struct {
 OVERLAPPED :: struct {
 	Internal: ^c_ulong,
 	Internal: ^c_ulong,
 	InternalHigh: ^c_ulong,
 	InternalHigh: ^c_ulong,
@@ -2776,6 +2944,16 @@ SYSTEMTIME :: struct {
 	milliseconds: WORD,
 	milliseconds: WORD,
 }
 }
 
 
+TIME_ZONE_INFORMATION :: struct {
+	Bias:         LONG,
+	StandardName: [32]WCHAR,
+	StandardDate: SYSTEMTIME,
+	StandardBias: LONG,
+	DaylightName: [32]WCHAR,
+	DaylightDate: SYSTEMTIME,
+	DaylightBias: LONG,
+}
+
 
 
 @(private="file")
 @(private="file")
 IMAGE_DOS_HEADER :: struct {
 IMAGE_DOS_HEADER :: struct {
@@ -3047,12 +3225,32 @@ SHCONTF_FLATLIST              :: 0x4000
 SHCONTF_ENABLE_ASYNC          :: 0x8000
 SHCONTF_ENABLE_ASYNC          :: 0x8000
 SHCONTF_INCLUDESUPERHIDDEN    :: 0x10000
 SHCONTF_INCLUDESUPERHIDDEN    :: 0x10000
 
 
+SHACF_DEFAULT               :: 0x00000000  // Currently (SHACF_FILESYSTEM | SHACF_URLALL)
+SHACF_FILESYSTEM            :: 0x00000001  // This includes the File System as well as the rest of the shell (Desktop\My Computer\Control Panel\)
+SHACF_URLALL                :: (SHACF_URLHISTORY | SHACF_URLMRU)
+SHACF_URLHISTORY            :: 0x00000002  // URLs in the User's History
+SHACF_URLMRU                :: 0x00000004  // URLs in the User's Recently Used list.
+SHACF_USETAB                :: 0x00000008  // Use the tab to move thru the autocomplete possibilities instead of to the next dialog/window control.
+SHACF_FILESYS_ONLY          :: 0x00000010  // This includes the File System
+SHACF_FILESYS_DIRS          :: 0x00000020  // Same as SHACF_FILESYS_ONLY except it only includes directories, UNC servers, and UNC server shares.
+SHACF_VIRTUAL_NAMESPACE     :: 0x00000040  // Also include the virtual namespace
+SHACF_AUTOSUGGEST_FORCE_ON  :: 0x10000000  // Ignore the registry default and force the feature on.
+SHACF_AUTOSUGGEST_FORCE_OFF :: 0x20000000  // Ignore the registry default and force the feature off.
+SHACF_AUTOAPPEND_FORCE_ON   :: 0x40000000  // Ignore the registry default and force the feature on. (Also know as AutoComplete)
+SHACF_AUTOAPPEND_FORCE_OFF  :: 0x80000000  // Ignore the registry default and force the feature off. (Also know as AutoComplete)
+
+LWSTDAPI :: HRESULT
+
 CLSID_FileOpenDialog := &GUID{0xDC1C5A9C, 0xE88A, 0x4DDE, {0xA5, 0xA1, 0x60, 0xF8, 0x2A, 0x20, 0xAE, 0xF7}}
 CLSID_FileOpenDialog := &GUID{0xDC1C5A9C, 0xE88A, 0x4DDE, {0xA5, 0xA1, 0x60, 0xF8, 0x2A, 0x20, 0xAE, 0xF7}}
 CLSID_FileSaveDialog := &GUID{0xC0B4E2F3, 0xBA21, 0x4773, {0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B}}
 CLSID_FileSaveDialog := &GUID{0xC0B4E2F3, 0xBA21, 0x4773, {0x8D, 0xBA, 0x33, 0x5E, 0xC9, 0x46, 0xEB, 0x8B}}
+CLSID_TaskbarList := &GUID{0x56FDF344, 0xFD6D, 0x11d0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}
 
 
 IID_IFileDialog := &GUID{0x42F85136, 0xDB7E, 0x439C, {0x85, 0xF1, 0xE4, 0x07, 0x5D, 0x13, 0x5F, 0xC8}}
 IID_IFileDialog := &GUID{0x42F85136, 0xDB7E, 0x439C, {0x85, 0xF1, 0xE4, 0x07, 0x5D, 0x13, 0x5F, 0xC8}}
 IID_IFileSaveDialog := &GUID{0x84BCCD23, 0x5FDE, 0x4CDB, {0xAE, 0xA4, 0xAF, 0x64, 0xB8, 0x3D, 0x78, 0xAB}}
 IID_IFileSaveDialog := &GUID{0x84BCCD23, 0x5FDE, 0x4CDB, {0xAE, 0xA4, 0xAF, 0x64, 0xB8, 0x3D, 0x78, 0xAB}}
 IID_IFileOpenDialog := &GUID{0xD57C7288, 0xD4AD, 0x4768, {0xBE, 0x02, 0x9D, 0x96, 0x95, 0x32, 0xD9, 0x60}}
 IID_IFileOpenDialog := &GUID{0xD57C7288, 0xD4AD, 0x4768, {0xBE, 0x02, 0x9D, 0x96, 0x95, 0x32, 0xD9, 0x60}}
+IID_ITaskbarList := &GUID{0x56FDF342, 0xFD6D, 0x11d0, {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}}
+IID_ITaskbarList2 := &GUID{0x602D4995, 0xB13A, 0x429b, {0xA6, 0x6E, 0x19, 0x35, 0xE4, 0x4F, 0x43, 0x17}}
+IID_ITaskbarList3 := &GUID{0xea1afb91, 0x9e28, 0x4b86, {0x90, 0xe9, 0x9e, 0x9f, 0x8a, 0x5e, 0xef, 0xaf}}
 
 
 IModalWindow :: struct #raw_union {
 IModalWindow :: struct #raw_union {
 	#subtype IUnknown: IUnknown,
 	#subtype IUnknown: IUnknown,
@@ -3357,6 +3555,84 @@ IFileSaveDialogVtbl :: struct {
 	ApplyProperties:        proc "stdcall" (this: ^IFileSaveDialog, psi: ^IShellItem, pStore: ^IPropertyStore, hwnd: HWND, pSink: ^IFileOperationProgressSink) -> HRESULT,
 	ApplyProperties:        proc "stdcall" (this: ^IFileSaveDialog, psi: ^IShellItem, pStore: ^IPropertyStore, hwnd: HWND, pSink: ^IFileOperationProgressSink) -> HRESULT,
 }
 }
 
 
+ITaskbarList :: struct #raw_union {
+	#subtype IUnknown: IUnknown,
+	using Vtbl: ^ITaskbarListVtbl,
+}
+ITaskbarListVtbl :: struct {
+	using IUnknownVtbl: IUnknownVtbl,
+	HrInit: proc "stdcall" (this: ^ITaskbarList) -> HRESULT,
+	AddTab: proc "stdcall" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
+	DeleteTab: proc "stdcall" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
+	ActivateTab: proc "stdcall" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
+	SetActiveAlt: proc "stdcall" (this: ^ITaskbarList, hwnd: HWND) -> HRESULT,
+}
+
+ITaskbarList2 :: struct #raw_union {
+	#subtype ITaskbarList: ITaskbarList,
+	using Vtbl: ^ITaskbarList2Vtbl,
+}
+ITaskbarList2Vtbl :: struct {
+	using ITaskbarListVtbl: ITaskbarListVtbl,
+	MarkFullscreenWindow: proc "stdcall" (this: ^ITaskbarList2, hwnd: HWND, fFullscreen: BOOL) -> HRESULT,
+}
+
+TBPFLAG :: enum c_int {
+	NOPROGRESS    = 0,
+	INDETERMINATE = 0x1,
+	NORMAL        = 0x2,
+	ERROR         = 0x4,
+	PAUSED        = 0x8,
+}
+
+THUMBBUTTONFLAGS :: enum c_int {
+	ENABLED        = 0,
+	DISABLED       = 0x1,
+	DISMISSONCLICK = 0x2,
+	NOBACKGROUND   = 0x4,
+	HIDDEN         = 0x8,
+	NONINTERACTIVE = 0x10,
+}
+
+THUMBBUTTONMASK :: enum c_int {
+	BITMAP  = 0x1,
+	ICON    = 0x2,
+	TOOLTIP = 0x4,
+	FLAGS   = 0x8,
+}
+
+THUMBBUTTON :: struct {
+	dwMask: THUMBBUTTONMASK,
+	iId: UINT,
+	iBitmap: UINT,
+	hIcon: HICON,
+	szTip: [260]WCHAR,
+	dwFlags: THUMBBUTTONFLAGS,
+}
+LPTHUMBBUTTON :: ^THUMBBUTTON
+
+HIMAGELIST :: ^IUnknown
+
+ITaskbarList3 :: struct #raw_union {
+	#subtype ITaskbarList2: ITaskbarList2,
+	using Vtbl: ^ITaskbarList3Vtbl,
+}
+ITaskbarList3Vtbl :: struct {
+	using ITaskbarList2Vtbl: ITaskbarList2Vtbl,
+	SetProgressValue: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, ullCompleted: ULONGLONG, ullTotal: ULONGLONG) -> HRESULT,
+	SetProgressState: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, tbpFlags: TBPFLAG) -> HRESULT,
+	RegisterTab: proc "stdcall" (this: ^ITaskbarList3, hwndTab: HWND, hwndMDI: HWND) -> HRESULT,
+	UnregisterTab: proc "stdcall" (this: ^ITaskbarList3, hwndTab: HWND) -> HRESULT,
+	SetTabOrder: proc "stdcall" (this: ^ITaskbarList3, hwndTab: HWND, hwndInsertBefore: HWND) -> HRESULT,
+	SetTabActive: proc "stdcall" (this: ^ITaskbarList3, hwndTab: HWND, hwndMDI: HWND, dwReserved: DWORD) -> HRESULT,
+	ThumbBarAddButtons: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, cButtons: UINT, pButton: LPTHUMBBUTTON) -> HRESULT,
+	ThumbBarUpdateButtons: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, cButtons: UINT, pButton: LPTHUMBBUTTON) -> HRESULT,
+	ThumbBarSetImageList: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, himl: HIMAGELIST) -> HRESULT,
+	SetOverlayIcon: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, hIcon: HICON, pszDescription: LPCWSTR) -> HRESULT,
+	SetThumbnailTooltip: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, pszTip: LPCWSTR) -> HRESULT,
+	SetThumbnailClip: proc "stdcall" (this: ^ITaskbarList3, hwnd: HWND, prcClip: ^RECT) -> HRESULT,
+}
+
 MEMORYSTATUSEX :: struct {
 MEMORYSTATUSEX :: struct {
 	dwLength:                DWORD,
 	dwLength:                DWORD,
 	dwMemoryLoad:            DWORD,
 	dwMemoryLoad:            DWORD,

+ 4 - 0
core/sys/windows/user32.odin

@@ -78,6 +78,7 @@ foreign user32 {
 	LoadIconW :: proc(hInstance: HINSTANCE, lpIconName: LPCWSTR) -> HICON ---
 	LoadIconW :: proc(hInstance: HINSTANCE, lpIconName: LPCWSTR) -> HICON ---
 	LoadCursorA :: proc(hInstance: HINSTANCE, lpCursorName: LPCSTR) -> HCURSOR ---
 	LoadCursorA :: proc(hInstance: HINSTANCE, lpCursorName: LPCSTR) -> HCURSOR ---
 	LoadCursorW :: proc(hInstance: HINSTANCE, lpCursorName: LPCWSTR) -> HCURSOR ---
 	LoadCursorW :: proc(hInstance: HINSTANCE, lpCursorName: LPCWSTR) -> HCURSOR ---
+	LoadImageW :: proc(hInst: HINSTANCE, name: LPCWSTR, type: UINT, cx: c_int, cy: c_int, fuLoad: UINT) -> HANDLE ---
 
 
 	GetWindowRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL ---
 	GetWindowRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL ---
 	GetClientRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL ---
 	GetClientRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL ---
@@ -104,6 +105,9 @@ foreign user32 {
 	GetDC :: proc(hWnd: HWND) -> HDC ---
 	GetDC :: proc(hWnd: HWND) -> HDC ---
 	ReleaseDC :: proc(hWnd: HWND, hDC: HDC) -> c_int ---
 	ReleaseDC :: proc(hWnd: HWND, hDC: HDC) -> c_int ---
 
 
+	GetDlgCtrlID :: proc(hWnd: HWND) -> c_int ---
+	GetDlgItem :: proc(hDlg: HWND, nIDDlgItem: c_int) -> HWND ---
+
 	GetUpdateRect :: proc(hWnd: HWND, lpRect: LPRECT, bErase: BOOL) -> BOOL ---
 	GetUpdateRect :: proc(hWnd: HWND, lpRect: LPRECT, bErase: BOOL) -> BOOL ---
 	ValidateRect :: proc(hWnd: HWND, lpRect: ^RECT) -> BOOL ---
 	ValidateRect :: proc(hWnd: HWND, lpRect: ^RECT) -> BOOL ---
 	InvalidateRect :: proc(hWnd: HWND, lpRect: ^RECT, bErase: BOOL) -> BOOL ---
 	InvalidateRect :: proc(hWnd: HWND, lpRect: ^RECT, bErase: BOOL) -> BOOL ---

+ 4 - 4
core/sys/windows/util.odin

@@ -62,19 +62,19 @@ utf8_to_wstring :: proc(s: string, allocator := context.temp_allocator) -> wstri
 wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> (res: string, err: runtime.Allocator_Error) {
 wstring_to_utf8 :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> (res: string, err: runtime.Allocator_Error) {
 	context.allocator = allocator
 	context.allocator = allocator
 
 
-	if N <= 0 {
+	if N == 0 {
 		return
 		return
 	}
 	}
 
 
-	n := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N), nil, 0, nil, nil)
+	n := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, i32(N) if N > 0 else -1, nil, 0, nil, nil)
 	if n == 0 {
 	if n == 0 {
 		return
 		return
 	}
 	}
 
 
-	// If N == -1 the call to WideCharToMultiByte assume the wide string is null terminated
+	// If N < 0 the call to WideCharToMultiByte assume the wide string is null terminated
 	// and will scan it to find the first null terminated character. The resulting string will
 	// and will scan it to find the first null terminated character. The resulting string will
 	// also be null terminated.
 	// also be null terminated.
-	// If N != -1 it assumes the wide string is not null terminated and the resulting string
+	// If N > 0 it assumes the wide string is not null terminated and the resulting string
 	// will not be null terminated.
 	// will not be null terminated.
 	text := make([]byte, n) or_return
 	text := make([]byte, n) or_return
 
 

+ 1095 - 1084
core/sys/windows/window_messages.odin

@@ -1,1088 +1,1099 @@
 // +build windows
 // +build windows
 package sys_windows
 package sys_windows
 
 
-WM_NULL                       :: 0x0000
-WM_CREATE                     :: 0x0001
-WM_DESTROY                    :: 0x0002
-WM_MOVE                       :: 0x0003
-WM_SIZE                       :: 0x0005
-WM_ACTIVATE                   :: 0x0006
-WM_SETFOCUS                   :: 0x0007
-WM_KILLFOCUS                  :: 0x0008
-WM_ENABLE                     :: 0x000a
-WM_SETREDRAW                  :: 0x000b
-WM_SETTEXT                    :: 0x000c
-WM_GETTEXT                    :: 0x000d
-WM_GETTEXTLENGTH              :: 0x000e
-WM_PAINT                      :: 0x000f
-WM_CLOSE                      :: 0x0010
-WM_QUERYENDSESSION            :: 0x0011
-WM_QUIT                       :: 0x0012
-WM_QUERYOPEN                  :: 0x0013
-WM_ERASEBKGND                 :: 0x0014
-WM_SYSCOLORCHANGE             :: 0x0015
-WM_ENDSESSION                 :: 0x0016
-WM_SHOWWINDOW                 :: 0x0018
-WM_CTLCOLOR                   :: 0x0019
-WM_WININICHANGE               :: 0x001a
-WM_SETTINGCHANGE              :: WM_WININICHANGE
-WM_DEVMODECHANGE              :: 0x001b
-WM_ACTIVATEAPP                :: 0x001c
-WM_FONTCHANGE                 :: 0x001d
-WM_TIMECHANGE                 :: 0x001e
-WM_CANCELMODE                 :: 0x001f
-WM_SETCURSOR                  :: 0x0020
-WM_MOUSEACTIVATE              :: 0x0021
-WM_CHILDACTIVATE              :: 0x0022
-WM_QUEUESYNC                  :: 0x0023
-WM_GETMINMAXINFO              :: 0x0024
-WM_PAINTICON                  :: 0x0026
-WM_ICONERASEBKGND             :: 0x0027
-WM_NEXTDLGCTL                 :: 0x0028
-WM_SPOOLERSTATUS              :: 0x002a
-WM_DRAWITEM                   :: 0x002b
-WM_MEASUREITEM                :: 0x002c
-WM_DELETEITEM                 :: 0x002d
-WM_VKEYTOITEM                 :: 0x002e
-WM_CHARTOITEM                 :: 0x002f
-WM_SETFONT                    :: 0x0030
-WM_GETFONT                    :: 0x0031
-WM_SETHOTKEY                  :: 0x0032
-WM_GETHOTKEY                  :: 0x0033
-WM_QUERYDRAGICON              :: 0x0037
-WM_COMPAREITEM                :: 0x0039
-WM_GETOBJECT                  :: 0x003d
-WM_COMPACTING                 :: 0x0041
-WM_COMMNOTIFY                 :: 0x0044
-WM_WINDOWPOSCHANGING          :: 0x0046
-WM_WINDOWPOSCHANGED           :: 0x0047
-WM_POWER                      :: 0x0048
-WM_COPYGLOBALDATA             :: 0x0049
-WM_COPYDATA                   :: 0x004a
-WM_CANCELJOURNAL              :: 0x004b
-WM_NOTIFY                     :: 0x004e
-WM_INPUTLANGCHANGEREQUEST     :: 0x0050
-WM_INPUTLANGCHANGE            :: 0x0051
-WM_TCARD                      :: 0x0052
-WM_HELP                       :: 0x0053
-WM_USERCHANGED                :: 0x0054
-WM_NOTIFYFORMAT               :: 0x0055
-WM_CONTEXTMENU                :: 0x007b
-WM_STYLECHANGING              :: 0x007c
-WM_STYLECHANGED               :: 0x007d
-WM_DISPLAYCHANGE              :: 0x007e
-WM_GETICON                    :: 0x007f
-WM_SETICON                    :: 0x0080
-WM_NCCREATE                   :: 0x0081
-WM_NCDESTROY                  :: 0x0082
-WM_NCCALCSIZE                 :: 0x0083
-WM_NCHITTEST                  :: 0x0084
-WM_NCPAINT                    :: 0x0085
-WM_NCACTIVATE                 :: 0x0086
-WM_GETDLGCODE                 :: 0x0087
-WM_SYNCPAINT                  :: 0x0088
-WM_NCMOUSEMOVE                :: 0x00a0
-WM_NCLBUTTONDOWN              :: 0x00a1
-WM_NCLBUTTONUP                :: 0x00a2
-WM_NCLBUTTONDBLCLK            :: 0x00a3
-WM_NCRBUTTONDOWN              :: 0x00a4
-WM_NCRBUTTONUP                :: 0x00a5
-WM_NCRBUTTONDBLCLK            :: 0x00a6
-WM_NCMBUTTONDOWN              :: 0x00a7
-WM_NCMBUTTONUP                :: 0x00a8
-WM_NCMBUTTONDBLCLK            :: 0x00a9
-WM_NCXBUTTONDOWN              :: 0x00ab
-WM_NCXBUTTONUP                :: 0x00ac
-WM_NCXBUTTONDBLCLK            :: 0x00ad
-EM_GETSEL                     :: 0x00b0
-EM_SETSEL                     :: 0x00b1
-EM_GETRECT                    :: 0x00b2
-EM_SETRECT                    :: 0x00b3
-EM_SETRECTNP                  :: 0x00b4
-EM_SCROLL                     :: 0x00b5
-EM_LINESCROLL                 :: 0x00b6
-EM_SCROLLCARET                :: 0x00b7
-EM_GETMODIFY                  :: 0x00b8
-EM_SETMODIFY                  :: 0x00b9
-EM_GETLINECOUNT               :: 0x00ba
-EM_LINEINDEX                  :: 0x00bb
-EM_SETHANDLE                  :: 0x00bc
-EM_GETHANDLE                  :: 0x00bd
-EM_GETTHUMB                   :: 0x00be
-EM_LINELENGTH                 :: 0x00c1
-EM_REPLACESEL                 :: 0x00c2
-EM_SETFONT                    :: 0x00c3
-EM_GETLINE                    :: 0x00c4
-EM_LIMITTEXT                  :: 0x00c5
-EM_SETLIMITTEXT               :: 0x00c5
-EM_CANUNDO                    :: 0x00c6
-EM_UNDO                       :: 0x00c7
-EM_FMTLINES                   :: 0x00c8
-EM_LINEFROMCHAR               :: 0x00c9
-EM_SETWORDBREAK               :: 0x00ca
-EM_SETTABSTOPS                :: 0x00cb
-EM_SETPASSWORDCHAR            :: 0x00cc
-EM_EMPTYUNDOBUFFER            :: 0x00cd
-EM_GETFIRSTVISIBLELINE        :: 0x00ce
-EM_SETREADONLY                :: 0x00cf
-EM_SETWORDBREAKPROC           :: 0x00d0
-EM_GETWORDBREAKPROC           :: 0x00d1
-EM_GETPASSWORDCHAR            :: 0x00d2
-EM_SETMARGINS                 :: 0x00d3
-EM_GETMARGINS                 :: 0x00d4
-EM_GETLIMITTEXT               :: 0x00d5
-EM_POSFROMCHAR                :: 0x00d6
-EM_CHARFROMPOS                :: 0x00d7
-EM_SETIMESTATUS               :: 0x00d8
-EM_GETIMESTATUS               :: 0x00d9
-SBM_SETPOS                    :: 0x00e0
-SBM_GETPOS                    :: 0x00e1
-SBM_SETRANGE                  :: 0x00e2
-SBM_GETRANGE                  :: 0x00e3
-SBM_ENABLE_ARROWS             :: 0x00e4
-SBM_SETRANGEREDRAW            :: 0x00e6
-SBM_SETSCROLLINFO             :: 0x00e9
-SBM_GETSCROLLINFO             :: 0x00ea
-SBM_GETSCROLLBARINFO          :: 0x00eb
-BM_GETCHECK                   :: 0x00f0
-BM_SETCHECK                   :: 0x00f1
-BM_GETSTATE                   :: 0x00f2
-BM_SETSTATE                   :: 0x00f3
-BM_SETSTYLE                   :: 0x00f4
-BM_CLICK                      :: 0x00f5
-BM_GETIMAGE                   :: 0x00f6
-BM_SETIMAGE                   :: 0x00f7
-BM_SETDONTCLICK               :: 0x00f8
-WM_INPUT_DEVICE_CHANGE        :: 0x00fe
-WM_INPUT                      :: 0x00ff
-WM_KEYDOWN                    :: 0x0100
-WM_KEYFIRST                   :: 0x0100
-WM_KEYUP                      :: 0x0101
-WM_CHAR                       :: 0x0102
-WM_DEADCHAR                   :: 0x0103
-WM_SYSKEYDOWN                 :: 0x0104
-WM_SYSKEYUP                   :: 0x0105
-WM_SYSCHAR                    :: 0x0106
-WM_SYSDEADCHAR                :: 0x0107
-WM_UNICHAR                    :: 0x0109
-WM_KEYLAST                    :: 0x0109
-UNICODE_NOCHAR                :: 0xFFFF
-WM_WNT_CONVERTREQUESTEX       :: 0x0109
-WM_CONVERTREQUEST             :: 0x010a
-WM_CONVERTRESULT              :: 0x010b
-WM_INTERIM                    :: 0x010c
-WM_IME_STARTCOMPOSITION       :: 0x010d
-WM_IME_ENDCOMPOSITION         :: 0x010e
-WM_IME_COMPOSITION            :: 0x010f
-WM_IME_KEYLAST                :: 0x010f
-WM_INITDIALOG                 :: 0x0110
-WM_COMMAND                    :: 0x0111
-WM_SYSCOMMAND                 :: 0x0112
-WM_TIMER                      :: 0x0113
-WM_HSCROLL                    :: 0x0114
-WM_VSCROLL                    :: 0x0115
-WM_INITMENU                   :: 0x0116
-WM_INITMENUPOPUP              :: 0x0117
-WM_SYSTIMER                   :: 0x0118
-WM_MENUSELECT                 :: 0x011f
-WM_MENUCHAR                   :: 0x0120
-WM_ENTERIDLE                  :: 0x0121
-WM_MENURBUTTONUP              :: 0x0122
-WM_MENUDRAG                   :: 0x0123
-WM_MENUGETOBJECT              :: 0x0124
-WM_UNINITMENUPOPUP            :: 0x0125
-WM_MENUCOMMAND                :: 0x0126
-WM_CHANGEUISTATE              :: 0x0127
-WM_UPDATEUISTATE              :: 0x0128
-WM_QUERYUISTATE               :: 0x0129
-WM_LBTRACKPOINT               :: 0x0131
-WM_CTLCOLORMSGBOX             :: 0x0132
-WM_CTLCOLOREDIT               :: 0x0133
-WM_CTLCOLORLISTBOX            :: 0x0134
-WM_CTLCOLORBTN                :: 0x0135
-WM_CTLCOLORDLG                :: 0x0136
-WM_CTLCOLORSCROLLBAR          :: 0x0137
-WM_CTLCOLORSTATIC             :: 0x0138
-CB_GETEDITSEL                 :: 0x0140
-CB_LIMITTEXT                  :: 0x0141
-CB_SETEDITSEL                 :: 0x0142
-CB_ADDSTRING                  :: 0x0143
-CB_DELETESTRING               :: 0x0144
-CB_DIR                        :: 0x0145
-CB_GETCOUNT                   :: 0x0146
-CB_GETCURSEL                  :: 0x0147
-CB_GETLBTEXT                  :: 0x0148
-CB_GETLBTEXTLEN               :: 0x0149
-CB_INSERTSTRING               :: 0x014a
-CB_RESETCONTENT               :: 0x014b
-CB_FINDSTRING                 :: 0x014c
-CB_SELECTSTRING               :: 0x014d
-CB_SETCURSEL                  :: 0x014e
-CB_SHOWDROPDOWN               :: 0x014f
-CB_GETITEMDATA                :: 0x0150
-CB_SETITEMDATA                :: 0x0151
-CB_GETDROPPEDCONTROLRECT      :: 0x0152
-CB_SETITEMHEIGHT              :: 0x0153
-CB_GETITEMHEIGHT              :: 0x0154
-CB_SETEXTENDEDUI              :: 0x0155
-CB_GETEXTENDEDUI              :: 0x0156
-CB_GETDROPPEDSTATE            :: 0x0157
-CB_FINDSTRINGEXACT            :: 0x0158
-CB_SETLOCALE                  :: 0x0159
-CB_GETLOCALE                  :: 0x015a
-CB_GETTOPINDEX                :: 0x015b
-CB_SETTOPINDEX                :: 0x015c
-CB_GETHORIZONTALEXTENT        :: 0x015d
-CB_SETHORIZONTALEXTENT        :: 0x015e
-CB_GETDROPPEDWIDTH            :: 0x015f
-CB_SETDROPPEDWIDTH            :: 0x0160
-CB_INITSTORAGE                :: 0x0161
-CB_MULTIPLEADDSTRING          :: 0x0163
-CB_GETCOMBOBOXINFO            :: 0x0164
-CB_MSGMAX                     :: 0x0165
-WM_MOUSEFIRST                 :: 0x0200
-WM_MOUSEMOVE                  :: 0x0200
-WM_LBUTTONDOWN                :: 0x0201
-WM_LBUTTONUP                  :: 0x0202
-WM_LBUTTONDBLCLK              :: 0x0203
-WM_RBUTTONDOWN                :: 0x0204
-WM_RBUTTONUP                  :: 0x0205
-WM_RBUTTONDBLCLK              :: 0x0206
-WM_MBUTTONDOWN                :: 0x0207
-WM_MBUTTONUP                  :: 0x0208
-WM_MBUTTONDBLCLK              :: 0x0209
-WM_MOUSELAST                  :: 0x0209
-WM_MOUSEWHEEL                 :: 0x020a
-WM_XBUTTONDOWN                :: 0x020b
-WM_XBUTTONUP                  :: 0x020c
-WM_XBUTTONDBLCLK              :: 0x020d
-WM_MOUSEHWHEEL                :: 0x020e
-WM_PARENTNOTIFY               :: 0x0210
-WM_ENTERMENULOOP              :: 0x0211
-WM_EXITMENULOOP               :: 0x0212
-WM_NEXTMENU                   :: 0x0213
-WM_SIZING                     :: 0x0214
-WM_CAPTURECHANGED             :: 0x0215
-WM_MOVING                     :: 0x0216
-WM_POWERBROADCAST             :: 0x0218
-WM_DEVICECHANGE               :: 0x0219
-WM_MDICREATE                  :: 0x0220
-WM_MDIDESTROY                 :: 0x0221
-WM_MDIACTIVATE                :: 0x0222
-WM_MDIRESTORE                 :: 0x0223
-WM_MDINEXT                    :: 0x0224
-WM_MDIMAXIMIZE                :: 0x0225
-WM_MDITILE                    :: 0x0226
-WM_MDICASCADE                 :: 0x0227
-WM_MDIICONARRANGE             :: 0x0228
-WM_MDIGETACTIVE               :: 0x0229
-WM_MDISETMENU                 :: 0x0230
-WM_ENTERSIZEMOVE              :: 0x0231
-WM_EXITSIZEMOVE               :: 0x0232
-WM_DROPFILES                  :: 0x0233
-WM_MDIREFRESHMENU             :: 0x0234
-WM_POINTERDEVICECHANGE        :: 0x0238
-WM_POINTERDEVICEINRANGE       :: 0x0239
-WM_POINTERDEVICEOUTOFRANGE    :: 0x023a
-WM_TOUCH                      :: 0x0240
-WM_NCPOINTERUPDATE            :: 0x0241
-WM_NCPOINTERDOWN              :: 0x0242
-WM_NCPOINTERUP                :: 0x0243
-WM_POINTERUPDATE              :: 0x0245
-WM_POINTERDOWN                :: 0x0246
-WM_POINTERUP                  :: 0x0247
-WM_POINTERENTER               :: 0x0249
-WM_POINTERLEAVE               :: 0x024a
-WM_POINTERACTIVATE            :: 0x024b
-WM_POINTERCAPTURECHANGED      :: 0x024c
-WM_TOUCHHITTESTING            :: 0x024d
-WM_POINTERWHEEL               :: 0x024e
-WM_POINTERHWHEEL              :: 0x024f
-DM_POINTERHITTEST             :: 0x0250
-WM_POINTERROUTEDTO            :: 0x0251
-WM_POINTERROUTEDAWAY          :: 0x0252
-WM_POINTERROUTEDRELEASED      :: 0x0253
-WM_IME_REPORT                 :: 0x0280
-WM_IME_SETCONTEXT             :: 0x0281
-WM_IME_NOTIFY                 :: 0x0282
-WM_IME_CONTROL                :: 0x0283
-WM_IME_COMPOSITIONFULL        :: 0x0284
-WM_IME_SELECT                 :: 0x0285
-WM_IME_CHAR                   :: 0x0286
-WM_IME_REQUEST                :: 0x0288
-WM_IMEKEYDOWN                 :: 0x0290
-WM_IME_KEYDOWN                :: 0x0290
-WM_IMEKEYUP                   :: 0x0291
-WM_IME_KEYUP                  :: 0x0291
-WM_NCMOUSEHOVER               :: 0x02a0
-WM_MOUSEHOVER                 :: 0x02a1
-WM_NCMOUSELEAVE               :: 0x02a2
-WM_MOUSELEAVE                 :: 0x02a3
-WM_WTSSESSION_CHANGE          :: 0x02b1
-WM_TABLET_FIRST               :: 0x02c0
-WM_TABLET_LAST                :: 0x02df
-WM_DPICHANGED                 :: 0x02e0
-WM_DPICHANGED_BEFOREPARENT    :: 0x02e2
-WM_DPICHANGED_AFTERPARENT     :: 0x02e3
-WM_GETDPISCALEDSIZE           :: 0x02e4
-WM_CUT                        :: 0x0300
-WM_COPY                       :: 0x0301
-WM_PASTE                      :: 0x0302
-WM_CLEAR                      :: 0x0303
-WM_UNDO                       :: 0x0304
-WM_RENDERFORMAT               :: 0x0305
-WM_RENDERALLFORMATS           :: 0x0306
-WM_DESTROYCLIPBOARD           :: 0x0307
-WM_DRAWCLIPBOARD              :: 0x0308
-WM_PAINTCLIPBOARD             :: 0x0309
-WM_VSCROLLCLIPBOARD           :: 0x030a
-WM_SIZECLIPBOARD              :: 0x030b
-WM_ASKCBFORMATNAME            :: 0x030c
-WM_CHANGECBCHAIN              :: 0x030d
-WM_HSCROLLCLIPBOARD           :: 0x030e
-WM_QUERYNEWPALETTE            :: 0x030f
-WM_PALETTEISCHANGING          :: 0x0310
-WM_PALETTECHANGED             :: 0x0311
-WM_HOTKEY                     :: 0x0312
-WM_PRINT                      :: 0x0317
-WM_PRINTCLIENT                :: 0x0318
-WM_APPCOMMAND                 :: 0x0319
-WM_THEMECHANGED               :: 0x031A
-WM_CLIPBOARDUPDATE            :: 0x031D
-WM_DWMCOMPOSITIONCHANGED      :: 0x031E
-WM_DWMNCRENDERINGCHANGED      :: 0x031F
-WM_DWMCOLORIZATIONCOLORCHANGED:: 0x0320
-WM_DWMWINDOWMAXIMIZEDCHANGE   :: 0x0321
-WM_DWMSENDICONICTHUMBNAIL     :: 0x0323
+WM_NULL                           :: 0x0000
+WM_CREATE                         :: 0x0001
+WM_DESTROY                        :: 0x0002
+WM_MOVE                           :: 0x0003
+WM_SIZE                           :: 0x0005
+WM_ACTIVATE                       :: 0x0006
+WM_SETFOCUS                       :: 0x0007
+WM_KILLFOCUS                      :: 0x0008
+WM_ENABLE                         :: 0x000a
+WM_SETREDRAW                      :: 0x000b
+WM_SETTEXT                        :: 0x000c
+WM_GETTEXT                        :: 0x000d
+WM_GETTEXTLENGTH                  :: 0x000e
+WM_PAINT                          :: 0x000f
+WM_CLOSE                          :: 0x0010
+WM_QUERYENDSESSION                :: 0x0011
+WM_QUIT                           :: 0x0012
+WM_QUERYOPEN                      :: 0x0013
+WM_ERASEBKGND                     :: 0x0014
+WM_SYSCOLORCHANGE                 :: 0x0015
+WM_ENDSESSION                     :: 0x0016
+WM_SHOWWINDOW                     :: 0x0018
+WM_CTLCOLOR                       :: 0x0019
+WM_WININICHANGE                   :: 0x001a
+WM_SETTINGCHANGE                  :: WM_WININICHANGE
+WM_DEVMODECHANGE                  :: 0x001b
+WM_ACTIVATEAPP                    :: 0x001c
+WM_FONTCHANGE                     :: 0x001d
+WM_TIMECHANGE                     :: 0x001e
+WM_CANCELMODE                     :: 0x001f
+WM_SETCURSOR                      :: 0x0020
+WM_MOUSEACTIVATE                  :: 0x0021
+WM_CHILDACTIVATE                  :: 0x0022
+WM_QUEUESYNC                      :: 0x0023
+WM_GETMINMAXINFO                  :: 0x0024
+WM_PAINTICON                      :: 0x0026
+WM_ICONERASEBKGND                 :: 0x0027
+WM_NEXTDLGCTL                     :: 0x0028
+WM_SPOOLERSTATUS                  :: 0x002a
+WM_DRAWITEM                       :: 0x002b
+WM_MEASUREITEM                    :: 0x002c
+WM_DELETEITEM                     :: 0x002d
+WM_VKEYTOITEM                     :: 0x002e
+WM_CHARTOITEM                     :: 0x002f
+WM_SETFONT                        :: 0x0030
+WM_GETFONT                        :: 0x0031
+WM_SETHOTKEY                      :: 0x0032
+WM_GETHOTKEY                      :: 0x0033
+WM_QUERYDRAGICON                  :: 0x0037
+WM_COMPAREITEM                    :: 0x0039
+WM_GETOBJECT                      :: 0x003d
+WM_COMPACTING                     :: 0x0041
+WM_COMMNOTIFY                     :: 0x0044
+WM_WINDOWPOSCHANGING              :: 0x0046
+WM_WINDOWPOSCHANGED               :: 0x0047
+WM_POWER                          :: 0x0048
+WM_COPYGLOBALDATA                 :: 0x0049
+WM_COPYDATA                       :: 0x004a
+WM_CANCELJOURNAL                  :: 0x004b
+WM_NOTIFY                         :: 0x004e
+WM_INPUTLANGCHANGEREQUEST         :: 0x0050
+WM_INPUTLANGCHANGE                :: 0x0051
+WM_TCARD                          :: 0x0052
+WM_HELP                           :: 0x0053
+WM_USERCHANGED                    :: 0x0054
+WM_NOTIFYFORMAT                   :: 0x0055
+WM_CONTEXTMENU                    :: 0x007b
+WM_STYLECHANGING                  :: 0x007c
+WM_STYLECHANGED                   :: 0x007d
+WM_DISPLAYCHANGE                  :: 0x007e
+WM_GETICON                        :: 0x007f
+WM_SETICON                        :: 0x0080
+WM_NCCREATE                       :: 0x0081
+WM_NCDESTROY                      :: 0x0082
+WM_NCCALCSIZE                     :: 0x0083
+WM_NCHITTEST                      :: 0x0084
+WM_NCPAINT                        :: 0x0085
+WM_NCACTIVATE                     :: 0x0086
+WM_GETDLGCODE                     :: 0x0087
+WM_SYNCPAINT                      :: 0x0088
+WM_NCMOUSEMOVE                    :: 0x00a0
+WM_NCLBUTTONDOWN                  :: 0x00a1
+WM_NCLBUTTONUP                    :: 0x00a2
+WM_NCLBUTTONDBLCLK                :: 0x00a3
+WM_NCRBUTTONDOWN                  :: 0x00a4
+WM_NCRBUTTONUP                    :: 0x00a5
+WM_NCRBUTTONDBLCLK                :: 0x00a6
+WM_NCMBUTTONDOWN                  :: 0x00a7
+WM_NCMBUTTONUP                    :: 0x00a8
+WM_NCMBUTTONDBLCLK                :: 0x00a9
+WM_NCXBUTTONDOWN                  :: 0x00ab
+WM_NCXBUTTONUP                    :: 0x00ac
+WM_NCXBUTTONDBLCLK                :: 0x00ad
+EM_GETSEL                         :: 0x00b0
+EM_SETSEL                         :: 0x00b1
+EM_GETRECT                        :: 0x00b2
+EM_SETRECT                        :: 0x00b3
+EM_SETRECTNP                      :: 0x00b4
+EM_SCROLL                         :: 0x00b5
+EM_LINESCROLL                     :: 0x00b6
+EM_SCROLLCARET                    :: 0x00b7
+EM_GETMODIFY                      :: 0x00b8
+EM_SETMODIFY                      :: 0x00b9
+EM_GETLINECOUNT                   :: 0x00ba
+EM_LINEINDEX                      :: 0x00bb
+EM_SETHANDLE                      :: 0x00bc
+EM_GETHANDLE                      :: 0x00bd
+EM_GETTHUMB                       :: 0x00be
+EM_LINELENGTH                     :: 0x00c1
+EM_REPLACESEL                     :: 0x00c2
+EM_SETFONT                        :: 0x00c3
+EM_GETLINE                        :: 0x00c4
+EM_LIMITTEXT                      :: 0x00c5
+EM_SETLIMITTEXT                   :: 0x00c5
+EM_CANUNDO                        :: 0x00c6
+EM_UNDO                           :: 0x00c7
+EM_FMTLINES                       :: 0x00c8
+EM_LINEFROMCHAR                   :: 0x00c9
+EM_SETWORDBREAK                   :: 0x00ca
+EM_SETTABSTOPS                    :: 0x00cb
+EM_SETPASSWORDCHAR                :: 0x00cc
+EM_EMPTYUNDOBUFFER                :: 0x00cd
+EM_GETFIRSTVISIBLELINE            :: 0x00ce
+EM_SETREADONLY                    :: 0x00cf
+EM_SETWORDBREAKPROC               :: 0x00d0
+EM_GETWORDBREAKPROC               :: 0x00d1
+EM_GETPASSWORDCHAR                :: 0x00d2
+EM_SETMARGINS                     :: 0x00d3
+EM_GETMARGINS                     :: 0x00d4
+EM_GETLIMITTEXT                   :: 0x00d5
+EM_POSFROMCHAR                    :: 0x00d6
+EM_CHARFROMPOS                    :: 0x00d7
+EM_SETIMESTATUS                   :: 0x00d8
+EM_GETIMESTATUS                   :: 0x00d9
+SBM_SETPOS                        :: 0x00e0
+SBM_GETPOS                        :: 0x00e1
+SBM_SETRANGE                      :: 0x00e2
+SBM_GETRANGE                      :: 0x00e3
+SBM_ENABLE_ARROWS                 :: 0x00e4
+SBM_SETRANGEREDRAW                :: 0x00e6
+SBM_SETSCROLLINFO                 :: 0x00e9
+SBM_GETSCROLLINFO                 :: 0x00ea
+SBM_GETSCROLLBARINFO              :: 0x00eb
+BM_GETCHECK                       :: 0x00f0
+BM_SETCHECK                       :: 0x00f1
+BM_GETSTATE                       :: 0x00f2
+BM_SETSTATE                       :: 0x00f3
+BM_SETSTYLE                       :: 0x00f4
+BM_CLICK                          :: 0x00f5
+BM_GETIMAGE                       :: 0x00f6
+BM_SETIMAGE                       :: 0x00f7
+BM_SETDONTCLICK                   :: 0x00f8
+WM_INPUT_DEVICE_CHANGE            :: 0x00fe
+WM_INPUT                          :: 0x00ff
+WM_KEYDOWN                        :: 0x0100
+WM_KEYFIRST                       :: 0x0100
+WM_KEYUP                          :: 0x0101
+WM_CHAR                           :: 0x0102
+WM_DEADCHAR                       :: 0x0103
+WM_SYSKEYDOWN                     :: 0x0104
+WM_SYSKEYUP                       :: 0x0105
+WM_SYSCHAR                        :: 0x0106
+WM_SYSDEADCHAR                    :: 0x0107
+WM_UNICHAR                        :: 0x0109
+WM_KEYLAST                        :: 0x0109
+UNICODE_NOCHAR                    :: 0xFFFF
+WM_WNT_CONVERTREQUESTEX           :: 0x0109
+WM_CONVERTREQUEST                 :: 0x010a
+WM_CONVERTRESULT                  :: 0x010b
+WM_INTERIM                        :: 0x010c
+WM_IME_STARTCOMPOSITION           :: 0x010d
+WM_IME_ENDCOMPOSITION             :: 0x010e
+WM_IME_COMPOSITION                :: 0x010f
+WM_IME_KEYLAST                    :: 0x010f
+WM_INITDIALOG                     :: 0x0110
+WM_COMMAND                        :: 0x0111
+WM_SYSCOMMAND                     :: 0x0112
+WM_TIMER                          :: 0x0113
+WM_HSCROLL                        :: 0x0114
+WM_VSCROLL                        :: 0x0115
+WM_INITMENU                       :: 0x0116
+WM_INITMENUPOPUP                  :: 0x0117
+WM_SYSTIMER                       :: 0x0118
+WM_MENUSELECT                     :: 0x011f
+WM_MENUCHAR                       :: 0x0120
+WM_ENTERIDLE                      :: 0x0121
+WM_MENURBUTTONUP                  :: 0x0122
+WM_MENUDRAG                       :: 0x0123
+WM_MENUGETOBJECT                  :: 0x0124
+WM_UNINITMENUPOPUP                :: 0x0125
+WM_MENUCOMMAND                    :: 0x0126
+WM_CHANGEUISTATE                  :: 0x0127
+WM_UPDATEUISTATE                  :: 0x0128
+WM_QUERYUISTATE                   :: 0x0129
+WM_LBTRACKPOINT                   :: 0x0131
+WM_CTLCOLORMSGBOX                 :: 0x0132
+WM_CTLCOLOREDIT                   :: 0x0133
+WM_CTLCOLORLISTBOX                :: 0x0134
+WM_CTLCOLORBTN                    :: 0x0135
+WM_CTLCOLORDLG                    :: 0x0136
+WM_CTLCOLORSCROLLBAR              :: 0x0137
+WM_CTLCOLORSTATIC                 :: 0x0138
+CB_GETEDITSEL                     :: 0x0140
+CB_LIMITTEXT                      :: 0x0141
+CB_SETEDITSEL                     :: 0x0142
+CB_ADDSTRING                      :: 0x0143
+CB_DELETESTRING                   :: 0x0144
+CB_DIR                            :: 0x0145
+CB_GETCOUNT                       :: 0x0146
+CB_GETCURSEL                      :: 0x0147
+CB_GETLBTEXT                      :: 0x0148
+CB_GETLBTEXTLEN                   :: 0x0149
+CB_INSERTSTRING                   :: 0x014a
+CB_RESETCONTENT                   :: 0x014b
+CB_FINDSTRING                     :: 0x014c
+CB_SELECTSTRING                   :: 0x014d
+CB_SETCURSEL                      :: 0x014e
+CB_SHOWDROPDOWN                   :: 0x014f
+CB_GETITEMDATA                    :: 0x0150
+CB_SETITEMDATA                    :: 0x0151
+CB_GETDROPPEDCONTROLRECT          :: 0x0152
+CB_SETITEMHEIGHT                  :: 0x0153
+CB_GETITEMHEIGHT                  :: 0x0154
+CB_SETEXTENDEDUI                  :: 0x0155
+CB_GETEXTENDEDUI                  :: 0x0156
+CB_GETDROPPEDSTATE                :: 0x0157
+CB_FINDSTRINGEXACT                :: 0x0158
+CB_SETLOCALE                      :: 0x0159
+CB_GETLOCALE                      :: 0x015a
+CB_GETTOPINDEX                    :: 0x015b
+CB_SETTOPINDEX                    :: 0x015c
+CB_GETHORIZONTALEXTENT            :: 0x015d
+CB_SETHORIZONTALEXTENT            :: 0x015e
+CB_GETDROPPEDWIDTH                :: 0x015f
+CB_SETDROPPEDWIDTH                :: 0x0160
+CB_INITSTORAGE                    :: 0x0161
+CB_MULTIPLEADDSTRING              :: 0x0163
+CB_GETCOMBOBOXINFO                :: 0x0164
+CB_MSGMAX                         :: 0x0165
+WM_MOUSEFIRST                     :: 0x0200
+WM_MOUSEMOVE                      :: 0x0200
+WM_LBUTTONDOWN                    :: 0x0201
+WM_LBUTTONUP                      :: 0x0202
+WM_LBUTTONDBLCLK                  :: 0x0203
+WM_RBUTTONDOWN                    :: 0x0204
+WM_RBUTTONUP                      :: 0x0205
+WM_RBUTTONDBLCLK                  :: 0x0206
+WM_MBUTTONDOWN                    :: 0x0207
+WM_MBUTTONUP                      :: 0x0208
+WM_MBUTTONDBLCLK                  :: 0x0209
+WM_MOUSELAST                      :: 0x0209
+WM_MOUSEWHEEL                     :: 0x020a
+WM_XBUTTONDOWN                    :: 0x020b
+WM_XBUTTONUP                      :: 0x020c
+WM_XBUTTONDBLCLK                  :: 0x020d
+WM_MOUSEHWHEEL                    :: 0x020e
+WM_PARENTNOTIFY                   :: 0x0210
+WM_ENTERMENULOOP                  :: 0x0211
+WM_EXITMENULOOP                   :: 0x0212
+WM_NEXTMENU                       :: 0x0213
+WM_SIZING                         :: 0x0214
+WM_CAPTURECHANGED                 :: 0x0215
+WM_MOVING                         :: 0x0216
+WM_POWERBROADCAST                 :: 0x0218
+WM_DEVICECHANGE                   :: 0x0219
+WM_MDICREATE                      :: 0x0220
+WM_MDIDESTROY                     :: 0x0221
+WM_MDIACTIVATE                    :: 0x0222
+WM_MDIRESTORE                     :: 0x0223
+WM_MDINEXT                        :: 0x0224
+WM_MDIMAXIMIZE                    :: 0x0225
+WM_MDITILE                        :: 0x0226
+WM_MDICASCADE                     :: 0x0227
+WM_MDIICONARRANGE                 :: 0x0228
+WM_MDIGETACTIVE                   :: 0x0229
+WM_MDISETMENU                     :: 0x0230
+WM_ENTERSIZEMOVE                  :: 0x0231
+WM_EXITSIZEMOVE                   :: 0x0232
+WM_DROPFILES                      :: 0x0233
+WM_MDIREFRESHMENU                 :: 0x0234
+WM_POINTERDEVICECHANGE            :: 0x0238
+WM_POINTERDEVICEINRANGE           :: 0x0239
+WM_POINTERDEVICEOUTOFRANGE        :: 0x023a
+WM_TOUCH                          :: 0x0240
+WM_NCPOINTERUPDATE                :: 0x0241
+WM_NCPOINTERDOWN                  :: 0x0242
+WM_NCPOINTERUP                    :: 0x0243
+WM_POINTERUPDATE                  :: 0x0245
+WM_POINTERDOWN                    :: 0x0246
+WM_POINTERUP                      :: 0x0247
+WM_POINTERENTER                   :: 0x0249
+WM_POINTERLEAVE                   :: 0x024a
+WM_POINTERACTIVATE                :: 0x024b
+WM_POINTERCAPTURECHANGED          :: 0x024c
+WM_TOUCHHITTESTING                :: 0x024d
+WM_POINTERWHEEL                   :: 0x024e
+WM_POINTERHWHEEL                  :: 0x024f
+DM_POINTERHITTEST                 :: 0x0250
+WM_POINTERROUTEDTO                :: 0x0251
+WM_POINTERROUTEDAWAY              :: 0x0252
+WM_POINTERROUTEDRELEASED          :: 0x0253
+WM_IME_REPORT                     :: 0x0280
+WM_IME_SETCONTEXT                 :: 0x0281
+WM_IME_NOTIFY                     :: 0x0282
+WM_IME_CONTROL                    :: 0x0283
+WM_IME_COMPOSITIONFULL            :: 0x0284
+WM_IME_SELECT                     :: 0x0285
+WM_IME_CHAR                       :: 0x0286
+WM_IME_REQUEST                    :: 0x0288
+WM_IMEKEYDOWN                     :: 0x0290
+WM_IME_KEYDOWN                    :: 0x0290
+WM_IMEKEYUP                       :: 0x0291
+WM_IME_KEYUP                      :: 0x0291
+WM_NCMOUSEHOVER                   :: 0x02a0
+WM_MOUSEHOVER                     :: 0x02a1
+WM_NCMOUSELEAVE                   :: 0x02a2
+WM_MOUSELEAVE                     :: 0x02a3
+WM_WTSSESSION_CHANGE              :: 0x02b1
+WM_TABLET_FIRST                   :: 0x02c0
+WM_TABLET_LAST                    :: 0x02df
+WM_DPICHANGED                     :: 0x02e0
+WM_DPICHANGED_BEFOREPARENT        :: 0x02e2
+WM_DPICHANGED_AFTERPARENT         :: 0x02e3
+WM_GETDPISCALEDSIZE               :: 0x02e4
+WM_CUT                            :: 0x0300
+WM_COPY                           :: 0x0301
+WM_PASTE                          :: 0x0302
+WM_CLEAR                          :: 0x0303
+WM_UNDO                           :: 0x0304
+WM_RENDERFORMAT                   :: 0x0305
+WM_RENDERALLFORMATS               :: 0x0306
+WM_DESTROYCLIPBOARD               :: 0x0307
+WM_DRAWCLIPBOARD                  :: 0x0308
+WM_PAINTCLIPBOARD                 :: 0x0309
+WM_VSCROLLCLIPBOARD               :: 0x030a
+WM_SIZECLIPBOARD                  :: 0x030b
+WM_ASKCBFORMATNAME                :: 0x030c
+WM_CHANGECBCHAIN                  :: 0x030d
+WM_HSCROLLCLIPBOARD               :: 0x030e
+WM_QUERYNEWPALETTE                :: 0x030f
+WM_PALETTEISCHANGING              :: 0x0310
+WM_PALETTECHANGED                 :: 0x0311
+WM_HOTKEY                         :: 0x0312
+WM_PRINT                          :: 0x0317
+WM_PRINTCLIENT                    :: 0x0318
+WM_APPCOMMAND                     :: 0x0319
+WM_THEMECHANGED                   :: 0x031A
+WM_CLIPBOARDUPDATE                :: 0x031D
+WM_DWMCOMPOSITIONCHANGED          :: 0x031E
+WM_DWMNCRENDERINGCHANGED          :: 0x031F
+WM_DWMCOLORIZATIONCOLORCHANGED    :: 0x0320
+WM_DWMWINDOWMAXIMIZEDCHANGE       :: 0x0321
+WM_DWMSENDICONICTHUMBNAIL         :: 0x0323
 WM_DWMSENDICONICLIVEPREVIEWBITMAP :: 0x0326
 WM_DWMSENDICONICLIVEPREVIEWBITMAP :: 0x0326
-WM_GETTITLEBARINFOEX          ::  0x033F
-WM_HANDHELDFIRST              :: 0x0358
-WM_HANDHELDLAST               :: 0x035f
-WM_AFXFIRST                   :: 0x0360
-WM_AFXLAST                    :: 0x037f
-WM_PENWINFIRST                :: 0x0380
-WM_RCRESULT                   :: 0x0381
-WM_HOOKRCRESULT               :: 0x0382
-WM_GLOBALRCCHANGE             :: 0x0383
-WM_PENMISCINFO                :: 0x0383
-WM_SKB                        :: 0x0384
-WM_HEDITCTL                   :: 0x0385
-WM_PENCTL                     :: 0x0385
-WM_PENMISC                    :: 0x0386
-WM_CTLINIT                    :: 0x0387
-WM_PENEVENT                   :: 0x0388
-WM_PENWINLAST                 :: 0x038f
-DDM_SETFMT                    :: 0x0400
-DM_GETDEFID                   :: 0x0400
-NIN_SELECT                    :: 0x0400
-TBM_GETPOS                    :: 0x0400
-WM_PSD_PAGESETUPDLG           :: 0x0400
-WM_USER                       :: 0x0400
-CBEM_INSERTITEMA              :: 0x0401
-DDM_DRAW                      :: 0x0401
-DM_SETDEFID                   :: 0x0401
-HKM_SETHOTKEY                 :: 0x0401
-PBM_SETRANGE                  :: 0x0401
-RB_INSERTBANDA                :: 0x0401
-SB_SETTEXTA                   :: 0x0401
-TB_ENABLEBUTTON               :: 0x0401
-TBM_GETRANGEMIN               :: 0x0401
-TTM_ACTIVATE                  :: 0x0401
-WM_CHOOSEFONT_GETLOGFONT      :: 0x0401
-WM_PSD_FULLPAGERECT           :: 0x0401
-CBEM_SETIMAGELIST             :: 0x0402
-DDM_CLOSE                     :: 0x0402
-DM_REPOSITION                 :: 0x0402
-HKM_GETHOTKEY                 :: 0x0402
-PBM_SETPOS                    :: 0x0402
-RB_DELETEBAND                 :: 0x0402
-SB_GETTEXTA                   :: 0x0402
-TB_CHECKBUTTON                :: 0x0402
-TBM_GETRANGEMAX               :: 0x0402
-WM_PSD_MINMARGINRECT          :: 0x0402
-CBEM_GETIMAGELIST             :: 0x0403
-DDM_BEGIN                     :: 0x0403
-HKM_SETRULES                  :: 0x0403
-PBM_DELTAPOS                  :: 0x0403
-RB_GETBARINFO                 :: 0x0403
-SB_GETTEXTLENGTHA             :: 0x0403
-TBM_GETTIC                    :: 0x0403
-TB_PRESSBUTTON                :: 0x0403
-TTM_SETDELAYTIME              :: 0x0403
-WM_PSD_MARGINRECT             :: 0x0403
-CBEM_GETITEMA                 :: 0x0404
-DDM_END                       :: 0x0404
-PBM_SETSTEP                   :: 0x0404
-RB_SETBARINFO                 :: 0x0404
-SB_SETPARTS                   :: 0x0404
-TB_HIDEBUTTON                 :: 0x0404
-TBM_SETTIC                    :: 0x0404
-TTM_ADDTOOLA                  :: 0x0404
-WM_PSD_GREEKTEXTRECT          :: 0x0404
-CBEM_SETITEMA                 :: 0x0405
-PBM_STEPIT                    :: 0x0405
-TB_INDETERMINATE              :: 0x0405
-TBM_SETPOS                    :: 0x0405
-TTM_DELTOOLA                  :: 0x0405
-WM_PSD_ENVSTAMPRECT           :: 0x0405
-CBEM_GETCOMBOCONTROL          :: 0x0406
-PBM_SETRANGE32                :: 0x0406
-RB_SETBANDINFOA               :: 0x0406
-SB_GETPARTS                   :: 0x0406
-TB_MARKBUTTON                 :: 0x0406
-TBM_SETRANGE                  :: 0x0406
-TTM_NEWTOOLRECTA              :: 0x0406
-WM_PSD_YAFULLPAGERECT         :: 0x0406
-CBEM_GETEDITCONTROL           :: 0x0407
-PBM_GETRANGE                  :: 0x0407
-RB_SETPARENT                  :: 0x0407
-SB_GETBORDERS                 :: 0x0407
-TBM_SETRANGEMIN               :: 0x0407
-TTM_RELAYEVENT                :: 0x0407
-CBEM_SETEXSTYLE               :: 0x0408
-PBM_GETPOS                    :: 0x0408
-RB_HITTEST                    :: 0x0408
-SB_SETMINHEIGHT               :: 0x0408
-TBM_SETRANGEMAX               :: 0x0408
-TTM_GETTOOLINFOA              :: 0x0408
-CBEM_GETEXSTYLE               :: 0x0409
-CBEM_GETEXTENDEDSTYLE         :: 0x0409
-PBM_SETBARCOLOR               :: 0x0409
-RB_GETRECT                    :: 0x0409
-SB_SIMPLE                     :: 0x0409
-TB_ISBUTTONENABLED            :: 0x0409
-TBM_CLEARTICS                 :: 0x0409
-TTM_SETTOOLINFOA              :: 0x0409
-CBEM_HASEDITCHANGED           :: 0x040a
-RB_INSERTBANDW                :: 0x040a
-SB_GETRECT                    :: 0x040a
-TB_ISBUTTONCHECKED            :: 0x040a
-TBM_SETSEL                    :: 0x040a
-TTM_HITTESTA                  :: 0x040a
-WIZ_QUERYNUMPAGES             :: 0x040a
-CBEM_INSERTITEMW              :: 0x040b
-RB_SETBANDINFOW               :: 0x040b
-SB_SETTEXTW                   :: 0x040b
-TB_ISBUTTONPRESSED            :: 0x040b
-TBM_SETSELSTART               :: 0x040b
-TTM_GETTEXTA                  :: 0x040b
-WIZ_NEXT                      :: 0x040b
-CBEM_SETITEMW                 :: 0x040c
-RB_GETBANDCOUNT               :: 0x040c
-SB_GETTEXTLENGTHW             :: 0x040c
-TB_ISBUTTONHIDDEN             :: 0x040c
-TBM_SETSELEND                 :: 0x040c
-TTM_UPDATETIPTEXTA            :: 0x040c
-WIZ_PREV                      :: 0x040c
-CBEM_GETITEMW                 :: 0x040d
-RB_GETROWCOUNT                :: 0x040d
-SB_GETTEXTW                   :: 0x040d
-TB_ISBUTTONINDETERMINATE      :: 0x040d
-TTM_GETTOOLCOUNT              :: 0x040d
-CBEM_SETEXTENDEDSTYLE         :: 0x040e
-RB_GETROWHEIGHT               :: 0x040e
-SB_ISSIMPLE                   :: 0x040e
-TB_ISBUTTONHIGHLIGHTED        :: 0x040e
-TBM_GETPTICS                  :: 0x040e
-TTM_ENUMTOOLSA                :: 0x040e
-SB_SETICON                    :: 0x040f
-TBM_GETTICPOS                 :: 0x040f
-TTM_GETCURRENTTOOLA           :: 0x040f
-RB_IDTOINDEX                  :: 0x0410
-SB_SETTIPTEXTA                :: 0x0410
-TBM_GETNUMTICS                :: 0x0410
-TTM_WINDOWFROMPOINT           :: 0x0410
-RB_GETTOOLTIPS                :: 0x0411
-SB_SETTIPTEXTW                :: 0x0411
-TBM_GETSELSTART               :: 0x0411
-TB_SETSTATE                   :: 0x0411
-TTM_TRACKACTIVATE             :: 0x0411
-RB_SETTOOLTIPS                :: 0x0412
-SB_GETTIPTEXTA                :: 0x0412
-TB_GETSTATE                   :: 0x0412
-TBM_GETSELEND                 :: 0x0412
-TTM_TRACKPOSITION             :: 0x0412
-RB_SETBKCOLOR                 :: 0x0413
-SB_GETTIPTEXTW                :: 0x0413
-TB_ADDBITMAP                  :: 0x0413
-TBM_CLEARSEL                  :: 0x0413
-TTM_SETTIPBKCOLOR             :: 0x0413
-RB_GETBKCOLOR                 :: 0x0414
-SB_GETICON                    :: 0x0414
-TB_ADDBUTTONSA                :: 0x0414
-TBM_SETTICFREQ                :: 0x0414
-TTM_SETTIPTEXTCOLOR           :: 0x0414
-RB_SETTEXTCOLOR               :: 0x0415
-TB_INSERTBUTTONA              :: 0x0415
-TBM_SETPAGESIZE               :: 0x0415
-TTM_GETDELAYTIME              :: 0x0415
-RB_GETTEXTCOLOR               :: 0x0416
-TB_DELETEBUTTON               :: 0x0416
-TBM_GETPAGESIZE               :: 0x0416
-TTM_GETTIPBKCOLOR             :: 0x0416
-RB_SIZETORECT                 :: 0x0417
-TB_GETBUTTON                  :: 0x0417
-TBM_SETLINESIZE               :: 0x0417
-TTM_GETTIPTEXTCOLOR           :: 0x0417
-RB_BEGINDRAG                  :: 0x0418
-TB_BUTTONCOUNT                :: 0x0418
-TBM_GETLINESIZE               :: 0x0418
-TTM_SETMAXTIPWIDTH            :: 0x0418
-RB_ENDDRAG                    :: 0x0419
-TB_COMMANDTOINDEX             :: 0x0419
-TBM_GETTHUMBRECT              :: 0x0419
-TTM_GETMAXTIPWIDTH            :: 0x0419
-RB_DRAGMOVE                   :: 0x041a
-TBM_GETCHANNELRECT            :: 0x041a
-TB_SAVERESTOREA               :: 0x041a
-TTM_SETMARGIN                 :: 0x041a
-RB_GETBARHEIGHT               :: 0x041b
-TB_CUSTOMIZE                  :: 0x041b
-TBM_SETTHUMBLENGTH            :: 0x041b
-TTM_GETMARGIN                 :: 0x041b
-RB_GETBANDINFOW               :: 0x041c
-TB_ADDSTRINGA                 :: 0x041c
-TBM_GETTHUMBLENGTH            :: 0x041c
-TTM_POP                       :: 0x041c
-RB_GETBANDINFOA               :: 0x041d
-TB_GETITEMRECT                :: 0x041d
-TBM_SETTOOLTIPS               :: 0x041d
-TTM_UPDATE                    :: 0x041d
-RB_MINIMIZEBAND               :: 0x041e
-TB_BUTTONSTRUCTSIZE           :: 0x041e
-TBM_GETTOOLTIPS               :: 0x041e
-TTM_GETBUBBLESIZE             :: 0x041e
-RB_MAXIMIZEBAND               :: 0x041f
-TBM_SETTIPSIDE                :: 0x041f
-TB_SETBUTTONSIZE              :: 0x041f
-TTM_ADJUSTRECT                :: 0x041f
-TBM_SETBUDDY                  :: 0x0420
-TB_SETBITMAPSIZE              :: 0x0420
-TTM_SETTITLEA                 :: 0x0420
-MSG_FTS_JUMP_VA               :: 0x0421
-TB_AUTOSIZE                   :: 0x0421
-TBM_GETBUDDY                  :: 0x0421
-TTM_SETTITLEW                 :: 0x0421
-RB_GETBANDBORDERS             :: 0x0422
-MSG_FTS_JUMP_QWORD            :: 0x0423
-RB_SHOWBAND                   :: 0x0423
-TB_GETTOOLTIPS                :: 0x0423
-MSG_REINDEX_REQUEST           :: 0x0424
-TB_SETTOOLTIPS                :: 0x0424
-MSG_FTS_WHERE_IS_IT           :: 0x0425
-RB_SETPALETTE                 :: 0x0425
-TB_SETPARENT                  :: 0x0425
-RB_GETPALETTE                 :: 0x0426
-RB_MOVEBAND                   :: 0x0427
-TB_SETROWS                    :: 0x0427
-TB_GETROWS                    :: 0x0428
-TB_GETBITMAPFLAGS             :: 0x0429
-TB_SETCMDID                   :: 0x042a
-RB_PUSHCHEVRON                :: 0x042b
-TB_CHANGEBITMAP               :: 0x042b
-TB_GETBITMAP                  :: 0x042c
-MSG_GET_DEFFONT               :: 0x042d
-TB_GETBUTTONTEXTA             :: 0x042d
-TB_REPLACEBITMAP              :: 0x042e
-TB_SETINDENT                  :: 0x042f
-TB_SETIMAGELIST               :: 0x0430
-TB_GETIMAGELIST               :: 0x0431
-TB_LOADIMAGES                 :: 0x0432
-EM_CANPASTE                   :: 0x0432
-TTM_ADDTOOLW                  :: 0x0432
-EM_DISPLAYBAND                :: 0x0433
-TB_GETRECT                    :: 0x0433
-TTM_DELTOOLW                  :: 0x0433
-EM_EXGETSEL                   :: 0x0434
-TB_SETHOTIMAGELIST            :: 0x0434
-TTM_NEWTOOLRECTW              :: 0x0434
-EM_EXLIMITTEXT                :: 0x0435
-TB_GETHOTIMAGELIST            :: 0x0435
-TTM_GETTOOLINFOW              :: 0x0435
-EM_EXLINEFROMCHAR             :: 0x0436
-TB_SETDISABLEDIMAGELIST       :: 0x0436
-TTM_SETTOOLINFOW              :: 0x0436
-EM_EXSETSEL                   :: 0x0437
-TB_GETDISABLEDIMAGELIST       :: 0x0437
-TTM_HITTESTW                  :: 0x0437
-EM_FINDTEXT                   :: 0x0438
-TB_SETSTYLE                   :: 0x0438
-TTM_GETTEXTW                  :: 0x0438
-EM_FORMATRANGE                :: 0x0439
-TB_GETSTYLE                   :: 0x0439
-TTM_UPDATETIPTEXTW            :: 0x0439
-EM_GETCHARFORMAT              :: 0x043a
-TB_GETBUTTONSIZE              :: 0x043a
-TTM_ENUMTOOLSW                :: 0x043a
-EM_GETEVENTMASK               :: 0x043b
-TB_SETBUTTONWIDTH             :: 0x043b
-TTM_GETCURRENTTOOLW           :: 0x043b
-EM_GETOLEINTERFACE            :: 0x043c
-TB_SETMAXTEXTROWS             :: 0x043c
-EM_GETPARAFORMAT              :: 0x043d
-TB_GETTEXTROWS                :: 0x043d
-EM_GETSELTEXT                 :: 0x043e
-TB_GETOBJECT                  :: 0x043e
-EM_HIDESELECTION              :: 0x043f
-TB_GETBUTTONINFOW             :: 0x043f
-EM_PASTESPECIAL               :: 0x0440
-TB_SETBUTTONINFOW             :: 0x0440
-EM_REQUESTRESIZE              :: 0x0441
-TB_GETBUTTONINFOA             :: 0x0441
-EM_SELECTIONTYPE              :: 0x0442
-TB_SETBUTTONINFOA             :: 0x0442
-EM_SETBKGNDCOLOR              :: 0x0443
-TB_INSERTBUTTONW              :: 0x0443
-EM_SETCHARFORMAT              :: 0x0444
-TB_ADDBUTTONSW                :: 0x0444
-EM_SETEVENTMASK               :: 0x0445
-TB_HITTEST                    :: 0x0445
-EM_SETOLECALLBACK             :: 0x0446
-TB_SETDRAWTEXTFLAGS           :: 0x0446
-EM_SETPARAFORMAT              :: 0x0447
-TB_GETHOTITEM                 :: 0x0447
-EM_SETTARGETDEVICE            :: 0x0448
-TB_SETHOTITEM                 :: 0x0448
-EM_STREAMIN                   :: 0x0449
-TB_SETANCHORHIGHLIGHT         :: 0x0449
-EM_STREAMOUT                  :: 0x044a
-TB_GETANCHORHIGHLIGHT         :: 0x044a
-EM_GETTEXTRANGE               :: 0x044b
-TB_GETBUTTONTEXTW             :: 0x044b
-EM_FINDWORDBREAK              :: 0x044c
-TB_SAVERESTOREW               :: 0x044c
-EM_SETOPTIONS                 :: 0x044d
-TB_ADDSTRINGW                 :: 0x044d
-EM_GETOPTIONS                 :: 0x044e
-TB_MAPACCELERATORA            :: 0x044e
-EM_FINDTEXTEX                 :: 0x044f
-TB_GETINSERTMARK              :: 0x044f
-EM_GETWORDBREAKPROCEX         :: 0x0450
-TB_SETINSERTMARK              :: 0x0450
-EM_SETWORDBREAKPROCEX         :: 0x0451
-TB_INSERTMARKHITTEST          :: 0x0451
-EM_SETUNDOLIMIT               :: 0x0452
-TB_MOVEBUTTON                 :: 0x0452
-TB_GETMAXSIZE                 :: 0x0453
-EM_REDO                       :: 0x0454
-TB_SETEXTENDEDSTYLE           :: 0x0454
-EM_CANREDO                    :: 0x0455
-TB_GETEXTENDEDSTYLE           :: 0x0455
-EM_GETUNDONAME                :: 0x0456
-TB_GETPADDING                 :: 0x0456
-EM_GETREDONAME                :: 0x0457
-TB_SETPADDING                 :: 0x0457
-EM_STOPGROUPTYPING            :: 0x0458
-TB_SETINSERTMARKCOLOR         :: 0x0458
-EM_SETTEXTMODE                :: 0x0459
-TB_GETINSERTMARKCOLOR         :: 0x0459
-EM_GETTEXTMODE                :: 0x045a
-TB_MAPACCELERATORW            :: 0x045a
-EM_AUTOURLDETECT              :: 0x045b
-TB_GETSTRINGW                 :: 0x045b
-EM_GETAUTOURLDETECT           :: 0x045c
-TB_GETSTRINGA                 :: 0x045c
-EM_SETPALETTE                 :: 0x045d
-EM_GETTEXTEX                  :: 0x045e
-EM_GETTEXTLENGTHEX            :: 0x045f
-EM_SHOWSCROLLBAR              :: 0x0460
-EM_SETTEXTEX                  :: 0x0461
-TAPI_REPLY                    :: 0x0463
-ACM_OPENA                     :: 0x0464
-BFFM_SETSTATUSTEXTA           :: 0x0464
-CDM_FIRST                     :: 0x0464
-CDM_GETSPEC                   :: 0x0464
-EM_SETPUNCTUATION             :: 0x0464
-IPM_CLEARADDRESS              :: 0x0464
-WM_CAP_UNICODE_START          :: 0x0464
-ACM_PLAY                      :: 0x0465
-BFFM_ENABLEOK                 :: 0x0465
-CDM_GETFILEPATH               :: 0x0465
-EM_GETPUNCTUATION             :: 0x0465
-IPM_SETADDRESS                :: 0x0465
-PSM_SETCURSEL                 :: 0x0465
-UDM_SETRANGE                  :: 0x0465
-WM_CHOOSEFONT_SETLOGFONT      :: 0x0465
-ACM_STOP                      :: 0x0466
-BFFM_SETSELECTIONA            :: 0x0466
-CDM_GETFOLDERPATH             :: 0x0466
-EM_SETWORDWRAPMODE            :: 0x0466
-IPM_GETADDRESS                :: 0x0466
-PSM_REMOVEPAGE                :: 0x0466
-UDM_GETRANGE                  :: 0x0466
-WM_CAP_SET_CALLBACK_ERRORW    :: 0x0466
-WM_CHOOSEFONT_SETFLAGS        :: 0x0466
-ACM_OPENW                     :: 0x0467
-BFFM_SETSELECTIONW            :: 0x0467
-CDM_GETFOLDERIDLIST           :: 0x0467
-EM_GETWORDWRAPMODE            :: 0x0467
-IPM_SETRANGE                  :: 0x0467
-PSM_ADDPAGE                   :: 0x0467
-UDM_SETPOS                    :: 0x0467
-WM_CAP_SET_CALLBACK_STATUSW   :: 0x0467
-BFFM_SETSTATUSTEXTW           :: 0x0468
-CDM_SETCONTROLTEXT            :: 0x0468
-EM_SETIMECOLOR                :: 0x0468
-IPM_SETFOCUS                  :: 0x0468
-PSM_CHANGED                   :: 0x0468
-UDM_GETPOS                    :: 0x0468
-CDM_HIDECONTROL               :: 0x0469
-EM_GETIMECOLOR                :: 0x0469
-IPM_ISBLANK                   :: 0x0469
-PSM_RESTARTWINDOWS            :: 0x0469
-UDM_SETBUDDY                  :: 0x0469
-CDM_SETDEFEXT                 :: 0x046a
-EM_SETIMEOPTIONS              :: 0x046a
-PSM_REBOOTSYSTEM              :: 0x046a
-UDM_GETBUDDY                  :: 0x046a
-EM_GETIMEOPTIONS              :: 0x046b
-PSM_CANCELTOCLOSE             :: 0x046b
-UDM_SETACCEL                  :: 0x046b
-EM_CONVPOSITION               :: 0x046c
-PSM_QUERYSIBLINGS             :: 0x046c
-UDM_GETACCEL                  :: 0x046c
-MCIWNDM_GETZOOM               :: 0x046d
-PSM_UNCHANGED                 :: 0x046d
-UDM_SETBASE                   :: 0x046d
-PSM_APPLY                     :: 0x046e
-UDM_GETBASE                   :: 0x046e
-PSM_SETTITLEA                 :: 0x046f
-UDM_SETRANGE32                :: 0x046f
-PSM_SETWIZBUTTONS             :: 0x0470
-UDM_GETRANGE32                :: 0x0470
-WM_CAP_DRIVER_GET_NAMEW       :: 0x0470
-PSM_PRESSBUTTON               :: 0x0471
-UDM_SETPOS32                  :: 0x0471
-WM_CAP_DRIVER_GET_VERSIONW    :: 0x0471
-PSM_SETCURSELID               :: 0x0472
-UDM_GETPOS32                  :: 0x0472
-PSM_SETFINISHTEXTA            :: 0x0473
-PSM_GETTABCONTROL             :: 0x0474
-PSM_ISDIALOGMESSAGE           :: 0x0475
-MCIWNDM_REALIZE               :: 0x0476
-PSM_GETCURRENTPAGEHWND        :: 0x0476
-MCIWNDM_SETTIMEFORMATA        :: 0x0477
-PSM_INSERTPAGE                :: 0x0477
-EM_SETLANGOPTIONS             :: 0x0478
-MCIWNDM_GETTIMEFORMATA        :: 0x0478
-PSM_SETTITLEW                 :: 0x0478
-WM_CAP_FILE_SET_CAPTURE_FILEW :: 0x0478
-EM_GETLANGOPTIONS             :: 0x0479
-MCIWNDM_VALIDATEMEDIA         :: 0x0479
-PSM_SETFINISHTEXTW            :: 0x0479
-WM_CAP_FILE_GET_CAPTURE_FILEW :: 0x0479
-EM_GETIMECOMPMODE             :: 0x047a
-EM_FINDTEXTW                  :: 0x047b
-MCIWNDM_PLAYTO                :: 0x047b
-WM_CAP_FILE_SAVEASW           :: 0x047b
-EM_FINDTEXTEXW                :: 0x047c
-MCIWNDM_GETFILENAMEA          :: 0x047c
-EM_RECONVERSION               :: 0x047d
-MCIWNDM_GETDEVICEA            :: 0x047d
-PSM_SETHEADERTITLEA           :: 0x047d
-WM_CAP_FILE_SAVEDIBW          :: 0x047d
-EM_SETIMEMODEBIAS             :: 0x047e
-MCIWNDM_GETPALETTE            :: 0x047e
-PSM_SETHEADERTITLEW           :: 0x047e
-EM_GETIMEMODEBIAS             :: 0x047f
-MCIWNDM_SETPALETTE            :: 0x047f
-PSM_SETHEADERSUBTITLEA        :: 0x047f
-MCIWNDM_GETERRORA             :: 0x0480
-PSM_SETHEADERSUBTITLEW        :: 0x0480
-PSM_HWNDTOINDEX               :: 0x0481
-PSM_INDEXTOHWND               :: 0x0482
-MCIWNDM_SETINACTIVETIMER      :: 0x0483
-PSM_PAGETOINDEX               :: 0x0483
-PSM_INDEXTOPAGE               :: 0x0484
-DL_BEGINDRAG                  :: 0x0485
-MCIWNDM_GETINACTIVETIMER      :: 0x0485
-PSM_IDTOINDEX                 :: 0x0485
-DL_DRAGGING                   :: 0x0486
-PSM_INDEXTOID                 :: 0x0486
-DL_DROPPED                    :: 0x0487
-PSM_GETRESULT                 :: 0x0487
-DL_CANCELDRAG                 :: 0x0488
-PSM_RECALCPAGESIZES           :: 0x0488
-MCIWNDM_GET_SOURCE            :: 0x048c
-MCIWNDM_PUT_SOURCE            :: 0x048d
-MCIWNDM_GET_DEST              :: 0x048e
-MCIWNDM_PUT_DEST              :: 0x048f
-MCIWNDM_CAN_PLAY              :: 0x0490
-MCIWNDM_CAN_WINDOW            :: 0x0491
-MCIWNDM_CAN_RECORD            :: 0x0492
-MCIWNDM_CAN_SAVE              :: 0x0493
-MCIWNDM_CAN_EJECT             :: 0x0494
-MCIWNDM_CAN_CONFIG            :: 0x0495
-IE_GETINK                     :: 0x0496
-IE_MSGFIRST                   :: 0x0496
-MCIWNDM_PALETTEKICK           :: 0x0496
-IE_SETINK                     :: 0x0497
-IE_GETPENTIP                  :: 0x0498
-IE_SETPENTIP                  :: 0x0499
-IE_GETERASERTIP               :: 0x049a
-IE_SETERASERTIP               :: 0x049b
-IE_GETBKGND                   :: 0x049c
-IE_SETBKGND                   :: 0x049d
-IE_GETGRIDORIGIN              :: 0x049e
-IE_SETGRIDORIGIN              :: 0x049f
-IE_GETGRIDPEN                 :: 0x04a0
-IE_SETGRIDPEN                 :: 0x04a1
-IE_GETGRIDSIZE                :: 0x04a2
-IE_SETGRIDSIZE                :: 0x04a3
-IE_GETMODE                    :: 0x04a4
-IE_SETMODE                    :: 0x04a5
-IE_GETINKRECT                 :: 0x04a6
-WM_CAP_SET_MCI_DEVICEW        :: 0x04a6
-WM_CAP_GET_MCI_DEVICEW        :: 0x04a7
-WM_CAP_PAL_OPENW              :: 0x04b4
-WM_CAP_PAL_SAVEW              :: 0x04b5
-IE_GETAPPDATA                 :: 0x04b8
-IE_SETAPPDATA                 :: 0x04b9
-IE_GETDRAWOPTS                :: 0x04ba
-IE_SETDRAWOPTS                :: 0x04bb
-IE_GETFORMAT                  :: 0x04bc
-IE_SETFORMAT                  :: 0x04bd
-IE_GETINKINPUT                :: 0x04be
-IE_SETINKINPUT                :: 0x04bf
-IE_GETNOTIFY                  :: 0x04c0
-IE_SETNOTIFY                  :: 0x04c1
-IE_GETRECOG                   :: 0x04c2
-IE_SETRECOG                   :: 0x04c3
-IE_GETSECURITY                :: 0x04c4
-IE_SETSECURITY                :: 0x04c5
-IE_GETSEL                     :: 0x04c6
-IE_SETSEL                     :: 0x04c7
-CDM_LAST                      :: 0x04c8
-EM_SETBIDIOPTIONS             :: 0x04c8
-IE_DOCOMMAND                  :: 0x04c8
-MCIWNDM_NOTIFYMODE            :: 0x04c8
-EM_GETBIDIOPTIONS             :: 0x04c9
-IE_GETCOMMAND                 :: 0x04c9
-EM_SETTYPOGRAPHYOPTIONS       :: 0x04ca
-IE_GETCOUNT                   :: 0x04ca
-EM_GETTYPOGRAPHYOPTIONS       :: 0x04cb
-IE_GETGESTURE                 :: 0x04cb
-MCIWNDM_NOTIFYMEDIA           :: 0x04cb
-EM_SETEDITSTYLE               :: 0x04cc
-IE_GETMENU                    :: 0x04cc
-EM_GETEDITSTYLE               :: 0x04cd
-IE_GETPAINTDC                 :: 0x04cd
-MCIWNDM_NOTIFYERROR           :: 0x04cd
-IE_GETPDEVENT                 :: 0x04ce
-IE_GETSELCOUNT                :: 0x04cf
-IE_GETSELITEMS                :: 0x04d0
-IE_GETSTYLE                   :: 0x04d1
-MCIWNDM_SETTIMEFORMATW        :: 0x04db
-EM_OUTLINE                    :: 0x04dc
-MCIWNDM_GETTIMEFORMATW        :: 0x04dc
-EM_GETSCROLLPOS               :: 0x04dd
-EM_SETSCROLLPOS               :: 0x04de
-EM_SETFONTSIZE                :: 0x04df
-EM_GETZOOM                    :: 0x04e0
-MCIWNDM_GETFILENAMEW          :: 0x04e0
-EM_SETZOOM                    :: 0x04e1
-MCIWNDM_GETDEVICEW            :: 0x04e1
-EM_GETVIEWKIND                :: 0x04e2
-EM_SETVIEWKIND                :: 0x04e3
-EM_GETPAGE                    :: 0x04e4
-MCIWNDM_GETERRORW             :: 0x04e4
-EM_SETPAGE                    :: 0x04e5
-EM_GETHYPHENATEINFO           :: 0x04e6
-EM_SETHYPHENATEINFO           :: 0x04e7
-EM_GETPAGEROTATE              :: 0x04eb
-EM_SETPAGEROTATE              :: 0x04ec
-EM_GETCTFMODEBIAS             :: 0x04ed
-EM_SETCTFMODEBIAS             :: 0x04ee
-EM_GETCTFOPENSTATUS           :: 0x04f0
-EM_SETCTFOPENSTATUS           :: 0x04f1
-EM_GETIMECOMPTEXT             :: 0x04f2
-EM_ISIME                      :: 0x04f3
-EM_GETIMEPROPERTY             :: 0x04f4
-EM_GETQUERYRTFOBJ             :: 0x050d
-EM_SETQUERYRTFOBJ             :: 0x050e
-FM_GETFOCUS                   :: 0x0600
-FM_GETDRIVEINFOA              :: 0x0601
-FM_GETSELCOUNT                :: 0x0602
-FM_GETSELCOUNTLFN             :: 0x0603
-FM_GETFILESELA                :: 0x0604
-FM_GETFILESELLFNA             :: 0x0605
-FM_REFRESH_WINDOWS            :: 0x0606
-FM_RELOAD_EXTENSIONS          :: 0x0607
-FM_GETDRIVEINFOW              :: 0x0611
-FM_GETFILESELW                :: 0x0614
-FM_GETFILESELLFNW             :: 0x0615
-WLX_WM_SAS                    :: 0x0659
-SM_GETSELCOUNT                :: 0x07e8
-UM_GETSELCOUNT                :: 0x07e8
-WM_CPL_LAUNCH                 :: 0x07e8
-SM_GETSERVERSELA              :: 0x07e9
-UM_GETUSERSELA                :: 0x07e9
-WM_CPL_LAUNCHED               :: 0x07e9
-SM_GETSERVERSELW              :: 0x07ea
-UM_GETUSERSELW                :: 0x07ea
-SM_GETCURFOCUSA               :: 0x07eb
-UM_GETGROUPSELA               :: 0x07eb
-SM_GETCURFOCUSW               :: 0x07ec
-UM_GETGROUPSELW               :: 0x07ec
-SM_GETOPTIONS                 :: 0x07ed
-UM_GETCURFOCUSA               :: 0x07ed
-UM_GETCURFOCUSW               :: 0x07ee
-UM_GETOPTIONS                 :: 0x07ef
-UM_GETOPTIONS2                :: 0x07f0
-LVM_FIRST                     :: 0x1000
-LVM_GETBKCOLOR                :: 0x1000
-LVM_SETBKCOLOR                :: 0x1001
-LVM_GETIMAGELIST              :: 0x1002
-LVM_SETIMAGELIST              :: 0x1003
-LVM_GETITEMCOUNT              :: 0x1004
-LVM_GETITEMA                  :: 0x1005
-LVM_SETITEMA                  :: 0x1006
-LVM_INSERTITEMA               :: 0x1007
-LVM_DELETEITEM                :: 0x1008
-LVM_DELETEALLITEMS            :: 0x1009
-LVM_GETCALLBACKMASK           :: 0x100a
-LVM_SETCALLBACKMASK           :: 0x100b
-LVM_GETNEXTITEM               :: 0x100c
-LVM_FINDITEMA                 :: 0x100d
-LVM_GETITEMRECT               :: 0x100e
-LVM_SETITEMPOSITION           :: 0x100f
-LVM_GETITEMPOSITION           :: 0x1010
-LVM_GETSTRINGWIDTHA           :: 0x1011
-LVM_HITTEST                   :: 0x1012
-LVM_ENSUREVISIBLE             :: 0x1013
-LVM_SCROLL                    :: 0x1014
-LVM_REDRAWITEMS               :: 0x1015
-LVM_ARRANGE                   :: 0x1016
-LVM_EDITLABELA                :: 0x1017
-LVM_GETEDITCONTROL            :: 0x1018
-LVM_GETCOLUMNA                :: 0x1019
-LVM_SETCOLUMNA                :: 0x101a
-LVM_INSERTCOLUMNA             :: 0x101b
-LVM_DELETECOLUMN              :: 0x101c
-LVM_GETCOLUMNWIDTH            :: 0x101d
-LVM_SETCOLUMNWIDTH            :: 0x101e
-LVM_GETHEADER                 :: 0x101f
-LVM_CREATEDRAGIMAGE           :: 0x1021
-LVM_GETVIEWRECT               :: 0x1022
-LVM_GETTEXTCOLOR              :: 0x1023
-LVM_SETTEXTCOLOR              :: 0x1024
-LVM_GETTEXTBKCOLOR            :: 0x1025
-LVM_SETTEXTBKCOLOR            :: 0x1026
-LVM_GETTOPINDEX               :: 0x1027
-LVM_GETCOUNTPERPAGE           :: 0x1028
-LVM_GETORIGIN                 :: 0x1029
-LVM_UPDATE                    :: 0x102a
-LVM_SETITEMSTATE              :: 0x102b
-LVM_GETITEMSTATE              :: 0x102c
-LVM_GETITEMTEXTA              :: 0x102d
-LVM_SETITEMTEXTA              :: 0x102e
-LVM_SETITEMCOUNT              :: 0x102f
-LVM_SORTITEMS                 :: 0x1030
-LVM_SETITEMPOSITION32         :: 0x1031
-LVM_GETSELECTEDCOUNT          :: 0x1032
-LVM_GETITEMSPACING            :: 0x1033
-LVM_GETISEARCHSTRINGA         :: 0x1034
-LVM_SETICONSPACING            :: 0x1035
-LVM_SETEXTENDEDLISTVIEWSTYLE  :: 0x1036
-LVM_GETEXTENDEDLISTVIEWSTYLE  :: 0x1037
-LVM_GETSUBITEMRECT            :: 0x1038
-LVM_SUBITEMHITTEST            :: 0x1039
-LVM_SETCOLUMNORDERARRAY       :: 0x103a
-LVM_GETCOLUMNORDERARRAY       :: 0x103b
-LVM_SETHOTITEM                :: 0x103c
-LVM_GETHOTITEM                :: 0x103d
-LVM_SETHOTCURSOR              :: 0x103e
-LVM_GETHOTCURSOR              :: 0x103f
-LVM_APPROXIMATEVIEWRECT       :: 0x1040
-LVM_SETWORKAREAS              :: 0x1041
-LVM_GETSELECTIONMARK          :: 0x1042
-LVM_SETSELECTIONMARK          :: 0x1043
-LVM_SETBKIMAGEA               :: 0x1044
-LVM_GETBKIMAGEA               :: 0x1045
-LVM_GETWORKAREAS              :: 0x1046
-LVM_SETHOVERTIME              :: 0x1047
-LVM_GETHOVERTIME              :: 0x1048
-LVM_GETNUMBEROFWORKAREAS      :: 0x1049
-LVM_SETTOOLTIPS               :: 0x104a
-LVM_GETITEMW                  :: 0x104b
-LVM_SETITEMW                  :: 0x104c
-LVM_INSERTITEMW               :: 0x104d
-LVM_GETTOOLTIPS               :: 0x104e
-LVM_FINDITEMW                 :: 0x1053
-LVM_GETSTRINGWIDTHW           :: 0x1057
-LVM_GETCOLUMNW                :: 0x105f
-LVM_SETCOLUMNW                :: 0x1060
-LVM_INSERTCOLUMNW             :: 0x1061
-LVM_GETITEMTEXTW              :: 0x1073
-LVM_SETITEMTEXTW              :: 0x1074
-LVM_GETISEARCHSTRINGW         :: 0x1075
-LVM_EDITLABELW                :: 0x1076
-LVM_GETBKIMAGEW               :: 0x108b
-LVM_SETSELECTEDCOLUMN         :: 0x108c
-LVM_SETTILEWIDTH              :: 0x108d
-LVM_SETVIEW                   :: 0x108e
-LVM_GETVIEW                   :: 0x108f
-LVM_INSERTGROUP               :: 0x1091
-LVM_SETGROUPINFO              :: 0x1093
-LVM_GETGROUPINFO              :: 0x1095
-LVM_REMOVEGROUP               :: 0x1096
-LVM_MOVEGROUP                 :: 0x1097
-LVM_MOVEITEMTOGROUP           :: 0x109a
-LVM_SETGROUPMETRICS           :: 0x109b
-LVM_GETGROUPMETRICS           :: 0x109c
-LVM_ENABLEGROUPVIEW           :: 0x109d
-LVM_SORTGROUPS                :: 0x109e
-LVM_INSERTGROUPSORTED         :: 0x109f
-LVM_REMOVEALLGROUPS           :: 0x10a0
-LVM_HASGROUP                  :: 0x10a1
-LVM_SETTILEVIEWINFO           :: 0x10a2
-LVM_GETTILEVIEWINFO           :: 0x10a3
-LVM_SETTILEINFO               :: 0x10a4
-LVM_GETTILEINFO               :: 0x10a5
-LVM_SETINSERTMARK             :: 0x10a6
-LVM_GETINSERTMARK             :: 0x10a7
-LVM_INSERTMARKHITTEST         :: 0x10a8
-LVM_GETINSERTMARKRECT         :: 0x10a9
-LVM_SETINSERTMARKCOLOR        :: 0x10aa
-LVM_GETINSERTMARKCOLOR        :: 0x10ab
-LVM_SETINFOTIP                :: 0x10ad
-LVM_GETSELECTEDCOLUMN         :: 0x10ae
-LVM_ISGROUPVIEWENABLED        :: 0x10af
-LVM_GETOUTLINECOLOR           :: 0x10b0
-LVM_SETOUTLINECOLOR           :: 0x10b1
-LVM_CANCELEDITLABEL           :: 0x10b3
-LVM_MAPINDEXTOID              :: 0x10b4
-LVM_MAPIDTOINDEX              :: 0x10b5
-LVM_ISITEMVISIBLE             :: 0x10b6
-LVM_GETEMPTYTEXT              :: 0x10cc
-LVM_GETFOOTERRECT             :: 0x10cd
-LVM_GETFOOTERINFO             :: 0x10ce
-LVM_GETFOOTERITEMRECT         :: 0x10cf
-LVM_GETFOOTERITEM             :: 0x10d0
-LVM_GETITEMINDEXRECT          :: 0x10d1
-LVM_SETITEMINDEXSTATE         :: 0x10d2
-LVM_GETNEXTITEMINDEX          :: 0x10d3
-OCM__BASE                     :: 0x2000
-LVM_SETUNICODEFORMAT          :: 0x2005
-LVM_GETUNICODEFORMAT          :: 0x2006
-OCM_CTLCOLOR                  :: 0x2019
-OCM_DRAWITEM                  :: 0x202b
-OCM_MEASUREITEM               :: 0x202c
-OCM_DELETEITEM                :: 0x202d
-OCM_VKEYTOITEM                :: 0x202e
-OCM_CHARTOITEM                :: 0x202f
-OCM_COMPAREITEM               :: 0x2039
-OCM_NOTIFY                    :: 0x204e
-OCM_COMMAND                   :: 0x2111
-OCM_HSCROLL                   :: 0x2114
-OCM_VSCROLL                   :: 0x2115
-OCM_CTLCOLORMSGBOX            :: 0x2132
-OCM_CTLCOLOREDIT              :: 0x2133
-OCM_CTLCOLORLISTBOX           :: 0x2134
-OCM_CTLCOLORBTN               :: 0x2135
-OCM_CTLCOLORDLG               :: 0x2136
-OCM_CTLCOLORSCROLLBAR         :: 0x2137
-OCM_CTLCOLORSTATIC            :: 0x2138
-OCM_PARENTNOTIFY              :: 0x2210
-WM_APP                        :: 0x8000
-WM_RASDIALEVENT               :: 0xcccd
+WM_GETTITLEBARINFOEX              :: 0x033F
+WM_HANDHELDFIRST                  :: 0x0358
+WM_HANDHELDLAST                   :: 0x035f
+WM_AFXFIRST                       :: 0x0360
+WM_AFXLAST                        :: 0x037f
+WM_PENWINFIRST                    :: 0x0380
+WM_RCRESULT                       :: 0x0381
+WM_HOOKRCRESULT                   :: 0x0382
+WM_GLOBALRCCHANGE                 :: 0x0383
+WM_PENMISCINFO                    :: 0x0383
+WM_SKB                            :: 0x0384
+WM_HEDITCTL                       :: 0x0385
+WM_PENCTL                         :: 0x0385
+WM_PENMISC                        :: 0x0386
+WM_CTLINIT                        :: 0x0387
+WM_PENEVENT                       :: 0x0388
+WM_PENWINLAST                     :: 0x038f
+DDM_SETFMT                        :: 0x0400
+DM_GETDEFID                       :: 0x0400
+NIN_SELECT                        :: 0x0400
+TBM_GETPOS                        :: 0x0400
+WM_PSD_PAGESETUPDLG               :: 0x0400
+WM_USER                           :: 0x0400
+CBEM_INSERTITEMA                  :: 0x0401
+DDM_DRAW                          :: 0x0401
+DM_SETDEFID                       :: 0x0401
+HKM_SETHOTKEY                     :: 0x0401
+PBM_SETRANGE                      :: 0x0401
+RB_INSERTBANDA                    :: 0x0401
+SB_SETTEXTA                       :: 0x0401
+TB_ENABLEBUTTON                   :: 0x0401
+TBM_GETRANGEMIN                   :: 0x0401
+TTM_ACTIVATE                      :: 0x0401
+WM_CHOOSEFONT_GETLOGFONT          :: 0x0401
+WM_PSD_FULLPAGERECT               :: 0x0401
+CBEM_SETIMAGELIST                 :: 0x0402
+DDM_CLOSE                         :: 0x0402
+DM_REPOSITION                     :: 0x0402
+HKM_GETHOTKEY                     :: 0x0402
+PBM_SETPOS                        :: 0x0402
+RB_DELETEBAND                     :: 0x0402
+SB_GETTEXTA                       :: 0x0402
+TB_CHECKBUTTON                    :: 0x0402
+TBM_GETRANGEMAX                   :: 0x0402
+WM_PSD_MINMARGINRECT              :: 0x0402
+CBEM_GETIMAGELIST                 :: 0x0403
+DDM_BEGIN                         :: 0x0403
+HKM_SETRULES                      :: 0x0403
+PBM_DELTAPOS                      :: 0x0403
+RB_GETBARINFO                     :: 0x0403
+SB_GETTEXTLENGTHA                 :: 0x0403
+TBM_GETTIC                        :: 0x0403
+TB_PRESSBUTTON                    :: 0x0403
+TTM_SETDELAYTIME                  :: 0x0403
+WM_PSD_MARGINRECT                 :: 0x0403
+CBEM_GETITEMA                     :: 0x0404
+DDM_END                           :: 0x0404
+PBM_SETSTEP                       :: 0x0404
+RB_SETBARINFO                     :: 0x0404
+SB_SETPARTS                       :: 0x0404
+TB_HIDEBUTTON                     :: 0x0404
+TBM_SETTIC                        :: 0x0404
+TTM_ADDTOOLA                      :: 0x0404
+WM_PSD_GREEKTEXTRECT              :: 0x0404
+CBEM_SETITEMA                     :: 0x0405
+PBM_STEPIT                        :: 0x0405
+TB_INDETERMINATE                  :: 0x0405
+TBM_SETPOS                        :: 0x0405
+TTM_DELTOOLA                      :: 0x0405
+WM_PSD_ENVSTAMPRECT               :: 0x0405
+CBEM_GETCOMBOCONTROL              :: 0x0406
+PBM_SETRANGE32                    :: 0x0406
+RB_SETBANDINFOA                   :: 0x0406
+SB_GETPARTS                       :: 0x0406
+TB_MARKBUTTON                     :: 0x0406
+TBM_SETRANGE                      :: 0x0406
+TTM_NEWTOOLRECTA                  :: 0x0406
+WM_PSD_YAFULLPAGERECT             :: 0x0406
+CBEM_GETEDITCONTROL               :: 0x0407
+PBM_GETRANGE                      :: 0x0407
+RB_SETPARENT                      :: 0x0407
+SB_GETBORDERS                     :: 0x0407
+TBM_SETRANGEMIN                   :: 0x0407
+TTM_RELAYEVENT                    :: 0x0407
+CBEM_SETEXSTYLE                   :: 0x0408
+PBM_GETPOS                        :: 0x0408
+RB_HITTEST                        :: 0x0408
+SB_SETMINHEIGHT                   :: 0x0408
+TBM_SETRANGEMAX                   :: 0x0408
+TTM_GETTOOLINFOA                  :: 0x0408
+CBEM_GETEXSTYLE                   :: 0x0409
+CBEM_GETEXTENDEDSTYLE             :: 0x0409
+PBM_SETBARCOLOR                   :: 0x0409
+RB_GETRECT                        :: 0x0409
+SB_SIMPLE                         :: 0x0409
+TB_ISBUTTONENABLED                :: 0x0409
+TBM_CLEARTICS                     :: 0x0409
+TTM_SETTOOLINFOA                  :: 0x0409
+CBEM_HASEDITCHANGED               :: 0x040a
+PBM_SETMARQUEE                    :: 0x040a
+RB_INSERTBANDW                    :: 0x040a
+SB_GETRECT                        :: 0x040a
+TB_ISBUTTONCHECKED                :: 0x040a
+TBM_SETSEL                        :: 0x040a
+TTM_HITTESTA                      :: 0x040a
+WIZ_QUERYNUMPAGES                 :: 0x040a
+CBEM_INSERTITEMW                  :: 0x040b
+RB_SETBANDINFOW                   :: 0x040b
+SB_SETTEXTW                       :: 0x040b
+TB_ISBUTTONPRESSED                :: 0x040b
+TBM_SETSELSTART                   :: 0x040b
+TTM_GETTEXTA                      :: 0x040b
+WIZ_NEXT                          :: 0x040b
+CBEM_SETITEMW                     :: 0x040c
+RB_GETBANDCOUNT                   :: 0x040c
+SB_GETTEXTLENGTHW                 :: 0x040c
+TB_ISBUTTONHIDDEN                 :: 0x040c
+TBM_SETSELEND                     :: 0x040c
+TTM_UPDATETIPTEXTA                :: 0x040c
+WIZ_PREV                          :: 0x040c
+CBEM_GETITEMW                     :: 0x040d
+RB_GETROWCOUNT                    :: 0x040d
+SB_GETTEXTW                       :: 0x040d
+TB_ISBUTTONINDETERMINATE          :: 0x040d
+TTM_GETTOOLCOUNT                  :: 0x040d
+CBEM_SETEXTENDEDSTYLE             :: 0x040e
+RB_GETROWHEIGHT                   :: 0x040e
+SB_ISSIMPLE                       :: 0x040e
+TB_ISBUTTONHIGHLIGHTED            :: 0x040e
+TBM_GETPTICS                      :: 0x040e
+TTM_ENUMTOOLSA                    :: 0x040e
+SB_SETICON                        :: 0x040f
+TBM_GETTICPOS                     :: 0x040f
+TTM_GETCURRENTTOOLA               :: 0x040f
+PBM_SETSTATE                      :: 0x0410
+RB_IDTOINDEX                      :: 0x0410
+SB_SETTIPTEXTA                    :: 0x0410
+TBM_GETNUMTICS                    :: 0x0410
+TTM_WINDOWFROMPOINT               :: 0x0410
+PBM_GETSTATE                      :: 0x0411
+RB_GETTOOLTIPS                    :: 0x0411
+SB_SETTIPTEXTW                    :: 0x0411
+TBM_GETSELSTART                   :: 0x0411
+TB_SETSTATE                       :: 0x0411
+TTM_TRACKACTIVATE                 :: 0x0411
+RB_SETTOOLTIPS                    :: 0x0412
+SB_GETTIPTEXTA                    :: 0x0412
+TB_GETSTATE                       :: 0x0412
+TBM_GETSELEND                     :: 0x0412
+TTM_TRACKPOSITION                 :: 0x0412
+RB_SETBKCOLOR                     :: 0x0413
+SB_GETTIPTEXTW                    :: 0x0413
+TB_ADDBITMAP                      :: 0x0413
+TBM_CLEARSEL                      :: 0x0413
+TTM_SETTIPBKCOLOR                 :: 0x0413
+RB_GETBKCOLOR                     :: 0x0414
+SB_GETICON                        :: 0x0414
+TB_ADDBUTTONSA                    :: 0x0414
+TBM_SETTICFREQ                    :: 0x0414
+TTM_SETTIPTEXTCOLOR               :: 0x0414
+RB_SETTEXTCOLOR                   :: 0x0415
+TB_INSERTBUTTONA                  :: 0x0415
+TBM_SETPAGESIZE                   :: 0x0415
+TTM_GETDELAYTIME                  :: 0x0415
+RB_GETTEXTCOLOR                   :: 0x0416
+TB_DELETEBUTTON                   :: 0x0416
+TBM_GETPAGESIZE                   :: 0x0416
+TTM_GETTIPBKCOLOR                 :: 0x0416
+RB_SIZETORECT                     :: 0x0417
+TB_GETBUTTON                      :: 0x0417
+TBM_SETLINESIZE                   :: 0x0417
+TTM_GETTIPTEXTCOLOR               :: 0x0417
+RB_BEGINDRAG                      :: 0x0418
+TB_BUTTONCOUNT                    :: 0x0418
+TBM_GETLINESIZE                   :: 0x0418
+TTM_SETMAXTIPWIDTH                :: 0x0418
+RB_ENDDRAG                        :: 0x0419
+TB_COMMANDTOINDEX                 :: 0x0419
+TBM_GETTHUMBRECT                  :: 0x0419
+TTM_GETMAXTIPWIDTH                :: 0x0419
+RB_DRAGMOVE                       :: 0x041a
+TBM_GETCHANNELRECT                :: 0x041a
+TB_SAVERESTOREA                   :: 0x041a
+TTM_SETMARGIN                     :: 0x041a
+RB_GETBARHEIGHT                   :: 0x041b
+TB_CUSTOMIZE                      :: 0x041b
+TBM_SETTHUMBLENGTH                :: 0x041b
+TTM_GETMARGIN                     :: 0x041b
+RB_GETBANDINFOW                   :: 0x041c
+TB_ADDSTRINGA                     :: 0x041c
+TBM_GETTHUMBLENGTH                :: 0x041c
+TTM_POP                           :: 0x041c
+RB_GETBANDINFOA                   :: 0x041d
+TB_GETITEMRECT                    :: 0x041d
+TBM_SETTOOLTIPS                   :: 0x041d
+TTM_UPDATE                        :: 0x041d
+RB_MINIMIZEBAND                   :: 0x041e
+TB_BUTTONSTRUCTSIZE               :: 0x041e
+TBM_GETTOOLTIPS                   :: 0x041e
+TTM_GETBUBBLESIZE                 :: 0x041e
+RB_MAXIMIZEBAND                   :: 0x041f
+TBM_SETTIPSIDE                    :: 0x041f
+TB_SETBUTTONSIZE                  :: 0x041f
+TTM_ADJUSTRECT                    :: 0x041f
+TBM_SETBUDDY                      :: 0x0420
+TB_SETBITMAPSIZE                  :: 0x0420
+TTM_SETTITLEA                     :: 0x0420
+MSG_FTS_JUMP_VA                   :: 0x0421
+TB_AUTOSIZE                       :: 0x0421
+TBM_GETBUDDY                      :: 0x0421
+TTM_SETTITLEW                     :: 0x0421
+RB_GETBANDBORDERS                 :: 0x0422
+MSG_FTS_JUMP_QWORD                :: 0x0423
+RB_SHOWBAND                       :: 0x0423
+TB_GETTOOLTIPS                    :: 0x0423
+MSG_REINDEX_REQUEST               :: 0x0424
+TB_SETTOOLTIPS                    :: 0x0424
+MSG_FTS_WHERE_IS_IT               :: 0x0425
+RB_SETPALETTE                     :: 0x0425
+TB_SETPARENT                      :: 0x0425
+RB_GETPALETTE                     :: 0x0426
+RB_MOVEBAND                       :: 0x0427
+TB_SETROWS                        :: 0x0427
+TB_GETROWS                        :: 0x0428
+TB_GETBITMAPFLAGS                 :: 0x0429
+TB_SETCMDID                       :: 0x042a
+RB_PUSHCHEVRON                    :: 0x042b
+TB_CHANGEBITMAP                   :: 0x042b
+TB_GETBITMAP                      :: 0x042c
+MSG_GET_DEFFONT                   :: 0x042d
+TB_GETBUTTONTEXTA                 :: 0x042d
+TB_REPLACEBITMAP                  :: 0x042e
+TB_SETINDENT                      :: 0x042f
+TB_SETIMAGELIST                   :: 0x0430
+TB_GETIMAGELIST                   :: 0x0431
+TB_LOADIMAGES                     :: 0x0432
+EM_CANPASTE                       :: 0x0432
+TTM_ADDTOOLW                      :: 0x0432
+EM_DISPLAYBAND                    :: 0x0433
+TB_GETRECT                        :: 0x0433
+TTM_DELTOOLW                      :: 0x0433
+EM_EXGETSEL                       :: 0x0434
+TB_SETHOTIMAGELIST                :: 0x0434
+TTM_NEWTOOLRECTW                  :: 0x0434
+EM_EXLIMITTEXT                    :: 0x0435
+TB_GETHOTIMAGELIST                :: 0x0435
+TTM_GETTOOLINFOW                  :: 0x0435
+EM_EXLINEFROMCHAR                 :: 0x0436
+TB_SETDISABLEDIMAGELIST           :: 0x0436
+TTM_SETTOOLINFOW                  :: 0x0436
+EM_EXSETSEL                       :: 0x0437
+TB_GETDISABLEDIMAGELIST           :: 0x0437
+TTM_HITTESTW                      :: 0x0437
+EM_FINDTEXT                       :: 0x0438
+TB_SETSTYLE                       :: 0x0438
+TTM_GETTEXTW                      :: 0x0438
+EM_FORMATRANGE                    :: 0x0439
+TB_GETSTYLE                       :: 0x0439
+TTM_UPDATETIPTEXTW                :: 0x0439
+EM_GETCHARFORMAT                  :: 0x043a
+TB_GETBUTTONSIZE                  :: 0x043a
+TTM_ENUMTOOLSW                    :: 0x043a
+EM_GETEVENTMASK                   :: 0x043b
+TB_SETBUTTONWIDTH                 :: 0x043b
+TTM_GETCURRENTTOOLW               :: 0x043b
+EM_GETOLEINTERFACE                :: 0x043c
+TB_SETMAXTEXTROWS                 :: 0x043c
+EM_GETPARAFORMAT                  :: 0x043d
+TB_GETTEXTROWS                    :: 0x043d
+EM_GETSELTEXT                     :: 0x043e
+TB_GETOBJECT                      :: 0x043e
+EM_HIDESELECTION                  :: 0x043f
+TB_GETBUTTONINFOW                 :: 0x043f
+EM_PASTESPECIAL                   :: 0x0440
+TB_SETBUTTONINFOW                 :: 0x0440
+EM_REQUESTRESIZE                  :: 0x0441
+TB_GETBUTTONINFOA                 :: 0x0441
+EM_SELECTIONTYPE                  :: 0x0442
+TB_SETBUTTONINFOA                 :: 0x0442
+EM_SETBKGNDCOLOR                  :: 0x0443
+TB_INSERTBUTTONW                  :: 0x0443
+EM_SETCHARFORMAT                  :: 0x0444
+TB_ADDBUTTONSW                    :: 0x0444
+EM_SETEVENTMASK                   :: 0x0445
+TB_HITTEST                        :: 0x0445
+EM_SETOLECALLBACK                 :: 0x0446
+TB_SETDRAWTEXTFLAGS               :: 0x0446
+EM_SETPARAFORMAT                  :: 0x0447
+TB_GETHOTITEM                     :: 0x0447
+EM_SETTARGETDEVICE                :: 0x0448
+TB_SETHOTITEM                     :: 0x0448
+EM_STREAMIN                       :: 0x0449
+TB_SETANCHORHIGHLIGHT             :: 0x0449
+EM_STREAMOUT                      :: 0x044a
+TB_GETANCHORHIGHLIGHT             :: 0x044a
+EM_GETTEXTRANGE                   :: 0x044b
+TB_GETBUTTONTEXTW                 :: 0x044b
+EM_FINDWORDBREAK                  :: 0x044c
+TB_SAVERESTOREW                   :: 0x044c
+EM_SETOPTIONS                     :: 0x044d
+TB_ADDSTRINGW                     :: 0x044d
+EM_GETOPTIONS                     :: 0x044e
+TB_MAPACCELERATORA                :: 0x044e
+EM_FINDTEXTEX                     :: 0x044f
+TB_GETINSERTMARK                  :: 0x044f
+EM_GETWORDBREAKPROCEX             :: 0x0450
+TB_SETINSERTMARK                  :: 0x0450
+EM_SETWORDBREAKPROCEX             :: 0x0451
+TB_INSERTMARKHITTEST              :: 0x0451
+EM_SETUNDOLIMIT                   :: 0x0452
+TB_MOVEBUTTON                     :: 0x0452
+TB_GETMAXSIZE                     :: 0x0453
+EM_REDO                           :: 0x0454
+TB_SETEXTENDEDSTYLE               :: 0x0454
+EM_CANREDO                        :: 0x0455
+TB_GETEXTENDEDSTYLE               :: 0x0455
+EM_GETUNDONAME                    :: 0x0456
+TB_GETPADDING                     :: 0x0456
+EM_GETREDONAME                    :: 0x0457
+TB_SETPADDING                     :: 0x0457
+EM_STOPGROUPTYPING                :: 0x0458
+TB_SETINSERTMARKCOLOR             :: 0x0458
+EM_SETTEXTMODE                    :: 0x0459
+TB_GETINSERTMARKCOLOR             :: 0x0459
+EM_GETTEXTMODE                    :: 0x045a
+TB_MAPACCELERATORW                :: 0x045a
+EM_AUTOURLDETECT                  :: 0x045b
+TB_GETSTRINGW                     :: 0x045b
+EM_GETAUTOURLDETECT               :: 0x045c
+TB_GETSTRINGA                     :: 0x045c
+EM_SETPALETTE                     :: 0x045d
+EM_GETTEXTEX                      :: 0x045e
+EM_GETTEXTLENGTHEX                :: 0x045f
+EM_SHOWSCROLLBAR                  :: 0x0460
+EM_SETTEXTEX                      :: 0x0461
+TAPI_REPLY                        :: 0x0463
+ACM_OPENA                         :: 0x0464
+BFFM_SETSTATUSTEXTA               :: 0x0464
+CDM_FIRST                         :: 0x0464
+CDM_GETSPEC                       :: 0x0464
+EM_SETPUNCTUATION                 :: 0x0464
+IPM_CLEARADDRESS                  :: 0x0464
+WM_CAP_UNICODE_START              :: 0x0464
+ACM_PLAY                          :: 0x0465
+BFFM_ENABLEOK                     :: 0x0465
+CDM_GETFILEPATH                   :: 0x0465
+EM_GETPUNCTUATION                 :: 0x0465
+IPM_SETADDRESS                    :: 0x0465
+PSM_SETCURSEL                     :: 0x0465
+UDM_SETRANGE                      :: 0x0465
+WM_CHOOSEFONT_SETLOGFONT          :: 0x0465
+ACM_STOP                          :: 0x0466
+BFFM_SETSELECTIONA                :: 0x0466
+CDM_GETFOLDERPATH                 :: 0x0466
+EM_SETWORDWRAPMODE                :: 0x0466
+IPM_GETADDRESS                    :: 0x0466
+PSM_REMOVEPAGE                    :: 0x0466
+UDM_GETRANGE                      :: 0x0466
+WM_CAP_SET_CALLBACK_ERRORW        :: 0x0466
+WM_CHOOSEFONT_SETFLAGS            :: 0x0466
+ACM_OPENW                         :: 0x0467
+BFFM_SETSELECTIONW                :: 0x0467
+CDM_GETFOLDERIDLIST               :: 0x0467
+EM_GETWORDWRAPMODE                :: 0x0467
+IPM_SETRANGE                      :: 0x0467
+PSM_ADDPAGE                       :: 0x0467
+UDM_SETPOS                        :: 0x0467
+WM_CAP_SET_CALLBACK_STATUSW       :: 0x0467
+BFFM_SETSTATUSTEXTW               :: 0x0468
+CDM_SETCONTROLTEXT                :: 0x0468
+EM_SETIMECOLOR                    :: 0x0468
+IPM_SETFOCUS                      :: 0x0468
+PSM_CHANGED                       :: 0x0468
+UDM_GETPOS                        :: 0x0468
+CDM_HIDECONTROL                   :: 0x0469
+EM_GETIMECOLOR                    :: 0x0469
+IPM_ISBLANK                       :: 0x0469
+PSM_RESTARTWINDOWS                :: 0x0469
+UDM_SETBUDDY                      :: 0x0469
+CDM_SETDEFEXT                     :: 0x046a
+EM_SETIMEOPTIONS                  :: 0x046a
+PSM_REBOOTSYSTEM                  :: 0x046a
+UDM_GETBUDDY                      :: 0x046a
+EM_GETIMEOPTIONS                  :: 0x046b
+PSM_CANCELTOCLOSE                 :: 0x046b
+UDM_SETACCEL                      :: 0x046b
+EM_CONVPOSITION                   :: 0x046c
+PSM_QUERYSIBLINGS                 :: 0x046c
+UDM_GETACCEL                      :: 0x046c
+MCIWNDM_GETZOOM                   :: 0x046d
+PSM_UNCHANGED                     :: 0x046d
+UDM_SETBASE                       :: 0x046d
+PSM_APPLY                         :: 0x046e
+UDM_GETBASE                       :: 0x046e
+PSM_SETTITLEA                     :: 0x046f
+UDM_SETRANGE32                    :: 0x046f
+PSM_SETWIZBUTTONS                 :: 0x0470
+UDM_GETRANGE32                    :: 0x0470
+WM_CAP_DRIVER_GET_NAMEW           :: 0x0470
+PSM_PRESSBUTTON                   :: 0x0471
+UDM_SETPOS32                      :: 0x0471
+WM_CAP_DRIVER_GET_VERSIONW        :: 0x0471
+PSM_SETCURSELID                   :: 0x0472
+UDM_GETPOS32                      :: 0x0472
+PSM_SETFINISHTEXTA                :: 0x0473
+PSM_GETTABCONTROL                 :: 0x0474
+PSM_ISDIALOGMESSAGE               :: 0x0475
+MCIWNDM_REALIZE                   :: 0x0476
+PSM_GETCURRENTPAGEHWND            :: 0x0476
+MCIWNDM_SETTIMEFORMATA            :: 0x0477
+PSM_INSERTPAGE                    :: 0x0477
+EM_SETLANGOPTIONS                 :: 0x0478
+MCIWNDM_GETTIMEFORMATA            :: 0x0478
+PSM_SETTITLEW                     :: 0x0478
+WM_CAP_FILE_SET_CAPTURE_FILEW     :: 0x0478
+EM_GETLANGOPTIONS                 :: 0x0479
+MCIWNDM_VALIDATEMEDIA             :: 0x0479
+PSM_SETFINISHTEXTW                :: 0x0479
+WM_CAP_FILE_GET_CAPTURE_FILEW     :: 0x0479
+EM_GETIMECOMPMODE                 :: 0x047a
+EM_FINDTEXTW                      :: 0x047b
+MCIWNDM_PLAYTO                    :: 0x047b
+WM_CAP_FILE_SAVEASW               :: 0x047b
+EM_FINDTEXTEXW                    :: 0x047c
+MCIWNDM_GETFILENAMEA              :: 0x047c
+EM_RECONVERSION                   :: 0x047d
+MCIWNDM_GETDEVICEA                :: 0x047d
+PSM_SETHEADERTITLEA               :: 0x047d
+WM_CAP_FILE_SAVEDIBW              :: 0x047d
+EM_SETIMEMODEBIAS                 :: 0x047e
+MCIWNDM_GETPALETTE                :: 0x047e
+PSM_SETHEADERTITLEW               :: 0x047e
+EM_GETIMEMODEBIAS                 :: 0x047f
+MCIWNDM_SETPALETTE                :: 0x047f
+PSM_SETHEADERSUBTITLEA            :: 0x047f
+MCIWNDM_GETERRORA                 :: 0x0480
+PSM_SETHEADERSUBTITLEW            :: 0x0480
+PSM_HWNDTOINDEX                   :: 0x0481
+PSM_INDEXTOHWND                   :: 0x0482
+MCIWNDM_SETINACTIVETIMER          :: 0x0483
+PSM_PAGETOINDEX                   :: 0x0483
+PSM_INDEXTOPAGE                   :: 0x0484
+DL_BEGINDRAG                      :: 0x0485
+MCIWNDM_GETINACTIVETIMER          :: 0x0485
+PSM_IDTOINDEX                     :: 0x0485
+DL_DRAGGING                       :: 0x0486
+PSM_INDEXTOID                     :: 0x0486
+DL_DROPPED                        :: 0x0487
+PSM_GETRESULT                     :: 0x0487
+DL_CANCELDRAG                     :: 0x0488
+PSM_RECALCPAGESIZES               :: 0x0488
+MCIWNDM_GET_SOURCE                :: 0x048c
+MCIWNDM_PUT_SOURCE                :: 0x048d
+MCIWNDM_GET_DEST                  :: 0x048e
+MCIWNDM_PUT_DEST                  :: 0x048f
+MCIWNDM_CAN_PLAY                  :: 0x0490
+MCIWNDM_CAN_WINDOW                :: 0x0491
+MCIWNDM_CAN_RECORD                :: 0x0492
+MCIWNDM_CAN_SAVE                  :: 0x0493
+MCIWNDM_CAN_EJECT                 :: 0x0494
+MCIWNDM_CAN_CONFIG                :: 0x0495
+IE_GETINK                         :: 0x0496
+IE_MSGFIRST                       :: 0x0496
+MCIWNDM_PALETTEKICK               :: 0x0496
+IE_SETINK                         :: 0x0497
+IE_GETPENTIP                      :: 0x0498
+IE_SETPENTIP                      :: 0x0499
+IE_GETERASERTIP                   :: 0x049a
+IE_SETERASERTIP                   :: 0x049b
+IE_GETBKGND                       :: 0x049c
+IE_SETBKGND                       :: 0x049d
+IE_GETGRIDORIGIN                  :: 0x049e
+IE_SETGRIDORIGIN                  :: 0x049f
+IE_GETGRIDPEN                     :: 0x04a0
+IE_SETGRIDPEN                     :: 0x04a1
+IE_GETGRIDSIZE                    :: 0x04a2
+IE_SETGRIDSIZE                    :: 0x04a3
+IE_GETMODE                        :: 0x04a4
+IE_SETMODE                        :: 0x04a5
+IE_GETINKRECT                     :: 0x04a6
+WM_CAP_SET_MCI_DEVICEW            :: 0x04a6
+WM_CAP_GET_MCI_DEVICEW            :: 0x04a7
+WM_CAP_PAL_OPENW                  :: 0x04b4
+WM_CAP_PAL_SAVEW                  :: 0x04b5
+IE_GETAPPDATA                     :: 0x04b8
+IE_SETAPPDATA                     :: 0x04b9
+IE_GETDRAWOPTS                    :: 0x04ba
+IE_SETDRAWOPTS                    :: 0x04bb
+IE_GETFORMAT                      :: 0x04bc
+IE_SETFORMAT                      :: 0x04bd
+IE_GETINKINPUT                    :: 0x04be
+IE_SETINKINPUT                    :: 0x04bf
+IE_GETNOTIFY                      :: 0x04c0
+IE_SETNOTIFY                      :: 0x04c1
+IE_GETRECOG                       :: 0x04c2
+IE_SETRECOG                       :: 0x04c3
+IE_GETSECURITY                    :: 0x04c4
+IE_SETSECURITY                    :: 0x04c5
+IE_GETSEL                         :: 0x04c6
+IE_SETSEL                         :: 0x04c7
+CDM_LAST                          :: 0x04c8
+EM_SETBIDIOPTIONS                 :: 0x04c8
+IE_DOCOMMAND                      :: 0x04c8
+MCIWNDM_NOTIFYMODE                :: 0x04c8
+EM_GETBIDIOPTIONS                 :: 0x04c9
+IE_GETCOMMAND                     :: 0x04c9
+EM_SETTYPOGRAPHYOPTIONS           :: 0x04ca
+IE_GETCOUNT                       :: 0x04ca
+EM_GETTYPOGRAPHYOPTIONS           :: 0x04cb
+IE_GETGESTURE                     :: 0x04cb
+MCIWNDM_NOTIFYMEDIA               :: 0x04cb
+EM_SETEDITSTYLE                   :: 0x04cc
+IE_GETMENU                        :: 0x04cc
+EM_GETEDITSTYLE                   :: 0x04cd
+IE_GETPAINTDC                     :: 0x04cd
+MCIWNDM_NOTIFYERROR               :: 0x04cd
+IE_GETPDEVENT                     :: 0x04ce
+IE_GETSELCOUNT                    :: 0x04cf
+IE_GETSELITEMS                    :: 0x04d0
+IE_GETSTYLE                       :: 0x04d1
+MCIWNDM_SETTIMEFORMATW            :: 0x04db
+EM_OUTLINE                        :: 0x04dc
+MCIWNDM_GETTIMEFORMATW            :: 0x04dc
+EM_GETSCROLLPOS                   :: 0x04dd
+EM_SETSCROLLPOS                   :: 0x04de
+EM_SETFONTSIZE                    :: 0x04df
+EM_GETZOOM                        :: 0x04e0
+MCIWNDM_GETFILENAMEW              :: 0x04e0
+EM_SETZOOM                        :: 0x04e1
+MCIWNDM_GETDEVICEW                :: 0x04e1
+EM_GETVIEWKIND                    :: 0x04e2
+EM_SETVIEWKIND                    :: 0x04e3
+EM_GETPAGE                        :: 0x04e4
+MCIWNDM_GETERRORW                 :: 0x04e4
+EM_SETPAGE                        :: 0x04e5
+EM_GETHYPHENATEINFO               :: 0x04e6
+EM_SETHYPHENATEINFO               :: 0x04e7
+EM_GETPAGEROTATE                  :: 0x04eb
+EM_SETPAGEROTATE                  :: 0x04ec
+EM_GETCTFMODEBIAS                 :: 0x04ed
+EM_SETCTFMODEBIAS                 :: 0x04ee
+EM_GETCTFOPENSTATUS               :: 0x04f0
+EM_SETCTFOPENSTATUS               :: 0x04f1
+EM_GETIMECOMPTEXT                 :: 0x04f2
+EM_ISIME                          :: 0x04f3
+EM_GETIMEPROPERTY                 :: 0x04f4
+EM_GETQUERYRTFOBJ                 :: 0x050d
+EM_SETQUERYRTFOBJ                 :: 0x050e
+FM_GETFOCUS                       :: 0x0600
+FM_GETDRIVEINFOA                  :: 0x0601
+FM_GETSELCOUNT                    :: 0x0602
+FM_GETSELCOUNTLFN                 :: 0x0603
+FM_GETFILESELA                    :: 0x0604
+FM_GETFILESELLFNA                 :: 0x0605
+FM_REFRESH_WINDOWS                :: 0x0606
+FM_RELOAD_EXTENSIONS              :: 0x0607
+FM_GETDRIVEINFOW                  :: 0x0611
+FM_GETFILESELW                    :: 0x0614
+FM_GETFILESELLFNW                 :: 0x0615
+WLX_WM_SAS                        :: 0x0659
+SM_GETSELCOUNT                    :: 0x07e8
+UM_GETSELCOUNT                    :: 0x07e8
+WM_CPL_LAUNCH                     :: 0x07e8
+SM_GETSERVERSELA                  :: 0x07e9
+UM_GETUSERSELA                    :: 0x07e9
+WM_CPL_LAUNCHED                   :: 0x07e9
+SM_GETSERVERSELW                  :: 0x07ea
+UM_GETUSERSELW                    :: 0x07ea
+SM_GETCURFOCUSA                   :: 0x07eb
+UM_GETGROUPSELA                   :: 0x07eb
+SM_GETCURFOCUSW                   :: 0x07ec
+UM_GETGROUPSELW                   :: 0x07ec
+SM_GETOPTIONS                     :: 0x07ed
+UM_GETCURFOCUSA                   :: 0x07ed
+UM_GETCURFOCUSW                   :: 0x07ee
+UM_GETOPTIONS                     :: 0x07ef
+UM_GETOPTIONS2                    :: 0x07f0
+LVM_FIRST                         :: 0x1000
+LVM_GETBKCOLOR                    :: 0x1000
+LVM_SETBKCOLOR                    :: 0x1001
+LVM_GETIMAGELIST                  :: 0x1002
+LVM_SETIMAGELIST                  :: 0x1003
+LVM_GETITEMCOUNT                  :: 0x1004
+LVM_GETITEMA                      :: 0x1005
+LVM_SETITEMA                      :: 0x1006
+LVM_INSERTITEMA                   :: 0x1007
+LVM_DELETEITEM                    :: 0x1008
+LVM_DELETEALLITEMS                :: 0x1009
+LVM_GETCALLBACKMASK               :: 0x100a
+LVM_SETCALLBACKMASK               :: 0x100b
+LVM_GETNEXTITEM                   :: 0x100c
+LVM_FINDITEMA                     :: 0x100d
+LVM_GETITEMRECT                   :: 0x100e
+LVM_SETITEMPOSITION               :: 0x100f
+LVM_GETITEMPOSITION               :: 0x1010
+LVM_GETSTRINGWIDTHA               :: 0x1011
+LVM_HITTEST                       :: 0x1012
+LVM_ENSUREVISIBLE                 :: 0x1013
+LVM_SCROLL                        :: 0x1014
+LVM_REDRAWITEMS                   :: 0x1015
+LVM_ARRANGE                       :: 0x1016
+LVM_EDITLABELA                    :: 0x1017
+LVM_GETEDITCONTROL                :: 0x1018
+LVM_GETCOLUMNA                    :: 0x1019
+LVM_SETCOLUMNA                    :: 0x101a
+LVM_INSERTCOLUMNA                 :: 0x101b
+LVM_DELETECOLUMN                  :: 0x101c
+LVM_GETCOLUMNWIDTH                :: 0x101d
+LVM_SETCOLUMNWIDTH                :: 0x101e
+LVM_GETHEADER                     :: 0x101f
+LVM_CREATEDRAGIMAGE               :: 0x1021
+LVM_GETVIEWRECT                   :: 0x1022
+LVM_GETTEXTCOLOR                  :: 0x1023
+LVM_SETTEXTCOLOR                  :: 0x1024
+LVM_GETTEXTBKCOLOR                :: 0x1025
+LVM_SETTEXTBKCOLOR                :: 0x1026
+LVM_GETTOPINDEX                   :: 0x1027
+LVM_GETCOUNTPERPAGE               :: 0x1028
+LVM_GETORIGIN                     :: 0x1029
+LVM_UPDATE                        :: 0x102a
+LVM_SETITEMSTATE                  :: 0x102b
+LVM_GETITEMSTATE                  :: 0x102c
+LVM_GETITEMTEXTA                  :: 0x102d
+LVM_SETITEMTEXTA                  :: 0x102e
+LVM_SETITEMCOUNT                  :: 0x102f
+LVM_SORTITEMS                     :: 0x1030
+LVM_SETITEMPOSITION32             :: 0x1031
+LVM_GETSELECTEDCOUNT              :: 0x1032
+LVM_GETITEMSPACING                :: 0x1033
+LVM_GETISEARCHSTRINGA             :: 0x1034
+LVM_SETICONSPACING                :: 0x1035
+LVM_SETEXTENDEDLISTVIEWSTYLE      :: 0x1036
+LVM_GETEXTENDEDLISTVIEWSTYLE      :: 0x1037
+LVM_GETSUBITEMRECT                :: 0x1038
+LVM_SUBITEMHITTEST                :: 0x1039
+LVM_SETCOLUMNORDERARRAY           :: 0x103a
+LVM_GETCOLUMNORDERARRAY           :: 0x103b
+LVM_SETHOTITEM                    :: 0x103c
+LVM_GETHOTITEM                    :: 0x103d
+LVM_SETHOTCURSOR                  :: 0x103e
+LVM_GETHOTCURSOR                  :: 0x103f
+LVM_APPROXIMATEVIEWRECT           :: 0x1040
+LVM_SETWORKAREAS                  :: 0x1041
+LVM_GETSELECTIONMARK              :: 0x1042
+LVM_SETSELECTIONMARK              :: 0x1043
+LVM_SETBKIMAGEA                   :: 0x1044
+LVM_GETBKIMAGEA                   :: 0x1045
+LVM_GETWORKAREAS                  :: 0x1046
+LVM_SETHOVERTIME                  :: 0x1047
+LVM_GETHOVERTIME                  :: 0x1048
+LVM_GETNUMBEROFWORKAREAS          :: 0x1049
+LVM_SETTOOLTIPS                   :: 0x104a
+LVM_GETITEMW                      :: 0x104b
+LVM_SETITEMW                      :: 0x104c
+LVM_INSERTITEMW                   :: 0x104d
+LVM_GETTOOLTIPS                   :: 0x104e
+LVM_FINDITEMW                     :: 0x1053
+LVM_GETSTRINGWIDTHW               :: 0x1057
+LVM_GETCOLUMNW                    :: 0x105f
+LVM_SETCOLUMNW                    :: 0x1060
+LVM_INSERTCOLUMNW                 :: 0x1061
+LVM_GETITEMTEXTW                  :: 0x1073
+LVM_SETITEMTEXTW                  :: 0x1074
+LVM_GETISEARCHSTRINGW             :: 0x1075
+LVM_EDITLABELW                    :: 0x1076
+LVM_GETBKIMAGEW                   :: 0x108b
+LVM_SETSELECTEDCOLUMN             :: 0x108c
+LVM_SETTILEWIDTH                  :: 0x108d
+LVM_SETVIEW                       :: 0x108e
+LVM_GETVIEW                       :: 0x108f
+LVM_INSERTGROUP                   :: 0x1091
+LVM_SETGROUPINFO                  :: 0x1093
+LVM_GETGROUPINFO                  :: 0x1095
+LVM_REMOVEGROUP                   :: 0x1096
+LVM_MOVEGROUP                     :: 0x1097
+LVM_MOVEITEMTOGROUP               :: 0x109a
+LVM_SETGROUPMETRICS               :: 0x109b
+LVM_GETGROUPMETRICS               :: 0x109c
+LVM_ENABLEGROUPVIEW               :: 0x109d
+LVM_SORTGROUPS                    :: 0x109e
+LVM_INSERTGROUPSORTED             :: 0x109f
+LVM_REMOVEALLGROUPS               :: 0x10a0
+LVM_HASGROUP                      :: 0x10a1
+LVM_SETTILEVIEWINFO               :: 0x10a2
+LVM_GETTILEVIEWINFO               :: 0x10a3
+LVM_SETTILEINFO                   :: 0x10a4
+LVM_GETTILEINFO                   :: 0x10a5
+LVM_SETINSERTMARK                 :: 0x10a6
+LVM_GETINSERTMARK                 :: 0x10a7
+LVM_INSERTMARKHITTEST             :: 0x10a8
+LVM_GETINSERTMARKRECT             :: 0x10a9
+LVM_SETINSERTMARKCOLOR            :: 0x10aa
+LVM_GETINSERTMARKCOLOR            :: 0x10ab
+LVM_SETINFOTIP                    :: 0x10ad
+LVM_GETSELECTEDCOLUMN             :: 0x10ae
+LVM_ISGROUPVIEWENABLED            :: 0x10af
+LVM_GETOUTLINECOLOR               :: 0x10b0
+LVM_SETOUTLINECOLOR               :: 0x10b1
+LVM_CANCELEDITLABEL               :: 0x10b3
+LVM_MAPINDEXTOID                  :: 0x10b4
+LVM_MAPIDTOINDEX                  :: 0x10b5
+LVM_ISITEMVISIBLE                 :: 0x10b6
+LVM_GETEMPTYTEXT                  :: 0x10cc
+LVM_GETFOOTERRECT                 :: 0x10cd
+LVM_GETFOOTERINFO                 :: 0x10ce
+LVM_GETFOOTERITEMRECT             :: 0x10cf
+LVM_GETFOOTERITEM                 :: 0x10d0
+LVM_GETITEMINDEXRECT              :: 0x10d1
+LVM_SETITEMINDEXSTATE             :: 0x10d2
+LVM_GETNEXTITEMINDEX              :: 0x10d3
+BCM_FIRST                         :: 0x1600
+BCM_SETDROPDOWNSTATE              :: BCM_FIRST + 0x0006
+BCM_SETSPLITINFO                  :: BCM_FIRST + 0x0007
+BCM_GETSPLITINFO                  :: BCM_FIRST + 0x0008
+BCM_SETNOTE                       :: BCM_FIRST + 0x0009
+BCM_GETNOTE                       :: BCM_FIRST + 0x000A
+BCM_GETNOTELENGTH                 :: BCM_FIRST + 0x000B
+BCM_SETSHIELD                     :: BCM_FIRST + 0x000C
+OCM__BASE                         :: 0x2000
+LVM_SETUNICODEFORMAT              :: 0x2005
+LVM_GETUNICODEFORMAT              :: 0x2006
+OCM_CTLCOLOR                      :: 0x2019
+OCM_DRAWITEM                      :: 0x202b
+OCM_MEASUREITEM                   :: 0x202c
+OCM_DELETEITEM                    :: 0x202d
+OCM_VKEYTOITEM                    :: 0x202e
+OCM_CHARTOITEM                    :: 0x202f
+OCM_COMPAREITEM                   :: 0x2039
+OCM_NOTIFY                        :: 0x204e
+OCM_COMMAND                       :: 0x2111
+OCM_HSCROLL                       :: 0x2114
+OCM_VSCROLL                       :: 0x2115
+OCM_CTLCOLORMSGBOX                :: 0x2132
+OCM_CTLCOLOREDIT                  :: 0x2133
+OCM_CTLCOLORLISTBOX               :: 0x2134
+OCM_CTLCOLORBTN                   :: 0x2135
+OCM_CTLCOLORDLG                   :: 0x2136
+OCM_CTLCOLORSCROLLBAR             :: 0x2137
+OCM_CTLCOLORSTATIC                :: 0x2138
+OCM_PARENTNOTIFY                  :: 0x2210
+WM_APP                            :: 0x8000
+WM_RASDIALEVENT                   :: 0xcccd

+ 34 - 32
core/time/time.odin

@@ -17,7 +17,7 @@ MAX_DURATION :: Duration(1<<63 - 1)
 IS_SUPPORTED :: _IS_SUPPORTED
 IS_SUPPORTED :: _IS_SUPPORTED
 
 
 Time :: struct {
 Time :: struct {
-	_nsec: i64, // zero is 1970-01-01 00:00:00
+	_nsec: i64, // Measured in UNIX nanonseconds
 }
 }
 
 
 Month :: enum int {
 Month :: enum int {
@@ -59,36 +59,36 @@ sleep :: proc "contextless" (d: Duration) {
 	_sleep(d)
 	_sleep(d)
 }
 }
 
 
-stopwatch_start :: proc(using stopwatch: ^Stopwatch) {
+stopwatch_start :: proc "contextless" (using stopwatch: ^Stopwatch) {
 	if !running {
 	if !running {
 		_start_time = tick_now()
 		_start_time = tick_now()
 		running = true
 		running = true
 	}
 	}
 }
 }
 
 
-stopwatch_stop :: proc(using stopwatch: ^Stopwatch) {
+stopwatch_stop :: proc "contextless" (using stopwatch: ^Stopwatch) {
 	if running {
 	if running {
 		_accumulation += tick_diff(_start_time, tick_now())
 		_accumulation += tick_diff(_start_time, tick_now())
 		running = false
 		running = false
 	}
 	}
 }
 }
 
 
-stopwatch_reset :: proc(using stopwatch: ^Stopwatch) {
+stopwatch_reset :: proc "contextless" (using stopwatch: ^Stopwatch) {
 	_accumulation = {}
 	_accumulation = {}
 	running = false
 	running = false
 }
 }
 
 
-stopwatch_duration :: proc(using stopwatch: Stopwatch) -> Duration {
+stopwatch_duration :: proc "contextless" (using stopwatch: Stopwatch) -> Duration {
 	if !running { return _accumulation }
 	if !running { return _accumulation }
 	return _accumulation + tick_diff(_start_time, tick_now())
 	return _accumulation + tick_diff(_start_time, tick_now())
 }
 }
 
 
-diff :: proc(start, end: Time) -> Duration {
+diff :: proc "contextless" (start, end: Time) -> Duration {
 	d := end._nsec - start._nsec
 	d := end._nsec - start._nsec
 	return Duration(d)
 	return Duration(d)
 }
 }
 
 
-since :: proc(start: Time) -> Duration {
+since :: proc "contextless" (start: Time) -> Duration {
 	return diff(start, now())
 	return diff(start, now())
 }
 }
 
 
@@ -117,8 +117,8 @@ duration_hours :: proc "contextless" (d: Duration) -> f64 {
 	return f64(hour) + f64(nsec)/(60*60*1e9)
 	return f64(hour) + f64(nsec)/(60*60*1e9)
 }
 }
 
 
-duration_round :: proc(d, m: Duration) -> Duration {
-	_less_than_half :: #force_inline proc(x, y: Duration) -> bool {
+duration_round :: proc "contextless" (d, m: Duration) -> Duration {
+	_less_than_half :: #force_inline proc "contextless" (x, y: Duration) -> bool {
 		return u64(x)+u64(x) < u64(y)
 		return u64(x)+u64(x) < u64(y)
 	}
 	}
 
 
@@ -146,45 +146,45 @@ duration_round :: proc(d, m: Duration) -> Duration {
 	return MAX_DURATION
 	return MAX_DURATION
 }
 }
 
 
-duration_truncate :: proc(d, m: Duration) -> Duration {
+duration_truncate :: proc "contextless" (d, m: Duration) -> Duration {
 	return d if m <= 0 else d - d%m
 	return d if m <= 0 else d - d%m
 }
 }
 
 
-date :: proc(t: Time) -> (year: int, month: Month, day: int) {
+date :: proc "contextless" (t: Time) -> (year: int, month: Month, day: int) {
 	year, month, day, _ = _abs_date(_time_abs(t), true)
 	year, month, day, _ = _abs_date(_time_abs(t), true)
 	return
 	return
 }
 }
 
 
-year :: proc(t: Time) -> (year: int) {
+year :: proc "contextless" (t: Time) -> (year: int) {
 	year, _, _, _ = _date(t, true)
 	year, _, _, _ = _date(t, true)
 	return
 	return
 }
 }
 
 
-month :: proc(t: Time) -> (month: Month) {
+month :: proc "contextless" (t: Time) -> (month: Month) {
 	_, month, _, _ = _date(t, true)
 	_, month, _, _ = _date(t, true)
 	return
 	return
 }
 }
 
 
-day :: proc(t: Time) -> (day: int) {
+day :: proc "contextless" (t: Time) -> (day: int) {
 	_, _, day, _ = _date(t, true)
 	_, _, day, _ = _date(t, true)
 	return
 	return
 }
 }
 
 
 clock :: proc { clock_from_time, clock_from_duration, clock_from_stopwatch }
 clock :: proc { clock_from_time, clock_from_duration, clock_from_stopwatch }
 
 
-clock_from_time :: proc(t: Time) -> (hour, min, sec: int) {
+clock_from_time :: proc "contextless" (t: Time) -> (hour, min, sec: int) {
 	return clock_from_seconds(_time_abs(t))
 	return clock_from_seconds(_time_abs(t))
 }
 }
 
 
-clock_from_duration :: proc(d: Duration) -> (hour, min, sec: int) {
+clock_from_duration :: proc "contextless" (d: Duration) -> (hour, min, sec: int) {
 	return clock_from_seconds(u64(d/1e9))
 	return clock_from_seconds(u64(d/1e9))
 }
 }
 
 
-clock_from_stopwatch :: proc(s: Stopwatch) -> (hour, min, sec: int) {
+clock_from_stopwatch :: proc "contextless" (s: Stopwatch) -> (hour, min, sec: int) {
 	return clock_from_duration(stopwatch_duration(s))
 	return clock_from_duration(stopwatch_duration(s))
 }
 }
 
 
-clock_from_seconds :: proc(nsec: u64) -> (hour, min, sec: int) {
+clock_from_seconds :: proc "contextless" (nsec: u64) -> (hour, min, sec: int) {
 	sec = int(nsec % SECONDS_PER_DAY)
 	sec = int(nsec % SECONDS_PER_DAY)
 	hour = sec / SECONDS_PER_HOUR
 	hour = sec / SECONDS_PER_HOUR
 	sec -= hour * SECONDS_PER_HOUR
 	sec -= hour * SECONDS_PER_HOUR
@@ -193,11 +193,11 @@ clock_from_seconds :: proc(nsec: u64) -> (hour, min, sec: int) {
 	return
 	return
 }
 }
 
 
-read_cycle_counter :: proc() -> u64 {
+read_cycle_counter :: proc "contextless" () -> u64 {
 	return u64(intrinsics.read_cycle_counter())
 	return u64(intrinsics.read_cycle_counter())
 }
 }
 
 
-unix :: proc(sec: i64, nsec: i64) -> Time {
+unix :: proc "contextless" (sec: i64, nsec: i64) -> Time {
 	sec, nsec := sec, nsec
 	sec, nsec := sec, nsec
 	if nsec < 0 || nsec >= 1e9 {
 	if nsec < 0 || nsec >= 1e9 {
 		n := nsec / 1e9
 		n := nsec / 1e9
@@ -208,20 +208,20 @@ unix :: proc(sec: i64, nsec: i64) -> Time {
 			sec -= 1
 			sec -= 1
 		}
 		}
 	}
 	}
-	return Time{(sec*1e9 + nsec) + UNIX_TO_INTERNAL}
+	return Time{(sec*1e9 + nsec)}
 }
 }
 
 
 to_unix_seconds :: time_to_unix
 to_unix_seconds :: time_to_unix
-time_to_unix :: proc(t: Time) -> i64 {
+time_to_unix :: proc "contextless" (t: Time) -> i64 {
 	return t._nsec/1e9
 	return t._nsec/1e9
 }
 }
 
 
 to_unix_nanoseconds :: time_to_unix_nano
 to_unix_nanoseconds :: time_to_unix_nano
-time_to_unix_nano :: proc(t: Time) -> i64 {
+time_to_unix_nano :: proc "contextless" (t: Time) -> i64 {
 	return t._nsec
 	return t._nsec
 }
 }
 
 
-time_add :: proc(t: Time, d: Duration) -> Time {
+time_add :: proc "contextless" (t: Time, d: Duration) -> Time {
 	return Time{t._nsec + i64(d)}
 	return Time{t._nsec + i64(d)}
 }
 }
 
 
@@ -231,7 +231,7 @@ time_add :: proc(t: Time, d: Duration) -> Time {
 // On Windows it depends but is comparable with regular sleep in the worst case.
 // On Windows it depends but is comparable with regular sleep in the worst case.
 // To get the same kind of accuracy as on Linux, have your program call `win32.time_begin_period(1)` to
 // To get the same kind of accuracy as on Linux, have your program call `win32.time_begin_period(1)` to
 // tell Windows to use a more accurate timer for your process.
 // tell Windows to use a more accurate timer for your process.
-accurate_sleep :: proc(d: Duration) {
+accurate_sleep :: proc "contextless" (d: Duration) {
 	to_sleep, estimate, mean, m2, count: Duration
 	to_sleep, estimate, mean, m2, count: Duration
 
 
 	to_sleep = d
 	to_sleep = d
@@ -279,19 +279,19 @@ ABSOLUTE_TO_UNIX :: -UNIX_TO_ABSOLUTE
 
 
 
 
 @(private)
 @(private)
-_date :: proc(t: Time, full: bool) -> (year: int, month: Month, day: int, yday: int) {
+_date :: proc "contextless" (t: Time, full: bool) -> (year: int, month: Month, day: int, yday: int) {
 	year, month, day, yday = _abs_date(_time_abs(t), full)
 	year, month, day, yday = _abs_date(_time_abs(t), full)
 	return
 	return
 }
 }
 
 
 @(private)
 @(private)
-_time_abs :: proc(t: Time) -> u64 {
+_time_abs :: proc "contextless" (t: Time) -> u64 {
 	return u64(t._nsec/1e9 + UNIX_TO_ABSOLUTE)
 	return u64(t._nsec/1e9 + UNIX_TO_ABSOLUTE)
 }
 }
 
 
 @(private)
 @(private)
-_abs_date :: proc(abs: u64, full: bool) -> (year: int, month: Month, day: int, yday: int) {
-	_is_leap_year :: proc(year: int) -> bool {
+_abs_date :: proc "contextless" (abs: u64, full: bool) -> (year: int, month: Month, day: int, yday: int) {
+	_is_leap_year :: proc "contextless" (year: int) -> bool {
 		return year%4 == 0 && (year%100 != 0 || year%400 == 0)
 		return year%4 == 0 && (year%100 != 0 || year%400 == 0)
 	}
 	}
 
 
@@ -352,9 +352,11 @@ _abs_date :: proc(abs: u64, full: bool) -> (year: int, month: Month, day: int, y
 	return
 	return
 }
 }
 
 
-datetime_to_time :: proc(year, month, day, hour, minute, second: int, nsec := int(0)) -> (t: Time, ok: bool) {
-	divmod :: proc(year: int, divisor: int) -> (div: int, mod: int) {
-		assert(divisor > 0)
+datetime_to_time :: proc "contextless" (year, month, day, hour, minute, second: int, nsec := int(0)) -> (t: Time, ok: bool) {
+	divmod :: proc "contextless" (year: int, divisor: int) -> (div: int, mod: int) {
+		if divisor <= 0 {
+			intrinsics.debug_trap()
+		}
 		div = int(year / divisor)
 		div = int(year / divisor)
 		mod = year % divisor
 		mod = year % divisor
 		return
 		return

+ 2 - 0
core/time/time_wasi.odin

@@ -22,3 +22,5 @@ _tick_now :: proc "contextless" () -> Tick {
 	return {}
 	return {}
 }
 }
 
 
+_yield :: proc "contextless" () {
+}

+ 10 - 3
core/time/time_windows.odin

@@ -7,9 +7,16 @@ _IS_SUPPORTED :: true
 
 
 _now :: proc "contextless" () -> Time {
 _now :: proc "contextless" () -> Time {
 	file_time: win32.FILETIME
 	file_time: win32.FILETIME
-	win32.GetSystemTimeAsFileTime(&file_time)
-	ns := win32.FILETIME_as_unix_nanoseconds(file_time)
-	return Time{_nsec=ns}
+
+	ns: i64
+
+	// monotonic
+	win32.GetSystemTimePreciseAsFileTime(&file_time)
+
+	dt := u64(transmute(u64le)file_time) // in 100ns units
+	ns = i64((dt - 116444736000000000) * 100) // convert to ns
+
+	return unix(0, ns)
 }
 }
 
 
 _sleep :: proc "contextless" (d: Duration) {
 _sleep :: proc "contextless" (d: Duration) {

+ 1 - 1
src/big_int.cpp

@@ -71,7 +71,7 @@ void big_int_and    (BigInt *dst, BigInt const *x, BigInt const *y);
 void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y);
 void big_int_and_not(BigInt *dst, BigInt const *x, BigInt const *y);
 void big_int_xor    (BigInt *dst, BigInt const *x, BigInt const *y);
 void big_int_xor    (BigInt *dst, BigInt const *x, BigInt const *y);
 void big_int_or     (BigInt *dst, BigInt const *x, BigInt const *y);
 void big_int_or     (BigInt *dst, BigInt const *x, BigInt const *y);
-void big_int_not    (BigInt *dst, BigInt const *x, u64 bit_count, bool is_signed);
+void big_int_not    (BigInt *dst, BigInt const *x, i32 bit_count, bool is_signed);
 
 
 
 
 void big_int_add_eq(BigInt *dst, BigInt const *x);
 void big_int_add_eq(BigInt *dst, BigInt const *x);

+ 12 - 9
src/build_settings.cpp

@@ -298,17 +298,17 @@ struct BuildContext {
 	bool   ignore_microsoft_magic;
 	bool   ignore_microsoft_magic;
 	bool   linker_map_file;
 	bool   linker_map_file;
 
 
-	bool use_separate_modules;
-	bool threaded_checker;
+	bool   use_separate_modules;
+	bool   threaded_checker;
 
 
-	bool show_debug_messages;
+	bool   show_debug_messages;
 	
 	
-	bool copy_file_contents;
+	bool   copy_file_contents;
 
 
-	bool disallow_rtti;
+	bool   disallow_rtti;
 
 
 	RelocMode reloc_mode;
 	RelocMode reloc_mode;
-	bool disable_red_zone;
+	bool   disable_red_zone;
 
 
 
 
 	u32 cmd_doc_flags;
 	u32 cmd_doc_flags;
@@ -326,7 +326,7 @@ struct BuildContext {
 	BlockingMutex target_features_mutex;
 	BlockingMutex target_features_mutex;
 	StringSet target_features_set;
 	StringSet target_features_set;
 	String target_features_string;
 	String target_features_string;
-
+	String minimum_os_version_string;
 };
 };
 
 
 gb_global BuildContext build_context = {0};
 gb_global BuildContext build_context = {0};
@@ -1311,13 +1311,16 @@ void enable_target_feature(TokenPos pos, String const &target_feature_list) {
 	defer (mutex_unlock(&bc->target_features_mutex));
 	defer (mutex_unlock(&bc->target_features_mutex));
 
 
 	auto items = split_by_comma(target_feature_list);
 	auto items = split_by_comma(target_feature_list);
-	array_free(&items);
 	for_array(i, items) {
 	for_array(i, items) {
 		String const &item = items.data[i];
 		String const &item = items.data[i];
 		if (!check_target_feature_is_valid(pos, item)) {
 		if (!check_target_feature_is_valid(pos, item)) {
 			error(pos, "Target feature '%.*s' is not valid", LIT(item));
 			error(pos, "Target feature '%.*s' is not valid", LIT(item));
+			continue;
 		}
 		}
+
+		string_set_add(&bc->target_features_set, item);
 	}
 	}
+	array_free(&items);
 }
 }
 
 
 
 
@@ -1340,7 +1343,7 @@ char const *target_features_set_to_cstring(gbAllocator allocator, bool with_quot
 
 
 		if (with_quotes) features[len++] = '"';
 		if (with_quotes) features[len++] = '"';
 		String feature = build_context.target_features_set.entries[i].value;
 		String feature = build_context.target_features_set.entries[i].value;
-		gb_memmove(features, feature.text, feature.len);
+		gb_memmove(features + len, feature.text, feature.len);
 		len += feature.len;
 		len += feature.len;
 		if (with_quotes) features[len++] = '"';
 		if (with_quotes) features[len++] = '"';
 	}
 	}

+ 141 - 3
src/check_builtin.cpp

@@ -1533,10 +1533,10 @@ bool check_builtin_procedure_directive(CheckerContext *c, Operand *operand, Ast
 		}
 		}
 
 
 		bool is_defined = check_identifier_exists(c->scope, arg);
 		bool is_defined = check_identifier_exists(c->scope, arg);
-		gb_unused(is_defined);
+		// gb_unused(is_defined);
 		operand->type = t_untyped_bool;
 		operand->type = t_untyped_bool;
 		operand->mode = Addressing_Constant;
 		operand->mode = Addressing_Constant;
-		operand->value = exact_value_bool(false);
+		operand->value = exact_value_bool(is_defined);
 
 
 	} else if (name == "config") {
 	} else if (name == "config") {
 		if (ce->args.count != 2) {
 		if (ce->args.count != 2) {
@@ -3651,6 +3651,59 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
 		operand->mode = Addressing_NoValue;
 		operand->mode = Addressing_NoValue;
 		break;
 		break;
 
 
+	case BuiltinProc_raw_data:
+		{
+			Operand x = {};
+			check_expr(c, &x, ce->args[0]);
+			if (x.mode == Addressing_Invalid) {
+				return false;
+			}
+			if (!is_operand_value(x)) {
+				gbString s = expr_to_string(x.expr);
+				error(call, "'%.*s' expects a string, slice, dynamic array, or pointer to array type, got %s", LIT(builtin_name), s);
+				gb_string_free(s);
+				return false;
+			}
+			Type *t = base_type(x.type);
+
+			operand->mode = Addressing_Value;
+			operand->type = nullptr;
+			switch (t->kind) {
+			case Type_Slice:
+				operand->type = alloc_type_multi_pointer(t->MultiPointer.elem);
+				break;
+			case Type_DynamicArray:
+				operand->type = alloc_type_multi_pointer(t->DynamicArray.elem);
+				break;
+			case Type_Basic:
+				if (t->Basic.kind == Basic_string) {
+					operand->type = alloc_type_multi_pointer(t_u8);
+				}
+				break;
+			case Type_Pointer:
+			case Type_MultiPointer:
+				{
+					Type *base = base_type(type_deref(t, true));
+					switch (base->kind) {
+					case Type_Array:
+					case Type_EnumeratedArray:
+					case Type_SimdVector:
+						operand->type = alloc_type_multi_pointer(base_array_type(base));
+						break;
+					}
+				}
+				break;
+			}
+
+			if (operand->type == nullptr) {
+				gbString s = type_to_string(x.type);
+				error(call, "'%.*s' expects a string, slice, dynamic array, or pointer to array type, got %s", LIT(builtin_name), s);
+				gb_string_free(s);
+				return false;
+			}
+		}
+		break;
+
 	case BuiltinProc_read_cycle_counter:
 	case BuiltinProc_read_cycle_counter:
 		operand->mode = Addressing_Value;
 		operand->mode = Addressing_Value;
 		operand->type = t_i64;
 		operand->type = t_i64;
@@ -3685,8 +3738,92 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
 				gb_string_free(xts);
 				gb_string_free(xts);
 			}
 			}
 
 
+			Type *type = default_type(x.type);
 			operand->mode = Addressing_Value;
 			operand->mode = Addressing_Value;
-			operand->type = default_type(x.type);
+			operand->type = type;
+
+			if (id == BuiltinProc_reverse_bits) {
+				// make runtime only for the time being
+			} else if (x.mode == Addressing_Constant && x.value.kind == ExactValue_Integer) {
+				convert_to_typed(c, &x, type);
+				if (x.mode == Addressing_Invalid) {
+					return false;
+				}
+
+				ExactValue res = {};
+
+				i64 sz = type_size_of(x.type);
+				u64 bit_size = sz*8;
+				u64 rop64[4] = {}; // 2 u64 is the maximum we will ever need, so doubling it will ne fine
+				u8 *rop = cast(u8 *)rop64;
+
+				size_t max_count = 0;
+				size_t written = 0;
+				size_t size = 1;
+				size_t nails = 0;
+				mp_endian endian = MP_LITTLE_ENDIAN;
+
+				max_count = mp_pack_count(&x.value.value_integer, nails, size);
+				GB_ASSERT(sz >= cast(i64)max_count);
+
+				mp_err err = mp_pack(rop, max_count, &written, MP_LSB_FIRST, size, endian, nails, &x.value.value_integer);
+				GB_ASSERT(err == MP_OKAY);
+
+				if (id == BuiltinProc_reverse_bits) {
+					// TODO(bill): Should this even be allowed at compile time?
+				} else {
+					u64 v = 0;
+					switch (id) {
+					case BuiltinProc_count_ones:
+					case BuiltinProc_count_zeros:
+						switch (sz) {
+						case 1: v = bit_set_count(cast(u32)rop[0]);  break;
+						case 2: v = bit_set_count(cast(u32)*(u16 *)rop); break;
+						case 4: v = bit_set_count(*(u32 *)rop); break;
+						case 8: v = bit_set_count(rop64[0]); break;
+						case 16:
+							v += bit_set_count(rop64[0]);
+							v += bit_set_count(rop64[1]);
+							break;
+						default: GB_PANIC("Unhandled sized");
+						}
+						if (id == BuiltinProc_count_zeros) {
+							// flip the result
+							v = bit_size - v;
+						}
+						break;
+					case BuiltinProc_count_trailing_zeros:
+						for (u64 i = 0; i < bit_size; i++) {
+							u8 b = cast(u8)(i & 7);
+							u8 j = cast(u8)(i >> 3);
+							if (rop[j] & (1 << b)) {
+								break;
+							}
+							v += 1;
+						}
+						break;
+					case BuiltinProc_count_leading_zeros:
+						for (u64 i = bit_size-1; i < bit_size; i--) {
+							u8 b = cast(u8)(i & 7);
+							u8 j = cast(u8)(i >> 3);
+							if (rop[j] & (1 << b)) {
+								break;
+							}
+							v += 1;
+						}
+						break;
+					}
+
+
+					res = exact_value_u64(v);
+				}
+
+				if (res.kind != ExactValue_Invalid) {
+					operand->mode = Addressing_Constant;
+					operand->value = res;
+				}
+			}
+
 		}
 		}
 		break;
 		break;
 
 
@@ -4667,6 +4804,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
 			new_type->Union.variants = variants;
 			new_type->Union.variants = variants;
 
 
 			// NOTE(bill): Is this even correct?
 			// NOTE(bill): Is this even correct?
+			new_type->Union.node = operand->expr;
 			new_type->Union.scope = bt->Union.scope;
 			new_type->Union.scope = bt->Union.scope;
 
 
 			operand->type = new_type;
 			operand->type = new_type;

+ 5 - 0
src/check_decl.cpp

@@ -1488,6 +1488,11 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
 				if (!(e->flags & EntityFlag_Using)) {
 				if (!(e->flags & EntityFlag_Using)) {
 					continue;
 					continue;
 				}
 				}
+				if (is_blank_ident(e->token)) {
+                    error(e->token, "'using' a procedure parameter requires a non blank identifier");
+					break;
+				}
+
 				bool is_value = (e->flags & EntityFlag_Value) != 0 && !is_type_pointer(e->type);
 				bool is_value = (e->flags & EntityFlag_Value) != 0 && !is_type_pointer(e->type);
 				String name = e->token.string;
 				String name = e->token.string;
 				Type *t = base_type(type_deref(e->type));
 				Type *t = base_type(type_deref(e->type));

+ 64 - 16
src/check_expr.cpp

@@ -821,11 +821,12 @@ i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type
 		if (are_types_identical(src, dst)) {
 		if (are_types_identical(src, dst)) {
 			return 5;
 			return 5;
 		}
 		}
-
-		Type *dst_elem = base_array_type(dst);
-		i64 distance = check_distance_between_types(c, operand, dst_elem);
-		if (distance >= 0) {
-			return distance + 7;
+		if (dst->Matrix.row_count == dst->Matrix.column_count) {
+			Type *dst_elem = base_array_type(dst);
+			i64 distance = check_distance_between_types(c, operand, dst_elem);
+			if (distance >= 0) {
+				return distance + 7;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -2916,7 +2917,12 @@ bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) {
 	// 	return false;
 	// 	return false;
 	// }
 	// }
 
 
-	if (is_type_untyped(o->type)) {
+	Type *src_t = o->type;
+	Type *dst_t = t;
+	Type *src_bt = base_type(src_t);
+	Type *dst_bt = base_type(dst_t);
+
+	if (is_type_untyped(src_t)) {
 		gbString expr_str = expr_to_string(o->expr);
 		gbString expr_str = expr_to_string(o->expr);
 		error(o->expr, "Cannot transmute untyped expression: '%s'", expr_str);
 		error(o->expr, "Cannot transmute untyped expression: '%s'", expr_str);
 		gb_string_free(expr_str);
 		gb_string_free(expr_str);
@@ -2925,7 +2931,6 @@ bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) {
 		return false;
 		return false;
 	}
 	}
 
 
-	Type *dst_bt = base_type(t);
 	if (dst_bt == nullptr || dst_bt == t_invalid) {
 	if (dst_bt == nullptr || dst_bt == t_invalid) {
 		GB_ASSERT(global_error_collector.count != 0);
 		GB_ASSERT(global_error_collector.count != 0);
 
 
@@ -2934,21 +2939,21 @@ bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) {
 		return false;
 		return false;
 	}
 	}
 
 
-	Type *src_bt = base_type(o->type);
 	if (src_bt == nullptr || src_bt == t_invalid) {
 	if (src_bt == nullptr || src_bt == t_invalid) {
 		// NOTE(bill): this should be an error
 		// NOTE(bill): this should be an error
 		GB_ASSERT(global_error_collector.count != 0);
 		GB_ASSERT(global_error_collector.count != 0);
 		o->mode = Addressing_Value;
 		o->mode = Addressing_Value;
 		o->expr = node;
 		o->expr = node;
-		o->type = t;
+		o->type = dst_t;
 		return true;
 		return true;
 	}
 	}
 
 
-	i64 srcz = type_size_of(o->type);
-	i64 dstz = type_size_of(t);
+
+	i64 srcz = type_size_of(src_t);
+	i64 dstz = type_size_of(dst_t);
 	if (srcz != dstz) {
 	if (srcz != dstz) {
 		gbString expr_str = expr_to_string(o->expr);
 		gbString expr_str = expr_to_string(o->expr);
-		gbString type_str = type_to_string(t);
+		gbString type_str = type_to_string(dst_t);
 		error(o->expr, "Cannot transmute '%s' to '%s', %lld vs %lld bytes", expr_str, type_str, srcz, dstz);
 		error(o->expr, "Cannot transmute '%s' to '%s', %lld vs %lld bytes", expr_str, type_str, srcz, dstz);
 		gb_string_free(type_str);
 		gb_string_free(type_str);
 		gb_string_free(expr_str);
 		gb_string_free(expr_str);
@@ -2958,16 +2963,53 @@ bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) {
 	}
 	}
 
 
 	if (build_context.vet_extra) {
 	if (build_context.vet_extra) {
-		if (are_types_identical(o->type, t)) {
-			gbString str = type_to_string(t);
+		if (are_types_identical(o->type, dst_t)) {
+			gbString str = type_to_string(dst_t);
 			warning(o->expr, "Unneeded transmute to the same type '%s'", str);
 			warning(o->expr, "Unneeded transmute to the same type '%s'", str);
 			gb_string_free(str);
 			gb_string_free(str);
 		}
 		}
 	}
 	}
 
 
 	o->expr = node;
 	o->expr = node;
+	o->type = dst_t;
+	if (o->mode == Addressing_Constant) {
+		if (are_types_identical(src_bt, dst_bt)) {
+			return true;
+		}
+		if (is_type_integer(src_t) && is_type_integer(dst_t)) {
+			if (types_have_same_internal_endian(src_t, dst_t)) {
+				ExactValue src_v = exact_value_to_integer(o->value);
+				GB_ASSERT(src_v.kind == ExactValue_Integer);
+				BigInt v = src_v.value_integer;
+
+				BigInt smax = {};
+				BigInt umax = {};
+
+				big_int_from_u64(&smax, 0);
+				big_int_not(&smax, &smax, cast(i32)(srcz*8 - 1), false);
+
+				big_int_from_u64(&umax, 1);
+				BigInt sz_in_bits = big_int_make_i64(srcz*8);
+				big_int_shl_eq(&umax, &sz_in_bits);
+
+				if (is_type_unsigned(src_t) && !is_type_unsigned(dst_t)) {
+					if (big_int_cmp(&v, &smax) >= 0) {
+						big_int_sub_eq(&v, &umax);
+					}
+				} else if (!is_type_unsigned(src_t) && is_type_unsigned(dst_t)) {
+					if (big_int_is_neg(&v)) {
+						big_int_add_eq(&v, &umax);
+					}
+				}
+
+				o->value.kind = ExactValue_Integer;
+				o->value.value_integer = v;
+				return true;
+			}
+		}
+	}
+
 	o->mode = Addressing_Value;
 	o->mode = Addressing_Value;
-	o->type = t;
 	o->value = {};
 	o->value = {};
 	return true;
 	return true;
 }
 }
@@ -6413,7 +6455,9 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper
 		if (e->kind == Entity_TypeName) {
 		if (e->kind == Entity_TypeName) {
 			if (o->mode != Addressing_Type) {
 			if (o->mode != Addressing_Type) {
 				if (show_error) {
 				if (show_error) {
-					error(o->expr, "Expected a type for the argument '%.*s'", LIT(e->token.string));
+					gbString expr = expr_to_string(o->expr);
+					error(o->expr, "Expected a type for the argument '%.*s', got %s", LIT(e->token.string), expr);
+					gb_string_free(expr);
 				}
 				}
 				err = CallArgumentError_WrongTypes;
 				err = CallArgumentError_WrongTypes;
 			}
 			}
@@ -6456,6 +6500,10 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper
 		// add_type_info_type(c, o->type);
 		// add_type_info_type(c, o->type);
 	}
 	}
 
 
+	if (show_error && err) {
+		return err;
+	}
+
 	{
 	{
 		bool failure = false;
 		bool failure = false;
 		Entity *found_entity = find_polymorphic_record_entity(c, original_type, param_count, ordered_operands, &failure);
 		Entity *found_entity = find_polymorphic_record_entity(c, original_type, param_count, ordered_operands, &failure);

+ 5 - 1
src/check_stmt.cpp

@@ -584,7 +584,11 @@ void check_label(CheckerContext *ctx, Ast *label, Ast *parent) {
 // Returns 'true' for 'continue', 'false' for 'return'
 // Returns 'true' for 'continue', 'false' for 'return'
 bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, bool is_selector, Entity *e) {
 bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us, Ast *expr, bool is_selector, Entity *e) {
 	if (e == nullptr) {
 	if (e == nullptr) {
-		error(us->token, "'using' applied to an unknown entity");
+		if (is_blank_ident(expr)) {
+			error(us->token, "'using' in a statement is not allowed with the blank identifier '_'");
+		} else {
+			error(us->token, "'using' applied to an unknown entity");
+		}
 		return true;
 		return true;
 	}
 	}
 
 

+ 12 - 1
src/checker.cpp

@@ -1673,7 +1673,18 @@ bool could_entity_be_lazy(Entity *e, DeclInfo *d) {
 }
 }
 
 
 void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported) {
 void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported) {
-	GB_ASSERT(identifier->kind == Ast_Ident);
+	if (identifier == nullptr) {
+		// NOTE(bill): Should only happen on errors
+		error(e->token, "Invalid variable declaration");
+		return;
+	}
+	if (identifier->kind != Ast_Ident) {
+		// NOTE(bill): This is a safety check
+		gbString s = expr_to_string(identifier);
+		error(identifier, "A variable declaration must be an identifer, got %s", s);
+		gb_string_free(s);
+		return;
+	}
 	GB_ASSERT(e != nullptr && d != nullptr);
 	GB_ASSERT(e != nullptr && d != nullptr);
 	GB_ASSERT(identifier->Ident.token.string == e->token.string);
 	GB_ASSERT(identifier->Ident.token.string == e->token.string);
 
 

+ 4 - 0
src/checker_builtin_procs.hpp

@@ -42,6 +42,8 @@ enum BuiltinProcId {
 
 
 	BuiltinProc_unreachable,
 	BuiltinProc_unreachable,
 
 
+	BuiltinProc_raw_data,
+
 	BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures
 	BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures
 
 
 	// "Intrinsics"
 	// "Intrinsics"
@@ -338,6 +340,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
 
 
 	{STR_LIT("unreachable"),      0, false, Expr_Expr, BuiltinProcPkg_builtin, /*diverging*/true},
 	{STR_LIT("unreachable"),      0, false, Expr_Expr, BuiltinProcPkg_builtin, /*diverging*/true},
 
 
+	{STR_LIT("raw_data"),         1, false, Expr_Expr, BuiltinProcPkg_builtin},
+
 	{STR_LIT(""),                 0, true,  Expr_Expr, BuiltinProcPkg_builtin}, // DIRECTIVE
 	{STR_LIT(""),                 0, true,  Expr_Expr, BuiltinProcPkg_builtin}, // DIRECTIVE
 
 
 
 

+ 1 - 1
src/docs_writer.cpp

@@ -639,7 +639,7 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
 			doc_type.polmorphic_params = odin_doc_type(w, type->Union.polymorphic_params);
 			doc_type.polmorphic_params = odin_doc_type(w, type->Union.polymorphic_params);
 		}
 		}
 
 
-		if (type->Union.node) {
+		if (type->Union.node && type->Union.node->kind == Ast_UnionType) {
 			ast_node(ut, UnionType, type->Union.node);
 			ast_node(ut, UnionType, type->Union.node);
 			if (ut->align) {
 			if (ut->align) {
 				doc_type.custom_align = odin_doc_expr_string(w, ut->align);
 				doc_type.custom_align = odin_doc_expr_string(w, ut->align);

+ 7 - 0
src/exact_value.cpp

@@ -499,6 +499,13 @@ i64 exact_value_to_i64(ExactValue v) {
 	}
 	}
 	return 0;
 	return 0;
 }
 }
+u64 exact_value_to_u64(ExactValue v) {
+	v = exact_value_to_integer(v);
+	if (v.kind == ExactValue_Integer) {
+		return big_int_to_u64(&v.value_integer);
+	}
+	return 0;
+}
 f64 exact_value_to_f64(ExactValue v) {
 f64 exact_value_to_f64(ExactValue v) {
 	v = exact_value_to_float(v);
 	v = exact_value_to_float(v);
 	if (v.kind == ExactValue_Float) {
 	if (v.kind == ExactValue_Float) {

+ 44 - 19
src/llvm_abi.cpp

@@ -537,6 +537,22 @@ namespace lbAbiAmd64SysV {
 		return false;
 		return false;
 	}
 	}
 
 
+	bool is_llvm_type_slice_like(LLVMTypeRef type) {
+		if (!lb_is_type_kind(type, LLVMStructTypeKind)) {
+			return false;
+		}
+		if (LLVMCountStructElementTypes(type) != 2) {
+			return false;
+		}
+		LLVMTypeRef fields[2] = {};
+		LLVMGetStructElementTypes(type, fields);
+		if (!lb_is_type_kind(fields[0], LLVMPointerTypeKind)) {
+			return false;
+		}
+		return lb_is_type_kind(fields[1], LLVMIntegerTypeKind) && lb_sizeof(fields[1]) == 8;
+
+	}
+
 	lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention) {
 	lbArgType amd64_type(LLVMContextRef c, LLVMTypeRef type, Amd64TypeAttributeKind attribute_kind, ProcCallingConvention calling_convention) {
 		if (is_register(type)) {
 		if (is_register(type)) {
 			LLVMAttributeRef attribute = nullptr;
 			LLVMAttributeRef attribute = nullptr;
@@ -550,16 +566,25 @@ namespace lbAbiAmd64SysV {
 		if (is_mem_cls(cls, attribute_kind)) {
 		if (is_mem_cls(cls, attribute_kind)) {
 			LLVMAttributeRef attribute = nullptr;
 			LLVMAttributeRef attribute = nullptr;
 			if (attribute_kind == Amd64TypeAttribute_ByVal) {
 			if (attribute_kind == Amd64TypeAttribute_ByVal) {
-				if (!is_calling_convention_odin(calling_convention)) {
+				// if (!is_calling_convention_odin(calling_convention)) {
 					return lb_arg_type_indirect_byval(c, type);
 					return lb_arg_type_indirect_byval(c, type);
-				}
-				attribute = nullptr;
+				// }
+				// attribute = nullptr;
 			} else if (attribute_kind == Amd64TypeAttribute_StructRect) {
 			} else if (attribute_kind == Amd64TypeAttribute_StructRect) {
 				attribute = lb_create_enum_attribute_with_type(c, "sret", type);
 				attribute = lb_create_enum_attribute_with_type(c, "sret", type);
 			}
 			}
 			return lb_arg_type_indirect(type, attribute);
 			return lb_arg_type_indirect(type, attribute);
 		} else {
 		} else {
-			return lb_arg_type_direct(type, llreg(c, cls), nullptr, nullptr);
+			LLVMTypeRef reg_type = nullptr;
+			if (is_llvm_type_slice_like(type)) {
+				// NOTE(bill): This is to make the ABI look closer to what the
+				// original code is just for slices/strings whilst still adhering
+				// the ABI rules for SysV
+				reg_type = type;
+			} else {
+				reg_type = llreg(c, cls);
+			}
+			return lb_arg_type_direct(type, reg_type, nullptr, nullptr);
 		}
 		}
 	}
 	}
 
 
@@ -982,13 +1007,13 @@ namespace lbAbiArm64 {
 		}
 		}
 		return false;
 		return false;
 	}
 	}
-    
-    unsigned is_homogenous_aggregate_small_enough(LLVMTypeRef *base_type_, unsigned member_count_) {
-        return (member_count_ <= 4);
-    }
+
+	unsigned is_homogenous_aggregate_small_enough(LLVMTypeRef base_type, unsigned member_count) {
+		return (member_count <= 4);
+	}
 
 
 	lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef type, bool return_is_defined) {
 	lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef type, bool return_is_defined) {
-		LLVMTypeRef homo_base_type = {};
+		LLVMTypeRef homo_base_type = nullptr;
 		unsigned homo_member_count = 0;
 		unsigned homo_member_count = 0;
 
 
 		if (!return_is_defined) {
 		if (!return_is_defined) {
@@ -996,16 +1021,16 @@ namespace lbAbiArm64 {
 		} else if (is_register(type)) {
 		} else if (is_register(type)) {
 			return non_struct(c, type);
 			return non_struct(c, type);
 		} else if (is_homogenous_aggregate(c, type, &homo_base_type, &homo_member_count)) {
 		} else if (is_homogenous_aggregate(c, type, &homo_base_type, &homo_member_count)) {
-            if(is_homogenous_aggregate_small_enough(&homo_base_type, homo_member_count)) {
-                return lb_arg_type_direct(type, LLVMArrayType(homo_base_type, homo_member_count), nullptr, nullptr);
-            } else {
-                //TODO(Platin): do i need to create stuff that can handle the diffrent return type?
-                //              else this needs a fix in llvm_backend_proc as we would need to cast it to the correct array type
-                
-                //LLVMTypeRef array_type = LLVMArrayType(homo_base_type, homo_member_count);
-                LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", type);
-                return lb_arg_type_indirect(type, attr);
-            }
+			if (is_homogenous_aggregate_small_enough(homo_base_type, homo_member_count)) {
+				return lb_arg_type_direct(type, LLVMArrayType(homo_base_type, homo_member_count), nullptr, nullptr);
+			} else {
+				//TODO(Platin): do i need to create stuff that can handle the diffrent return type?
+				//              else this needs a fix in llvm_backend_proc as we would need to cast it to the correct array type
+
+				//LLVMTypeRef array_type = LLVMArrayType(homo_base_type, homo_member_count);
+				LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", type);
+				return lb_arg_type_indirect(type, attr);
+			}
 		} else {
 		} else {
 			i64 size = lb_sizeof(type);
 			i64 size = lb_sizeof(type);
 			if (size <= 16) {
 			if (size <= 16) {

+ 29 - 2
src/llvm_backend.cpp

@@ -646,7 +646,7 @@ void lb_insert_dynamic_map_key_and_value(lbProcedure *p, lbValue const &map_ptr,
 	args[2] = key_hash;
 	args[2] = key_hash;
 	args[3] = key_ptr;
 	args[3] = key_ptr;
 	args[4] = lb_emit_conv(p, value_addr.addr, t_rawptr);
 	args[4] = lb_emit_conv(p, value_addr.addr, t_rawptr);
-	args[5] = lb_emit_source_code_location(p, node);
+	args[5] = lb_emit_source_code_location_as_global(p, node);
 	lb_emit_runtime_call(p, "__dynamic_map_set", args);
 	lb_emit_runtime_call(p, "__dynamic_map_set", args);
 }
 }
 
 
@@ -662,7 +662,7 @@ void lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const
 	args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
 	args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
 	args[1] = lb_gen_map_header_table_internal(p, type_deref(map_ptr.type));
 	args[1] = lb_gen_map_header_table_internal(p, type_deref(map_ptr.type));
 	args[2] = lb_const_int(p->module, t_int, capacity);
 	args[2] = lb_const_int(p->module, t_int, capacity);
-	args[3] = lb_emit_source_code_location(p, proc_name, pos);
+	args[3] = lb_emit_source_code_location_as_global(p, proc_name, pos);
 	lb_emit_runtime_call(p, "__dynamic_map_reserve", args);
 	lb_emit_runtime_call(p, "__dynamic_map_reserve", args);
 }
 }
 
 
@@ -1736,6 +1736,13 @@ void lb_generate_code(lbGenerator *gen) {
 	lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, objc_names, global_variables);
 	lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, objc_names, global_variables);
 	gb_unused(startup_runtime);
 	gb_unused(startup_runtime);
 
 
+	if (build_context.ODIN_DEBUG) {
+		for_array(i, builtin_pkg->scope->elements.entries) {
+			Entity *e = builtin_pkg->scope->elements.entries[i].value;
+			add_debug_info_for_global_constant_from_entity(gen, e);
+		}
+	}
+
 	TIME_SECTION("LLVM Global Procedures and Types");
 	TIME_SECTION("LLVM Global Procedures and Types");
 	for_array(i, info->entities) {
 	for_array(i, info->entities) {
 		Entity *e = info->entities[i];
 		Entity *e = info->entities[i];
@@ -1759,6 +1766,11 @@ void lb_generate_code(lbGenerator *gen) {
 		case Entity_TypeName:
 		case Entity_TypeName:
 		case Entity_Procedure:
 		case Entity_Procedure:
 			break;
 			break;
+		case Entity_Constant:
+			if (build_context.ODIN_DEBUG) {
+				add_debug_info_for_global_constant_from_entity(gen, e);
+			}
+			break;
 		}
 		}
 
 
 		bool polymorphic_struct = false;
 		bool polymorphic_struct = false;
@@ -1820,6 +1832,21 @@ void lb_generate_code(lbGenerator *gen) {
 	lb_finalize_objc_names(objc_names);
 	lb_finalize_objc_names(objc_names);
 
 
 	if (build_context.ODIN_DEBUG) {
 	if (build_context.ODIN_DEBUG) {
+		TIME_SECTION("LLVM Debug Info for global constant value declarations");
+		{
+			// lbModule *m = default_module;
+
+
+		}
+		// if (gen->modules.entries.count == 1) {
+		// } else {
+		// 	for_array(j, gen->modules.entries) {
+		// 		lbModule *m = gen->modules.entries[j].value;
+		// 		if (m->debug_builder != nullptr) {
+		// 		}
+		// 	}
+		// }
+
 		TIME_SECTION("LLVM Debug Info Complete Types and Finalize");
 		TIME_SECTION("LLVM Debug Info Complete Types and Finalize");
 		for_array(j, gen->modules.entries) {
 		for_array(j, gen->modules.entries) {
 			lbModule *m = gen->modules.entries[j].value;
 			lbModule *m = gen->modules.entries[j].value;

+ 2 - 1
src/llvm_backend.hpp

@@ -298,6 +298,7 @@ struct lbProcedure {
 	lbBlock *        entry_block;
 	lbBlock *        entry_block;
 	lbBlock *        curr_block;
 	lbBlock *        curr_block;
 	lbTargetList *   target_list;
 	lbTargetList *   target_list;
+	PtrMap<Entity *, lbValue> direct_parameters;
 
 
 	Ast *curr_stmt;
 	Ast *curr_stmt;
 
 
@@ -456,7 +457,7 @@ lbValue lb_find_value_from_entity(lbModule *m, Entity *e);
 
 
 void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value);
 void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value);
 lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
 lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
-lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, TokenPos const &pos);
+lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedure, TokenPos const &pos);
 
 
 lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos);
 lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos);
 
 

+ 20 - 3
src/llvm_backend_const.cpp

@@ -256,7 +256,7 @@ lbValue lb_expr_untyped_const_to_typed(lbModule *m, Ast *expr, Type *t) {
 	return lb_const_value(m, t, tv.value);
 	return lb_const_value(m, t, tv.value);
 }
 }
 
 
-lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, TokenPos const &pos) {
+lbValue lb_emit_source_code_location_const(lbProcedure *p, String const &procedure, TokenPos const &pos) {
 	lbModule *m = p->module;
 	lbModule *m = p->module;
 
 
 	LLVMValueRef fields[4] = {};
 	LLVMValueRef fields[4] = {};
@@ -271,7 +271,7 @@ lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, To
 	return res;
 	return res;
 }
 }
 
 
-lbValue lb_emit_source_code_location(lbProcedure *p, Ast *node) {
+lbValue lb_emit_source_code_location_const(lbProcedure *p, Ast *node) {
 	String proc_name = {};
 	String proc_name = {};
 	if (p->entity) {
 	if (p->entity) {
 		proc_name = p->entity->token.string;
 		proc_name = p->entity->token.string;
@@ -280,9 +280,26 @@ lbValue lb_emit_source_code_location(lbProcedure *p, Ast *node) {
 	if (node) {
 	if (node) {
 		pos = ast_token(node).pos;
 		pos = ast_token(node).pos;
 	}
 	}
-	return lb_emit_source_code_location(p, proc_name, pos);
+	return lb_emit_source_code_location_const(p, proc_name, pos);
 }
 }
 
 
+lbValue lb_emit_source_code_location_as_global(lbProcedure *p, String const &procedure, TokenPos const &pos) {
+	lbValue loc = lb_emit_source_code_location_const(p, procedure, pos);
+	lbAddr addr = lb_add_global_generated(p->module, loc.type, loc, nullptr);
+	lb_make_global_private_const(addr);
+	return lb_addr_load(p, addr);
+}
+
+
+lbValue lb_emit_source_code_location_as_global(lbProcedure *p, Ast *node) {
+	lbValue loc = lb_emit_source_code_location_const(p, node);
+	lbAddr addr = lb_add_global_generated(p->module, loc.type, loc, nullptr);
+	lb_make_global_private_const(addr);
+	return lb_addr_load(p, addr);
+}
+
+
+
 LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type, Type *elem_type, isize count, LLVMValueRef *values, bool allow_local) {
 LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type, Type *elem_type, isize count, LLVMValueRef *values, bool allow_local) {
 	bool is_local = allow_local && m->curr_procedure != nullptr;
 	bool is_local = allow_local && m->curr_procedure != nullptr;
 	bool is_const = true;
 	bool is_const = true;

+ 114 - 0
src/llvm_backend_debug.cpp

@@ -293,6 +293,7 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
 	case Type_Named:
 	case Type_Named:
 		GB_PANIC("Type_Named should be handled in lb_debug_type separately");
 		GB_PANIC("Type_Named should be handled in lb_debug_type separately");
 
 
+	case Type_SoaPointer:
 	case Type_Pointer:
 	case Type_Pointer:
 		return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->Pointer.elem), word_bits, word_bits, 0, nullptr, 0);
 		return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->Pointer.elem), word_bits, word_bits, 0, nullptr, 0);
 	case Type_MultiPointer:
 	case Type_MultiPointer:
@@ -1079,3 +1080,116 @@ void lb_add_debug_context_variable(lbProcedure *p, lbAddr const &ctx) {
 
 
 	lb_add_debug_local_variable(p, ptr, t_context, token);
 	lb_add_debug_local_variable(p, ptr, t_context, token);
 }
 }
+
+
+String debug_info_mangle_constant_name(Entity *e, bool *did_allocate_) {
+	String name = e->token.string;
+	if (e->pkg && e->pkg->name.len > 0) {
+		// NOTE(bill): C++ NONSENSE FOR DEBUG SHITE!
+		name = concatenate3_strings(heap_allocator(), e->pkg->name, str_lit("::"), name);
+		if (did_allocate_) *did_allocate_ = true;
+	}
+	return name;
+}
+
+void add_debug_info_global_variable_expr(lbModule *m, String const &name, LLVMMetadataRef dtype, LLVMMetadataRef expr) {
+	LLVMMetadataRef scope = nullptr;
+	LLVMMetadataRef file = nullptr;
+	unsigned line = 0;
+
+	LLVMMetadataRef decl = nullptr;
+
+	LLVMDIBuilderCreateGlobalVariableExpression(
+		m->debug_builder, scope,
+		cast(char const *)name.text, cast(size_t)name.len,
+		"", 0, // Linkage
+		file, line, dtype,
+		false, // local to unit
+		expr, decl, 8/*AlignInBits*/);
+}
+
+void add_debug_info_for_global_constant_internal_i64(lbModule *m, Entity *e, LLVMMetadataRef dtype, i64 v) {
+	LLVMMetadataRef expr = LLVMDIBuilderCreateConstantValueExpression(m->debug_builder, v);
+
+	bool did_allocate = false;
+	String name = debug_info_mangle_constant_name(e, &did_allocate);
+	defer (if (did_allocate) {
+		gb_free(heap_allocator(), name.text);
+	});
+
+	add_debug_info_global_variable_expr(m, name, dtype, expr);
+	if ((e->pkg && e->pkg->kind == Package_Init) ||
+	    (e->scope && (e->scope->flags & ScopeFlag_Global))) {
+		add_debug_info_global_variable_expr(m, e->token.string, dtype, expr);
+	}
+}
+
+void add_debug_info_for_global_constant_from_entity(lbGenerator *gen, Entity *e) {
+	if (e == nullptr || e->kind != Entity_Constant) {
+		return;
+	}
+	if (is_blank_ident(e->token)) {
+		return;
+	}
+	lbModule *m = &gen->default_module;
+	if (USE_SEPARATE_MODULES) {
+		m = lb_pkg_module(gen, e->pkg);
+	}
+
+	if (is_type_integer(e->type)) {
+		ExactValue const &value = e->Constant.value;
+		if (value.kind == ExactValue_Integer) {
+			LLVMMetadataRef dtype = nullptr;
+			i64 v = 0;
+			bool is_signed = false;
+			if (big_int_is_neg(&value.value_integer)) {
+				v = exact_value_to_i64(value);
+				is_signed = true;
+			} else {
+				v = cast(i64)exact_value_to_u64(value);
+			}
+			if (is_type_untyped(e->type)) {
+				dtype = lb_debug_type(m, is_signed ? t_i64 : t_u64);
+			} else {
+				dtype = lb_debug_type(m, e->type);
+			}
+
+			add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
+		}
+	} else if (is_type_rune(e->type)) {
+		ExactValue const &value = e->Constant.value;
+		if (value.kind == ExactValue_Integer) {
+			LLVMMetadataRef dtype = lb_debug_type(m, t_rune);
+			i64 v = exact_value_to_i64(value);
+			add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
+		}
+	} else if (is_type_boolean(e->type)) {
+		ExactValue const &value = e->Constant.value;
+		if (value.kind == ExactValue_Bool) {
+			LLVMMetadataRef dtype = lb_debug_type(m, default_type(e->type));
+			i64 v = cast(i64)value.value_bool;
+
+			add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
+		}
+	} else if (is_type_enum(e->type)) {
+		ExactValue const &value = e->Constant.value;
+		if (value.kind == ExactValue_Integer) {
+			LLVMMetadataRef dtype = lb_debug_type(m, default_type(e->type));
+			i64 v = 0;
+			if (big_int_is_neg(&value.value_integer)) {
+				v = exact_value_to_i64(value);
+			} else {
+				v = cast(i64)exact_value_to_u64(value);
+			}
+
+			add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
+		}
+	} else if (is_type_pointer(e->type)) {
+		ExactValue const &value = e->Constant.value;
+		if (value.kind == ExactValue_Integer) {
+			LLVMMetadataRef dtype = lb_debug_type(m, default_type(e->type));
+			i64 v = cast(i64)exact_value_to_u64(value);
+			add_debug_info_for_global_constant_internal_i64(m, e, dtype, v);
+		}
+	}
+}

+ 25 - 26
src/llvm_backend_expr.cpp

@@ -1952,34 +1952,33 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
 		Type *dt = t;
 		Type *dt = t;
 
 
 		GB_ASSERT(is_type_struct(st) || is_type_raw_union(st));
 		GB_ASSERT(is_type_struct(st) || is_type_raw_union(st));
-		String field_name = lookup_subtype_polymorphic_field(t, src_type);
-		if (field_name.len > 0) {
-			// NOTE(bill): It can be casted
-			Selection sel = lookup_field(st, field_name, false, true);
-			if (sel.entity != nullptr) {
-				if (st_is_ptr) {
-					lbValue res = lb_emit_deep_field_gep(p, value, sel);
-					Type *rt = res.type;
+		Selection sel = {};
+		sel.index.allocator = heap_allocator();
+		defer (array_free(&sel.index));
+		if (lookup_subtype_polymorphic_selection(t, src_type, &sel)) {
+			if (sel.entity == nullptr) {
+				GB_PANIC("invalid subtype cast  %s -> ", type_to_string(src_type), type_to_string(t));
+			}
+			if (st_is_ptr) {
+				lbValue res = lb_emit_deep_field_gep(p, value, sel);
+				Type *rt = res.type;
+				if (!are_types_identical(rt, dt) && are_types_identical(type_deref(rt), dt)) {
+					res = lb_emit_load(p, res);
+				}
+				return res;
+			} else {
+				if (is_type_pointer(value.type)) {
+					Type *rt = value.type;
 					if (!are_types_identical(rt, dt) && are_types_identical(type_deref(rt), dt)) {
 					if (!are_types_identical(rt, dt) && are_types_identical(type_deref(rt), dt)) {
-						res = lb_emit_load(p, res);
-					}
-					return res;
-				} else {
-					if (is_type_pointer(value.type)) {
-						Type *rt = value.type;
-						if (!are_types_identical(rt, dt) && are_types_identical(type_deref(rt), dt)) {
-							value = lb_emit_load(p, value);
-						} else {
-							value = lb_emit_deep_field_gep(p, value, sel);
-							return lb_emit_load(p, value);
-						}
+						value = lb_emit_load(p, value);
+					} else {
+						value = lb_emit_deep_field_gep(p, value, sel);
+						return lb_emit_load(p, value);
 					}
 					}
+				}
 
 
-					return lb_emit_deep_field_ev(p, value, sel);
+				return lb_emit_deep_field_ev(p, value, sel);
 
 
-				}
-			} else {
-				GB_PANIC("invalid subtype cast  %s.%.*s", type_to_string(src_type), LIT(field_name));
 			}
 			}
 		}
 		}
 	}
 	}
@@ -4232,7 +4231,7 @@ lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) {
 			args[1] = size;
 			args[1] = size;
 			args[2] = align;
 			args[2] = align;
 			args[3] = lb_const_int(p->module, t_int, item_count);
 			args[3] = lb_const_int(p->module, t_int, item_count);
-			args[4] = lb_emit_source_code_location(p, proc_name, pos);
+			args[4] = lb_emit_source_code_location_as_global(p, proc_name, pos);
 			lb_emit_runtime_call(p, "__dynamic_array_reserve", args);
 			lb_emit_runtime_call(p, "__dynamic_array_reserve", args);
 		}
 		}
 
 
@@ -4253,7 +4252,7 @@ lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) {
 			args[2] = align;
 			args[2] = align;
 			args[3] = lb_emit_conv(p, items, t_rawptr);
 			args[3] = lb_emit_conv(p, items, t_rawptr);
 			args[4] = lb_const_int(p->module, t_int, item_count);
 			args[4] = lb_const_int(p->module, t_int, item_count);
-			args[5] = lb_emit_source_code_location(p, proc_name, pos);
+			args[5] = lb_emit_source_code_location_as_global(p, proc_name, pos);
 			lb_emit_runtime_call(p, "__dynamic_array_append", args);
 			lb_emit_runtime_call(p, "__dynamic_array_append", args);
 		}
 		}
 		break;
 		break;

+ 40 - 9
src/llvm_backend_general.cpp

@@ -383,16 +383,27 @@ Type *lb_addr_type(lbAddr const &addr) {
 	if (addr.addr.value == nullptr) {
 	if (addr.addr.value == nullptr) {
 		return nullptr;
 		return nullptr;
 	}
 	}
-	if (addr.kind == lbAddr_Map) {
-		Type *t = base_type(addr.map.type);
-		GB_ASSERT(is_type_map(t));
-		return t->Map.value;
-	}
-	if (addr.kind == lbAddr_Swizzle) {
+	switch (addr.kind) {
+	case lbAddr_Map:
+		{
+			Type *t = base_type(addr.map.type);
+			GB_ASSERT(is_type_map(t));
+			return t->Map.value;
+		}
+	case lbAddr_Swizzle:
 		return addr.swizzle.type;
 		return addr.swizzle.type;
-	}
-	if (addr.kind == lbAddr_SwizzleLarge) {
+	case lbAddr_SwizzleLarge:
 		return addr.swizzle_large.type;
 		return addr.swizzle_large.type;
+	case lbAddr_Context:
+		if (addr.ctx.sel.index.count > 0) {
+			Type *t = t_context;
+			for_array(i, addr.ctx.sel.index) {
+				GB_ASSERT(is_type_struct(t));
+				t = base_type(t)->Struct.fields[addr.ctx.sel.index[i]]->type;
+			}
+			return t;
+		}
+		break;
 	}
 	}
 	return type_deref(addr.addr.type);
 	return type_deref(addr.addr.type);
 }
 }
@@ -1507,6 +1518,7 @@ LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type) {
 
 
 	LLVMTypeRef ret = nullptr;
 	LLVMTypeRef ret = nullptr;
 	LLVMTypeRef *params = gb_alloc_array(permanent_allocator(), LLVMTypeRef, param_count);
 	LLVMTypeRef *params = gb_alloc_array(permanent_allocator(), LLVMTypeRef, param_count);
+	bool *params_by_ptr = gb_alloc_array(permanent_allocator(), bool, param_count);
 	if (type->Proc.result_count != 0) {
 	if (type->Proc.result_count != 0) {
 		Type *single_ret = reduce_tuple_to_single_type(type->Proc.results);
 		Type *single_ret = reduce_tuple_to_single_type(type->Proc.results);
 		ret = lb_type(m, single_ret);
 		ret = lb_type(m, single_ret);
@@ -1532,9 +1544,12 @@ LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type) {
 			}
 			}
 			Type *e_type = reduce_tuple_to_single_type(e->type);
 			Type *e_type = reduce_tuple_to_single_type(e->type);
 
 
+			bool param_is_by_ptr = false;
 			LLVMTypeRef param_type = nullptr;
 			LLVMTypeRef param_type = nullptr;
 			if (e->flags & EntityFlag_ByPtr) {
 			if (e->flags & EntityFlag_ByPtr) {
-				param_type = lb_type(m, alloc_type_pointer(e_type));
+				// it will become a pointer afterwards by making it indirect
+				param_type = lb_type(m, e_type);
+				param_is_by_ptr = true;
 			} else if (is_type_boolean(e_type) &&
 			} else if (is_type_boolean(e_type) &&
 			    type_size_of(e_type) <= 1) {
 			    type_size_of(e_type) <= 1) {
 				param_type = LLVMInt1TypeInContext(m->ctx);
 				param_type = LLVMInt1TypeInContext(m->ctx);
@@ -1546,6 +1561,7 @@ LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type) {
 				}
 				}
 			}
 			}
 
 
+			params_by_ptr[param_index] = param_is_by_ptr;
 			params[param_index++] = param_type;
 			params[param_index++] = param_type;
 		}
 		}
 	}
 	}
@@ -1571,6 +1587,12 @@ LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *type) {
 		              LLVMPrintTypeToString(ft->ret.type),
 		              LLVMPrintTypeToString(ft->ret.type),
 		              LLVMGetTypeContext(ft->ret.type), ft->ctx, LLVMGetGlobalContext());
 		              LLVMGetTypeContext(ft->ret.type), ft->ctx, LLVMGetGlobalContext());
 	}
 	}
+	for_array(j, ft->args) {
+		if (params_by_ptr[j]) {
+			// NOTE(bill): The parameter needs to be passed "indirectly", override it
+			ft->args[j].kind = lbArg_Indirect;
+		}
+	}
 
 
 	map_set(&m->function_type_map, type, ft);
 	map_set(&m->function_type_map, type, ft);
 	LLVMTypeRef new_abi_fn_type = lb_function_type_to_llvm_raw(ft, type->Proc.c_vararg);
 	LLVMTypeRef new_abi_fn_type = lb_function_type_to_llvm_raw(ft, type->Proc.c_vararg);
@@ -2579,6 +2601,15 @@ lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule *m, String co
 
 
 
 
 lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
 lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
+	if (e->flags & EntityFlag_Param) {
+		// NOTE(bill): Bypass the stack copied variable for
+		// direct parameters as there is no need for the direct load
+		auto *found = map_get(&p->direct_parameters, e);
+		if (found) {
+			return *found;
+		}
+	}
+
 	auto *found = map_get(&m->values, e);
 	auto *found = map_get(&m->values, e);
 	if (found) {
 	if (found) {
 		auto v = *found;
 		auto v = *found;

+ 60 - 4
src/llvm_backend_proc.cpp

@@ -486,6 +486,8 @@ void lb_begin_procedure_body(lbProcedure *p) {
 	p->entry_block = lb_create_block(p, "entry", true);
 	p->entry_block = lb_create_block(p, "entry", true);
 	lb_start_block(p, p->entry_block);
 	lb_start_block(p, p->entry_block);
 
 
+	map_init(&p->direct_parameters, heap_allocator());
+
 	GB_ASSERT(p->type != nullptr);
 	GB_ASSERT(p->type != nullptr);
 
 
 	lb_ensure_abi_function_type(p->module, p);
 	lb_ensure_abi_function_type(p->module, p);
@@ -539,6 +541,8 @@ void lb_begin_procedure_body(lbProcedure *p) {
 						param.value = value;
 						param.value = value;
 						param.type = e->type;
 						param.type = e->type;
 
 
+						map_set(&p->direct_parameters, e, param);
+
 						lbValue ptr = lb_address_from_load_or_generate_local(p, param);
 						lbValue ptr = lb_address_from_load_or_generate_local(p, param);
 						GB_ASSERT(LLVMIsAAllocaInst(ptr.value));
 						GB_ASSERT(LLVMIsAAllocaInst(ptr.value));
 						lb_add_entity(p->module, e, ptr);
 						lb_add_entity(p->module, e, ptr);
@@ -753,12 +757,16 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
 		}
 		}
 		GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
 		GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
 
 
+		lbFunctionType *ft = map_must_get(&p->module->function_type_map, base_type(value.type));
+
 		{
 		{
 			unsigned param_count = LLVMCountParamTypes(fnp);
 			unsigned param_count = LLVMCountParamTypes(fnp);
 			GB_ASSERT(arg_count >= param_count);
 			GB_ASSERT(arg_count >= param_count);
 
 
 			LLVMTypeRef *param_types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, param_count);
 			LLVMTypeRef *param_types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, param_count);
 			LLVMGetParamTypes(fnp, param_types);
 			LLVMGetParamTypes(fnp, param_types);
+
+
 			for (unsigned i = 0; i < param_count; i++) {
 			for (unsigned i = 0; i < param_count; i++) {
 				LLVMTypeRef param_type = param_types[i];
 				LLVMTypeRef param_type = param_types[i];
 				LLVMTypeRef arg_type = LLVMTypeOf(args[i]);
 				LLVMTypeRef arg_type = LLVMTypeOf(args[i]);
@@ -776,10 +784,20 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
 
 
 		LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, "");
 		LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, "");
 
 
+		LLVMAttributeIndex param_offset = LLVMAttributeIndex_FirstArgIndex;
 		if (return_ptr.value != nullptr) {
 		if (return_ptr.value != nullptr) {
+			param_offset += 1;
+
 			LLVMAddCallSiteAttribute(ret, 1, lb_create_enum_attribute_with_type(p->module->ctx, "sret", LLVMTypeOf(args[0])));
 			LLVMAddCallSiteAttribute(ret, 1, lb_create_enum_attribute_with_type(p->module->ctx, "sret", LLVMTypeOf(args[0])));
 		}
 		}
 
 
+		for_array(i, ft->args) {
+			LLVMAttributeRef attribute = ft->args[i].attribute;
+			if (attribute != nullptr) {
+				LLVMAddCallSiteAttribute(ret, param_offset + cast(LLVMAttributeIndex)i, attribute);
+			}
+		}
+
 		switch (inlining) {
 		switch (inlining) {
 		case ProcInlining_none:
 		case ProcInlining_none:
 			break;
 			break;
@@ -893,6 +911,9 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args,
 	auto processed_args = array_make<lbValue>(permanent_allocator(), 0, args.count);
 	auto processed_args = array_make<lbValue>(permanent_allocator(), 0, args.count);
 
 
 	{
 	{
+
+		bool is_odin_cc = is_calling_convention_odin(pt->Proc.calling_convention);
+
 		lbFunctionType *ft = lb_get_function_type(m, p, pt);
 		lbFunctionType *ft = lb_get_function_type(m, p, pt);
 		bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
 		bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
 
 
@@ -928,8 +949,12 @@ lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args,
 			} else if (arg->kind == lbArg_Indirect) {
 			} else if (arg->kind == lbArg_Indirect) {
 				lbValue ptr = {};
 				lbValue ptr = {};
 				if (arg->is_byval) {
 				if (arg->is_byval) {
-					ptr = lb_copy_value_to_ptr(p, x, original_type, arg->byval_alignment);
-				} else if (is_calling_convention_odin(pt->Proc.calling_convention)) {
+					if (is_odin_cc && are_types_identical(original_type, t_source_code_location)) {
+						ptr = lb_address_from_load_or_generate_local(p, x);
+					} else {
+						ptr = lb_copy_value_to_ptr(p, x, original_type, arg->byval_alignment);
+					}
+				} else if (is_odin_cc) {
 					// NOTE(bill): Odin parameters are immutable so the original value can be passed if possible
 					// NOTE(bill): Odin parameters are immutable so the original value can be passed if possible
 					// i.e. `T const &` in C++
 					// i.e. `T const &` in C++
 					ptr = lb_address_from_load_or_generate_local(p, x);
 					ptr = lb_address_from_load_or_generate_local(p, x);
@@ -1485,7 +1510,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
 			pos = e->token.pos;
 			pos = e->token.pos;
 
 
 		}
 		}
-		return lb_emit_source_code_location(p, procedure, pos);
+		return lb_emit_source_code_location_as_global(p, procedure, pos);
 	}
 	}
 
 
 	case BuiltinProc_type_info_of: {
 	case BuiltinProc_type_info_of: {
@@ -1836,6 +1861,37 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
 		lb_emit_unreachable(p);
 		lb_emit_unreachable(p);
 		return {};
 		return {};
 
 
+	case BuiltinProc_raw_data:
+		{
+			lbValue x = lb_build_expr(p, ce->args[0]);
+			Type *t = base_type(x.type);
+			lbValue res = {};
+			switch (t->kind) {
+			case Type_Slice:
+				res = lb_slice_elem(p, x);
+				res = lb_emit_conv(p, res, tv.type);
+				break;
+			case Type_DynamicArray:
+				res = lb_dynamic_array_elem(p, x);
+				res = lb_emit_conv(p, res, tv.type);
+				break;
+			case Type_Basic:
+				if (t->Basic.kind == Basic_string) {
+					res = lb_string_elem(p, x);
+					res = lb_emit_conv(p, res, tv.type);
+				} else if (t->Basic.kind == Basic_cstring) {
+					res = lb_emit_conv(p, x, tv.type);
+				}
+				break;
+			case Type_Pointer:
+			case Type_MultiPointer:
+				res = lb_emit_conv(p, x, tv.type);
+				break;
+			}
+			GB_ASSERT(res.value != nullptr);
+			return res;
+		}
+
 
 
 	// "Intrinsics"
 	// "Intrinsics"
 
 
@@ -2825,7 +2881,7 @@ lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterVal
 			if (p->entity != nullptr) {
 			if (p->entity != nullptr) {
 				proc_name = p->entity->token.string;
 				proc_name = p->entity->token.string;
 			}
 			}
-			return lb_emit_source_code_location(p, proc_name, pos);
+			return lb_emit_source_code_location_as_global(p, proc_name, pos);
 		}
 		}
 	case ParameterValue_Value:
 	case ParameterValue_Value:
 		return lb_build_expr(p, param_value.ast_value);
 		return lb_build_expr(p, param_value.ast_value);

+ 1 - 1
src/llvm_backend_type.cpp

@@ -235,7 +235,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
 			}
 			}
 			TokenPos pos = t->Named.type_name->token.pos;
 			TokenPos pos = t->Named.type_name->token.pos;
 
 
-			lbValue loc = lb_emit_source_code_location(p, proc_name, pos);
+			lbValue loc = lb_emit_source_code_location_const(p, proc_name, pos);
 
 
 			LLVMValueRef vals[4] = {
 			LLVMValueRef vals[4] = {
 				lb_const_string(p->module, t->Named.type_name->token.string).value,
 				lb_const_string(p->module, t->Named.type_name->token.string).value,

+ 37 - 48
src/main.cpp

@@ -53,6 +53,9 @@ gb_global Timings global_timings = {0};
 	#if LLVM_VERSION_MAJOR < 11
 	#if LLVM_VERSION_MAJOR < 11
 	#error LLVM Version 11+ is required => "brew install llvm@11"
 	#error LLVM Version 11+ is required => "brew install llvm@11"
 	#endif
 	#endif
+	#if LLVM_VERSION_MAJOR > 14
+	#error LLVM Version 11..=14 is required => "brew install llvm@14"
+	#endif
 #endif
 #endif
 
 
 #include "query_data.cpp"
 #include "query_data.cpp"
@@ -478,9 +481,9 @@ i32 linker_stage(lbGenerator *gen) {
 
 
 			if (build_context.metrics.os == TargetOs_darwin) {
 			if (build_context.metrics.os == TargetOs_darwin) {
 				// This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit.
 				// This sets a requirement of Mountain Lion and up, but the compiler doesn't work without this limit.
-				// NOTE: If you change this (although this minimum is as low as you can go with Odin working)
-				//       make sure to also change the 'mtriple' param passed to 'opt'
-				if (build_context.metrics.arch == TargetArch_arm64) {
+				if (build_context.minimum_os_version_string.len) {
+					link_settings = gb_string_append_fmt(link_settings, " -mmacosx-version-min=%.*s ", LIT(build_context.minimum_os_version_string));
+				} else if (build_context.metrics.arch == TargetArch_arm64) {
 					link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=12.0.0  ");
 					link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=12.0.0  ");
 				} else {
 				} else {
 					link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=10.12.0 ");
 					link_settings = gb_string_appendc(link_settings, " -mmacosx-version-min=10.12.0 ");
@@ -588,7 +591,6 @@ enum BuildFlagKind {
 	BuildFlag_SingleFile,
 	BuildFlag_SingleFile,
 
 
 	BuildFlag_OutFile,
 	BuildFlag_OutFile,
-	BuildFlag_OptimizationLevel,
 	BuildFlag_OptimizationMode,
 	BuildFlag_OptimizationMode,
 	BuildFlag_ShowTimings,
 	BuildFlag_ShowTimings,
 	BuildFlag_ShowUnused,
 	BuildFlag_ShowUnused,
@@ -622,6 +624,7 @@ enum BuildFlagKind {
 	BuildFlag_ExtraAssemblerFlags,
 	BuildFlag_ExtraAssemblerFlags,
 	BuildFlag_Microarch,
 	BuildFlag_Microarch,
 	BuildFlag_TargetFeatures,
 	BuildFlag_TargetFeatures,
+	BuildFlag_MinimumOSVersion,
 
 
 	BuildFlag_RelocMode,
 	BuildFlag_RelocMode,
 	BuildFlag_DisableRedZone,
 	BuildFlag_DisableRedZone,
@@ -742,13 +745,25 @@ ExactValue build_param_to_exact_value(String name, String param) {
 	return value;
 	return value;
 }
 }
 
 
+// Writes a did-you-mean message for formerly deprecated flags.
+void did_you_mean_flag(String flag) {
+	gbAllocator a = heap_allocator();
+	String name = copy_string(a, flag);
+	defer (gb_free(a, name.text));
+	string_to_lower(&name);
+
+	if (name == "opt") {
+		gb_printf_err("`-opt` is an unrecognized option. Did you mean `-o`?\n");
+		return;
+	}
+	gb_printf_err("Unknown flag: '%.*s'\n", LIT(flag));
+}
 
 
 bool parse_build_flags(Array<String> args) {
 bool parse_build_flags(Array<String> args) {
 	auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT);
 	auto build_flags = array_make<BuildFlag>(heap_allocator(), 0, BuildFlag_COUNT);
 	add_flag(&build_flags, BuildFlag_Help,                    str_lit("help"),                      BuildFlagParam_None,    Command_all);
 	add_flag(&build_flags, BuildFlag_Help,                    str_lit("help"),                      BuildFlagParam_None,    Command_all);
 	add_flag(&build_flags, BuildFlag_SingleFile,              str_lit("file"),                      BuildFlagParam_None,    Command__does_build | Command__does_check);
 	add_flag(&build_flags, BuildFlag_SingleFile,              str_lit("file"),                      BuildFlagParam_None,    Command__does_build | Command__does_check);
 	add_flag(&build_flags, BuildFlag_OutFile,                 str_lit("out"),                       BuildFlagParam_String,  Command__does_build &~ Command_test);
 	add_flag(&build_flags, BuildFlag_OutFile,                 str_lit("out"),                       BuildFlagParam_String,  Command__does_build &~ Command_test);
-	add_flag(&build_flags, BuildFlag_OptimizationLevel,       str_lit("opt"),                       BuildFlagParam_Integer, Command__does_build);
 	add_flag(&build_flags, BuildFlag_OptimizationMode,        str_lit("o"),                         BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_OptimizationMode,        str_lit("o"),                         BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_OptimizationMode,        str_lit("O"),                         BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_OptimizationMode,        str_lit("O"),                         BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_ShowTimings,             str_lit("show-timings"),              BuildFlagParam_None,    Command__does_check);
 	add_flag(&build_flags, BuildFlag_ShowTimings,             str_lit("show-timings"),              BuildFlagParam_None,    Command__does_check);
@@ -783,6 +798,7 @@ bool parse_build_flags(Array<String> args) {
 	add_flag(&build_flags, BuildFlag_ExtraAssemblerFlags,     str_lit("extra-assembler-flags"),     BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_ExtraAssemblerFlags,     str_lit("extra-assembler-flags"),     BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_Microarch,               str_lit("microarch"),                 BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_Microarch,               str_lit("microarch"),                 BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_TargetFeatures,          str_lit("target-features"),           BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_TargetFeatures,          str_lit("target-features"),           BuildFlagParam_String,  Command__does_build);
+	add_flag(&build_flags, BuildFlag_MinimumOSVersion,        str_lit("minimum-os-version"),        BuildFlagParam_String,  Command__does_build);
 
 
 	add_flag(&build_flags, BuildFlag_RelocMode,               str_lit("reloc-mode"),                BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_RelocMode,               str_lit("reloc-mode"),                BuildFlagParam_String,  Command__does_build);
 	add_flag(&build_flags, BuildFlag_DisableRedZone,          str_lit("disable-red-zone"),          BuildFlagParam_None,    Command__does_build);
 	add_flag(&build_flags, BuildFlag_DisableRedZone,          str_lit("disable-red-zone"),          BuildFlagParam_None,    Command__does_build);
@@ -850,16 +866,14 @@ bool parse_build_flags(Array<String> args) {
 				break;
 				break;
 			}
 			}
 		}
 		}
-		name = substring(name, 0, end);
-		if (have_equals && name != "opt") {
-			gb_printf_err("`flag=value` has been deprecated and will be removed next release. Use `%.*s:` instead.\n", LIT(name));
-		}
 
 
+		name = substring(name, 0, end);
 		String param = {};
 		String param = {};
 		if (end < flag.len-1) param = substring(flag, 2+end, flag.len);
 		if (end < flag.len-1) param = substring(flag, 2+end, flag.len);
 
 
 		bool is_supported = true;
 		bool is_supported = true;
 		bool found = false;
 		bool found = false;
+
 		BuildFlag found_bf = {};
 		BuildFlag found_bf = {};
 		for_array(build_flag_index, build_flags) {
 		for_array(build_flag_index, build_flags) {
 			BuildFlag bf = build_flags[build_flag_index];
 			BuildFlag bf = build_flags[build_flag_index];
@@ -979,37 +993,8 @@ bool parse_build_flags(Array<String> args) {
 							}
 							}
 							break;
 							break;
 						}
 						}
-						case BuildFlag_OptimizationLevel: {
-							GB_ASSERT(value.kind == ExactValue_Integer);
-							if (set_flags[BuildFlag_OptimizationMode]) {
-								gb_printf_err("Mixture of -opt and -o is not allowed\n");
-								bad_flags = true;
-								break;
-							}
-
-							build_context.optimization_level = cast(i32)big_int_to_i64(&value.value_integer);
-							if (build_context.optimization_level < 0 || build_context.optimization_level > 3) {
-								gb_printf_err("Invalid optimization level for -o:<integer>, got %d\n", build_context.optimization_level);
-								gb_printf_err("Valid optimization levels:\n");
-								gb_printf_err("\t0\n");
-								gb_printf_err("\t1\n");
-								gb_printf_err("\t2\n");
-								gb_printf_err("\t3\n");
-								bad_flags = true;
-							}
-
-							// Deprecation warning.
-							gb_printf_err("`-opt` has been deprecated and will be removed next release. Use `-o:minimal`, etc.\n");
-							break;
-						}
 						case BuildFlag_OptimizationMode: {
 						case BuildFlag_OptimizationMode: {
 							GB_ASSERT(value.kind == ExactValue_String);
 							GB_ASSERT(value.kind == ExactValue_String);
-							if (set_flags[BuildFlag_OptimizationLevel]) {
-								gb_printf_err("Mixture of -opt and -o is not allowed\n");
-								bad_flags = true;
-								break;
-							}
-
 							if (value.value_string == "minimal") {
 							if (value.value_string == "minimal") {
 								build_context.optimization_level = 0;
 								build_context.optimization_level = 0;
 							} else if (value.value_string == "size") {
 							} else if (value.value_string == "size") {
@@ -1378,6 +1363,11 @@ bool parse_build_flags(Array<String> args) {
 							string_to_lower(&build_context.target_features_string);
 							string_to_lower(&build_context.target_features_string);
 							break;
 							break;
 						}
 						}
+						case BuildFlag_MinimumOSVersion: {
+							GB_ASSERT(value.kind == ExactValue_String);
+							build_context.minimum_os_version_string = value.value_string;
+							break;
+						}
 						case BuildFlag_RelocMode: {
 						case BuildFlag_RelocMode: {
 							GB_ASSERT(value.kind == ExactValue_String);
 							GB_ASSERT(value.kind == ExactValue_String);
 							String v = value.value_string;
 							String v = value.value_string;
@@ -1625,7 +1615,7 @@ bool parse_build_flags(Array<String> args) {
 			gb_printf_err("\n");
 			gb_printf_err("\n");
 			bad_flags = true;
 			bad_flags = true;
 		} else if (!found) {
 		} else if (!found) {
-			gb_printf_err("Unknown flag: '%.*s'\n", LIT(name));
+			did_you_mean_flag(name);
 			bad_flags = true;
 			bad_flags = true;
 		}
 		}
 	}
 	}
@@ -1989,12 +1979,6 @@ void print_show_help(String const arg0, String const &command) {
 		print_usage_line(2, "Example: -out:foo.exe");
 		print_usage_line(2, "Example: -out:foo.exe");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
-		print_usage_line(1, "-opt:<integer>");
-		print_usage_line(2, "Set the optimization level for compilation");
-		print_usage_line(2, "Accepted values: 0, 1, 2, 3");
-		print_usage_line(2, "Example: -opt:2");
-		print_usage_line(0, "");
-
 		print_usage_line(1, "-o:<string>");
 		print_usage_line(1, "-o:<string>");
 		print_usage_line(2, "Set the optimization mode for compilation");
 		print_usage_line(2, "Set the optimization mode for compilation");
 		print_usage_line(2, "Accepted values: minimal, size, speed");
 		print_usage_line(2, "Accepted values: minimal, size, speed");
@@ -2056,8 +2040,8 @@ void print_show_help(String const arg0, String const &command) {
 		print_usage_line(3, "import \"shared:foo\"");
 		print_usage_line(3, "import \"shared:foo\"");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
-		print_usage_line(1, "-define:<name>=<expression>");
-		print_usage_line(2, "Defines a global constant with a value");
+		print_usage_line(1, "-define:<name>=<value>");
+		print_usage_line(2, "Defines a scalar boolean, integer or string as global constant");
 		print_usage_line(2, "Example: -define:SPAM=123");
 		print_usage_line(2, "Example: -define:SPAM=123");
 		print_usage_line(2, "To use:  #config(SPAM, default_value)");
 		print_usage_line(2, "To use:  #config(SPAM, default_value)");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
@@ -2158,6 +2142,12 @@ void print_show_help(String const arg0, String const &command) {
 	}
 	}
 
 
 	if (run_or_build) {
 	if (run_or_build) {
+		print_usage_line(1, "-minimum-os-version:<string>");
+		print_usage_line(2, "Sets the minimum OS version targeted by the application");
+		print_usage_line(2, "e.g. -minimum-os-version:12.0.0");
+		print_usage_line(2, "(Only used when target is Darwin)");
+		print_usage_line(0, "");
+
 		print_usage_line(1, "-extra-linker-flags:<string>");
 		print_usage_line(1, "-extra-linker-flags:<string>");
 		print_usage_line(2, "Adds extra linker specific flags in a string");
 		print_usage_line(2, "Adds extra linker specific flags in a string");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
@@ -2166,7 +2156,6 @@ void print_show_help(String const arg0, String const &command) {
 		print_usage_line(2, "Adds extra assembler specific flags in a string");
 		print_usage_line(2, "Adds extra assembler specific flags in a string");
 		print_usage_line(0, "");
 		print_usage_line(0, "");
 
 
-
 		print_usage_line(1, "-microarch:<string>");
 		print_usage_line(1, "-microarch:<string>");
 		print_usage_line(2, "Specifies the specific micro-architecture for the build in a string");
 		print_usage_line(2, "Specifies the specific micro-architecture for the build in a string");
 		print_usage_line(2, "Examples:");
 		print_usage_line(2, "Examples:");

+ 38 - 0
src/types.cpp

@@ -2526,6 +2526,44 @@ String lookup_subtype_polymorphic_field(Type *dst, Type *src) {
 	return str_lit("");
 	return str_lit("");
 }
 }
 
 
+bool lookup_subtype_polymorphic_selection(Type *dst, Type *src, Selection *sel) {
+	Type *prev_src = src;
+	// Type *prev_dst = dst;
+	src = base_type(type_deref(src));
+	// dst = base_type(type_deref(dst));
+	bool src_is_ptr = src != prev_src;
+	// bool dst_is_ptr = dst != prev_dst;
+
+	GB_ASSERT(is_type_struct(src) || is_type_union(src));
+	for_array(i, src->Struct.fields) {
+		Entity *f = src->Struct.fields[i];
+		if (f->kind == Entity_Variable && f->flags & EntityFlags_IsSubtype) {
+			if (are_types_identical(dst, f->type)) {
+				array_add(&sel->index, cast(i32)i);
+				sel->entity = f;
+				return true;
+			}
+			if (src_is_ptr && is_type_pointer(dst)) {
+				if (are_types_identical(type_deref(dst), f->type)) {
+					array_add(&sel->index, cast(i32)i);
+					sel->indirect = true;
+					sel->entity = f;
+					return true;
+				}
+			}
+			if ((f->flags & EntityFlag_Using) != 0 && is_type_struct(f->type)) {
+				String name = lookup_subtype_polymorphic_field(dst, f->type);
+				if (name.len > 0) {
+					array_add(&sel->index, cast(i32)i);
+					return lookup_subtype_polymorphic_selection(dst, f->type, sel);
+				}
+			}
+		}
+	}
+	return false;
+}
+
+
 
 
 
 
 Type *strip_type_aliasing(Type *x) {
 Type *strip_type_aliasing(Type *x) {

+ 12 - 6
tests/issues/run.bat

@@ -1,17 +1,23 @@
 @echo off
 @echo off
 
 
 if not exist "build\" mkdir build
 if not exist "build\" mkdir build
+pushd build
 
 
-set COMMON=-collection:tests=.. -out:build\test_issue.exe
+set COMMON=-collection:tests=..\..
 
 
-@echo on
+set ERROR_DID_OCCUR=0
 
 
-..\..\odin build test_issue_829.odin %COMMON% -file
-build\test_issue
+@echo on
 
 
-..\..\odin build test_issue_1592.odin %COMMON% -file
-build\test_issue
+..\..\..\odin test ..\test_issue_829.odin %COMMON% -file
+..\..\..\odin test ..\test_issue_1592.odin %COMMON% -file
+..\..\..\odin test ..\test_issue_2087.odin %COMMON% -file
+..\..\..\odin build ..\test_issue_2113.odin %COMMON% -file -debug
 
 
 @echo off
 @echo off
 
 
+if %ERRORLEVEL% NEQ 0 set ERROR_DID_OCCUR=1
+
+popd
 rmdir /S /Q build
 rmdir /S /Q build
+if %ERROR_DID_OCCUR% NEQ 0 EXIT /B 1

+ 8 - 7
tests/issues/run.sh

@@ -2,17 +2,18 @@
 set -eu
 set -eu
 
 
 mkdir -p build
 mkdir -p build
-ODIN=../../odin
-COMMON="-collection:tests=.. -out:build/test_issue"
+pushd build
+ODIN=../../../odin
+COMMON="-collection:tests=../.."
 
 
 set -x
 set -x
 
 
-$ODIN build test_issue_829.odin $COMMON -file
-./build/test_issue
-
-$ODIN build test_issue_1592.odin $COMMON -file
-./build/test_issue
+$ODIN test ../test_issue_829.odin  $COMMON -file
+$ODIN test ../test_issue_1592.odin $COMMON -file
+$ODIN test ../test_issue_2087.odin $COMMON -file
+$ODIN build ../test_issue_2113.odin $COMMON -file -debug
 
 
 set +x
 set +x
 
 
+popd
 rm -rf build
 rm -rf build

+ 146 - 177
tests/issues/test_issue_1592.odin

@@ -3,36 +3,6 @@ package test_issues
 
 
 import "core:fmt"
 import "core:fmt"
 import "core:testing"
 import "core:testing"
-import tc "tests:common"
-
-main :: proc() {
-	t := testing.T{}
-
-	/* This won't short-circuit */
-	test_orig()
-
-	/* These will short-circuit */
-	test_simple_const_false(&t)
-	test_simple_const_true(&t)
-
-	/* These won't short-circuit */
-	test_simple_proc_false(&t)
-	test_simple_proc_true(&t)
-
-	/* These won't short-circuit */
-	test_const_false_const_false(&t)
-	test_const_false_const_true(&t)
-	test_const_true_const_false(&t)
-	test_const_true_const_true(&t)
-
-	/* These won't short-circuit */
-	test_proc_false_const_false(&t)
-	test_proc_false_const_true(&t)
-	test_proc_true_const_false(&t)
-	test_proc_true_const_true(&t)
-
-	tc.report(&t)
-}
 
 
 /* Original issue #1592 example */
 /* Original issue #1592 example */
 
 
@@ -43,7 +13,6 @@ bool_result :: proc() -> bool {
 	return false
 	return false
 }
 }
 
 
-@test
 test_orig :: proc() {
 test_orig :: proc() {
 	if bool_result() || CONSTANT_BOOL {
 	if bool_result() || CONSTANT_BOOL {
 	}
 	}
@@ -62,428 +31,428 @@ true_result :: proc() -> bool {
 @test
 @test
 test_simple_const_false :: proc(t: ^testing.T) {
 test_simple_const_false :: proc(t: ^testing.T) {
 	if CONSTANT_FALSE {
 	if CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if (CONSTANT_FALSE) {
 	if (CONSTANT_FALSE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !CONSTANT_FALSE {
 	if !CONSTANT_FALSE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if (!CONSTANT_FALSE) {
 	if (!CONSTANT_FALSE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !(CONSTANT_FALSE) {
 	if !(CONSTANT_FALSE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !!CONSTANT_FALSE {
 	if !!CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if CONSTANT_FALSE == true {
 	if CONSTANT_FALSE == true {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if CONSTANT_FALSE == false {
 	if CONSTANT_FALSE == false {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !(CONSTANT_FALSE == true) {
 	if !(CONSTANT_FALSE == true) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !(CONSTANT_FALSE == false) {
 	if !(CONSTANT_FALSE == false) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_simple_const_true :: proc(t: ^testing.T) {
 test_simple_const_true :: proc(t: ^testing.T) {
 	if CONSTANT_TRUE {
 	if CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if (CONSTANT_TRUE) {
 	if (CONSTANT_TRUE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !CONSTANT_TRUE {
 	if !CONSTANT_TRUE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if (!CONSTANT_TRUE) {
 	if (!CONSTANT_TRUE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if (!CONSTANT_TRUE) {
 	if (!CONSTANT_TRUE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !(CONSTANT_TRUE) {
 	if !(CONSTANT_TRUE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !!CONSTANT_TRUE {
 	if !!CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if CONSTANT_TRUE == true {
 	if CONSTANT_TRUE == true {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if CONSTANT_TRUE == false {
 	if CONSTANT_TRUE == false {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !(CONSTANT_TRUE == true) {
 	if !(CONSTANT_TRUE == true) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !(CONSTANT_TRUE == false) {
 	if !(CONSTANT_TRUE == false) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_simple_proc_false :: proc(t: ^testing.T) {
 test_simple_proc_false :: proc(t: ^testing.T) {
 	if false_result() {
 	if false_result() {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !false_result() {
 	if !false_result() {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_simple_proc_true :: proc(t: ^testing.T) {
 test_simple_proc_true :: proc(t: ^testing.T) {
 	if true_result() {
 	if true_result() {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !true_result() {
 	if !true_result() {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_const_false_const_false :: proc(t: ^testing.T) {
 test_const_false_const_false :: proc(t: ^testing.T) {
 	if CONSTANT_FALSE || CONSTANT_FALSE {
 	if CONSTANT_FALSE || CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if CONSTANT_FALSE && CONSTANT_FALSE {
 	if CONSTANT_FALSE && CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if !CONSTANT_FALSE || CONSTANT_FALSE {
 	if !CONSTANT_FALSE || CONSTANT_FALSE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !CONSTANT_FALSE && CONSTANT_FALSE {
 	if !CONSTANT_FALSE && CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if CONSTANT_FALSE || !CONSTANT_FALSE {
 	if CONSTANT_FALSE || !CONSTANT_FALSE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if CONSTANT_FALSE && !CONSTANT_FALSE {
 	if CONSTANT_FALSE && !CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if !(CONSTANT_FALSE || CONSTANT_FALSE) {
 	if !(CONSTANT_FALSE || CONSTANT_FALSE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !(CONSTANT_FALSE && CONSTANT_FALSE) {
 	if !(CONSTANT_FALSE && CONSTANT_FALSE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_const_false_const_true :: proc(t: ^testing.T) {
 test_const_false_const_true :: proc(t: ^testing.T) {
 	if CONSTANT_FALSE || CONSTANT_TRUE {
 	if CONSTANT_FALSE || CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if CONSTANT_FALSE && CONSTANT_TRUE {
 	if CONSTANT_FALSE && CONSTANT_TRUE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if !CONSTANT_FALSE || CONSTANT_TRUE {
 	if !CONSTANT_FALSE || CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !CONSTANT_FALSE && CONSTANT_TRUE {
 	if !CONSTANT_FALSE && CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 
 
 	if CONSTANT_FALSE || !CONSTANT_TRUE {
 	if CONSTANT_FALSE || !CONSTANT_TRUE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if CONSTANT_FALSE && !CONSTANT_TRUE {
 	if CONSTANT_FALSE && !CONSTANT_TRUE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if !(CONSTANT_FALSE || CONSTANT_TRUE) {
 	if !(CONSTANT_FALSE || CONSTANT_TRUE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !(CONSTANT_FALSE && CONSTANT_TRUE) {
 	if !(CONSTANT_FALSE && CONSTANT_TRUE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_const_true_const_false :: proc(t: ^testing.T) {
 test_const_true_const_false :: proc(t: ^testing.T) {
 	if CONSTANT_TRUE || CONSTANT_FALSE {
 	if CONSTANT_TRUE || CONSTANT_FALSE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if CONSTANT_TRUE && CONSTANT_FALSE {
 	if CONSTANT_TRUE && CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if !CONSTANT_TRUE || CONSTANT_FALSE {
 	if !CONSTANT_TRUE || CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !CONSTANT_TRUE && CONSTANT_FALSE {
 	if !CONSTANT_TRUE && CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if CONSTANT_TRUE || !CONSTANT_FALSE {
 	if CONSTANT_TRUE || !CONSTANT_FALSE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if CONSTANT_TRUE && !CONSTANT_FALSE {
 	if CONSTANT_TRUE && !CONSTANT_FALSE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 
 
 	if !(CONSTANT_TRUE || CONSTANT_FALSE) {
 	if !(CONSTANT_TRUE || CONSTANT_FALSE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !(CONSTANT_TRUE && CONSTANT_FALSE) {
 	if !(CONSTANT_TRUE && CONSTANT_FALSE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_const_true_const_true :: proc(t: ^testing.T) {
 test_const_true_const_true :: proc(t: ^testing.T) {
 	if CONSTANT_TRUE || CONSTANT_TRUE {
 	if CONSTANT_TRUE || CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if CONSTANT_TRUE && CONSTANT_TRUE {
 	if CONSTANT_TRUE && CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 
 
 	if !CONSTANT_TRUE || CONSTANT_TRUE {
 	if !CONSTANT_TRUE || CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !CONSTANT_TRUE && CONSTANT_TRUE {
 	if !CONSTANT_TRUE && CONSTANT_TRUE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if CONSTANT_TRUE || !CONSTANT_TRUE {
 	if CONSTANT_TRUE || !CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if CONSTANT_TRUE && !CONSTANT_TRUE {
 	if CONSTANT_TRUE && !CONSTANT_TRUE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if !(CONSTANT_TRUE || CONSTANT_TRUE) {
 	if !(CONSTANT_TRUE || CONSTANT_TRUE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !(CONSTANT_TRUE && CONSTANT_TRUE) {
 	if !(CONSTANT_TRUE && CONSTANT_TRUE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_proc_false_const_false :: proc(t: ^testing.T) {
 test_proc_false_const_false :: proc(t: ^testing.T) {
 	if false_result() || CONSTANT_FALSE {
 	if false_result() || CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if false_result() && CONSTANT_FALSE {
 	if false_result() && CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if !(false_result() || CONSTANT_FALSE) {
 	if !(false_result() || CONSTANT_FALSE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if !(false_result() && CONSTANT_FALSE) {
 	if !(false_result() && CONSTANT_FALSE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_proc_false_const_true :: proc(t: ^testing.T) {
 test_proc_false_const_true :: proc(t: ^testing.T) {
 	if false_result() || CONSTANT_TRUE {
 	if false_result() || CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if false_result() && CONSTANT_TRUE {
 	if false_result() && CONSTANT_TRUE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if !(false_result() || CONSTANT_TRUE) {
 	if !(false_result() || CONSTANT_TRUE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !(false_result() && CONSTANT_TRUE) {
 	if !(false_result() && CONSTANT_TRUE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_proc_true_const_false :: proc(t: ^testing.T) {
 test_proc_true_const_false :: proc(t: ^testing.T) {
 	if true_result() || CONSTANT_FALSE {
 	if true_result() || CONSTANT_FALSE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if true_result() && CONSTANT_FALSE {
 	if true_result() && CONSTANT_FALSE {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 
 
 	if !(true_result() || CONSTANT_FALSE) {
 	if !(true_result() || CONSTANT_FALSE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !(true_result() && CONSTANT_FALSE) {
 	if !(true_result() && CONSTANT_FALSE) {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 }
 }
 
 
 @test
 @test
 test_proc_true_const_true :: proc(t: ^testing.T) {
 test_proc_true_const_true :: proc(t: ^testing.T) {
 	if true_result() || CONSTANT_TRUE {
 	if true_result() || CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 	if true_result() && CONSTANT_TRUE {
 	if true_result() && CONSTANT_TRUE {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	}
 	}
 
 
 	if !(true_result() || CONSTANT_TRUE) {
 	if !(true_result() || CONSTANT_TRUE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 	if !(true_result() && CONSTANT_TRUE) {
 	if !(true_result() && CONSTANT_TRUE) {
-		tc.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
+		testing.expect(t, false, fmt.tprintf("%s: !false\n", #procedure))
 	} else {
 	} else {
-		tc.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
+		testing.expect(t, true, fmt.tprintf("%s: !true\n", #procedure))
 	}
 	}
 }
 }

+ 62 - 0
tests/issues/test_issue_2087.odin

@@ -0,0 +1,62 @@
+// Tests issue #2087 https://github.com/odin-lang/Odin/issues/2087
+package test_issues
+
+import "core:math"
+import "core:strconv"
+import "core:testing"
+
+@(test)
+test_parse_float :: proc(t: ^testing.T) {
+	{
+		f, ok := strconv.parse_f64("1.2")
+		testing.expect(t, ok && f == 1.2, "expected f64(1.2), fully consumed")
+		f, ok = strconv.parse_f64("1.2a")
+		testing.expect(t, !ok && f == 1.2, "expected f64(1.2), partially consumed")
+		f, ok = strconv.parse_f64("+")
+		testing.expect(t, !ok && f == 0.0, "expected f64(0.0), with ok=false")
+		f, ok = strconv.parse_f64("-")
+		testing.expect(t, !ok && f == 0.0, "expected f64(0.0), with ok=false")
+
+
+		f, ok = strconv.parse_f64("inf")
+		testing.expect(t, ok && math.classify(f) == math.Float_Class.Inf, "expected f64(+inf), fully consumed")
+		f, ok = strconv.parse_f64("+inf")
+		testing.expect(t, ok && math.classify(f) == math.Float_Class.Inf, "expected f64(+inf), fully consumed")
+		f, ok = strconv.parse_f64("-inf")
+		testing.expect(t, ok && math.classify(f) == math.Float_Class.Neg_Inf, "expected f64(-inf), fully consumed")
+		f, ok = strconv.parse_f64("inFinity")
+		testing.expect(t, !ok && math.classify(f) == math.Float_Class.Inf, "expected f64(+inf), partially consumed")
+		f, ok = strconv.parse_f64("+InFinity")
+		testing.expect(t, !ok && math.classify(f) == math.Float_Class.Inf, "expected f64(+inf), partially consumed")
+		f, ok = strconv.parse_f64("-InfiniTy")
+		testing.expect(t, !ok && math.classify(f) == math.Float_Class.Neg_Inf, "expected f64(-inf), partially consumed")
+		f, ok = strconv.parse_f64("nan")
+		testing.expect(t, ok && math.classify(f) == math.Float_Class.NaN, "expected f64(nan), fully consumed")
+		f, ok = strconv.parse_f64("nAN")
+		testing.expect(t, ok && math.classify(f) == math.Float_Class.NaN, "expected f64(nan), fully consumed")
+	}
+	{
+		f, ok := strconv.parse_f32("1.2")
+		testing.expect(t, ok && f == 1.2, "expected f32(1.2), fully consumed")
+
+		f, ok = strconv.parse_f32("1.2a")
+		testing.expect(t, !ok && f == 1.2, "expected f32(1.2), partially consumed")
+
+		f, ok = strconv.parse_f32("inf")
+		testing.expect(t, ok && math.classify(f) == math.Float_Class.Inf, "expected f32(+inf), fully consumed")
+		f, ok = strconv.parse_f32("+inf")
+		testing.expect(t, ok && math.classify(f) == math.Float_Class.Inf, "expected f32(+inf), fully consumed")
+		f, ok = strconv.parse_f32("-inf")
+		testing.expect(t, ok && math.classify(f) == math.Float_Class.Neg_Inf, "expected f32(-inf), fully consumed")
+		f, ok = strconv.parse_f32("inFinity")
+		testing.expect(t, !ok && math.classify(f) == math.Float_Class.Inf, "expected f32(+inf), partially consumed")
+		f, ok = strconv.parse_f32("+InFinity")
+		testing.expect(t, !ok && math.classify(f) == math.Float_Class.Inf, "expected f32(+inf), partially consumed")
+		f, ok = strconv.parse_f32("-InfiniTy")
+		testing.expect(t, !ok && math.classify(f) == math.Float_Class.Neg_Inf, "expected f32(-inf), partially consumed")
+		f, ok = strconv.parse_f32("nan")
+		testing.expect(t, ok && math.classify(f) == math.Float_Class.NaN, "expected f32(nan), fully consumed")
+		f, ok = strconv.parse_f32("nAN")
+		testing.expect(t, ok && math.classify(f) == math.Float_Class.NaN, "expected f32(nan), fully consumed")
+	}
+}

+ 13 - 0
tests/issues/test_issue_2113.odin

@@ -0,0 +1,13 @@
+// Tests issue #2113 https://github.com/odin-lang/Odin/issues/2113
+// Causes a panic on compilation
+package test_issues
+
+T :: struct {
+    a: int,
+}
+
+main :: proc() {
+    array: #soa[1]T
+    a := &array[0]
+    _ = a
+}

+ 2 - 17
tests/issues/test_issue_829.odin

@@ -3,31 +3,16 @@ package test_issues
 
 
 import "core:fmt"
 import "core:fmt"
 import "core:testing"
 import "core:testing"
-import tc "tests:common"
 
 
 /* Original issue #829 example */
 /* Original issue #829 example */
-
 env : map[string]proc(a, b : int) -> int = {
 env : map[string]proc(a, b : int) -> int = {
 	"+" = proc(a, b : int) -> int {
 	"+" = proc(a, b : int) -> int {
 		return a + b
 		return a + b
 	},
 	},
 }
 }
 
 
-test_orig :: proc() {
-	fmt.println(env["+"](1, 2))
-}
-
-main :: proc() {
-	t := testing.T{}
-
-	test_orig()
-
-	test_orig_ret(&t)
-
-	tc.report(&t)
-}
-
+@(test)
 test_orig_ret :: proc(t: ^testing.T) {
 test_orig_ret :: proc(t: ^testing.T) {
 	r := fmt.tprint(env["+"](1, 2))
 	r := fmt.tprint(env["+"](1, 2))
-	tc.expect(t, r == "3", fmt.tprintf("%s: \"%s\" != \"3\"\n", #procedure, r))
+	testing.expect(t, r == "3", fmt.tprintf("%s: \"%s\" != \"3\"\n", #procedure, r))
 }
 }

+ 3 - 3
vendor/darwin/Foundation/NSApplication.odin

@@ -11,7 +11,7 @@ ActivationPolicy :: enum UInteger {
 ApplicationDelegate :: struct {
 ApplicationDelegate :: struct {
 	willFinishLaunching:                  proc "c" (self: ^ApplicationDelegate, notification: ^Notification),
 	willFinishLaunching:                  proc "c" (self: ^ApplicationDelegate, notification: ^Notification),
 	didFinishLaunching:                   proc "c" (self: ^ApplicationDelegate, notification: ^Notification),
 	didFinishLaunching:                   proc "c" (self: ^ApplicationDelegate, notification: ^Notification),
-	shouldTerminateAfterLastWindowClosed: proc "c" (self: ^ApplicationDelegate, sender: ^Application),
+	shouldTerminateAfterLastWindowClosed: proc "c" (self: ^ApplicationDelegate, sender: ^Application) -> BOOL,
 
 
 	user_data: rawptr,
 	user_data: rawptr,
 }
 }
@@ -34,9 +34,9 @@ Application_setDelegate :: proc(self: ^Application, delegate: ^ApplicationDelega
 		del := (^ApplicationDelegate)(self->pointerValue())
 		del := (^ApplicationDelegate)(self->pointerValue())
 		del->didFinishLaunching(notification)
 		del->didFinishLaunching(notification)
 	}
 	}
-	shouldTerminateAfterLastWindowClosed :: proc "c" (self: ^Value, _: SEL, application: ^Application) {
+	shouldTerminateAfterLastWindowClosed :: proc "c" (self: ^Value, _: SEL, application: ^Application) -> BOOL {
 		del := (^ApplicationDelegate)(self->pointerValue())
 		del := (^ApplicationDelegate)(self->pointerValue())
-		del->shouldTerminateAfterLastWindowClosed(application)
+		return del->shouldTerminateAfterLastWindowClosed(application)
 	}
 	}
 
 
 	wrapper := Value.valueWithPointer(delegate)
 	wrapper := Value.valueWithPointer(delegate)

+ 16 - 0
vendor/darwin/Foundation/NSWindow.odin

@@ -156,6 +156,22 @@ Window_makeKeyAndOrderFront :: proc(self: ^Window, key: ^NS.Object) {
 Window_setTitle :: proc(self: ^Window, title: ^NS.String) {
 Window_setTitle :: proc(self: ^Window, title: ^NS.String) {
 	msgSend(nil, self, "setTitle:", title)
 	msgSend(nil, self, "setTitle:", title)
 }
 }
+@(objc_type=Window, objc_name="setTitlebarAppearsTransparent")
+Window_setTitlebarAppearsTransparent :: proc(self: ^Window, ok: NS.BOOL) {
+	msgSend(nil, self, "setTitlebarAppearsTransparent:", ok)
+}
+@(objc_type=Window, objc_name="setMovable")
+Window_setMovable :: proc(self: ^Window, ok: NS.BOOL) {
+	msgSend(nil, self, "setMovable:", ok)
+}
+@(objc_type=Window, objc_name="setMovableByWindowBackground")
+Window_setMovableByWindowBackground :: proc(self: ^Window, ok: NS.BOOL) {
+	msgSend(nil, self, "setMovableByWindowBackground:", ok)
+}
+@(objc_type=Window, objc_name="setStyleMask")
+Window_setStyleMask :: proc(self: ^Window, style_mask: WindowStyleMask) {
+	msgSend(nil, self, "setStyleMask:", style_mask)
+}
 @(objc_type=Window, objc_name="close")
 @(objc_type=Window, objc_name="close")
 Window_close :: proc(self: ^Window) {
 Window_close :: proc(self: ^Window) {
 	msgSend(nil, self, "close")
 	msgSend(nil, self, "close")

+ 5 - 1
vendor/darwin/Foundation/objc.odin

@@ -10,9 +10,13 @@ IMP :: proc "c" (object: id, sel: SEL, #c_vararg args: ..any) -> id
 foreign Foundation {
 foreign Foundation {
 	objc_lookUpClass       :: proc "c" (name: cstring) -> Class ---
 	objc_lookUpClass       :: proc "c" (name: cstring) -> Class ---
 	sel_registerName       :: proc "c" (name: cstring) -> SEL ---
 	sel_registerName       :: proc "c" (name: cstring) -> SEL ---
-	objc_allocateClassPair :: proc "c" (superclass: Class, name: cstring, extraBytes: uint) ---
+	objc_allocateClassPair :: proc "c" (superclass : Class, name : cstring, extraBytes : c.size_t) -> Class ---
+	objc_registerClassPair :: proc "c" (cls : Class) ---
 
 
 	class_addMethod :: proc "c" (cls: Class, name: SEL, imp: IMP, types: cstring) -> BOOL ---
 	class_addMethod :: proc "c" (cls: Class, name: SEL, imp: IMP, types: cstring) -> BOOL ---
+	class_getInstanceMethod :: proc "c" (cls: Class, name: SEL) -> Method ---
+
+	method_setImplementation :: proc "c" (method: Method, imp: IMP) ---
 }
 }
 
 
 
 

+ 190 - 149
vendor/directx/d3d11/d3d11.odin

@@ -30,7 +30,7 @@ foreign d3d11 {
 		DriverType:         DRIVER_TYPE,
 		DriverType:         DRIVER_TYPE,
 		Software:           HMODULE,
 		Software:           HMODULE,
 		Flags:              CREATE_DEVICE_FLAGS,
 		Flags:              CREATE_DEVICE_FLAGS,
-		pFeatureLevels:     ^FEATURE_LEVEL,
+		pFeatureLevels:     [^]FEATURE_LEVEL,
 		FeatureLevels:      u32,
 		FeatureLevels:      u32,
 		SDKVersion:         u32,
 		SDKVersion:         u32,
 		ppDevice:           ^^IDevice,
 		ppDevice:           ^^IDevice,
@@ -41,8 +41,8 @@ foreign d3d11 {
 		pAdapter:           ^dxgi.IAdapter,
 		pAdapter:           ^dxgi.IAdapter,
 		DriverType:         DRIVER_TYPE,
 		DriverType:         DRIVER_TYPE,
 		Software:           HMODULE,
 		Software:           HMODULE,
-		Flags:              u32,
-		pFeatureLevels:     ^FEATURE_LEVEL,
+		Flags:              CREATE_DEVICE_FLAGS,
+		pFeatureLevels:     [^]FEATURE_LEVEL,
 		FeatureLevels:      u32,
 		FeatureLevels:      u32,
 		SDKVersion:         u32,
 		SDKVersion:         u32,
 		pSwapChainDesc:     ^dxgi.SWAP_CHAIN_DESC,
 		pSwapChainDesc:     ^dxgi.SWAP_CHAIN_DESC,
@@ -539,24 +539,36 @@ ANISOTROPIC_FILTERING_BIT :: 0x40
 SDK_VERSION :: 7
 SDK_VERSION :: 7
 RETURN_PARAMETER_INDEX :: -1
 RETURN_PARAMETER_INDEX :: -1
 
 
-COMPONENT_MASK :: enum u32 { // TODO: make bit_set
+COMPONENT_MASK :: distinct bit_set[COMPONENT_MASK_ELEMENT; u32]
+COMPONENT_MASK_ELEMENT :: enum u32 {
 	X = 1,
 	X = 1,
 	Y = 2,
 	Y = 2,
 	Z = 4,
 	Z = 4,
 	W = 8,
 	W = 8,
 }
 }
 
 
-SHADER_REQUIRES :: enum u32 { // TODO: make bit_set
-	DOUBLES                      = 0x00000001,
-	EARLY_DEPTH_STENCIL          = 0x00000002,
-	UAVS_AT_EVERY_STAGE          = 0x00000004,
-	_64_UAVS                     = 0x00000008,
-	MINIMUM_PRECISION            = 0x00000010,
-	_11_1_DOUBLE_EXTENSIONS      = 0x00000020,
-	_11_1_SHADER_EXTENSIONS      = 0x00000040,
-	LEVEL_9_COMPARISON_FILTERING = 0x00000080,
-	TILED_RESOURCES              = 0x00000100,
-}
+SHADER_REQUIRES_FLAGS :: distinct bit_set[SHADER_REQUIRES_FLAG; u64]
+SHADER_REQUIRES_FLAG :: enum u64 {
+	DOUBLES                      = 0,
+	EARLY_DEPTH_STENCIL          = 1,
+	UAVS_AT_EVERY_STAGE          = 2,
+	_64_UAVS                     = 3,
+	MINIMUM_PRECISION            = 4,
+	_11_1_DOUBLE_EXTENSIONS      = 5,
+	_11_1_SHADER_EXTENSIONS      = 6,
+	LEVEL_9_COMPARISON_FILTERING = 7,
+	TILED_RESOURCES              = 8,
+}
+
+SHADER_REQUIRES_DOUBLES                      :: SHADER_REQUIRES_FLAGS{.DOUBLES}
+SHADER_REQUIRES_EARLY_DEPTH_STENCIL          :: SHADER_REQUIRES_FLAGS{.EARLY_DEPTH_STENCIL}
+SHADER_REQUIRES_UAVS_AT_EVERY_STAGE          :: SHADER_REQUIRES_FLAGS{.UAVS_AT_EVERY_STAGE}
+SHADER_REQUIRES_64_UAVS                      :: SHADER_REQUIRES_FLAGS{._64_UAVS}
+SHADER_REQUIRES_MINIMUM_PRECISION            :: SHADER_REQUIRES_FLAGS{.MINIMUM_PRECISION}
+SHADER_REQUIRES_11_1_DOUBLE_EXTENSIONS       :: SHADER_REQUIRES_FLAGS{._11_1_DOUBLE_EXTENSIONS}
+SHADER_REQUIRES_11_1_SHADER_EXTENSIONS       :: SHADER_REQUIRES_FLAGS{._11_1_SHADER_EXTENSIONS}
+SHADER_REQUIRES_LEVEL_9_COMPARISON_FILTERING :: SHADER_REQUIRES_FLAGS{.LEVEL_9_COMPARISON_FILTERING}
+SHADER_REQUIRES_TILED_RESOURCES              :: SHADER_REQUIRES_FLAGS{.TILED_RESOURCES}
 
 
 DRIVER_TYPE :: enum i32 {
 DRIVER_TYPE :: enum i32 {
 	UNKNOWN   = 0,
 	UNKNOWN   = 0,
@@ -708,11 +720,12 @@ SHADER_VARIABLE_CLASS :: enum i32 {
 	INTERFACE_POINTER     = 7,
 	INTERFACE_POINTER     = 7,
 }
 }
 
 
-SHADER_VARIABLE_FLAGS :: enum u32 { // TODO: make bit_set
-	USERPACKED              = 0x1,
-	USED                    = 0x2,
-	INTERFACE_POINTER       = 0x4,
-	INTERFACE_PARAMETER     = 0x8,
+SHADER_VARIABLE_FLAGS :: distinct bit_set[SHADER_VARIABLE_FLAG; u32]
+SHADER_VARIABLE_FLAG :: enum u32 {
+	USERPACKED              = 0,
+	USED                    = 1,
+	INTERFACE_POINTER       = 2,
+	INTERFACE_PARAMETER     = 3,
 }
 }
 
 
 SHADER_VARIABLE_TYPE :: enum i32 {
 SHADER_VARIABLE_TYPE :: enum i32 {
@@ -776,14 +789,21 @@ SHADER_VARIABLE_TYPE :: enum i32 {
 	MIN16UINT                     = 57,
 	MIN16UINT                     = 57,
 }
 }
 
 
-SHADER_INPUT_FLAGS :: enum u32 { // TODO: make bit_set
-	USERPACKED          = 0x1,
-	COMPARISON_SAMPLER  = 0x2,
-	TEXTURE_COMPONENT_0 = 0x4,
-	TEXTURE_COMPONENT_1 = 0x8,
+SHADER_INPUT_FLAGS :: distinct bit_set[SHADER_INPUT_FLAG; u32]
+SHADER_INPUT_FLAG :: enum u32 {
+	USERPACKED          = 0,
+	COMPARISON_SAMPLER  = 1,
+	TEXTURE_COMPONENT_0 = 2,
+	TEXTURE_COMPONENT_1 = 3,
 	TEXTURE_COMPONENTS  = 0xc,
 	TEXTURE_COMPONENTS  = 0xc,
-	UNUSED              = 0x10,
+	UNUSED              = 4,
 }
 }
+SHADER_INPUT_FLAG_USERPACKED          :: SHADER_INPUT_FLAGS{.USERPACKED}
+SHADER_INPUT_FLAG_COMPARISON_SAMPLER  :: SHADER_INPUT_FLAGS{.COMPARISON_SAMPLER}
+SHADER_INPUT_FLAG_TEXTURE_COMPONENT_0 :: SHADER_INPUT_FLAGS{.TEXTURE_COMPONENT_0}
+SHADER_INPUT_FLAG_TEXTURE_COMPONENT_1 :: SHADER_INPUT_FLAGS{.TEXTURE_COMPONENT_1}
+SHADER_INPUT_FLAG_TEXTURE_COMPONENTS  :: SHADER_INPUT_FLAGS{.TEXTURE_COMPONENT_0, .TEXTURE_COMPONENT_1}
+SHADER_INPUT_FLAG_UNUSED              :: SHADER_INPUT_FLAGS{.UNUSED}
 
 
 SHADER_INPUT_TYPE :: enum i32 {
 SHADER_INPUT_TYPE :: enum i32 {
 	CBUFFER                       = 0,
 	CBUFFER                       = 0,
@@ -802,8 +822,9 @@ SHADER_INPUT_TYPE :: enum i32 {
 	UAV_FEEDBACKTEXTURE           = 13,
 	UAV_FEEDBACKTEXTURE           = 13,
 }
 }
 
 
-SHADER_CBUFFER_FLAGS :: enum u32 { // TODO: make bit_set
-	USERPACKED = 0x1,
+SHADER_CBUFFER_FLAGS :: distinct bit_set[SHADER_CBUFFER_FLAG; u32]
+SHADER_CBUFFER_FLAG :: enum u32 {
+	USERPACKED = 0,
 }
 }
 
 
 CBUFFER_TYPE :: enum i32 {
 CBUFFER_TYPE :: enum i32 {
@@ -906,10 +927,10 @@ INTERPOLATION_MODE :: enum i32 {
 	LINEAR_NOPERSPECTIVE_SAMPLE   = 7,
 	LINEAR_NOPERSPECTIVE_SAMPLE   = 7,
 }
 }
 
 
-PARAMETER_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE = 0x0,
-	IN   = 0x1,
-	OUT  = 0x2,
+PARAMETER_FLAGS :: distinct bit_set[PARAMETER_FLAG; u32]
+PARAMETER_FLAG :: enum u32 {
+	IN   = 0,
+	OUT  = 1,
 }
 }
 
 
 CDEFAULT :: struct {
 CDEFAULT :: struct {
@@ -1022,43 +1043,46 @@ USAGE :: enum i32 {
 	STAGING   = 3,
 	STAGING   = 3,
 }
 }
 
 
-BIND_FLAG :: enum u32 { // TODO: make bit_set
-	VERTEX_BUFFER    = 0x1,
-	INDEX_BUFFER     = 0x2,
-	CONSTANT_BUFFER  = 0x4,
-	SHADER_RESOURCE  = 0x8,
-	STREAM_OUTPUT    = 0x10,
-	RENDER_TARGET    = 0x20,
-	DEPTH_STENCIL    = 0x40,
-	UNORDERED_ACCESS = 0x80,
-	DECODER          = 0x200,
-	VIDEO_ENCODER    = 0x400,
-}
-
-CPU_ACCESS_FLAG :: enum u32 { // TODO: make bit_set
-	WRITE = 0x10000,
-	READ  = 0x20000,
-
-}
-
-RESOURCE_MISC_FLAG :: enum u32 { // TODO: make bit_set
-	GENERATE_MIPS                   = 0x1,
-	SHARED                          = 0x2,
-	TEXTURECUBE                     = 0x4,
-	DRAWINDIRECT_ARGS               = 0x10,
-	BUFFER_ALLOW_RAW_VIEWS          = 0x20,
-	BUFFER_STRUCTURED               = 0x40,
-	RESOURCE_CLAMP                  = 0x80,
-	SHARED_KEYEDMUTEX               = 0x100,
-	GDI_COMPATIBLE                  = 0x200,
-	SHARED_NTHANDLE                 = 0x800,
-	RESTRICTED_CONTENT              = 0x1000,
-	RESTRICT_SHARED_RESOURCE        = 0x2000,
-	RESTRICT_SHARED_RESOURCE_DRIVER = 0x4000,
-	GUARDED                         = 0x8000,
-	TILE_POOL                       = 0x20000,
-	TILED                           = 0x40000,
-	HW_PROTECTED                    = 0x80000,
+BIND_FLAGS :: distinct bit_set[BIND_FLAG; u32]
+BIND_FLAG :: enum u32 {
+	VERTEX_BUFFER    = 0,
+	INDEX_BUFFER     = 1,
+	CONSTANT_BUFFER  = 2,
+	SHADER_RESOURCE  = 3,
+	STREAM_OUTPUT    = 4,
+	RENDER_TARGET    = 5,
+	DEPTH_STENCIL    = 6,
+	UNORDERED_ACCESS = 7,
+	DECODER          = 9,
+	VIDEO_ENCODER    = 10,
+}
+
+CPU_ACCESS_FLAGS :: distinct bit_set[CPU_ACCESS_FLAG; u32]
+CPU_ACCESS_FLAG :: enum u32 {
+	WRITE = 16,
+	READ  = 17,
+
+}
+
+RESOURCE_MISC_FLAGS :: distinct bit_set[RESOURCE_MISC_FLAG; u32]
+RESOURCE_MISC_FLAG :: enum u32 {
+	GENERATE_MIPS                   = 0,
+	SHARED                          = 1,
+	TEXTURECUBE                     = 2,
+	DRAWINDIRECT_ARGS               = 4,
+	BUFFER_ALLOW_RAW_VIEWS          = 5,
+	BUFFER_STRUCTURED               = 6,
+	RESOURCE_CLAMP                  = 7,
+	SHARED_KEYEDMUTEX               = 8,
+	GDI_COMPATIBLE                  = 9,
+	SHARED_NTHANDLE                 = 11,
+	RESTRICTED_CONTENT              = 12,
+	RESTRICT_SHARED_RESOURCE        = 13,
+	RESTRICT_SHARED_RESOURCE_DRIVER = 14,
+	GUARDED                         = 15,
+	TILE_POOL                       = 17,
+	TILED                           = 18,
+	HW_PROTECTED                    = 19,
 }
 }
 
 
 MAP :: enum i32 {
 MAP :: enum i32 {
@@ -1069,17 +1093,20 @@ MAP :: enum i32 {
 	WRITE_NO_OVERWRITE = 5,
 	WRITE_NO_OVERWRITE = 5,
 }
 }
 
 
-MAP_FLAG :: enum u32 { // TODO: make bit_set
-	DO_NOT_WAIT = 0x100000,
+MAP_FLAGS :: distinct bit_set[MAP_FLAG; u32]
+MAP_FLAG :: enum u32 {
+	DO_NOT_WAIT = 20,
 }
 }
 
 
-RAISE_FLAG :: enum u32 { // TODO: make bit_set
-	DRIVER_INTERNAL_ERROR = 0x1,
+RAISE_FLAGS :: distinct bit_set[RAISE_FLAG; u32]
+RAISE_FLAG :: enum u32 {
+	DRIVER_INTERNAL_ERROR = 0,
 }
 }
 
 
-CLEAR_FLAG :: enum u32 { // TODO: make bit_set
-	DEPTH   = 0x1,
-	STENCIL = 0x2,
+CLEAR_FLAGS :: distinct bit_set[CLEAR_FLAG; u32]
+CLEAR_FLAG :: enum u32 {
+	DEPTH   = 0,
+	STENCIL = 1,
 }
 }
 
 
 
 
@@ -1206,12 +1233,19 @@ BLEND_OP :: enum i32 {
 	MAX          = 5,
 	MAX          = 5,
 }
 }
 
 
-COLOR_WRITE_ENABLE :: enum i32 { // TODO: make bit_set
-	RED   = 1,
-	GREEN = 2,
-	BLUE  = 4,
-	ALPHA = 8,
-	ALL   = 15,
+COLOR_WRITE_ENABLE_MASK   :: distinct bit_set[COLOR_WRITE_ENABLE; u32]
+
+COLOR_WRITE_ENABLE_RED   :: COLOR_WRITE_ENABLE_MASK{.RED}
+COLOR_WRITE_ENABLE_GREEN :: COLOR_WRITE_ENABLE_MASK{.GREEN}
+COLOR_WRITE_ENABLE_BLUE  :: COLOR_WRITE_ENABLE_MASK{.BLUE}
+COLOR_WRITE_ENABLE_ALPHA :: COLOR_WRITE_ENABLE_MASK{.ALPHA}
+COLOR_WRITE_ENABLE_ALL   :: COLOR_WRITE_ENABLE_MASK{.RED, .GREEN, .BLUE, .ALPHA}
+
+COLOR_WRITE_ENABLE :: enum i32 {
+	RED   = 0,
+	GREEN = 1,
+	BLUE  = 2,
+	ALPHA = 3,
 }
 }
 
 
 RENDER_TARGET_BLEND_DESC :: struct {
 RENDER_TARGET_BLEND_DESC :: struct {
@@ -1308,9 +1342,9 @@ IResource_VTable :: struct {
 BUFFER_DESC :: struct {
 BUFFER_DESC :: struct {
 	ByteWidth:           u32,
 	ByteWidth:           u32,
 	Usage:               USAGE,
 	Usage:               USAGE,
-	BindFlags:           BIND_FLAG,
-	CPUAccessFlags:      CPU_ACCESS_FLAG,
-	MiscFlags:           RESOURCE_MISC_FLAG,
+	BindFlags:           BIND_FLAGS,
+	CPUAccessFlags:      CPU_ACCESS_FLAGS,
+	MiscFlags:           RESOURCE_MISC_FLAGS,
 	StructureByteStride: u32,
 	StructureByteStride: u32,
 }
 }
 
 
@@ -1337,9 +1371,9 @@ TEXTURE1D_DESC :: struct {
 	ArraySize:      u32,
 	ArraySize:      u32,
 	Format:         dxgi.FORMAT,
 	Format:         dxgi.FORMAT,
 	Usage:          USAGE,
 	Usage:          USAGE,
-	BindFlags:      BIND_FLAG,
-	CPUAccessFlags: CPU_ACCESS_FLAG,
-	MiscFlags:      RESOURCE_MISC_FLAG,
+	BindFlags:      BIND_FLAGS,
+	CPUAccessFlags: CPU_ACCESS_FLAGS,
+	MiscFlags:      RESOURCE_MISC_FLAGS,
 }
 }
 
 
 CTEXTURE1D_DESC :: struct {
 CTEXTURE1D_DESC :: struct {
@@ -1367,9 +1401,9 @@ TEXTURE2D_DESC :: struct {
 	Format:         dxgi.FORMAT,
 	Format:         dxgi.FORMAT,
 	SampleDesc:     dxgi.SAMPLE_DESC,
 	SampleDesc:     dxgi.SAMPLE_DESC,
 	Usage:          USAGE,
 	Usage:          USAGE,
-	BindFlags:      BIND_FLAG,
-	CPUAccessFlags: CPU_ACCESS_FLAG,
-	MiscFlags:      RESOURCE_MISC_FLAG,
+	BindFlags:      BIND_FLAGS,
+	CPUAccessFlags: CPU_ACCESS_FLAGS,
+	MiscFlags:      RESOURCE_MISC_FLAGS,
 }
 }
 
 
 CTEXTURE2D_DESC :: struct {
 CTEXTURE2D_DESC :: struct {
@@ -1396,9 +1430,9 @@ TEXTURE3D_DESC :: struct {
 	MipLevels:      u32,
 	MipLevels:      u32,
 	Format:         dxgi.FORMAT,
 	Format:         dxgi.FORMAT,
 	Usage:          USAGE,
 	Usage:          USAGE,
-	BindFlags:      BIND_FLAG,
-	CPUAccessFlags: CPU_ACCESS_FLAG,
-	MiscFlags:      RESOURCE_MISC_FLAG,
+	BindFlags:      BIND_FLAGS,
+	CPUAccessFlags: CPU_ACCESS_FLAGS,
+	MiscFlags:      RESOURCE_MISC_FLAGS,
 }
 }
 
 
 CTEXTURE3D_DESC :: struct {
 CTEXTURE3D_DESC :: struct {
@@ -1451,14 +1485,15 @@ BUFFER_SRV :: struct {
 	},
 	},
 }
 }
 
 
-BUFFEREX_SRV_FLAG :: enum u32 { // TODO: make bit_set
-	RAW = 0x1,
+BUFFEREX_SRV_FLAGS :: distinct bit_set[BUFFEREX_SRV_FLAG; u32]
+BUFFEREX_SRV_FLAG :: enum u32 {
+	RAW = 0,
 }
 }
 
 
 BUFFEREX_SRV :: struct {
 BUFFEREX_SRV :: struct {
 	FirstElement: u32,
 	FirstElement: u32,
 	NumElements:  u32,
 	NumElements:  u32,
-	Flags:        u32,
+	Flags:        BUFFEREX_SRV_FLAGS,
 }
 }
 
 
 TEX1D_SRV :: struct {
 TEX1D_SRV :: struct {
@@ -1657,15 +1692,16 @@ TEX2DMS_ARRAY_DSV :: struct {
 	ArraySize:       u32,
 	ArraySize:       u32,
 }
 }
 
 
-DSV_FLAG :: enum u32 { // TODO: make bit_set
-	DEPTH   = 0x1,
-	STENCIL = 0x2,
+DSV_FLAGS :: distinct bit_set[DSV_FLAG; u32]
+DSV_FLAG :: enum u32 {
+	DEPTH   = 0,
+	STENCIL = 1,
 }
 }
 
 
 DEPTH_STENCIL_VIEW_DESC :: struct {
 DEPTH_STENCIL_VIEW_DESC :: struct {
 	Format:        dxgi.FORMAT,
 	Format:        dxgi.FORMAT,
 	ViewDimension: DSV_DIMENSION,
 	ViewDimension: DSV_DIMENSION,
-	Flags:         u32,
+	Flags:         DSV_FLAGS,
 	using _: struct #raw_union {
 	using _: struct #raw_union {
 		Texture1D:        TEX1D_DSV,
 		Texture1D:        TEX1D_DSV,
 		Texture1DArray:   TEX1D_ARRAY_DSV,
 		Texture1DArray:   TEX1D_ARRAY_DSV,
@@ -1693,16 +1729,17 @@ IDepthStencilView_VTable :: struct {
 }
 }
 
 
 
 
-BUFFER_UAV_FLAG :: enum u32 { // TODO: make bit_set
-	RAW     = 0x1,
-	APPEND  = 0x2,
-	COUNTER = 0x4,
+BUFFER_UAV_FLAGS :: distinct bit_set[BUFFER_UAV_FLAG; u32]
+BUFFER_UAV_FLAG :: enum u32 {
+	RAW     = 0,
+	APPEND  = 1,
+	COUNTER = 2,
 }
 }
 
 
 BUFFER_UAV :: struct {
 BUFFER_UAV :: struct {
 	FirstElement: u32,
 	FirstElement: u32,
 	NumElements:  u32,
 	NumElements:  u32,
-	Flags:        u32,
+	Flags:        BUFFER_UAV_FLAGS,
 }
 }
 
 
 TEX1D_UAV :: struct {
 TEX1D_UAV :: struct {
@@ -1961,8 +1998,9 @@ IAsynchronous_VTable :: struct {
 }
 }
 
 
 
 
-ASYNC_GETDATA_FLAG :: enum u32 { // TODO: make bit_set
-	DONOTFLUSH = 0x1,
+ASYNC_GETDATA_FLAGS :: distinct bit_set[ASYNC_GETDATA_FLAG; u32]
+ASYNC_GETDATA_FLAG :: enum u32 {
+	DONOTFLUSH = 0,
 }
 }
 
 
 QUERY :: enum i32 {
 QUERY :: enum i32 {
@@ -1984,13 +2022,14 @@ QUERY :: enum i32 {
 	SO_OVERFLOW_PREDICATE_STREAM3 = 15,
 	SO_OVERFLOW_PREDICATE_STREAM3 = 15,
 }
 }
 
 
-QUERY_MISC_FLAG :: enum u32 { // TODO: make bit_set
-	QUERY_MISC_PREDICATEHINT = 0x1,
+QUERY_MISC_FLAGS :: distinct bit_set[QUERY_MISC_FLAG; u32]
+QUERY_MISC_FLAG :: enum u32 {
+	PREDICATEHINT = 0,
 }
 }
 
 
 QUERY_DESC :: struct {
 QUERY_DESC :: struct {
 	Query:     QUERY,
 	Query:     QUERY,
-	MiscFlags: RESOURCE_MISC_FLAG,
+	MiscFlags: QUERY_MISC_FLAGS,
 }
 }
 
 
 CQUERY_DESC :: struct {
 CQUERY_DESC :: struct {
@@ -2054,7 +2093,7 @@ COUNTER_TYPE :: enum i32 {
 
 
 COUNTER_DESC :: struct {
 COUNTER_DESC :: struct {
 	Counter:   COUNTER,
 	Counter:   COUNTER,
-	MiscFlags: RESOURCE_MISC_FLAG,
+	MiscFlags: RESOURCE_MISC_FLAGS,
 }
 }
 
 
 CCOUNTER_DESC :: struct {
 CCOUNTER_DESC :: struct {
@@ -2150,21 +2189,21 @@ FEATURE :: enum i32 {
 	FORMAT_SUPPORT                 = 2,
 	FORMAT_SUPPORT                 = 2,
 	FORMAT_SUPPORT2                = 3,
 	FORMAT_SUPPORT2                = 3,
 	D3D10_X_HARDWARE_OPTIONS       = 4,
 	D3D10_X_HARDWARE_OPTIONS       = 4,
-	OPTIONS                  = 5,
+	OPTIONS                        = 5,
 	ARCHITECTURE_INFO              = 6,
 	ARCHITECTURE_INFO              = 6,
 	D3D9_OPTIONS                   = 7,
 	D3D9_OPTIONS                   = 7,
 	SHADER_MIN_PRECISION_SUPPORT   = 8,
 	SHADER_MIN_PRECISION_SUPPORT   = 8,
 	D3D9_SHADOW_SUPPORT            = 9,
 	D3D9_SHADOW_SUPPORT            = 9,
-	OPTIONS1                 = 10,
+	OPTIONS1                       = 10,
 	D3D9_SIMPLE_INSTANCING_SUPPORT = 11,
 	D3D9_SIMPLE_INSTANCING_SUPPORT = 11,
 	MARKER_SUPPORT                 = 12,
 	MARKER_SUPPORT                 = 12,
 	D3D9_OPTIONS1                  = 13,
 	D3D9_OPTIONS1                  = 13,
-	OPTIONS2                 = 14,
-	OPTIONS3                 = 15,
+	OPTIONS2                       = 14,
+	OPTIONS3                       = 15,
 	GPU_VIRTUAL_ADDRESS_SUPPORT    = 16,
 	GPU_VIRTUAL_ADDRESS_SUPPORT    = 16,
-	OPTIONS4                 = 17,
+	OPTIONS4                       = 17,
 	SHADER_CACHE                   = 18,
 	SHADER_CACHE                   = 18,
-	OPTIONS5                 = 19,
+	OPTIONS5                       = 19,
 }
 }
 
 
 FEATURE_DATA_THREADING :: struct {
 FEATURE_DATA_THREADING :: struct {
@@ -2285,14 +2324,14 @@ FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT :: struct {
 	MaxGPUVirtualAddressBitsPerProcess:  u32,
 	MaxGPUVirtualAddressBitsPerProcess:  u32,
 }
 }
 
 
-SHADER_CACHE_SUPPORT_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                   = 0x0,
-	AUTOMATIC_INPROC_CACHE = 0x1,
-	AUTOMATIC_DISK_CACHE   = 0x2,
+SHADER_CACHE_SUPPORT_FLAGS :: distinct bit_set[SHADER_CACHE_SUPPORT_FLAG; u32]
+SHADER_CACHE_SUPPORT_FLAG :: enum u32 {
+	AUTOMATIC_INPROC_CACHE = 0,
+	AUTOMATIC_DISK_CACHE   = 1,
 }
 }
 
 
 FEATURE_DATA_SHADER_CACHE :: struct {
 FEATURE_DATA_SHADER_CACHE :: struct {
-	SupportFlags: u32,
+	SupportFlags: SHADER_CACHE_SUPPORT_FLAGS,
 }
 }
 
 
 SHARED_RESOURCE_TIER :: enum i32 {
 SHARED_RESOURCE_TIER :: enum i32 {
@@ -2322,7 +2361,7 @@ IDeviceContext_VTable :: struct {
 	VSSetShader:                               proc "stdcall" (this: ^IDeviceContext, pVertexShader: ^IVertexShader, ppClassInstances: ^^IClassInstance, NumClassInstances: u32),
 	VSSetShader:                               proc "stdcall" (this: ^IDeviceContext, pVertexShader: ^IVertexShader, ppClassInstances: ^^IClassInstance, NumClassInstances: u32),
 	DrawIndexed:                               proc "stdcall" (this: ^IDeviceContext, IndexCount: u32, StartIndexLocation: u32, BaseVertexLocation: i32),
 	DrawIndexed:                               proc "stdcall" (this: ^IDeviceContext, IndexCount: u32, StartIndexLocation: u32, BaseVertexLocation: i32),
 	Draw:                                      proc "stdcall" (this: ^IDeviceContext, VertexCount: u32, StartVertexLocation: u32),
 	Draw:                                      proc "stdcall" (this: ^IDeviceContext, VertexCount: u32, StartVertexLocation: u32),
-	Map:                                       proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, Subresource: u32, MapType: MAP, MapFlags: u32, pMappedResource: ^MAPPED_SUBRESOURCE) -> HRESULT,
+	Map:                                       proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, Subresource: u32, MapType: MAP, MapFlags: MAP_FLAGS, pMappedResource: ^MAPPED_SUBRESOURCE) -> HRESULT,
 	Unmap:                                     proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, Subresource: u32),
 	Unmap:                                     proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, Subresource: u32),
 	PSSetConstantBuffers:                      proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer),
 	PSSetConstantBuffers:                      proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumBuffers: u32, ppConstantBuffers: ^^IBuffer),
 	IASetInputLayout:                          proc "stdcall" (this: ^IDeviceContext, pInputLayout: ^IInputLayout),
 	IASetInputLayout:                          proc "stdcall" (this: ^IDeviceContext, pInputLayout: ^IInputLayout),
@@ -2343,7 +2382,7 @@ IDeviceContext_VTable :: struct {
 	GSSetSamplers:                             proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState),
 	GSSetSamplers:                             proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState),
 	OMSetRenderTargets:                        proc "stdcall" (this: ^IDeviceContext, NumViews: u32, ppRenderTargetViews: ^^IRenderTargetView, pDepthStencilView: ^IDepthStencilView),
 	OMSetRenderTargets:                        proc "stdcall" (this: ^IDeviceContext, NumViews: u32, ppRenderTargetViews: ^^IRenderTargetView, pDepthStencilView: ^IDepthStencilView),
 	OMSetRenderTargetsAndUnorderedAccessViews: proc "stdcall" (this: ^IDeviceContext, NumRTVs: u32, ppRenderTargetViews: ^^IRenderTargetView, pDepthStencilView: ^IDepthStencilView, UAVStartSlot: u32, NumUAVs: u32, ppUnorderedAccessViews: ^^IUnorderedAccessView, pUAVInitialCounts: ^u32),
 	OMSetRenderTargetsAndUnorderedAccessViews: proc "stdcall" (this: ^IDeviceContext, NumRTVs: u32, ppRenderTargetViews: ^^IRenderTargetView, pDepthStencilView: ^IDepthStencilView, UAVStartSlot: u32, NumUAVs: u32, ppUnorderedAccessViews: ^^IUnorderedAccessView, pUAVInitialCounts: ^u32),
-	OMSetBlendState:                           proc "stdcall" (this: ^IDeviceContext, pBlendState: ^IBlendState, BlendFactor: ^[4]f32, SampleMask: u32),
+	OMSetBlendState:                           proc "stdcall" (this: ^IDeviceContext, pBlendState: ^IBlendState, BlendFactor: ^[4]f32, SampleMask: COLOR_WRITE_ENABLE_MASK),
 	OMSetDepthStencilState:                    proc "stdcall" (this: ^IDeviceContext, pDepthStencilState: ^IDepthStencilState, StencilRef: u32),
 	OMSetDepthStencilState:                    proc "stdcall" (this: ^IDeviceContext, pDepthStencilState: ^IDepthStencilState, StencilRef: u32),
 	SOSetTargets:                              proc "stdcall" (this: ^IDeviceContext, NumBuffers: u32, ppSOTargets: ^^IBuffer, pOffsets: ^u32),
 	SOSetTargets:                              proc "stdcall" (this: ^IDeviceContext, NumBuffers: u32, ppSOTargets: ^^IBuffer, pOffsets: ^u32),
 	DrawAuto:                                  proc "stdcall" (this: ^IDeviceContext),
 	DrawAuto:                                  proc "stdcall" (this: ^IDeviceContext),
@@ -2361,7 +2400,7 @@ IDeviceContext_VTable :: struct {
 	ClearRenderTargetView:                     proc "stdcall" (this: ^IDeviceContext, pRenderTargetView: ^IRenderTargetView, ColorRGBA: ^[4]f32),
 	ClearRenderTargetView:                     proc "stdcall" (this: ^IDeviceContext, pRenderTargetView: ^IRenderTargetView, ColorRGBA: ^[4]f32),
 	ClearUnorderedAccessViewUint:              proc "stdcall" (this: ^IDeviceContext, pUnorderedAccessView: ^IUnorderedAccessView, Values: ^[4]u32),
 	ClearUnorderedAccessViewUint:              proc "stdcall" (this: ^IDeviceContext, pUnorderedAccessView: ^IUnorderedAccessView, Values: ^[4]u32),
 	ClearUnorderedAccessViewFloat:             proc "stdcall" (this: ^IDeviceContext, pUnorderedAccessView: ^IUnorderedAccessView, Values: ^[4]f32),
 	ClearUnorderedAccessViewFloat:             proc "stdcall" (this: ^IDeviceContext, pUnorderedAccessView: ^IUnorderedAccessView, Values: ^[4]f32),
-	ClearDepthStencilView:                     proc "stdcall" (this: ^IDeviceContext, pDepthStencilView: ^IDepthStencilView, ClearFlags: CLEAR_FLAG, Depth: f32, Stencil: u8),
+	ClearDepthStencilView:                     proc "stdcall" (this: ^IDeviceContext, pDepthStencilView: ^IDepthStencilView, ClearFlags: CLEAR_FLAGS, Depth: f32, Stencil: u8),
 	GenerateMips:                              proc "stdcall" (this: ^IDeviceContext, pShaderResourceView: ^IShaderResourceView),
 	GenerateMips:                              proc "stdcall" (this: ^IDeviceContext, pShaderResourceView: ^IShaderResourceView),
 	SetResourceMinLOD:                         proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, MinLOD: f32),
 	SetResourceMinLOD:                         proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource, MinLOD: f32),
 	GetResourceMinLOD:                         proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource) -> f32,
 	GetResourceMinLOD:                         proc "stdcall" (this: ^IDeviceContext, pResource: ^IResource) -> f32,
@@ -2399,7 +2438,7 @@ IDeviceContext_VTable :: struct {
 	GSGetSamplers:                             proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState),
 	GSGetSamplers:                             proc "stdcall" (this: ^IDeviceContext, StartSlot: u32, NumSamplers: u32, ppSamplers: ^^ISamplerState),
 	OMGetRenderTargets:                        proc "stdcall" (this: ^IDeviceContext, NumViews: u32, ppRenderTargetViews: ^^IRenderTargetView, ppDepthStencilView: ^^IDepthStencilView),
 	OMGetRenderTargets:                        proc "stdcall" (this: ^IDeviceContext, NumViews: u32, ppRenderTargetViews: ^^IRenderTargetView, ppDepthStencilView: ^^IDepthStencilView),
 	OMGetRenderTargetsAndUnorderedAccessViews: proc "stdcall" (this: ^IDeviceContext, NumRTVs: u32, ppRenderTargetViews: ^^IRenderTargetView, ppDepthStencilView: ^^IDepthStencilView, UAVStartSlot: u32, NumUAVs: u32, ppUnorderedAccessViews: ^^IUnorderedAccessView),
 	OMGetRenderTargetsAndUnorderedAccessViews: proc "stdcall" (this: ^IDeviceContext, NumRTVs: u32, ppRenderTargetViews: ^^IRenderTargetView, ppDepthStencilView: ^^IDepthStencilView, UAVStartSlot: u32, NumUAVs: u32, ppUnorderedAccessViews: ^^IUnorderedAccessView),
-	OMGetBlendState:                           proc "stdcall" (this: ^IDeviceContext, ppBlendState: ^^IBlendState, BlendFactor: ^[4]f32, pSampleMask: ^u32),
+	OMGetBlendState:                           proc "stdcall" (this: ^IDeviceContext, ppBlendState: ^^IBlendState, BlendFactor: ^[4]f32, pSampleMask: ^COLOR_WRITE_ENABLE_MASK),
 	OMGetDepthStencilState:                    proc "stdcall" (this: ^IDeviceContext, ppDepthStencilState: ^^IDepthStencilState, pStencilRef: ^u32),
 	OMGetDepthStencilState:                    proc "stdcall" (this: ^IDeviceContext, ppDepthStencilState: ^^IDepthStencilState, pStencilRef: ^u32),
 	SOGetTargets:                              proc "stdcall" (this: ^IDeviceContext, NumBuffers: u32, ppSOTargets: ^^IBuffer),
 	SOGetTargets:                              proc "stdcall" (this: ^IDeviceContext, NumBuffers: u32, ppSOTargets: ^^IBuffer),
 	RSGetState:                                proc "stdcall" (this: ^IDeviceContext, ppRasterizerState: ^^IRasterizerState),
 	RSGetState:                                proc "stdcall" (this: ^IDeviceContext, ppRasterizerState: ^^IRasterizerState),
@@ -3315,13 +3354,13 @@ IDevice_VTable :: struct {
 	GetCreationFlags:                     proc "stdcall" (this: ^IDevice) -> u32,
 	GetCreationFlags:                     proc "stdcall" (this: ^IDevice) -> u32,
 	GetDeviceRemovedReason:               proc "stdcall" (this: ^IDevice) -> HRESULT,
 	GetDeviceRemovedReason:               proc "stdcall" (this: ^IDevice) -> HRESULT,
 	GetImmediateContext:                  proc "stdcall" (this: ^IDevice, ppImmediateContext: ^^IDeviceContext),
 	GetImmediateContext:                  proc "stdcall" (this: ^IDevice, ppImmediateContext: ^^IDeviceContext),
-	SetExceptionMode:                     proc "stdcall" (this: ^IDevice, RaiseFlags: u32) -> HRESULT,
+	SetExceptionMode:                     proc "stdcall" (this: ^IDevice, RaiseFlags: RAISE_FLAGS) -> HRESULT,
 	GetExceptionMode:                     proc "stdcall" (this: ^IDevice) -> u32,
 	GetExceptionMode:                     proc "stdcall" (this: ^IDevice) -> u32,
 }
 }
 
 
 
 
 CREATE_DEVICE_FLAGS :: distinct bit_set[CREATE_DEVICE_FLAG; u32]
 CREATE_DEVICE_FLAGS :: distinct bit_set[CREATE_DEVICE_FLAG; u32]
-CREATE_DEVICE_FLAG :: enum u32 { // TODO: make bit_set
+CREATE_DEVICE_FLAG :: enum u32 {
 	SINGLETHREADED                                = 0,
 	SINGLETHREADED                                = 0,
 	DEBUG                                         = 1,
 	DEBUG                                         = 1,
 	SWITCH_TO_REF                                 = 2,
 	SWITCH_TO_REF                                 = 2,
@@ -3367,14 +3406,14 @@ SHADER_BUFFER_DESC :: struct {
 	Type:      CBUFFER_TYPE,
 	Type:      CBUFFER_TYPE,
 	Variables: u32,
 	Variables: u32,
 	Size:      u32,
 	Size:      u32,
-	uFlags:    u32,
+	uFlags:    SHADER_CBUFFER_FLAGS,
 }
 }
 
 
 SHADER_VARIABLE_DESC :: struct {
 SHADER_VARIABLE_DESC :: struct {
 	Name:         cstring,
 	Name:         cstring,
 	StartOffset:  u32,
 	StartOffset:  u32,
 	Size:         u32,
 	Size:         u32,
-	uFlags:       u32,
+	uFlags:       SHADER_VARIABLE_FLAGS,
 	DefaultValue: rawptr,
 	DefaultValue: rawptr,
 	StartTexture: u32,
 	StartTexture: u32,
 	TextureSize:  u32,
 	TextureSize:  u32,
@@ -3443,7 +3482,7 @@ SHADER_INPUT_BIND_DESC :: struct {
 	BindPoint:  u32,
 	BindPoint:  u32,
 	BindCount:  u32,
 	BindCount:  u32,
 
 
-	uFlags:     u32,
+	uFlags:     SHADER_INPUT_FLAGS,
 	ReturnType: RESOURCE_RETURN_TYPE,
 	ReturnType: RESOURCE_RETURN_TYPE,
 	Dimension:  SRV_DIMENSION,
 	Dimension:  SRV_DIMENSION,
 	NumSamples: u32,
 	NumSamples: u32,
@@ -3485,7 +3524,7 @@ FUNCTION_DESC :: struct {
 	ConversionInstructionCount:  u32,
 	ConversionInstructionCount:  u32,
 	BitwiseInstructionCount:     u32,
 	BitwiseInstructionCount:     u32,
 	MinFeatureLevel:             FEATURE_LEVEL,
 	MinFeatureLevel:             FEATURE_LEVEL,
-	RequiredFeatureFlags:        u64,
+	RequiredFeatureFlags:        SHADER_REQUIRES_FLAGS,
 
 
 	Name:                        cstring,
 	Name:                        cstring,
 	FunctionParameterCount:      i32,
 	FunctionParameterCount:      i32,
@@ -3571,7 +3610,7 @@ IShaderReflection_VTable :: struct {
 	GetNumInterfaceSlots:          proc "stdcall" (this: ^IShaderReflection) -> u32,
 	GetNumInterfaceSlots:          proc "stdcall" (this: ^IShaderReflection) -> u32,
 	GetMinFeatureLevel:            proc "stdcall" (this: ^IShaderReflection, pLevel: ^FEATURE_LEVEL) -> HRESULT,
 	GetMinFeatureLevel:            proc "stdcall" (this: ^IShaderReflection, pLevel: ^FEATURE_LEVEL) -> HRESULT,
 	GetThreadGroupSize:            proc "stdcall" (this: ^IShaderReflection, pSizeX: ^u32, pSizeY: ^u32, pSizeZ: ^u32) -> u32,
 	GetThreadGroupSize:            proc "stdcall" (this: ^IShaderReflection, pSizeX: ^u32, pSizeY: ^u32, pSizeZ: ^u32) -> u32,
-	GetRequiresFlags:              proc "stdcall" (this: ^IShaderReflection) -> u64,
+	GetRequiresFlags:              proc "stdcall" (this: ^IShaderReflection) -> SHADER_REQUIRES_FLAGS,
 }
 }
 
 
 
 
@@ -3634,22 +3673,24 @@ IDebug :: struct #raw_union {
 	using id3d11debug_vtable: ^IDebug_VTable,
 	using id3d11debug_vtable: ^IDebug_VTable,
 }
 }
 
 
-RLDO_FLAGS :: enum u32 { // TODO: make bit_set
-	SUMMARY = 0x1,
-	DETAIL = 0x2,
-	IGNORE_INTERNAL = 0x4,
+RLDO_FLAGS :: distinct bit_set[RLDO_FLAG; u32]
+RLDO_FLAG :: enum u32 {
+	SUMMARY = 0,
+	DETAIL = 1,
+	IGNORE_INTERNAL = 2,
 }
 }
 
 
-DEBUG_FEATURE :: enum u32 { // TODO: make bit_set
-	FLUSH_PER_RENDER_OP = 0x1,
-	FINISH_PER_RENDER_OP = 0x2,
-	FEATURE_PRESENT_PER_RENDER_OP = 0x4,
+DEBUG_FEATURES :: distinct bit_set[DEBUG_FEATURE; u32]
+DEBUG_FEATURE :: enum u32 {
+	FLUSH_PER_RENDER_OP = 0,
+	FINISH_PER_RENDER_OP = 1,
+	FEATURE_PRESENT_PER_RENDER_OP = 2,
 }
 }
 
 
 IDebug_VTable :: struct {
 IDebug_VTable :: struct {
 	using iunkown_vtable: IUnknown_VTable,
 	using iunkown_vtable: IUnknown_VTable,
-	SetFeatureMask:             proc "stdcall" (this: ^IDebug, mask: DEBUG_FEATURE) -> HRESULT,
-	GetFeatureMask:             proc "stdcall" (this: ^IDebug) -> DEBUG_FEATURE,
+	SetFeatureMask:             proc "stdcall" (this: ^IDebug, mask: DEBUG_FEATURES) -> HRESULT,
+	GetFeatureMask:             proc "stdcall" (this: ^IDebug) -> DEBUG_FEATURES,
 	SetPresentPerRenderOpDelay: proc "stdcall" (this: ^IDebug, Milliseconds: u32) -> HRESULT,
 	SetPresentPerRenderOpDelay: proc "stdcall" (this: ^IDebug, Milliseconds: u32) -> HRESULT,
 	GetPresentPerRenderOpDelay: proc "stdcall" (this: ^IDebug) -> u32,
 	GetPresentPerRenderOpDelay: proc "stdcall" (this: ^IDebug) -> u32,
 	SetSwapChain:               proc "stdcall" (this: ^IDebug, pSwapChain: ^dxgi.ISwapChain) -> HRESULT,
 	SetSwapChain:               proc "stdcall" (this: ^IDebug, pSwapChain: ^dxgi.ISwapChain) -> HRESULT,
@@ -3667,7 +3708,7 @@ IInfoQueue :: struct #raw_union {
 	using id3d11infoqueue_vtable: ^IInfoQueue_VTable,
 	using id3d11infoqueue_vtable: ^IInfoQueue_VTable,
 }
 }
 
 
-MESSAGE_SEVERITY :: enum u32 { // TODO: make bit_set
+MESSAGE_SEVERITY :: enum u32 {
 	CORRUPTION = 0,
 	CORRUPTION = 0,
 	ERROR,
 	ERROR,
 	WARNING,
 	WARNING,
@@ -3675,7 +3716,7 @@ MESSAGE_SEVERITY :: enum u32 { // TODO: make bit_set
 	MESSAGE, // Not supported until D3D 11.1
 	MESSAGE, // Not supported until D3D 11.1
 }
 }
 
 
-MESSAGE_CATEGORY :: enum u32 { // TODO: make bit_set
+MESSAGE_CATEGORY :: enum u32 {
 	APPLICATION_DEFINED = 0,
 	APPLICATION_DEFINED = 0,
 	MISCELLANEOUS,
 	MISCELLANEOUS,
 	INITIALIZATION,
 	INITIALIZATION,
@@ -3692,10 +3733,10 @@ MESSAGE_CATEGORY :: enum u32 { // TODO: make bit_set
 INFO_QUEUE_FILTER_DESC :: struct {
 INFO_QUEUE_FILTER_DESC :: struct {
 	NumCategories:    u32,
 	NumCategories:    u32,
 	pCategoryList:    ^MESSAGE_CATEGORY,
 	pCategoryList:    ^MESSAGE_CATEGORY,
-	
+
 	NumSeverities:    u32,
 	NumSeverities:    u32,
 	pSeverityList:    ^MESSAGE_SEVERITY,
 	pSeverityList:    ^MESSAGE_SEVERITY,
-	
+
 	NumIDs:           u32,
 	NumIDs:           u32,
 	pIDList:          ^MESSAGE_ID,
 	pIDList:          ^MESSAGE_ID,
 }
 }
@@ -3750,7 +3791,7 @@ IInfoQueue_VTable :: struct {
 	SetMuteDebugOutput:                           proc "stdcall" (this: ^IInfoQueue, bMute: BOOL),
 	SetMuteDebugOutput:                           proc "stdcall" (this: ^IInfoQueue, bMute: BOOL),
 }
 }
 
 
-MESSAGE_ID :: enum u32 { // TODO: make bit_set
+MESSAGE_ID :: enum u32 {
 	UNKNOWN = 0,
 	UNKNOWN = 0,
 	DEVICE_IASETVERTEXBUFFERS_HAZARD,
 	DEVICE_IASETVERTEXBUFFERS_HAZARD,
 	DEVICE_IASETINDEXBUFFER_HAZARD,
 	DEVICE_IASETINDEXBUFFER_HAZARD,

+ 339 - 311
vendor/directx/d3d12/d3d12.odin

@@ -212,11 +212,12 @@ SHADER_VARIABLE_CLASS :: enum i32 {
 	INTERFACE_POINTER     = 7,
 	INTERFACE_POINTER     = 7,
 }
 }
 
 
-SHADER_VARIABLE_FLAGS :: enum u32 { // TODO: make bit_set
-	USERPACKED              = 0x1,
-	USED                    = 0x2,
-	INTERFACE_POINTER       = 0x4,
-	INTERFACE_PARAMETER     = 0x8,
+SHADER_VARIABLE_FLAGS :: distinct bit_set[SHADER_VARIABLE_FLAG; u32]
+SHADER_VARIABLE_FLAG :: enum u32 {
+	USERPACKED              = 0,
+	USED                    = 1,
+	INTERFACE_POINTER       = 2,
+	INTERFACE_PARAMETER     = 3,
 }
 }
 
 
 SHADER_VARIABLE_TYPE :: enum i32 {
 SHADER_VARIABLE_TYPE :: enum i32 {
@@ -280,15 +281,16 @@ SHADER_VARIABLE_TYPE :: enum i32 {
 	MIN16UINT                     = 57,
 	MIN16UINT                     = 57,
 }
 }
 
 
-SHADER_INPUT_FLAGS :: enum u32 { // TODO: make bit_set
-	USERPACKED              = 0x1,
-	COMPARISON_SAMPLER      = 0x2,
-	TEXTURE_COMPONENT_0     = 0x4,
-	TEXTURE_COMPONENT_1     = 0x8,
-	TEXTURE_COMPONENTS      = 0xc,
-	UNUSED                  = 0x10,
+SHADER_INPUT_FLAGS :: distinct bit_set[SHADER_INPUT_FLAG; u32]
+SHADER_INPUT_FLAG :: enum u32 {
+	USERPACKED              = 0,
+	COMPARISON_SAMPLER      = 1,
+	TEXTURE_COMPONENT_0     = 2,
+	TEXTURE_COMPONENT_1     = 3,
+	UNUSED                  = 4,
 }
 }
 
 
+
 SHADER_INPUT_TYPE :: enum i32 {
 SHADER_INPUT_TYPE :: enum i32 {
 	CBUFFER                        = 0,
 	CBUFFER                        = 0,
 	TBUFFER                        = 1,
 	TBUFFER                        = 1,
@@ -306,8 +308,9 @@ SHADER_INPUT_TYPE :: enum i32 {
 	UAV_FEEDBACKTEXTURE            = 13,
 	UAV_FEEDBACKTEXTURE            = 13,
 }
 }
 
 
-SHADER_CBUFFER_FLAGS :: enum u32 { // TODO: make bit_set
-	USERPACKED = 0x1,
+SHADER_CBUFFER_FLAGS :: distinct bit_set[SHADER_CBUFFER_FLAG; u32]
+SHADER_CBUFFER_FLAG :: enum u32 {
+	USERPACKED = 0,
 }
 }
 
 
 CBUFFER_TYPE :: enum i32 {
 CBUFFER_TYPE :: enum i32 {
@@ -410,13 +413,12 @@ INTERPOLATION_MODE :: enum i32 {
 	LINEAR_NOPERSPECTIVE_SAMPLE   = 7,
 	LINEAR_NOPERSPECTIVE_SAMPLE   = 7,
 }
 }
 
 
-PARAMETER_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE = 0x0,
-	IN   = 0x1,
-	OUT  = 0x2,
+PARAMETER_FLAGS :: distinct bit_set[PARAMETER_FLAG; u32]
+PARAMETER_FLAG :: enum u32 {
+	IN   = 0,
+	OUT  = 1,
 }
 }
 
 
-
 GPU_VIRTUAL_ADDRESS :: u64
 GPU_VIRTUAL_ADDRESS :: u64
 
 
 COMMAND_LIST_TYPE :: enum i32 {
 COMMAND_LIST_TYPE :: enum i32 {
@@ -429,9 +431,9 @@ COMMAND_LIST_TYPE :: enum i32 {
 	VIDEO_ENCODE  = 6,
 	VIDEO_ENCODE  = 6,
 }
 }
 
 
-COMMAND_QUEUE_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                = 0x0,
-	DISABLE_GPU_TIMEOUT = 0x1,
+COMMAND_QUEUE_FLAGS :: distinct bit_set[COMMAND_QUEUE_FLAG; u32]
+COMMAND_QUEUE_FLAG :: enum u32 {
+	DISABLE_GPU_TIMEOUT = 0,
 }
 }
 
 
 COMMAND_QUEUE_PRIORITY :: enum i32 {
 COMMAND_QUEUE_PRIORITY :: enum i32 {
@@ -593,12 +595,19 @@ BLEND_OP :: enum i32 {
 	MAX          = 5,
 	MAX          = 5,
 }
 }
 
 
-COLOR_WRITE_ENABLE :: enum i32 { // TODO: make bit_set
-	RED   = 1,
-	GREEN = 2,
-	BLUE  = 4,
-	ALPHA = 8,
-	ALL   = 15,
+COLOR_WRITE_ENABLE_MASK   :: distinct bit_set[COLOR_WRITE_ENABLE; u32]
+
+COLOR_WRITE_ENABLE_RED   :: COLOR_WRITE_ENABLE_MASK{.RED}
+COLOR_WRITE_ENABLE_GREEN :: COLOR_WRITE_ENABLE_MASK{.GREEN}
+COLOR_WRITE_ENABLE_BLUE  :: COLOR_WRITE_ENABLE_MASK{.BLUE}
+COLOR_WRITE_ENABLE_ALPHA :: COLOR_WRITE_ENABLE_MASK{.ALPHA}
+COLOR_WRITE_ENABLE_ALL   :: COLOR_WRITE_ENABLE_MASK{.RED, .GREEN, .BLUE, .ALPHA}
+
+COLOR_WRITE_ENABLE :: enum i32 {
+	RED   = 0,
+	GREEN = 1,
+	BLUE  = 2,
+	ALPHA = 3,
 }
 }
 
 
 LOGIC_OP :: enum i32 {
 LOGIC_OP :: enum i32 {
@@ -721,9 +730,9 @@ CACHED_PIPELINE_STATE :: struct {
 	CachedBlobSizeInBytes: SIZE_T,
 	CachedBlobSizeInBytes: SIZE_T,
 }
 }
 
 
-PIPELINE_STATE_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE       = 0x0,
-	TOOL_DEBUG = 0x1,
+PIPELINE_STATE_FLAGS :: distinct bit_set[PIPELINE_STATE_FLAG; u32]
+PIPELINE_STATE_FLAG :: enum u32 {
+	TOOL_DEBUG = 0,
 }
 }
 
 
 GRAPHICS_PIPELINE_STATE_DESC :: struct {
 GRAPHICS_PIPELINE_STATE_DESC :: struct {
@@ -853,58 +862,61 @@ CONSERVATIVE_RASTERIZATION_TIER :: enum i32 {
 	_3            = 3,
 	_3            = 3,
 }
 }
 
 
-FORMAT_SUPPORT1 :: enum i32 { // TODO: make bit_set
-	NONE                        = 0,
-	BUFFER                      = 1,
-	IA_VERTEX_BUFFER            = 2,
-	IA_INDEX_BUFFER             = 4,
-	SO_BUFFER                   = 8,
-	TEXTURE1D                   = 16,
-	TEXTURE2D                   = 32,
-	TEXTURE3D                   = 64,
-	TEXTURECUBE                 = 128,
-	SHADER_LOAD                 = 256,
-	SHADER_SAMPLE               = 512,
-	SHADER_SAMPLE_COMPARISON    = 1024,
-	SHADER_SAMPLE_MONO_TEXT     = 2048,
-	MIP                         = 4096,
-	RENDER_TARGET               = 16384,
-	BLENDABLE                   = 32768,
-	DEPTH_STENCIL               = 65536,
-	MULTISAMPLE_RESOLVE         = 262144,
-	DISPLAY                     = 524288,
-	CAST_WITHIN_BIT_LAYOUT      = 1048576,
-	MULTISAMPLE_RENDERTARGET    = 2097152,
-	MULTISAMPLE_LOAD            = 4194304,
-	SHADER_GATHER               = 8388608,
-	BACK_BUFFER_CAST            = 16777216,
-	TYPED_UNORDERED_ACCESS_VIEW = 33554432,
-	SHADER_GATHER_COMPARISON    = 67108864,
-	DECODER_OUTPUT              = 134217728,
-	VIDEO_PROCESSOR_OUTPUT      = 268435456,
-	VIDEO_PROCESSOR_INPUT       = 536870912,
-	VIDEO_ENCODER               = 1073741824,
-}
-
-FORMAT_SUPPORT2 :: enum i32 { // TODO: make bit_set
-	NONE                                         = 0,
-	UAV_ATOMIC_ADD                               = 1,
-	UAV_ATOMIC_BITWISE_OPS                       = 2,
-	UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE = 4,
-	UAV_ATOMIC_EXCHANGE                          = 8,
-	UAV_ATOMIC_SIGNED_MIN_OR_MAX                 = 16,
-	UAV_ATOMIC_UNSIGNED_MIN_OR_MAX               = 32,
-	UAV_TYPED_LOAD                               = 64,
-	UAV_TYPED_STORE                              = 128,
-	OUTPUT_MERGER_LOGIC_OP                       = 256,
-	TILED                                        = 512,
-	MULTIPLANE_OVERLAY                           = 16384,
-	SAMPLER_FEEDBACK                             = 32768,
-}
-
-MULTISAMPLE_QUALITY_LEVEL_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE           = 0x0,
-	TILED_RESOURCE = 0x1,
+FORMAT_SUPPORT1 :: distinct bit_set[FORMAT_SUPPORT1_FLAG; u32]
+FORMAT_SUPPORT1_FLAG :: enum i32 {
+	BUFFER                      = 0,
+	IA_VERTEX_BUFFER            = 1,
+	IA_INDEX_BUFFER             = 2,
+	SO_BUFFER                   = 3,
+	TEXTURE1D                   = 4,
+	TEXTURE2D                   = 5,
+	TEXTURE3D                   = 6,
+	TEXTURECUBE                 = 7,
+	SHADER_LOAD                 = 8,
+	SHADER_SAMPLE               = 9,
+	SHADER_SAMPLE_COMPARISON    = 10,
+	SHADER_SAMPLE_MONO_TEXT     = 11,
+	MIP                         = 12,
+
+	RENDER_TARGET               = 14,
+	BLENDABLE                   = 15,
+	DEPTH_STENCIL               = 16,
+
+	MULTISAMPLE_RESOLVE         = 18,
+	DISPLAY                     = 19,
+	CAST_WITHIN_BIT_LAYOUT      = 20,
+	MULTISAMPLE_RENDERTARGET    = 21,
+	MULTISAMPLE_LOAD            = 22,
+	SHADER_GATHER               = 23,
+	BACK_BUFFER_CAST            = 24,
+	TYPED_UNORDERED_ACCESS_VIEW = 25,
+	SHADER_GATHER_COMPARISON    = 26,
+	DECODER_OUTPUT              = 27,
+	VIDEO_PROCESSOR_OUTPUT      = 28,
+	VIDEO_PROCESSOR_INPUT       = 29,
+	VIDEO_ENCODER               = 30,
+}
+
+FORMAT_SUPPORT2 :: distinct bit_set[FORMAT_SUPPORT2_FLAG; u32]
+FORMAT_SUPPORT2_FLAG :: enum i32 {
+	UAV_ATOMIC_ADD                               = 0,
+	UAV_ATOMIC_BITWISE_OPS                       = 1,
+	UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE = 2,
+	UAV_ATOMIC_EXCHANGE                          = 3,
+	UAV_ATOMIC_SIGNED_MIN_OR_MAX                 = 4,
+	UAV_ATOMIC_UNSIGNED_MIN_OR_MAX               = 5,
+	UAV_TYPED_LOAD                               = 6,
+	UAV_TYPED_STORE                              = 7,
+	OUTPUT_MERGER_LOGIC_OP                       = 8,
+	TILED                                        = 9,
+
+	MULTIPLANE_OVERLAY                           = 14,
+	SAMPLER_FEEDBACK                             = 15,
+}
+
+MULTISAMPLE_QUALITY_LEVEL_FLAGS :: distinct bit_set[MULTISAMPLE_QUALITY_LEVEL_FLAG; u32]
+MULTISAMPLE_QUALITY_LEVEL_FLAG :: enum u32 {
+	TILED_RESOURCE = 0,
 }
 }
 
 
 CROSS_NODE_SHARING_TIER :: enum i32 {
 CROSS_NODE_SHARING_TIER :: enum i32 {
@@ -1034,12 +1046,12 @@ FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT :: struct {
 	MaxGPUVirtualAddressBitsPerProcess:  u32,
 	MaxGPUVirtualAddressBitsPerProcess:  u32,
 }
 }
 
 
-SHADER_CACHE_SUPPORT_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                   = 0x0,
-	SINGLE_PSO             = 0x1,
-	LIBRARY                = 0x2,
-	AUTOMATIC_INPROC_CACHE = 0x4,
-	AUTOMATIC_DISK_CACHE   = 0x8,
+SHADER_CACHE_SUPPORT_FLAGS :: distinct bit_set[SHADER_CACHE_SUPPORT_FLAG; u32]
+SHADER_CACHE_SUPPORT_FLAG :: enum u32 {
+	SINGLE_PSO             = 0,
+	LIBRARY                = 1,
+	AUTOMATIC_INPROC_CACHE = 2,
+	AUTOMATIC_DISK_CACHE   = 3,
 }
 }
 
 
 FEATURE_DATA_SHADER_CACHE :: struct {
 FEATURE_DATA_SHADER_CACHE :: struct {
@@ -1052,15 +1064,15 @@ FEATURE_DATA_COMMAND_QUEUE_PRIORITY :: struct {
 	PriorityForTypeIsSupported: BOOL,
 	PriorityForTypeIsSupported: BOOL,
 }
 }
 
 
-COMMAND_LIST_SUPPORT_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE          = 0x0,
-	DIRECT        = 0x1,
-	BUNDLE        = 0x2,
-	COMPUTE       = 0x4,
-	COPY          = 0x8,
-	VIDEO_DECODE  = 0x10,
-	VIDEO_PROCESS = 0x20,
-	VIDEO_ENCODE  = 0x40,
+COMMAND_LIST_SUPPORT_FLAGS :: distinct bit_set[COMMAND_LIST_SUPPORT_FLAG; u32]
+COMMAND_LIST_SUPPORT_FLAG :: enum u32 {
+	DIRECT        = 0,
+	BUNDLE        = 1,
+	COMPUTE       = 2,
+	COPY          = 3,
+	VIDEO_DECODE  = 4,
+	VIDEO_PROCESS = 5,
+	VIDEO_ENCODE  = 6,
 }
 }
 
 
 FEATURE_DATA_OPTIONS3 :: struct {
 FEATURE_DATA_OPTIONS3 :: struct {
@@ -1198,25 +1210,26 @@ HEAP_PROPERTIES :: struct {
 	VisibleNodeMask:      u32,
 	VisibleNodeMask:      u32,
 }
 }
 
 
-HEAP_FLAGS :: enum u32 { // TODO: make bit_set ???
-	NONE                           = 0x0,
-	SHARED                         = 0x1,
-	DENY_BUFFERS                   = 0x4,
-	ALLOW_DISPLAY                  = 0x8,
-	SHARED_CROSS_ADAPTER           = 0x20,
-	DENY_RT_DS_TEXTURES            = 0x40,
-	DENY_NON_RT_DS_TEXTURES        = 0x80,
-	HARDWARE_PROTECTED             = 0x100,
-	ALLOW_WRITE_WATCH              = 0x200,
-	ALLOW_SHADER_ATOMICS           = 0x400,
-	CREATE_NOT_RESIDENT            = 0x800,
-	CREATE_NOT_ZEROED              = 0x1000,
-	ALLOW_ALL_BUFFERS_AND_TEXTURES = 0x0,
-	ALLOW_ONLY_BUFFERS             = 0xc0,
-	ALLOW_ONLY_NON_RT_DS_TEXTURES  = 0x44,
-	ALLOW_ONLY_RT_DS_TEXTURES      = 0x84,
+HEAP_FLAGS :: distinct bit_set[HEAP_FLAG; u32]
+HEAP_FLAG :: enum u32 {
+	SHARED                         = 0,
+	DENY_BUFFERS                   = 2,
+	ALLOW_DISPLAY                  = 3,
+	SHARED_CROSS_ADAPTER           = 5,
+	DENY_RT_DS_TEXTURES            = 6,
+	DENY_NON_RT_DS_TEXTURES        = 7,
+	HARDWARE_PROTECTED             = 8,
+	ALLOW_WRITE_WATCH              = 9,
+	ALLOW_SHADER_ATOMICS           = 10,
+	CREATE_NOT_RESIDENT            = 11,
+	CREATE_NOT_ZEROED              = 12,
 }
 }
 
 
+HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES :: HEAP_FLAGS{}
+HEAP_FLAG_ALLOW_ONLY_BUFFERS             :: HEAP_FLAGS{.DENY_BUFFERS, .ALLOW_DISPLAY}
+HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES  :: HEAP_FLAGS{.DENY_BUFFERS, .DENY_RT_DS_TEXTURES}
+HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES      :: HEAP_FLAGS{.DENY_BUFFERS, .DENY_NON_RT_DS_TEXTURES}
+
 HEAP_DESC :: struct {
 HEAP_DESC :: struct {
 	SizeInBytes: u64,
 	SizeInBytes: u64,
 	Properties:  HEAP_PROPERTIES,
 	Properties:  HEAP_PROPERTIES,
@@ -1239,15 +1252,15 @@ TEXTURE_LAYOUT :: enum i32 {
 	_64KB_STANDARD_SWIZZLE  = 3,
 	_64KB_STANDARD_SWIZZLE  = 3,
 }
 }
 
 
-RESOURCE_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                        = 0x0,
-	ALLOW_RENDER_TARGET         = 0x1,
-	ALLOW_DEPTH_STENCIL         = 0x2,
-	ALLOW_UNORDERED_ACCESS      = 0x4,
-	DENY_SHADER_RESOURCE        = 0x8,
-	ALLOW_CROSS_ADAPTER         = 0x10,
-	ALLOW_SIMULTANEOUS_ACCESS   = 0x20,
-	VIDEO_DECODE_REFERENCE_ONLY = 0x40,
+RESOURCE_FLAGS :: distinct bit_set[RESOURCE_FLAG; u32]
+RESOURCE_FLAG :: enum u32 {
+	ALLOW_RENDER_TARGET         = 0,
+	ALLOW_DEPTH_STENCIL         = 1,
+	ALLOW_UNORDERED_ACCESS      = 2,
+	DENY_SHADER_RESOURCE        = 3,
+	ALLOW_CROSS_ADAPTER         = 4,
+	ALLOW_SIMULTANEOUS_ACCESS   = 5,
+	VIDEO_DECODE_REFERENCE_ONLY = 6,
 }
 }
 
 
 MIP_REGION :: struct {
 MIP_REGION :: struct {
@@ -1332,11 +1345,11 @@ TILE_REGION_SIZE :: struct {
 	Depth:    u16,
 	Depth:    u16,
 }
 }
 
 
-TILE_RANGE_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE              = 0x0,
-	NULL              = 0x1,
-	SKIP              = 0x2,
-	REUSE_SINGLE_TILE = 0x4,
+TILE_RANGE_FLAGS :: distinct bit_set[TILE_RANGE_FLAG; u32]
+TILE_RANGE_FLAG :: enum u32 {
+	NULL              = 0,
+	SKIP              = 1,
+	REUSE_SINGLE_TILE = 2,
 }
 }
 
 
 SUBRESOURCE_TILING :: struct {
 SUBRESOURCE_TILING :: struct {
@@ -1359,45 +1372,52 @@ PACKED_MIP_INFO :: struct {
 	StartTileIndexInOverallResource: u32,
 	StartTileIndexInOverallResource: u32,
 }
 }
 
 
-TILE_MAPPING_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE      = 0x0,
-	NO_HAZARD = 0x1,
-}
-
-TILE_COPY_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                                     = 0x0,
-	NO_HAZARD                                = 0x1,
-	LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE = 0x2,
-	SWIZZLED_TILED_RESOURCE_TO_LINEAR_BUFFER = 0x4,
-}
-
-RESOURCE_STATES :: enum i32 { // TODO: make bit_set
-	COMMON                            = 0,
-	VERTEX_AND_CONSTANT_BUFFER        = 1,
-	INDEX_BUFFER                      = 2,
-	RENDER_TARGET                     = 4,
-	UNORDERED_ACCESS                  = 8,
-	DEPTH_WRITE                       = 16,
-	DEPTH_READ                        = 32,
-	NON_PIXEL_SHADER_RESOURCE         = 64,
-	PIXEL_SHADER_RESOURCE             = 128,
-	STREAM_OUT                        = 256,
-	INDIRECT_ARGUMENT                 = 512,
-	COPY_DEST                         = 1024,
-	COPY_SOURCE                       = 2048,
-	RESOLVE_DEST                      = 4096,
-	RESOLVE_SOURCE                    = 8192,
-	RAYTRACING_ACCELERATION_STRUCTURE = 4194304,
-	SHADING_RATE_SOURCE               = 16777216,
-	GENERIC_READ                      = 2755,
-	PRESENT                           = 0,
-	PREDICATION                       = 512,
-	VIDEO_DECODE_READ                 = 65536,
-	VIDEO_DECODE_WRITE                = 131072,
-	VIDEO_PROCESS_READ                = 262144,
-	VIDEO_PROCESS_WRITE               = 524288,
-	VIDEO_ENCODE_READ                 = 2097152,
-	VIDEO_ENCODE_WRITE                = 8388608,
+TILE_MAPPING_FLAGS :: distinct bit_set[TILE_MAPPING_FLAG; u32]
+TILE_MAPPING_FLAG :: enum u32 {
+	NO_HAZARD = 0,
+}
+
+TILE_COPY_FLAGS :: distinct bit_set[TILE_COPY_FLAG; u32]
+TILE_COPY_FLAG :: enum u32 {
+	NO_HAZARD                                = 0,
+	LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE = 1,
+	SWIZZLED_TILED_RESOURCE_TO_LINEAR_BUFFER = 2,
+}
+
+RESOURCE_STATES :: distinct bit_set[RESOURCE_STATE; u32]
+RESOURCE_STATE :: enum i32 {
+	VERTEX_AND_CONSTANT_BUFFER        = 0,
+	INDEX_BUFFER                      = 1,
+	RENDER_TARGET                     = 2,
+	UNORDERED_ACCESS                  = 3,
+	DEPTH_WRITE                       = 4,
+	DEPTH_READ                        = 5,
+	NON_PIXEL_SHADER_RESOURCE         = 6,
+	PIXEL_SHADER_RESOURCE             = 7,
+	STREAM_OUT                        = 8,
+	INDIRECT_ARGUMENT                 = 9,
+	COPY_DEST                         = 10,
+	COPY_SOURCE                       = 11,
+	RESOLVE_DEST                      = 12,
+	RESOLVE_SOURCE                    = 13,
+	RAYTRACING_ACCELERATION_STRUCTURE = 22,
+	SHADING_RATE_SOURCE               = 24,
+	PREDICATION                       = 9,
+	VIDEO_DECODE_READ                 = 16,
+	VIDEO_DECODE_WRITE                = 17,
+	VIDEO_PROCESS_READ                = 18,
+	VIDEO_PROCESS_WRITE               = 19,
+	VIDEO_ENCODE_READ                 = 21,
+	VIDEO_ENCODE_WRITE                = 23,
+}
+
+RESOURCE_STATE_COMMON :: RESOURCE_STATES{}
+RESOURCE_STATE_PRESENT :: RESOURCE_STATES{}
+RESOURCE_STATE_GENERIC_READ :: RESOURCE_STATES{
+	.VERTEX_AND_CONSTANT_BUFFER, .INDEX_BUFFER, .NON_PIXEL_SHADER_RESOURCE, .PIXEL_SHADER_RESOURCE, .INDIRECT_ARGUMENT, .COPY_SOURCE,
+}
+RESOURCE_STATE_ALL_SHADER_RESOURCE :: RESOURCE_STATES{
+	.SHADING_RATE_SOURCE, .INDEX_BUFFER,
 }
 }
 
 
 RESOURCE_BARRIER_TYPE :: enum i32 {
 RESOURCE_BARRIER_TYPE :: enum i32 {
@@ -1422,10 +1442,10 @@ RESOURCE_UAV_BARRIER :: struct {
 	pResource: ^IResource,
 	pResource: ^IResource,
 }
 }
 
 
-RESOURCE_BARRIER_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE       = 0x0,
-	BEGIN_ONLY = 0x1,
-	END_ONLY   = 0x2,
+RESOURCE_BARRIER_FLAGS :: distinct bit_set[RESOURCE_BARRIER_FLAG; u32]
+RESOURCE_BARRIER_FLAG :: enum u32 {
+	BEGIN_ONLY = 0,
+	END_ONLY   = 1,
 }
 }
 
 
 RESOURCE_BARRIER :: struct {
 RESOURCE_BARRIER :: struct {
@@ -1484,9 +1504,9 @@ VIEW_INSTANCE_LOCATION :: struct {
 	RenderTargetArrayIndex: u32,
 	RenderTargetArrayIndex: u32,
 }
 }
 
 
-VIEW_INSTANCING_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                         = 0x0,
-	ENABLE_VIEW_INSTANCE_MASKING = 0x1,
+VIEW_INSTANCING_FLAGS :: distinct bit_set[VIEW_INSTANCING_FLAG; u32]
+VIEW_INSTANCING_FLAG :: enum u32 {
+	ENABLE_VIEW_INSTANCE_MASKING = 0,
 }
 }
 
 
 VIEW_INSTANCING_DESC :: struct {
 VIEW_INSTANCING_DESC :: struct {
@@ -1504,9 +1524,9 @@ SHADER_COMPONENT_MAPPING :: enum i32 {
 	FORCE_VALUE_1           = 5,
 	FORCE_VALUE_1           = 5,
 }
 }
 
 
-BUFFER_SRV_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE = 0x0,
-	RAW  = 0x1,
+BUFFER_SRV_FLAGS :: distinct bit_set[BUFFER_SRV_FLAG; u32]
+BUFFER_SRV_FLAG :: enum u32 {
+	RAW = 0,
 }
 }
 
 
 BUFFER_SRV :: struct {
 BUFFER_SRV :: struct {
@@ -1675,9 +1695,9 @@ SAMPLER_DESC :: struct {
 	MaxLOD:         f32,
 	MaxLOD:         f32,
 }
 }
 
 
-BUFFER_UAV_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE = 0x0,
-	RAW  = 0x1,
+BUFFER_UAV_FLAGS :: distinct bit_set[BUFFER_UAV_FLAG; u32]
+BUFFER_UAV_FLAG :: enum u32 {
+	RAW = 0,
 }
 }
 
 
 BUFFER_UAV :: struct {
 BUFFER_UAV :: struct {
@@ -1837,10 +1857,10 @@ TEX2DMS_ARRAY_DSV :: struct {
 	ArraySize:       u32,
 	ArraySize:       u32,
 }
 }
 
 
-DSV_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE              = 0x0,
-	READ_ONLY_DEPTH   = 0x1,
-	READ_ONLY_STENCIL = 0x2,
+DSV_FLAGS :: distinct bit_set[DSV_FLAG; u32]
+DSV_FLAG :: enum u32 {
+	READ_ONLY_DEPTH   = 0,
+	READ_ONLY_STENCIL = 1,
 }
 }
 
 
 DSV_DIMENSION :: enum i32 {
 DSV_DIMENSION :: enum i32 {
@@ -1867,16 +1887,17 @@ DEPTH_STENCIL_VIEW_DESC :: struct {
 	},
 	},
 }
 }
 
 
-CLEAR_FLAGS :: enum u32 { // TODO: make bit_set
-	DEPTH   = 0x1,
-	STENCIL = 0x2,
+CLEAR_FLAGS :: distinct bit_set[CLEAR_FLAG; u32]
+CLEAR_FLAG :: enum u32 {
+	DEPTH   = 0,
+	STENCIL = 1,
 }
 }
 
 
-FENCE_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                 = 0x0,
-	SHARED               = 0x1,
-	SHARED_CROSS_ADAPTER = 0x2,
-	NON_MONITORED        = 0x4,
+FENCE_FLAGS :: distinct bit_set[FENCE_FLAG; u32]
+FENCE_FLAG :: enum u32 {
+	SHARED               = 0,
+	SHARED_CROSS_ADAPTER = 1,
+	NON_MONITORED        = 2,
 }
 }
 
 
 DESCRIPTOR_HEAP_TYPE :: enum i32 {
 DESCRIPTOR_HEAP_TYPE :: enum i32 {
@@ -1887,9 +1908,9 @@ DESCRIPTOR_HEAP_TYPE :: enum i32 {
 	NUM_TYPES   = 4,
 	NUM_TYPES   = 4,
 }
 }
 
 
-DESCRIPTOR_HEAP_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE           = 0x0,
-	SHADER_VISIBLE = 0x1,
+DESCRIPTOR_HEAP_FLAGS :: distinct bit_set[DESCRIPTOR_HEAP_FLAG; u32]
+DESCRIPTOR_HEAP_FLAG :: enum u32 {
+	SHADER_VISIBLE = 0,
 }
 }
 
 
 DESCRIPTOR_HEAP_DESC :: struct {
 DESCRIPTOR_HEAP_DESC :: struct {
@@ -1959,18 +1980,18 @@ ROOT_PARAMETER :: struct {
 	ShaderVisibility: SHADER_VISIBILITY,
 	ShaderVisibility: SHADER_VISIBILITY,
 }
 }
 
 
-ROOT_SIGNATURE_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                                  = 0x0,
-	ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT    = 0x1,
-	DENY_VERTEX_SHADER_ROOT_ACCESS        = 0x2,
-	DENY_HULL_SHADER_ROOT_ACCESS          = 0x4,
-	DENY_DOMAIN_SHADER_ROOT_ACCESS        = 0x8,
-	DENY_GEOMETRY_SHADER_ROOT_ACCESS      = 0x10,
-	DENY_PIXEL_SHADER_ROOT_ACCESS         = 0x20,
-	ALLOW_STREAM_OUTPUT                   = 0x40,
-	LOCAL_ROOT_SIGNATURE                  = 0x80,
-	DENY_AMPLIFICATION_SHADER_ROOT_ACCESS = 0x100,
-	DENY_MESH_SHADER_ROOT_ACCESS          = 0x200,
+ROOT_SIGNATURE_FLAGS :: distinct bit_set[ROOT_SIGNATURE_FLAG; u32]
+ROOT_SIGNATURE_FLAG :: enum u32 {
+	ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT    = 0,
+	DENY_VERTEX_SHADER_ROOT_ACCESS        = 1,
+	DENY_HULL_SHADER_ROOT_ACCESS          = 2,
+	DENY_DOMAIN_SHADER_ROOT_ACCESS        = 3,
+	DENY_GEOMETRY_SHADER_ROOT_ACCESS      = 4,
+	DENY_PIXEL_SHADER_ROOT_ACCESS         = 5,
+	ALLOW_STREAM_OUTPUT                   = 6,
+	LOCAL_ROOT_SIGNATURE                  = 7,
+	DENY_AMPLIFICATION_SHADER_ROOT_ACCESS = 8,
+	DENY_MESH_SHADER_ROOT_ACCESS          = 9,
 }
 }
 
 
 STATIC_BORDER_COLOR :: enum i32 {
 STATIC_BORDER_COLOR :: enum i32 {
@@ -2003,13 +2024,13 @@ ROOT_SIGNATURE_DESC :: struct {
 	Flags:             ROOT_SIGNATURE_FLAGS,
 	Flags:             ROOT_SIGNATURE_FLAGS,
 }
 }
 
 
-DESCRIPTOR_RANGE_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                                            = 0x0,
-	DESCRIPTORS_VOLATILE                            = 0x1,
-	DATA_VOLATILE                                   = 0x2,
-	DATA_STATIC_WHILE_SET_AT_EXECUTE                = 0x4,
-	DATA_STATIC                                     = 0x8,
-	DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 0x10000,
+DESCRIPTOR_RANGE_FLAGS :: distinct bit_set[DESCRIPTOR_RANGE_FLAG; u32]
+DESCRIPTOR_RANGE_FLAG :: enum u32 {
+	DESCRIPTORS_VOLATILE                            = 0,
+	DATA_VOLATILE                                   = 1,
+	DATA_STATIC_WHILE_SET_AT_EXECUTE                = 2,
+	DATA_STATIC                                     = 3,
+	DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 16,
 }
 }
 
 
 DESCRIPTOR_RANGE1 :: struct {
 DESCRIPTOR_RANGE1 :: struct {
@@ -2026,11 +2047,11 @@ ROOT_DESCRIPTOR_TABLE1 :: struct {
 	pDescriptorRanges:   ^DESCRIPTOR_RANGE1,
 	pDescriptorRanges:   ^DESCRIPTOR_RANGE1,
 }
 }
 
 
-ROOT_DESCRIPTOR_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                             = 0x0,
-	DATA_VOLATILE                    = 0x2,
-	DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
-	DATA_STATIC                      = 0x8,
+ROOT_DESCRIPTOR_FLAGS :: distinct bit_set[ROOT_DESCRIPTOR_FLAG; u32]
+ROOT_DESCRIPTOR_FLAG :: enum u32 {
+	DATA_VOLATILE                    = 2,
+	DATA_STATIC_WHILE_SET_AT_EXECUTE = 3,
+	DATA_STATIC                      = 4,
 }
 }
 
 
 ROOT_DESCRIPTOR1 :: struct {
 ROOT_DESCRIPTOR1 :: struct {
@@ -2571,11 +2592,13 @@ IPipelineLibrary1_VTable :: struct {
 	LoadPipeline: proc "stdcall" (this: ^IPipelineLibrary1, pName: [^]u16, pDesc: ^PIPELINE_STATE_STREAM_DESC, riid: ^IID, ppPipelineState: ^rawptr) -> HRESULT,
 	LoadPipeline: proc "stdcall" (this: ^IPipelineLibrary1, pName: [^]u16, pDesc: ^PIPELINE_STATE_STREAM_DESC, riid: ^IID, ppPipelineState: ^rawptr) -> HRESULT,
 }
 }
 
 
-MULTIPLE_FENCE_WAIT_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE = 0x0,
-	ANY  = 0x1,
-	ALL  = 0x0,
+MULTIPLE_FENCE_WAIT_FLAGS :: distinct bit_set[MULTIPLE_FENCE_WAIT_FLAG; u32]
+MULTIPLE_FENCE_WAIT_FLAG :: enum u32 {
+	ANY = 0,
 }
 }
+MULTIPLE_FENCE_WAIT_FLAG_NONE :: MULTIPLE_FENCE_WAIT_FLAGS{}
+MULTIPLE_FENCE_WAIT_FLAG_ANY  :: MULTIPLE_FENCE_WAIT_FLAGS{.ANY}
+MULTIPLE_FENCE_WAIT_FLAG_ALL  :: MULTIPLE_FENCE_WAIT_FLAGS{}
 
 
 RESIDENCY_PRIORITY :: enum i32 {
 RESIDENCY_PRIORITY :: enum i32 {
 	MINIMUM = 671088640,
 	MINIMUM = 671088640,
@@ -2611,9 +2634,9 @@ IDevice2_VTable :: struct {
 	CreatePipelineState: proc "stdcall" (this: ^IDevice2, pDesc: ^PIPELINE_STATE_STREAM_DESC, riid: ^IID, ppPipelineState: ^rawptr) -> HRESULT,
 	CreatePipelineState: proc "stdcall" (this: ^IDevice2, pDesc: ^PIPELINE_STATE_STREAM_DESC, riid: ^IID, ppPipelineState: ^rawptr) -> HRESULT,
 }
 }
 
 
-RESIDENCY_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE            = 0x0,
-	DENY_OVERBUDGET = 0x1,
+RESIDENCY_FLAGS :: distinct bit_set[RESIDENCY_FLAG; u32]
+RESIDENCY_FLAG :: enum u32 {
+	DENY_OVERBUDGET = 0,
 }
 }
 
 
 
 
@@ -2630,16 +2653,16 @@ IDevice3_VTable :: struct {
 	EnqueueMakeResident:             proc "stdcall" (this: ^IDevice3, Flags: RESIDENCY_FLAGS, NumObjects: u32, ppObjects: ^^IPageable, pFenceToSignal: ^IFence, FenceValueToSignal: u64) -> HRESULT,
 	EnqueueMakeResident:             proc "stdcall" (this: ^IDevice3, Flags: RESIDENCY_FLAGS, NumObjects: u32, ppObjects: ^^IPageable, pFenceToSignal: ^IFence, FenceValueToSignal: u64) -> HRESULT,
 }
 }
 
 
-COMMAND_LIST_FLAGS :: enum u32 { // TODO: make bit_set
-	COMMAND_LIST_FLAG_NONE = 0x0,
+COMMAND_LIST_FLAGS :: distinct bit_set[COMMAND_LIST_FLAG; u32]
+COMMAND_LIST_FLAG :: enum u32 {
 }
 }
 
 
-COMMAND_POOL_FLAGS :: enum u32 { // TODO: make bit_set
-	COMMAND_POOL_FLAG_NONE = 0x0,
+COMMAND_POOL_FLAGS :: distinct bit_set[COMMAND_POOL_FLAG; u32]
+COMMAND_POOL_FLAG :: enum u32 {
 }
 }
 
 
-COMMAND_RECORDER_FLAGS :: enum u32 { // TODO: make bit_set
-	COMMAND_RECORDER_FLAG_NONE = 0x0,
+COMMAND_RECORDER_FLAGS :: distinct bit_set[COMMAND_RECORDER_FLAG; u32]
+COMMAND_RECORDER_FLAG :: enum u32 {
 }
 }
 
 
 PROTECTED_SESSION_STATUS :: enum i32 {
 PROTECTED_SESSION_STATUS :: enum i32 {
@@ -2660,9 +2683,9 @@ IProtectedSession_VTable :: struct {
 	GetSessionStatus: proc "stdcall" (this: ^IProtectedSession) -> PROTECTED_SESSION_STATUS,
 	GetSessionStatus: proc "stdcall" (this: ^IProtectedSession) -> PROTECTED_SESSION_STATUS,
 }
 }
 
 
-PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE      = 0x0,
-	SUPPORTED = 0x1,
+PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS :: distinct bit_set[PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG; u32]
+PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG :: enum u32 {
+	SUPPORTED = 0,
 }
 }
 
 
 FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT :: struct {
 FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT :: struct {
@@ -2670,8 +2693,8 @@ FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT :: struct {
 	Support:   PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS,
 	Support:   PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS,
 }
 }
 
 
-PROTECTED_RESOURCE_SESSION_FLAGS :: enum u32 { // TODO: make bit_set
-	PROTECTED_RESOURCE_SESSION_FLAG_NONE = 0x0,
+PROTECTED_RESOURCE_SESSION_FLAGS :: distinct bit_set[PROTECTED_RESOURCE_SESSION_FLAG; u32]
+PROTECTED_RESOURCE_SESSION_FLAG :: enum u32 {
 }
 }
 
 
 PROTECTED_RESOURCE_SESSION_DESC :: struct {
 PROTECTED_RESOURCE_SESSION_DESC :: struct {
@@ -2760,9 +2783,10 @@ META_COMMAND_PARAMETER_TYPE :: enum i32 {
 	GPU_DESCRIPTOR_HANDLE_HEAP_TYPE_CBV_SRV_UAV = 4,
 	GPU_DESCRIPTOR_HANDLE_HEAP_TYPE_CBV_SRV_UAV = 4,
 }
 }
 
 
-META_COMMAND_PARAMETER_FLAGS :: enum u32 { // TODO: make bit_set
-	INPUT  = 0x1,
-	OUTPUT = 0x2,
+META_COMMAND_PARAMETER_FLAGS :: distinct bit_set[META_COMMAND_PARAMETER_FLAG; u32]
+META_COMMAND_PARAMETER_FLAG :: enum u32 {
+	INPUT  = 0,
+	OUTPUT = 1,
 }
 }
 
 
 META_COMMAND_PARAMETER_STAGE :: enum i32 {
 META_COMMAND_PARAMETER_STAGE :: enum i32 {
@@ -2850,11 +2874,11 @@ STATE_SUBOBJECT :: struct {
 	pDesc: rawptr,
 	pDesc: rawptr,
 }
 }
 
 
-STATE_OBJECT_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                                             = 0x0,
-	ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITIONS = 0x1,
-	ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS = 0x2,
-	ALLOW_STATE_OBJECT_ADDITIONS                     = 0x4,
+STATE_OBJECT_FLAGS :: distinct bit_set[STATE_OBJECT_FLAG; u32]
+STATE_OBJECT_FLAG :: enum u32 {
+	ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITIONS = 0,
+	ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS = 1,
+	ALLOW_STATE_OBJECT_ADDITIONS                     = 2,
 }
 }
 
 
 STATE_OBJECT_CONFIG :: struct {
 STATE_OBJECT_CONFIG :: struct {
@@ -2873,8 +2897,8 @@ NODE_MASK :: struct {
 	NodeMask: u32,
 	NodeMask: u32,
 }
 }
 
 
-EXPORT_FLAGS :: enum u32 { // TODO: make bit_set
-	EXPORT_FLAG_NONE = 0x0,
+EXPORT_FLAGS :: distinct bit_set[EXPORT_FLAG; u32]
+EXPORT_FLAG :: enum u32 {
 }
 }
 
 
 EXPORT_DESC :: struct {
 EXPORT_DESC :: struct {
@@ -2929,10 +2953,10 @@ RAYTRACING_PIPELINE_CONFIG :: struct {
 	MaxTraceRecursionDepth: u32,
 	MaxTraceRecursionDepth: u32,
 }
 }
 
 
-RAYTRACING_PIPELINE_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                       = 0x0,
-	SKIP_TRIANGLES             = 0x100,
-	SKIP_PROCEDURAL_PRIMITIVES = 0x200,
+RAYTRACING_PIPELINE_FLAGS :: distinct bit_set[RAYTRACING_PIPELINE_FLAG; u32]
+RAYTRACING_PIPELINE_FLAG :: enum u32 {
+	SKIP_TRIANGLES             = 8,
+	SKIP_PROCEDURAL_PRIMITIVES = 9,
 }
 }
 
 
 RAYTRACING_PIPELINE_CONFIG1 :: struct {
 RAYTRACING_PIPELINE_CONFIG1 :: struct {
@@ -2951,10 +2975,10 @@ STATE_OBJECT_DESC :: struct {
 	pSubobjects:   ^STATE_SUBOBJECT,
 	pSubobjects:   ^STATE_SUBOBJECT,
 }
 }
 
 
-RAYTRACING_GEOMETRY_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                           = 0x0,
-	OPAQUE                         = 0x1,
-	NO_DUPLICATE_ANYHIT_INVOCATION = 0x2,
+RAYTRACING_GEOMETRY_FLAGS :: distinct bit_set[RAYTRACING_GEOMETRY_FLAG; u32]
+RAYTRACING_GEOMETRY_FLAG :: enum u32 {
+	OPAQUE                         = 0,
+	NO_DUPLICATE_ANYHIT_INVOCATION = 1,
 }
 }
 
 
 RAYTRACING_GEOMETRY_TYPE :: enum i32 {
 RAYTRACING_GEOMETRY_TYPE :: enum i32 {
@@ -2962,12 +2986,12 @@ RAYTRACING_GEOMETRY_TYPE :: enum i32 {
 	PROCEDURAL_PRIMITIVE_AABBS = 1,
 	PROCEDURAL_PRIMITIVE_AABBS = 1,
 }
 }
 
 
-RAYTRACING_INSTANCE_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                            = 0x0,
-	TRIANGLE_CULL_DISABLE           = 0x1,
-	TRIANGLE_FRONT_COUNTERCLOCKWISE = 0x2,
-	FORCE_OPAQUE                    = 0x4,
-	FORCE_NON_OPAQUE                = 0x8,
+RAYTRACING_INSTANCE_FLAGS :: distinct bit_set[RAYTRACING_INSTANCE_FLAG; u32]
+RAYTRACING_INSTANCE_FLAG :: enum u32 {
+	TRIANGLE_CULL_DISABLE           = 0,
+	TRIANGLE_FRONT_COUNTERCLOCKWISE = 1,
+	FORCE_OPAQUE                    = 2,
+	FORCE_NON_OPAQUE                = 3,
 }
 }
 
 
 GPU_VIRTUAL_ADDRESS_AND_STRIDE :: struct {
 GPU_VIRTUAL_ADDRESS_AND_STRIDE :: struct {
@@ -3010,14 +3034,14 @@ RAYTRACING_GEOMETRY_AABBS_DESC :: struct {
 	AABBs:     GPU_VIRTUAL_ADDRESS_AND_STRIDE,
 	AABBs:     GPU_VIRTUAL_ADDRESS_AND_STRIDE,
 }
 }
 
 
-RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE              = 0x0,
-	ALLOW_UPDATE      = 0x1,
-	ALLOW_COMPACTION  = 0x2,
-	PREFER_FAST_TRACE = 0x4,
-	PREFER_FAST_BUILD = 0x8,
-	MINIMIZE_MEMORY   = 0x10,
-	PERFORM_UPDATE    = 0x20,
+RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS :: distinct bit_set[RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG; u32]
+RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAG :: enum u32 {
+	ALLOW_UPDATE      = 0,
+	ALLOW_COMPACTION  = 1,
+	PREFER_FAST_TRACE = 2,
+	PREFER_FAST_BUILD = 3,
+	MINIMIZE_MEMORY   = 4,
+	PERFORM_UPDATE    = 5,
 }
 }
 
 
 RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE :: enum i32 {
 RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE :: enum i32 {
@@ -3137,18 +3161,18 @@ RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO :: struct {
 	UpdateScratchDataSizeInBytes: u64,
 	UpdateScratchDataSizeInBytes: u64,
 }
 }
 
 
-RAY_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                            = 0x0,
-	FORCE_OPAQUE                    = 0x1,
-	FORCE_NON_OPAQUE                = 0x2,
-	ACCEPT_FIRST_HIT_AND_END_SEARCH = 0x4,
-	SKIP_CLOSEST_HIT_SHADER         = 0x8,
-	CULL_BACK_FACING_TRIANGLES      = 0x10,
-	CULL_FRONT_FACING_TRIANGLES     = 0x20,
-	CULL_OPAQUE                     = 0x40,
-	CULL_NON_OPAQUE                 = 0x80,
-	SKIP_TRIANGLES                  = 0x100,
-	SKIP_PROCEDURAL_PRIMITIVES      = 0x200,
+RAY_FLAGS :: distinct bit_set[RAY_FLAG; u32]
+RAY_FLAG :: enum u32 {
+	FORCE_OPAQUE                    = 0,
+	FORCE_NON_OPAQUE                = 1,
+	ACCEPT_FIRST_HIT_AND_END_SEARCH = 2,
+	SKIP_CLOSEST_HIT_SHADER         = 3,
+	CULL_BACK_FACING_TRIANGLES      = 4,
+	CULL_FRONT_FACING_TRIANGLES     = 5,
+	CULL_OPAQUE                     = 6,
+	CULL_NON_OPAQUE                 = 7,
+	SKIP_TRIANGLES                  = 8,
+	SKIP_PROCEDURAL_PRIMITIVES      = 9,
 }
 }
 
 
 HIT_KIND :: enum i32 {
 HIT_KIND :: enum i32 {
@@ -3260,10 +3284,10 @@ DRED_VERSION :: enum i32 {
 	_1_2 = 3,
 	_1_2 = 3,
 }
 }
 
 
-DRED_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                    = 0x0,
-	FORCE_ENABLE            = 0x1,
-	DISABLE_AUTOBREADCRUMBS = 0x2,
+DRED_FLAGS :: distinct bit_set[DRED_FLAG; u32]
+DRED_FLAG :: enum u32 {
+	FORCE_ENABLE            = 0,
+	DISABLE_AUTOBREADCRUMBS = 1,
 }
 }
 
 
 DRED_ENABLEMENT :: enum i32 {
 DRED_ENABLEMENT :: enum i32 {
@@ -3611,11 +3635,11 @@ RENDER_PASS_DEPTH_STENCIL_DESC :: struct {
 	StencilEndingAccess:    RENDER_PASS_ENDING_ACCESS,
 	StencilEndingAccess:    RENDER_PASS_ENDING_ACCESS,
 }
 }
 
 
-RENDER_PASS_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE             = 0x0,
-	ALLOW_UAV_WRITES = 0x1,
-	SUSPENDING_PASS  = 0x2,
-	RESUMING_PASS    = 0x4,
+RENDER_PASS_FLAGS :: distinct bit_set[RENDER_PASS_FLAG; u32]
+RENDER_PASS_FLAG :: enum u32 {
+	ALLOW_UAV_WRITES = 0,
+	SUSPENDING_PASS  = 1,
+	RESUMING_PASS    = 2,
 }
 }
 
 
 
 
@@ -3697,9 +3721,9 @@ IDebug_VTable :: struct {
 	EnableDebugLayer: proc "stdcall" (this: ^IDebug),
 	EnableDebugLayer: proc "stdcall" (this: ^IDebug),
 }
 }
 
 
-GPU_BASED_VALIDATION_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE                   = 0x0,
-	DISABLE_STATE_TRACKING = 0x1,
+GPU_BASED_VALIDATION_FLAGS :: distinct bit_set[GPU_BASED_VALIDATION_FLAG; u32]
+GPU_BASED_VALIDATION_FLAG :: enum u32 {
+	DISABLE_STATE_TRACKING = 0,
 }
 }
 
 
 
 
@@ -3741,11 +3765,11 @@ IDebug3_VTable :: struct {
 	SetGPUBasedValidationFlags:                  proc "stdcall" (this: ^IDebug3, Flags: GPU_BASED_VALIDATION_FLAGS),
 	SetGPUBasedValidationFlags:                  proc "stdcall" (this: ^IDebug3, Flags: GPU_BASED_VALIDATION_FLAGS),
 }
 }
 
 
-RLDO_FLAGS :: enum u32 { // TODO: make bit_set
-	NONE            = 0x0,
-	SUMMARY         = 0x1,
-	DETAIL          = 0x2,
-	IGNORE_INTERNAL = 0x4,
+RLDO_FLAGS :: distinct bit_set[RLDO_FLAG; u32]
+RLDO_FLAG :: enum u32 {
+	SUMMARY         = 0,
+	DETAIL          = 1,
+	IGNORE_INTERNAL = 2,
 }
 }
 
 
 DEBUG_DEVICE_PARAMETER_TYPE :: enum i32 {
 DEBUG_DEVICE_PARAMETER_TYPE :: enum i32 {
@@ -3754,12 +3778,12 @@ DEBUG_DEVICE_PARAMETER_TYPE :: enum i32 {
 	GPU_SLOWDOWN_PERFORMANCE_FACTOR = 2,
 	GPU_SLOWDOWN_PERFORMANCE_FACTOR = 2,
 }
 }
 
 
-DEBUG_FEATURE :: enum i32 { // TODO: make bit_set
-	NONE                                   = 0,
-	ALLOW_BEHAVIOR_CHANGING_DEBUG_AIDS     = 1,
-	CONSERVATIVE_RESOURCE_STATE_TRACKING   = 2,
-	DISABLE_VIRTUALIZED_BUNDLES_VALIDATION = 4,
-	EMULATE_WINDOWS7                       = 8,
+DEBUG_FEATURE :: distinct bit_set[DEBUG_FEATURE_FLAG; u32]
+DEBUG_FEATURE_FLAG :: enum i32 {
+	ALLOW_BEHAVIOR_CHANGING_DEBUG_AIDS     = 0,
+	CONSERVATIVE_RESOURCE_STATE_TRACKING   = 1,
+	DISABLE_VIRTUALIZED_BUNDLES_VALIDATION = 2,
+	EMULATE_WINDOWS7                       = 3,
 }
 }
 
 
 GPU_BASED_VALIDATION_SHADER_PATCH_MODE :: enum i32 {
 GPU_BASED_VALIDATION_SHADER_PATCH_MODE :: enum i32 {
@@ -3770,12 +3794,16 @@ GPU_BASED_VALIDATION_SHADER_PATCH_MODE :: enum i32 {
 	NUM_GPU_BASED_VALIDATION_SHADER_PATCH_MODES = 4,
 	NUM_GPU_BASED_VALIDATION_SHADER_PATCH_MODES = 4,
 }
 }
 
 
-GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAGS :: enum u32 { // TODO: make bit_set
-	GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_NONE                                           = 0x0,
-	GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_FRONT_LOAD_CREATE_TRACKING_ONLY_SHADERS        = 0x1,
-	GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_FRONT_LOAD_CREATE_UNGUARDED_VALIDATION_SHADERS = 0x2,
-	GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_FRONT_LOAD_CREATE_GUARDED_VALIDATION_SHADERS   = 0x4,
-	VALID_MASK                                                                                           = 0x7,
+GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAGS :: distinct bit_set[GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG; u32]
+GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG :: enum u32 {
+	FRONT_LOAD_CREATE_TRACKING_ONLY_SHADERS        = 0,
+	FRONT_LOAD_CREATE_UNGUARDED_VALIDATION_SHADERS = 1,
+	FRONT_LOAD_CREATE_GUARDED_VALIDATION_SHADERS   = 2,
+}
+GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAG_VALID_MASK :: GPU_BASED_VALIDATION_PIPELINE_STATE_CREATE_FLAGS{
+	.FRONT_LOAD_CREATE_TRACKING_ONLY_SHADERS,
+	.FRONT_LOAD_CREATE_UNGUARDED_VALIDATION_SHADERS,
+	.FRONT_LOAD_CREATE_GUARDED_VALIDATION_SHADERS,
 }
 }
 
 
 DEBUG_DEVICE_GPU_BASED_VALIDATION_SETTINGS :: struct {
 DEBUG_DEVICE_GPU_BASED_VALIDATION_SETTINGS :: struct {

+ 53 - 46
vendor/directx/d3d_compiler/d3d_compiler.odin

@@ -45,50 +45,57 @@ foreign d3dcompiler {
 
 
 
 
 
 
-D3DCOMPILE :: enum u32 { // TODO: make bit_field
-	DEBUG                              = 1 << 0,
-	SKIP_VALIDATION                    = 1 << 1,
-	SKIP_OPTIMIZATION                  = 1 << 2,
-	PACK_MATRIX_ROW_MAJOR              = 1 << 3,
-	PACK_MATRIX_COLUMN_MAJOR           = 1 << 4,
-	PARTIAL_PRECISION                  = 1 << 5,
-	FORCE_VS_SOFTWARE_NO_OPT           = 1 << 6,
-	FORCE_PS_SOFTWARE_NO_OPT           = 1 << 7,
-	NO_PRESHADER                       = 1 << 8,
-	AVOID_FLOW_CONTROL                 = 1 << 9,
-	PREFER_FLOW_CONTROL                = 1 << 10,
-	ENABLE_STRICTNESS                  = 1 << 11,
-	ENABLE_BACKWARDS_COMPATIBILITY     = 1 << 12,
-	IEEE_STRICTNESS                    = 1 << 13,
-	OPTIMIZATION_LEVEL0                = 1 << 14,
-	OPTIMIZATION_LEVEL1                = 0,
-	OPTIMIZATION_LEVEL2                = (1 << 14)|(1 << 15), // Added manually
-	OPTIMIZATION_LEVEL3                = 1 << 15,
-	RESERVED16                         = 1 << 16,
-	RESERVED17                         = 1 << 17,
-	WARNINGS_ARE_ERRORS                = 1 << 18,
-	RESOURCES_MAY_ALIAS                = 1 << 19,
-	ENABLE_UNBOUNDED_DESCRIPTOR_TABLES = 1 << 20,
-	ALL_RESOURCES_BOUND                = 1 << 21,
-	DEBUG_NAME_FOR_SOURCE              = 1 << 22,
-	DEBUG_NAME_FOR_BINARY              = 1 << 23,
-}
-
-EFFECT :: enum u32 { // TODO: make bit_field
-	CHILD_EFFECT   = 1 << 0,
-	ALLOW_SLOW_OPS = 1 << 1,
-}
-
-FLAGS2 :: enum u32 { // TODO: make bit_field
+D3DCOMPILE :: distinct bit_set[D3DCOMPILE_FLAG; u32]
+D3DCOMPILE_FLAG :: enum u32 {
+	DEBUG                              = 0,
+	SKIP_VALIDATION                    = 1,
+	SKIP_OPTIMIZATION                  = 2,
+	PACK_MATRIX_ROW_MAJOR              = 3,
+	PACK_MATRIX_COLUMN_MAJOR           = 4,
+	PARTIAL_PRECISION                  = 5,
+	FORCE_VS_SOFTWARE_NO_OPT           = 6,
+	FORCE_PS_SOFTWARE_NO_OPT           = 7,
+	NO_PRESHADER                       = 8,
+	AVOID_FLOW_CONTROL                 = 9,
+	PREFER_FLOW_CONTROL                = 10,
+	ENABLE_STRICTNESS                  = 11,
+	ENABLE_BACKWARDS_COMPATIBILITY     = 12,
+	IEEE_STRICTNESS                    = 13,
+	OPTIMIZATION_LEVEL0                = 14,
+	OPTIMIZATION_LEVEL3                = 15,
+	RESERVED16                         = 16,
+	RESERVED17                         = 17,
+	WARNINGS_ARE_ERRORS                = 18,
+	RESOURCES_MAY_ALIAS                = 19,
+	ENABLE_UNBOUNDED_DESCRIPTOR_TABLES = 20,
+	ALL_RESOURCES_BOUND                = 21,
+	DEBUG_NAME_FOR_SOURCE              = 22,
+	DEBUG_NAME_FOR_BINARY              = 23,
+}
+
+D3DCOMPILE_OPTIMIZATION_LEVEL0 :: D3DCOMPILE{.OPTIMIZATION_LEVEL0}
+D3DCOMPILE_OPTIMIZATION_LEVEL1 :: D3DCOMPILE{}
+D3DCOMPILE_OPTIMIZATION_LEVEL2 :: D3DCOMPILE{.IEEE_STRICTNESS, .OPTIMIZATION_LEVEL3}
+D3DCOMPILE_OPTIMIZATION_LEVEL3 :: D3DCOMPILE{.OPTIMIZATION_LEVEL3}
+
+
+EFFECT :: distinct bit_set[EFFECT_FLAG; u32]
+EFFECT_FLAG :: enum u32 {
+	CHILD_EFFECT   = 0,
+	ALLOW_SLOW_OPS = 1,
+}
+
+FLAGS2 :: enum u32 {
 	FORCE_ROOT_SIGNATURE_LATEST = 0,
 	FORCE_ROOT_SIGNATURE_LATEST = 0,
 	FORCE_ROOT_SIGNATURE_1_0    = 1 << 4,
 	FORCE_ROOT_SIGNATURE_1_0    = 1 << 4,
 	FORCE_ROOT_SIGNATURE_1_1    = 1 << 5,
 	FORCE_ROOT_SIGNATURE_1_1    = 1 << 5,
 }
 }
 
 
-SECDATA :: enum u32 { // TODO: make bit_field
-	MERGE_UAV_SLOTS         = 0x00000001,
-	PRESERVE_TEMPLATE_SLOTS = 0x00000002,
-	REQUIRE_TEMPLATE_MATCH  = 0x00000004,
+SECDATA :: distinct bit_set[SECDATA_FLAG; u32]
+SECDATA_FLAG :: enum u32 {
+	MERGE_UAV_SLOTS         = 0,
+	PRESERVE_TEMPLATE_SLOTS = 1,
+	REQUIRE_TEMPLATE_MATCH  = 2,
 }
 }
 
 
 DISASM_ENABLE_COLOR_CODE            :: 0x00000001
 DISASM_ENABLE_COLOR_CODE            :: 0x00000001
@@ -188,13 +195,13 @@ pD3DCompile     :: #type proc "c" (a0: rawptr, a1: SIZE_T, a2: cstring, a3: ^SHA
 pD3DPreprocess  :: #type proc "c" (a0: rawptr, a1: SIZE_T, a2: cstring, a3: ^SHADER_MACRO, a4: ^ID3DInclude, a5: ^^ID3DBlob, a6: ^^ID3DBlob) -> HRESULT
 pD3DPreprocess  :: #type proc "c" (a0: rawptr, a1: SIZE_T, a2: cstring, a3: ^SHADER_MACRO, a4: ^ID3DInclude, a5: ^^ID3DBlob, a6: ^^ID3DBlob) -> HRESULT
 pD3DDisassemble :: #type proc "c" (a0: rawptr, a1: SIZE_T, a2: u32, a3: cstring, a4: ^^ID3DBlob) -> HRESULT
 pD3DDisassemble :: #type proc "c" (a0: rawptr, a1: SIZE_T, a2: u32, a3: cstring, a4: ^^ID3DBlob) -> HRESULT
 
 
-D3DCOMPILER_STRIP_FLAGS :: enum u32 { // TODO: make bit_field
-	REFLECTION_DATA = 0x1,
-	DEBUG_INFO      = 0x2,
-	TEST_BLOBS      = 0x4,
-	PRIVATE_DATA    = 0x8,
-	ROOT_SIGNATURE  = 0x10,
-	FORCE_DWORD     = 0x7fffffff,
+D3DCOMPILER_STRIP_FLAGS :: distinct bit_set[D3DCOMPILER_STRIP_FLAG; u32]
+D3DCOMPILER_STRIP_FLAG :: enum u32 {
+	REFLECTION_DATA = 0,
+	DEBUG_INFO      = 1,
+	TEST_BLOBS      = 2,
+	PRIVATE_DATA    = 3,
+	ROOT_SIGNATURE  = 4,
 }
 }
 
 
 BLOB_PART :: enum i32 {
 BLOB_PART :: enum i32 {

+ 40 - 31
vendor/directx/dxgi/dxgi.odin

@@ -57,14 +57,15 @@ CPU_ACCESS :: enum u32 {
 	FIELD      = 15,
 	FIELD      = 15,
 }
 }
 
 
-USAGE :: enum u32 { // TODO: convert to bit_set
-	SHADER_INPUT         = 0x00000010,
-	RENDER_TARGET_OUTPUT = 0x00000020,
-	BACK_BUFFER          = 0x00000040,
-	SHARED               = 0x00000080,
-	READ_ONLY            = 0x00000100,
-	DISCARD_ON_PRESENT   = 0x00000200,
-	UNORDERED_ACCESS     = 0x00000400,
+USAGE :: distinct bit_set[USAGE_FLAG; u32]
+USAGE_FLAG :: enum u32 {
+	SHADER_INPUT         =  4,
+	RENDER_TARGET_OUTPUT =  5,
+	BACK_BUFFER          =  6,
+	SHARED               =  7,
+	READ_ONLY            =  8,
+	DISCARD_ON_PRESENT   =  9,
+	UNORDERED_ACCESS     = 10,
 }
 }
 
 
 RESOURCE_PRIORITY :: enum u32 {
 RESOURCE_PRIORITY :: enum u32 {
@@ -75,37 +76,45 @@ RESOURCE_PRIORITY :: enum u32 {
 	MAXIMUM = 0xc8000000,
 	MAXIMUM = 0xc8000000,
 }
 }
 
 
-MAP :: enum u32 { // TODO: convert to bit_set
+MAP :: enum u32 {
 	READ    = 1,
 	READ    = 1,
 	WRITE   = 2,
 	WRITE   = 2,
 	DISCARD = 4,
 	DISCARD = 4,
 }
 }
 
 
-ENUM_MODES :: enum u32 { // TODO: convert to bit_set
-	INTERLACED      = 1,
-	SCALING         = 2,
-	STEREO          = 4,
-	DISABLED_STEREO = 8,
+ENUM_MODES :: distinct bit_set[ENUM_MODE; u32]
+ENUM_MODE :: enum u32 {
+	INTERLACED      = 0,
+	SCALING         = 1,
+	STEREO          = 2,
+	DISABLED_STEREO = 3,
 }
 }
 
 
 MAX_SWAP_CHAIN_BUFFERS :: 16
 MAX_SWAP_CHAIN_BUFFERS :: 16
-PRESENT :: enum u32 { // TODO: convert to bit_set
-	TEST                  = 0x00000001,
-	DO_NOT_SEQUENCE       = 0x00000002,
-	RESTART               = 0x00000004,
-	DO_NOT_WAIT           = 0x00000008,
-	STEREO_PREFER_RIGHT   = 0x00000010,
-	STEREO_TEMPORARY_MONO = 0x00000020,
-	RESTRICT_TO_OUTPUT    = 0x00000040,
-	USE_DURATION          = 0x00000100,
-	ALLOW_TEARING         = 0x00000200,
-}
-
-MWA :: enum u32 { // TODO: convert to bit_set
-	NO_WINDOW_CHANGES = 1 << 0,
-	NO_ALT_ENTER      = 1 << 1,
-	NO_PRINT_SCREEN   = 1 << 2,
-	VALID             = 0x7,
+PRESENT :: distinct bit_set[PRESENT_FLAG; u32]
+PRESENT_FLAG :: enum u32 {
+	TEST                  = 0,
+	DO_NOT_SEQUENCE       = 1,
+	RESTART               = 2,
+	DO_NOT_WAIT           = 3,
+	STEREO_PREFER_RIGHT   = 4,
+	STEREO_TEMPORARY_MONO = 5,
+	RESTRICT_TO_OUTPUT    = 6,
+
+	USE_DURATION          = 8,
+	ALLOW_TEARING         = 9,
+}
+
+MWA :: distinct bit_set[MWA_FLAG; u32]
+MWA_FLAG :: enum u32 {
+	NO_WINDOW_CHANGES = 0,
+	NO_ALT_ENTER      = 1,
+	NO_PRINT_SCREEN   = 2,
+}
+MWA_VALID :: MWA{
+	.NO_WINDOW_CHANGES,
+	.NO_ALT_ENTER,
+	.NO_PRINT_SCREEN,
 }
 }
 
 
 SHARED_RESOURCE_READ  :: 0x80000000
 SHARED_RESOURCE_READ  :: 0x80000000

+ 1 - 0
vendor/glfw/bindings/bindings.odin

@@ -110,6 +110,7 @@ foreign glfw {
 	WaitEventsTimeout :: proc(timeout: f64) ---
 	WaitEventsTimeout :: proc(timeout: f64) ---
 	PostEmptyEvent    :: proc() ---
 	PostEmptyEvent    :: proc() ---
 
 
+	RawMouseMotionSupported :: proc() -> b32 ---
 	GetInputMode :: proc(window: WindowHandle, mode: c.int) -> c.int ---
 	GetInputMode :: proc(window: WindowHandle, mode: c.int) -> c.int ---
 	SetInputMode :: proc(window: WindowHandle, mode, value: c.int) ---
 	SetInputMode :: proc(window: WindowHandle, mode, value: c.int) ---
 
 

+ 3 - 0
vendor/glfw/constants.odin

@@ -339,6 +339,9 @@ CURSOR_NORMAL   :: 0x00034001
 CURSOR_HIDDEN   :: 0x00034002
 CURSOR_HIDDEN   :: 0x00034002
 CURSOR_DISABLED :: 0x00034003
 CURSOR_DISABLED :: 0x00034003
 
 
+/* Mouse motion */
+RAW_MOUSE_MOTION :: 0x00033005
+
 /* Behavior? */
 /* Behavior? */
 ANY_RELEASE_BEHAVIOR   :: 0
 ANY_RELEASE_BEHAVIOR   :: 0
 RELEASE_BEHAVIOR_FLUSH :: 0x00035001
 RELEASE_BEHAVIOR_FLUSH :: 0x00035001

+ 0 - 33
vendor/glfw/native.odin

@@ -1,33 +0,0 @@
-package glfw
-
-when ODIN_OS == .Windows {
-	import win32 "core:sys/windows"
-	
-	foreign import glfw { "lib/glfw3_mt.lib", "system:user32.lib", "system:gdi32.lib", "system:shell32.lib" }
-	
-	@(default_calling_convention="c", link_prefix="glfw")
-	foreign glfw {
-		GetWin32Adapter :: proc(monitor: MonitorHandle) -> cstring ---
-		GetWin32Monitor :: proc(monitor: MonitorHandle) -> cstring ---
-		GetWin32Window  :: proc(window: WindowHandle) -> win32.HWND ---
-		GetWGLContext   :: proc(window: WindowHandle) -> rawptr ---
-	}
-} else when ODIN_OS == .Linux {
-	// TODO: Native Linux
-	// Display* glfwGetX11Display(void);
-	// RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
-	// RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
-	// Window glfwGetX11Window(GLFWwindow* window);
-	// void glfwSetX11SelectionString(const char* string);
-	// const char* glfwGetX11SelectionString(void);
-	
-	// struct wl_display* glfwGetWaylandDisplay(void);
-	// struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
-	// struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
-} else when ODIN_OS == .Darwin {
-	// TODO: Native Darwin
-	// CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
-	// id glfwGetCocoaWindow(GLFWwindow* window);
-	// id glfwGetNSGLContext(GLFWwindow* window);
-}
-

+ 16 - 0
vendor/glfw/native_darwin.odin

@@ -0,0 +1,16 @@
+//+build darwin
+
+package glfw
+
+import NS "vendor:darwin/foundation"
+
+foreign import glfw { "lib/darwin/libglfw3.a" }
+
+@(default_calling_convention="c", link_prefix="glfw")
+foreign glfw {
+    GetCocoaWindow :: proc(window: WindowHandle) -> ^NS.Window ---
+}
+
+// TODO:
+// CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
+// id glfwGetNSGLContext(GLFWwindow* window);

+ 15 - 0
vendor/glfw/native_linux.odin

@@ -0,0 +1,15 @@
+//+build linux
+
+package glfw
+
+// TODO: Native Linux
+// Display* glfwGetX11Display(void);
+// RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
+// RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
+// Window glfwGetX11Window(GLFWwindow* window);
+// void glfwSetX11SelectionString(const char* string);
+// const char* glfwGetX11SelectionString(void);
+
+// struct wl_display* glfwGetWaylandDisplay(void);
+// struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
+// struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);

+ 15 - 0
vendor/glfw/native_windows.odin

@@ -0,0 +1,15 @@
+//+build windows
+
+package glfw
+
+import win32 "core:sys/windows"
+
+foreign import glfw { "lib/glfw3_mt.lib", "system:user32.lib", "system:gdi32.lib", "system:shell32.lib" }
+
+@(default_calling_convention="c", link_prefix="glfw")
+foreign glfw {
+    GetWin32Adapter :: proc(monitor: MonitorHandle) -> cstring ---
+    GetWin32Monitor :: proc(monitor: MonitorHandle) -> cstring ---
+    GetWin32Window  :: proc(window: WindowHandle) -> win32.HWND ---
+    GetWGLContext   :: proc(window: WindowHandle) -> rawptr ---
+}

+ 1 - 1
vendor/stb/rect_pack/stb_rect_pack.odin

@@ -6,7 +6,7 @@ import c "core:c/libc"
 
 
 when ODIN_OS == .Windows { foreign import lib "../lib/stb_rect_pack.lib" }
 when ODIN_OS == .Windows { foreign import lib "../lib/stb_rect_pack.lib" }
 when ODIN_OS == .Linux   { foreign import lib "../lib/stb_rect_pack.a"   }
 when ODIN_OS == .Linux   { foreign import lib "../lib/stb_rect_pack.a"   }
-when ODIN_OS == .Darwin  { foreign import lib "../lib/stb_rect_pack.a"   }
+when ODIN_OS == .Darwin  { foreign import lib "../lib/darwin/stb_rect_pack.a"   }
 
 
 Coord :: distinct c.int
 Coord :: distinct c.int
 _MAXVAL :: max(Coord)
 _MAXVAL :: max(Coord)

+ 1 - 1
vendor/stb/truetype/stb_truetype.odin

@@ -5,7 +5,7 @@ import stbrp "vendor:stb/rect_pack"
 
 
 when ODIN_OS == .Windows { foreign import stbtt "../lib/stb_truetype.lib" }
 when ODIN_OS == .Windows { foreign import stbtt "../lib/stb_truetype.lib" }
 when ODIN_OS == .Linux   { foreign import stbtt "../lib/stb_truetype.a"   }
 when ODIN_OS == .Linux   { foreign import stbtt "../lib/stb_truetype.a"   }
-when ODIN_OS == .Darwin  { foreign import stbtt "../lib/stb_truetype.a"   }
+when ODIN_OS == .Darwin  { foreign import stbtt "../lib/darwin/stb_truetype.a"   }
 
 
 
 
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////

+ 1 - 1
vendor/stb/vorbis/stb_vorbis.odin

@@ -5,7 +5,7 @@ import c "core:c/libc"
 
 
 when ODIN_OS == .Windows { foreign import lib "../lib/stb_vorbis.lib" }
 when ODIN_OS == .Windows { foreign import lib "../lib/stb_vorbis.lib" }
 when ODIN_OS == .Linux   { foreign import lib "../lib/stb_vorbis.a"   }
 when ODIN_OS == .Linux   { foreign import lib "../lib/stb_vorbis.a"   }
-when ODIN_OS == .Darwin  { foreign import lib "../lib/stb_vorbis.a"   }
+when ODIN_OS == .Darwin  { foreign import lib "../lib/darwin/stb_vorbis.a"   }
 
 
 
 
 
 

+ 7 - 7
vendor/vulkan/_gen/create_vulkan_odin_wrapper.py

@@ -84,7 +84,7 @@ def convert_type(t, prev_name, curr_name):
         else:
         else:
             ttype = t[:len(t)-1]
             ttype = t[:len(t)-1]
             elem = convert_type(ttype, prev_name, curr_name)
             elem = convert_type(ttype, prev_name, curr_name)
-            
+
         if curr_name.endswith("s") or curr_name.endswith("Table"):
         if curr_name.endswith("s") or curr_name.endswith("Table"):
             if prev_name.endswith("Count") or prev_name.endswith("Counts"):
             if prev_name.endswith("Count") or prev_name.endswith("Counts"):
                 pointer = "[^]"
                 pointer = "[^]"
@@ -95,10 +95,10 @@ def convert_type(t, prev_name, curr_name):
                     pointer = "[^]"
                     pointer = "[^]"
             elif curr_name.startswith("p"):
             elif curr_name.startswith("p"):
                 pointer = "[^]"
                 pointer = "[^]"
-                
+
         if curr_name and elem.endswith("Flags"):
         if curr_name and elem.endswith("Flags"):
             pointer = "[^]"
             pointer = "[^]"
-                    
+
         return "{}{}".format(pointer, elem)
         return "{}{}".format(pointer, elem)
     elif t[0].isupper():
     elif t[0].isupper():
         return t
         return t
@@ -276,7 +276,7 @@ def parse_enums(f):
     f.write("// Enums\n")
     f.write("// Enums\n")
 
 
     data = re.findall(r"typedef enum Vk(\w+) {(.+?)} \w+;", src, re.S)
     data = re.findall(r"typedef enum Vk(\w+) {(.+?)} \w+;", src, re.S)
-    
+
     data.sort(key=lambda x: x[0])
     data.sort(key=lambda x: x[0])
 
 
     generated_flags = set()
     generated_flags = set()
@@ -458,14 +458,14 @@ def parse_procedures(f):
 
 
     for rt, name, fields in data:
     for rt, name, fields in data:
         proc_name = no_vk(name)
         proc_name = no_vk(name)
-        
+
         pf = []
         pf = []
         prev_name = ""
         prev_name = ""
         for type_, fname in re.findall(r"(?:\s*|)(.+?)\s*(\w+)(?:,|$)", fields):
         for type_, fname in re.findall(r"(?:\s*|)(.+?)\s*(\w+)(?:,|$)", fields):
             curr_name = fix_arg(fname)
             curr_name = fix_arg(fname)
             pf.append((do_type(type_, prev_name, curr_name), curr_name))
             pf.append((do_type(type_, prev_name, curr_name), curr_name))
             prev_name = curr_name
             prev_name = curr_name
-            
+
         data_fields = ', '.join(["{}: {}".format(n, t) for t, n in pf if t != ""])
         data_fields = ', '.join(["{}: {}".format(n, t) for t, n in pf if t != ""])
 
 
         ts = "proc \"c\" ({})".format(data_fields)
         ts = "proc \"c\" ({})".format(data_fields)
@@ -510,7 +510,7 @@ def group_functions(f):
 
 
         if table_name in ('Device', 'Queue', 'CommandBuffer') and name != 'GetDeviceProcAddr':
         if table_name in ('Device', 'Queue', 'CommandBuffer') and name != 'GetDeviceProcAddr':
             group_map["Device"].append(nn)
             group_map["Device"].append(nn)
-        elif table_name in ('Instance', 'PhysicalDevice') or name == 'GetDeviceProcAddr':
+        elif table_name in ('Instance', 'PhysicalDevice') and name != 'ProcGetInstanceProcAddr' or name == 'GetDeviceProcAddr':
             group_map["Instance"].append(nn)
             group_map["Instance"].append(nn)
         elif table_name in ('rawptr', '', 'DebugReportFlagsEXT') or name == 'GetInstanceProcAddr':
         elif table_name in ('rawptr', '', 'DebugReportFlagsEXT') or name == 'GetInstanceProcAddr':
             # Skip the allocation function and the dll entry point
             # Skip the allocation function and the dll entry point

+ 3 - 3
vendor/vulkan/procedures.odin

@@ -533,6 +533,7 @@ DeviceMemoryReportCallbackEXT:        ProcDeviceMemoryReportCallbackEXT
 EnumerateInstanceExtensionProperties: ProcEnumerateInstanceExtensionProperties
 EnumerateInstanceExtensionProperties: ProcEnumerateInstanceExtensionProperties
 EnumerateInstanceLayerProperties:     ProcEnumerateInstanceLayerProperties
 EnumerateInstanceLayerProperties:     ProcEnumerateInstanceLayerProperties
 EnumerateInstanceVersion:             ProcEnumerateInstanceVersion
 EnumerateInstanceVersion:             ProcEnumerateInstanceVersion
+GetInstanceProcAddr:                  ProcGetInstanceProcAddr
 
 
 // Instance Procedures
 // Instance Procedures
 AcquireDrmDisplayEXT:                                            ProcAcquireDrmDisplayEXT
 AcquireDrmDisplayEXT:                                            ProcAcquireDrmDisplayEXT
@@ -564,7 +565,6 @@ GetDisplayPlaneCapabilities2KHR:                                 ProcGetDisplayP
 GetDisplayPlaneCapabilitiesKHR:                                  ProcGetDisplayPlaneCapabilitiesKHR
 GetDisplayPlaneCapabilitiesKHR:                                  ProcGetDisplayPlaneCapabilitiesKHR
 GetDisplayPlaneSupportedDisplaysKHR:                             ProcGetDisplayPlaneSupportedDisplaysKHR
 GetDisplayPlaneSupportedDisplaysKHR:                             ProcGetDisplayPlaneSupportedDisplaysKHR
 GetDrmDisplayEXT:                                                ProcGetDrmDisplayEXT
 GetDrmDisplayEXT:                                                ProcGetDrmDisplayEXT
-GetInstanceProcAddr:                                             ProcGetInstanceProcAddr
 GetPhysicalDeviceCalibrateableTimeDomainsEXT:                    ProcGetPhysicalDeviceCalibrateableTimeDomainsEXT
 GetPhysicalDeviceCalibrateableTimeDomainsEXT:                    ProcGetPhysicalDeviceCalibrateableTimeDomainsEXT
 GetPhysicalDeviceCooperativeMatrixPropertiesNV:                  ProcGetPhysicalDeviceCooperativeMatrixPropertiesNV
 GetPhysicalDeviceCooperativeMatrixPropertiesNV:                  ProcGetPhysicalDeviceCooperativeMatrixPropertiesNV
 GetPhysicalDeviceDisplayPlaneProperties2KHR:                     ProcGetPhysicalDeviceDisplayPlaneProperties2KHR
 GetPhysicalDeviceDisplayPlaneProperties2KHR:                     ProcGetPhysicalDeviceDisplayPlaneProperties2KHR
@@ -1045,6 +1045,7 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) {
 	set_proc_address(&EnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties")
 	set_proc_address(&EnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties")
 	set_proc_address(&EnumerateInstanceLayerProperties,     "vkEnumerateInstanceLayerProperties")
 	set_proc_address(&EnumerateInstanceLayerProperties,     "vkEnumerateInstanceLayerProperties")
 	set_proc_address(&EnumerateInstanceVersion,             "vkEnumerateInstanceVersion")
 	set_proc_address(&EnumerateInstanceVersion,             "vkEnumerateInstanceVersion")
+	set_proc_address(&GetInstanceProcAddr,                  "vkGetInstanceProcAddr")
 
 
 	// Instance Procedures
 	// Instance Procedures
 	set_proc_address(&AcquireDrmDisplayEXT,                                            "vkAcquireDrmDisplayEXT")
 	set_proc_address(&AcquireDrmDisplayEXT,                                            "vkAcquireDrmDisplayEXT")
@@ -1076,7 +1077,6 @@ load_proc_addresses_custom :: proc(set_proc_address: SetProcAddressType) {
 	set_proc_address(&GetDisplayPlaneCapabilitiesKHR,                                  "vkGetDisplayPlaneCapabilitiesKHR")
 	set_proc_address(&GetDisplayPlaneCapabilitiesKHR,                                  "vkGetDisplayPlaneCapabilitiesKHR")
 	set_proc_address(&GetDisplayPlaneSupportedDisplaysKHR,                             "vkGetDisplayPlaneSupportedDisplaysKHR")
 	set_proc_address(&GetDisplayPlaneSupportedDisplaysKHR,                             "vkGetDisplayPlaneSupportedDisplaysKHR")
 	set_proc_address(&GetDrmDisplayEXT,                                                "vkGetDrmDisplayEXT")
 	set_proc_address(&GetDrmDisplayEXT,                                                "vkGetDrmDisplayEXT")
-	set_proc_address(&GetInstanceProcAddr,                                             "vkGetInstanceProcAddr")
 	set_proc_address(&GetPhysicalDeviceCalibrateableTimeDomainsEXT,                    "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT")
 	set_proc_address(&GetPhysicalDeviceCalibrateableTimeDomainsEXT,                    "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT")
 	set_proc_address(&GetPhysicalDeviceCooperativeMatrixPropertiesNV,                  "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV")
 	set_proc_address(&GetPhysicalDeviceCooperativeMatrixPropertiesNV,                  "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV")
 	set_proc_address(&GetPhysicalDeviceDisplayPlaneProperties2KHR,                     "vkGetPhysicalDeviceDisplayPlaneProperties2KHR")
 	set_proc_address(&GetPhysicalDeviceDisplayPlaneProperties2KHR,                     "vkGetPhysicalDeviceDisplayPlaneProperties2KHR")
@@ -2839,7 +2839,6 @@ load_proc_addresses_instance :: proc(instance: Instance) {
 	GetDisplayPlaneCapabilitiesKHR                                  = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")
 	GetDisplayPlaneCapabilitiesKHR                                  = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayPlaneCapabilitiesKHR")
 	GetDisplayPlaneSupportedDisplaysKHR                             = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayPlaneSupportedDisplaysKHR")
 	GetDisplayPlaneSupportedDisplaysKHR                             = auto_cast GetInstanceProcAddr(instance, "vkGetDisplayPlaneSupportedDisplaysKHR")
 	GetDrmDisplayEXT                                                = auto_cast GetInstanceProcAddr(instance, "vkGetDrmDisplayEXT")
 	GetDrmDisplayEXT                                                = auto_cast GetInstanceProcAddr(instance, "vkGetDrmDisplayEXT")
-	GetInstanceProcAddr                                             = auto_cast GetInstanceProcAddr(instance, "vkGetInstanceProcAddr")
 	GetPhysicalDeviceCalibrateableTimeDomainsEXT                    = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT")
 	GetPhysicalDeviceCalibrateableTimeDomainsEXT                    = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT")
 	GetPhysicalDeviceCooperativeMatrixPropertiesNV                  = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV")
 	GetPhysicalDeviceCooperativeMatrixPropertiesNV                  = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV")
 	GetPhysicalDeviceDisplayPlaneProperties2KHR                     = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR")
 	GetPhysicalDeviceDisplayPlaneProperties2KHR                     = auto_cast GetInstanceProcAddr(instance, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR")
@@ -3322,6 +3321,7 @@ load_proc_addresses_global :: proc(vk_get_instance_proc_addr: rawptr) {
 	EnumerateInstanceExtensionProperties = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceExtensionProperties")
 	EnumerateInstanceExtensionProperties = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceExtensionProperties")
 	EnumerateInstanceLayerProperties     = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceLayerProperties")
 	EnumerateInstanceLayerProperties     = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceLayerProperties")
 	EnumerateInstanceVersion             = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceVersion")
 	EnumerateInstanceVersion             = auto_cast GetInstanceProcAddr(nil, "vkEnumerateInstanceVersion")
+	GetInstanceProcAddr                  = auto_cast GetInstanceProcAddr(nil, "vkGetInstanceProcAddr")
 }
 }
 
 
 load_proc_addresses :: proc{
 load_proc_addresses :: proc{