diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e40372af3..801bffd87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -204,7 +204,7 @@ jobs: run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat cd tests\documentation - rem call build.bat + call build.bat timeout-minutes: 10 - name: core:math/big tests shell: cmd diff --git a/base/runtime/core.odin b/base/runtime/core.odin index c62301c34..66099e787 100644 --- a/base/runtime/core.odin +++ b/base/runtime/core.odin @@ -273,14 +273,14 @@ Typeid_Kind :: enum u8 { } #assert(len(Typeid_Kind) < 32) -// Typeid_Bit_Field :: bit_field #align(align_of(uintptr)) { -// index: 8*size_of(uintptr) - 8, -// kind: 5, // Typeid_Kind -// named: 1, -// special: 1, // signed, cstring, etc -// reserved: 1, -// } -// #assert(size_of(Typeid_Bit_Field) == size_of(uintptr)); +Typeid_Bit_Field :: bit_field uintptr { + index: uintptr | 8*size_of(uintptr) - 8, + kind: Typeid_Kind | 5, // Typeid_Kind + named: bool | 1, + special: bool | 1, // signed, cstring, etc + reserved: bool | 1, +} +#assert(size_of(Typeid_Bit_Field) == size_of(uintptr)) // NOTE(bill): only the ones that are needed (not all types) // This will be set by the compiler diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index f45cdb1f1..83c0f8f79 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -469,12 +469,15 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case: panic("Invalid union tag type") } - if v.data == nil || tag == 0 { - io.write_string(w, "null") or_return - } else { - id := info.variants[tag-1].id - return marshal_to_writer(w, any{v.data, id}, opt) + if !info.no_nil { + if tag == 0 { + io.write_string(w, "null") or_return + return nil + } + tag -= 1 } + id := info.variants[tag].id + return marshal_to_writer(w, any{v.data, id}, opt) case runtime.Type_Info_Enum: if !opt.use_enum_names || len(info.names) == 0 { diff --git a/core/fmt/doc.odin b/core/fmt/doc.odin index 597342e76..be666dcc4 100644 --- a/core/fmt/doc.odin +++ b/core/fmt/doc.odin @@ -1,5 +1,5 @@ /* -package fmt implemented formatted I/O with procedures similar to C's printf and Python's format. +package fmt implements formatted I/O with procedures similar to C's printf and Python's format. The format 'verbs' are derived from C's but simpler. Printing @@ -33,6 +33,8 @@ Floating-point, complex numbers, and quaternions: %E scientific notation, e.g. -1.23456E+78 %f decimal point but no exponent, e.g. 123.456 %F synonym for %f + %g synonym for %f with default maximum precision + %G synonym for %g %h hexadecimal (lower-case) representation with 0h prefix (0h01234abcd) %H hexadecimal (upper-case) representation with 0H prefix (0h01234ABCD) %m number of bytes in the best unit of measurement, e.g. 123.45mib @@ -61,9 +63,9 @@ For compound values, the elements are printed using these rules recursively; lai bit sets {key0 = elem0, key1 = elem1, ...} pointer to above: &{}, &[], &map[] -Width is specified by an optional decimal number immediately preceding the verb. +Width is specified by an optional decimal number immediately after the '%'. If not present, the width is whatever is necessary to represent the value. -Precision is specified after the (optional) width followed by a period followed by a decimal number. +Precision is specified after the (optional) width by a period followed by a decimal number. If no period is present, a default precision is used. A period with no following number specifies a precision of 0. @@ -75,7 +77,7 @@ Examples: %8.f width 8, precision 0 Width and precision are measured in units of Unicode code points (runes). -n.b. C's printf uses units of bytes +n.b. C's printf uses units of bytes. Other flags: @@ -92,7 +94,7 @@ Other flags: 0 pad with leading zeros rather than spaces -Flags are ignored by verbs that don't expect them +Flags are ignored by verbs that don't expect them. For each printf-like procedure, there is a print function that takes no @@ -105,19 +107,20 @@ Explicit argument indices: In printf-like procedures, the default behaviour is for each formatting verb to format successive arguments passed in the call. However, the notation [n] immediately before the verb indicates that the nth zero-index argument is to be formatted instead. -The same notation before an '*' for a width or precision selecting the argument index holding the value. -Python-like syntax with argument indices differs for the selecting the argument index: {N:v} +The same notation before an '*' for a width or precision specifier selects the argument index +holding the value. +Python-like syntax with argument indices differs for selecting the argument index: {n:v} Examples: - fmt.printf("%[1]d %[0]d\n", 13, 37); // C-like syntax - fmt.printf("{1:d} {0:d}\n", 13, 37); // Python-like syntax + fmt.printfln("%[1]d %[0]d", 13, 37) // C-like syntax + fmt.printfln("{1:d} {0:d}", 13, 37) // Python-like syntax prints "37 13", whilst: - fmt.printf("%[2]*.[1]*[0]f\n", 17.0, 2, 6); // C-like syntax - fmt.printf("%{0:[2]*.[1]*f}\n", 17.0, 2, 6); // Python-like syntax -equivalent to: - fmt.printf("%6.2f\n", 17.0, 2, 6); // C-like syntax - fmt.printf("{:6.2f}\n", 17.0, 2, 6); // Python-like syntax -prints "17.00" + fmt.printfln("%*[2].*[1][0]f", 17.0, 2, 6) // C-like syntax + fmt.printfln("{0:*[2].*[1]f}", 17.0, 2, 6) // Python-like syntax +is equivalent to: + fmt.printfln("%6.2f", 17.0) // C-like syntax + fmt.printfln("{:6.2f}", 17.0) // Python-like syntax +and prints "17.00". Format errors: diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 867257491..772d3dd9c 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -25,8 +25,6 @@ Info :: struct { prec: int, indent: int, - reordered: bool, - good_arg_index: bool, ignore_user_formatters: bool, in_bad: bool, @@ -527,13 +525,107 @@ wprintln :: proc(w: io.Writer, args: ..any, sep := " ", flush := true) -> int { // Returns: The number of bytes written // wprintf :: proc(w: io.Writer, fmt: string, args: ..any, flush := true, newline := false) -> int { + MAX_CHECKED_ARGS :: 64 + assert(len(args) <= MAX_CHECKED_ARGS, "number of args > 64 is unsupported") + + parse_options :: proc(fi: ^Info, fmt: string, index, end: int, unused_args: ^bit_set[0 ..< MAX_CHECKED_ARGS], args: ..any) -> int { + i := index + + // Prefix + prefix_loop: for ; i < end; i += 1 { + switch fmt[i] { + case '+': + fi.plus = true + case '-': + fi.minus = true + fi.zero = false + case ' ': + fi.space = true + case '#': + fi.hash = true + case '0': + fi.zero = !fi.minus + case: + break prefix_loop + } + } + + // Width + if i < end && fmt[i] == '*' { + i += 1 + width_index, _, index_ok := _arg_number(fmt, &i, len(args)) + + if index_ok { + unused_args^ -= {width_index} + + fi.width, _, fi.width_set = int_from_arg(args, width_index) + if !fi.width_set { + io.write_string(fi.writer, "%!(BAD WIDTH)", &fi.n) + } + + if fi.width < 0 { + fi.width = -fi.width + fi.minus = true + fi.zero = false + } + } + } else { + fi.width, i, fi.width_set = _parse_int(fmt, i) + } + + // Precision + if i < end && fmt[i] == '.' { + i += 1 + if i < end && fmt[i] == '*' { + i += 1 + precision_index, _, index_ok := _arg_number(fmt, &i, len(args)) + + if index_ok { + unused_args^ -= {precision_index} + fi.prec, _, fi.prec_set = int_from_arg(args, precision_index) + if fi.prec < 0 { + fi.prec = 0 + fi.prec_set = false + } + if !fi.prec_set { + io.write_string(fi.writer, "%!(BAD PRECISION)", &fi.n) + } + } + } else { + prev_i := i + fi.prec, i, fi.prec_set = _parse_int(fmt, i) + if i == prev_i { + fi.prec = 0 + fi.prec_set = true + } + } + } + + return i + } + + error_check_arg :: proc(fi: ^Info, arg_parsed: bool, unused_args: bit_set[0 ..< MAX_CHECKED_ARGS]) -> (int, bool) { + if !arg_parsed { + for index in unused_args { + return index, true + } + io.write_string(fi.writer, "%!(MISSING ARGUMENT)", &fi.n) + } else { + io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER)", &fi.n) + } + + return 0, false + } + fi: Info - arg_index: int = 0 end := len(fmt) - was_prev_index := false + unused_args: bit_set[0 ..< MAX_CHECKED_ARGS] + for i in 0 ..< len(args) { + unused_args += {i} + } loop: for i := 0; i < end; /**/ { - fi = Info{writer = w, good_arg_index = true, reordered = fi.reordered, n = fi.n} + fi = Info{writer = w, n = fi.n} prev_i := i for i < end && !(fmt[i] == '%' || fmt[i] == '{' || fmt[i] == '}') { @@ -567,191 +659,65 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any, flush := true, newline : } if char == '%' { - prefix_loop: for ; i < end; i += 1 { - switch fmt[i] { - case '+': - fi.plus = true - case '-': - fi.minus = true - fi.zero = false - case ' ': - fi.space = true - case '#': - fi.hash = true - case '0': - fi.zero = !fi.minus - case: - break prefix_loop - } - } - - arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args)) - - // Width - if i < end && fmt[i] == '*' { + if i < end && fmt[i] == '%' { + io.write_byte(fi.writer, '%', &fi.n) i += 1 - fi.width, arg_index, fi.width_set = int_from_arg(args, arg_index) - if !fi.width_set { - io.write_string(w, "%!(BAD WIDTH)", &fi.n) - } - - if fi.width < 0 { - fi.width = -fi.width - fi.minus = true - fi.zero = false - } - was_prev_index = false - } else { - fi.width, i, fi.width_set = _parse_int(fmt, i) - if was_prev_index && fi.width_set { // %[6]2d - fi.good_arg_index = false - } + continue loop } - // Precision - if i < end && fmt[i] == '.' { - i += 1 - if was_prev_index { // %[6].2d - fi.good_arg_index = false - } - if i < end && fmt[i] == '*' { - arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args)) - i += 1 - fi.prec, arg_index, fi.prec_set = int_from_arg(args, arg_index) - if fi.prec < 0 { - fi.prec = 0 - fi.prec_set = false - } - if !fi.prec_set { - io.write_string(fi.writer, "%!(BAD PRECISION)", &fi.n) - } - was_prev_index = false - } else { - fi.prec, i, fi.prec_set = _parse_int(fmt, i) - } - } + i = parse_options(&fi, fmt, i, end, &unused_args, ..args) - if !was_prev_index { - arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args)) + arg_index, arg_parsed, index_ok := _arg_number(fmt, &i, len(args)) + + if !index_ok { + arg_index, index_ok = error_check_arg(&fi, arg_parsed, unused_args) } if i >= end { io.write_string(fi.writer, "%!(NO VERB)", &fi.n) break loop + } else if fmt[i] == ' ' { + io.write_string(fi.writer, "%!(NO VERB)", &fi.n) + continue loop } verb, w := utf8.decode_rune_in_string(fmt[i:]) i += w - switch { - case verb == '%': - io.write_byte(fi.writer, '%', &fi.n) - case !fi.good_arg_index: - io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER)", &fi.n) - case arg_index >= len(args): - io.write_string(fi.writer, "%!(MISSING ARGUMENT)", &fi.n) - case: + if index_ok { + unused_args -= {arg_index} fmt_arg(&fi, args[arg_index], verb) - arg_index += 1 } } else if char == '{' { + arg_index: int + arg_parsed, index_ok: bool + if i < end && fmt[i] != '}' && fmt[i] != ':' { - new_arg_index, new_i, ok := _parse_int(fmt, i) - if ok { - fi.reordered = true - was_prev_index = true - arg_index = new_arg_index - i = new_i - } else { - io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER ", &fi.n) - // Skip over the bad argument - start_index := i - for i < end && fmt[i] != '}' && fmt[i] != ':' { - i += 1 - } - fmt_arg(&fi, fmt[start_index:i], 'v') - io.write_string(fi.writer, ")", &fi.n) + arg_index, i, arg_parsed = _parse_int(fmt, i) + if arg_parsed { + index_ok = 0 <= arg_index && arg_index < len(args) } } + if !index_ok { + arg_index, index_ok = error_check_arg(&fi, arg_parsed, unused_args) + } + verb: rune = 'v' if i < end && fmt[i] == ':' { i += 1 - prefix_loop_percent: for ; i < end; i += 1 { - switch fmt[i] { - case '+': - fi.plus = true - case '-': - fi.minus = true - fi.zero = false - case ' ': - fi.space = true - case '#': - fi.hash = true - case '0': - fi.zero = !fi.minus - case: - break prefix_loop_percent - } - } - - arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args)) - - // Width - if i < end && fmt[i] == '*' { - i += 1 - fi.width, arg_index, fi.width_set = int_from_arg(args, arg_index) - if !fi.width_set { - io.write_string(fi.writer, "%!(BAD WIDTH)", &fi.n) - } - - if fi.width < 0 { - fi.width = -fi.width - fi.minus = true - fi.zero = false - } - was_prev_index = false - } else { - fi.width, i, fi.width_set = _parse_int(fmt, i) - if was_prev_index && fi.width_set { // %[6]2d - fi.good_arg_index = false - } - } - - // Precision - if i < end && fmt[i] == '.' { - i += 1 - if was_prev_index { // %[6].2d - fi.good_arg_index = false - } - if i < end && fmt[i] == '*' { - arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args)) - i += 1 - fi.prec, arg_index, fi.prec_set = int_from_arg(args, arg_index) - if fi.prec < 0 { - fi.prec = 0 - fi.prec_set = false - } - if !fi.prec_set { - io.write_string(fi.writer, "%!(BAD PRECISION)", &fi.n) - } - was_prev_index = false - } else { - fi.prec, i, fi.prec_set = _parse_int(fmt, i) - } - } - - if !was_prev_index { - arg_index, i, was_prev_index = _arg_number(&fi, arg_index, fmt, i, len(args)) - } - + i = parse_options(&fi, fmt, i, end, &unused_args, ..args) if i >= end { io.write_string(fi.writer, "%!(NO VERB)", &fi.n) break loop + } else if fmt[i] == '}' { + i += 1 + io.write_string(fi.writer, "%!(NO VERB)", &fi.n) + continue } w: int = 1 @@ -770,31 +736,35 @@ wprintf :: proc(w: io.Writer, fmt: string, args: ..any, flush := true, newline : switch { case brace != '}': io.write_string(fi.writer, "%!(MISSING CLOSE BRACE)", &fi.n) - case !fi.good_arg_index: - io.write_string(fi.writer, "%!(BAD ARGUMENT NUMBER)", &fi.n) - case arg_index >= len(args): - io.write_string(fi.writer, "%!(MISSING ARGUMENT)", &fi.n) - case: + case index_ok: fmt_arg(&fi, args[arg_index], verb) - arg_index += 1 + unused_args -= {arg_index} } } } - if !fi.reordered && arg_index < len(args) { - io.write_string(fi.writer, "%!(EXTRA ", &fi.n) - for arg, index in args[arg_index:] { - if index > 0 { - io.write_string(fi.writer, ", ", &fi.n) + if unused_args != {} { + // Use default options when formatting extra arguments. + extra_fi := Info { writer = fi.writer, n = fi.n } + + io.write_string(extra_fi.writer, "%!(EXTRA ", &extra_fi.n) + first_printed := false + for index in unused_args { + if first_printed { + io.write_string(extra_fi.writer, ", ", &extra_fi.n) } + arg := args[index] if arg == nil { - io.write_string(fi.writer, "", &fi.n) + io.write_string(extra_fi.writer, "", &extra_fi.n) } else { - fmt_arg(&fi, args[index], 'v') + fmt_arg(&extra_fi, arg, 'v') } + first_printed = true } - io.write_string(fi.writer, ")", &fi.n) + io.write_byte(extra_fi.writer, ')', &extra_fi.n) + + fi.n = extra_fi.n } if newline { @@ -877,18 +847,16 @@ _parse_int :: proc(s: string, offset: int) -> (result: int, new_offset: int, ok: // Parses an argument number from a format string and determines if it's valid // // Inputs: -// - fi: A pointer to an Info structure -// - arg_index: The current argument index // - format: The format string to parse -// - offset: The current position in the format string +// - offset: A pointer to the current position in the format string // - arg_count: The total number of arguments // // Returns: // - index: The parsed argument index -// - new_offset: The new position in the format string -// - ok: A boolean indicating if the parsed argument number is valid +// - parsed: A boolean indicating if an argument number was parsed +// - ok: A boolean indicating if the parsed argument number is within arg_count // -_arg_number :: proc(fi: ^Info, arg_index: int, format: string, offset, arg_count: int) -> (index, new_offset: int, ok: bool) { +_arg_number :: proc(format: string, offset: ^int, arg_count: int) -> (index: int, parsed, ok: bool) { parse_arg_number :: proc(format: string) -> (int, int, bool) { if len(format) < 3 { return 0, 1, false @@ -896,30 +864,28 @@ _arg_number :: proc(fi: ^Info, arg_index: int, format: string, offset, arg_count for i in 1.. (pkg: ^ast.Package, success: bool) { NO_POS :: tokenizer.Pos{} @@ -32,11 +33,18 @@ collect_package :: proc(path: string) -> (pkg: ^ast.Package, success: bool) { if !ok { return } + src, ok = os.read_entire_file(fullpath) if !ok { delete(fullpath) return } + if strings.trim_space(string(src)) == "" { + delete(fullpath) + delete(src) + continue + } + file := ast.new(ast.File, NO_POS, NO_POS) file.pkg = pkg file.src = string(src) @@ -69,7 +77,9 @@ parse_package :: proc(pkg: ^ast.Package, p: ^Parser = nil) -> bool { if !parse_file(p, file) { ok = false } - if pkg.name == "" { + if file.pkg_decl == nil { + error(p, p.curr_tok.pos, "Expected a package declaration at the start of the file") + } else if pkg.name == "" { pkg.name = file.pkg_decl.name } else if pkg.name != file.pkg_decl.name { error(p, file.pkg_decl.pos, "different package name, expected '%s', got '%s'", pkg.name, file.pkg_decl.name) diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index b2ffd3888..e32fbdced 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -2117,7 +2117,9 @@ parse_proc_type :: proc(p: ^Parser, tok: tokenizer.Token) -> ^ast.Proc_Type { } expect_token(p, .Open_Paren) + p.expr_level += 1 params, _ := parse_field_list(p, .Close_Paren, ast.Field_Flags_Signature_Params) + p.expr_level -= 1 expect_closing_parentheses_of_field_list(p) results, diverging := parse_results(p) diff --git a/core/strconv/generic_float.odin b/core/strconv/generic_float.odin index 4ad42a647..6dc11c0be 100644 --- a/core/strconv/generic_float.odin +++ b/core/strconv/generic_float.odin @@ -104,8 +104,7 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, precision, bit_size: int) } else { switch fmt { case 'e', 'E': - prec += 1 - decimal.round(d, prec) + decimal.round(d, prec + 1) case 'f', 'F': decimal.round(d, d.decimal_point+prec) case 'g', 'G': diff --git a/core/strconv/strconv.odin b/core/strconv/strconv.odin index c2e81ef3e..94842617e 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -727,10 +727,10 @@ Example: import "core:strconv" parse_f32_example :: proc() { n, ok := strconv.parse_f32("1234eee") - fmt.println(n, ok) + fmt.printfln("%.3f %v", n, ok) n, ok = strconv.parse_f32("5678e2") - fmt.println(n, ok) + fmt.printfln("%.3f %v", n, ok) } Output: @@ -760,10 +760,10 @@ Example: import "core:strconv" parse_f64_example :: proc() { n, ok := strconv.parse_f64("1234eee") - fmt.println(n, ok) + fmt.printfln("%.3f %v", n, ok) n, ok = strconv.parse_f64("5678e2") - fmt.println(n, ok) + fmt.printfln("%.3f %v", n, ok) } Output: @@ -796,10 +796,10 @@ Example: import "core:strconv" parse_f32_prefix_example :: proc() { n, _, ok := strconv.parse_f32_prefix("1234eee") - fmt.println(n, ok) + fmt.printfln("%.3f %v", n, ok) n, _, ok = strconv.parse_f32_prefix("5678e2") - fmt.println(n, ok) + fmt.printfln("%.3f %v", n, ok) } Output: @@ -831,10 +831,10 @@ Example: import "core:strconv" parse_f64_prefix_example :: proc() { n, _, ok := strconv.parse_f64_prefix("12.34eee") - fmt.println(n, ok) + fmt.printfln("%.3f %v", n, ok) n, _, ok = strconv.parse_f64_prefix("12.34e2") - fmt.println(n, ok) + fmt.printfln("%.3f %v", n, ok) } Output: @@ -1283,7 +1283,7 @@ Example: import "core:fmt" import "core:strconv" atof_example :: proc() { - fmt.println(strconv.atof("3.14")) + fmt.printfln("%.3f", strconv.atof("3.14")) } Output: diff --git a/core/sys/windows/hidpi.odin b/core/sys/windows/hidpi.odin index f862971f4..bea03694e 100644 --- a/core/sys/windows/hidpi.odin +++ b/core/sys/windows/hidpi.odin @@ -2,8 +2,20 @@ package sys_windows import "core:c" -USAGE :: distinct USHORT -PUSAGE :: ^USAGE +HIDD_CONFIGURATION :: struct { + cookie: PVOID, + size: ULONG, + RingBufferSize: ULONG, +} +PHIDD_CONFIGURATION :: ^HIDD_CONFIGURATION + +HIDD_ATTRIBUTES :: struct { + Size: ULONG, + VendorID: USHORT, + ProductID: USHORT, + VersionNumber: USHORT, +} +PHIDD_ATTRIBUTES :: ^HIDD_ATTRIBUTES HIDP_CAPS :: struct { Usage: USAGE, @@ -113,7 +125,32 @@ HIDP_VALUE_CAPS :: struct { } PHIDP_VALUE_CAPS :: ^HIDP_VALUE_CAPS -PHIDP_PREPARSED_DATA :: rawptr +HIDP_DATA :: struct { + DataIndex: USHORT, + Reserved: USHORT, + using _ : struct #raw_union { + RawValue: ULONG, + On: BOOLEAN, + }, +} +PHIDP_DATA :: ^HIDP_DATA + +HIDP_LINK_COLLECTION_NODE :: struct { + LinkUsage: USAGE, + LinkUsagePage: USAGE, + Parent: USHORT, + NumberOfChildren: USHORT, + NextSibling: USHORT, + FirstChild: USHORT, + CollectionType: [8]ULONG, + IsAlias: [1]ULONG, + Reserved: [23]ULONG, + UserContext: PVOID, +} +PHIDP_LINK_COLLECTION_NODE :: ^HIDP_LINK_COLLECTION_NODE + +HIDP_PREPARSED_DATA :: rawptr +PHIDP_PREPARSED_DATA :: ^HIDP_PREPARSED_DATA HIDP_REPORT_TYPE :: enum c.int { Input, @@ -122,6 +159,26 @@ HIDP_REPORT_TYPE :: enum c.int { } HIDP_STATUS_SUCCESS : NTSTATUS : 0x110000 +HIDP_STATUS_NULL : NTSTATUS : -2146369535 //0x80110001 +HIDP_STATUS_INVALID_PREPARSED_DATA : NTSTATUS : -1072627711 //0xC0110001 +HIDP_STATUS_INVALID_REPORT_TYPE : NTSTATUS : -1072627710 //0xC0110002 +HIDP_STATUS_INVALID_REPORT_LENGTH : NTSTATUS : -1072627709 //0xC0110003 +HIDP_STATUS_USAGE_NOT_FOUND : NTSTATUS : -1072627708 //0xC0110004 +HIDP_STATUS_VALUE_OUT_OF_RANGE : NTSTATUS : -1072627707 //0xC0110005 +HIDP_STATUS_BAD_LOG_PHY_VALUES : NTSTATUS : -1072627706 //0xC0100006 +HIDP_STATUS_BUFFER_TOO_SMALL : NTSTATUS : -1072627705 //0xC0110007 +HIDP_STATUS_INTERNAL_ERROR : NTSTATUS : -1072627704 //0xC0110008 +HIDP_STATUS_I8042_TRANS_UNKNOWN : NTSTATUS : -1072627703 //0xC0110009 +HIDP_STATUS_INCOMPATIBLE_REPORT_ID : NTSTATUS : -1072627702 //0xC011000A +HIDP_STATUS_NOT_VALUE_ARRAY : NTSTATUS : -1072627701 //0xC011000B +HIDP_STATUS_IS_VALUE_ARRAY : NTSTATUS : -1072627700 //0xC011000C +HIDP_STATUS_DATA_INDEX_NOT_FOUND : NTSTATUS : -1072627699 //0xC011000D +HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE : NTSTATUS : -1072627698 //0xC011000E +HIDP_STATUS_BUTTON_NOT_PRESSED : NTSTATUS : -1072627697 //0xC011000F +HIDP_STATUS_REPORT_DOES_NOT_EXIST : NTSTATUS : -1072627696 //0xC0110010 +HIDP_STATUS_NOT_IMPLEMENTED : NTSTATUS : -1072627680 //0xC0110020 +HIDP_STATUS_NOT_BUTTON_ARRAY : NTSTATUS : -1072627679 //0xC0110021 +HIDP_STATUS_I8242_TRANS_UNKNOWN :: HIDP_STATUS_I8042_TRANS_UNKNOWN foreign import hid "system:hid.lib" @(default_calling_convention="system") @@ -131,4 +188,26 @@ foreign hid { HidP_GetValueCaps :: proc(ReportType: HIDP_REPORT_TYPE, ValueCaps: PHIDP_VALUE_CAPS, ValueCapsLength: PUSHORT, PreparsedData: PHIDP_PREPARSED_DATA) -> NTSTATUS --- HidP_GetUsages :: proc(ReportType: HIDP_REPORT_TYPE, UsagePage: USAGE, LinkCollection: USHORT, UsageList: PUSAGE, UsageLength: PULONG, PreparsedData: PHIDP_PREPARSED_DATA, Report: PCHAR, ReportLength: ULONG) -> NTSTATUS --- HidP_GetUsageValue :: proc(ReportType: HIDP_REPORT_TYPE, UsagePage: USAGE, LinkCollection: USHORT, Usage: USAGE, UsageValue: PULONG, PreparsedData: PHIDP_PREPARSED_DATA, Report: PCHAR, ReportLength: ULONG) -> NTSTATUS --- + HidP_GetData :: proc(ReportType: HIDP_REPORT_TYPE, DataList: PHIDP_DATA, DataLength: PULONG, PreparsedData: PHIDP_PREPARSED_DATA, Report: PCHAR, ReportLength: ULONG) -> NTSTATUS --- + HidP_GetLinkCollectionNodes :: proc(LinkCollectionNodes: PHIDP_LINK_COLLECTION_NODE, LinkCollectionNodesLength: PULONG, PreparsedData: PHIDP_PREPARSED_DATA) -> NTSTATUS --- + + HidD_GetAttributes :: proc(HidDeviceObject: HANDLE, Attributes: PHIDD_ATTRIBUTES) -> BOOLEAN --- + HidD_GetHidGuid :: proc(HidGuid: LPGUID) --- + HidD_GetPreparsedData :: proc(HidDeviceObject: HANDLE, PreparsedData: ^PHIDP_PREPARSED_DATA) -> BOOLEAN --- + HidD_FreePreparsedData :: proc(PreparsedData: PHIDP_PREPARSED_DATA) -> BOOLEAN --- + HidD_FlushQueue :: proc(HidDeviceObject: HANDLE) -> BOOLEAN --- + HidD_GetConfiguration :: proc(HidDeviceObject: HANDLE, Configuration: PHIDD_CONFIGURATION, ConfigurationLength: ULONG) -> BOOLEAN --- + HidD_SetConfiguration :: proc(HidDeviceObject: HANDLE, Configuration: PHIDD_CONFIGURATION, ConfigurationLength: ULONG) -> BOOLEAN --- + HidD_GetFeature :: proc(HidDeviceObject: HANDLE, ReportBuffer: PVOID, ReportBufferLength: ULONG) -> BOOLEAN --- + HidD_SetFeature :: proc(HidDeviceObject: HANDLE, ReportBuffer: PVOID, ReportBufferLength: ULONG) -> BOOLEAN --- + HidD_GetInputReport :: proc(HidDeviceObject: HANDLE, ReportBuffer: PVOID, ReportBufferLength: ULONG) -> BOOLEAN --- + HidD_SetOutputReport :: proc(HidDeviceObject: HANDLE, ReportBuffer: PVOID, ReportBufferLength: ULONG) -> BOOLEAN --- + HidD_GetNumInputBuffers :: proc(HidDeviceObject: HANDLE, NumberBuffers: PULONG) -> BOOLEAN --- + HidD_SetNumInputBuffers :: proc(HidDeviceObject: HANDLE, NumberBuffers: ULONG) -> BOOLEAN --- + HidD_GetPhysicalDescriptor :: proc(HidDeviceObject: HANDLE, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN --- + HidD_GetManufacturerString :: proc(HidDeviceObject: HANDLE, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN --- + HidD_GetProductString :: proc(HidDeviceObject: HANDLE, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN --- + HidD_GetIndexedString :: proc(HidDeviceObject: HANDLE, StringIndex: ULONG, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN --- + HidD_GetSerialNumberString :: proc(HidDeviceObject: HANDLE, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN --- + HidD_GetMsGenreDescriptor :: proc(HidDeviceObject: HANDLE, Buffer: PVOID, BufferLength: ULONG) -> BOOLEAN --- } diff --git a/core/sys/windows/hidusage.odin b/core/sys/windows/hidusage.odin new file mode 100644 index 000000000..a32aa7b9f --- /dev/null +++ b/core/sys/windows/hidusage.odin @@ -0,0 +1,690 @@ +// +build windows +package sys_windows + +USAGE :: distinct USHORT +PUSAGE :: ^USAGE + +HID_USAGE_PAGE_UNDEFINED :: 0x00 +HID_USAGE_PAGE_GENERIC :: 0x01 +HID_USAGE_PAGE_SIMULATION :: 0x02 +HID_USAGE_PAGE_VR :: 0x03 +HID_USAGE_PAGE_SPORT :: 0x04 +HID_USAGE_PAGE_GAME :: 0x05 +HID_USAGE_PAGE_GENERIC_DEVICE :: 0x06 +HID_USAGE_PAGE_KEYBOARD :: 0x07 +HID_USAGE_PAGE_LED :: 0x08 +HID_USAGE_PAGE_BUTTON :: 0x09 +HID_USAGE_PAGE_ORDINAL :: 0x0A +HID_USAGE_PAGE_TELEPHONY :: 0x0B +HID_USAGE_PAGE_CONSUMER :: 0x0C +HID_USAGE_PAGE_DIGITIZER :: 0x0D +HID_USAGE_PAGE_HAPTICS :: 0x0E +HID_USAGE_PAGE_PID :: 0x0F +HID_USAGE_PAGE_UNICODE :: 0x10 +HID_USAGE_PAGE_ALPHANUMERIC :: 0x14 +HID_USAGE_PAGE_SENSOR :: 0x20 +HID_USAGE_PAGE_LIGHTING_ILLUMINATION :: 0x59 +HID_USAGE_PAGE_BARCODE_SCANNER :: 0x8C +HID_USAGE_PAGE_WEIGHING_DEVICE :: 0x8D +HID_USAGE_PAGE_MAGNETIC_STRIPE_READER :: 0x8E +HID_USAGE_PAGE_CAMERA_CONTROL :: 0x90 +HID_USAGE_PAGE_ARCADE :: 0x91 +HID_USAGE_PAGE_MICROSOFT_BLUETOOTH_HANDSFREE :: 0xFFF3 +HID_USAGE_PAGE_VENDOR_DEFINED_BEGIN :: 0xFF00 +HID_USAGE_PAGE_VENDOR_DEFINED_END :: 0xFFFF + +HID_USAGE_GENERIC_POINTER :: 0x01 +HID_USAGE_GENERIC_MOUSE :: 0x02 +HID_USAGE_GENERIC_JOYSTICK :: 0x04 +HID_USAGE_GENERIC_GAMEPAD :: 0x05 +HID_USAGE_GENERIC_KEYBOARD :: 0x06 +HID_USAGE_GENERIC_KEYPAD :: 0x07 +HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER :: 0x08 +HID_USAGE_GENERIC_TABLET_PC_SYSTEM_CTL :: 0x09 +HID_USAGE_GENERIC_PORTABLE_DEVICE_CONTROL :: 0x0D +HID_USAGE_GENERIC_INTERACTIVE_CONTROL :: 0x0E +HID_USAGE_GENERIC_SYSTEM_CTL :: 0x80 + +HID_USAGE_GENERIC_X :: 0x30 +HID_USAGE_GENERIC_Y :: 0x31 +HID_USAGE_GENERIC_Z :: 0x32 +HID_USAGE_GENERIC_RX :: 0x33 +HID_USAGE_GENERIC_RY :: 0x34 +HID_USAGE_GENERIC_RZ :: 0x35 +HID_USAGE_GENERIC_SLIDER :: 0x36 +HID_USAGE_GENERIC_DIAL :: 0x37 +HID_USAGE_GENERIC_WHEEL :: 0x38 +HID_USAGE_GENERIC_HATSWITCH :: 0x39 +HID_USAGE_GENERIC_COUNTED_BUFFER :: 0x3A +HID_USAGE_GENERIC_BYTE_COUNT :: 0x3B +HID_USAGE_GENERIC_MOTION_WAKEUP :: 0x3C +HID_USAGE_GENERIC_START :: 0x3D +HID_USAGE_GENERIC_SELECT :: 0x3E +HID_USAGE_GENERIC_VX :: 0x40 +HID_USAGE_GENERIC_VY :: 0x41 +HID_USAGE_GENERIC_VZ :: 0x42 +HID_USAGE_GENERIC_VBRX :: 0x43 +HID_USAGE_GENERIC_VBRY :: 0x44 +HID_USAGE_GENERIC_VBRZ :: 0x45 +HID_USAGE_GENERIC_VNO :: 0x46 +HID_USAGE_GENERIC_FEATURE_NOTIFICATION :: 0x47 +HID_USAGE_GENERIC_RESOLUTION_MULTIPLIER :: 0x48 +HID_USAGE_GENERIC_SYSCTL_POWER :: 0x81 +HID_USAGE_GENERIC_SYSCTL_SLEEP :: 0x82 +HID_USAGE_GENERIC_SYSCTL_WAKE :: 0x83 +HID_USAGE_GENERIC_SYSCTL_CONTEXT_MENU :: 0x84 +HID_USAGE_GENERIC_SYSCTL_MAIN_MENU :: 0x85 +HID_USAGE_GENERIC_SYSCTL_APP_MENU :: 0x86 +HID_USAGE_GENERIC_SYSCTL_HELP_MENU :: 0x87 +HID_USAGE_GENERIC_SYSCTL_MENU_EXIT :: 0x88 +HID_USAGE_GENERIC_SYSCTL_MENU_SELECT :: 0x89 +HID_USAGE_GENERIC_SYSCTL_MENU_RIGHT :: 0x8A +HID_USAGE_GENERIC_SYSCTL_MENU_LEFT :: 0x8B +HID_USAGE_GENERIC_SYSCTL_MENU_UP :: 0x8C +HID_USAGE_GENERIC_SYSCTL_MENU_DOWN :: 0x8D +HID_USAGE_GENERIC_SYSCTL_COLD_RESTART :: 0x8E +HID_USAGE_GENERIC_SYSCTL_WARM_RESTART :: 0x8F +HID_USAGE_GENERIC_DPAD_UP :: 0x90 +HID_USAGE_GENERIC_DPAD_DOWN :: 0x91 +HID_USAGE_GENERIC_DPAD_RIGHT :: 0x92 +HID_USAGE_GENERIC_DPAD_LEFT :: 0x93 +HID_USAGE_GENERIC_SYSCTL_FN :: 0x97 +HID_USAGE_GENERIC_SYSCTL_FN_LOCK :: 0x98 +HID_USAGE_GENERIC_SYSCTL_FN_LOCK_INDICATOR :: 0x99 +HID_USAGE_GENERIC_SYSCTL_DISMISS_NOTIFICATION :: 0x9A +HID_USAGE_GENERIC_SYSCTL_DOCK :: 0xA0 +HID_USAGE_GENERIC_SYSCTL_UNDOCK :: 0xA1 +HID_USAGE_GENERIC_SYSCTL_SETUP :: 0xA2 +HID_USAGE_GENERIC_SYSCTL_SYS_BREAK :: 0xA3 +HID_USAGE_GENERIC_SYSCTL_SYS_DBG_BREAK :: 0xA4 +HID_USAGE_GENERIC_SYSCTL_APP_BREAK :: 0xA5 +HID_USAGE_GENERIC_SYSCTL_APP_DBG_BREAK :: 0xA6 +HID_USAGE_GENERIC_SYSCTL_MUTE :: 0xA7 +HID_USAGE_GENERIC_SYSCTL_HIBERNATE :: 0xA8 +HID_USAGE_GENERIC_SYSCTL_DISP_INVERT :: 0xB0 +HID_USAGE_GENERIC_SYSCTL_DISP_INTERNAL :: 0xB1 +HID_USAGE_GENERIC_SYSCTL_DISP_EXTERNAL :: 0xB2 +HID_USAGE_GENERIC_SYSCTL_DISP_BOTH :: 0xB3 +HID_USAGE_GENERIC_SYSCTL_DISP_DUAL :: 0xB4 +HID_USAGE_GENERIC_SYSCTL_DISP_TOGGLE :: 0xB5 +HID_USAGE_GENERIC_SYSCTL_DISP_SWAP :: 0xB6 +HID_USAGE_GENERIC_SYSCTL_DISP_AUTOSCALE :: 0xB7 +HID_USAGE_GENERIC_SYSTEM_DISPLAY_ROTATION_LOCK_BUTTON :: 0xC9 +HID_USAGE_GENERIC_SYSTEM_DISPLAY_ROTATION_LOCK_SLIDER_SWITCH :: 0xCA +HID_USAGE_GENERIC_CONTROL_ENABLE :: 0xCB + +HID_USAGE_SIMULATION_FLIGHT_SIMULATION_DEVICE :: 0x01 +HID_USAGE_SIMULATION_AUTOMOBILE_SIMULATION_DEVICE :: 0x02 +HID_USAGE_SIMULATION_TANK_SIMULATION_DEVICE :: 0x03 +HID_USAGE_SIMULATION_SPACESHIP_SIMULATION_DEVICE :: 0x04 +HID_USAGE_SIMULATION_SUBMARINE_SIMULATION_DEVICE :: 0x05 +HID_USAGE_SIMULATION_SAILING_SIMULATION_DEVICE :: 0x06 +HID_USAGE_SIMULATION_MOTORCYCLE_SIMULATION_DEVICE :: 0x07 +HID_USAGE_SIMULATION_SPORTS_SIMULATION_DEVICE :: 0x08 +HID_USAGE_SIMULATION_AIRPLANE_SIMULATION_DEVICE :: 0x09 +HID_USAGE_SIMULATION_HELICOPTER_SIMULATION_DEVICE :: 0x0A +HID_USAGE_SIMULATION_MAGIC_CARPET_SIMULATION_DEVICE :: 0x0B +HID_USAGE_SIMULATION_BICYCLE_SIMULATION_DEVICE :: 0x0C +HID_USAGE_SIMULATION_FLIGHT_CONTROL_STICK :: 0x20 +HID_USAGE_SIMULATION_FLIGHT_STICK :: 0x21 +HID_USAGE_SIMULATION_CYCLIC_CONTROL :: 0x22 +HID_USAGE_SIMULATION_CYCLIC_TRIM :: 0x23 +HID_USAGE_SIMULATION_FLIGHT_YOKE :: 0x24 +HID_USAGE_SIMULATION_TRACK_CONTROL :: 0x25 + +HID_USAGE_SIMULATION_AILERON :: 0xB0 +HID_USAGE_SIMULATION_AILERON_TRIM :: 0xB1 +HID_USAGE_SIMULATION_ANTI_TORQUE_CONTROL :: 0xB2 +HID_USAGE_SIMULATION_AUTOPIOLOT_ENABLE :: 0xB3 +HID_USAGE_SIMULATION_CHAFF_RELEASE :: 0xB4 +HID_USAGE_SIMULATION_COLLECTIVE_CONTROL :: 0xB5 +HID_USAGE_SIMULATION_DIVE_BRAKE :: 0xB6 +HID_USAGE_SIMULATION_ELECTRONIC_COUNTERMEASURES :: 0xB7 +HID_USAGE_SIMULATION_ELEVATOR :: 0xB8 +HID_USAGE_SIMULATION_ELEVATOR_TRIM :: 0xB9 +HID_USAGE_SIMULATION_RUDDER :: 0xBA +HID_USAGE_SIMULATION_THROTTLE :: 0xBB +HID_USAGE_SIMULATION_FLIGHT_COMMUNICATIONS :: 0xBC +HID_USAGE_SIMULATION_FLARE_RELEASE :: 0xBD +HID_USAGE_SIMULATION_LANDING_GEAR :: 0xBE +HID_USAGE_SIMULATION_TOE_BRAKE :: 0xBF +HID_USAGE_SIMULATION_TRIGGER :: 0xC0 +HID_USAGE_SIMULATION_WEAPONS_ARM :: 0xC1 +HID_USAGE_SIMULATION_WEAPONS_SELECT :: 0xC2 +HID_USAGE_SIMULATION_WING_FLAPS :: 0xC3 +HID_USAGE_SIMULATION_ACCELLERATOR :: 0xC4 +HID_USAGE_SIMULATION_BRAKE :: 0xC5 +HID_USAGE_SIMULATION_CLUTCH :: 0xC6 +HID_USAGE_SIMULATION_SHIFTER :: 0xC7 +HID_USAGE_SIMULATION_STEERING :: 0xC8 +HID_USAGE_SIMULATION_TURRET_DIRECTION :: 0xC9 +HID_USAGE_SIMULATION_BARREL_ELEVATION :: 0xCA +HID_USAGE_SIMULATION_DIVE_PLANE :: 0xCB +HID_USAGE_SIMULATION_BALLAST :: 0xCC +HID_USAGE_SIMULATION_BICYCLE_CRANK :: 0xCD +HID_USAGE_SIMULATION_HANDLE_BARS :: 0xCE +HID_USAGE_SIMULATION_FRONT_BRAKE :: 0xCF +HID_USAGE_SIMULATION_REAR_BRAKE :: 0xD0 + +HID_USAGE_VR_BELT :: 0x01 +HID_USAGE_VR_BODY_SUIT :: 0x02 +HID_USAGE_VR_FLEXOR :: 0x03 +HID_USAGE_VR_GLOVE :: 0x04 +HID_USAGE_VR_HEAD_TRACKER :: 0x05 +HID_USAGE_VR_HEAD_MOUNTED_DISPLAY :: 0x06 +HID_USAGE_VR_HAND_TRACKER :: 0x07 +HID_USAGE_VR_OCULOMETER :: 0x08 +HID_USAGE_VR_VEST :: 0x09 +HID_USAGE_VR_ANIMATRONIC_DEVICE :: 0x0A + +HID_USAGE_VR_STEREO_ENABLE :: 0x20 +HID_USAGE_VR_DISPLAY_ENABLE :: 0x21 + +HID_USAGE_SPORT_BASEBALL_BAT :: 0x01 +HID_USAGE_SPORT_GOLF_CLUB :: 0x02 +HID_USAGE_SPORT_ROWING_MACHINE :: 0x03 +HID_USAGE_SPORT_TREADMILL :: 0x04 +HID_USAGE_SPORT_STICK_TYPE :: 0x38 + +HID_USAGE_SPORT_OAR :: 0x30 +HID_USAGE_SPORT_SLOPE :: 0x31 +HID_USAGE_SPORT_RATE :: 0x32 +HID_USAGE_SPORT_STICK_SPEED :: 0x33 +HID_USAGE_SPORT_STICK_FACE_ANGLE :: 0x34 +HID_USAGE_SPORT_HEEL_TOE :: 0x35 +HID_USAGE_SPORT_FOLLOW_THROUGH :: 0x36 +HID_USAGE_SPORT_TEMPO :: 0x37 +HID_USAGE_SPORT_HEIGHT :: 0x39 +HID_USAGE_SPORT_PUTTER :: 0x50 +HID_USAGE_SPORT_1_IRON :: 0x51 +HID_USAGE_SPORT_2_IRON :: 0x52 +HID_USAGE_SPORT_3_IRON :: 0x53 +HID_USAGE_SPORT_4_IRON :: 0x54 +HID_USAGE_SPORT_5_IRON :: 0x55 +HID_USAGE_SPORT_6_IRON :: 0x56 +HID_USAGE_SPORT_7_IRON :: 0x57 +HID_USAGE_SPORT_8_IRON :: 0x58 +HID_USAGE_SPORT_9_IRON :: 0x59 +HID_USAGE_SPORT_10_IRON :: 0x5A +HID_USAGE_SPORT_11_IRON :: 0x5B +HID_USAGE_SPORT_SAND_WEDGE :: 0x5C +HID_USAGE_SPORT_LOFT_WEDGE :: 0x5D +HID_USAGE_SPORT_POWER_WEDGE :: 0x5E +HID_USAGE_SPORT_1_WOOD :: 0x5F +HID_USAGE_SPORT_3_WOOD :: 0x60 +HID_USAGE_SPORT_5_WOOD :: 0x61 +HID_USAGE_SPORT_7_WOOD :: 0x62 +HID_USAGE_SPORT_9_WOOD :: 0x63 + +HID_USAGE_GAME_3D_GAME_CONTROLLER :: 0x01 +HID_USAGE_GAME_PINBALL_DEVICE :: 0x02 +HID_USAGE_GAME_GUN_DEVICE :: 0x03 +HID_USAGE_GAME_POINT_OF_VIEW :: 0x20 +HID_USAGE_GAME_GUN_SELECTOR :: 0x32 +HID_USAGE_GAME_GAMEPAD_FIRE_JUMP :: 0x37 +HID_USAGE_GAME_GAMEPAD_TRIGGER :: 0x39 + +HID_USAGE_GAME_TURN_RIGHT_LEFT :: 0x21 +HID_USAGE_GAME_PITCH_FORWARD_BACK :: 0x22 +HID_USAGE_GAME_ROLL_RIGHT_LEFT :: 0x23 +HID_USAGE_GAME_MOVE_RIGHT_LEFT :: 0x24 +HID_USAGE_GAME_MOVE_FORWARD_BACK :: 0x25 +HID_USAGE_GAME_MOVE_UP_DOWN :: 0x26 +HID_USAGE_GAME_LEAN_RIGHT_LEFT :: 0x27 +HID_USAGE_GAME_LEAN_FORWARD_BACK :: 0x28 +HID_USAGE_GAME_POV_HEIGHT :: 0x29 +HID_USAGE_GAME_FLIPPER :: 0x2A +HID_USAGE_GAME_SECONDARY_FLIPPER :: 0x2B +HID_USAGE_GAME_BUMP :: 0x2C +HID_USAGE_GAME_NEW_GAME :: 0x2D +HID_USAGE_GAME_SHOOT_BALL :: 0x2E +HID_USAGE_GAME_PLAYER :: 0x2F +HID_USAGE_GAME_GUN_BOLT :: 0x30 +HID_USAGE_GAME_GUN_CLIP :: 0x31 +HID_USAGE_GAME_GUN_SINGLE_SHOT :: 0x33 +HID_USAGE_GAME_GUN_BURST :: 0x34 +HID_USAGE_GAME_GUN_AUTOMATIC :: 0x35 +HID_USAGE_GAME_GUN_SAFETY :: 0x36 + +HID_USAGE_GENERIC_DEVICE_BATTERY_STRENGTH :: 0x20 +HID_USAGE_GENERIC_DEVICE_WIRELESS_CHANNEL :: 0x21 +HID_USAGE_GENERIC_DEVICE_WIRELESS_ID :: 0x22 +HID_USAGE_GENERIC_DEVICE_DISCOVER_WIRELESS_CONTROL :: 0x23 +HID_USAGE_GENERIC_DEVICE_SECURITY_CODE_CHAR_ENTERED :: 0x24 +HID_USAGE_GENERIC_DEVICE_SECURITY_CODE_CHAR_ERASED :: 0x25 +HID_USAGE_GENERIC_DEVICE_SECURITY_CODE_CLEARED :: 0x26 + +// Error "keys" +HID_USAGE_KEYBOARD_NOEVENT :: 0x00 +HID_USAGE_KEYBOARD_ROLLOVER :: 0x01 +HID_USAGE_KEYBOARD_POSTFAIL :: 0x02 +HID_USAGE_KEYBOARD_UNDEFINED :: 0x03 + +// Letters +HID_USAGE_KEYBOARD_aA :: 0x04 +HID_USAGE_KEYBOARD_zZ :: 0x1D + +// Numbers +HID_USAGE_KEYBOARD_ONE :: 0x1E +HID_USAGE_KEYBOARD_ZERO :: 0x27 + +// Modifier Keys +HID_USAGE_KEYBOARD_LCTRL :: 0xE0 +HID_USAGE_KEYBOARD_LSHFT :: 0xE1 +HID_USAGE_KEYBOARD_LALT :: 0xE2 +HID_USAGE_KEYBOARD_LGUI :: 0xE3 +HID_USAGE_KEYBOARD_RCTRL :: 0xE4 +HID_USAGE_KEYBOARD_RSHFT :: 0xE5 +HID_USAGE_KEYBOARD_RALT :: 0xE6 +HID_USAGE_KEYBOARD_RGUI :: 0xE7 +HID_USAGE_KEYBOARD_SCROLL_LOCK :: 0x47 +HID_USAGE_KEYBOARD_NUM_LOCK :: 0x53 +HID_USAGE_KEYBOARD_CAPS_LOCK :: 0x39 + +// Function keys +HID_USAGE_KEYBOARD_F1 :: 0x3A +HID_USAGE_KEYBOARD_F2 :: 0x3B +HID_USAGE_KEYBOARD_F3 :: 0x3C +HID_USAGE_KEYBOARD_F4 :: 0x3D +HID_USAGE_KEYBOARD_F5 :: 0x3E +HID_USAGE_KEYBOARD_F6 :: 0x3F +HID_USAGE_KEYBOARD_F7 :: 0x40 +HID_USAGE_KEYBOARD_F8 :: 0x41 +HID_USAGE_KEYBOARD_F9 :: 0x42 +HID_USAGE_KEYBOARD_F10 :: 0x43 +HID_USAGE_KEYBOARD_F11 :: 0x44 +HID_USAGE_KEYBOARD_F12 :: 0x45 +HID_USAGE_KEYBOARD_F13 :: 0x68 +HID_USAGE_KEYBOARD_F14 :: 0x69 +HID_USAGE_KEYBOARD_F15 :: 0x6A +HID_USAGE_KEYBOARD_F16 :: 0x6B +HID_USAGE_KEYBOARD_F17 :: 0x6C +HID_USAGE_KEYBOARD_F18 :: 0x6D +HID_USAGE_KEYBOARD_F19 :: 0x6E +HID_USAGE_KEYBOARD_F20 :: 0x6F +HID_USAGE_KEYBOARD_F21 :: 0x70 +HID_USAGE_KEYBOARD_F22 :: 0x71 +HID_USAGE_KEYBOARD_F23 :: 0x72 +HID_USAGE_KEYBOARD_F24 :: 0x73 + +HID_USAGE_KEYBOARD_RETURN :: 0x28 +HID_USAGE_KEYBOARD_ESCAPE :: 0x29 +HID_USAGE_KEYBOARD_DELETE :: 0x2A + +HID_USAGE_KEYBOARD_PRINT_SCREEN :: 0x46 +HID_USAGE_KEYBOARD_DELETE_FORWARD :: 0x4C + +// Numeric Keypad +HID_USAGE_KEYBOARD_KEYPAD_1_AND_END :: 0x59 +HID_USAGE_KEYBOARD_KEYPAD_0_AND_INSERT :: 0x62 + +HID_USAGE_LED_NUM_LOCK :: 0x01 +HID_USAGE_LED_CAPS_LOCK :: 0x02 +HID_USAGE_LED_SCROLL_LOCK :: 0x03 +HID_USAGE_LED_COMPOSE :: 0x04 +HID_USAGE_LED_KANA :: 0x05 +HID_USAGE_LED_POWER :: 0x06 +HID_USAGE_LED_SHIFT :: 0x07 +HID_USAGE_LED_DO_NOT_DISTURB :: 0x08 +HID_USAGE_LED_MUTE :: 0x09 +HID_USAGE_LED_TONE_ENABLE :: 0x0A +HID_USAGE_LED_HIGH_CUT_FILTER :: 0x0B +HID_USAGE_LED_LOW_CUT_FILTER :: 0x0C +HID_USAGE_LED_EQUALIZER_ENABLE :: 0x0D +HID_USAGE_LED_SOUND_FIELD_ON :: 0x0E +HID_USAGE_LED_SURROUND_FIELD_ON :: 0x0F +HID_USAGE_LED_REPEAT :: 0x10 +HID_USAGE_LED_STEREO :: 0x11 +HID_USAGE_LED_SAMPLING_RATE_DETECT :: 0x12 +HID_USAGE_LED_SPINNING :: 0x13 +HID_USAGE_LED_CAV :: 0x14 +HID_USAGE_LED_CLV :: 0x15 +HID_USAGE_LED_RECORDING_FORMAT_DET :: 0x16 +HID_USAGE_LED_OFF_HOOK :: 0x17 +HID_USAGE_LED_RING :: 0x18 +HID_USAGE_LED_MESSAGE_WAITING :: 0x19 +HID_USAGE_LED_DATA_MODE :: 0x1A +HID_USAGE_LED_BATTERY_OPERATION :: 0x1B +HID_USAGE_LED_BATTERY_OK :: 0x1C +HID_USAGE_LED_BATTERY_LOW :: 0x1D +HID_USAGE_LED_SPEAKER :: 0x1E +HID_USAGE_LED_HEAD_SET :: 0x1F +HID_USAGE_LED_HOLD :: 0x20 +HID_USAGE_LED_MICROPHONE :: 0x21 +HID_USAGE_LED_COVERAGE :: 0x22 +HID_USAGE_LED_NIGHT_MODE :: 0x23 +HID_USAGE_LED_SEND_CALLS :: 0x24 +HID_USAGE_LED_CALL_PICKUP :: 0x25 +HID_USAGE_LED_CONFERENCE :: 0x26 +HID_USAGE_LED_STAND_BY :: 0x27 +HID_USAGE_LED_CAMERA_ON :: 0x28 +HID_USAGE_LED_CAMERA_OFF :: 0x29 +HID_USAGE_LED_ON_LINE :: 0x2A +HID_USAGE_LED_OFF_LINE :: 0x2B +HID_USAGE_LED_BUSY :: 0x2C +HID_USAGE_LED_READY :: 0x2D +HID_USAGE_LED_PAPER_OUT :: 0x2E +HID_USAGE_LED_PAPER_JAM :: 0x2F +HID_USAGE_LED_REMOTE :: 0x30 +HID_USAGE_LED_FORWARD :: 0x31 +HID_USAGE_LED_REVERSE :: 0x32 +HID_USAGE_LED_STOP :: 0x33 +HID_USAGE_LED_REWIND :: 0x34 +HID_USAGE_LED_FAST_FORWARD :: 0x35 +HID_USAGE_LED_PLAY :: 0x36 +HID_USAGE_LED_PAUSE :: 0x37 +HID_USAGE_LED_RECORD :: 0x38 +HID_USAGE_LED_ERROR :: 0x39 +HID_USAGE_LED_SELECTED_INDICATOR :: 0x3A +HID_USAGE_LED_IN_USE_INDICATOR :: 0x3B +HID_USAGE_LED_MULTI_MODE_INDICATOR :: 0x3C +HID_USAGE_LED_INDICATOR_ON :: 0x3D +HID_USAGE_LED_INDICATOR_FLASH :: 0x3E +HID_USAGE_LED_INDICATOR_SLOW_BLINK :: 0x3F +HID_USAGE_LED_INDICATOR_FAST_BLINK :: 0x40 +HID_USAGE_LED_INDICATOR_OFF :: 0x41 +HID_USAGE_LED_FLASH_ON_TIME :: 0x42 +HID_USAGE_LED_SLOW_BLINK_ON_TIME :: 0x43 +HID_USAGE_LED_SLOW_BLINK_OFF_TIME :: 0x44 +HID_USAGE_LED_FAST_BLINK_ON_TIME :: 0x45 +HID_USAGE_LED_FAST_BLINK_OFF_TIME :: 0x46 +HID_USAGE_LED_INDICATOR_COLOR :: 0x47 +HID_USAGE_LED_RED :: 0x48 +HID_USAGE_LED_GREEN :: 0x49 +HID_USAGE_LED_AMBER :: 0x4A +HID_USAGE_LED_GENERIC_INDICATOR :: 0x4B +HID_USAGE_LED_SYSTEM_SUSPEND :: 0x4C +HID_USAGE_LED_EXTERNAL_POWER :: 0x4D + +HID_USAGE_TELEPHONY_PHONE :: 0x01 +HID_USAGE_TELEPHONY_ANSWERING_MACHINE :: 0x02 +HID_USAGE_TELEPHONY_MESSAGE_CONTROLS :: 0x03 +HID_USAGE_TELEPHONY_HANDSET :: 0x04 +HID_USAGE_TELEPHONY_HEADSET :: 0x05 +HID_USAGE_TELEPHONY_KEYPAD :: 0x06 +HID_USAGE_TELEPHONY_PROGRAMMABLE_BUTTON :: 0x07 +HID_USAGE_TELEPHONY_REDIAL :: 0x24 +HID_USAGE_TELEPHONY_TRANSFER :: 0x25 +HID_USAGE_TELEPHONY_DROP :: 0x26 +HID_USAGE_TELEPHONY_LINE :: 0x2A +HID_USAGE_TELEPHONY_RING_ENABLE :: 0x2D +HID_USAGE_TELEPHONY_SEND :: 0x31 +HID_USAGE_TELEPHONY_KEYPAD_0 :: 0xB0 +HID_USAGE_TELEPHONY_KEYPAD_D :: 0xBF +HID_USAGE_TELEPHONY_HOST_AVAILABLE :: 0xF1 + +HID_USAGE_CONSUMERCTRL :: 0x01 + +// channel +HID_USAGE_CONSUMER_CHANNEL_INCREMENT :: 0x9C +HID_USAGE_CONSUMER_CHANNEL_DECREMENT :: 0x9D + +// transport control +HID_USAGE_CONSUMER_PLAY :: 0xB0 +HID_USAGE_CONSUMER_PAUSE :: 0xB1 +HID_USAGE_CONSUMER_RECORD :: 0xB2 +HID_USAGE_CONSUMER_FAST_FORWARD :: 0xB3 +HID_USAGE_CONSUMER_REWIND :: 0xB4 +HID_USAGE_CONSUMER_SCAN_NEXT_TRACK :: 0xB5 +HID_USAGE_CONSUMER_SCAN_PREV_TRACK :: 0xB6 +HID_USAGE_CONSUMER_STOP :: 0xB7 +HID_USAGE_CONSUMER_PLAY_PAUSE :: 0xCD + +// GameDVR +HID_USAGE_CONSUMER_GAMEDVR_OPEN_GAMEBAR :: 0xD0 +HID_USAGE_CONSUMER_GAMEDVR_TOGGLE_RECORD :: 0xD1 +HID_USAGE_CONSUMER_GAMEDVR_RECORD_CLIP :: 0xD2 +HID_USAGE_CONSUMER_GAMEDVR_SCREENSHOT :: 0xD3 +HID_USAGE_CONSUMER_GAMEDVR_TOGGLE_INDICATOR :: 0xD4 +HID_USAGE_CONSUMER_GAMEDVR_TOGGLE_MICROPHONE :: 0xD5 +HID_USAGE_CONSUMER_GAMEDVR_TOGGLE_CAMERA :: 0xD6 +HID_USAGE_CONSUMER_GAMEDVR_TOGGLE_BROADCAST :: 0xD7 + +// audio +HID_USAGE_CONSUMER_VOLUME :: 0xE0 +HID_USAGE_CONSUMER_BALANCE :: 0xE1 +HID_USAGE_CONSUMER_MUTE :: 0xE2 +HID_USAGE_CONSUMER_BASS :: 0xE3 +HID_USAGE_CONSUMER_TREBLE :: 0xE4 +HID_USAGE_CONSUMER_BASS_BOOST :: 0xE5 +HID_USAGE_CONSUMER_SURROUND_MODE :: 0xE6 +HID_USAGE_CONSUMER_LOUDNESS :: 0xE7 +HID_USAGE_CONSUMER_MPX :: 0xE8 +HID_USAGE_CONSUMER_VOLUME_INCREMENT :: 0xE9 +HID_USAGE_CONSUMER_VOLUME_DECREMENT :: 0xEA + +// supplementary audio +HID_USAGE_CONSUMER_BASS_INCREMENT :: 0x152 +HID_USAGE_CONSUMER_BASS_DECREMENT :: 0x153 +HID_USAGE_CONSUMER_TREBLE_INCREMENT :: 0x154 +HID_USAGE_CONSUMER_TREBLE_DECREMENT :: 0x155 + +// Application Launch +HID_USAGE_CONSUMER_AL_CONFIGURATION :: 0x183 +HID_USAGE_CONSUMER_AL_EMAIL :: 0x18A +HID_USAGE_CONSUMER_AL_CALCULATOR :: 0x192 +HID_USAGE_CONSUMER_AL_BROWSER :: 0x194 +HID_USAGE_CONSUMER_AL_SEARCH :: 0x1C6 + +// Application Control +HID_USAGE_CONSUMER_AC_SEARCH :: 0x221 +HID_USAGE_CONSUMER_AC_GOTO :: 0x222 +HID_USAGE_CONSUMER_AC_HOME :: 0x223 +HID_USAGE_CONSUMER_AC_BACK :: 0x224 +HID_USAGE_CONSUMER_AC_FORWARD :: 0x225 +HID_USAGE_CONSUMER_AC_STOP :: 0x226 +HID_USAGE_CONSUMER_AC_REFRESH :: 0x227 +HID_USAGE_CONSUMER_AC_PREVIOUS :: 0x228 +HID_USAGE_CONSUMER_AC_NEXT :: 0x229 +HID_USAGE_CONSUMER_AC_BOOKMARKS :: 0x22A +HID_USAGE_CONSUMER_AC_PAN :: 0x238 + +// Keyboard Extended Attributes (defined on consumer page in HUTRR42) +HID_USAGE_CONSUMER_EXTENDED_KEYBOARD_ATTRIBUTES_COLLECTION :: 0x2C0 +HID_USAGE_CONSUMER_KEYBOARD_FORM_FACTOR :: 0x2C1 +HID_USAGE_CONSUMER_KEYBOARD_KEY_TYPE :: 0x2C2 +HID_USAGE_CONSUMER_KEYBOARD_PHYSICAL_LAYOUT :: 0x2C3 +HID_USAGE_CONSUMER_VENDOR_SPECIFIC_KEYBOARD_PHYSICAL_LAYOUT :: 0x2C4 +HID_USAGE_CONSUMER_KEYBOARD_IETF_LANGUAGE_TAG_INDEX :: 0x2C5 +HID_USAGE_CONSUMER_IMPLEMENTED_KEYBOARD_INPUT_ASSIST_CONTROLS :: 0x2C6 + +HID_USAGE_DIGITIZER_DIGITIZER :: 0x01 +HID_USAGE_DIGITIZER_PEN :: 0x02 +HID_USAGE_DIGITIZER_LIGHT_PEN :: 0x03 +HID_USAGE_DIGITIZER_TOUCH_SCREEN :: 0x04 +HID_USAGE_DIGITIZER_TOUCH_PAD :: 0x05 +HID_USAGE_DIGITIZER_WHITE_BOARD :: 0x06 +HID_USAGE_DIGITIZER_COORD_MEASURING :: 0x07 +HID_USAGE_DIGITIZER_3D_DIGITIZER :: 0x08 +HID_USAGE_DIGITIZER_STEREO_PLOTTER :: 0x09 +HID_USAGE_DIGITIZER_ARTICULATED_ARM :: 0x0A +HID_USAGE_DIGITIZER_ARMATURE :: 0x0B +HID_USAGE_DIGITIZER_MULTI_POINT :: 0x0C +HID_USAGE_DIGITIZER_FREE_SPACE_WAND :: 0x0D +HID_USAGE_DIGITIZER_HEAT_MAP :: 0x0F +HID_USAGE_DIGITIZER_STYLUS :: 0x20 +HID_USAGE_DIGITIZER_PUCK :: 0x21 +HID_USAGE_DIGITIZER_FINGER :: 0x22 +HID_USAGE_DIGITIZER_TABLET_FUNC_KEYS :: 0x39 +HID_USAGE_DIGITIZER_PROG_CHANGE_KEYS :: 0x3A + +HID_USAGE_DIGITIZER_TIP_PRESSURE :: 0x30 +HID_USAGE_DIGITIZER_BARREL_PRESSURE :: 0x31 +HID_USAGE_DIGITIZER_IN_RANGE :: 0x32 +HID_USAGE_DIGITIZER_TOUCH :: 0x33 +HID_USAGE_DIGITIZER_UNTOUCH :: 0x34 +HID_USAGE_DIGITIZER_TAP :: 0x35 +HID_USAGE_DIGITIZER_QUALITY :: 0x36 +HID_USAGE_DIGITIZER_DATA_VALID :: 0x37 +HID_USAGE_DIGITIZER_TRANSDUCER_INDEX :: 0x38 +HID_USAGE_DIGITIZER_BATTERY_STRENGTH :: 0x3B +HID_USAGE_DIGITIZER_INVERT :: 0x3C +HID_USAGE_DIGITIZER_X_TILT :: 0x3D +HID_USAGE_DIGITIZER_Y_TILT :: 0x3E +HID_USAGE_DIGITIZER_AZIMUTH :: 0x3F +HID_USAGE_DIGITIZER_ALTITUDE :: 0x40 +HID_USAGE_DIGITIZER_TWIST :: 0x41 +HID_USAGE_DIGITIZER_TIP_SWITCH :: 0x42 +HID_USAGE_DIGITIZER_SECONDARY_TIP_SWITCH :: 0x43 +HID_USAGE_DIGITIZER_BARREL_SWITCH :: 0x44 +HID_USAGE_DIGITIZER_ERASER :: 0x45 +HID_USAGE_DIGITIZER_TABLET_PICK :: 0x46 +HID_USAGE_DIGITIZER_TRANSDUCER_SERIAL :: 0x5B +HID_USAGE_DIGITIZER_HEAT_MAP_PROTOCOL_VENDOR_ID :: 0x6A +HID_USAGE_DIGITIZER_HEAT_MAP_PROTOCOL_VERSION :: 0x6B +HID_USAGE_DIGITIZER_HEAT_MAP_FRAME_DATA :: 0x6C +HID_USAGE_DIGITIZER_TRANSDUCER_SERIAL_PART2 :: 0x6E +HID_USAGE_DIGITIZER_TRANSDUCER_VENDOR :: 0x91 +HID_USAGE_DIGITIZER_TRANSDUCER_PRODUCT :: 0x92 +HID_USAGE_DIGITIZER_TRANSDUCER_CONNECTED :: 0xA2 + +HID_USAGE_HAPTICS_SIMPLE_CONTROLLER :: 0x01 + +HID_USAGE_HAPTICS_WAVEFORM_LIST :: 0x10 +HID_USAGE_HAPTICS_DURATION_LIST :: 0x11 + +HID_USAGE_HAPTICS_AUTO_TRIGGER :: 0x20 +HID_USAGE_HAPTICS_MANUAL_TRIGGER :: 0x21 +HID_USAGE_HAPTICS_AUTO_ASSOCIATED_CONTROL :: 0x22 +HID_USAGE_HAPTICS_INTENSITY :: 0x23 +HID_USAGE_HAPTICS_REPEAT_COUNT :: 0x24 +HID_USAGE_HAPTICS_RETRIGGER_PERIOD :: 0x25 +HID_USAGE_HAPTICS_WAVEFORM_VENDOR_PAGE :: 0x26 +HID_USAGE_HAPTICS_WAVEFORM_VENDOR_ID :: 0x27 +HID_USAGE_HAPTICS_WAVEFORM_CUTOFF_TIME :: 0x28 + +// Waveform types +HID_USAGE_HAPTICS_WAVEFORM_BEGIN :: 0x1000 +HID_USAGE_HAPTICS_WAVEFORM_STOP :: 0x1001 +HID_USAGE_HAPTICS_WAVEFORM_NULL :: 0x1002 +HID_USAGE_HAPTICS_WAVEFORM_CLICK :: 0x1003 +HID_USAGE_HAPTICS_WAVEFORM_BUZZ :: 0x1004 +HID_USAGE_HAPTICS_WAVEFORM_RUMBLE :: 0x1005 +HID_USAGE_HAPTICS_WAVEFORM_PRESS :: 0x1006 +HID_USAGE_HAPTICS_WAVEFORM_RELEASE :: 0x1007 +HID_USAGE_HAPTICS_WAVEFORM_END :: 0x1FFF + +HID_USAGE_HAPTICS_WAVEFORM_VENDOR_BEGIN :: 0x2000 +HID_USAGE_HAPTICS_WAVEFORM_VENDOR_END :: 0x2FFF + +HID_USAGE_ALPHANUMERIC_ALPHANUMERIC_DISPLAY :: 0x01 +HID_USAGE_ALPHANUMERIC_BITMAPPED_DISPLAY :: 0x02 +HID_USAGE_ALPHANUMERIC_DISPLAY_ATTRIBUTES_REPORT :: 0x20 +HID_USAGE_ALPHANUMERIC_DISPLAY_CONTROL_REPORT :: 0x24 +HID_USAGE_ALPHANUMERIC_CHARACTER_REPORT :: 0x2B +HID_USAGE_ALPHANUMERIC_DISPLAY_STATUS :: 0x2D +HID_USAGE_ALPHANUMERIC_CURSOR_POSITION_REPORT :: 0x32 +HID_USAGE_ALPHANUMERIC_FONT_REPORT :: 0x3B +HID_USAGE_ALPHANUMERIC_FONT_DATA :: 0x3C +HID_USAGE_ALPHANUMERIC_CHARACTER_ATTRIBUTE :: 0x48 +HID_USAGE_ALPHANUMERIC_PALETTE_REPORT :: 0x85 +HID_USAGE_ALPHANUMERIC_PALETTE_DATA :: 0x88 +HID_USAGE_ALPHANUMERIC_BLIT_REPORT :: 0x8A +HID_USAGE_ALPHANUMERIC_BLIT_DATA :: 0x8F +HID_USAGE_ALPHANUMERIC_SOFT_BUTTON :: 0x90 + +HID_USAGE_ALPHANUMERIC_ASCII_CHARACTER_SET :: 0x21 +HID_USAGE_ALPHANUMERIC_DATA_READ_BACK :: 0x22 +HID_USAGE_ALPHANUMERIC_FONT_READ_BACK :: 0x23 +HID_USAGE_ALPHANUMERIC_CLEAR_DISPLAY :: 0x25 +HID_USAGE_ALPHANUMERIC_DISPLAY_ENABLE :: 0x26 +HID_USAGE_ALPHANUMERIC_SCREEN_SAVER_DELAY :: 0x27 +HID_USAGE_ALPHANUMERIC_SCREEN_SAVER_ENABLE :: 0x28 +HID_USAGE_ALPHANUMERIC_VERTICAL_SCROLL :: 0x29 +HID_USAGE_ALPHANUMERIC_HORIZONTAL_SCROLL :: 0x2A +HID_USAGE_ALPHANUMERIC_DISPLAY_DATA :: 0x2C +HID_USAGE_ALPHANUMERIC_STATUS_NOT_READY :: 0x2E +HID_USAGE_ALPHANUMERIC_STATUS_READY :: 0x2F +HID_USAGE_ALPHANUMERIC_ERR_NOT_A_LOADABLE_CHARACTER :: 0x30 +HID_USAGE_ALPHANUMERIC_ERR_FONT_DATA_CANNOT_BE_READ :: 0x31 +HID_USAGE_ALPHANUMERIC_ROW :: 0x33 +HID_USAGE_ALPHANUMERIC_COLUMN :: 0x34 +HID_USAGE_ALPHANUMERIC_ROWS :: 0x35 +HID_USAGE_ALPHANUMERIC_COLUMNS :: 0x36 +HID_USAGE_ALPHANUMERIC_CURSOR_PIXEL_POSITIONING :: 0x37 +HID_USAGE_ALPHANUMERIC_CURSOR_MODE :: 0x38 +HID_USAGE_ALPHANUMERIC_CURSOR_ENABLE :: 0x39 +HID_USAGE_ALPHANUMERIC_CURSOR_BLINK :: 0x3A +HID_USAGE_ALPHANUMERIC_CHAR_WIDTH :: 0x3D +HID_USAGE_ALPHANUMERIC_CHAR_HEIGHT :: 0x3E +HID_USAGE_ALPHANUMERIC_CHAR_SPACING_HORIZONTAL :: 0x3F +HID_USAGE_ALPHANUMERIC_CHAR_SPACING_VERTICAL :: 0x40 +HID_USAGE_ALPHANUMERIC_UNICODE_CHAR_SET :: 0x41 +HID_USAGE_ALPHANUMERIC_FONT_7_SEGMENT :: 0x42 +HID_USAGE_ALPHANUMERIC_7_SEGMENT_DIRECT_MAP :: 0x43 +HID_USAGE_ALPHANUMERIC_FONT_14_SEGMENT :: 0x44 +HID_USAGE_ALPHANUMERIC_14_SEGMENT_DIRECT_MAP :: 0x45 +HID_USAGE_ALPHANUMERIC_DISPLAY_BRIGHTNESS :: 0x46 +HID_USAGE_ALPHANUMERIC_DISPLAY_CONTRAST :: 0x47 +HID_USAGE_ALPHANUMERIC_ATTRIBUTE_READBACK :: 0x49 +HID_USAGE_ALPHANUMERIC_ATTRIBUTE_DATA :: 0x4A +HID_USAGE_ALPHANUMERIC_CHAR_ATTR_ENHANCE :: 0x4B +HID_USAGE_ALPHANUMERIC_CHAR_ATTR_UNDERLINE :: 0x4C +HID_USAGE_ALPHANUMERIC_CHAR_ATTR_BLINK :: 0x4D +HID_USAGE_ALPHANUMERIC_BITMAP_SIZE_X :: 0x80 +HID_USAGE_ALPHANUMERIC_BITMAP_SIZE_Y :: 0x81 +HID_USAGE_ALPHANUMERIC_BIT_DEPTH_FORMAT :: 0x83 +HID_USAGE_ALPHANUMERIC_DISPLAY_ORIENTATION :: 0x84 +HID_USAGE_ALPHANUMERIC_PALETTE_DATA_SIZE :: 0x86 +HID_USAGE_ALPHANUMERIC_PALETTE_DATA_OFFSET :: 0x87 +HID_USAGE_ALPHANUMERIC_BLIT_RECTANGLE_X1 :: 0x8B +HID_USAGE_ALPHANUMERIC_BLIT_RECTANGLE_Y1 :: 0x8C +HID_USAGE_ALPHANUMERIC_BLIT_RECTANGLE_X2 :: 0x8D +HID_USAGE_ALPHANUMERIC_BLIT_RECTANGLE_Y2 :: 0x8E +HID_USAGE_ALPHANUMERIC_SOFT_BUTTON_ID :: 0x91 +HID_USAGE_ALPHANUMERIC_SOFT_BUTTON_SIDE :: 0x92 +HID_USAGE_ALPHANUMERIC_SOFT_BUTTON_OFFSET1 :: 0x93 +HID_USAGE_ALPHANUMERIC_SOFT_BUTTON_OFFSET2 :: 0x94 +HID_USAGE_ALPHANUMERIC_SOFT_BUTTON_REPORT :: 0x95 + +HID_USAGE_LAMPARRAY :: 0x01 +HID_USAGE_LAMPARRAY_ATTRBIUTES_REPORT :: 0x02 +HID_USAGE_LAMPARRAY_LAMP_COUNT :: 0x03 +HID_USAGE_LAMPARRAY_BOUNDING_BOX_WIDTH_IN_MICROMETERS :: 0x04 +HID_USAGE_LAMPARRAY_BOUNDING_BOX_HEIGHT_IN_MICROMETERS :: 0x05 +HID_USAGE_LAMPARRAY_BOUNDING_BOX_DEPTH_IN_MICROMETERS :: 0x06 +HID_USAGE_LAMPARRAY_KIND :: 0x07 +HID_USAGE_LAMPARRAY_MIN_UPDATE_INTERVAL_IN_MICROSECONDS :: 0x08 + +// 0x09 - 0x1F Reserved + +HID_USAGE_LAMPARRAY_LAMP_ATTRIBUTES_REQUEST_REPORT :: 0x20 +HID_USAGE_LAMPARRAY_LAMP_ID :: 0x21 +HID_USAGE_LAMPARRAY_LAMP_ATTRIBUTES_RESPONSE_REPORT :: 0x22 +HID_USAGE_LAMPARRAY_POSITION_X_IN_MICROMETERS :: 0x23 +HID_USAGE_LAMPARRAY_POSITION_Y_IN_MICROMETERS :: 0x24 +HID_USAGE_LAMPARRAY_POSITION_Z_IN_MICROMETERS :: 0x25 +HID_USAGE_LAMPARRAY_LAMP_PURPOSES :: 0x26 +HID_USAGE_LAMPARRAY_UPDATE_LATENCY_IN_MICROSECONDS :: 0x27 +HID_USAGE_LAMPARRAY_RED_LEVEL_COUNT :: 0x28 +HID_USAGE_LAMPARRAY_GREEN_LEVEL_COUNT :: 0x29 +HID_USAGE_LAMPARRAY_BLUE_LEVEL_COUNT :: 0x2A +HID_USAGE_LAMPARRAY_INTENSITY_LEVEL_COUNT :: 0x2B +HID_USAGE_LAMPARRAY_IS_PROGRAMMABLE :: 0x2C +HID_USAGE_LAMPARRAY_INPUT_BINDING :: 0x2D + +// 0x2E - 0x4F Reserved + +HID_USAGE_LAMPARRAY_LAMP_MULTI_UPDATE_REPORT :: 0x50 +HID_USAGE_LAMPARRAY_LAMP_RED_UPDATE_CHANNEL :: 0x51 +HID_USAGE_LAMPARRAY_LAMP_GREEN_UPDATE_CHANNEL :: 0x52 +HID_USAGE_LAMPARRAY_LAMP_BLUE_UPDATE_CHANNEL :: 0x53 +HID_USAGE_LAMPARRAY_LAMP_INTENSITY_UPDATE_CHANNEL :: 0x54 +HID_USAGE_LAMPARRAY_LAMP_UPDATE_FLAGS :: 0x55 + +// 0x55 - 0x5F Reserved + +HID_USAGE_LAMPARRAY_LAMP_RANGE_UPDATE_REPORT :: 0x60 +HID_USAGE_LAMPARRAY_LAMP_ID_START :: 0x61 +HID_USAGE_LAMPARRAY_LAMP_ID_END :: 0x62 + +// 0x63 - 0x6F Reserved + +HID_USAGE_LAMPARRAY_CONTROL_REPORT :: 0x70 +HID_USAGE_LAMPARRAY_AUTONOMOUS_MODE :: 0x71 + +HID_USAGE_CAMERA_AUTO_FOCUS :: 0x20 +HID_USAGE_CAMERA_SHUTTER :: 0x21 + +HID_USAGE_MS_BTH_HF_DIALNUMBER :: 0x21 +HID_USAGE_MS_BTH_HF_DIALMEMORY :: 0x22 diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin index f998f33da..eba275522 100644 --- a/core/sys/windows/kernel32.odin +++ b/core/sys/windows/kernel32.odin @@ -429,6 +429,8 @@ foreign kernel32 { DisconnectNamedPipe :: proc(hNamedPipe: HANDLE) -> BOOL --- WaitNamedPipeW :: proc(lpNamedPipeName: LPCWSTR, nTimeOut: DWORD) -> BOOL --- + AllocConsole :: proc() -> BOOL --- + AttachConsole :: proc(dwProcessId: DWORD) -> BOOL --- SetConsoleCtrlHandler :: proc(HandlerRoutine: PHANDLER_ROUTINE, Add: BOOL) -> BOOL --- GenerateConsoleCtrlEvent :: proc(dwCtrlEvent: DWORD, dwProcessGroupId: DWORD) -> BOOL --- FreeConsole :: proc() -> BOOL --- diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin index cb4091058..1fc0116f5 100644 --- a/core/sys/windows/user32.odin +++ b/core/sys/windows/user32.odin @@ -356,9 +356,9 @@ RAWHID :: struct { RAWMOUSE :: struct { usFlags: USHORT, - DUMMYUNIONNAME: struct #raw_union { + using DUMMYUNIONNAME: struct #raw_union { ulButtons: ULONG, - DUMMYSTRUCTNAME: struct { + using DUMMYSTRUCTNAME: struct { usButtonFlags: USHORT, usButtonData: USHORT, }, @@ -434,7 +434,7 @@ RID_DEVICE_INFO_MOUSE :: struct { RID_DEVICE_INFO :: struct { cbSize: DWORD, dwType: DWORD, - DUMMYUNIONNAME: struct #raw_union { + using DUMMYUNIONNAME: struct #raw_union { mouse: RID_DEVICE_INFO_MOUSE, keyboard: RID_DEVICE_INFO_KEYBOARD, hid: RID_DEVICE_INFO_HID, @@ -455,10 +455,21 @@ RIDEV_DEVNOTIFY :: 0x00002000 RID_HEADER :: 0x10000005 RID_INPUT :: 0x10000003 +RIDI_PREPARSEDDATA :: 0x20000005 +RIDI_DEVICENAME :: 0x20000007 +RIDI_DEVICEINFO :: 0x2000000b + RIM_TYPEMOUSE :: 0 RIM_TYPEKEYBOARD :: 1 RIM_TYPEHID :: 2 +RI_KEY_MAKE :: 0 +RI_KEY_BREAK :: 1 +RI_KEY_E0 :: 2 +RI_KEY_E1 :: 4 +RI_KEY_TERMSRV_SET_LED :: 8 +RI_KEY_TERMSRV_SHADOW :: 0x10 + MOUSE_MOVE_RELATIVE :: 0x00 MOUSE_MOVE_ABSOLUTE :: 0x01 MOUSE_VIRTUAL_DESKTOP :: 0x02 @@ -484,19 +495,6 @@ RI_MOUSE_BUTTON_5_UP :: 0x0200 RI_MOUSE_WHEEL :: 0x0400 RI_MOUSE_HWHEEL :: 0x0800 -HID_USAGE_PAGE_GENERIC :: 0x01 -HID_USAGE_PAGE_GAME :: 0x05 -HID_USAGE_PAGE_LED :: 0x08 -HID_USAGE_PAGE_BUTTON :: 0x09 - -HID_USAGE_GENERIC_POINTER :: 0x01 -HID_USAGE_GENERIC_MOUSE :: 0x02 -HID_USAGE_GENERIC_JOYSTICK :: 0x04 -HID_USAGE_GENERIC_GAMEPAD :: 0x05 -HID_USAGE_GENERIC_KEYBOARD :: 0x06 -HID_USAGE_GENERIC_KEYPAD :: 0x07 -HID_USAGE_GENERIC_MULTI_AXIS_CONTROLLER :: 0x08 - WINDOWPLACEMENT :: struct { length: UINT, flags: UINT, @@ -521,11 +519,11 @@ WINDOWINFO :: struct { PWINDOWINFO :: ^WINDOWINFO DRAWTEXTPARAMS :: struct { - cbSize : UINT , - iTabLength: int , - iLeftMargin: int , - iRightMargin: int , - uiLengthDrawn: UINT , + cbSize: UINT, + iTabLength: int, + iLeftMargin: int, + iRightMargin: int, + uiLengthDrawn: UINT, } PDRAWTEXTPARAMS :: ^DRAWTEXTPARAMS diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 441c8000d..1ec366ae7 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1619,7 +1619,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de if (e->kind != Entity_Variable) { continue; } - if (is_type_polymorphic(e->type)) { + if (is_type_polymorphic(e->type) && is_type_polymorphic_record_unspecialized(e->type)) { gbString s = type_to_string(e->type); char const *msg = "Unspecialized polymorphic types are not allowed in procedure parameters, got %s"; if (e->Variable.type_expr) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index f0c33d9d8..08f488642 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -10788,6 +10788,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast return Expr_Expr; case_end; + case Ast_DistinctType: case Ast_TypeidType: case Ast_PolyType: case Ast_ProcType: diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index cccbab4f6..c018077f9 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -161,8 +161,7 @@ gb_internal bool check_is_terminating_list(Slice const &stmts, String con } gb_internal bool check_has_break_list(Slice const &stmts, String const &label, bool implicit) { - for_array(i, stmts) { - Ast *stmt = stmts[i]; + for (Ast *stmt : stmts) { if (check_has_break(stmt, label, implicit)) { return true; } @@ -170,6 +169,14 @@ gb_internal bool check_has_break_list(Slice const &stmts, String const &l return false; } +gb_internal bool check_has_break_expr_list(Slice const &exprs, String const &label) { + for (Ast *expr : exprs) { + if (expr && expr->viral_state_flags & ViralStateFlag_ContainsOrBreak) { + return true; + } + } + return false; +} gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit) { switch (stmt->kind) { @@ -227,6 +234,20 @@ gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit) return true; } break; + + case Ast_ValueDecl: + if (stmt->ValueDecl.is_mutable && check_has_break_expr_list(stmt->ValueDecl.values, label)) { + return true; + } + break; + case Ast_AssignStmt: + if (check_has_break_expr_list(stmt->AssignStmt.lhs, label)) { + return true; + } + if (check_has_break_expr_list(stmt->AssignStmt.rhs, label)) { + return true; + } + break; } return false; @@ -250,6 +271,15 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) { return check_is_terminating(unparen_expr(es->expr), label); case_end; + case_ast_node(vd, ValueDecl, node); + return check_has_break_expr_list(vd->values, label); + case_end; + + case_ast_node(as, AssignStmt, node); + return check_has_break_expr_list(as->lhs, label) || + check_has_break_expr_list(as->rhs, label); + case_end; + case_ast_node(bs, BranchStmt, node); return bs->token.kind == Token_fallthrough; case_end; diff --git a/src/check_type.cpp b/src/check_type.cpp index 11e332757..4df0c5d19 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1133,18 +1133,21 @@ gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, return Endian_Native; }; - EndianKind backing_type_endian_kind = determine_endian_kind(core_array_type(backing_type)); + Type *backing_type_elem = core_array_type(backing_type); + i64 backing_type_elem_size = type_size_of(backing_type_elem); + EndianKind backing_type_endian_kind = determine_endian_kind(backing_type_elem); EndianKind endian_kind = Endian_Unknown; for (Entity *f : fields) { EndianKind field_kind = determine_endian_kind(f->type); + i64 field_size = type_size_of(f->type); - if (field_kind && backing_type_endian_kind != field_kind) { + if (field_kind && backing_type_endian_kind != field_kind && field_size > 1 && backing_type_elem_size > 1) { error(f->token, "All 'bit_field' field types must match the same endian kind as the backing type, i.e. all native, all little, or all big"); } if (endian_kind == Endian_Unknown) { endian_kind = field_kind; - } else if (field_kind && endian_kind != field_kind) { + } else if (field_kind && endian_kind != field_kind && field_size > 1) { error(f->token, "All 'bit_field' field types must be of the same endian variety, i.e. all native, all little, or all big"); } } diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index ba71eae4d..ad8d9d245 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -26,11 +26,11 @@ struct OdinDocWriter { StringMap string_cache; - PtrMap file_cache; - PtrMap pkg_cache; - PtrMap entity_cache; - PtrMap type_cache; - PtrMap stable_type_cache; + OrderedInsertPtrMap file_cache; + OrderedInsertPtrMap pkg_cache; + OrderedInsertPtrMap entity_cache; + OrderedInsertPtrMap type_cache; + OrderedInsertPtrMap stable_type_cache; OdinDocWriterItemTracker files; OdinDocWriterItemTracker pkgs; @@ -57,11 +57,11 @@ gb_internal void odin_doc_writer_prepare(OdinDocWriter *w) { string_map_init(&w->string_cache); - map_init(&w->file_cache); - map_init(&w->pkg_cache); - map_init(&w->entity_cache); - map_init(&w->type_cache); - map_init(&w->stable_type_cache); + map_init(&w->file_cache, 1<<10); + map_init(&w->pkg_cache, 1<<10); + map_init(&w->entity_cache, 1<<18); + map_init(&w->type_cache, 1<<18); + map_init(&w->stable_type_cache, 1<<18); odin_doc_writer_item_tracker_init(&w->files, 1); odin_doc_writer_item_tracker_init(&w->pkgs, 1); @@ -485,6 +485,13 @@ gb_internal OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { return 0; } + if (type->kind == Type_Named) { + Entity *e = type->Named.type_name; + if (e->TypeName.is_type_alias) { + type = type->Named.base; + } + } + // Type **mapped_type = map_get(&w->stable_type_cache, type); // may map to itself // if (mapped_type && *mapped_type) { // type = *mapped_type; @@ -506,13 +513,6 @@ gb_internal OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { if (!x | !y) { continue; } - - if (x->kind == Type_Named) { - Entity *e = x->Named.type_name; - if (e->TypeName.is_type_alias) { - x = x->Named.base; - } - } if (y->kind == Type_Named) { Entity *e = y->Named.type_name; if (e->TypeName.is_type_alias) { diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 030926079..ad02ff7dd 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2514,7 +2514,7 @@ gb_internal lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left case Token_Lt: runtime_procedure = "cstring_lt"; break; case Token_Gt: runtime_procedure = "cstring_gt"; break; case Token_LtEq: runtime_procedure = "cstring_le"; break; - case Token_GtEq: runtime_procedure = "cstring_gt"; break; + case Token_GtEq: runtime_procedure = "cstring_ge"; break; } GB_ASSERT(runtime_procedure != nullptr); @@ -2537,7 +2537,7 @@ gb_internal lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left case Token_Lt: runtime_procedure = "string_lt"; break; case Token_Gt: runtime_procedure = "string_gt"; break; case Token_LtEq: runtime_procedure = "string_le"; break; - case Token_GtEq: runtime_procedure = "string_gt"; break; + case Token_GtEq: runtime_procedure = "string_ge"; break; } GB_ASSERT(runtime_procedure != nullptr); diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 898c9ac31..736c54e52 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2835,8 +2835,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu { GB_ASSERT(arg_count <= 7); - char asm_string_default[] = "int $$0x80"; - char *asm_string = asm_string_default; + char asm_string[] = "int $$0x80"; gbString constraints = gb_string_make(heap_allocator(), "={eax}"); for (unsigned i = 0; i < gb_min(arg_count, 6); i++) { @@ -2848,16 +2847,11 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu "edx", "esi", "edi", + "ebp", }; constraints = gb_string_appendc(constraints, regs[i]); constraints = gb_string_appendc(constraints, "}"); } - if (arg_count == 7) { - char asm_string7[] = "push %[arg6]\npush %%ebp\nmov 4(%%esp), %%ebp\nint $0x80\npop %%ebp\nadd $4, %%esp"; - asm_string = asm_string7; - - constraints = gb_string_appendc(constraints, ",rm"); - } inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints)); } diff --git a/src/parser.cpp b/src/parser.cpp index 6e859fe32..ee3c56daf 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -3883,10 +3883,12 @@ gb_internal Ast *parse_proc_type(AstFile *f, Token proc_token) { expect_token(f, Token_OpenParen); + f->expr_level += 1; params = parse_field_list(f, nullptr, FieldFlag_Signature, Token_CloseParen, true, true); if (file_allow_newline(f)) { skip_possible_newline(f); } + f->expr_level -= 1; expect_token_after(f, Token_CloseParen, "parameter list"); results = parse_results(f, &diverging); diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp index 362e412ba..1c157c386 100644 --- a/src/ptr_map.cpp +++ b/src/ptr_map.cpp @@ -9,12 +9,6 @@ enum { }; -struct MapFindResult { - MapIndex hash_index; - MapIndex entry_prev; - MapIndex entry_index; -}; - enum : MapIndex { MAP_SENTINEL = ~(MapIndex)0 }; static void *const MAP_TOMBSTONE = (void *)~(uintptr)0; @@ -433,3 +427,435 @@ gb_internal PtrMapIterator const begin(PtrMap const &m) noexcept { } return PtrMapIterator{&m, index}; } + + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +struct MapFindResult { + MapIndex hash_index; + MapIndex entry_prev; + MapIndex entry_index; +}; + +template +struct OrderedInsertPtrMapEntry { + static_assert(sizeof(K) == sizeof(void *), "Key size must be pointer size"); + + K key; + V value; + MapIndex next; +}; + +template +struct OrderedInsertPtrMap { + MapIndex *hashes; + usize hashes_count; + OrderedInsertPtrMapEntry *entries; + u32 count; + u32 entries_capacity; +}; + + +template gb_internal void map_destroy (OrderedInsertPtrMap *h); +template gb_internal V * map_get (OrderedInsertPtrMap *h, K key); +template gb_internal void map_set (OrderedInsertPtrMap *h, K key, V const &value); +template gb_internal bool map_set_if_not_previously_exists(OrderedInsertPtrMap *h, K key, V const &value); // returns true if it previously existed +template gb_internal void map_remove (OrderedInsertPtrMap *h, K key); +template gb_internal void map_clear (OrderedInsertPtrMap *h); +template gb_internal void map_grow (OrderedInsertPtrMap *h); +template gb_internal void map_rehash (OrderedInsertPtrMap *h, isize new_count); +template gb_internal void map_reserve (OrderedInsertPtrMap *h, isize cap); + +// Mutlivalued map procedure +template gb_internal OrderedInsertPtrMapEntry * multi_map_find_first(OrderedInsertPtrMap *h, K key); +template gb_internal OrderedInsertPtrMapEntry * multi_map_find_next (OrderedInsertPtrMap *h, OrderedInsertPtrMapEntry *e); + +template gb_internal isize multi_map_count (OrderedInsertPtrMap *h, K key); +template gb_internal void multi_map_get_all (OrderedInsertPtrMap *h, K key, V *items); +template gb_internal void multi_map_insert (OrderedInsertPtrMap *h, K key, V const &value); +template gb_internal void multi_map_remove (OrderedInsertPtrMap *h, K key, OrderedInsertPtrMapEntry *e); +template gb_internal void multi_map_remove_all(OrderedInsertPtrMap *h, K key); + +template +gb_internal gb_inline void map_init(OrderedInsertPtrMap *h, isize capacity) { + capacity = next_pow2_isize(capacity); + map_reserve(h, capacity); +} + +template +gb_internal gb_inline void map_destroy(OrderedInsertPtrMap *h) { + gbAllocator a = map_allocator(); + gb_free(a, h->hashes); + gb_free(a, h->entries); +} + +template +gb_internal void map__resize_hashes(OrderedInsertPtrMap *h, usize count) { + h->hashes_count = cast(u32)resize_array_raw(&h->hashes, map_allocator(), h->hashes_count, count, MAP_CACHE_LINE_SIZE); +} + +template +gb_internal void map__reserve_entries(OrderedInsertPtrMap *h, usize capacity) { + h->entries_capacity = cast(u32)resize_array_raw(&h->entries, map_allocator(), h->entries_capacity, capacity, MAP_CACHE_LINE_SIZE); +} + + +template +gb_internal MapIndex map__add_entry(OrderedInsertPtrMap *h, K key) { + OrderedInsertPtrMapEntry e = {}; + e.key = key; + e.next = MAP_SENTINEL; + if (h->count+1 >= h->entries_capacity) { + map__reserve_entries(h, gb_max(h->entries_capacity*2, 4)); + } + h->entries[h->count++] = e; + return cast(MapIndex)(h->count-1); +} + +template +gb_internal MapFindResult map__find(OrderedInsertPtrMap *h, K key) { + MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; + if (h->hashes_count == 0) { + return fr; + } + u32 hash = ptr_map_hash_key(key); + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; + while (fr.entry_index != MAP_SENTINEL) { + auto *entry = &h->entries[fr.entry_index]; + if (entry->key == key) { + return fr; + } + fr.entry_prev = fr.entry_index; + fr.entry_index = entry->next; + } + return fr; +} + +template +gb_internal MapFindResult map__find_from_entry(OrderedInsertPtrMap *h, OrderedInsertPtrMapEntry *e) { + MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; + if (h->hashes_count == 0) { + return fr; + } + u32 hash = ptr_map_hash_key(e->key); + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; + while (fr.entry_index != MAP_SENTINEL) { + if (&h->entries[fr.entry_index] == e) { + return fr; + } + fr.entry_prev = fr.entry_index; + fr.entry_index = h->entries[fr.entry_index].next; + } + return fr; +} + +template +gb_internal b32 map__full(OrderedInsertPtrMap *h) { + return 0.75f * h->hashes_count <= h->count; +} + +template +gb_internal gb_inline void map_grow(OrderedInsertPtrMap *h) { + isize new_count = gb_max(h->hashes_count<<1, 16); + map_rehash(h, new_count); +} + +template +gb_internal void map_reset_entries(OrderedInsertPtrMap *h) { + for (usize i = 0; i < h->hashes_count; i++) { + h->hashes[i] = MAP_SENTINEL; + } + for (usize i = 0; i < h->count; i++) { + MapFindResult fr; + OrderedInsertPtrMapEntry *e = &h->entries[i]; + e->next = MAP_SENTINEL; + fr = map__find_from_entry(h, e); + if (fr.entry_prev == MAP_SENTINEL) { + h->hashes[fr.hash_index] = cast(MapIndex)i; + } else { + h->entries[fr.entry_prev].next = cast(MapIndex)i; + } + } +} + +template +gb_internal void map_reserve(OrderedInsertPtrMap *h, isize cap) { + if (h->count*2 < h->hashes_count) { + return; + } + map__reserve_entries(h, cap); + map__resize_hashes(h, cap*2); + map_reset_entries(h); +} + + +template +gb_internal void map_rehash(OrderedInsertPtrMap *h, isize new_count) { + map_reserve(h, new_count); +} + +template +gb_internal V *map_get(OrderedInsertPtrMap *h, K key) { + MapIndex hash_index = MAP_SENTINEL; + MapIndex entry_prev = MAP_SENTINEL; + MapIndex entry_index = MAP_SENTINEL; + if (h->hashes_count != 0) { + u32 hash = ptr_map_hash_key(key); + hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + entry_index = h->hashes[hash_index]; + while (entry_index != MAP_SENTINEL) { + auto *entry = &h->entries[entry_index]; + if (entry->key == key) { + return &entry->value; + } + entry_prev = entry_index; + entry_index = entry->next; + } + } + return nullptr; +} +template +gb_internal V *map_try_get(OrderedInsertPtrMap *h, K key, MapFindResult *fr_) { + MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; + if (h->hashes_count != 0) { + u32 hash = ptr_map_hash_key(key); + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; + while (fr.entry_index != MAP_SENTINEL) { + auto *entry = &h->entries[fr.entry_index]; + if (entry->key == key) { + return &entry->value; + } + fr.entry_prev = fr.entry_index; + fr.entry_index = entry->next; + } + } + if (h->hashes_count == 0 || map__full(h)) { + map_grow(h); + } + if (fr_) *fr_ = fr; + return nullptr; +} + + +template +gb_internal void map_set_internal_from_try_get(OrderedInsertPtrMap *h, K key, V const &value, MapFindResult const &fr) { + MapIndex index = map__add_entry(h, key); + if (fr.entry_prev != MAP_SENTINEL) { + h->entries[fr.entry_prev].next = index; + } else { + h->hashes[fr.hash_index] = index; + } + h->entries[index].value = value; +} + +template +gb_internal V &map_must_get(OrderedInsertPtrMap *h, K key) { + V *ptr = map_get(h, key); + GB_ASSERT(ptr != nullptr); + return *ptr; +} + +template +gb_internal void map_set(OrderedInsertPtrMap *h, K key, V const &value) { + MapIndex index; + MapFindResult fr; + if (h->hashes_count == 0) { + map_grow(h); + } + fr = map__find(h, key); + if (fr.entry_index != MAP_SENTINEL) { + index = fr.entry_index; + } else { + index = map__add_entry(h, key); + if (fr.entry_prev != MAP_SENTINEL) { + h->entries[fr.entry_prev].next = index; + } else { + h->hashes[fr.hash_index] = index; + } + } + h->entries[index].value = value; + + if (map__full(h)) { + map_grow(h); + } +} + +// returns true if it previously existed +template +gb_internal bool map_set_if_not_previously_exists(OrderedInsertPtrMap *h, K key, V const &value) { + MapIndex index; + MapFindResult fr; + if (h->hashes_count == 0) { + map_grow(h); + } + fr = map__find(h, key); + if (fr.entry_index != MAP_SENTINEL) { + return true; + } else { + index = map__add_entry(h, key); + if (fr.entry_prev != MAP_SENTINEL) { + h->entries[fr.entry_prev].next = index; + } else { + h->hashes[fr.hash_index] = index; + } + } + h->entries[index].value = value; + + if (map__full(h)) { + map_grow(h); + } + return false; +} + + +template +gb_internal void map__erase(OrderedInsertPtrMap *h, MapFindResult const &fr) { + MapFindResult last; + if (fr.entry_prev == MAP_SENTINEL) { + h->hashes[fr.hash_index] = h->entries[fr.entry_index].next; + } else { + h->entries[fr.entry_prev].next = h->entries[fr.entry_index].next; + } + if (fr.entry_index == h->count-1) { + h->count--; + return; + } + h->entries[fr.entry_index] = h->entries[h->count-1]; + h->count--; + + last = map__find(h, h->entries[fr.entry_index].key); + if (last.entry_prev != MAP_SENTINEL) { + h->entries[last.entry_prev].next = fr.entry_index; + } else { + h->hashes[last.hash_index] = fr.entry_index; + } +} + +template +gb_internal void map_remove(OrderedInsertPtrMap *h, K key) { + MapFindResult fr = map__find(h, key); + if (fr.entry_index != MAP_SENTINEL) { + map__erase(h, fr); + } +} + +template +gb_internal gb_inline void map_clear(OrderedInsertPtrMap *h) { + h->count = 0; + for (usize i = 0; i < h->hashes_count; i++) { + h->hashes[i] = MAP_SENTINEL; + } +} + + +template +gb_internal OrderedInsertPtrMapEntry *multi_map_find_first(OrderedInsertPtrMap *h, K key) { + MapIndex i = map__find(h, key).entry_index; + if (i == MAP_SENTINEL) { + return nullptr; + } + return &h->entries[i]; +} + +template +gb_internal OrderedInsertPtrMapEntry *multi_map_find_next(OrderedInsertPtrMap *h, OrderedInsertPtrMapEntry *e) { + MapIndex i = e->next; + while (i != MAP_SENTINEL) { + if (h->entries[i].key == e->key) { + return &h->entries[i]; + } + i = h->entries[i].next; + } + return nullptr; +} + +template +gb_internal isize multi_map_count(OrderedInsertPtrMap *h, K key) { + isize count = 0; + OrderedInsertPtrMapEntry *e = multi_map_find_first(h, key); + while (e != nullptr) { + count++; + e = multi_map_find_next(h, e); + } + return count; +} + +template +gb_internal void multi_map_get_all(OrderedInsertPtrMap *h, K key, V *items) { + usize i = 0; + OrderedInsertPtrMapEntry *e = multi_map_find_first(h, key); + while (e != nullptr) { + items[i++] = e->value; + e = multi_map_find_next(h, e); + } +} + +template +gb_internal void multi_map_insert(OrderedInsertPtrMap *h, K key, V const &value) { + MapFindResult fr; + MapIndex i; + if (h->hashes_count == 0) { + map_grow(h); + } + // Make + fr = map__find(h, key); + i = map__add_entry(h, key); + if (fr.entry_prev == MAP_SENTINEL) { + h->hashes[fr.hash_index] = i; + } else { + h->entries[fr.entry_prev].next = i; + } + h->entries[i].next = fr.entry_index; + h->entries[i].value = value; + // Grow if needed + if (map__full(h)) { + map_grow(h); + } +} + +template +gb_internal void multi_map_remove(OrderedInsertPtrMap *h, K key, OrderedInsertPtrMapEntry *e) { + MapFindResult fr = map__find_from_entry(h, e); + if (fr.entry_index != MAP_SENTINEL) { + map__erase(h, fr); + } +} + +template +gb_internal void multi_map_remove_all(OrderedInsertPtrMap *h, K key) { + while (map_get(h, key) != nullptr) { + map_remove(h, key); + } +} + + +template +gb_internal OrderedInsertPtrMapEntry *begin(OrderedInsertPtrMap &m) { + return m.entries; +} +template +gb_internal OrderedInsertPtrMapEntry const *begin(OrderedInsertPtrMap const &m) { + return m.entries; +} + + +template +gb_internal OrderedInsertPtrMapEntry *end(OrderedInsertPtrMap &m) { + return m.entries + m.count; +} + +template +gb_internal OrderedInsertPtrMapEntry const *end(OrderedInsertPtrMap const &m) { + return m.entries + m.count; +} \ No newline at end of file diff --git a/src/types.cpp b/src/types.cpp index 30e009086..47ed86f7a 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2100,8 +2100,8 @@ gb_internal bool is_type_polymorphic_record_unspecialized(Type *t) { t = base_type(t); if (t->kind == Type_Struct) { return t->Struct.is_polymorphic && !t->Struct.is_poly_specialized; - } else if (t->kind == Type_Struct) { - return t->Struct.is_polymorphic && !t->Struct.is_poly_specialized; + } else if (t->kind == Type_Union) { + return t->Union.is_polymorphic && !t->Union.is_poly_specialized; } return false; } diff --git a/tests/core/Makefile b/tests/core/Makefile index 12047f0ff..8996e2241 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -25,7 +25,8 @@ all: c_libc_test \ strings_test \ thread_test \ runtime_test \ - time_test + time_test \ + fmt_test download_test_assets: $(PYTHON) download_assets.py @@ -100,4 +101,4 @@ runtime_test: $(ODIN) run runtime $(COMMON) -out:test_core_runtime time_test: - $(ODIN) run time $(COMMON) -out:test_core_time + $(ODIN) run time $(COMMON) -out:test_core_time \ No newline at end of file diff --git a/tests/core/build.bat b/tests/core/build.bat index 36d2bb9c4..5dd2d1932 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -107,4 +107,9 @@ echo --- echo --- echo Running core:time tests echo --- -%PATH_TO_ODIN% run time %COMMON% %COLLECTION% -out:test_core_time.exe || exit /b \ No newline at end of file +%PATH_TO_ODIN% run time %COMMON% %COLLECTION% -out:test_core_time.exe || exit /b + +echo --- +echo Running core:fmt tests +echo --- +%PATH_TO_ODIN% run fmt %COMMON% %COLLECTION% -out:test_core_fmt.exe || exit /b \ No newline at end of file diff --git a/tests/core/fmt/test_core_fmt.odin b/tests/core/fmt/test_core_fmt.odin index 4459af609..82d009ac6 100644 --- a/tests/core/fmt/test_core_fmt.odin +++ b/tests/core/fmt/test_core_fmt.odin @@ -29,6 +29,8 @@ when ODIN_TEST { main :: proc() { t := testing.T{} test_fmt_memory(&t) + test_fmt_doc_examples(&t) + test_fmt_options(&t) fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) if TEST_fail > 0 { @@ -36,12 +38,13 @@ main :: proc() { } } -test_fmt_memory :: proc(t: ^testing.T) { - check :: proc(t: ^testing.T, exp: string, format: string, args: ..any, loc := #caller_location) { - got := fmt.tprintf(format, ..args) - expect(t, got == exp, fmt.tprintf("(%q, %v): %q != %q", format, args, got, exp), loc) - } +check :: proc(t: ^testing.T, exp: string, format: string, args: ..any, loc := #caller_location) { + got := fmt.tprintf(format, ..args) + expect(t, got == exp, fmt.tprintf("(%q, %v): %q != %q", format, args, got, exp), loc) +} +@(test) +test_fmt_memory :: proc(t: ^testing.T) { check(t, "5b", "%m", 5) check(t, "5B", "%M", 5) check(t, "-5B", "%M", -5) @@ -52,8 +55,129 @@ test_fmt_memory :: proc(t: ^testing.T) { check(t, "3.50 gib", "%#m", u32(mem.Gigabyte * 3.5)) check(t, "01tib", "%5.0m", mem.Terabyte) check(t, "-1tib", "%5.0m", -mem.Terabyte) - check(t, "2.50 pib", "%#5.m", uint(mem.Petabyte * 2.5)) + check(t, "2 pib", "%#5.m", uint(mem.Petabyte * 2.5)) check(t, "1.00 EiB", "%#M", mem.Exabyte) check(t, "255 B", "%#M", u8(255)) check(t, "0b", "%m", u8(0)) } + +@(test) +test_fmt_doc_examples :: proc(t: ^testing.T) { + // C-like syntax + check(t, "37 13", "%[1]d %[0]d", 13, 37) + check(t, "017.00", "%*[2].*[1][0]f", 17.0, 2, 6) + check(t, "017.00", "%6.2f", 17.0) + + // Python-like syntax + check(t, "37 13", "{1:d} {0:d}", 13, 37) + check(t, "017.00", "{0:*[2].*[1]f}", 17.0, 2, 6) + check(t, "017.00", "{:6.2f}", 17.0) +} + +@(test) +test_fmt_options :: proc(t: ^testing.T) { + // Escaping + check(t, "% { } 0 { } } {", "%% {{ }} {} {{ }} }} {{", 0 ) + + // Prefixes + check(t, "+3.000", "%+f", 3.0 ) + check(t, "0003", "%04i", 3 ) + check(t, "3 ", "% -4i", 3 ) + check(t, "+3", "%+i", 3 ) + check(t, "0b11", "%#b", 3 ) + check(t, "0xA", "%#X", 10 ) + + // Specific index formatting + check(t, "1 2 3", "%i %i %i", 1, 2, 3) + check(t, "1 2 3", "%[0]i %[1]i %[2]i", 1, 2, 3) + check(t, "3 2 1", "%[2]i %[1]i %[0]i", 1, 2, 3) + check(t, "3 1 2", "%[2]i %i %i", 1, 2, 3) + check(t, "1 2 3", "%i %[1]i %i", 1, 2, 3) + check(t, "1 3 2", "%i %[2]i %i", 1, 2, 3) + check(t, "1 1 1", "%[0]i %[0]i %[0]i", 1) + + // Width + check(t, "3.140", "%f", 3.14) + check(t, "3.140", "%4f", 3.14) + check(t, "3.140", "%5f", 3.14) + check(t, "03.140", "%6f", 3.14) + + // Precision + check(t, "3", "%.f", 3.14) + check(t, "3", "%.0f", 3.14) + check(t, "3.1", "%.1f", 3.14) + check(t, "3.140", "%.3f", 3.14) + check(t, "3.14000", "%.5f", 3.14) + + check(t, "3.1415", "%g", 3.1415) + + // Scientific notation + check(t, "3.000000e+00", "%e", 3.0) + + check(t, "3e+02", "%.e", 300.0) + check(t, "3e+02", "%.0e", 300.0) + check(t, "3.0e+02", "%.1e", 300.0) + check(t, "3.00e+02", "%.2e", 300.0) + check(t, "3.000e+02", "%.3e", 300.0) + + check(t, "3e+01", "%.e", 30.56) + check(t, "3e+01", "%.0e", 30.56) + check(t, "3.1e+01", "%.1e", 30.56) + check(t, "3.06e+01", "%.2e", 30.56) + check(t, "3.056e+01", "%.3e", 30.56) + + // Width and precision + check(t, "3.140", "%5.3f", 3.14) + check(t, "3.140", "%*[1].3f", 3.14, 5) + check(t, "3.140", "%*[1].*[2]f", 3.14, 5, 3) + check(t, "3.140", "%*[1].*[2][0]f", 3.14, 5, 3) + check(t, "3.140", "%*[2].*[1]f", 3.14, 3, 5) + check(t, "3.140", "%5.*[1]f", 3.14, 3) + + // Error checking + check(t, "%!(MISSING ARGUMENT)%!(NO VERB)", "%" ) + + check(t, "1%!(EXTRA 2, 3)", "%i", 1, 2, 3) + check(t, "2%!(EXTRA 1, 3)", "%[1]i", 1, 2, 3) + + check(t, "%!(BAD ARGUMENT NUMBER)%!(EXTRA 0)", "%[1]i", 0) + + check(t, "%!(MISSING ARGUMENT)", "%f") + check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB)", "%[0]") + check(t, "%!(BAD ARGUMENT NUMBER)", "%[0]f") + + check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB) %!(MISSING ARGUMENT)", "%[0] %i") + + check(t, "%!(NO VERB) 1%!(EXTRA 2)", "%[0] %i", 1, 2) + + check(t, "1 2 %!(MISSING ARGUMENT)", "%i %i %i", 1, 2) + check(t, "1 2 %!(BAD ARGUMENT NUMBER)", "%i %i %[2]i", 1, 2) + + check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB)%!(EXTRA 0)", "%[1]", 0) + + check(t, "3.1%!(EXTRA 3.14)", "%.1f", 3.14, 3.14) + + // Python-like syntax + check(t, "1 2 3", "{} {} {}", 1, 2, 3) + check(t, "3 2 1", "{2} {1} {0}", 1, 2, 3) + check(t, "1 2 3", "{:i} {:i} {:i}", 1, 2, 3) + check(t, "1 2 3", "{0:i} {1:i} {2:i}", 1, 2, 3) + check(t, "3 2 1", "{2:i} {1:i} {0:i}", 1, 2, 3) + check(t, "3 1 2", "{2:i} {0:i} {1:i}", 1, 2, 3) + check(t, "1 2 3", "{:i} {1:i} {:i}", 1, 2, 3) + check(t, "1 3 2", "{:i} {2:i} {:i}", 1, 2, 3) + check(t, "1 1 1", "{0:i} {0:i} {0:i}", 1) + + check(t, "1 1%!(EXTRA 2)", "{} {0}", 1, 2) + check(t, "2 1", "{1} {}", 1, 2) + check(t, "%!(BAD ARGUMENT NUMBER) 1%!(EXTRA 2)", "{2} {}", 1, 2) + + check(t, "%!(BAD ARGUMENT NUMBER)", "{1}") + check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB)", "{1:}") + check(t, "%!(BAD ARGUMENT NUMBER)%!(NO VERB)%!(EXTRA 0)", "{1:}", 0) + + check(t, "%!(MISSING ARGUMENT)", "{}" ) + check(t, "%!(MISSING ARGUMENT)%!(MISSING CLOSE BRACE)", "{" ) + check(t, "%!(MISSING CLOSE BRACE)%!(EXTRA 1)", "{", 1) + check(t, "%!(MISSING CLOSE BRACE)%!(EXTRA 1)", "{0", 1 ) +} diff --git a/tests/internal/Makefile b/tests/internal/Makefile index c5c612cdd..d17b9d012 100644 --- a/tests/internal/Makefile +++ b/tests/internal/Makefile @@ -1,6 +1,6 @@ ODIN=../../odin -all: rtti_test map_test pow_test 128_test asan_test +all: rtti_test map_test pow_test 128_test asan_test string_compare_test rtti_test: $(ODIN) run test_rtti.odin -file -vet -strict-style -o:minimal @@ -16,3 +16,6 @@ pow_test: asan_test: $(ODIN) run test_asan.odin -file -sanitize:address -debug + +string_compare_test: + $(ODIN) run test_string_compare.odin -file -vet -strict-style -o:minimal \ No newline at end of file diff --git a/tests/internal/build.bat b/tests/internal/build.bat index da4fe890d..29b3e36c3 100644 --- a/tests/internal/build.bat +++ b/tests/internal/build.bat @@ -1,8 +1,10 @@ @echo off set PATH_TO_ODIN==..\..\odin rem %PATH_TO_ODIN% run test_rtti.odin -file -vet -strict-style -o:minimal || exit /b -%PATH_TO_ODIN% run test_map.odin -file -vet -strict-style -o:minimal || exit /b +%PATH_TO_ODIN% run test_map.odin -file -vet -strict-style -o:minimal || exit /b rem -define:SEED=42 -%PATH_TO_ODIN% run test_pow.odin -file -vet -strict-style -o:minimal || exit /b +%PATH_TO_ODIN% run test_pow.odin -file -vet -strict-style -o:minimal || exit /b -%PATH_TO_ODIN% run test_128.odin -file -vet -strict-style -o:minimal || exit /b +%PATH_TO_ODIN% run test_128.odin -file -vet -strict-style -o:minimal || exit /b + +%PATH_TO_ODIN% run test_string_compare.odin -file -vet -strict-style -o:minimal || exit /b \ No newline at end of file diff --git a/tests/internal/test_string_compare.odin b/tests/internal/test_string_compare.odin new file mode 100644 index 000000000..ff65b41c2 --- /dev/null +++ b/tests/internal/test_string_compare.odin @@ -0,0 +1,93 @@ +package test_internal_string_compare + +import "core:fmt" +import "core:os" +import "core:testing" + +Op :: enum { Eq, Lt, Gt } + +Test :: struct { + a: cstring, + b: cstring, + res: [Op]bool, +} + +CASES := []Test{ + {"hellope", "hellope", {.Eq=true, .Lt=false, .Gt=false}}, + {"Hellope", "hellope", {.Eq=false, .Lt=true, .Gt=false}}, // H < h + {"Hell", "Hellope", {.Eq=false, .Lt=true, .Gt=false}}, + {"Hellope!", "Hellope", {.Eq=false, .Lt=false, .Gt=true }}, + {"Hellopf", "Hellope", {.Eq=false, .Lt=false, .Gt=true }}, +} + +@test +string_compare :: proc(t: ^testing.T) { + for v in CASES { + s_a := string(v.a) + s_b := string(v.b) + + for res, op in v.res { + switch op { + case .Eq: + expect(t, (v.a == v.b) == res, fmt.tprintf("Expected cstring(\"%v\") == cstring(\"%v\") to be %v", v.a, v.b, res)) + expect(t, (s_a == s_b) == res, fmt.tprintf("Expected string(\"%v\") == string(\"%v\") to be %v", v.a, v.b, res)) + + // If a == b then a != b + expect(t, (v.a != v.b) == !res, fmt.tprintf("Expected cstring(\"%v\") != cstring(\"%v\") to be %v", v.a, v.b, !res)) + expect(t, (s_a != s_b) == !res, fmt.tprintf("Expected string(\"%v\") != string(\"%v\") to be %v", v.a, v.b, !res)) + + case .Lt: + expect(t, (v.a < v.b) == res, fmt.tprintf("Expected cstring(\"%v\") < cstring(\"%v\") to be %v", v.a, v.b, res)) + expect(t, (s_a < s_b) == res, fmt.tprintf("Expected string(\"%v\") < string(\"%v\") to be %v", v.a, v.b, res)) + + // .Lt | .Eq == .LtEq + lteq := v.res[.Eq] | res + expect(t, (v.a <= v.b) == lteq, fmt.tprintf("Expected cstring(\"%v\") <= cstring(\"%v\") to be %v", v.a, v.b, lteq)) + expect(t, (s_a <= s_b) == lteq, fmt.tprintf("Expected string(\"%v\") <= string(\"%v\") to be %v", v.a, v.b, lteq)) + + case .Gt: + expect(t, (v.a > v.b) == res, fmt.tprintf("Expected cstring(\"%v\") > cstring(\"%v\") to be %v", v.a, v.b, res)) + expect(t, (s_a > s_b) == res, fmt.tprintf("Expected string(\"%v\") > string(\"%v\") to be %v", v.a, v.b, res)) + + // .Gt | .Eq == .GtEq + gteq := v.res[.Eq] | res + expect(t, (v.a >= v.b) == gteq, fmt.tprintf("Expected cstring(\"%v\") >= cstring(\"%v\") to be %v", v.a, v.b, gteq)) + expect(t, (s_a >= s_b) == gteq, fmt.tprintf("Expected string(\"%v\") >= string(\"%v\") to be %v", v.a, v.b, gteq)) + } + } + } +} + +// -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- + +main :: proc() { + t := testing.T{} + + string_compare(&t) + + fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) + if TEST_fail > 0 { + os.exit(1) + } +} + +TEST_count := 0 +TEST_fail := 0 + +when ODIN_TEST { + expect :: testing.expect + log :: testing.log +} else { + expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { + TEST_count += 1 + if !condition { + TEST_fail += 1 + fmt.printf("[%v] %v\n", loc, message) + return + } + } + log :: proc(t: ^testing.T, v: any, loc := #caller_location) { + fmt.printf("[%v] ", loc) + fmt.printf("log: %v\n", v) + } +} \ No newline at end of file diff --git a/vendor/directx/d3d12/d3d12.odin b/vendor/directx/d3d12/d3d12.odin index 7c4065d8b..e33845b73 100644 --- a/vendor/directx/d3d12/d3d12.odin +++ b/vendor/directx/d3d12/d3d12.odin @@ -82,6 +82,7 @@ FEATURE_LEVEL :: enum i32 { _11_1 = 45312, _12_0 = 49152, _12_1 = 49408, + _12_2 = 49664, } PRIMITIVE_TOPOLOGY :: enum i32 { @@ -833,6 +834,9 @@ FEATURE :: enum i32 { OPTIONS7 = 32, PROTECTED_RESOURCE_SESSION_TYPE_COUNT = 33, PROTECTED_RESOURCE_SESSION_TYPES = 34, + OPTIONS8 = 36, + OPTIONS9 = 37, + WAVE_MMA = 38, } SHADER_MIN_PRECISION_SUPPORT :: enum i32 { @@ -1017,6 +1021,7 @@ SHADER_MODEL :: enum i32 { _6_4 = 100, _6_5 = 101, _6_6 = 102, + _6_7 = 103, } FEATURE_DATA_SHADER_MODEL :: struct { @@ -1052,6 +1057,7 @@ SHADER_CACHE_SUPPORT_FLAG :: enum u32 { LIBRARY = 1, AUTOMATIC_INPROC_CACHE = 2, AUTOMATIC_DISK_CACHE = 3, + DRIVER_MANAGED_CACHE = 4, } FEATURE_DATA_SHADER_CACHE :: struct { @@ -1171,6 +1177,55 @@ FEATURE_DATA_QUERY_META_COMMAND :: struct { QueryOutputDataSizeInBytes: SIZE_T, } +FEATURE_DATA_OPTIONS8 :: struct { + UnalignedBlockTexturesSupported: BOOL, +} + +WAVE_MMA_TIER :: enum i32 { + NOT_SUPPORTED = 0, + _1_0 = 10, +} + +FEATURE_DATA_OPTIONS9 :: struct { + MeshShaderPipelineStatsSupported: BOOL, + MeshShaderSupportsFullRangeRenderTargetArrayIndex: BOOL, + AtomicInt64OnTypedResourceSupported: BOOL, + AtomicInt64OnGroupSharedSupported: BOOL, + DerivativesInMeshAndAmplificationShadersSupported: BOOL, + WaveMMATier: WAVE_MMA_TIER, +} + +WAVE_MMA_INPUT_DATATYPE :: enum i32 { + INVALID = 0, + BYTE = 1, + FLOAT16 = 2, + FLOAT = 3, +} + +WAVE_MMA_DIMENSION :: enum i32 { + INVALID = 0, + _16 = 1, + _64 = 2, +} + +WAVE_MMA_ACCUM_DATATYPE :: enum i32 { + NONE = 0, + INT32 = 1, + FLOAT16 = 2, + FLOAT = 4, +} + +FEATURE_DATA_WAVE_MMA :: struct { + InputDataType: WAVE_MMA_INPUT_DATATYPE, + M: WAVE_MMA_DIMENSION, + N: WAVE_MMA_DIMENSION, + Supported: BOOL, + K: u32, + AccumDataTypes: WAVE_MMA_ACCUM_DATATYPE, + RequiredWaveLaneCountMin: u32, + RequiredWaveLaneCountMax: u32, +} + RESOURCE_ALLOCATION_INFO :: struct { SizeInBytes: u64, Alignment: u64, @@ -1261,6 +1316,7 @@ RESOURCE_FLAG :: enum u32 { ALLOW_CROSS_ADAPTER = 4, ALLOW_SIMULTANEOUS_ACCESS = 5, VIDEO_DECODE_REFERENCE_ONLY = 6, + VIDEO_ENCODE_REFERENCE_ONLY = 7, } MIP_REGION :: struct { @@ -2140,6 +2196,7 @@ QUERY_HEAP_TYPE :: enum i32 { SO_STATISTICS = 3, VIDEO_DECODE_STATISTICS = 4, COPY_QUEUE_TIMESTAMP = 5, + PIPELINE_STATISTICS1 = 7, } QUERY_HEAP_DESC :: struct { @@ -2158,6 +2215,7 @@ QUERY_TYPE :: enum i32 { SO_STATISTICS_STREAM2 = 6, SO_STATISTICS_STREAM3 = 7, VIDEO_DECODE_STATISTICS = 8, + PIPELINE_STATISTICS1 = 10, } PREDICATION_OP :: enum i32 { @@ -2179,6 +2237,23 @@ QUERY_DATA_PIPELINE_STATISTICS :: struct { CSInvocations: u64, } +QUERY_DATA_PIPELINE_STATISTICS1 :: struct { + IAVertices: u64, + IAPrimitives: u64, + VSInvocations: u64, + GSInvocations: u64, + GSPrimitives: u64, + CInvocations: u64, + CPrimitives: u64, + PSInvocations: u64, + HSInvocations: u64, + DSInvocations: u64, + CSInvocations: u64, + ASInvocations: u64, + MSInvocations: u64, + MSPrimitives: u64, +} + QUERY_DATA_SO_STATISTICS :: struct { NumPrimitivesWritten: u64, PrimitivesStorageNeeded: u64, @@ -3244,6 +3319,8 @@ AUTO_BREADCRUMB_OP :: enum i32 { INITIALIZEEXTENSIONCOMMAND = 40, EXECUTEEXTENSIONCOMMAND = 41, DISPATCHMESH = 42, + ENCODEFRAME = 43, + RESOLVEENCODEROUTPUTMETADATA = 44, } AUTO_BREADCRUMB_NODE :: struct { @@ -3283,6 +3360,7 @@ DRED_VERSION :: enum i32 { _1_0 = 1, _1_1 = 2, _1_2 = 3, + _1_3 = 4, } DRED_FLAGS :: distinct bit_set[DRED_FLAG; u32] @@ -3329,6 +3407,8 @@ DRED_ALLOCATION_TYPE :: enum i32 { VIDEO_MOTION_ESTIMATOR = 45, VIDEO_MOTION_VECTOR_HEAP = 46, VIDEO_EXTENSION_COMMAND = 47, + VIDEO_ENCODER = 48, + VIDEO_ENCODER_HEAP = 49, INVALID = -1, } @@ -3367,6 +3447,24 @@ DRED_PAGE_FAULT_OUTPUT1 :: struct { pHeadRecentFreedAllocationNode: ^DRED_ALLOCATION_NODE1, } +DRED_PAGE_FAULT_FLAGS :: bit_set[DRED_PAGE_FAULT_FLAG;u32] +DRED_PAGE_FAULT_FLAG :: enum u32 { +} + +DRED_DEVICE_STATE :: enum i32 { + UNKNOWN = 0, + HUNG = 3, + FAULT = 6, + PAGEFAULT = 7, +} + +DRED_PAGE_FAULT_OUTPUT2 :: struct { + PageFaultVA: GPU_VIRTUAL_ADDRESS, + pHeadExistingAllocationNode: ^DRED_ALLOCATION_NODE1, + pHeadRecentFreedAllocationNode: ^DRED_ALLOCATION_NODE1, + PageFaultFlags: DRED_PAGE_FAULT_FLAGS, +} + DEVICE_REMOVED_EXTENDED_DATA1 :: struct { DeviceRemovedReason: HRESULT, AutoBreadcrumbsOutput: DRED_AUTO_BREADCRUMBS_OUTPUT, @@ -3379,12 +3477,20 @@ DEVICE_REMOVED_EXTENDED_DATA2 :: struct { PageFaultOutput: DRED_PAGE_FAULT_OUTPUT1, } +DEVICE_REMOVED_EXTENDED_DATA3 :: struct { + DeviceRemovedReason: HRESULT, + AutoBreadcrumbsOutput: DRED_AUTO_BREADCRUMBS_OUTPUT1, + PageFaultOutput: DRED_PAGE_FAULT_OUTPUT2, + DeviceState: DRED_DEVICE_STATE, +} + VERSIONED_DEVICE_REMOVED_EXTENDED_DATA :: struct { Version: DRED_VERSION, using _: struct #raw_union { Dred_1_0: DEVICE_REMOVED_EXTENDED_DATA, Dred_1_1: DEVICE_REMOVED_EXTENDED_DATA1, Dred_1_2: DEVICE_REMOVED_EXTENDED_DATA2, + Dred_1_3: DEVICE_REMOVED_EXTENDED_DATA3, }, } @@ -3440,6 +3546,18 @@ IDeviceRemovedExtendedData1_VTable :: struct { GetPageFaultAllocationOutput1: proc "system" (this: ^IDeviceRemovedExtendedData1, pOutput: ^DRED_PAGE_FAULT_OUTPUT1) -> HRESULT, } +IDeviceRemovedExtendedData2_UUID_STRING :: "67FC5816-E4CA-4915-BF18-42541272DA54" +IDeviceRemovedExtendedData2_UUID := &IID{0x67FC5816, 0xE4CA, 0x4915, {0xBF, 0x18, 0x42, 0x54, 0x12, 0x72, 0xDA, 0x54}} +IDeviceRemovedExtendedData2 :: struct #raw_union { + #subtype id3d12deviceremovedextendeddata1: IDeviceRemovedExtendedData1, + using id3d12deviceremovedextendeddata2_vtable: ^IDeviceRemovedExtendedData2_VTable, +} +IDeviceRemovedExtendedData2_VTable :: struct { + using id3d12deviceremovedextendeddata1_vtable: IDeviceRemovedExtendedData1_VTable, + GetPageFaultAllocationOutput2: proc "system" (this: ^IDeviceRemovedExtendedData2, pOutput: ^DRED_PAGE_FAULT_OUTPUT2) -> HRESULT, + GetDeviceState: proc "system" (this: ^IDeviceRemovedExtendedData2) -> DRED_DEVICE_STATE, +} + BACKGROUND_PROCESSING_MODE :: enum i32 { ALLOWED = 0, ALLOW_INTRUSIVE_MEASUREMENTS = 1, @@ -3686,6 +3804,71 @@ IGraphicsCommandList4_VTable :: struct { } +SHADER_CACHE_MODE :: enum i32 { + MEMORY = 0, + DISK = 1, +} + +SHADER_CACHE_FLAGS :: bit_set[SHADER_CACHE_FLAG;u32] +SHADER_CACHE_FLAG :: enum u32 { + DRIVER_VERSIONED = 0, + USE_WORKING_DIR = 1, +} + +SHADER_CACHE_SESSION_DESC :: struct { + Identifier: GUID, + Mode: SHADER_CACHE_MODE, + Flags: SHADER_CACHE_FLAGS, + MaximumInMemoryCacheSizeBytes: u32, + MaximumInMemoryCacheEntries: u32, + MaximumValueFileSizeBytes: u32, + Version: u64, +} + +IShaderCacheSession_UUID_STRING :: "28E2495D-0F64-4AE4-A6EC-129255DC49A8" +IShaderCacheSession_UUID := &IID{0x28E2495D, 0x0F64, 0x4AE4, {0xA6, 0xEC, 0x12, 0x92, 0x55, 0xDC, 0x49, 0xA8}} +IShaderCacheSession :: struct #raw_union { + #subtype idevicechild: IDeviceChild, + using id3d12shadercachesession_vtable: ^IShaderCacheSession_VTable, +} +IShaderCacheSession_VTable :: struct { + using idevicechild_vtable: IDeviceChild_VTable, + FindValue: proc "system" (this: ^IShaderCacheSession, pKey: rawptr, KeySize: u32, pValue: rawptr, pValueSize: ^u32) -> HRESULT, + StoreValue: proc "system" (this: ^IShaderCacheSession, pKey: rawptr, KeySize: u32, pValue: rawptr, ValueSize: u32) -> HRESULT, + SetDeleteOnDestroy: proc "system" (this: ^IShaderCacheSession), + GetDesc: proc "system" (this: ^IShaderCacheSession, pRetValue: ^SHADER_CACHE_SESSION_DESC) -> ^SHADER_CACHE_SESSION_DESC, +} + + +SHADER_CACHE_KIND_FLAGS :: bit_set[SHADER_CACHE_KIND_FLAG;u32] +SHADER_CACHE_KIND_FLAG :: enum u32 { + IMPLICIT_D3D_CACHE_FOR_DRIVER = 0, + IMPLICIT_D3D_CONVERSIONS = 1, + IMPLICIT_DRIVER_MANAGED = 2, + APPLICATION_MANAGED = 3, +} + +SHADER_CACHE_CONTROL_FLAGS :: bit_set[SHADER_CACHE_CONTROL_FLAG;u32] +SHADER_CACHE_CONTROL_FLAG :: enum u32 { + DISABLE = 0, + ENABLE = 1, + CLEAR = 2, +} + +IDevice9_UUID_STRING :: "4C80E962-F032-4F60-BC9E-EBC2CFA1D83C" +IDevice9_UUID := &IID{0x4C80E962, 0xF032, 0x4F60, {0xBC, 0x9E, 0xEB, 0xC2, 0xCF, 0xA1, 0xD8, 0x3C}} +IDevice9 :: struct #raw_union { + #subtype id3d12device8: IDevice8, + using id3d12device9_vtable: ^IDevice9_VTable, +} +IDevice9_VTable :: struct { + using id3d12device8_vtable: IDevice8_VTable, + CreateShaderCacheSession: proc "system" (this: ^IDevice9, pDesc: ^SHADER_CACHE_SESSION_DESC , riid: ^IID, ppvSession: ^rawptr) -> HRESULT, + ShaderCacheControl: proc "system" (this: ^IDevice9, Kinds: SHADER_CACHE_KIND_FLAGS, Control: SHADER_CACHE_CONTROL_FLAGS) -> HRESULT, + CreateCommandQueue1: proc "system" (this: ^IDevice9, pDesc: ^COMMAND_QUEUE_DESC, CreatorID: ^IID, riid: ^IID, ppCommandQueue: ^rawptr) -> HRESULT, +} + + ITools_UUID_STRING :: "7071e1f0-e84b-4b33-974f-12fa49de65c5" ITools_UUID := &IID{0x7071e1f0, 0xe84b, 0x4b33, {0x97, 0x4f, 0x12, 0xfa, 0x49, 0xde, 0x65, 0xc5}} ITools :: struct #raw_union { @@ -3766,6 +3949,30 @@ IDebug3_VTable :: struct { SetGPUBasedValidationFlags: proc "system" (this: ^IDebug3, Flags: GPU_BASED_VALIDATION_FLAGS), } + +IDebug4_UUID_STRING :: "014B816E-9EC5-4A2F-A845-FFBE441CE13A" +IDebug4_UUID := &IID{0x014B816E, 0x9EC5, 0x4A2F, {0xA8, 0x45, 0xFF, 0xBE, 0x44, 0x1C, 0xE1, 0x3A}} +IDebug4 :: struct #raw_union { + #subtype id3d12debug3: IDebug3, + using id3d12debug4_vtable: ^IDebug4_VTable, +} +IDebug4_VTable :: struct { + using id3d12debug3_vtable: IDebug3_VTable, + DisableDebugLayer: proc "system" (this: ^IDebug4), +} + + +IDebug5_UUID_STRING :: "548D6B12-09FA-40E0-9069-5DCD589A52C9" +IDebug5_UUID := &IID{0x548D6B12, 0x09FA, 0x40E0, {0x90, 0x69, 0x5D, 0xCD, 0x58, 0x9A, 0x52, 0xC9}} +IDebug5 :: struct #raw_union { + #subtype id3d12debug4: IDebug4, + using id3d12debug5_vtable: ^IDebug5_VTable, +} +IDebug5_VTable :: struct { + using id3d12debug4_vtable: IDebug4_VTable, + SetEnableAutoName: proc "system" (this: ^IDebug5, Enable: BOOL), +} + RLDO_FLAGS :: distinct bit_set[RLDO_FLAG; u32] RLDO_FLAG :: enum u32 { SUMMARY = 0, @@ -4890,6 +5097,19 @@ IInfoQueue1_VTable :: struct { UnregisterMessageCallback: proc "system" (this: ^IInfoQueue1, pCallbackCookie: u32) -> HRESULT, } + +ISDKConfiguration_UUID_STRING :: "E9EB5314-33AA-42B2-A718-D77F58B1F1C7" +ISDKConfiguration_UUID := &IID{0xE9EB5314, 0x33AA, 0x42B2, {0xA7, 0x18, 0xD7, 0x7F, 0x58, 0xB1, 0xF1, 0xC7}} +ISDKConfiguration :: struct #raw_union { + #subtype iunknown: IUnknown, + using id3d12sdkconfiguration_vtable: ^ISDKConfiguration_VTable, +} +ISDKConfiguration_VTable :: struct { + using iunknown_vtable: IUnknown_VTable, + SetSDKVersion: proc "system" (this: ^ISDKConfiguration, SDKVersion: u32, SDKPath: cstring) -> HRESULT, +} + + PFN_CREATE_DEVICE :: #type proc "c" (a0: ^IUnknown, a1: FEATURE_LEVEL, a2: ^IID, a3: ^rawptr) -> HRESULT PFN_GET_DEBUG_INTERFACE :: #type proc "c" (a0: ^IID, a1: ^rawptr) -> HRESULT diff --git a/vendor/directx/dxgi/dxgi.odin b/vendor/directx/dxgi/dxgi.odin index 5412747bc..235e07633 100644 --- a/vendor/directx/dxgi/dxgi.odin +++ b/vendor/directx/dxgi/dxgi.odin @@ -26,6 +26,8 @@ LONG :: win32.LONG RECT :: win32.RECT POINT :: win32.POINT SIZE :: win32.SIZE +WCHAR :: win32.WCHAR +DWORD :: win32.DWORD IUnknown :: struct { using _iunknown_vtable: ^IUnknown_VTable, @@ -38,10 +40,11 @@ IUnknown_VTable :: struct { @(default_calling_convention="system") foreign dxgi { - CreateDXGIFactory :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT --- - CreateDXGIFactory1 :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT --- - CreateDXGIFactory2 :: proc(Flags: CREATE_FACTORY, riid: ^IID, ppFactory: ^rawptr) -> HRESULT --- - DXGIGetDebugInterface1 :: proc(Flags: u32, riid: ^IID, pDebug: ^rawptr) -> HRESULT --- + CreateDXGIFactory :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT --- + CreateDXGIFactory1 :: proc(riid: ^IID, ppFactory: ^rawptr) -> HRESULT --- + CreateDXGIFactory2 :: proc(Flags: CREATE_FACTORY, riid: ^IID, ppFactory: ^rawptr) -> HRESULT --- + DXGIGetDebugInterface1 :: proc(Flags: u32, riid: ^IID, pDebug: ^rawptr) -> HRESULT --- + DeclareAdapterRemovalSupport :: proc() -> HRESULT --- } STANDARD_MULTISAMPLE_QUALITY_PATTERN :: 0xffffffff @@ -617,11 +620,11 @@ IDevice_VTable :: struct { SetGPUThreadPriority: proc "system" (this: ^IDevice, Priority: i32) -> HRESULT, GetGPUThreadPriority: proc "system" (this: ^IDevice, pPriority: ^i32) -> HRESULT, } -ADAPTER_FLAG :: enum u32 { // TODO: convert to bit_set - NONE = 0x0, - REMOTE = 0x1, - SOFTWARE = 0x2, - FORCE_DWORD = 0xffffffff, + +ADAPTER_FLAGS :: bit_set[ADAPTER_FLAG;u32] +ADAPTER_FLAG :: enum u32 { + REMOTE = 0, + SOFTWARE = 1, } ADAPTER_DESC1 :: struct { @@ -634,7 +637,7 @@ ADAPTER_DESC1 :: struct { DedicatedSystemMemory: SIZE_T, SharedSystemMemory: SIZE_T, AdapterLuid: LUID, - Flags: ADAPTER_FLAG, + Flags: ADAPTER_FLAGS, } DISPLAY_COLOR_SPACE :: struct { @@ -911,7 +914,7 @@ ADAPTER_DESC2 :: struct { DedicatedSystemMemory: SIZE_T, SharedSystemMemory: SIZE_T, AdapterLuid: LUID, - Flags: ADAPTER_FLAG, + Flags: ADAPTER_FLAGS, GraphicsPreemptionGranularity: GRAPHICS_PREEMPTION_GRANULARITY, ComputePreemptionGranularity: COMPUTE_PREEMPTION_GRANULARITY, } @@ -1165,6 +1168,199 @@ IAdapter3_VTable :: struct { UnregisterVideoMemoryBudgetChangeNotification: proc "system" (this: ^IAdapter3, dwCookie: u32), } +OUTDUPL_FLAG :: enum i32 { + COMPOSITED_UI_CAPTURE_ONLY = 1, +} + + +IOutput5_UUID_STRING :: "80A07424-AB52-42EB-833C-0C42FD282D98" +IOutput5_UUID := &IID{0x80A07424, 0xAB52, 0x42EB, {0x83, 0x3C, 0x0C, 0x42, 0xFD, 0x28, 0x2D, 0x98}} +IOutput5 :: struct #raw_union { + #subtype idxgioutput4: IOutput4, + using idxgioutput5_vtable: ^IOutput5_VTable, +} +IOutput5_VTable :: struct { + using idxgioutput4_vtable: IOutput4_VTable, + DuplicateOutput1: proc "system" (this: ^IOutput5, pDevice: ^IUnknown, Flags: u32, SupportedFormatsCount: u32, pSupportedFormats: ^FORMAT, ppOutputDuplication: ^^IOutputDuplication) -> HRESULT, +} + +HDR_METADATA_TYPE :: enum i32 { + NONE = 0, + HDR10 = 1, + HDR10PLUS = 2, +} + +HDR_METADATA_HDR10 :: struct { + RedPrimary: [2]u16, + GreenPrimary: [2]u16, + BluePrimary: [2]u16, + WhitePoint: [2]u16, + MaxMasteringLuminance: u32, + MinMasteringLuminance: u32, + MaxContentLightLevel: u16, + MaxFrameAverageLightLevel: u16, +} + +HDR_METADATA_HDR10PLUS :: struct { + Data: [72]byte, +} + + +ISwapChain4_UUID_STRING :: "3D585D5A-BD4A-489E-B1F4-3DBCB6452FFB" +ISwapChain4_UUID := &IID{0x3D585D5A, 0xBD4A, 0x489E, {0xB1, 0xF4, 0x3D, 0xBC, 0xB6, 0x45, 0x2F, 0xFB}} +ISwapChain4 :: struct #raw_union { + #subtype idxgiswapchain3: ISwapChain3, + using idxgiswapchain4_vtable: ^ISwapChain4_VTable, +} +ISwapChain4_VTable :: struct { + using idxgiswapchain3_vtable: ISwapChain3_VTable, + SetHDRMetaData: proc "system" (this: ^ISwapChain4, Type: HDR_METADATA_TYPE, Size: u32, pMetaData: rawptr) -> HRESULT, +} + +OFFER_RESOURCE_FLAGS :: bit_set[OFFER_RESOURCE_FLAG;u32] +OFFER_RESOURCE_FLAG :: enum u32 { + ALLOW_DECOMMIT = 0, +} + +RECLAIM_RESOURCE_RESULTS :: enum i32 { + OK = 0, + DISCARDED = 1, + NOT_COMMITTED = 2, +} + + +IDevice4_UUID_STRING :: "95B4F95F-D8DA-4CA4-9EE6-3B76D5968A10" +IDevice4_UUID := &IID{0x95B4F95F, 0xD8DA, 0x4CA4, {0x9E, 0xE6, 0x3B, 0x76, 0xD5, 0x96, 0x8A, 0x10}} +IDevice4 :: struct #raw_union { + #subtype idxgidevice3: IDevice3, + using idxgidevice4_vtable: ^IDevice4_VTable, +} +IDevice4_VTable :: struct { + using idxgidevice3_vtable: IDevice3_VTable, + OfferResources1: proc "system" (this: ^IDevice4, NumResources: u32, ppResources: ^^IResource, Priority: OFFER_RESOURCE_PRIORITY, Flags: OFFER_RESOURCE_FLAGS) -> HRESULT, + ReclaimResources1: proc "system" (this: ^IDevice4, NumResources: u32, ppResources: ^^IResource, pResults: ^RECLAIM_RESOURCE_RESULTS) -> HRESULT, +} + +FEATURE :: enum i32 { + PRESENT_ALLOW_TEARING = 0, +} + + +IFactory5_UUID_STRING :: "7632e1f5-ee65-4dca-87fd-84cd75f8838d" +IFactory5_UUID := &IID{0x7632e1f5, 0xee65, 0x4dca, {0x87, 0xfd, 0x84, 0xcd, 0x75, 0xf8, 0x83, 0x8d}} +IFactory5 :: struct #raw_union { + #subtype idxgifactory4: IFactory4, + using idxgifactory5_vtable: ^IFactory5_VTable, +} +IFactory5_VTable :: struct { + using idxgifactory4_vtable: IFactory4_VTable, + CheckFeatureSupport: proc "system" (this: ^IFactory5, Feature: FEATURE, pFeatureSupportData: rawptr, FeatureSupportDataSize: u32) -> HRESULT, +} + +ADAPTER_FLAGS3 :: bit_set[ADAPTER_FLAG3;u32] +ADAPTER_FLAG3 :: enum u32 { + REMOTE = 0, + SOFTWARE = 1, + ACG_COMPATIBLE = 3, + SUPPORT_MONITORED_FENCES = 4, + SUPPORT_NON_MONITORED_FENCES = 5, + KEYED_MUTEX_CONFORMANCE = 6, +} + +ADAPTER_DESC3 :: struct { + Description: [128]WCHAR, + VendorId: u32, + DeviceId: u32, + SubSysId: u32, + Revision: u32, + DedicatedVideoMemory: u64, + DedicatedSystemMemory: u64, + SharedSystemMemory: u64, + AdapterLuid: LUID, + Flags: ADAPTER_FLAGS3, + GraphicsPreemptionGranularity: GRAPHICS_PREEMPTION_GRANULARITY, + ComputePreemptionGranularity: COMPUTE_PREEMPTION_GRANULARITY, +} + + +IAdapter4_UUID_STRING :: "3c8d99d1-4fbf-4181-a82c-af66bf7bd24e" +IAdapter4_UUID := &IID{0x3c8d99d1, 0x4fbf, 0x4181, {0xa8, 0x2c, 0xaf, 0x66, 0xbf, 0x7b, 0xd2, 0x4e}} +IAdapter4 :: struct #raw_union { + #subtype idxgiadapter3: IAdapter3, + using idxgiadapter4_vtable: ^IAdapter4_VTable, +} +IAdapter4_VTable :: struct { + using idxgiadapter3_vtable: IAdapter3_VTable, + GetDesc3: proc "system" (this: ^IAdapter4, pDesc: ^ADAPTER_DESC3) -> HRESULT, +} + +OUTPUT_DESC1 :: struct { + DeviceName: [32]WCHAR, + DesktopCoordinates: RECT, + AttachedToDesktop: BOOL, + Rotation: MODE_ROTATION, + Monitor: HMONITOR, + BitsPerColor: u32, + ColorSpace: COLOR_SPACE_TYPE, + RedPrimary: [2]f32, + GreenPrimary: [2]f32, + BluePrimary: [2]f32, + WhitePoint: [2]f32, + MinLuminance: f32, + MaxLuminance: f32, + MaxFullFrameLuminance: f32, +} + +HARDWARE_COMPOSITION_SUPPORT_FLAGS :: bit_set[HARDWARE_COMPOSITION_SUPPORT_FLAG;u32] +HARDWARE_COMPOSITION_SUPPORT_FLAG :: enum u32 { + FULLSCREEN = 0, + WINDOWED = 1, + CURSOR_STRETCHED = 2, +} + + +IOutput6_UUID_STRING :: "068346e8-aaec-4b84-add7-137f513f77a1" +IOutput6_UUID := &IID{0x068346e8, 0xaaec, 0x4b84, {0xad, 0xd7, 0x13, 0x7f, 0x51, 0x3f, 0x77, 0xa1}} +IOutput6 :: struct #raw_union { + #subtype idxgioutput5: IOutput5, + using idxgioutput6_vtable: ^IOutput6_VTable, +} +IOutput6_VTable :: struct { + using idxgioutput5_vtable: IOutput5_VTable, + GetDesc1: proc "system" (this: ^IOutput6, pDesc: ^OUTPUT_DESC1) -> HRESULT, + CheckHardwareCompositionSupport: proc "system" (this: ^IOutput6, pFlags: ^HARDWARE_COMPOSITION_SUPPORT_FLAGS) -> HRESULT, +} + +GPU_PREFERENCE :: enum i32 { + UNSPECIFIED = 0, + MINIMUM_POWER = 1, + HIGH_PERFORMANCE = 2, +} + + +IFactory6_UUID_STRING :: "c1b6694f-ff09-44a9-b03c-77900a0a1d17" +IFactory6_UUID := &IID{0xc1b6694f, 0xff09, 0x44a9, {0xb0, 0x3c, 0x77, 0x90, 0x0a, 0x0a, 0x1d, 0x17}} +IFactory6 :: struct #raw_union { + #subtype idxgifactory5: IFactory5, + using idxgifactory6_vtable: ^IFactory6_VTable, +} +IFactory6_VTable :: struct { + using idxgifactory5_vtable: IFactory5_VTable, + EnumAdapterByGpuPreference: proc "system" (this: ^IFactory6, Adapter: u32, GpuPreference: GPU_PREFERENCE, riid: ^IID, ppvAdapter: ^rawptr) -> HRESULT, +} + +IFactory7_UUID_STRING :: "a4966eed-76db-44da-84c1-ee9a7afb20a8" +IFactory7_UUID := &IID{0xa4966eed, 0x76db, 0x44da, {0x84, 0xc1, 0xee, 0x9a, 0x7a, 0xfb, 0x20, 0xa8}} +IFactory7 :: struct #raw_union { + #subtype idxgifactory6: IFactory6, + using idxgifactory7_vtable: ^IFactory7_VTable, +} +IFactory7_VTable :: struct { + using idxgifactory6_vtable: IFactory6_VTable, + RegisterAdaptersChangedEvent: proc "system" (this: ^IFactory7, hEvent: HANDLE, pdwCookie: ^DWORD) -> HRESULT, + UnregisterAdaptersChangedEvent: proc "system" (this: ^IFactory7, dwCookie: DWORD) -> HRESULT, +} + ERROR_ACCESS_DENIED :: HRESULT(-2005270485) //0x887A002B ERROR_ACCESS_LOST :: HRESULT(-2005270490) //0x887A0026 ERROR_ALREADY_EXISTS :: HRESULT(-2005270474) //0x887A0036 @@ -1192,4 +1388,4 @@ ERROR_WAS_STILL_DRAWING :: HRESULT(-2005270518) //0x887A000A STATUS_OCCLUDED :: HRESULT( 142213121) //0x087A0001 STATUS_MODE_CHANGED :: HRESULT( 142213127) //0x087A0007 -STATUS_MODE_CHANGE_IN_PROGRESS :: HRESULT( 142213128) //0x087A0008 \ No newline at end of file +STATUS_MODE_CHANGE_IN_PROGRESS :: HRESULT( 142213128) //0x087A0008