mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-31 03:40:08 +00:00
Nearly finished Jai-like declarations
This commit is contained in:
+110
-114
@@ -12,74 +12,72 @@ import "mem.odin";
|
||||
|
||||
// IMPORTANT NOTE(bill): Do not change the order of any of this data
|
||||
// The compiler relies upon this _exact_ order
|
||||
type {
|
||||
Type_Info_Member struct #ordered {
|
||||
name string; // can be empty if tuple
|
||||
type_info ^Type_Info;
|
||||
offset int; // offsets are not used in tuples
|
||||
}
|
||||
Type_Info_Record struct #ordered {
|
||||
fields []Type_Info_Member;
|
||||
size int; // in bytes
|
||||
align int; // in bytes
|
||||
packed bool;
|
||||
ordered bool;
|
||||
}
|
||||
|
||||
Type_Info union {
|
||||
Named struct #ordered {
|
||||
name string;
|
||||
base ^Type_Info; // This will _not_ be a Type_Info.Named
|
||||
};
|
||||
Integer struct #ordered {
|
||||
size int; // in bytes
|
||||
signed bool;
|
||||
};
|
||||
Float struct #ordered {
|
||||
size int; // in bytes
|
||||
};
|
||||
Any struct #ordered {};
|
||||
String struct #ordered {};
|
||||
Boolean struct #ordered {};
|
||||
Pointer struct #ordered {
|
||||
elem ^Type_Info; // nil -> rawptr
|
||||
};
|
||||
Maybe struct #ordered {
|
||||
elem ^Type_Info;
|
||||
};
|
||||
Procedure struct #ordered {
|
||||
params ^Type_Info; // Type_Info.Tuple
|
||||
results ^Type_Info; // Type_Info.Tuple
|
||||
variadic bool;
|
||||
};
|
||||
Array struct #ordered {
|
||||
elem ^Type_Info;
|
||||
elem_size int;
|
||||
count int;
|
||||
};
|
||||
Slice struct #ordered {
|
||||
elem ^Type_Info;
|
||||
elem_size int;
|
||||
};
|
||||
Vector struct #ordered {
|
||||
elem ^Type_Info;
|
||||
elem_size int;
|
||||
count int;
|
||||
align int;
|
||||
};
|
||||
Tuple Type_Info_Record;
|
||||
Struct Type_Info_Record;
|
||||
Union Type_Info_Record;
|
||||
Raw_Union Type_Info_Record;
|
||||
Enum struct #ordered {
|
||||
base ^Type_Info;
|
||||
names []string;
|
||||
// TODO(bill): store values some how. Maybe using a raw_union
|
||||
};
|
||||
}
|
||||
Type_Info_Member :: struct #ordered {
|
||||
name string; // can be empty if tuple
|
||||
type_info ^Type_Info;
|
||||
offset int; // offsets are not used in tuples
|
||||
}
|
||||
Type_Info_Record :: struct #ordered {
|
||||
fields []Type_Info_Member;
|
||||
size int; // in bytes
|
||||
align int; // in bytes
|
||||
packed bool;
|
||||
ordered bool;
|
||||
}
|
||||
|
||||
proc type_info_base(info ^Type_Info) -> ^Type_Info {
|
||||
Type_Info :: union {
|
||||
Named struct #ordered {
|
||||
name string;
|
||||
base ^Type_Info; // This will _not_ be a Type_Info.Named
|
||||
};
|
||||
Integer struct #ordered {
|
||||
size int; // in bytes
|
||||
signed bool;
|
||||
};
|
||||
Float struct #ordered {
|
||||
size int; // in bytes
|
||||
};
|
||||
Any struct #ordered {};
|
||||
String struct #ordered {};
|
||||
Boolean struct #ordered {};
|
||||
Pointer struct #ordered {
|
||||
elem ^Type_Info; // nil -> rawptr
|
||||
};
|
||||
Maybe struct #ordered {
|
||||
elem ^Type_Info;
|
||||
};
|
||||
Procedure struct #ordered {
|
||||
params ^Type_Info; // Type_Info.Tuple
|
||||
results ^Type_Info; // Type_Info.Tuple
|
||||
variadic bool;
|
||||
};
|
||||
Array struct #ordered {
|
||||
elem ^Type_Info;
|
||||
elem_size int;
|
||||
count int;
|
||||
};
|
||||
Slice struct #ordered {
|
||||
elem ^Type_Info;
|
||||
elem_size int;
|
||||
};
|
||||
Vector struct #ordered {
|
||||
elem ^Type_Info;
|
||||
elem_size int;
|
||||
count int;
|
||||
align int;
|
||||
};
|
||||
Tuple Type_Info_Record;
|
||||
Struct Type_Info_Record;
|
||||
Union Type_Info_Record;
|
||||
Raw_Union Type_Info_Record;
|
||||
Enum struct #ordered {
|
||||
base ^Type_Info;
|
||||
names []string;
|
||||
// TODO(bill): store values some how. Maybe using a raw_union
|
||||
};
|
||||
}
|
||||
|
||||
type_info_base :: proc(info ^Type_Info) -> ^Type_Info {
|
||||
if info == nil {
|
||||
return nil;
|
||||
}
|
||||
@@ -93,51 +91,49 @@ proc type_info_base(info ^Type_Info) -> ^Type_Info {
|
||||
|
||||
|
||||
|
||||
proc assume(cond bool) #foreign "llvm.assume"
|
||||
assume :: proc(cond bool) #foreign "llvm.assume"
|
||||
|
||||
proc __debug_trap () #foreign "llvm.debugtrap"
|
||||
proc __trap () #foreign "llvm.trap"
|
||||
proc read_cycle_counter() -> u64 #foreign "llvm.readcyclecounter"
|
||||
__debug_trap :: proc() #foreign "llvm.debugtrap"
|
||||
__trap :: proc() #foreign "llvm.trap"
|
||||
read_cycle_counter :: proc() -> u64 #foreign "llvm.readcyclecounter"
|
||||
|
||||
proc bit_reverse16(b u16) -> u16 #foreign "llvm.bitreverse.i16"
|
||||
proc bit_reverse32(b u32) -> u32 #foreign "llvm.bitreverse.i32"
|
||||
proc bit_reverse64(b u64) -> u64 #foreign "llvm.bitreverse.i64"
|
||||
bit_reverse16 :: proc(b u16) -> u16 #foreign "llvm.bitreverse.i16"
|
||||
bit_reverse32 :: proc(b u32) -> u32 #foreign "llvm.bitreverse.i32"
|
||||
bit_reverse64 :: proc(b u64) -> u64 #foreign "llvm.bitreverse.i64"
|
||||
|
||||
proc byte_swap16(b u16) -> u16 #foreign "llvm.bswap.i16"
|
||||
proc byte_swap32(b u32) -> u32 #foreign "llvm.bswap.i32"
|
||||
proc byte_swap64(b u64) -> u64 #foreign "llvm.bswap.i64"
|
||||
byte_swap16 :: proc(b u16) -> u16 #foreign "llvm.bswap.i16"
|
||||
byte_swap32 :: proc(b u32) -> u32 #foreign "llvm.bswap.i32"
|
||||
byte_swap64 :: proc(b u64) -> u64 #foreign "llvm.bswap.i64"
|
||||
|
||||
proc fmuladd32(a, b, c f32) -> f32 #foreign "llvm.fmuladd.f32"
|
||||
proc fmuladd64(a, b, c f64) -> f64 #foreign "llvm.fmuladd.f64"
|
||||
fmuladd32 :: proc(a, b, c f32) -> f32 #foreign "llvm.fmuladd.f32"
|
||||
fmuladd64 :: proc(a, b, c f64) -> f64 #foreign "llvm.fmuladd.f64"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
type Allocator_Mode enum u8 {
|
||||
Allocator_Mode :: enum u8 {
|
||||
ALLOC = iota,
|
||||
FREE,
|
||||
FREE_ALL,
|
||||
RESIZE,
|
||||
}
|
||||
type {
|
||||
Allocator_Proc proc(allocator_data rawptr, mode Allocator_Mode,
|
||||
size, alignment int,
|
||||
old_memory rawptr, old_size int, flags u64) -> rawptr;
|
||||
Allocator struct #ordered {
|
||||
procedure Allocator_Proc;
|
||||
data rawptr;
|
||||
}
|
||||
Allocator_Proc :: type proc(allocator_data rawptr, mode Allocator_Mode,
|
||||
size, alignment int,
|
||||
old_memory rawptr, old_size int, flags u64) -> rawptr;
|
||||
Allocator :: struct #ordered {
|
||||
procedure Allocator_Proc;
|
||||
data rawptr;
|
||||
}
|
||||
|
||||
Context struct #ordered {
|
||||
thread_id int;
|
||||
Context :: struct #ordered {
|
||||
thread_id int;
|
||||
|
||||
allocator Allocator;
|
||||
allocator Allocator;
|
||||
|
||||
user_data rawptr;
|
||||
user_index int;
|
||||
}
|
||||
user_data rawptr;
|
||||
user_index int;
|
||||
}
|
||||
|
||||
#thread_local __context: Context;
|
||||
@@ -146,7 +142,7 @@ type {
|
||||
DEFAULT_ALIGNMENT :: align_of([vector 4]f32);
|
||||
|
||||
|
||||
proc __check_context() {
|
||||
__check_context:: proc() {
|
||||
c := ^__context;
|
||||
|
||||
if c.allocator.procedure == nil {
|
||||
@@ -157,30 +153,30 @@ proc __check_context() {
|
||||
}
|
||||
}
|
||||
|
||||
proc alloc(size int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNMENT); }
|
||||
alloc:: proc(size int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNMENT); }
|
||||
|
||||
proc alloc_align(size, alignment int) -> rawptr #inline {
|
||||
alloc_align:: proc(size, alignment int) -> rawptr #inline {
|
||||
__check_context();
|
||||
a := context.allocator;
|
||||
return a.procedure(a.data, Allocator_Mode.ALLOC, size, alignment, nil, 0, 0);
|
||||
}
|
||||
|
||||
proc free(ptr rawptr) #inline {
|
||||
free:: proc(ptr rawptr) #inline {
|
||||
__check_context();
|
||||
a := context.allocator;
|
||||
if ptr != nil {
|
||||
a.procedure(a.data, Allocator_Mode.FREE, 0, 0, ptr, 0, 0);
|
||||
}
|
||||
}
|
||||
proc free_all() #inline {
|
||||
free_all:: proc() #inline {
|
||||
__check_context();
|
||||
a := context.allocator;
|
||||
a.procedure(a.data, Allocator_Mode.FREE_ALL, 0, 0, nil, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
proc resize (ptr rawptr, old_size, new_size int) -> rawptr #inline { return resize_align(ptr, old_size, new_size, DEFAULT_ALIGNMENT); }
|
||||
proc resize_align(ptr rawptr, old_size, new_size, alignment int) -> rawptr #inline {
|
||||
resize:: proc (ptr rawptr, old_size, new_size int) -> rawptr #inline { return resize_align(ptr, old_size, new_size, DEFAULT_ALIGNMENT); }
|
||||
resize_align:: proc(ptr rawptr, old_size, new_size, alignment int) -> rawptr #inline {
|
||||
__check_context();
|
||||
a := context.allocator;
|
||||
return a.procedure(a.data, Allocator_Mode.RESIZE, new_size, alignment, ptr, old_size, 0);
|
||||
@@ -188,7 +184,7 @@ proc resize_align(ptr rawptr, old_size, new_size, alignment int) -> rawptr #inli
|
||||
|
||||
|
||||
|
||||
proc default_resize_align(old_memory rawptr, old_size, new_size, alignment int) -> rawptr {
|
||||
default_resize_align:: proc(old_memory rawptr, old_size, new_size, alignment int) -> rawptr {
|
||||
if old_memory == nil {
|
||||
return alloc_align(new_size, alignment);
|
||||
}
|
||||
@@ -213,7 +209,7 @@ proc default_resize_align(old_memory rawptr, old_size, new_size, alignment int)
|
||||
}
|
||||
|
||||
|
||||
proc default_allocator_proc(allocator_data rawptr, mode Allocator_Mode,
|
||||
default_allocator_proc:: proc(allocator_data rawptr, mode Allocator_Mode,
|
||||
size, alignment int,
|
||||
old_memory rawptr, old_size int, flags u64) -> rawptr {
|
||||
using Allocator_Mode;
|
||||
@@ -263,7 +259,7 @@ proc default_allocator_proc(allocator_data rawptr, mode Allocator_Mode,
|
||||
return nil;
|
||||
}
|
||||
|
||||
proc default_allocator() -> Allocator {
|
||||
default_allocator:: proc() -> Allocator {
|
||||
return Allocator{
|
||||
procedure = default_allocator_proc,
|
||||
data = nil,
|
||||
@@ -280,7 +276,7 @@ proc default_allocator() -> Allocator {
|
||||
|
||||
|
||||
|
||||
proc __string_eq(a, b string) -> bool {
|
||||
__string_eq:: proc(a, b string) -> bool {
|
||||
if a.count != b.count {
|
||||
return false;
|
||||
}
|
||||
@@ -290,24 +286,24 @@ proc __string_eq(a, b string) -> bool {
|
||||
return mem.compare(a.data, b.data, a.count) == 0;
|
||||
}
|
||||
|
||||
proc __string_cmp(a, b string) -> int {
|
||||
__string_cmp:: proc(a, b string) -> int {
|
||||
return mem.compare(a.data, b.data, min(a.count, b.count));
|
||||
}
|
||||
|
||||
proc __string_ne(a, b string) -> bool #inline { return !__string_eq(a, b); }
|
||||
proc __string_lt(a, b string) -> bool #inline { return __string_cmp(a, b) < 0; }
|
||||
proc __string_gt(a, b string) -> bool #inline { return __string_cmp(a, b) > 0; }
|
||||
proc __string_le(a, b string) -> bool #inline { return __string_cmp(a, b) <= 0; }
|
||||
proc __string_ge(a, b string) -> bool #inline { return __string_cmp(a, b) >= 0; }
|
||||
__string_ne:: proc(a, b string) -> bool #inline { return !__string_eq(a, b); }
|
||||
__string_lt:: proc(a, b string) -> bool #inline { return __string_cmp(a, b) < 0; }
|
||||
__string_gt:: proc(a, b string) -> bool #inline { return __string_cmp(a, b) > 0; }
|
||||
__string_le:: proc(a, b string) -> bool #inline { return __string_cmp(a, b) <= 0; }
|
||||
__string_ge:: proc(a, b string) -> bool #inline { return __string_cmp(a, b) >= 0; }
|
||||
|
||||
|
||||
proc __assert(file string, line, column int, msg string) #inline {
|
||||
__assert:: proc(file string, line, column int, msg string) #inline {
|
||||
fmt.fprintf(os.stderr, "%(%:%) Runtime assertion: %\n",
|
||||
file, line, column, msg);
|
||||
__debug_trap();
|
||||
}
|
||||
|
||||
proc __bounds_check_error(file string, line, column int, index, count int) {
|
||||
__bounds_check_error:: proc(file string, line, column int, index, count int) {
|
||||
if 0 <= index && index < count {
|
||||
return;
|
||||
}
|
||||
@@ -316,7 +312,7 @@ proc __bounds_check_error(file string, line, column int, index, count int) {
|
||||
__debug_trap();
|
||||
}
|
||||
|
||||
proc __slice_expr_error(file string, line, column int, low, high, max int) {
|
||||
__slice_expr_error:: proc(file string, line, column int, low, high, max int) {
|
||||
if 0 <= low && low <= high && high <= max {
|
||||
return;
|
||||
}
|
||||
@@ -324,7 +320,7 @@ proc __slice_expr_error(file string, line, column int, low, high, max int) {
|
||||
file, line, column, low, high, max);
|
||||
__debug_trap();
|
||||
}
|
||||
proc __substring_expr_error(file string, line, column int, low, high int) {
|
||||
__substring_expr_error:: proc(file string, line, column int, low, high int) {
|
||||
if 0 <= low && low <= high {
|
||||
return;
|
||||
}
|
||||
|
||||
+24
-24
@@ -5,36 +5,36 @@ import win32 "sys/windows.odin" when ODIN_OS == "windows";
|
||||
_ := compile_assert(ODIN_ARCH == "amd64"); // TODO(bill): x86 version
|
||||
|
||||
|
||||
proc yield_thread() { win32._mm_pause(); }
|
||||
proc mfence () { win32.ReadWriteBarrier(); }
|
||||
proc sfence () { win32.WriteBarrier(); }
|
||||
proc lfence () { win32.ReadBarrier(); }
|
||||
yield_thread :: proc() { win32._mm_pause(); }
|
||||
mfence :: proc() { win32.ReadWriteBarrier(); }
|
||||
sfence :: proc() { win32.WriteBarrier(); }
|
||||
lfence :: proc() { win32.ReadBarrier(); }
|
||||
|
||||
|
||||
proc load32(a ^i32) -> i32 {
|
||||
load32 :: proc(a ^i32) -> i32 {
|
||||
return a^;
|
||||
}
|
||||
proc store32(a ^i32, value i32) {
|
||||
store32 :: proc(a ^i32, value i32) {
|
||||
a^ = value;
|
||||
}
|
||||
proc compare_exchange32(a ^i32, expected, desired i32) -> i32 {
|
||||
compare_exchange32 :: proc(a ^i32, expected, desired i32) -> i32 {
|
||||
return win32.InterlockedCompareExchange(a, desired, expected);
|
||||
}
|
||||
proc exchanged32(a ^i32, desired i32) -> i32 {
|
||||
exchanged32 :: proc(a ^i32, desired i32) -> i32 {
|
||||
return win32.InterlockedExchange(a, desired);
|
||||
}
|
||||
proc fetch_add32(a ^i32, operand i32) -> i32 {
|
||||
fetch_add32 :: proc(a ^i32, operand i32) -> i32 {
|
||||
return win32.InterlockedExchangeAdd(a, operand);
|
||||
|
||||
}
|
||||
proc fetch_and32(a ^i32, operand i32) -> i32 {
|
||||
fetch_and32 :: proc(a ^i32, operand i32) -> i32 {
|
||||
return win32.InterlockedAnd(a, operand);
|
||||
|
||||
}
|
||||
proc fetch_or32(a ^i32, operand i32) -> i32 {
|
||||
fetch_or32 :: proc(a ^i32, operand i32) -> i32 {
|
||||
return win32.InterlockedOr(a, operand);
|
||||
}
|
||||
proc spin_lock32(a ^i32, time_out int) -> bool { // NOTE(bill) time_out = -1 as default
|
||||
spin_lock32 :: proc(a ^i32, time_out int) -> bool { // NOTE(bill) time_out = -1 as default
|
||||
old_value := compare_exchange32(a, 1, 0);
|
||||
counter := 0;
|
||||
for old_value != 0 && (time_out < 0 || counter < time_out) {
|
||||
@@ -45,11 +45,11 @@ proc spin_lock32(a ^i32, time_out int) -> bool { // NOTE(bill) time_out = -1 as
|
||||
}
|
||||
return old_value == 0;
|
||||
}
|
||||
proc spin_unlock32(a ^i32) {
|
||||
spin_unlock32 :: proc(a ^i32) {
|
||||
store32(a, 0);
|
||||
mfence();
|
||||
}
|
||||
proc try_acquire_lock32(a ^i32) -> bool {
|
||||
try_acquire_lock32 :: proc(a ^i32) -> bool {
|
||||
yield_thread();
|
||||
old_value := compare_exchange32(a, 1, 0);
|
||||
mfence();
|
||||
@@ -57,28 +57,28 @@ proc try_acquire_lock32(a ^i32) -> bool {
|
||||
}
|
||||
|
||||
|
||||
proc load64(a ^i64) -> i64 {
|
||||
load64 :: proc(a ^i64) -> i64 {
|
||||
return a^;
|
||||
}
|
||||
proc store64(a ^i64, value i64) {
|
||||
store64 :: proc(a ^i64, value i64) {
|
||||
a^ = value;
|
||||
}
|
||||
proc compare_exchange64(a ^i64, expected, desired i64) -> i64 {
|
||||
compare_exchange64 :: proc(a ^i64, expected, desired i64) -> i64 {
|
||||
return win32.InterlockedCompareExchange64(a, desired, expected);
|
||||
}
|
||||
proc exchanged64(a ^i64, desired i64) -> i64 {
|
||||
exchanged64 :: proc(a ^i64, desired i64) -> i64 {
|
||||
return win32.InterlockedExchange64(a, desired);
|
||||
}
|
||||
proc fetch_add64(a ^i64, operand i64) -> i64 {
|
||||
fetch_add64 :: proc(a ^i64, operand i64) -> i64 {
|
||||
return win32.InterlockedExchangeAdd64(a, operand);
|
||||
}
|
||||
proc fetch_and64(a ^i64, operand i64) -> i64 {
|
||||
fetch_and64 :: proc(a ^i64, operand i64) -> i64 {
|
||||
return win32.InterlockedAnd64(a, operand);
|
||||
}
|
||||
proc fetch_or64(a ^i64, operand i64) -> i64 {
|
||||
fetch_or64 :: proc(a ^i64, operand i64) -> i64 {
|
||||
return win32.InterlockedOr64(a, operand);
|
||||
}
|
||||
proc spin_lock64(a ^i64, time_out int) -> bool { // NOTE(bill) time_out = -1 as default
|
||||
spin_lock64 :: proc(a ^i64, time_out int) -> bool { // NOTE(bill) time_out = -1 as default
|
||||
old_value := compare_exchange64(a, 1, 0);
|
||||
counter := 0;
|
||||
for old_value != 0 && (time_out < 0 || counter < time_out) {
|
||||
@@ -89,11 +89,11 @@ proc spin_lock64(a ^i64, time_out int) -> bool { // NOTE(bill) time_out = -1 as
|
||||
}
|
||||
return old_value == 0;
|
||||
}
|
||||
proc spin_unlock64(a ^i64) {
|
||||
spin_unlock64 :: proc(a ^i64) {
|
||||
store64(a, 0);
|
||||
mfence();
|
||||
}
|
||||
proc try_acquire_lock64(a ^i64) -> bool {
|
||||
try_acquire_lock64 :: proc(a ^i64) -> bool {
|
||||
yield_thread();
|
||||
old_value := compare_exchange64(a, 1, 0);
|
||||
mfence();
|
||||
|
||||
+37
-37
@@ -6,23 +6,23 @@ import {
|
||||
|
||||
PRINT_BUF_SIZE :: 1<<12;
|
||||
|
||||
proc fprint(fd os.Handle, args ..any) -> int {
|
||||
data :[PRINT_BUF_SIZE]byte;
|
||||
fprint :: proc(fd os.Handle, args ..any) -> int {
|
||||
data: [PRINT_BUF_SIZE]byte;
|
||||
buf := data[:0];
|
||||
bprint(^buf, ..args);
|
||||
os.write(fd, buf);
|
||||
return buf.count;
|
||||
}
|
||||
|
||||
proc fprintln(fd os.Handle, args ..any) -> int {
|
||||
data :[PRINT_BUF_SIZE]byte;
|
||||
fprintln :: proc(fd os.Handle, args ..any) -> int {
|
||||
data: [PRINT_BUF_SIZE]byte;
|
||||
buf := data[:0];
|
||||
bprintln(^buf, ..args);
|
||||
os.write(fd, buf);
|
||||
return buf.count;
|
||||
}
|
||||
proc fprintf(fd os.Handle, fmt string, args ..any) -> int {
|
||||
data :[PRINT_BUF_SIZE]byte;
|
||||
fprintf :: proc(fd os.Handle, fmt string, args ..any) -> int {
|
||||
data: [PRINT_BUF_SIZE]byte;
|
||||
buf := data[:0];
|
||||
bprintf(^buf, fmt, ..args);
|
||||
os.write(fd, buf);
|
||||
@@ -30,20 +30,20 @@ proc fprintf(fd os.Handle, fmt string, args ..any) -> int {
|
||||
}
|
||||
|
||||
|
||||
proc print(args ..any) -> int {
|
||||
print :: proc(args ..any) -> int {
|
||||
return fprint(os.stdout, ..args);
|
||||
}
|
||||
proc println(args ..any) -> int {
|
||||
println :: proc(args ..any) -> int {
|
||||
return fprintln(os.stdout, ..args);
|
||||
}
|
||||
proc printf(fmt string, args ..any) -> int {
|
||||
printf :: proc(fmt string, args ..any) -> int {
|
||||
return fprintf(os.stdout, fmt, ..args);
|
||||
}
|
||||
|
||||
|
||||
|
||||
proc fprint_type(fd os.Handle, info ^Type_Info) {
|
||||
data :[PRINT_BUF_SIZE]byte;
|
||||
fprint_type :: proc(fd os.Handle, info ^Type_Info) {
|
||||
data: [PRINT_BUF_SIZE]byte;
|
||||
buf := data[:0];
|
||||
bprint_type(^buf, info);
|
||||
os.write(fd, buf);
|
||||
@@ -51,7 +51,7 @@ proc fprint_type(fd os.Handle, info ^Type_Info) {
|
||||
|
||||
|
||||
|
||||
proc print_byte_buffer(buf ^[]byte, b []byte) {
|
||||
print_byte_buffer :: proc(buf ^[]byte, b []byte) {
|
||||
if buf.count < buf.capacity {
|
||||
n := min(buf.capacity-buf.count, b.count);
|
||||
if n > 0 {
|
||||
@@ -61,29 +61,29 @@ proc print_byte_buffer(buf ^[]byte, b []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
proc bprint_string(buf ^[]byte, s string) {
|
||||
bprint_string :: proc(buf ^[]byte, s string) {
|
||||
print_byte_buffer(buf, s as []byte);
|
||||
}
|
||||
|
||||
|
||||
proc byte_reverse(b []byte) {
|
||||
byte_reverse :: proc(b []byte) {
|
||||
n := b.count;
|
||||
for i := 0; i < n/2; i++ {
|
||||
b[i], b[n-1-i] = b[n-1-i], b[i];
|
||||
}
|
||||
}
|
||||
|
||||
proc bprint_rune(buf ^[]byte, r rune) {
|
||||
bprint_rune :: proc(buf ^[]byte, r rune) {
|
||||
b, n := utf8.encode_rune(r);
|
||||
bprint_string(buf, b[:n] as string);
|
||||
}
|
||||
|
||||
proc bprint_space(buf ^[]byte) { bprint_rune(buf, ' '); }
|
||||
proc bprint_nl (buf ^[]byte) { bprint_rune(buf, '\n'); }
|
||||
bprint_space :: proc(buf ^[]byte) { bprint_rune(buf, ' '); }
|
||||
bprint_nl :: proc (buf ^[]byte) { bprint_rune(buf, '\n'); }
|
||||
|
||||
__NUM_TO_CHAR_TABLE := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@$";
|
||||
|
||||
proc bprint_bool(buffer ^[]byte, b bool) {
|
||||
bprint_bool :: proc(buffer ^[]byte, b bool) {
|
||||
if b {
|
||||
bprint_string(buffer, "true");
|
||||
} else {
|
||||
@@ -91,15 +91,15 @@ proc bprint_bool(buffer ^[]byte, b bool) {
|
||||
}
|
||||
}
|
||||
|
||||
proc bprint_pointer(buffer ^[]byte, p rawptr) #inline {
|
||||
bprint_pointer :: proc(buffer ^[]byte, p rawptr) #inline {
|
||||
bprint_string(buffer, "0x");
|
||||
bprint_u64(buffer, p as uint as u64);
|
||||
}
|
||||
|
||||
proc bprint_f16 (buffer ^[]byte, f f32) #inline { print__f64(buffer, f as f64, 4); }
|
||||
proc bprint_f32 (buffer ^[]byte, f f32) #inline { print__f64(buffer, f as f64, 7); }
|
||||
proc bprint_f64 (buffer ^[]byte, f f64) #inline { print__f64(buffer, f as f64, 16); }
|
||||
proc bprint_u64(buffer ^[]byte, value u64) {
|
||||
bprint_f16 :: proc (buffer ^[]byte, f f32) #inline { print__f64(buffer, f as f64, 4); }
|
||||
bprint_f32 :: proc (buffer ^[]byte, f f32) #inline { print__f64(buffer, f as f64, 7); }
|
||||
bprint_f64 :: proc (buffer ^[]byte, f f64) #inline { print__f64(buffer, f as f64, 16); }
|
||||
bprint_u64 :: proc(buffer ^[]byte, value u64) {
|
||||
i := value;
|
||||
buf :[20]byte;
|
||||
len := 0;
|
||||
@@ -115,7 +115,7 @@ proc bprint_u64(buffer ^[]byte, value u64) {
|
||||
byte_reverse(buf[:len]);
|
||||
bprint_string(buffer, buf[:len] as string);
|
||||
}
|
||||
proc bprint_i64(buffer ^[]byte, value i64) {
|
||||
bprint_i64 :: proc(buffer ^[]byte, value i64) {
|
||||
// TODO(bill): Cleanup printing
|
||||
i := value;
|
||||
if i < 0 {
|
||||
@@ -126,14 +126,14 @@ proc bprint_i64(buffer ^[]byte, value i64) {
|
||||
}
|
||||
|
||||
/*
|
||||
proc bprint_u128(buffer ^[]byte, value u128) {
|
||||
bprint_u128 :: proc(buffer ^[]byte, value u128) {
|
||||
a := value transmute [2]u64;
|
||||
if a[1] != 0 {
|
||||
bprint_u64(buffer, a[1]);
|
||||
}
|
||||
bprint_u64(buffer, a[0]);
|
||||
}
|
||||
proc bprint_i128(buffer ^[]byte, value i128) {
|
||||
bprint_i128 :: proc(buffer ^[]byte, value i128) {
|
||||
i := value;
|
||||
if i < 0 {
|
||||
i = -i;
|
||||
@@ -144,7 +144,7 @@ proc bprint_i128(buffer ^[]byte, value i128) {
|
||||
*/
|
||||
|
||||
|
||||
proc print__f64(buffer ^[]byte, value f64, decimal_places int) {
|
||||
print__f64 :: proc(buffer ^[]byte, value f64, decimal_places int) {
|
||||
f := value;
|
||||
if f == 0 {
|
||||
bprint_rune(buffer, '0');
|
||||
@@ -170,7 +170,7 @@ proc print__f64(buffer ^[]byte, value f64, decimal_places int) {
|
||||
}
|
||||
}
|
||||
|
||||
proc bprint_type(buf ^[]byte, ti ^Type_Info) {
|
||||
bprint_type :: proc(buf ^[]byte, ti ^Type_Info) {
|
||||
if ti == nil {
|
||||
return;
|
||||
}
|
||||
@@ -302,14 +302,14 @@ proc bprint_type(buf ^[]byte, ti ^Type_Info) {
|
||||
}
|
||||
|
||||
|
||||
proc make_any(type_info ^Type_Info, data rawptr) -> any {
|
||||
make_any :: proc(type_info ^Type_Info, data rawptr) -> any {
|
||||
a :any;
|
||||
a.type_info = type_info;
|
||||
a.data = data;
|
||||
return a;
|
||||
}
|
||||
|
||||
proc bprint_any(buf ^[]byte, arg any) {
|
||||
bprint_any :: proc(buf ^[]byte, arg any) {
|
||||
if arg.type_info == nil {
|
||||
bprint_string(buf, "<nil>");
|
||||
return;
|
||||
@@ -423,7 +423,7 @@ proc bprint_any(buf ^[]byte, arg any) {
|
||||
}
|
||||
|
||||
case Vector:
|
||||
proc is_bool(type_info ^Type_Info) -> bool {
|
||||
is_bool :: proc(type_info ^Type_Info) -> bool {
|
||||
match type info : type_info {
|
||||
case Named:
|
||||
return is_bool(info.base);
|
||||
@@ -481,12 +481,12 @@ proc bprint_any(buf ^[]byte, arg any) {
|
||||
}
|
||||
|
||||
|
||||
proc bprintf(buf ^[]byte, fmt string, args ..any) -> int {
|
||||
proc is_digit(r rune) -> bool #inline {
|
||||
bprintf :: proc(buf ^[]byte, fmt string, args ..any) -> int {
|
||||
is_digit :: proc(r rune) -> bool #inline {
|
||||
return '0' <= r && r <= '9';
|
||||
}
|
||||
|
||||
proc parse_int(s string, offset int) -> (int, int) {
|
||||
parse_int :: proc(s string, offset int) -> (int, int) {
|
||||
result := 0;
|
||||
|
||||
for ; offset < s.count; offset++ {
|
||||
@@ -546,8 +546,8 @@ proc bprintf(buf ^[]byte, fmt string, args ..any) -> int {
|
||||
}
|
||||
|
||||
|
||||
proc bprint(buf ^[]byte, args ..any) -> int {
|
||||
proc is_type_string(info ^Type_Info) -> bool {
|
||||
bprint :: proc(buf ^[]byte, args ..any) -> int {
|
||||
is_type_string :: proc(info ^Type_Info) -> bool {
|
||||
using Type_Info;
|
||||
if info == nil {
|
||||
return false;
|
||||
@@ -574,7 +574,7 @@ proc bprint(buf ^[]byte, args ..any) -> int {
|
||||
return buf.count;
|
||||
}
|
||||
|
||||
proc bprintln(buf ^[]byte, args ..any) -> int {
|
||||
bprintln :: proc(buf ^[]byte, args ..any) -> int {
|
||||
for i := 0; i < args.count; i++ {
|
||||
if i > 0 {
|
||||
append(buf, ' ');
|
||||
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
proc crc32(data rawptr, len int) -> u32 {
|
||||
crc32 :: proc(data rawptr, len int) -> u32 {
|
||||
result := ~(0 as u32);
|
||||
s := slice_ptr(data as ^u8, len);
|
||||
for i := 0; i < len; i++ {
|
||||
@@ -7,7 +7,7 @@ proc crc32(data rawptr, len int) -> u32 {
|
||||
}
|
||||
return ~result;
|
||||
}
|
||||
proc crc64(data rawptr, len int) -> u64 {
|
||||
crc64 :: proc(data rawptr, len int) -> u64 {
|
||||
result := ~(0 as u64);
|
||||
s := slice_ptr(data as ^u8, len);
|
||||
for i := 0; i < len; i++ {
|
||||
@@ -17,7 +17,7 @@ proc crc64(data rawptr, len int) -> u64 {
|
||||
return ~result;
|
||||
}
|
||||
|
||||
proc fnv32(data rawptr, len int) -> u32 {
|
||||
fnv32 :: proc(data rawptr, len int) -> u32 {
|
||||
s := slice_ptr(data as ^u8, len);
|
||||
|
||||
h :u32 = 0x811c9dc5;
|
||||
@@ -27,7 +27,7 @@ proc fnv32(data rawptr, len int) -> u32 {
|
||||
return h;
|
||||
}
|
||||
|
||||
proc fnv64(data rawptr, len int) -> u64 {
|
||||
fnv64 :: proc(data rawptr, len int) -> u64 {
|
||||
s := slice_ptr(data as ^u8, len);
|
||||
|
||||
h :u64 = 0xcbf29ce484222325;
|
||||
@@ -37,7 +37,7 @@ proc fnv64(data rawptr, len int) -> u64 {
|
||||
return h;
|
||||
}
|
||||
|
||||
proc fnv32a(data rawptr, len int) -> u32 {
|
||||
fnv32a :: proc(data rawptr, len int) -> u32 {
|
||||
s := slice_ptr(data as ^u8, len);
|
||||
|
||||
h :u32 = 0x811c9dc5;
|
||||
@@ -47,7 +47,7 @@ proc fnv32a(data rawptr, len int) -> u32 {
|
||||
return h;
|
||||
}
|
||||
|
||||
proc fnv64a(data rawptr, len int) -> u64 {
|
||||
fnv64a :: proc(data rawptr, len int) -> u64 {
|
||||
s := slice_ptr(data as ^u8, len);
|
||||
|
||||
h :u64 = 0xcbf29ce484222325;
|
||||
@@ -58,7 +58,7 @@ proc fnv64a(data rawptr, len int) -> u64 {
|
||||
}
|
||||
|
||||
|
||||
proc murmur64(data_ rawptr, len int) -> u64 {
|
||||
murmur64 :: proc(data_ rawptr, len int) -> u64 {
|
||||
SEED :: 0x9747b28c;
|
||||
|
||||
when size_of(int) == 8 {
|
||||
|
||||
+51
-53
@@ -16,67 +16,65 @@ EPSILON :: 1.19209290e-7;
|
||||
τ :: TAU;
|
||||
π :: PI;
|
||||
|
||||
type {
|
||||
Vec2 [vector 2]f32;
|
||||
Vec3 [vector 3]f32;
|
||||
Vec4 [vector 4]f32;
|
||||
Vec2 :: [vector 2]f32;
|
||||
Vec3 :: [vector 3]f32;
|
||||
Vec4 :: [vector 4]f32;
|
||||
|
||||
Mat2 [2]Vec2;
|
||||
Mat3 [3]Vec3;
|
||||
Mat4 [4]Vec4;
|
||||
}
|
||||
Mat2 :: [2]Vec2;
|
||||
Mat3 :: [3]Vec3;
|
||||
Mat4 :: [4]Vec4;
|
||||
|
||||
proc sqrt32(x f32) -> f32 #foreign "llvm.sqrt.f32"
|
||||
proc sqrt64(x f64) -> f64 #foreign "llvm.sqrt.f64"
|
||||
sqrt32 :: proc(x f32) -> f32 #foreign "llvm.sqrt.f32"
|
||||
sqrt64 :: proc(x f64) -> f64 #foreign "llvm.sqrt.f64"
|
||||
|
||||
proc sin32(x f32) -> f32 #foreign "llvm.sin.f32"
|
||||
proc sin64(x f64) -> f64 #foreign "llvm.sin.f64"
|
||||
sin32 :: proc(x f32) -> f32 #foreign "llvm.sin.f32"
|
||||
sin64 :: proc(x f64) -> f64 #foreign "llvm.sin.f64"
|
||||
|
||||
proc cos32(x f32) -> f32 #foreign "llvm.cos.f32"
|
||||
proc cos64(x f64) -> f64 #foreign "llvm.cos.f64"
|
||||
cos32 :: proc(x f32) -> f32 #foreign "llvm.cos.f32"
|
||||
cos64 :: proc(x f64) -> f64 #foreign "llvm.cos.f64"
|
||||
|
||||
proc tan32(x f32) -> f32 #inline { return sin32(x)/cos32(x); }
|
||||
proc tan64(x f64) -> f64 #inline { return sin64(x)/cos64(x); }
|
||||
tan32 :: proc(x f32) -> f32 #inline { return sin32(x)/cos32(x); }
|
||||
tan64 :: proc(x f64) -> f64 #inline { return sin64(x)/cos64(x); }
|
||||
|
||||
proc lerp32(a, b, t f32) -> f32 { return a*(1-t) + b*t; }
|
||||
proc lerp64(a, b, t f64) -> f64 { return a*(1-t) + b*t; }
|
||||
lerp32 :: proc(a, b, t f32) -> f32 { return a*(1-t) + b*t; }
|
||||
lerp64 :: proc(a, b, t f64) -> f64 { return a*(1-t) + b*t; }
|
||||
|
||||
proc sign32(x f32) -> f32 { if x >= 0 { return +1; } return -1; }
|
||||
proc sign64(x f64) -> f64 { if x >= 0 { return +1; } return -1; }
|
||||
sign32 :: proc(x f32) -> f32 { if x >= 0 { return +1; } return -1; }
|
||||
sign64 :: proc(x f64) -> f64 { if x >= 0 { return +1; } return -1; }
|
||||
|
||||
|
||||
|
||||
proc copy_sign32(x, y f32) -> f32 {
|
||||
copy_sign32 :: proc(x, y f32) -> f32 {
|
||||
ix := x transmute u32;
|
||||
iy := y transmute u32;
|
||||
ix &= 0x7fffffff;
|
||||
ix |= iy & 0x80000000;
|
||||
return ix transmute f32;
|
||||
}
|
||||
proc round32(x f32) -> f32 {
|
||||
round32 :: proc(x f32) -> f32 {
|
||||
if x >= 0 {
|
||||
return floor32(x + 0.5);
|
||||
}
|
||||
return ceil32(x - 0.5);
|
||||
}
|
||||
proc floor32(x f32) -> f32 {
|
||||
floor32 :: proc(x f32) -> f32 {
|
||||
if x >= 0 {
|
||||
return x as int as f32;
|
||||
}
|
||||
return (x-0.5) as int as f32;
|
||||
}
|
||||
proc ceil32(x f32) -> f32 {
|
||||
ceil32 :: proc(x f32) -> f32 {
|
||||
if x < 0 {
|
||||
return x as int as f32;
|
||||
}
|
||||
return ((x as int)+1) as f32;
|
||||
}
|
||||
|
||||
proc remainder32(x, y f32) -> f32 {
|
||||
remainder32 :: proc(x, y f32) -> f32 {
|
||||
return x - round32(x/y) * y;
|
||||
}
|
||||
|
||||
proc fmod32(x, y f32) -> f32 {
|
||||
fmod32 :: proc(x, y f32) -> f32 {
|
||||
y = abs(y);
|
||||
result := remainder32(abs(x), y);
|
||||
if sign32(result) < 0 {
|
||||
@@ -86,32 +84,32 @@ proc fmod32(x, y f32) -> f32 {
|
||||
}
|
||||
|
||||
|
||||
proc to_radians(degrees f32) -> f32 { return degrees * TAU / 360; }
|
||||
proc to_degrees(radians f32) -> f32 { return radians * 360 / TAU; }
|
||||
to_radians :: proc(degrees f32) -> f32 { return degrees * TAU / 360; }
|
||||
to_degrees :: proc(radians f32) -> f32 { return radians * 360 / TAU; }
|
||||
|
||||
|
||||
|
||||
|
||||
proc dot2(a, b Vec2) -> f32 { c := a*b; return c.x + c.y; }
|
||||
proc dot3(a, b Vec3) -> f32 { c := a*b; return c.x + c.y + c.z; }
|
||||
proc dot4(a, b Vec4) -> f32 { c := a*b; return c.x + c.y + c.z + c.w; }
|
||||
dot2 :: proc(a, b Vec2) -> f32 { c := a*b; return c.x + c.y; }
|
||||
dot3 :: proc(a, b Vec3) -> f32 { c := a*b; return c.x + c.y + c.z; }
|
||||
dot4 :: proc(a, b Vec4) -> f32 { c := a*b; return c.x + c.y + c.z + c.w; }
|
||||
|
||||
proc cross3(x, y Vec3) -> Vec3 {
|
||||
cross3 :: proc(x, y Vec3) -> Vec3 {
|
||||
a := swizzle(x, 1, 2, 0) * swizzle(y, 2, 0, 1);
|
||||
b := swizzle(x, 2, 0, 1) * swizzle(y, 1, 2, 0);
|
||||
return a - b;
|
||||
}
|
||||
|
||||
|
||||
proc vec2_mag(v Vec2) -> f32 { return sqrt32(dot2(v, v)); }
|
||||
proc vec3_mag(v Vec3) -> f32 { return sqrt32(dot3(v, v)); }
|
||||
proc vec4_mag(v Vec4) -> f32 { return sqrt32(dot4(v, v)); }
|
||||
vec2_mag :: proc(v Vec2) -> f32 { return sqrt32(dot2(v, v)); }
|
||||
vec3_mag :: proc(v Vec3) -> f32 { return sqrt32(dot3(v, v)); }
|
||||
vec4_mag :: proc(v Vec4) -> f32 { return sqrt32(dot4(v, v)); }
|
||||
|
||||
proc vec2_norm(v Vec2) -> Vec2 { return v / Vec2{vec2_mag(v)}; }
|
||||
proc vec3_norm(v Vec3) -> Vec3 { return v / Vec3{vec3_mag(v)}; }
|
||||
proc vec4_norm(v Vec4) -> Vec4 { return v / Vec4{vec4_mag(v)}; }
|
||||
vec2_norm :: proc(v Vec2) -> Vec2 { return v / Vec2{vec2_mag(v)}; }
|
||||
vec3_norm :: proc(v Vec3) -> Vec3 { return v / Vec3{vec3_mag(v)}; }
|
||||
vec4_norm :: proc(v Vec4) -> Vec4 { return v / Vec4{vec4_mag(v)}; }
|
||||
|
||||
proc vec2_norm0(v Vec2) -> Vec2 {
|
||||
vec2_norm0 :: proc(v Vec2) -> Vec2 {
|
||||
m := vec2_mag(v);
|
||||
if m == 0 {
|
||||
return Vec2{0};
|
||||
@@ -119,7 +117,7 @@ proc vec2_norm0(v Vec2) -> Vec2 {
|
||||
return v / Vec2{m};
|
||||
}
|
||||
|
||||
proc vec3_norm0(v Vec3) -> Vec3 {
|
||||
vec3_norm0 :: proc(v Vec3) -> Vec3 {
|
||||
m := vec3_mag(v);
|
||||
if m == 0 {
|
||||
return Vec3{0};
|
||||
@@ -127,7 +125,7 @@ proc vec3_norm0(v Vec3) -> Vec3 {
|
||||
return v / Vec3{m};
|
||||
}
|
||||
|
||||
proc vec4_norm0(v Vec4) -> Vec4 {
|
||||
vec4_norm0 :: proc(v Vec4) -> Vec4 {
|
||||
m := vec4_mag(v);
|
||||
if m == 0 {
|
||||
return Vec4{0};
|
||||
@@ -137,7 +135,7 @@ proc vec4_norm0(v Vec4) -> Vec4 {
|
||||
|
||||
|
||||
|
||||
proc mat4_identity() -> Mat4 {
|
||||
mat4_identity :: proc() -> Mat4 {
|
||||
return Mat4{
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
@@ -146,7 +144,7 @@ proc mat4_identity() -> Mat4 {
|
||||
};
|
||||
}
|
||||
|
||||
proc mat4_transpose(m Mat4) -> Mat4 {
|
||||
mat4_transpose :: proc(m Mat4) -> Mat4 {
|
||||
for j := 0; j < 4; j++ {
|
||||
for i := 0; i < 4; i++ {
|
||||
m[i][j], m[j][i] = m[j][i], m[i][j];
|
||||
@@ -155,7 +153,7 @@ proc mat4_transpose(m Mat4) -> Mat4 {
|
||||
return m;
|
||||
}
|
||||
|
||||
proc mat4_mul(a, b Mat4) -> Mat4 {
|
||||
mat4_mul :: proc(a, b Mat4) -> Mat4 {
|
||||
c: Mat4;
|
||||
for j := 0; j < 4; j++ {
|
||||
for i := 0; i < 4; i++ {
|
||||
@@ -168,7 +166,7 @@ proc mat4_mul(a, b Mat4) -> Mat4 {
|
||||
return c;
|
||||
}
|
||||
|
||||
proc mat4_mul_vec4(m Mat4, v Vec4) -> Vec4 {
|
||||
mat4_mul_vec4 :: proc(m Mat4, v Vec4) -> Vec4 {
|
||||
return Vec4{
|
||||
m[0][0]*v.x + m[1][0]*v.y + m[2][0]*v.z + m[3][0]*v.w,
|
||||
m[0][1]*v.x + m[1][1]*v.y + m[2][1]*v.z + m[3][1]*v.w,
|
||||
@@ -177,7 +175,7 @@ proc mat4_mul_vec4(m Mat4, v Vec4) -> Vec4 {
|
||||
};
|
||||
}
|
||||
|
||||
proc mat4_inverse(m Mat4) -> Mat4 {
|
||||
mat4_inverse :: proc(m Mat4) -> Mat4 {
|
||||
o: Mat4;
|
||||
|
||||
sf00 := m[2][2] * m[3][3] - m[3][2] * m[2][3];
|
||||
@@ -246,7 +244,7 @@ proc mat4_inverse(m Mat4) -> Mat4 {
|
||||
}
|
||||
|
||||
|
||||
proc mat4_translate(v Vec3) -> Mat4 {
|
||||
mat4_translate :: proc(v Vec3) -> Mat4 {
|
||||
m := mat4_identity();
|
||||
m[3][0] = v.x;
|
||||
m[3][1] = v.y;
|
||||
@@ -255,7 +253,7 @@ proc mat4_translate(v Vec3) -> Mat4 {
|
||||
return m;
|
||||
}
|
||||
|
||||
proc mat4_rotate(v Vec3, angle_radians f32) -> Mat4 {
|
||||
mat4_rotate :: proc(v Vec3, angle_radians f32) -> Mat4 {
|
||||
c := cos32(angle_radians);
|
||||
s := sin32(angle_radians);
|
||||
|
||||
@@ -282,14 +280,14 @@ proc mat4_rotate(v Vec3, angle_radians f32) -> Mat4 {
|
||||
return rot;
|
||||
}
|
||||
|
||||
proc mat4_scale(m Mat4, v Vec3) -> Mat4 {
|
||||
mat4_scale :: proc(m Mat4, v Vec3) -> Mat4 {
|
||||
m[0][0] *= v.x;
|
||||
m[1][1] *= v.y;
|
||||
m[2][2] *= v.z;
|
||||
return m;
|
||||
}
|
||||
|
||||
proc mat4_scalef(m Mat4, s f32) -> Mat4 {
|
||||
mat4_scalef :: proc(m Mat4, s f32) -> Mat4 {
|
||||
m[0][0] *= s;
|
||||
m[1][1] *= s;
|
||||
m[2][2] *= s;
|
||||
@@ -297,7 +295,7 @@ proc mat4_scalef(m Mat4, s f32) -> Mat4 {
|
||||
}
|
||||
|
||||
|
||||
proc mat4_look_at(eye, centre, up Vec3) -> Mat4 {
|
||||
mat4_look_at :: proc(eye, centre, up Vec3) -> Mat4 {
|
||||
f := vec3_norm(centre - eye);
|
||||
s := vec3_norm(cross3(f, up));
|
||||
u := cross3(s, f);
|
||||
@@ -311,7 +309,7 @@ proc mat4_look_at(eye, centre, up Vec3) -> Mat4 {
|
||||
|
||||
return m;
|
||||
}
|
||||
proc mat4_perspective(fovy, aspect, near, far f32) -> Mat4 {
|
||||
mat4_perspective :: proc(fovy, aspect, near, far f32) -> Mat4 {
|
||||
m: Mat4;
|
||||
tan_half_fovy := tan32(0.5 * fovy);
|
||||
m[0][0] = 1.0 / (aspect*tan_half_fovy);
|
||||
@@ -323,7 +321,7 @@ proc mat4_perspective(fovy, aspect, near, far f32) -> Mat4 {
|
||||
}
|
||||
|
||||
|
||||
proc mat4_ortho3d(left, right, bottom, top, near, far f32) -> Mat4 {
|
||||
mat4_ortho3d :: proc(left, right, bottom, top, near, far f32) -> Mat4 {
|
||||
m := mat4_identity();
|
||||
m[0][0] = +2.0 / (right - left);
|
||||
m[1][1] = +2.0 / (top - bottom);
|
||||
|
||||
+38
-40
@@ -3,32 +3,31 @@ import {
|
||||
"os.odin";
|
||||
}
|
||||
|
||||
proc set(data rawptr, value i32, len int) -> rawptr #link_name "__mem_set" {
|
||||
proc llvm_memset_64bit(dst rawptr, val byte, len int, align i32, is_volatile bool) #foreign "llvm.memset.p0i8.i64"
|
||||
set :: proc(data rawptr, value i32, len int) -> rawptr #link_name "__mem_set" {
|
||||
llvm_memset_64bit :: proc(dst rawptr, val byte, len int, align i32, is_volatile bool) #foreign "llvm.memset.p0i8.i64"
|
||||
llvm_memset_64bit(data, value as byte, len, 1, false);
|
||||
return data;
|
||||
}
|
||||
|
||||
proc zero(data rawptr, len int) -> rawptr #link_name "__mem_zero" {
|
||||
zero :: proc(data rawptr, len int) -> rawptr #link_name "__mem_zero" {
|
||||
return set(data, 0, len);
|
||||
}
|
||||
|
||||
proc copy(dst, src rawptr, len int) -> rawptr #link_name "__mem_copy" {
|
||||
copy :: proc(dst, src rawptr, len int) -> rawptr #link_name "__mem_copy" {
|
||||
// NOTE(bill): This _must_ implemented like C's memmove
|
||||
proc llvm_memmove_64bit(dst, src rawptr, len int, align i32, is_volatile bool) #foreign "llvm.memmove.p0i8.p0i8.i64"
|
||||
llvm_memmove_64bit :: proc(dst, src rawptr, len int, align i32, is_volatile bool) #foreign "llvm.memmove.p0i8.p0i8.i64"
|
||||
llvm_memmove_64bit(dst, src, len, 1, false);
|
||||
return dst;
|
||||
}
|
||||
|
||||
proc copy_non_overlapping(dst, src rawptr, len int) -> rawptr #link_name "__mem_copy_non_overlapping" {
|
||||
copy_non_overlapping :: proc(dst, src rawptr, len int) -> rawptr #link_name "__mem_copy_non_overlapping" {
|
||||
// NOTE(bill): This _must_ implemented like C's memcpy
|
||||
proc llvm_memcpy_64bit(dst, src rawptr, len int, align i32, is_volatile bool) #foreign "llvm.memcpy.p0i8.p0i8.i64"
|
||||
llvm_memcpy_64bit :: proc(dst, src rawptr, len int, align i32, is_volatile bool) #foreign "llvm.memcpy.p0i8.p0i8.i64"
|
||||
llvm_memcpy_64bit(dst, src, len, 1, false);
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
proc compare(dst, src rawptr, n int) -> int #link_name "__mem_compare" {
|
||||
compare :: proc(dst, src rawptr, n int) -> int #link_name "__mem_compare" {
|
||||
// Translation of http://mgronhol.github.io/fast-strcmp/
|
||||
a := slice_ptr(dst as ^byte, n);
|
||||
b := slice_ptr(src as ^byte, n);
|
||||
@@ -65,19 +64,19 @@ proc compare(dst, src rawptr, n int) -> int #link_name "__mem_compare" {
|
||||
|
||||
|
||||
|
||||
proc kilobytes(x int) -> int #inline { return (x) * 1024; }
|
||||
proc megabytes(x int) -> int #inline { return kilobytes(x) * 1024; }
|
||||
proc gigabytes(x int) -> int #inline { return gigabytes(x) * 1024; }
|
||||
proc terabytes(x int) -> int #inline { return terabytes(x) * 1024; }
|
||||
kilobytes :: proc(x int) -> int #inline { return (x) * 1024; }
|
||||
megabytes :: proc(x int) -> int #inline { return kilobytes(x) * 1024; }
|
||||
gigabytes :: proc(x int) -> int #inline { return gigabytes(x) * 1024; }
|
||||
terabytes :: proc(x int) -> int #inline { return terabytes(x) * 1024; }
|
||||
|
||||
proc is_power_of_two(x int) -> bool {
|
||||
is_power_of_two :: proc(x int) -> bool {
|
||||
if x <= 0 {
|
||||
return false;
|
||||
}
|
||||
return (x & (x-1)) == 0;
|
||||
}
|
||||
|
||||
proc align_forward(ptr rawptr, align int) -> rawptr {
|
||||
align_forward :: proc(ptr rawptr, align int) -> rawptr {
|
||||
assert(is_power_of_two(align));
|
||||
|
||||
a := align as uint;
|
||||
@@ -91,11 +90,11 @@ proc align_forward(ptr rawptr, align int) -> rawptr {
|
||||
|
||||
|
||||
|
||||
type Allocation_Header struct {
|
||||
Allocation_Header :: struct {
|
||||
size int;
|
||||
}
|
||||
|
||||
proc allocation_header_fill(header ^Allocation_Header, data rawptr, size int) {
|
||||
allocation_header_fill :: proc(header ^Allocation_Header, data rawptr, size int) {
|
||||
header.size = size;
|
||||
ptr := (header+1) as ^int;
|
||||
|
||||
@@ -103,7 +102,7 @@ proc allocation_header_fill(header ^Allocation_Header, data rawptr, size int) {
|
||||
(ptr+i)^ = -1;
|
||||
}
|
||||
}
|
||||
proc allocation_header(data rawptr) -> ^Allocation_Header {
|
||||
allocation_header :: proc(data rawptr) -> ^Allocation_Header {
|
||||
p := data as ^int;
|
||||
for (p-1)^ == -1 {
|
||||
p = (p-1);
|
||||
@@ -116,35 +115,34 @@ proc allocation_header(data rawptr) -> ^Allocation_Header {
|
||||
|
||||
|
||||
// Custom allocators
|
||||
type {
|
||||
Arena struct {
|
||||
backing Allocator;
|
||||
memory []byte;
|
||||
temp_count int;
|
||||
}
|
||||
Arena :: struct {
|
||||
backing Allocator;
|
||||
memory []byte;
|
||||
temp_count int;
|
||||
}
|
||||
|
||||
Arena_Temp_Memory struct {
|
||||
arena ^Arena;
|
||||
original_count int;
|
||||
}
|
||||
Arena_Temp_Memory :: struct {
|
||||
arena ^Arena;
|
||||
original_count int;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
proc init_arena_from_memory(using a ^Arena, data []byte) {
|
||||
|
||||
init_arena_from_memory :: proc(using a ^Arena, data []byte) {
|
||||
backing = Allocator{};
|
||||
memory = data[:0];
|
||||
temp_count = 0;
|
||||
}
|
||||
|
||||
proc init_arena_from_context(using a ^Arena, size int) {
|
||||
init_arena_from_context :: proc(using a ^Arena, size int) {
|
||||
backing = context.allocator;
|
||||
memory = new_slice(byte, 0, size);
|
||||
temp_count = 0;
|
||||
}
|
||||
|
||||
proc free_arena(using a ^Arena) {
|
||||
free_arena :: proc(using a ^Arena) {
|
||||
if backing.procedure != nil {
|
||||
push_allocator backing {
|
||||
free(memory.data);
|
||||
@@ -153,14 +151,14 @@ proc free_arena(using a ^Arena) {
|
||||
}
|
||||
}
|
||||
|
||||
proc arena_allocator(arena ^Arena) -> Allocator {
|
||||
arena_allocator :: proc(arena ^Arena) -> Allocator {
|
||||
return Allocator{
|
||||
procedure = arena_allocator_proc,
|
||||
data = arena,
|
||||
};
|
||||
}
|
||||
|
||||
proc arena_allocator_proc(allocator_data rawptr, mode Allocator_Mode,
|
||||
arena_allocator_proc :: proc(allocator_data rawptr, mode Allocator_Mode,
|
||||
size, alignment int,
|
||||
old_memory rawptr, old_size int, flags u64) -> rawptr {
|
||||
using Allocator_Mode;
|
||||
@@ -195,7 +193,7 @@ proc arena_allocator_proc(allocator_data rawptr, mode Allocator_Mode,
|
||||
return nil;
|
||||
}
|
||||
|
||||
proc begin_arena_temp_memory(a ^Arena) -> Arena_Temp_Memory {
|
||||
begin_arena_temp_memory :: proc(a ^Arena) -> Arena_Temp_Memory {
|
||||
tmp: Arena_Temp_Memory;
|
||||
tmp.arena = a;
|
||||
tmp.original_count = a.memory.count;
|
||||
@@ -203,7 +201,7 @@ proc begin_arena_temp_memory(a ^Arena) -> Arena_Temp_Memory {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
proc end_arena_temp_memory(using tmp Arena_Temp_Memory) {
|
||||
end_arena_temp_memory :: proc(using tmp Arena_Temp_Memory) {
|
||||
assert(arena.memory.count >= original_count);
|
||||
assert(arena.temp_count > 0);
|
||||
arena.memory.count = original_count;
|
||||
@@ -216,8 +214,8 @@ proc end_arena_temp_memory(using tmp Arena_Temp_Memory) {
|
||||
|
||||
|
||||
|
||||
proc align_of_type_info(type_info ^Type_Info) -> int {
|
||||
proc prev_pow2(n i64) -> i64 {
|
||||
align_of_type_info :: proc(type_info ^Type_Info) -> int {
|
||||
prev_pow2 :: proc(n i64) -> i64 {
|
||||
if n <= 0 {
|
||||
return 0;
|
||||
}
|
||||
@@ -271,12 +269,12 @@ proc align_of_type_info(type_info ^Type_Info) -> int {
|
||||
return 0;
|
||||
}
|
||||
|
||||
proc align_formula(size, align int) -> int {
|
||||
align_formula :: proc(size, align int) -> int {
|
||||
result := size + align-1;
|
||||
return result - result%align;
|
||||
}
|
||||
|
||||
proc size_of_type_info(type_info ^Type_Info) -> int {
|
||||
size_of_type_info :: proc(type_info ^Type_Info) -> int {
|
||||
WORD_SIZE :: size_of(int);
|
||||
using Type_Info;
|
||||
match type info : type_info {
|
||||
@@ -310,7 +308,7 @@ proc size_of_type_info(type_info ^Type_Info) -> int {
|
||||
case Slice:
|
||||
return 3*WORD_SIZE;
|
||||
case Vector:
|
||||
proc is_bool(type_info ^Type_Info) -> bool {
|
||||
is_bool :: proc(type_info ^Type_Info) -> bool {
|
||||
match type info : type_info {
|
||||
case Named:
|
||||
return is_bool(info.base);
|
||||
|
||||
+27
-27
@@ -2,37 +2,37 @@
|
||||
import win32 "sys/windows.odin" when ODIN_OS == "windows";
|
||||
include "opengl_constants.odin";
|
||||
|
||||
proc Clear (mask u32) #foreign "glClear"
|
||||
proc ClearColor (r, g, b, a f32) #foreign "glClearColor"
|
||||
proc Begin (mode i32) #foreign "glBegin"
|
||||
proc End () #foreign "glEnd"
|
||||
proc Finish () #foreign "glFinish"
|
||||
proc BlendFunc (sfactor, dfactor i32) #foreign "glBlendFunc"
|
||||
proc Enable (cap i32) #foreign "glEnable"
|
||||
proc Disable (cap i32) #foreign "glDisable"
|
||||
proc GenTextures (count i32, result ^u32) #foreign "glGenTextures"
|
||||
proc DeleteTextures(count i32, result ^u32) #foreign "glDeleteTextures"
|
||||
proc TexParameteri (target, pname, param i32) #foreign "glTexParameteri"
|
||||
proc TexParameterf (target i32, pname i32, param f32) #foreign "glTexParameterf"
|
||||
proc BindTexture (target i32, texture u32) #foreign "glBindTexture"
|
||||
proc LoadIdentity () #foreign "glLoadIdentity"
|
||||
proc Viewport (x, y, width, height i32) #foreign "glViewport"
|
||||
proc Ortho (left, right, bottom, top, near, far f64) #foreign "glOrtho"
|
||||
proc Color3f (r, g, b f32) #foreign "glColor3f"
|
||||
proc Vertex3f (x, y, z f32) #foreign "glVertex3f"
|
||||
proc TexImage2D (target, level, internal_format,
|
||||
width, height, border,
|
||||
format, _type i32, pixels rawptr) #foreign "glTexImage2D"
|
||||
Clear :: proc(mask u32) #foreign "glClear"
|
||||
ClearColor :: proc(r, g, b, a f32) #foreign "glClearColor"
|
||||
Begin :: proc(mode i32) #foreign "glBegin"
|
||||
End :: proc() #foreign "glEnd"
|
||||
Finish :: proc() #foreign "glFinish"
|
||||
BlendFunc :: proc(sfactor, dfactor i32) #foreign "glBlendFunc"
|
||||
Enable :: proc(cap i32) #foreign "glEnable"
|
||||
Disable :: proc(cap i32) #foreign "glDisable"
|
||||
GenTextures :: proc(count i32, result ^u32) #foreign "glGenTextures"
|
||||
DeleteTextures:: proc(count i32, result ^u32) #foreign "glDeleteTextures"
|
||||
TexParameteri :: proc(target, pname, param i32) #foreign "glTexParameteri"
|
||||
TexParameterf :: proc(target i32, pname i32, param f32) #foreign "glTexParameterf"
|
||||
BindTexture :: proc(target i32, texture u32) #foreign "glBindTexture"
|
||||
LoadIdentity :: proc() #foreign "glLoadIdentity"
|
||||
Viewport :: proc(x, y, width, height i32) #foreign "glViewport"
|
||||
Ortho :: proc(left, right, bottom, top, near, far f64) #foreign "glOrtho"
|
||||
Color3f :: proc(r, g, b f32) #foreign "glColor3f"
|
||||
Vertex3f :: proc(x, y, z f32) #foreign "glVertex3f"
|
||||
TexImage2D :: proc(target, level, internal_format,
|
||||
width, height, border,
|
||||
format, _type i32, pixels rawptr) #foreign "glTexImage2D"
|
||||
|
||||
proc GetError () -> i32 #foreign "glGetError"
|
||||
proc GetString (name i32) -> ^byte #foreign "glGetString"
|
||||
proc GetIntegerv(name i32, v ^i32) #foreign "glGetIntegerv"
|
||||
GetError :: proc() -> i32 #foreign "glGetError"
|
||||
GetString :: proc(name i32) -> ^byte #foreign "glGetString"
|
||||
GetIntegerv :: proc(name i32, v ^i32) #foreign "glGetIntegerv"
|
||||
|
||||
|
||||
|
||||
_libgl := win32.LoadLibraryA(("opengl32.dll\x00" as string).data);
|
||||
|
||||
proc GetProcAddress(name string) -> proc() #cc_c {
|
||||
GetProcAddress :: proc(name string) -> proc() #cc_c {
|
||||
assert(name[name.count-1] == 0);
|
||||
res := win32.wglGetProcAddress(name.data);
|
||||
if res == nil {
|
||||
@@ -99,8 +99,8 @@ UniformMatrix4fv: proc(loc i32, count u32, transpose i32, value ^f32) #cc_c;
|
||||
|
||||
GetUniformLocation: proc(program u32, name ^byte) -> i32 #cc_c;
|
||||
|
||||
proc init() {
|
||||
proc set_proc_address(p rawptr, name string) #inline { (p as ^(proc() #cc_c))^ = GetProcAddress(name); }
|
||||
init :: proc() {
|
||||
set_proc_address :: proc(p rawptr, name string) #inline { (p as ^(proc() #cc_c))^ = GetProcAddress(name); }
|
||||
|
||||
set_proc_address(^GenBuffers, "glGenBuffers\x00");
|
||||
set_proc_address(^GenVertexArrays, "glGenVertexArrays\x00");
|
||||
|
||||
+18
-20
@@ -4,11 +4,9 @@ import {
|
||||
}
|
||||
|
||||
|
||||
type {
|
||||
Handle uint;
|
||||
File_Time u64;
|
||||
Error int;
|
||||
}
|
||||
Handle :: uint;
|
||||
File_Time :: u64;
|
||||
Error :: int;
|
||||
|
||||
INVALID_HANDLE: Handle : ~(0 as Handle);
|
||||
|
||||
@@ -56,7 +54,7 @@ ERROR_FILE_IS_PIPE : Error : 1<<29 + 0;
|
||||
|
||||
|
||||
|
||||
proc open(path string, mode int, perm u32) -> (Handle, Error) {
|
||||
open :: proc(path string, mode int, perm u32) -> (Handle, Error) {
|
||||
using win32;
|
||||
if path.count == 0 {
|
||||
return INVALID_HANDLE, ERROR_FILE_NOT_FOUND;
|
||||
@@ -109,11 +107,11 @@ proc open(path string, mode int, perm u32) -> (Handle, Error) {
|
||||
return INVALID_HANDLE, err as Error;
|
||||
}
|
||||
|
||||
proc close(fd Handle) {
|
||||
close :: proc(fd Handle) {
|
||||
win32.CloseHandle(fd as win32.HANDLE);
|
||||
}
|
||||
|
||||
proc write(fd Handle, data []byte) -> (int, Error) {
|
||||
write :: proc(fd Handle, data []byte) -> (int, Error) {
|
||||
bytes_written: i32;
|
||||
e := win32.WriteFile(fd as win32.HANDLE, data.data, data.count as i32, ^bytes_written, nil);
|
||||
if e != 0 {
|
||||
@@ -122,7 +120,7 @@ proc write(fd Handle, data []byte) -> (int, Error) {
|
||||
return bytes_written as int, ERROR_NONE;
|
||||
}
|
||||
|
||||
proc read(fd Handle, data []byte) -> (int, Error) {
|
||||
read :: proc(fd Handle, data []byte) -> (int, Error) {
|
||||
bytes_read: i32;
|
||||
e := win32.ReadFile(fd as win32.HANDLE, data.data, data.count as u32, ^bytes_read, nil);
|
||||
if e != win32.FALSE {
|
||||
@@ -132,7 +130,7 @@ proc read(fd Handle, data []byte) -> (int, Error) {
|
||||
return bytes_read as int, ERROR_NONE;
|
||||
}
|
||||
|
||||
proc seek(fd Handle, offset i64, whence int) -> (i64, Error) {
|
||||
seek :: proc(fd Handle, offset i64, whence int) -> (i64, Error) {
|
||||
using win32;
|
||||
w: u32;
|
||||
match whence {
|
||||
@@ -161,7 +159,7 @@ stdout := get_std_handle(win32.STD_OUTPUT_HANDLE);
|
||||
stderr := get_std_handle(win32.STD_ERROR_HANDLE);
|
||||
|
||||
|
||||
proc get_std_handle(h int) -> Handle {
|
||||
get_std_handle :: proc(h int) -> Handle {
|
||||
fd := win32.GetStdHandle(h as i32);
|
||||
win32.SetHandleInformation(fd, win32.HANDLE_FLAG_INHERIT, 0);
|
||||
return fd as Handle;
|
||||
@@ -172,7 +170,7 @@ proc get_std_handle(h int) -> Handle {
|
||||
|
||||
|
||||
|
||||
proc last_write_time(fd Handle) -> File_Time {
|
||||
last_write_time :: proc(fd Handle) -> File_Time {
|
||||
file_info: win32.BY_HANDLE_FILE_INFORMATION;
|
||||
win32.GetFileInformationByHandle(fd as win32.HANDLE, ^file_info);
|
||||
lo := file_info.last_write_time.lo as File_Time;
|
||||
@@ -180,7 +178,7 @@ proc last_write_time(fd Handle) -> File_Time {
|
||||
return lo | hi << 32;
|
||||
}
|
||||
|
||||
proc last_write_time_by_name(name string) -> File_Time {
|
||||
last_write_time_by_name :: proc(name string) -> File_Time {
|
||||
last_write_time: win32.FILETIME;
|
||||
data: win32.FILE_ATTRIBUTE_DATA;
|
||||
buf: [1024]byte;
|
||||
@@ -202,7 +200,7 @@ proc last_write_time_by_name(name string) -> File_Time {
|
||||
|
||||
|
||||
|
||||
proc read_entire_file(name string) -> ([]byte, bool) {
|
||||
read_entire_file :: proc(name string) -> ([]byte, bool) {
|
||||
buf: [300]byte;
|
||||
copy(buf[:], name as []byte);
|
||||
|
||||
@@ -250,25 +248,25 @@ proc read_entire_file(name string) -> ([]byte, bool) {
|
||||
|
||||
|
||||
|
||||
proc heap_alloc(size int) -> rawptr {
|
||||
heap_alloc :: proc(size int) -> rawptr {
|
||||
return win32.HeapAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, size);
|
||||
}
|
||||
proc heap_resize(ptr rawptr, new_size int) -> rawptr {
|
||||
heap_resize :: proc(ptr rawptr, new_size int) -> rawptr {
|
||||
return win32.HeapReAlloc(win32.GetProcessHeap(), win32.HEAP_ZERO_MEMORY, ptr, new_size);
|
||||
}
|
||||
proc heap_free(ptr rawptr) {
|
||||
heap_free :: proc(ptr rawptr) {
|
||||
win32.HeapFree(win32.GetProcessHeap(), 0, ptr);
|
||||
}
|
||||
|
||||
|
||||
proc exit(code int) {
|
||||
exit :: proc(code int) {
|
||||
win32.ExitProcess(code as u32);
|
||||
}
|
||||
|
||||
|
||||
|
||||
proc current_thread_id() -> int {
|
||||
proc GetCurrentThreadId() -> u32 #foreign #dll_import
|
||||
current_thread_id :: proc() -> int {
|
||||
GetCurrentThreadId :: proc() -> u32 #foreign #dll_import
|
||||
return GetCurrentThreadId() as int;
|
||||
}
|
||||
|
||||
|
||||
+20
-22
@@ -3,52 +3,50 @@ import {
|
||||
"atomic.odin";
|
||||
}
|
||||
|
||||
type {
|
||||
Semaphore struct {
|
||||
handle win32.HANDLE;
|
||||
}
|
||||
|
||||
Mutex struct {
|
||||
semaphore Semaphore;
|
||||
counter i32;
|
||||
owner i32;
|
||||
recursion i32;
|
||||
}
|
||||
Semaphore :: struct {
|
||||
handle win32.HANDLE;
|
||||
}
|
||||
|
||||
proc current_thread_id() -> i32 {
|
||||
Mutex :: struct {
|
||||
semaphore Semaphore;
|
||||
counter i32;
|
||||
owner i32;
|
||||
recursion i32;
|
||||
}
|
||||
|
||||
current_thread_id :: proc() -> i32 {
|
||||
return win32.GetCurrentThreadId() as i32;
|
||||
}
|
||||
|
||||
proc semaphore_init(s ^Semaphore) {
|
||||
semaphore_init :: proc(s ^Semaphore) {
|
||||
s.handle = win32.CreateSemaphoreA(nil, 0, 1<<31-1, nil);
|
||||
}
|
||||
|
||||
proc semaphore_destroy(s ^Semaphore) {
|
||||
semaphore_destroy :: proc(s ^Semaphore) {
|
||||
win32.CloseHandle(s.handle);
|
||||
}
|
||||
|
||||
proc semaphore_post(s ^Semaphore, count int) {
|
||||
semaphore_post :: proc(s ^Semaphore, count int) {
|
||||
win32.ReleaseSemaphore(s.handle, count as i32, nil);
|
||||
}
|
||||
|
||||
proc semaphore_release(s ^Semaphore) #inline { semaphore_post(s, 1); }
|
||||
semaphore_release :: proc(s ^Semaphore) #inline { semaphore_post(s, 1); }
|
||||
|
||||
proc semaphore_wait(s ^Semaphore) {
|
||||
semaphore_wait :: proc(s ^Semaphore) {
|
||||
win32.WaitForSingleObject(s.handle, win32.INFINITE);
|
||||
}
|
||||
|
||||
|
||||
proc mutex_init(m ^Mutex) {
|
||||
mutex_init :: proc(m ^Mutex) {
|
||||
atomic.store32(^m.counter, 0);
|
||||
atomic.store32(^m.owner, current_thread_id());
|
||||
semaphore_init(^m.semaphore);
|
||||
m.recursion = 0;
|
||||
}
|
||||
proc mutex_destroy(m ^Mutex) {
|
||||
mutex_destroy :: proc(m ^Mutex) {
|
||||
semaphore_destroy(^m.semaphore);
|
||||
}
|
||||
proc mutex_lock(m ^Mutex) {
|
||||
mutex_lock :: proc(m ^Mutex) {
|
||||
thread_id := current_thread_id();
|
||||
if atomic.fetch_add32(^m.counter, 1) > 0 {
|
||||
if thread_id != atomic.load32(^m.owner) {
|
||||
@@ -58,7 +56,7 @@ proc mutex_lock(m ^Mutex) {
|
||||
atomic.store32(^m.owner, thread_id);
|
||||
m.recursion++;
|
||||
}
|
||||
proc mutex_try_lock(m ^Mutex) -> bool {
|
||||
mutex_try_lock :: proc(m ^Mutex) -> bool {
|
||||
thread_id := current_thread_id();
|
||||
if atomic.load32(^m.owner) == thread_id {
|
||||
atomic.fetch_add32(^m.counter, 1);
|
||||
@@ -75,7 +73,7 @@ proc mutex_try_lock(m ^Mutex) -> bool {
|
||||
m.recursion++;
|
||||
return true;
|
||||
}
|
||||
proc mutex_unlock(m ^Mutex) {
|
||||
mutex_unlock :: proc(m ^Mutex) {
|
||||
recursion: i32;
|
||||
thread_id := current_thread_id();
|
||||
assert(thread_id == atomic.load32(^m.owner));
|
||||
|
||||
+210
-217
@@ -1,24 +1,22 @@
|
||||
#foreign_system_library "user32" when ODIN_OS == "windows";
|
||||
#foreign_system_library "gdi32" when ODIN_OS == "windows";
|
||||
|
||||
type {
|
||||
HANDLE rawptr;
|
||||
HWND HANDLE;
|
||||
HDC HANDLE;
|
||||
HINSTANCE HANDLE;
|
||||
HICON HANDLE;
|
||||
HCURSOR HANDLE;
|
||||
HMENU HANDLE;
|
||||
HBRUSH HANDLE;
|
||||
HGDIOBJ HANDLE;
|
||||
HMODULE HANDLE;
|
||||
WPARAM uint;
|
||||
LPARAM int;
|
||||
LRESULT int;
|
||||
ATOM i16;
|
||||
BOOL i32;
|
||||
WNDPROC proc(hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT;
|
||||
}
|
||||
HANDLE :: rawptr;
|
||||
HWND :: HANDLE;
|
||||
HDC :: HANDLE;
|
||||
HINSTANCE :: HANDLE;
|
||||
HICON :: HANDLE;
|
||||
HCURSOR :: HANDLE;
|
||||
HMENU :: HANDLE;
|
||||
HBRUSH :: HANDLE;
|
||||
HGDIOBJ :: HANDLE;
|
||||
HMODULE :: HANDLE;
|
||||
WPARAM :: uint;
|
||||
LPARAM :: int;
|
||||
LRESULT :: int;
|
||||
ATOM :: i16;
|
||||
BOOL :: i32;
|
||||
WNDPROC :: type proc(hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT;
|
||||
|
||||
|
||||
INVALID_HANDLE_VALUE :: (-1 as int) as HANDLE;
|
||||
@@ -57,137 +55,136 @@ SM_CYSCREEN :: 1;
|
||||
SW_SHOW :: 5;
|
||||
|
||||
|
||||
type {
|
||||
POINT struct #ordered {
|
||||
x, y i32;
|
||||
}
|
||||
|
||||
WNDCLASSEXA struct #ordered {
|
||||
size, style u32;
|
||||
wnd_proc WNDPROC;
|
||||
cls_extra, wnd_extra i32;
|
||||
instance HINSTANCE;
|
||||
icon HICON;
|
||||
cursor HCURSOR;
|
||||
background HBRUSH;
|
||||
menu_name, class_name ^u8;
|
||||
sm HICON;
|
||||
}
|
||||
|
||||
MSG struct #ordered {
|
||||
hwnd HWND;
|
||||
message u32;
|
||||
wparam WPARAM;
|
||||
lparam LPARAM;
|
||||
time u32;
|
||||
pt POINT;
|
||||
}
|
||||
|
||||
RECT struct #ordered {
|
||||
left i32;
|
||||
top i32;
|
||||
right i32;
|
||||
bottom i32;
|
||||
}
|
||||
|
||||
FILETIME struct #ordered {
|
||||
lo, hi u32;
|
||||
}
|
||||
|
||||
BY_HANDLE_FILE_INFORMATION struct #ordered {
|
||||
file_attributes u32;
|
||||
creation_time,
|
||||
last_access_time,
|
||||
last_write_time FILETIME;
|
||||
volume_serial_number,
|
||||
file_size_high,
|
||||
file_size_low,
|
||||
number_of_links,
|
||||
file_index_high,
|
||||
file_index_low u32;
|
||||
}
|
||||
|
||||
FILE_ATTRIBUTE_DATA struct #ordered {
|
||||
file_attributes u32;
|
||||
creation_time,
|
||||
last_access_time,
|
||||
last_write_time FILETIME;
|
||||
file_size_high,
|
||||
file_size_low u32;
|
||||
}
|
||||
|
||||
GET_FILEEX_INFO_LEVELS i32;
|
||||
POINT :: struct #ordered {
|
||||
x, y i32;
|
||||
}
|
||||
|
||||
WNDCLASSEXA :: struct #ordered {
|
||||
size, style u32;
|
||||
wnd_proc WNDPROC;
|
||||
cls_extra, wnd_extra i32;
|
||||
instance HINSTANCE;
|
||||
icon HICON;
|
||||
cursor HCURSOR;
|
||||
background HBRUSH;
|
||||
menu_name, class_name ^u8;
|
||||
sm HICON;
|
||||
}
|
||||
|
||||
MSG :: struct #ordered {
|
||||
hwnd HWND;
|
||||
message u32;
|
||||
wparam WPARAM;
|
||||
lparam LPARAM;
|
||||
time u32;
|
||||
pt POINT;
|
||||
}
|
||||
|
||||
RECT :: struct #ordered {
|
||||
left i32;
|
||||
top i32;
|
||||
right i32;
|
||||
bottom i32;
|
||||
}
|
||||
|
||||
FILETIME :: struct #ordered {
|
||||
lo, hi u32;
|
||||
}
|
||||
|
||||
BY_HANDLE_FILE_INFORMATION :: struct #ordered {
|
||||
file_attributes u32;
|
||||
creation_time,
|
||||
last_access_time,
|
||||
last_write_time FILETIME;
|
||||
volume_serial_number,
|
||||
file_size_high,
|
||||
file_size_low,
|
||||
number_of_links,
|
||||
file_index_high,
|
||||
file_index_low u32;
|
||||
}
|
||||
|
||||
FILE_ATTRIBUTE_DATA :: struct #ordered {
|
||||
file_attributes u32;
|
||||
creation_time,
|
||||
last_access_time,
|
||||
last_write_time FILETIME;
|
||||
file_size_high,
|
||||
file_size_low u32;
|
||||
}
|
||||
|
||||
GET_FILEEX_INFO_LEVELS :: i32;
|
||||
|
||||
GetFileExInfoStandard: GET_FILEEX_INFO_LEVELS : 0;
|
||||
GetFileExMaxInfoLevel: GET_FILEEX_INFO_LEVELS : 1;
|
||||
|
||||
proc GetLastError () -> i32 #foreign #dll_import
|
||||
proc ExitProcess (exit_code u32) #foreign #dll_import
|
||||
proc GetDesktopWindow() -> HWND #foreign #dll_import
|
||||
proc GetCursorPos (p ^POINT) -> i32 #foreign #dll_import
|
||||
proc ScreenToClient (h HWND, p ^POINT) -> i32 #foreign #dll_import
|
||||
proc GetModuleHandleA(module_name ^u8) -> HINSTANCE #foreign #dll_import
|
||||
proc GetStockObject (fn_object i32) -> HGDIOBJ #foreign #dll_import
|
||||
proc PostQuitMessage (exit_code i32) #foreign #dll_import
|
||||
proc SetWindowTextA (hwnd HWND, c_string ^u8) -> BOOL #foreign #dll_import
|
||||
GetLastError :: proc() -> i32 #foreign #dll_import
|
||||
ExitProcess :: proc(exit_code u32) #foreign #dll_import
|
||||
GetDesktopWindow :: proc() -> HWND #foreign #dll_import
|
||||
GetCursorPos :: proc(p ^POINT) -> i32 #foreign #dll_import
|
||||
ScreenToClient :: proc(h HWND, p ^POINT) -> i32 #foreign #dll_import
|
||||
GetModuleHandleA :: proc(module_name ^u8) -> HINSTANCE #foreign #dll_import
|
||||
GetStockObject :: proc(fn_object i32) -> HGDIOBJ #foreign #dll_import
|
||||
PostQuitMessage :: proc(exit_code i32) #foreign #dll_import
|
||||
SetWindowTextA :: proc(hwnd HWND, c_string ^u8) -> BOOL #foreign #dll_import
|
||||
|
||||
proc QueryPerformanceFrequency(result ^i64) -> i32 #foreign #dll_import
|
||||
proc QueryPerformanceCounter (result ^i64) -> i32 #foreign #dll_import
|
||||
QueryPerformanceFrequency :: proc(result ^i64) -> i32 #foreign #dll_import
|
||||
QueryPerformanceCounter :: proc(result ^i64) -> i32 #foreign #dll_import
|
||||
|
||||
proc Sleep(ms i32) -> i32 #foreign #dll_import
|
||||
Sleep :: proc(ms i32) -> i32 #foreign #dll_import
|
||||
|
||||
proc OutputDebugStringA(c_str ^u8) #foreign #dll_import
|
||||
OutputDebugStringA :: proc(c_str ^u8) #foreign #dll_import
|
||||
|
||||
|
||||
proc RegisterClassExA(wc ^WNDCLASSEXA) -> ATOM #foreign #dll_import
|
||||
proc CreateWindowExA (ex_style u32,
|
||||
class_name, title ^u8,
|
||||
style u32,
|
||||
x, y, w, h i32,
|
||||
parent HWND, menu HMENU, instance HINSTANCE,
|
||||
param rawptr) -> HWND #foreign #dll_import
|
||||
RegisterClassExA :: proc(wc ^WNDCLASSEXA) -> ATOM #foreign #dll_import
|
||||
CreateWindowExA :: proc(ex_style u32,
|
||||
class_name, title ^u8,
|
||||
style u32,
|
||||
x, y, w, h i32,
|
||||
parent HWND, menu HMENU, instance HINSTANCE,
|
||||
param rawptr) -> HWND #foreign #dll_import
|
||||
|
||||
proc ShowWindow (hwnd HWND, cmd_show i32) -> BOOL #foreign #dll_import
|
||||
proc TranslateMessage(msg ^MSG) -> BOOL #foreign #dll_import
|
||||
proc DispatchMessageA(msg ^MSG) -> LRESULT #foreign #dll_import
|
||||
proc UpdateWindow (hwnd HWND) -> BOOL #foreign #dll_import
|
||||
proc PeekMessageA (msg ^MSG, hwnd HWND,
|
||||
ShowWindow :: proc(hwnd HWND, cmd_show i32) -> BOOL #foreign #dll_import
|
||||
TranslateMessage :: proc(msg ^MSG) -> BOOL #foreign #dll_import
|
||||
DispatchMessageA :: proc(msg ^MSG) -> LRESULT #foreign #dll_import
|
||||
UpdateWindow :: proc(hwnd HWND) -> BOOL #foreign #dll_import
|
||||
PeekMessageA :: proc(msg ^MSG, hwnd HWND,
|
||||
msg_filter_min, msg_filter_max, remove_msg u32) -> BOOL #foreign #dll_import
|
||||
|
||||
proc DefWindowProcA (hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT #foreign #dll_import
|
||||
DefWindowProcA :: proc(hwnd HWND, msg u32, wparam WPARAM, lparam LPARAM) -> LRESULT #foreign #dll_import
|
||||
|
||||
proc AdjustWindowRect(rect ^RECT, style u32, menu BOOL) -> BOOL #foreign #dll_import
|
||||
proc GetActiveWindow () -> HWND #foreign #dll_import
|
||||
AdjustWindowRect :: proc(rect ^RECT, style u32, menu BOOL) -> BOOL #foreign #dll_import
|
||||
GetActiveWindow :: proc() -> HWND #foreign #dll_import
|
||||
|
||||
|
||||
proc GetQueryPerformanceFrequency() -> i64 {
|
||||
GetQueryPerformanceFrequency :: proc() -> i64 {
|
||||
r: i64;
|
||||
QueryPerformanceFrequency(^r);
|
||||
return r;
|
||||
}
|
||||
|
||||
proc GetCommandLineA() -> ^u8 #foreign #dll_import
|
||||
proc GetSystemMetrics(index i32) -> i32 #foreign #dll_import
|
||||
proc GetCurrentThreadId() -> u32 #foreign #dll_import
|
||||
GetCommandLineA :: proc() -> ^u8 #foreign #dll_import
|
||||
GetSystemMetrics :: proc(index i32) -> i32 #foreign #dll_import
|
||||
GetCurrentThreadId :: proc() -> u32 #foreign #dll_import
|
||||
|
||||
// File Stuff
|
||||
|
||||
proc CloseHandle (h HANDLE) -> i32 #foreign #dll_import
|
||||
proc GetStdHandle(h i32) -> HANDLE #foreign #dll_import
|
||||
proc CreateFileA (filename ^u8, desired_access, share_mode u32,
|
||||
CloseHandle :: proc(h HANDLE) -> i32 #foreign #dll_import
|
||||
GetStdHandle :: proc(h i32) -> HANDLE #foreign #dll_import
|
||||
CreateFileA :: proc(filename ^u8, desired_access, share_mode u32,
|
||||
security rawptr,
|
||||
creation, flags_and_attribs u32, template_file HANDLE) -> HANDLE #foreign #dll_import
|
||||
proc ReadFile (h HANDLE, buf rawptr, to_read u32, bytes_read ^i32, overlapped rawptr) -> BOOL #foreign #dll_import
|
||||
proc WriteFile (h HANDLE, buf rawptr, len i32, written_result ^i32, overlapped rawptr) -> i32 #foreign #dll_import
|
||||
ReadFile :: proc(h HANDLE, buf rawptr, to_read u32, bytes_read ^i32, overlapped rawptr) -> BOOL #foreign #dll_import
|
||||
WriteFile :: proc(h HANDLE, buf rawptr, len i32, written_result ^i32, overlapped rawptr) -> i32 #foreign #dll_import
|
||||
|
||||
proc GetFileSizeEx (file_handle HANDLE, file_size ^i64) -> BOOL #foreign #dll_import
|
||||
proc GetFileAttributesExA (filename ^u8, info_level_id GET_FILEEX_INFO_LEVELS, file_info rawptr) -> BOOL #foreign #dll_import
|
||||
proc GetFileInformationByHandle(file_handle HANDLE, file_info ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign #dll_import
|
||||
GetFileSizeEx :: proc(file_handle HANDLE, file_size ^i64) -> BOOL #foreign #dll_import
|
||||
GetFileAttributesExA :: proc(filename ^u8, info_level_id GET_FILEEX_INFO_LEVELS, file_info rawptr) -> BOOL #foreign #dll_import
|
||||
GetFileInformationByHandle :: proc(file_handle HANDLE, file_info ^BY_HANDLE_FILE_INFORMATION) -> BOOL #foreign #dll_import
|
||||
|
||||
proc GetFileType(file_handle HANDLE) -> u32 #foreign #dll_import
|
||||
proc SetFilePointer(file_handle HANDLE, distance_to_move i32, distance_to_move_high ^i32, move_method u32) -> u32 #foreign #dll_import
|
||||
GetFileType :: proc(file_handle HANDLE) -> u32 #foreign #dll_import
|
||||
SetFilePointer :: proc(file_handle HANDLE, distance_to_move i32, distance_to_move_high ^i32, move_method u32) -> u32 #foreign #dll_import
|
||||
|
||||
proc SetHandleInformation(obj HANDLE, mask, flags u32) -> BOOL #foreign #dll_import
|
||||
SetHandleInformation :: proc(obj HANDLE, mask, flags u32) -> BOOL #foreign #dll_import
|
||||
|
||||
HANDLE_FLAG_INHERIT :: 1;
|
||||
HANDLE_FLAG_PROTECT_FROM_CLOSE :: 2;
|
||||
@@ -241,17 +238,17 @@ INVALID_SET_FILE_POINTER :: ~(0 as u32);
|
||||
|
||||
|
||||
|
||||
proc HeapAlloc (h HANDLE, flags u32, bytes int) -> rawptr #foreign #dll_import
|
||||
proc HeapReAlloc (h HANDLE, flags u32, memory rawptr, bytes int) -> rawptr #foreign #dll_import
|
||||
proc HeapFree (h HANDLE, flags u32, memory rawptr) -> BOOL #foreign #dll_import
|
||||
proc GetProcessHeap() -> HANDLE #foreign #dll_import
|
||||
HeapAlloc :: proc (h HANDLE, flags u32, bytes int) -> rawptr #foreign #dll_import
|
||||
HeapReAlloc :: proc (h HANDLE, flags u32, memory rawptr, bytes int) -> rawptr #foreign #dll_import
|
||||
HeapFree :: proc (h HANDLE, flags u32, memory rawptr) -> BOOL #foreign #dll_import
|
||||
GetProcessHeap :: proc () -> HANDLE #foreign #dll_import
|
||||
|
||||
|
||||
HEAP_ZERO_MEMORY :: 0x00000008;
|
||||
|
||||
// Synchronization
|
||||
|
||||
type SECURITY_ATTRIBUTES struct #ordered {
|
||||
SECURITY_ATTRIBUTES :: struct #ordered {
|
||||
length u32;
|
||||
security_descriptor rawptr;
|
||||
inherit_handle BOOL;
|
||||
@@ -259,51 +256,49 @@ type SECURITY_ATTRIBUTES struct #ordered {
|
||||
|
||||
INFINITE :: 0xffffffff;
|
||||
|
||||
proc CreateSemaphoreA (attributes ^SECURITY_ATTRIBUTES, initial_count, maximum_count i32, name ^byte) -> HANDLE #foreign #dll_import
|
||||
proc ReleaseSemaphore (semaphore HANDLE, release_count i32, previous_count ^i32) -> BOOL #foreign #dll_import
|
||||
proc WaitForSingleObject(handle HANDLE, milliseconds u32) -> u32 #foreign #dll_import
|
||||
CreateSemaphoreA :: proc(attributes ^SECURITY_ATTRIBUTES, initial_count, maximum_count i32, name ^byte) -> HANDLE #foreign #dll_import
|
||||
ReleaseSemaphore :: proc(semaphore HANDLE, release_count i32, previous_count ^i32) -> BOOL #foreign #dll_import
|
||||
WaitForSingleObject :: proc(handle HANDLE, milliseconds u32) -> u32 #foreign #dll_import
|
||||
|
||||
|
||||
proc InterlockedCompareExchange(dst ^i32, exchange, comparand i32) -> i32 #foreign
|
||||
proc InterlockedExchange (dst ^i32, desired i32) -> i32 #foreign
|
||||
proc InterlockedExchangeAdd (dst ^i32, desired i32) -> i32 #foreign
|
||||
proc InterlockedAnd (dst ^i32, desired i32) -> i32 #foreign
|
||||
proc InterlockedOr (dst ^i32, desired i32) -> i32 #foreign
|
||||
InterlockedCompareExchange :: proc(dst ^i32, exchange, comparand i32) -> i32 #foreign
|
||||
InterlockedExchange :: proc(dst ^i32, desired i32) -> i32 #foreign
|
||||
InterlockedExchangeAdd :: proc(dst ^i32, desired i32) -> i32 #foreign
|
||||
InterlockedAnd :: proc(dst ^i32, desired i32) -> i32 #foreign
|
||||
InterlockedOr :: proc(dst ^i32, desired i32) -> i32 #foreign
|
||||
|
||||
proc InterlockedCompareExchange64(dst ^i64, exchange, comparand i64) -> i64 #foreign
|
||||
proc InterlockedExchange64 (dst ^i64, desired i64) -> i64 #foreign
|
||||
proc InterlockedExchangeAdd64 (dst ^i64, desired i64) -> i64 #foreign
|
||||
proc InterlockedAnd64 (dst ^i64, desired i64) -> i64 #foreign
|
||||
proc InterlockedOr64 (dst ^i64, desired i64) -> i64 #foreign
|
||||
InterlockedCompareExchange64 :: proc(dst ^i64, exchange, comparand i64) -> i64 #foreign
|
||||
InterlockedExchange64 :: proc(dst ^i64, desired i64) -> i64 #foreign
|
||||
InterlockedExchangeAdd64 :: proc(dst ^i64, desired i64) -> i64 #foreign
|
||||
InterlockedAnd64 :: proc(dst ^i64, desired i64) -> i64 #foreign
|
||||
InterlockedOr64 :: proc(dst ^i64, desired i64) -> i64 #foreign
|
||||
|
||||
proc _mm_pause () #foreign
|
||||
proc ReadWriteBarrier() #foreign
|
||||
proc WriteBarrier () #foreign
|
||||
proc ReadBarrier () #foreign
|
||||
_mm_pause :: proc() #foreign
|
||||
ReadWriteBarrier :: proc() #foreign
|
||||
WriteBarrier :: proc() #foreign
|
||||
ReadBarrier :: proc() #foreign
|
||||
|
||||
|
||||
// GDI
|
||||
type {
|
||||
BITMAPINFOHEADER struct #ordered {
|
||||
size u32;
|
||||
width, height i32;
|
||||
planes, bit_count i16;
|
||||
compression u32;
|
||||
size_image u32;
|
||||
x_pels_per_meter i32;
|
||||
y_pels_per_meter i32;
|
||||
clr_used u32;
|
||||
clr_important u32;
|
||||
}
|
||||
BITMAPINFO struct #ordered {
|
||||
using header BITMAPINFOHEADER;
|
||||
colors [1]RGBQUAD;
|
||||
}
|
||||
BITMAPINFOHEADER :: struct #ordered {
|
||||
size u32;
|
||||
width, height i32;
|
||||
planes, bit_count i16;
|
||||
compression u32;
|
||||
size_image u32;
|
||||
x_pels_per_meter i32;
|
||||
y_pels_per_meter i32;
|
||||
clr_used u32;
|
||||
clr_important u32;
|
||||
}
|
||||
BITMAPINFO :: struct #ordered {
|
||||
using header BITMAPINFOHEADER;
|
||||
colors [1]RGBQUAD;
|
||||
}
|
||||
|
||||
|
||||
RGBQUAD struct #ordered {
|
||||
blue, green, red, reserved byte;
|
||||
}
|
||||
RGBQUAD :: struct #ordered {
|
||||
blue, green, red, reserved byte;
|
||||
}
|
||||
|
||||
BI_RGB :: 0;
|
||||
@@ -311,20 +306,20 @@ DIB_RGB_COLORS :: 0x00;
|
||||
SRCCOPY: u32 : 0x00cc0020;
|
||||
|
||||
|
||||
proc StretchDIBits(hdc HDC,
|
||||
x_dst, y_dst, width_dst, height_dst i32,
|
||||
x_src, y_src, width_src, header_src i32,
|
||||
bits rawptr, bits_info ^BITMAPINFO,
|
||||
usage u32,
|
||||
rop u32) -> i32 #foreign #dll_import
|
||||
StretchDIBits :: proc (hdc HDC,
|
||||
x_dst, y_dst, width_dst, height_dst i32,
|
||||
x_src, y_src, width_src, header_src i32,
|
||||
bits rawptr, bits_info ^BITMAPINFO,
|
||||
usage u32,
|
||||
rop u32) -> i32 #foreign #dll_import
|
||||
|
||||
|
||||
|
||||
proc LoadLibraryA (c_str ^u8) -> HMODULE #foreign
|
||||
proc FreeLibrary (h HMODULE) #foreign
|
||||
proc GetProcAddress(h HMODULE, c_str ^u8) -> PROC #foreign
|
||||
LoadLibraryA :: proc (c_str ^u8) -> HMODULE #foreign
|
||||
FreeLibrary :: proc (h HMODULE) #foreign
|
||||
GetProcAddress :: proc (h HMODULE, c_str ^u8) -> PROC #foreign
|
||||
|
||||
proc GetClientRect(hwnd HWND, rect ^RECT) -> BOOL #foreign
|
||||
GetClientRect :: proc(hwnd HWND, rect ^RECT) -> BOOL #foreign
|
||||
|
||||
|
||||
|
||||
@@ -351,49 +346,47 @@ PFD_DEPTH_DONTCARE :: 0x20000000;
|
||||
PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000;
|
||||
PFD_STEREO_DONTCARE :: 0x80000000;
|
||||
|
||||
type {
|
||||
HGLRC HANDLE;
|
||||
PROC proc() #cc_c;
|
||||
wglCreateContextAttribsARBType proc(hdc HDC, hshareContext rawptr, attribList ^i32) -> HGLRC;
|
||||
HGLRC :: HANDLE;
|
||||
PROC :: type proc() #cc_c;
|
||||
wglCreateContextAttribsARBType :: proc(hdc HDC, hshareContext rawptr, attribList ^i32) -> HGLRC;
|
||||
|
||||
|
||||
PIXELFORMATDESCRIPTOR struct #ordered {
|
||||
size,
|
||||
version,
|
||||
flags u32;
|
||||
PIXELFORMATDESCRIPTOR :: struct #ordered {
|
||||
size,
|
||||
version,
|
||||
flags u32;
|
||||
|
||||
pixel_type,
|
||||
color_bits,
|
||||
red_bits,
|
||||
red_shift,
|
||||
green_bits,
|
||||
green_shift,
|
||||
blue_bits,
|
||||
blue_shift,
|
||||
alpha_bits,
|
||||
alpha_shift,
|
||||
accum_bits,
|
||||
accum_red_bits,
|
||||
accum_green_bits,
|
||||
accum_blue_bits,
|
||||
accum_alpha_bits,
|
||||
depth_bits,
|
||||
stencil_bits,
|
||||
aux_buffers,
|
||||
layer_type,
|
||||
reserved byte;
|
||||
pixel_type,
|
||||
color_bits,
|
||||
red_bits,
|
||||
red_shift,
|
||||
green_bits,
|
||||
green_shift,
|
||||
blue_bits,
|
||||
blue_shift,
|
||||
alpha_bits,
|
||||
alpha_shift,
|
||||
accum_bits,
|
||||
accum_red_bits,
|
||||
accum_green_bits,
|
||||
accum_blue_bits,
|
||||
accum_alpha_bits,
|
||||
depth_bits,
|
||||
stencil_bits,
|
||||
aux_buffers,
|
||||
layer_type,
|
||||
reserved byte;
|
||||
|
||||
layer_mask,
|
||||
visible_mask,
|
||||
damage_mask u32;
|
||||
}
|
||||
layer_mask,
|
||||
visible_mask,
|
||||
damage_mask u32;
|
||||
}
|
||||
|
||||
proc GetDC (h HANDLE) -> HDC #foreign
|
||||
proc SetPixelFormat (hdc HDC, pixel_format i32, pfd ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import
|
||||
proc ChoosePixelFormat(hdc HDC, pfd ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll_import
|
||||
proc SwapBuffers (hdc HDC) -> BOOL #foreign #dll_import
|
||||
proc ReleaseDC (wnd HWND, hdc HDC) -> i32 #foreign #dll_import
|
||||
GetDC :: proc(h HANDLE) -> HDC #foreign
|
||||
SetPixelFormat :: proc(hdc HDC, pixel_format i32, pfd ^PIXELFORMATDESCRIPTOR ) -> BOOL #foreign #dll_import
|
||||
ChoosePixelFormat :: proc(hdc HDC, pfd ^PIXELFORMATDESCRIPTOR) -> i32 #foreign #dll_import
|
||||
SwapBuffers :: proc(hdc HDC) -> BOOL #foreign #dll_import
|
||||
ReleaseDC :: proc(wnd HWND, hdc HDC) -> i32 #foreign #dll_import
|
||||
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB :: 0x2091;
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB :: 0x2092;
|
||||
@@ -401,19 +394,19 @@ WGL_CONTEXT_PROFILE_MASK_ARB :: 0x9126;
|
||||
WGL_CONTEXT_CORE_PROFILE_BIT_ARB :: 0x0001;
|
||||
WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB :: 0x0002;
|
||||
|
||||
proc wglCreateContext (hdc HDC) -> HGLRC #foreign #dll_import
|
||||
proc wglMakeCurrent (hdc HDC, hglrc HGLRC) -> BOOL #foreign #dll_import
|
||||
proc wglGetProcAddress(c_str ^u8) -> PROC #foreign #dll_import
|
||||
proc wglDeleteContext (hglrc HGLRC) -> BOOL #foreign #dll_import
|
||||
wglCreateContext :: proc(hdc HDC) -> HGLRC #foreign #dll_import
|
||||
wglMakeCurrent :: proc(hdc HDC, hglrc HGLRC) -> BOOL #foreign #dll_import
|
||||
wglGetProcAddress :: proc(c_str ^u8) -> PROC #foreign #dll_import
|
||||
wglDeleteContext :: proc(hglrc HGLRC) -> BOOL #foreign #dll_import
|
||||
|
||||
|
||||
|
||||
proc GetKeyState (v_key i32) -> i16 #foreign #dll_import
|
||||
proc GetAsyncKeyState(v_key i32) -> i16 #foreign #dll_import
|
||||
GetKeyState :: proc(v_key i32) -> i16 #foreign #dll_import
|
||||
GetAsyncKeyState :: proc(v_key i32) -> i16 #foreign #dll_import
|
||||
|
||||
proc is_key_down(key Key_Code) -> bool #inline { return GetAsyncKeyState(key as i32) < 0; }
|
||||
is_key_down :: proc(key Key_Code) -> bool #inline { return GetAsyncKeyState(key as i32) < 0; }
|
||||
|
||||
type Key_Code enum i32 {
|
||||
Key_Code :: enum i32 {
|
||||
LBUTTON = 0x01,
|
||||
RBUTTON = 0x02,
|
||||
CANCEL = 0x03,
|
||||
|
||||
+7
-7
@@ -8,7 +8,7 @@ UTF_MAX :: 4;
|
||||
SURROGATE_MIN :: 0xd800;
|
||||
SURROGATE_MAX :: 0xdfff;
|
||||
|
||||
type Accept_Range struct {
|
||||
Accept_Range :: struct {
|
||||
lo, hi u8;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ accept_sizes := [256]byte{
|
||||
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
|
||||
};
|
||||
|
||||
proc encode_rune(r rune) -> ([4]byte, int) {
|
||||
encode_rune :: proc(r rune) -> ([4]byte, int) {
|
||||
buf: [4]byte;
|
||||
i := r as u32;
|
||||
mask: byte : 0x3f;
|
||||
@@ -74,7 +74,7 @@ proc encode_rune(r rune) -> ([4]byte, int) {
|
||||
return buf, 4;
|
||||
}
|
||||
|
||||
proc decode_rune(s string) -> (rune, int) {
|
||||
decode_rune :: proc(s string) -> (rune, int) {
|
||||
n := s.count;
|
||||
if n < 1 {
|
||||
return RUNE_ERROR, 0;
|
||||
@@ -119,7 +119,7 @@ proc decode_rune(s string) -> (rune, int) {
|
||||
}
|
||||
|
||||
|
||||
proc valid_rune(r rune) -> bool {
|
||||
valid_rune :: proc(r rune) -> bool {
|
||||
if r < 0 {
|
||||
return false;
|
||||
} else if SURROGATE_MIN <= r && r <= SURROGATE_MAX {
|
||||
@@ -130,7 +130,7 @@ proc valid_rune(r rune) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
proc valid_string(s string) -> bool {
|
||||
valid_string :: proc(s string) -> bool {
|
||||
n := s.count;
|
||||
for i := 0; i < n; {
|
||||
si := s[i];
|
||||
@@ -163,7 +163,7 @@ proc valid_string(s string) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
proc rune_count(s string) -> int {
|
||||
rune_count :: proc(s string) -> int {
|
||||
count := 0;
|
||||
n := s.count;
|
||||
for i := 0; i < n; count++ {
|
||||
@@ -200,7 +200,7 @@ proc rune_count(s string) -> int {
|
||||
}
|
||||
|
||||
|
||||
proc rune_size(r rune) -> int {
|
||||
rune_size :: proc(r rune) -> int {
|
||||
match {
|
||||
case r < 0: return -1;
|
||||
case r <= 1<<7 - 1: return 1;
|
||||
|
||||
Reference in New Issue
Block a user