mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
+241
-175
@@ -972,7 +972,7 @@ fmt_bad_verb :: proc(fi: ^Info, verb: rune) {
|
|||||||
//
|
//
|
||||||
fmt_bool :: proc(fi: ^Info, b: bool, verb: rune) {
|
fmt_bool :: proc(fi: ^Info, b: bool, verb: rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
case 't', 'v':
|
case 't', 'v', 'w':
|
||||||
fmt_string(fi, b ? "true" : "false", 's')
|
fmt_string(fi, b ? "true" : "false", 's')
|
||||||
case:
|
case:
|
||||||
fmt_bad_verb(fi, verb)
|
fmt_bad_verb(fi, verb)
|
||||||
@@ -1209,7 +1209,7 @@ fmt_rune :: proc(fi: ^Info, r: rune, verb: rune) {
|
|||||||
switch verb {
|
switch verb {
|
||||||
case 'c', 'r', 'v':
|
case 'c', 'r', 'v':
|
||||||
io.write_rune(fi.writer, r, &fi.n)
|
io.write_rune(fi.writer, r, &fi.n)
|
||||||
case 'q':
|
case 'q', 'w':
|
||||||
fi.n += io.write_quoted_rune(fi.writer, r)
|
fi.n += io.write_quoted_rune(fi.writer, r)
|
||||||
case:
|
case:
|
||||||
fmt_int(fi, u64(r), false, 32, verb)
|
fmt_int(fi, u64(r), false, 32, verb)
|
||||||
@@ -1226,7 +1226,8 @@ fmt_rune :: proc(fi: ^Info, r: rune, verb: rune) {
|
|||||||
//
|
//
|
||||||
fmt_int :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, verb: rune) {
|
fmt_int :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, verb: rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'v': _fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
case 'v', 'w':
|
||||||
|
_fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
||||||
case 'b': _fmt_int(fi, u, 2, is_signed, bit_size, __DIGITS_LOWER)
|
case 'b': _fmt_int(fi, u, 2, is_signed, bit_size, __DIGITS_LOWER)
|
||||||
case 'o': _fmt_int(fi, u, 8, is_signed, bit_size, __DIGITS_LOWER)
|
case 'o': _fmt_int(fi, u, 8, is_signed, bit_size, __DIGITS_LOWER)
|
||||||
case 'i', 'd': _fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
case 'i', 'd': _fmt_int(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
||||||
@@ -1261,7 +1262,8 @@ fmt_int :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, verb: rune) {
|
|||||||
//
|
//
|
||||||
fmt_int_128 :: proc(fi: ^Info, u: u128, is_signed: bool, bit_size: int, verb: rune) {
|
fmt_int_128 :: proc(fi: ^Info, u: u128, is_signed: bool, bit_size: int, verb: rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'v': _fmt_int_128(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
case 'v', 'w':
|
||||||
|
_fmt_int_128(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
||||||
case 'b': _fmt_int_128(fi, u, 2, is_signed, bit_size, __DIGITS_LOWER)
|
case 'b': _fmt_int_128(fi, u, 2, is_signed, bit_size, __DIGITS_LOWER)
|
||||||
case 'o': _fmt_int_128(fi, u, 8, is_signed, bit_size, __DIGITS_LOWER)
|
case 'o': _fmt_int_128(fi, u, 8, is_signed, bit_size, __DIGITS_LOWER)
|
||||||
case 'i', 'd': _fmt_int_128(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
case 'i', 'd': _fmt_int_128(fi, u, 10, is_signed, bit_size, __DIGITS_LOWER)
|
||||||
@@ -1351,7 +1353,7 @@ _fmt_float_as :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune, float_fmt: b
|
|||||||
//
|
//
|
||||||
fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
|
fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'g', 'G', 'v':
|
case 'g', 'G', 'v', 'w':
|
||||||
_fmt_float_as(fi, v, bit_size, verb, 'g', -1)
|
_fmt_float_as(fi, v, bit_size, verb, 'g', -1)
|
||||||
case 'f', 'F':
|
case 'f', 'F':
|
||||||
_fmt_float_as(fi, v, bit_size, verb, 'f', 3)
|
_fmt_float_as(fi, v, bit_size, verb, 'f', 3)
|
||||||
@@ -1424,7 +1426,7 @@ fmt_string :: proc(fi: ^Info, s: string, verb: rune) {
|
|||||||
io.write_string(fi.writer, s, &fi.n)
|
io.write_string(fi.writer, s, &fi.n)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'q': // quoted string
|
case 'q', 'w': // quoted string
|
||||||
io.write_quoted_string(fi.writer, s, '"', &fi.n)
|
io.write_quoted_string(fi.writer, s, '"', &fi.n)
|
||||||
|
|
||||||
case 'x', 'X':
|
case 'x', 'X':
|
||||||
@@ -1467,7 +1469,7 @@ fmt_cstring :: proc(fi: ^Info, s: cstring, verb: rune) {
|
|||||||
fmt_pointer :: proc(fi: ^Info, p: rawptr, verb: rune) {
|
fmt_pointer :: proc(fi: ^Info, p: rawptr, verb: rune) {
|
||||||
u := u64(uintptr(p))
|
u := u64(uintptr(p))
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'p', 'v':
|
case 'p', 'v', 'w':
|
||||||
if !fi.hash && verb == 'v' {
|
if !fi.hash && verb == 'v' {
|
||||||
io.write_string(fi.writer, "0x", &fi.n)
|
io.write_string(fi.writer, "0x", &fi.n)
|
||||||
}
|
}
|
||||||
@@ -1535,7 +1537,7 @@ string_to_enum_value :: proc($T: typeid, s: string) -> (T, bool) {
|
|||||||
// Inputs:
|
// Inputs:
|
||||||
// - fi: Pointer to the Info struct containing format settings.
|
// - fi: Pointer to the Info struct containing format settings.
|
||||||
// - v: The enum value to format.
|
// - v: The enum value to format.
|
||||||
// - verb: The format specifier character (e.g. 'i','d','f','s','v','q').
|
// - verb: The format specifier character (e.g. 'i','d','f','s','v','q','w').
|
||||||
//
|
//
|
||||||
fmt_enum :: proc(fi: ^Info, v: any, verb: rune) {
|
fmt_enum :: proc(fi: ^Info, v: any, verb: rune) {
|
||||||
if v.id == nil || v.data == nil {
|
if v.id == nil || v.data == nil {
|
||||||
@@ -1559,6 +1561,15 @@ fmt_enum :: proc(fi: ^Info, v: any, verb: rune) {
|
|||||||
fmt_arg(fi, any{v.data, runtime.type_info_base(e.base).id}, 'i')
|
fmt_arg(fi, any{v.data, runtime.type_info_base(e.base).id}, 'i')
|
||||||
io.write_string(fi.writer, ")", &fi.n)
|
io.write_string(fi.writer, ")", &fi.n)
|
||||||
}
|
}
|
||||||
|
case 'w':
|
||||||
|
if str, ok := enum_value_to_string(v); ok {
|
||||||
|
io.write_byte(fi.writer, '.', &fi.n)
|
||||||
|
io.write_string(fi.writer, str, &fi.n)
|
||||||
|
} else {
|
||||||
|
io.write_string(fi.writer, "%!(BAD ENUM VALUE=", &fi.n)
|
||||||
|
fmt_arg(fi, any{v.data, runtime.type_info_base(e.base).id}, 'i')
|
||||||
|
io.write_string(fi.writer, ")", &fi.n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1747,8 +1758,8 @@ fmt_write_indent :: proc(fi: ^Info) {
|
|||||||
// - verb: The formatting verb to be used for the array elements.
|
// - verb: The formatting verb to be used for the array elements.
|
||||||
//
|
//
|
||||||
fmt_write_array :: proc(fi: ^Info, array_data: rawptr, count: int, elem_size: int, elem_id: typeid, verb: rune) {
|
fmt_write_array :: proc(fi: ^Info, array_data: rawptr, count: int, elem_size: int, elem_id: typeid, verb: rune) {
|
||||||
io.write_byte(fi.writer, '[', &fi.n)
|
io.write_byte(fi.writer, '[' if verb != 'w' else '{', &fi.n)
|
||||||
defer io.write_byte(fi.writer, ']', &fi.n)
|
defer io.write_byte(fi.writer, ']' if verb != 'w' else '}', &fi.n)
|
||||||
|
|
||||||
if count <= 0 {
|
if count <= 0 {
|
||||||
return
|
return
|
||||||
@@ -1821,6 +1832,13 @@ handle_tag :: proc(data: rawptr, info: reflect.Type_Info_Struct, idx: int, verb:
|
|||||||
r, w := utf8.decode_rune_in_string(value)
|
r, w := utf8.decode_rune_in_string(value)
|
||||||
value = value[w:]
|
value = value[w:]
|
||||||
if value == "" || value[0] == ',' {
|
if value == "" || value[0] == ',' {
|
||||||
|
if verb^ == 'w' {
|
||||||
|
// TODO(bill): is this a good idea overriding that field tags if 'w' is used?
|
||||||
|
switch r {
|
||||||
|
case 's': r = 'q'
|
||||||
|
case: r = 'w'
|
||||||
|
}
|
||||||
|
}
|
||||||
verb^ = r
|
verb^ = r
|
||||||
if len(value) > 0 && value[0] == ',' {
|
if len(value) > 0 && value[0] == ',' {
|
||||||
field_name := value[1:]
|
field_name := value[1:]
|
||||||
@@ -1832,7 +1850,7 @@ handle_tag :: proc(data: rawptr, info: reflect.Type_Info_Struct, idx: int, verb:
|
|||||||
switch r {
|
switch r {
|
||||||
case 's', 'q':
|
case 's', 'q':
|
||||||
handle_optional_len(data, info, field_name, optional_len)
|
handle_optional_len(data, info, field_name, optional_len)
|
||||||
case 'v':
|
case 'v', 'w':
|
||||||
#partial switch reflect.type_kind(info.types[idx].id) {
|
#partial switch reflect.type_kind(info.types[idx].id) {
|
||||||
case .String, .Multi_Pointer, .Array, .Slice, .Dynamic_Array:
|
case .String, .Multi_Pointer, .Array, .Slice, .Dynamic_Array:
|
||||||
handle_optional_len(data, info, field_name, optional_len)
|
handle_optional_len(data, info, field_name, optional_len)
|
||||||
@@ -1854,7 +1872,7 @@ handle_tag :: proc(data: rawptr, info: reflect.Type_Info_Struct, idx: int, verb:
|
|||||||
// - type_name: The name of the type being formatted
|
// - type_name: The name of the type being formatted
|
||||||
//
|
//
|
||||||
fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_Struct, type_name: string) {
|
fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_Struct, type_name: string) {
|
||||||
if the_verb != 'v' {
|
if the_verb != 'v' && the_verb != 'w' {
|
||||||
fmt_bad_verb(fi, the_verb)
|
fmt_bad_verb(fi, the_verb)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -1871,7 +1889,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St
|
|||||||
is_soa := info.soa_kind != .None
|
is_soa := info.soa_kind != .None
|
||||||
|
|
||||||
io.write_string(fi.writer, type_name, &fi.n)
|
io.write_string(fi.writer, type_name, &fi.n)
|
||||||
io.write_byte(fi.writer, '[' if is_soa else '{', &fi.n)
|
io.write_byte(fi.writer, '[' if is_soa && the_verb == 'v' else '{', &fi.n)
|
||||||
fi.record_level += 1
|
fi.record_level += 1
|
||||||
defer fi.record_level -= 1
|
defer fi.record_level -= 1
|
||||||
|
|
||||||
@@ -1889,7 +1907,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St
|
|||||||
if hash {
|
if hash {
|
||||||
for _ in 0..<indent { io.write_byte(fi.writer, '\t', &fi.n) }
|
for _ in 0..<indent { io.write_byte(fi.writer, '\t', &fi.n) }
|
||||||
}
|
}
|
||||||
io.write_byte(fi.writer, ']' if is_soa else '}', &fi.n)
|
io.write_byte(fi.writer, ']' if is_soa && the_verb == 'v' else '}', &fi.n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_soa {
|
if is_soa {
|
||||||
@@ -1972,7 +1990,7 @@ fmt_struct :: proc(fi: ^Info, v: any, the_verb: rune, info: runtime.Type_Info_St
|
|||||||
for name, i in info.names {
|
for name, i in info.names {
|
||||||
optional_len: int = -1
|
optional_len: int = -1
|
||||||
use_nul_termination: bool = false
|
use_nul_termination: bool = false
|
||||||
verb := 'v'
|
verb := the_verb if the_verb == 'w' else 'v'
|
||||||
if handle_tag(v.data, info, i, &verb, &optional_len, &use_nul_termination) {
|
if handle_tag(v.data, info, i, &verb, &optional_len, &use_nul_termination) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -2051,7 +2069,7 @@ fmt_array_nul_terminated :: proc(fi: ^Info, data: rawptr, max_n: int, elem_size:
|
|||||||
// - n: The number of elements in the array.
|
// - n: The number of elements in the array.
|
||||||
// - elem_size: The size of each element in the array.
|
// - elem_size: The size of each element in the array.
|
||||||
// - elem: Pointer to the type information of the array element.
|
// - elem: Pointer to the type information of the array element.
|
||||||
// - verb: The formatting verb (e.g. 's','q','p').
|
// - verb: The formatting verb (e.g. 's','q','p','w').
|
||||||
//
|
//
|
||||||
fmt_array :: proc(fi: ^Info, data: rawptr, n: int, elem_size: int, elem: ^reflect.Type_Info, verb: rune) {
|
fmt_array :: proc(fi: ^Info, data: rawptr, n: int, elem_size: int, elem: ^reflect.Type_Info, verb: rune) {
|
||||||
if data == nil && n > 0 {
|
if data == nil && n > 0 {
|
||||||
@@ -2130,141 +2148,143 @@ fmt_named :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Named)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Built-in Custom Formatters for core library types
|
// Built-in Custom Formatters for core library types
|
||||||
switch a in v {
|
if verb != 'w' {
|
||||||
case runtime.Source_Code_Location:
|
switch a in v {
|
||||||
io.write_string(fi.writer, a.file_path, &fi.n)
|
case runtime.Source_Code_Location:
|
||||||
|
io.write_string(fi.writer, a.file_path, &fi.n)
|
||||||
|
|
||||||
when ODIN_ERROR_POS_STYLE == .Default {
|
when ODIN_ERROR_POS_STYLE == .Default {
|
||||||
io.write_byte(fi.writer, '(', &fi.n)
|
io.write_byte(fi.writer, '(', &fi.n)
|
||||||
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
||||||
io.write_byte(fi.writer, ':', &fi.n)
|
io.write_byte(fi.writer, ':', &fi.n)
|
||||||
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
||||||
io.write_byte(fi.writer, ')', &fi.n)
|
io.write_byte(fi.writer, ')', &fi.n)
|
||||||
} else when ODIN_ERROR_POS_STYLE == .Unix {
|
} else when ODIN_ERROR_POS_STYLE == .Unix {
|
||||||
io.write_byte(fi.writer, ':', &fi.n)
|
io.write_byte(fi.writer, ':', &fi.n)
|
||||||
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
io.write_int(fi.writer, int(a.line), 10, &fi.n)
|
||||||
io.write_byte(fi.writer, ':', &fi.n)
|
io.write_byte(fi.writer, ':', &fi.n)
|
||||||
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
io.write_int(fi.writer, int(a.column), 10, &fi.n)
|
||||||
io.write_byte(fi.writer, ':', &fi.n)
|
io.write_byte(fi.writer, ':', &fi.n)
|
||||||
} else {
|
|
||||||
#panic("Unhandled ODIN_ERROR_POS_STYLE")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
|
|
||||||
case time.Duration:
|
|
||||||
ffrac :: proc(buf: []byte, v: u64, prec: int) -> (nw: int, nv: u64) {
|
|
||||||
v := v
|
|
||||||
w := len(buf)
|
|
||||||
print := false
|
|
||||||
for _ in 0..<prec {
|
|
||||||
digit := v % 10
|
|
||||||
print = print || digit != 0
|
|
||||||
if print {
|
|
||||||
w -= 1
|
|
||||||
buf[w] = byte(digit) + '0'
|
|
||||||
}
|
|
||||||
v /= 10
|
|
||||||
}
|
|
||||||
if print {
|
|
||||||
w -= 1
|
|
||||||
buf[w] = '.'
|
|
||||||
}
|
|
||||||
return w, v
|
|
||||||
}
|
|
||||||
fint :: proc(buf: []byte, v: u64) -> int {
|
|
||||||
v := v
|
|
||||||
w := len(buf)
|
|
||||||
if v == 0 {
|
|
||||||
w -= 1
|
|
||||||
buf[w] = '0'
|
|
||||||
} else {
|
} else {
|
||||||
for v > 0 {
|
#panic("Unhandled ODIN_ERROR_POS_STYLE")
|
||||||
w -= 1
|
}
|
||||||
buf[w] = byte(v%10) + '0'
|
return
|
||||||
|
|
||||||
|
case time.Duration:
|
||||||
|
ffrac :: proc(buf: []byte, v: u64, prec: int) -> (nw: int, nv: u64) {
|
||||||
|
v := v
|
||||||
|
w := len(buf)
|
||||||
|
print := false
|
||||||
|
for _ in 0..<prec {
|
||||||
|
digit := v % 10
|
||||||
|
print = print || digit != 0
|
||||||
|
if print {
|
||||||
|
w -= 1
|
||||||
|
buf[w] = byte(digit) + '0'
|
||||||
|
}
|
||||||
v /= 10
|
v /= 10
|
||||||
}
|
}
|
||||||
|
if print {
|
||||||
|
w -= 1
|
||||||
|
buf[w] = '.'
|
||||||
|
}
|
||||||
|
return w, v
|
||||||
}
|
}
|
||||||
return w
|
fint :: proc(buf: []byte, v: u64) -> int {
|
||||||
}
|
v := v
|
||||||
|
w := len(buf)
|
||||||
buf: [32]byte
|
if v == 0 {
|
||||||
w := len(buf)
|
w -= 1
|
||||||
u := u64(a)
|
buf[w] = '0'
|
||||||
neg := a < 0
|
} else {
|
||||||
if neg {
|
for v > 0 {
|
||||||
u = -u
|
w -= 1
|
||||||
}
|
buf[w] = byte(v%10) + '0'
|
||||||
|
v /= 10
|
||||||
if u < u64(time.Second) {
|
}
|
||||||
prec: int
|
}
|
||||||
w -= 1
|
return w
|
||||||
buf[w] = 's'
|
|
||||||
w -= 1
|
|
||||||
switch {
|
|
||||||
case u == 0:
|
|
||||||
io.write_string(fi.writer, "0s", &fi.n)
|
|
||||||
return
|
|
||||||
case u < u64(time.Microsecond):
|
|
||||||
prec = 0
|
|
||||||
buf[w] = 'n'
|
|
||||||
case u < u64(time.Millisecond):
|
|
||||||
prec = 3
|
|
||||||
// U+00B5 'µ' micro sign == 0xC2 0xB5
|
|
||||||
w -= 1 // Need room for two bytes
|
|
||||||
copy(buf[w:], "µ")
|
|
||||||
case:
|
|
||||||
prec = 6
|
|
||||||
buf[w] = 'm'
|
|
||||||
}
|
}
|
||||||
w, u = ffrac(buf[:w], u, prec)
|
|
||||||
w = fint(buf[:w], u)
|
buf: [32]byte
|
||||||
} else {
|
w := len(buf)
|
||||||
w -= 1
|
u := u64(a)
|
||||||
buf[w] = 's'
|
neg := a < 0
|
||||||
w, u = ffrac(buf[:w], u, 9)
|
if neg {
|
||||||
w = fint(buf[:w], u%60)
|
u = -u
|
||||||
u /= 60
|
}
|
||||||
if u > 0 {
|
|
||||||
|
if u < u64(time.Second) {
|
||||||
|
prec: int
|
||||||
w -= 1
|
w -= 1
|
||||||
buf[w] = 'm'
|
buf[w] = 's'
|
||||||
|
w -= 1
|
||||||
|
switch {
|
||||||
|
case u == 0:
|
||||||
|
io.write_string(fi.writer, "0s", &fi.n)
|
||||||
|
return
|
||||||
|
case u < u64(time.Microsecond):
|
||||||
|
prec = 0
|
||||||
|
buf[w] = 'n'
|
||||||
|
case u < u64(time.Millisecond):
|
||||||
|
prec = 3
|
||||||
|
// U+00B5 'µ' micro sign == 0xC2 0xB5
|
||||||
|
w -= 1 // Need room for two bytes
|
||||||
|
copy(buf[w:], "µ")
|
||||||
|
case:
|
||||||
|
prec = 6
|
||||||
|
buf[w] = 'm'
|
||||||
|
}
|
||||||
|
w, u = ffrac(buf[:w], u, prec)
|
||||||
|
w = fint(buf[:w], u)
|
||||||
|
} else {
|
||||||
|
w -= 1
|
||||||
|
buf[w] = 's'
|
||||||
|
w, u = ffrac(buf[:w], u, 9)
|
||||||
w = fint(buf[:w], u%60)
|
w = fint(buf[:w], u%60)
|
||||||
u /= 60
|
u /= 60
|
||||||
if u > 0 {
|
if u > 0 {
|
||||||
w -= 1
|
w -= 1
|
||||||
buf[w] = 'h'
|
buf[w] = 'm'
|
||||||
w = fint(buf[:w], u)
|
w = fint(buf[:w], u%60)
|
||||||
|
u /= 60
|
||||||
|
if u > 0 {
|
||||||
|
w -= 1
|
||||||
|
buf[w] = 'h'
|
||||||
|
w = fint(buf[:w], u)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if neg {
|
||||||
|
w -= 1
|
||||||
|
buf[w] = '-'
|
||||||
|
}
|
||||||
|
io.write_string(fi.writer, string(buf[w:]), &fi.n)
|
||||||
|
return
|
||||||
|
|
||||||
|
case time.Time:
|
||||||
|
t := a
|
||||||
|
y, mon, d := time.date(t)
|
||||||
|
h, min, s := time.clock(t)
|
||||||
|
ns := (t._nsec - (t._nsec/1e9 + time.UNIX_TO_ABSOLUTE)*1e9) % 1e9
|
||||||
|
write_padded_number(fi, i64(y), 4)
|
||||||
|
io.write_byte(fi.writer, '-', &fi.n)
|
||||||
|
write_padded_number(fi, i64(mon), 2)
|
||||||
|
io.write_byte(fi.writer, '-', &fi.n)
|
||||||
|
write_padded_number(fi, i64(d), 2)
|
||||||
|
io.write_byte(fi.writer, ' ', &fi.n)
|
||||||
|
|
||||||
|
write_padded_number(fi, i64(h), 2)
|
||||||
|
io.write_byte(fi.writer, ':', &fi.n)
|
||||||
|
write_padded_number(fi, i64(min), 2)
|
||||||
|
io.write_byte(fi.writer, ':', &fi.n)
|
||||||
|
write_padded_number(fi, i64(s), 2)
|
||||||
|
io.write_byte(fi.writer, '.', &fi.n)
|
||||||
|
write_padded_number(fi, (ns), 9)
|
||||||
|
io.write_string(fi.writer, " +0000 UTC", &fi.n)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if neg {
|
|
||||||
w -= 1
|
|
||||||
buf[w] = '-'
|
|
||||||
}
|
|
||||||
io.write_string(fi.writer, string(buf[w:]), &fi.n)
|
|
||||||
return
|
|
||||||
|
|
||||||
case time.Time:
|
|
||||||
t := a
|
|
||||||
y, mon, d := time.date(t)
|
|
||||||
h, min, s := time.clock(t)
|
|
||||||
ns := (t._nsec - (t._nsec/1e9 + time.UNIX_TO_ABSOLUTE)*1e9) % 1e9
|
|
||||||
write_padded_number(fi, i64(y), 4)
|
|
||||||
io.write_byte(fi.writer, '-', &fi.n)
|
|
||||||
write_padded_number(fi, i64(mon), 2)
|
|
||||||
io.write_byte(fi.writer, '-', &fi.n)
|
|
||||||
write_padded_number(fi, i64(d), 2)
|
|
||||||
io.write_byte(fi.writer, ' ', &fi.n)
|
|
||||||
|
|
||||||
write_padded_number(fi, i64(h), 2)
|
|
||||||
io.write_byte(fi.writer, ':', &fi.n)
|
|
||||||
write_padded_number(fi, i64(min), 2)
|
|
||||||
io.write_byte(fi.writer, ':', &fi.n)
|
|
||||||
write_padded_number(fi, i64(s), 2)
|
|
||||||
io.write_byte(fi.writer, '.', &fi.n)
|
|
||||||
write_padded_number(fi, (ns), 9)
|
|
||||||
io.write_string(fi.writer, " +0000 UTC", &fi.n)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#partial switch b in info.base.variant {
|
#partial switch b in info.base.variant {
|
||||||
@@ -2275,6 +2295,23 @@ fmt_named :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Named)
|
|||||||
case runtime.Type_Info_Bit_Set:
|
case runtime.Type_Info_Bit_Set:
|
||||||
fmt_bit_set(fi, v, verb = verb)
|
fmt_bit_set(fi, v, verb = verb)
|
||||||
case:
|
case:
|
||||||
|
if verb == 'w' {
|
||||||
|
#partial switch _ in info.base.variant {
|
||||||
|
case runtime.Type_Info_Array,
|
||||||
|
runtime.Type_Info_Enumerated_Array,
|
||||||
|
runtime.Type_Info_Dynamic_Array,
|
||||||
|
runtime.Type_Info_Slice,
|
||||||
|
runtime.Type_Info_Struct,
|
||||||
|
runtime.Type_Info_Union,
|
||||||
|
runtime.Type_Info_Enum,
|
||||||
|
runtime.Type_Info_Map,
|
||||||
|
runtime.Type_Info_Bit_Set,
|
||||||
|
runtime.Type_Info_Simd_Vector,
|
||||||
|
runtime.Type_Info_Matrix,
|
||||||
|
runtime.Type_Info_Bit_Field:
|
||||||
|
io.write_string(fi.writer, info.name, &fi.n)
|
||||||
|
}
|
||||||
|
}
|
||||||
fmt_value(fi, any{v.data, info.base.id}, verb)
|
fmt_value(fi, any{v.data, info.base.id}, verb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2341,8 +2378,13 @@ fmt_union :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Union,
|
|||||||
// - info: A runtime.Type_Info_Matrix struct containing matrix type information.
|
// - info: A runtime.Type_Info_Matrix struct containing matrix type information.
|
||||||
//
|
//
|
||||||
fmt_matrix :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Matrix) {
|
fmt_matrix :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Matrix) {
|
||||||
io.write_string(fi.writer, "matrix[", &fi.n)
|
if verb == 'w' {
|
||||||
defer io.write_byte(fi.writer, ']', &fi.n)
|
io.write_byte(fi.writer, '{', &fi.n)
|
||||||
|
} else {
|
||||||
|
io.write_string(fi.writer, "matrix", &fi.n)
|
||||||
|
io.write_byte(fi.writer, '[', &fi.n)
|
||||||
|
}
|
||||||
|
defer io.write_byte(fi.writer, ']' if verb != 'w' else '}', &fi.n)
|
||||||
|
|
||||||
fi.indent += 1
|
fi.indent += 1
|
||||||
|
|
||||||
@@ -2413,8 +2455,8 @@ fmt_bit_field :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Bit
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
io.write_string(fi.writer, type_name if len(type_name) != 0 else "bit_field", &fi.n)
|
io.write_string(fi.writer, type_name if len(type_name) != 0 || verb == 'w' else "bit_field", &fi.n)
|
||||||
io.write_string(fi.writer, "{", &fi.n)
|
io.write_byte(fi.writer, '{', &fi.n)
|
||||||
|
|
||||||
hash := fi.hash; defer fi.hash = hash
|
hash := fi.hash; defer fi.hash = hash
|
||||||
indent := fi.indent; defer fi.indent -= 1
|
indent := fi.indent; defer fi.indent -= 1
|
||||||
@@ -2631,11 +2673,12 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
|||||||
defer fi.record_level -= 1
|
defer fi.record_level -= 1
|
||||||
|
|
||||||
if fi.hash {
|
if fi.hash {
|
||||||
io.write_string(fi.writer, "[\n", &fi.n)
|
io.write_byte(fi.writer, '[' if verb != 'w' else '{', &fi.n)
|
||||||
|
io.write_byte(fi.writer, '\n', &fi.n)
|
||||||
defer {
|
defer {
|
||||||
io.write_byte(fi.writer, '\n', &fi.n)
|
io.write_byte(fi.writer, '\n', &fi.n)
|
||||||
fmt_write_indent(fi)
|
fmt_write_indent(fi)
|
||||||
io.write_byte(fi.writer, ']', &fi.n)
|
io.write_byte(fi.writer, ']' if verb != 'w' else '}', &fi.n)
|
||||||
}
|
}
|
||||||
indent := fi.indent
|
indent := fi.indent
|
||||||
fi.indent += 1
|
fi.indent += 1
|
||||||
@@ -2659,8 +2702,8 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
|||||||
io.write_string(fi.writer, ",\n", &fi.n)
|
io.write_string(fi.writer, ",\n", &fi.n)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
io.write_byte(fi.writer, '[', &fi.n)
|
io.write_byte(fi.writer, '[' if verb != 'w' else '{', &fi.n)
|
||||||
defer io.write_byte(fi.writer, ']', &fi.n)
|
io.write_byte(fi.writer, ']' if verb != 'w' else '}', &fi.n)
|
||||||
for i in 0..<info.count {
|
for i in 0..<info.count {
|
||||||
if i > 0 { io.write_string(fi.writer, ", ", &fi.n) }
|
if i > 0 { io.write_string(fi.writer, ", ", &fi.n) }
|
||||||
|
|
||||||
@@ -2725,38 +2768,61 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
|||||||
|
|
||||||
|
|
||||||
case runtime.Type_Info_Map:
|
case runtime.Type_Info_Map:
|
||||||
if verb != 'v' {
|
switch verb {
|
||||||
|
case:
|
||||||
fmt_bad_verb(fi, verb)
|
fmt_bad_verb(fi, verb)
|
||||||
return
|
case 'v', 'w':
|
||||||
}
|
if verb == 'v' {
|
||||||
|
io.write_string(fi.writer, "map", &fi.n)
|
||||||
io.write_string(fi.writer, "map[", &fi.n)
|
|
||||||
defer io.write_byte(fi.writer, ']', &fi.n)
|
|
||||||
fi.record_level += 1
|
|
||||||
defer fi.record_level -= 1
|
|
||||||
|
|
||||||
m := (^mem.Raw_Map)(v.data)
|
|
||||||
if m != nil {
|
|
||||||
if info.map_info == nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
map_cap := uintptr(runtime.map_cap(m^))
|
io.write_byte(fi.writer, '[' if verb != 'w' else '{', &fi.n)
|
||||||
ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(m^, info.map_info)
|
defer io.write_byte(fi.writer, ']' if verb != 'w' else '}', &fi.n)
|
||||||
j := 0
|
|
||||||
for bucket_index in 0..<map_cap {
|
|
||||||
runtime.map_hash_is_valid(hs[bucket_index]) or_continue
|
|
||||||
|
|
||||||
if j > 0 {
|
|
||||||
io.write_string(fi.writer, ", ", &fi.n)
|
hash := fi.hash; defer fi.hash = hash
|
||||||
|
indent := fi.indent; defer fi.indent -= 1
|
||||||
|
do_trailing_comma := hash
|
||||||
|
|
||||||
|
fi.indent += 1
|
||||||
|
if hash {
|
||||||
|
io.write_byte(fi.writer, '\n', &fi.n)
|
||||||
|
}
|
||||||
|
defer {
|
||||||
|
if hash {
|
||||||
|
for _ in 0..<indent { io.write_byte(fi.writer, '\t', &fi.n) }
|
||||||
}
|
}
|
||||||
j += 1
|
}
|
||||||
|
|
||||||
key := runtime.map_cell_index_dynamic(ks, info.map_info.ks, bucket_index)
|
m := (^mem.Raw_Map)(v.data)
|
||||||
value := runtime.map_cell_index_dynamic(vs, info.map_info.vs, bucket_index)
|
if m != nil {
|
||||||
|
if info.map_info == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
map_cap := uintptr(runtime.map_cap(m^))
|
||||||
|
ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(m^, info.map_info)
|
||||||
|
j := 0
|
||||||
|
for bucket_index in 0..<map_cap {
|
||||||
|
runtime.map_hash_is_valid(hs[bucket_index]) or_continue
|
||||||
|
|
||||||
fmt_arg(&Info{writer = fi.writer}, any{rawptr(key), info.key.id}, 'v')
|
if !do_trailing_comma && j > 0 { io.write_string(fi.writer, ", ") }
|
||||||
io.write_string(fi.writer, "=", &fi.n)
|
if hash {
|
||||||
fmt_arg(fi, any{rawptr(value), info.value.id}, 'v')
|
fmt_write_indent(fi)
|
||||||
|
}
|
||||||
|
j += 1
|
||||||
|
|
||||||
|
key := runtime.map_cell_index_dynamic(ks, info.map_info.ks, bucket_index)
|
||||||
|
value := runtime.map_cell_index_dynamic(vs, info.map_info.vs, bucket_index)
|
||||||
|
|
||||||
|
fmt_arg(&Info{writer = fi.writer}, any{rawptr(key), info.key.id}, verb)
|
||||||
|
if verb == 'v' {
|
||||||
|
io.write_string(fi.writer, "=", &fi.n)
|
||||||
|
} else {
|
||||||
|
io.write_string(fi.writer, " = ", &fi.n)
|
||||||
|
}
|
||||||
|
fmt_arg(fi, any{rawptr(value), info.value.id}, verb)
|
||||||
|
|
||||||
|
if do_trailing_comma { io.write_string(fi.writer, ",\n", &fi.n) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2811,11 +2877,11 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
|||||||
// - fi: A pointer to an Info struct containing formatting information.
|
// - fi: A pointer to an Info struct containing formatting information.
|
||||||
// - c: The complex128 value to be formatted.
|
// - c: The complex128 value to be formatted.
|
||||||
// - bits: The number of bits in the complex number (32 or 64).
|
// - bits: The number of bits in the complex number (32 or 64).
|
||||||
// - verb: The formatting verb rune ('f', 'F', 'v', 'h', 'H').
|
// - verb: The formatting verb rune ('f', 'F', 'v', 'h', 'H', 'w').
|
||||||
//
|
//
|
||||||
fmt_complex :: proc(fi: ^Info, c: complex128, bits: int, verb: rune) {
|
fmt_complex :: proc(fi: ^Info, c: complex128, bits: int, verb: rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'f', 'F', 'v', 'h', 'H':
|
case 'f', 'F', 'v', 'h', 'H', 'w':
|
||||||
r, i := real(c), imag(c)
|
r, i := real(c), imag(c)
|
||||||
fmt_float(fi, r, bits/2, verb)
|
fmt_float(fi, r, bits/2, verb)
|
||||||
if !fi.plus && i >= 0 {
|
if !fi.plus && i >= 0 {
|
||||||
@@ -2835,11 +2901,11 @@ fmt_complex :: proc(fi: ^Info, c: complex128, bits: int, verb: rune) {
|
|||||||
// - fi: A pointer to an Info struct containing formatting information.
|
// - fi: A pointer to an Info struct containing formatting information.
|
||||||
// - q: The quaternion256 value to be formatted.
|
// - q: The quaternion256 value to be formatted.
|
||||||
// - bits: The number of bits in the quaternion number (64, 128, or 256).
|
// - bits: The number of bits in the quaternion number (64, 128, or 256).
|
||||||
// - verb: The formatting verb rune ('f', 'F', 'v', 'h', 'H').
|
// - verb: The formatting verb rune ('f', 'F', 'v', 'h', 'H', 'w').
|
||||||
//
|
//
|
||||||
fmt_quaternion :: proc(fi: ^Info, q: quaternion256, bits: int, verb: rune) {
|
fmt_quaternion :: proc(fi: ^Info, q: quaternion256, bits: int, verb: rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'f', 'F', 'v', 'h', 'H':
|
case 'f', 'F', 'v', 'h', 'H', 'w':
|
||||||
r, i, j, k := real(q), imag(q), jmag(q), kmag(q)
|
r, i, j, k := real(q), imag(q), jmag(q), kmag(q)
|
||||||
|
|
||||||
fmt_float(fi, r, bits/4, verb)
|
fmt_float(fi, r, bits/4, verb)
|
||||||
|
|||||||
+32
-10
@@ -17,18 +17,23 @@ Arena_Kind :: enum uint {
|
|||||||
Buffer: A single `Memory_Block` created from a user provided []byte.
|
Buffer: A single `Memory_Block` created from a user provided []byte.
|
||||||
*/
|
*/
|
||||||
Arena :: struct {
|
Arena :: struct {
|
||||||
kind: Arena_Kind,
|
kind: Arena_Kind,
|
||||||
curr_block: ^Memory_Block,
|
curr_block: ^Memory_Block,
|
||||||
total_used: uint,
|
|
||||||
total_reserved: uint,
|
total_used: uint,
|
||||||
minimum_block_size: uint,
|
total_reserved: uint,
|
||||||
temp_count: uint,
|
|
||||||
mutex: sync.Mutex,
|
default_commit_size: uint, // commit size <= reservation size
|
||||||
|
minimum_block_size: uint, // block size == total reservation
|
||||||
|
|
||||||
|
temp_count: uint,
|
||||||
|
mutex: sync.Mutex,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 1 MiB should be enough to start with
|
// 1 MiB should be enough to start with
|
||||||
DEFAULT_ARENA_STATIC_COMMIT_SIZE :: mem.Megabyte
|
DEFAULT_ARENA_STATIC_COMMIT_SIZE :: mem.Megabyte
|
||||||
|
DEFAULT_ARENA_GROWING_COMMIT_SIZE :: 8*mem.Megabyte
|
||||||
DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE :: DEFAULT_ARENA_STATIC_COMMIT_SIZE
|
DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE :: DEFAULT_ARENA_STATIC_COMMIT_SIZE
|
||||||
|
|
||||||
// 1 GiB on 64-bit systems, 128 MiB on 32-bit systems by default
|
// 1 GiB on 64-bit systems, 128 MiB on 32-bit systems by default
|
||||||
@@ -102,8 +107,20 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l
|
|||||||
if arena.curr_block == nil || (safe_add(arena.curr_block.used, needed) or_else 0) > arena.curr_block.reserved {
|
if arena.curr_block == nil || (safe_add(arena.curr_block.used, needed) or_else 0) > arena.curr_block.reserved {
|
||||||
if arena.minimum_block_size == 0 {
|
if arena.minimum_block_size == 0 {
|
||||||
arena.minimum_block_size = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE
|
arena.minimum_block_size = DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE
|
||||||
|
arena.minimum_block_size = mem.align_forward_uint(arena.minimum_block_size, DEFAULT_PAGE_SIZE)
|
||||||
|
}
|
||||||
|
if arena.default_commit_size == 0 {
|
||||||
|
arena.default_commit_size = min(DEFAULT_ARENA_GROWING_COMMIT_SIZE, arena.minimum_block_size)
|
||||||
|
arena.default_commit_size = mem.align_forward_uint(arena.default_commit_size, DEFAULT_PAGE_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if arena.default_commit_size != 0 {
|
||||||
|
arena.default_commit_size, arena.minimum_block_size =
|
||||||
|
min(arena.default_commit_size, arena.minimum_block_size),
|
||||||
|
max(arena.default_commit_size, arena.minimum_block_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
needed = max(needed, arena.default_commit_size)
|
||||||
block_size := max(needed, arena.minimum_block_size)
|
block_size := max(needed, arena.minimum_block_size)
|
||||||
|
|
||||||
new_block := memory_block_alloc(needed, block_size, alignment, {}) or_return
|
new_block := memory_block_alloc(needed, block_size, alignment, {}) or_return
|
||||||
@@ -113,7 +130,7 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l
|
|||||||
}
|
}
|
||||||
|
|
||||||
prev_used := arena.curr_block.used
|
prev_used := arena.curr_block.used
|
||||||
data, err = alloc_from_memory_block(arena.curr_block, size, alignment)
|
data, err = alloc_from_memory_block(arena.curr_block, size, alignment, default_commit_size=arena.default_commit_size)
|
||||||
arena.total_used += arena.curr_block.used - prev_used
|
arena.total_used += arena.curr_block.used - prev_used
|
||||||
case .Static:
|
case .Static:
|
||||||
if arena.curr_block == nil {
|
if arena.curr_block == nil {
|
||||||
@@ -122,12 +139,17 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l
|
|||||||
}
|
}
|
||||||
arena_init_static(arena, reserved=arena.minimum_block_size, commit_size=DEFAULT_ARENA_STATIC_COMMIT_SIZE) or_return
|
arena_init_static(arena, reserved=arena.minimum_block_size, commit_size=DEFAULT_ARENA_STATIC_COMMIT_SIZE) or_return
|
||||||
}
|
}
|
||||||
fallthrough
|
if arena.curr_block == nil {
|
||||||
|
return nil, .Out_Of_Memory
|
||||||
|
}
|
||||||
|
data, err = alloc_from_memory_block(arena.curr_block, size, alignment, default_commit_size=arena.default_commit_size)
|
||||||
|
arena.total_used = arena.curr_block.used
|
||||||
|
|
||||||
case .Buffer:
|
case .Buffer:
|
||||||
if arena.curr_block == nil {
|
if arena.curr_block == nil {
|
||||||
return nil, .Out_Of_Memory
|
return nil, .Out_Of_Memory
|
||||||
}
|
}
|
||||||
data, err = alloc_from_memory_block(arena.curr_block, size, alignment)
|
data, err = alloc_from_memory_block(arena.curr_block, size, alignment, default_commit_size=0)
|
||||||
arena.total_used = arena.curr_block.used
|
arena.total_used = arena.curr_block.used
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ memory_block_alloc :: proc(committed, reserved: uint, alignment: uint = 0, flags
|
|||||||
}
|
}
|
||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint) -> (data: []byte, err: Allocator_Error) {
|
alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint, default_commit_size: uint = 0) -> (data: []byte, err: Allocator_Error) {
|
||||||
calc_alignment_offset :: proc "contextless" (block: ^Memory_Block, alignment: uintptr) -> uint {
|
calc_alignment_offset :: proc "contextless" (block: ^Memory_Block, alignment: uintptr) -> uint {
|
||||||
alignment_offset := uint(0)
|
alignment_offset := uint(0)
|
||||||
ptr := uintptr(block.base[block.used:])
|
ptr := uintptr(block.base[block.used:])
|
||||||
@@ -123,7 +123,7 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint)
|
|||||||
return alignment_offset
|
return alignment_offset
|
||||||
|
|
||||||
}
|
}
|
||||||
do_commit_if_necessary :: proc(block: ^Memory_Block, size: uint) -> (err: Allocator_Error) {
|
do_commit_if_necessary :: proc(block: ^Memory_Block, size: uint, default_commit_size: uint) -> (err: Allocator_Error) {
|
||||||
if block.committed - block.used < size {
|
if block.committed - block.used < size {
|
||||||
pmblock := (^Platform_Memory_Block)(block)
|
pmblock := (^Platform_Memory_Block)(block)
|
||||||
base_offset := uint(uintptr(pmblock.block.base) - uintptr(pmblock))
|
base_offset := uint(uintptr(pmblock.block.base) - uintptr(pmblock))
|
||||||
@@ -133,7 +133,7 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint)
|
|||||||
extra_size := max(size, block.committed>>1)
|
extra_size := max(size, block.committed>>1)
|
||||||
platform_total_commit := base_offset + block.used + extra_size
|
platform_total_commit := base_offset + block.used + extra_size
|
||||||
platform_total_commit = align_formula(platform_total_commit, DEFAULT_PAGE_SIZE)
|
platform_total_commit = align_formula(platform_total_commit, DEFAULT_PAGE_SIZE)
|
||||||
platform_total_commit = min(platform_total_commit, pmblock.reserved)
|
platform_total_commit = min(max(platform_total_commit, default_commit_size), pmblock.reserved)
|
||||||
|
|
||||||
assert(pmblock.committed <= pmblock.reserved)
|
assert(pmblock.committed <= pmblock.reserved)
|
||||||
assert(pmblock.committed < platform_total_commit)
|
assert(pmblock.committed < platform_total_commit)
|
||||||
@@ -163,7 +163,7 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert(block.committed <= block.reserved)
|
assert(block.committed <= block.reserved)
|
||||||
do_commit_if_necessary(block, size) or_return
|
do_commit_if_necessary(block, size, default_commit_size) or_return
|
||||||
|
|
||||||
data = block.base[block.used+alignment_offset:][:min_size]
|
data = block.base[block.used+alignment_offset:][:min_size]
|
||||||
block.used += size
|
block.used += size
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// +build windows
|
// +build windows
|
||||||
package sys_windows
|
package sys_windows
|
||||||
|
|
||||||
|
import "core:math/fixed"
|
||||||
|
|
||||||
foreign import gdi32 "system:Gdi32.lib"
|
foreign import gdi32 "system:Gdi32.lib"
|
||||||
|
|
||||||
@(default_calling_convention="system")
|
@(default_calling_convention="system")
|
||||||
@@ -11,6 +13,7 @@ foreign gdi32 {
|
|||||||
SetBkColor :: proc(hdc: HDC, color: COLORREF) -> COLORREF ---
|
SetBkColor :: proc(hdc: HDC, color: COLORREF) -> COLORREF ---
|
||||||
|
|
||||||
CreateCompatibleDC :: proc(hdc: HDC) -> HDC ---
|
CreateCompatibleDC :: proc(hdc: HDC) -> HDC ---
|
||||||
|
DeleteDC :: proc(hdc: HDC) -> BOOL ---
|
||||||
|
|
||||||
CreateDIBPatternBrush :: proc(h: HGLOBAL, iUsage: UINT) -> HBRUSH ---
|
CreateDIBPatternBrush :: proc(h: HGLOBAL, iUsage: UINT) -> HBRUSH ---
|
||||||
|
|
||||||
@@ -93,3 +96,45 @@ foreign gdi32 {
|
|||||||
RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF {
|
RGB :: #force_inline proc "contextless" (r, g, b: u8) -> COLORREF {
|
||||||
return transmute(COLORREF)[4]u8{r, g, b, 0}
|
return transmute(COLORREF)[4]u8{r, g, b, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FXPT2DOT30 :: distinct fixed.Fixed(i32, 30)
|
||||||
|
|
||||||
|
CIEXYZ :: struct {
|
||||||
|
ciexyzX: FXPT2DOT30,
|
||||||
|
ciexyzY: FXPT2DOT30,
|
||||||
|
ciexyzZ: FXPT2DOT30,
|
||||||
|
}
|
||||||
|
|
||||||
|
CIEXYZTRIPLE :: struct {
|
||||||
|
ciexyzRed: CIEXYZ,
|
||||||
|
ciexyzGreen: CIEXYZ,
|
||||||
|
ciexyzBlue: CIEXYZ,
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapv5header
|
||||||
|
BITMAPV5HEADER :: struct {
|
||||||
|
bV5Size: DWORD,
|
||||||
|
bV5Width: LONG,
|
||||||
|
bV5Height: LONG,
|
||||||
|
bV5Planes: WORD,
|
||||||
|
bV5BitCount: WORD,
|
||||||
|
bV5Compression: DWORD,
|
||||||
|
bV5SizeImage: DWORD,
|
||||||
|
bV5XPelsPerMeter: LONG,
|
||||||
|
bV5YPelsPerMeter: LONG,
|
||||||
|
bV5ClrUsed: DWORD,
|
||||||
|
bV5ClrImportant: DWORD,
|
||||||
|
bV5RedMask: DWORD,
|
||||||
|
bV5GreenMask: DWORD,
|
||||||
|
bV5BlueMask: DWORD,
|
||||||
|
bV5AlphaMask: DWORD,
|
||||||
|
bV5CSType: DWORD,
|
||||||
|
bV5Endpoints: CIEXYZTRIPLE,
|
||||||
|
bV5GammaRed: DWORD,
|
||||||
|
bV5GammaGreen: DWORD,
|
||||||
|
bV5GammaBlue: DWORD,
|
||||||
|
bV5Intent: DWORD,
|
||||||
|
bV5ProfileData: DWORD,
|
||||||
|
bV5ProfileSize: DWORD,
|
||||||
|
bV5Reserved: DWORD,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1200,3 +1200,22 @@ SYSTEM_LOGICAL_PROCESSOR_INFORMATION :: struct {
|
|||||||
Relationship: LOGICAL_PROCESSOR_RELATIONSHIP,
|
Relationship: LOGICAL_PROCESSOR_RELATIONSHIP,
|
||||||
DummyUnion: DUMMYUNIONNAME_u,
|
DummyUnion: DUMMYUNIONNAME_u,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Global Memory Flags */
|
||||||
|
GMEM_FIXED :: 0x0000
|
||||||
|
GMEM_MOVEABLE :: 0x0002
|
||||||
|
GMEM_NOCOMPACT :: 0x0010
|
||||||
|
GMEM_NODISCARD :: 0x0020
|
||||||
|
GMEM_ZEROINIT :: 0x0040
|
||||||
|
GMEM_MODIFY :: 0x0080
|
||||||
|
GMEM_DISCARDABLE :: 0x0100
|
||||||
|
GMEM_NOT_BANKED :: 0x1000
|
||||||
|
GMEM_SHARE :: 0x2000
|
||||||
|
GMEM_DDESHARE :: 0x2000
|
||||||
|
GMEM_NOTIFY :: 0x4000
|
||||||
|
GMEM_LOWER :: GMEM_NOT_BANKED
|
||||||
|
GMEM_VALID_FLAGS :: 0x7F72
|
||||||
|
GMEM_INVALID_HANDLE :: 0x8000
|
||||||
|
|
||||||
|
GHND :: (GMEM_MOVEABLE | GMEM_ZEROINIT)
|
||||||
|
GPTR :: (GMEM_FIXED | GMEM_ZEROINIT)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ foreign shell32 {
|
|||||||
SHAppBarMessage :: proc(dwMessage: DWORD, pData: PAPPBARDATA) -> UINT_PTR ---
|
SHAppBarMessage :: proc(dwMessage: DWORD, pData: PAPPBARDATA) -> UINT_PTR ---
|
||||||
|
|
||||||
Shell_NotifyIconW :: proc(dwMessage: DWORD, lpData: ^NOTIFYICONDATAW) -> BOOL ---
|
Shell_NotifyIconW :: proc(dwMessage: DWORD, lpData: ^NOTIFYICONDATAW) -> BOOL ---
|
||||||
|
SHChangeNotify :: proc(wEventId: LONG, uFlags: UINT, dwItem1: LPCVOID, dwItem2: LPCVOID) ---
|
||||||
|
|
||||||
SHGetKnownFolderIDList :: proc(rfid: REFKNOWNFOLDERID, dwFlags: /* KNOWN_FOLDER_FLAG */ DWORD, hToken: HANDLE, ppidl: rawptr) -> HRESULT ---
|
SHGetKnownFolderIDList :: proc(rfid: REFKNOWNFOLDERID, dwFlags: /* KNOWN_FOLDER_FLAG */ DWORD, hToken: HANDLE, ppidl: rawptr) -> HRESULT ---
|
||||||
SHSetKnownFolderPath :: proc(rfid: REFKNOWNFOLDERID, dwFlags: /* KNOWN_FOLDER_FLAG */ DWORD, hToken: HANDLE, pszPath: PCWSTR ) -> HRESULT ---
|
SHSetKnownFolderPath :: proc(rfid: REFKNOWNFOLDERID, dwFlags: /* KNOWN_FOLDER_FLAG */ DWORD, hToken: HANDLE, pszPath: PCWSTR ) -> HRESULT ---
|
||||||
@@ -91,3 +92,53 @@ KNOWN_FOLDER_FLAG :: enum u32 {
|
|||||||
SIMPLE_IDLIST = 0x00000100,
|
SIMPLE_IDLIST = 0x00000100,
|
||||||
ALIAS_ONLY = 0x80000000,
|
ALIAS_ONLY = 0x80000000,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHCNRF_InterruptLevel :: 0x0001
|
||||||
|
SHCNRF_ShellLevel :: 0x0002
|
||||||
|
SHCNRF_RecursiveInterrupt :: 0x1000
|
||||||
|
SHCNRF_NewDelivery :: 0x8000
|
||||||
|
|
||||||
|
SHCNE_RENAMEITEM :: 0x00000001
|
||||||
|
SHCNE_CREATE :: 0x00000002
|
||||||
|
SHCNE_DELETE :: 0x00000004
|
||||||
|
SHCNE_MKDIR :: 0x00000008
|
||||||
|
SHCNE_RMDIR :: 0x00000010
|
||||||
|
SHCNE_MEDIAINSERTED :: 0x00000020
|
||||||
|
SHCNE_MEDIAREMOVED :: 0x00000040
|
||||||
|
SHCNE_DRIVEREMOVED :: 0x00000080
|
||||||
|
SHCNE_DRIVEADD :: 0x00000100
|
||||||
|
SHCNE_NETSHARE :: 0x00000200
|
||||||
|
SHCNE_NETUNSHARE :: 0x00000400
|
||||||
|
SHCNE_ATTRIBUTES :: 0x00000800
|
||||||
|
SHCNE_UPDATEDIR :: 0x00001000
|
||||||
|
SHCNE_UPDATEITEM :: 0x00002000
|
||||||
|
SHCNE_SERVERDISCONNECT :: 0x00004000
|
||||||
|
SHCNE_UPDATEIMAGE :: 0x00008000
|
||||||
|
SHCNE_DRIVEADDGUI :: 0x00010000
|
||||||
|
SHCNE_RENAMEFOLDER :: 0x00020000
|
||||||
|
SHCNE_FREESPACE :: 0x00040000
|
||||||
|
|
||||||
|
SHCNE_EXTENDED_EVENT :: 0x04000000
|
||||||
|
|
||||||
|
SHCNE_ASSOCCHANGED :: 0x08000000
|
||||||
|
|
||||||
|
SHCNE_DISKEVENTS :: 0x0002381F
|
||||||
|
SHCNE_GLOBALEVENTS :: 0x0C0581E0
|
||||||
|
SHCNE_ALLEVENTS :: 0x7FFFFFFF
|
||||||
|
SHCNE_INTERRUPT :: 0x80000000
|
||||||
|
|
||||||
|
SHCNEE_ORDERCHANGED :: 2
|
||||||
|
SHCNEE_MSI_CHANGE :: 4
|
||||||
|
SHCNEE_MSI_UNINSTALL :: 5
|
||||||
|
|
||||||
|
SHCNF_IDLIST :: 0x0000
|
||||||
|
SHCNF_PATHA :: 0x0001
|
||||||
|
SHCNF_PRINTERA :: 0x0002
|
||||||
|
SHCNF_DWORD :: 0x0003
|
||||||
|
SHCNF_PATHW :: 0x0005
|
||||||
|
SHCNF_PRINTERW :: 0x0006
|
||||||
|
SHCNF_TYPE :: 0x00FF
|
||||||
|
SHCNF_FLUSH :: 0x1000
|
||||||
|
SHCNF_FLUSHNOWAIT :: 0x3000
|
||||||
|
|
||||||
|
SHCNF_NOTIFYRECURSIVE :: 0x10000
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ foreign user32 {
|
|||||||
UpdateWindow :: proc(hWnd: HWND) -> BOOL ---
|
UpdateWindow :: proc(hWnd: HWND) -> BOOL ---
|
||||||
SetActiveWindow :: proc(hWnd: HWND) -> HWND ---
|
SetActiveWindow :: proc(hWnd: HWND) -> HWND ---
|
||||||
GetActiveWindow :: proc() -> HWND ---
|
GetActiveWindow :: proc() -> HWND ---
|
||||||
|
RedrawWindow :: proc(hwnd: HWND, lprcUpdate: LPRECT, hrgnUpdate: HRGN, flags: RedrawWindowFlags) -> BOOL ---
|
||||||
|
|
||||||
GetMessageW :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> BOOL ---
|
GetMessageW :: proc(lpMsg: ^MSG, hWnd: HWND, wMsgFilterMin: UINT, wMsgFilterMax: UINT) -> BOOL ---
|
||||||
|
|
||||||
@@ -85,6 +86,14 @@ foreign user32 {
|
|||||||
LoadCursorW :: proc(hInstance: HINSTANCE, lpCursorName: LPCWSTR) -> HCURSOR ---
|
LoadCursorW :: proc(hInstance: HINSTANCE, lpCursorName: LPCWSTR) -> HCURSOR ---
|
||||||
LoadImageW :: proc(hInst: HINSTANCE, name: LPCWSTR, type: UINT, cx: c_int, cy: c_int, fuLoad: UINT) -> HANDLE ---
|
LoadImageW :: proc(hInst: HINSTANCE, name: LPCWSTR, type: UINT, cx: c_int, cy: c_int, fuLoad: UINT) -> HANDLE ---
|
||||||
|
|
||||||
|
CreateIcon :: proc(hInstance: HINSTANCE, nWidth: c_int, nHeight: c_int, cPlanes: BYTE, cBitsPixel: BYTE, lpbANDbits: PBYTE, lpbXORbits: PBYTE) -> HICON ---
|
||||||
|
CreateIconFromResource :: proc(presbits: PBYTE, dwResSize: DWORD, fIcon: BOOL, dwVer: DWORD) -> HICON ---
|
||||||
|
DestroyIcon :: proc(hIcon: HICON) -> BOOL ---
|
||||||
|
DrawIcon :: proc(hDC: HDC, X: c_int, Y: c_int, hIcon: HICON) -> BOOL ---
|
||||||
|
|
||||||
|
CreateCursor :: proc(hInst: HINSTANCE, xHotSpot: c_int, yHotSpot: c_int, nWidth: c_int, nHeight: c_int, pvANDPlane: PVOID, pvXORPlane: PVOID) -> HCURSOR ---
|
||||||
|
DestroyCursor :: proc(hCursor: HCURSOR) -> BOOL ---
|
||||||
|
|
||||||
GetWindowRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL ---
|
GetWindowRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL ---
|
||||||
GetClientRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL ---
|
GetClientRect :: proc(hWnd: HWND, lpRect: LPRECT) -> BOOL ---
|
||||||
ClientToScreen :: proc(hWnd: HWND, lpPoint: LPPOINT) -> BOOL ---
|
ClientToScreen :: proc(hWnd: HWND, lpPoint: LPPOINT) -> BOOL ---
|
||||||
@@ -134,7 +143,7 @@ foreign user32 {
|
|||||||
|
|
||||||
GetKeyState :: proc(nVirtKey: c_int) -> SHORT ---
|
GetKeyState :: proc(nVirtKey: c_int) -> SHORT ---
|
||||||
GetAsyncKeyState :: proc(vKey: c_int) -> SHORT ---
|
GetAsyncKeyState :: proc(vKey: c_int) -> SHORT ---
|
||||||
|
|
||||||
GetKeyboardState :: proc(lpKeyState: PBYTE) -> BOOL ---
|
GetKeyboardState :: proc(lpKeyState: PBYTE) -> BOOL ---
|
||||||
|
|
||||||
MapVirtualKeyW :: proc(uCode: UINT, uMapType: UINT) -> UINT ---
|
MapVirtualKeyW :: proc(uCode: UINT, uMapType: UINT) -> UINT ---
|
||||||
@@ -166,7 +175,7 @@ foreign user32 {
|
|||||||
MonitorFromRect :: proc(lprc: LPRECT, dwFlags: Monitor_From_Flags) -> HMONITOR ---
|
MonitorFromRect :: proc(lprc: LPRECT, dwFlags: Monitor_From_Flags) -> HMONITOR ---
|
||||||
MonitorFromWindow :: proc(hwnd: HWND, dwFlags: Monitor_From_Flags) -> HMONITOR ---
|
MonitorFromWindow :: proc(hwnd: HWND, dwFlags: Monitor_From_Flags) -> HMONITOR ---
|
||||||
EnumDisplayMonitors :: proc(hdc: HDC, lprcClip: LPRECT, lpfnEnum: Monitor_Enum_Proc, dwData: LPARAM) -> BOOL ---
|
EnumDisplayMonitors :: proc(hdc: HDC, lprcClip: LPRECT, lpfnEnum: Monitor_Enum_Proc, dwData: LPARAM) -> BOOL ---
|
||||||
|
|
||||||
EnumWindows :: proc(lpEnumFunc: Window_Enum_Proc, lParam: LPARAM) -> BOOL ---
|
EnumWindows :: proc(lpEnumFunc: Window_Enum_Proc, lParam: LPARAM) -> BOOL ---
|
||||||
|
|
||||||
SetThreadDpiAwarenessContext :: proc(dpiContext: DPI_AWARENESS_CONTEXT) -> DPI_AWARENESS_CONTEXT ---
|
SetThreadDpiAwarenessContext :: proc(dpiContext: DPI_AWARENESS_CONTEXT) -> DPI_AWARENESS_CONTEXT ---
|
||||||
@@ -239,6 +248,9 @@ foreign user32 {
|
|||||||
|
|
||||||
GetSystemMenu :: proc(hWnd: HWND, bRevert: BOOL) -> HMENU ---
|
GetSystemMenu :: proc(hWnd: HWND, bRevert: BOOL) -> HMENU ---
|
||||||
EnableMenuItem :: proc(hMenu: HMENU, uIDEnableItem: UINT, uEnable: UINT) -> BOOL ---
|
EnableMenuItem :: proc(hMenu: HMENU, uIDEnableItem: UINT, uEnable: UINT) -> BOOL ---
|
||||||
|
|
||||||
|
DrawTextW :: proc(hdc: HDC, lpchText: LPCWSTR, cchText: INT, lprc: LPRECT, format: DrawTextFormat) -> INT ---
|
||||||
|
DrawTextExW :: proc(hdc: HDC, lpchText: LPCWSTR, cchText: INT, lprc: LPRECT, format: DrawTextFormat, lpdtp: PDRAWTEXTPARAMS) -> INT ---
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateWindowW :: #force_inline proc "system" (
|
CreateWindowW :: #force_inline proc "system" (
|
||||||
@@ -471,6 +483,19 @@ RI_MOUSE_BUTTON_5_UP :: 0x0200
|
|||||||
RI_MOUSE_WHEEL :: 0x0400
|
RI_MOUSE_WHEEL :: 0x0400
|
||||||
RI_MOUSE_HWHEEL :: 0x0800
|
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 {
|
WINDOWPLACEMENT :: struct {
|
||||||
length: UINT,
|
length: UINT,
|
||||||
flags: UINT,
|
flags: UINT,
|
||||||
@@ -493,3 +518,54 @@ WINDOWINFO :: struct {
|
|||||||
wCreatorVersion: WORD,
|
wCreatorVersion: WORD,
|
||||||
}
|
}
|
||||||
PWINDOWINFO :: ^WINDOWINFO
|
PWINDOWINFO :: ^WINDOWINFO
|
||||||
|
|
||||||
|
DRAWTEXTPARAMS :: struct {
|
||||||
|
cbSize : UINT ,
|
||||||
|
iTabLength: int ,
|
||||||
|
iLeftMargin: int ,
|
||||||
|
iRightMargin: int ,
|
||||||
|
uiLengthDrawn: UINT ,
|
||||||
|
}
|
||||||
|
PDRAWTEXTPARAMS :: ^DRAWTEXTPARAMS
|
||||||
|
|
||||||
|
DrawTextFormat :: enum UINT {
|
||||||
|
DT_TOP = 0x00000000,
|
||||||
|
DT_LEFT = 0x00000000,
|
||||||
|
DT_CENTER = 0x00000001,
|
||||||
|
DT_RIGHT = 0x00000002,
|
||||||
|
DT_VCENTER = 0x00000004,
|
||||||
|
DT_BOTTOM = 0x00000008,
|
||||||
|
DT_WORDBREAK = 0x00000010,
|
||||||
|
DT_SINGLELINE = 0x00000020,
|
||||||
|
DT_EXPANDTABS = 0x00000040,
|
||||||
|
DT_TABSTOP = 0x00000080,
|
||||||
|
DT_NOCLIP = 0x00000100,
|
||||||
|
DT_EXTERNALLEADING = 0x00000200,
|
||||||
|
DT_CALCRECT = 0x00000400,
|
||||||
|
DT_NOPREFIX = 0x00000800,
|
||||||
|
DT_INTERNAL = 0x00001000,
|
||||||
|
DT_EDITCONTROL = 0x00002000,
|
||||||
|
DT_PATH_ELLIPSIS = 0x00004000,
|
||||||
|
DT_END_ELLIPSIS = 0x00008000,
|
||||||
|
DT_MODIFYSTRING = 0x00010000,
|
||||||
|
DT_RTLREADING = 0x00020000,
|
||||||
|
DT_WORD_ELLIPSIS = 0x00040000,
|
||||||
|
DT_NOFULLWIDTHCHARBREAK = 0x00080000,
|
||||||
|
DT_HIDEPREFIX = 0x00100000,
|
||||||
|
DT_PREFIXONLY = 0x00200000,
|
||||||
|
}
|
||||||
|
|
||||||
|
RedrawWindowFlags :: enum UINT {
|
||||||
|
RDW_INVALIDATE = 0x0001,
|
||||||
|
RDW_INTERNALPAINT = 0x0002,
|
||||||
|
RDW_ERASE = 0x0004,
|
||||||
|
RDW_VALIDATE = 0x0008,
|
||||||
|
RDW_NOINTERNALPAINT = 0x0010,
|
||||||
|
RDW_NOERASE = 0x0020,
|
||||||
|
RDW_NOCHILDREN = 0x0040,
|
||||||
|
RDW_ALLCHILDREN = 0x0080,
|
||||||
|
RDW_UPDATENOW = 0x0100,
|
||||||
|
RDW_ERASENOW = 0x0200,
|
||||||
|
RDW_FRAME = 0x0400,
|
||||||
|
RDW_NOFRAME = 0x0800,
|
||||||
|
}
|
||||||
|
|||||||
+205
-1
@@ -11,6 +11,32 @@ foreign winmm {
|
|||||||
timeBeginPeriod :: proc(uPeriod: UINT) -> MMRESULT ---
|
timeBeginPeriod :: proc(uPeriod: UINT) -> MMRESULT ---
|
||||||
timeEndPeriod :: proc(uPeriod: UINT) -> MMRESULT ---
|
timeEndPeriod :: proc(uPeriod: UINT) -> MMRESULT ---
|
||||||
timeGetTime :: proc() -> DWORD ---
|
timeGetTime :: proc() -> DWORD ---
|
||||||
|
|
||||||
|
waveOutGetNumDevs :: proc() -> UINT ---
|
||||||
|
waveOutGetDevCapsW :: proc(uDeviceID: UINT_PTR, pwoc: LPWAVEOUTCAPSW, cbwoc: UINT) -> MMRESULT ---
|
||||||
|
waveOutGetVolume :: proc(hwo: HWAVEOUT, pdwVolume: LPDWORD) -> MMRESULT ---
|
||||||
|
waveOutSetVolume :: proc(hwo: HWAVEOUT, dwVolume: DWORD) -> MMRESULT ---
|
||||||
|
waveOutGetErrorTextW :: proc(mmrError: MMRESULT, pszText: LPWSTR, cchText: UINT) -> MMRESULT ---
|
||||||
|
waveOutOpen :: proc(phwo: LPHWAVEOUT, uDeviceID: UINT, pwfx: LPCWAVEFORMATEX, dwCallback: DWORD_PTR, dwInstance: DWORD_PTR, fdwOpen: DWORD) -> MMRESULT ---
|
||||||
|
waveOutClose :: proc(hwo: HWAVEOUT) -> MMRESULT ---
|
||||||
|
waveOutPrepareHeader :: proc(hwo: HWAVEOUT, pwh: LPWAVEHDR, cbwh: UINT) -> MMRESULT ---
|
||||||
|
waveOutUnprepareHeader :: proc(hwo: HWAVEOUT, pwh: LPWAVEHDR, cbwh: UINT) -> MMRESULT ---
|
||||||
|
waveOutWrite :: proc(hwo: HWAVEOUT, pwh: LPWAVEHDR, cbwh: UINT) -> MMRESULT ---
|
||||||
|
waveOutPause :: proc(hwo: HWAVEOUT) -> MMRESULT ---
|
||||||
|
waveOutRestart :: proc(hwo: HWAVEOUT) -> MMRESULT ---
|
||||||
|
waveOutReset :: proc(hwo: HWAVEOUT) -> MMRESULT ---
|
||||||
|
waveOutBreakLoop :: proc(hwo: HWAVEOUT) -> MMRESULT ---
|
||||||
|
waveOutGetPosition :: proc(hwo: HWAVEOUT, pmmt: LPMMTIME, cbmmt: UINT) -> MMRESULT ---
|
||||||
|
waveOutGetPitch :: proc(hwo: HWAVEOUT, pdwPitch: LPDWORD) -> MMRESULT ---
|
||||||
|
waveOutSetPitch :: proc(hwo: HWAVEOUT, pdwPitch: DWORD) -> MMRESULT ---
|
||||||
|
waveOutGetPlaybackRate :: proc(hwo: HWAVEOUT, pdwRate: LPDWORD) -> MMRESULT ---
|
||||||
|
waveOutSetPlaybackRate :: proc(hwo: HWAVEOUT, pdwRate: DWORD) -> MMRESULT ---
|
||||||
|
waveOutGetID :: proc(hwo: HWAVEOUT, puDeviceID: LPUINT) -> MMRESULT ---
|
||||||
|
|
||||||
|
waveInGetNumDevs :: proc() -> UINT ---
|
||||||
|
waveInGetDevCapsW :: proc(uDeviceID: UINT_PTR, pwic: LPWAVEINCAPSW, cbwic: UINT) -> MMRESULT ---
|
||||||
|
|
||||||
|
PlaySoundW :: proc(pszSound: LPCWSTR, hmod: HMODULE, fdwSound: DWORD) -> BOOL ---
|
||||||
}
|
}
|
||||||
|
|
||||||
LPTIMECAPS :: ^TIMECAPS
|
LPTIMECAPS :: ^TIMECAPS
|
||||||
@@ -169,4 +195,182 @@ MCIERR_NO_IDENTITY :: MCIERR_BASE + 94
|
|||||||
MIXERR_INVALLINE :: (MIXERR_BASE + 0)
|
MIXERR_INVALLINE :: (MIXERR_BASE + 0)
|
||||||
MIXERR_INVALCONTROL :: (MIXERR_BASE + 1)
|
MIXERR_INVALCONTROL :: (MIXERR_BASE + 1)
|
||||||
MIXERR_INVALVALUE :: (MIXERR_BASE + 2)
|
MIXERR_INVALVALUE :: (MIXERR_BASE + 2)
|
||||||
MIXERR_LASTERROR :: (MIXERR_BASE + 2)
|
MIXERR_LASTERROR :: (MIXERR_BASE + 2)
|
||||||
|
|
||||||
|
/* waveform output */
|
||||||
|
MM_WOM_OPEN :: 0x3BB
|
||||||
|
MM_WOM_CLOSE :: 0x3BC
|
||||||
|
MM_WOM_DONE :: 0x3BD
|
||||||
|
/* waveform input */
|
||||||
|
MM_WIM_OPEN :: 0x3BE
|
||||||
|
MM_WIM_CLOSE :: 0x3BF
|
||||||
|
MM_WIM_DATA :: 0x3C0
|
||||||
|
|
||||||
|
WOM_OPEN :: MM_WOM_OPEN
|
||||||
|
WOM_CLOSE :: MM_WOM_CLOSE
|
||||||
|
WOM_DONE :: MM_WOM_DONE
|
||||||
|
WIM_OPEN :: MM_WIM_OPEN
|
||||||
|
WIM_CLOSE :: MM_WIM_CLOSE
|
||||||
|
WIM_DATA :: MM_WIM_DATA
|
||||||
|
|
||||||
|
WAVE_MAPPER : UINT : 0xFFFFFFFF // -1
|
||||||
|
|
||||||
|
WAVE_FORMAT_QUERY :: 0x0001
|
||||||
|
WAVE_ALLOWSYNC :: 0x0002
|
||||||
|
WAVE_MAPPED :: 0x0004
|
||||||
|
WAVE_FORMAT_DIRECT :: 0x0008
|
||||||
|
WAVE_FORMAT_DIRECT_QUERY :: (WAVE_FORMAT_QUERY | WAVE_FORMAT_DIRECT)
|
||||||
|
WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE :: 0x0010
|
||||||
|
|
||||||
|
WHDR_DONE :: 0x00000001 /* done bit */
|
||||||
|
WHDR_PREPARED :: 0x00000002 /* set if this header has been prepared */
|
||||||
|
WHDR_BEGINLOOP :: 0x00000004 /* loop start block */
|
||||||
|
WHDR_ENDLOOP :: 0x00000008 /* loop end block */
|
||||||
|
WHDR_INQUEUE :: 0x00000010 /* reserved for driver */
|
||||||
|
|
||||||
|
WAVECAPS_PITCH :: 0x0001 /* supports pitch control */
|
||||||
|
WAVECAPS_PLAYBACKRATE :: 0x0002 /* supports playback rate control */
|
||||||
|
WAVECAPS_VOLUME :: 0x0004 /* supports volume control */
|
||||||
|
WAVECAPS_LRVOLUME :: 0x0008 /* separate left-right volume control */
|
||||||
|
WAVECAPS_SYNC :: 0x0010
|
||||||
|
WAVECAPS_SAMPLEACCURATE :: 0x0020
|
||||||
|
|
||||||
|
WAVE_INVALIDFORMAT :: 0x00000000 /* invalid format */
|
||||||
|
WAVE_FORMAT_1M08 :: 0x00000001 /* 11.025 kHz, Mono, 8-bit */
|
||||||
|
WAVE_FORMAT_1S08 :: 0x00000002 /* 11.025 kHz, Stereo, 8-bit */
|
||||||
|
WAVE_FORMAT_1M16 :: 0x00000004 /* 11.025 kHz, Mono, 16-bit */
|
||||||
|
WAVE_FORMAT_1S16 :: 0x00000008 /* 11.025 kHz, Stereo, 16-bit */
|
||||||
|
WAVE_FORMAT_2M08 :: 0x00000010 /* 22.05 kHz, Mono, 8-bit */
|
||||||
|
WAVE_FORMAT_2S08 :: 0x00000020 /* 22.05 kHz, Stereo, 8-bit */
|
||||||
|
WAVE_FORMAT_2M16 :: 0x00000040 /* 22.05 kHz, Mono, 16-bit */
|
||||||
|
WAVE_FORMAT_2S16 :: 0x00000080 /* 22.05 kHz, Stereo, 16-bit */
|
||||||
|
WAVE_FORMAT_4M08 :: 0x00000100 /* 44.1 kHz, Mono, 8-bit */
|
||||||
|
WAVE_FORMAT_4S08 :: 0x00000200 /* 44.1 kHz, Stereo, 8-bit */
|
||||||
|
WAVE_FORMAT_4M16 :: 0x00000400 /* 44.1 kHz, Mono, 16-bit */
|
||||||
|
WAVE_FORMAT_4S16 :: 0x00000800 /* 44.1 kHz, Stereo, 16-bit */
|
||||||
|
WAVE_FORMAT_44M08 :: 0x00000100 /* 44.1 kHz, Mono, 8-bit */
|
||||||
|
WAVE_FORMAT_44S08 :: 0x00000200 /* 44.1 kHz, Stereo, 8-bit */
|
||||||
|
WAVE_FORMAT_44M16 :: 0x00000400 /* 44.1 kHz, Mono, 16-bit */
|
||||||
|
WAVE_FORMAT_44S16 :: 0x00000800 /* 44.1 kHz, Stereo, 16-bit */
|
||||||
|
WAVE_FORMAT_48M08 :: 0x00001000 /* 48 kHz, Mono, 8-bit */
|
||||||
|
WAVE_FORMAT_48S08 :: 0x00002000 /* 48 kHz, Stereo, 8-bit */
|
||||||
|
WAVE_FORMAT_48M16 :: 0x00004000 /* 48 kHz, Mono, 16-bit */
|
||||||
|
WAVE_FORMAT_48S16 :: 0x00008000 /* 48 kHz, Stereo, 16-bit */
|
||||||
|
WAVE_FORMAT_96M08 :: 0x00010000 /* 96 kHz, Mono, 8-bit */
|
||||||
|
WAVE_FORMAT_96S08 :: 0x00020000 /* 96 kHz, Stereo, 8-bit */
|
||||||
|
WAVE_FORMAT_96M16 :: 0x00040000 /* 96 kHz, Mono, 16-bit */
|
||||||
|
WAVE_FORMAT_96S16 :: 0x00080000 /* 96 kHz, Stereo, 16-bit */
|
||||||
|
|
||||||
|
HWAVE :: distinct HANDLE
|
||||||
|
HWAVEIN :: distinct HANDLE
|
||||||
|
HWAVEOUT :: distinct HANDLE
|
||||||
|
|
||||||
|
LPHWAVEIN :: ^HWAVEIN
|
||||||
|
LPHWAVEOUT :: ^HWAVEOUT
|
||||||
|
|
||||||
|
// https://learn.microsoft.com/en-us/windows/win32/multimedia/multimedia-timer-structures
|
||||||
|
MMTIME :: struct {
|
||||||
|
wType: UINT,
|
||||||
|
u: struct #raw_union {
|
||||||
|
ms: DWORD,
|
||||||
|
sample: DWORD,
|
||||||
|
cb: DWORD,
|
||||||
|
ticks: DWORD,
|
||||||
|
smpte: struct {
|
||||||
|
hour: BYTE,
|
||||||
|
min: BYTE,
|
||||||
|
sec: BYTE,
|
||||||
|
frame: BYTE,
|
||||||
|
fps: BYTE,
|
||||||
|
dummy: BYTE,
|
||||||
|
pad: [2]BYTE,
|
||||||
|
},
|
||||||
|
midi: struct {
|
||||||
|
songptrpos: DWORD,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
LPMMTIME :: ^MMTIME
|
||||||
|
|
||||||
|
MAXPNAMELEN :: 32
|
||||||
|
MAXERRORLENGTH :: 256
|
||||||
|
MMVERSION :: UINT
|
||||||
|
|
||||||
|
/* flags for wFormatTag field of WAVEFORMAT */
|
||||||
|
WAVE_FORMAT_PCM :: 1
|
||||||
|
|
||||||
|
WAVEFORMATEX :: struct {
|
||||||
|
wFormatTag: WORD,
|
||||||
|
nChannels: WORD,
|
||||||
|
nSamplesPerSec: DWORD,
|
||||||
|
nAvgBytesPerSec: DWORD,
|
||||||
|
nBlockAlign: WORD,
|
||||||
|
wBitsPerSample: WORD,
|
||||||
|
cbSize: WORD,
|
||||||
|
}
|
||||||
|
LPCWAVEFORMATEX :: ^WAVEFORMATEX
|
||||||
|
|
||||||
|
WAVEHDR :: struct {
|
||||||
|
lpData: LPSTR, /* pointer to locked data buffer */
|
||||||
|
dwBufferLength: DWORD, /* length of data buffer */
|
||||||
|
dwBytesRecorded: DWORD, /* used for input only */
|
||||||
|
dwUser: DWORD_PTR, /* for client's use */
|
||||||
|
dwFlags: DWORD, /* assorted flags (see defines) */
|
||||||
|
dwLoops: DWORD, /* loop control counter */
|
||||||
|
lpNext: LPWAVEHDR, /* reserved for driver */
|
||||||
|
reserved: DWORD_PTR, /* reserved for driver */
|
||||||
|
}
|
||||||
|
LPWAVEHDR :: ^WAVEHDR
|
||||||
|
|
||||||
|
WAVEINCAPSW :: struct {
|
||||||
|
wMid: WORD, /* manufacturer ID */
|
||||||
|
wPid: WORD, /* product ID */
|
||||||
|
vDriverVersion: MMVERSION, /* version of the driver */
|
||||||
|
szPname: [MAXPNAMELEN]WCHAR, /* product name (NULL terminated string) */
|
||||||
|
dwFormats: DWORD, /* formats supported */
|
||||||
|
wChannels: WORD, /* number of channels supported */
|
||||||
|
wReserved1: WORD, /* structure packing */
|
||||||
|
}
|
||||||
|
LPWAVEINCAPSW :: ^WAVEINCAPSW
|
||||||
|
|
||||||
|
WAVEOUTCAPSW :: struct {
|
||||||
|
wMid: WORD, /* manufacturer ID */
|
||||||
|
wPid: WORD, /* product ID */
|
||||||
|
vDriverVersion: MMVERSION, /* version of the driver */
|
||||||
|
szPname: [MAXPNAMELEN]WCHAR, /* product name (NULL terminated string) */
|
||||||
|
dwFormats: DWORD, /* formats supported */
|
||||||
|
wChannels: WORD, /* number of sources supported */
|
||||||
|
wReserved1: WORD, /* packing */
|
||||||
|
dwSupport: DWORD, /* functionality supported by driver */
|
||||||
|
}
|
||||||
|
LPWAVEOUTCAPSW :: ^WAVEOUTCAPSW
|
||||||
|
|
||||||
|
// flag values for PlaySound
|
||||||
|
SND_SYNC :: 0x0000 /* play synchronously (default) */
|
||||||
|
SND_ASYNC :: 0x0001 /* play asynchronously */
|
||||||
|
SND_NODEFAULT :: 0x0002 /* silence (!default) if sound not found */
|
||||||
|
SND_MEMORY :: 0x0004 /* pszSound points to a memory file */
|
||||||
|
SND_LOOP :: 0x0008 /* loop the sound until next sndPlaySound */
|
||||||
|
SND_NOSTOP :: 0x0010 /* don't stop any currently playing sound */
|
||||||
|
|
||||||
|
SND_NOWAIT :: 0x00002000 /* don't wait if the driver is busy */
|
||||||
|
SND_ALIAS :: 0x00010000 /* name is a registry alias */
|
||||||
|
SND_ALIAS_ID :: 0x00110000 /* alias is a predefined ID */
|
||||||
|
SND_FILENAME :: 0x00020000 /* name is file name */
|
||||||
|
SND_RESOURCE :: 0x00040004 /* name is resource name or atom */
|
||||||
|
|
||||||
|
SND_PURGE :: 0x0040 /* purge non-static events for task */
|
||||||
|
SND_APPLICATION :: 0x0080 /* look for application specific association */
|
||||||
|
|
||||||
|
SND_SENTRY :: 0x00080000 /* Generate a SoundSentry event with this sound */
|
||||||
|
SND_RING :: 0x00100000 /* Treat this as a "ring" from a communications app - don't duck me */
|
||||||
|
SND_SYSTEM :: 0x00200000 /* Treat this as a system sound */
|
||||||
|
|
||||||
|
|
||||||
|
CALLBACK_TYPEMASK :: 0x00070000 /* callback type mask */
|
||||||
|
CALLBACK_NULL :: 0x00000000 /* no callback */
|
||||||
|
CALLBACK_WINDOW :: 0x00010000 /* dwCallback is a HWND */
|
||||||
|
CALLBACK_TASK :: 0x00020000 /* dwCallback is a HTASK */
|
||||||
|
CALLBACK_FUNCTION :: 0x00030000 /* dwCallback is a FARPROC */
|
||||||
|
CALLBACK_THREAD :: CALLBACK_TASK /* thread ID replaces 16 bit task */
|
||||||
|
CALLBACK_EVENT :: 0x00050000 /* dwCallback is an EVENT Handle */
|
||||||
|
|||||||
@@ -932,6 +932,9 @@ gb_internal Type *core_type(Type *t) {
|
|||||||
case Type_Enum:
|
case Type_Enum:
|
||||||
t = t->Enum.base_type;
|
t = t->Enum.base_type;
|
||||||
continue;
|
continue;
|
||||||
|
case Type_BitField:
|
||||||
|
t = t->BitField.backing_type;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user