random improvements and upgrades
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 4 Mar 2022 14:34:03 +0000 (08:34 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 4 Mar 2022 14:34:03 +0000 (08:34 -0600)
run_tree/scenes/quick_save_new.scene
src/build.onyx
src/entity/components/patron.onyx
src/entity/editor.onyx
src/gfx/font.onyx
src/gfx/immediate.onyx
src/gfx/ui.onyx
src/utils/input.onyx

index 01a3580d89600c2dc7b4690750d428e8e39b39cd..4b0bc41ef4edfa955944f8e17be4e0821a9e7525 100644 (file)
@@ -120,6 +120,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 31
@@ -141,6 +147,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 32
@@ -162,6 +174,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 40
@@ -183,6 +201,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 41
@@ -204,6 +228,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 42
@@ -225,6 +255,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 55
@@ -246,6 +282,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 54
@@ -267,6 +309,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 53
@@ -288,6 +336,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 52
@@ -309,6 +363,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 51
@@ -330,6 +390,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Furniture]
 id = 50
@@ -351,6 +417,12 @@ sprite.color.r = 1.0000
 sprite.color.g = 1.0000
 sprite.color.b = 1.0000
 sprite.color.a = 1.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 
 [Wall]
 id = 35
@@ -424,7 +496,7 @@ max_timeout = 2.0000
 [Player]
 id = 12
 flags = 2
-pos.x = 312.4881
+pos.x = 312.4880
 pos.y = 271.0974
 size.x = 16.0000
 size.y = 32.0000
@@ -436,7 +508,7 @@ controls.right = 68
 controls.interact = 70
 controls.pick_up = 71
 facing = 3
-velocity.x = -0.0000
+velocity.x = 0.0000
 velocity.y = 0.0000
 :PlayerComponent
 holding = 150
@@ -450,7 +522,16 @@ color.a = 1.0000
 [Item_Entity]
 id = 150
 flags = 6
-size.x = 16
-size.y = 16
+pos.x = 312.4880
+pos.y = 247.0973
+size.x = 16.0000
+size.y = 16.0000
+:RenderComponent
+layer = 10
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
 :ItemComponent
-item = "burger"
\ No newline at end of file
+item = "burger"
+
index 1485f53a8126696e9a4d9cb7869b4a7e3fdb4e6a..8906ca407c21c0d660a400a8af708b316baf4332 100644 (file)
@@ -4,7 +4,7 @@ package runtime.vars
 MAJOR_VERSION :: 0
 MINOR_VERSION :: 1
 
-// DEBUG :: false
+DEBUG :: true
 
 
 #load_path ONYX_PATH
index 6d32f96592d54f2de19d5d25f51fac70c549d2be..87f0312a3927baad48cf16d0a576ded3f5a426b1 100644 (file)
@@ -36,7 +36,9 @@ PatronComponent :: struct {
         defer memory.free_slice(^seats);
         if seats.count == 0 do return false;
 
-        while seat == Entity_Nothing {
+        attempts := seats.count;
+
+        while seat == Entity_Nothing && attempts > 0 {
             it := random.choice(seats);
             furniture := it->get(FurnitureComponent);
             if furniture.furniture_type != .Seat do continue;
@@ -44,9 +46,11 @@ PatronComponent :: struct {
                 seat = it.id;
                 break;
             }
+
+            attempts -= 1;
         }
 
-        return true;
+        return seat != Entity_Nothing;
     }
 
     update :: (use this: ^PatronComponent, entity: ^Entity, dt: f32) {
index b6e85aaa69c14de14d26ff96b4e7f4fb370dcbcb..288f0c231cdc691361677c865766ba7a5e11a878 100644 (file)
@@ -34,8 +34,8 @@ editor_toggle :: () {
 editor_update :: (dt: f32) {
     move_towards(^editor_openness, editor_target_openness, dt * 6);
 
-    if is_key_just_up(GLFW_KEY_1) do clicked_tab = .Create;
-    if is_key_just_up(GLFW_KEY_2) do clicked_tab = .Edit;
+    if is_key_just_up(GLFW_KEY_1) do clicked_tab = .Edit;
+    if is_key_just_up(GLFW_KEY_2) do clicked_tab = .Create;
     if is_key_just_up(GLFW_KEY_G) do editor_grid_shown = !editor_grid_shown;
 
     handle_clicking_tab(dt);
@@ -72,19 +72,19 @@ editor_update :: (dt: f32) {
     mouse_pos := mouse_get_position_vector() - scene_render_offset;
 
     if mouse_pos.x < ~~window_width - sidebar_width {
-        if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) || is_button_just_down(GLFW_MOUSE_BUTTON_RIGHT) {
+        if is_button_just_up(GLFW_MOUSE_BUTTON_LEFT) || is_button_just_up(GLFW_MOUSE_BUTTON_RIGHT) {
             if active_tab == .Edit do active_index = -1;
             selected_entity_id = Entity_Nothing;
 
             for scene.entities {
                 if Entity.get_rect(it) |> Rect.contains(mouse_pos) {
                     selected_entity_id = it.id;
-                    // break;
+                    // break_just_up;
                 }
             }
 
-            dragging = is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) && selected_entity_id != Entity_Nothing;
-            resizing = is_button_just_down(GLFW_MOUSE_BUTTON_RIGHT) && selected_entity_id != Entity_Nothing;
+            dragging = is_button_just_up(GLFW_MOUSE_BUTTON_LEFT) && selected_entity_id != Entity_Nothing;
+            resizing = is_button_just_up(GLFW_MOUSE_BUTTON_RIGHT) && selected_entity_id != Entity_Nothing;
         }
     }
 
@@ -336,6 +336,7 @@ editor_draw :: () {
             if !is_disabled && Rect.contains(.{x, y + 2, w, Field_Height + 2}, mouse_get_position_vector()) {
                 if active_index < 0 do sidebar_width += w;
                 active_index = i - 1;
+                prepare_field_editor(member_any);
             }
         }
 
@@ -375,6 +376,13 @@ editor_draw :: () {
     return y, i;
 }
 
+#local prepare_field_editor :: (v: any) {
+    array.ensure_capacity(^field_buffer, 256);
+    field_buffer.count = 256;
+    s := conv.format_va(field_buffer, "{}", .[v]);
+    field_buffer.count = s.count;
+}
+
 #local render_field_editor :: (v: any, y: f32, field_name: str) {
     w := sidebar_width / 2;
     h := 200.0f;
@@ -388,10 +396,16 @@ editor_draw :: () {
     switch v.type {
         type_is(i32) {
             font_print(editor_font, x, y + 32, "INT: {}\n", value);
+            if draw_textbox(.{ x, y + 64, w, 48 }, ^field_buffer) {
+                conv.parse_any(v.data, v.type, field_buffer);
+            }
         }
 
         type_is(f32) {
             font_print(editor_font, x, y + 32, "FLOAT: {}\n", value);
+            if draw_textbox(.{ x, y + 64, w, 48 }, ^field_buffer) {
+                conv.parse_any(v.data, v.type, field_buffer);
+            }
         }
 
         case #default {
@@ -459,14 +473,16 @@ editor_draw :: () {
 
     Tabs :: enum {
         None;
-        Create;
         Edit;
+        Create;
     }
 
-    active_tab  := Tabs.Create;
+    active_tab  := Tabs.Edit;
     clicked_tab := Tabs.None;
 
     active_index := -1;
+    field_shown  := -1;
+    field_buffer: [..] u8;
 
     editor_grid_shown := false;
     editor_grid_size := 16.0f; @TODO // This should be configurable
index 35994bbb11d3719cb11e7cbb7db6e1cfd404a41e..0cfcafbaf314c91eb20abd18bccb3a90ae1c236a 100644 (file)
@@ -232,6 +232,16 @@ font_get_height :: (font: Font, msg: str) -> f32 {
     return y_ + font.em + 2;
 }
 
+font_get_char_width :: (font: Font, ch: u8) -> f32 {
+    x, y := 0.0f, 0.0f;
+    quad: stbtt_aligned_quad;
+
+    stbtt_GetPackedQuad(font.chars.data, font.texture_width, font.texture_height,
+        ~~(ch - #char " "), ^x, ^y, ^quad, false);
+
+    return x;
+}
+
 
 FontDescriptor :: struct {
     path : str;
index 487e5bd872ddf42c33e1e8ca0454d4df671e6471..a4720176282c9efd6d05402470107001451e776f 100644 (file)
@@ -126,6 +126,8 @@ immediate_ellipse :: () {}
 
 immediate_push_scissor :: (x, y, w, h: f32) {
     // Assuming that x, y, w, and h are in screen (window) coordinates.
+    x += offset.x;
+    y += offset.y;
 
     scissors << .{x, y, w, h};
     glEnable(GL_SCISSOR_TEST);
index b1b0f965865b517fffee4f9aff5a838aaf208200..20f9dc81a9a23c75d7e9cb9922b870075184f857 100644 (file)
@@ -164,6 +164,7 @@ draw_textbox :: (use r: Rect, text_buffer: ^[..] u8, placeholder := null_str, th
     if is_hot_item(hash) && !is_active_item(hash) {
         if is_button_down(GLFW_MOUSE_BUTTON_LEFT) && contains {
             set_active_item(hash);
+            input_capture_keys();
             textbox_editing_state.hash = hash;
             textbox_editing_state.cursor_animation_speed = theme.cursor_blink_speed;
         }
@@ -172,6 +173,7 @@ draw_textbox :: (use r: Rect, text_buffer: ^[..] u8, placeholder := null_str, th
     if is_active_item(hash) {
         if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) && !contains {
             set_active_item(0);
+            input_release_keys();
             textbox_editing_state.hash = 0;
             textbox_editing_state.cursor_position = 0;
         }
@@ -191,37 +193,51 @@ draw_textbox :: (use r: Rect, text_buffer: ^[..] u8, placeholder := null_str, th
         }
 
         keys := input_get_keys_this_frame();
-        if keys.count > 0 {
-            for key: keys {
-                switch key {
-                    case GLFW_KEY_LEFT  do textbox_editing_state.cursor_position -= 1;
-                    case GLFW_KEY_RIGHT do textbox_editing_state.cursor_position += 1;
-                    case GLFW_KEY_END   do textbox_editing_state.cursor_position = text_buffer.count;
-                    case GLFW_KEY_HOME  do textbox_editing_state.cursor_position = 0;
-
-                    case GLFW_KEY_BACKSPACE {
-                        array.pop(text_buffer);
-                        textbox_editing_state.cursor_position = math.max(~~0, textbox_editing_state.cursor_position - 1);
+        for key: iter.as_iterator(^keys) {
+            switch key.key {
+                case GLFW_KEY_LEFT  do textbox_editing_state.cursor_position -= 1;
+                case GLFW_KEY_RIGHT do textbox_editing_state.cursor_position += 1;
+                case GLFW_KEY_END   do textbox_editing_state.cursor_position = text_buffer.count;
+                case GLFW_KEY_HOME  do textbox_editing_state.cursor_position = 0;
+
+                case GLFW_KEY_BACKSPACE {
+                    if textbox_editing_state.cursor_position > 0 {
+                        array.delete(text_buffer, textbox_editing_state.cursor_position - 1);
                     }
+                    textbox_editing_state.cursor_position = math.max(~~0, textbox_editing_state.cursor_position - 1);
+                }
+
+                case GLFW_KEY_DELETE {
+                    array.delete(text_buffer, textbox_editing_state.cursor_position);
+                }
 
-                    case GLFW_KEY_DELETE {
-                        array.delete(text_buffer, textbox_editing_state.cursor_position);
+                case #default {
+                    if key.key >= 256 {
+                        // This is probably a modifier key.
+                        continue;
                     }
 
-                    case #default {
-                        if key >= #char " " && key <= 128 {
-                            array.push(text_buffer, ~~key);
-                            textbox_editing_state.cursor_position += 1;
-                        }
+                    shift_is_pressed := (key.mod & 1) != 0;
+                    index := key.key * 2;
+                    if shift_is_pressed do index += 1;
+
+                    char := key_map[index];
+                    if char != #char "\0" {
+                        // array.push(text_buffer, char);
+                        array.insert(text_buffer, textbox_editing_state.cursor_position, char);
+                        textbox_editing_state.cursor_position += 1;
+                    } else {
+                        println(key.key);
                     }
                 }
             }
+            result = true;
+        }
 
-            textbox_editing_state.cursor_position = math.clamp(textbox_editing_state.cursor_position, 0, text_buffer.count);
-            textbox_editing_state.cursor_animation = 1.0f;
+        textbox_editing_state.cursor_position = math.clamp(textbox_editing_state.cursor_position, 0, text_buffer.count);
+        textbox_editing_state.cursor_animation = 1.0f;
 
-            text = str.{text_buffer.data, text_buffer.count};
-        }
+        text = str.{text_buffer.data, text_buffer.count};
     }
 
     if is_hot_item(hash) {
@@ -240,6 +256,11 @@ draw_textbox :: (use r: Rect, text_buffer: ^[..] u8, placeholder := null_str, th
     immediate_rectangle(x + border_width, y + border_width, w - border_width * 2, h - border_width * 2);
 
     // Draw the cursor on textboxes
+    if is_active_item(hash) {
+        cursor := cursor_to_screen(^font, x + border_width, y + border_width, text, textbox_editing_state.cursor_position);
+        immediate_set_color(.{0,0,0});
+        immediate_rectangle(cursor.x, cursor.y + 2, 2, h - border_width * 2 - 4);
+    }
 
     font_set_color(theme.text_color);
     font_draw(font, text_x, text_y, text); // This is technically a frame late for updating the text?
@@ -248,6 +269,22 @@ draw_textbox :: (use r: Rect, text_buffer: ^[..] u8, placeholder := null_str, th
 
     immediate_pop_scissor();
     return result;
+
+    cursor_to_screen :: (font: ^Font, x, y: f32, text: str, cur_pos: i32) -> Vector2 {
+        cx := x;
+        cy := y;
+
+        for text[0 .. cur_pos] {
+            if it == #char "\n" {
+                cx = 0;
+                cy += font.em + 2;
+            } else {
+                cx += font_get_char_width(*font, it);
+            }
+        }
+
+        return .{ cx, cy };
+    }
 }
 
 
@@ -478,4 +515,242 @@ scrolling_region_stop :: () {
         b = c1.b * (1 - t) + c2.b * t,
         a = c1.a * (1 - t) + c2.a * t,
     };
+
+    @Relocate @Cleanup
+    // This keymap is very wrong in a lot of ways. It works for my standard US keyboard, but will break horribly
+    // for any other keyboard layout. I would like to use something else from the browser, but unsurprisingly the
+    // browser does not make this easy. Gotta love web "standards"....
+    key_map := u8.[
+        // Keycode     Normal        Shift
+        /* 00  */    #char "\0",   #char "\0",
+        /* 01  */    #char "\0",   #char "\0",
+        /* 02  */    #char "\0",   #char "\0",
+        /* 03  */    #char "\0",   #char "\0",
+        /* 04  */    #char "\0",   #char "\0",
+        /* 05  */    #char "\0",   #char "\0",
+        /* 06  */    #char "\0",   #char "\0",
+        /* 07  */    #char "\0",   #char "\0",
+        /* 08  */    #char "\0",   #char "\0",
+        /* 09  */    #char "\0",   #char "\0",
+        /* 10  */    #char "\0",   #char "\0",
+        /* 11  */    #char "\0",   #char "\0",
+        /* 12  */    #char "\0",   #char "\0",
+        /* 13  */    #char "\0",   #char "\0",
+        /* 14  */    #char "\0",   #char "\0",
+        /* 15  */    #char "\0",   #char "\0",
+        /* 16  */    #char "\0",   #char "\0",
+        /* 17  */    #char "\0",   #char "\0",
+        /* 18  */    #char "\0",   #char "\0",
+        /* 19  */    #char "\0",   #char "\0",
+        /* 20  */    #char "\0",   #char "\0",
+        /* 21  */    #char "\0",   #char "\0",
+        /* 22  */    #char "\0",   #char "\0",
+        /* 23  */    #char "\0",   #char "\0",
+        /* 24  */    #char "\0",   #char "\0",
+        /* 25  */    #char "\0",   #char "\0",
+        /* 26  */    #char "\0",   #char "\0",
+        /* 27  */    #char "\0",   #char "\0",
+        /* 28  */    #char "\0",   #char "\0",
+        /* 29  */    #char "\0",   #char "\0",
+        /* 30  */    #char "\0",   #char "\0",
+        /* 31  */    #char "\0",   #char "\0",
+        /* 32  */    #char " ",    #char " ",
+        /* 33  */    #char "\0",   #char "\0",
+        /* 34  */    #char "\0",   #char "\0",
+        /* 35  */    #char "\0",   #char "\0",
+        /* 36  */    #char "\0",   #char "\0",
+        /* 37  */    #char "\0",   #char "\0",
+        /* 38  */    #char "\0",   #char "\0",
+        /* 39  */    #char "'",    #char "\"",
+        /* 40  */    #char "\0",   #char "\0",
+        /* 41  */    #char "\0",   #char "\0",
+        /* 42  */    #char "\0",   #char "\0",
+        /* 43  */    #char "\0",   #char "\0",
+        /* 44  */    #char ",",    #char "<",
+        /* 45  */    #char "-",    #char "_",
+        /* 46  */    #char ".",    #char ">",
+        /* 47  */    #char "/",    #char "?",
+        /* 48  */    #char "0",    #char ")",
+        /* 49  */    #char "1",    #char "!",
+        /* 50  */    #char "2",    #char "@",
+        /* 51  */    #char "3",    #char "#",
+        /* 52  */    #char "4",    #char "$",
+        /* 53  */    #char "5",    #char "%",
+        /* 54  */    #char "6",    #char "^",
+        /* 55  */    #char "7",    #char "&",
+        /* 56  */    #char "8",    #char "*",
+        /* 57  */    #char "9",    #char "(",
+        /* 58  */    #char "\0",   #char "\0",
+        /* 59  */    #char ";",    #char ":",
+        /* 60  */    #char "\0",   #char "\0",
+        /* 61  */    #char "=",    #char "+",
+        /* 62  */    #char "\0",   #char "\0",
+        /* 63  */    #char "\0",   #char "\0",
+        /* 64  */    #char "\0",   #char "\0",
+        /* 65  */    #char "a",    #char "A",
+        /* 66  */    #char "b",    #char "B",
+        /* 67  */    #char "c",    #char "C",
+        /* 68  */    #char "d",    #char "D",
+        /* 69  */    #char "e",    #char "E",
+        /* 70  */    #char "f",    #char "F",
+        /* 71  */    #char "g",    #char "G",
+        /* 72  */    #char "h",    #char "H",
+        /* 73  */    #char "i",    #char "I",
+        /* 74  */    #char "j",    #char "J",
+        /* 75  */    #char "k",    #char "K",
+        /* 76  */    #char "l",    #char "L",
+        /* 77  */    #char "m",    #char "M",
+        /* 78  */    #char "n",    #char "N",
+        /* 79  */    #char "o",    #char "O",
+        /* 80  */    #char "p",    #char "P",
+        /* 81  */    #char "q",    #char "Q",
+        /* 82  */    #char "r",    #char "R",
+        /* 83  */    #char "s",    #char "S",
+        /* 84  */    #char "t",    #char "T",
+        /* 85  */    #char "u",    #char "U",
+        /* 86  */    #char "v",    #char "V",
+        /* 87  */    #char "w",    #char "W",
+        /* 88  */    #char "x",    #char "X",
+        /* 89  */    #char "y",    #char "Y",
+        /* 90  */    #char "z",    #char "Z",
+        /* 91  */    #char "[",    #char "{",
+        /* 92  */    #char "\\",   #char "|",
+        /* 93  */    #char "]",    #char "}",
+        /* 94  */    #char "\0",   #char "\0",
+        /* 95  */    #char "\0",   #char "\0",
+        /* 96  */    #char "`",    #char "~",
+        /* 97  */    #char "\0",   #char "\0",
+        /* 98  */    #char "\0",   #char "\0",
+        /* 99  */    #char "\0",   #char "\0",
+        /* 100 */    #char "\0",   #char "\0",
+        /* 101 */    #char "\0",   #char "\0",
+        /* 102 */    #char "\0",   #char "\0",
+        /* 103 */    #char "\0",   #char "\0",
+        /* 104 */    #char "\0",   #char "\0",
+        /* 105 */    #char "\0",   #char "\0",
+        /* 106 */    #char "\0",   #char "\0",
+        /* 107 */    #char "\0",   #char "\0",
+        /* 108 */    #char "\0",   #char "\0",
+        /* 109 */    #char "\0",   #char "\0",
+        /* 110 */    #char "\0",   #char "\0",
+        /* 111 */    #char "\0",   #char "\0",
+        /* 112 */    #char "\0",   #char "\0",
+        /* 113 */    #char "\0",   #char "\0",
+        /* 114 */    #char "\0",   #char "\0",
+        /* 115 */    #char "\0",   #char "\0",
+        /* 116 */    #char "\0",   #char "\0",
+        /* 117 */    #char "\0",   #char "\0",
+        /* 118 */    #char "\0",   #char "\0",
+        /* 119 */    #char "\0",   #char "\0",
+        /* 120 */    #char "\0",   #char "\0",
+        /* 121 */    #char "\0",   #char "\0",
+        /* 122 */    #char "\0",   #char "\0",
+        /* 123 */    #char "\0",   #char "\0",
+        /* 124 */    #char "\0",   #char "\0",
+        /* 125 */    #char "\0",   #char "\0",
+        /* 126 */    #char "\0",   #char "\0",
+        /* 127 */    #char "\0",   #char "\0",
+        /* 128 */    #char "\0",   #char "\0",
+        /* 129 */    #char "\0",   #char "\0",
+        /* 130 */    #char "\0",   #char "\0",
+        /* 131 */    #char "\0",   #char "\0",
+        /* 132 */    #char "\0",   #char "\0",
+        /* 133 */    #char "\0",   #char "\0",
+        /* 134 */    #char "\0",   #char "\0",
+        /* 135 */    #char "\0",   #char "\0",
+        /* 136 */    #char "\0",   #char "\0",
+        /* 137 */    #char "\0",   #char "\0",
+        /* 138 */    #char "\0",   #char "\0",
+        /* 139 */    #char "\0",   #char "\0",
+        /* 140 */    #char "\0",   #char "\0",
+        /* 141 */    #char "\0",   #char "\0",
+        /* 142 */    #char "\0",   #char "\0",
+        /* 143 */    #char "\0",   #char "\0",
+        /* 144 */    #char "\0",   #char "\0",
+        /* 145 */    #char "\0",   #char "\0",
+        /* 146 */    #char "\0",   #char "\0",
+        /* 147 */    #char "\0",   #char "\0",
+        /* 148 */    #char "\0",   #char "\0",
+        /* 149 */    #char "\0",   #char "\0",
+        /* 150 */    #char "\0",   #char "\0",
+        /* 151 */    #char "\0",   #char "\0",
+        /* 152 */    #char "\0",   #char "\0",
+        /* 153 */    #char "\0",   #char "\0",
+        /* 154 */    #char "\0",   #char "\0",
+        /* 155 */    #char "\0",   #char "\0",
+        /* 156 */    #char "\0",   #char "\0",
+        /* 157 */    #char "\0",   #char "\0",
+        /* 158 */    #char "\0",   #char "\0",
+        /* 159 */    #char "\0",   #char "\0",
+        /* 160 */    #char "\0",   #char "\0",
+        /* 161 */    #char "\0",   #char "\0",
+        /* 162 */    #char "\0",   #char "\0",
+        /* 163 */    #char "\0",   #char "\0",
+        /* 164 */    #char "\0",   #char "\0",
+        /* 165 */    #char "\0",   #char "\0",
+        /* 166 */    #char "\0",   #char "\0",
+        /* 167 */    #char "\0",   #char "\0",
+        /* 168 */    #char "\0",   #char "\0",
+        /* 169 */    #char "\0",   #char "\0",
+        /* 170 */    #char "\0",   #char "\0",
+        /* 171 */    #char "\0",   #char "\0",
+        /* 172 */    #char "\0",   #char "\0",
+        /* 173 */    #char "\0",   #char "\0",
+        /* 174 */    #char "\0",   #char "\0",
+        /* 175 */    #char "\0",   #char "\0",
+        /* 176 */    #char "\0",   #char "\0",
+        /* 177 */    #char "\0",   #char "\0",
+        /* 178 */    #char "\0",   #char "\0",
+        /* 179 */    #char "\0",   #char "\0",
+        /* 180 */    #char "\0",   #char "\0",
+        /* 181 */    #char "\0",   #char "\0",
+        /* 182 */    #char "\0",   #char "\0",
+        /* 183 */    #char "\0",   #char "\0",
+        /* 184 */    #char "\0",   #char "\0",
+        /* 185 */    #char "\0",   #char "\0",
+        /* 186 */    #char ";",    #char ":",
+        /* 187 */    #char "=",    #char "+",
+        /* 188 */    #char ",",    #char "<",
+        /* 189 */    #char "-",    #char "_",
+        /* 190 */    #char ".",    #char ">",
+        /* 191 */    #char "/",    #char "?",
+        /* 192 */    #char "`",    #char "~",
+        /* 193 */    #char "\0",   #char "\0",
+        /* 194 */    #char "\0",   #char "\0",
+        /* 195 */    #char "\0",   #char "\0",
+        /* 196 */    #char "\0",   #char "\0",
+        /* 197 */    #char "\0",   #char "\0",
+        /* 198 */    #char "\0",   #char "\0",
+        /* 199 */    #char "\0",   #char "\0",
+        /* 200 */    #char "\0",   #char "\0",
+        /* 201 */    #char "\0",   #char "\0",
+        /* 202 */    #char "\0",   #char "\0",
+        /* 203 */    #char "\0",   #char "\0",
+        /* 204 */    #char "\0",   #char "\0",
+        /* 205 */    #char "\0",   #char "\0",
+        /* 206 */    #char "\0",   #char "\0",
+        /* 207 */    #char "\0",   #char "\0",
+        /* 208 */    #char "\0",   #char "\0",
+        /* 209 */    #char "\0",   #char "\0",
+        /* 210 */    #char "\0",   #char "\0",
+        /* 211 */    #char "\0",   #char "\0",
+        /* 212 */    #char "\0",   #char "\0",
+        /* 213 */    #char "\0",   #char "\0",
+        /* 214 */    #char "\0",   #char "\0",
+        /* 215 */    #char "\0",   #char "\0",
+        /* 216 */    #char "\0",   #char "\0",
+        /* 217 */    #char "\0",   #char "\0",
+        /* 218 */    #char "\0",   #char "\0",
+        /* 219 */    #char "[",    #char "{",
+        /* 220 */    #char "\\",   #char "|",
+        /* 221 */    #char "]",    #char "}",
+        /* 222 */    #char "'",    #char "\"",
+        /* 223 */    #char "\0",   #char "\0",
+        /* 224 */    #char "\0",   #char "\0",
+        /* 225 */    #char "\0",   #char "\0",
+        /* 226 */    #char "\0",   #char "\0",
+        /* 227 */    #char "\0",   #char "\0",
+        /* 228 */    #char "\0",   #char "\0",
+        /* 229 */    #char "\0",   #char "\0",
+    ];
 }
index 5273c5076f7e623a58cd9363dcdab80cc29566b8..da9a2c33dacf6d4506ef1356555b42535f9e6810 100644 (file)
@@ -9,32 +9,48 @@ Mouse_Offset_Function :: immediate_get_scroll
 
 
 #local {
-       keys_this_frame  : [..] u32   // Keys currently being pressed this frame
-       keys_pulse_frame : [..] u32   // Keys pressed during this frame, only set once per keypress
-       keys_last_frame  : [..] u32   // Keys being pressed in the last frame
+       keys_this_frame  : Set(Key_Descriptor)   // Keys currently being pressed this frame
+       keys_pulse_frame : Set(Key_Descriptor)   // Keys pressed during this frame, only set once per keypress
+       keys_last_frame  : Set(Key_Descriptor)   // Keys being pressed in the last frame
 
        buttons_this_frame: [8] bool  // Mouse buttons being pressed this frame
        buttons_last_frame: [8] bool  // Mouse buttons being pressed last frame
 
        scroll_x: f64
        scroll_y: f64
+
+       keys_captured := false;
+}
+
+#init () {
+       set.init(^keys_this_frame);
+       set.init(^keys_pulse_frame);
+       set.init(^keys_last_frame);
 }
 
+Key_Descriptor :: struct {
+       key: u32;
+       scancode: u32 = 0;
+       mod: u32      = 0;
+}
+#match hash.to_u32 (use x: Key_Descriptor) => hash.to_u32(key);
+#operator == (x, y: Key_Descriptor) => x.key == y.key;
+
 input_update :: () {
     glfwGetCursorPos(window, ^mouse_x, ^mouse_y);
 
-       array.clear(^keys_pulse_frame);
-       for keys_this_frame {
-               if !array.contains(keys_last_frame, it) {
+       set.clear(^keys_pulse_frame);
+       for iter.as_iterator(^keys_this_frame) {
+               if !set.has(^keys_last_frame, it) {
                        keys_pulse_frame << it;
                }
        }
 }
 
 input_post_update :: () {
-       array.clear(^keys_pulse_frame);
-       array.clear(^keys_last_frame);
-       for keys_this_frame do keys_last_frame << it;
+       set.clear(^keys_pulse_frame);
+       set.clear(^keys_last_frame);
+       for keys_this_frame.entries do keys_last_frame << it.value;
 
        for 8 do buttons_last_frame[it] = buttons_this_frame[it];
 
@@ -44,13 +60,21 @@ input_post_update :: () {
        scroll_y = 0;
 }
 
-input_get_keys_this_frame :: () -> [] u32 {
+input_get_keys_this_frame :: () -> Set(Key_Descriptor) {
        return keys_pulse_frame;
 }
 
-is_key_down      :: (key) => array.contains(keys_this_frame, key);
-is_key_just_down :: (key) => array.contains(keys_this_frame, key) && !array.contains(keys_last_frame, key);
-is_key_just_up   :: (key) => !array.contains(keys_this_frame, key) && array.contains(keys_last_frame, key);
+input_capture_keys :: () {
+       keys_captured = true;
+}
+
+input_release_keys :: () {
+       keys_captured = false;
+}
+
+is_key_down      :: (key) => !keys_captured && set.has(^keys_this_frame, .{key});
+is_key_just_down :: (key) => !keys_captured && set.has(^keys_this_frame, .{key}) && !set.has(^keys_last_frame, .{key});
+is_key_just_up   :: (key) => !keys_captured && !set.has(^keys_this_frame, .{key}) && set.has(^keys_last_frame, .{key});
 
 is_button_down      :: (button) => buttons_this_frame[button];
 is_button_just_down :: (button) => buttons_this_frame[button] && !buttons_last_frame[button];
@@ -125,11 +149,15 @@ input_bind_glfw_events :: (window: GLFWwindow_p) {
 
 #export INPUT_KEY_EVENT (window: GLFWwindow_p, key, scancode, action, mod: u32) {
        if action == GLFW_PRESS {
-               keys_this_frame << key;
+               keys_this_frame << .{ key, scancode, mod };
+       }
+
+       if action == GLFW_REPEAT {
+               set.remove(^keys_last_frame, .{key});
        }
 
        if action == GLFW_RELEASE {
-               array.remove(^keys_this_frame, key);
+               set.remove(^keys_this_frame, .{ key });
        }
 }