added event system and input handler
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 9 Sep 2020 03:31:48 +0000 (22:31 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 9 Sep 2020 03:31:48 +0000 (22:31 -0500)
index.html
js/environment.js
js/webgl.js
src/gfx/quad_renderer.onyx
src/input.onyx [new file with mode: 0644]
src/main.onyx
src/shaders/basic.frag
src/shaders/basic.vert
tags

index ec76c5b589aa2de9d1b116df6449cdfdfc4642f4..637004979ed41dc2821411230ede288e31cecaa9 100644 (file)
@@ -9,6 +9,11 @@
         <script defer src="js/environment.js"></script>
         <script defer src="js/index.js"></script>
 
+        <style>
+            * { margin: 0; padding: 0; overflow: hidden; width: 100%; height: 100%; }
+            #gamecanvas { width: 100%; height: 100%; cursor: none; }
+        </style>
+
     </head>
     <body style="background: black">
         <canvas id="gamecanvas" width="1200" height="1200">No canvas for you.</canvas>
index 03a3b7d875b6ac3f04c048f4ce833c890d7bed15..dd5dc70af188c516ab3fedbcad89e762c5057340 100644 (file)
@@ -80,6 +80,8 @@ return {
             window.addEventListener("resize", (ev) => {
                 push_event_to_buffer(esp, event_size, 0x06, [ window.innerWidth, window.innerHeight ]);
             });
+
+            push_event_to_buffer(esp, event_size, 0x06, [ window.innerWidth, window.innerHeight ]);
         }
     }
 }
index 1199e8969f6625fe7027fe7d1cf61b1bbcf325f6..a8e727dfe49a8d57dfba92324069d7819a647e48 100644 (file)
@@ -57,6 +57,10 @@ WebGl_Wasm = {
         const data = new DataView(WASM_MEMORY.buffer, bufferdata, bufferlen);
         this.gl.bufferSubData(target, offset, data);
     },
+    canvasSize(width, height) {
+        this.canvas.width = width;
+        this.canvas.height = height;
+    },
     checkFrameBufferStatus(target) { return this.gl.checkFrameBufferStatus(target); },
     clear(bit) { this.gl.clear(bit); },
     clearColor(r, g, b, a) { this.gl.clearColor(r, g, b, a); },
index 37940e56e23ce0f8e7108b3c8192d8139e012d8a..ad3fddb6d4e6784251185941f4090805e51eaeec 100644 (file)
@@ -31,6 +31,7 @@ Quad :: struct {
     r : f32 = 0.0f;
     g : f32 = 0.0f;
     b : f32 = 0.0f;
+    a : f32 = 0.0f;
 }
 
 quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {
@@ -64,6 +65,7 @@ quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {
     default_quad.r = 0.0f;
     default_quad.g = 0.0f;
     default_quad.b = 0.0f;
+    default_quad.a = 0.0f;
     for i: 0 .. initial_quads {
         array_push(^quad_data, default_quad);
     }
@@ -83,7 +85,7 @@ quad_renderer_init :: proc (use qr: ^QuadRenderer, initial_quads := 10) {
     gl.vertexAttribDivisor(3, 1);
     gl.vertexAttribPointer(1, 2, gl.FLOAT, false, sizeof Quad, 0);
     gl.vertexAttribPointer(2, 2, gl.FLOAT, false, sizeof Quad, 2 * sizeof f32);
-    gl.vertexAttribPointer(3, 3, gl.FLOAT, false, sizeof Quad, 4 * sizeof f32);
+    gl.vertexAttribPointer(3, 4, gl.FLOAT, false, sizeof Quad, 4 * sizeof f32);
     gl.bindBuffer(gl.ARRAY_BUFFER, -1);
 
     index_data : [6] gl.GLubyte;
diff --git a/src/input.onyx b/src/input.onyx
new file mode 100644 (file)
index 0000000..4d8029c
--- /dev/null
@@ -0,0 +1,97 @@
+package input
+
+use package event as event
+use package core { print }
+
+KEY_COUNT :: 256
+BUTTON_COUNT :: 3
+
+Key :: enum {
+    ArrowLeft  :: 0x25;
+    ArrowUp    :: 0x26;
+    ArrowRight :: 0x27;
+    ArrowDown  :: 0x28;
+
+    Space :: 0x32;
+    A :: 0x41; B; C; D; E; F; G; H; I; J; K; L; M; N; O; P; Q; R; S; T; U; V; W; X; Y; Z;
+}
+
+InputState :: struct {
+    keys_down      : [KEY_COUNT] bool;
+    keys_just_down : [KEY_COUNT] bool;
+
+    mouse : struct {
+        x : u32;
+        y : u32;
+
+        buttons_down      : [BUTTON_COUNT] bool;
+        buttons_just_down : [BUTTON_COUNT] bool;
+    };
+}
+
+init :: proc (use state: ^InputState) {
+    for ^key: keys_down                  do *key = false;
+    for ^key: keys_just_down             do *key = false;
+    for ^button: mouse.buttons_down      do *button = false;
+    for ^button: mouse.buttons_just_down do *button = false;
+
+    mouse.x = 0;
+    mouse.y = 0;
+}
+
+process_event :: proc (use state: ^InputState, ev: ^event.Event) {
+    switch ev.kind {
+        case event.DomEventKind.KeyDown {
+            keys_just_down[ev.keyboard.keycode] = !keys_down[ev.keyboard.keycode];
+            keys_down[ev.keyboard.keycode] = true;
+        }
+
+        case event.DomEventKind.KeyUp {
+            keys_down[ev.keyboard.keycode] = false;
+            keys_just_down[ev.keyboard.keycode] = false;
+        }
+
+        case event.DomEventKind.MouseDown {
+            mouse.x = ev.mouse.pos_x;
+            mouse.y = ev.mouse.pos_y;
+
+            mouse.buttons_just_down[cast(u32) ev.mouse.button] = !mouse.buttons_down[cast(u32) ev.mouse.button];
+            mouse.buttons_down[cast(u32) ev.mouse.button] = true;
+        }
+
+        case event.DomEventKind.MouseUp {
+            mouse.x = ev.mouse.pos_x;
+            mouse.y = ev.mouse.pos_y;
+            mouse.buttons_down[cast(u32) ev.mouse.button] = false;
+            mouse.buttons_just_down[cast(u32) ev.mouse.button] = false;
+        }
+
+        case event.DomEventKind.MouseMove {
+            mouse.x = ev.mouse.pos_x;
+            mouse.y = ev.mouse.pos_y;
+        }
+    }
+}
+
+preupdate :: proc (use state: ^InputState) ---
+
+postupdate :: proc (use state: ^InputState) {
+    for ^key: keys_just_down             do *key = false;
+    for ^button: mouse.buttons_just_down do *button = false;
+}
+
+
+
+
+key_down :: proc (use state: ^InputState, key: Key) -> bool {
+    return keys_down[cast(u32) key];
+}
+
+key_just_down :: proc (use state: ^InputState, key: Key) -> bool {
+    return keys_just_down[cast(u32) key];
+}
+
+key_up :: proc (use state: ^InputState, key: Key) -> bool {
+    return !keys_down[cast(u32) key];
+}
+
index fda6efa16c61a0fc0fa23524451054a84038a428..f8f7e3c2e12524f68599060713d996153d5d659c 100644 (file)
@@ -7,68 +7,65 @@ package main
 #include_file "utils/gl"
 #include_file "gfx/quad_renderer"
 #include_file "events"
+#include_file "input"
 
 use package core
 use package gfx
 use package gl as gl
 use package event as event
+use package input as input { Key }
 
-NUM_QUADS :: 1000
+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) {
     ev : event.Event;
-    while event.poll(^ev) {
-        switch ev.kind {
-            case event.DomEventKind.KeyDown {
-                print("Key pressed: ");
-                print(ev.keyboard.keycode, 16);
-                print("\n");
-            }
-
-            case event.DomEventKind.KeyUp {
-                print("Key released: ");
-                print(ev.keyboard.keycode, 16);
-                print("\n");
-            }
-
-            case event.DomEventKind.MouseDown,
-                 event.DomEventKind.MouseUp {
-                print("Mouse event: (");
-                print(ev.mouse.pos_x);
-                print(", ");
-                print(ev.mouse.pos_y);
-                print(")    button: ");
-                print(cast(u32) ev.mouse.button);
-                print("\n");
-            }
-
-            case event.DomEventKind.MouseMove ---
-
-            case event.DomEventKind.Resize {
-                print("New window size: ");
-                print(ev.resize.width);
-                print("x");
-                print(ev.resize.height);
-                print("\n");
-            }
-
-            case #default {
-                print("Unknown event kind: ");
-                print(cast(u32) ev.kind);
-                print("\n");
-            }
+    while event.poll(^ev) do switch ev.kind {
+        case event.DomEventKind.KeyDown,
+             event.DomEventKind.KeyUp,
+             event.DomEventKind.MouseDown,
+             event.DomEventKind.MouseUp,
+             event.DomEventKind.MouseMove {
+            input.process_event(^input_state, ^ev);
+        }
+
+        case event.DomEventKind.Resize {
+            window_width  = ev.resize.width;
+            window_height = ev.resize.height;
+
+            gl.canvasSize(window_width, window_height);
+            gl.viewport(0, 0, window_width, window_height);
         }
     }
 }
 
 update :: proc (use gs: ^GameState) {
+    input.preupdate(^input_state);
+    defer input.postupdate(^input_state);
     poll_events(gs);
 
-    for i: 0 .. NUM_QUADS {
+    player_speed :: 0.004f;
+
+    if input.key_down(^input_state, Key.ArrowUp)    do player.y -= player_speed;
+    if input.key_down(^input_state, Key.ArrowDown)  do player.y += player_speed;
+    if input.key_down(^input_state, Key.ArrowLeft)  do player.x -= player_speed;
+    if input.key_down(^input_state, Key.ArrowRight) do player.x += player_speed;
+
+    /* for i: 0 .. NUM_QUADS {
         t := random_float();
         d := random_float(0.8f, 1.0f);
 
@@ -82,8 +79,27 @@ update :: proc (use gs: ^GameState) {
             r = random_float(),
             g = random_float(0.6f, 1.0f),
             b = random_float(0.6f, 1.0f),
+            a = 1.0f
         });
-    }
+    } */
+
+    quad_update_at_index(^quad_renderer, NUM_QUADS - 1, Quad.{
+        x = cast(f32) input_state.mouse.x / cast(f32) window_width - 0.025f,
+        y = cast(f32) input_state.mouse.y / cast(f32) window_height - 0.025f,
+
+        w = 0.05f, h = 0.05f,
+
+        r = 1.0f, g = 0.0f, b = 0.0f, a = 0.5f,
+    });
+
+    quad_update_at_index(^quad_renderer, 0, Quad.{
+        x = player.x,
+        y = player.y,
+
+        w = 0.025f, h = 0.025f,
+
+        r = 0.0f, g = 0.0f, b = 1.0f, a = 1.0f
+    });
 }
 
 draw :: proc (use gs: ^GameState) {
@@ -112,11 +128,17 @@ main :: proc (args: [] cstring) {
     gl.enable(gl.CULL_FACE);
     gl.cullFace(gl.BACK);
 
+    gl.enable(gl.BLEND);
+    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
     gs := cast(^GameState) calloc(sizeof GameState);
 
+    gs.player.pos = Vec2.{ 0.0f, 0.0f };
+
     quad_renderer_init(^gs.quad_renderer, NUM_QUADS);
 
     event.init();
+    input.init(^gs.input_state);
 
     game_launch(gs);
 }
index cce4d85776251fd15a12285f9ccddc37d0dc3a72..c32ab08f8bfc1f3855453ad35d14124f7f08abcc 100644 (file)
@@ -2,10 +2,10 @@
 
 precision mediump float;
 
-in vec3 v_col;
+in vec4 v_col;
 
 out vec4 fragColor;
 
 void main() {
-       fragColor = vec4(v_col, 1);
+       fragColor = v_col;
 }
index f3e02e25da0f98a35d976ed838604e05ae823f48..e73ac2579adda0e11553626c57b1fc12f2bf60fd 100644 (file)
@@ -3,11 +3,11 @@
 layout(location = 0) in vec2 a_vert_pos;
 layout(location = 1) in vec2 a_pos;
 layout(location = 2) in vec2 a_size;
-layout(location = 3) in vec3 a_col;
+layout(location = 3) in vec4 a_col;
 
 uniform mat3 u_proj;
 
-out vec3 v_col;
+out vec4 v_col;
 
 void main() {
        gl_Position = vec4(u_proj * vec3(a_vert_pos * a_size + a_pos, 1), 1);
diff --git a/tags b/tags
index a2e928c56a5cbbc4dbd082a5a2c8ee02e02c15b1..9bae4261636860e2ebc0302445db9cc11d6a7cae 100644 (file)
--- a/tags
+++ b/tags
@@ -41,6 +41,7 @@ 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$/
@@ -234,7 +235,10 @@ INVALID_INDEX      /usr/share/onyx/core/js/webgl.onyx      /^INVALID_INDEX
 INVALID_OPERATION      /usr/share/onyx/core/js/webgl.onyx      /^INVALID_OPERATION              :: 0x0502$/
 INVALID_VALUE  /usr/share/onyx/core/js/webgl.onyx      /^INVALID_VALUE                  :: 0x0501$/
 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$/
 LESS   /usr/share/onyx/core/js/webgl.onyx      /^LESS                           :: 0x0201$/
@@ -305,7 +309,7 @@ NICEST      /usr/share/onyx/core/js/webgl.onyx      /^NICEST                         :: 0x
 NONE   /usr/share/onyx/core/js/webgl.onyx      /^NONE                           :: 0$/
 NOTEQUAL       /usr/share/onyx/core/js/webgl.onyx      /^NOTEQUAL                       :: 0x0205$/
 NO_ERROR       /usr/share/onyx/core/js/webgl.onyx      /^NO_ERROR                       :: 0$/
-NUM_QUADS      src/main.onyx   /^NUM_QUADS :: 1000$/
+NUM_QUADS      src/main.onyx   /^NUM_QUADS :: 100$/
 OBJECT_TYPE    /usr/share/onyx/core/js/webgl.onyx      /^OBJECT_TYPE                                   :: 0x9112$/
 ONE    /usr/share/onyx/core/js/webgl.onyx      /^ONE                            :: 1$/
 ONE_MINUS_CONSTANT_ALPHA       /usr/share/onyx/core/js/webgl.onyx      /^ONE_MINUS_CONSTANT_ALPHA       :: 0x8004$/
@@ -750,9 +754,13 @@ hint       /usr/share/onyx/core/js/webgl.onyx      /^hint                           :: proc
 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   /usr/share/onyx/core/js/webgl.onyx      /^init                           :: proc (canvasname: string) -> GLboolean #foreign "gl" "init" ---$/
+init   src/input.onyx  /^init :: proc (use state: ^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" ---$/
+key_down       src/input.onyx  /^key_down :: proc (use state: ^InputState, key: Key) -> bool {$/
+key_just_down  src/input.onyx  /^key_just_down :: proc (use state: ^InputState, key: Key) -> bool {$/
+key_up src/input.onyx  /^key_up :: proc (use state: ^InputState, key: Key) -> bool {$/
 lineWidth      /usr/share/onyx/core/js/webgl.onyx      /^lineWidth                      :: proc (width: GLfloat) #foreign "gl" "lineWidth" ---$/
 linkProgram    /usr/share/onyx/core/js/webgl.onyx      /^linkProgram                    :: proc (program: GLProgram) #foreign "gl" "linkProgram" ---$/
 link_program   src/utils/gl.onyx       /^link_program :: proc (vertex_shader: gl.GLShader, frag_shader: gl.GLShader) -> gl.GLProgram {$/
@@ -778,6 +786,8 @@ poll_events src/main.onyx   /^poll_events :: proc (use gs: ^GameState) {$/
 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 {$/
 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" ---$/
@@ -791,6 +801,7 @@ print_i64   /usr/share/onyx/core/stdio.onyx /^print_i64     :: proc (n: i64, 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) {$/
+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) {$/
 ptrmap_free    /usr/share/onyx/core/ptrmap.onyx        /^ptrmap_free :: proc (use pmap: ^PtrMap) {$/
@@ -890,5 +901,6 @@ vertexAttrib4f      /usr/share/onyx/core/js/webgl.onyx      /^vertexAttrib4f
 vertexAttribDivisor    /usr/share/onyx/core/js/webgl.onyx      /^vertexAttribDivisor            :: proc (idx: GLuint, divisor: GLuint) #foreign "gl" "vertexAttribDivisor" ---$/
 vertexAttribPointer    /usr/share/onyx/core/js/webgl.onyx      /^vertexAttribPointer            :: proc (idx: GLuint, size: GLint, type: GLenum, normalized: GLboolean, stride: GLsizei, offset: GLint) #foreign "gl" "vertexAttribPointer" ---$/
 viewport       /usr/share/onyx/core/js/webgl.onyx      /^viewport                       :: proc (x: GLint, y: GLint, width: GLsizei, height: GLsizei) #foreign "gl" "viewport" ---      $/
+window_width   src/main.onyx   /^window_width := 0$/
 xor_i32        /usr/share/onyx/core/intrinsics.onyx    /^xor_i32      :: proc (lhs: i32, rhs: i32) -> i32 #intrinsic ---$/
 xor_i64        /usr/share/onyx/core/intrinsics.onyx    /^xor_i64      :: proc (lhs: i64, rhs: i64) -> i64 #intrinsic ---$/