using new language features
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 20 Sep 2020 00:36:06 +0000 (19:36 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 20 Sep 2020 00:36:06 +0000 (19:36 -0500)
build.sh [new file with mode: 0755]
js/environment.js
src/events.onyx
src/gfx/quad_renderer.onyx
src/gfx/texture.onyx [new file with mode: 0644]
src/input.onyx
src/main.onyx
src/utils/gl.onyx
tags

diff --git a/build.sh b/build.sh
new file mode 100755 (executable)
index 0000000..d66a9bb
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+onyx doc src/main.onyx
+onyx src/main.onyx
\ No newline at end of file
index dd5dc70af188c516ab3fedbcad89e762c5057340..84d0bb9b42a42138ba7180c6b2cbfd01364bed9d 100644 (file)
@@ -5,11 +5,11 @@ let anim_frame = () => {
     });
 }
 
-async function start_game(gs) {
+async function start_game() {
     while (true) {
         await anim_frame();
 
-        WASM_EXPORTS.new_frame_callback(gs);
+        WASM_EXPORTS.new_frame_callback();
     }
 }
 
index 84fa804e64f1784fc8a0000df2f4d4c1a182f270..80cb2cb2b3f6ce8877a68673b126a6a2b0e7867d 100644 (file)
@@ -2,7 +2,7 @@ package event
 
 use package core { print }
 
-MAX_EVENTS :: 16
+#private_file MAX_EVENTS :: 16
 
 // NOTE: These need to match exactly what is in the corresponding javascript
 DomEventKind :: enum {
@@ -67,7 +67,7 @@ clear_event :: proc (ev: ^Event) {
     dev.timestamp = 0;
 }
 
-init :: proc {
+init :: proc () {
     event_storage.event_count = 0;
     event_storage.max_events = MAX_EVENTS;
 
@@ -91,11 +91,11 @@ poll :: proc (ev: ^Event) -> bool {
 
 /* Private members */
 
-#private EventStorage :: struct {
+#private_file EventStorage :: struct {
     event_count  : u32;
     max_events   : u32;
     event_buffer : [MAX_EVENTS] Event;
 }
 
-#private event_storage : EventStorage;
-#private event_setup :: proc (event_storage: ^EventStorage, event_size: u32) #foreign "event" "setup" ---
+#private_file event_storage : EventStorage;
+#private_file event_setup :: proc (event_storage: ^EventStorage, event_size: u32) #foreign "event" "setup" ---
index 5af29244cbba628bea995300cbc4a1ac0cd6e772..9191818fabebbbe114c17721ea16d82f40386a5c 100644 (file)
@@ -3,7 +3,6 @@ package gfx
 use package core
 use package gl as gl
 use package gl_utils as gl_utils
-
 use package main { window_width, window_height }
 
 Vec2 :: struct {
@@ -26,20 +25,16 @@ QuadRenderer :: struct {
     is_data_dirty : bool = false;
 }
 
+Color4f32 :: struct { r: f32; g: f32; b: f32; a: f32; }
+
 Quad :: struct {
-    use pos : Vec2;
-    w : f32 = 0.0f;
-    h : f32 = 0.0f;
-
-    u : f32 = 0.0f;
-    v : f32 = 0.0f;
-    tw : f32 = 0.0f;
-    th : f32 = 0.0f;
-
-    r : f32 = 0.0f;
-    g : f32 = 0.0f;
-    b : f32 = 0.0f;
-    a : f32 = 0.0f;
+    pos  : Vec2;
+    size : Vec2;
+
+    tex_pos  : Vec2;
+    tex_size : Vec2;
+
+    color : Color4f32;
 }
 
 quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {
@@ -67,17 +62,11 @@ quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {
     array_init(^quad_data, initial_quads);
 
     default_quad : Quad;
-    default_quad.pos = Vec2.{ 0.0f, 0.0f };
-    default_quad.w = 0.0f;
-    default_quad.h = 0.0f;
-    default_quad.u = 0.0f;
-    default_quad.v = 0.0f;
-    default_quad.tw = 0.0f;
-    default_quad.th = 0.0f;
-    default_quad.r = 0.0f;
-    default_quad.g = 0.0f;
-    default_quad.b = 0.0f;
-    default_quad.a = 0.0f;
+    default_quad.pos  = Vec2.{ 0.0f, 0.0f };
+    default_quad.size = Vec2.{ 0.0f, 0.0f };
+    default_quad.tex_pos = Vec2.{ 0.0f, 0.0f };
+    default_quad.tex_size = Vec2.{ 0.0f, 0.0f };
+    default_quad.color = Color4f32.{ 0.0f, 0.0f, 0.0f, 0.0f };
     for i: 0 .. initial_quads {
         array_push(^quad_data, default_quad);
     }
@@ -108,6 +97,8 @@ quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {
     index_data[4] = cast(gl.GLubyte) 2;
     index_data[5] = cast(gl.GLubyte) 3;
 
+    // index_data := { 0, 1, 2, 0, 2, 3 };
+
     indexBuffer = gl.createBuffer();
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, Buffer.{
@@ -136,7 +127,7 @@ quad_renderer_update_view :: proc (use qr: ^QuadRenderer) {
     proj_mat : [4 * 4] gl.GLfloat;
     for ^it: proj_mat do *it = 0.0f;
 
-    // Orthographic projection matrix samelessly stolen from:
+    // Orthographic projection matrix shamelessly stolen from:
     //     https://en.wikipedia.org/wiki/Orthographic_projection
     r :: cast(f32) window_width;
     l :: 0.0f;
diff --git a/src/gfx/texture.onyx b/src/gfx/texture.onyx
new file mode 100644 (file)
index 0000000..a3475ae
--- /dev/null
@@ -0,0 +1,51 @@
+package gfx
+
+use package core
+use package gl as gl
+use package gl_utils as gl_utils
+
+Color3 :: struct { r: u8; g: u8; b: u8; }
+
+Texture :: struct {
+    // NOTE: After a texture is loaded, we may not want to keep the
+    // raw texture data in memory any longer. This would not be possible
+    // if it is stored in the data section.
+    data       : [] Color3;
+    width      : i32;
+    height     : i32;
+
+    texture_id : gl.GLTexture;
+}
+
+// NOTE: This assumes that the data is raw u8 RGB packed color data.
+texture_create :: proc (texdata: [] Color3, width: i32, height: i32) -> Texture {
+    tex : Texture;
+    tex.data = texdata;
+    tex.width = width;
+    tex.height = height;
+    tex.texture_id = -1;
+
+    if width * height != tex.data.count {
+        println("Warning: Texture width and height does not match the size of data given.");
+    }
+
+    return tex;
+}
+
+texture_prepare :: proc (use tex: ^Texture) {
+    if texture_id != -1 do return;
+
+    texdata := (cast(^u8) data.data)[0 .. data.count * 3];
+
+    texture_id = gl.createTexture();
+    gl.activeTexture(gl.TEXTURE0);
+    gl.bindTexture(gl.TEXTURE_2D, texture_id);
+    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_BYTE, texdata);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+    gl.bindTexture(gl.TEXTURE_2D, -1);
+}
+
+texture_use :: proc (use tex: ^Texture) {
+    gl.bindTexture(gl.TEXTURE_2D, texture_id);
+}
index 4d8029caf6d516c411fc892fccca925f810dec5e..bf9a110f2d438b47534e713eabbf5ed14609cb45 100644 (file)
@@ -3,8 +3,8 @@ package input
 use package event as event
 use package core { print }
 
-KEY_COUNT :: 256
-BUTTON_COUNT :: 3
+#private_file KEY_COUNT :: 256
+#private_file BUTTON_COUNT :: 3
 
 Key :: enum {
     ArrowLeft  :: 0x25;
index 64b8272c7d6fd33769a6ebea2b4d40b7ab630759..099623ce399dd4294de1923436f7968a555b798f 100644 (file)
@@ -6,6 +6,7 @@ package main
 #include_folder "src/"
 #include_file "utils/gl"
 #include_file "gfx/quad_renderer"
+#include_file "gfx/texture"
 #include_file "events"
 #include_file "input"
 
@@ -17,22 +18,18 @@ use package input as input { Key }
 
 NUM_QUADS :: 1 << 7
 
-GameState :: struct {
-    quad_renderer : QuadRenderer;
-    input_state   : input.InputState;
-
-    player : Player;
-}
-
-Player :: struct {
-    use pos : Vec2;
-}
-
 // @Cleanup
 window_width  := 0
 window_height := 0
 
-poll_events :: proc (use gs: ^GameState) {
+quad_renderer : QuadRenderer
+input_state   : input.InputState
+
+Player :: struct { use pos : Vec2; }
+player : Player
+
+
+poll_events :: proc () {
     ev : event.Event;
     while event.poll(^ev) do switch ev.kind {
         case event.DomEventKind.KeyDown,
@@ -55,10 +52,10 @@ poll_events :: proc (use gs: ^GameState) {
     }
 }
 
-update :: proc (use gs: ^GameState) {
+update :: proc () {
     input.preupdate(^input_state);
     defer input.postupdate(^input_state);
-    poll_events(gs);
+    poll_events();
 
     player_speed :: 4f;
 
@@ -68,29 +65,27 @@ update :: proc (use gs: ^GameState) {
     if input.key_down(^input_state, Key.ArrowRight) do player.x += player_speed;
 
     quad_update_at_index(^quad_renderer, NUM_QUADS - 1, Quad.{
-        x = input_state.mouse.x,
-        y = cast(f32) input_state.mouse.y,
-
-        w = 32.0f, h = 32.0f,
+        pos = Vec2.{ ~~input_state.mouse.x, ~~input_state.mouse.y },
+        size = Vec2.{ 32.0f, 32.0f },
 
-        u = 0.25f, v = 0.25f, tw = 0.25f, th = 0.25f,
+        tex_pos = Vec2.{ 0.25f, 0.25f },
+        tex_size = Vec2.{ 0.25f, 0.25f },
 
-        r = 1.0f, g = 0.0f, b = 0.0f, a = 0.5f,
+        color = Color4f32.{ 1.0f, 0.0f, 0.0f, 0.5f },
     });
 
     quad_update_at_index(^quad_renderer, 0, Quad.{
-        x = player.x,
-        y = player.y,
-
-        w = 100.0f, h = 100.0f,
+        pos = player.pos,
+        size = Vec2.{ 100.0f, 100.0f },
 
-        u = 0.0f, v = 0.0f, tw = 1.0f, th = 1.0f,
+        tex_pos = Vec2.{ 0.0f, 0.0f },
+        tex_size = Vec2.{ 1.0f, 1.0f },
 
-        r = 0.0f, g = 0.0f, b = 1.0f, a = 1.0f
+        color = Color4f32.{ 0.0f, 0.0f, 1.0f, 1.0f },
     });
 }
 
-draw :: proc (use gs: ^GameState) {
+draw :: proc () {
     gl.clearColor(0.1f, 0.1f, 0.1f, 1.0f);
     gl.clear(gl.COLOR_BUFFER_BIT);
 
@@ -98,50 +93,47 @@ draw :: proc (use gs: ^GameState) {
     quad_renderer_draw(^quad_renderer);
 }
 
-// This procedure is called asynchronously from JS.
-// It provides us with the pointer we gave it in main.
-new_frame_callback :: proc (gs: ^GameState) #export {
-    update(gs);
-    draw(gs);
+// This procedure is called asynchronously from JS every frame.
+new_frame_callback :: proc () #export {
+    update();
+    draw();
 }
 
 main :: proc (args: [] cstring) {
-    print("Setting up WebGL2 canvas...\n");
+    println("Setting up WebGL2 canvas...");
 
     if !gl.init("gamecanvas") {
         print("Failed to initialize GL canvas.");
         return;
     }
 
-
     gl.enable(gl.CULL_FACE);
     gl.cullFace(gl.BACK);
 
     gl.enable(gl.BLEND);
     gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
 
+    quad_renderer_init(^quad_renderer, NUM_QUADS);
 
-    gs := cast(^GameState) calloc(sizeof GameState);
-
-    gs.player.pos = Vec2.{ 0.0f, 0.0f };
-
-    quad_renderer_init(^gs.quad_renderer, NUM_QUADS);
+    // CLEANUP: Maybe there should be a way to cast between slices?
+    // Automatically multiply / divide the count by the ratio of the type sizes?
+    // This could be very buggy
+    image_data : [] Color3;
+    raw_image_data := #file_contents "res/smile.data";
+    image_data.data  = cast(^Color3) raw_image_data.data;
+    image_data.count = raw_image_data.count / 3;
 
-    image_data := string.{ data = #file_contents "res/smile.data", count = 32 * 32 * 3 };
-    texture := gl.createTexture();
-    gl.activeTexture(gl.TEXTURE0);
-    gl.bindTexture(gl.TEXTURE_2D, texture);
-    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 32, 32, 0, gl.RGB, gl.UNSIGNED_BYTE, image_data);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+    smile := texture_create(image_data, 32, 32);
+    texture_prepare(^smile);
+    texture_use(^smile);
 
     event.init();
-    input.init(^gs.input_state);
+    input.init(^input_state);
 
-    game_launch(gs);
+    game_launch();
 }
 
 
 
-game_launch :: proc (gs: ^GameState) #foreign "game" "launch" ---
+game_launch :: proc () #foreign "game" "launch" ---
 
index 90832950a2b9969d64f7100d6a7d021f6d00ebef..36238a860c3c1151e65960bc86aef4f7bdee0d43 100644 (file)
@@ -3,9 +3,9 @@ package gl_utils
 use package core { string_make }
 use package gl as gl
 
-compile_shader :: proc (shader_type: gl.GLenum, source: cstring) -> gl.GLShader {
+compile_shader :: proc (shader_type: gl.GLenum, source: string) -> gl.GLShader {
     shader := gl.createShader(shader_type);
-    gl.shaderSource(shader, string_make(source));
+    gl.shaderSource(shader, source);
     gl.compileShader(shader);
 
     if cast(i32) gl.getShaderParameter(shader, gl.COMPILE_STATUS) == 0 {
diff --git a/tags b/tags
index 175ecf3ea4fd9730874099266f87c1045701ffbb..c4c1d1fa03cd89c5f29bc8a540d7de1fd0c0e614 100644 (file)
--- a/tags
+++ b/tags
@@ -41,7 +41,6 @@ BOOL_VEC4     /usr/share/onyx/core/js/webgl.onyx      /^BOOL_VEC4                      ::
 BROWSER_DEFAULT_WEBGL  /usr/share/onyx/core/js/webgl.onyx      /^BROWSER_DEFAULT_WEBGL          :: 0x9244$/
 BUFFER_SIZE    /usr/share/onyx/core/js/webgl.onyx      /^BUFFER_SIZE                    :: 0x8764$/
 BUFFER_USAGE   /usr/share/onyx/core/js/webgl.onyx      /^BUFFER_USAGE                   :: 0x8765$/
-BUTTON_COUNT   src/input.onyx  /^BUTTON_COUNT :: 3$/
 BYTE   /usr/share/onyx/core/js/webgl.onyx      /^BYTE                           :: 0x1400$/
 Buffer /usr/share/onyx/core/builtin.onyx       /^Buffer :: #type []void;$/
 CCW    /usr/share/onyx/core/js/webgl.onyx      /^CCW                            :: 0x0901$/
@@ -83,6 +82,8 @@ CURRENT_PROGRAM       /usr/share/onyx/core/js/webgl.onyx      /^CURRENT_PROGRAM
 CURRENT_QUERY  /usr/share/onyx/core/js/webgl.onyx      /^CURRENT_QUERY                                 :: 0x8865$/
 CURRENT_VERTEX_ATTRIB  /usr/share/onyx/core/js/webgl.onyx      /^CURRENT_VERTEX_ATTRIB          :: 0x8626$/
 CW     /usr/share/onyx/core/js/webgl.onyx      /^CW                             :: 0x0900$/
+Color3 src/gfx/texture.onyx    /^Color3 :: struct { r: u8; g: u8; b: u8; }$/
+Color4f32      src/gfx/quad_renderer.onyx      /^Color4f32 :: struct { r: f32; g: f32; b: f32; a: f32; }$/
 DECR   /usr/share/onyx/core/js/webgl.onyx      /^DECR                           :: 0x1E03$/
 DECR_WRAP      /usr/share/onyx/core/js/webgl.onyx      /^DECR_WRAP                      :: 0x8508$/
 DEFAULT_ALLOCATION_ALIGNMENT   /usr/share/onyx/core/builtin.onyx       /^DEFAULT_ALLOCATION_ALIGNMENT :: 16$/
@@ -135,7 +136,6 @@ ELEMENT_ARRAY_BUFFER        /usr/share/onyx/core/js/webgl.onyx      /^ELEMENT_ARRAY_BUFFER
 ELEMENT_ARRAY_BUFFER_BINDING   /usr/share/onyx/core/js/webgl.onyx      /^ELEMENT_ARRAY_BUFFER_BINDING   :: 0x8895$/
 EQUAL  /usr/share/onyx/core/js/webgl.onyx      /^EQUAL                          :: 0x0202$/
 Event  src/events.onyx /^Event :: struct #union {$/
-EventStorage   src/events.onyx /^#private EventStorage :: struct {$/
 FASTEST        /usr/share/onyx/core/js/webgl.onyx      /^FASTEST                        :: 0x1101$/
 FLOAT  /usr/share/onyx/core/js/webgl.onyx      /^FLOAT                          :: 0x1406$/
 FLOAT_32_UNSIGNED_INT_24_8_REV /usr/share/onyx/core/js/webgl.onyx      /^FLOAT_32_UNSIGNED_INT_24_8_REV                :: 0x8DAD$/
@@ -211,10 +211,11 @@ GLuint    /usr/share/onyx/core/js/webgl.onyx      /^GLuint     :: #type u32$/
 GLushort       /usr/share/onyx/core/js/webgl.onyx      /^GLushort   :: #type u16$/
 GREATER        /usr/share/onyx/core/js/webgl.onyx      /^GREATER                        :: 0x0204$/
 GREEN_BITS     /usr/share/onyx/core/js/webgl.onyx      /^GREEN_BITS                     :: 0x0D53$/
-GameState      src/main.onyx   /^GameState :: struct {$/
 HALF_FLOAT     /usr/share/onyx/core/js/webgl.onyx      /^HALF_FLOAT                                    :: 0x140B$/
 HIGH_FLOAT     /usr/share/onyx/core/js/webgl.onyx      /^HIGH_FLOAT                     :: 0x8DF2$/
 HIGH_INT       /usr/share/onyx/core/js/webgl.onyx      /^HIGH_INT                       :: 0x8DF5$/
+I32Map /usr/share/onyx/core/i32map.onyx        /^I32Map :: struct ($T) {$/
+I32MapEntry    /usr/share/onyx/core/i32map.onyx        /^I32MapEntry :: struct ($T) {$/
 IMPLEMENTATION_COLOR_READ_FORMAT       /usr/share/onyx/core/js/webgl.onyx      /^IMPLEMENTATION_COLOR_READ_FORMAT :: 0x8B9B$/
 IMPLEMENTATION_COLOR_READ_TYPE /usr/share/onyx/core/js/webgl.onyx      /^IMPLEMENTATION_COLOR_READ_TYPE   :: 0x8B9A$/
 INCR   /usr/share/onyx/core/js/webgl.onyx      /^INCR                           :: 0x1E02$/
@@ -237,7 +238,6 @@ INVALID_VALUE       /usr/share/onyx/core/js/webgl.onyx      /^INVALID_VALUE
 INVERT /usr/share/onyx/core/js/webgl.onyx      /^INVERT                         :: 0x150A$/
 InputState     src/input.onyx  /^InputState :: struct {$/
 KEEP   /usr/share/onyx/core/js/webgl.onyx      /^KEEP                           :: 0x1E00$/
-KEY_COUNT      src/input.onyx  /^KEY_COUNT :: 256$/
 Key    src/input.onyx  /^Key :: enum {$/
 KeyboardEvent  src/events.onyx /^KeyboardEvent :: struct {$/
 LEQUAL /usr/share/onyx/core/js/webgl.onyx      /^LEQUAL                         :: 0x0203$/
@@ -268,7 +268,6 @@ MAX_DRAW_BUFFERS    /usr/share/onyx/core/js/webgl.onyx      /^MAX_DRAW_BUFFERS
 MAX_ELEMENTS_INDICES   /usr/share/onyx/core/js/webgl.onyx      /^MAX_ELEMENTS_INDICES                          :: 0x80E9$/
 MAX_ELEMENTS_VERTICES  /usr/share/onyx/core/js/webgl.onyx      /^MAX_ELEMENTS_VERTICES                         :: 0x80E8$/
 MAX_ELEMENT_INDEX      /usr/share/onyx/core/js/webgl.onyx      /^MAX_ELEMENT_INDEX                             :: 0x8D6B$/
-MAX_EVENTS     src/events.onyx /^MAX_EVENTS :: 16$/
 MAX_FRAGMENT_INPUT_COMPONENTS  /usr/share/onyx/core/js/webgl.onyx      /^MAX_FRAGMENT_INPUT_COMPONENTS                 :: 0x9125$/
 MAX_FRAGMENT_UNIFORM_BLOCKS    /usr/share/onyx/core/js/webgl.onyx      /^MAX_FRAGMENT_UNIFORM_BLOCKS                   :: 0x8A2D$/
 MAX_FRAGMENT_UNIFORM_COMPONENTS        /usr/share/onyx/core/js/webgl.onyx      /^MAX_FRAGMENT_UNIFORM_COMPONENTS               :: 0x8B49$/
@@ -332,10 +331,9 @@ POINTS     /usr/share/onyx/core/js/webgl.onyx      /^POINTS                         :: 0x
 POLYGON_OFFSET_FACTOR  /usr/share/onyx/core/js/webgl.onyx      /^POLYGON_OFFSET_FACTOR          :: 0x8038$/
 POLYGON_OFFSET_FILL    /usr/share/onyx/core/js/webgl.onyx      /^POLYGON_OFFSET_FILL            :: 0x8037$/
 POLYGON_OFFSET_UNITS   /usr/share/onyx/core/js/webgl.onyx      /^POLYGON_OFFSET_UNITS           :: 0x2A00$/
-Player src/main.onyx   /^Player :: struct {$/
+Player src/main.onyx   /^Player :: struct { use pos : Vec2; }$/
 PtrMap /usr/share/onyx/core/ptrmap.onyx        /^PtrMap :: struct {$/
 PtrMapEntry    /usr/share/onyx/core/ptrmap.onyx        /^PtrMapEntry :: struct {$/
-PtrMapLookupResult     /usr/share/onyx/core/ptrmap.onyx        /^PtrMapLookupResult :: struct {$/
 QUERY_RESULT   /usr/share/onyx/core/js/webgl.onyx      /^QUERY_RESULT                                  :: 0x8866$/
 QUERY_RESULT_AVAILABLE /usr/share/onyx/core/js/webgl.onyx      /^QUERY_RESULT_AVAILABLE                        :: 0x8867$/
 Quad   src/gfx/quad_renderer.onyx      /^Quad :: struct {$/
@@ -558,6 +556,7 @@ TRANSFORM_FEEDBACK_VARYINGS /usr/share/onyx/core/js/webgl.onyx      /^TRANSFORM_FEEDB
 TRIANGLES      /usr/share/onyx/core/js/webgl.onyx      /^TRIANGLES                      :: 0x0004$/
 TRIANGLE_FAN   /usr/share/onyx/core/js/webgl.onyx      /^TRIANGLE_FAN                   :: 0x0006$/
 TRIANGLE_STRIP /usr/share/onyx/core/js/webgl.onyx      /^TRIANGLE_STRIP                 :: 0x0005$/
+Texture        src/gfx/texture.onyx    /^Texture :: struct {$/
 UNIFORM_ARRAY_STRIDE   /usr/share/onyx/core/js/webgl.onyx      /^UNIFORM_ARRAY_STRIDE                          :: 0x8A3C$/
 UNIFORM_BLOCK_ACTIVE_UNIFORMS  /usr/share/onyx/core/js/webgl.onyx      /^UNIFORM_BLOCK_ACTIVE_UNIFORMS                 :: 0x8A42$/
 UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES   /usr/share/onyx/core/js/webgl.onyx      /^UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES          :: 0x8A43$/
@@ -626,6 +625,7 @@ abs_f32     /usr/share/onyx/core/intrinsics.onyx    /^abs_f32      :: proc (val: f32) -
 abs_f64        /usr/share/onyx/core/intrinsics.onyx    /^abs_f64      :: proc (val: f64) -> f64 #intrinsic ---$/
 activeTexture  /usr/share/onyx/core/js/webgl.onyx      /^activeTexture                  :: proc (texture: GLenum) #foreign "gl" "activeTexture" ---$/
 alloc  /usr/share/onyx/core/builtin.onyx       /^alloc :: proc (use a: Allocator, size: u32) -> rawptr {$/
+alloc_slice    /usr/share/onyx/core/alloc.onyx /^alloc_slice :: proc (sl: ^[] $T, count: i32) {$/
 allocator_proc /usr/share/onyx/core/builtin.onyx       /^allocator_proc :: #type proc (rawptr, AllocAction, u32, u32, rawptr) -> rawptr;$/
 and_i32        /usr/share/onyx/core/intrinsics.onyx    /^and_i32      :: proc (lhs: i32, rhs: i32) -> i32 #intrinsic ---$/
 and_i64        /usr/share/onyx/core/intrinsics.onyx    /^and_i64      :: proc (lhs: i64, rhs: i64) -> i64 #intrinsic ---$/
@@ -658,7 +658,7 @@ blendEquationSeparate       /usr/share/onyx/core/js/webgl.onyx      /^blendEquationSeparate
 blendFunc      /usr/share/onyx/core/js/webgl.onyx      /^blendFunc                      :: proc (sfactor: GLenum, dfactor: GLenum) #foreign "gl" "blendFunc" ---$/
 blendFuncSeparate      /usr/share/onyx/core/js/webgl.onyx      /^blendFuncSeparate              :: proc (srcRGB: GLenum, dstRGB: GLenum, srcAlpha: GLenum, dstAlpha: GLenum) #foreign "gl" "blendFuncSeparate" ---$/
 blitFramebuffer        /usr/share/onyx/core/js/webgl.onyx      /^blitFramebuffer                :: proc (sx0: GLint, sy0: GLint, sx1: GLint, sy1: GLint, dx0: GLint, dy0: GLint, dx1: GLint, dy1: GLint, mask: GLbitfield, filter: GLenum) #foreign "gl" "blitFramebuffer" ---$/
-bufferData     /usr/share/onyx/core/js/webgl.onyx      /^bufferData                     :: proc #overloaded { bufferDataWithData, bufferDataNoData }$/
+bufferData     /usr/share/onyx/core/js/webgl.onyx      /^bufferData                     :: proc { bufferDataWithData, bufferDataNoData }$/
 bufferDataNoData       /usr/share/onyx/core/js/webgl.onyx      /^bufferDataNoData               :: proc (target: GLenum, size: GLsizeiptr, usage: GLenum) #foreign "gl" "bufferDataNoData" ---$/
 bufferDataWithData     /usr/share/onyx/core/js/webgl.onyx      /^bufferDataWithData             :: proc (target: GLenum, buffer: Buffer, usage: GLenum) #foreign "gl" "bufferDataWithData" ---$/
 bufferSubData  /usr/share/onyx/core/js/webgl.onyx      /^bufferSubData                  :: proc (target: GLenum, offset: GLsizei, data: Buffer) #foreign "gl" "bufferSubData" ---$/
@@ -679,7 +679,7 @@ cmp_asc     /usr/share/onyx/core/builtin.onyx       /^cmp_asc :: proc (a: $T, b: T) -> i32
 cmp_dec        /usr/share/onyx/core/builtin.onyx       /^cmp_dec :: proc (a: $T, b: T) -> i32 do return cast(i32) (b - a);$/
 colorMask      /usr/share/onyx/core/js/webgl.onyx      /^colorMask                      :: proc (red: GLboolean, green: GLboolean, blue: GLboolean, alpha: GLboolean) #foreign "gl" "colorMask" ---$/
 compileShader  /usr/share/onyx/core/js/webgl.onyx      /^compileShader                  :: proc (shader: GLShader) #foreign "gl" "compileShader" ---$/
-compile_shader src/utils/gl.onyx       /^compile_shader :: proc (shader_type: gl.GLenum, source: cstring) -> gl.GLShader {$/
+compile_shader src/utils/gl.onyx       /^compile_shader :: proc (shader_type: gl.GLenum, source: string) -> gl.GLShader {$/
 compressedTexImage2D   /usr/share/onyx/core/js/webgl.onyx      /^compressedTexImage2D           :: proc (target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, border: GLint, data: string) #foreign "gl" "compressedTexImage2D" ---$/
 compressedTexSubImage2D        /usr/share/onyx/core/js/webgl.onyx      /^compressedTexSubImage2D        :: proc (target: GLenum, level: GLint, internalformat: GLenum, xoff: GLint, yoff: GLint, width: GLsizei, height: GLsizei, format: GLenum, data: string) #foreign "gl" "compressedTexSubImage2D" ---$/
 context        /usr/share/onyx/core/builtin.onyx       /^context : struct {$/
@@ -689,13 +689,13 @@ copyTexSubImage2D /usr/share/onyx/core/js/webgl.onyx      /^copyTexSubImage2D
 copysign_f32   /usr/share/onyx/core/intrinsics.onyx    /^copysign_f32 :: proc (lhs: f32, rhs: f32) -> f32 #intrinsic ---$/
 copysign_f64   /usr/share/onyx/core/intrinsics.onyx    /^copysign_f64 :: proc (lhs: f64, rhs: f64) -> f64 #intrinsic ---$/
 cos    /usr/share/onyx/core/math.onyx  /^cos :: proc (t_: f32) -> f32 {$/
-createBuffer   /usr/share/onyx/core/js/webgl.onyx      /^createBuffer                   :: proc -> GLBuffer #foreign "gl" "createBuffer" ---$/
-createFramebuffer      /usr/share/onyx/core/js/webgl.onyx      /^createFramebuffer              :: proc -> GLFramebuffer #foreign "gl" "createFramebuffer" ---$/
-createProgram  /usr/share/onyx/core/js/webgl.onyx      /^createProgram                  :: proc -> GLProgram #foreign "gl" "createProgram" ---$/
-createRenderbuffer     /usr/share/onyx/core/js/webgl.onyx      /^createRenderbuffer             :: proc -> GLRenderbuffer #foreign "gl" "createRenderbuffer" ---$/
+createBuffer   /usr/share/onyx/core/js/webgl.onyx      /^createBuffer                   :: proc () -> GLBuffer #foreign "gl" "createBuffer" ---$/
+createFramebuffer      /usr/share/onyx/core/js/webgl.onyx      /^createFramebuffer              :: proc () -> GLFramebuffer #foreign "gl" "createFramebuffer" ---$/
+createProgram  /usr/share/onyx/core/js/webgl.onyx      /^createProgram                  :: proc () -> GLProgram #foreign "gl" "createProgram" ---$/
+createRenderbuffer     /usr/share/onyx/core/js/webgl.onyx      /^createRenderbuffer             :: proc () -> GLRenderbuffer #foreign "gl" "createRenderbuffer" ---$/
 createShader   /usr/share/onyx/core/js/webgl.onyx      /^createShader                   :: proc (type: GLenum) -> GLShader #foreign "gl" "createShader" ---$/
-createTexture  /usr/share/onyx/core/js/webgl.onyx      /^createTexture                  :: proc -> GLTexture #foreign "gl" "createTexture" ---$/
-createVertexArray      /usr/share/onyx/core/js/webgl.onyx      /^createVertexArray              :: proc -> GLVertexArrayObject #foreign "gl" "createVertexArray" ---$/
+createTexture  /usr/share/onyx/core/js/webgl.onyx      /^createTexture                  :: proc () -> GLTexture #foreign "gl" "createTexture" ---$/
+createVertexArray      /usr/share/onyx/core/js/webgl.onyx      /^createVertexArray              :: proc () -> GLVertexArrayObject #foreign "gl" "createVertexArray" ---$/
 cresize        /usr/share/onyx/core/builtin.onyx       /^cresize :: proc (ptr: rawptr, size: u32) -> rawptr do return resize(context.allocator, ptr, size);$/
 cstring        /usr/share/onyx/core/builtin.onyx       /^cstring :: #type ^u8;$/
 ctz_i32        /usr/share/onyx/core/intrinsics.onyx    /^ctz_i32      :: proc (val: i32) -> i32 #intrinsic ---$/
@@ -714,31 +714,29 @@ depthRange        /usr/share/onyx/core/js/webgl.onyx      /^depthRange                     :
 detachShader   /usr/share/onyx/core/js/webgl.onyx      /^detachShader                   :: proc (program: GLProgram, shader: GLShader) #foreign "gl" "detachShader" ---$/
 disable        /usr/share/onyx/core/js/webgl.onyx      /^disable                        :: proc (cap: GLenum) #foreign "gl" "disable" ---$/
 disableVertexAttribArray       /usr/share/onyx/core/js/webgl.onyx      /^disableVertexAttribArray       :: proc (index: GLuint) #foreign "gl" "disableVertexAttribArray" ---$/
-draw   src/main.onyx   /^draw :: proc (use gs: ^GameState) {$/
+draw   src/main.onyx   /^draw :: proc () {$/
 drawArrays     /usr/share/onyx/core/js/webgl.onyx      /^drawArrays                     :: proc (mode: GLenum, first: GLint, count: GLsizei) #foreign "gl" "drawArrays" ---$/
 drawArraysInstanced    /usr/share/onyx/core/js/webgl.onyx      /^drawArraysInstanced            :: proc (mode: GLenum, first: GLint, count: GLsizei, instanceCount: GLsizei) #foreign "gl" "drawArraysInstanced" ---$/
 drawElements   /usr/share/onyx/core/js/webgl.onyx      /^drawElements                   :: proc (mode: GLenum, count: GLsizei, type: GLenum, offset: GLint) #foreign "gl" "drawElements" ---$/
 drawElementsInstanced  /usr/share/onyx/core/js/webgl.onyx      /^drawElementsInstanced          :: proc (mode: GLenum, count: GLsizei, type: GLenum, offset: GLint, instanceCount: GLsizei) #foreign "gl" "drawElementsInstanced" ---$/
 enable /usr/share/onyx/core/js/webgl.onyx      /^enable                         :: proc (cap: GLenum) #foreign "gl" "enable" ---$/
 enableVertexAttribArray        /usr/share/onyx/core/js/webgl.onyx      /^enableVertexAttribArray        :: proc (index: GLuint) #foreign "gl" "enableVertexAttribArray" ---$/
-event_setup    src/events.onyx /^#private event_setup :: proc (event_storage: ^EventStorage, event_size: u32) #foreign "event" "setup" ---$/
-event_storage  src/events.onyx /^#private event_storage : EventStorage;$/
-finish /usr/share/onyx/core/js/webgl.onyx      /^finish                         :: proc #foreign "gl" "finish" ---$/
+finish /usr/share/onyx/core/js/webgl.onyx      /^finish                         :: proc () #foreign "gl" "finish" ---$/
 floor_f32      /usr/share/onyx/core/intrinsics.onyx    /^floor_f32    :: proc (val: f32) -> f32 #intrinsic ---$/
 floor_f64      /usr/share/onyx/core/intrinsics.onyx    /^floor_f64    :: proc (val: f64) -> f64 #intrinsic ---$/
-flush  /usr/share/onyx/core/js/webgl.onyx      /^flush                          :: proc #foreign "gl" "flush" ---$/
+flush  /usr/share/onyx/core/js/webgl.onyx      /^flush                          :: proc () #foreign "gl" "flush" ---$/
 framebufferRenderbuffer        /usr/share/onyx/core/js/webgl.onyx      /^framebufferRenderbuffer        :: proc (target: GLenum, attachment: GLenum, renderbuffertarget: GLenum, renderbuffer: GLRenderbuffer) #foreign "gl" "framebufferRenderbuffer" ---$/
 framebufferTexture2D   /usr/share/onyx/core/js/webgl.onyx      /^framebufferTexture2D           :: proc (target: GLenum, attachment: GLenum, textarget: GLenum, texture: GLTexture, level: GLint) #foreign "gl" "framebufferTexture2D" ---$/
 framebufferTextureLayer        /usr/share/onyx/core/js/webgl.onyx      /^framebufferTextureLayer        :: proc (target: GLenum, attachment: GLenum, texture: GLTexture, level: GLint, layer: GLint) #foreign "gl" "framebufferTextureLayer" ---$/
 free   /usr/share/onyx/core/builtin.onyx       /^free :: proc (use a: Allocator, ptr: rawptr) {$/
 frontFace      /usr/share/onyx/core/js/webgl.onyx      /^frontFace                      :: proc (mode: GLenum) #foreign "gl" "frontFace" ---$/
-game_launch    src/main.onyx   /^game_launch :: proc (gs: ^GameState) #foreign "game" "launch" ---$/
+game_launch    src/main.onyx   /^game_launch :: proc () #foreign "game" "launch" ---$/
 generateMipmap /usr/share/onyx/core/js/webgl.onyx      /^generateMipmap                 :: proc (target: GLenum) #foreign "gl" "generateMipmap" ---$/
 getActiveAttrib        /usr/share/onyx/core/js/webgl.onyx      /^getActiveAttrib                :: proc (program: GLProgram, index: GLuint, out: ^GLActiveInfo) #foreign "gl" "getActiveAttrib" ---$/
 getActiveUniform       /usr/share/onyx/core/js/webgl.onyx      /^getActiveUniform               :: proc (program: GLProgram, index: GLuint, out: ^GLActiveInfo) #foreign "gl" "getActiveUniform" ---$/
 getAttribLocation      /usr/share/onyx/core/js/webgl.onyx      /^getAttribLocation              :: proc (program: GLProgram, name: string) -> GLint #foreign "gl" "getAttribLocation" ---$/
 getBufferSubData       /usr/share/onyx/core/js/webgl.onyx      /^getBufferSubData               :: proc (target: GLenum, srcByteOffset: GLintptr, dstBuffer: string, dstOffset: GLuint, length: GLuint) #foreign "gl" "getBufferSubData" ---$/
-getError       /usr/share/onyx/core/js/webgl.onyx      /^getError                       :: proc -> GLenum #foreign "gl" "getError" ---$/
+getError       /usr/share/onyx/core/js/webgl.onyx      /^getError                       :: proc () -> GLenum #foreign "gl" "getError" ---$/
 getInternalformatParameter     /usr/share/onyx/core/js/webgl.onyx      /^getInternalformatParameter     :: proc (target: GLenum, internalFormat: GLenum, pname: GLenum) -> GLenum #foreign "gl" "getInternalformatParameter" ---$/
 getProgramParameter    /usr/share/onyx/core/js/webgl.onyx      /^getProgramParameter            :: proc (program: GLProgram, pname: GLenum) -> GLenum #foreign "gl" "getProgramParameter" ---$/
 getShaderParameter     /usr/share/onyx/core/js/webgl.onyx      /^getShaderParameter             :: proc (shader: GLShader, pname: GLenum) -> GLenum #foreign "gl" "getShaderParameter" ---$/
@@ -749,14 +747,22 @@ heap_alloc_proc   /usr/share/onyx/core/alloc.onyx /^heap_alloc_proc :: proc (data:
 heap_allocator /usr/share/onyx/core/alloc.onyx /^heap_allocator : Allocator;$/
 heap_block     /usr/share/onyx/core/alloc.onyx /^heap_block :: struct {$/
 heap_free      /usr/share/onyx/core/alloc.onyx /^heap_free :: proc (ptr: rawptr) {$/
-heap_init      /usr/share/onyx/core/alloc.onyx /^heap_init :: proc {$/
+heap_init      /usr/share/onyx/core/alloc.onyx /^heap_init :: proc () {$/
 heap_resize    /usr/share/onyx/core/alloc.onyx /^heap_resize :: proc (ptr: rawptr, new_size: u32, align: u32) -> rawptr {$/
 heap_state     /usr/share/onyx/core/alloc.onyx /^heap_state : struct {$/
 hint   /usr/share/onyx/core/js/webgl.onyx      /^hint                           :: proc (target: GLenum, mode: GLenum) #foreign "gl" "hint" ---$/
+i32map_clear   /usr/share/onyx/core/i32map.onyx        /^i32map_clear :: proc (use imap: ^I32Map($T)) {$/
+i32map_delete  /usr/share/onyx/core/i32map.onyx        /^i32map_delete :: proc (use imap: ^I32Map($T), key: i32) {$/
+i32map_free    /usr/share/onyx/core/i32map.onyx        /^i32map_free :: proc (use imap: ^I32Map($T)) {$/
+i32map_get     /usr/share/onyx/core/i32map.onyx        /^i32map_get :: proc (use imap: ^I32Map($T), key: i32, default := cast(T) 0) -> T {$/
+i32map_has     /usr/share/onyx/core/i32map.onyx        /^i32map_has :: proc (use imap: ^I32Map($T), key: i32) -> bool {$/
+i32map_init    /usr/share/onyx/core/i32map.onyx        /^i32map_init :: proc (use imap: ^I32Map($T), hash_count: i32 = 16) {$/
+i32map_put     /usr/share/onyx/core/i32map.onyx        /^i32map_put :: proc (use imap: ^I32Map($T), key: i32, value: T) {$/
 i64_to_string  /usr/share/onyx/core/string.onyx        /^i64_to_string :: proc (n_: i64, base: u64, buf: Buffer) -> string {$/
-init   src/events.onyx /^init :: proc {$/
+init   src/events.onyx /^init :: proc () {$/
 init   /usr/share/onyx/core/js/webgl.onyx      /^init                           :: proc (canvasname: string) -> GLboolean #foreign "gl" "init" ---$/
 init   src/input.onyx  /^init :: proc (use state: ^InputState) {$/
+input_state    src/main.onyx   /^input_state   : input.InputState$/
 invalidateFramebuffer  /usr/share/onyx/core/js/webgl.onyx      /^invalidateFramebuffer          :: proc (target: GLenum, attachments: string) #foreign "gl" "invalidateFramebuffer" ---$/
 invalidateSubFramebuffer       /usr/share/onyx/core/js/webgl.onyx      /^invalidateSubFramebuffer       :: proc (target: GLenum, attachments: string, x: GLint, y: GLint, width: GLsizei, height: GLsizei) #foreign "gl" "invalidateSubFramebuffer" ---$/
 isEnabled      /usr/share/onyx/core/js/webgl.onyx      /^isEnabled                      :: proc (cap: GLenum) -> GLboolean #foreign "gl" "isEnabled" ---$/
@@ -771,38 +777,39 @@ max_f32   /usr/share/onyx/core/intrinsics.onyx    /^max_f32      :: proc (lhs: f32, r
 max_f64        /usr/share/onyx/core/intrinsics.onyx    /^max_f64      :: proc (lhs: f64, rhs: f64) -> f64 #intrinsic ---$/
 memory_copy    /usr/share/onyx/core/memory.onyx        /^memory_copy :: proc (dst_: rawptr, src_: rawptr, len: u32) {$/
 memory_grow    /usr/share/onyx/core/intrinsics.onyx    /^memory_grow  :: proc (val: i32) -> i32 #intrinsic ---$/
-memory_init    /usr/share/onyx/core/alloc.onyx /^memory_init :: proc {$/
-memory_size    /usr/share/onyx/core/intrinsics.onyx    /^memory_size  :: proc -> i32 #intrinsic ---$/
+memory_init    /usr/share/onyx/core/alloc.onyx /^memory_init :: proc () {$/
+memory_size    /usr/share/onyx/core/intrinsics.onyx    /^memory_size  :: proc () -> i32 #intrinsic ---$/
 min_f32        /usr/share/onyx/core/intrinsics.onyx    /^min_f32      :: proc (lhs: f32, rhs: f32) -> f32 #intrinsic ---$/
 min_f64        /usr/share/onyx/core/intrinsics.onyx    /^min_f64      :: proc (lhs: f64, rhs: f64) -> f64 #intrinsic ---$/
 nearest_f32    /usr/share/onyx/core/intrinsics.onyx    /^nearest_f32  :: proc (val: f32) -> f32 #intrinsic ---$/
 nearest_f64    /usr/share/onyx/core/intrinsics.onyx    /^nearest_f64  :: proc (val: f64) -> f64 #intrinsic ---$/
-new_frame_callback     src/main.onyx   /^new_frame_callback :: proc (gs: ^GameState) #export {$/
+new_frame_callback     src/main.onyx   /^new_frame_callback :: proc () #export {$/
 null   /usr/share/onyx/core/builtin.onyx       /^null :: cast(rawptr) 0;$/
 or_i32 /usr/share/onyx/core/intrinsics.onyx    /^or_i32       :: proc (lhs: i32, rhs: i32) -> i32 #intrinsic ---$/
 or_i64 /usr/share/onyx/core/intrinsics.onyx    /^or_i64       :: proc (lhs: i64, rhs: i64) -> i64 #intrinsic ---$/
 output_string  /usr/share/onyx/core/sys/js.onyx        /^output_string :: proc (s: string) -> u32 #foreign "host" "print_str" ---$/
 pixelStorei    /usr/share/onyx/core/js/webgl.onyx      /^pixelStorei                    :: proc (pname: GLenum, param: GLenum) #foreign "gl" "pixelStorei" ---$/
+player src/main.onyx   /^player : Player$/
 poll   src/events.onyx /^poll :: proc (ev: ^Event) -> bool {$/
-poll_events    src/main.onyx   /^poll_events :: proc (use gs: ^GameState) {$/
+poll_events    src/main.onyx   /^poll_events :: proc () {$/
 polygonOffset  /usr/share/onyx/core/js/webgl.onyx      /^polygonOffset                  :: proc (factor: GLfloat, units: GLfloat) #foreign "gl" "polygonOffset" ---$/
 popcnt_i32     /usr/share/onyx/core/intrinsics.onyx    /^popcnt_i32   :: proc (val: i32) -> i32 #intrinsic ---$/
 popcnt_i64     /usr/share/onyx/core/intrinsics.onyx    /^popcnt_i64   :: proc (val: i64) -> i64 #intrinsic ---$/
 postupdate     src/input.onyx  /^postupdate :: proc (use state: ^InputState) {$/
 preupdate      src/input.onyx  /^preupdate :: proc (use state: ^InputState) ---$/
-print  /usr/share/onyx/core/stdio.onyx /^print :: proc #overloaded {$/
+print  /usr/share/onyx/core/stdio.onyx /^print :: proc {$/
 printProgramInfoLog    /usr/share/onyx/core/js/webgl.onyx      /^printProgramInfoLog            :: proc (program: GLProgram) #foreign "gl" "printProgramInfoLog" ---$/
 printShaderInfoLog     /usr/share/onyx/core/js/webgl.onyx      /^printShaderInfoLog             :: proc (shader: GLShader) #foreign "gl" "printShaderInfoLog" ---$/
 print_array    /usr/share/onyx/core/stdio.onyx /^print_array :: proc (arr: $T, sep := " ") {$/
 print_bool     /usr/share/onyx/core/stdio.onyx /^print_bool    :: proc (b: bool) do string_builder_append(^print_buffer, b);$/
-print_buffer   /usr/share/onyx/core/stdio.onyx /^print_buffer : StringBuilder;$/
-print_buffer_flush     /usr/share/onyx/core/stdio.onyx /^print_buffer_flush :: proc {$/
+print_buffer_flush     /usr/share/onyx/core/stdio.onyx /^print_buffer_flush :: proc () {$/
 print_cstring  /usr/share/onyx/core/stdio.onyx /^print_cstring :: proc (s: cstring) do string_builder_append(^print_buffer, s);$/
 print_i32      /usr/share/onyx/core/stdio.onyx /^print_i32     :: proc (n: i32, base := 10)  do string_builder_append(^print_buffer, cast(i64) n, cast(u64) base);$/
 print_i64      /usr/share/onyx/core/stdio.onyx /^print_i64     :: proc (n: i64, base := 10l) do string_builder_append(^print_buffer, n, base);$/
 print_ptr      /usr/share/onyx/core/stdio.onyx /^print_ptr     :: proc (p: ^void) do string_builder_append(^print_buffer, cast(i64) p, 16l);$/
 print_range    /usr/share/onyx/core/stdio.onyx /^print_range :: proc (r: range, sep := " ") {$/
 print_string   /usr/share/onyx/core/stdio.onyx /^print_string  :: proc (s: string) {$/
+println        /usr/share/onyx/core/stdio.onyx /^println :: proc (x: $T) {$/
 process_event  src/input.onyx  /^process_event :: proc (use state: ^InputState, ev: ^event.Event) {$/
 ptrmap_clear   /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_clear :: proc (use pmap: ^PtrMap) {$/
 ptrmap_delete  /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_delete :: proc (use pmap: ^PtrMap, key: rawptr) {$/
@@ -810,11 +817,12 @@ ptrmap_free       /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_free :: proc (use pmap: ^P
 ptrmap_get     /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_get :: proc (use pmap: ^PtrMap, key: rawptr) -> rawptr {$/
 ptrmap_has     /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_has :: proc (use pmap: ^PtrMap, key: rawptr) -> bool {$/
 ptrmap_init    /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_init :: proc (use pmap: ^PtrMap, hash_count: i32 = 16) {$/
-ptrmap_lookup  /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_lookup :: proc (use pmap: ^PtrMap, key: rawptr) -> PtrMapLookupResult {$/
 ptrmap_put     /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_put :: proc (use pmap: ^PtrMap, key: rawptr, value: rawptr) {$/
 quad_rebuffer_data     src/gfx/quad_renderer.onyx      /^quad_rebuffer_data :: proc (use qr: ^QuadRenderer) {$/
+quad_renderer  src/main.onyx   /^quad_renderer : QuadRenderer$/
 quad_renderer_draw     src/gfx/quad_renderer.onyx      /^quad_renderer_draw :: proc (use qr: ^QuadRenderer) {$/
 quad_renderer_init     src/gfx/quad_renderer.onyx      /^quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {$/
+quad_renderer_update_view      src/gfx/quad_renderer.onyx      /^quad_renderer_update_view :: proc (use qr: ^QuadRenderer) {$/
 quad_update_at_index   src/gfx/quad_renderer.onyx      /^quad_update_at_index :: proc (use qr: ^QuadRenderer, idx: i32, quad: Quad) {$/
 random /usr/share/onyx/core/random.onyx        /^random :: proc (s := ^seed) -> u32 {$/
 random_between /usr/share/onyx/core/random.onyx        /^random_between :: proc (lo: i32, hi: i32) -> i32 do return random() % (hi + 1 - lo) + lo;$/
@@ -845,7 +853,7 @@ slr_i32     /usr/share/onyx/core/intrinsics.onyx    /^slr_i32      :: proc (lhs: i32, r
 slr_i64        /usr/share/onyx/core/intrinsics.onyx    /^slr_i64      :: proc (lhs: i64, rhs: i64) -> i64 #intrinsic ---$/
 sqrt_f32       /usr/share/onyx/core/intrinsics.onyx    /^sqrt_f32     :: proc (val: f32) -> f32 #intrinsic ---$/
 sqrt_f64       /usr/share/onyx/core/intrinsics.onyx    /^sqrt_f64     :: proc (val: f64) -> f64 #intrinsic ---$/
-stdio_init     /usr/share/onyx/core/stdio.onyx /^stdio_init :: proc {$/
+stdio_init     /usr/share/onyx/core/stdio.onyx /^stdio_init :: proc () {$/
 stencilFunc    /usr/share/onyx/core/js/webgl.onyx      /^stencilFunc                    :: proc (func: GLenum, ref: GLint, mask: GLuint) #foreign "gl" "stencilFunc" ---$/
 stencilFuncSeparate    /usr/share/onyx/core/js/webgl.onyx      /^stencilFuncSeparate            :: proc (face: GLenum, func: GLenum, ref: GLint, mask: GLuint) #foreign "gl" "stencilFuncSeparate" ---$/
 stencilMask    /usr/share/onyx/core/js/webgl.onyx      /^stencilMask                    :: proc (mask: GLuint) #foreign "gl" "stencilMask" ---$/
@@ -858,17 +866,16 @@ string_builder_add_bool   /usr/share/onyx/core/string.onyx        /^string_builder_add_bo
 string_builder_add_cstring     /usr/share/onyx/core/string.onyx        /^string_builder_add_cstring :: proc (use sb: ^StringBuilder, cstr: cstring) -> ^StringBuilder {$/
 string_builder_add_i64 /usr/share/onyx/core/string.onyx        /^string_builder_add_i64 :: proc (use sb: ^StringBuilder, n: i64, base := 10l) -> ^StringBuilder {$/
 string_builder_add_string      /usr/share/onyx/core/string.onyx        /^string_builder_add_string :: proc (use sb: ^StringBuilder, str: string) -> ^StringBuilder {$/
-string_builder_append  /usr/share/onyx/core/string.onyx        /^string_builder_append :: proc #overloaded {$/
+string_builder_append  /usr/share/onyx/core/string.onyx        /^string_builder_append :: proc {$/
 string_builder_clear   /usr/share/onyx/core/string.onyx        /^string_builder_clear :: proc (use sb: ^StringBuilder) -> ^StringBuilder {$/
 string_builder_make    /usr/share/onyx/core/string.onyx        /^string_builder_make :: proc (initial_cap: u32) -> StringBuilder {$/
 string_builder_to_string       /usr/share/onyx/core/string.onyx        /^string_builder_to_string :: proc (use sb: ^StringBuilder) -> string {$/
 string_concat  /usr/share/onyx/core/string.onyx        /^string_concat :: proc (s1: string, s2: string) -> string {$/
 string_contains        /usr/share/onyx/core/string.onyx        /^string_contains :: proc (str: string, c: u8) -> bool {$/
 string_free    /usr/share/onyx/core/string.onyx        /^string_free :: proc (s: string) do cfree(s.data);$/
-string_length  /usr/share/onyx/core/string.onyx        /^string_length :: proc #overloaded {$/
-string_make    /usr/share/onyx/core/string.onyx        /^string_make :: proc #overloaded { string_make_from_cstring }$/
-string_make_from_cstring       /usr/share/onyx/core/string.onyx        /^string_make_from_cstring :: proc (s: cstring) -> string {$/
-string_read    /usr/share/onyx/core/string.onyx        /^string_read :: proc #overloaded {$/
+string_length  /usr/share/onyx/core/string.onyx        /^string_length :: proc {$/
+string_make    /usr/share/onyx/core/string.onyx        /^string_make :: proc (s: cstring) -> string {$/
+string_read    /usr/share/onyx/core/string.onyx        /^string_read :: proc {$/
 string_read_char       /usr/share/onyx/core/string.onyx        /^string_read_char :: proc (str: ^string, out: ^u8) {$/
 string_read_line       /usr/share/onyx/core/string.onyx        /^string_read_line :: proc (str: ^string, out: ^string) {$/
 string_read_u32        /usr/share/onyx/core/string.onyx        /^string_read_u32 :: proc (str: ^string, out: ^u32) {$/
@@ -880,6 +887,9 @@ texImage2D  /usr/share/onyx/core/js/webgl.onyx      /^texImage2D                     :
 texParameterf  /usr/share/onyx/core/js/webgl.onyx      /^texParameterf                  :: proc (target: GLenum, pname: GLenum, param: GLfloat) #foreign "gl" "texParameterf" ---$/
 texParameteri  /usr/share/onyx/core/js/webgl.onyx      /^texParameteri                  :: proc (target: GLenum, pname: GLenum, param: GLint) #foreign "gl" "texParameteri" ---$/
 texSubImage2D  /usr/share/onyx/core/js/webgl.onyx      /^texSubImage2D                  :: proc (target: GLenum, level: GLint, xoff: GLint, yoff: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: string) #foreign "gl" "texSubImage2D" ---$/
+texture_create src/gfx/texture.onyx    /^texture_create :: proc (texdata: [] Color3, width: i32, height: i32) -> Texture {$/
+texture_prepare        src/gfx/texture.onyx    /^texture_prepare :: proc (use tex: ^Texture) {$/
+texture_use    src/gfx/texture.onyx    /^texture_use :: proc (use tex: ^Texture) {$/
 trunc_f32      /usr/share/onyx/core/intrinsics.onyx    /^trunc_f32    :: proc (val: f32) -> f32 #intrinsic ---$/
 trunc_f64      /usr/share/onyx/core/intrinsics.onyx    /^trunc_f64    :: proc (val: f64) -> f64 #intrinsic ---$/
 uniform1f      /usr/share/onyx/core/js/webgl.onyx      /^uniform1f                      :: proc (loc: GLUniformLocation, x: GLfloat) #foreign "gl" "uniform1f" ---$/
@@ -893,7 +903,7 @@ uniform4i   /usr/share/onyx/core/js/webgl.onyx      /^uniform4i                      ::
 uniformMatrix2 /usr/share/onyx/core/js/webgl.onyx      /^uniformMatrix2                 :: proc (loc: GLUniformLocation, transpose: GLboolean, value: GLMat2) #foreign "gl" "uniformMatrix2" ---$/
 uniformMatrix3 /usr/share/onyx/core/js/webgl.onyx      /^uniformMatrix3                 :: proc (loc: GLUniformLocation, transpose: GLboolean, value: GLMat3) #foreign "gl" "uniformMatrix3" ---$/
 uniformMatrix4 /usr/share/onyx/core/js/webgl.onyx      /^uniformMatrix4                 :: proc (loc: GLUniformLocation, transpose: GLboolean, value: GLMat4) #foreign "gl" "uniformMatrix4" ---$/
-update src/main.onyx   /^update :: proc (use gs: ^GameState) {$/
+update src/main.onyx   /^update :: proc () {$/
 useProgram     /usr/share/onyx/core/js/webgl.onyx      /^useProgram                     :: proc (program: GLProgram) #foreign "gl" "useProgram" ---$/
 validateProgram        /usr/share/onyx/core/js/webgl.onyx      /^validateProgram                :: proc (program: GLProgram) #foreign "gl" "validateProgram" ---$/
 vertexAttrib1f /usr/share/onyx/core/js/webgl.onyx      /^vertexAttrib1f                 :: proc (idx: GLuint, x: GLfloat) #foreign "gl" "vertexAttrib1f" ---$/