From: Brendan Hansen Date: Wed, 9 Sep 2020 03:31:48 +0000 (-0500) Subject: added event system and input handler X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=f220df7f164f07235e1a8d2e3f0eef13975cd237;p=onyx-game.git added event system and input handler --- diff --git a/index.html b/index.html index ec76c5b..6370049 100644 --- a/index.html +++ b/index.html @@ -9,6 +9,11 @@ + + No canvas for you. diff --git a/js/environment.js b/js/environment.js index 03a3b7d..dd5dc70 100644 --- a/js/environment.js +++ b/js/environment.js @@ -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 ]); } } } diff --git a/js/webgl.js b/js/webgl.js index 1199e89..a8e727d 100644 --- a/js/webgl.js +++ b/js/webgl.js @@ -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); }, diff --git a/src/gfx/quad_renderer.onyx b/src/gfx/quad_renderer.onyx index 37940e5..ad3fddb 100644 --- a/src/gfx/quad_renderer.onyx +++ b/src/gfx/quad_renderer.onyx @@ -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 index 0000000..4d8029c --- /dev/null +++ b/src/input.onyx @@ -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]; +} + diff --git a/src/main.onyx b/src/main.onyx index fda6efa..f8f7e3c 100644 --- a/src/main.onyx +++ b/src/main.onyx @@ -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); } diff --git a/src/shaders/basic.frag b/src/shaders/basic.frag index cce4d85..c32ab08 100644 --- a/src/shaders/basic.frag +++ b/src/shaders/basic.frag @@ -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; } diff --git a/src/shaders/basic.vert b/src/shaders/basic.vert index f3e02e2..e73ac25 100644 --- a/src/shaders/basic.vert +++ b/src/shaders/basic.vert @@ -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 a2e928c..9bae426 100644 --- 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 ---$/