Implicit Context and #thread_local

This commit is contained in:
gingerBill
2016-08-19 23:35:09 +01:00
parent 745237459a
commit 680274b6f1
16 changed files with 1161 additions and 618 deletions
+135 -57
View File
@@ -1,6 +1,7 @@
// Demo 001
#load "basic.odin"
#load "math.odin"
// #load "game.odin"
#load "game.odin"
main :: proc() {
_ = hellope();
@@ -9,7 +10,8 @@ main :: proc() {
constants();
types();
data_control();
// run_game();
run_game();
}
hellope :: proc() -> int {
@@ -17,9 +19,22 @@ hellope :: proc() -> int {
return 1;
}
// Line comment
/*
Block Comment
*/
/*
Nested /*
Block /*
Comment
*/
*/
*/
apple, banana, carrot: bool;
box, carboard: bool = true, false;
hellope_value := hellope();
hellope_value: int = hellope();
variables :: proc() {
i: int; // initialized with zero value
@@ -39,21 +54,23 @@ variables :: proc() {
//
// f32 f64
//
// int uint (size_of(int) = size_of(rawptr))
// int uint (size_of(int) == size_of(uint) == size_of(rawptr))
//
// rawptr
// rawptr (equivalent to void * in C/C++)
//
// string
//
// byte - alias for u8
// rune - alias for i32 // Unicode Codepoint
//
// untyped bool - "untyped" types can implicitly convert to any of the "typed" types
// untyped integer
// untyped float
// untyped pointer
// untyped string
// untyped rune
// "untyped" types can implicitly convert to any of the "typed" types
// Default Type
// untyped bool - bool
// untyped integer - int
// untyped float - f64
// untyped pointer - rawptr
// untyped string - string
// untyped rune - rune/i32
// // Zero values
@@ -62,6 +79,7 @@ variables :: proc() {
zero_pointer := null;
zero_string1 := ""; // Escaped string
zero_string2 := ``; // Raw string
// Compound types have a different kind of zero value
// Unary operators
// +a
@@ -70,28 +88,28 @@ variables :: proc() {
// !a
// Binary operators
// a + b
// a - b
// a ~ b
// a | b
// a + b add
// a - b sub
// a ~ b xor
// a | b or
// a * b
// a / b
// a % b
// a & b
// a &~ b == a & (~b)
// a << b
// a >> b
// a * b mul
// a / b quo
// a % b mod
// a & b and
// a &~ b bitclear == a & (~b)
// a << b shl
// a >> b shr
// a as Type
// a transmute Type
// a as Type // Type cast
// a transmute Type // Bit cast
// a == b
// a != b
// a < b
// a > b
// a <= b
// a >= b
// a == b eq
// a != b ne
// a < b lt
// a > b gt
// a <= b le
// a >= b ge
}
@@ -115,10 +133,11 @@ procedures :: proc() {
print_string(b);
a, b = b, a; // Quirk of grammar the of multiple assignments
// Swap variables
print_string(a);
print_string(b);
// Not hints, it's mandatory
// Not a hint like C/C++, it's mandatory (unless it cannot do it but it will warn)
proc1 :: proc(a, b: int) #inline {
print_int(a + b);
}
@@ -136,6 +155,16 @@ constants :: proc() {
TAU_32 : f32 : 6.28318530718;
TAU_AS_32 :: 6.28318530718 as f32;
PI :: TAU / 2;
CLOSE_TO_PI :: 3;
DIFF :: (PI - CLOSE_TO_PI) / PI; // Evaluated at compile time
a := TAU; // the constant's value becomes typed as f32
b := CLOSE_TO_PI; // the constant's value becomes typed as int
c := DIFF;
}
nl :: proc() { print_rune('\n'); }
@@ -147,13 +176,22 @@ types :: proc() {
// z: f32 = x; // invalid
z: f32 = x as f32;
ptr_z := ^z; // Pascal notation
ptr_z := ^z; // Pascal notation
ptr_z^ = 123; // Derefence Notation
w: f32 = ptr_z^; // 123
print_f32(z); nl();
// ^z - pointer to z
// z^ - z from pointer
// Implicit conversion to and from rawptr
r_ptr: rawptr = ptr_z;
ptr_z = r_ptr;
f32_array: [12]f32; // Array of 12 f32
f32_array[0] = 2;
f32_array[1] = 3;
@@ -162,15 +200,28 @@ types :: proc() {
f32_array_len := len(f32_array); // builtin procedure
f32_array_cap := cap(f32_array); // == len(f32_array)
mda: [2][3][4]int; // Column-major
// mda[x][y][z]
api: [2]^f32;
papi: ^[2]^f32;
f32_slice: []f32; // Array reference
f32_slice: []f32; // Slice / Array reference
f32_slice = f32_array[0:5];
f32_slice = f32_array[:5];
f32_slice = f32_array[:]; // f32_array[0:len(f32_array)-1];
f32_slice = f32_array[1:5:7]; // low:1, high:5, capacity:7
f32_slice = f32_array[1:5:7]; // low:1, high:5, max:7
// len: 5-1 == 4
// cap: 7-1 == 6
append_success := append(^f32_slice, 1);
_ = append(^f32_slice, 2);
@@ -178,8 +229,16 @@ types :: proc() {
_ = copy(f32_array[0:2], f32_array[2:4]); // You can use memcpy/memmove if you want
s := "Hellope World";
sub_string := s[5:10];
sub_string: string = s[5:10];
v0: {4}f32; // Vector of 4 f32
v0[0] = 1;
@@ -199,6 +258,11 @@ types :: proc() {
// LLVM rant?
type Vec4: {4}f32;
type Array3Int: [3]int;
@@ -218,7 +282,7 @@ types :: proc() {
b: u16,
c: u32,
}
static_assert(size_of(Packed) == 7);
static_assert(size_of(Packed) == 7); // builtin procedure
{
@@ -261,15 +325,17 @@ types :: proc() {
}
// transmute only works if the size of the types are equal
/{
/*
// in C
union {
i32 i;
f32 y;
};
}/
*/
}
{ // Compound Literals
a := [3]int{1, 2, 3};
b := [3]int{};
@@ -293,7 +359,10 @@ types :: proc() {
print_f32(i[1]); print_rune('\n');
}
{
{ // First class procedures
do_thing :: proc(p: proc(a, b: int) -> int) {
print_int(p(3, 4)); nl();
}
@@ -309,11 +378,13 @@ types :: proc() {
do_thing(add);
do_thing(add_lambda);
do_thing(proc(a, b: int) -> int {
do_thing(proc(a, b: int) -> int { // Anonymous
return a * b;
});
}
{ // strings and runes
escaped := "Hellope World\n";
raw := `Hellope World\n`;
@@ -346,11 +417,12 @@ void main() {
}`;
knot1 := '';
knot2 := '\u2318'; // 16 bit
knot3 := '\U00002318'; // 32 bit
knot4 := "\xe2\x8c\x98"; // Note it's a string, should I allow untyped string -> untyped rune casts?
hearts1 := '💕';
hearts2 := '\U0001f495'; // 32 bit
hearts3 := "\xf0\x9f\x92\x95"; // Note it's a string, should I allow untyped string -> untyped rune casts?
:= '㐒';
㐒16 := '\u4db5'; // 16 bit
// String ideas "nicked" from Go, so far. I think I might change how some of it works later.
}
@@ -439,7 +511,7 @@ data_control :: proc() {
{
{ // Defer statement
defer print_string("日本語\n");
print_string("Japanese\n");
}
@@ -451,21 +523,26 @@ data_control :: proc() {
}
{
prev_allocator := context.allocator;
context.allocator = __default_allocator();
defer context.allocator = prev_allocator;
// C strings, yuk!
to_c_string :: proc(s: string) -> ^u8 {
c := heap_alloc(len(s)+1) as ^u8;
to_c_string := proc(s: string) -> ^u8 {
c := alloc(len(s)+1) as ^u8;
mem_copy(c, ^s[0], len(s));
c[len(s)] = 0;
return c;
}
};
fopen :: proc(filename, mode: ^u8) -> rawptr #foreign
fclose :: proc(f: rawptr) -> i32 #foreign
filename := to_c_string("../examples/base.odin");
mode := to_c_string("rb");
defer heap_free(filename);
defer heap_free(mode);
defer dealloc(filename);
defer dealloc(mode);
f := fopen(filename, mode);
if f == null {
@@ -478,10 +555,10 @@ data_control :: proc() {
// rest of code
// Better version
/{
/*
type File: struct { filename: string }
type FileError: int
open_file :: proc(filename: string) -> (File, FileError) { ... }
open_file :: proc(filename: string) -> (File, FileError) { ... }
close_file :: proc(f: ^File) { ... }
f, err := open_file("Test");
if err != 0 {
@@ -489,17 +566,17 @@ data_control :: proc() {
}
defer close_file(^f);
}/
*/
}
for i := 0; i < 100; i++ {
blah := heap_alloc(100 * size_of(int)) as ^int;
blah := alloc(100 * size_of(int)) as ^int;
defer {
defer print_string("!");
defer print_string("heap_free");
heap_free(blah);
defer print_string("dealloc");
dealloc(blah);
}
if i == 3 {
@@ -509,7 +586,7 @@ data_control :: proc() {
if i == 5 {
// defers called
return;
return; // End of procedure
}
if i == 8 {
@@ -523,3 +600,4 @@ data_control :: proc() {
print_string("It'll never happen, mate 3");
}
+49 -23
View File
@@ -35,13 +35,12 @@ to_c_string :: proc(s: string) -> ^u8 {
type Window: struct {
width, height: int,
wc: WNDCLASSEXA,
dc: HDC,
hwnd: HWND,
opengl_context: rawptr,
rc: HGLRC,
c_title: ^u8,
width, height: int,
wc: WNDCLASSEXA,
dc: HDC,
hwnd: HWND,
opengl_context, rc: HGLRC,
c_title: ^u8,
}
make_window :: proc(title: string, msg, height: int, window_proc: WNDPROC) -> (Window, bool) {
@@ -55,11 +54,11 @@ make_window :: proc(title: string, msg, height: int, window_proc: WNDPROC) -> (W
instance := GetModuleHandleA(null);
w.wc = WNDCLASSEXA{
cbSize = size_of(WNDCLASSEXA) as u32,
style = CS_VREDRAW | CS_HREDRAW,
hInstance = instance as HINSTANCE,
className = c_class_name,
wndProc = window_proc,
size = size_of(WNDCLASSEXA) as u32,
style = CS_VREDRAW | CS_HREDRAW,
instance = instance as HINSTANCE,
class_name = c_class_name,
wnd_proc = window_proc,
};
if RegisterClassExA(^w.wc) == 0 {
@@ -82,15 +81,15 @@ make_window :: proc(title: string, msg, height: int, window_proc: WNDPROC) -> (W
{
pfd := PIXELFORMATDESCRIPTOR{
nSize = size_of(PIXELFORMATDESCRIPTOR) as u32,
nVersion = 1,
dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
iPixelType = PFD_TYPE_RGBA,
cColorBits = 32,
cAlphaBits = 8,
cDepthBits = 24,
cStencilBits = 8,
iLayerType = PFD_MAIN_PLANE,
size = size_of(PIXELFORMATDESCRIPTOR) as u32,
version = 1,
flags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
pixel_type = PFD_TYPE_RGBA,
color_bits = 32,
alpha_bits = 8,
depth_bits = 24,
stencil_bits = 8,
layer_type = PFD_MAIN_PLANE,
};
SetPixelFormat(w.dc, ChoosePixelFormat(w.dc, ^pfd), null);
@@ -124,6 +123,11 @@ display_window :: proc(w: ^Window) {
}
type Entity: struct {
pos: Vec2,
dim: Vec2,
}
run_game :: proc() {
win32_proc :: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT #no_inline {
@@ -143,6 +147,9 @@ run_game :: proc() {
prev_time := time_now();
running := true;
pos := Vec2{100, 100};
for running {
curr_time := time_now();
dt := (curr_time - prev_time) as f32;
@@ -157,12 +164,32 @@ run_game :: proc() {
_ = DispatchMessageA(^msg);
}
if is_key_down(VK_ESCAPE) {
running = false;
}
{
SPEED :: 500;
v: Vec2;
if is_key_down(VK_RIGHT) { v[0] += 1; }
if is_key_down(VK_LEFT) { v[0] -= 1; }
if is_key_down(VK_UP) { v[1] += 1; }
if is_key_down(VK_DOWN) { v[1] -= 1; }
v = vec2_norm0(v);
pos += v * Vec2{SPEED * dt};
}
glClearColor(0.5, 0.7, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glOrtho(0, window.width as f64,
0, window.height as f64, 0, 1);
draw_rect :: proc(x, y, w, h: f32) {
glBegin(GL_TRIANGLES);
@@ -177,8 +204,7 @@ run_game :: proc() {
glEnd();
}
x, y : f32 = 100+50*sinf(curr_time as f32), 100;
draw_rect(x, y, 50, 50);
draw_rect(pos[0], pos[1], 50, 50);
display_window(^window);
ms_to_sleep := (16 - 1000*dt) as i32;
+142 -7
View File
@@ -1,19 +1,154 @@
MATH_TAU :: 6.28318530717958647692528676655900576;
MATH_PI :: 3.14159265358979323846264338327950288;
MATH_ONE_OVER_TAU :: 0.636619772367581343075535053490057448;
MATH_ONE_OVER_PI :: 0.159154943091895335768883763372514362;
MATH_E :: 2.71828182845904523536;
MATH_SQRT_TWO :: 1.41421356237309504880168872420969808;
MATH_SQRT_THREE :: 1.73205080756887729352744634150587236;
MATH_SQRT_FIVE :: 2.23606797749978969640917366873127623;
MATH_LOG_TWO :: 0.693147180559945309417232121458176568;
MATH_LOG_TEN :: 2.30258509299404568401799145468436421;
MATH_EPSILON :: 1.19209290e-7;
type Vec2: {2}f32
type Vec3: {3}f32
type Vec4: {4}f32
type Mat2: {4}f32
type Mat2: {4}f32
type Mat3: {9}f32
type Mat4: {16}f32
fsqrt :: proc(x: f32) -> f32 #foreign "llvm.sqrt.f32"
fsin :: proc(x: f32) -> f32 #foreign "llvm.sin.f32"
fcos :: proc(x: f32) -> f32 #foreign "llvm.cos.f32"
flerp :: proc(a, b, t: f32) -> f32 { return a*(1-t) + b*t; }
fclamp :: proc(x, lower, upper: f32) -> f32 { return fmin(fmax(x, lower), upper); }
fclamp01 :: proc(x: f32) -> f32 { return fclamp(x, 0, 1); }
fabs :: proc(x: f32) -> f32 { if x < 0 { x = -x; } return x; }
fsign :: proc(x: f32) -> f32 { if x >= 0 { return +1; } return -1; }
fmin :: proc(a, b: f32) -> f32 { if a < b { return a; } return b; }
fmax :: proc(a, b: f32) -> f32 { if a > b { return a; } return b; }
fmin3 :: proc(a, b, c: f32) -> f32 { return fmin(fmin(a, b), c); }
fmax3 :: proc(a, b, c: f32) -> f32 { return fmax(fmax(a, b), c); }
copy_sign :: proc(x, y: f32) -> f32 {
ix := x transmute u32;
iy := y transmute u32;
ix &= 0x7fffffff;
ix |= iy & 0x80000000;
return ix transmute f32;
}
round :: proc(x: f32) -> f32 {
if x >= 0 {
return floor(x + 0.5);
}
return ceil(x - 0.5);
}
floor :: proc(x: f32) -> f32 {
if x >= 0 {
return x as int as f32;
}
return (x-0.5) as int as f32;
}
ceil :: proc(x: f32) -> f32 {
if x < 0 {
return x as int as f32;
}
return ((x as int)+1) as f32;
}
remainder :: proc(x, y: f32) -> f32 {
return x - round(x/y) * y;
}
fmod :: proc(x, y: f32) -> f32 {
y = fabs(y);
result := remainder(fabs(x), y);
if fsign(result) < 0 {
result += y;
}
return copy_sign(result, x);
}
to_radians :: proc(degrees: f32) -> f32 { return degrees * MATH_TAU / 360; }
to_degrees :: proc(radians: f32) -> f32 { return radians * 360 / MATH_TAU; }
sqrtf :: proc(x: f32) -> f32 #foreign "llvm.sqrt.f32"
sinf :: proc(x: f32) -> f32 #foreign "llvm.sin.f32"
cosf :: proc(x: f32) -> f32 #foreign "llvm.cos.f32"
vec2_dot :: proc(a, b: Vec2) -> f32 { c := a*b; return c[0] + c[1]; }
vec3_dot :: proc(a, b: Vec3) -> f32 { c := a*b; return c[0] + c[1] + c[2]; }
vec4_dot :: proc(a, b: Vec4) -> f32 { c := a*b; return c[0] + c[1] + c[2] + c[3]; }
lerp :: proc(a, b, t: f32) -> f32 { return a*(1-t) + b*t; }
vec2_mag :: proc(a: Vec2) -> f32 { return sqrtf(vec2_dot(a, a)); }
vec3_mag :: proc(a: Vec3) -> f32 { return sqrtf(vec3_dot(a, a)); }
vec2_mag :: proc(v: Vec2) -> f32 { return fsqrt(vec2_dot(v, v)); }
vec3_mag :: proc(v: Vec3) -> f32 { return fsqrt(vec3_dot(v, v)); }
vec4_mag :: proc(v: Vec4) -> f32 { return fsqrt(vec4_dot(v, 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)}; }
vec2_norm0 :: proc(v: Vec2) -> Vec2 {
m := vec2_mag(v);
if m == 0 {
return Vec2{0};
}
return v / Vec2{m};
}
vec3_norm0 :: proc(v: Vec3) -> Vec3 {
m := vec3_mag(v);
if m == 0 {
return Vec3{0};
}
return v / Vec3{m};
}
vec4_norm0 :: proc(v: Vec4) -> Vec4 {
m := vec4_mag(v);
if m == 0 {
return Vec4{0};
}
return v / Vec4{m};
}
F32_DIG :: 6;
F32_EPSILON :: 1.192092896e-07;
F32_GUARD :: 0;
F32_MANT_DIG :: 24;
F32_MAX :: 3.402823466e+38;
F32_MAX_10_EXP :: 38;
F32_MAX_EXP :: 128;
F32_MIN :: 1.175494351e-38;
F32_MIN_10_EXP :: -37;
F32_MIN_EXP :: -125;
F32_NORMALIZE :: 0;
F32_RADIX :: 2;
F32_ROUNDS :: 1;
F64_DIG :: 15; // # of decimal digits of precision
F64_EPSILON :: 2.2204460492503131e-016; // smallest such that 1.0+F64_EPSILON != 1.0
F64_MANT_DIG :: 53; // # of bits in mantissa
F64_MAX :: 1.7976931348623158e+308; // max value
F64_MAX_10_EXP :: 308; // max decimal exponent
F64_MAX_EXP :: 1024; // max binary exponent
F64_MIN :: 2.2250738585072014e-308; // min positive value
F64_MIN_10_EXP :: -307; // min decimal exponent
F64_MIN_EXP :: -1021; // min binary exponent
F64_RADIX :: 2; // exponent radix
F64_ROUNDS :: 1; // addition rounding: near
+127 -3
View File
@@ -1,14 +1,16 @@
putchar :: proc(c: i32) -> i32 #foreign
heap_alloc :: proc(sz: int) -> rawptr #foreign "malloc"
heap_free :: proc(ptr: rawptr) #foreign "free"
mem_compare :: proc(dst, src : rawptr, len: int) -> i32 #foreign "memcmp"
mem_copy :: proc(dst, src : rawptr, len: int) -> i32 #foreign "memcpy"
mem_move :: proc(dst, src : rawptr, len: int) -> i32 #foreign "memmove"
debug_trap :: proc() #foreign "llvm.debugtrap"
// TODO(bill): make custom heap procedures
heap_realloc :: proc(ptr: rawptr, sz: int) -> rawptr #foreign "realloc"
heap_alloc :: proc(sz: int) -> rawptr { return heap_realloc(null, sz); }
heap_free :: proc(ptr: rawptr) { _ = heap_realloc(ptr, 0); }
__string_eq :: proc(a, b : string) -> bool {
if len(a) != len(b) {
@@ -50,3 +52,125 @@ __string_lt :: proc(a, b : string) -> bool { return __string_cmp(a, b) < 0; }
__string_gt :: proc(a, b : string) -> bool { return __string_cmp(a, b) > 0; }
__string_le :: proc(a, b : string) -> bool { return __string_cmp(a, b) <= 0; }
__string_ge :: proc(a, b : string) -> bool { return __string_cmp(a, b) >= 0; }
type AllocationMode: int;
ALLOCATION_ALLOC :: 0;
ALLOCATION_DEALLOC :: 1;
ALLOCATION_DEALLOC_ALL :: 2;
ALLOCATION_RESIZE :: 3;
type AllocatorProc: proc(allocator_data: rawptr, mode: AllocationMode,
size, alignment: int,
old_memory: rawptr, old_size: int, flags: u64) -> rawptr;
type Allocator: struct {
procedure: AllocatorProc,
data: rawptr,
}
type Context: struct {
thread_id: i32,
user_index: i32,
user_data: rawptr,
allocator: Allocator,
}
#thread_local context: Context;
DEFAULT_ALIGNMENT :: 2*size_of(int);
__check_context :: proc() {
if context.allocator.procedure == null {
context.allocator = __default_allocator();
}
ptr := __check_context as rawptr;
}
alloc :: proc(size: int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNMENT); }
alloc_align :: proc(size, alignment: int) -> rawptr #inline {
__check_context();
a := context.allocator;
return a.procedure(a.data, ALLOCATION_ALLOC, size, alignment, null, 0, 0);
}
dealloc :: proc(ptr: rawptr) #inline {
__check_context();
a := context.allocator;
_ = a.procedure(a.data, ALLOCATION_DEALLOC, 0, 0, ptr, 0, 0);
}
dealloc_all :: proc(ptr: rawptr) #inline {
__check_context();
a := context.allocator;
_ = a.procedure(a.data, ALLOCATION_DEALLOC_ALL, 0, 0, ptr, 0, 0);
}
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, ALLOCATION_RESIZE, new_size, alignment, ptr, old_size, 0);
}
default_resize_align :: proc(old_memory: rawptr, old_size, new_size, alignment: int) -> rawptr {
if old_memory == null {
return alloc_align(new_size, alignment);
}
if new_size == 0 {
dealloc(old_memory);
return null;
}
if new_size < old_size {
new_size = old_size;
}
if old_size == new_size {
return old_memory;
}
new_memory := alloc_align(new_size, alignment);
if new_memory == null {
return null;
}
_ = copy((new_memory as ^u8)[:new_size], (old_memory as ^u8)[:old_size]);
dealloc(old_memory);
return new_memory;
}
__default_allocator_proc :: proc(allocator_data: rawptr, mode: AllocationMode,
size, alignment: int,
old_memory: rawptr, old_size: int, flags: u64) -> rawptr {
if mode == ALLOCATION_ALLOC {
return heap_alloc(size);
} else if mode == ALLOCATION_RESIZE {
return heap_realloc(old_memory, size);
} else if mode == ALLOCATION_DEALLOC {
heap_free(old_memory);
} else if mode == ALLOCATION_DEALLOC_ALL {
// NOTE(bill): Does nothing
}
return null;
}
__default_allocator :: proc() -> Allocator {
return Allocator{
__default_allocator_proc,
null,
};
}
+202 -40
View File
@@ -42,24 +42,24 @@ type POINT: struct { x, y: i32 }
type WNDPROC: proc(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT
type WNDCLASSEXA: struct {
cbSize, style: u32,
wndProc: WNDPROC,
cbClsExtra, cbWndExtra: i32,
hInstance: HINSTANCE,
hIcon: HICON,
hCursor: HCURSOR,
hbrBackground: HBRUSH,
menuName, className: ^u8,
hIconSm: HICON,
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,
}
type MSG: struct {
hwnd: HWND,
hwnd: HWND,
message: u32,
wparam: WPARAM,
lparam: LPARAM,
time: u32,
pt: POINT,
wparam: WPARAM,
lparam: LPARAM,
time: u32,
pt: POINT,
}
@@ -145,34 +145,34 @@ type wglCreateContextAttribsARBType: proc(hdc: HDC, hshareContext: rawptr, attri
type PIXELFORMATDESCRIPTOR: struct {
nSize,
nVersion,
dwFlags: u32,
size,
version,
flags: u32,
iPixelType,
cColorBits,
cRedBits,
cRedShift,
cGreenBits,
cGreenShift,
cBlueBits,
cBlueShift,
cAlphaBits,
cAlphaShift,
cAccumBits,
cAccumRedBits,
cAccumGreenBits,
cAccumBlueBits,
cAccumAlphaBits,
cDepthBits,
cStencilBits,
cAuxBuffers,
iLayerType,
bReserved: 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,
dwLayerMask,
dwVisibleMask,
dwDamageMask: u32,
layer_mask,
visible_mask,
damage_mask: u32,
}
GetDC :: proc(h: HANDLE) -> HDC #foreign
@@ -190,3 +190,165 @@ wglCreateContext :: proc(hdc: HDC) -> HGLRC #foreign
wglMakeCurrent :: proc(hdc: HDC, hglrc: HGLRC) -> BOOL #foreign
wglGetProcAddress :: proc(c_str: ^u8) -> PROC #foreign
wglDeleteContext :: proc(hglrc: HGLRC) -> BOOL #foreign
GetAsyncKeyState :: proc(v_key: i32) -> i16 #foreign
is_key_down :: proc(key: int) -> bool {
return GetAsyncKeyState(key as i32) < 0;
}
VK_LBUTTON :: 0x01;
VK_RBUTTON :: 0x02;
VK_CANCEL :: 0x03;
VK_MBUTTON :: 0x04;
VK_BACK :: 0x08;
VK_TAB :: 0x09;
VK_CLEAR :: 0x0C;
VK_RETURN :: 0x0D;
VK_SHIFT :: 0x10;
VK_CONTROL :: 0x11;
VK_MENU :: 0x12;
VK_PAUSE :: 0x13;
VK_CAPITAL :: 0x14;
VK_KANA :: 0x15;
VK_HANGEUL :: 0x15;
VK_HANGUL :: 0x15;
VK_JUNJA :: 0x17;
VK_FINAL :: 0x18;
VK_HANJA :: 0x19;
VK_KANJI :: 0x19;
VK_ESCAPE :: 0x1B;
VK_CONVERT :: 0x1C;
VK_NONCONVERT :: 0x1D;
VK_ACCEPT :: 0x1E;
VK_MODECHANGE :: 0x1F;
VK_SPACE :: 0x20;
VK_PRIOR :: 0x21;
VK_NEXT :: 0x22;
VK_END :: 0x23;
VK_HOME :: 0x24;
VK_LEFT :: 0x25;
VK_UP :: 0x26;
VK_RIGHT :: 0x27;
VK_DOWN :: 0x28;
VK_SELECT :: 0x29;
VK_PRINT :: 0x2A;
VK_EXECUTE :: 0x2B;
VK_SNAPSHOT :: 0x2C;
VK_INSERT :: 0x2D;
VK_DELETE :: 0x2E;
VK_HELP :: 0x2F;
VK_0 :: '0';
VK_1 :: '1';
VK_2 :: '2';
VK_3 :: '3';
VK_4 :: '4';
VK_5 :: '5';
VK_6 :: '6';
VK_7 :: '7';
VK_8 :: '8';
VK_9 :: '9';
VK_A :: 'A';
VK_B :: 'B';
VK_C :: 'C';
VK_D :: 'D';
VK_E :: 'E';
VK_F :: 'F';
VK_G :: 'G';
VK_H :: 'H';
VK_I :: 'I';
VK_J :: 'J';
VK_K :: 'K';
VK_L :: 'L';
VK_M :: 'M';
VK_N :: 'N';
VK_O :: 'O';
VK_P :: 'P';
VK_Q :: 'Q';
VK_R :: 'R';
VK_S :: 'S';
VK_T :: 'T';
VK_U :: 'U';
VK_V :: 'V';
VK_W :: 'W';
VK_X :: 'X';
VK_Y :: 'Y';
VK_Z :: 'Z';
VK_LWIN :: 0x5B;
VK_RWIN :: 0x5C;
VK_APPS :: 0x5D;
VK_NUMPAD0 :: 0x60;
VK_NUMPAD1 :: 0x61;
VK_NUMPAD2 :: 0x62;
VK_NUMPAD3 :: 0x63;
VK_NUMPAD4 :: 0x64;
VK_NUMPAD5 :: 0x65;
VK_NUMPAD6 :: 0x66;
VK_NUMPAD7 :: 0x67;
VK_NUMPAD8 :: 0x68;
VK_NUMPAD9 :: 0x69;
VK_MULTIPLY :: 0x6A;
VK_ADD :: 0x6B;
VK_SEPARATOR :: 0x6C;
VK_SUBTRACT :: 0x6D;
VK_DECIMAL :: 0x6E;
VK_DIVIDE :: 0x6F;
VK_F1 :: 0x70;
VK_F2 :: 0x71;
VK_F3 :: 0x72;
VK_F4 :: 0x73;
VK_F5 :: 0x74;
VK_F6 :: 0x75;
VK_F7 :: 0x76;
VK_F8 :: 0x77;
VK_F9 :: 0x78;
VK_F10 :: 0x79;
VK_F11 :: 0x7A;
VK_F12 :: 0x7B;
VK_F13 :: 0x7C;
VK_F14 :: 0x7D;
VK_F15 :: 0x7E;
VK_F16 :: 0x7F;
VK_F17 :: 0x80;
VK_F18 :: 0x81;
VK_F19 :: 0x82;
VK_F20 :: 0x83;
VK_F21 :: 0x84;
VK_F22 :: 0x85;
VK_F23 :: 0x86;
VK_F24 :: 0x87;
VK_NUMLOCK :: 0x90;
VK_SCROLL :: 0x91;
VK_LSHIFT :: 0xA0;
VK_RSHIFT :: 0xA1;
VK_LCONTROL :: 0xA2;
VK_RCONTROL :: 0xA3;
VK_LMENU :: 0xA4;
VK_RMENU :: 0xA5;
VK_PROCESSKEY :: 0xE5;
VK_ATTN :: 0xF6;
VK_CRSEL :: 0xF7;
VK_EXSEL :: 0xF8;
VK_EREOF :: 0xF9;
VK_PLAY :: 0xFA;
VK_ZOOM :: 0xFB;
VK_NONAME :: 0xFC;
VK_PA1 :: 0xFD;
VK_OEM_CLEAR :: 0xFE;